react-native-glitter 1.0.4 → 1.0.5

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/README.md CHANGED
@@ -264,6 +264,44 @@ function ControlledGlitter() {
264
264
  </Glitter>
265
265
  ```
266
266
 
267
+ ## Ref API
268
+
269
+ You can control the animation programmatically using a ref:
270
+
271
+ ```tsx
272
+ import { useRef } from 'react';
273
+ import { Glitter, type GlitterRef } from 'react-native-glitter';
274
+
275
+ function MyComponent() {
276
+ const glitterRef = useRef<GlitterRef>(null);
277
+
278
+ const handleStart = () => glitterRef.current?.start();
279
+ const handleStop = () => glitterRef.current?.stop();
280
+ const handleRestart = () => glitterRef.current?.restart();
281
+ const checkStatus = () => console.log(glitterRef.current?.isAnimating());
282
+
283
+ return (
284
+ <>
285
+ <Glitter ref={glitterRef} active={false}>
286
+ <View style={styles.box} />
287
+ </Glitter>
288
+ <Button title="Start" onPress={handleStart} />
289
+ <Button title="Stop" onPress={handleStop} />
290
+ <Button title="Restart" onPress={handleRestart} />
291
+ </>
292
+ );
293
+ }
294
+ ```
295
+
296
+ ### Ref Methods
297
+
298
+ | Method | Return | Description |
299
+ |--------|--------|-------------|
300
+ | `start()` | `void` | Start the shimmer animation |
301
+ | `stop()` | `void` | Stop the shimmer animation |
302
+ | `restart()` | `void` | Restart the animation from the beginning |
303
+ | `isAnimating()` | `boolean` | Check if animation is currently running |
304
+
267
305
  ## TypeScript
268
306
 
269
307
  This library is written in TypeScript and includes type definitions:
@@ -272,6 +310,7 @@ This library is written in TypeScript and includes type definitions:
272
310
  import {
273
311
  Glitter,
274
312
  type GlitterProps,
313
+ type GlitterRef,
275
314
  type GlitterMode,
276
315
  type GlitterPosition,
277
316
  type GlitterDirection,
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useEffect, useRef, useState, useCallback, useMemo, memo, } from 'react';
2
+ import { useEffect, useRef, useState, useCallback, useMemo, memo, useImperativeHandle, forwardRef, } from 'react';
3
3
  import { View, Animated, StyleSheet, Easing, } from 'react-native';
4
4
  function generateGlitterOpacities(count, peak = 1) {
5
5
  const opacities = [];
@@ -52,7 +52,7 @@ const HEIGHT_MULTIPLIER = 1.5;
52
52
  const NORMAL_FADE_RATIO = (HEIGHT_MULTIPLIER - 1) / HEIGHT_MULTIPLIER / 2;
53
53
  const ANIMATED_SEGMENTS = generateVerticalSegments(0.25);
54
54
  const NORMAL_SEGMENTS = generateVerticalSegments(NORMAL_FADE_RATIO);
55
- function GlitterComponent({ children, duration = 1500, delay = 400, color = 'rgba(255, 255, 255, 0.8)', angle = 20, shimmerWidth = 60, active = true, style, easing, mode = 'normal', position = 'center', direction = 'left-to-right', iterations = -1, onAnimationStart, onAnimationComplete, testID, accessibilityLabel, accessible = true, }) {
55
+ function GlitterComponent({ children, duration = 1500, delay = 400, color = 'rgba(255, 255, 255, 0.8)', angle = 20, shimmerWidth = 60, active = true, style, easing, mode = 'normal', position = 'center', direction = 'left-to-right', iterations = -1, onAnimationStart, onAnimationComplete, testID, accessibilityLabel, accessible = true, }, ref) {
56
56
  const animatedValue = useRef(new Animated.Value(0)).current;
57
57
  const [containerWidth, setContainerWidth] = useState(0);
58
58
  const [containerHeight, setContainerHeight] = useState(0);
@@ -68,6 +68,23 @@ function GlitterComponent({ children, duration = 1500, delay = 400, color = 'rgb
68
68
  currentIterationRef.current?.stop();
69
69
  currentIterationRef.current = null;
70
70
  }, []);
71
+ const restartAnimation = useCallback(() => {
72
+ stopAnimation();
73
+ animatedValue.setValue(0);
74
+ // Trigger re-render to start animation
75
+ setContainerWidth((prev) => prev);
76
+ }, [stopAnimation, animatedValue]);
77
+ useImperativeHandle(ref, () => ({
78
+ start: () => {
79
+ if (!isAnimatingRef.current && containerWidth > 0) {
80
+ // Force start by triggering the effect
81
+ setContainerWidth((prev) => prev);
82
+ }
83
+ },
84
+ stop: stopAnimation,
85
+ restart: restartAnimation,
86
+ isAnimating: () => isAnimatingRef.current,
87
+ }), [stopAnimation, restartAnimation, containerWidth]);
71
88
  const startAnimation = useCallback(() => {
72
89
  if (!active || containerWidth === 0)
73
90
  return;
@@ -231,5 +248,6 @@ const styles = StyleSheet.create({
231
248
  width: '100%',
232
249
  },
233
250
  });
234
- export const Glitter = memo(GlitterComponent);
251
+ const ForwardedGlitter = forwardRef(GlitterComponent);
252
+ export const Glitter = memo(ForwardedGlitter);
235
253
  export default Glitter;
@@ -1,4 +1,4 @@
1
- import { type ReactNode, type ReactElement } from 'react';
1
+ import { type ReactNode } from 'react';
2
2
  import { type StyleProp, type ViewStyle } from 'react-native';
3
3
  export type GlitterMode = 'normal' | 'expand' | 'shrink';
4
4
  export type GlitterPosition = 'top' | 'center' | 'bottom';
@@ -26,6 +26,16 @@ export interface GlitterProps {
26
26
  /** Whether the component is accessible (default: true) */
27
27
  accessible?: boolean;
28
28
  }
29
- declare function GlitterComponent({ children, duration, delay, color, angle, shimmerWidth, active, style, easing, mode, position, direction, iterations, onAnimationStart, onAnimationComplete, testID, accessibilityLabel, accessible, }: GlitterProps): ReactElement;
30
- export declare const Glitter: import("react").MemoExoticComponent<typeof GlitterComponent>;
29
+ /** Ref methods exposed by Glitter component */
30
+ export interface GlitterRef {
31
+ /** Start the shimmer animation */
32
+ start: () => void;
33
+ /** Stop the shimmer animation */
34
+ stop: () => void;
35
+ /** Restart the shimmer animation from the beginning */
36
+ restart: () => void;
37
+ /** Check if animation is currently running */
38
+ isAnimating: () => boolean;
39
+ }
40
+ export declare const Glitter: import("react").NamedExoticComponent<GlitterProps & import("react").RefAttributes<GlitterRef>>;
31
41
  export default Glitter;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-glitter",
3
- "version": "1.0.4",
3
+ "version": "1.0.5",
4
4
  "description": "A beautiful shimmer/glitter effect component for React Native. Add a sparkling diagonal shine animation to any component!",
5
5
  "main": "./lib/module/index.js",
6
6
  "types": "./lib/typescript/src/index.d.ts",
package/src/index.tsx CHANGED
@@ -5,8 +5,11 @@ import {
5
5
  useCallback,
6
6
  useMemo,
7
7
  memo,
8
+ useImperativeHandle,
9
+ forwardRef,
8
10
  type ReactNode,
9
11
  type ReactElement,
12
+ type ForwardedRef,
10
13
  } from 'react';
11
14
  import {
12
15
  View,
@@ -48,6 +51,18 @@ export interface GlitterProps {
48
51
  accessible?: boolean;
49
52
  }
50
53
 
54
+ /** Ref methods exposed by Glitter component */
55
+ export interface GlitterRef {
56
+ /** Start the shimmer animation */
57
+ start: () => void;
58
+ /** Stop the shimmer animation */
59
+ stop: () => void;
60
+ /** Restart the shimmer animation from the beginning */
61
+ restart: () => void;
62
+ /** Check if animation is currently running */
63
+ isAnimating: () => boolean;
64
+ }
65
+
51
66
  function generateGlitterOpacities(count: number, peak: number = 1): number[] {
52
67
  const opacities: number[] = [];
53
68
  const center = (count - 1) / 2;
@@ -114,26 +129,29 @@ const NORMAL_FADE_RATIO = (HEIGHT_MULTIPLIER - 1) / HEIGHT_MULTIPLIER / 2;
114
129
  const ANIMATED_SEGMENTS = generateVerticalSegments(0.25);
115
130
  const NORMAL_SEGMENTS = generateVerticalSegments(NORMAL_FADE_RATIO);
116
131
 
117
- function GlitterComponent({
118
- children,
119
- duration = 1500,
120
- delay = 400,
121
- color = 'rgba(255, 255, 255, 0.8)',
122
- angle = 20,
123
- shimmerWidth = 60,
124
- active = true,
125
- style,
126
- easing,
127
- mode = 'normal',
128
- position = 'center',
129
- direction = 'left-to-right',
130
- iterations = -1,
131
- onAnimationStart,
132
- onAnimationComplete,
133
- testID,
134
- accessibilityLabel,
135
- accessible = true,
136
- }: GlitterProps): ReactElement {
132
+ function GlitterComponent(
133
+ {
134
+ children,
135
+ duration = 1500,
136
+ delay = 400,
137
+ color = 'rgba(255, 255, 255, 0.8)',
138
+ angle = 20,
139
+ shimmerWidth = 60,
140
+ active = true,
141
+ style,
142
+ easing,
143
+ mode = 'normal',
144
+ position = 'center',
145
+ direction = 'left-to-right',
146
+ iterations = -1,
147
+ onAnimationStart,
148
+ onAnimationComplete,
149
+ testID,
150
+ accessibilityLabel,
151
+ accessible = true,
152
+ }: GlitterProps,
153
+ ref: ForwardedRef<GlitterRef>
154
+ ): ReactElement {
137
155
  const animatedValue = useRef(new Animated.Value(0)).current;
138
156
  const [containerWidth, setContainerWidth] = useState(0);
139
157
  const [containerHeight, setContainerHeight] = useState(0);
@@ -154,6 +172,29 @@ function GlitterComponent({
154
172
  currentIterationRef.current = null;
155
173
  }, []);
156
174
 
175
+ const restartAnimation = useCallback(() => {
176
+ stopAnimation();
177
+ animatedValue.setValue(0);
178
+ // Trigger re-render to start animation
179
+ setContainerWidth((prev) => prev);
180
+ }, [stopAnimation, animatedValue]);
181
+
182
+ useImperativeHandle(
183
+ ref,
184
+ () => ({
185
+ start: () => {
186
+ if (!isAnimatingRef.current && containerWidth > 0) {
187
+ // Force start by triggering the effect
188
+ setContainerWidth((prev) => prev);
189
+ }
190
+ },
191
+ stop: stopAnimation,
192
+ restart: restartAnimation,
193
+ isAnimating: () => isAnimatingRef.current,
194
+ }),
195
+ [stopAnimation, restartAnimation, containerWidth]
196
+ );
197
+
157
198
  const startAnimation = useCallback(() => {
158
199
  if (!active || containerWidth === 0) return;
159
200
 
@@ -404,6 +445,7 @@ const styles = StyleSheet.create({
404
445
  },
405
446
  });
406
447
 
407
- export const Glitter = memo(GlitterComponent);
448
+ const ForwardedGlitter = forwardRef(GlitterComponent);
449
+ export const Glitter = memo(ForwardedGlitter);
408
450
 
409
451
  export default Glitter;