@webority-technologies/mobile 0.0.7 → 0.0.9

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 (105) hide show
  1. package/lib/commonjs/components/Accordion/Accordion.js +3 -3
  2. package/lib/commonjs/components/Avatar/Avatar.js +1 -1
  3. package/lib/commonjs/components/Badge/Badge.js +24 -14
  4. package/lib/commonjs/components/Banner/Banner.js +2 -2
  5. package/lib/commonjs/components/BottomNavigation/BottomNavigation.js +1 -1
  6. package/lib/commonjs/components/BottomSheet/BottomSheet.js +39 -5
  7. package/lib/commonjs/components/Button/Button.js +25 -6
  8. package/lib/commonjs/components/Card/Card.js +13 -1
  9. package/lib/commonjs/components/Carousel/Carousel.js +2 -2
  10. package/lib/commonjs/components/Checkbox/Checkbox.js +6 -4
  11. package/lib/commonjs/components/Chip/Chip.js +12 -3
  12. package/lib/commonjs/components/DatePicker/DatePicker.js +8 -8
  13. package/lib/commonjs/components/DateRangePicker/DateRangePicker.js +4 -4
  14. package/lib/commonjs/components/Dialog/Dialog.js +15 -8
  15. package/lib/commonjs/components/EmptyState/EmptyState.js +32 -26
  16. package/lib/commonjs/components/FloatingActionButton/FloatingActionButton.js +2 -2
  17. package/lib/commonjs/components/FormField/FormField.js +4 -4
  18. package/lib/commonjs/components/Input/Input.js +18 -10
  19. package/lib/commonjs/components/ListItem/ListItem.js +33 -27
  20. package/lib/commonjs/components/Modal/Modal.js +4 -4
  21. package/lib/commonjs/components/OTPInput/OTPInput.js +7 -4
  22. package/lib/commonjs/components/ProgressBar/ProgressBar.js +2 -2
  23. package/lib/commonjs/components/Radio/Radio.js +8 -7
  24. package/lib/commonjs/components/SearchBar/SearchBar.js +10 -6
  25. package/lib/commonjs/components/SegmentedControl/SegmentedControl.js +2 -2
  26. package/lib/commonjs/components/Select/Select.js +3 -3
  27. package/lib/commonjs/components/Skeleton/Skeleton.js +1 -1
  28. package/lib/commonjs/components/Slider/Slider.js +6 -6
  29. package/lib/commonjs/components/Spinner/Spinner.js +2 -2
  30. package/lib/commonjs/components/Stepper/Stepper.js +3 -3
  31. package/lib/commonjs/components/Switch/Switch.js +33 -4
  32. package/lib/commonjs/components/Tabs/Tabs.js +2 -2
  33. package/lib/commonjs/components/TimePicker/TimePicker.js +3 -3
  34. package/lib/commonjs/components/Toast/Toast.js +19 -14
  35. package/lib/commonjs/components/Tooltip/Tooltip.js +2 -2
  36. package/lib/commonjs/theme/Gradient.js +57 -0
  37. package/lib/commonjs/theme/animatedValue.js +28 -0
  38. package/lib/commonjs/theme/index.js +27 -0
  39. package/lib/commonjs/theme/textStyle.js +37 -0
  40. package/lib/commonjs/theme/tokens.js +260 -2
  41. package/lib/module/components/Accordion/Accordion.js +4 -4
  42. package/lib/module/components/Avatar/Avatar.js +2 -2
  43. package/lib/module/components/Badge/Badge.js +25 -15
  44. package/lib/module/components/Banner/Banner.js +3 -3
  45. package/lib/module/components/BottomNavigation/BottomNavigation.js +2 -2
  46. package/lib/module/components/BottomSheet/BottomSheet.js +40 -6
  47. package/lib/module/components/Button/Button.js +26 -7
  48. package/lib/module/components/Card/Card.js +14 -2
  49. package/lib/module/components/Carousel/Carousel.js +3 -3
  50. package/lib/module/components/Checkbox/Checkbox.js +7 -5
  51. package/lib/module/components/Chip/Chip.js +13 -4
  52. package/lib/module/components/DatePicker/DatePicker.js +9 -9
  53. package/lib/module/components/DateRangePicker/DateRangePicker.js +5 -5
  54. package/lib/module/components/Dialog/Dialog.js +16 -9
  55. package/lib/module/components/EmptyState/EmptyState.js +33 -27
  56. package/lib/module/components/FloatingActionButton/FloatingActionButton.js +3 -3
  57. package/lib/module/components/FormField/FormField.js +5 -5
  58. package/lib/module/components/Input/Input.js +19 -11
  59. package/lib/module/components/ListItem/ListItem.js +34 -28
  60. package/lib/module/components/Modal/Modal.js +5 -5
  61. package/lib/module/components/OTPInput/OTPInput.js +8 -5
  62. package/lib/module/components/ProgressBar/ProgressBar.js +3 -3
  63. package/lib/module/components/Radio/Radio.js +9 -8
  64. package/lib/module/components/SearchBar/SearchBar.js +11 -7
  65. package/lib/module/components/SegmentedControl/SegmentedControl.js +3 -3
  66. package/lib/module/components/Select/Select.js +4 -4
  67. package/lib/module/components/Skeleton/Skeleton.js +2 -2
  68. package/lib/module/components/Slider/Slider.js +7 -7
  69. package/lib/module/components/Spinner/Spinner.js +3 -3
  70. package/lib/module/components/Stepper/Stepper.js +4 -4
  71. package/lib/module/components/Switch/Switch.js +34 -5
  72. package/lib/module/components/Tabs/Tabs.js +3 -3
  73. package/lib/module/components/TimePicker/TimePicker.js +4 -4
  74. package/lib/module/components/Toast/Toast.js +20 -15
  75. package/lib/module/components/Tooltip/Tooltip.js +3 -3
  76. package/lib/module/theme/Gradient.js +50 -0
  77. package/lib/module/theme/animatedValue.js +24 -0
  78. package/lib/module/theme/index.js +3 -0
  79. package/lib/module/theme/textStyle.js +32 -0
  80. package/lib/module/theme/tokens.js +260 -2
  81. package/lib/typescript/commonjs/components/BottomSheet/BottomSheet.d.ts +10 -0
  82. package/lib/typescript/commonjs/components/Button/Button.d.ts +8 -0
  83. package/lib/typescript/commonjs/components/Card/Card.d.ts +8 -0
  84. package/lib/typescript/commonjs/components/Dialog/Dialog.d.ts +5 -0
  85. package/lib/typescript/commonjs/components/Input/Input.d.ts +12 -0
  86. package/lib/typescript/commonjs/components/Switch/Switch.d.ts +5 -0
  87. package/lib/typescript/commonjs/components/Toast/Toast.d.ts +5 -0
  88. package/lib/typescript/commonjs/theme/Gradient.d.ts +11 -0
  89. package/lib/typescript/commonjs/theme/animatedValue.d.ts +21 -0
  90. package/lib/typescript/commonjs/theme/index.d.ts +6 -1
  91. package/lib/typescript/commonjs/theme/textStyle.d.ts +18 -0
  92. package/lib/typescript/commonjs/theme/types.d.ts +178 -0
  93. package/lib/typescript/module/components/BottomSheet/BottomSheet.d.ts +10 -0
  94. package/lib/typescript/module/components/Button/Button.d.ts +8 -0
  95. package/lib/typescript/module/components/Card/Card.d.ts +8 -0
  96. package/lib/typescript/module/components/Dialog/Dialog.d.ts +5 -0
  97. package/lib/typescript/module/components/Input/Input.d.ts +12 -0
  98. package/lib/typescript/module/components/Switch/Switch.d.ts +5 -0
  99. package/lib/typescript/module/components/Toast/Toast.d.ts +5 -0
  100. package/lib/typescript/module/theme/Gradient.d.ts +11 -0
  101. package/lib/typescript/module/theme/animatedValue.d.ts +21 -0
  102. package/lib/typescript/module/theme/index.d.ts +6 -1
  103. package/lib/typescript/module/theme/textStyle.d.ts +18 -0
  104. package/lib/typescript/module/theme/types.d.ts +178 -0
  105. package/package.json +5 -1
