@kanso-labs/react-native-kanso-ui 0.0.0-stage → 0.1.0

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 (145) hide show
  1. package/LICENSE.md +20 -0
  2. package/README.md +205 -2
  3. package/dist/button/index.d.ts +56 -0
  4. package/dist/button/index.js +169 -0
  5. package/dist/button/index.js.map +1 -0
  6. package/dist/button/palettes.js +47 -0
  7. package/dist/button/palettes.js.map +1 -0
  8. package/dist/chip/index.js +194 -0
  9. package/dist/chip/index.js.map +1 -0
  10. package/dist/chip/styles.js +36 -0
  11. package/dist/chip/styles.js.map +1 -0
  12. package/dist/clipboard/index.js +58 -0
  13. package/dist/clipboard/index.js.map +1 -0
  14. package/dist/components/avatar/index.d.ts +82 -0
  15. package/dist/components/avatar/index.js +62 -0
  16. package/dist/components/avatar/index.js.map +1 -0
  17. package/dist/components/button/index.d.ts +87 -0
  18. package/dist/components/button/index.js +377 -0
  19. package/dist/components/button/index.js.map +1 -0
  20. package/dist/components/card/index.d.ts +78 -0
  21. package/dist/components/card/index.js +315 -0
  22. package/dist/components/card/index.js.map +1 -0
  23. package/dist/components/checkbox/index.d.ts +76 -0
  24. package/dist/components/checkbox/index.js +360 -0
  25. package/dist/components/checkbox/index.js.map +1 -0
  26. package/dist/components/chip/index.d.ts +84 -0
  27. package/dist/components/chip/index.js +257 -0
  28. package/dist/components/chip/index.js.map +1 -0
  29. package/dist/components/chip-group/index.d.ts +143 -0
  30. package/dist/components/chip-group/index.js +669 -0
  31. package/dist/components/chip-group/index.js.map +1 -0
  32. package/dist/components/copy-field/index.d.ts +60 -0
  33. package/dist/components/copy-field/index.js +277 -0
  34. package/dist/components/copy-field/index.js.map +1 -0
  35. package/dist/components/currency/index.d.ts +69 -0
  36. package/dist/components/currency/index.js +162 -0
  37. package/dist/components/currency/index.js.map +1 -0
  38. package/dist/components/form/index.d.ts +84 -0
  39. package/dist/components/form/index.js +95 -0
  40. package/dist/components/form/index.js.map +1 -0
  41. package/dist/components/icon-button/index.d.ts +68 -0
  42. package/dist/components/icon-button/index.js +289 -0
  43. package/dist/components/icon-button/index.js.map +1 -0
  44. package/dist/components/link/index.d.ts +59 -0
  45. package/dist/components/link/index.js +191 -0
  46. package/dist/components/link/index.js.map +1 -0
  47. package/dist/components/number-field/index.d.ts +151 -0
  48. package/dist/components/number-field/index.js +832 -0
  49. package/dist/components/number-field/index.js.map +1 -0
  50. package/dist/components/product-icon/index.d.ts +70 -0
  51. package/dist/components/product-icon/index.js +60 -0
  52. package/dist/components/product-icon/index.js.map +1 -0
  53. package/dist/components/radio-group/index.d.ts +105 -0
  54. package/dist/components/radio-group/index.js +597 -0
  55. package/dist/components/radio-group/index.js.map +1 -0
  56. package/dist/components/search-field/index.d.ts +98 -0
  57. package/dist/components/search-field/index.js +521 -0
  58. package/dist/components/search-field/index.js.map +1 -0
  59. package/dist/components/segmented-button/index.d.ts +113 -0
  60. package/dist/components/segmented-button/index.js +937 -0
  61. package/dist/components/segmented-button/index.js.map +1 -0
  62. package/dist/components/separator/index.d.ts +45 -0
  63. package/dist/components/separator/index.js +109 -0
  64. package/dist/components/separator/index.js.map +1 -0
  65. package/dist/components/stack/index.d.ts +70 -0
  66. package/dist/components/stack/index.js +107 -0
  67. package/dist/components/stack/index.js.map +1 -0
  68. package/dist/components/switch/index.d.ts +76 -0
  69. package/dist/components/switch/index.js +591 -0
  70. package/dist/components/switch/index.js.map +1 -0
  71. package/dist/components/text/index.d.ts +44 -0
  72. package/dist/components/text/index.js +78 -0
  73. package/dist/components/text/index.js.map +1 -0
  74. package/dist/components/text-field/index.d.ts +146 -0
  75. package/dist/components/text-field/index.js +228 -0
  76. package/dist/components/text-field/index.js.map +1 -0
  77. package/dist/control/index.js +117 -0
  78. package/dist/control/index.js.map +1 -0
  79. package/dist/control/styles.js +36 -0
  80. package/dist/control/styles.js.map +1 -0
  81. package/dist/field/index.d.ts +13 -0
  82. package/dist/field/index.js +1007 -0
  83. package/dist/field/index.js.map +1 -0
  84. package/dist/field/styles.js +131 -0
  85. package/dist/field/styles.js.map +1 -0
  86. package/dist/form/index.d.ts +24 -0
  87. package/dist/form/index.js +209 -0
  88. package/dist/form/index.js.map +1 -0
  89. package/dist/glyphs/icon-style.d.ts +25 -0
  90. package/dist/glyphs/icon-style.js +22 -0
  91. package/dist/glyphs/icon-style.js.map +1 -0
  92. package/dist/glyphs/index.js +170 -0
  93. package/dist/glyphs/index.js.map +1 -0
  94. package/dist/glyphs/styles.js +7 -0
  95. package/dist/glyphs/styles.js.map +1 -0
  96. package/dist/hooks/useWindowSizeClass.d.ts +25 -0
  97. package/dist/hooks/useWindowSizeClass.js +39 -0
  98. package/dist/hooks/useWindowSizeClass.js.map +1 -0
  99. package/dist/index.d.ts +31 -0
  100. package/dist/index.js +27 -0
  101. package/dist/mark/image.js +61 -0
  102. package/dist/mark/image.js.map +1 -0
  103. package/dist/mark/index.d.ts +9 -0
  104. package/dist/mark/index.js +234 -0
  105. package/dist/mark/index.js.map +1 -0
  106. package/dist/mark/initials.js +65 -0
  107. package/dist/mark/initials.js.map +1 -0
  108. package/dist/mark/styles.d.ts +1 -0
  109. package/dist/mark/styles.js +73 -0
  110. package/dist/mark/styles.js.map +1 -0
  111. package/dist/number/parser.js +321 -0
  112. package/dist/number/parser.js.map +1 -0
  113. package/dist/number/state.js +235 -0
  114. package/dist/number/state.js.map +1 -0
  115. package/dist/overlay/host.js +111 -0
  116. package/dist/overlay/host.js.map +1 -0
  117. package/dist/press/index.js +350 -0
  118. package/dist/press/index.js.map +1 -0
  119. package/dist/press/styles.js +31 -0
  120. package/dist/press/styles.js.map +1 -0
  121. package/dist/router/index.d.ts +28 -0
  122. package/dist/router/index.js +82 -0
  123. package/dist/router/index.js.map +1 -0
  124. package/dist/theme/color.js +25 -0
  125. package/dist/theme/color.js.map +1 -0
  126. package/dist/theme/resolve.d.ts +6 -0
  127. package/dist/theme/resolve.js +310 -0
  128. package/dist/theme/resolve.js.map +1 -0
  129. package/dist/theme/scope.d.ts +42 -0
  130. package/dist/theme/scope.js +80 -0
  131. package/dist/theme/scope.js.map +1 -0
  132. package/dist/theme/styles.js +39 -0
  133. package/dist/theme/styles.js.map +1 -0
  134. package/dist/theme-scope.d.ts +56 -0
  135. package/dist/theme-scope.js +127 -0
  136. package/dist/theme-scope.js.map +1 -0
  137. package/dist/tokens/defaults.d.ts +407 -0
  138. package/dist/tokens/defaults.js +403 -0
  139. package/dist/tokens/defaults.js.map +1 -0
  140. package/dist/typography/fonts.js +84 -0
  141. package/dist/typography/fonts.js.map +1 -0
  142. package/dist/typography/roles.d.ts +10 -0
  143. package/dist/typography/roles.js +82 -0
  144. package/dist/typography/roles.js.map +1 -0
  145. package/package.json +132 -4
