@webority-technologies/mobile 0.0.21 → 0.0.23

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 (187) hide show
  1. package/lib/commonjs/components/Accordion/Accordion.js +4 -2
  2. package/lib/commonjs/components/Avatar/Avatar.js +4 -2
  3. package/lib/commonjs/components/Badge/Badge.js +5 -5
  4. package/lib/commonjs/components/Banner/Banner.js +8 -4
  5. package/lib/commonjs/components/BottomNavigation/BottomNavigation.js +6 -4
  6. package/lib/commonjs/components/BottomSheet/BottomSheet.js +69 -13
  7. package/lib/commonjs/components/BottomSheet/index.js +6 -0
  8. package/lib/commonjs/components/Box/Box.js +162 -0
  9. package/lib/commonjs/components/Box/index.js +37 -0
  10. package/lib/commonjs/components/Button/Button.js +7 -7
  11. package/lib/commonjs/components/Carousel/Carousel.js +4 -2
  12. package/lib/commonjs/components/Checkbox/Checkbox.js +14 -5
  13. package/lib/commonjs/components/DatePicker/DatePicker.js +9 -7
  14. package/lib/commonjs/components/DateRangePicker/DateRangePicker.js +5 -2
  15. package/lib/commonjs/components/Dialog/Dialog.js +2 -2
  16. package/lib/commonjs/components/FieldBase/FieldBase.js +8 -4
  17. package/lib/commonjs/components/FloatingActionButton/FloatingActionButton.js +13 -5
  18. package/lib/commonjs/components/FormField/FormField.js +61 -25
  19. package/lib/commonjs/components/Input/Input.js +41 -29
  20. package/lib/commonjs/components/KeyboardAwareScrollView/KeyboardAwareScrollView.js +102 -0
  21. package/lib/commonjs/components/KeyboardAwareScrollView/index.js +13 -0
  22. package/lib/commonjs/components/KeyboardToolbar/KeyboardToolbar.js +130 -0
  23. package/lib/commonjs/components/KeyboardToolbar/index.js +13 -0
  24. package/lib/commonjs/components/Modal/Modal.js +17 -6
  25. package/lib/commonjs/components/NumberInput/NumberInput.js +35 -28
  26. package/lib/commonjs/components/OTPInput/OTPInput.js +33 -18
  27. package/lib/commonjs/components/Radio/Radio.js +7 -5
  28. package/lib/commonjs/components/Radio/RadioGroup.js +10 -3
  29. package/lib/commonjs/components/SearchBar/SearchBar.js +4 -2
  30. package/lib/commonjs/components/SegmentedControl/SegmentedControl.js +20 -10
  31. package/lib/commonjs/components/Select/Select.js +33 -32
  32. package/lib/commonjs/components/Skeleton/SkeletonContent.js +5 -2
  33. package/lib/commonjs/components/Slider/Slider.js +42 -26
  34. package/lib/commonjs/components/Spinner/Spinner.js +5 -5
  35. package/lib/commonjs/components/Switch/Switch.js +29 -16
  36. package/lib/commonjs/components/Tabs/Tabs.js +4 -2
  37. package/lib/commonjs/components/Text/Text.js +142 -0
  38. package/lib/commonjs/components/Text/index.js +13 -0
  39. package/lib/commonjs/components/TimePicker/TimePicker.js +10 -7
  40. package/lib/commonjs/components/Toast/Toast.js +22 -10
  41. package/lib/commonjs/components/Tooltip/Tooltip.js +6 -2
  42. package/lib/commonjs/components/index.js +141 -89
  43. package/lib/commonjs/form/FormContext.js +40 -0
  44. package/lib/commonjs/form/index.js +68 -0
  45. package/lib/commonjs/form/path.js +79 -0
  46. package/lib/commonjs/form/rules.js +67 -0
  47. package/lib/commonjs/form/types.js +2 -0
  48. package/lib/commonjs/form/useField.js +54 -0
  49. package/lib/commonjs/form/useForm.js +316 -0
  50. package/lib/commonjs/hooks/index.js +14 -0
  51. package/lib/commonjs/hooks/useControllableState.js +30 -0
  52. package/lib/commonjs/hooks/useReducedMotion.js +31 -0
  53. package/lib/commonjs/index.js +96 -11
  54. package/lib/commonjs/theme/ThemeContext.js +30 -2
  55. package/lib/commonjs/theme/tokens.js +12 -0
  56. package/lib/module/components/Accordion/Accordion.js +4 -2
  57. package/lib/module/components/Avatar/Avatar.js +4 -2
  58. package/lib/module/components/Badge/Badge.js +5 -5
  59. package/lib/module/components/Banner/Banner.js +8 -4
  60. package/lib/module/components/BottomNavigation/BottomNavigation.js +6 -4
  61. package/lib/module/components/BottomSheet/BottomSheet.js +68 -13
  62. package/lib/module/components/BottomSheet/index.js +1 -1
  63. package/lib/module/components/Box/Box.js +156 -0
  64. package/lib/module/components/Box/index.js +4 -0
  65. package/lib/module/components/Button/Button.js +7 -7
  66. package/lib/module/components/Carousel/Carousel.js +4 -2
  67. package/lib/module/components/Checkbox/Checkbox.js +14 -5
  68. package/lib/module/components/DatePicker/DatePicker.js +9 -7
  69. package/lib/module/components/DateRangePicker/DateRangePicker.js +5 -2
  70. package/lib/module/components/Dialog/Dialog.js +2 -2
  71. package/lib/module/components/FieldBase/FieldBase.js +8 -4
  72. package/lib/module/components/FloatingActionButton/FloatingActionButton.js +13 -5
  73. package/lib/module/components/FormField/FormField.js +62 -26
  74. package/lib/module/components/Input/Input.js +41 -29
  75. package/lib/module/components/KeyboardAwareScrollView/KeyboardAwareScrollView.js +98 -0
  76. package/lib/module/components/KeyboardAwareScrollView/index.js +4 -0
  77. package/lib/module/components/KeyboardToolbar/KeyboardToolbar.js +125 -0
  78. package/lib/module/components/KeyboardToolbar/index.js +4 -0
  79. package/lib/module/components/Modal/Modal.js +17 -6
  80. package/lib/module/components/NumberInput/NumberInput.js +30 -23
  81. package/lib/module/components/OTPInput/OTPInput.js +30 -15
  82. package/lib/module/components/Radio/Radio.js +7 -5
  83. package/lib/module/components/Radio/RadioGroup.js +10 -3
  84. package/lib/module/components/SearchBar/SearchBar.js +4 -2
  85. package/lib/module/components/SegmentedControl/SegmentedControl.js +20 -10
  86. package/lib/module/components/Select/Select.js +33 -32
  87. package/lib/module/components/Skeleton/SkeletonContent.js +5 -2
  88. package/lib/module/components/Slider/Slider.js +42 -26
  89. package/lib/module/components/Spinner/Spinner.js +5 -5
  90. package/lib/module/components/Switch/Switch.js +29 -16
  91. package/lib/module/components/Tabs/Tabs.js +4 -2
  92. package/lib/module/components/Text/Text.js +138 -0
  93. package/lib/module/components/Text/index.js +4 -0
  94. package/lib/module/components/TimePicker/TimePicker.js +10 -7
  95. package/lib/module/components/Toast/Toast.js +22 -10
  96. package/lib/module/components/Tooltip/Tooltip.js +6 -2
  97. package/lib/module/components/index.js +5 -1
  98. package/lib/module/form/FormContext.js +32 -0
  99. package/lib/module/form/index.js +12 -0
  100. package/lib/module/form/path.js +72 -0
  101. package/lib/module/form/rules.js +52 -0
  102. package/lib/module/form/types.js +2 -0
  103. package/lib/module/form/useField.js +49 -0
  104. package/lib/module/form/useForm.js +312 -0
  105. package/lib/module/hooks/index.js +2 -0
  106. package/lib/module/hooks/useControllableState.js +26 -0
  107. package/lib/module/hooks/useReducedMotion.js +27 -0
  108. package/lib/module/index.js +3 -1
  109. package/lib/module/theme/ThemeContext.js +30 -2
  110. package/lib/module/theme/tokens.js +12 -0
  111. package/lib/typescript/commonjs/components/BottomNavigation/BottomNavigation.d.ts +1 -1
  112. package/lib/typescript/commonjs/components/BottomSheet/BottomSheet.d.ts +41 -0
  113. package/lib/typescript/commonjs/components/BottomSheet/index.d.ts +2 -2
  114. package/lib/typescript/commonjs/components/Box/Box.d.ts +60 -0
  115. package/lib/typescript/commonjs/components/Box/index.d.ts +3 -0
  116. package/lib/typescript/commonjs/components/Button/Button.d.ts +1 -1
  117. package/lib/typescript/commonjs/components/Checkbox/Checkbox.d.ts +3 -2
  118. package/lib/typescript/commonjs/components/DatePicker/DatePicker.d.ts +3 -3
  119. package/lib/typescript/commonjs/components/Dialog/Dialog.d.ts +2 -2
  120. package/lib/typescript/commonjs/components/FormField/FormField.d.ts +13 -2
  121. package/lib/typescript/commonjs/components/KeyboardAwareScrollView/KeyboardAwareScrollView.d.ts +20 -0
  122. package/lib/typescript/commonjs/components/KeyboardAwareScrollView/index.d.ts +3 -0
  123. package/lib/typescript/commonjs/components/KeyboardToolbar/KeyboardToolbar.d.ts +29 -0
  124. package/lib/typescript/commonjs/components/KeyboardToolbar/index.d.ts +3 -0
  125. package/lib/typescript/commonjs/components/NumberInput/NumberInput.d.ts +3 -2
  126. package/lib/typescript/commonjs/components/OTPInput/OTPInput.d.ts +3 -2
  127. package/lib/typescript/commonjs/components/Radio/Radio.d.ts +2 -2
  128. package/lib/typescript/commonjs/components/Radio/RadioGroup.d.ts +3 -2
  129. package/lib/typescript/commonjs/components/SegmentedControl/SegmentedControl.d.ts +3 -2
  130. package/lib/typescript/commonjs/components/Slider/Slider.d.ts +6 -4
  131. package/lib/typescript/commonjs/components/Spinner/Spinner.d.ts +1 -1
  132. package/lib/typescript/commonjs/components/Switch/Switch.d.ts +3 -2
  133. package/lib/typescript/commonjs/components/Text/Text.d.ts +25 -0
  134. package/lib/typescript/commonjs/components/Text/index.d.ts +3 -0
  135. package/lib/typescript/commonjs/components/TimePicker/TimePicker.d.ts +3 -3
  136. package/lib/typescript/commonjs/components/index.d.ts +10 -2
  137. package/lib/typescript/commonjs/form/FormContext.d.ts +17 -0
  138. package/lib/typescript/commonjs/form/index.d.ts +9 -0
  139. package/lib/typescript/commonjs/form/path.d.ts +10 -0
  140. package/lib/typescript/commonjs/form/rules.d.ts +31 -0
  141. package/lib/typescript/commonjs/form/types.d.ts +94 -0
  142. package/lib/typescript/commonjs/form/useField.d.ts +27 -0
  143. package/lib/typescript/commonjs/form/useForm.d.ts +10 -0
  144. package/lib/typescript/commonjs/hooks/index.d.ts +3 -0
  145. package/lib/typescript/commonjs/hooks/useControllableState.d.ts +17 -0
  146. package/lib/typescript/commonjs/hooks/useReducedMotion.d.ts +8 -0
  147. package/lib/typescript/commonjs/index.d.ts +4 -2
  148. package/lib/typescript/commonjs/theme/types.d.ts +15 -0
  149. package/lib/typescript/module/components/BottomNavigation/BottomNavigation.d.ts +1 -1
  150. package/lib/typescript/module/components/BottomSheet/BottomSheet.d.ts +41 -0
  151. package/lib/typescript/module/components/BottomSheet/index.d.ts +2 -2
  152. package/lib/typescript/module/components/Box/Box.d.ts +60 -0
  153. package/lib/typescript/module/components/Box/index.d.ts +3 -0
  154. package/lib/typescript/module/components/Button/Button.d.ts +1 -1
  155. package/lib/typescript/module/components/Checkbox/Checkbox.d.ts +3 -2
  156. package/lib/typescript/module/components/DatePicker/DatePicker.d.ts +3 -3
  157. package/lib/typescript/module/components/Dialog/Dialog.d.ts +2 -2
  158. package/lib/typescript/module/components/FormField/FormField.d.ts +13 -2
  159. package/lib/typescript/module/components/KeyboardAwareScrollView/KeyboardAwareScrollView.d.ts +20 -0
  160. package/lib/typescript/module/components/KeyboardAwareScrollView/index.d.ts +3 -0
  161. package/lib/typescript/module/components/KeyboardToolbar/KeyboardToolbar.d.ts +29 -0
  162. package/lib/typescript/module/components/KeyboardToolbar/index.d.ts +3 -0
  163. package/lib/typescript/module/components/NumberInput/NumberInput.d.ts +3 -2
  164. package/lib/typescript/module/components/OTPInput/OTPInput.d.ts +3 -2
  165. package/lib/typescript/module/components/Radio/Radio.d.ts +2 -2
  166. package/lib/typescript/module/components/Radio/RadioGroup.d.ts +3 -2
  167. package/lib/typescript/module/components/SegmentedControl/SegmentedControl.d.ts +3 -2
  168. package/lib/typescript/module/components/Slider/Slider.d.ts +6 -4
  169. package/lib/typescript/module/components/Spinner/Spinner.d.ts +1 -1
  170. package/lib/typescript/module/components/Switch/Switch.d.ts +3 -2
  171. package/lib/typescript/module/components/Text/Text.d.ts +25 -0
  172. package/lib/typescript/module/components/Text/index.d.ts +3 -0
  173. package/lib/typescript/module/components/TimePicker/TimePicker.d.ts +3 -3
  174. package/lib/typescript/module/components/index.d.ts +10 -2
  175. package/lib/typescript/module/form/FormContext.d.ts +17 -0
  176. package/lib/typescript/module/form/index.d.ts +9 -0
  177. package/lib/typescript/module/form/path.d.ts +10 -0
  178. package/lib/typescript/module/form/rules.d.ts +31 -0
  179. package/lib/typescript/module/form/types.d.ts +94 -0
  180. package/lib/typescript/module/form/useField.d.ts +27 -0
  181. package/lib/typescript/module/form/useForm.d.ts +10 -0
  182. package/lib/typescript/module/hooks/index.d.ts +3 -0
  183. package/lib/typescript/module/hooks/useControllableState.d.ts +17 -0
  184. package/lib/typescript/module/hooks/useReducedMotion.d.ts +8 -0
  185. package/lib/typescript/module/index.d.ts +4 -2
  186. package/lib/typescript/module/theme/types.d.ts +15 -0
  187. package/package.json +1 -1
