@webority-technologies/mobile 0.0.7 → 0.0.8

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 (63) hide show
  1. package/lib/commonjs/components/Badge/Badge.js +23 -13
  2. package/lib/commonjs/components/BottomSheet/BottomSheet.js +39 -5
  3. package/lib/commonjs/components/Button/Button.js +25 -6
  4. package/lib/commonjs/components/Card/Card.js +13 -1
  5. package/lib/commonjs/components/Checkbox/Checkbox.js +5 -3
  6. package/lib/commonjs/components/Chip/Chip.js +12 -3
  7. package/lib/commonjs/components/Dialog/Dialog.js +15 -8
  8. package/lib/commonjs/components/EmptyState/EmptyState.js +32 -26
  9. package/lib/commonjs/components/FormField/FormField.js +3 -3
  10. package/lib/commonjs/components/Input/Input.js +13 -5
  11. package/lib/commonjs/components/ListItem/ListItem.js +33 -27
  12. package/lib/commonjs/components/OTPInput/OTPInput.js +6 -3
  13. package/lib/commonjs/components/Radio/Radio.js +7 -6
  14. package/lib/commonjs/components/SearchBar/SearchBar.js +9 -5
  15. package/lib/commonjs/components/Switch/Switch.js +31 -2
  16. package/lib/commonjs/components/Toast/Toast.js +16 -11
  17. package/lib/commonjs/theme/Gradient.js +57 -0
  18. package/lib/commonjs/theme/index.js +20 -0
  19. package/lib/commonjs/theme/textStyle.js +37 -0
  20. package/lib/commonjs/theme/tokens.js +260 -2
  21. package/lib/module/components/Badge/Badge.js +24 -14
  22. package/lib/module/components/BottomSheet/BottomSheet.js +40 -6
  23. package/lib/module/components/Button/Button.js +26 -7
  24. package/lib/module/components/Card/Card.js +14 -2
  25. package/lib/module/components/Checkbox/Checkbox.js +5 -3
  26. package/lib/module/components/Chip/Chip.js +13 -4
  27. package/lib/module/components/Dialog/Dialog.js +16 -9
  28. package/lib/module/components/EmptyState/EmptyState.js +33 -27
  29. package/lib/module/components/FormField/FormField.js +4 -4
  30. package/lib/module/components/Input/Input.js +14 -6
  31. package/lib/module/components/ListItem/ListItem.js +34 -28
  32. package/lib/module/components/OTPInput/OTPInput.js +7 -4
  33. package/lib/module/components/Radio/Radio.js +7 -6
  34. package/lib/module/components/SearchBar/SearchBar.js +10 -6
  35. package/lib/module/components/Switch/Switch.js +31 -2
  36. package/lib/module/components/Toast/Toast.js +17 -12
  37. package/lib/module/theme/Gradient.js +50 -0
  38. package/lib/module/theme/index.js +2 -0
  39. package/lib/module/theme/textStyle.js +32 -0
  40. package/lib/module/theme/tokens.js +260 -2
  41. package/lib/typescript/commonjs/components/BottomSheet/BottomSheet.d.ts +10 -0
  42. package/lib/typescript/commonjs/components/Button/Button.d.ts +8 -0
  43. package/lib/typescript/commonjs/components/Card/Card.d.ts +8 -0
  44. package/lib/typescript/commonjs/components/Dialog/Dialog.d.ts +5 -0
  45. package/lib/typescript/commonjs/components/Input/Input.d.ts +12 -0
  46. package/lib/typescript/commonjs/components/Switch/Switch.d.ts +5 -0
  47. package/lib/typescript/commonjs/components/Toast/Toast.d.ts +5 -0
  48. package/lib/typescript/commonjs/theme/Gradient.d.ts +11 -0
  49. package/lib/typescript/commonjs/theme/index.d.ts +5 -1
  50. package/lib/typescript/commonjs/theme/textStyle.d.ts +18 -0
  51. package/lib/typescript/commonjs/theme/types.d.ts +178 -0
  52. package/lib/typescript/module/components/BottomSheet/BottomSheet.d.ts +10 -0
  53. package/lib/typescript/module/components/Button/Button.d.ts +8 -0
  54. package/lib/typescript/module/components/Card/Card.d.ts +8 -0
  55. package/lib/typescript/module/components/Dialog/Dialog.d.ts +5 -0
  56. package/lib/typescript/module/components/Input/Input.d.ts +12 -0
  57. package/lib/typescript/module/components/Switch/Switch.d.ts +5 -0
  58. package/lib/typescript/module/components/Toast/Toast.d.ts +5 -0
  59. package/lib/typescript/module/theme/Gradient.d.ts +11 -0
  60. package/lib/typescript/module/theme/index.d.ts +5 -1
  61. package/lib/typescript/module/theme/textStyle.d.ts +18 -0
  62. package/lib/typescript/module/theme/types.d.ts +178 -0
  63. package/package.json +5 -1
