feat(components): LiveDot pulsing indicator

This commit is contained in:
fightrate-bot committed 2026-06-16 01:47:19 -03:00
1 parent e8f828d90a
commit 9b02c10926
2 files changed
+82

No files matched your search

+46
View File
@@ -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();
});
});
});
+36
View File
@@ -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',
},
});