@@ -15,14 +15,14 @@ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r
15
15
  /**
16
16
  * DatePicker operates in two modes:
17
17
  *
18
- * 1. **Controlled-modal mode** — pass `visible` (plus `onSelect` / `onClose`)
18
+ * 1. **Controlled-modal mode** — pass `visible` (plus `onChange` / `onClose`)
19
19
  * and own the open state externally. The component renders only the modal.
20
20
  * 2. **Trigger mode** — omit `visible`. The component renders a built-in
21
21
  * PickerTrigger field (label / value / placeholder / chevron / clear /
22
22
  * helper / error / size / variant) and manages its own open state. The
23
23
  * field opens the modal on press and closes it on confirm/cancel.
24
24
  *
25
- * `onSelect` / `onClose` are typed optional to support trigger-only usage
25
+ * `onChange` / `onClose` are typed optional to support trigger-only usage
26
26
  * where the consumer may not need either callback. In controlled-modal mode
27
27
  * they remain semantically required.
28
28
  */
@@ -104,7 +104,7 @@ const buildDecadeCells = anchorYear => {
104
104
  const DatePicker = props => {
105
105
  const {
106
106
  value,
107
- onSelect,
107
+ onChange,
108
108
  onClose,
109
109
  minDate,
110
110
  maxDate,
@@ -179,7 +179,7 @@ const DatePicker = props => {
179
179
  if (open) {
180
180
  backdrop.setValue(0);
181
181
  (0, _index.setNativeValue)(sheet, 0);
182
- _reactNative.Animated.parallel([_reactNative.Animated.timing(backdrop, {
182
+ const anim = _reactNative.Animated.parallel([_reactNative.Animated.timing(backdrop, {
183
183
  toValue: 1,
184
184
  duration: theme.motion.duration.normal,
185
185
  easing: _reactNative.Easing.out(_reactNative.Easing.cubic),
@@ -190,7 +190,9 @@ const DatePicker = props => {
190
190
  stiffness: theme.motion.spring.gentle.stiffness,
191
191
  mass: theme.motion.spring.gentle.mass,
192
192
  useNativeDriver: true
193
- })]).start();
193
+ })]);
194
+ anim.start();
195
+ return () => anim.stop();
194
196
  }
195
197
  }, [open, mode, backdrop, sheet, theme.motion]);
196
198
  const disabledIsoSet = (0, _react.useMemo)(() => {
@@ -390,9 +392,9 @@ const DatePicker = props => {
390
392
  const handleConfirm = (0, _react.useCallback)(() => {
391
393
  if (!pendingDate) return;
392
394
  if (theme.components.datePicker?.haptic) (0, _index2.triggerHaptic)('notificationSuccess');
393
- onSelect?.(pendingDate);
395
+ onChange?.(pendingDate);
394
396
  handleClose();
395
- }, [handleClose, onSelect, pendingDate, theme.components.datePicker]);
397
+ }, [handleClose, onChange, pendingDate, theme.components.datePicker]);
396
398
  const sheetTranslate = sheet.interpolate({
397
399
  inputRange: [0, 1],
398
400
  outputRange: [320, 0]
@@ -152,10 +152,11 @@ const DateRangePicker = exports.DateRangePicker = /*#__PURE__*/(0, _react.forwar
152
152
  // Modal open / close animation. Backdrop opacity uses JS driver — see
153
153
  // Modal.tsx for the Fabric reason. Sheet transform stays native.
154
154
  (0, _react.useEffect)(() => {
155
+ let anim;
155
156
  if (open) {
156
157
  backdrop.setValue(0);
157
158
  (0, _index.setNativeValue)(sheet, 0);
158
- _reactNative.Animated.parallel([_reactNative.Animated.timing(backdrop, {
159
+ anim = _reactNative.Animated.parallel([_reactNative.Animated.timing(backdrop, {
159
160
  toValue: 1,
160
161
  duration: theme.motion.duration.normal,
161
162
  easing: _reactNative.Easing.out(_reactNative.Easing.cubic),
@@ -166,8 +167,10 @@ const DateRangePicker = exports.DateRangePicker = /*#__PURE__*/(0, _react.forwar
166
167
  stiffness: theme.motion.spring.gentle.stiffness,
167
168
  mass: theme.motion.spring.gentle.mass,
168
169
  useNativeDriver: true
169
- })]).start();
170
+ })]);
171
+ anim.start();
170
172
  }
173
+ return () => anim?.stop();
171
174
  }, [open, backdrop, sheet, theme.motion]);
172
175
  const disabledIsoSet = (0, _react.useMemo)(() => {
173
176
  const set = new Set();
@@ -150,7 +150,7 @@ const tintForVariant = (theme, variant) => {
150
150
  base: theme.colors.warning,
151
151
  muted: theme.colors.background.secondary
152
152
  };
153
- case 'danger':
153
+ case 'error':
154
154
  return {
155
155
  base: theme.colors.error,
156
156
  muted: theme.colors.background.secondary
@@ -181,7 +181,7 @@ const actionStyleFor = (theme, tone, variant) => {
181
181
  textColor: theme.colors.text.inverse
182
182
  };
183
183
  }
184
- case 'danger':
184
+ case 'error':
185
185
  return {
186
186
  backgroundColor: theme.colors.error,
187
187
  borderColor: 'transparent',
@@ -294,20 +294,24 @@ const FieldBase = props => {
294
294
  const focusAnim = (0, _react.useRef)((0, _index.createAnimatedValue)(focused ? 1 : 0)).current;
295
295
  const errorAnim = (0, _react.useRef)((0, _index.createAnimatedValue)(error ? 1 : 0)).current;
296
296
  (0, _react.useEffect)(() => {
297
- _reactNative.Animated.timing(focusAnim, {
297
+ const anim = _reactNative.Animated.timing(focusAnim, {
298
298
  toValue: focused ? 1 : 0,
299
299
  duration: theme.motion.duration.fast,
300
300
  easing: _reactNative.Easing.bezier(...theme.motion.easing.standard),
301
301
  useNativeDriver: false
302
- }).start();
302
+ });
303
+ anim.start();
304
+ return () => anim.stop();
303
305
  }, [focused, focusAnim, theme.motion.duration.fast, theme.motion.easing.standard]);
304
306
  (0, _react.useEffect)(() => {
305
- _reactNative.Animated.timing(errorAnim, {
307
+ const anim = _reactNative.Animated.timing(errorAnim, {
306
308
  toValue: error ? 1 : 0,
307
309
  duration: theme.motion.duration.fast,
308
310
  easing: _reactNative.Easing.bezier(...theme.motion.easing.standard),
309
311
  useNativeDriver: false
310
- }).start();
312
+ });
313
+ anim.start();
314
+ return () => anim.stop();
311
315
  }, [error, errorAnim, theme.motion.duration.fast, theme.motion.easing.standard]);
312
316
 
313
317
  // Resting border + fill (pre-animation). Error wins over focus when both
@@ -95,12 +95,14 @@ const FloatingActionButton = exports.FloatingActionButton = /*#__PURE__*/(0, _re
95
95
  (0, _index.setNativeValue)(hideAnim, 0);
96
96
  return;
97
97
  }
98
- _reactNative.Animated.timing(hideAnim, {
98
+ const anim = _reactNative.Animated.timing(hideAnim, {
99
99
  toValue: isScrolling ? 1 : 0,
100
100
  duration: theme.motion.duration.normal,
101
101
  easing: _reactNative.Easing.bezier(...theme.motion.easing.standard),
102
102
  useNativeDriver: true
103
- }).start();
103
+ });
104
+ anim.start();
105
+ return () => anim.stop();
104
106
  }, [hideOnScroll, isScrolling, hideAnim, theme.motion.duration.normal, theme.motion.easing.standard]);
105
107
  const hideTranslateY = hideAnim.interpolate({
106
108
  inputRange: [0, 1],
@@ -276,12 +278,13 @@ const FloatingActionButtonGroup = props => {
276
278
  // eslint-disable-next-line react-hooks/exhaustive-deps
277
279
  }, [actions.length]);
278
280
  (0, _react.useEffect)(() => {
279
- _reactNative.Animated.timing(progress, {
281
+ const progressAnim = _reactNative.Animated.timing(progress, {
280
282
  toValue: isOpen ? 1 : 0,
281
283
  duration: theme.motion.duration.normal,
282
284
  easing: _reactNative.Easing.bezier(...theme.motion.easing.standard),
283
285
  useNativeDriver: true
284
- }).start();
286
+ });
287
+ progressAnim.start();
285
288
  const animations = itemAnims.current.map(value => _reactNative.Animated.timing(value, {
286
289
  toValue: isOpen ? 1 : 0,
287
290
  duration: theme.motion.duration.normal,
@@ -290,7 +293,12 @@ const FloatingActionButtonGroup = props => {
290
293
  }));
291
294
  // Reverse stagger order on close so items closest to primary collapse last
292
295
  const ordered = isOpen ? animations : [...animations].reverse();
293
- _reactNative.Animated.stagger(staggerMs, ordered).start();
296
+ const staggerAnim = _reactNative.Animated.stagger(staggerMs, ordered);
297
+ staggerAnim.start();
298
+ return () => {
299
+ progressAnim.stop();
300
+ staggerAnim.stop();
301
+ };
294
302
  }, [isOpen, progress, theme.motion.duration.normal, theme.motion.easing.standard, actions.length, itemAnimsVersion, staggerMs]);
295
303
  const setOpen = (0, _react.useCallback)(next => {
296
304
  if (pressHaptic) (0, _hapticUtils.triggerHaptic)('impactLight');
@@ -7,6 +7,7 @@ exports.default = exports.FormField = void 0;
7
7
  var _react = _interopRequireWildcard(require("react"));
8
8
  var _reactNative = require("react-native");
9
9
  var _index = require("../../theme/index.js");
10
+ var _FormContext = require("../../form/FormContext.js");
10
11
  var _jsxRuntime = require("react/jsx-runtime");
11
12
  function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
12
13
  const FormField = exports.FormField = /*#__PURE__*/(0, _react.forwardRef)((props, ref) => {
@@ -15,6 +16,7 @@ const FormField = exports.FormField = /*#__PURE__*/(0, _react.forwardRef)((props
15
16
  helperText,
16
17
  error,
17
18
  required = false,
19
+ name,
18
20
  children,
19
21
  layout = 'stacked',
20
22
  labelStyle,
@@ -27,19 +29,32 @@ const FormField = exports.FormField = /*#__PURE__*/(0, _react.forwardRef)((props
27
29
  } = props;
28
30
  const theme = (0, _index.useTheme)();
29
31
  const styles = (0, _react.useMemo)(() => buildStyles(theme), [theme]);
30
- const errorOpacity = (0, _react.useRef)((0, _index.createAnimatedValue)(error ? 1 : 0)).current;
32
+ const formCtx = (0, _FormContext.useOptionalFormContext)();
33
+ const isConnected = name != null && formCtx != null;
34
+ const field = isConnected ? formCtx.getFieldProps(name) : null;
35
+ const isRenderProp = typeof children === 'function';
36
+
37
+ // Error the FormField renders itself. When connected to an element child the
38
+ // child (Input/Select etc.) shows the injected error, so FormField stays
39
+ // quiet to avoid a duplicate message; the render-prop form keeps it here.
40
+ const ownError = isConnected ? isRenderProp ? field?.error : undefined : error;
41
+ // Error used purely for assistive tech — always reflects the real error.
42
+ const a11yError = isConnected ? field?.error : error;
43
+ const errorOpacity = (0, _react.useRef)((0, _index.createAnimatedValue)(ownError ? 1 : 0)).current;
31
44
  (0, _react.useEffect)(() => {
32
- _reactNative.Animated.timing(errorOpacity, {
33
- toValue: error ? 1 : 0,
34
- duration: 150,
45
+ const anim = _reactNative.Animated.timing(errorOpacity, {
46
+ toValue: ownError ? 1 : 0,
47
+ duration: theme.motion.duration.fast,
35
48
  useNativeDriver: true
36
- }).start();
37
- }, [error, errorOpacity]);
49
+ });
50
+ anim.start();
51
+ return () => anim.stop();
52
+ }, [ownError, errorOpacity, theme.motion.duration.fast]);
38
53
  const computedAccessibilityLabel = (0, _react.useMemo)(() => {
39
54
  if (accessibilityLabel) return accessibilityLabel;
40
55
  if (!label) return undefined;
41
- return error ? `${label}, error: ${error}` : label;
42
- }, [accessibilityLabel, label, error]);
56
+ return a11yError ? `${label}, error: ${a11yError}` : label;
57
+ }, [accessibilityLabel, label, a11yError]);
43
58
  const labelNode = label ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
44
59
  style: [styles.label, layout === 'inline' ? styles.labelInline : null, labelStyle],
45
60
  children: [label, required ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
@@ -48,39 +63,60 @@ const FormField = exports.FormField = /*#__PURE__*/(0, _react.forwardRef)((props
48
63
  }) : null]
49
64
  }) : null;
50
65
  const inputContainerStyle = layout === 'inline' ? styles.inputInline : styles.inputStacked;
51
- const showError = Boolean(error);
66
+ const showError = Boolean(ownError);
52
67
  const showHelper = !showError && Boolean(helperText);
68
+ const renderedChildren = (() => {
69
+ if (isRenderProp) {
70
+ return field ? children(field) : null;
71
+ }
72
+ if (isConnected && field && /*#__PURE__*/_react.default.isValidElement(children)) {
73
+ const child = children;
74
+ const childOnChangeText = child.props.onChangeText;
75
+ const childOnBlur = child.props.onBlur;
76
+ const childOnFocus = child.props.onFocus;
77
+ return /*#__PURE__*/_react.default.cloneElement(child, {
78
+ value: field.value,
79
+ onChangeText: text => {
80
+ field.onChangeText(text);
81
+ childOnChangeText?.(text);
82
+ },
83
+ onBlur: e => {
84
+ field.onBlur();
85
+ childOnBlur?.(e);
86
+ },
87
+ onFocus: e => {
88
+ field.onFocus();
89
+ childOnFocus?.(e);
90
+ },
91
+ error: field.error,
92
+ ref: node => formCtx.registerField(name, node ?? null)
93
+ });
94
+ }
95
+ return children;
96
+ })();
53
97
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
54
98
  ref: ref,
55
99
  style: [layout === 'inline' ? styles.rootInline : styles.rootStacked, containerStyle],
56
100
  accessibilityLabel: computedAccessibilityLabel
57
- // Surface the invalid state to assistive tech via the hint. RN's
58
- // AccessibilityState type does not expose an `invalid` field, so the
59
- // error message itself is folded into the label and hint.
101
+ // RN's AccessibilityState type has no `invalid` field, so the error is
102
+ // folded into the label and surfaced again via the hint.
60
103
  ,
61
- accessibilityHint: error ? error : undefined,
104
+ accessibilityHint: a11yError ? a11yError : undefined,
62
105
  testID: testID,
63
- children: [layout === 'inline' ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
64
- children: [labelNode, /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
65
- style: [inputContainerStyle, inputContainerStyleProp],
66
- children: children
67
- })]
68
- }) : /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
69
- children: [labelNode, /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
70
- style: [inputContainerStyle, inputContainerStyleProp],
71
- children: children
72
- })]
106
+ children: [labelNode, /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
107
+ style: [inputContainerStyle, inputContainerStyleProp],
108
+ children: renderedChildren
73
109
  }), showHelper ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
74
110
  style: [styles.helper, helperStyle],
75
111
  numberOfLines: 2,
76
112
  children: helperText
77
- }) : null, error ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Animated.Text, {
113
+ }) : null, ownError ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Animated.Text, {
78
114
  style: [styles.error, {
79
115
  opacity: errorOpacity
80
116
  }, errorStyle],
81
117
  numberOfLines: 2,
82
118
  accessibilityLiveRegion: "polite",
83
- children: error
119
+ children: ownError
84
120
  }) : null]
85
121
  });