@@ -2,7 +2,7 @@
2
2
 
3
3
  import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
4
4
  import { AccessibilityInfo, Animated, Easing, FlatList, Modal, Platform, Pressable, StyleSheet, Text, View } from 'react-native';
5
- import { useTheme } from "../../theme/index.js";
5
+ import { useTheme, createAnimatedValue } from "../../theme/index.js";
6
6
  import { triggerHaptic } from "../../utils/hapticUtils.js";
7
7
  import Button from "../Button/Button.js";
8
8
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
@@ -59,7 +59,7 @@ const Wheel = ({
59
59
  testID
60
60
  }) => {
61
61
  const listRef = useRef(null);
62
- const scrollY = useRef(new Animated.Value(selectedIndex * ITEM_HEIGHT)).current;
62
+ const scrollY = useRef(createAnimatedValue(selectedIndex * ITEM_HEIGHT)).current;
63
63
  const lastIndexRef = useRef(selectedIndex);
64
64
  const lastHapticAtRef = useRef(0);
65
65
 
@@ -258,8 +258,8 @@ const TimePicker = ({
258
258
  }, [visible, value, format, minuteStep, hours, minutes]);
259
259
 
260
260
  // Sheet animations.
261
- const opacity = useRef(new Animated.Value(0)).current;
262
- const translateY = useRef(new Animated.Value(40)).current;
261
+ const opacity = useRef(createAnimatedValue(0)).current;
262
+ const translateY = useRef(createAnimatedValue(40)).current;
263
263
  useEffect(() => {
264
264
  if (visible) {
265
265
  Animated.parallel([Animated.timing(opacity, {
@@ -2,7 +2,7 @@
2
2
 
3
3
  import React, { useEffect, useMemo, useRef } from 'react';
4
4
  import { Animated, PanResponder, Pressable, StyleSheet, Text, View } from 'react-native';
5
- import { useTheme } from "../../theme/index.js";
5
+ import { fontFor, useTheme, createAnimatedValue } from "../../theme/index.js";
6
6
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
7
7
  const SWIPE_DISMISS_THRESHOLD = 80;
8
8
  const SWIPE_VELOCITY_THRESHOLD = 0.5;
@@ -18,10 +18,15 @@ const Toast = ({
18
18
  const position = toast.position ?? 'bottom';
19
19
  const styles = useMemo(() => buildStyles(theme), [theme]);
20
20
  const tint = useMemo(() => tintFor(theme, variant), [theme, variant]);
21
+ const toastTokens = theme.components.toast;
22
+ const iconCircleSize = toastTokens?.iconCircleSize ?? 28;
23
+ const iconCircleBorderRadius = toastTokens?.iconCircleBorderRadius ?? 14;
24
+ const iconGlyphFontSize = toastTokens?.iconGlyphFontSize ?? 16;
25
+ const tintBarWidth = toastTokens?.tintBarWidth ?? 4;
21
26
  const enterFrom = position === 'top' ? -120 : 120;
22
- const translateY = useRef(new Animated.Value(enterFrom)).current;
23
- const translateX = useRef(new Animated.Value(0)).current;
24
- const opacity = useRef(new Animated.Value(0)).current;
27
+ const translateY = useRef(createAnimatedValue(enterFrom)).current;
28
+ const translateX = useRef(createAnimatedValue(0)).current;
29
+ const opacity = useRef(createAnimatedValue(0)).current;
25
30
  const dismissedRef = useRef(false);
26
31
  const dismiss = (animateOut = true) => {
27
32
  if (dismissedRef.current) return;
@@ -107,11 +112,15 @@ const Toast = ({
107
112
  if (!glyph) return null;
108
113
  return /*#__PURE__*/_jsx(View, {
109
114
  style: [styles.iconCircle, {
115
+ width: iconCircleSize,
116
+ height: iconCircleSize,
117
+ borderRadius: iconCircleBorderRadius,
110
118
  backgroundColor: tint + '22'
111
119
  }],
112
120
  children: /*#__PURE__*/_jsx(Text, {
113
121
  style: [styles.iconGlyph, {
114
- color: tint
122
+ color: tint,
123
+ fontSize: iconGlyphFontSize
115
124
  }],
116
125
  accessible: false,
117
126
  children: glyph
@@ -138,9 +147,10 @@ const Toast = ({
138
147
  }, {
139
148
  scale: stackScale
140
149
  }]
141
- }],
150
+ }, toast.style],
142
151
  children: [/*#__PURE__*/_jsx(View, {
143
152
  style: [styles.tintBar, {
153
+ width: tintBarWidth,
144
154
  backgroundColor: tint
145
155
  }]
146
156
  }), /*#__PURE__*/_jsxs(View, {
@@ -151,8 +161,8 @@ const Toast = ({
151
161
  style: [styles.message, {
152
162
  color: theme.colors.text.primary,
153
163
  fontSize: theme.typography.fontSize.base,
154
- fontWeight: theme.typography.fontWeight.semibold
155
- }],
164
+ ...fontFor(theme, 'semibold')
165
+ }, toast.textStyle],
156
166
  numberOfLines: 2,
157
167
  children: toast.message
158
168
  }), toast.description ? /*#__PURE__*/_jsx(Text, {
@@ -176,7 +186,7 @@ const Toast = ({
176
186
  style: {
177
187
  color: tint,
178
188
  fontSize: theme.typography.fontSize.sm,
179
- fontWeight: theme.typography.fontWeight.semibold
189
+ ...fontFor(theme, 'semibold')
180
190
  },
181
191
  numberOfLines: 1,
182
192
  children: toast.action.label
@@ -224,8 +234,7 @@ const buildStyles = _theme => StyleSheet.create({
224
234
  position: 'absolute',
225
235
  left: 0,
226
236
  top: 0,
227
- bottom: 0,
228
- width: 4
237
+ bottom: 0
229
238
  },
230
239
  row: {
231
240
  flexDirection: 'row',
@@ -233,15 +242,11 @@ const buildStyles = _theme => StyleSheet.create({
233
242
  paddingLeft: 8
234
243
  },
235
244
  iconCircle: {
236
- width: 28,
237
- height: 28,
238
- borderRadius: 14,
239
245
  alignItems: 'center',
240
246
  justifyContent: 'center',
241
247
  marginRight: 12
242
248
  },
243
249
  iconGlyph: {
244
- fontSize: 16,
245
250
  fontWeight: '700',
246
251
  lineHeight: 18
247
252
  },
@@ -2,7 +2,7 @@
2
2
 
3
3
  import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
4
4
  import { Animated, Dimensions, Modal, Pressable, StyleSheet, Text, View } from 'react-native';
5
- import { useTheme } from "../../theme/index.js";
5
+ import { useTheme, createAnimatedValue } from "../../theme/index.js";
6
6
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
7
7
  const TOOLTIP_GAP = 8;
8
8
  const SCREEN_PADDING = 8;
@@ -36,8 +36,8 @@ const Tooltip = props => {
36
36
  height: 0
37
37
  });
38
38
  const wrapperRef = useRef(null);
39
- const scale = useRef(new Animated.Value(visible ? 1 : 0.85)).current;
40
- const opacity = useRef(new Animated.Value(visible ? 1 : 0)).current;
39
+ const scale = useRef(createAnimatedValue(visible ? 1 : 0.85)).current;
40
+ const opacity = useRef(createAnimatedValue(visible ? 1 : 0)).current;
41
41
  const autoHideTimer = useRef(null);
42
42
  const didMount = useRef(false);
43
43
  const setVisible = useCallback(next => {
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+
3
+ import React from 'react';
4
+ import { View } from 'react-native';
5
+ import { jsx as _jsx } from "react/jsx-runtime";
6
+ /**
7
+ * Render a linear gradient using `react-native-linear-gradient` when available.
8
+ *
9
+ * The dep is OPTIONAL — apps that never use gradients don't need it installed.
10
+ * If `<Gradient>` (or any component that accepts a `gradient` prop) is reached
11
+ * without the package present, we fall back to a flat View using the first
12
+ * colour and emit a one-time dev warning so the omission is loud but
13
+ * non-fatal.
14
+ */
15
+ let LinearGradientImpl = null;
16
+ let warned = false;
17
+ try {
18
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
19
+ LinearGradientImpl = require('react-native-linear-gradient').default;
20
+ } catch {
21
+ // Optional peer; resolved lazily by consumers that need gradients.
22
+ }
23
+ export const Gradient = ({
24
+ gradient,
25
+ style,
26
+ children
27
+ }) => {
28
+ if (LinearGradientImpl) {
29
+ return /*#__PURE__*/_jsx(LinearGradientImpl, {
30
+ colors: gradient.colors,
31
+ locations: gradient.locations,
32
+ start: gradient.start,
33
+ end: gradient.end,
34
+ style: style,
35
+ children: children
36
+ });
37
+ }
38
+ if (__DEV__ && !warned) {
39
+ warned = true;
40
+ console.warn('[@webority-technologies/mobile] gradient prop set but react-native-linear-gradient is not installed. ' + 'Run `npm install react-native-linear-gradient` to enable.');
41
+ }
42
+ return /*#__PURE__*/_jsx(View, {
43
+ style: [{
44
+ backgroundColor: gradient.colors[0]
45
+ }, style],
46
+ children: children
47
+ });
48
+ };
49
+ export const isGradientAvailable = () => LinearGradientImpl != null;
50
+ //# sourceMappingURL=Gradient.js.map
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+
3
+ import { Animated } from 'react-native';
4
+
5
+ /**
6
+ * Create an `Animated.Value` that survives RN 0.85's dev-mode prop deepFreeze.
7
+ *
8
+ * RN's Fabric renderer deep-freezes prop trees on host components. If an
9
+ * `Animated.Value` is reachable from a `style` prop via interpolation chains
10
+ * (the `_parent` ref on `AnimatedInterpolation` nodes), the recursive freeze
11
+ * converts the value's `_animation` slot into a throwing setter — the next
12
+ * `Animated.timing(v).start()` then crashes with
13
+ * "_animation: object that is meant to be immutable".
14
+ *
15
+ * Sealing the value at construction makes `Object.isSealed(v) === true`,
16
+ * which causes `deepFreezeAndThrowOnMutationInDev` to skip-and-return at
17
+ * its top guard. Existing-property mutation (`_animation`, `_value`,
18
+ * `_listeners`, `_tracking`) keeps working — seal only blocks adding NEW
19
+ * properties, and `Animated.Value` doesn't add any post-construction.
20
+ *
21
+ * Use everywhere the library would otherwise call `new Animated.Value(...)`.
22
+ */
23
+ export const createAnimatedValue = (initial, config) => Object.seal(new Animated.Value(initial, config));
24
+ //# sourceMappingURL=animatedValue.js.map
@@ -45,4 +45,7 @@ export const subscribeTheme = callback => {
45
45
  export { ThemeProvider, useTheme, useThemeMode } from "./ThemeContext.js";
46
46
  export { lightTheme, darkTheme } from "./tokens.js";
47
47
  export { mergeTheme } from "./merge.js";
48
+ export { fontFor } from "./textStyle.js";
49
+ export { createAnimatedValue } from "./animatedValue.js";
50
+ export { Gradient, isGradientAvailable } from "./Gradient.js";
48
51
  //# sourceMappingURL=index.js.map
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+
3
+ const FAMILY_KEY = {
4
+ normal: 'regular',
5
+ medium: 'medium',
6
+ semibold: 'semibold',
7
+ bold: 'bold'
8
+ };
9
+
10
+ /**
11
+ * Resolve text-weight style for the active theme.
12
+ *
13
+ * When the consumer registers a brand `theme.typography.fontFamily.<weight>`,
14
+ * we set `fontFamily` and leave `fontWeight` undefined — RN can't combine the
15
+ * two reliably across iOS/Android once a custom face is in play, so the brand
16
+ * file controls the weight glyph itself. Falls back to `fontWeight` when no
17
+ * brand font is registered for that weight.
18
+ *
19
+ * Note: the fontWeight scale uses `normal` while FontFamilyScale uses
20
+ * `regular` (the conventional font-name suffix). The helper maps between
21
+ * them transparently.
22
+ */
23
+ export const fontFor = (theme, weight) => {
24
+ const family = theme.typography.fontFamily?.[FAMILY_KEY[weight]];
25
+ if (family) return {
26
+ fontFamily: family
27
+ };
28
+ return {
29
+ fontWeight: theme.typography.fontWeight[weight]
30
+ };
31
+ };
32
+ //# sourceMappingURL=textStyle.js.map
@@ -50,6 +50,260 @@ const radius = {
50
50
  '2xl': 28,
51
51
  full: 9999
52
52
  };
53
+ const components = {
54
+ button: {
55
+ xs: {
56
+ paddingHorizontal: 10,
57
+ paddingVertical: 4,
58
+ minHeight: 28,
59
+ fontSize: 12,
60
+ borderRadius: 8
61
+ },
62
+ sm: {
63
+ paddingHorizontal: 12,
64
+ paddingVertical: 6,
65
+ minHeight: 34,
66
+ fontSize: 13,
67
+ borderRadius: 10
68
+ },
69
+ md: {
70
+ paddingHorizontal: 16,
71
+ paddingVertical: 9,
72
+ minHeight: 42,
73
+ fontSize: 15,
74
+ borderRadius: 12
75
+ },
76
+ lg: {
77
+ paddingHorizontal: 20,
78
+ paddingVertical: 12,
79
+ minHeight: 50,
80
+ fontSize: 16,
81
+ borderRadius: 14
82
+ },
83
+ xl: {
84
+ paddingHorizontal: 24,
85
+ paddingVertical: 14,
86
+ minHeight: 58,
87
+ fontSize: 17,
88
+ borderRadius: 16
89
+ }
90
+ },
91
+ input: {
92
+ sm: {
93
+ paddingHorizontal: 12,
94
+ paddingVertical: 8,
95
+ minHeight: 38,
96
+ multilineMinHeight: 72,
97
+ fontSize: 13,
98
+ borderRadius: 10,
99
+ iconSize: 16
100
+ },
101
+ md: {
102
+ paddingHorizontal: 14,
103
+ paddingVertical: 11,
104
+ minHeight: 46,
105
+ multilineMinHeight: 92,
106
+ fontSize: 15,
107
+ borderRadius: 12,
108
+ iconSize: 18
109
+ },
110
+ lg: {
111
+ paddingHorizontal: 16,
112
+ paddingVertical: 14,
113
+ minHeight: 54,
114
+ multilineMinHeight: 110,
115
+ fontSize: 16,
116
+ borderRadius: 14,
117
+ iconSize: 20
118
+ }
119
+ },
120
+ searchBar: {
121
+ sm: {
122
+ height: 36,
123
+ paddingHorizontal: 10,
124
+ fontSize: 13,
125
+ iconSize: 16,
126
+ gap: 6
127
+ },
128
+ md: {
129
+ height: 44,
130
+ paddingHorizontal: 12,
131
+ fontSize: 15,
132
+ iconSize: 18,
133
+ gap: 8
134
+ },
135
+ lg: {
136
+ height: 52,
137
+ paddingHorizontal: 14,
138
+ fontSize: 16,
139
+ iconSize: 20,
140
+ gap: 10
141
+ },
142
+ cancelButtonWidth: 72
143
+ },
144
+ emptyState: {
145
+ sm: {
146
+ iconSize: 48,
147
+ titleFontSize: 'lg',
148
+ descriptionFontSize: 'sm',
149
+ paddingVertical: 'lg'
150
+ },
151
+ md: {
152
+ iconSize: 64,
153
+ titleFontSize: 'xl',
154
+ descriptionFontSize: 'base',
155
+ paddingVertical: 'xl'
156
+ },
157
+ lg: {
158
+ iconSize: 80,
159
+ titleFontSize: '2xl',
160
+ descriptionFontSize: 'base',
161
+ paddingVertical: '2xl'
162
+ }
163
+ },
164
+ listItem: {
165
+ sm: {
166
+ paddingVertical: 'sm',
167
+ titleFontSize: 'sm',
168
+ subtitleFontSize: 'xs',
169
+ minHeight: 44
170
+ },
171
+ md: {
172
+ paddingVertical: 'md',
173
+ titleFontSize: 'base',
174
+ subtitleFontSize: 'sm',
175
+ minHeight: 56
176
+ },
177
+ lg: {
178
+ paddingVertical: 'lg',
179
+ titleFontSize: 'lg',
180
+ subtitleFontSize: 'sm',
181
+ minHeight: 72
182
+ }
183
+ },
184
+ badge: {
185
+ sm: {
186
+ fontSize: 10,
187
+ minWidth: 16,
188
+ height: 16,
189
+ paddingHorizontal: 5,
190
+ dotSize: 8
191
+ },
192
+ md: {
193
+ fontSize: 11,
194
+ minWidth: 20,
195
+ height: 20,
196
+ paddingHorizontal: 6,
197
+ dotSize: 10
198
+ },
199
+ borderWidth: 1.5,
200
+ anchorOffset: 4
201
+ },
202
+ chip: {
203
+ sm: {
204
+ paddingHorizontal: 10,
205
+ paddingVertical: 4,
206
+ fontSize: 12,
207
+ minHeight: 26,
208
+ closeSize: 16,
209
+ closeFontSize: 12,
210
+ gap: 6
211
+ },
212
+ md: {
213
+ paddingHorizontal: 12,
214
+ paddingVertical: 6,
215
+ fontSize: 13,
216
+ minHeight: 32,
217
+ closeSize: 18,
218
+ closeFontSize: 13,
219
+ gap: 8
220
+ }
221
+ },
222
+ checkbox: {
223
+ sm: {
224
+ boxSize: 16
225
+ },
226
+ md: {
227
+ boxSize: 20
228
+ },
229
+ lg: {
230
+ boxSize: 24
231
+ },
232
+ borderWidth: 1.5,
233
+ labelGap: 10
234
+ },
235
+ radio: {
236
+ sm: {
237
+ outer: 16,
238
+ inner: 8
239
+ },
240
+ md: {
241
+ outer: 20,
242
+ inner: 10
243
+ },
244
+ lg: {
245
+ outer: 24,
246
+ inner: 12
247
+ },
248
+ borderWidth: 1.5,
249
+ labelGap: 10
250
+ },
251
+ switch: {
252
+ sm: {
253
+ trackWidth: 42,
254
+ trackHeight: 26,
255
+ thumbSize: 22,
256
+ padding: 2
257
+ },
258
+ md: {
259
+ trackWidth: 51,
260
+ trackHeight: 31,
261
+ thumbSize: 27,
262
+ padding: 2
263
+ },
264
+ lg: {
265
+ trackWidth: 60,
266
+ trackHeight: 36,
267
+ thumbSize: 32,
268
+ padding: 2
269
+ },
270
+ thumbColor: '#FFFFFF'
271
+ },
272
+ otpInput: {
273
+ sm: {
274
+ cell: 36,
275
+ fontSize: 16,
276
+ borderRadius: 8,
277
+ gap: 8
278
+ },
279
+ md: {
280
+ cell: 48,
281
+ fontSize: 20,
282
+ borderRadius: 10,
283
+ gap: 10
284
+ },
285
+ lg: {
286
+ cell: 56,
287
+ fontSize: 24,
288
+ borderRadius: 12,
289
+ gap: 12
290
+ }
291
+ },
292
+ dialog: {
293
+ iconWrapperSize: 48,
294
+ iconWrapperBorderRadius: 24,
295
+ actionButtonMinHeight: 44
296
+ },
297
+ toast: {
298
+ iconCircleSize: 28,
299
+ iconCircleBorderRadius: 14,
300
+ iconGlyphFontSize: 16,
301
+ tintBarWidth: 4
302
+ },
303
+ formField: {
304
+ inlineLabelWidth: '35%'
305
+ }
306
+ };
53
307
  const motion = {
54
308
  duration: {
55
309
  instant: 80,
@@ -258,7 +512,9 @@ export const lightTheme = {
258
512
  spacing,
259
513
  radius,
260
514
  shadows: lightShadows,
261
- motion
515
+ motion,
516
+ components,
517
+ gradients: {}
262
518
  };
263
519
  export const darkTheme = {
264
520
  mode: 'dark',
@@ -310,6 +566,8 @@ export const darkTheme = {
310
566
  spacing,
311
567
  radius,
312
568
  shadows: darkShadows,
313
- motion
569
+ motion,
570
+ components,
571
+ gradients: {}
314
572
  };
315
573
  //# sourceMappingURL=tokens.js.map
@@ -19,6 +19,7 @@
19
19
  import React from 'react';
20
20
  import type { StyleProp, ViewStyle } from 'react-native';
21
21
  export type SnapPoint = number | `${number}%`;
22
+ export type KeyboardBehavior = 'none' | 'shift';
22
23
  export interface BottomSheetProps {
23
24
  snapPoints: SnapPoint[];
24
25
  index?: number;
@@ -27,6 +28,15 @@ export interface BottomSheetProps {
27
28
  enablePanDownToClose?: boolean;
28
29
  enableBackdropPress?: boolean;
29
30
  backdropOpacity?: number;
31
+ /**
32
+ * How the sheet reacts to the soft keyboard.
33
+ * - `'none'` (default): the sheet stays put; keyboard may overlap content.
34
+ * - `'shift'`: animate the sheet upward by the keyboard height while it's
35
+ * visible (clamped so the sheet never extends past the top of the screen)
36
+ * and animate back when dismissed. Best for forms that live inside the
37
+ * sheet itself.
38
+ */
39
+ keyboardBehavior?: KeyboardBehavior;
30
40
  handleIndicatorStyle?: StyleProp<ViewStyle>;
31
41
  containerStyle?: StyleProp<ViewStyle>;
32
42
  children?: React.ReactNode;
@@ -1,6 +1,7 @@
1
1
  import React from 'react';
2
2
  import { View } from 'react-native';
3
3
  import type { PressableProps, StyleProp, TextStyle, ViewStyle } from 'react-native';
4
+ import type { GradientDefinition } from '../../theme/types';
4
5
  import type { HapticType } from '../../utils/hapticUtils';
5
6
  export type ButtonVariant = 'solid' | 'outline' | 'ghost' | 'link';
6
7
  export type ButtonTone = 'primary' | 'secondary' | 'success' | 'warning' | 'danger' | 'neutral';
@@ -23,6 +24,13 @@ export interface ButtonProps extends Omit<PressableProps, 'style' | 'children'>
23
24
  rightIcon?: React.ReactNode;
24
25
  haptic?: HapticType | false;
25
26
  rounded?: boolean;
27
+ /**
28
+ * Optional gradient background. Pass either a key from `theme.gradients`
29
+ * (e.g. `"primary"`) or a `GradientDefinition` literal. Requires
30
+ * `react-native-linear-gradient` to be installed; without it the button
31
+ * falls back to flat colour with a dev warning.
32
+ */
33
+ gradient?: string | GradientDefinition;
26
34
  style?: StyleProp<ViewStyle>;
27
35
  textStyle?: StyleProp<TextStyle>;
28
36
  pressAnimation?: boolean;
@@ -1,6 +1,7 @@
1
1
  import React from 'react';
2
2
  import { View } from 'react-native';
3
3
  import type { GestureResponderEvent, ImageSourcePropType, PressableProps, StyleProp, ViewStyle } from 'react-native';
4
+ import type { GradientDefinition } from '../../theme/types';
4
5
  export type CardVariant = 'elevated' | 'outlined' | 'filled';
5
6
  export type CardElevation = 'none' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl';
6
7
  export type CardRadius = 'sm' | 'md' | 'lg' | 'xl' | '2xl';
@@ -24,6 +25,13 @@ export interface CardProps extends Omit<PressableProps, 'style' | 'children'> {
24
25
  * with shimmer blocks. Use this when the data driving the component is still being fetched.
25
26
  */
26
27
  loading?: boolean;
28
+ /**
29
+ * Optional gradient background. Pass a key from `theme.gradients` or a
30
+ * literal `GradientDefinition`. Layered behind the card's content so
31
+ * existing variant/elevation/radius continue to work. Requires
32
+ * `react-native-linear-gradient` to be installed.
33
+ */
34
+ gradient?: string | GradientDefinition;
27
35
  onPress?: (event: GestureResponderEvent) => void;
28
36
  accessibilityLabel?: string;
29
37
  style?: StyleProp<ViewStyle>;
@@ -1,4 +1,5 @@
1
1
  import React from 'react';
2
+ import type { StyleProp, ViewStyle } from 'react-native';
2
3
  export type DialogVariant = 'default' | 'success' | 'warning' | 'danger' | 'info';
3
4
  export type DialogActionTone = 'primary' | 'neutral' | 'danger';
4
5
  export interface DialogAction {
@@ -17,6 +18,10 @@ export interface DialogProps {
17
18
  actions?: DialogAction[];
18
19
  dismissOnAction?: boolean;
19
20
  accessibilityLabel?: string;
21
+ /** Style applied to the underlying Modal sheet (consumer may override radius, padding, etc.). */
22
+ contentStyle?: StyleProp<ViewStyle>;
23
+ /** Style applied to the dialog inner container (above icon/title/message). */
24
+ containerStyle?: StyleProp<ViewStyle>;
20
25
  testID?: string;
21
26
  }
22
27
  declare const Dialog: React.FC<DialogProps>;
@@ -20,6 +20,18 @@ export interface InputProps extends Omit<TextInputProps, 'style'> {
20
20
  variant?: InputVariant;
21
21
  required?: boolean;
22
22
  maxLength?: number;
23
+ /**
24
+ * Format the raw `value` for display. Common uses: phone-number formatting
25
+ * ("5551234567" → "(555) 123-4567"), currency, postal codes, masked IDs.
26
+ * The TextInput shows `format(value)`; user input is passed to `parse` (or
27
+ * left raw) before reaching `onChangeText`.
28
+ */
29
+ format?: (raw: string) => string;
30
+ /**
31
+ * Reverse of `format` — strips the formatted display back to the canonical
32
+ * value the consumer wants in state. If omitted, defaults to identity.
33
+ */
34
+ parse?: (formatted: string) => string;
23
35
  style?: StyleProp<ViewStyle>;
24
36
  inputStyle?: StyleProp<TextStyle>;
25
37
  labelStyle?: StyleProp<TextStyle>;
@@ -13,6 +13,11 @@ export interface SwitchProps extends Omit<PressableProps, 'style' | 'children' |
13
13
  label?: string;
14
14
  accessibilityLabel?: string;
15
15
  haptic?: HapticType | false;
16
+ /**
17
+ * When true, the thumb briefly scales up on value change (1 → 1.15 → 1).
18
+ * Use for playful/brand-flavored switches; default off for system feel.
19
+ */
20
+ bounce?: boolean;
16
21
  style?: StyleProp<ViewStyle>;
17
22
  trackStyle?: StyleProp<ViewStyle>;
18
23
  thumbStyle?: StyleProp<ViewStyle>;
@@ -1,4 +1,5 @@
1
1
  import React from 'react';
2
+ import type { StyleProp, TextStyle, ViewStyle } from 'react-native';
2
3
  import type { HapticType } from '../../utils/hapticUtils';
3
4
  export type ToastVariant = 'default' | 'success' | 'error' | 'warning' | 'info';
4
5
  export type ToastPosition = 'top' | 'bottom';
@@ -15,6 +16,10 @@ export interface ToastOptions {
15
16
  action?: ToastAction;
16
17
  haptic?: HapticType | false;
17
18
  icon?: React.ReactNode;
19
+ /** Style applied to the toast container (override radius, padding, shadow per-toast). */
20
+ style?: StyleProp<ViewStyle>;
21
+ /** Style applied to the toast message Text. */
22
+ textStyle?: StyleProp<TextStyle>;
18
23
  }
19
24
  export interface ToastItem extends ToastOptions {
20
25
  id: string;