@webority-technologies/mobile 0.0.14 → 0.0.20

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.
Files changed (202) hide show
  1. package/lib/commonjs/components/Accordion/Accordion.js +60 -19
  2. package/lib/commonjs/components/AppBar/AppBar.js +29 -20
  3. package/lib/commonjs/components/Avatar/Avatar.js +38 -8
  4. package/lib/commonjs/components/Badge/Badge.js +66 -4
  5. package/lib/commonjs/components/Banner/Banner.js +146 -66
  6. package/lib/commonjs/components/BottomNavigation/BottomNavigation.js +37 -15
  7. package/lib/commonjs/components/BottomSheet/BottomSheet.js +85 -50
  8. package/lib/commonjs/components/Button/Button.js +12 -5
  9. package/lib/commonjs/components/Card/Card.js +106 -16
  10. package/lib/commonjs/components/Carousel/Carousel.js +66 -12
  11. package/lib/commonjs/components/Checkbox/Checkbox.js +11 -7
  12. package/lib/commonjs/components/Chip/Chip.js +44 -12
  13. package/lib/commonjs/components/DatePicker/DatePicker.js +185 -76
  14. package/lib/commonjs/components/DateRangePicker/DateRangePicker.js +133 -59
  15. package/lib/commonjs/components/Dialog/Dialog.js +16 -10
  16. package/lib/commonjs/components/Drawer/Drawer.js +13 -10
  17. package/lib/commonjs/components/FieldBase/FieldBase.js +306 -0
  18. package/lib/commonjs/components/FieldBase/index.js +32 -0
  19. package/lib/commonjs/components/FloatingActionButton/FloatingActionButton.js +69 -44
  20. package/lib/commonjs/components/ForceUpdateDialog/ForceUpdateDialog.js +8 -2
  21. package/lib/commonjs/components/FormField/FormField.js +3 -2
  22. package/lib/commonjs/components/ImageGallery/ImageGallery.js +132 -44
  23. package/lib/commonjs/components/Input/Input.js +144 -181
  24. package/lib/commonjs/components/ListItem/ListItem.js +90 -11
  25. package/lib/commonjs/components/Modal/Modal.js +55 -27
  26. package/lib/commonjs/components/NumberInput/NumberInput.js +60 -106
  27. package/lib/commonjs/components/OTPInput/OTPInput.js +65 -58
  28. package/lib/commonjs/components/PickerTrigger/PickerTrigger.js +185 -0
  29. package/lib/commonjs/components/{AppIcon → PickerTrigger}/index.js +4 -4
  30. package/lib/commonjs/components/ProgressBar/ProgressBar.js +19 -11
  31. package/lib/commonjs/components/Radio/Radio.js +11 -6
  32. package/lib/commonjs/components/Rating/Rating.js +85 -19
  33. package/lib/commonjs/components/SearchBar/SearchBar.js +84 -107
  34. package/lib/commonjs/components/SegmentedControl/SegmentedControl.js +22 -11
  35. package/lib/commonjs/components/Select/Select.js +62 -91
  36. package/lib/commonjs/components/Skeleton/Skeleton.js +131 -174
  37. package/lib/commonjs/components/Skeleton/SkeletonClock.js +117 -0
  38. package/lib/commonjs/components/Skeleton/SkeletonContent.js +164 -81
  39. package/lib/commonjs/components/Skeleton/SkeletonProvider.js +72 -10
  40. package/lib/commonjs/components/Skeleton/index.js +17 -16
  41. package/lib/commonjs/components/Slider/Slider.js +44 -25
  42. package/lib/commonjs/components/Stepper/Stepper.js +199 -29
  43. package/lib/commonjs/components/Swipeable/Swipeable.js +36 -19
  44. package/lib/commonjs/components/Switch/Switch.js +9 -2
  45. package/lib/commonjs/components/Tabs/Tabs.js +84 -21
  46. package/lib/commonjs/components/TimePicker/TimePicker.js +123 -45
  47. package/lib/commonjs/components/Toast/Toast.js +27 -16
  48. package/lib/commonjs/components/Tooltip/Tooltip.js +56 -32
  49. package/lib/commonjs/components/index.js +37 -37
  50. package/lib/commonjs/theme/tokens.js +55 -7
  51. package/lib/module/components/Accordion/Accordion.js +61 -20
  52. package/lib/module/components/AppBar/AppBar.js +29 -20
  53. package/lib/module/components/Avatar/Avatar.js +39 -9
  54. package/lib/module/components/Badge/Badge.js +67 -5
  55. package/lib/module/components/Banner/Banner.js +147 -67
  56. package/lib/module/components/BottomNavigation/BottomNavigation.js +37 -15
  57. package/lib/module/components/BottomSheet/BottomSheet.js +87 -52
  58. package/lib/module/components/Button/Button.js +12 -5
  59. package/lib/module/components/Card/Card.js +107 -17
  60. package/lib/module/components/Carousel/Carousel.js +67 -13
  61. package/lib/module/components/Checkbox/Checkbox.js +11 -7
  62. package/lib/module/components/Chip/Chip.js +45 -13
  63. package/lib/module/components/DatePicker/DatePicker.js +185 -76
  64. package/lib/module/components/DateRangePicker/DateRangePicker.js +134 -60
  65. package/lib/module/components/Dialog/Dialog.js +16 -10
  66. package/lib/module/components/Drawer/Drawer.js +13 -10
  67. package/lib/module/components/FieldBase/FieldBase.js +297 -0
  68. package/lib/module/components/FieldBase/index.js +4 -0
  69. package/lib/module/components/FloatingActionButton/FloatingActionButton.js +69 -44
  70. package/lib/module/components/ForceUpdateDialog/ForceUpdateDialog.js +8 -2
  71. package/lib/module/components/FormField/FormField.js +3 -2
  72. package/lib/module/components/ImageGallery/ImageGallery.js +128 -40
  73. package/lib/module/components/Input/Input.js +144 -179
  74. package/lib/module/components/ListItem/ListItem.js +91 -12
  75. package/lib/module/components/Modal/Modal.js +55 -27
  76. package/lib/module/components/NumberInput/NumberInput.js +60 -106
  77. package/lib/module/components/OTPInput/OTPInput.js +65 -58
  78. package/lib/module/components/PickerTrigger/PickerTrigger.js +181 -0
  79. package/lib/module/components/PickerTrigger/index.js +4 -0
  80. package/lib/module/components/ProgressBar/ProgressBar.js +19 -11
  81. package/lib/module/components/Radio/Radio.js +11 -6
  82. package/lib/module/components/Rating/Rating.js +86 -20
  83. package/lib/module/components/SearchBar/SearchBar.js +84 -107
  84. package/lib/module/components/SegmentedControl/SegmentedControl.js +22 -11
  85. package/lib/module/components/Select/Select.js +62 -91
  86. package/lib/module/components/Skeleton/Skeleton.js +135 -175
  87. package/lib/module/components/Skeleton/SkeletonClock.js +110 -0
  88. package/lib/module/components/Skeleton/SkeletonContent.js +167 -84
  89. package/lib/module/components/Skeleton/SkeletonProvider.js +71 -10
  90. package/lib/module/components/Skeleton/index.js +3 -2
  91. package/lib/module/components/Slider/Slider.js +44 -25
  92. package/lib/module/components/Stepper/Stepper.js +201 -31
  93. package/lib/module/components/Swipeable/Swipeable.js +36 -19
  94. package/lib/module/components/Switch/Switch.js +9 -2
  95. package/lib/module/components/Tabs/Tabs.js +84 -21
  96. package/lib/module/components/TimePicker/TimePicker.js +123 -45
  97. package/lib/module/components/Toast/Toast.js +27 -16
  98. package/lib/module/components/Tooltip/Tooltip.js +56 -32
  99. package/lib/module/components/index.js +2 -2
  100. package/lib/module/theme/tokens.js +55 -7
  101. package/lib/typescript/commonjs/components/Accordion/Accordion.d.ts +10 -5
  102. package/lib/typescript/commonjs/components/AppBar/AppBar.d.ts +8 -0
  103. package/lib/typescript/commonjs/components/Avatar/Avatar.d.ts +12 -6
  104. package/lib/typescript/commonjs/components/Badge/Badge.d.ts +7 -6
  105. package/lib/typescript/commonjs/components/Banner/Banner.d.ts +17 -6
  106. package/lib/typescript/commonjs/components/BottomSheet/BottomSheet.d.ts +7 -0
  107. package/lib/typescript/commonjs/components/Card/Card.d.ts +17 -6
  108. package/lib/typescript/commonjs/components/Carousel/Carousel.d.ts +7 -6
  109. package/lib/typescript/commonjs/components/Checkbox/Checkbox.d.ts +9 -1
  110. package/lib/typescript/commonjs/components/Chip/Chip.d.ts +13 -6
  111. package/lib/typescript/commonjs/components/DatePicker/DatePicker.d.ts +38 -3
  112. package/lib/typescript/commonjs/components/DateRangePicker/DateRangePicker.d.ts +36 -3
  113. package/lib/typescript/commonjs/components/Dialog/Dialog.d.ts +13 -1
  114. package/lib/typescript/commonjs/components/FieldBase/FieldBase.d.ts +141 -0
  115. package/lib/typescript/commonjs/components/FieldBase/index.d.ts +3 -0
  116. package/lib/typescript/commonjs/components/FloatingActionButton/FloatingActionButton.d.ts +8 -6
  117. package/lib/typescript/commonjs/components/FloatingActionButton/index.d.ts +1 -1
  118. package/lib/typescript/commonjs/components/ForceUpdateDialog/ForceUpdateDialog.d.ts +7 -0
  119. package/lib/typescript/commonjs/components/FormField/FormField.d.ts +7 -0
  120. package/lib/typescript/commonjs/components/ImageGallery/ImageGallery.d.ts +6 -4
  121. package/lib/typescript/commonjs/components/Input/Input.d.ts +6 -0
  122. package/lib/typescript/commonjs/components/ListItem/ListItem.d.ts +13 -6
  123. package/lib/typescript/commonjs/components/NumberInput/NumberInput.d.ts +3 -0
  124. package/lib/typescript/commonjs/components/PickerTrigger/PickerTrigger.d.ts +57 -0
  125. package/lib/typescript/commonjs/components/PickerTrigger/index.d.ts +3 -0
  126. package/lib/typescript/commonjs/components/ProgressBar/ProgressBar.d.ts +2 -0
  127. package/lib/typescript/commonjs/components/Radio/Radio.d.ts +3 -0
  128. package/lib/typescript/commonjs/components/Rating/Rating.d.ts +9 -6
  129. package/lib/typescript/commonjs/components/SegmentedControl/SegmentedControl.d.ts +3 -0
  130. package/lib/typescript/commonjs/components/Skeleton/Skeleton.d.ts +49 -20
  131. package/lib/typescript/commonjs/components/Skeleton/SkeletonClock.d.ts +60 -0
  132. package/lib/typescript/commonjs/components/Skeleton/SkeletonContent.d.ts +80 -19
  133. package/lib/typescript/commonjs/components/Skeleton/SkeletonProvider.d.ts +39 -5
  134. package/lib/typescript/commonjs/components/Skeleton/index.d.ts +6 -4
  135. package/lib/typescript/commonjs/components/Slider/Slider.d.ts +12 -1
  136. package/lib/typescript/commonjs/components/Stepper/Stepper.d.ts +18 -6
  137. package/lib/typescript/commonjs/components/Swipeable/Swipeable.d.ts +2 -0
  138. package/lib/typescript/commonjs/components/Switch/Switch.d.ts +1 -0
  139. package/lib/typescript/commonjs/components/Tabs/Tabs.d.ts +26 -2
  140. package/lib/typescript/commonjs/components/TimePicker/TimePicker.d.ts +36 -3
  141. package/lib/typescript/commonjs/components/Toast/Toast.d.ts +8 -0
  142. package/lib/typescript/commonjs/components/Tooltip/Tooltip.d.ts +7 -1
  143. package/lib/typescript/commonjs/components/index.d.ts +5 -5
  144. package/lib/typescript/commonjs/index.d.ts +1 -1
  145. package/lib/typescript/commonjs/theme/index.d.ts +1 -1
  146. package/lib/typescript/commonjs/theme/types.d.ts +553 -11
  147. package/lib/typescript/module/components/Accordion/Accordion.d.ts +10 -5
  148. package/lib/typescript/module/components/AppBar/AppBar.d.ts +8 -0
  149. package/lib/typescript/module/components/Avatar/Avatar.d.ts +12 -6
  150. package/lib/typescript/module/components/Badge/Badge.d.ts +7 -6
  151. package/lib/typescript/module/components/Banner/Banner.d.ts +17 -6
  152. package/lib/typescript/module/components/BottomSheet/BottomSheet.d.ts +7 -0
  153. package/lib/typescript/module/components/Card/Card.d.ts +17 -6
  154. package/lib/typescript/module/components/Carousel/Carousel.d.ts +7 -6
  155. package/lib/typescript/module/components/Checkbox/Checkbox.d.ts +9 -1
  156. package/lib/typescript/module/components/Chip/Chip.d.ts +13 -6
  157. package/lib/typescript/module/components/DatePicker/DatePicker.d.ts +38 -3
  158. package/lib/typescript/module/components/DateRangePicker/DateRangePicker.d.ts +36 -3
  159. package/lib/typescript/module/components/Dialog/Dialog.d.ts +13 -1
  160. package/lib/typescript/module/components/FieldBase/FieldBase.d.ts +141 -0
  161. package/lib/typescript/module/components/FieldBase/index.d.ts +3 -0
  162. package/lib/typescript/module/components/FloatingActionButton/FloatingActionButton.d.ts +8 -6
  163. package/lib/typescript/module/components/FloatingActionButton/index.d.ts +1 -1
  164. package/lib/typescript/module/components/ForceUpdateDialog/ForceUpdateDialog.d.ts +7 -0
  165. package/lib/typescript/module/components/FormField/FormField.d.ts +7 -0
  166. package/lib/typescript/module/components/ImageGallery/ImageGallery.d.ts +6 -4
  167. package/lib/typescript/module/components/Input/Input.d.ts +6 -0
  168. package/lib/typescript/module/components/ListItem/ListItem.d.ts +13 -6
  169. package/lib/typescript/module/components/NumberInput/NumberInput.d.ts +3 -0
  170. package/lib/typescript/module/components/PickerTrigger/PickerTrigger.d.ts +57 -0
  171. package/lib/typescript/module/components/PickerTrigger/index.d.ts +3 -0
  172. package/lib/typescript/module/components/ProgressBar/ProgressBar.d.ts +2 -0
  173. package/lib/typescript/module/components/Radio/Radio.d.ts +3 -0
  174. package/lib/typescript/module/components/Rating/Rating.d.ts +9 -6
  175. package/lib/typescript/module/components/SegmentedControl/SegmentedControl.d.ts +3 -0
  176. package/lib/typescript/module/components/Skeleton/Skeleton.d.ts +49 -20
  177. package/lib/typescript/module/components/Skeleton/SkeletonClock.d.ts +60 -0
  178. package/lib/typescript/module/components/Skeleton/SkeletonContent.d.ts +80 -19
  179. package/lib/typescript/module/components/Skeleton/SkeletonProvider.d.ts +39 -5
  180. package/lib/typescript/module/components/Skeleton/index.d.ts +6 -4
  181. package/lib/typescript/module/components/Slider/Slider.d.ts +12 -1
  182. package/lib/typescript/module/components/Stepper/Stepper.d.ts +18 -6
  183. package/lib/typescript/module/components/Swipeable/Swipeable.d.ts +2 -0
  184. package/lib/typescript/module/components/Switch/Switch.d.ts +1 -0
  185. package/lib/typescript/module/components/Tabs/Tabs.d.ts +26 -2
  186. package/lib/typescript/module/components/TimePicker/TimePicker.d.ts +36 -3
  187. package/lib/typescript/module/components/Toast/Toast.d.ts +8 -0
  188. package/lib/typescript/module/components/Tooltip/Tooltip.d.ts +7 -1
  189. package/lib/typescript/module/components/index.d.ts +5 -5
  190. package/lib/typescript/module/index.d.ts +1 -1
  191. package/lib/typescript/module/theme/index.d.ts +1 -1
  192. package/lib/typescript/module/theme/types.d.ts +553 -11
  193. package/package.json +2 -6
  194. package/lib/commonjs/components/AppIcon/AppIcon.js +0 -120
  195. package/lib/commonjs/types/vector-icons.d.js +0 -2
  196. package/lib/module/components/AppIcon/AppIcon.js +0 -111
  197. package/lib/module/components/AppIcon/index.js +0 -4
  198. package/lib/module/types/vector-icons.d.js +0 -2
  199. package/lib/typescript/commonjs/components/AppIcon/AppIcon.d.ts +0 -20
  200. package/lib/typescript/commonjs/components/AppIcon/index.d.ts +0 -3
  201. package/lib/typescript/module/components/AppIcon/AppIcon.d.ts +0 -20
  202. package/lib/typescript/module/components/AppIcon/index.d.ts +0 -3
