@xaui/native 0.9.1-alpha.3 → 0.9.1-alpha.30

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 (143) hide show
  1. package/dist/chunk-27ZRTZEE.js +293 -0
  2. package/dist/chunk-3FV4COTM.js +68 -0
  3. package/dist/chunk-423RQBOX.js +21 -0
  4. package/dist/chunk-4GTAZM2C.js +174 -0
  5. package/dist/chunk-4XPLPQLM.cjs +147 -0
  6. package/dist/{chunk-3QBT3Q65.cjs → chunk-57SJ4LJF.cjs} +7 -2
  7. package/dist/chunk-5GO7MAVY.cjs +74 -0
  8. package/dist/chunk-5RQ7AZPN.cjs +455 -0
  9. package/dist/chunk-5Z4P6WHR.cjs +525 -0
  10. package/dist/chunk-6RVCGLKZ.js +661 -0
  11. package/dist/chunk-7DPL3ZDS.cjs +21 -0
  12. package/dist/chunk-7EIHHOHP.cjs +42 -0
  13. package/dist/chunk-7SEZGVTY.js +62 -0
  14. package/dist/chunk-7XKQJQF2.cjs +70 -0
  15. package/dist/{chunk-X2K2FX3W.js → chunk-A3EGFI6T.js} +6 -1
  16. package/dist/chunk-A5OCK3C2.js +525 -0
  17. package/dist/chunk-BA2DBSAN.js +102 -0
  18. package/dist/chunk-BFMTUMTU.js +669 -0
  19. package/dist/chunk-BVJQ3UPZ.js +62 -0
  20. package/dist/chunk-DFME724B.js +147 -0
  21. package/dist/chunk-E2CWBQTV.js +119 -0
  22. package/dist/chunk-E4TS6632.cjs +314 -0
  23. package/dist/chunk-EGLLDKN6.js +9 -0
  24. package/dist/chunk-EJQCQPET.cjs +9 -0
  25. package/dist/chunk-F6CQ6CBI.cjs +112 -0
  26. package/dist/chunk-F6W3JQ7K.js +42 -0
  27. package/dist/chunk-FMZQW35T.js +431 -0
  28. package/dist/chunk-FNEUOBCV.cjs +174 -0
  29. package/dist/chunk-G7K652GC.js +145 -0
  30. package/dist/chunk-GGW42MY4.js +20 -0
  31. package/dist/chunk-GI24YJPE.js +314 -0
  32. package/dist/chunk-GLGU2WFL.cjs +190 -0
  33. package/dist/chunk-GPVNCJ3Z.cjs +696 -0
  34. package/dist/chunk-GVQOD3VW.js +74 -0
  35. package/dist/chunk-KOC3KQIT.js +124 -0
  36. package/dist/chunk-KPWZLUES.cjs +124 -0
  37. package/dist/chunk-KWCHSIMI.cjs +293 -0
  38. package/dist/chunk-MC7SY2QH.cjs +20 -0
  39. package/dist/chunk-N527BTY4.cjs +366 -0
  40. package/dist/chunk-NBFWWQFW.cjs +346 -0
  41. package/dist/chunk-NYRXUGVL.js +104 -0
  42. package/dist/{chunk-AW63PTQ4.cjs → chunk-OHEHPQLC.cjs} +72 -72
  43. package/dist/chunk-Q3WFY5N3.js +366 -0
  44. package/dist/chunk-QGN2BBJO.cjs +104 -0
  45. package/dist/chunk-TGZZ3RZU.cjs +86 -0
  46. package/dist/{chunk-2KXQATVL.js → chunk-TZG3DERP.js} +46 -46
  47. package/dist/chunk-UBQLKIZC.cjs +431 -0
  48. package/dist/chunk-URSKA2VR.js +190 -0
  49. package/dist/chunk-V4WDMM6Z.js +86 -0
  50. package/dist/chunk-VJEER76X.js +455 -0
  51. package/dist/chunk-VZBWYWEI.cjs +736 -0
  52. package/dist/chunk-WR7YLDVV.cjs +68 -0
  53. package/dist/chunk-X4HQ4H2V.js +701 -0
  54. package/dist/chunk-XFSW3ZNI.cjs +145 -0
  55. package/dist/chunk-XQFAUDR2.cjs +62 -0
  56. package/dist/chunk-YKL6XHM6.js +346 -0
  57. package/dist/chunk-ZP2E2H2G.cjs +119 -0
  58. package/dist/chunk-ZSLNGBDS.cjs +700 -0
  59. package/dist/close-button.type-BUYuoSt2.d.ts +36 -0
  60. package/dist/close-button.type-CHsgZ3wO.d.cts +36 -0
  61. package/dist/components/alert/index.cjs +20 -0
  62. package/dist/components/alert/index.d.cts +169 -0
  63. package/dist/components/alert/index.d.ts +169 -0
  64. package/dist/components/alert/index.js +20 -0
  65. package/dist/components/button/index.cjs +21 -0
  66. package/dist/components/button/index.d.cts +613 -0
  67. package/dist/components/button/index.d.ts +613 -0
  68. package/dist/components/button/index.js +21 -0
  69. package/dist/components/card/index.cjs +22 -0
  70. package/dist/components/card/index.d.cts +620 -0
  71. package/dist/components/card/index.d.ts +620 -0
  72. package/dist/components/card/index.js +22 -0
  73. package/dist/components/checkbox/index.cjs +26 -0
  74. package/dist/components/checkbox/index.d.cts +1136 -0
  75. package/dist/components/checkbox/index.d.ts +1136 -0
  76. package/dist/components/checkbox/index.js +26 -0
  77. package/dist/components/chip/index.cjs +20 -0
  78. package/dist/components/chip/index.d.cts +608 -0
  79. package/dist/components/chip/index.d.ts +608 -0
  80. package/dist/components/chip/index.js +20 -0
  81. package/dist/components/input/index.cjs +25 -0
  82. package/dist/components/input/index.d.cts +205 -0
  83. package/dist/components/input/index.d.ts +205 -0
  84. package/dist/components/input/index.js +25 -0
  85. package/dist/components/input-group/index.cjs +27 -0
  86. package/dist/components/input-group/index.d.cts +270 -0
  87. package/dist/components/input-group/index.d.ts +270 -0
  88. package/dist/components/input-group/index.js +27 -0
  89. package/dist/components/input-otp/index.cjs +29 -0
  90. package/dist/components/input-otp/index.d.cts +325 -0
  91. package/dist/components/input-otp/index.d.ts +325 -0
  92. package/dist/components/input-otp/index.js +29 -0
  93. package/dist/components/radio/index.cjs +26 -0
  94. package/dist/components/radio/index.d.cts +1102 -0
  95. package/dist/components/radio/index.d.ts +1102 -0
  96. package/dist/components/radio/index.js +26 -0
  97. package/dist/components/spinner/index.cjs +16 -0
  98. package/dist/components/spinner/index.d.cts +104 -0
  99. package/dist/components/spinner/index.d.ts +104 -0
  100. package/dist/components/spinner/index.js +16 -0
  101. package/dist/components/switch/index.cjs +27 -0
  102. package/dist/components/switch/index.d.cts +1154 -0
  103. package/dist/components/switch/index.d.ts +1154 -0
  104. package/dist/components/switch/index.js +27 -0
  105. package/dist/components/text-area/index.cjs +14 -0
  106. package/dist/components/text-area/index.d.cts +73 -0
  107. package/dist/components/text-area/index.d.ts +73 -0
  108. package/dist/components/text-area/index.js +14 -0
  109. package/dist/components/typography/index.cjs +15 -0
  110. package/dist/components/typography/index.d.cts +116 -0
  111. package/dist/components/typography/index.d.ts +116 -0
  112. package/dist/components/typography/index.js +15 -0
  113. package/dist/components/view/index.cjs +17 -0
  114. package/dist/components/view/index.d.cts +152 -0
  115. package/dist/components/view/index.d.ts +152 -0
  116. package/dist/components/view/index.js +17 -0
  117. package/dist/create-recipe-BdVd2ffi.d.ts +114 -0
  118. package/dist/create-recipe-dC7wMfnj.d.cts +114 -0
  119. package/dist/icon.type-Kml72iSz.d.ts +73 -0
  120. package/dist/icon.type-d_i9ma-i.d.cts +73 -0
  121. package/dist/index.cjs +246 -4
  122. package/dist/index.d.cts +109 -4
  123. package/dist/index.d.ts +109 -4
  124. package/dist/index.js +266 -24
  125. package/dist/input.type-BUMDlzL9.d.cts +167 -0
  126. package/dist/input.type-D2qgi03E.d.ts +167 -0
  127. package/dist/pressable-feedback.type-BA2C9sSz.d.cts +127 -0
  128. package/dist/pressable-feedback.type-Bs4dQlGj.d.ts +127 -0
  129. package/dist/style-props.type-CfnoGEP7.d.cts +31 -0
  130. package/dist/style-props.type-CfnoGEP7.d.ts +31 -0
  131. package/dist/system/index.cjs +60 -3
  132. package/dist/system/index.d.cts +347 -181
  133. package/dist/system/index.d.ts +347 -181
  134. package/dist/system/index.js +71 -14
  135. package/dist/theme/index.cjs +4 -3
  136. package/dist/theme/index.d.cts +34 -23
  137. package/dist/theme/index.d.ts +34 -23
  138. package/dist/theme/index.js +3 -2
  139. package/dist/{theme.type-C9bFJKFm.d.cts → theme.type-C2gNHpEx.d.cts} +1 -1
  140. package/dist/{theme.type-C9bFJKFm.d.ts → theme.type-C2gNHpEx.d.ts} +1 -1
  141. package/package.json +174 -18
  142. package/dist/chunk-QAMNNTGM.js +0 -637
  143. package/dist/chunk-V63JO65F.cjs +0 -637