86
122
  });
@@ -8,6 +8,7 @@ var _react = _interopRequireWildcard(require("react"));
8
8
  var _reactNative = require("react-native");
9
9
  var _index = require("../../theme/index.js");
10
10
  var _index2 = require("../../utils/index.js");
11
+ var _index3 = require("../../hooks/index.js");
11
12
  var _FieldBase = require("../FieldBase/FieldBase.js");
12
13
  var _jsxRuntime = require("react/jsx-runtime");
13
14
  function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
@@ -84,26 +85,31 @@ const Input = exports.Input = /*#__PURE__*/(0, _react.forwardRef)((props, ref) =
84
85
 
85
86
  // Floating label animation
86
87
  (0, _react.useEffect)(() => {
87
- _reactNative.Animated.timing(labelAnim, {
88
+ const anim = _reactNative.Animated.timing(labelAnim, {
88
89
  toValue: shouldFloat ? 1 : 0,
89
90
  duration: theme.motion.duration.fast,
90
91
  easing: _reactNative.Easing.bezier(...theme.motion.easing.standard),
91
92
  useNativeDriver: false
92
- }).start();
93
+ });
94
+ anim.start();
95
+ return () => anim.stop();
93
96
  }, [shouldFloat, labelAnim, theme.motion.duration.fast, theme.motion.easing.standard]);
94
97
 
95
98
  // Helper / error fade
96
99
  (0, _react.useEffect)(() => {
97
- _reactNative.Animated.timing(messageAnim, {
100
+ const anim = _reactNative.Animated.timing(messageAnim, {
98
101
  toValue: hasError || Boolean(helperText) ? 1 : 0,
99
- duration: 150,
102
+ duration: theme.motion.duration.fast,
100
103
  easing: _reactNative.Easing.bezier(...theme.motion.easing.standard),
101
104
  useNativeDriver: true
102
- }).start();
103
- }, [hasError, helperText, messageAnim, theme.motion.easing.standard]);
105
+ });
106
+ anim.start();
107
+ return () => anim.stop();
108
+ }, [hasError, helperText, messageAnim, theme.motion.duration.fast, theme.motion.easing.standard]);
104
109
 
