feat(components): EmptyState with instrument geometry
This commit is contained in:
1 parent
fc42e1da43
commit
bea019fb0f
2 files changed
+138
No files matched your search
@@ -0,0 +1,30 @@
|
||||
import React from 'react';
|
||||
import TestRenderer from 'react-test-renderer';
|
||||
|
||||
import { EmptyState } from '../components/EmptyState';
|
||||
|
||||
describe('EmptyState', () => {
|
||||
it('renders eyebrow, title, and copy', () => {
|
||||
let tree: any;
|
||||
TestRenderer.act(() => {
|
||||
tree = TestRenderer.create(
|
||||
React.createElement(EmptyState, { eyebrow: 'SEM USO', title: 'Nenhum treino salvo', copy: 'Comece uma janela.' }),
|
||||
);
|
||||
});
|
||||
const json = JSON.stringify(tree.toJSON());
|
||||
expect(json).toContain('SEM USO');
|
||||
expect(json).toContain('Nenhum treino salvo');
|
||||
expect(json).toContain('Comece uma janela.');
|
||||
});
|
||||
|
||||
it('uses amber tone by default', () => {
|
||||
let tree: any;
|
||||
TestRenderer.act(() => {
|
||||
tree = TestRenderer.create(
|
||||
React.createElement(EmptyState, { eyebrow: 'X', title: 'Y', copy: 'Z', testID: 'es' }),
|
||||
);
|
||||
});
|
||||
const json = JSON.stringify(tree.toJSON());
|
||||
expect(json).toContain('rgba(255, 180, 61');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,108 @@
|
||||
import React from 'react';
|
||||
import { StyleSheet, Text, View } from 'react-native';
|
||||
import Svg, { Circle, Line, Rect } from 'react-native-svg';
|
||||
import { colors, radius, spacing, typography } from '../theme';
|
||||
|
||||
type Tone = 'amber' | 'red' | 'green';
|
||||
|
||||
type Props = {
|
||||
readonly eyebrow: string;
|
||||
readonly title: string;
|
||||
readonly copy: string;
|
||||
readonly tone?: Tone;
|
||||
readonly testID?: string;
|
||||
};
|
||||
|
||||
function toneColor(tone: Tone): string {
|
||||
if (tone === 'red') return colors.action;
|
||||
if (tone === 'green') return colors.success;
|
||||
return colors.warning;
|
||||
}
|
||||
|
||||
function toneBackground(tone: Tone): string {
|
||||
if (tone === 'red') return 'rgba(226, 59, 46, 0.12)';
|
||||
if (tone === 'green') return 'rgba(52, 199, 123, 0.12)';
|
||||
return 'rgba(255, 180, 61, 0.10)';
|
||||
}
|
||||
|
||||
export function EmptyState({
|
||||
eyebrow,
|
||||
title,
|
||||
copy,
|
||||
tone = 'amber',
|
||||
testID,
|
||||
}: Props) {
|
||||
return (
|
||||
<View
|
||||
accessibilityLabel={`${eyebrow}. ${title}. ${copy}`}
|
||||
style={[styles.wrap, { backgroundColor: toneBackground(tone) }]}
|
||||
testID={testID}
|
||||
>
|
||||
<View style={styles.geom}>
|
||||
<Svg height={64} viewBox="0 0 64 64" width={64}>
|
||||
<Rect
|
||||
x={6}
|
||||
y={6}
|
||||
width={52}
|
||||
height={52}
|
||||
stroke={toneColor(tone)}
|
||||
strokeWidth={1}
|
||||
fill="none"
|
||||
/>
|
||||
<Circle
|
||||
cx={32}
|
||||
cy={32}
|
||||
r={20}
|
||||
stroke={toneColor(tone)}
|
||||
strokeWidth={1}
|
||||
fill="none"
|
||||
/>
|
||||
<Line
|
||||
x1={6}
|
||||
y1={58}
|
||||
x2={58}
|
||||
y2={6}
|
||||
stroke={toneColor(tone)}
|
||||
strokeWidth={1}
|
||||
/>
|
||||
</Svg>
|
||||
</View>
|
||||
<Text style={[styles.eyebrow, { color: toneColor(tone) }]}>{eyebrow}</Text>
|
||||
<Text style={styles.title}>{title}</Text>
|
||||
<Text style={styles.copy}>{copy}</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
wrap: {
|
||||
borderTopWidth: 1,
|
||||
borderBottomWidth: 1,
|
||||
borderColor: colors.line,
|
||||
borderRadius: radius.md,
|
||||
paddingVertical: spacing.xl,
|
||||
paddingHorizontal: spacing.md,
|
||||
minHeight: 220,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
gap: spacing.sm,
|
||||
},
|
||||
geom: {
|
||||
marginBottom: spacing.sm,
|
||||
},
|
||||
eyebrow: {
|
||||
...typography.label,
|
||||
},
|
||||
title: {
|
||||
...typography.display,
|
||||
fontSize: 36,
|
||||
lineHeight: 38,
|
||||
textAlign: 'center',
|
||||
},
|
||||
copy: {
|
||||
...typography.body,
|
||||
color: colors.textMuted,
|
||||
textAlign: 'center',
|
||||
maxWidth: 280,
|
||||
},
|
||||
});
|
||||
Reference in new issue
Block a user