@umituz/react-native-design-system 2.6.48 → 2.6.50
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/atoms/skeleton/AtomicSkeleton.tsx +16 -62
- package/src/index.ts +0 -32
- package/src/molecules/bottom-sheet/components/BottomSheetModal.tsx +1 -12
- package/src/molecules/index.ts +0 -6
- package/src/molecules/animation/core/AnimationCore.ts +0 -29
- package/src/molecules/animation/domain/entities/Animation.ts +0 -81
- package/src/molecules/animation/domain/entities/Fireworks.ts +0 -44
- package/src/molecules/animation/domain/entities/Theme.ts +0 -76
- package/src/molecules/animation/index.ts +0 -146
- package/src/molecules/animation/infrastructure/services/AnimationConfigService.ts +0 -35
- package/src/molecules/animation/infrastructure/services/SpringAnimationConfigService.ts +0 -67
- package/src/molecules/animation/infrastructure/services/TimingAnimationConfigService.ts +0 -57
- package/src/molecules/animation/infrastructure/services/__tests__/SpringAnimationConfigService.test.ts +0 -114
- package/src/molecules/animation/infrastructure/services/__tests__/TimingAnimationConfigService.test.ts +0 -105
- package/src/molecules/animation/presentation/components/Fireworks.tsx +0 -127
- package/src/molecules/animation/presentation/components/__tests__/Fireworks.test.tsx +0 -185
- package/src/molecules/animation/presentation/hooks/__tests__/useAnimation.integration.test.ts +0 -210
- package/src/molecules/animation/presentation/hooks/__tests__/useFireworks.test.ts +0 -242
- package/src/molecules/animation/presentation/hooks/__tests__/useGesture.test.ts +0 -108
- package/src/molecules/animation/presentation/hooks/__tests__/useSpringAnimation.test.ts +0 -127
- package/src/molecules/animation/presentation/hooks/__tests__/useTimingAnimation.test.ts +0 -172
- package/src/molecules/animation/presentation/hooks/__tests__/useTransformAnimation.test.ts +0 -133
- package/src/molecules/animation/presentation/hooks/useAnimation.ts +0 -77
- package/src/molecules/animation/presentation/hooks/useFireworks.ts +0 -144
- package/src/molecules/animation/presentation/hooks/useGesture.ts +0 -57
- package/src/molecules/animation/presentation/hooks/useGestureCreators.ts +0 -163
- package/src/molecules/animation/presentation/hooks/useGestureState.ts +0 -53
- package/src/molecules/animation/presentation/hooks/useIconAnimations.ts +0 -120
- package/src/molecules/animation/presentation/hooks/useModalAnimations.ts +0 -124
- package/src/molecules/animation/presentation/hooks/useReanimatedReady.ts +0 -60
- package/src/molecules/animation/presentation/hooks/useSpringAnimation.ts +0 -69
- package/src/molecules/animation/presentation/hooks/useTimingAnimation.ts +0 -111
- package/src/molecules/animation/presentation/hooks/useTransformAnimation.ts +0 -57
- package/src/molecules/animation/presentation/providers/AnimationThemeProvider.tsx +0 -60
- package/src/molecules/animation/presentation/providers/__tests__/AnimationThemeProvider.test.tsx +0 -165
- package/src/molecules/celebration/domain/entities/CelebrationConfig.ts +0 -17
- package/src/molecules/celebration/domain/entities/FireworksConfig.ts +0 -32
- package/src/molecules/celebration/index.ts +0 -93
- package/src/molecules/celebration/infrastructure/services/FireworksConfigService.ts +0 -49
- package/src/molecules/celebration/presentation/components/CelebrationFireworksOverlay.tsx +0 -33
- package/src/molecules/celebration/presentation/components/CelebrationModal.tsx +0 -81
- package/src/molecules/celebration/presentation/components/CelebrationModalContent.tsx +0 -88
- package/src/molecules/celebration/presentation/hooks/useCelebrationModalAnimation.ts +0 -49
- package/src/molecules/celebration/presentation/hooks/useCelebrationState.ts +0 -45
- package/src/molecules/celebration/presentation/styles/CelebrationModalStyles.ts +0 -65
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Spring Animation Config Service
|
|
3
|
-
*
|
|
4
|
-
* Infrastructure service for spring animation configurations.
|
|
5
|
-
* Separates spring configuration logic from domain entities.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import type { AnimationSpringConfig } from '../../domain/entities/Animation';
|
|
9
|
-
import {
|
|
10
|
-
AnimationPreset,
|
|
11
|
-
ANIMATION_CONSTANTS,
|
|
12
|
-
} from '../../domain/entities/Animation';
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Service for providing spring animation configurations
|
|
16
|
-
*/
|
|
17
|
-
export class SpringAnimationConfigService {
|
|
18
|
-
/**
|
|
19
|
-
* Get preset spring config
|
|
20
|
-
*/
|
|
21
|
-
static getSpringConfig(preset: AnimationPreset): AnimationSpringConfig {
|
|
22
|
-
const configs: Record<AnimationPreset, AnimationSpringConfig> = {
|
|
23
|
-
[AnimationPreset.FADE_IN]: {
|
|
24
|
-
damping: ANIMATION_CONSTANTS.SPRING.DAMPING,
|
|
25
|
-
stiffness: ANIMATION_CONSTANTS.SPRING.STIFFNESS,
|
|
26
|
-
},
|
|
27
|
-
[AnimationPreset.FADE_OUT]: {
|
|
28
|
-
damping: ANIMATION_CONSTANTS.SPRING.DAMPING,
|
|
29
|
-
stiffness: ANIMATION_CONSTANTS.SPRING.STIFFNESS,
|
|
30
|
-
},
|
|
31
|
-
[AnimationPreset.SLIDE_IN_UP]: {
|
|
32
|
-
damping: ANIMATION_CONSTANTS.SPRING.DAMPING,
|
|
33
|
-
stiffness: ANIMATION_CONSTANTS.SPRING.STIFFNESS,
|
|
34
|
-
},
|
|
35
|
-
[AnimationPreset.SLIDE_IN_DOWN]: {
|
|
36
|
-
damping: ANIMATION_CONSTANTS.SPRING.DAMPING,
|
|
37
|
-
stiffness: ANIMATION_CONSTANTS.SPRING.STIFFNESS,
|
|
38
|
-
},
|
|
39
|
-
[AnimationPreset.SLIDE_IN_LEFT]: {
|
|
40
|
-
damping: ANIMATION_CONSTANTS.SPRING.DAMPING,
|
|
41
|
-
stiffness: ANIMATION_CONSTANTS.SPRING.STIFFNESS,
|
|
42
|
-
},
|
|
43
|
-
[AnimationPreset.SLIDE_IN_RIGHT]: {
|
|
44
|
-
damping: ANIMATION_CONSTANTS.SPRING.DAMPING,
|
|
45
|
-
stiffness: ANIMATION_CONSTANTS.SPRING.STIFFNESS,
|
|
46
|
-
},
|
|
47
|
-
[AnimationPreset.SCALE_IN]: {
|
|
48
|
-
damping: 15,
|
|
49
|
-
stiffness: 150,
|
|
50
|
-
},
|
|
51
|
-
[AnimationPreset.SCALE_OUT]: {
|
|
52
|
-
damping: 15,
|
|
53
|
-
stiffness: 150,
|
|
54
|
-
},
|
|
55
|
-
[AnimationPreset.BOUNCE]: {
|
|
56
|
-
damping: 5,
|
|
57
|
-
stiffness: 120,
|
|
58
|
-
},
|
|
59
|
-
[AnimationPreset.SHAKE]: {
|
|
60
|
-
damping: 8,
|
|
61
|
-
stiffness: 200,
|
|
62
|
-
},
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
return configs[preset];
|
|
66
|
-
}
|
|
67
|
-
}
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Timing Animation Config Service
|
|
3
|
-
*
|
|
4
|
-
* Infrastructure service for timing animation configurations.
|
|
5
|
-
* Separates timing configuration logic from domain entities.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import type { AnimationTimingConfig } from '../../domain/entities/Animation';
|
|
9
|
-
import {
|
|
10
|
-
AnimationPreset,
|
|
11
|
-
ANIMATION_CONSTANTS,
|
|
12
|
-
} from '../../domain/entities/Animation';
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Service for providing timing animation configurations
|
|
16
|
-
*/
|
|
17
|
-
export class TimingAnimationConfigService {
|
|
18
|
-
/**
|
|
19
|
-
* Get preset timing config
|
|
20
|
-
*/
|
|
21
|
-
static getTimingConfig(preset: AnimationPreset): AnimationTimingConfig {
|
|
22
|
-
const configs: Record<AnimationPreset, AnimationTimingConfig> = {
|
|
23
|
-
[AnimationPreset.FADE_IN]: {
|
|
24
|
-
duration: ANIMATION_CONSTANTS.DURATION.NORMAL,
|
|
25
|
-
},
|
|
26
|
-
[AnimationPreset.FADE_OUT]: {
|
|
27
|
-
duration: ANIMATION_CONSTANTS.DURATION.NORMAL,
|
|
28
|
-
},
|
|
29
|
-
[AnimationPreset.SLIDE_IN_UP]: {
|
|
30
|
-
duration: ANIMATION_CONSTANTS.DURATION.NORMAL,
|
|
31
|
-
},
|
|
32
|
-
[AnimationPreset.SLIDE_IN_DOWN]: {
|
|
33
|
-
duration: ANIMATION_CONSTANTS.DURATION.NORMAL,
|
|
34
|
-
},
|
|
35
|
-
[AnimationPreset.SLIDE_IN_LEFT]: {
|
|
36
|
-
duration: ANIMATION_CONSTANTS.DURATION.NORMAL,
|
|
37
|
-
},
|
|
38
|
-
[AnimationPreset.SLIDE_IN_RIGHT]: {
|
|
39
|
-
duration: ANIMATION_CONSTANTS.DURATION.NORMAL,
|
|
40
|
-
},
|
|
41
|
-
[AnimationPreset.SCALE_IN]: {
|
|
42
|
-
duration: ANIMATION_CONSTANTS.DURATION.FAST,
|
|
43
|
-
},
|
|
44
|
-
[AnimationPreset.SCALE_OUT]: {
|
|
45
|
-
duration: ANIMATION_CONSTANTS.DURATION.FAST,
|
|
46
|
-
},
|
|
47
|
-
[AnimationPreset.BOUNCE]: {
|
|
48
|
-
duration: ANIMATION_CONSTANTS.DURATION.SLOW,
|
|
49
|
-
},
|
|
50
|
-
[AnimationPreset.SHAKE]: {
|
|
51
|
-
duration: ANIMATION_CONSTANTS.DURATION.FAST,
|
|
52
|
-
},
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
return configs[preset];
|
|
56
|
-
}
|
|
57
|
-
}
|
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* SpringAnimationConfigService Tests
|
|
3
|
-
*
|
|
4
|
-
* Unit tests for spring animation configuration service.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { SpringAnimationConfigService } from '../SpringAnimationConfigService';
|
|
8
|
-
import { AnimationPreset, ANIMATION_CONSTANTS } from '../../../domain/entities/Animation';
|
|
9
|
-
|
|
10
|
-
describe('SpringAnimationConfigService', () => {
|
|
11
|
-
describe('getSpringConfig', () => {
|
|
12
|
-
it('should return config for FADE_IN preset', () => {
|
|
13
|
-
const config = SpringAnimationConfigService.getSpringConfig(AnimationPreset.FADE_IN);
|
|
14
|
-
|
|
15
|
-
expect(config).toEqual({
|
|
16
|
-
damping: ANIMATION_CONSTANTS.SPRING.DAMPING,
|
|
17
|
-
stiffness: ANIMATION_CONSTANTS.SPRING.STIFFNESS,
|
|
18
|
-
});
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
it('should return config for FADE_OUT preset', () => {
|
|
22
|
-
const config = SpringAnimationConfigService.getSpringConfig(AnimationPreset.FADE_OUT);
|
|
23
|
-
|
|
24
|
-
expect(config).toEqual({
|
|
25
|
-
damping: ANIMATION_CONSTANTS.SPRING.DAMPING,
|
|
26
|
-
stiffness: ANIMATION_CONSTANTS.SPRING.STIFFNESS,
|
|
27
|
-
});
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
it('should return config for SCALE_IN preset', () => {
|
|
31
|
-
const config = SpringAnimationConfigService.getSpringConfig(AnimationPreset.SCALE_IN);
|
|
32
|
-
|
|
33
|
-
expect(config).toEqual({
|
|
34
|
-
damping: 15,
|
|
35
|
-
stiffness: 150,
|
|
36
|
-
});
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
it('should return config for SCALE_OUT preset', () => {
|
|
40
|
-
const config = SpringAnimationConfigService.getSpringConfig(AnimationPreset.SCALE_OUT);
|
|
41
|
-
|
|
42
|
-
expect(config).toEqual({
|
|
43
|
-
damping: 15,
|
|
44
|
-
stiffness: 150,
|
|
45
|
-
});
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
it('should return config for BOUNCE preset', () => {
|
|
49
|
-
const config = SpringAnimationConfigService.getSpringConfig(AnimationPreset.BOUNCE);
|
|
50
|
-
|
|
51
|
-
expect(config).toEqual({
|
|
52
|
-
damping: 5,
|
|
53
|
-
stiffness: 120,
|
|
54
|
-
});
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
it('should return config for SHAKE preset', () => {
|
|
58
|
-
const config = SpringAnimationConfigService.getSpringConfig(AnimationPreset.SHAKE);
|
|
59
|
-
|
|
60
|
-
expect(config).toEqual({
|
|
61
|
-
damping: 8,
|
|
62
|
-
stiffness: 200,
|
|
63
|
-
});
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
it('should return default spring config for slide presets', () => {
|
|
67
|
-
const slidePresets = [
|
|
68
|
-
AnimationPreset.SLIDE_IN_UP,
|
|
69
|
-
AnimationPreset.SLIDE_IN_DOWN,
|
|
70
|
-
AnimationPreset.SLIDE_IN_LEFT,
|
|
71
|
-
AnimationPreset.SLIDE_IN_RIGHT,
|
|
72
|
-
];
|
|
73
|
-
|
|
74
|
-
slidePresets.forEach(preset => {
|
|
75
|
-
const config = SpringAnimationConfigService.getSpringConfig(preset);
|
|
76
|
-
|
|
77
|
-
expect(config).toEqual({
|
|
78
|
-
damping: ANIMATION_CONSTANTS.SPRING.DAMPING,
|
|
79
|
-
stiffness: ANIMATION_CONSTANTS.SPRING.STIFFNESS,
|
|
80
|
-
});
|
|
81
|
-
});
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
it('should handle all animation presets', () => {
|
|
85
|
-
const presets = Object.values(AnimationPreset);
|
|
86
|
-
|
|
87
|
-
presets.forEach(preset => {
|
|
88
|
-
const config = SpringAnimationConfigService.getSpringConfig(preset);
|
|
89
|
-
|
|
90
|
-
expect(config).toBeDefined();
|
|
91
|
-
expect(config).toHaveProperty('damping');
|
|
92
|
-
expect(config).toHaveProperty('stiffness');
|
|
93
|
-
expect(typeof config.damping).toBe('number');
|
|
94
|
-
expect(typeof config.stiffness).toBe('number');
|
|
95
|
-
expect(config.damping).toBeGreaterThan(0);
|
|
96
|
-
expect(config.stiffness).toBeGreaterThan(0);
|
|
97
|
-
});
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
it('should have appropriate values for different animation types', () => {
|
|
101
|
-
const bounceConfig = SpringAnimationConfigService.getSpringConfig(AnimationPreset.BOUNCE);
|
|
102
|
-
const shakeConfig = SpringAnimationConfigService.getSpringConfig(AnimationPreset.SHAKE);
|
|
103
|
-
const scaleConfig = SpringAnimationConfigService.getSpringConfig(AnimationPreset.SCALE_IN);
|
|
104
|
-
|
|
105
|
-
// Bounce should be more bouncy (lower damping, moderate stiffness)
|
|
106
|
-
expect(bounceConfig.damping).toBeLessThan(scaleConfig.damping);
|
|
107
|
-
expect(bounceConfig.stiffness).toBeLessThan(scaleConfig.stiffness);
|
|
108
|
-
|
|
109
|
-
// Shake should be quick and responsive (higher damping and stiffness)
|
|
110
|
-
expect(shakeConfig.damping).toBeGreaterThan(bounceConfig.damping);
|
|
111
|
-
expect(shakeConfig.stiffness).toBeGreaterThan(scaleConfig.stiffness);
|
|
112
|
-
});
|
|
113
|
-
});
|
|
114
|
-
});
|
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* TimingAnimationConfigService Tests
|
|
3
|
-
*
|
|
4
|
-
* Unit tests for timing animation configuration service.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { TimingAnimationConfigService } from '../TimingAnimationConfigService';
|
|
8
|
-
import { AnimationPreset, ANIMATION_CONSTANTS } from '../../../domain/entities/Animation';
|
|
9
|
-
|
|
10
|
-
describe('TimingAnimationConfigService', () => {
|
|
11
|
-
describe('getTimingConfig', () => {
|
|
12
|
-
it('should return config for FADE_IN preset', () => {
|
|
13
|
-
const config = TimingAnimationConfigService.getTimingConfig(AnimationPreset.FADE_IN);
|
|
14
|
-
|
|
15
|
-
expect(config).toEqual({
|
|
16
|
-
duration: ANIMATION_CONSTANTS.DURATION.NORMAL,
|
|
17
|
-
});
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
it('should return config for FADE_OUT preset', () => {
|
|
21
|
-
const config = TimingAnimationConfigService.getTimingConfig(AnimationPreset.FADE_OUT);
|
|
22
|
-
|
|
23
|
-
expect(config).toEqual({
|
|
24
|
-
duration: ANIMATION_CONSTANTS.DURATION.NORMAL,
|
|
25
|
-
});
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
it('should return config for SLIDE_IN_UP preset', () => {
|
|
29
|
-
const config = TimingAnimationConfigService.getTimingConfig(AnimationPreset.SLIDE_IN_UP);
|
|
30
|
-
|
|
31
|
-
expect(config).toEqual({
|
|
32
|
-
duration: ANIMATION_CONSTANTS.DURATION.NORMAL,
|
|
33
|
-
});
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
it('should return config for SLIDE_IN_DOWN preset', () => {
|
|
37
|
-
const config = TimingAnimationConfigService.getTimingConfig(AnimationPreset.SLIDE_IN_DOWN);
|
|
38
|
-
|
|
39
|
-
expect(config).toEqual({
|
|
40
|
-
duration: ANIMATION_CONSTANTS.DURATION.NORMAL,
|
|
41
|
-
});
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
it('should return config for SLIDE_IN_LEFT preset', () => {
|
|
45
|
-
const config = TimingAnimationConfigService.getTimingConfig(AnimationPreset.SLIDE_IN_LEFT);
|
|
46
|
-
|
|
47
|
-
expect(config).toEqual({
|
|
48
|
-
duration: ANIMATION_CONSTANTS.DURATION.NORMAL,
|
|
49
|
-
});
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
it('should return config for SLIDE_IN_RIGHT preset', () => {
|
|
53
|
-
const config = TimingAnimationConfigService.getTimingConfig(AnimationPreset.SLIDE_IN_RIGHT);
|
|
54
|
-
|
|
55
|
-
expect(config).toEqual({
|
|
56
|
-
duration: ANIMATION_CONSTANTS.DURATION.NORMAL,
|
|
57
|
-
});
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
it('should return config for SCALE_IN preset', () => {
|
|
61
|
-
const config = TimingAnimationConfigService.getTimingConfig(AnimationPreset.SCALE_IN);
|
|
62
|
-
|
|
63
|
-
expect(config).toEqual({
|
|
64
|
-
duration: ANIMATION_CONSTANTS.DURATION.FAST,
|
|
65
|
-
});
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
it('should return config for SCALE_OUT preset', () => {
|
|
69
|
-
const config = TimingAnimationConfigService.getTimingConfig(AnimationPreset.SCALE_OUT);
|
|
70
|
-
|
|
71
|
-
expect(config).toEqual({
|
|
72
|
-
duration: ANIMATION_CONSTANTS.DURATION.FAST,
|
|
73
|
-
});
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
it('should return config for BOUNCE preset', () => {
|
|
77
|
-
const config = TimingAnimationConfigService.getTimingConfig(AnimationPreset.BOUNCE);
|
|
78
|
-
|
|
79
|
-
expect(config).toEqual({
|
|
80
|
-
duration: ANIMATION_CONSTANTS.DURATION.SLOW,
|
|
81
|
-
});
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
it('should return config for SHAKE preset', () => {
|
|
85
|
-
const config = TimingAnimationConfigService.getTimingConfig(AnimationPreset.SHAKE);
|
|
86
|
-
|
|
87
|
-
expect(config).toEqual({
|
|
88
|
-
duration: ANIMATION_CONSTANTS.DURATION.FAST,
|
|
89
|
-
});
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
it('should handle all animation presets', () => {
|
|
93
|
-
const presets = Object.values(AnimationPreset);
|
|
94
|
-
|
|
95
|
-
presets.forEach(preset => {
|
|
96
|
-
const config = TimingAnimationConfigService.getTimingConfig(preset);
|
|
97
|
-
|
|
98
|
-
expect(config).toBeDefined();
|
|
99
|
-
expect(config).toHaveProperty('duration');
|
|
100
|
-
expect(typeof config.duration).toBe('number');
|
|
101
|
-
expect(config.duration).toBeGreaterThan(0);
|
|
102
|
-
});
|
|
103
|
-
});
|
|
104
|
-
});
|
|
105
|
-
});
|
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Fireworks Component
|
|
3
|
-
*
|
|
4
|
-
* Particle-based fireworks animation component.
|
|
5
|
-
* Single Responsibility: Render fireworks particles.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import React from 'react';
|
|
9
|
-
import { View, StyleSheet } from 'react-native';
|
|
10
|
-
import Animated, { useAnimatedStyle, withTiming } from 'react-native-reanimated';
|
|
11
|
-
import { useFireworks } from '../hooks/useFireworks';
|
|
12
|
-
import type { FireworksConfig } from '../../domain/entities/Fireworks';
|
|
13
|
-
|
|
14
|
-
const AnimatedView = (Animated as any).createAnimatedComponent(View);
|
|
15
|
-
|
|
16
|
-
export interface FireworksProps extends FireworksConfig {
|
|
17
|
-
/**
|
|
18
|
-
* X position to trigger fireworks (0-1, relative to container width)
|
|
19
|
-
*/
|
|
20
|
-
triggerX?: number;
|
|
21
|
-
/**
|
|
22
|
-
* Y position to trigger fireworks (0-1, relative to container height)
|
|
23
|
-
*/
|
|
24
|
-
triggerY?: number;
|
|
25
|
-
/**
|
|
26
|
-
* Auto-trigger on mount
|
|
27
|
-
*/
|
|
28
|
-
autoTrigger?: boolean;
|
|
29
|
-
/**
|
|
30
|
-
* Container style
|
|
31
|
-
*/
|
|
32
|
-
style?: any;
|
|
33
|
-
/**
|
|
34
|
-
* Test ID
|
|
35
|
-
*/
|
|
36
|
-
testID?: string;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Particle Component
|
|
41
|
-
*/
|
|
42
|
-
const Particle: React.FC<{
|
|
43
|
-
x: number;
|
|
44
|
-
y: number;
|
|
45
|
-
color: string;
|
|
46
|
-
size: number;
|
|
47
|
-
opacity: number;
|
|
48
|
-
}> = ({ x, y, color, size, opacity }) => {
|
|
49
|
-
const animatedStyle = useAnimatedStyle(() => ({
|
|
50
|
-
position: 'absolute',
|
|
51
|
-
left: x,
|
|
52
|
-
top: y,
|
|
53
|
-
width: size,
|
|
54
|
-
height: size,
|
|
55
|
-
backgroundColor: color,
|
|
56
|
-
borderRadius: size / 2,
|
|
57
|
-
opacity: withTiming(opacity, { duration: 100 }),
|
|
58
|
-
}));
|
|
59
|
-
|
|
60
|
-
return <AnimatedView style={animatedStyle} />;
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Fireworks Component
|
|
65
|
-
*
|
|
66
|
-
* @example
|
|
67
|
-
* <Fireworks
|
|
68
|
-
* autoTrigger
|
|
69
|
-
* particleCount={100}
|
|
70
|
-
* colors={['#FF6B6B', '#4ECDC4']}
|
|
71
|
-
* />
|
|
72
|
-
*/
|
|
73
|
-
export const Fireworks: React.FC<FireworksProps> = ({
|
|
74
|
-
triggerX = 0.5,
|
|
75
|
-
triggerY = 0.5,
|
|
76
|
-
autoTrigger = false,
|
|
77
|
-
style,
|
|
78
|
-
testID = 'fireworks',
|
|
79
|
-
...config
|
|
80
|
-
}) => {
|
|
81
|
-
const { particles, trigger } = useFireworks(config);
|
|
82
|
-
const [containerSize, setContainerSize] = React.useState({ width: 0, height: 0 });
|
|
83
|
-
|
|
84
|
-
React.useEffect(() => {
|
|
85
|
-
if (autoTrigger && containerSize.width > 0 && containerSize.height > 0) {
|
|
86
|
-
const x = containerSize.width * triggerX;
|
|
87
|
-
const y = containerSize.height * triggerY;
|
|
88
|
-
trigger(x, y);
|
|
89
|
-
}
|
|
90
|
-
}, [autoTrigger, containerSize, triggerX, triggerY, trigger]);
|
|
91
|
-
|
|
92
|
-
const handleLayout = (event: any) => {
|
|
93
|
-
const { width, height } = event.nativeEvent.layout;
|
|
94
|
-
setContainerSize({ width, height });
|
|
95
|
-
};
|
|
96
|
-
|
|
97
|
-
return (
|
|
98
|
-
<View
|
|
99
|
-
style={[styles.container, style]}
|
|
100
|
-
onLayout={handleLayout}
|
|
101
|
-
testID={testID}
|
|
102
|
-
pointerEvents="none"
|
|
103
|
-
>
|
|
104
|
-
{particles.map((particle, index) => (
|
|
105
|
-
<Particle
|
|
106
|
-
key={`particle-${index}`}
|
|
107
|
-
x={particle.x}
|
|
108
|
-
y={particle.y}
|
|
109
|
-
color={particle.color}
|
|
110
|
-
size={particle.size}
|
|
111
|
-
opacity={particle.life}
|
|
112
|
-
/>
|
|
113
|
-
))}
|
|
114
|
-
</View>
|
|
115
|
-
);
|
|
116
|
-
};
|
|
117
|
-
|
|
118
|
-
const styles = StyleSheet.create({
|
|
119
|
-
container: {
|
|
120
|
-
position: 'absolute',
|
|
121
|
-
top: 0,
|
|
122
|
-
left: 0,
|
|
123
|
-
right: 0,
|
|
124
|
-
bottom: 0,
|
|
125
|
-
overflow: 'hidden',
|
|
126
|
-
},
|
|
127
|
-
});
|
|
@@ -1,185 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Fireworks Component Tests
|
|
3
|
-
*
|
|
4
|
-
* Unit tests for fireworks particle system.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import React from 'react';
|
|
8
|
-
import { render, fireEvent } from '@testing-library/react-native';
|
|
9
|
-
import { Fireworks } from '../Fireworks';
|
|
10
|
-
import { useFireworks } from '../../hooks/useFireworks';
|
|
11
|
-
|
|
12
|
-
// Mock react-native-reanimated
|
|
13
|
-
jest.mock('react-native-reanimated', () => ({
|
|
14
|
-
useAnimatedStyle: jest.fn((styleFactory) => styleFactory()),
|
|
15
|
-
withTiming: jest.fn((toValue, config) => ({ toValue, config })),
|
|
16
|
-
}));
|
|
17
|
-
|
|
18
|
-
// Mock useFireworks hook
|
|
19
|
-
jest.mock('../../hooks/useFireworks', () => ({
|
|
20
|
-
useFireworks: jest.fn(() => ({
|
|
21
|
-
particles: [
|
|
22
|
-
{ x: 100, y: 100, color: '#FF0000', size: 4, life: 1 },
|
|
23
|
-
{ x: 150, y: 150, color: '#00FF00', size: 6, life: 0.5 },
|
|
24
|
-
],
|
|
25
|
-
trigger: jest.fn(),
|
|
26
|
-
isActive: true,
|
|
27
|
-
})),
|
|
28
|
-
}));
|
|
29
|
-
|
|
30
|
-
describe('Fireworks Component', () => {
|
|
31
|
-
const defaultProps = {
|
|
32
|
-
colors: ['#FF0000', '#00FF00', '#0000FF'],
|
|
33
|
-
testID: 'test-fireworks',
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
beforeEach(() => {
|
|
37
|
-
jest.clearAllMocks();
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
it('should render correctly', () => {
|
|
41
|
-
const { getByTestId } = render(<Fireworks {...defaultProps} />);
|
|
42
|
-
|
|
43
|
-
expect(getByTestId('test-fireworks')).toBeTruthy();
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
it('should render particles', () => {
|
|
47
|
-
const { getAllByTestId } = render(<Fireworks {...defaultProps} />);
|
|
48
|
-
|
|
49
|
-
const particles = getAllByTestId(/particle-/);
|
|
50
|
-
expect(particles).toHaveLength(2);
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
it('should use default props when not provided', () => {
|
|
54
|
-
const { getByTestId } = render(
|
|
55
|
-
<Fireworks colors={['#FF0000']} />
|
|
56
|
-
);
|
|
57
|
-
|
|
58
|
-
expect(getByTestId('fireworks')).toBeTruthy();
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
it('should apply custom styles', () => {
|
|
62
|
-
const customStyle = { backgroundColor: 'blue' };
|
|
63
|
-
const { getByTestId } = render(
|
|
64
|
-
<Fireworks
|
|
65
|
-
colors={['#FF0000']}
|
|
66
|
-
style={customStyle}
|
|
67
|
-
/>
|
|
68
|
-
);
|
|
69
|
-
|
|
70
|
-
const container = getByTestId('fireworks');
|
|
71
|
-
expect(container.props.style).toEqual(
|
|
72
|
-
expect.arrayContaining([customStyle])
|
|
73
|
-
);
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
it('should handle layout changes', () => {
|
|
77
|
-
const { getByTestId } = render(<Fireworks {...defaultProps} />);
|
|
78
|
-
const container = getByTestId('test-fireworks');
|
|
79
|
-
|
|
80
|
-
fireEvent(container, 'layout', {
|
|
81
|
-
nativeEvent: {
|
|
82
|
-
layout: { width: 300, height: 400 }
|
|
83
|
-
}
|
|
84
|
-
});
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
it('should have pointerEvents disabled', () => {
|
|
88
|
-
const { getByTestId } = render(<Fireworks {...defaultProps} />);
|
|
89
|
-
const container = getByTestId('test-fireworks');
|
|
90
|
-
|
|
91
|
-
expect(container.props.pointerEvents).toBe('none');
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
describe('autoTrigger', () => {
|
|
95
|
-
it('should trigger fireworks when autoTrigger is true and container has size', () => {
|
|
96
|
-
const mockTrigger = jest.fn();
|
|
97
|
-
(useFireworks as jest.Mock).mockReturnValue({
|
|
98
|
-
particles: [],
|
|
99
|
-
trigger: mockTrigger,
|
|
100
|
-
isActive: false,
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
const { getByTestId } = render(
|
|
104
|
-
<Fireworks
|
|
105
|
-
colors={['#FF0000']}
|
|
106
|
-
autoTrigger={true}
|
|
107
|
-
/>
|
|
108
|
-
);
|
|
109
|
-
|
|
110
|
-
const container = getByTestId('fireworks');
|
|
111
|
-
fireEvent(container, 'layout', {
|
|
112
|
-
nativeEvent: {
|
|
113
|
-
layout: { width: 300, height: 400 }
|
|
114
|
-
}
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
expect(mockTrigger).toHaveBeenCalledWith(150, 200); // center of container
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
it('should not trigger when autoTrigger is false', () => {
|
|
121
|
-
const mockTrigger = jest.fn();
|
|
122
|
-
(useFireworks as jest.Mock).mockReturnValue({
|
|
123
|
-
particles: [],
|
|
124
|
-
trigger: mockTrigger,
|
|
125
|
-
isActive: false,
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
render(
|
|
129
|
-
<Fireworks
|
|
130
|
-
colors={['#FF0000']}
|
|
131
|
-
autoTrigger={false}
|
|
132
|
-
/>
|
|
133
|
-
);
|
|
134
|
-
|
|
135
|
-
expect(mockTrigger).not.toHaveBeenCalled();
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
it('should use custom trigger position', () => {
|
|
139
|
-
const mockTrigger = jest.fn();
|
|
140
|
-
(useFireworks as jest.Mock).mockReturnValue({
|
|
141
|
-
particles: [],
|
|
142
|
-
trigger: mockTrigger,
|
|
143
|
-
isActive: false,
|
|
144
|
-
});
|
|
145
|
-
|
|
146
|
-
const { getByTestId } = render(
|
|
147
|
-
<Fireworks
|
|
148
|
-
colors={['#FF0000']}
|
|
149
|
-
autoTrigger={true}
|
|
150
|
-
triggerX={0.25}
|
|
151
|
-
triggerY={0.75}
|
|
152
|
-
/>
|
|
153
|
-
);
|
|
154
|
-
|
|
155
|
-
const container = getByTestId('fireworks');
|
|
156
|
-
fireEvent(container, 'layout', {
|
|
157
|
-
nativeEvent: {
|
|
158
|
-
layout: { width: 400, height: 200 }
|
|
159
|
-
}
|
|
160
|
-
});
|
|
161
|
-
|
|
162
|
-
expect(mockTrigger).toHaveBeenCalledWith(100, 150); // 25% of width, 75% of height
|
|
163
|
-
});
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
describe('Particle rendering', () => {
|
|
167
|
-
it('should render particle with correct properties', () => {
|
|
168
|
-
const particles = [
|
|
169
|
-
{ x: 100, y: 100, color: '#FF0000', size: 4, life: 1 },
|
|
170
|
-
];
|
|
171
|
-
(useFireworks as jest.Mock).mockReturnValue({
|
|
172
|
-
particles,
|
|
173
|
-
trigger: jest.fn(),
|
|
174
|
-
isActive: false,
|
|
175
|
-
});
|
|
176
|
-
|
|
177
|
-
render(<Fireworks colors={['#FF0000']} />);
|
|
178
|
-
|
|
179
|
-
// Particle should be rendered with correct properties
|
|
180
|
-
expect(useFireworks).toHaveBeenCalledWith({
|
|
181
|
-
colors: ['#FF0000'],
|
|
182
|
-
});
|
|
183
|
-
});
|
|
184
|
-
});
|
|
185
|
-
});
|