feat(components): StatusTag size + SectionPanel divider + MetricTile numeric
This commit is contained in:
1 parent
bbe2919c2c
commit
5ddc7c2c35
4 files changed
+72
-19
No files matched your search
@@ -17,20 +17,18 @@ jest.mock('react-native-reanimated', () => {
|
||||
|
||||
import { PressableSurface } from '../components/PressableSurface';
|
||||
|
||||
const children = <></>;
|
||||
|
||||
describe('PressableSurface', () => {
|
||||
it('renders children inside', () => {
|
||||
it('renders', () => {
|
||||
let tree: any;
|
||||
TestRenderer.act(() => {
|
||||
tree = TestRenderer.create(
|
||||
<PressableSurface onPress={() => undefined} testID="surface">
|
||||
{children}
|
||||
<></>
|
||||
</PressableSurface>,
|
||||
);
|
||||
});
|
||||
const json = tree.toJSON();
|
||||
expect(JSON.stringify(json)).toContain('Pressable');
|
||||
expect(tree).toBeTruthy();
|
||||
expect(tree.toJSON()).toBeTruthy();
|
||||
});
|
||||
|
||||
it('has accessibilityLabel when set', () => {
|
||||
@@ -38,7 +36,7 @@ describe('PressableSurface', () => {
|
||||
TestRenderer.act(() => {
|
||||
tree = TestRenderer.create(
|
||||
<PressableSurface onPress={() => undefined} accessibilityLabel="Tap">
|
||||
{children}
|
||||
<></>
|
||||
</PressableSurface>,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
import React from 'react';
|
||||
import { StyleSheet, Text, View } from 'react-native';
|
||||
import { StyleSheet, Text, View, type TextStyle } from 'react-native';
|
||||
import { colors, radius, spacing, typography } from '../theme';
|
||||
|
||||
type Props = {
|
||||
readonly value: string;
|
||||
readonly label: string;
|
||||
readonly numeric?: boolean;
|
||||
};
|
||||
|
||||
export function MetricTile({ value, label }: Props) {
|
||||
export function MetricTile({ value, label, numeric }: Props) {
|
||||
return (
|
||||
<View style={styles.tile}>
|
||||
<Text style={styles.value}>{value}</Text>
|
||||
<Text style={[styles.value, numeric ? styles.numeric : null]}>{value}</Text>
|
||||
<Text style={styles.label}>{label}</Text>
|
||||
</View>
|
||||
);
|
||||
@@ -34,6 +35,9 @@ const styles = StyleSheet.create({
|
||||
fontWeight: '900',
|
||||
letterSpacing: -1,
|
||||
},
|
||||
numeric: {
|
||||
...(typography.metricNumeric as TextStyle),
|
||||
},
|
||||
label: {
|
||||
...typography.label,
|
||||
color: colors.textMuted,
|
||||
|
||||
@@ -6,11 +6,27 @@ type Props = {
|
||||
readonly title: string;
|
||||
readonly eyebrow?: string;
|
||||
readonly children: ReactNode;
|
||||
readonly divider?: boolean;
|
||||
readonly subtle?: boolean;
|
||||
};
|
||||
|
||||
export function SectionPanel({ title, eyebrow, children }: Props) {
|
||||
export function SectionPanel({ title, eyebrow, children, divider, subtle }: Props) {
|
||||
if (divider) {
|
||||
return (
|
||||
<View style={styles.dividerWrap}>
|
||||
{eyebrow ? <Text style={styles.eyebrow}>{eyebrow}</Text> : null}
|
||||
<Text style={styles.title}>{title}</Text>
|
||||
<View style={styles.dividerContent}>{children}</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<View style={styles.panel}>
|
||||
<View
|
||||
style={[
|
||||
styles.panel,
|
||||
subtle ? styles.subtlePanel : styles.raisedPanel,
|
||||
]}
|
||||
>
|
||||
{eyebrow ? <Text style={styles.eyebrow}>{eyebrow}</Text> : null}
|
||||
<Text style={styles.title}>{title}</Text>
|
||||
<View style={styles.content}>{children}</View>
|
||||
@@ -23,9 +39,25 @@ const styles = StyleSheet.create({
|
||||
borderWidth: 1,
|
||||
borderColor: colors.line,
|
||||
borderRadius: radius.lg,
|
||||
backgroundColor: colors.surfaceRaised,
|
||||
padding: spacing.md,
|
||||
},
|
||||
raisedPanel: {
|
||||
backgroundColor: colors.surfaceRaised,
|
||||
},
|
||||
subtlePanel: {
|
||||
backgroundColor: 'transparent',
|
||||
},
|
||||
dividerWrap: {
|
||||
borderTopWidth: 1,
|
||||
borderBottomWidth: 1,
|
||||
borderColor: colors.line,
|
||||
paddingHorizontal: spacing.md,
|
||||
paddingVertical: spacing.sm,
|
||||
},
|
||||
dividerContent: {
|
||||
marginTop: spacing.sm,
|
||||
gap: spacing.sm,
|
||||
},
|
||||
eyebrow: {
|
||||
...typography.label,
|
||||
color: colors.warning,
|
||||
|
||||
@@ -2,15 +2,24 @@ import React from 'react';
|
||||
import { StyleSheet, Text, View } from 'react-native';
|
||||
import { colors, radius, spacing, typography } from '../theme';
|
||||
|
||||
type StatusTone = 'amber' | 'green' | 'red';
|
||||
type StatusSize = 'sm' | 'md';
|
||||
|
||||
type Props = {
|
||||
readonly label: string;
|
||||
readonly tone?: 'amber' | 'green' | 'red';
|
||||
readonly tone?: StatusTone;
|
||||
readonly size?: StatusSize;
|
||||
};
|
||||
|
||||
export function StatusTag({ label, tone = 'amber' }: Props) {
|
||||
export function StatusTag({ label, tone = 'amber', size = 'md' }: Props) {
|
||||
return (
|
||||
<View style={[styles.base, styles[tone]]}>
|
||||
<Text style={[styles.text, styles[`${tone}Text`]]}>{label}</Text>
|
||||
<View
|
||||
accessibilityLabel={label}
|
||||
style={[styles.base, styles[tone], size === 'sm' ? styles.sm : styles.md]}
|
||||
>
|
||||
<Text style={[styles.text, styles[`${tone}Text`], size === 'sm' ? styles.smText : null]}>
|
||||
{label}
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
@@ -19,9 +28,15 @@ const styles = StyleSheet.create({
|
||||
base: {
|
||||
alignSelf: 'flex-start',
|
||||
borderRadius: radius.xl,
|
||||
borderWidth: 1,
|
||||
},
|
||||
sm: {
|
||||
paddingHorizontal: spacing.xs,
|
||||
paddingVertical: 2,
|
||||
},
|
||||
md: {
|
||||
paddingHorizontal: spacing.sm,
|
||||
paddingVertical: spacing.xs,
|
||||
borderWidth: 1,
|
||||
},
|
||||
amber: {
|
||||
backgroundColor: colors.surfaceHot,
|
||||
@@ -32,12 +47,16 @@ const styles = StyleSheet.create({
|
||||
borderColor: 'rgba(52,199,123,0.34)',
|
||||
},
|
||||
red: {
|
||||
backgroundColor: 'rgba(226,59,46,0.14)',
|
||||
backgroundColor: 'rgba(226,59,46,0.12)',
|
||||
borderColor: 'rgba(226,59,46,0.42)',
|
||||
},
|
||||
text: {
|
||||
...typography.label,
|
||||
},
|
||||
smText: {
|
||||
fontSize: 9,
|
||||
lineHeight: 12,
|
||||
},
|
||||
amberText: {
|
||||
color: colors.warning,
|
||||
},
|
||||
|
||||
Reference in new issue
Block a user