feat(components): DialTile for sensor signal rows

This commit is contained in:
fightrate-bot committed 2026-06-16 01:48:12 -03:00
1 parent bea019fb0f
commit 8232882977
2 files changed
+99

No files matched your search

+34
View File
@@ -0,0 +1,34 @@
import React from 'react';
import TestRenderer from 'react-test-renderer';
import { DialTile } from '../components/DialTile';
describe('DialTile', () => {
it('renders label and value', () => {
let tree: any;
TestRenderer.act(() => {
tree = TestRenderer.create(React.createElement(DialTile, { label: 'RSSI', value: '-61 dBm', testID: 'dial' }));
});
const json = JSON.stringify(tree.toJSON());
expect(json).toContain('RSSI');
expect(json).toContain('-61 dBm');
});
it('combines label and value into accessibilityLabel', () => {
let tree: any;
TestRenderer.act(() => {
tree = TestRenderer.create(React.createElement(DialTile, { label: 'RSSI', value: '-61 dBm', testID: 'dial' }));
});
const json = JSON.stringify(tree.toJSON());
expect(json).toContain('"accessibilityLabel":"RSSI: -61 dBm"');
});
it('uses action color when tone=red', () => {
let tree: any;
TestRenderer.act(() => {
tree = TestRenderer.create(React.createElement(DialTile, { label: 'X', value: 'Y', tone: 'red', testID: 'dial' }));
});
const json = JSON.stringify(tree.toJSON());
expect(json).toContain('#E23B2E');
});
});
+65
View File
@@ -0,0 +1,65 @@
import React from 'react';
import { StyleSheet, Text, View, type ViewStyle } from 'react-native';
import { colors, spacing, typography } from '../theme';
type Tone = 'amber' | 'green' | 'red';
type Props = {
readonly label: string;
readonly value: string;
readonly tone?: Tone;
readonly testID?: string;
};
function toneColor(tone: Tone | undefined): string {
if (tone === 'red') return colors.action;
if (tone === 'green') return colors.success;
return colors.warning;
}
export function DialTile({ label, value, tone = 'amber', testID }: Props) {
const markerStyle: ViewStyle = { backgroundColor: toneColor(tone) };
return (
<View
accessibilityLabel={`${label}: ${value}`}
style={styles.row}
testID={testID}
>
<View style={styles.markerWrap}>
<View style={[styles.marker, markerStyle]} />
</View>
<Text style={styles.value}>{value}</Text>
<Text style={styles.label}>{label}</Text>
</View>
);
}
const styles = StyleSheet.create({
row: {
minHeight: 56,
flexDirection: 'row',
alignItems: 'center',
borderTopWidth: 1,
borderColor: colors.line,
paddingVertical: spacing.sm,
paddingHorizontal: spacing.md,
gap: spacing.md,
},
markerWrap: {
width: 4,
height: 32,
justifyContent: 'center',
},
marker: {
width: 2,
height: 32,
},
value: {
...typography.detailNumeric,
flex: 1,
},
label: {
...typography.label,
color: colors.textDim,
},
});