105
110
  // Error shake — off by default; consumers opt in via
106
111
  // theme.components.input.shakeOnError. The haptic ships with the shake.
112
+ const reduceMotion = (0, _index3.useReducedMotion)();
107
113
  const shakeOnError = theme.components.input?.shakeOnError ?? false;
108
114
  const prevErrorRef = (0, _react.useRef)(hasError);
109
115
  (0, _react.useEffect)(() => {
@@ -111,33 +117,39 @@ const Input = exports.Input = /*#__PURE__*/(0, _react.forwardRef)((props, ref) =
111
117
  prevErrorRef.current = hasError;
112
118
  return;
113
119
  }
120
+ let anim;
114
121
  if (hasError && !prevErrorRef.current) {
115
- (0, _index.setNativeValue)(shakeAnim, 0);
116
- _reactNative.Animated.sequence([_reactNative.Animated.timing(shakeAnim, {
117
- toValue: 1,
118
- duration: 50,
119
- useNativeDriver: true
120
- }), _reactNative.Animated.timing(shakeAnim, {
121
- toValue: -1,
122
- duration: 50,
123
- useNativeDriver: true
124
- }), _reactNative.Animated.timing(shakeAnim, {
125
- toValue: 1,
126
- duration: 50,
127
- useNativeDriver: true
128
- }), _reactNative.Animated.timing(shakeAnim, {
129
- toValue: -1,
130
- duration: 50,
131
- useNativeDriver: true
132
- }), _reactNative.Animated.timing(shakeAnim, {
133
- toValue: 0,
134
- duration: 100,
135
- useNativeDriver: true
136
- })]).start();
122
+ // Reduce Motion: keep the error haptic, skip the shake.
123
+ if (!reduceMotion) {
124
+ (0, _index.setNativeValue)(shakeAnim, 0);
125
+ anim = _reactNative.Animated.sequence([_reactNative.Animated.timing(shakeAnim, {
126
+ toValue: 1,
127
+ duration: 50,
128
+ useNativeDriver: true
129
+ }), _reactNative.Animated.timing(shakeAnim, {
130
+ toValue: -1,
131
+ duration: 50,
132
+ useNativeDriver: true
133
+ }), _reactNative.Animated.timing(shakeAnim, {
134
+ toValue: 1,
135
+ duration: 50,
136
+ useNativeDriver: true
137
+ }), _reactNative.Animated.timing(shakeAnim, {
138
+ toValue: -1,
139
+ duration: 50,
140
+ useNativeDriver: true
141
+ }), _reactNative.Animated.timing(shakeAnim, {
142
+ toValue: 0,
143
+ duration: 100,
144
+ useNativeDriver: true
145
+ })]);
146
+ anim.start();
147
+ }
137
148
  (0, _index2.triggerHaptic)('notificationError');
138
149
  }
139
150
  prevErrorRef.current = hasError;
140
- }, [hasError, shakeAnim, shakeOnError]);
151
+ return () => anim?.stop();
152
+ }, [hasError, shakeAnim, shakeOnError, reduceMotion]);
141
153
  const handleFocus = (0, _react.useCallback)(e => {
142
154
  setIsFocused(true);
143
155
  onFocus?.(e);
@@ -0,0 +1,102 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = exports.KeyboardAwareScrollView = void 0;
7
+ var _react = _interopRequireWildcard(require("react"));
8
+ var _reactNative = require("react-native");
9
+ var _jsxRuntime = require("react/jsx-runtime");
10
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
11
+ /**
12
+ * A ScrollView that keeps the focused input visible above the keyboard — no
13
+ * native dependency. On keyboard show it pads the content by the keyboard
14
+ * height and scrolls the focused TextInput so its bottom sits `extraScrollHeight`
15
+ * above the keyboard, but only when it would otherwise be covered (so already-
16
+ * visible fields don't jump). The classic measure-and-scroll approach, in pure RN.
17
+ */
18
+ const KeyboardAwareScrollView = exports.KeyboardAwareScrollView = /*#__PURE__*/(0, _react.forwardRef)((props, ref) => {
19
+ const {
20
+ children,
21
+ extraScrollHeight = 24,
22
+ disabled = false,
23
+ contentContainerStyle,
24
+ onScroll,
25
+ onLayout,
26
+ ...rest
27
+ } = props;
28
+ const scrollRef = (0, _react.useRef)(null);
29
+ const scrollYRef = (0, _react.useRef)(0);
30
+ const viewportHeightRef = (0, _react.useRef)(0);
31
+ const [keyboardHeight, setKeyboardHeight] = (0, _react.useState)(0);
32
+ const setRefs = (0, _react.useCallback)(node => {
33
+ scrollRef.current = node;
34
+ if (typeof ref === 'function') ref(node);else if (ref) ref.current = node;
35
+ }, [ref]);
36
+ const scrollFocusedIntoView = (0, _react.useCallback)(kbHeight => {
37
+ const scroll = scrollRef.current;
38
+ const scrollNode = scroll ? (0, _reactNative.findNodeHandle)(scroll) : null;
39
+ const stateApi = _reactNative.TextInput?.State;
40
+ const focused = stateApi?.currentlyFocusedInput?.();
41
+ if (!scroll || scrollNode == null || !focused?.measureLayout) return;
42
+ focused.measureLayout(scrollNode, (_left, top, _width, height) => {
43
+ const scrollY = scrollYRef.current;
44
+ const viewportH = viewportHeightRef.current;
45
+ if (viewportH <= 0) return;
46
+ const keyboardTop = viewportH - kbHeight - extraScrollHeight;
47
+ const fieldBottomInViewport = top - scrollY + height;
48
+ if (fieldBottomInViewport > keyboardTop) {
49
+ const delta = fieldBottomInViewport - keyboardTop;
50
+ scroll.scrollTo({
51
+ y: scrollY + delta,
52
+ animated: true
53
+ });
54
+ }
55
+ }, () => undefined);
56
+ }, [extraScrollHeight]);
57
+ (0, _react.useEffect)(() => {
58
+ if (disabled) return undefined;
59
+ // iOS exposes the will* events (smoother); Android only fires did*.
60
+ const showEvent = _reactNative.Platform.OS === 'ios' ? 'keyboardWillShow' : 'keyboardDidShow';
61
+ const hideEvent = _reactNative.Platform.OS === 'ios' ? 'keyboardWillHide' : 'keyboardDidHide';
62
+ let rafId;
63
+ const showSub = _reactNative.Keyboard.addListener(showEvent, e => {
64
+ const height = e.endCoordinates?.height ?? 0;
65
+ setKeyboardHeight(height);
66
+ // Wait a frame so the padding is applied before we scroll. Tracked so
67
+ // it can be cancelled on unmount (never runs against a torn-down tree).
68
+ if (rafId != null) cancelAnimationFrame(rafId);
69
+ rafId = requestAnimationFrame(() => scrollFocusedIntoView(height));
70
+ });
71
+ const hideSub = _reactNative.Keyboard.addListener(hideEvent, () => setKeyboardHeight(0));
72
+ return () => {
73
+ if (rafId != null) cancelAnimationFrame(rafId);
74
+ showSub.remove();
75
+ hideSub.remove();
76
+ };
77
+ }, [disabled, scrollFocusedIntoView]);
78
+ const handleScroll = (0, _react.useCallback)(e => {
79
+ scrollYRef.current = e.nativeEvent.contentOffset.y;
80
+ onScroll?.(e);
81
+ }, [onScroll]);
82
+ const handleLayout = (0, _react.useCallback)(e => {
83
+ viewportHeightRef.current = e.nativeEvent.layout.height;
84
+ onLayout?.(e);
85
+ }, [onLayout]);
86
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.ScrollView, {
87
+ ref: setRefs,
88
+ onScroll: handleScroll,
89
+ onLayout: handleLayout,
90
+ scrollEventThrottle: 16,
91
+ keyboardShouldPersistTaps: "handled",
92
+ keyboardDismissMode: _reactNative.Platform.OS === 'ios' ? 'interactive' : 'on-drag',
93
+ contentContainerStyle: [contentContainerStyle, {
94
+ paddingBottom: keyboardHeight
95
+ }],
96
+ ...rest,
97
+ children: children
98
+ });
99
+ });
100
+ KeyboardAwareScrollView.displayName = 'KeyboardAwareScrollView';
101
+ var _default = exports.default = KeyboardAwareScrollView;
102
+ //# sourceMappingURL=KeyboardAwareScrollView.js.map
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ Object.defineProperty(exports, "KeyboardAwareScrollView", {
7
+ enumerable: true,
8
+ get: function () {
9
+ return _KeyboardAwareScrollView.KeyboardAwareScrollView;
10
+ }
11
+ });
12
+ var _KeyboardAwareScrollView = require("./KeyboardAwareScrollView.js");
13
+ //# sourceMappingURL=index.js.map