feat(components): LiveDot pulsing indicator
This commit is contained in:
1 parent
e8f828d90a
commit
9b02c10926
2 files changed
+82
No files matched your search
@@ -0,0 +1,46 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import TestRenderer from 'react-test-renderer';
|
||||||
|
|
||||||
|
jest.mock('react-native-reanimated', () => {
|
||||||
|
const { View } = require('react-native');
|
||||||
|
const Animated = {
|
||||||
|
View: View,
|
||||||
|
Text: require('react-native').Text,
|
||||||
|
};
|
||||||
|
return {
|
||||||
|
__esModule: true,
|
||||||
|
default: Animated,
|
||||||
|
Easing: { out: () => (() => 0), inOut: () => (() => 0), quad: () => 0 },
|
||||||
|
useSharedValue: (initial: number) => ({ value: initial }),
|
||||||
|
useAnimatedStyle: (fn: () => unknown) => fn(),
|
||||||
|
withTiming: (to: number) => to,
|
||||||
|
withRepeat: (to: number) => to,
|
||||||
|
cancelAnimation: () => undefined,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
import { LiveDot } from '../components/LiveDot';
|
||||||
|
|
||||||
|
describe('LiveDot', () => {
|
||||||
|
it('renders with AO VIVO label when live=true', () => {
|
||||||
|
let tree: any;
|
||||||
|
TestRenderer.act(() => {
|
||||||
|
tree = TestRenderer.create(React.createElement(LiveDot, { live: true }));
|
||||||
|
});
|
||||||
|
expect(JSON.stringify(tree.toJSON())).toContain('AO VIVO');
|
||||||
|
TestRenderer.act(() => {
|
||||||
|
tree.unmount();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders with INATIVO label when live=false', () => {
|
||||||
|
let tree: any;
|
||||||
|
TestRenderer.act(() => {
|
||||||
|
tree = TestRenderer.create(React.createElement(LiveDot, { live: false }));
|
||||||
|
});
|
||||||
|
expect(JSON.stringify(tree.toJSON())).toContain('INATIVO');
|
||||||
|
TestRenderer.act(() => {
|
||||||
|
tree.unmount();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { StyleSheet, type ViewStyle } from 'react-native';
|
||||||
|
import Animated from 'react-native-reanimated';
|
||||||
|
import { colors } from '../theme';
|
||||||
|
import { usePulseAnimation } from '../hooks/usePulseAnimation';
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
readonly live: boolean;
|
||||||
|
readonly size?: number;
|
||||||
|
readonly testID?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function LiveDot({ live, size = 8, testID }: Props) {
|
||||||
|
const animatedStyle = usePulseAnimation(live);
|
||||||
|
const dotStyle: ViewStyle = {
|
||||||
|
width: size,
|
||||||
|
height: size,
|
||||||
|
borderRadius: size / 2,
|
||||||
|
backgroundColor: live ? colors.success : colors.textDim,
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Animated.View
|
||||||
|
accessibilityLabel={live ? 'AO VIVO' : 'INATIVO'}
|
||||||
|
accessibilityRole="image"
|
||||||
|
style={[styles.base, dotStyle, animatedStyle]}
|
||||||
|
testID={testID}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
base: {
|
||||||
|
alignSelf: 'center',
|
||||||
|
},
|
||||||
|
});
|
||||||
Reference in new issue
Block a user