@@ -0,0 +1,1007 @@
1
+ import { IconStyleContext } from "../glyphs/icon-style.js";
2
+ import { useTheme } from "../theme/scope.js";
3
+ import { composeStyles } from "../theme/styles.js";
4
+ import { useFontFamily } from "../typography/fonts.js";
5
+ import { useTypeRole } from "../typography/roles.js";
6
+ import { useInsideForm } from "../form/index.js";
7
+ import { withOpacity } from "../theme/color.js";
8
+ import { usePressFeedback } from "../press/index.js";
9
+ import { fieldStylesOf } from "./styles.js";
10
+ import { c } from "react/compiler-runtime";
11
+ import { AccessibilityInfo, Platform, Pressable, Text, TextInput, View, useWindowDimensions } from "react-native";
12
+ import { createContext, use, useEffect, useId, useRef, useState } from "react";
13
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
14
+ import Animated, { Easing, useAnimatedStyle, useDerivedValue, useReducedMotion, withTiming } from "react-native-reanimated";
15
+ //#region src/field/index.tsx
16
+ const ICON_SIZE = 24;
17
+ const OUTSIDE_BOX = {
18
+ disabled: false,
19
+ floated: true,
20
+ invalid: false,
21
+ label: "none",
22
+ required: false,
23
+ underLabel: false
24
+ };
25
+ const BoxContext = createContext(OUTSIDE_BOX);
26
+ const NO_PARTS = [];
27
+ let counterFormat;
28
+ /**
29
+ * How a field's control is described by the line under it: the error while
30
+ * there is one, otherwise the description, then the limit where there is a
31
+ * `maxLength`. Hand the result to {@link FieldInput} as `described`, and the
32
+ * same `id` to {@link FieldMessage}.
33
+ */
34
+ function describedBy(id, { characterLimitLabel, description, error, maxLength }) {
35
+ const ids = idsOf(id);
36
+ const message = error === void 0 ? {
37
+ id: ids.description,
38
+ text: description ?? ""
39
+ } : {
40
+ id: ids.error,
41
+ text: error
42
+ };
43
+ const limit = limitOf(maxLength, characterLimitLabel);
44
+ return [...message.text === "" ? [] : [message], ...limit === void 0 ? [] : [{
45
+ id: ids.limit,
46
+ text: limit
47
+ }]];
48
+ }
49
+ /**
50
+ * The box a control sits in, filled or outlined, with its label. Pressed
51
+ * anywhere, it focuses its control. The states it draws are handed to it,
52
+ * since the field around it is what knows them.
53
+ */
54
+ function FieldBox(t0) {
55
+ const $ = c(72);
56
+ const { children, control, end, floatingLabel: t1, isDisabled: t2, isFocused: t3, isInvalid: t4, isPopulated: t5, isRequired: t6, label, leading, trailing, variant: t7 } = t0;
57
+ const floatingLabel = t1 === void 0 ? true : t1;
58
+ const isDisabled = t2 === void 0 ? false : t2;
59
+ const isFocused = t3 === void 0 ? false : t3;
60
+ const isInvalid = t4 === void 0 ? false : t4;
61
+ const isPopulated = t5 === void 0 ? false : t5;
62
+ const isRequired = t6 === void 0 ? false : t6;
63
+ const variant = t7 === void 0 ? "filled" : t7;
64
+ const theme = useTheme();
65
+ const styles = fieldStylesOf(theme);
66
+ const { fontScale } = useWindowDimensions();
67
+ const [notch, setNotch] = useState(0);
68
+ const { colors, radii, spacing, stateLayerOpacity, typography } = theme;
69
+ let t8;
70
+ if ($[0] !== radii.xs) {
71
+ t8 = {
72
+ borderTopEndRadius: radii.xs,
73
+ borderTopStartRadius: radii.xs
74
+ };
75
+ $[0] = radii.xs;
76
+ $[1] = t8;
77
+ } else t8 = $[1];
78
+ let t9;
79
+ if ($[2] !== colors.onSurface || $[3] !== isDisabled || $[4] !== t8) {
80
+ t9 = {
81
+ color: colors.onSurface,
82
+ corners: t8,
83
+ disabled: isDisabled,
84
+ disableRipple: true
85
+ };
86
+ $[2] = colors.onSurface;
87
+ $[3] = isDisabled;
88
+ $[4] = t8;
89
+ $[5] = t9;
90
+ } else t9 = $[5];
91
+ const feedback = usePressFeedback(t9);
92
+ const outlined = variant === "outlined";
93
+ const floated = !floatingLabel || isFocused || isPopulated;
94
+ let t10;
95
+ if ($[6] !== feedback.hovered || $[7] !== isDisabled || $[8] !== isFocused || $[9] !== isInvalid) {
96
+ t10 = {
97
+ disabled: isDisabled,
98
+ focused: isFocused,
99
+ hovered: feedback.hovered,
100
+ invalid: isInvalid
101
+ };
102
+ $[6] = feedback.hovered;
103
+ $[7] = isDisabled;
104
+ $[8] = isFocused;
105
+ $[9] = isInvalid;
106
+ $[10] = t10;
107
+ } else t10 = $[10];
108
+ const rule = useRuleMotion(theme, t10);
109
+ const t11 = !outlined;
110
+ let t12;
111
+ if ($[11] !== floated || $[12] !== floatingLabel || $[13] !== isDisabled || $[14] !== isInvalid || $[15] !== isRequired || $[16] !== t11) {
112
+ t12 = boxControlOf(floatingLabel, floated, isDisabled, isInvalid, isRequired, t11);
113
+ $[11] = floated;
114
+ $[12] = floatingLabel;
115
+ $[13] = isDisabled;
116
+ $[14] = isInvalid;
117
+ $[15] = isRequired;
118
+ $[16] = t11;
119
+ $[17] = t12;
120
+ } else t12 = $[17];
121
+ const boxControl = t12;
122
+ let t13;
123
+ if ($[18] !== colors.onSurface || $[19] !== stateLayerOpacity.disabledContent) {
124
+ t13 = withOpacity(colors.onSurface, stateLayerOpacity.disabledContent);
125
+ $[18] = colors.onSurface;
126
+ $[19] = stateLayerOpacity.disabledContent;
127
+ $[20] = t13;
128
+ } else t13 = $[20];
129
+ const disabledContent = t13;
130
+ const T0 = Pressable;
131
+ const t14 = false;
132
+ const t15 = false;
133
+ const t16 = feedback.handlers.onHoverIn;
134
+ const t17 = feedback.handlers.onHoverOut;
135
+ let t18;
136
+ if ($[21] !== control) {
137
+ t18 = focusOf(control);
138
+ $[21] = control;
139
+ $[22] = t18;
140
+ } else t18 = $[22];
141
+ const t19 = composeStyles(styles.box, leading === void 0 ? void 0 : styles.boxLeading, trailing === void 0 ? void 0 : styles.boxTrailing, outlined ? styles.boxOutlined : void 0, isDisabled && !outlined ? styles.boxDisabled : void 0, minHeightOf(outlined ? 2 * spacing.lg + typography.bodyLargeLineHeight * fontScale : 2 * spacing.sm + (typography.bodySmallLineHeight + typography.bodyLargeLineHeight) * fontScale));
142
+ const t20 = outlined ? /* @__PURE__ */ jsxs(View, {
143
+ "aria-hidden": true,
144
+ style: styles.outline,
145
+ children: [
146
+ /* @__PURE__ */ jsx(View, {
147
+ style: composeStyles(styles.outlineStart, widthOf(outlineInset(spacing, leading))),
148
+ children: /* @__PURE__ */ jsx(FieldStroke, {
149
+ color: rule.color,
150
+ sides: "all",
151
+ style: styles.outlineStartBox,
152
+ width: rule.width
153
+ })
154
+ }),
155
+ /* @__PURE__ */ jsx(View, {
156
+ style: composeStyles(styles.outlineNotch, widthOf(floated ? notch : 0)),
157
+ children: /* @__PURE__ */ jsx(FieldStroke, {
158
+ color: rule.color,
159
+ sides: "all",
160
+ style: styles.outlineNotchBox,
161
+ width: rule.width
162
+ })
163
+ }),
164
+ /* @__PURE__ */ jsx(View, {
165
+ style: composeStyles(styles.outlineEnd, minWidthOf(outlineInset(spacing, trailing))),
166
+ children: /* @__PURE__ */ jsx(FieldStroke, {
167
+ color: rule.color,
168
+ sides: "all",
169
+ style: styles.outlineEndBox,
170
+ width: rule.width
171
+ })
172
+ })
173
+ ]
174
+ }) : /* @__PURE__ */ jsxs(Fragment$1, { children: [feedback.layer, /* @__PURE__ */ jsx(FieldStroke, {
175
+ color: rule.color,
176
+ sides: "top",
177
+ style: styles.indicator,
178
+ width: rule.width
179
+ })] });
180
+ let t21;
181
+ if ($[23] !== colors.onSurfaceVariant || $[24] !== disabledContent || $[25] !== isDisabled || $[26] !== leading || $[27] !== styles.icon) {
182
+ t21 = leading === void 0 ? null : /* @__PURE__ */ jsx(View, {
183
+ style: styles.icon,
184
+ children: /* @__PURE__ */ jsx(IconStyleContext, {
185
+ value: iconStyleOf(isDisabled ? disabledContent : colors.onSurfaceVariant),
186
+ children: leading
187
+ })
188
+ });
189
+ $[23] = colors.onSurfaceVariant;
190
+ $[24] = disabledContent;
191
+ $[25] = isDisabled;
192
+ $[26] = leading;
193
+ $[27] = styles.icon;
194
+ $[28] = t21;
195
+ } else t21 = $[28];
196
+ let t22;
197
+ if ($[29] !== floated || $[30] !== floatingLabel || $[31] !== isDisabled || $[32] !== isFocused || $[33] !== isInvalid || $[34] !== isRequired || $[35] !== label || $[36] !== variant) {
198
+ t22 = /* @__PURE__ */ jsx(BoxLabel, {
199
+ floated,
200
+ floatingLabel,
201
+ isDisabled,
202
+ isFocused,
203
+ isInvalid,
204
+ isRequired,
205
+ variant,
206
+ children: label
207
+ });
208
+ $[29] = floated;
209
+ $[30] = floatingLabel;
210
+ $[31] = isDisabled;
211
+ $[32] = isFocused;
212
+ $[33] = isInvalid;
213
+ $[34] = isRequired;
214
+ $[35] = label;
215
+ $[36] = variant;
216
+ $[37] = t22;
217
+ } else t22 = $[37];
218
+ let t23;
219
+ if ($[38] !== floatingLabel || $[39] !== isRequired || $[40] !== label || $[41] !== outlined || $[42] !== setNotch) {
220
+ t23 = outlined ? /* @__PURE__ */ jsx(NotchMeasure, {
221
+ floatingLabel,
222
+ isRequired,
223
+ onMeasure: setNotch,
224
+ children: label
225
+ }) : null;
226
+ $[38] = floatingLabel;
227
+ $[39] = isRequired;
228
+ $[40] = label;
229
+ $[41] = outlined;
230
+ $[42] = setNotch;
231
+ $[43] = t23;
232
+ } else t23 = $[43];
233
+ let t24;
234
+ if ($[44] !== boxControl || $[45] !== children) {
235
+ t24 = /* @__PURE__ */ jsx(BoxContext, {
236
+ value: boxControl,
237
+ children
238
+ });
239
+ $[44] = boxControl;
240
+ $[45] = children;
241
+ $[46] = t24;
242
+ } else t24 = $[46];
243
+ let t25;
244
+ if ($[47] !== styles.column || $[48] !== t22 || $[49] !== t23 || $[50] !== t24) {
245
+ t25 = /* @__PURE__ */ jsxs(View, {
246
+ style: styles.column,
247
+ children: [
248
+ t22,
249
+ t23,
250
+ t24
251
+ ]
252
+ });
253
+ $[47] = styles.column;
254
+ $[48] = t22;
255
+ $[49] = t23;
256
+ $[50] = t24;
257
+ $[51] = t25;
258
+ } else t25 = $[51];
259
+ let t26;
260
+ if ($[52] !== colors.error || $[53] !== colors.onSurfaceVariant || $[54] !== disabledContent || $[55] !== isDisabled || $[56] !== isInvalid || $[57] !== styles.icon || $[58] !== trailing) {
261
+ t26 = trailing === void 0 ? null : /* @__PURE__ */ jsx(View, {
262
+ style: styles.icon,
263
+ children: /* @__PURE__ */ jsx(IconStyleContext, {
264
+ value: iconStyleOf(isDisabled ? disabledContent : isInvalid ? colors.error : colors.onSurfaceVariant),
265
+ children: trailing
266
+ })
267
+ });
268
+ $[52] = colors.error;
269
+ $[53] = colors.onSurfaceVariant;
270
+ $[54] = disabledContent;
271
+ $[55] = isDisabled;
272
+ $[56] = isInvalid;
273
+ $[57] = styles.icon;
274
+ $[58] = trailing;
275
+ $[59] = t26;
276
+ } else t26 = $[59];
277
+ let t27;
278
+ if ($[60] !== T0 || $[61] !== end || $[62] !== feedback.handlers.onHoverIn || $[63] !== feedback.handlers.onHoverOut || $[64] !== isDisabled || $[65] !== t18 || $[66] !== t19 || $[67] !== t20 || $[68] !== t21 || $[69] !== t25 || $[70] !== t26) {
279
+ t27 = /* @__PURE__ */ jsxs(T0, {
280
+ accessible: t14,
281
+ disabled: isDisabled,
282
+ focusable: t15,
283
+ onHoverIn: t16,
284
+ onHoverOut: t17,
285
+ onPress: t18,
286
+ style: t19,
287
+ children: [
288
+ t20,
289
+ t21,
290
+ t25,
291
+ end,
292
+ t26
293
+ ]
294
+ });
295
+ $[60] = T0;
296
+ $[61] = end;
297
+ $[62] = feedback.handlers.onHoverIn;
298
+ $[63] = feedback.handlers.onHoverOut;
299
+ $[64] = isDisabled;
300
+ $[65] = t18;
301
+ $[66] = t19;
302
+ $[67] = t20;
303
+ $[68] = t21;
304
+ $[69] = t25;
305
+ $[70] = t26;
306
+ $[71] = t27;
307
+ } else t27 = $[71];
308
+ return t27;
309
+ }
310
+ /**
311
+ * A field's text control, in a {@link FieldBox}, or in {@link FieldStates}
312
+ * inside a container of a field's own. In a box it clears the label at the
313
+ * top where the box is filled, and shows a prefix and a suffix only while the
314
+ * label has floated, since at rest the label sits on their line. It takes the
315
+ * error role for its caret while the field has an error, and draws a
316
+ * placeholder in the muted role.
317
+ *
318
+ * It is described by its prefix and suffix, ahead of what the field hands it
319
+ * in `described`, so a reader hears the unit the value is read against as a
320
+ * sighted one sees it beside the value: on iOS and Android as its hint, and
321
+ * under React Native Web through `aria-describedby`, which drops the hint.
322
+ */
323
+ function FieldInput(t0) {
324
+ const $ = c(23);
325
+ let prefix;
326
+ let props;
327
+ let suffix;
328
+ let t1;
329
+ let t2;
330
+ if ($[0] !== t0) {
331
+ ({described: t1, numeric: t2, prefix, suffix, ...props} = t0);
332
+ $[0] = t0;
333
+ $[1] = prefix;
334
+ $[2] = props;
335
+ $[3] = suffix;
336
+ $[4] = t1;
337
+ $[5] = t2;
338
+ } else {
339
+ prefix = $[1];
340
+ props = $[2];
341
+ suffix = $[3];
342
+ t1 = $[4];
343
+ t2 = $[5];
344
+ }
345
+ const described = t1 === void 0 ? NO_PARTS : t1;
346
+ const numeric = t2 === void 0 ? false : t2;
347
+ const box = use(BoxContext);
348
+ const theme = useTheme();
349
+ const styles = fieldStylesOf(theme);
350
+ const { fontScale } = useWindowDimensions();
351
+ const role = useTypeRole("bodyLarge");
352
+ const mono = useFontFamily(theme.typography.fontFamilyMono);
353
+ const id = useId();
354
+ const { colors, stateLayerOpacity, typography } = theme;
355
+ const content = box.disabled ? withOpacity(colors.onSurface, stateLayerOpacity.disabledContent) : colors.onSurface;
356
+ const caret = box.invalid ? colors.error : colors.primary;
357
+ const muted = box.disabled ? withOpacity(colors.onSurface, stateLayerOpacity.disabledContent) : colors.onSurfaceVariant;
358
+ const affixed = prefix !== void 0 || suffix !== void 0;
359
+ const clearance = box.underLabel ? marginTopOf(typography.bodySmallLineHeight * fontScale) : void 0;
360
+ const affixStyle = composeStyles(role, colorOf(muted));
361
+ let t3;
362
+ if ($[6] !== described || $[7] !== id || $[8] !== prefix || $[9] !== suffix) {
363
+ t3 = descriptionOf([
364
+ ...affixPart(`${id}-prefix`, prefix),
365
+ ...affixPart(`${id}-suffix`, suffix),
366
+ ...described
367
+ ]);
368
+ $[6] = described;
369
+ $[7] = id;
370
+ $[8] = prefix;
371
+ $[9] = suffix;
372
+ $[10] = t3;
373
+ } else t3 = $[10];
374
+ let t4;
375
+ if ($[11] !== box) {
376
+ t4 = webStateOf(box);
377
+ $[11] = box;
378
+ $[12] = t4;
379
+ } else t4 = $[12];
380
+ const control = /* @__PURE__ */ jsx(TextInput, {
381
+ ...Platform.OS === "web" ? INHERITS_DIRECTION : void 0,
382
+ ...props,
383
+ ...t3,
384
+ ...t4,
385
+ "aria-disabled": box.disabled,
386
+ cursorColor: caret,
387
+ placeholderTextColor: muted,
388
+ selectionColor: caret,
389
+ style: composeStyles(role, styles.input, colorOf(content), numeric ? numericOf(mono) : void 0, minHeightOf(typography.bodyLargeLineHeight * fontScale), affixed ? void 0 : clearance),
390
+ underlineColorAndroid: "transparent"
391
+ });
392
+ if (!affixed) return control;
393
+ let t5;
394
+ if ($[13] !== affixStyle || $[14] !== box.floated || $[15] !== id || $[16] !== prefix) {
395
+ t5 = prefix === void 0 ? null : /* @__PURE__ */ jsx(Affix, {
396
+ floated: box.floated,
397
+ id: `${id}-prefix`,
398
+ style: affixStyle,
399
+ children: prefix
400
+ });
401
+ $[13] = affixStyle;
402
+ $[14] = box.floated;
403
+ $[15] = id;
404
+ $[16] = prefix;
405
+ $[17] = t5;
406
+ } else t5 = $[17];
407
+ let t6;
408
+ if ($[18] !== affixStyle || $[19] !== box.floated || $[20] !== id || $[21] !== suffix) {
409
+ t6 = suffix === void 0 ? null : /* @__PURE__ */ jsx(Affix, {
410
+ floated: box.floated,
411
+ id: `${id}-suffix`,
412
+ style: affixStyle,
413
+ children: suffix
414
+ });
415
+ $[18] = affixStyle;
416
+ $[19] = box.floated;
417
+ $[20] = id;
418
+ $[21] = suffix;
419
+ $[22] = t6;
420
+ } else t6 = $[22];
421
+ return /* @__PURE__ */ jsxs(View, {
422
+ style: composeStyles(styles.affixLine, clearance),
423
+ children: [
424
+ t5,
425
+ control,
426
+ t6
427
+ ]
428
+ });
429
+ }
430
+ /**
431
+ * The line under a field: the error while there is one, the description
432
+ * otherwise, and the count of characters at its end. With nothing to show it
433
+ * is out of the flow, so the field ends at its box. Inside a form it is drawn
434
+ * anyway, empty, since a form is where an error arrives after the fact, from
435
+ * a server or on a submission, and every field below this one would
436
+ * otherwise move by the line's height when it does.
437
+ *
438
+ * On iOS and Android the control reads the line out as its hint, so the line
439
+ * itself is hidden from VoiceOver and TalkBack rather than read twice. An
440
+ * error is announced as it arrives, since a hint that changes is not read
441
+ * again: on iOS through `announceForAccessibility`, and on Android, where the
442
+ * error is left reachable for it, by a polite live region around it, which
443
+ * is also what announces it under React Native Web. An error the field opens
444
+ * with is not announced, as a live region in a browser does not read what it
445
+ * was mounted holding.
446
+ *
447
+ * The count is hidden everywhere. It changes on every keystroke, and read
448
+ * back at that rate it is worse than not hearing it, so the limit is said
449
+ * once in the control's description instead.
450
+ */
451
+ function FieldMessage(t0) {
452
+ const $ = c(18);
453
+ const { characterCount: t1, characterLimitLabel, description, error, id, length: t2, maxLength } = t0;
454
+ const characterCount = t1 === void 0 ? false : t1;
455
+ const length = t2 === void 0 ? 0 : t2;
456
+ const theme = useTheme();
457
+ const styles = fieldStylesOf(theme);
458
+ const role = useTypeRole("bodySmall");
459
+ const { fontScale } = useWindowDimensions();
460
+ let t3;
461
+ if ($[0] !== id) {
462
+ t3 = idsOf(id);
463
+ $[0] = id;
464
+ $[1] = t3;
465
+ } else t3 = $[1];
466
+ const ids = t3;
467
+ const invalid = error !== void 0;
468
+ let t4;
469
+ if ($[2] !== characterLimitLabel || $[3] !== maxLength) {
470
+ t4 = limitOf(maxLength, characterLimitLabel);
471
+ $[2] = characterLimitLabel;
472
+ $[3] = maxLength;
473
+ $[4] = t4;
474
+ } else t4 = $[4];
475
+ const limit = t4;
476
+ const insideForm = useInsideForm();
477
+ const collapsed = !invalid && description === void 0 && !characterCount && !insideForm;
478
+ const { colors, typography } = theme;
479
+ const messageStyle = composeStyles(role, colorOf(invalid ? colors.error : colors.onSurfaceVariant), SHRINKS);
480
+ useErrorAnnouncement(error);
481
+ const T0 = View;
482
+ const t5 = composeStyles(styles.messageLine, collapsed ? styles.messageLineCollapsed : minHeightOf(typography.bodySmallLineHeight * fontScale));
483
+ const t6 = invalid && error !== "" ? SHRINKS : OUT_OF_FLOW;
484
+ const t7 = invalid && error !== "" ? /* @__PURE__ */ jsx(Text, {
485
+ id: ids.error,
486
+ style: messageStyle,
487
+ children: error
488
+ }) : null;
489
+ let t8;
490
+ if ($[5] !== t6 || $[6] !== t7) {
491
+ t8 = /* @__PURE__ */ jsx(View, {
492
+ "aria-live": "polite",
493
+ ...Platform.OS === "web" ? ATOMIC : void 0,
494
+ ...Platform.OS === "ios" ? HIDDEN : void 0,
495
+ style: t6,
496
+ children: t7
497
+ });
498
+ $[5] = t6;
499
+ $[6] = t7;
500
+ $[7] = t8;
501
+ } else t8 = $[7];
502
+ const t9 = invalid || description === void 0 ? null : /* @__PURE__ */ jsx(Text, {
503
+ ...Platform.OS === "web" ? void 0 : HIDDEN,
504
+ id: ids.description,
505
+ style: messageStyle,
506
+ children: description
507
+ });
508
+ let t10;
509
+ if ($[8] !== ids || $[9] !== limit) {
510
+ t10 = limit === void 0 || Platform.OS !== "web" ? null : /* @__PURE__ */ jsx(Text, {
511
+ id: ids.limit,
512
+ style: NOT_DRAWN,
513
+ children: limit
514
+ });
515
+ $[8] = ids;
516
+ $[9] = limit;
517
+ $[10] = t10;
518
+ } else t10 = $[10];
519
+ const t11 = characterCount ? /* @__PURE__ */ jsx(Text, {
520
+ "aria-hidden": true,
521
+ style: composeStyles(messageStyle, styles.counter),
522
+ children: countOf(length, maxLength)
523
+ }) : null;
524
+ let t12;
525
+ if ($[11] !== T0 || $[12] !== t10 || $[13] !== t11 || $[14] !== t5 || $[15] !== t8 || $[16] !== t9) {
526
+ t12 = /* @__PURE__ */ jsxs(T0, {
527
+ style: t5,
528
+ children: [
529
+ t8,
530
+ t9,
531
+ t10,
532
+ t11
533
+ ]
534
+ });
535
+ $[11] = T0;
536
+ $[12] = t10;
537
+ $[13] = t11;
538
+ $[14] = t5;
539
+ $[15] = t8;
540
+ $[16] = t9;
541
+ $[17] = t12;
542
+ } else t12 = $[17];
543
+ return t12;
544
+ }
545
+ /**
546
+ * Hands a control outside a box the states it is drawn in, for a field that
547
+ * draws a container of its own around the control, as SearchField's bar is.
548
+ * The control takes its colours and the state a screen reader reads from
549
+ * these, as it does from the box around it.
550
+ */
551
+ function FieldStates(t0) {
552
+ const $ = c(7);
553
+ const { children, isDisabled: t1, isInvalid: t2, isRequired: t3 } = t0;
554
+ const isDisabled = t1 === void 0 ? false : t1;
555
+ const isInvalid = t2 === void 0 ? false : t2;
556
+ const isRequired = t3 === void 0 ? false : t3;
557
+ let t4;
558
+ if ($[0] !== isDisabled || $[1] !== isInvalid || $[2] !== isRequired) {
559
+ t4 = {
560
+ ...OUTSIDE_BOX,
561
+ disabled: isDisabled,
562
+ invalid: isInvalid,
563
+ required: isRequired
564
+ };
565
+ $[0] = isDisabled;
566
+ $[1] = isInvalid;
567
+ $[2] = isRequired;
568
+ $[3] = t4;
569
+ } else t4 = $[3];
570
+ const states = t4;
571
+ let t5;
572
+ if ($[4] !== children || $[5] !== states) {
573
+ t5 = /* @__PURE__ */ jsx(BoxContext, {
574
+ value: states,
575
+ children
576
+ });
577
+ $[4] = children;
578
+ $[5] = states;
579
+ $[6] = t5;
580
+ } else t5 = $[6];
581
+ return t5;
582
+ }
583
+ /**
584
+ * Tracks whether the control has focus, around the handlers the field was
585
+ * given, which are called after.
586
+ */
587
+ function useFieldFocus(t0) {
588
+ const $ = c(10);
589
+ const { onBlur, onFocus } = t0;
590
+ const [focused, setFocused] = useState(false);
591
+ let t1;
592
+ if ($[0] !== onBlur) {
593
+ t1 = (event) => {
594
+ setFocused(false);
595
+ onBlur?.(event);
596
+ };
597
+ $[0] = onBlur;
598
+ $[1] = t1;
599
+ } else t1 = $[1];
600
+ const t2 = t1;
601
+ let t3;
602
+ if ($[2] !== onFocus) {
603
+ t3 = (event_0) => {
604
+ setFocused(true);
605
+ onFocus?.(event_0);
606
+ };
607
+ $[2] = onFocus;
608
+ $[3] = t3;
609
+ } else t3 = $[3];
610
+ const t4 = t3;
611
+ let t5;
612
+ if ($[4] !== t2 || $[5] !== t4) {
613
+ t5 = {
614
+ onBlur: t2,
615
+ onFocus: t4
616
+ };
617
+ $[4] = t2;
618
+ $[5] = t4;
619
+ $[6] = t5;
620
+ } else t5 = $[6];
621
+ let t6;
622
+ if ($[7] !== focused || $[8] !== t5) {
623
+ t6 = {
624
+ focused,
625
+ handlers: t5
626
+ };
627
+ $[7] = focused;
628
+ $[8] = t5;
629
+ $[9] = t6;
630
+ } else t6 = $[9];
631
+ return t6;
632
+ }
633
+ const ATOMIC = { "aria-atomic": true };
634
+ const HIDDEN = { "aria-hidden": true };
635
+ const INHERITS_DIRECTION = { dir: null };
636
+ const NOT_DRAWN = { display: "none" };
637
+ const OUT_OF_FLOW = { position: "absolute" };
638
+ const SHRINKS = { flexShrink: 1 };
639
+ /**
640
+ * A prefix or a suffix, faded in once the label has floated and out when it
641
+ * comes back to rest, over the label's own `durationShort3`.
642
+ */
643
+ function Affix(t0) {
644
+ const $ = c(7);
645
+ const { children, floated, id, style } = t0;
646
+ const { motion } = useTheme();
647
+ const reduceMotion = useReducedMotion();
648
+ const opacity = floated ? 1 : 0;
649
+ const timing = {
650
+ duration: motion.durationShort3,
651
+ easing: Easing.bezier(...motion.easingStandard)
652
+ };
653
+ const fade = useAnimatedStyle(() => {
654
+ "worklet";
655
+ return { opacity: reduceMotion ? opacity : withTiming(opacity, timing) };
656
+ });
657
+ let t1;
658
+ if ($[0] !== fade || $[1] !== style) {
659
+ t1 = composeStyles(style, fade);
660
+ $[0] = fade;
661
+ $[1] = style;
662
+ $[2] = t1;
663
+ } else t1 = $[2];
664
+ let t2;
665
+ if ($[3] !== children || $[4] !== id || $[5] !== t1) {
666
+ t2 = /* @__PURE__ */ jsx(Animated.Text, {
667
+ id,
668
+ style: t1,
669
+ children
670
+ });
671
+ $[3] = children;
672
+ $[4] = id;
673
+ $[5] = t1;
674
+ $[6] = t2;
675
+ } else t2 = $[6];
676
+ return t2;
677
+ }
678
+ function affixPart(id, affix) {
679
+ if (affix === void 0) return [];
680
+ return [{
681
+ id,
682
+ text: typeof affix === "string" || typeof affix === "number" ? String(affix) : ""
683
+ }];
684
+ }
685
+ function boxControlOf(floatingLabel, floated, disabled, invalid, required, underLabel) {
686
+ return {
687
+ disabled,
688
+ floated,
689
+ invalid,
690
+ label: floatingLabel ? "floating" : "fixed",
691
+ required,
692
+ underLabel
693
+ };
694
+ }
695
+ /**
696
+ * The box's label: one line, cut short with an ellipsis, moving between its
697
+ * resting place and its floated one. Hidden from screen readers, since the
698
+ * control is named by the same words.
699
+ */
700
+ function BoxLabel(t0) {
701
+ const $ = c(9);
702
+ const { children, floated, floatingLabel, isDisabled, isFocused, isInvalid, isRequired, variant } = t0;
703
+ const theme = useTheme();
704
+ const styles = fieldStylesOf(theme);
705
+ const { fontScale } = useWindowDimensions();
706
+ const reduceMotion = useReducedMotion();
707
+ const large = useTypeRole("bodyLarge");
708
+ const small = useTypeRole(floatingLabel ? "bodySmall" : "labelMedium");
709
+ const { colors, motion, spacing, stateLayerOpacity, typography } = theme;
710
+ const outlined = variant === "outlined";
711
+ const smallRole = floatingLabel ? "bodySmall" : "labelMedium";
712
+ const place = floated ? {
713
+ fontSize: typography[`${smallRole}Size`],
714
+ letterSpacing: typography[`${smallRole}Tracking`],
715
+ lineHeight: typography[`${smallRole}LineHeight`],
716
+ top: outlined ? -(spacing.lg + typography[`${smallRole}LineHeight`] * fontScale / 2) : 0
717
+ } : {
718
+ fontSize: typography.bodyLargeSize,
719
+ letterSpacing: typography.bodyLargeTracking,
720
+ lineHeight: typography.bodyLargeLineHeight,
721
+ top: outlined ? 0 : typography.bodySmallLineHeight * fontScale / 2
722
+ };
723
+ const color = isDisabled ? withOpacity(colors.onSurface, stateLayerOpacity.disabledContent) : isInvalid ? colors.error : isFocused ? colors.primary : colors.onSurfaceVariant;
724
+ const timing = {
725
+ duration: motion.durationShort3,
726
+ easing: Easing.bezier(...motion.easingStandard)
727
+ };
728
+ const motionStyle = useAnimatedStyle(() => {
729
+ "worklet";
730
+ return {
731
+ color: reduceMotion ? color : withTiming(color, timing),
732
+ fontSize: reduceMotion ? place.fontSize : withTiming(place.fontSize, timing),
733
+ letterSpacing: reduceMotion ? place.letterSpacing : withTiming(place.letterSpacing, timing),
734
+ lineHeight: reduceMotion ? place.lineHeight : withTiming(place.lineHeight, timing),
735
+ top: reduceMotion ? place.top : withTiming(place.top, timing)
736
+ };
737
+ });
738
+ const T0 = View;
739
+ const t1 = true;
740
+ const t2 = composeStyles(styles.label, outlined ? styles.labelOutlined : void 0);
741
+ const t3 = Animated;
742
+ const t4 = 1;
743
+ const t5 = composeStyles(floated ? small : large, outlined ? styles.labelTextOutlined : void 0, motionStyle);
744
+ const t6 = isRequired ? REQUIRED_MARK : null;
745
+ let t7;
746
+ if ($[0] !== children || $[1] !== t3.Text || $[2] !== t5 || $[3] !== t6) {
747
+ t7 = /* @__PURE__ */ jsxs(t3.Text, {
748
+ numberOfLines: t4,
749
+ style: t5,
750
+ children: [children, t6]
751
+ });
752
+ $[0] = children;
753
+ $[1] = t3.Text;
754
+ $[2] = t5;
755
+ $[3] = t6;
756
+ $[4] = t7;
757
+ } else t7 = $[4];
758
+ let t8;
759
+ if ($[5] !== T0 || $[6] !== t2 || $[7] !== t7) {
760
+ t8 = /* @__PURE__ */ jsx(T0, {
761
+ "aria-hidden": t1,
762
+ style: t2,
763
+ children: t7
764
+ });
765
+ $[5] = T0;
766
+ $[6] = t2;
767
+ $[7] = t7;
768
+ $[8] = t8;
769
+ } else t8 = $[8];
770
+ return t8;
771
+ }
772
+ function colorOf(color) {
773
+ return { color };
774
+ }
775
+ function countOf(length, maxLength) {
776
+ counterFormat ??= new Intl.NumberFormat();
777
+ return maxLength === void 0 ? counterFormat.format(length) : `${counterFormat.format(length)}/${counterFormat.format(maxLength)}`;
778
+ }
779
+ function descriptionOf(parts) {
780
+ if (Platform.OS === "web") return parts.length === 0 ? void 0 : { "aria-describedby": parts.map((part) => part.id).join(" ") };
781
+ const said = parts.map((part) => part.text).filter((text) => text !== "");
782
+ return said.length === 0 ? void 0 : { accessibilityHint: said.join(" ") };
783
+ }
784
+ function focusOf(control) {
785
+ return () => {
786
+ control.current?.focus();
787
+ };
788
+ }
789
+ function iconStyleOf(color) {
790
+ return {
791
+ color,
792
+ size: ICON_SIZE
793
+ };
794
+ }
795
+ function idsOf(id) {
796
+ return {
797
+ description: `${id}-description`,
798
+ error: `${id}-error`,
799
+ limit: `${id}-limit`
800
+ };
801
+ }
802
+ /**
803
+ * The limit in words where there is one: the field's own, or English, which
804
+ * an app in another language replaces through `characterLimitLabel`.
805
+ */
806
+ function limitOf(maxLength, label) {
807
+ if (maxLength === void 0) return;
808
+ return label ?? (maxLength === 1 ? "Up to 1 character" : `Up to ${String(maxLength)} characters`);
809
+ }
810
+ function marginTopOf(marginTop) {
811
+ return { marginTop };
812
+ }
813
+ function minHeightOf(minHeight) {
814
+ return { minHeight };
815
+ }
816
+ function minWidthOf(minWidth) {
817
+ return { minWidth };
818
+ }
819
+ /**
820
+ * The label's text in its floated type, out of sight, measured for the
821
+ * outlined box's notch.
822
+ */
823
+ function NotchMeasure(t0) {
824
+ const $ = c(12);
825
+ const { children, floatingLabel, isRequired, onMeasure } = t0;
826
+ const styles = fieldStylesOf(useTheme());
827
+ const small = useTypeRole(floatingLabel ? "bodySmall" : "labelMedium");
828
+ const T0 = View;
829
+ const t1 = true;
830
+ const t2 = composeStyles(styles.label, styles.labelOutlined, styles.notchMeasure);
831
+ const T1 = Text;
832
+ const t3 = 1;
833
+ let t4;
834
+ if ($[0] !== onMeasure) {
835
+ t4 = widthTo(onMeasure);
836
+ $[0] = onMeasure;
837
+ $[1] = t4;
838
+ } else t4 = $[1];
839
+ const t5 = composeStyles(small, styles.labelTextOutlined);
840
+ const t6 = isRequired ? REQUIRED_MARK : null;
841
+ let t7;
842
+ if ($[2] !== T1 || $[3] !== children || $[4] !== t4 || $[5] !== t5 || $[6] !== t6) {
843
+ t7 = /* @__PURE__ */ jsxs(T1, {
844
+ numberOfLines: t3,
845
+ onLayout: t4,
846
+ style: t5,
847
+ children: [children, t6]
848
+ });
849
+ $[2] = T1;
850
+ $[3] = children;
851
+ $[4] = t4;
852
+ $[5] = t5;
853
+ $[6] = t6;
854
+ $[7] = t7;
855
+ } else t7 = $[7];
856
+ let t8;
857
+ if ($[8] !== T0 || $[9] !== t2 || $[10] !== t7) {
858
+ t8 = /* @__PURE__ */ jsx(T0, {
859
+ "aria-hidden": t1,
860
+ style: t2,
861
+ children: t7
862
+ });
863
+ $[8] = T0;
864
+ $[9] = t2;
865
+ $[10] = t7;
866
+ $[11] = t8;
867
+ } else t8 = $[11];
868
+ return t8;
869
+ }
870
+ function numericOf(fontFamily) {
871
+ return {
872
+ fontFamily,
873
+ fontVariant: ["tabular-nums"]
874
+ };
875
+ }
876
+ function outlineInset(spacing, icon) {
877
+ return (icon === void 0 ? spacing.lg : spacing.md + ICON_SIZE + spacing.lg) - spacing.xs;
878
+ }
879
+ const REQUIRED_MARK = "*";
880
+ /**
881
+ * One view drawing a field's rule in its eased colour and width, from
882
+ * {@link useStrokeMotion}: on every side, for the outlined box's outline,
883
+ * which the piece around it clips, and a bar's ring, or on the top alone,
884
+ * for the filled box's indicator.
885
+ */
886
+ function FieldStroke(t0) {
887
+ const $ = c(5);
888
+ const { color, sides, style, width } = t0;
889
+ const stroke = useAnimatedStyle(() => {
890
+ "worklet";
891
+ return sides === "all" ? {
892
+ borderColor: color.get(),
893
+ borderWidth: width.get()
894
+ } : {
895
+ borderColor: color.get(),
896
+ borderTopWidth: width.get()
897
+ };
898
+ });
899
+ let t1;
900
+ if ($[0] !== stroke || $[1] !== style) {
901
+ t1 = composeStyles(style, stroke);
902
+ $[0] = stroke;
903
+ $[1] = style;
904
+ $[2] = t1;
905
+ } else t1 = $[2];
906
+ let t2;
907
+ if ($[3] !== t1) {
908
+ t2 = /* @__PURE__ */ jsx(Animated.View, {
909
+ "aria-hidden": true,
910
+ style: t1
911
+ });
912
+ $[3] = t1;
913
+ $[4] = t2;
914
+ } else t2 = $[4];
915
+ return t2;
916
+ }
917
+ function useErrorAnnouncement(error) {
918
+ const $ = c(3);
919
+ const said = useRef(error);
920
+ let t0;
921
+ let t1;
922
+ if ($[0] !== error) {
923
+ t0 = () => {
924
+ if (Platform.OS === "ios" && error !== void 0 && error !== "" && error !== said.current) AccessibilityInfo.announceForAccessibility(error);
925
+ said.current = error;
926
+ };
927
+ t1 = [error];
928
+ $[0] = error;
929
+ $[1] = t0;
930
+ $[2] = t1;
931
+ } else {
932
+ t0 = $[1];
933
+ t1 = $[2];
934
+ }
935
+ useEffect(t0, t1);
936
+ }
937
+ /**
938
+ * The rule the box draws, the filled box's indicator or the outlined box's
939
+ * outline: its colour and its width by state.
940
+ */
941
+ function useRuleMotion(theme, state) {
942
+ const $ = c(11);
943
+ const { colors, stateLayerOpacity } = theme;
944
+ const width = !state.disabled && state.focused ? 2 : 1;
945
+ let t0;
946
+ if ($[0] !== colors.error || $[1] !== colors.onErrorContainer || $[2] !== colors.onSurface || $[3] !== colors.outline || $[4] !== colors.primary || $[5] !== state.disabled || $[6] !== state.focused || $[7] !== state.hovered || $[8] !== state.invalid || $[9] !== stateLayerOpacity) {
947
+ t0 = state.disabled ? withOpacity(colors.onSurface, stateLayerOpacity.disabledContainer) : state.focused ? state.invalid ? colors.error : colors.primary : state.hovered ? state.invalid ? colors.onErrorContainer : colors.onSurface : state.invalid ? colors.error : colors.outline;
948
+ $[0] = colors.error;
949
+ $[1] = colors.onErrorContainer;
950
+ $[2] = colors.onSurface;
951
+ $[3] = colors.outline;
952
+ $[4] = colors.primary;
953
+ $[5] = state.disabled;
954
+ $[6] = state.focused;
955
+ $[7] = state.hovered;
956
+ $[8] = state.invalid;
957
+ $[9] = stateLayerOpacity;
958
+ $[10] = t0;
959
+ } else t0 = $[10];
960
+ return useStrokeMotion(t0, width);
961
+ }
962
+ /**
963
+ * A rule's colour and width, eased to each new pair over `durationShort2` as
964
+ * web transitions them, and moved at once under reduced motion. Hand the
965
+ * result to {@link FieldStroke}.
966
+ */
967
+ function useStrokeMotion(color, width) {
968
+ const $ = c(3);
969
+ const { motion } = useTheme();
970
+ const reduceMotion = useReducedMotion();
971
+ const timing = {
972
+ duration: motion.durationShort2,
973
+ easing: Easing.bezier(...motion.easingStandard)
974
+ };
975
+ const t0 = useDerivedValue(() => reduceMotion ? color : withTiming(color, timing));
976
+ const t1 = useDerivedValue(() => reduceMotion ? width : withTiming(width, timing));
977
+ let t2;
978
+ if ($[0] !== t0 || $[1] !== t1) {
979
+ t2 = {
980
+ color: t0,
981
+ width: t1
982
+ };
983
+ $[0] = t0;
984
+ $[1] = t1;
985
+ $[2] = t2;
986
+ } else t2 = $[2];
987
+ return t2;
988
+ }
989
+ function webStateOf(box) {
990
+ if (Platform.OS !== "web") return;
991
+ return {
992
+ ...box.invalid ? { "aria-invalid": true } : void 0,
993
+ ...box.required ? { "aria-required": true } : void 0
994
+ };
995
+ }
996
+ function widthOf(width) {
997
+ return { width };
998
+ }
999
+ function widthTo(onMeasure) {
1000
+ return (event) => {
1001
+ onMeasure(event.nativeEvent.layout.width);
1002
+ };
1003
+ }
1004
+ //#endregion
1005
+ export { FieldBox, FieldInput, FieldMessage, FieldStates, FieldStroke, describedBy, useFieldFocus, useStrokeMotion };
1006
+
1007
+ //# sourceMappingURL=index.js.map