@@ -0,0 +1,525 @@
1
+ import {
2
+ createRecipe,
3
+ radiusAxis
4
+ } from "./chunk-4GTAZM2C.js";
5
+ import {
6
+ useXAUITheme
7
+ } from "./chunk-A3EGFI6T.js";
8
+ import {
9
+ Slot,
10
+ createSlotContext
11
+ } from "./chunk-E2CWBQTV.js";
12
+ import {
13
+ useStyleProps
14
+ } from "./chunk-URSKA2VR.js";
15
+
16
+ // src/components/input/input-description.tsx
17
+ import { forwardRef } from "react";
18
+ import { Text } from "react-native";
19
+
20
+ // src/components/input/input.context.ts
21
+ var [InputProvider, useInput] = createSlotContext("Input");
22
+
23
+ // src/components/input/input-description.tsx
24
+ import { jsx } from "react/jsx-runtime";
25
+ var InputDescription = forwardRef(
26
+ function InputDescription2({ children, style, nativeID, ...props }, ref) {
27
+ const { descriptionStyle, descriptionId } = useInput();
28
+ const [styleProps, rest] = useStyleProps(props);
29
+ return /* @__PURE__ */ jsx(
30
+ Text,
31
+ {
32
+ ref,
33
+ nativeID: nativeID ?? descriptionId,
34
+ style: [descriptionStyle, styleProps, style],
35
+ ...rest,
36
+ children
37
+ }
38
+ );
39
+ }
40
+ );
41
+ InputDescription.displayName = "XAUI.Input.Description";
42
+
43
+ // src/components/input/input-error.tsx
44
+ import { forwardRef as forwardRef2 } from "react";
45
+ import { Text as Text2 } from "react-native";
46
+ import { jsx as jsx2 } from "react/jsx-runtime";
47
+ var InputError = forwardRef2(function InputError2({ children, style, ...props }, ref) {
48
+ const { errorStyle } = useInput();
49
+ const [styleProps, rest] = useStyleProps(props);
50
+ return /* @__PURE__ */ jsx2(Text2, { ref, style: [errorStyle, styleProps, style], ...rest, children });
51
+ });
52
+ InputError.displayName = "XAUI.Input.Error";
53
+
54
+ // src/components/input/input-field.tsx
55
+ import { forwardRef as forwardRef3, useCallback } from "react";
56
+ import { TextInput } from "react-native";
57
+ import { jsx as jsx3 } from "react/jsx-runtime";
58
+ var InputField = forwardRef3(function InputField2({ style, onFocus, onBlur, placeholderTextColor, ...props }, ref) {
59
+ const {
60
+ fieldStyle,
61
+ placeholderTextColor: resolvedPlaceholder,
62
+ onFieldFocus,
63
+ onFieldBlur,
64
+ labelId,
65
+ descriptionId,
66
+ isDisabled,
67
+ isInvalid
68
+ } = useInput();
69
+ const [styleProps, rest] = useStyleProps(props);
70
+ const handleFocus = useCallback(
71
+ (event) => {
72
+ onFieldFocus(event);
73
+ onFocus?.(event);
74
+ },
75
+ [onFieldFocus, onFocus]
76
+ );
77
+ const handleBlur = useCallback(
78
+ (event) => {
79
+ onFieldBlur(event);
80
+ onBlur?.(event);
81
+ },
82
+ [onFieldBlur, onBlur]
83
+ );
84
+ return /* @__PURE__ */ jsx3(
85
+ TextInput,
86
+ {
87
+ ref,
88
+ "aria-labelledby": labelId,
89
+ "aria-describedby": descriptionId,
90
+ "aria-invalid": isInvalid,
91
+ editable: !isDisabled,
92
+ accessibilityState: { disabled: isDisabled },
93
+ placeholderTextColor: placeholderTextColor ?? resolvedPlaceholder,
94
+ ...rest,
95
+ style: [fieldStyle, styleProps, style],
96
+ onFocus: handleFocus,
97
+ onBlur: handleBlur
98
+ }
99
+ );
100
+ });
101
+ InputField.displayName = "XAUI.Input.Field";
102
+
103
+ // src/components/input/input-label.tsx
104
+ import { forwardRef as forwardRef4 } from "react";
105
+ import { Text as Text3 } from "react-native";
106
+ import { jsx as jsx4 } from "react/jsx-runtime";
107
+ var InputLabel = forwardRef4(function InputLabel2({ children, style, nativeID, ...props }, ref) {
108
+ const { labelStyle, labelId } = useInput();
109
+ const [styleProps, rest] = useStyleProps(props);
110
+ return /* @__PURE__ */ jsx4(
111
+ Text3,
112
+ {
113
+ ref,
114
+ nativeID: nativeID ?? labelId,
115
+ style: [labelStyle, styleProps, style],
116
+ ...rest,
117
+ children
118
+ }
119
+ );
120
+ });
121
+ InputLabel.displayName = "XAUI.Input.Label";
122
+
123
+ // src/components/input/input.tsx
124
+ import { forwardRef as forwardRef5, useCallback as useCallback2, useId, useMemo, useState } from "react";
125
+ import { StyleSheet, View } from "react-native";
126
+
127
+ // src/components/input/input.recipe.ts
128
+ var SLOTS = [
129
+ "root",
130
+ "label",
131
+ "field",
132
+ "textArea",
133
+ "placeholder",
134
+ "description",
135
+ "error",
136
+ "prefix",
137
+ "suffix",
138
+ "icon"
139
+ ];
140
+ var VARIANT_TOKENS = {
141
+ primary: {
142
+ bg: "fieldBackground",
143
+ border: "fieldBorder",
144
+ borderFocus: "fieldBorderFocus",
145
+ fg: "fieldForeground"
146
+ },
147
+ // `bg: 'default'` is the neutral *token*, not this variant's name — the two namespaces
148
+ // meet here and nowhere else. It is also what keeps a field visible on a card, where
149
+ // `fieldBackground` is the card's own colour.
150
+ secondary: {
151
+ bg: "default",
152
+ border: "fieldBorder",
153
+ borderFocus: "fieldBorderFocus",
154
+ fg: "fieldForeground"
155
+ },
156
+ tertiary: {
157
+ border: "fieldBorder",
158
+ borderFocus: "fieldBorderFocus",
159
+ fg: "fieldForeground"
160
+ },
161
+ ghost: { borderFocus: "fieldBorderFocus", fg: "fieldForeground" }
162
+ };
163
+ function sizeAxis(step) {
164
+ const { control, padding, gap, field, label, help, glyph, textAreaPadding } = step;
165
+ return (theme) => {
166
+ const inset = { paddingHorizontal: theme.spacing(LABEL_INSET) };
167
+ const helpType = {
168
+ fontSize: theme.fontSizes[help],
169
+ lineHeight: theme.lineHeights[help]
170
+ };
171
+ const decorator = {
172
+ paddingHorizontal: theme.spacing(padding),
173
+ gap: theme.spacing(padding)
174
+ };
175
+ return {
176
+ root: { gap: theme.spacing(gap) },
177
+ label: {
178
+ ...inset,
179
+ fontSize: theme.fontSizes[label],
180
+ lineHeight: theme.lineHeights[label]
181
+ },
182
+ field: {
183
+ minHeight: theme.controlHeights[control],
184
+ paddingHorizontal: theme.spacing(padding),
185
+ fontSize: theme.fontSizes[field]
186
+ },
187
+ // Only what a multiline field *adds* — `Input.TextArea` layers this over the field's
188
+ // own style rather than restating it, so the colours, the border and the radius are
189
+ // resolved once for both. The height is not here: `rows` is a raw value, and the
190
+ // slot computes it from the two numbers below.
191
+ textArea: {
192
+ lineHeight: theme.lineHeights[field],
193
+ paddingTop: theme.spacing(textAreaPadding),
194
+ paddingBottom: theme.spacing(textAreaPadding)
195
+ },
196
+ description: { ...inset, ...helpType },
197
+ error: { ...inset, ...helpType },
198
+ prefix: decorator,
199
+ suffix: decorator,
200
+ icon: { fontSize: theme.fontSizes[glyph] }
201
+ };
202
+ };
203
+ }
204
+ var LABEL_INSET = 1.5;
205
+ var DECORATOR = {
206
+ position: "absolute",
207
+ top: 0,
208
+ bottom: 0,
209
+ flexDirection: "row",
210
+ alignItems: "center",
211
+ justifyContent: "center",
212
+ zIndex: 10
213
+ };
214
+ var SIZES = {
215
+ xs: {
216
+ control: "xs",
217
+ padding: 2.5,
218
+ gap: 0.75,
219
+ field: "sm",
220
+ label: "sm",
221
+ help: "xs",
222
+ glyph: "md",
223
+ labelInside: "xs",
224
+ textAreaPadding: 1.5
225
+ },
226
+ sm: {
227
+ control: "sm",
228
+ padding: 3,
229
+ gap: 0.75,
230
+ field: "md",
231
+ label: "sm",
232
+ help: "xs",
233
+ glyph: "lg",
234
+ labelInside: "xs",
235
+ textAreaPadding: 2
236
+ },
237
+ md: {
238
+ control: "md",
239
+ padding: 3,
240
+ gap: 1.25,
241
+ field: "md",
242
+ label: "md",
243
+ help: "sm",
244
+ glyph: "lg",
245
+ labelInside: "xs",
246
+ textAreaPadding: 2
247
+ },
248
+ lg: {
249
+ control: "lg",
250
+ padding: 4,
251
+ gap: 1.75,
252
+ field: "lg",
253
+ label: "lg",
254
+ help: "md",
255
+ glyph: "xl",
256
+ labelInside: "sm",
257
+ textAreaPadding: 2.5
258
+ }
259
+ };
260
+ function insideLabel(step) {
261
+ const { control, padding, field, labelInside } = step;
262
+ return (theme) => {
263
+ const top = theme.spacing(LABEL_INSIDE_TOP);
264
+ const block = top + theme.lineHeights[labelInside];
265
+ return {
266
+ label: {
267
+ position: "absolute",
268
+ top,
269
+ // `start`, never `left` (R13): RTL mirrors the logical property and only it.
270
+ start: theme.spacing(padding),
271
+ paddingHorizontal: 0,
272
+ fontSize: theme.fontSizes[labelInside],
273
+ lineHeight: theme.lineHeights[labelInside]
274
+ },
275
+ // The height is built from the two lines it now holds rather than added to the
276
+ // control height: `controlHeights` already pays for centring one line, so adding
277
+ // the label's block to it would pay for that room twice. It is floored at the
278
+ // control height all the same, so a theme that raises `controlHeights` does not end
279
+ // up with an inside field shorter than the outside one beside it.
280
+ field: {
281
+ minHeight: Math.max(
282
+ block + theme.lineHeights[field] + top,
283
+ theme.controlHeights[control]
284
+ ),
285
+ paddingTop: block,
286
+ paddingBottom: top
287
+ },
288
+ // The same room, because `Input.TextArea` layers its own padding over the field's
289
+ // and would otherwise put the first line back under the label.
290
+ textArea: { paddingTop: block, paddingBottom: top }
291
+ };
292
+ };
293
+ }
294
+ var LABEL_INSIDE_TOP = 1.5;
295
+ var inputRecipe = createRecipe({
296
+ slots: SLOTS,
297
+ base: (theme) => ({
298
+ root: { flexDirection: "column" },
299
+ label: {
300
+ fontFamily: theme.fontFamilies.body,
301
+ fontWeight: theme.fontWeights.medium
302
+ },
303
+ field: {
304
+ fontFamily: theme.fontFamilies.body,
305
+ // `regular`, not `medium`: what the user typed is content, not a control's label,
306
+ // and a heavier weight makes a filled field read as a button.
307
+ fontWeight: theme.fontWeights.regular,
308
+ borderWidth: theme.borderWidth.field,
309
+ // The theme has a radius named for this component, so every size uses it and the
310
+ // `radius` axis is what overrides it — the same shape a `Chip` takes from `full`.
311
+ // It is HeroUI's twelve points since the scale was aligned on theirs; it was 21,
312
+ // which put a 48-tall field at 87% of its geometric maximum.
313
+ borderRadius: theme.radius.field,
314
+ borderCurve: "continuous",
315
+ // RN centres a single line inside `minHeight` on iOS and pins it to the top on
316
+ // Android. Saying it removes a difference nobody chose.
317
+ textAlignVertical: "center"
318
+ },
319
+ // Several lines start at the top; only a single line is centred in its box.
320
+ textArea: { textAlignVertical: "top" },
321
+ // Not a node — the root flattens this one into `placeholderTextColor`, which is a
322
+ // `TextInput` prop rather than a style.
323
+ placeholder: { color: theme.colors.fieldPlaceholder },
324
+ description: {
325
+ fontFamily: theme.fontFamilies.body,
326
+ color: theme.colors.muted
327
+ },
328
+ error: {
329
+ fontFamily: theme.fontFamilies.body,
330
+ color: theme.colors.danger
331
+ },
332
+ prefix: { ...DECORATOR, start: 0 },
333
+ suffix: { ...DECORATOR, end: 0 },
334
+ // The glyph sits with the placeholder rather than with the value: a search mark or a
335
+ // lock is decoration for the text, not text. `paint` leaves it alone, so a tinted
336
+ // filled field is the one case where the caller names a colour on the icon itself.
337
+ icon: { color: theme.colors.fieldPlaceholder }
338
+ }),
339
+ variantTokens: VARIANT_TOKENS,
340
+ /**
341
+ * Where the variant's colours land. The border width follows the *presence* of the
342
+ * border role, so `ghost` needs no rule of its own to say it has no edge.
343
+ *
344
+ * The label is **not** painted from the variant: it sits outside the box, on the screen
345
+ * behind it, so it takes `foreground` and not the field's own text colour. That is also
346
+ * why a tinted input does not tint its label — the tint is the field's, not the form's.
347
+ */
348
+ paint: (theme, colors) => ({
349
+ field: {
350
+ backgroundColor: colors.bg,
351
+ borderColor: colors.border,
352
+ borderWidth: colors.border ? theme.borderWidth.field : 0,
353
+ color: colors.fg
354
+ },
355
+ label: { color: theme.colors.foreground }
356
+ }),
357
+ /**
358
+ * Declaration order is application order, and it is load-bearing here: `isInvalid`
359
+ * comes after `size` so its border wins, and it must also outrank focus — which is why
360
+ * the root passes `focused` only when the field is *not* invalid, rather than relying
361
+ * on an order that states cannot express.
362
+ */
363
+ variants: {
364
+ size: {
365
+ xs: sizeAxis(SIZES.xs),
366
+ sm: sizeAxis(SIZES.sm),
367
+ md: sizeAxis(SIZES.md),
368
+ lg: sizeAxis(SIZES.lg)
369
+ },
370
+ radius: radiusAxis("field"),
371
+ /**
372
+ * `outside` is the base behaviour, so it adds nothing — it is declared because an
373
+ * axis needs both of its values for the selection to be typed, and because a reader
374
+ * looking for "what does outside do" should find the answer here rather than infer it
375
+ * from an absence. The size-dependent half of `inside` is in `compoundVariants`.
376
+ */
377
+ labelPlacement: {
378
+ outside: () => ({}),
379
+ inside: () => ({})
380
+ },
381
+ isInvalid: {
382
+ true: (theme) => ({
383
+ field: { borderColor: theme.colors.danger },
384
+ // The label and the description turn with it: on a long form the field that is
385
+ // wrong has to be findable without reading every message.
386
+ label: { color: theme.colors.danger },
387
+ description: { color: theme.colors.danger }
388
+ })
389
+ }
390
+ },
391
+ /**
392
+ * The focus treatment is the border darkening towards the mode's ink — the theme's
393
+ * `fieldBorderFocus`, which is `fieldBorder` mixed 26% towards `fieldForeground`. No
394
+ * ring and no accent: a form where every focused field flashes the brand colour is a
395
+ * form where the accent has stopped meaning "the action".
396
+ *
397
+ * `borderFocus` is a role rather than a token named here, so a raw `color` follows the
398
+ * field into focus the same way it follows a `Button` into its pressed state.
399
+ */
400
+ /**
401
+ * What `primary` adds to a filled field, and the four halves of the inside label that
402
+ * need to know the size — a compound is how the engine expresses a rule that depends on
403
+ * two axes at once.
404
+ */
405
+ compoundVariants: [
406
+ {
407
+ when: { variant: "primary" },
408
+ style: (theme) => ({ field: theme.shadows.field })
409
+ },
410
+ { when: { size: "xs", labelPlacement: "inside" }, style: insideLabel(SIZES.xs) },
411
+ { when: { size: "sm", labelPlacement: "inside" }, style: insideLabel(SIZES.sm) },
412
+ { when: { size: "md", labelPlacement: "inside" }, style: insideLabel(SIZES.md) },
413
+ { when: { size: "lg", labelPlacement: "inside" }, style: insideLabel(SIZES.lg) }
414
+ ],
415
+ states: {
416
+ focused: (_theme, colors) => ({ field: { borderColor: colors.borderFocus } }),
417
+ disabled: (theme) => ({ root: { opacity: theme.opacity.disabled } })
418
+ },
419
+ defaultVariants: { variant: "secondary", size: "md", labelPlacement: "outside" }
420
+ });
421
+
422
+ // src/components/input/input.tsx
423
+ import { jsx as jsx5 } from "react/jsx-runtime";
424
+ var InputRoot = forwardRef5(function Input({
425
+ children,
426
+ variant,
427
+ size,
428
+ radius,
429
+ labelPlacement,
430
+ color,
431
+ isInvalid = false,
432
+ isDisabled = false,
433
+ asChild = false,
434
+ style,
435
+ ...props
436
+ }, ref) {
437
+ const theme = useXAUITheme();
438
+ const [styleProps, rest] = useStyleProps(props);
439
+ const [isFocused, setIsFocused] = useState(false);
440
+ const onFieldFocus = useCallback2(() => setIsFocused(true), []);
441
+ const onFieldBlur = useCallback2(() => setIsFocused(false), []);
442
+ const id = useId();
443
+ const labelId = `${id}-label`;
444
+ const descriptionId = `${id}-description`;
445
+ const selection = {
446
+ variant,
447
+ size,
448
+ radius,
449
+ labelPlacement,
450
+ isInvalid: isInvalid ? "true" : void 0
451
+ };
452
+ const states = { focused: isFocused && !isInvalid, disabled: isDisabled };
453
+ const styles = inputRecipe.resolve({ theme, selection, states });
454
+ const tint = color ? inputRecipe.tint({ theme, color, selection, states }) : void 0;
455
+ const context = useMemo(() => {
456
+ const placeholder = StyleSheet.flatten(styles.placeholder);
457
+ const icon = StyleSheet.flatten(styles.icon);
458
+ const textArea = StyleSheet.flatten(styles.textArea);
459
+ return {
460
+ labelStyle: tint ? [styles.label, tint.label] : styles.label,
461
+ fieldStyle: tint ? [styles.field, tint.field] : styles.field,
462
+ textAreaStyle: styles.textArea,
463
+ textArea: {
464
+ lineHeight: textArea.lineHeight ?? 0,
465
+ // `DimensionValue` also covers a percentage and `auto`, neither of which can be
466
+ // multiplied by a number of rows. The recipe only ever writes points here.
467
+ paddingVertical: typeof textArea.paddingBottom === "number" ? textArea.paddingBottom : 0
468
+ },
469
+ descriptionStyle: styles.description,
470
+ errorStyle: styles.error,
471
+ prefixStyle: styles.prefix,
472
+ suffixStyle: styles.suffix,
473
+ icon: {
474
+ size: icon.fontSize,
475
+ // `ColorValue` also covers the platform's opaque colours, which an icon component
476
+ // takes as a `string` and nothing else.
477
+ color: typeof icon.color === "string" ? icon.color : void 0
478
+ },
479
+ // `ColorValue` also covers the platform's opaque colours, which `TextInput` cannot
480
+ // take for a placeholder.
481
+ placeholderTextColor: typeof placeholder.color === "string" ? placeholder.color : void 0,
482
+ onFieldFocus,
483
+ onFieldBlur,
484
+ labelId,
485
+ descriptionId,
486
+ isDisabled,
487
+ isInvalid
488
+ };
489
+ }, [
490
+ styles,
491
+ tint,
492
+ onFieldFocus,
493
+ onFieldBlur,
494
+ labelId,
495
+ descriptionId,
496
+ isDisabled,
497
+ isInvalid
498
+ ]);
499
+ const rootStyle = [styles.root, tint?.root, styleProps, style];
500
+ const surface = asChild ? (
501
+ // R12 — the caller's element *is* the column.
502
+ /* @__PURE__ */ jsx5(Slot, { ref, ...rest, style: rootStyle, children })
503
+ ) : /* @__PURE__ */ jsx5(View, { ref, ...rest, style: rootStyle, children });
504
+ return /* @__PURE__ */ jsx5(InputProvider, { value: context, children: surface });
505
+ });
506
+ InputRoot.displayName = "XAUI.Input.Root";
507
+
508
+ // src/components/input/index.ts
509
+ var Input2 = Object.assign(InputRoot, {
510
+ Label: InputLabel,
511
+ Field: InputField,
512
+ Description: InputDescription,
513
+ Error: InputError
514
+ });
515
+
516
+ export {
517
+ useInput,
518
+ InputDescription,
519
+ InputError,
520
+ InputField,
521
+ InputLabel,
522
+ inputRecipe,
523
+ InputRoot,
524
+ Input2 as Input
525
+ };
@@ -0,0 +1,102 @@
1
+ // src/system/selection-fill/selection-fill.tsx
2
+ import { View } from "react-native";
3
+ import Animated, { useAnimatedStyle, useDerivedValue, withTiming } from "react-native-reanimated";
4
+ import { jsx } from "react/jsx-runtime";
5
+ var DURATION = 120;
6
+ var FROM_SCALE = 0.8;
7
+ function SelectionFill({
8
+ isVisible,
9
+ style,
10
+ animation = true,
11
+ children
12
+ }) {
13
+ if (!animation) {
14
+ return isVisible ? /* @__PURE__ */jsx(View, {
15
+ style,
16
+ children
17
+ }) : null;
18
+ }
19
+ return /* @__PURE__ */jsx(AnimatedFill, {
20
+ isVisible,
21
+ style,
22
+ children
23
+ });
24
+ }
25
+ SelectionFill.displayName = "XAUI.SelectionFill";
26
+ const _worklet_13281565252924_init_data = {
27
+ code: "function chunkBA2DBSANJs1(){const{withTiming,isVisible,DURATION}=this.__closure;return withTiming(isVisible?1:0,{duration:DURATION});}",
28
+ location: "/home/runner/work/xaui/xaui/packages/native/dist/chunk-BA2DBSAN.js",
29
+ sourceMap: "{\"version\":3,\"names\":[\"chunkBA2DBSANJs1\",\"withTiming\",\"isVisible\",\"DURATION\",\"__closure\",\"duration\"],\"sources\":[\"/home/runner/work/xaui/xaui/packages/native/dist/chunk-BA2DBSAN.js\"],\"mappings\":\"AA2BmC,SAAAA,gBAAMA,CAAA,QAAAC,UAAA,CAAAC,SAAA,CAAAC,QAAA,OAAAC,SAAA,CAErC,MAAO,CAAAH,UAAU,CAACC,SAAS,CAAG,CAAC,CAAG,CAAC,CAAE,CAAEG,QAAQ,CAAEF,QAAS,CAAC,CAAC,CAC9D\",\"ignoreList\":[]}"
30
+ };
31
+ const _worklet_2224484425301_init_data = {
32
+ code: "function chunkBA2DBSANJs2(){const{progress,FROM_SCALE}=this.__closure;return{opacity:progress.value,transform:[{scale:FROM_SCALE+(1-FROM_SCALE)*progress.value}]};}",
33
+ location: "/home/runner/work/xaui/xaui/packages/native/dist/chunk-BA2DBSAN.js",
34
+ sourceMap: "{\"version\":3,\"names\":[\"chunkBA2DBSANJs2\",\"progress\",\"FROM_SCALE\",\"__closure\",\"opacity\",\"value\",\"transform\",\"scale\"],\"sources\":[\"/home/runner/work/xaui/xaui/packages/native/dist/chunk-BA2DBSAN.js\"],\"mappings\":\"AA+ByC,SAAAA,gBAAMA,CAAA,QAAAC,QAAA,CAAAC,UAAA,OAAAC,SAAA,CAE3C,MAAO,CACLC,OAAO,CAAEH,QAAQ,CAACI,KAAK,CACvBC,SAAS,CAAE,CAAC,CAAEC,KAAK,CAAEL,UAAU,CAAG,CAAC,CAAC,CAAGA,UAAU,EAAID,QAAQ,CAACI,KAAM,CAAC,CACvE,CAAC,CACH\",\"ignoreList\":[]}"
35
+ };
36
+ function AnimatedFill({
37
+ isVisible,
38
+ style,
39
+ children
40
+ }) {
41
+ const progress = useDerivedValue(function chunkBA2DBSANJs1Factory({
42
+ _worklet_13281565252924_init_data,
43
+ withTiming,
44
+ isVisible,
45
+ DURATION
46
+ }) {
47
+ const _e = [new global.Error(), -4, -27];
48
+ const chunkBA2DBSANJs1 = function () {
49
+ return withTiming(isVisible ? 1 : 0, {
50
+ duration: DURATION
51
+ });
52
+ };
53
+ chunkBA2DBSANJs1.__closure = {
54
+ withTiming,
55
+ isVisible,
56
+ DURATION
57
+ };
58
+ chunkBA2DBSANJs1.__workletHash = 13281565252924;
59
+ chunkBA2DBSANJs1.__pluginVersion = "0.7.4";
60
+ chunkBA2DBSANJs1.__initData = _worklet_13281565252924_init_data;
61
+ chunkBA2DBSANJs1.__stackDetails = _e;
62
+ return chunkBA2DBSANJs1;
63
+ }({
64
+ _worklet_13281565252924_init_data,
65
+ withTiming,
66
+ isVisible,
67
+ DURATION
68
+ }), [isVisible]);
69
+ const animatedStyle = useAnimatedStyle(function chunkBA2DBSANJs2Factory({
70
+ _worklet_2224484425301_init_data,
71
+ progress,
72
+ FROM_SCALE
73
+ }) {
74
+ const _e = [new global.Error(), -3, -27];
75
+ const chunkBA2DBSANJs2 = function () {
76
+ return {
77
+ opacity: progress.value,
78
+ transform: [{
79
+ scale: FROM_SCALE + (1 - FROM_SCALE) * progress.value
80
+ }]
81
+ };
82
+ };
83
+ chunkBA2DBSANJs2.__closure = {
84
+ progress,
85
+ FROM_SCALE
86
+ };
87
+ chunkBA2DBSANJs2.__workletHash = 2224484425301;
88
+ chunkBA2DBSANJs2.__pluginVersion = "0.7.4";
89
+ chunkBA2DBSANJs2.__initData = _worklet_2224484425301_init_data;
90
+ chunkBA2DBSANJs2.__stackDetails = _e;
91
+ return chunkBA2DBSANJs2;
92
+ }({
93
+ _worklet_2224484425301_init_data,
94
+ progress,
95
+ FROM_SCALE
96
+ }), [progress]);
97
+ return /* @__PURE__ */jsx(Animated.View, {
98
+ style: [style, animatedStyle],
99
+ children
100
+ });
101
+ }
102
+ export { SelectionFill };