react-native-gleam 1.0.0-beta.6 → 1.0.0-beta.7
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 +49 -3
- package/android/src/main/java/com/gleam/GleamView.kt +3 -0
- package/ios/GleamView.mm +3 -0
- package/lib/module/GleamContext.js +5 -0
- package/lib/module/GleamContext.js.map +1 -0
- package/lib/module/GleamLine.js +50 -0
- package/lib/module/GleamLine.js.map +1 -0
- package/lib/module/index.js +115 -1
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/src/GleamContext.d.ts +14 -0
- package/lib/typescript/src/GleamContext.d.ts.map +1 -0
- package/lib/typescript/src/GleamLine.d.ts +12 -0
- package/lib/typescript/src/GleamLine.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +23 -2
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/GleamContext.ts +16 -0
- package/src/GleamLine.tsx +65 -0
- package/src/index.tsx +158 -2
package/README.md
CHANGED
|
@@ -52,6 +52,32 @@ function UserCard({ loading, user }) {
|
|
|
52
52
|
|
|
53
53
|
When `loading={true}`, children are hidden and a shimmer animation plays. When `loading={false}`, the shimmer fades out and children fade in.
|
|
54
54
|
|
|
55
|
+
### Multi-line skeleton (`GleamView.Line`)
|
|
56
|
+
|
|
57
|
+
Use `GleamView.Line` to create individual shimmer bars that inherit props from a parent `GleamView`. No conditional rendering — the wrapper pattern works for multi-line skeletons too.
|
|
58
|
+
|
|
59
|
+
```tsx
|
|
60
|
+
<GleamView loading={loading} speed={800} baseColor="#E0E0E0">
|
|
61
|
+
<GleamView.Line style={{ height: 22, borderRadius: 6, width: '70%' }}>
|
|
62
|
+
<Text style={{ fontSize: 16 }}>{title}</Text>
|
|
63
|
+
</GleamView.Line>
|
|
64
|
+
<GleamView.Line
|
|
65
|
+
style={{ height: 16, borderRadius: 4, width: '50%' }}
|
|
66
|
+
delay={100}
|
|
67
|
+
>
|
|
68
|
+
<Text style={{ fontSize: 13 }}>{subtitle}</Text>
|
|
69
|
+
</GleamView.Line>
|
|
70
|
+
</GleamView>
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
When `loading={true}`, each `GleamView.Line` renders its own shimmer bar, sized by `style`. The parent acts as a plain container (no block shimmer). When `loading={false}`, Lines become transparent and children render normally.
|
|
74
|
+
|
|
75
|
+
Lines inherit `loading`, `speed`, `direction`, `baseColor`, `highlightColor`, `intensity`, `transitionDuration`, and `transitionType` from the parent. `delay` and `onTransitionEnd` are per-line.
|
|
76
|
+
|
|
77
|
+
For best performance, place `GleamView.Line` as direct children of `GleamView` (or inside fragments). Lines nested inside intermediate wrappers (e.g., `<View>`) still work, but require an extra render cycle to detect.
|
|
78
|
+
|
|
79
|
+
Every `GleamView` provides context to its subtree. A `GleamView.Line` always binds to its nearest `GleamView` ancestor — nested `GleamView` components each control their own Lines independently.
|
|
80
|
+
|
|
55
81
|
### Staggered skeleton
|
|
56
82
|
|
|
57
83
|
```tsx
|
|
@@ -95,10 +121,21 @@ When `loading={true}`, children are hidden and a shimmer animation plays. When `
|
|
|
95
121
|
| `intensity` | `number` | `1` | Highlight strength (0-1). Lower = more subtle shimmer |
|
|
96
122
|
| `baseColor` | `string` | `#E0E0E0` | Background color of the shimmer |
|
|
97
123
|
| `highlightColor` | `string` | `#F5F5F5` | Color of the moving highlight |
|
|
98
|
-
| `onTransitionEnd` | `function` | — | Called when the
|
|
124
|
+
| `onTransitionEnd` | `function` | — | Called when the transition completes or is interrupted. Receives `{ nativeEvent: { finished: boolean } }` — `true` if completed, `false` if interrupted (e.g., `loading` toggled back to `true`) |
|
|
99
125
|
|
|
100
126
|
All standard `View` props are also supported (`style`, `testID`, etc.). Note: the shimmer overlay supports uniform `borderRadius` only — per-corner radii are not applied to the shimmer.
|
|
101
127
|
|
|
128
|
+
### GleamView.Line Props
|
|
129
|
+
|
|
130
|
+
| Prop | Type | Default | Description |
|
|
131
|
+
|------|------|---------|-------------|
|
|
132
|
+
| `style` | `ViewStyle` | — | Style for the shimmer bar (height, width, borderRadius) |
|
|
133
|
+
| `delay` | `number` | `0` | Phase offset for this line (useful for stagger) |
|
|
134
|
+
| `onTransitionEnd` | `function` | — | Called when this line's transition completes |
|
|
135
|
+
| `testID` | `string` | — | Test identifier |
|
|
136
|
+
|
|
137
|
+
All standard accessibility props (`accessibilityLabel`, `accessibilityRole`, etc.) are accepted directly. Shimmer props (`loading`, `speed`, `direction`, etc.) cannot be passed to `GleamView.Line` — they are inherited automatically from the parent `GleamView`.
|
|
138
|
+
|
|
102
139
|
### GleamDirection
|
|
103
140
|
|
|
104
141
|
```tsx
|
|
@@ -121,7 +158,8 @@ GleamTransition.Collapse // 'collapse' — shimmer collapses vertically then ho
|
|
|
121
158
|
|
|
122
159
|
## Requirements
|
|
123
160
|
|
|
124
|
-
- React
|
|
161
|
+
- React **19+**
|
|
162
|
+
- React Native **0.78+** (New Architecture / Fabric)
|
|
125
163
|
- iOS 15+
|
|
126
164
|
- Android SDK 24+
|
|
127
165
|
|
|
@@ -139,12 +177,20 @@ When `loading` switches to `false`:
|
|
|
139
177
|
|
|
140
178
|
1. The shimmer transitions out over `transitionDuration` ms (style depends on `transitionType`)
|
|
141
179
|
2. Children fade in simultaneously
|
|
142
|
-
3. `onTransitionEnd` fires
|
|
180
|
+
3. `onTransitionEnd` fires with `finished: true` (or `finished: false` if interrupted)
|
|
143
181
|
|
|
144
182
|
All shimmer instances sharing the same `speed` are automatically synchronized via a shared clock.
|
|
145
183
|
|
|
146
184
|
The shimmer respects uniform `borderRadius` and standard view styles.
|
|
147
185
|
|
|
186
|
+
## Breaking changes (beta)
|
|
187
|
+
|
|
188
|
+
- When `GleamView.Line` children are present, the parent `GleamView` renders as a plain `View` container. `onTransitionEnd` on the parent is ignored in this mode — use `onTransitionEnd` on individual `GleamView.Line` components instead. A dev warning is emitted if this happens.
|
|
189
|
+
|
|
190
|
+
## Limitations
|
|
191
|
+
|
|
192
|
+
- The shimmer overlay supports uniform `borderRadius` only — per-corner radii are not applied to the shimmer.
|
|
193
|
+
|
|
148
194
|
## License
|
|
149
195
|
|
|
150
196
|
MIT
|
|
@@ -325,6 +325,9 @@ class GleamView(context: Context) : ReactViewGroup(context) {
|
|
|
325
325
|
|
|
326
326
|
private fun applyLoadingState(wasLoading: Boolean) {
|
|
327
327
|
if (loading) {
|
|
328
|
+
if (isTransitioning) {
|
|
329
|
+
emitTransitionEnd(false)
|
|
330
|
+
}
|
|
328
331
|
// Set isTransitioning=false BEFORE cancel to prevent stale onAnimationEnd
|
|
329
332
|
isTransitioning = false
|
|
330
333
|
transitionGeneration++
|
package/ios/GleamView.mm
CHANGED
|
@@ -494,6 +494,9 @@ static void _unregisterView(GleamView *view) {
|
|
|
494
494
|
- (void)_applyLoadingState
|
|
495
495
|
{
|
|
496
496
|
if (_loading) {
|
|
497
|
+
if (_isTransitioning) {
|
|
498
|
+
[self _emitTransitionEnd:NO];
|
|
499
|
+
}
|
|
497
500
|
_isTransitioning = NO;
|
|
498
501
|
_contentAlpha = 0.0;
|
|
499
502
|
_lastSetChildrenAlpha = -1.0;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["createContext","GleamContext"],"sourceRoot":"../../src","sources":["GleamContext.ts"],"mappings":";;AAAA,SAASA,aAAa,QAAQ,OAAO;AAerC,OAAO,MAAMC,YAAY,gBAAGD,aAAa,CAA2B,IAAI,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { useContext, useLayoutEffect } from 'react';
|
|
4
|
+
import { View } from 'react-native';
|
|
5
|
+
import NativeGleamView from './GleamViewNativeComponent';
|
|
6
|
+
import { GleamContext } from "./GleamContext.js";
|
|
7
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
8
|
+
export function GleamLine({
|
|
9
|
+
children,
|
|
10
|
+
style,
|
|
11
|
+
testID,
|
|
12
|
+
delay,
|
|
13
|
+
onTransitionEnd,
|
|
14
|
+
...accessibilityProps
|
|
15
|
+
}) {
|
|
16
|
+
const ctx = useContext(GleamContext);
|
|
17
|
+
const register = ctx?.registerLine;
|
|
18
|
+
useLayoutEffect(() => {
|
|
19
|
+
if (!register) return;
|
|
20
|
+
return register();
|
|
21
|
+
}, [register]);
|
|
22
|
+
if (!ctx) {
|
|
23
|
+
if (__DEV__) {
|
|
24
|
+
console.warn('GleamView.Line must be used inside a GleamView');
|
|
25
|
+
}
|
|
26
|
+
return /*#__PURE__*/_jsx(View, {
|
|
27
|
+
style: style,
|
|
28
|
+
testID: testID,
|
|
29
|
+
...accessibilityProps,
|
|
30
|
+
children: children
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
return /*#__PURE__*/_jsx(NativeGleamView, {
|
|
34
|
+
loading: ctx.loading,
|
|
35
|
+
speed: ctx.speed,
|
|
36
|
+
direction: ctx.direction,
|
|
37
|
+
delay: delay,
|
|
38
|
+
transitionDuration: ctx.transitionDuration,
|
|
39
|
+
transitionType: ctx.transitionType,
|
|
40
|
+
intensity: ctx.intensity,
|
|
41
|
+
baseColor: ctx.baseColor,
|
|
42
|
+
highlightColor: ctx.highlightColor,
|
|
43
|
+
onTransitionEnd: onTransitionEnd,
|
|
44
|
+
style: style,
|
|
45
|
+
testID: testID,
|
|
46
|
+
...accessibilityProps,
|
|
47
|
+
children: children
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=GleamLine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["useContext","useLayoutEffect","View","NativeGleamView","GleamContext","jsx","_jsx","GleamLine","children","style","testID","delay","onTransitionEnd","accessibilityProps","ctx","register","registerLine","__DEV__","console","warn","loading","speed","direction","transitionDuration","transitionType","intensity","baseColor","highlightColor"],"sourceRoot":"../../src","sources":["GleamLine.tsx"],"mappings":";;AAAA,SAASA,UAAU,EAAEC,eAAe,QAAwB,OAAO;AACnE,SACEC,IAAI,QAIC,cAAc;AACrB,OAAOC,eAAe,MAA4B,4BAA4B;AAC9E,SAASC,YAAY,QAAQ,mBAAgB;AAAC,SAAAC,GAAA,IAAAC,IAAA;AAU9C,OAAO,SAASC,SAASA,CAAC;EACxBC,QAAQ;EACRC,KAAK;EACLC,MAAM;EACNC,KAAK;EACLC,eAAe;EACf,GAAGC;AACW,CAAC,EAAE;EACjB,MAAMC,GAAG,GAAGd,UAAU,CAACI,YAAY,CAAC;EACpC,MAAMW,QAAQ,GAAGD,GAAG,EAAEE,YAAY;EAElCf,eAAe,CAAC,MAAM;IACpB,IAAI,CAACc,QAAQ,EAAE;IACf,OAAOA,QAAQ,CAAC,CAAC;EACnB,CAAC,EAAE,CAACA,QAAQ,CAAC,CAAC;EAEd,IAAI,CAACD,GAAG,EAAE;IACR,IAAIG,OAAO,EAAE;MACXC,OAAO,CAACC,IAAI,CAAC,gDAAgD,CAAC;IAChE;IACA,oBACEb,IAAA,CAACJ,IAAI;MAACO,KAAK,EAAEA,KAAM;MAACC,MAAM,EAAEA,MAAO;MAAA,GAAKG,kBAAkB;MAAAL,QAAA,EACvDA;IAAQ,CACL,CAAC;EAEX;EAEA,oBACEF,IAAA,CAACH,eAAe;IACdiB,OAAO,EAAEN,GAAG,CAACM,OAAQ;IACrBC,KAAK,EAAEP,GAAG,CAACO,KAAM;IACjBC,SAAS,EAAER,GAAG,CAACQ,SAAU;IACzBX,KAAK,EAAEA,KAAM;IACbY,kBAAkB,EAAET,GAAG,CAACS,kBAAmB;IAC3CC,cAAc,EAAEV,GAAG,CAACU,cAAe;IACnCC,SAAS,EAAEX,GAAG,CAACW,SAAU;IACzBC,SAAS,EAAEZ,GAAG,CAACY,SAAU;IACzBC,cAAc,EAAEb,GAAG,CAACa,cAAe;IACnCf,eAAe,EAAEA,eAAgB;IACjCH,KAAK,EAAEA,KAAM;IACbC,MAAM,EAAEA,MAAO;IAAA,GACXG,kBAAkB;IAAAL,QAAA,EAErBA;EAAQ,CACM,CAAC;AAEtB","ignoreList":[]}
|
package/lib/module/index.js
CHANGED
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
import React, { useCallback, useMemo, useRef, useState } from 'react';
|
|
4
|
+
import { View } from 'react-native';
|
|
5
|
+
import NativeGleamView from './GleamViewNativeComponent';
|
|
6
|
+
import { GleamContext } from "./GleamContext.js";
|
|
7
|
+
import { GleamLine } from "./GleamLine.js";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Props accepted by GleamView, including ref (React 19 ref-as-prop).
|
|
11
|
+
* Use this type instead of `ComponentProps<typeof GleamView>` for
|
|
12
|
+
* accurate ref typing.
|
|
13
|
+
*/
|
|
14
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
4
15
|
export let GleamDirection = /*#__PURE__*/function (GleamDirection) {
|
|
5
16
|
GleamDirection["LeftToRight"] = "ltr";
|
|
6
17
|
GleamDirection["RightToLeft"] = "rtl";
|
|
@@ -13,4 +24,107 @@ export let GleamTransition = /*#__PURE__*/function (GleamTransition) {
|
|
|
13
24
|
GleamTransition["Collapse"] = "collapse";
|
|
14
25
|
return GleamTransition;
|
|
15
26
|
}({});
|
|
27
|
+
|
|
28
|
+
// Shimmer-specific prop keys to exclude when rendering as a plain View container.
|
|
29
|
+
// Typed against NativeProps so a missing key triggers a compile error.
|
|
30
|
+
const SHIMMER_KEY_LIST = ['loading', 'speed', 'direction', 'delay', 'transitionDuration', 'transitionType', 'intensity', 'baseColor', 'highlightColor', 'onTransitionEnd', 'children'];
|
|
31
|
+
const SHIMMER_KEYS = new Set(SHIMMER_KEY_LIST);
|
|
32
|
+
function pickViewProps(props) {
|
|
33
|
+
const viewProps = {};
|
|
34
|
+
for (const key of Object.keys(props)) {
|
|
35
|
+
if (!SHIMMER_KEYS.has(key)) {
|
|
36
|
+
viewProps[key] = props[key];
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return viewProps;
|
|
40
|
+
}
|
|
41
|
+
function hasLineChildren(children) {
|
|
42
|
+
let found = false;
|
|
43
|
+
React.Children.forEach(children, child => {
|
|
44
|
+
if (found) return;
|
|
45
|
+
if (! /*#__PURE__*/React.isValidElement(child)) return;
|
|
46
|
+
if (child.type === GleamLine) {
|
|
47
|
+
found = true;
|
|
48
|
+
} else if (child.type === React.Fragment) {
|
|
49
|
+
found = hasLineChildren(child.props.children);
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
return found;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// React 19: ref is a regular prop, no forwardRef needed.
|
|
56
|
+
// Internal ref type is loosened to avoid monorepo type conflicts between
|
|
57
|
+
// root and example workspace @types/react copies. The exported GleamViewProps
|
|
58
|
+
// provides the correct consumer-facing type.
|
|
59
|
+
function GleamViewComponent({
|
|
60
|
+
ref,
|
|
61
|
+
...props
|
|
62
|
+
}) {
|
|
63
|
+
const {
|
|
64
|
+
loading,
|
|
65
|
+
speed,
|
|
66
|
+
direction,
|
|
67
|
+
transitionDuration,
|
|
68
|
+
transitionType,
|
|
69
|
+
intensity,
|
|
70
|
+
baseColor,
|
|
71
|
+
highlightColor,
|
|
72
|
+
children
|
|
73
|
+
} = props;
|
|
74
|
+
const lineCountRef = useRef(0);
|
|
75
|
+
const warnedTransitionRef = useRef(false);
|
|
76
|
+
const [hasLines, setHasLines] = useState(() => hasLineChildren(children));
|
|
77
|
+
const registerLine = useCallback(() => {
|
|
78
|
+
lineCountRef.current++;
|
|
79
|
+
setHasLines(true);
|
|
80
|
+
return () => {
|
|
81
|
+
lineCountRef.current--;
|
|
82
|
+
if (lineCountRef.current === 0) {
|
|
83
|
+
setHasLines(false);
|
|
84
|
+
warnedTransitionRef.current = false;
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
}, []);
|
|
88
|
+
const contextValue = useMemo(() => ({
|
|
89
|
+
loading,
|
|
90
|
+
speed,
|
|
91
|
+
direction,
|
|
92
|
+
transitionDuration,
|
|
93
|
+
transitionType,
|
|
94
|
+
intensity,
|
|
95
|
+
baseColor,
|
|
96
|
+
highlightColor,
|
|
97
|
+
registerLine
|
|
98
|
+
}), [loading, speed, direction, transitionDuration, transitionType, intensity, baseColor, highlightColor, registerLine]);
|
|
99
|
+
|
|
100
|
+
// Cast needed: View and NativeGleamView accept Ref<ReactNativeElement>
|
|
101
|
+
// but that type isn't publicly exported from react-native. Safe at runtime.
|
|
102
|
+
const nativeRef = ref;
|
|
103
|
+
if (hasLines) {
|
|
104
|
+
if (__DEV__ && props.onTransitionEnd && !warnedTransitionRef.current) {
|
|
105
|
+
warnedTransitionRef.current = true;
|
|
106
|
+
console.warn('GleamView: onTransitionEnd is ignored when GleamView.Line children are present. ' + 'Use onTransitionEnd on individual GleamView.Line components instead.');
|
|
107
|
+
}
|
|
108
|
+
return /*#__PURE__*/_jsx(GleamContext.Provider, {
|
|
109
|
+
value: contextValue,
|
|
110
|
+
children: /*#__PURE__*/_jsx(View, {
|
|
111
|
+
ref: nativeRef,
|
|
112
|
+
...pickViewProps(props),
|
|
113
|
+
children: children
|
|
114
|
+
})
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
return /*#__PURE__*/_jsx(GleamContext.Provider, {
|
|
118
|
+
value: contextValue,
|
|
119
|
+
children: /*#__PURE__*/_jsx(NativeGleamView, {
|
|
120
|
+
ref: nativeRef,
|
|
121
|
+
...props,
|
|
122
|
+
children: children
|
|
123
|
+
})
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
GleamViewComponent.displayName = 'GleamView';
|
|
127
|
+
export const GleamView = Object.assign(GleamViewComponent, {
|
|
128
|
+
Line: GleamLine
|
|
129
|
+
});
|
|
16
130
|
//# sourceMappingURL=index.js.map
|
package/lib/module/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["
|
|
1
|
+
{"version":3,"names":["React","useCallback","useMemo","useRef","useState","View","NativeGleamView","GleamContext","GleamLine","jsx","_jsx","GleamDirection","GleamTransition","SHIMMER_KEY_LIST","SHIMMER_KEYS","Set","pickViewProps","props","viewProps","key","Object","keys","has","hasLineChildren","children","found","Children","forEach","child","isValidElement","type","Fragment","GleamViewComponent","ref","loading","speed","direction","transitionDuration","transitionType","intensity","baseColor","highlightColor","lineCountRef","warnedTransitionRef","hasLines","setHasLines","registerLine","current","contextValue","nativeRef","__DEV__","onTransitionEnd","console","warn","Provider","value","displayName","GleamView","assign","Line"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type NativeProps } from './GleamViewNativeComponent';
|
|
2
|
+
export interface GleamContextValue {
|
|
3
|
+
loading: NativeProps['loading'];
|
|
4
|
+
speed: NativeProps['speed'];
|
|
5
|
+
direction: NativeProps['direction'];
|
|
6
|
+
transitionDuration: NativeProps['transitionDuration'];
|
|
7
|
+
transitionType: NativeProps['transitionType'];
|
|
8
|
+
intensity: NativeProps['intensity'];
|
|
9
|
+
baseColor: NativeProps['baseColor'];
|
|
10
|
+
highlightColor: NativeProps['highlightColor'];
|
|
11
|
+
registerLine: () => () => void;
|
|
12
|
+
}
|
|
13
|
+
export declare const GleamContext: import("react").Context<GleamContextValue | null>;
|
|
14
|
+
//# sourceMappingURL=GleamContext.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GleamContext.d.ts","sourceRoot":"","sources":["../../../src/GleamContext.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAE9D,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC;IAChC,KAAK,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;IAC5B,SAAS,EAAE,WAAW,CAAC,WAAW,CAAC,CAAC;IACpC,kBAAkB,EAAE,WAAW,CAAC,oBAAoB,CAAC,CAAC;IACtD,cAAc,EAAE,WAAW,CAAC,gBAAgB,CAAC,CAAC;IAC9C,SAAS,EAAE,WAAW,CAAC,WAAW,CAAC,CAAC;IACpC,SAAS,EAAE,WAAW,CAAC,WAAW,CAAC,CAAC;IACpC,cAAc,EAAE,WAAW,CAAC,gBAAgB,CAAC,CAAC;IAC9C,YAAY,EAAE,MAAM,MAAM,IAAI,CAAC;CAChC;AAED,eAAO,MAAM,YAAY,mDAAgD,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import { type AccessibilityProps, type StyleProp, type ViewStyle } from 'react-native';
|
|
3
|
+
import { type NativeProps } from './GleamViewNativeComponent';
|
|
4
|
+
export interface GleamLineProps extends AccessibilityProps {
|
|
5
|
+
children?: ReactNode;
|
|
6
|
+
style?: StyleProp<ViewStyle>;
|
|
7
|
+
testID?: string;
|
|
8
|
+
delay?: NativeProps['delay'];
|
|
9
|
+
onTransitionEnd?: NativeProps['onTransitionEnd'];
|
|
10
|
+
}
|
|
11
|
+
export declare function GleamLine({ children, style, testID, delay, onTransitionEnd, ...accessibilityProps }: GleamLineProps): import("react/jsx-runtime").JSX.Element;
|
|
12
|
+
//# sourceMappingURL=GleamLine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GleamLine.d.ts","sourceRoot":"","sources":["../../../src/GleamLine.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA+B,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AACpE,OAAO,EAEL,KAAK,kBAAkB,EACvB,KAAK,SAAS,EACd,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;AACtB,OAAwB,EAAE,KAAK,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAG/E,MAAM,WAAW,cAAe,SAAQ,kBAAkB;IACxD,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;IAC7B,eAAe,CAAC,EAAE,WAAW,CAAC,iBAAiB,CAAC,CAAC;CAClD;AAED,wBAAgB,SAAS,CAAC,EACxB,QAAQ,EACR,KAAK,EACL,MAAM,EACN,KAAK,EACL,eAAe,EACf,GAAG,kBAAkB,EACtB,EAAE,cAAc,2CAuChB"}
|
|
@@ -1,5 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { View } from 'react-native';
|
|
3
|
+
import { type NativeProps } from './GleamViewNativeComponent';
|
|
4
|
+
import { GleamLine } from './GleamLine';
|
|
5
|
+
export type { NativeProps } from './GleamViewNativeComponent';
|
|
6
|
+
export type { GleamLineProps } from './GleamLine';
|
|
7
|
+
/**
|
|
8
|
+
* Props accepted by GleamView, including ref (React 19 ref-as-prop).
|
|
9
|
+
* Use this type instead of `ComponentProps<typeof GleamView>` for
|
|
10
|
+
* accurate ref typing.
|
|
11
|
+
*/
|
|
12
|
+
export type GleamViewProps = NativeProps & {
|
|
13
|
+
ref?: React.Ref<View>;
|
|
14
|
+
};
|
|
3
15
|
export declare enum GleamDirection {
|
|
4
16
|
LeftToRight = "ltr",
|
|
5
17
|
RightToLeft = "rtl",
|
|
@@ -10,4 +22,13 @@ export declare enum GleamTransition {
|
|
|
10
22
|
Shrink = "shrink",
|
|
11
23
|
Collapse = "collapse"
|
|
12
24
|
}
|
|
25
|
+
declare function GleamViewComponent({ ref, ...props }: NativeProps & {
|
|
26
|
+
ref?: React.Ref<unknown>;
|
|
27
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
28
|
+
declare namespace GleamViewComponent {
|
|
29
|
+
var displayName: string;
|
|
30
|
+
}
|
|
31
|
+
export declare const GleamView: typeof GleamViewComponent & {
|
|
32
|
+
Line: typeof GleamLine;
|
|
33
|
+
};
|
|
13
34
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAiD,MAAM,OAAO,CAAC;AACtE,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AACpC,OAAwB,EAAE,KAAK,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAE/E,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,YAAY,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAC9D,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG,WAAW,GAAG;IACzC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;CACvB,CAAC;AAEF,oBAAY,cAAc;IACxB,WAAW,QAAQ;IACnB,WAAW,QAAQ;IACnB,WAAW,QAAQ;CACpB;AAED,oBAAY,eAAe;IACzB,IAAI,SAAS;IACb,MAAM,WAAW;IACjB,QAAQ,aAAa;CACtB;AAkDD,iBAAS,kBAAkB,CAAC,EAC1B,GAAG,EACH,GAAG,KAAK,EACT,EAAE,WAAW,GAAG;IAAE,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;CAAE,2CAkF5C;kBArFQ,kBAAkB;;;AAyF3B,eAAO,MAAM,SAAS;;CAEpB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-gleam",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.7",
|
|
4
4
|
"description": "Native-powered shimmer loading effect for React Native",
|
|
5
5
|
"main": "./lib/module/index.js",
|
|
6
6
|
"types": "./lib/typescript/src/index.d.ts",
|
|
@@ -92,8 +92,8 @@
|
|
|
92
92
|
"typescript": "^5.9.2"
|
|
93
93
|
},
|
|
94
94
|
"peerDependencies": {
|
|
95
|
-
"react": ">=
|
|
96
|
-
"react-native": ">=0.
|
|
95
|
+
"react": ">=19.0.0",
|
|
96
|
+
"react-native": ">=0.78.0"
|
|
97
97
|
},
|
|
98
98
|
"workspaces": [
|
|
99
99
|
"example"
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { createContext } from 'react';
|
|
2
|
+
import { type NativeProps } from './GleamViewNativeComponent';
|
|
3
|
+
|
|
4
|
+
export interface GleamContextValue {
|
|
5
|
+
loading: NativeProps['loading'];
|
|
6
|
+
speed: NativeProps['speed'];
|
|
7
|
+
direction: NativeProps['direction'];
|
|
8
|
+
transitionDuration: NativeProps['transitionDuration'];
|
|
9
|
+
transitionType: NativeProps['transitionType'];
|
|
10
|
+
intensity: NativeProps['intensity'];
|
|
11
|
+
baseColor: NativeProps['baseColor'];
|
|
12
|
+
highlightColor: NativeProps['highlightColor'];
|
|
13
|
+
registerLine: () => () => void;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const GleamContext = createContext<GleamContextValue | null>(null);
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { useContext, useLayoutEffect, type ReactNode } from 'react';
|
|
2
|
+
import {
|
|
3
|
+
View,
|
|
4
|
+
type AccessibilityProps,
|
|
5
|
+
type StyleProp,
|
|
6
|
+
type ViewStyle,
|
|
7
|
+
} from 'react-native';
|
|
8
|
+
import NativeGleamView, { type NativeProps } from './GleamViewNativeComponent';
|
|
9
|
+
import { GleamContext } from './GleamContext';
|
|
10
|
+
|
|
11
|
+
export interface GleamLineProps extends AccessibilityProps {
|
|
12
|
+
children?: ReactNode;
|
|
13
|
+
style?: StyleProp<ViewStyle>;
|
|
14
|
+
testID?: string;
|
|
15
|
+
delay?: NativeProps['delay'];
|
|
16
|
+
onTransitionEnd?: NativeProps['onTransitionEnd'];
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function GleamLine({
|
|
20
|
+
children,
|
|
21
|
+
style,
|
|
22
|
+
testID,
|
|
23
|
+
delay,
|
|
24
|
+
onTransitionEnd,
|
|
25
|
+
...accessibilityProps
|
|
26
|
+
}: GleamLineProps) {
|
|
27
|
+
const ctx = useContext(GleamContext);
|
|
28
|
+
const register = ctx?.registerLine;
|
|
29
|
+
|
|
30
|
+
useLayoutEffect(() => {
|
|
31
|
+
if (!register) return;
|
|
32
|
+
return register();
|
|
33
|
+
}, [register]);
|
|
34
|
+
|
|
35
|
+
if (!ctx) {
|
|
36
|
+
if (__DEV__) {
|
|
37
|
+
console.warn('GleamView.Line must be used inside a GleamView');
|
|
38
|
+
}
|
|
39
|
+
return (
|
|
40
|
+
<View style={style} testID={testID} {...accessibilityProps}>
|
|
41
|
+
{children}
|
|
42
|
+
</View>
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return (
|
|
47
|
+
<NativeGleamView
|
|
48
|
+
loading={ctx.loading}
|
|
49
|
+
speed={ctx.speed}
|
|
50
|
+
direction={ctx.direction}
|
|
51
|
+
delay={delay}
|
|
52
|
+
transitionDuration={ctx.transitionDuration}
|
|
53
|
+
transitionType={ctx.transitionType}
|
|
54
|
+
intensity={ctx.intensity}
|
|
55
|
+
baseColor={ctx.baseColor}
|
|
56
|
+
highlightColor={ctx.highlightColor}
|
|
57
|
+
onTransitionEnd={onTransitionEnd}
|
|
58
|
+
style={style}
|
|
59
|
+
testID={testID}
|
|
60
|
+
{...accessibilityProps}
|
|
61
|
+
>
|
|
62
|
+
{children}
|
|
63
|
+
</NativeGleamView>
|
|
64
|
+
);
|
|
65
|
+
}
|
package/src/index.tsx
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import React, { useCallback, useMemo, useRef, useState } from 'react';
|
|
2
|
+
import { View } from 'react-native';
|
|
3
|
+
import NativeGleamView, { type NativeProps } from './GleamViewNativeComponent';
|
|
4
|
+
import { GleamContext, type GleamContextValue } from './GleamContext';
|
|
5
|
+
import { GleamLine } from './GleamLine';
|
|
6
|
+
|
|
7
|
+
export type { NativeProps } from './GleamViewNativeComponent';
|
|
8
|
+
export type { GleamLineProps } from './GleamLine';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Props accepted by GleamView, including ref (React 19 ref-as-prop).
|
|
12
|
+
* Use this type instead of `ComponentProps<typeof GleamView>` for
|
|
13
|
+
* accurate ref typing.
|
|
14
|
+
*/
|
|
15
|
+
export type GleamViewProps = NativeProps & {
|
|
16
|
+
ref?: React.Ref<View>;
|
|
17
|
+
};
|
|
3
18
|
|
|
4
19
|
export enum GleamDirection {
|
|
5
20
|
LeftToRight = 'ltr',
|
|
@@ -12,3 +27,144 @@ export enum GleamTransition {
|
|
|
12
27
|
Shrink = 'shrink',
|
|
13
28
|
Collapse = 'collapse',
|
|
14
29
|
}
|
|
30
|
+
|
|
31
|
+
// Shimmer-specific prop keys to exclude when rendering as a plain View container.
|
|
32
|
+
// Typed against NativeProps so a missing key triggers a compile error.
|
|
33
|
+
const SHIMMER_KEY_LIST = [
|
|
34
|
+
'loading',
|
|
35
|
+
'speed',
|
|
36
|
+
'direction',
|
|
37
|
+
'delay',
|
|
38
|
+
'transitionDuration',
|
|
39
|
+
'transitionType',
|
|
40
|
+
'intensity',
|
|
41
|
+
'baseColor',
|
|
42
|
+
'highlightColor',
|
|
43
|
+
'onTransitionEnd',
|
|
44
|
+
'children',
|
|
45
|
+
] as const satisfies ReadonlyArray<keyof NativeProps | 'children'>;
|
|
46
|
+
|
|
47
|
+
const SHIMMER_KEYS: ReadonlySet<string> = new Set(SHIMMER_KEY_LIST);
|
|
48
|
+
|
|
49
|
+
function pickViewProps(props: NativeProps) {
|
|
50
|
+
const viewProps: Record<string, unknown> = {};
|
|
51
|
+
for (const key of Object.keys(props)) {
|
|
52
|
+
if (!SHIMMER_KEYS.has(key)) {
|
|
53
|
+
viewProps[key] = (props as Record<string, unknown>)[key];
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return viewProps;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function hasLineChildren(children: React.ReactNode): boolean {
|
|
60
|
+
let found = false;
|
|
61
|
+
React.Children.forEach(children, (child) => {
|
|
62
|
+
if (found) return;
|
|
63
|
+
if (!React.isValidElement(child)) return;
|
|
64
|
+
if (child.type === GleamLine) {
|
|
65
|
+
found = true;
|
|
66
|
+
} else if (child.type === React.Fragment) {
|
|
67
|
+
found = hasLineChildren(
|
|
68
|
+
(child.props as { children?: React.ReactNode }).children
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
return found;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// React 19: ref is a regular prop, no forwardRef needed.
|
|
76
|
+
// Internal ref type is loosened to avoid monorepo type conflicts between
|
|
77
|
+
// root and example workspace @types/react copies. The exported GleamViewProps
|
|
78
|
+
// provides the correct consumer-facing type.
|
|
79
|
+
function GleamViewComponent({
|
|
80
|
+
ref,
|
|
81
|
+
...props
|
|
82
|
+
}: NativeProps & { ref?: React.Ref<unknown> }) {
|
|
83
|
+
const {
|
|
84
|
+
loading,
|
|
85
|
+
speed,
|
|
86
|
+
direction,
|
|
87
|
+
transitionDuration,
|
|
88
|
+
transitionType,
|
|
89
|
+
intensity,
|
|
90
|
+
baseColor,
|
|
91
|
+
highlightColor,
|
|
92
|
+
children,
|
|
93
|
+
} = props;
|
|
94
|
+
|
|
95
|
+
const lineCountRef = useRef(0);
|
|
96
|
+
const warnedTransitionRef = useRef(false);
|
|
97
|
+
const [hasLines, setHasLines] = useState(() => hasLineChildren(children));
|
|
98
|
+
|
|
99
|
+
const registerLine = useCallback(() => {
|
|
100
|
+
lineCountRef.current++;
|
|
101
|
+
setHasLines(true);
|
|
102
|
+
return () => {
|
|
103
|
+
lineCountRef.current--;
|
|
104
|
+
if (lineCountRef.current === 0) {
|
|
105
|
+
setHasLines(false);
|
|
106
|
+
warnedTransitionRef.current = false;
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
}, []);
|
|
110
|
+
|
|
111
|
+
const contextValue = useMemo<GleamContextValue>(
|
|
112
|
+
() => ({
|
|
113
|
+
loading,
|
|
114
|
+
speed,
|
|
115
|
+
direction,
|
|
116
|
+
transitionDuration,
|
|
117
|
+
transitionType,
|
|
118
|
+
intensity,
|
|
119
|
+
baseColor,
|
|
120
|
+
highlightColor,
|
|
121
|
+
registerLine,
|
|
122
|
+
}),
|
|
123
|
+
[
|
|
124
|
+
loading,
|
|
125
|
+
speed,
|
|
126
|
+
direction,
|
|
127
|
+
transitionDuration,
|
|
128
|
+
transitionType,
|
|
129
|
+
intensity,
|
|
130
|
+
baseColor,
|
|
131
|
+
highlightColor,
|
|
132
|
+
registerLine,
|
|
133
|
+
]
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
// Cast needed: View and NativeGleamView accept Ref<ReactNativeElement>
|
|
137
|
+
// but that type isn't publicly exported from react-native. Safe at runtime.
|
|
138
|
+
const nativeRef = ref as any;
|
|
139
|
+
|
|
140
|
+
if (hasLines) {
|
|
141
|
+
if (__DEV__ && props.onTransitionEnd && !warnedTransitionRef.current) {
|
|
142
|
+
warnedTransitionRef.current = true;
|
|
143
|
+
console.warn(
|
|
144
|
+
'GleamView: onTransitionEnd is ignored when GleamView.Line children are present. ' +
|
|
145
|
+
'Use onTransitionEnd on individual GleamView.Line components instead.'
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
return (
|
|
149
|
+
<GleamContext.Provider value={contextValue}>
|
|
150
|
+
<View ref={nativeRef} {...pickViewProps(props)}>
|
|
151
|
+
{children}
|
|
152
|
+
</View>
|
|
153
|
+
</GleamContext.Provider>
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return (
|
|
158
|
+
<GleamContext.Provider value={contextValue}>
|
|
159
|
+
<NativeGleamView ref={nativeRef} {...props}>
|
|
160
|
+
{children}
|
|
161
|
+
</NativeGleamView>
|
|
162
|
+
</GleamContext.Provider>
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
GleamViewComponent.displayName = 'GleamView';
|
|
167
|
+
|
|
168
|
+
export const GleamView = Object.assign(GleamViewComponent, {
|
|
169
|
+
Line: GleamLine,
|
|
170
|
+
});
|