@@ -1,10 +1,67 @@
1
1
  "use strict";
2
2
 
3
- import React, { Children, cloneElement, isValidElement, useState } from 'react';
4
- import { Image, StyleSheet, Text, View } from 'react-native';
3
+ /**
4
+ * SkeletonContent show placeholder shapes while data is loading, then
5
+ * cross-fade to the real children once it arrives.
6
+ *
7
+ * Three usage patterns, listed in order of preference:
8
+ *
9
+ * 1. **Explicit placeholder** (recommended):
10
+ *
11
+ * <SkeletonContent loading={isLoading} placeholder={<Card.Skeleton />}>
12
+ * <Card>{realChildren}</Card>
13
+ * </SkeletonContent>
14
+ *
15
+ * Renders `placeholder` verbatim while loading and `children` once loaded.
16
+ * Most precise and predictable — what you write is exactly what shimmers.
17
+ * Prefer this for any non-trivial layout.
18
+ *
19
+ * 2. **Self-describing components inside an auto-walked tree**:
20
+ *
21
+ * <SkeletonContent loading={isLoading}>
22
+ * <Stepper steps={steps} />
23
+ * <Card>...</Card>
24
+ * </SkeletonContent>
25
+ *
26
+ * With no `placeholder` prop, the walker substitutes each element. For
27
+ * library components, the walker checks for a `Component.Skeleton` static
28
+ * and replaces the element wholesale with it (the component author knows
29
+ * its shape best). For plain `<Text>`, `<Image>`, and sized `<View>`
30
+ * leaves the walker substitutes shape-matched `<Skeleton>` blocks based
31
+ * on the element's own style. Good for screen-level wrappers.
32
+ *
33
+ * 3. **Hand-authored primitive trees** (legacy / quick prototyping):
34
+ *
35
+ * <SkeletonContent loading={isLoading}>
36
+ * <View>
37
+ * <Text style={{ fontSize: 20 }}>Title</Text>
38
+ * <Text>Subtitle</Text>
39
+ * </View>
40
+ * </SkeletonContent>
41
+ *
42
+ * Same walker as (2) — the Text/Image/View introspection handles
43
+ * primitive trees that mirror the loaded layout.
44
+ *
45
+ * Cross-fade: when `loading` flips from true to false, real children fade in
46
+ * over `fadeDuration` ms. The first render is guarded — content that was
47
+ * never in a loading state does NOT fade on mount, only the actual
48
+ * loading→loaded transition does. Matches Chakra UI's `isLoaded` feel.
49
+ */
50
+
51
+ import React, { Children, cloneElement, isValidElement, useEffect, useRef } from 'react';
52
+ import { Animated, Image, StyleSheet, Text, View } from 'react-native';
53
+ import { createAnimatedValue } from "../../theme/index.js";
5
54
  import { Skeleton } from "./Skeleton.js";
