@syraui/core 0.1.0

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/skeleton/Skeleton.native.tsx"],"names":["React","Animated","View","StyleSheet","useRef","useCallback","useEffect","_a","useState","_b","Easing"],"mappings":"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","file":"index.js","sourcesContent":["import React, { useCallback, useEffect, useRef, useState } from \"react\";\nimport {\n Animated,\n Easing,\n StyleSheet,\n View,\n type LayoutChangeEvent,\n type ViewStyle,\n} from \"react-native\";\nimport type { SkeletonBlock, SkeletonTheme } from \"../types/skeleton\";\n\n// ─── ShimmerBlock ─────────────────────────────────────────────────────────────\n\ninterface ShimmerBlockProps {\n block: SkeletonBlock;\n theme: SkeletonTheme;\n progress: Animated.Value;\n containerWidth: number;\n}\n\nfunction ShimmerBlock({\n block,\n theme,\n progress,\n containerWidth,\n}: ShimmerBlockProps) {\n const base = theme.baseColor ?? \"#EAECF0\";\n const highlight = theme.highlightColor ?? \"#F8F9FB\";\n const anim = theme.animation ?? \"shimmer\";\n const br =\n typeof theme.borderRadius === \"number\"\n ? theme.borderRadius\n : (block.borderRadius ?? 6);\n\n if (anim === \"pulse\") {\n return (\n <Animated.View\n style={{\n position: \"absolute\",\n top: block.y,\n left: block.x,\n width: block.width,\n height: block.height,\n borderRadius: br,\n backgroundColor: base,\n opacity: progress.interpolate({\n inputRange: [0, 0.5, 1],\n outputRange: [1, 0.4, 1],\n }),\n }}\n />\n );\n }\n\n if (anim === \"none\") {\n return (\n <View\n style={{\n position: \"absolute\",\n top: block.y,\n left: block.x,\n width: block.width,\n height: block.height,\n borderRadius: br,\n backgroundColor: base,\n }}\n />\n );\n }\n\n const dir = theme.direction ?? \"ltr\";\n const translateX = progress.interpolate({\n inputRange: [0, 1],\n outputRange:\n dir === \"rtl\"\n ? [containerWidth, -containerWidth]\n : [-containerWidth, containerWidth],\n });\n\n return (\n <View\n style={{\n position: \"absolute\",\n top: block.y,\n left: block.x,\n width: block.width,\n height: block.height,\n borderRadius: br,\n backgroundColor: base,\n overflow: \"hidden\",\n }}\n >\n <Animated.View\n style={[\n StyleSheet.absoluteFill,\n {\n backgroundColor: highlight,\n opacity: 0.7,\n transform: [{ translateX }],\n },\n ]}\n />\n </View>\n );\n}\n\n// ─── Context ──────────────────────────────────────────────────────────────────\n\ninterface SkeletonContextValue {\n loading: boolean;\n containerRef: React.RefObject<View | null>;\n register: (block: SkeletonBlock) => void;\n theme: SkeletonTheme;\n}\n\nconst SkeletonContext = React.createContext<SkeletonContextValue | null>(null);\n\nconst sx = StyleSheet.create({\n hidden: { opacity: 0 },\n visible: { opacity: 1 },\n});\n\n// ─── SkeletonItem ─────────────────────────────────────────────────────────────\n\nexport interface SkeletonItemProps {\n /** The element to shimmer. Its style is read automatically. */\n children: React.ReactElement;\n /** Override border radius. Defaults to the child's style borderRadius. */\n borderRadius?: number;\n}\n\n/**\n * Marks an element to be shimmer'd by the parent `<Skeleton>`.\n * Reads dimensions directly from the child's style — no duplication needed.\n *\n * @example\n * <Skeleton loading={loading}>\n * <View style={s.card}>\n * <SkeletonItem><Image source={...} style={s.avatar} /></SkeletonItem>\n * <SkeletonItem><Text style={s.name}>{name}</Text></SkeletonItem>\n * </View>\n * </Skeleton>\n */\nexport function SkeletonItem({\n children,\n borderRadius: brOverride,\n}: SkeletonItemProps) {\n const ctx = React.useContext(SkeletonContext);\n const wrapRef = useRef<View>(null);\n\n const childProps = children.props as { style?: ViewStyle | ViewStyle[] };\n const flatStyle = Array.isArray(childProps.style)\n ? Object.assign({}, ...(childProps.style as object[]))\n : ((childProps.style ?? {}) as ViewStyle & { borderRadius?: number });\n const br =\n brOverride ?? (flatStyle as { borderRadius?: number }).borderRadius ?? 6;\n\n const measure = useCallback(() => {\n if (!ctx) return;\n const self = wrapRef.current;\n const container = ctx.containerRef.current;\n if (!self || !container) return;\n self.measureLayout(\n container,\n (x, y, width, height) => {\n if (width > 1 && height > 1)\n ctx.register({ x, y, width, height, borderRadius: br });\n },\n () => {},\n );\n }, [ctx, br]);\n\n useEffect(() => {\n if (!ctx?.loading) return;\n const t = setTimeout(measure, 50);\n return () => clearTimeout(t);\n }, [ctx?.loading, measure]);\n\n const loading = ctx?.loading ?? false;\n const base = ctx?.theme.baseColor ?? \"#EAECF0\";\n\n return (\n <View\n ref={wrapRef}\n collapsable={false}\n onLayout={measure}\n style={flatStyle}\n >\n <View style={loading ? sx.hidden : sx.visible}>{children}</View>\n {loading && (\n <View\n pointerEvents=\"none\"\n style={[\n StyleSheet.absoluteFill,\n { backgroundColor: base, borderRadius: br },\n ]}\n />\n )}\n </View>\n );\n}\n\n// ─── Skeleton ─────────────────────────────────────────────────────────────────\n\nexport interface NativeSkeletonProps extends SkeletonTheme {\n /** Toggle between skeleton and real content. */\n loading: boolean;\n /** Your component — wrap elements to shimmer with `<SkeletonItem>`. */\n children: React.ReactNode;\n /** Optional style for the outer container. */\n style?: ViewStyle;\n}\n\n/**\n * Wraps a component and renders shimmer blocks over elements\n * marked with `<SkeletonItem>`.\n */\nexport function Skeleton({\n loading,\n children,\n style,\n ...theme\n}: NativeSkeletonProps) {\n const progress = useRef(new Animated.Value(0)).current;\n const animRef = useRef<Animated.CompositeAnimation | null>(null);\n const containerRef = useRef<View>(null);\n const blocksMapRef = useRef<Map<string, SkeletonBlock>>(new Map());\n const childrenKeyRef = useRef<string>(\"\");\n\n const [blocks, setBlocks] = useState<SkeletonBlock[]>([]);\n const [containerWidth, setContainerWidth] = useState(320);\n\n const register = useCallback((block: SkeletonBlock) => {\n const key = `${Math.round(block.x)}-${Math.round(block.y)}-${Math.round(block.width)}-${Math.round(block.height)}`;\n blocksMapRef.current.set(key, block);\n setBlocks(Array.from(blocksMapRef.current.values()));\n }, []);\n\n useEffect(() => {\n const key = React.Children.count(children).toString();\n if (childrenKeyRef.current !== key) {\n childrenKeyRef.current = key;\n blocksMapRef.current.clear();\n setBlocks([]);\n }\n });\n\n useEffect(() => {\n if (!loading) {\n animRef.current?.stop();\n return;\n }\n progress.setValue(0);\n animRef.current?.stop();\n animRef.current = Animated.loop(\n Animated.timing(progress, {\n toValue: 1,\n duration: (theme.speed ?? 1.8) * 1000,\n easing: Easing.inOut(Easing.ease),\n useNativeDriver: true,\n }),\n );\n animRef.current.start();\n return () => {\n animRef.current?.stop();\n };\n }, [loading, theme.speed, theme.animation, progress]);\n\n return (\n <SkeletonContext.Provider\n value={{ loading, containerRef, register, theme }}\n >\n <View\n ref={containerRef}\n style={[{ position: \"relative\" }, style]}\n onLayout={(e: LayoutChangeEvent) =>\n setContainerWidth(e.nativeEvent.layout.width)\n }\n accessible\n accessibilityLabel={loading ? \"Loading\" : undefined}\n >\n {children}\n\n {loading && blocks.length > 0 && (\n <View\n style={StyleSheet.absoluteFill}\n pointerEvents=\"none\"\n accessibilityRole=\"progressbar\"\n >\n {blocks.map((block, i) => (\n <ShimmerBlock\n key={i}\n block={block}\n theme={theme}\n progress={progress}\n containerWidth={containerWidth}\n />\n ))}\n </View>\n )}\n\n {loading && blocks.length === 0 && (\n <View style={StyleSheet.absoluteFill} pointerEvents=\"none\">\n <Animated.View\n style={[\n StyleSheet.absoluteFill,\n {\n backgroundColor: theme.baseColor ?? \"#EAECF0\",\n borderRadius:\n typeof theme.borderRadius === \"number\"\n ? theme.borderRadius\n : 6,\n opacity: progress.interpolate({\n inputRange: [0, 0.5, 1],\n outputRange: [0.4, 0.9, 0.4],\n }),\n },\n ]}\n />\n </View>\n )}\n </View>\n </SkeletonContext.Provider>\n );\n}\n"]}
@@ -0,0 +1,266 @@
1
+ import React, { useRef, useCallback, useEffect, useState } from 'react';
2
+ import { StyleSheet, View, Animated, Easing } from 'react-native';
3
+
4
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
7
+ var __objRest = (source, exclude) => {
8
+ var target = {};
9
+ for (var prop in source)
10
+ if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
11
+ target[prop] = source[prop];
12
+ if (source != null && __getOwnPropSymbols)
13
+ for (var prop of __getOwnPropSymbols(source)) {
14
+ if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
15
+ target[prop] = source[prop];
16
+ }
17
+ return target;
18
+ };
19
+ function ShimmerBlock({
20
+ block,
21
+ theme,
22
+ progress,
23
+ containerWidth
24
+ }) {
25
+ var _a, _b, _c, _d, _e;
26
+ const base = (_a = theme.baseColor) != null ? _a : "#EAECF0";
27
+ const highlight = (_b = theme.highlightColor) != null ? _b : "#F8F9FB";
28
+ const anim = (_c = theme.animation) != null ? _c : "shimmer";
29
+ const br = typeof theme.borderRadius === "number" ? theme.borderRadius : (_d = block.borderRadius) != null ? _d : 6;
30
+ if (anim === "pulse") {
31
+ return /* @__PURE__ */ React.createElement(
32
+ Animated.View,
33
+ {
34
+ style: {
35
+ position: "absolute",
36
+ top: block.y,
37
+ left: block.x,
38
+ width: block.width,
39
+ height: block.height,
40
+ borderRadius: br,
41
+ backgroundColor: base,
42
+ opacity: progress.interpolate({
43
+ inputRange: [0, 0.5, 1],
44
+ outputRange: [1, 0.4, 1]
45
+ })
46
+ }
47
+ }
48
+ );
49
+ }
50
+ if (anim === "none") {
51
+ return /* @__PURE__ */ React.createElement(
52
+ View,
53
+ {
54
+ style: {
55
+ position: "absolute",
56
+ top: block.y,
57
+ left: block.x,
58
+ width: block.width,
59
+ height: block.height,
60
+ borderRadius: br,
61
+ backgroundColor: base
62
+ }
63
+ }
64
+ );
65
+ }
66
+ const dir = (_e = theme.direction) != null ? _e : "ltr";
67
+ const translateX = progress.interpolate({
68
+ inputRange: [0, 1],
69
+ outputRange: dir === "rtl" ? [containerWidth, -containerWidth] : [-containerWidth, containerWidth]
70
+ });
71
+ return /* @__PURE__ */ React.createElement(
72
+ View,
73
+ {
74
+ style: {
75
+ position: "absolute",
76
+ top: block.y,
77
+ left: block.x,
78
+ width: block.width,
79
+ height: block.height,
80
+ borderRadius: br,
81
+ backgroundColor: base,
82
+ overflow: "hidden"
83
+ }
84
+ },
85
+ /* @__PURE__ */ React.createElement(
86
+ Animated.View,
87
+ {
88
+ style: [
89
+ StyleSheet.absoluteFill,
90
+ {
91
+ backgroundColor: highlight,
92
+ opacity: 0.7,
93
+ transform: [{ translateX }]
94
+ }
95
+ ]
96
+ }
97
+ )
98
+ );
99
+ }
100
+ var SkeletonContext = React.createContext(null);
101
+ var sx = StyleSheet.create({
102
+ hidden: { opacity: 0 },
103
+ visible: { opacity: 1 }
104
+ });
105
+ function SkeletonItem({
106
+ children,
107
+ borderRadius: brOverride
108
+ }) {
109
+ var _a, _b, _c, _d;
110
+ const ctx = React.useContext(SkeletonContext);
111
+ const wrapRef = useRef(null);
112
+ const childProps = children.props;
113
+ const flatStyle = Array.isArray(childProps.style) ? Object.assign({}, ...childProps.style) : (_a = childProps.style) != null ? _a : {};
114
+ const br = (_b = brOverride != null ? brOverride : flatStyle.borderRadius) != null ? _b : 6;
115
+ const measure = useCallback(() => {
116
+ if (!ctx) return;
117
+ const self = wrapRef.current;
118
+ const container = ctx.containerRef.current;
119
+ if (!self || !container) return;
120
+ self.measureLayout(
121
+ container,
122
+ (x, y, width, height) => {
123
+ if (width > 1 && height > 1)
124
+ ctx.register({ x, y, width, height, borderRadius: br });
125
+ },
126
+ () => {
127
+ }
128
+ );
129
+ }, [ctx, br]);
130
+ useEffect(() => {
131
+ if (!(ctx == null ? void 0 : ctx.loading)) return;
132
+ const t = setTimeout(measure, 50);
133
+ return () => clearTimeout(t);
134
+ }, [ctx == null ? void 0 : ctx.loading, measure]);
135
+ const loading = (_c = ctx == null ? void 0 : ctx.loading) != null ? _c : false;
136
+ const base = (_d = ctx == null ? void 0 : ctx.theme.baseColor) != null ? _d : "#EAECF0";
137
+ return /* @__PURE__ */ React.createElement(
138
+ View,
139
+ {
140
+ ref: wrapRef,
141
+ collapsable: false,
142
+ onLayout: measure,
143
+ style: flatStyle
144
+ },
145
+ /* @__PURE__ */ React.createElement(View, { style: loading ? sx.hidden : sx.visible }, children),
146
+ loading && /* @__PURE__ */ React.createElement(
147
+ View,
148
+ {
149
+ pointerEvents: "none",
150
+ style: [
151
+ StyleSheet.absoluteFill,
152
+ { backgroundColor: base, borderRadius: br }
153
+ ]
154
+ }
155
+ )
156
+ );
157
+ }
158
+ function Skeleton(_a) {
159
+ var _b = _a, {
160
+ loading,
161
+ children,
162
+ style
163
+ } = _b, theme = __objRest(_b, [
164
+ "loading",
165
+ "children",
166
+ "style"
167
+ ]);
168
+ var _a2;
169
+ const progress = useRef(new Animated.Value(0)).current;
170
+ const animRef = useRef(null);
171
+ const containerRef = useRef(null);
172
+ const blocksMapRef = useRef(/* @__PURE__ */ new Map());
173
+ const childrenKeyRef = useRef("");
174
+ const [blocks, setBlocks] = useState([]);
175
+ const [containerWidth, setContainerWidth] = useState(320);
176
+ const register = useCallback((block) => {
177
+ const key = `${Math.round(block.x)}-${Math.round(block.y)}-${Math.round(block.width)}-${Math.round(block.height)}`;
178
+ blocksMapRef.current.set(key, block);
179
+ setBlocks(Array.from(blocksMapRef.current.values()));
180
+ }, []);
181
+ useEffect(() => {
182
+ const key = React.Children.count(children).toString();
183
+ if (childrenKeyRef.current !== key) {
184
+ childrenKeyRef.current = key;
185
+ blocksMapRef.current.clear();
186
+ setBlocks([]);
187
+ }
188
+ });
189
+ useEffect(() => {
190
+ var _a3, _b2, _c;
191
+ if (!loading) {
192
+ (_a3 = animRef.current) == null ? void 0 : _a3.stop();
193
+ return;
194
+ }
195
+ progress.setValue(0);
196
+ (_b2 = animRef.current) == null ? void 0 : _b2.stop();
197
+ animRef.current = Animated.loop(
198
+ Animated.timing(progress, {
199
+ toValue: 1,
200
+ duration: ((_c = theme.speed) != null ? _c : 1.8) * 1e3,
201
+ easing: Easing.inOut(Easing.ease),
202
+ useNativeDriver: true
203
+ })
204
+ );
205
+ animRef.current.start();
206
+ return () => {
207
+ var _a4;
208
+ (_a4 = animRef.current) == null ? void 0 : _a4.stop();
209
+ };
210
+ }, [loading, theme.speed, theme.animation, progress]);
211
+ return /* @__PURE__ */ React.createElement(
212
+ SkeletonContext.Provider,
213
+ {
214
+ value: { loading, containerRef, register, theme }
215
+ },
216
+ /* @__PURE__ */ React.createElement(
217
+ View,
218
+ {
219
+ ref: containerRef,
220
+ style: [{ position: "relative" }, style],
221
+ onLayout: (e) => setContainerWidth(e.nativeEvent.layout.width),
222
+ accessible: true,
223
+ accessibilityLabel: loading ? "Loading" : void 0
224
+ },
225
+ children,
226
+ loading && blocks.length > 0 && /* @__PURE__ */ React.createElement(
227
+ View,
228
+ {
229
+ style: StyleSheet.absoluteFill,
230
+ pointerEvents: "none",
231
+ accessibilityRole: "progressbar"
232
+ },
233
+ blocks.map((block, i) => /* @__PURE__ */ React.createElement(
234
+ ShimmerBlock,
235
+ {
236
+ key: i,
237
+ block,
238
+ theme,
239
+ progress,
240
+ containerWidth
241
+ }
242
+ ))
243
+ ),
244
+ loading && blocks.length === 0 && /* @__PURE__ */ React.createElement(View, { style: StyleSheet.absoluteFill, pointerEvents: "none" }, /* @__PURE__ */ React.createElement(
245
+ Animated.View,
246
+ {
247
+ style: [
248
+ StyleSheet.absoluteFill,
249
+ {
250
+ backgroundColor: (_a2 = theme.baseColor) != null ? _a2 : "#EAECF0",
251
+ borderRadius: typeof theme.borderRadius === "number" ? theme.borderRadius : 6,
252
+ opacity: progress.interpolate({
253
+ inputRange: [0, 0.5, 1],
254
+ outputRange: [0.4, 0.9, 0.4]
255
+ })
256
+ }
257
+ ]
258
+ }
259
+ ))
260
+ )
261
+ );
262
+ }
263
+
264
+ export { Skeleton, SkeletonItem };
265
+ //# sourceMappingURL=index.mjs.map
266
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/skeleton/Skeleton.native.tsx"],"names":["_a","_b"],"mappings":"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","file":"index.mjs","sourcesContent":["import React, { useCallback, useEffect, useRef, useState } from \"react\";\nimport {\n Animated,\n Easing,\n StyleSheet,\n View,\n type LayoutChangeEvent,\n type ViewStyle,\n} from \"react-native\";\nimport type { SkeletonBlock, SkeletonTheme } from \"../types/skeleton\";\n\n// ─── ShimmerBlock ─────────────────────────────────────────────────────────────\n\ninterface ShimmerBlockProps {\n block: SkeletonBlock;\n theme: SkeletonTheme;\n progress: Animated.Value;\n containerWidth: number;\n}\n\nfunction ShimmerBlock({\n block,\n theme,\n progress,\n containerWidth,\n}: ShimmerBlockProps) {\n const base = theme.baseColor ?? \"#EAECF0\";\n const highlight = theme.highlightColor ?? \"#F8F9FB\";\n const anim = theme.animation ?? \"shimmer\";\n const br =\n typeof theme.borderRadius === \"number\"\n ? theme.borderRadius\n : (block.borderRadius ?? 6);\n\n if (anim === \"pulse\") {\n return (\n <Animated.View\n style={{\n position: \"absolute\",\n top: block.y,\n left: block.x,\n width: block.width,\n height: block.height,\n borderRadius: br,\n backgroundColor: base,\n opacity: progress.interpolate({\n inputRange: [0, 0.5, 1],\n outputRange: [1, 0.4, 1],\n }),\n }}\n />\n );\n }\n\n if (anim === \"none\") {\n return (\n <View\n style={{\n position: \"absolute\",\n top: block.y,\n left: block.x,\n width: block.width,\n height: block.height,\n borderRadius: br,\n backgroundColor: base,\n }}\n />\n );\n }\n\n const dir = theme.direction ?? \"ltr\";\n const translateX = progress.interpolate({\n inputRange: [0, 1],\n outputRange:\n dir === \"rtl\"\n ? [containerWidth, -containerWidth]\n : [-containerWidth, containerWidth],\n });\n\n return (\n <View\n style={{\n position: \"absolute\",\n top: block.y,\n left: block.x,\n width: block.width,\n height: block.height,\n borderRadius: br,\n backgroundColor: base,\n overflow: \"hidden\",\n }}\n >\n <Animated.View\n style={[\n StyleSheet.absoluteFill,\n {\n backgroundColor: highlight,\n opacity: 0.7,\n transform: [{ translateX }],\n },\n ]}\n />\n </View>\n );\n}\n\n// ─── Context ──────────────────────────────────────────────────────────────────\n\ninterface SkeletonContextValue {\n loading: boolean;\n containerRef: React.RefObject<View | null>;\n register: (block: SkeletonBlock) => void;\n theme: SkeletonTheme;\n}\n\nconst SkeletonContext = React.createContext<SkeletonContextValue | null>(null);\n\nconst sx = StyleSheet.create({\n hidden: { opacity: 0 },\n visible: { opacity: 1 },\n});\n\n// ─── SkeletonItem ─────────────────────────────────────────────────────────────\n\nexport interface SkeletonItemProps {\n /** The element to shimmer. Its style is read automatically. */\n children: React.ReactElement;\n /** Override border radius. Defaults to the child's style borderRadius. */\n borderRadius?: number;\n}\n\n/**\n * Marks an element to be shimmer'd by the parent `<Skeleton>`.\n * Reads dimensions directly from the child's style — no duplication needed.\n *\n * @example\n * <Skeleton loading={loading}>\n * <View style={s.card}>\n * <SkeletonItem><Image source={...} style={s.avatar} /></SkeletonItem>\n * <SkeletonItem><Text style={s.name}>{name}</Text></SkeletonItem>\n * </View>\n * </Skeleton>\n */\nexport function SkeletonItem({\n children,\n borderRadius: brOverride,\n}: SkeletonItemProps) {\n const ctx = React.useContext(SkeletonContext);\n const wrapRef = useRef<View>(null);\n\n const childProps = children.props as { style?: ViewStyle | ViewStyle[] };\n const flatStyle = Array.isArray(childProps.style)\n ? Object.assign({}, ...(childProps.style as object[]))\n : ((childProps.style ?? {}) as ViewStyle & { borderRadius?: number });\n const br =\n brOverride ?? (flatStyle as { borderRadius?: number }).borderRadius ?? 6;\n\n const measure = useCallback(() => {\n if (!ctx) return;\n const self = wrapRef.current;\n const container = ctx.containerRef.current;\n if (!self || !container) return;\n self.measureLayout(\n container,\n (x, y, width, height) => {\n if (width > 1 && height > 1)\n ctx.register({ x, y, width, height, borderRadius: br });\n },\n () => {},\n );\n }, [ctx, br]);\n\n useEffect(() => {\n if (!ctx?.loading) return;\n const t = setTimeout(measure, 50);\n return () => clearTimeout(t);\n }, [ctx?.loading, measure]);\n\n const loading = ctx?.loading ?? false;\n const base = ctx?.theme.baseColor ?? \"#EAECF0\";\n\n return (\n <View\n ref={wrapRef}\n collapsable={false}\n onLayout={measure}\n style={flatStyle}\n >\n <View style={loading ? sx.hidden : sx.visible}>{children}</View>\n {loading && (\n <View\n pointerEvents=\"none\"\n style={[\n StyleSheet.absoluteFill,\n { backgroundColor: base, borderRadius: br },\n ]}\n />\n )}\n </View>\n );\n}\n\n// ─── Skeleton ─────────────────────────────────────────────────────────────────\n\nexport interface NativeSkeletonProps extends SkeletonTheme {\n /** Toggle between skeleton and real content. */\n loading: boolean;\n /** Your component — wrap elements to shimmer with `<SkeletonItem>`. */\n children: React.ReactNode;\n /** Optional style for the outer container. */\n style?: ViewStyle;\n}\n\n/**\n * Wraps a component and renders shimmer blocks over elements\n * marked with `<SkeletonItem>`.\n */\nexport function Skeleton({\n loading,\n children,\n style,\n ...theme\n}: NativeSkeletonProps) {\n const progress = useRef(new Animated.Value(0)).current;\n const animRef = useRef<Animated.CompositeAnimation | null>(null);\n const containerRef = useRef<View>(null);\n const blocksMapRef = useRef<Map<string, SkeletonBlock>>(new Map());\n const childrenKeyRef = useRef<string>(\"\");\n\n const [blocks, setBlocks] = useState<SkeletonBlock[]>([]);\n const [containerWidth, setContainerWidth] = useState(320);\n\n const register = useCallback((block: SkeletonBlock) => {\n const key = `${Math.round(block.x)}-${Math.round(block.y)}-${Math.round(block.width)}-${Math.round(block.height)}`;\n blocksMapRef.current.set(key, block);\n setBlocks(Array.from(blocksMapRef.current.values()));\n }, []);\n\n useEffect(() => {\n const key = React.Children.count(children).toString();\n if (childrenKeyRef.current !== key) {\n childrenKeyRef.current = key;\n blocksMapRef.current.clear();\n setBlocks([]);\n }\n });\n\n useEffect(() => {\n if (!loading) {\n animRef.current?.stop();\n return;\n }\n progress.setValue(0);\n animRef.current?.stop();\n animRef.current = Animated.loop(\n Animated.timing(progress, {\n toValue: 1,\n duration: (theme.speed ?? 1.8) * 1000,\n easing: Easing.inOut(Easing.ease),\n useNativeDriver: true,\n }),\n );\n animRef.current.start();\n return () => {\n animRef.current?.stop();\n };\n }, [loading, theme.speed, theme.animation, progress]);\n\n return (\n <SkeletonContext.Provider\n value={{ loading, containerRef, register, theme }}\n >\n <View\n ref={containerRef}\n style={[{ position: \"relative\" }, style]}\n onLayout={(e: LayoutChangeEvent) =>\n setContainerWidth(e.nativeEvent.layout.width)\n }\n accessible\n accessibilityLabel={loading ? \"Loading\" : undefined}\n >\n {children}\n\n {loading && blocks.length > 0 && (\n <View\n style={StyleSheet.absoluteFill}\n pointerEvents=\"none\"\n accessibilityRole=\"progressbar\"\n >\n {blocks.map((block, i) => (\n <ShimmerBlock\n key={i}\n block={block}\n theme={theme}\n progress={progress}\n containerWidth={containerWidth}\n />\n ))}\n </View>\n )}\n\n {loading && blocks.length === 0 && (\n <View style={StyleSheet.absoluteFill} pointerEvents=\"none\">\n <Animated.View\n style={[\n StyleSheet.absoluteFill,\n {\n backgroundColor: theme.baseColor ?? \"#EAECF0\",\n borderRadius:\n typeof theme.borderRadius === \"number\"\n ? theme.borderRadius\n : 6,\n opacity: progress.interpolate({\n inputRange: [0, 0.5, 1],\n outputRange: [0.4, 0.9, 0.4],\n }),\n },\n ]}\n />\n </View>\n )}\n </View>\n </SkeletonContext.Provider>\n );\n}\n"]}
package/package.json ADDED
@@ -0,0 +1,84 @@
1
+ {
2
+ "name": "@syraui/core",
3
+ "version": "0.1.0",
4
+ "description": "Cross-platform UX components that save developers from rebuilding common patterns — for React, React Native, Next.js, Vite, and Expo.",
5
+ "keywords": [
6
+ "react",
7
+ "react-native",
8
+ "expo",
9
+ "nextjs",
10
+ "vite",
11
+ "ui-library",
12
+ "component-library",
13
+ "design-system",
14
+ "ux-components",
15
+ "productivity",
16
+ "developer-experience",
17
+ "dx",
18
+ "boilerplate-ui",
19
+ "common-patterns",
20
+ "loading-ui",
21
+ "skeleton-loader",
22
+ "shimmer-effect",
23
+ "cross-platform",
24
+ "universal-components",
25
+ "syraui"
26
+ ],
27
+ "license": "MIT",
28
+ "author": "Ryan Aprianto",
29
+ "sideEffects": false,
30
+ "main": "./dist/index.js",
31
+ "module": "./dist/index.mjs",
32
+ "types": "./dist/index.d.ts",
33
+ "exports": {
34
+ ".": {
35
+ "types": "./dist/index.d.ts",
36
+ "import": "./dist/index.mjs",
37
+ "require": "./dist/index.js"
38
+ },
39
+ "./native": {
40
+ "types": "./dist/native/index.d.ts",
41
+ "import": "./dist/native/index.mjs",
42
+ "require": "./dist/native/index.js"
43
+ }
44
+ },
45
+ "files": [
46
+ "dist",
47
+ "README.md",
48
+ "LICENSE"
49
+ ],
50
+ "scripts": {
51
+ "build": "tsup",
52
+ "build:watch": "tsup --watch",
53
+ "type-check": "tsc --noEmit",
54
+ "prepublishOnly": "npm run build"
55
+ },
56
+ "peerDependencies": {
57
+ "react": ">=18.0.0",
58
+ "react-dom": ">=18.0.0"
59
+ },
60
+ "peerDependenciesMeta": {
61
+ "react-dom": {
62
+ "optional": true
63
+ },
64
+ "react-native": {
65
+ "optional": true
66
+ }
67
+ },
68
+ "devDependencies": {
69
+ "@types/react": "^19.1.1",
70
+ "@types/react-dom": "^19.1.1",
71
+ "react": "19.2.4",
72
+ "react-dom": "19.2.4",
73
+ "react-native": "0.84.1",
74
+ "tsup": "latest",
75
+ "typescript": "latest"
76
+ },
77
+ "dependencies": {},
78
+ "publishConfig": {
79
+ "access": "public"
80
+ },
81
+ "engines": {
82
+ "node": ">=18"
83
+ }
84
+ }