@webority-technologies/mobile 0.0.15 → 0.0.21
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/lib/commonjs/components/Accordion/Accordion.js +60 -19
- package/lib/commonjs/components/AppBar/AppBar.js +29 -20
- package/lib/commonjs/components/Avatar/Avatar.js +38 -8
- package/lib/commonjs/components/Badge/Badge.js +66 -4
- package/lib/commonjs/components/Banner/Banner.js +146 -66
- package/lib/commonjs/components/BottomNavigation/BottomNavigation.js +37 -15
- package/lib/commonjs/components/BottomSheet/BottomSheet.js +78 -53
- package/lib/commonjs/components/Button/Button.js +12 -5
- package/lib/commonjs/components/Card/Card.js +106 -16
- package/lib/commonjs/components/Carousel/Carousel.js +66 -12
- package/lib/commonjs/components/Checkbox/Checkbox.js +11 -7
- package/lib/commonjs/components/Chip/Chip.js +44 -12
- package/lib/commonjs/components/DatePicker/DatePicker.js +185 -76
- package/lib/commonjs/components/DateRangePicker/DateRangePicker.js +133 -59
- package/lib/commonjs/components/Dialog/Dialog.js +16 -10
- package/lib/commonjs/components/Drawer/Drawer.js +13 -10
- package/lib/commonjs/components/FieldBase/FieldBase.js +494 -0
- package/lib/commonjs/components/FieldBase/index.js +32 -0
- package/lib/commonjs/components/FloatingActionButton/FloatingActionButton.js +69 -44
- package/lib/commonjs/components/ForceUpdateDialog/ForceUpdateDialog.js +8 -2
- package/lib/commonjs/components/FormField/FormField.js +3 -2
- package/lib/commonjs/components/ImageGallery/ImageGallery.js +132 -44
- package/lib/commonjs/components/Input/Input.js +144 -181
- package/lib/commonjs/components/ListItem/ListItem.js +90 -11
- package/lib/commonjs/components/Modal/Modal.js +55 -27
- package/lib/commonjs/components/NumberInput/NumberInput.js +60 -106
- package/lib/commonjs/components/OTPInput/OTPInput.js +65 -58
- package/lib/commonjs/components/PickerTrigger/PickerTrigger.js +185 -0
- package/lib/commonjs/components/{AppIcon → PickerTrigger}/index.js +4 -4
- package/lib/commonjs/components/ProgressBar/ProgressBar.js +19 -11
- package/lib/commonjs/components/Radio/Radio.js +11 -6
- package/lib/commonjs/components/Rating/Rating.js +85 -19
- package/lib/commonjs/components/SearchBar/SearchBar.js +90 -107
- package/lib/commonjs/components/SegmentedControl/SegmentedControl.js +22 -11
- package/lib/commonjs/components/Select/Select.js +62 -91
- package/lib/commonjs/components/Skeleton/Skeleton.js +131 -174
- package/lib/commonjs/components/Skeleton/SkeletonClock.js +117 -0
- package/lib/commonjs/components/Skeleton/SkeletonContent.js +164 -81
- package/lib/commonjs/components/Skeleton/SkeletonProvider.js +72 -10
- package/lib/commonjs/components/Skeleton/index.js +17 -16
- package/lib/commonjs/components/Slider/Slider.js +44 -25
- package/lib/commonjs/components/Stepper/Stepper.js +199 -29
- package/lib/commonjs/components/Swipeable/Swipeable.js +36 -19
- package/lib/commonjs/components/Switch/Switch.js +9 -2
- package/lib/commonjs/components/Tabs/Tabs.js +84 -21
- package/lib/commonjs/components/TimePicker/TimePicker.js +123 -45
- package/lib/commonjs/components/Toast/Toast.js +27 -16
- package/lib/commonjs/components/Tooltip/Tooltip.js +56 -32
- package/lib/commonjs/components/index.js +37 -37
- package/lib/commonjs/theme/tokens.js +55 -7
- package/lib/module/components/Accordion/Accordion.js +61 -20
- package/lib/module/components/AppBar/AppBar.js +29 -20
- package/lib/module/components/Avatar/Avatar.js +39 -9
- package/lib/module/components/Badge/Badge.js +67 -5
- package/lib/module/components/Banner/Banner.js +147 -67
- package/lib/module/components/BottomNavigation/BottomNavigation.js +37 -15
- package/lib/module/components/BottomSheet/BottomSheet.js +80 -55
- package/lib/module/components/Button/Button.js +12 -5
- package/lib/module/components/Card/Card.js +107 -17
- package/lib/module/components/Carousel/Carousel.js +67 -13
- package/lib/module/components/Checkbox/Checkbox.js +11 -7
- package/lib/module/components/Chip/Chip.js +45 -13
- package/lib/module/components/DatePicker/DatePicker.js +185 -76
- package/lib/module/components/DateRangePicker/DateRangePicker.js +134 -60
- package/lib/module/components/Dialog/Dialog.js +16 -10
- package/lib/module/components/Drawer/Drawer.js +13 -10
- package/lib/module/components/FieldBase/FieldBase.js +485 -0
- package/lib/module/components/FieldBase/index.js +4 -0
- package/lib/module/components/FloatingActionButton/FloatingActionButton.js +69 -44
- package/lib/module/components/ForceUpdateDialog/ForceUpdateDialog.js +8 -2
- package/lib/module/components/FormField/FormField.js +3 -2
- package/lib/module/components/ImageGallery/ImageGallery.js +128 -40
- package/lib/module/components/Input/Input.js +144 -179
- package/lib/module/components/ListItem/ListItem.js +91 -12
- package/lib/module/components/Modal/Modal.js +55 -27
- package/lib/module/components/NumberInput/NumberInput.js +60 -106
- package/lib/module/components/OTPInput/OTPInput.js +65 -58
- package/lib/module/components/PickerTrigger/PickerTrigger.js +181 -0
- package/lib/module/components/PickerTrigger/index.js +4 -0
- package/lib/module/components/ProgressBar/ProgressBar.js +19 -11
- package/lib/module/components/Radio/Radio.js +11 -6
- package/lib/module/components/Rating/Rating.js +86 -20
- package/lib/module/components/SearchBar/SearchBar.js +90 -107
- package/lib/module/components/SegmentedControl/SegmentedControl.js +22 -11
- package/lib/module/components/Select/Select.js +62 -91
- package/lib/module/components/Skeleton/Skeleton.js +135 -175
- package/lib/module/components/Skeleton/SkeletonClock.js +110 -0
- package/lib/module/components/Skeleton/SkeletonContent.js +167 -84
- package/lib/module/components/Skeleton/SkeletonProvider.js +71 -10
- package/lib/module/components/Skeleton/index.js +3 -2
- package/lib/module/components/Slider/Slider.js +44 -25
- package/lib/module/components/Stepper/Stepper.js +201 -31
- package/lib/module/components/Swipeable/Swipeable.js +36 -19
- package/lib/module/components/Switch/Switch.js +9 -2
- package/lib/module/components/Tabs/Tabs.js +84 -21
- package/lib/module/components/TimePicker/TimePicker.js +123 -45
- package/lib/module/components/Toast/Toast.js +27 -16
- package/lib/module/components/Tooltip/Tooltip.js +56 -32
- package/lib/module/components/index.js +2 -2
- package/lib/module/theme/tokens.js +55 -7
- package/lib/typescript/commonjs/components/Accordion/Accordion.d.ts +10 -5
- package/lib/typescript/commonjs/components/AppBar/AppBar.d.ts +8 -0
- package/lib/typescript/commonjs/components/Avatar/Avatar.d.ts +12 -6
- package/lib/typescript/commonjs/components/Badge/Badge.d.ts +7 -6
- package/lib/typescript/commonjs/components/Banner/Banner.d.ts +17 -6
- package/lib/typescript/commonjs/components/BottomSheet/BottomSheet.d.ts +7 -0
- package/lib/typescript/commonjs/components/Card/Card.d.ts +17 -6
- package/lib/typescript/commonjs/components/Carousel/Carousel.d.ts +7 -6
- package/lib/typescript/commonjs/components/Checkbox/Checkbox.d.ts +9 -1
- package/lib/typescript/commonjs/components/Chip/Chip.d.ts +13 -6
- package/lib/typescript/commonjs/components/DatePicker/DatePicker.d.ts +38 -3
- package/lib/typescript/commonjs/components/DateRangePicker/DateRangePicker.d.ts +36 -3
- package/lib/typescript/commonjs/components/Dialog/Dialog.d.ts +13 -1
- package/lib/typescript/commonjs/components/FieldBase/FieldBase.d.ts +172 -0
- package/lib/typescript/commonjs/components/FieldBase/index.d.ts +3 -0
- package/lib/typescript/commonjs/components/FloatingActionButton/FloatingActionButton.d.ts +8 -6
- package/lib/typescript/commonjs/components/FloatingActionButton/index.d.ts +1 -1
- package/lib/typescript/commonjs/components/ForceUpdateDialog/ForceUpdateDialog.d.ts +7 -0
- package/lib/typescript/commonjs/components/FormField/FormField.d.ts +7 -0
- package/lib/typescript/commonjs/components/ImageGallery/ImageGallery.d.ts +6 -4
- package/lib/typescript/commonjs/components/Input/Input.d.ts +7 -1
- package/lib/typescript/commonjs/components/ListItem/ListItem.d.ts +13 -6
- package/lib/typescript/commonjs/components/NumberInput/NumberInput.d.ts +3 -0
- package/lib/typescript/commonjs/components/PickerTrigger/PickerTrigger.d.ts +57 -0
- package/lib/typescript/commonjs/components/PickerTrigger/index.d.ts +3 -0
- package/lib/typescript/commonjs/components/ProgressBar/ProgressBar.d.ts +2 -0
- package/lib/typescript/commonjs/components/Radio/Radio.d.ts +3 -0
- package/lib/typescript/commonjs/components/Rating/Rating.d.ts +9 -6
- package/lib/typescript/commonjs/components/SegmentedControl/SegmentedControl.d.ts +3 -0
- package/lib/typescript/commonjs/components/Skeleton/Skeleton.d.ts +49 -20
- package/lib/typescript/commonjs/components/Skeleton/SkeletonClock.d.ts +60 -0
- package/lib/typescript/commonjs/components/Skeleton/SkeletonContent.d.ts +80 -19
- package/lib/typescript/commonjs/components/Skeleton/SkeletonProvider.d.ts +39 -5
- package/lib/typescript/commonjs/components/Skeleton/index.d.ts +6 -4
- package/lib/typescript/commonjs/components/Slider/Slider.d.ts +12 -1
- package/lib/typescript/commonjs/components/Stepper/Stepper.d.ts +18 -6
- package/lib/typescript/commonjs/components/Swipeable/Swipeable.d.ts +2 -0
- package/lib/typescript/commonjs/components/Switch/Switch.d.ts +1 -0
- package/lib/typescript/commonjs/components/Tabs/Tabs.d.ts +26 -2
- package/lib/typescript/commonjs/components/TimePicker/TimePicker.d.ts +36 -3
- package/lib/typescript/commonjs/components/Toast/Toast.d.ts +8 -0
- package/lib/typescript/commonjs/components/Tooltip/Tooltip.d.ts +7 -1
- package/lib/typescript/commonjs/components/index.d.ts +5 -5
- package/lib/typescript/commonjs/index.d.ts +1 -1
- package/lib/typescript/commonjs/theme/index.d.ts +1 -1
- package/lib/typescript/commonjs/theme/types.d.ts +578 -12
- package/lib/typescript/module/components/Accordion/Accordion.d.ts +10 -5
- package/lib/typescript/module/components/AppBar/AppBar.d.ts +8 -0
- package/lib/typescript/module/components/Avatar/Avatar.d.ts +12 -6
- package/lib/typescript/module/components/Badge/Badge.d.ts +7 -6
- package/lib/typescript/module/components/Banner/Banner.d.ts +17 -6
- package/lib/typescript/module/components/BottomSheet/BottomSheet.d.ts +7 -0
- package/lib/typescript/module/components/Card/Card.d.ts +17 -6
- package/lib/typescript/module/components/Carousel/Carousel.d.ts +7 -6
- package/lib/typescript/module/components/Checkbox/Checkbox.d.ts +9 -1
- package/lib/typescript/module/components/Chip/Chip.d.ts +13 -6
- package/lib/typescript/module/components/DatePicker/DatePicker.d.ts +38 -3
- package/lib/typescript/module/components/DateRangePicker/DateRangePicker.d.ts +36 -3
- package/lib/typescript/module/components/Dialog/Dialog.d.ts +13 -1
- package/lib/typescript/module/components/FieldBase/FieldBase.d.ts +172 -0
- package/lib/typescript/module/components/FieldBase/index.d.ts +3 -0
- package/lib/typescript/module/components/FloatingActionButton/FloatingActionButton.d.ts +8 -6
- package/lib/typescript/module/components/FloatingActionButton/index.d.ts +1 -1
- package/lib/typescript/module/components/ForceUpdateDialog/ForceUpdateDialog.d.ts +7 -0
- package/lib/typescript/module/components/FormField/FormField.d.ts +7 -0
- package/lib/typescript/module/components/ImageGallery/ImageGallery.d.ts +6 -4
- package/lib/typescript/module/components/Input/Input.d.ts +7 -1
- package/lib/typescript/module/components/ListItem/ListItem.d.ts +13 -6
- package/lib/typescript/module/components/NumberInput/NumberInput.d.ts +3 -0
- package/lib/typescript/module/components/PickerTrigger/PickerTrigger.d.ts +57 -0
- package/lib/typescript/module/components/PickerTrigger/index.d.ts +3 -0
- package/lib/typescript/module/components/ProgressBar/ProgressBar.d.ts +2 -0
- package/lib/typescript/module/components/Radio/Radio.d.ts +3 -0
- package/lib/typescript/module/components/Rating/Rating.d.ts +9 -6
- package/lib/typescript/module/components/SegmentedControl/SegmentedControl.d.ts +3 -0
- package/lib/typescript/module/components/Skeleton/Skeleton.d.ts +49 -20
- package/lib/typescript/module/components/Skeleton/SkeletonClock.d.ts +60 -0
- package/lib/typescript/module/components/Skeleton/SkeletonContent.d.ts +80 -19
- package/lib/typescript/module/components/Skeleton/SkeletonProvider.d.ts +39 -5
- package/lib/typescript/module/components/Skeleton/index.d.ts +6 -4
- package/lib/typescript/module/components/Slider/Slider.d.ts +12 -1
- package/lib/typescript/module/components/Stepper/Stepper.d.ts +18 -6
- package/lib/typescript/module/components/Swipeable/Swipeable.d.ts +2 -0
- package/lib/typescript/module/components/Switch/Switch.d.ts +1 -0
- package/lib/typescript/module/components/Tabs/Tabs.d.ts +26 -2
- package/lib/typescript/module/components/TimePicker/TimePicker.d.ts +36 -3
- package/lib/typescript/module/components/Toast/Toast.d.ts +8 -0
- package/lib/typescript/module/components/Tooltip/Tooltip.d.ts +7 -1
- package/lib/typescript/module/components/index.d.ts +5 -5
- package/lib/typescript/module/index.d.ts +1 -1
- package/lib/typescript/module/theme/index.d.ts +1 -1
- package/lib/typescript/module/theme/types.d.ts +578 -12
- package/package.json +2 -6
- package/lib/commonjs/components/AppIcon/AppIcon.js +0 -120
- package/lib/commonjs/types/vector-icons.d.js +0 -2
- package/lib/module/components/AppIcon/AppIcon.js +0 -111
- package/lib/module/components/AppIcon/index.js +0 -4
- package/lib/module/types/vector-icons.d.js +0 -2
- package/lib/typescript/commonjs/components/AppIcon/AppIcon.d.ts +0 -20
- package/lib/typescript/commonjs/components/AppIcon/index.d.ts +0 -3
- package/lib/typescript/module/components/AppIcon/AppIcon.d.ts +0 -20
- package/lib/typescript/module/components/AppIcon/index.d.ts +0 -3
|
@@ -1,22 +1,57 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Skeleton — the leaf placeholder primitive.
|
|
5
|
+
*
|
|
6
|
+
* Every Skeleton on screen reads the shared shimmer/pulse clock from
|
|
7
|
+
* `SkeletonProvider` (see SkeletonClock.tsx). One native-driver loop per
|
|
8
|
+
* provider drives every instance, so 50 placeholders on a list don't spawn
|
|
9
|
+
* 50 timers and the shimmer bands never drift out of phase.
|
|
10
|
+
*
|
|
11
|
+
* Visual:
|
|
12
|
+
* - A View with the base color and `overflow: hidden` + radius gives the
|
|
13
|
+
* placeholder its shape.
|
|
14
|
+
* - For `animation: 'shimmer'`, an Animated.View carrying a 3-stop
|
|
15
|
+
* `LinearGradient` (transparent → highlight → transparent) translates
|
|
16
|
+
* across the box. The radius clips it to the right outline automatically.
|
|
17
|
+
* - For `animation: 'pulse'`, a full-fill Animated.View fades its opacity
|
|
18
|
+
* between 0 and 0.6. Cheap and useful for tiny shapes where a sweep
|
|
19
|
+
* would barely be visible.
|
|
20
|
+
* - For `animation: 'none'` (or when the OS Reduce Motion preference is
|
|
21
|
+
* on), just the base color renders.
|
|
22
|
+
*
|
|
23
|
+
* `variant` describes the SHAPE: rect (default), rounded (theme.radius.md),
|
|
24
|
+
* circle (50%), or text (small radius, slightly inset height). Set width /
|
|
25
|
+
* height directly for full control.
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
import React, { useMemo, useState } from 'react';
|
|
29
|
+
import { Animated, StyleSheet, View } from 'react-native';
|
|
30
|
+
import { useTheme } from "../../theme/index.js";
|
|
31
|
+
|
|
32
|
+
// `react-native-linear-gradient` is an OPTIONAL peer dep. When it's installed
|
|
33
|
+
// we sweep a real gradient band across the shimmer. When it isn't, we fall
|
|
34
|
+
// back to a solid-color band — still works, just less polished. This keeps
|
|
35
|
+
// the library deployable in apps that don't need gradients elsewhere.
|
|
36
|
+
let LinearGradientImpl = null;
|
|
37
|
+
try {
|
|
38
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
39
|
+
LinearGradientImpl = require('react-native-linear-gradient').default;
|
|
40
|
+
} catch {
|
|
41
|
+
// Optional peer; resolved lazily by consumers that need shimmer polish.
|
|
42
|
+
}
|
|
6
43
|
import { Responsive } from "../../utils/index.js";
|
|
44
|
+
import { useSkeletonClock } from "./SkeletonClock.js";
|
|
7
45
|
import { useSkeletonDefaults } from "./SkeletonProvider.js";
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
md: 48,
|
|
18
|
-
lg: 64
|
|
19
|
-
};
|
|
46
|
+
|
|
47
|
+
/** Animation pattern. */
|
|
48
|
+
|
|
49
|
+
/** Sweep speed for the shimmer band. Ignored for pulse / none. */
|
|
50
|
+
|
|
51
|
+
/** Pre-defined shape archetype. Plays nicely with `width`/`height` overrides. */
|
|
52
|
+
|
|
53
|
+
/** `theme.radius` token name or a literal pixel value. */
|
|
54
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
20
55
|
const resolveRadius = (theme, radius) => {
|
|
21
56
|
if (typeof radius === 'number') return radius;
|
|
22
57
|
return theme.radius[radius];
|
|
@@ -26,92 +61,128 @@ const resolveWidth = width => {
|
|
|
26
61
|
if (typeof width === 'number') return width;
|
|
27
62
|
return width;
|
|
28
63
|
};
|
|
64
|
+
const radiusForShape = (theme, shape, width, height, explicit) => {
|
|
65
|
+
if (explicit !== undefined) return resolveRadius(theme, explicit);
|
|
66
|
+
switch (shape) {
|
|
67
|
+
case 'circle':
|
|
68
|
+
// Half the smallest known dimension. If width is a percentage we can't
|
|
69
|
+
// resolve here — fall back to height/2 which is the typical caller
|
|
70
|
+
// intent (square avatars).
|
|
71
|
+
return Math.floor(typeof width === 'number' ? Math.min(width, height) / 2 : height / 2);
|
|
72
|
+
case 'rounded':
|
|
73
|
+
return theme.radius.md;
|
|
74
|
+
case 'text':
|
|
75
|
+
return theme.radius.sm;
|
|
76
|
+
case 'rect':
|
|
77
|
+
default:
|
|
78
|
+
return theme.radius.sm;
|
|
79
|
+
}
|
|
80
|
+
};
|
|
29
81
|
const Skeleton = ({
|
|
82
|
+
shape = 'rect',
|
|
30
83
|
width = '100%',
|
|
31
84
|
height = 16,
|
|
32
85
|
radius,
|
|
33
86
|
variant,
|
|
34
|
-
speed,
|
|
87
|
+
speed: _speedProp,
|
|
35
88
|
colors,
|
|
36
89
|
style,
|
|
37
90
|
testID
|
|
38
91
|
}) => {
|
|
39
92
|
const theme = useTheme();
|
|
40
93
|
const defaults = useSkeletonDefaults();
|
|
94
|
+
const clock = useSkeletonClock();
|
|
41
95
|
const resolvedVariant = variant ?? defaults.variant ?? 'shimmer';
|
|
42
|
-
const
|
|
43
|
-
const resolvedRadiusToken = radius ?? defaults.radius ?? 'sm';
|
|
96
|
+
const effectiveVariant = clock.enabled ? resolvedVariant : 'none';
|
|
44
97
|
const backgroundColor = colors?.background ?? defaults.colors?.background ?? theme.colors.skeleton.background;
|
|
45
98
|
const highlightColor = colors?.highlight ?? defaults.colors?.highlight ?? theme.colors.skeleton.highlight;
|
|
46
|
-
const styles = useMemo(() => buildStyles(
|
|
47
|
-
const borderRadius = resolveRadius(theme, resolvedRadiusToken);
|
|
99
|
+
const styles = useMemo(() => buildStyles(), []);
|
|
48
100
|
const resolvedWidth = resolveWidth(width);
|
|
49
101
|
const resolvedHeight = Responsive.size(height);
|
|
50
|
-
const
|
|
102
|
+
const borderRadius = radiusForShape(theme, shape, resolvedWidth, resolvedHeight, radius);
|
|
51
103
|
const [containerWidth, setContainerWidth] = useState(0);
|
|
52
|
-
useEffect(() => {
|
|
53
|
-
setNativeValue(progress, 0);
|
|
54
|
-
const duration = resolvedVariant === 'pulse' ? PULSE_DURATION : SPEED_DURATION[resolvedSpeed];
|
|
55
|
-
const animation = resolvedVariant === 'pulse' ? Animated.loop(Animated.sequence([Animated.timing(progress, {
|
|
56
|
-
toValue: 1,
|
|
57
|
-
duration: duration / 2,
|
|
58
|
-
easing: Easing.inOut(Easing.ease),
|
|
59
|
-
useNativeDriver: true
|
|
60
|
-
}), Animated.timing(progress, {
|
|
61
|
-
toValue: 0,
|
|
62
|
-
duration: duration / 2,
|
|
63
|
-
easing: Easing.inOut(Easing.ease),
|
|
64
|
-
useNativeDriver: true
|
|
65
|
-
})])) : Animated.loop(Animated.timing(progress, {
|
|
66
|
-
toValue: 1,
|
|
67
|
-
duration,
|
|
68
|
-
easing: Easing.linear,
|
|
69
|
-
useNativeDriver: true
|
|
70
|
-
}));
|
|
71
|
-
animation.start();
|
|
72
|
-
return () => {
|
|
73
|
-
animation.stop();
|
|
74
|
-
};
|
|
75
|
-
}, [progress, resolvedSpeed, resolvedVariant]);
|
|
76
104
|
const handleLayout = event => {
|
|
77
105
|
const next = event.nativeEvent.layout.width;
|
|
78
106
|
if (next !== containerWidth) setContainerWidth(next);
|
|
79
107
|
};
|
|
108
|
+
|
|
109
|
+
// The shimmer band is wider than the box so the gradient feathers off the
|
|
110
|
+
// edges instead of popping at them. Width = 70% of container, capped to a
|
|
111
|
+
// sensible minimum so tiny placeholders still get a visible sweep.
|
|
112
|
+
const bandWidth = useMemo(() => {
|
|
113
|
+
if (containerWidth <= 0) return 0;
|
|
114
|
+
return Math.max(48, containerWidth * 0.7);
|
|
115
|
+
}, [containerWidth]);
|
|
116
|
+
|
|
117
|
+
// Interpolate the shared 0→1 clock into translateX. The band starts fully
|
|
118
|
+
// off the left edge and ends fully off the right edge, so each loop sweeps
|
|
119
|
+
// the full width regardless of how wide the placeholder is.
|
|
120
|
+
const translateX = useMemo(() => {
|
|
121
|
+
if (containerWidth <= 0) return 0;
|
|
122
|
+
return clock.shimmer.interpolate({
|
|
123
|
+
inputRange: [0, 1],
|
|
124
|
+
outputRange: [-bandWidth, containerWidth]
|
|
125
|
+
});
|
|
126
|
+
}, [clock.shimmer, bandWidth, containerWidth]);
|
|
80
127
|
const overlay = useMemo(() => {
|
|
81
|
-
if (
|
|
128
|
+
if (effectiveVariant === 'none') return null;
|
|
129
|
+
if (effectiveVariant === 'pulse') {
|
|
130
|
+
// Pulse fades a full-fill highlight overlay in and out. Cheaper than
|
|
131
|
+
// shimmer and visible at any size.
|
|
82
132
|
return /*#__PURE__*/_jsx(Animated.View, {
|
|
83
133
|
pointerEvents: "none",
|
|
84
134
|
style: [StyleSheet.absoluteFillObject, {
|
|
85
135
|
backgroundColor: highlightColor,
|
|
86
|
-
opacity:
|
|
136
|
+
opacity: clock.pulse.interpolate({
|
|
87
137
|
inputRange: [0, 1],
|
|
88
|
-
outputRange: [0, 0.
|
|
138
|
+
outputRange: [0, 0.55]
|
|
89
139
|
})
|
|
90
140
|
}]
|
|
91
141
|
});
|
|
92
142
|
}
|
|
93
143
|
if (containerWidth <= 0) return null;
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
144
|
+
|
|
145
|
+
// 3-stop gradient: transparent → highlight → transparent. Feathered
|
|
146
|
+
// edges feel premium; a solid band looks like a bug. When the optional
|
|
147
|
+
// gradient package isn't installed we render the band as a solid
|
|
148
|
+
// highlight rectangle — visibly different but still recognizably a
|
|
149
|
+
// shimmer effect.
|
|
99
150
|
return /*#__PURE__*/_jsx(Animated.View, {
|
|
100
151
|
pointerEvents: "none",
|
|
101
|
-
style: [styles.
|
|
102
|
-
width:
|
|
103
|
-
backgroundColor: highlightColor,
|
|
152
|
+
style: [styles.shimmerBand, {
|
|
153
|
+
width: bandWidth,
|
|
104
154
|
transform: [{
|
|
105
155
|
translateX
|
|
106
156
|
}]
|
|
107
|
-
}]
|
|
157
|
+
}],
|
|
158
|
+
children: LinearGradientImpl ? /*#__PURE__*/_jsx(LinearGradientImpl, {
|
|
159
|
+
colors: ['transparent', highlightColor, 'transparent'],
|
|
160
|
+
locations: [0, 0.5, 1],
|
|
161
|
+
start: {
|
|
162
|
+
x: 0,
|
|
163
|
+
y: 0.5
|
|
164
|
+
},
|
|
165
|
+
end: {
|
|
166
|
+
x: 1,
|
|
167
|
+
y: 0.5
|
|
168
|
+
},
|
|
169
|
+
style: StyleSheet.absoluteFillObject
|
|
170
|
+
}) : /*#__PURE__*/_jsx(View, {
|
|
171
|
+
style: [StyleSheet.absoluteFillObject, {
|
|
172
|
+
backgroundColor: highlightColor,
|
|
173
|
+
opacity: 0.55
|
|
174
|
+
}]
|
|
175
|
+
})
|
|
108
176
|
});
|
|
109
|
-
}, [
|
|
177
|
+
}, [effectiveVariant, highlightColor, clock.pulse, containerWidth, styles.shimmerBand, bandWidth, translateX]);
|
|
110
178
|
return /*#__PURE__*/_jsx(View, {
|
|
111
179
|
onLayout: handleLayout,
|
|
112
180
|
accessible: true,
|
|
113
181
|
accessibilityLabel: "Loading",
|
|
114
182
|
accessibilityRole: "progressbar",
|
|
183
|
+
accessibilityState: {
|
|
184
|
+
busy: true
|
|
185
|
+
},
|
|
115
186
|
accessibilityLiveRegion: "polite",
|
|
116
187
|
testID: testID,
|
|
117
188
|
style: [styles.base, {
|
|
@@ -132,9 +203,9 @@ const SkeletonCircle = ({
|
|
|
132
203
|
const diameter = Responsive.size(size);
|
|
133
204
|
return /*#__PURE__*/_jsx(Skeleton, {
|
|
134
205
|
...rest,
|
|
206
|
+
shape: "circle",
|
|
135
207
|
width: diameter,
|
|
136
208
|
height: size,
|
|
137
|
-
radius: "full",
|
|
138
209
|
style: [{
|
|
139
210
|
width: diameter,
|
|
140
211
|
height: diameter,
|
|
@@ -168,6 +239,7 @@ const SkeletonText = ({
|
|
|
168
239
|
const isLast = index === safeLines - 1;
|
|
169
240
|
const lineWidth = isLast && safeLines > 1 ? lastLineWidth : width;
|
|
170
241
|
return /*#__PURE__*/_jsx(Skeleton, {
|
|
242
|
+
shape: "text",
|
|
171
243
|
width: lineWidth,
|
|
172
244
|
height: lineHeight,
|
|
173
245
|
radius: radius,
|
|
@@ -181,129 +253,17 @@ const SkeletonText = ({
|
|
|
181
253
|
});
|
|
182
254
|
};
|
|
183
255
|
SkeletonText.displayName = 'SkeletonText';
|
|
184
|
-
const
|
|
185
|
-
size = 'md',
|
|
186
|
-
...rest
|
|
187
|
-
}) => {
|
|
188
|
-
return /*#__PURE__*/_jsx(SkeletonCircle, {
|
|
189
|
-
...rest,
|
|
190
|
-
size: AVATAR_SIZE[size]
|
|
191
|
-
});
|
|
192
|
-
};
|
|
193
|
-
SkeletonAvatar.displayName = 'SkeletonAvatar';
|
|
194
|
-
const SkeletonCard = ({
|
|
195
|
-
variant,
|
|
196
|
-
speed,
|
|
197
|
-
radius = 'md',
|
|
198
|
-
style,
|
|
199
|
-
testID
|
|
200
|
-
}) => {
|
|
201
|
-
const theme = useTheme();
|
|
202
|
-
return /*#__PURE__*/_jsxs(View, {
|
|
203
|
-
style: [{
|
|
204
|
-
padding: theme.spacing.md
|
|
205
|
-
}, style],
|
|
206
|
-
testID: testID,
|
|
207
|
-
children: [/*#__PURE__*/_jsxs(View, {
|
|
208
|
-
style: {
|
|
209
|
-
flexDirection: 'row',
|
|
210
|
-
alignItems: 'center',
|
|
211
|
-
marginBottom: theme.spacing.md
|
|
212
|
-
},
|
|
213
|
-
children: [/*#__PURE__*/_jsx(SkeletonAvatar, {
|
|
214
|
-
size: "md",
|
|
215
|
-
variant: variant,
|
|
216
|
-
speed: speed
|
|
217
|
-
}), /*#__PURE__*/_jsxs(View, {
|
|
218
|
-
style: {
|
|
219
|
-
flex: 1,
|
|
220
|
-
marginLeft: theme.spacing.sm
|
|
221
|
-
},
|
|
222
|
-
children: [/*#__PURE__*/_jsx(Skeleton, {
|
|
223
|
-
width: "60%",
|
|
224
|
-
height: 14,
|
|
225
|
-
radius: radius,
|
|
226
|
-
variant: variant,
|
|
227
|
-
speed: speed,
|
|
228
|
-
style: {
|
|
229
|
-
marginBottom: theme.spacing.xs
|
|
230
|
-
}
|
|
231
|
-
}), /*#__PURE__*/_jsx(Skeleton, {
|
|
232
|
-
width: "40%",
|
|
233
|
-
height: 12,
|
|
234
|
-
radius: radius,
|
|
235
|
-
variant: variant,
|
|
236
|
-
speed: speed
|
|
237
|
-
})]
|
|
238
|
-
})]
|
|
239
|
-
}), /*#__PURE__*/_jsx(SkeletonText, {
|
|
240
|
-
lines: 2,
|
|
241
|
-
fontSize: 14,
|
|
242
|
-
variant: variant,
|
|
243
|
-
speed: speed,
|
|
244
|
-
radius: radius
|
|
245
|
-
})]
|
|
246
|
-
});
|
|
247
|
-
};
|
|
248
|
-
SkeletonCard.displayName = 'SkeletonCard';
|
|
249
|
-
const SkeletonListItem = ({
|
|
250
|
-
avatarSize = 'md',
|
|
251
|
-
variant,
|
|
252
|
-
speed,
|
|
253
|
-
radius = 'sm',
|
|
254
|
-
style,
|
|
255
|
-
testID
|
|
256
|
-
}) => {
|
|
257
|
-
const theme = useTheme();
|
|
258
|
-
return /*#__PURE__*/_jsxs(View, {
|
|
259
|
-
style: [{
|
|
260
|
-
flexDirection: 'row',
|
|
261
|
-
alignItems: 'center',
|
|
262
|
-
paddingHorizontal: theme.spacing.md,
|
|
263
|
-
paddingVertical: theme.spacing.sm
|
|
264
|
-
}, style],
|
|
265
|
-
testID: testID,
|
|
266
|
-
children: [/*#__PURE__*/_jsx(SkeletonAvatar, {
|
|
267
|
-
size: avatarSize,
|
|
268
|
-
variant: variant,
|
|
269
|
-
speed: speed
|
|
270
|
-
}), /*#__PURE__*/_jsxs(View, {
|
|
271
|
-
style: {
|
|
272
|
-
flex: 1,
|
|
273
|
-
marginLeft: theme.spacing.sm
|
|
274
|
-
},
|
|
275
|
-
children: [/*#__PURE__*/_jsx(Skeleton, {
|
|
276
|
-
width: "70%",
|
|
277
|
-
height: 14,
|
|
278
|
-
radius: radius,
|
|
279
|
-
variant: variant,
|
|
280
|
-
speed: speed,
|
|
281
|
-
style: {
|
|
282
|
-
marginBottom: theme.spacing.xs
|
|
283
|
-
}
|
|
284
|
-
}), /*#__PURE__*/_jsx(Skeleton, {
|
|
285
|
-
width: "45%",
|
|
286
|
-
height: 12,
|
|
287
|
-
radius: radius,
|
|
288
|
-
variant: variant,
|
|
289
|
-
speed: speed
|
|
290
|
-
})]
|
|
291
|
-
})]
|
|
292
|
-
});
|
|
293
|
-
};
|
|
294
|
-
SkeletonListItem.displayName = 'SkeletonListItem';
|
|
295
|
-
const buildStyles = _theme => StyleSheet.create({
|
|
256
|
+
const buildStyles = () => StyleSheet.create({
|
|
296
257
|
base: {
|
|
297
258
|
overflow: 'hidden'
|
|
298
259
|
},
|
|
299
|
-
|
|
260
|
+
shimmerBand: {
|
|
300
261
|
position: 'absolute',
|
|
301
262
|
top: 0,
|
|
302
263
|
bottom: 0,
|
|
303
|
-
left: 0
|
|
304
|
-
opacity: 0.55
|
|
264
|
+
left: 0
|
|
305
265
|
}
|
|
306
266
|
});
|
|
307
|
-
export { Skeleton, SkeletonCircle, SkeletonText
|
|
267
|
+
export { Skeleton, SkeletonCircle, SkeletonText };
|
|
308
268
|
export default Skeleton;
|
|
309
269
|
//# sourceMappingURL=Skeleton.js.map
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* SkeletonClock — single shared animation tick for every <Skeleton> on screen.
|
|
5
|
+
*
|
|
6
|
+
* Why this exists: previously every Skeleton primitive ran its own
|
|
7
|
+
* `Animated.loop` on its own `Animated.Value`. A list of 20 placeholders =
|
|
8
|
+
* 20 independent native-driver timers, each starting at a slightly different
|
|
9
|
+
* mount frame, so their shimmer bands drift out of phase within ~1s and the
|
|
10
|
+
* surface feels noisy. CSS-driven web skeleton libs (react-loading-skeleton,
|
|
11
|
+
* MUI) avoid this because the browser owns a single timeline. We emulate
|
|
12
|
+
* that on RN by hoisting the loop into context.
|
|
13
|
+
*
|
|
14
|
+
* The clock produces a value in `[0, 1)` that wraps every `duration` ms. Each
|
|
15
|
+
* Skeleton interpolates that value into its own translateX / opacity output.
|
|
16
|
+
* One native-driver loop, no drift, ~zero JS cost.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import React, { createContext, useContext, useEffect, useMemo, useRef } from 'react';
|
|
20
|
+
import { Animated, Easing } from 'react-native';
|
|
21
|
+
import { createAnimatedValue } from "../../theme/index.js";
|
|
22
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
23
|
+
const SHIMMER_DURATION = {
|
|
24
|
+
slow: 1800,
|
|
25
|
+
normal: 1200,
|
|
26
|
+
fast: 800
|
|
27
|
+
};
|
|
28
|
+
const PULSE_DURATION = 1000;
|
|
29
|
+
const SkeletonClockContext = /*#__PURE__*/createContext(null);
|
|
30
|
+
/**
|
|
31
|
+
* Owns the loops. Mount one of these inside `SkeletonProvider`; every
|
|
32
|
+
* `<Skeleton>` below it shares the same animated values.
|
|
33
|
+
*/
|
|
34
|
+
export const SkeletonClockProvider = ({
|
|
35
|
+
speed,
|
|
36
|
+
enabled,
|
|
37
|
+
variant: _variant,
|
|
38
|
+
children
|
|
39
|
+
}) => {
|
|
40
|
+
const shimmer = useRef(createAnimatedValue(0)).current;
|
|
41
|
+
const pulse = useRef(createAnimatedValue(0)).current;
|
|
42
|
+
useEffect(() => {
|
|
43
|
+
if (!enabled) {
|
|
44
|
+
// Park the values at a deterministic "off" state so any consumer that
|
|
45
|
+
// happens to be reading them still gets a visible (static) skeleton.
|
|
46
|
+
shimmer.setValue(0);
|
|
47
|
+
pulse.setValue(0.5);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Both loops use the native driver — the JS thread doesn't tick for
|
|
52
|
+
// either. Both run continuously; consumers read whichever they need.
|
|
53
|
+
// The negligible cost of running the *other* loop is worth keeping
|
|
54
|
+
// variant switching instant (no remount, no loop teardown).
|
|
55
|
+
const shimmerLoop = Animated.loop(Animated.timing(shimmer, {
|
|
56
|
+
toValue: 1,
|
|
57
|
+
duration: SHIMMER_DURATION[speed],
|
|
58
|
+
easing: Easing.linear,
|
|
59
|
+
useNativeDriver: true
|
|
60
|
+
}));
|
|
61
|
+
const pulseLoop = Animated.loop(Animated.sequence([Animated.timing(pulse, {
|
|
62
|
+
toValue: 1,
|
|
63
|
+
duration: PULSE_DURATION / 2,
|
|
64
|
+
easing: Easing.inOut(Easing.ease),
|
|
65
|
+
useNativeDriver: true
|
|
66
|
+
}), Animated.timing(pulse, {
|
|
67
|
+
toValue: 0,
|
|
68
|
+
duration: PULSE_DURATION / 2,
|
|
69
|
+
easing: Easing.inOut(Easing.ease),
|
|
70
|
+
useNativeDriver: true
|
|
71
|
+
})]));
|
|
72
|
+
shimmerLoop.start();
|
|
73
|
+
pulseLoop.start();
|
|
74
|
+
return () => {
|
|
75
|
+
shimmerLoop.stop();
|
|
76
|
+
pulseLoop.stop();
|
|
77
|
+
};
|
|
78
|
+
// `variant` is intentionally NOT a dependency — both loops always run
|
|
79
|
+
// so switching variants is a single render with no loop teardown.
|
|
80
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
81
|
+
}, [speed, enabled]);
|
|
82
|
+
const value = useMemo(() => ({
|
|
83
|
+
shimmer,
|
|
84
|
+
pulse,
|
|
85
|
+
enabled
|
|
86
|
+
}), [shimmer, pulse, enabled]);
|
|
87
|
+
return /*#__PURE__*/_jsx(SkeletonClockContext.Provider, {
|
|
88
|
+
value: value,
|
|
89
|
+
children: children
|
|
90
|
+
});
|
|
91
|
+
};
|
|
92
|
+
SkeletonClockProvider.displayName = 'SkeletonClockProvider';
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Read the active clock. Returns a fallback "always-still" clock when no
|
|
96
|
+
* provider is mounted, so the primitives still render (statically) outside
|
|
97
|
+
* one — keeps demo/storybook usage friction-free.
|
|
98
|
+
*/
|
|
99
|
+
export const useSkeletonClock = () => {
|
|
100
|
+
const ctx = useContext(SkeletonClockContext);
|
|
101
|
+
if (ctx) return ctx;
|
|
102
|
+
// Fallback: a permanently-stopped clock. Created once at module scope.
|
|
103
|
+
return fallbackClock;
|
|
104
|
+
};
|
|
105
|
+
const fallbackClock = {
|
|
106
|
+
shimmer: createAnimatedValue(0),
|
|
107
|
+
pulse: createAnimatedValue(0.5),
|
|
108
|
+
enabled: false
|
|
109
|
+
};
|
|
110
|
+
//# sourceMappingURL=SkeletonClock.js.map
|