@@ -2,38 +2,44 @@
2
2
 
3
3
  import React, { forwardRef, useMemo } from 'react';
4
4
  import { Animated, Pressable, StyleSheet, Text, View } from 'react-native';
5
- import { useTheme } from "../../theme/index.js";
5
+ import { fontFor, useTheme } from "../../theme/index.js";
6
6
  import { usePressAnimation } from "../../hooks/usePressAnimation.js";
7
7
  import { triggerHaptic } from "../../utils/hapticUtils.js";
8
8
  import { Swipeable } from "../Swipeable/index.js";
9
9
  import { SkeletonContent } from "../Skeleton/index.js";
10
10
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
11
- const sizeFor = (theme, size) => {
12
- switch (size) {
13
- case 'sm':
14
- return {
15
- paddingVertical: theme.spacing.sm,
16
- titleSize: theme.typography.fontSize.sm,
17
- subtitleSize: theme.typography.fontSize.xs,
18
- minHeight: 44
19
- };
20
- case 'lg':
21
- return {
22
- paddingVertical: theme.spacing.lg,
23
- titleSize: theme.typography.fontSize.lg,
24
- subtitleSize: theme.typography.fontSize.sm,
25
- minHeight: 72
26
- };
27
- case 'md':
28
- default:
29
- return {
30
- paddingVertical: theme.spacing.md,
31
- titleSize: theme.typography.fontSize.base,
32
- subtitleSize: theme.typography.fontSize.sm,
33
- minHeight: 56
34
- };
11
+ const SIZE_FALLBACK = {
12
+ sm: {
13
+ paddingVertical: 'sm',
14
+ titleFontSize: 'sm',
15
+ subtitleFontSize: 'xs',
16
+ minHeight: 44
17
+ },
18
+ md: {
19
+ paddingVertical: 'md',
20
+ titleFontSize: 'base',
21
+ subtitleFontSize: 'sm',
22
+ minHeight: 56
23
+ },
24
+ lg: {
25
+ paddingVertical: 'lg',
26
+ titleFontSize: 'lg',
27
+ subtitleFontSize: 'sm',
28
+ minHeight: 72
35
29
  }
36
30
  };
31
+ const sizeFor = (theme, size) => {
32
+ const tokens = {
33
+ ...SIZE_FALLBACK[size],
34
+ ...(theme.components.listItem?.[size] ?? {})
35
+ };
36
+ return {
37
+ paddingVertical: theme.spacing[tokens.paddingVertical],
38
+ titleSize: theme.typography.fontSize[tokens.titleFontSize],
39
+ subtitleSize: theme.typography.fontSize[tokens.subtitleFontSize],
40
+ minHeight: tokens.minHeight
41
+ };
42
+ };
37
43
  const Chevron = ({
38
44
  color
39
45
  }) => /*#__PURE__*/_jsx(Text, {
@@ -101,7 +107,7 @@ const ListItem = /*#__PURE__*/forwardRef((props, ref) => {
101
107
  children: [/*#__PURE__*/_jsx(Text, {
102
108
  style: [styles.title, {
103
109
  fontSize: sz.titleSize,
104
- fontWeight: theme.typography.fontWeight.medium,
110
+ ...fontFor(theme, 'medium'),
105
111
  color: disabled ? theme.colors.text.disabled : theme.colors.text.primary
106
112
  }],
107
113
  numberOfLines: 1,
@@ -232,11 +238,11 @@ const buildStyles = theme => StyleSheet.create({
232
238
  },
233
239
  subtitle: {
234
240
  marginTop: 2,
235
- fontWeight: theme.typography.fontWeight.normal
241
+ ...fontFor(theme, 'normal')
236
242
  },
237
243
  description: {
238
244
  marginTop: 2,
239
- fontWeight: theme.typography.fontWeight.normal
245
+ ...fontFor(theme, 'normal')
240
246
  }
241
247
  });
242
248
  export { ListItem };
@@ -2,7 +2,7 @@
2
2
 
3
3
  import React, { forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react';
4
4
  import { Animated, Easing, Pressable, StyleSheet, Text, TextInput, View } from 'react-native';
5
- import { useTheme } from "../../theme/index.js";
5
+ import { fontFor, useTheme } from "../../theme/index.js";
6
6
  import { triggerHaptic } from "../../utils/index.js";
7
7
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
8
8
  const sizeMap = {
@@ -52,7 +52,10 @@ const OTPInput = /*#__PURE__*/forwardRef((props, ref) => {
52
52
  } = props;
53
53
  const theme = useTheme();
54
54
  const styles = useMemo(() => buildStyles(theme), [theme]);
55
- const sizeStyles = sizeMap[size];
55
+ const sizeStyles = {
56
+ ...sizeMap[size],
57
+ ...(theme.components.otpInput?.[size] ?? {})
58
+ };
56
59
  const inputsRef = useRef([]);
57
60
  const [focusedIndex, setFocusedIndex] = useState(-1);
58
61
  const previousErrorRef = useRef(null);
@@ -297,7 +300,7 @@ const OTPInput = /*#__PURE__*/forwardRef((props, ref) => {
297
300
  style: [styles.input, {
298
301
  fontSize: sizeStyles.fontSize,
299
302
  color: theme.colors.text.primary,
300
- fontWeight: theme.typography.fontWeight.semibold
303
+ ...fontFor(theme, 'semibold')
301
304
  }, textStyle]
302
305
  }), secure && isFilled ? /*#__PURE__*/_jsx(View, {
303
306
  pointerEvents: "none",
@@ -306,7 +309,7 @@ const OTPInput = /*#__PURE__*/forwardRef((props, ref) => {
306
309
  style: [{
307
310
  fontSize: sizeStyles.fontSize,
308
311
  color: theme.colors.text.primary,
309
- fontWeight: theme.typography.fontWeight.semibold
312
+ ...fontFor(theme, 'semibold')
310
313
  }, textStyle],
311
314
  children: display
312
315
  })
@@ -56,10 +56,11 @@ const Radio = /*#__PURE__*/forwardRef((props, ref) => {
56
56
  const selected = ctx ? ctx.selectedValue === value : !!selectedProp;
57
57
  const disabled = ctx ? ctx.disabled || disabledProp : disabledProp;
58
58
  const fillColor = toneColor(theme, tone);
59
- const {
60
- outer,
61
- inner
62
- } = sizeMap[size];
59
+ const sizeOverrides = theme.components.radio?.[size];
60
+ const outer = sizeOverrides?.outer ?? sizeMap[size].outer;
61
+ const inner = sizeOverrides?.inner ?? sizeMap[size].inner;
62
+ const radioBorderWidth = theme.components.radio?.borderWidth ?? 1.5;
63
+ const radioLabelGap = theme.components.radio?.labelGap ?? 10;
63
64
  const progress = useRef(new Animated.Value(selected ? 1 : 0)).current;
64
65
  useEffect(() => {
65
66
  Animated.spring(progress, {
@@ -108,6 +109,7 @@ const Radio = /*#__PURE__*/forwardRef((props, ref) => {
108
109
  style: [styles.outer, {
109
110
  width: outer,
110
111
  height: outer,
112
+ borderWidth: radioBorderWidth,
111
113
  borderRadius: outer / 2,
112
114
  borderColor
113
115
  }, circleStyle],
@@ -125,6 +127,7 @@ const Radio = /*#__PURE__*/forwardRef((props, ref) => {
125
127
  })
126
128
  }), label ? /*#__PURE__*/_jsx(Text, {
127
129
  style: [styles.label, {
130
+ marginLeft: radioLabelGap,
128
131
  color: disabled ? theme.colors.text.disabled : theme.colors.text.primary,
129
132
  fontSize: theme.typography.fontSize.base
130
133
  }],
@@ -140,13 +143,11 @@ const buildStyles = _theme => StyleSheet.create({
140
143
  alignItems: 'center'
141
144
  },
142
145
  outer: {
143
- borderWidth: 1.5,
144
146
  alignItems: 'center',
145
147
  justifyContent: 'center'
146
148
  },
147
149
  inner: {},
148
150
  label: {
149
- marginLeft: 10,
150
151
  flexShrink: 1
151
152
  }
152
153
  });
@@ -2,7 +2,7 @@
2
2
 
3
3
  import React, { forwardRef, useCallback, useEffect, useMemo, useRef, useState } from 'react';
4
4
  import { Animated, Easing, Pressable, StyleSheet, Text, TextInput, View } from 'react-native';
5
- import { useTheme } from "../../theme/index.js";
5
+ import { fontFor, useTheme } from "../../theme/index.js";
6
6
  import { triggerHaptic } from "../../utils/hapticUtils.js";
7
7
  import { useDebounce } from "../../hooks/useDebounce.js";
8
8
  import { AppIcon } from "../AppIcon/index.js";
@@ -53,7 +53,11 @@ const SearchBar = /*#__PURE__*/forwardRef((props, ref) => {
53
53
  ...rest
54
54
  } = props;
55
55
  const theme = useTheme();
56
- const sizeStyles = sizeMap[size];
56
+ const sizeStyles = {
57
+ ...sizeMap[size],
58
+ ...(theme.components.searchBar?.[size] ?? {})
59
+ };
60
+ const cancelWidth = theme.components.searchBar?.cancelButtonWidth ?? CANCEL_WIDTH;
57
61
  const styles = useMemo(() => buildStyles(theme), [theme]);
58
62
  const [isFocused, setIsFocused] = useState(false);
59
63
  const [internalValue, setInternalValue] = useState(value);
@@ -122,7 +126,7 @@ const SearchBar = /*#__PURE__*/forwardRef((props, ref) => {
122
126
  // Container shrinks left to make room for cancel button on right.
123
127
  const cancelTranslateX = cancelAnim.interpolate({
124
128
  inputRange: [0, 1],
125
- outputRange: [CANCEL_WIDTH, 0]
129
+ outputRange: [cancelWidth, 0]
126
130
  });
127
131
  const cancelOpacity = cancelAnim;
128
132
  return /*#__PURE__*/_jsxs(View, {
@@ -139,7 +143,7 @@ const SearchBar = /*#__PURE__*/forwardRef((props, ref) => {
139
143
  opacity: disabled ? 0.55 : 1,
140
144
  marginRight: cancelAnim.interpolate({
141
145
  inputRange: [0, 1],
142
- outputRange: [0, CANCEL_WIDTH + theme.spacing.sm]
146
+ outputRange: [0, cancelWidth + theme.spacing.sm]
143
147
  })
144
148
  }],
145
149
  accessibilityRole: "search",
@@ -194,7 +198,7 @@ const SearchBar = /*#__PURE__*/forwardRef((props, ref) => {
194
198
  }), showCancel ? /*#__PURE__*/_jsx(Animated.View, {
195
199
  pointerEvents: showCancelButton ? 'auto' : 'none',
196
200
  style: [styles.cancelWrap, {
197
- width: CANCEL_WIDTH,
201
+ width: cancelWidth,
198
202
  transform: [{
199
203
  translateX: cancelTranslateX
200
204
  }],
@@ -210,7 +214,7 @@ const SearchBar = /*#__PURE__*/forwardRef((props, ref) => {
210
214
  style: [styles.cancelText, {
211
215
  color: theme.colors.primary,
212
216
  fontSize: sizeStyles.fontSize,
213
- fontWeight: theme.typography.fontWeight.medium
217
+ ...fontFor(theme, 'medium')
214
218
  }],
215
219
  numberOfLines: 1,
216
220
  children: cancelLabel
@@ -48,6 +48,7 @@ const Switch = /*#__PURE__*/forwardRef((props, ref) => {
48
48
  label,
49
49
  accessibilityLabel,
50
50
  haptic = 'selection',
51
+ bounce = false,
51
52
  style,
52
53
  trackStyle,
53
54
  thumbStyle,
@@ -55,7 +56,11 @@ const Switch = /*#__PURE__*/forwardRef((props, ref) => {
55
56
  ...rest
56
57
  } = props;
57
58
  const theme = useTheme();
58
- const sizeStyles = sizeMap[size];
59
+ const sizeStyles = {
60
+ ...sizeMap[size],
61
+ ...(theme.components.switch?.[size] ?? {})
62
+ };
63
+ const switchThumbColor = theme.components.switch?.thumbColor ?? '#FFFFFF';
59
64
  const styles = useMemo(() => buildStyles(theme), [theme]);
60
65
  const offTrackColor = theme.mode === 'dark' ? theme.colors.secondary : theme.colors.surface.disabled;
61
66
  const onTrackColor = toneColor(theme, tone);
@@ -88,6 +93,28 @@ const Switch = /*#__PURE__*/forwardRef((props, ref) => {
88
93
  inputRange: [0, 1],
89
94
  outputRange: [offTrackColor, onTrackColor]
90
95
  });
96
+ const bounceScale = useRef(new Animated.Value(1)).current;
97
+ const isFirstRender = useRef(true);
98
+ useEffect(() => {
99
+ if (!bounce) return;
100
+ if (isFirstRender.current) {
101
+ isFirstRender.current = false;
102
+ return;
103
+ }
104
+ Animated.sequence([Animated.spring(bounceScale, {
105
+ toValue: 1.15,
106
+ damping: 10,
107
+ stiffness: 220,
108
+ mass: 1,
109
+ useNativeDriver: true
110
+ }), Animated.spring(bounceScale, {
111
+ toValue: 1,
112
+ damping: 14,
113
+ stiffness: 240,
114
+ mass: 1,
115
+ useNativeDriver: true
116
+ })]).start();
117
+ }, [value, bounce, bounceScale]);
91
118
  const handlePress = event => {
92
119
  if (disabled) return;
93
120
  if (haptic !== false) triggerHaptic(haptic);
@@ -122,11 +149,14 @@ const Switch = /*#__PURE__*/forwardRef((props, ref) => {
122
149
  }, trackStyle],
123
150
  children: /*#__PURE__*/_jsx(Animated.View, {
124
151
  style: [styles.thumb, theme.shadows.sm, {
152
+ backgroundColor: switchThumbColor,
125
153
  width: sizeStyles.thumbSize,
126
154
  height: sizeStyles.thumbSize,
127
155
  borderRadius: sizeStyles.thumbSize / 2,
128
156
  transform: [{
129
157
  translateX
158
+ }, {
159
+ scale: bounceScale
130
160
  }]
131
161
  }, thumbStyle]
132
162
  })
@@ -155,7 +185,6 @@ const buildStyles = _theme => StyleSheet.create({
155
185
  justifyContent: 'center'
156
186
  },
157
187
  thumb: {
158
- backgroundColor: '#FFFFFF',
159
188
  position: 'absolute',
160
189
  top: 2
161
190
  },
@@ -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 } 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,6 +18,11 @@ 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
27
  const translateY = useRef(new Animated.Value(enterFrom)).current;
23
28
  const translateX = useRef(new Animated.Value(0)).current;
@@ -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
  },
@@ -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
@@ -45,4 +45,6 @@ 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 { Gradient, isGradientAvailable } from "./Gradient.js";
48
50
  //# 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