6
55
  import { SkeletonSkip } from "./SkeletonSkip.js";
7
- import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
56
+ import { useSkeletonDefaults } from "./SkeletonProvider.js";
57
+
58
+ /**
59
+ * Components that ship their own placeholder shape declare this static. The
60
+ * walker looks for it before falling back to primitive introspection. The
61
+ * function receives the original component's props so consumer-customizable
62
+ * dimensions (size, count, etc.) carry through to the placeholder.
63
+ */
64
+ import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
8
65
  const flattenStyle = style => {
9
66
  if (!style) return {};
10
67
  const flat = StyleSheet.flatten(style);
@@ -27,9 +84,9 @@ const skeletonizeNode = (node, variant, speed, colors, keyHint = 'r') => {
27
84
  if (node == null || typeof node === 'boolean') return null;
28
85
  if (typeof node === 'string' || typeof node === 'number') {
29
86
  return /*#__PURE__*/_jsx(Skeleton, {
87
+ shape: "text",
30
88
  width: "60%",
31
89
  height: 14,
32
- radius: "sm",
33
90
  variant: variant,
34
91
  speed: speed,
35
92
  colors: colors
@@ -41,18 +98,35 @@ const skeletonizeNode = (node, variant, speed, colors, keyHint = 'r') => {
41
98
  if (! /*#__PURE__*/isValidElement(node)) return null;
42
99
  const element = node;
43
100
  const props = element.props ?? {};
44
- const elementStyle = flattenStyle(props.style);
45
101
  const elementType = element.type;
46
102
 
47
- // <SkeletonSkip /> → opt-out marker; render its children unchanged
103
+ // <SkeletonSkip /> → opt-out marker; render its children unchanged.
48
104
  if (elementType === SkeletonSkip) {
49
105
  return /*#__PURE__*/cloneElement(element, {
50
106
  key: `${keyHint}-skip`
51
107
  });
52
108
  }
53
109
 
54
- // <Image /> fixed-size skeleton block matching style.width/height/borderRadius
110
+ // Self-describing component path. If a custom component (Stepper, Card,
111
+ // Banner, etc.) ships a `Skeleton` static, prefer it over the primitive
112
+ // walker — the component author knows the shape better than we can guess.
113
+ // Forwards the original props so consumer-tunable params (size, count,
114
+ // tone) flow through. Crucially this short-circuits the walker BEFORE
115
+ // it tries to recurse into custom-component children, so we never end up
116
+ // rendering half-real / half-placeholder UI.
117
+ if (typeof elementType === 'function' || typeof elementType === 'object') {
118
+ const SkeletonStatic = elementType.Skeleton;
119
+ if (SkeletonStatic) {
120
+ const Sk = SkeletonStatic;
121
+ return /*#__PURE__*/_jsx(Sk, {
122
+ ...props
123
+ }, `${keyHint}-self`);
124
+ }
125
+ }
126
+
127
+ // <Image /> → fixed-size skeleton block matching style.width/height/borderRadius.
55
128
  if (elementType === Image) {
129
+ const elementStyle = flattenStyle(props.style);
56
130
  const width = resolveWidth(elementStyle.width, '100%');
57
131
  const height = typeof elementStyle.height === 'number' ? elementStyle.height : 120;
58
132
  const radius = resolveRadius(elementStyle.borderRadius, 'sm');
@@ -69,14 +143,15 @@ const skeletonizeNode = (node, variant, speed, colors, keyHint = 'r') => {
69
143
  }, `${keyHint}-img`);
70
144
  }
71
145
 
72
- // <Text /> → text-line skeleton matching font size
146
+ // <Text /> → text-line skeleton matching font size.
73
147
  if (elementType === Text) {
148
+ const elementStyle = flattenStyle(props.style);
74
149
  const fontSize = typeof elementStyle.fontSize === 'number' ? elementStyle.fontSize : 14;
75
150
  const width = resolveWidth(elementStyle.width, '85%');
76
151
  return /*#__PURE__*/_jsx(Skeleton, {
152
+ shape: "text",
77
153
  width: width,
78
154
  height: Math.round(fontSize * 1.15),
79
- radius: "sm",
80
155
  variant: variant,
81
156
  speed: speed,
82
157
  colors: colors,
@@ -86,30 +161,36 @@ const skeletonizeNode = (node, variant, speed, colors, keyHint = 'r') => {
86
161
  }, `${keyHint}-txt`);
87
162
  }
88
163
 
89
- // Element with children → recurse, preserving the wrapper (View, Pressable, custom layouts)
164
+ // Element with children → recurse, preserving the wrapper (View, Pressable,
165
+ // custom layouts). Runs AFTER the self-describing check so any component
166
+ // with `.Skeleton` is replaced wholesale.
90
167
  if (props.children != null) {
91
168
  return /*#__PURE__*/cloneElement(element, {
92
169
  key: `${keyHint}-w`
93
170
  }, skeletonizeNode(props.children, variant, speed, colors, `${keyHint}-c`));
94
171
  }
95
172
 
96
- // Leaf <View /> with explicit dimensions → skeleton block
97
- if (elementType === View && (elementStyle.width != null || elementStyle.height != null)) {
98
- const width = resolveWidth(elementStyle.width, '100%');
99
- const height = typeof elementStyle.height === 'number' ? elementStyle.height : 20;
100
- const radius = resolveRadius(elementStyle.borderRadius, 'sm');
101
- return /*#__PURE__*/_jsx(Skeleton, {
102
- width: width,
103
- height: height,
104
- radius: radius,
105
- variant: variant,
106
- speed: speed,
107
- colors: colors
108
- }, `${keyHint}-vw`);
173
+ // Leaf <View /> with explicit dimensions → skeleton block.
174
+ if (elementType === View) {
175
+ const elementStyle = flattenStyle(props.style);
176
+ if (elementStyle.width != null || elementStyle.height != null) {
177
+ const width = resolveWidth(elementStyle.width, '100%');
178
+ const height = typeof elementStyle.height === 'number' ? elementStyle.height : 20;
179
+ const radius = resolveRadius(elementStyle.borderRadius, 'sm');
180
+ return /*#__PURE__*/_jsx(Skeleton, {
181
+ width: width,
182
+ height: height,
183
+ radius: radius,
184
+ variant: variant,
185
+ speed: speed,
186
+ colors: colors
187
+ }, `${keyHint}-vw`);
188
+ }
109
189
  }
110
190
 
111
- // Opaque leaf (custom component without inspectable children) leave as-is.
112
- // Consumers should use mode='block' when wrapping such elements.
191
+ // Opaque leaf (custom component without inspectable children and without a
192
+ // `.Skeleton` static) leave as-is. Consumers should provide an explicit
193
+ // `placeholder` or author a `.Skeleton` static to handle these.
113
194
  return /*#__PURE__*/cloneElement(element, {
114
195
  key: `${keyHint}-leaf`
115
196
  });
@@ -117,92 +198,94 @@ const skeletonizeNode = (node, variant, speed, colors, keyHint = 'r') => {
117
198
  const SkeletonContent = ({
118
199
  loading,
119
200
  children,
201
+ placeholder,
120
202
  variant,
121
203
  speed,
122
- mode = 'auto',
123
204
  count = 1,
124
205
  colors,
206
+ fadeDuration,
125
207
  style,
126
208
  testID
127
209
  }) => {
210
+ const defaults = useSkeletonDefaults();
211
+ const resolvedFadeDuration = fadeDuration ?? defaults.fadeDuration ?? 300;
212
+
213
+ // Cross-fade: opacity goes 0 → 1 when loading just flipped off. First
214
+ // render is guarded with `wasLoadingRef` so already-loaded content
215
+ // doesn't fade in on mount.
216
+ const wasLoadingRef = useRef(loading);
217
+ const fadeAnim = useRef(createAnimatedValue(loading ? 0 : 1)).current;
218
+ useEffect(() => {
219
+ if (wasLoadingRef.current && !loading) {
220
+ fadeAnim.setValue(0);
221
+ Animated.timing(fadeAnim, {
222
+ toValue: 1,
223
+ duration: resolvedFadeDuration,
224
+ useNativeDriver: true
225
+ }).start();
226
+ } else if (!wasLoadingRef.current && loading) {
227
+ // Going back into loading from loaded — snap opacity so the
228
+ // placeholder appears instantly when data invalidates.
229
+ fadeAnim.setValue(1);
230
+ }
231
+ wasLoadingRef.current = loading;
232
+ }, [loading, fadeAnim, resolvedFadeDuration]);
128
233
  if (!loading) {
129
- return /*#__PURE__*/_jsx(_Fragment, {
234
+ if (resolvedFadeDuration <= 0) {
235
+ return /*#__PURE__*/_jsx(_Fragment, {
236
+ children: children
237
+ });
238
+ }
239
+ return /*#__PURE__*/_jsx(Animated.View, {
240
+ style: [style, {
241
+ opacity: fadeAnim
242
+ }],
243
+ testID: testID,
130
244
  children: children
131
245
  });
132
246
  }
247
+
248
+ // Explicit placeholder path — no walker, no introspection.
249
+ if (placeholder !== undefined) {
250
+ const slots = count > 1 ? Array.from({
251
+ length: count
252
+ }, (_, i) => /*#__PURE__*/_jsx(React.Fragment, {
253
+ children: placeholder
254
+ }, `sk-ph-${i}`)) : placeholder;
255
+ return /*#__PURE__*/_jsx(View, {
256
+ style: style,
257
+ testID: testID,
258
+ accessible: true,
259
+ accessibilityLabel: "Loading",
260
+ accessibilityRole: "progressbar",
261
+ accessibilityState: {
262
+ busy: true
263
+ },
264
+ accessibilityLiveRegion: "polite",
265
+ children: slots
266
+ });
267
+ }
268
+
269
+ // Walker path — auto-substitute primitives and self-describing components.
133
270
  const repeated = count > 1 ? Array.from({
134
271
  length: count
135
272
  }, (_, i) => /*#__PURE__*/_jsx(React.Fragment, {
136
273
  children: children
137
274
  }, `sk-rep-${i}`)) : children;
138
- if (mode === 'block') {
139
- return /*#__PURE__*/_jsx(BlockSkeleton, {
140
- style: style,
141
- testID: testID,
142
- variant: variant,
143
- speed: speed,
144
- colors: colors,
145
- children: repeated
146
- });
147
- }
148
275
  return /*#__PURE__*/_jsx(View, {
149
276
  style: style,
150
277
  testID: testID,
151
278
  accessible: true,
152
279
  accessibilityLabel: "Loading",
153
280
  accessibilityRole: "progressbar",
281
+ accessibilityState: {
282
+ busy: true
283
+ },
154
284
  accessibilityLiveRegion: "polite",
155
285
  children: skeletonizeNode(repeated, variant, speed, colors)
156
286
  });
157
287
  };
158
288
  SkeletonContent.displayName = 'SkeletonContent';
159
- const BlockSkeleton = ({
160
- children,
161
- variant,
162
- speed,
163
- colors,
164
- style,
165
- testID
166
- }) => {
167
- const [size, setSize] = useState(null);
168
- const onLayout = event => {
169
- const {
170
- width,
171
- height
172
- } = event.nativeEvent.layout;
173
- if (!size || size.width !== width || size.height !== height) {
174
- setSize({
175
- width,
176
- height
177
- });
178
- }
179
- };
180
- return /*#__PURE__*/_jsxs(View, {
181
- style: style,
182
- testID: testID,
183
- onLayout: onLayout,
184
- accessible: true,
185
- accessibilityLabel: "Loading",
186
- children: [/*#__PURE__*/_jsx(View, {
187
- style: {
188
- opacity: 0
189
- },
190
- pointerEvents: "none",
191
- children: children
192
- }), size != null ? /*#__PURE__*/_jsx(View, {
193
- style: StyleSheet.absoluteFill,
194
- pointerEvents: "none",
195
- children: /*#__PURE__*/_jsx(Skeleton, {
196
- width: size.width,
197
- height: size.height,
198
- radius: "md",
199
- variant: variant,
200
- speed: speed,
201
- colors: colors
202
- })
203
- }) : null]
204
- });
205
- };
206
289
  export { SkeletonContent };
207
290
  export default SkeletonContent;
208
291
  //# sourceMappingURL=SkeletonContent.js.map
@@ -1,11 +1,29 @@
1
1
  "use strict";
2
2
 
3
- import React, { createContext, useContext, useMemo } from 'react';
3
+ /**
4
+ * SkeletonProvider — app-level defaults for every <Skeleton> below it.
5
+ *
6
+ * Two responsibilities:
7
+ * 1. Broadcasts the default variant / speed / colors / radius /
8
+ * placeholderCount so consumers don't repeat them per call site.
9
+ * 2. Mounts the shared `SkeletonClockProvider` (see SkeletonClock.tsx) so
10
+ * every primitive shares a single Animated.Value — synchronized shimmer
11
+ * across the whole subtree, one native-driver loop per provider.
12
+ *
13
+ * Also honors the OS "Reduce Motion" preference: when enabled, the clock is
14
+ * paused and skeletons render as static dim blocks. The detection is live —
15
+ * if the user toggles the setting while the app is open the skeletons stop
16
+ * shimmering immediately.
17
+ */
18
+
19
+ import React, { createContext, useContext, useEffect, useMemo, useState } from 'react';
20
+ import { AccessibilityInfo } from 'react-native';
21
+ import { SkeletonClockProvider } from "./SkeletonClock.js";
4
22
 
5
23
  /**
6
- * Per-instance color override for a skeleton. `background` is the resting tone
7
- * of the placeholder; `highlight` is the moving shimmer band (or pulse fade).
8
- * Either can be omitted — missing keys fall back to the active theme.
24
+ * Per-instance color override for a skeleton. `background` is the resting
25
+ * tone of the placeholder; `highlight` is the moving shimmer band (or pulse
26
+ * fade). Either can be omitted — missing keys fall back to the active theme.
9
27
  */
10
28
  import { jsx as _jsx } from "react/jsx-runtime";
11
29
  const SkeletonDefaultsContext = /*#__PURE__*/createContext({});
@@ -15,27 +33,70 @@ export const SkeletonProvider = ({
15
33
  speed,
16
34
  placeholderCount,
17
35
  radius,
18
- colors
36
+ colors,
37
+ fadeDuration,
38
+ animation = 'auto'
19
39
  }) => {
40
+ const reduceMotion = useReduceMotion();
41
+ // Resolve whether the clock should actually tick. `'never'` forces off,
42
+ // `'always'` forces on, `'auto'` follows the OS preference.
43
+ const animationsEnabled = animation === 'always' ? true : animation === 'never' ? false : !reduceMotion;
44
+ const resolvedSpeed = speed ?? 'normal';
45
+ const resolvedVariant = variant ?? 'shimmer';
20
46
  const value = useMemo(() => ({
21
47
  variant,
22
48
  speed,
23
49
  placeholderCount,
24
50
  radius,
25
- colors
26
- }), [variant, speed, placeholderCount, radius, colors]);
51
+ colors,
52
+ fadeDuration,
53
+ animation
54
+ }), [variant, speed, placeholderCount, radius, colors, fadeDuration, animation]);
27
55
  return /*#__PURE__*/_jsx(SkeletonDefaultsContext.Provider, {
28
56
  value: value,
29
- children: children
57
+ children: /*#__PURE__*/_jsx(SkeletonClockProvider, {
58
+ speed: resolvedSpeed,
59
+ variant: resolvedVariant,
60
+ enabled: animationsEnabled,
61
+ children: children
62
+ })
30
63
  });
31
64
  };
32
65
  SkeletonProvider.displayName = 'SkeletonProvider';
33
66
 
34
67
  /**
35
- * Read the current SkeletonProvider defaults. Returns an empty object when no
36
- * provider is mounted, so the skeleton primitives still work outside of one.
68
+ * Read the current SkeletonProvider defaults. Returns an empty object when
69
+ * no provider is mounted, so the skeleton primitives still work outside of
70
+ * one — but without a shared clock or theme-coordinated colors.
37
71
  */
38
72
  export const useSkeletonDefaults = () => {
39
73
  return useContext(SkeletonDefaultsContext);
40
74
  };
75
+
76
+ /**
77
+ * Subscribes to the OS "Reduce Motion" preference. Live — updates when the
78
+ * user toggles the setting while the app is open. Used internally by
79
+ * `SkeletonProvider`; exposed so consumer screens can branch on it too.
80
+ */
81
+ export const useReduceMotion = () => {
82
+ const [reduce, setReduce] = useState(false);
83
+ useEffect(() => {
84
+ let mounted = true;
85
+ AccessibilityInfo.isReduceMotionEnabled().then(value => {
86
+ if (mounted) setReduce(value);
87
+ }).catch(() => {
88
+ // Some platforms / older RN versions throw if the native module is
89
+ // missing. Treat as "motion allowed" — degrade quietly to shimmer.
90
+ if (mounted) setReduce(false);
91
+ });
92
+ const sub = AccessibilityInfo.addEventListener('reduceMotionChanged', value => {
93
+ setReduce(value);
94
+ });
95
+ return () => {
96
+ mounted = false;
97
+ sub.remove();
98
+ };
99
+ }, []);
100
+ return reduce;
101
+ };
41
102
  //# sourceMappingURL=SkeletonProvider.js.map
@@ -1,8 +1,9 @@
1
1
  "use strict";
2
2
 
3
- export { Skeleton, SkeletonCircle, SkeletonText, SkeletonAvatar, SkeletonCard, SkeletonListItem, default } from "./Skeleton.js";
3
+ export { Skeleton, SkeletonCircle, SkeletonText, default } from "./Skeleton.js";
4
4
  export { SkeletonContent } from "./SkeletonContent.js";
5
5
  export { SkeletonList } from "./SkeletonList.js";
6
- export { SkeletonProvider, useSkeletonDefaults } from "./SkeletonProvider.js";
6
+ export { SkeletonProvider, useSkeletonDefaults, useReduceMotion } from "./SkeletonProvider.js";
7
+ export { SkeletonClockProvider, useSkeletonClock } from "./SkeletonClock.js";
7
8
  export { SkeletonSkip } from "./SkeletonSkip.js";
8
9
  //# sourceMappingURL=index.js.map
@@ -47,10 +47,27 @@ const Slider = /*#__PURE__*/forwardRef((props, ref) => {
47
47
  formatLabel = defaultFormatLabel,
48
48
  accessibilityLabel,
49
49
  style,
50
+ containerStyle,
51
+ trackStyle,
52
+ fillStyle,
53
+ thumbStyle,
54
+ labelStyle,
55
+ thumbPressScale,
56
+ labelShowDuration,
57
+ labelOpacity: labelOpacityProp,
50
58
  testID
51
59
  } = props;
52
60
  const theme = useTheme();
53
- const sizeCfg = SIZE_MAP[size];
61
+ const sliderTheme = theme.components.slider;
62
+ const sliderSizeTheme = sliderTheme?.[size];
63
+ const sizeCfg = {
64
+ trackHeight: sliderSizeTheme?.trackHeight ?? SIZE_MAP[size].trackHeight,
65
+ thumbDiameter: sliderSizeTheme?.thumbDiameter ?? SIZE_MAP[size].thumbDiameter
66
+ };
67
+ const thumbPressAnimationEnabled = sliderTheme?.thumbPressAnimation ?? false;
68
+ const resolvedPressScale = thumbPressScale ?? sliderTheme?.thumbPressScale ?? 1.1;
69
+ const resolvedLabelDuration = labelShowDuration ?? sliderTheme?.labelShowDuration ?? theme.motion.duration.fast;
70
+ const resolvedLabelOpacity = labelOpacityProp ?? sliderTheme?.labelOpacity ?? 1;
54
71
  const styles = useMemo(() => buildStyles(theme, sizeCfg), [theme, sizeCfg]);
55
72
 
56
73
  // Track layout (width + x offset within container)
@@ -141,22 +158,24 @@ const Slider = /*#__PURE__*/forwardRef((props, ref) => {
141
158
  }
142
159
  }, [isRange, props]);
143
160
  const animateThumbPress = useCallback((target, opacity, pressed) => {
144
- Animated.spring(target, {
145
- toValue: pressed ? 1.1 : 1,
146
- damping: theme.motion.spring.snappy.damping,
147
- stiffness: theme.motion.spring.snappy.stiffness,
148
- mass: theme.motion.spring.snappy.mass,
149
- useNativeDriver: true
150
- }).start();
161
+ if (thumbPressAnimationEnabled) {
162
+ Animated.spring(target, {
163
+ toValue: pressed ? resolvedPressScale : 1,
164
+ damping: theme.motion.spring.snappy.damping,
165
+ stiffness: theme.motion.spring.snappy.stiffness,
166
+ mass: theme.motion.spring.snappy.mass,
167
+ useNativeDriver: true
168
+ }).start();
169
+ }
151
170
  if (showLabel) {
152
171
  Animated.timing(opacity, {
153
- toValue: pressed ? 1 : 0,
154
- duration: theme.motion.duration.fast,
172
+ toValue: pressed ? resolvedLabelOpacity : 0,
173
+ duration: resolvedLabelDuration,
155
174
  easing: Easing.out(Easing.cubic),
156
175
  useNativeDriver: true
157
176
  }).start();
158
177
  }
159
- }, [showLabel, theme.motion]);
178
+ }, [showLabel, theme.motion, thumbPressAnimationEnabled, resolvedPressScale, resolvedLabelDuration, resolvedLabelOpacity]);
160
179
 
161
180
  // Build PanResponder for a thumb.
162
181
  const buildResponder = useCallback(which => {
@@ -166,7 +185,7 @@ const Slider = /*#__PURE__*/forwardRef((props, ref) => {
166
185
  onPanResponderGrant: () => {
167
186
  dragOffsetRef.current = which === 'low' ? valueToPx(lowRef.current, trackWidth) : valueToPx(highRef.current, trackWidth);
168
187
  animateThumbPress(which === 'low' ? lowScale : highScale, which === 'low' ? lowLabelOpacity : highLabelOpacity, true);
169
- triggerHaptic('selection');
188
+ if (sliderTheme?.dragHaptic ?? false) triggerHaptic('selection');
170
189
  },
171
190
  onPanResponderMove: (_evt, gesture) => {
172
191
  if (trackWidth <= 0) return;
@@ -175,7 +194,7 @@ const Slider = /*#__PURE__*/forwardRef((props, ref) => {
175
194
  if (which === 'low') {
176
195
  if (isRange && nextValue > highRef.current) nextValue = highRef.current;
177
196
  if (nextValue !== lastReportedLow.current) {
178
- triggerHaptic('selection');
197
+ if (sliderTheme?.stepHaptic ?? false) triggerHaptic('selection');
179
198
  lastReportedLow.current = nextValue;
180
199
  }
181
200
  lowRef.current = nextValue;
@@ -184,7 +203,7 @@ const Slider = /*#__PURE__*/forwardRef((props, ref) => {
184
203
  } else {
185
204
  if (isRange && nextValue < lowRef.current) nextValue = lowRef.current;
186
205
  if (nextValue !== lastReportedHigh.current) {
187
- triggerHaptic('selection');
206
+ if (sliderTheme?.stepHaptic ?? false) triggerHaptic('selection');
188
207
  lastReportedHigh.current = nextValue;
189
208
  }
190
209
  highRef.current = nextValue;
@@ -211,7 +230,7 @@ const Slider = /*#__PURE__*/forwardRef((props, ref) => {
211
230
  const px = clamp(e.nativeEvent.locationX, 0, trackWidth);
212
231
  const next = pxToValue(px, trackWidth);
213
232
  if (next !== lowRef.current) {
214
- triggerHaptic('selection');
233
+ if (sliderTheme?.tapHaptic ?? false) triggerHaptic('selection');
215
234
  lowRef.current = next;
216
235
  lastReportedLow.current = next;
217
236
  Animated.timing(lowX, {
@@ -234,7 +253,7 @@ const Slider = /*#__PURE__*/forwardRef((props, ref) => {
234
253
  lowRef.current = nextLow;
235
254
  lastReportedLow.current = nextLow;
236
255
  setNativeValue(lowX, valueToPx(nextLow, trackWidth));
237
- triggerHaptic('selection');
256
+ if (sliderTheme?.a11yHaptic ?? false) triggerHaptic('selection');
238
257
  fireChange(nextLow, highRef.current);
239
258
  }
240
259
  } else {
@@ -243,11 +262,11 @@ const Slider = /*#__PURE__*/forwardRef((props, ref) => {
243
262
  lowRef.current = next;
244
263
  lastReportedLow.current = next;
245
264
  setNativeValue(lowX, valueToPx(next, trackWidth));
246
- triggerHaptic('selection');
265
+ if (sliderTheme?.a11yHaptic ?? false) triggerHaptic('selection');
247
266
  fireChange(next, next);
248
267
  }
249
268
  }
250
- }, [disabled, step, isRange, min, max, valueToPx, trackWidth, lowX, fireChange]);
269
+ }, [disabled, step, isRange, min, max, valueToPx, trackWidth, lowX, fireChange, sliderTheme]);
251
270
 
252
271
  // Computed values for fill bar.
253
272
  const fillLeft = isRange ? lowX : new Animated.Value(0);
@@ -259,7 +278,7 @@ const Slider = /*#__PURE__*/forwardRef((props, ref) => {
259
278
  const highDisplayValue = highRef.current;
260
279
  return /*#__PURE__*/_jsx(View, {
261
280
  ref: ref,
262
- style: [styles.container, style],
281
+ style: [styles.container, containerStyle, style],
263
282
  testID: testID,
264
283
  accessibilityRole: "adjustable",
265
284
  accessibilityLabel: accessibilityLabel,
@@ -289,14 +308,14 @@ const Slider = /*#__PURE__*/forwardRef((props, ref) => {
289
308
  children: [/*#__PURE__*/_jsx(View, {
290
309
  style: [styles.track, {
291
310
  backgroundColor: disabled ? theme.colors.surface.disabled : theme.colors.border.primary
292
- }]
311
+ }, trackStyle]
293
312
  }), /*#__PURE__*/_jsx(Animated.View, {
294
313
  style: [styles.fill, {
295
314
  left: fillLeft,
296
315
  width: fillWidth,
297
316
  backgroundColor: disabled ? theme.colors.surface.disabled : fillColor,
298
317
  opacity: disabled ? 0.6 : 1
299
- }]
318
+ }, fillStyle]
300
319
  }), /*#__PURE__*/_jsx(Animated.View, {
301
320
  ...lowResponder.panHandlers,
302
321
  style: [styles.thumb, {
@@ -311,7 +330,7 @@ const Slider = /*#__PURE__*/forwardRef((props, ref) => {
311
330
  scale: lowScale
312
331
  }],
313
332
  opacity: disabled ? 0.6 : 1
314
- }],
333
+ }, thumbStyle],
315
334
  accessibilityElementsHidden: true,
316
335
  importantForAccessibility: "no-hide-descendants",
317
336
  children: showLabel ? /*#__PURE__*/_jsx(Animated.View, {
@@ -321,7 +340,7 @@ const Slider = /*#__PURE__*/forwardRef((props, ref) => {
321
340
  }],
322
341
  pointerEvents: "none",
323
342
  children: /*#__PURE__*/_jsx(Text, {
324
- style: styles.bubbleText,
343
+ style: [styles.bubbleText, labelStyle],
325
344
  children: formatLabel(lowDisplayValue)
326
345
  })
327
346
  }) : null
@@ -339,7 +358,7 @@ const Slider = /*#__PURE__*/forwardRef((props, ref) => {
339
358
  scale: highScale
340
359
  }],
341
360
  opacity: disabled ? 0.6 : 1
342
- }],
361
+ }, thumbStyle],
343
362
  accessibilityElementsHidden: true,
344
363
  importantForAccessibility: "no-hide-descendants",
345
364
  children: showLabel ? /*#__PURE__*/_jsx(Animated.View, {
@@ -349,7 +368,7 @@ const Slider = /*#__PURE__*/forwardRef((props, ref) => {
349
368
  }],
350
369
  pointerEvents: "none",
351
370
  children: /*#__PURE__*/_jsx(Text, {
352
- style: styles.bubbleText,
371
+ style: [styles.bubbleText, labelStyle],
353
372
  children: formatLabel(highDisplayValue)
354
373
  })
355
374
  }) : null