@webority-technologies/mobile 0.0.15 → 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.
- package/lib/commonjs/components/Accordion/Accordion.js +60 -19
- package/lib/commonjs/components/AppBar/AppBar.js +29 -20
- package/lib/commonjs/components/Avatar/Avatar.js +38 -8
- package/lib/commonjs/components/Badge/Badge.js +66 -4
- package/lib/commonjs/components/Banner/Banner.js +146 -66
- package/lib/commonjs/components/BottomNavigation/BottomNavigation.js +37 -15
- package/lib/commonjs/components/BottomSheet/BottomSheet.js +78 -53
- package/lib/commonjs/components/Button/Button.js +12 -5
- package/lib/commonjs/components/Card/Card.js +106 -16
- package/lib/commonjs/components/Carousel/Carousel.js +66 -12
- package/lib/commonjs/components/Checkbox/Checkbox.js +11 -7
- package/lib/commonjs/components/Chip/Chip.js +44 -12
- package/lib/commonjs/components/DatePicker/DatePicker.js +185 -76
- package/lib/commonjs/components/DateRangePicker/DateRangePicker.js +133 -59
- package/lib/commonjs/components/Dialog/Dialog.js +16 -10
- package/lib/commonjs/components/Drawer/Drawer.js +13 -10
- package/lib/commonjs/components/FieldBase/FieldBase.js +306 -0
- package/lib/commonjs/components/FieldBase/index.js +32 -0
- package/lib/commonjs/components/FloatingActionButton/FloatingActionButton.js +69 -44
- package/lib/commonjs/components/ForceUpdateDialog/ForceUpdateDialog.js +8 -2
- package/lib/commonjs/components/FormField/FormField.js +3 -2
- package/lib/commonjs/components/ImageGallery/ImageGallery.js +132 -44
- package/lib/commonjs/components/Input/Input.js +144 -181
- package/lib/commonjs/components/ListItem/ListItem.js +90 -11
- package/lib/commonjs/components/Modal/Modal.js +55 -27
- package/lib/commonjs/components/NumberInput/NumberInput.js +60 -106
- package/lib/commonjs/components/OTPInput/OTPInput.js +65 -58
- package/lib/commonjs/components/PickerTrigger/PickerTrigger.js +185 -0
- package/lib/commonjs/components/{AppIcon → PickerTrigger}/index.js +4 -4
- package/lib/commonjs/components/ProgressBar/ProgressBar.js +19 -11
- package/lib/commonjs/components/Radio/Radio.js +11 -6
- package/lib/commonjs/components/Rating/Rating.js +85 -19
- package/lib/commonjs/components/SearchBar/SearchBar.js +84 -107
- package/lib/commonjs/components/SegmentedControl/SegmentedControl.js +22 -11
- package/lib/commonjs/components/Select/Select.js +62 -91
- package/lib/commonjs/components/Skeleton/Skeleton.js +131 -174
- package/lib/commonjs/components/Skeleton/SkeletonClock.js +117 -0
- package/lib/commonjs/components/Skeleton/SkeletonContent.js +164 -81
- package/lib/commonjs/components/Skeleton/SkeletonProvider.js +72 -10
- package/lib/commonjs/components/Skeleton/index.js +17 -16
- package/lib/commonjs/components/Slider/Slider.js +44 -25
- package/lib/commonjs/components/Stepper/Stepper.js +199 -29
- package/lib/commonjs/components/Swipeable/Swipeable.js +36 -19
- package/lib/commonjs/components/Switch/Switch.js +9 -2
- package/lib/commonjs/components/Tabs/Tabs.js +84 -21
- package/lib/commonjs/components/TimePicker/TimePicker.js +123 -45
- package/lib/commonjs/components/Toast/Toast.js +27 -16
- package/lib/commonjs/components/Tooltip/Tooltip.js +56 -32
- package/lib/commonjs/components/index.js +37 -37
- package/lib/commonjs/theme/tokens.js +55 -7
- package/lib/module/components/Accordion/Accordion.js +61 -20
- package/lib/module/components/AppBar/AppBar.js +29 -20
- package/lib/module/components/Avatar/Avatar.js +39 -9
- package/lib/module/components/Badge/Badge.js +67 -5
- package/lib/module/components/Banner/Banner.js +147 -67
- package/lib/module/components/BottomNavigation/BottomNavigation.js +37 -15
- package/lib/module/components/BottomSheet/BottomSheet.js +80 -55
- package/lib/module/components/Button/Button.js +12 -5
- package/lib/module/components/Card/Card.js +107 -17
- package/lib/module/components/Carousel/Carousel.js +67 -13
- package/lib/module/components/Checkbox/Checkbox.js +11 -7
- package/lib/module/components/Chip/Chip.js +45 -13
- package/lib/module/components/DatePicker/DatePicker.js +185 -76
- package/lib/module/components/DateRangePicker/DateRangePicker.js +134 -60
- package/lib/module/components/Dialog/Dialog.js +16 -10
- package/lib/module/components/Drawer/Drawer.js +13 -10
- package/lib/module/components/FieldBase/FieldBase.js +297 -0
- package/lib/module/components/FieldBase/index.js +4 -0
- package/lib/module/components/FloatingActionButton/FloatingActionButton.js +69 -44
- package/lib/module/components/ForceUpdateDialog/ForceUpdateDialog.js +8 -2
- package/lib/module/components/FormField/FormField.js +3 -2
- package/lib/module/components/ImageGallery/ImageGallery.js +128 -40
- package/lib/module/components/Input/Input.js +144 -179
- package/lib/module/components/ListItem/ListItem.js +91 -12
- package/lib/module/components/Modal/Modal.js +55 -27
- package/lib/module/components/NumberInput/NumberInput.js +60 -106
- package/lib/module/components/OTPInput/OTPInput.js +65 -58
- package/lib/module/components/PickerTrigger/PickerTrigger.js +181 -0
- package/lib/module/components/PickerTrigger/index.js +4 -0
- package/lib/module/components/ProgressBar/ProgressBar.js +19 -11
- package/lib/module/components/Radio/Radio.js +11 -6
- package/lib/module/components/Rating/Rating.js +86 -20
- package/lib/module/components/SearchBar/SearchBar.js +84 -107
- package/lib/module/components/SegmentedControl/SegmentedControl.js +22 -11
- package/lib/module/components/Select/Select.js +62 -91
- package/lib/module/components/Skeleton/Skeleton.js +135 -175
- package/lib/module/components/Skeleton/SkeletonClock.js +110 -0
- package/lib/module/components/Skeleton/SkeletonContent.js +167 -84
- package/lib/module/components/Skeleton/SkeletonProvider.js +71 -10
- package/lib/module/components/Skeleton/index.js +3 -2
- package/lib/module/components/Slider/Slider.js +44 -25
- package/lib/module/components/Stepper/Stepper.js +201 -31
- package/lib/module/components/Swipeable/Swipeable.js +36 -19
- package/lib/module/components/Switch/Switch.js +9 -2
- package/lib/module/components/Tabs/Tabs.js +84 -21
- package/lib/module/components/TimePicker/TimePicker.js +123 -45
- package/lib/module/components/Toast/Toast.js +27 -16
- package/lib/module/components/Tooltip/Tooltip.js +56 -32
- package/lib/module/components/index.js +2 -2
- package/lib/module/theme/tokens.js +55 -7
- package/lib/typescript/commonjs/components/Accordion/Accordion.d.ts +10 -5
- package/lib/typescript/commonjs/components/AppBar/AppBar.d.ts +8 -0
- package/lib/typescript/commonjs/components/Avatar/Avatar.d.ts +12 -6
- package/lib/typescript/commonjs/components/Badge/Badge.d.ts +7 -6
- package/lib/typescript/commonjs/components/Banner/Banner.d.ts +17 -6
- package/lib/typescript/commonjs/components/BottomSheet/BottomSheet.d.ts +7 -0
- package/lib/typescript/commonjs/components/Card/Card.d.ts +17 -6
- package/lib/typescript/commonjs/components/Carousel/Carousel.d.ts +7 -6
- package/lib/typescript/commonjs/components/Checkbox/Checkbox.d.ts +9 -1
- package/lib/typescript/commonjs/components/Chip/Chip.d.ts +13 -6
- package/lib/typescript/commonjs/components/DatePicker/DatePicker.d.ts +38 -3
- package/lib/typescript/commonjs/components/DateRangePicker/DateRangePicker.d.ts +36 -3
- package/lib/typescript/commonjs/components/Dialog/Dialog.d.ts +13 -1
- package/lib/typescript/commonjs/components/FieldBase/FieldBase.d.ts +141 -0
- package/lib/typescript/commonjs/components/FieldBase/index.d.ts +3 -0
- package/lib/typescript/commonjs/components/FloatingActionButton/FloatingActionButton.d.ts +8 -6
- package/lib/typescript/commonjs/components/FloatingActionButton/index.d.ts +1 -1
- package/lib/typescript/commonjs/components/ForceUpdateDialog/ForceUpdateDialog.d.ts +7 -0
- package/lib/typescript/commonjs/components/FormField/FormField.d.ts +7 -0
- package/lib/typescript/commonjs/components/ImageGallery/ImageGallery.d.ts +6 -4
- package/lib/typescript/commonjs/components/Input/Input.d.ts +6 -0
- package/lib/typescript/commonjs/components/ListItem/ListItem.d.ts +13 -6
- package/lib/typescript/commonjs/components/NumberInput/NumberInput.d.ts +3 -0
- package/lib/typescript/commonjs/components/PickerTrigger/PickerTrigger.d.ts +57 -0
- package/lib/typescript/commonjs/components/PickerTrigger/index.d.ts +3 -0
- package/lib/typescript/commonjs/components/ProgressBar/ProgressBar.d.ts +2 -0
- package/lib/typescript/commonjs/components/Radio/Radio.d.ts +3 -0
- package/lib/typescript/commonjs/components/Rating/Rating.d.ts +9 -6
- package/lib/typescript/commonjs/components/SegmentedControl/SegmentedControl.d.ts +3 -0
- package/lib/typescript/commonjs/components/Skeleton/Skeleton.d.ts +49 -20
- package/lib/typescript/commonjs/components/Skeleton/SkeletonClock.d.ts +60 -0
- package/lib/typescript/commonjs/components/Skeleton/SkeletonContent.d.ts +80 -19
- package/lib/typescript/commonjs/components/Skeleton/SkeletonProvider.d.ts +39 -5
- package/lib/typescript/commonjs/components/Skeleton/index.d.ts +6 -4
- package/lib/typescript/commonjs/components/Slider/Slider.d.ts +12 -1
- package/lib/typescript/commonjs/components/Stepper/Stepper.d.ts +18 -6
- package/lib/typescript/commonjs/components/Swipeable/Swipeable.d.ts +2 -0
- package/lib/typescript/commonjs/components/Switch/Switch.d.ts +1 -0
- package/lib/typescript/commonjs/components/Tabs/Tabs.d.ts +26 -2
- package/lib/typescript/commonjs/components/TimePicker/TimePicker.d.ts +36 -3
- package/lib/typescript/commonjs/components/Toast/Toast.d.ts +8 -0
- package/lib/typescript/commonjs/components/Tooltip/Tooltip.d.ts +7 -1
- package/lib/typescript/commonjs/components/index.d.ts +5 -5
- package/lib/typescript/commonjs/index.d.ts +1 -1
- package/lib/typescript/commonjs/theme/index.d.ts +1 -1
- package/lib/typescript/commonjs/theme/types.d.ts +553 -11
- package/lib/typescript/module/components/Accordion/Accordion.d.ts +10 -5
- package/lib/typescript/module/components/AppBar/AppBar.d.ts +8 -0
- package/lib/typescript/module/components/Avatar/Avatar.d.ts +12 -6
- package/lib/typescript/module/components/Badge/Badge.d.ts +7 -6
- package/lib/typescript/module/components/Banner/Banner.d.ts +17 -6
- package/lib/typescript/module/components/BottomSheet/BottomSheet.d.ts +7 -0
- package/lib/typescript/module/components/Card/Card.d.ts +17 -6
- package/lib/typescript/module/components/Carousel/Carousel.d.ts +7 -6
- package/lib/typescript/module/components/Checkbox/Checkbox.d.ts +9 -1
- package/lib/typescript/module/components/Chip/Chip.d.ts +13 -6
- package/lib/typescript/module/components/DatePicker/DatePicker.d.ts +38 -3
- package/lib/typescript/module/components/DateRangePicker/DateRangePicker.d.ts +36 -3
- package/lib/typescript/module/components/Dialog/Dialog.d.ts +13 -1
- package/lib/typescript/module/components/FieldBase/FieldBase.d.ts +141 -0
- package/lib/typescript/module/components/FieldBase/index.d.ts +3 -0
- package/lib/typescript/module/components/FloatingActionButton/FloatingActionButton.d.ts +8 -6
- package/lib/typescript/module/components/FloatingActionButton/index.d.ts +1 -1
- package/lib/typescript/module/components/ForceUpdateDialog/ForceUpdateDialog.d.ts +7 -0
- package/lib/typescript/module/components/FormField/FormField.d.ts +7 -0
- package/lib/typescript/module/components/ImageGallery/ImageGallery.d.ts +6 -4
- package/lib/typescript/module/components/Input/Input.d.ts +6 -0
- package/lib/typescript/module/components/ListItem/ListItem.d.ts +13 -6
- package/lib/typescript/module/components/NumberInput/NumberInput.d.ts +3 -0
- package/lib/typescript/module/components/PickerTrigger/PickerTrigger.d.ts +57 -0
- package/lib/typescript/module/components/PickerTrigger/index.d.ts +3 -0
- package/lib/typescript/module/components/ProgressBar/ProgressBar.d.ts +2 -0
- package/lib/typescript/module/components/Radio/Radio.d.ts +3 -0
- package/lib/typescript/module/components/Rating/Rating.d.ts +9 -6
- package/lib/typescript/module/components/SegmentedControl/SegmentedControl.d.ts +3 -0
- package/lib/typescript/module/components/Skeleton/Skeleton.d.ts +49 -20
- package/lib/typescript/module/components/Skeleton/SkeletonClock.d.ts +60 -0
- package/lib/typescript/module/components/Skeleton/SkeletonContent.d.ts +80 -19
- package/lib/typescript/module/components/Skeleton/SkeletonProvider.d.ts +39 -5
- package/lib/typescript/module/components/Skeleton/index.d.ts +6 -4
- package/lib/typescript/module/components/Slider/Slider.d.ts +12 -1
- package/lib/typescript/module/components/Stepper/Stepper.d.ts +18 -6
- package/lib/typescript/module/components/Swipeable/Swipeable.d.ts +2 -0
- package/lib/typescript/module/components/Switch/Switch.d.ts +1 -0
- package/lib/typescript/module/components/Tabs/Tabs.d.ts +26 -2
- package/lib/typescript/module/components/TimePicker/TimePicker.d.ts +36 -3
- package/lib/typescript/module/components/Toast/Toast.d.ts +8 -0
- package/lib/typescript/module/components/Tooltip/Tooltip.d.ts +7 -1
- package/lib/typescript/module/components/index.d.ts +5 -5
- package/lib/typescript/module/index.d.ts +1 -1
- package/lib/typescript/module/theme/index.d.ts +1 -1
- package/lib/typescript/module/theme/types.d.ts +553 -11
- package/package.json +2 -6
- package/lib/commonjs/components/AppIcon/AppIcon.js +0 -120
- package/lib/commonjs/types/vector-icons.d.js +0 -2
- package/lib/module/components/AppIcon/AppIcon.js +0 -111
- package/lib/module/components/AppIcon/index.js +0 -4
- package/lib/module/types/vector-icons.d.js +0 -2
- package/lib/typescript/commonjs/components/AppIcon/AppIcon.d.ts +0 -20
- package/lib/typescript/commonjs/components/AppIcon/index.d.ts +0 -3
- package/lib/typescript/module/components/AppIcon/AppIcon.d.ts +0 -20
- package/lib/typescript/module/components/AppIcon/index.d.ts +0 -3
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.resolveVariantColors = exports.resolveFieldTextStyle = exports.resolveFieldSize = exports.default = exports.FieldBase = void 0;
|
|
7
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
8
|
+
var _reactNative = require("react-native");
|
|
9
|
+
var _index = require("../../theme/index.js");
|
|
10
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
11
|
+
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
|
+
* FieldBase — the unified field-box primitive.
|
|
14
|
+
*
|
|
15
|
+
* Every input-like control in the library (Input, Select, SearchBar,
|
|
16
|
+
* NumberInput, OTPInput cell, PickerTrigger) composes FieldBase so the
|
|
17
|
+
* height / radius / padding / border / fill / focus + disabled + error
|
|
18
|
+
* states stay identical across the library. Differences (pill SearchBar,
|
|
19
|
+
* OTP underline, NumberInput steppers) become explicit overrides via
|
|
20
|
+
* props or via theme tokens — never accidental drift.
|
|
21
|
+
*
|
|
22
|
+
* Responsibilities:
|
|
23
|
+
* - Resolve size / variant dimensions from `theme.components.field`.
|
|
24
|
+
* - Animate the border + background between idle / focused / error.
|
|
25
|
+
* - Render leading + trailing slots either side of `children`.
|
|
26
|
+
* - Become Pressable when `onPress` is set (Select, PickerTrigger).
|
|
27
|
+
* - Apply disabled fill + cursor semantics.
|
|
28
|
+
*
|
|
29
|
+
* Non-responsibilities (the parent owns these):
|
|
30
|
+
* - The actual TextInput / Text / nested editor.
|
|
31
|
+
* - Floating / static labels rendered above the field.
|
|
32
|
+
* - Helper / error / counter text rendered below the field.
|
|
33
|
+
* - Shake-on-error or any cross-field animation.
|
|
34
|
+
*/
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Resolved text styling for the editable / displayed content inside a field.
|
|
38
|
+
* Single source of truth so every field component (Input, NumberInput,
|
|
39
|
+
* Select, SearchBar, PickerTrigger) renders identical colour + weight +
|
|
40
|
+
* fontFamily for value text — and reads the placeholder colour from the
|
|
41
|
+
* same place. OTPInput intentionally overrides this with its own semibold
|
|
42
|
+
* display weight.
|
|
43
|
+
*/
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Resolve the canonical text style chunk for a field's value. Reads from
|
|
47
|
+
* `theme.components.field.{textColor,disabledTextColor,placeholderColor,fontWeight}`
|
|
48
|
+
* with library-default fallbacks; brand fonts wired via `typography.fontFamily`
|
|
49
|
+
* apply via the shared `fontFor` helper.
|
|
50
|
+
*/
|
|
51
|
+
const resolveFieldTextStyle = (theme, options = {}) => {
|
|
52
|
+
const {
|
|
53
|
+
disabled = false
|
|
54
|
+
} = options;
|
|
55
|
+
const tokens = theme.components.field;
|
|
56
|
+
const color = disabled ? tokens?.disabledTextColor ?? theme.colors.text.disabled : tokens?.textColor ?? theme.colors.text.primary;
|
|
57
|
+
const placeholderColor = tokens?.placeholderColor ?? theme.colors.text.tertiary;
|
|
58
|
+
|
|
59
|
+
// If a consumer sets `field.fontWeight` directly (raw RN weight string),
|
|
60
|
+
// honour it verbatim — they've opted out of the brand-font path. Otherwise
|
|
61
|
+
// resolve weight through `fontFor` so `typography.fontFamily.<weight>`
|
|
62
|
+
// takes precedence when a custom face is registered.
|
|
63
|
+
const weightStyle = tokens?.fontWeight ? {
|
|
64
|
+
fontWeight: tokens.fontWeight
|
|
65
|
+
} : (0, _index.fontFor)(theme, 'medium');
|
|
66
|
+
return {
|
|
67
|
+
color,
|
|
68
|
+
placeholderColor,
|
|
69
|
+
weightStyle
|
|
70
|
+
};
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Public re-export of the resolved size tokens — components that need to
|
|
75
|
+
* compute their own padding adjustments (e.g. multiline Input, icon-slot
|
|
76
|
+
* sizing) read from this rather than re-hardcoding the size table.
|
|
77
|
+
*/
|
|
78
|
+
exports.resolveFieldTextStyle = resolveFieldTextStyle;
|
|
79
|
+
const resolveFieldSize = (theme, size) => {
|
|
80
|
+
const sizeFromTheme = theme.components.field?.[size];
|
|
81
|
+
return {
|
|
82
|
+
paddingHorizontal: sizeFromTheme?.paddingHorizontal ?? DEFAULT_SIZES[size].paddingHorizontal,
|
|
83
|
+
paddingVertical: sizeFromTheme?.paddingVertical ?? DEFAULT_SIZES[size].paddingVertical,
|
|
84
|
+
minHeight: sizeFromTheme?.minHeight ?? DEFAULT_SIZES[size].minHeight,
|
|
85
|
+
fontSize: sizeFromTheme?.fontSize ?? DEFAULT_SIZES[size].fontSize,
|
|
86
|
+
borderRadius: sizeFromTheme?.borderRadius ?? DEFAULT_SIZES[size].borderRadius,
|
|
87
|
+
iconSize: sizeFromTheme?.iconSize ?? DEFAULT_SIZES[size].iconSize
|
|
88
|
+
};
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
// Library defaults for when consumers haven't supplied per-size tokens. The
|
|
92
|
+
// numbers here MUST stay in sync with the `fieldSizes` table in tokens.ts —
|
|
93
|
+
// these are the same values, duplicated so resolveFieldSize works even when
|
|
94
|
+
// the consumer passes a custom theme without `components.field` set.
|
|
95
|
+
exports.resolveFieldSize = resolveFieldSize;
|
|
96
|
+
const DEFAULT_SIZES = {
|
|
97
|
+
sm: {
|
|
98
|
+
paddingHorizontal: 12,
|
|
99
|
+
paddingVertical: 8,
|
|
100
|
+
minHeight: 38,
|
|
101
|
+
fontSize: 13,
|
|
102
|
+
borderRadius: 10,
|
|
103
|
+
iconSize: 16
|
|
104
|
+
},
|
|
105
|
+
md: {
|
|
106
|
+
paddingHorizontal: 14,
|
|
107
|
+
paddingVertical: 11,
|
|
108
|
+
minHeight: 46,
|
|
109
|
+
fontSize: 15,
|
|
110
|
+
borderRadius: 12,
|
|
111
|
+
iconSize: 18
|
|
112
|
+
},
|
|
113
|
+
lg: {
|
|
114
|
+
paddingHorizontal: 16,
|
|
115
|
+
paddingVertical: 14,
|
|
116
|
+
minHeight: 54,
|
|
117
|
+
fontSize: 16,
|
|
118
|
+
borderRadius: 14,
|
|
119
|
+
iconSize: 20
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Strict, fully-resolved colour set used internally. Mirrors `FieldVariantTokens`
|
|
125
|
+
* but every field is non-optional — every state has a concrete colour by the
|
|
126
|
+
* time the box renders, so downstream code can rely on string-typed fills.
|
|
127
|
+
*/
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Resolve the full set of state-aware fill + border colours for a given
|
|
131
|
+
* variant. Order: explicit override → theme token → library default.
|
|
132
|
+
*/
|
|
133
|
+
const resolveVariantColors = (theme, variant, override) => {
|
|
134
|
+
const tokenSet = theme.components.field?.[variant];
|
|
135
|
+
const isOutlined = variant === 'outlined';
|
|
136
|
+
const idleEmpty = isOutlined ? theme.colors.background.primary : theme.colors.background.secondary;
|
|
137
|
+
const borderIdle = isOutlined ? theme.colors.border.primary : 'transparent';
|
|
138
|
+
const borderWidth = isOutlined ? theme.colors.border.width : 0;
|
|
139
|
+
return {
|
|
140
|
+
backgroundIdleEmpty: override?.backgroundIdleEmpty ?? tokenSet?.backgroundIdleEmpty ?? idleEmpty,
|
|
141
|
+
backgroundIdleFilled: override?.backgroundIdleFilled ?? tokenSet?.backgroundIdleFilled ?? override?.backgroundIdleEmpty ?? tokenSet?.backgroundIdleEmpty ?? idleEmpty,
|
|
142
|
+
backgroundFocused: override?.backgroundFocused ?? tokenSet?.backgroundFocused ?? undefined,
|
|
143
|
+
backgroundError: override?.backgroundError ?? tokenSet?.backgroundError ?? undefined,
|
|
144
|
+
backgroundDisabled: override?.backgroundDisabled ?? tokenSet?.backgroundDisabled ?? theme.colors.surface.disabled,
|
|
145
|
+
borderIdle: override?.borderIdle ?? tokenSet?.borderIdle ?? borderIdle,
|
|
146
|
+
borderFocused: override?.borderFocused ?? tokenSet?.borderFocused ?? theme.colors.border.focus,
|
|
147
|
+
borderError: override?.borderError ?? tokenSet?.borderError ?? theme.colors.border.error,
|
|
148
|
+
borderDisabled: override?.borderDisabled ?? tokenSet?.borderDisabled ?? borderIdle,
|
|
149
|
+
borderWidth: override?.borderWidth ?? tokenSet?.borderWidth ?? borderWidth
|
|
150
|
+
};
|
|
151
|
+
};
|
|
152
|
+
exports.resolveVariantColors = resolveVariantColors;
|
|
153
|
+
const FieldBase = props => {
|
|
154
|
+
const {
|
|
155
|
+
size = 'md',
|
|
156
|
+
variant: variantProp,
|
|
157
|
+
focused = false,
|
|
158
|
+
disabled = false,
|
|
159
|
+
error = false,
|
|
160
|
+
filled = false,
|
|
161
|
+
leading,
|
|
162
|
+
trailing,
|
|
163
|
+
children,
|
|
164
|
+
onPress,
|
|
165
|
+
minHeight: minHeightProp,
|
|
166
|
+
maxHeight,
|
|
167
|
+
width,
|
|
168
|
+
height,
|
|
169
|
+
paddingHorizontal: paddingHorizontalProp,
|
|
170
|
+
paddingVertical: paddingVerticalProp,
|
|
171
|
+
borderRadius: borderRadiusProp,
|
|
172
|
+
borderWidth: borderWidthProp,
|
|
173
|
+
gap: gapProp,
|
|
174
|
+
fillOverrides,
|
|
175
|
+
style,
|
|
176
|
+
testID,
|
|
177
|
+
accessibilityRole,
|
|
178
|
+
accessibilityLabel,
|
|
179
|
+
accessibilityState,
|
|
180
|
+
accessibilityHint
|
|
181
|
+
} = props;
|
|
182
|
+
const theme = (0, _index.useTheme)();
|
|
183
|
+
const styles = (0, _react.useMemo)(() => buildStyles(), []);
|
|
184
|
+
const variant = variantProp ?? theme.components.field?.defaultVariant ?? 'outlined';
|
|
185
|
+
const sizeTokens = resolveFieldSize(theme, size);
|
|
186
|
+
const colors = (0, _react.useMemo)(() => resolveVariantColors(theme, variant, fillOverrides), [theme, variant, fillOverrides]);
|
|
187
|
+
const focusAnim = (0, _react.useRef)((0, _index.createAnimatedValue)(focused ? 1 : 0)).current;
|
|
188
|
+
const errorAnim = (0, _react.useRef)((0, _index.createAnimatedValue)(error ? 1 : 0)).current;
|
|
189
|
+
(0, _react.useEffect)(() => {
|
|
190
|
+
_reactNative.Animated.timing(focusAnim, {
|
|
191
|
+
toValue: focused ? 1 : 0,
|
|
192
|
+
duration: theme.motion.duration.fast,
|
|
193
|
+
easing: _reactNative.Easing.bezier(...theme.motion.easing.standard),
|
|
194
|
+
useNativeDriver: false
|
|
195
|
+
}).start();
|
|
196
|
+
}, [focused, focusAnim, theme.motion.duration.fast, theme.motion.easing.standard]);
|
|
197
|
+
(0, _react.useEffect)(() => {
|
|
198
|
+
_reactNative.Animated.timing(errorAnim, {
|
|
199
|
+
toValue: error ? 1 : 0,
|
|
200
|
+
duration: theme.motion.duration.fast,
|
|
201
|
+
easing: _reactNative.Easing.bezier(...theme.motion.easing.standard),
|
|
202
|
+
useNativeDriver: false
|
|
203
|
+
}).start();
|
|
204
|
+
}, [error, errorAnim, theme.motion.duration.fast, theme.motion.easing.standard]);
|
|
205
|
+
|
|
206
|
+
// Resting border + fill (pre-animation). Error wins over focus when both
|
|
207
|
+
// happen at once; we drive a single interpolation between blurred ↔ active.
|
|
208
|
+
const idleFill = filled ? colors.backgroundIdleFilled : colors.backgroundIdleEmpty;
|
|
209
|
+
const focusedFill = colors.backgroundFocused ?? idleFill;
|
|
210
|
+
const errorFill = colors.backgroundError ?? idleFill;
|
|
211
|
+
const animatedBorderColor = disabled ? colors.borderDisabled : error ? errorAnim.interpolate({
|
|
212
|
+
inputRange: [0, 1],
|
|
213
|
+
outputRange: [colors.borderIdle, colors.borderError]
|
|
214
|
+
}) : focusAnim.interpolate({
|
|
215
|
+
inputRange: [0, 1],
|
|
216
|
+
outputRange: [colors.borderIdle, colors.borderFocused]
|
|
217
|
+
});
|
|
218
|
+
const animatedBackgroundColor = disabled ? colors.backgroundDisabled : error ? errorAnim.interpolate({
|
|
219
|
+
inputRange: [0, 1],
|
|
220
|
+
outputRange: [idleFill, errorFill]
|
|
221
|
+
}) : focusAnim.interpolate({
|
|
222
|
+
inputRange: [0, 1],
|
|
223
|
+
outputRange: [idleFill, focusedFill]
|
|
224
|
+
});
|
|
225
|
+
const boxStyle = {
|
|
226
|
+
minHeight: height ?? minHeightProp ?? sizeTokens.minHeight,
|
|
227
|
+
maxHeight,
|
|
228
|
+
paddingHorizontal: paddingHorizontalProp ?? sizeTokens.paddingHorizontal,
|
|
229
|
+
paddingVertical: paddingVerticalProp ?? sizeTokens.paddingVertical,
|
|
230
|
+
borderRadius: borderRadiusProp ?? sizeTokens.borderRadius,
|
|
231
|
+
borderWidth: borderWidthProp ?? colors.borderWidth,
|
|
232
|
+
borderColor: animatedBorderColor,
|
|
233
|
+
backgroundColor: animatedBackgroundColor,
|
|
234
|
+
columnGap: gapProp ?? theme.spacing.sm
|
|
235
|
+
};
|
|
236
|
+
if (width !== undefined) boxStyle.width = width;
|
|
237
|
+
if (height !== undefined) boxStyle.height = height;
|
|
238
|
+
const a11yState = {
|
|
239
|
+
disabled,
|
|
240
|
+
...accessibilityState
|
|
241
|
+
};
|
|
242
|
+
const innerContent = /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
|
|
243
|
+
children: [leading != null ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
244
|
+
style: styles.slot,
|
|
245
|
+
children: leading
|
|
246
|
+
}) : null, /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
247
|
+
style: styles.content,
|
|
248
|
+
children: children
|
|
249
|
+
}), trailing != null ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
250
|
+
style: styles.slot,
|
|
251
|
+
children: trailing
|
|
252
|
+
}) : null]
|
|
253
|
+
});
|
|
254
|
+
if (onPress) {
|
|
255
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Pressable, {
|
|
256
|
+
onPress: onPress,
|
|
257
|
+
disabled: disabled,
|
|
258
|
+
android_ripple: {
|
|
259
|
+
color: theme.colors.surface.pressed,
|
|
260
|
+
borderless: false
|
|
261
|
+
},
|
|
262
|
+
accessibilityRole: accessibilityRole ?? 'button',
|
|
263
|
+
accessibilityLabel: accessibilityLabel,
|
|
264
|
+
accessibilityHint: accessibilityHint,
|
|
265
|
+
accessibilityState: a11yState,
|
|
266
|
+
testID: testID,
|
|
267
|
+
children: ({
|
|
268
|
+
pressed
|
|
269
|
+
}) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Animated.View, {
|
|
270
|
+
style: [styles.box, boxStyle, pressed && !disabled ? {
|
|
271
|
+
backgroundColor: theme.colors.surface.pressed
|
|
272
|
+
} : null, style],
|
|
273
|
+
children: innerContent
|
|
274
|
+
})
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Animated.View, {
|
|
278
|
+
style: [styles.box, boxStyle, style],
|
|
279
|
+
accessibilityRole: accessibilityRole,
|
|
280
|
+
accessibilityLabel: accessibilityLabel,
|
|
281
|
+
accessibilityHint: accessibilityHint,
|
|
282
|
+
accessibilityState: a11yState,
|
|
283
|
+
testID: testID,
|
|
284
|
+
children: innerContent
|
|
285
|
+
});
|
|
286
|
+
};
|
|
287
|
+
exports.FieldBase = FieldBase;
|
|
288
|
+
FieldBase.displayName = 'FieldBase';
|
|
289
|
+
const buildStyles = () => _reactNative.StyleSheet.create({
|
|
290
|
+
box: {
|
|
291
|
+
flexDirection: 'row',
|
|
292
|
+
alignItems: 'center',
|
|
293
|
+
overflow: 'visible'
|
|
294
|
+
},
|
|
295
|
+
slot: {
|
|
296
|
+
alignItems: 'center',
|
|
297
|
+
justifyContent: 'center'
|
|
298
|
+
},
|
|
299
|
+
content: {
|
|
300
|
+
flex: 1,
|
|
301
|
+
flexDirection: 'row',
|
|
302
|
+
alignItems: 'center'
|
|
303
|
+
}
|
|
304
|
+
});
|
|
305
|
+
var _default = exports.default = FieldBase;
|
|
306
|
+
//# sourceMappingURL=FieldBase.js.map
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
Object.defineProperty(exports, "FieldBase", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: function () {
|
|
9
|
+
return _FieldBase.FieldBase;
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
Object.defineProperty(exports, "default", {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function () {
|
|
15
|
+
return _FieldBase.default;
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
Object.defineProperty(exports, "resolveFieldSize", {
|
|
19
|
+
enumerable: true,
|
|
20
|
+
get: function () {
|
|
21
|
+
return _FieldBase.resolveFieldSize;
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
Object.defineProperty(exports, "resolveFieldTextStyle", {
|
|
25
|
+
enumerable: true,
|
|
26
|
+
get: function () {
|
|
27
|
+
return _FieldBase.resolveFieldTextStyle;
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
var _FieldBase = _interopRequireWildcard(require("./FieldBase.js"));
|
|
31
|
+
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); }
|
|
32
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -10,9 +10,12 @@ var _reactNativeSafeAreaContext = require("react-native-safe-area-context");
|
|
|
10
10
|
var _index = require("../../theme/index.js");
|
|
11
11
|
var _usePressAnimation = require("../../hooks/usePressAnimation.js");
|
|
12
12
|
var _hapticUtils = require("../../utils/hapticUtils.js");
|
|
13
|
-
var _index2 = require("../AppIcon/index.js");
|
|
14
13
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
15
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); }
|
|
15
|
+
// Local shape mirror — see types.ts FloatingActionButtonTokens for the canonical
|
|
16
|
+
// definition. Declared here so the component can read tokens before types.ts is
|
|
17
|
+
// regenerated; will collapse to a direct import once that lands.
|
|
18
|
+
|
|
16
19
|
const sizeMap = {
|
|
17
20
|
sm: {
|
|
18
21
|
diameter: 40,
|
|
@@ -52,9 +55,6 @@ const toneForeground = (theme, tone) => {
|
|
|
52
55
|
if (tone === 'neutral') return theme.colors.text.primary;
|
|
53
56
|
return theme.colors.text.inverse;
|
|
54
57
|
};
|
|
55
|
-
const isIconConfig = value => {
|
|
56
|
-
return typeof value === 'object' && value !== null && ! /*#__PURE__*/_react.default.isValidElement(value) && typeof value.name === 'string';
|
|
57
|
-
};
|
|
58
58
|
const FloatingActionButton = exports.FloatingActionButton = /*#__PURE__*/(0, _react.forwardRef)((props, ref) => {
|
|
59
59
|
const {
|
|
60
60
|
icon,
|
|
@@ -70,6 +70,8 @@ const FloatingActionButton = exports.FloatingActionButton = /*#__PURE__*/(0, _re
|
|
|
70
70
|
accessibilityLabel,
|
|
71
71
|
accessibilityHint,
|
|
72
72
|
style,
|
|
73
|
+
containerStyle,
|
|
74
|
+
labelStyle,
|
|
73
75
|
testID
|
|
74
76
|
} = props;
|
|
75
77
|
const theme = (0, _index.useTheme)();
|
|
@@ -83,6 +85,10 @@ const FloatingActionButton = exports.FloatingActionButton = /*#__PURE__*/(0, _re
|
|
|
83
85
|
} = (0, _usePressAnimation.usePressAnimation)({
|
|
84
86
|
enabled: !disabled
|
|
85
87
|
});
|
|
88
|
+
const fabTokens = theme.components.floatingActionButton;
|
|
89
|
+
const edgeOffset = fabTokens?.edgeOffset ?? 24;
|
|
90
|
+
const defaultBottomOffset = fabTokens?.bottomOffset ?? 24;
|
|
91
|
+
const pressHaptic = fabTokens?.pressHaptic ?? false;
|
|
86
92
|
const hideAnim = (0, _react.useRef)((0, _index.createAnimatedValue)(0)).current;
|
|
87
93
|
(0, _react.useEffect)(() => {
|
|
88
94
|
if (!hideOnScroll) {
|
|
@@ -98,7 +104,7 @@ const FloatingActionButton = exports.FloatingActionButton = /*#__PURE__*/(0, _re
|
|
|
98
104
|
}, [hideOnScroll, isScrolling, hideAnim, theme.motion.duration.normal, theme.motion.easing.standard]);
|
|
99
105
|
const hideTranslateY = hideAnim.interpolate({
|
|
100
106
|
inputRange: [0, 1],
|
|
101
|
-
outputRange: [0, sizeStyles.diameter + (bottomOffset ??
|
|
107
|
+
outputRange: [0, sizeStyles.diameter + (bottomOffset ?? defaultBottomOffset) + insets.bottom + edgeOffset]
|
|
102
108
|
});
|
|
103
109
|
const hideOpacity = hideAnim.interpolate({
|
|
104
110
|
inputRange: [0, 1],
|
|
@@ -106,27 +112,22 @@ const FloatingActionButton = exports.FloatingActionButton = /*#__PURE__*/(0, _re
|
|
|
106
112
|
});
|
|
107
113
|
const handlePress = _event => {
|
|
108
114
|
if (disabled) return;
|
|
109
|
-
(0, _hapticUtils.triggerHaptic)('impactLight');
|
|
115
|
+
if (pressHaptic) (0, _hapticUtils.triggerHaptic)('impactLight');
|
|
110
116
|
onPress();
|
|
111
117
|
};
|
|
112
|
-
const renderedIcon =
|
|
113
|
-
name: icon.name,
|
|
114
|
-
family: icon.family ?? 'feather',
|
|
115
|
-
size: sizeStyles.iconSize,
|
|
116
|
-
color: toneForeground(theme, tone)
|
|
117
|
-
}) : icon;
|
|
118
|
+
const renderedIcon = icon;
|
|
118
119
|
const isExtended = typeof label === 'string' && label.length > 0;
|
|
119
120
|
const backgroundColor = disabled ? theme.colors.surface.disabled : toneBackground(theme, tone);
|
|
120
121
|
const foregroundColor = disabled ? theme.colors.text.disabled : toneForeground(theme, tone);
|
|
121
122
|
const positionStyle = (0, _react.useMemo)(() => {
|
|
122
123
|
if (!position) return null;
|
|
123
|
-
const bottom = (bottomOffset ??
|
|
124
|
+
const bottom = (bottomOffset ?? defaultBottomOffset) + insets.bottom;
|
|
124
125
|
switch (position) {
|
|
125
126
|
case 'bottomLeft':
|
|
126
127
|
return {
|
|
127
128
|
position: 'absolute',
|
|
128
129
|
bottom,
|
|
129
|
-
left:
|
|
130
|
+
left: edgeOffset
|
|
130
131
|
};
|
|
131
132
|
case 'bottomCenter':
|
|
132
133
|
return {
|
|
@@ -139,10 +140,10 @@ const FloatingActionButton = exports.FloatingActionButton = /*#__PURE__*/(0, _re
|
|
|
139
140
|
return {
|
|
140
141
|
position: 'absolute',
|
|
141
142
|
bottom,
|
|
142
|
-
right:
|
|
143
|
+
right: edgeOffset
|
|
143
144
|
};
|
|
144
145
|
}
|
|
145
|
-
}, [position, bottomOffset, insets.bottom]);
|
|
146
|
+
}, [position, bottomOffset, insets.bottom, defaultBottomOffset, edgeOffset]);
|
|
146
147
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Animated.View, {
|
|
147
148
|
style: [positionStyle, {
|
|
148
149
|
transform: [{
|
|
@@ -151,7 +152,7 @@ const FloatingActionButton = exports.FloatingActionButton = /*#__PURE__*/(0, _re
|
|
|
151
152
|
scale
|
|
152
153
|
}],
|
|
153
154
|
opacity: hideOpacity
|
|
154
|
-
}, style],
|
|
155
|
+
}, containerStyle, style],
|
|
155
156
|
pointerEvents: hideOnScroll && isScrolling ? 'none' : 'auto',
|
|
156
157
|
children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Pressable, {
|
|
157
158
|
ref: ref,
|
|
@@ -188,7 +189,7 @@ const FloatingActionButton = exports.FloatingActionButton = /*#__PURE__*/(0, _re
|
|
|
188
189
|
fontSize: sizeStyles.fontSize,
|
|
189
190
|
fontWeight: theme.typography.fontWeight.semibold,
|
|
190
191
|
marginLeft: theme.spacing.sm
|
|
191
|
-
}],
|
|
192
|
+
}, labelStyle],
|
|
192
193
|
numberOfLines: 1,
|
|
193
194
|
children: label
|
|
194
195
|
}) : null]
|
|
@@ -214,8 +215,6 @@ const buildStyles = _theme => _reactNative.StyleSheet.create({
|
|
|
214
215
|
// so they remain smooth during JS thread work.
|
|
215
216
|
// =====================================================================
|
|
216
217
|
|
|
217
|
-
const SECONDARY_GAP = 16;
|
|
218
|
-
const STAGGER_MS = 50;
|
|
219
218
|
const FloatingActionButtonGroup = props => {
|
|
220
219
|
const {
|
|
221
220
|
primaryIcon,
|
|
@@ -228,28 +227,54 @@ const FloatingActionButtonGroup = props => {
|
|
|
228
227
|
bottomOffset,
|
|
229
228
|
size = 'md',
|
|
230
229
|
accessibilityLabel = 'Quick actions',
|
|
230
|
+
containerStyle,
|
|
231
|
+
secondaryActionStyle,
|
|
232
|
+
labelPillStyle,
|
|
233
|
+
labelStyle,
|
|
231
234
|
testID
|
|
232
235
|
} = props;
|
|
233
236
|
const theme = (0, _index.useTheme)();
|
|
234
237
|
const insets = (0, _reactNativeSafeAreaContext.useSafeAreaInsets)();
|
|
235
238
|
const sizeStyles = sizeMap[size];
|
|
236
239
|
const styles = (0, _react.useMemo)(() => buildGroupStyles(theme), [theme]);
|
|
240
|
+
const fabTokens = theme.components.floatingActionButton;
|
|
241
|
+
const edgeOffset = fabTokens?.edgeOffset ?? 24;
|
|
242
|
+
const defaultBottomOffset = fabTokens?.bottomOffset ?? 24;
|
|
243
|
+
const secondaryGap = fabTokens?.secondaryGap ?? 16;
|
|
244
|
+
const staggerMs = fabTokens?.staggerMs ?? 50;
|
|
245
|
+
const pressHaptic = fabTokens?.pressHaptic ?? false;
|
|
237
246
|
const isControlled = typeof controlledOpen === 'boolean';
|
|
238
247
|
const [internalOpen, setInternalOpen] = (0, _react.useState)(defaultOpen);
|
|
239
248
|
const isOpen = isControlled ? controlledOpen : internalOpen;
|
|
240
249
|
|
|
241
250
|
// Animation drivers
|
|
242
251
|
const progress = (0, _react.useRef)((0, _index.createAnimatedValue)(isOpen ? 1 : 0)).current;
|
|
252
|
+
// Stable refs for per-item Animated.Values. Reconciled inside useEffect — never
|
|
253
|
+
// mutated during render — so re-renders don't recreate Animated.Value instances
|
|
254
|
+
// (previous implementation leaked one Animated.Value per re-render when the
|
|
255
|
+
// actions array length changed).
|
|
243
256
|
const itemAnims = (0, _react.useRef)([]);
|
|
244
|
-
|
|
245
|
-
//
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
257
|
+
// Bump this when the underlying refs array is re-shaped so downstream effects
|
|
258
|
+
// and mapping reads see the new length.
|
|
259
|
+
const [itemAnimsVersion, setItemAnimsVersion] = (0, _react.useState)(0);
|
|
260
|
+
(0, _react.useEffect)(() => {
|
|
261
|
+
const current = itemAnims.current;
|
|
262
|
+
if (current.length === actions.length) return;
|
|
263
|
+
if (current.length < actions.length) {
|
|
264
|
+
const next = current.slice();
|
|
265
|
+
for (let i = current.length; i < actions.length; i += 1) {
|
|
266
|
+
next.push(new _reactNative.Animated.Value(isOpen ? 1 : 0));
|
|
267
|
+
}
|
|
268
|
+
itemAnims.current = next;
|
|
269
|
+
} else {
|
|
270
|
+
// Drop stale refs when actions array shrinks.
|
|
271
|
+
itemAnims.current = current.slice(0, actions.length);
|
|
250
272
|
}
|
|
251
|
-
|
|
252
|
-
|
|
273
|
+
setItemAnimsVersion(v => v + 1);
|
|
274
|
+
// isOpen intentionally not in deps — only used to seed brand-new values; the
|
|
275
|
+
// open/close effect below will animate them to the correct target anyway.
|
|
276
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
277
|
+
}, [actions.length]);
|
|
253
278
|
(0, _react.useEffect)(() => {
|
|
254
279
|
_reactNative.Animated.timing(progress, {
|
|
255
280
|
toValue: isOpen ? 1 : 0,
|
|
@@ -265,34 +290,34 @@ const FloatingActionButtonGroup = props => {
|
|
|
265
290
|
}));
|
|
266
291
|
// Reverse stagger order on close so items closest to primary collapse last
|
|
267
292
|
const ordered = isOpen ? animations : [...animations].reverse();
|
|
268
|
-
_reactNative.Animated.stagger(
|
|
269
|
-
}, [isOpen, progress, theme.motion.duration.normal, theme.motion.easing.standard, actions.length]);
|
|
293
|
+
_reactNative.Animated.stagger(staggerMs, ordered).start();
|
|
294
|
+
}, [isOpen, progress, theme.motion.duration.normal, theme.motion.easing.standard, actions.length, itemAnimsVersion, staggerMs]);
|
|
270
295
|
const setOpen = (0, _react.useCallback)(next => {
|
|
271
|
-
(0, _hapticUtils.triggerHaptic)('impactLight');
|
|
296
|
+
if (pressHaptic) (0, _hapticUtils.triggerHaptic)('impactLight');
|
|
272
297
|
if (!isControlled) setInternalOpen(next);
|
|
273
298
|
onOpenChange?.(next);
|
|
274
|
-
}, [isControlled, onOpenChange]);
|
|
299
|
+
}, [isControlled, onOpenChange, pressHaptic]);
|
|
275
300
|
const handlePrimaryPress = (0, _react.useCallback)(() => {
|
|
276
301
|
setOpen(!isOpen);
|
|
277
302
|
}, [isOpen, setOpen]);
|
|
278
303
|
const handleActionPress = (0, _react.useCallback)(action => {
|
|
279
|
-
(0, _hapticUtils.triggerHaptic)('selection');
|
|
304
|
+
if (pressHaptic) (0, _hapticUtils.triggerHaptic)('selection');
|
|
280
305
|
action.onPress();
|
|
281
306
|
// Close after action runs
|
|
282
307
|
if (!isControlled) setInternalOpen(false);
|
|
283
308
|
onOpenChange?.(false);
|
|
284
|
-
}, [isControlled, onOpenChange]);
|
|
309
|
+
}, [isControlled, onOpenChange, pressHaptic]);
|
|
285
310
|
const handleBackdropPress = (0, _react.useCallback)(() => {
|
|
286
311
|
if (isOpen) setOpen(false);
|
|
287
312
|
}, [isOpen, setOpen]);
|
|
288
313
|
const positionStyle = (0, _react.useMemo)(() => {
|
|
289
|
-
const bottom = (bottomOffset ??
|
|
314
|
+
const bottom = (bottomOffset ?? defaultBottomOffset) + insets.bottom;
|
|
290
315
|
switch (position) {
|
|
291
316
|
case 'bottomLeft':
|
|
292
317
|
return {
|
|
293
318
|
position: 'absolute',
|
|
294
319
|
bottom,
|
|
295
|
-
left:
|
|
320
|
+
left: edgeOffset,
|
|
296
321
|
alignItems: 'flex-start'
|
|
297
322
|
};
|
|
298
323
|
case 'bottomCenter':
|
|
@@ -307,14 +332,14 @@ const FloatingActionButtonGroup = props => {
|
|
|
307
332
|
return {
|
|
308
333
|
position: 'absolute',
|
|
309
334
|
bottom,
|
|
310
|
-
right:
|
|
335
|
+
right: edgeOffset,
|
|
311
336
|
alignItems: 'flex-end'
|
|
312
337
|
};
|
|
313
338
|
}
|
|
314
|
-
}, [position, bottomOffset, insets.bottom]);
|
|
339
|
+
}, [position, bottomOffset, insets.bottom, defaultBottomOffset, edgeOffset]);
|
|
315
340
|
|
|
316
341
|
// Vertical slot offset per index: secondary at index i sits (diameter + gap) * (i + 1) above primary
|
|
317
|
-
const slotOffset = index => -((sizeStyles.diameter +
|
|
342
|
+
const slotOffset = index => -((sizeStyles.diameter + secondaryGap) * (index + 1));
|
|
318
343
|
const backdropOpacity = progress.interpolate({
|
|
319
344
|
inputRange: [0, 1],
|
|
320
345
|
outputRange: [0, 0.4]
|
|
@@ -338,7 +363,7 @@ const FloatingActionButtonGroup = props => {
|
|
|
338
363
|
testID: testID ? `${testID}-backdrop` : undefined
|
|
339
364
|
})
|
|
340
365
|
}) : null, /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
341
|
-
style: positionStyle,
|
|
366
|
+
style: [positionStyle, containerStyle],
|
|
342
367
|
accessibilityRole: 'menu',
|
|
343
368
|
testID: testID,
|
|
344
369
|
children: [actions.map((action, index) => {
|
|
@@ -374,13 +399,13 @@ const FloatingActionButtonGroup = props => {
|
|
|
374
399
|
paddingVertical: theme.spacing.xs,
|
|
375
400
|
borderRadius: theme.radius.sm,
|
|
376
401
|
marginRight: theme.spacing.sm
|
|
377
|
-
}],
|
|
402
|
+
}, labelPillStyle],
|
|
378
403
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
379
|
-
style: {
|
|
404
|
+
style: [{
|
|
380
405
|
color: theme.colors.text.primary,
|
|
381
406
|
fontSize: theme.typography.fontSize.sm,
|
|
382
407
|
fontWeight: theme.typography.fontWeight.medium
|
|
383
|
-
},
|
|
408
|
+
}, labelStyle],
|
|
384
409
|
numberOfLines: 1,
|
|
385
410
|
children: action.label
|
|
386
411
|
})
|
|
@@ -397,7 +422,7 @@ const FloatingActionButtonGroup = props => {
|
|
|
397
422
|
height: secondaryDiameter,
|
|
398
423
|
borderRadius: secondaryDiameter / 2,
|
|
399
424
|
backgroundColor: itemBackground
|
|
400
|
-
}],
|
|
425
|
+
}, secondaryActionStyle],
|
|
401
426
|
testID: testID ? `${testID}-action-${action.key}` : undefined,
|
|
402
427
|
children: /*#__PURE__*/_react.default.isValidElement(action.icon) ? action.icon : /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
403
428
|
style: {
|
|
@@ -32,7 +32,10 @@ const ForceUpdateDialog = ({
|
|
|
32
32
|
title = 'Update available',
|
|
33
33
|
message = 'A new version of the app is available. Please update to continue using the latest features and security improvements.',
|
|
34
34
|
updateLabel = 'Update now',
|
|
35
|
-
laterLabel = 'Later'
|
|
35
|
+
laterLabel = 'Later',
|
|
36
|
+
containerStyle,
|
|
37
|
+
titleStyle,
|
|
38
|
+
messageStyle
|
|
36
39
|
}) => {
|
|
37
40
|
const [updating, setUpdating] = (0, _react.useState)(false);
|
|
38
41
|
const handleUpdate = (0, _react.useCallback)(() => {
|
|
@@ -73,7 +76,10 @@ const ForceUpdateDialog = ({
|
|
|
73
76
|
message: message,
|
|
74
77
|
variant: "info",
|
|
75
78
|
actions: actions,
|
|
76
|
-
dismissOnAction: false
|
|
79
|
+
dismissOnAction: false,
|
|
80
|
+
containerStyle: containerStyle,
|
|
81
|
+
titleStyle: titleStyle,
|
|
82
|
+
messageStyle: messageStyle
|
|
77
83
|
});
|
|
78
84
|
};
|
|
79
85
|
exports.ForceUpdateDialog = ForceUpdateDialog;
|
|
@@ -21,6 +21,7 @@ const FormField = exports.FormField = /*#__PURE__*/(0, _react.forwardRef)((props
|
|
|
21
21
|
helperStyle,
|
|
22
22
|
errorStyle,
|
|
23
23
|
containerStyle,
|
|
24
|
+
inputContainerStyle: inputContainerStyleProp,
|
|
24
25
|
accessibilityLabel,
|
|
25
26
|
testID
|
|
26
27
|
} = props;
|
|
@@ -61,12 +62,12 @@ const FormField = exports.FormField = /*#__PURE__*/(0, _react.forwardRef)((props
|
|
|
61
62
|
testID: testID,
|
|
62
63
|
children: [layout === 'inline' ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
|
|
63
64
|
children: [labelNode, /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
64
|
-
style: inputContainerStyle,
|
|
65
|
+
style: [inputContainerStyle, inputContainerStyleProp],
|
|
65
66
|
children: children
|
|
66
67
|
})]
|
|
67
68
|
}) : /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
|
|
68
69
|
children: [labelNode, /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
69
|
-
style: inputContainerStyle,
|
|
70
|
+
style: [inputContainerStyle, inputContainerStyleProp],
|
|
70
71
|
children: children
|
|
71
72
|
})]
|
|
72
73
|
}), showHelper ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|