@xaui/native 0.9.1-alpha.2 → 0.9.1-alpha.21

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 (65) hide show
  1. package/dist/chunk-2WMVDMFV.cjs +62 -0
  2. package/dist/chunk-33QILJJH.cjs +143 -0
  3. package/dist/chunk-4NE3SLTM.cjs +695 -0
  4. package/dist/{chunk-M7P46XKI.cjs → chunk-57SJ4LJF.cjs} +33 -3
  5. package/dist/chunk-5LC6KVL3.cjs +68 -0
  6. package/dist/{chunk-RBNCR5KB.js → chunk-A3EGFI6T.js} +31 -1
  7. package/dist/chunk-APCBIHLR.cjs +507 -0
  8. package/dist/chunk-BPBY7ON7.cjs +451 -0
  9. package/dist/chunk-EVXZGNPA.cjs +303 -0
  10. package/dist/chunk-EXX6ATAS.js +303 -0
  11. package/dist/chunk-GGW42MY4.js +20 -0
  12. package/dist/chunk-IBRVMLUF.js +668 -0
  13. package/dist/chunk-ISVUXVFL.js +471 -0
  14. package/dist/chunk-JL27KVRT.js +68 -0
  15. package/dist/chunk-JXLRHKCQ.js +143 -0
  16. package/dist/chunk-MC7SY2QH.cjs +20 -0
  17. package/dist/{chunk-RCP3SD26.js → chunk-N7C4UNUL.js} +2 -126
  18. package/dist/chunk-RMLFMRWL.js +102 -0
  19. package/dist/chunk-RRRGLRRP.cjs +28 -0
  20. package/dist/chunk-SGHP76GU.js +28 -0
  21. package/dist/{chunk-PBVPOX7D.js → chunk-TUJBDS5M.js} +30 -63
  22. package/dist/chunk-UBA6AEY6.cjs +102 -0
  23. package/dist/{chunk-NHPQQQ7P.cjs → chunk-UL263KGM.cjs} +56 -89
  24. package/dist/{chunk-B755PRVJ.cjs → chunk-UVO4GFSW.cjs} +3 -127
  25. package/dist/chunk-XHZBXYVU.js +62 -0
  26. package/dist/chunk-YRCUALUQ.js +451 -0
  27. package/dist/components/button/index.cjs +17 -0
  28. package/dist/components/button/index.d.cts +659 -0
  29. package/dist/components/button/index.d.ts +659 -0
  30. package/dist/components/button/index.js +17 -0
  31. package/dist/components/card/index.cjs +20 -0
  32. package/dist/components/card/index.d.cts +620 -0
  33. package/dist/components/card/index.d.ts +620 -0
  34. package/dist/components/card/index.js +20 -0
  35. package/dist/components/typography/index.cjs +14 -0
  36. package/dist/components/typography/index.d.cts +116 -0
  37. package/dist/components/typography/index.d.ts +116 -0
  38. package/dist/components/typography/index.js +14 -0
  39. package/dist/components/view/index.cjs +16 -0
  40. package/dist/components/view/index.d.cts +152 -0
  41. package/dist/components/view/index.d.ts +152 -0
  42. package/dist/components/view/index.js +16 -0
  43. package/dist/create-recipe-CC3NNCqF.d.ts +94 -0
  44. package/dist/create-recipe-CPBFg7ym.d.cts +94 -0
  45. package/dist/icon.type-BkcEPJbK.d.ts +73 -0
  46. package/dist/icon.type-Cs1tMX0W.d.cts +73 -0
  47. package/dist/index.cjs +167 -5
  48. package/dist/index.d.cts +79 -4
  49. package/dist/index.d.ts +79 -4
  50. package/dist/index.js +171 -9
  51. package/dist/pressable-feedback.type-DsvWZXWC.d.ts +127 -0
  52. package/dist/pressable-feedback.type-wfeiJz5m.d.cts +127 -0
  53. package/dist/style-props.type-B1BG5TCm.d.cts +31 -0
  54. package/dist/style-props.type-B1BG5TCm.d.ts +31 -0
  55. package/dist/system/index.cjs +66 -3
  56. package/dist/system/index.d.cts +301 -75
  57. package/dist/system/index.d.ts +301 -75
  58. package/dist/system/index.js +68 -5
  59. package/dist/theme/index.cjs +4 -3
  60. package/dist/theme/index.d.cts +27 -15
  61. package/dist/theme/index.d.ts +27 -15
  62. package/dist/theme/index.js +7 -6
  63. package/dist/{theme.type-B3ODSLbB.d.cts → theme.type-C2gNHpEx.d.cts} +8 -2
  64. package/dist/{theme.type-B3ODSLbB.d.ts → theme.type-C2gNHpEx.d.ts} +8 -2
  65. package/package.json +74 -18
@@ -1,4 +1,25 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true});// src/utils/colors.ts
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});// src/theme/theme-context.ts
2
+ var _react = require('react');
3
+ var ThemeContext = _react.createContext.call(void 0, null);
4
+
5
+ // src/theme/theme-hooks.ts
6
+
7
+ function useXAUITheme() {
8
+ const theme = _react.useContext.call(void 0, ThemeContext);
9
+ if (theme === null) {
10
+ throw new Error("XAUI: useXAUITheme must be used within <XAUIProvider>.");
11
+ }
12
+ return theme;
13
+ }
14
+ function useColorMode() {
15
+ return useXAUITheme().mode;
16
+ }
17
+ function useThemeColor(token) {
18
+ const { colors } = useXAUITheme();
19
+ return Array.isArray(token) ? token.map((key) => colors[key]) : colors[token];
20
+ }
21
+
22
+ // src/utils/colors.ts
2
23
  var srgbToLinear = (c) => c <= 0.04045 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4;
3
24
  var linearToSrgb = (c) => c <= 31308e-7 ? 12.92 * c : 1.055 * c ** (1 / 2.4) - 0.055;
4
25
  var clamp01 = (n) => Math.min(1, Math.max(0, n));
@@ -86,7 +107,10 @@ function deriveTint(tint, theme) {
86
107
  foreground,
87
108
  soft: alpha(tint, 0.15),
88
109
  softForeground: mix(tint, theme.colors.foreground, 0.2),
89
- pressed: mix(tint, foreground, 0.1),
110
+ // Towards the mode's ink, not the tint's own foreground — the same single direction
111
+ // the token layer takes (P2-API-REVIEW §E). A raw tint has to behave like `accent`
112
+ // under the finger as much as it does at rest.
113
+ pressed: mix(tint, theme.colors.foreground, 0.1),
90
114
  softPressed: alpha(tint, 0.2)
91
115
  };
92
116
  cache.set(key, derived);
@@ -97,4 +121,10 @@ function deriveTint(tint, theme) {
97
121
 
98
122
 
99
123
 
100
- exports.mix = mix; exports.alpha = alpha; exports.deriveTint = deriveTint;
124
+
125
+
126
+
127
+
128
+
129
+
130
+ exports.ThemeContext = ThemeContext; exports.useXAUITheme = useXAUITheme; exports.useColorMode = useColorMode; exports.useThemeColor = useThemeColor; exports.isHex = isHex; exports.mix = mix; exports.alpha = alpha; exports.contrastOn = contrastOn; exports.deriveTint = deriveTint;
@@ -0,0 +1,68 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } }
2
+
3
+ var _chunkEVXZGNPAcjs = require('./chunk-EVXZGNPA.cjs');
4
+
5
+
6
+ var _chunk57SJ4LJFcjs = require('./chunk-57SJ4LJF.cjs');
7
+
8
+ // src/system/icon/icon-context.ts
9
+ var _react = require('react');
10
+ var IconContext = _react.createContext.call(void 0, {});
11
+ IconContext.displayName = "XAUI.Icon.Context";
12
+ function useIconContext() {
13
+ return _react.useContext.call(void 0, IconContext);
14
+ }
15
+
16
+ // src/system/icon/icon.tsx
17
+
18
+ var _reactnative = require('react-native');
19
+ var _jsxruntime = require('react/jsx-runtime');
20
+ function Icon(props) {
21
+ const inherited = useIconContext();
22
+ const theme = _chunk57SJ4LJFcjs.useXAUITheme.call(void 0, );
23
+ const size = _nullishCoalesce(_nullishCoalesce(props.size, () => ( inherited.size)), () => ( theme.fontSizes.md));
24
+ const color = _nullishCoalesce(_nullishCoalesce(props.color, () => ( inherited.color)), () => ( theme.colors.foreground));
25
+ if (props.as) {
26
+ const Component = props.as;
27
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Component, { size, color });
28
+ }
29
+ if (_react.isValidElement.call(void 0, props.children)) {
30
+ return _react.cloneElement.call(void 0, props.children, {
31
+ width: size,
32
+ height: size,
33
+ color
34
+ });
35
+ }
36
+ if (props.source) return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, IconImage, { ...props, resolved: { size, color } });
37
+ throw new Error(
38
+ "XAUI: Icon needs one of `as` (an icon component), a raw SVG element as its child, or `source` (an image). It renders nothing on its own."
39
+ );
40
+ }
41
+ Icon.displayName = "XAUI.Icon";
42
+ function IconImage({
43
+ source,
44
+ style,
45
+ resolved,
46
+ size: _size,
47
+ color: _color,
48
+ ...props
49
+ }) {
50
+ const [styleProps] = _chunkEVXZGNPAcjs.useStyleProps.call(void 0, props);
51
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
52
+ _reactnative.Image,
53
+ {
54
+ source,
55
+ style: [
56
+ { width: resolved.size, height: resolved.size, tintColor: resolved.color },
57
+ styleProps,
58
+ style
59
+ ]
60
+ }
61
+ );
62
+ }
63
+
64
+
65
+
66
+
67
+
68
+ exports.IconContext = IconContext; exports.useIconContext = useIconContext; exports.Icon = Icon;
@@ -1,3 +1,24 @@
1
+ // src/theme/theme-context.ts
2
+ import { createContext } from "react";
3
+ var ThemeContext = createContext(null);
4
+
5
+ // src/theme/theme-hooks.ts
6
+ import { useContext } from "react";
7
+ function useXAUITheme() {
8
+ const theme = useContext(ThemeContext);
9
+ if (theme === null) {
10
+ throw new Error("XAUI: useXAUITheme must be used within <XAUIProvider>.");
11
+ }
12
+ return theme;
13
+ }
14
+ function useColorMode() {
15
+ return useXAUITheme().mode;
16
+ }
17
+ function useThemeColor(token) {
18
+ const { colors } = useXAUITheme();
19
+ return Array.isArray(token) ? token.map((key) => colors[key]) : colors[token];
20
+ }
21
+
1
22
  // src/utils/colors.ts
2
23
  var srgbToLinear = (c) => c <= 0.04045 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4;
3
24
  var linearToSrgb = (c) => c <= 31308e-7 ? 12.92 * c : 1.055 * c ** (1 / 2.4) - 0.055;
@@ -86,7 +107,10 @@ function deriveTint(tint, theme) {
86
107
  foreground,
87
108
  soft: alpha(tint, 0.15),
88
109
  softForeground: mix(tint, theme.colors.foreground, 0.2),
89
- pressed: mix(tint, foreground, 0.1),
110
+ // Towards the mode's ink, not the tint's own foreground — the same single direction
111
+ // the token layer takes (P2-API-REVIEW §E). A raw tint has to behave like `accent`
112
+ // under the finger as much as it does at rest.
113
+ pressed: mix(tint, theme.colors.foreground, 0.1),
90
114
  softPressed: alpha(tint, 0.2)
91
115
  };
92
116
  cache.set(key, derived);
@@ -94,7 +118,13 @@ function deriveTint(tint, theme) {
94
118
  }
95
119
 
96
120
  export {
121
+ ThemeContext,
122
+ useXAUITheme,
123
+ useColorMode,
124
+ useThemeColor,
125
+ isHex,
97
126
  mix,
98
127
  alpha,
128
+ contrastOn,
99
129
  deriveTint
100
130
  };
@@ -0,0 +1,507 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ function _interopRequireDefault(obj) {
7
+ return obj && obj.__esModule ? obj : {
8
+ default: obj
9
+ };
10
+ }
11
+ function _nullishCoalesce(lhs, rhsFn) {
12
+ if (lhs != null) {
13
+ return lhs;
14
+ } else {
15
+ return rhsFn();
16
+ }
17
+ }
18
+ function _optionalChain(ops) {
19
+ let lastAccessLHS = undefined;
20
+ let value = ops[0];
21
+ let i = 1;
22
+ while (i < ops.length) {
23
+ const op = ops[i];
24
+ const fn = ops[i + 1];
25
+ i += 2;
26
+ if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) {
27
+ return undefined;
28
+ }
29
+ if (op === 'access' || op === 'optionalAccess') {
30
+ lastAccessLHS = value;
31
+ value = fn(value);
32
+ } else if (op === 'call' || op === 'optionalCall') {
33
+ value = fn((...args) => value.call(lastAccessLHS, ...args));
34
+ lastAccessLHS = undefined;
35
+ }
36
+ }
37
+ return value;
38
+ }
39
+ var _chunkRRRGLRRPcjs = require('./chunk-RRRGLRRP.cjs');
40
+ var _chunk5LC6KVL3cjs = require('./chunk-5LC6KVL3.cjs');
41
+ var _chunk4NE3SLTMcjs = require('./chunk-4NE3SLTM.cjs');
42
+ var _chunkUVO4GFSWcjs = require('./chunk-UVO4GFSW.cjs');
43
+ var _chunkEVXZGNPAcjs = require('./chunk-EVXZGNPA.cjs');
44
+ var _chunk57SJ4LJFcjs = require('./chunk-57SJ4LJF.cjs');
45
+
46
+ // src/components/button/button.context.ts
47
+ var [ButtonProvider, useButton] = _chunkEVXZGNPAcjs.createSlotContext.call(void 0, "Button");
48
+
49
+ // src/components/button/button-icon.tsx
50
+ var _jsxruntime = require('react/jsx-runtime');
51
+ function ButtonIcon({
52
+ size,
53
+ color,
54
+ ...rest
55
+ }) {
56
+ const {
57
+ icon
58
+ } = useButton();
59
+ return /* @__PURE__ */_jsxruntime.jsx.call(void 0, _chunk5LC6KVL3cjs.Icon, {
60
+ size: _nullishCoalesce(size, () => icon.size),
61
+ color: _nullishCoalesce(color, () => icon.color),
62
+ ...rest
63
+ });
64
+ }
65
+ ButtonIcon.displayName = "XAUI.Button.Icon";
66
+
67
+ // src/components/button/button-label.tsx
68
+ var _react = require('react');
69
+ var _reactnative = require('react-native');
70
+ var ButtonLabel = _react.forwardRef.call(void 0, function ButtonLabel2({
71
+ children,
72
+ style,
73
+ numberOfLines = 1,
74
+ ...props
75
+ }, ref) {
76
+ const {
77
+ labelStyle
78
+ } = useButton();
79
+ const [styleProps, rest] = _chunkEVXZGNPAcjs.useStyleProps.call(void 0, props);
80
+ return /* @__PURE__ */_jsxruntime.jsx.call(void 0, _reactnative.Text, {
81
+ ref,
82
+ numberOfLines,
83
+ style: [labelStyle, styleProps, style],
84
+ ...rest,
85
+ children
86
+ });
87
+ });
88
+ ButtonLabel.displayName = "XAUI.Button.Label";
89
+
90
+ // src/components/button/button-spinner.tsx
91
+
92
+ var _reactnativereanimated = require('react-native-reanimated');
93
+ var _reactnativereanimated2 = _interopRequireDefault(_reactnativereanimated);
94
+ var ROTATION_DURATION = 800;
95
+ function ButtonSpinner({
96
+ style,
97
+ animation = true,
98
+ ...props
99
+ }) {
100
+ const {
101
+ spinnerStyle
102
+ } = useButton();
103
+ const [styleProps] = _chunkEVXZGNPAcjs.useStyleProps.call(void 0, props);
104
+ const ringStyle = [spinnerStyle, styleProps, style];
105
+ if (!animation) return /* @__PURE__ */_jsxruntime.jsx.call(void 0, _reactnative.View, {
106
+ style: ringStyle
107
+ });
108
+ return /* @__PURE__ */_jsxruntime.jsx.call(void 0, SpinningRing, {
109
+ style: ringStyle
110
+ });
111
+ }
112
+ ButtonSpinner.displayName = "XAUI.Button.Spinner";
113
+ const _worklet_6059163963819_init_data = {
114
+ code: "function chunkAPCBIHLRCjs1(){const{angle}=this.__closure;return{transform:[{rotate:angle.value+\"deg\"}]};}",
115
+ location: "/home/runner/work/xaui/xaui/packages/native/dist/chunk-APCBIHLR.cjs",
116
+ sourceMap: "{\"version\":3,\"names\":[\"chunkAPCBIHLRCjs1\",\"angle\",\"__closure\",\"transform\",\"rotate\",\"value\"],\"sources\":[\"/home/runner/work/xaui/xaui/packages/native/dist/chunk-APCBIHLR.cjs\"],\"mappings\":\"AAoF6E,SAAAA,iBAAMA,CAAA,QAAAC,KAAA,OAAAC,SAAA,CAE/E,MAAO,CAAEC,SAAS,CAAE,CAAC,CAAEC,MAAM,CAAKH,KAAK,CAACI,KAAK,MAAM,CAAC,CAAE,CAAC,CACzD\",\"ignoreList\":[]}"
117
+ };
118
+ function SpinningRing({
119
+ style
120
+ }) {
121
+ const angle = _reactnativereanimated.useSharedValue.call(void 0, 0);
122
+ _react.useEffect.call(void 0, () => {
123
+ angle.value = _reactnativereanimated.withRepeat.call(void 0, _reactnativereanimated.withTiming.call(void 0, 360, {
124
+ duration: ROTATION_DURATION,
125
+ easing: _reactnativereanimated.Easing.linear
126
+ }), -1, false);
127
+ return () => _reactnativereanimated.cancelAnimation.call(void 0, angle);
128
+ }, [angle]);
129
+ const animatedStyle = _reactnativereanimated.useAnimatedStyle.call(void 0, function chunkAPCBIHLRCjs1Factory({
130
+ _worklet_6059163963819_init_data,
131
+ angle
132
+ }) {
133
+ const _e = [new global.Error(), -2, -27];
134
+ const chunkAPCBIHLRCjs1 = function () {
135
+ return {
136
+ transform: [{
137
+ rotate: `${angle.value}deg`
138
+ }]
139
+ };
140
+ };
141
+ chunkAPCBIHLRCjs1.__closure = {
142
+ angle
143
+ };
144
+ chunkAPCBIHLRCjs1.__workletHash = 6059163963819;
145
+ chunkAPCBIHLRCjs1.__pluginVersion = "0.7.4";
146
+ chunkAPCBIHLRCjs1.__initData = _worklet_6059163963819_init_data;
147
+ chunkAPCBIHLRCjs1.__stackDetails = _e;
148
+ return chunkAPCBIHLRCjs1;
149
+ }({
150
+ _worklet_6059163963819_init_data,
151
+ angle
152
+ }), [angle]);
153
+ return /* @__PURE__ */_jsxruntime.jsx.call(void 0, _reactnativereanimated2.default.View, {
154
+ style: [style, animatedStyle]
155
+ });
156
+ }
157
+
158
+ // src/components/button/button.tsx
159
+
160
+ // src/components/button/button.recipe.ts
161
+ var SLOTS = ["root", "label", "icon", "spinner"];
162
+ var VARIANT_TOKENS = {
163
+ primary: {
164
+ bg: "accent",
165
+ bgPressed: "accentPressed",
166
+ fg: "accentForeground"
167
+ },
168
+ // The accent's soft slice, not a second neutral: `secondary` is to `primary` what
169
+ // `danger-soft` is to `danger`, and it reads as the same family at lower emphasis.
170
+ secondary: {
171
+ bg: "accentSoft",
172
+ bgPressed: "accentSoftPressed",
173
+ fg: "accentSoftForeground"
174
+ },
175
+ default: {
176
+ bg: "default",
177
+ bgPressed: "defaultPressed",
178
+ fg: "defaultForeground"
179
+ },
180
+ tertiary: {
181
+ border: "border",
182
+ bgPressed: "defaultSoftPressed",
183
+ fg: "foreground"
184
+ },
185
+ ghost: {
186
+ bgPressed: "defaultSoftPressed",
187
+ fg: "foreground"
188
+ },
189
+ danger: {
190
+ bg: "danger",
191
+ bgPressed: "dangerPressed",
192
+ fg: "dangerForeground"
193
+ },
194
+ "danger-soft": {
195
+ bg: "dangerSoft",
196
+ bgPressed: "dangerSoftPressed",
197
+ fg: "dangerSoftForeground"
198
+ }
199
+ };
200
+ function ring(theme, size) {
201
+ return {
202
+ width: size,
203
+ height: size,
204
+ borderRadius: size / 2,
205
+ borderWidth: theme.borderWidth.default * 2,
206
+ borderTopColor: "transparent"
207
+ };
208
+ }
209
+ function sizeAxis(step) {
210
+ const {
211
+ size,
212
+ padding,
213
+ gap,
214
+ glyph,
215
+ radius
216
+ } = step;
217
+ return theme => ({
218
+ root: {
219
+ height: theme.controlHeights[size],
220
+ paddingHorizontal: theme.spacing(padding),
221
+ gap: theme.spacing(gap),
222
+ borderRadius: theme.radius[radius]
223
+ },
224
+ label: {
225
+ fontSize: theme.fontSizes[size],
226
+ lineHeight: theme.lineHeights[size]
227
+ },
228
+ icon: {
229
+ fontSize: theme.fontSizes[glyph]
230
+ },
231
+ spinner: ring(theme, theme.fontSizes[glyph])
232
+ });
233
+ }
234
+ var buttonRecipe = _chunkUVO4GFSWcjs.createRecipe.call(void 0, {
235
+ slots: SLOTS,
236
+ base: theme => ({
237
+ root: {
238
+ flexDirection: "row",
239
+ alignItems: "center",
240
+ justifyContent: "center",
241
+ borderWidth: 0,
242
+ // iOS's squircle. Free on Android, and it is what makes a large radius read as a
243
+ // shape rather than as two arcs meeting a straight edge.
244
+ borderCurve: "continuous"
245
+ },
246
+ label: {
247
+ fontFamily: theme.fontFamilies.body,
248
+ fontWeight: theme.fontWeights.medium
249
+ }
250
+ }),
251
+ variantTokens: VARIANT_TOKENS,
252
+ /**
253
+ * Where the variant's colours land, for every variant at once. The border width follows
254
+ * the *presence* of the border role rather than a per-variant flag — `tertiary` is the
255
+ * only variant that names one, and that fact is already in the table above.
256
+ */
257
+ paint: (theme, colors) => ({
258
+ root: {
259
+ backgroundColor: colors.bg,
260
+ borderColor: colors.border,
261
+ borderWidth: colors.border ? theme.borderWidth.default : 0
262
+ },
263
+ label: {
264
+ color: colors.fg
265
+ },
266
+ icon: {
267
+ color: colors.fg
268
+ },
269
+ spinner: {
270
+ borderColor: colors.fg
271
+ }
272
+ }),
273
+ /**
274
+ * Declaration order is application order: `radius` overrides the radius `size` set, and
275
+ * `isIconOnly` overrides its padding. Both are axes rather than a static sheet merged
276
+ * at the call site, so they stay inside the cache key and a press still allocates
277
+ * nothing.
278
+ */
279
+ variants: {
280
+ size: {
281
+ xs: sizeAxis({
282
+ size: "xs",
283
+ padding: 3,
284
+ gap: 1,
285
+ glyph: "sm",
286
+ radius: "3xl"
287
+ }),
288
+ sm: sizeAxis({
289
+ size: "sm",
290
+ padding: 3.5,
291
+ gap: 1.5,
292
+ glyph: "md",
293
+ radius: "3xl"
294
+ }),
295
+ md: sizeAxis({
296
+ size: "md",
297
+ padding: 4,
298
+ gap: 2,
299
+ glyph: "lg",
300
+ radius: "3xl"
301
+ }),
302
+ lg: sizeAxis({
303
+ size: "lg",
304
+ padding: 5,
305
+ gap: 2.5,
306
+ glyph: "xl",
307
+ radius: "4xl"
308
+ })
309
+ },
310
+ radius: {
311
+ xs: t => ({
312
+ root: {
313
+ borderRadius: t.radius.xs
314
+ }
315
+ }),
316
+ sm: t => ({
317
+ root: {
318
+ borderRadius: t.radius.sm
319
+ }
320
+ }),
321
+ md: t => ({
322
+ root: {
323
+ borderRadius: t.radius.md
324
+ }
325
+ }),
326
+ lg: t => ({
327
+ root: {
328
+ borderRadius: t.radius.lg
329
+ }
330
+ }),
331
+ xl: t => ({
332
+ root: {
333
+ borderRadius: t.radius.xl
334
+ }
335
+ }),
336
+ "2xl": t => ({
337
+ root: {
338
+ borderRadius: t.radius["2xl"]
339
+ }
340
+ }),
341
+ "3xl": t => ({
342
+ root: {
343
+ borderRadius: t.radius["3xl"]
344
+ }
345
+ }),
346
+ "4xl": t => ({
347
+ root: {
348
+ borderRadius: t.radius["4xl"]
349
+ }
350
+ }),
351
+ field: t => ({
352
+ root: {
353
+ borderRadius: t.radius.field
354
+ }
355
+ }),
356
+ full: t => ({
357
+ root: {
358
+ borderRadius: t.radius.full
359
+ }
360
+ })
361
+ },
362
+ // A square on a fixed height. No width is computed, and none needs to be.
363
+ isIconOnly: {
364
+ true: () => ({
365
+ root: {
366
+ paddingHorizontal: 0,
367
+ aspectRatio: 1
368
+ }
369
+ })
370
+ }
371
+ },
372
+ /**
373
+ * The pressed colour lives here rather than in a `PressableFeedback.Highlight`, because
374
+ * a control picks one treatment or the other — both, and a pressed button darkens
375
+ * twice. This one is the variant's own `…Pressed` token, so the press reads as the
376
+ * button's colour going down rather than as a neutral film over it, and a tinted button
377
+ * presses through the same OKLab formula as a token one.
378
+ */
379
+ states: {
380
+ pressed: (_theme, colors) => ({
381
+ root: {
382
+ backgroundColor: colors.bgPressed
383
+ }
384
+ }),
385
+ disabled: theme => ({
386
+ root: {
387
+ opacity: theme.opacity.disabled
388
+ }
389
+ })
390
+ },
391
+ defaultVariants: {
392
+ variant: "primary",
393
+ size: "md"
394
+ }
395
+ });
396
+
397
+ // src/components/button/button.utils.ts
398
+
399
+ function containsElementOfType(children, type) {
400
+ return _react.Children.toArray(children).some(child => _react.isValidElement.call(void 0, child) && child.type === type);
401
+ }
402
+
403
+ // src/components/button/button.tsx
404
+
405
+ var ButtonRoot = _react.forwardRef.call(void 0, function Button({
406
+ children,
407
+ variant,
408
+ size,
409
+ radius,
410
+ color,
411
+ isDisabled = false,
412
+ isLoading = false,
413
+ isIconOnly = false,
414
+ asChild = false,
415
+ accessibilityRole = "button",
416
+ accessibilityState,
417
+ style,
418
+ onPressIn,
419
+ onPressOut,
420
+ ...props
421
+ }, ref) {
422
+ const theme = _chunk57SJ4LJFcjs.useXAUITheme.call(void 0);
423
+ const [styleProps, rest] = _chunkEVXZGNPAcjs.useStyleProps.call(void 0, props);
424
+ const [isPressed, press] = _chunkRRRGLRRPcjs.usePressState.call(void 0, {
425
+ onPressIn,
426
+ onPressOut
427
+ });
428
+ const selection = {
429
+ variant,
430
+ size,
431
+ radius,
432
+ isIconOnly: isIconOnly ? "true" : void 0
433
+ };
434
+ const states = {
435
+ pressed: isPressed,
436
+ disabled: isDisabled || isLoading
437
+ };
438
+ const styles = buttonRecipe.resolve({
439
+ theme,
440
+ selection,
441
+ states
442
+ });
443
+ const tint = color ? buttonRecipe.tint({
444
+ theme,
445
+ color,
446
+ selection,
447
+ states
448
+ }) : void 0;
449
+ const context = _react.useMemo.call(void 0, () => {
450
+ const icon = _reactnative.StyleSheet.flatten([styles.icon, _optionalChain([tint, 'optionalAccess', _ => _.icon])]);
451
+ return {
452
+ labelStyle: tint ? [styles.label, tint.label] : styles.label,
453
+ spinnerStyle: tint ? [styles.spinner, tint.spinner] : styles.spinner,
454
+ icon: {
455
+ size: icon.fontSize,
456
+ // `ColorValue` also covers the platform's opaque colours, which `Icon` cannot
457
+ // hand to a third-party component expecting a string.
458
+ color: typeof icon.color === "string" ? icon.color : void 0
459
+ },
460
+ isDisabled,
461
+ isLoading
462
+ };
463
+ }, [styles, tint, isDisabled, isLoading]);
464
+ const rootStyle = [styles.root, _optionalChain([tint, 'optionalAccess', _2 => _2.root]), styleProps, typeof style === "function" ? style({
465
+ pressed: isPressed
466
+ }) : style];
467
+ const text = _chunkEVXZGNPAcjs.childrenToString.call(void 0, children);
468
+ const showSpinner = isLoading && !containsElementOfType(children, ButtonSpinner);
469
+ if (isIconOnly && !rest.accessibilityLabel && !rest["aria-label"]) {
470
+ _chunkRRRGLRRPcjs.warnDev.call(void 0, "Button: an icon-only button needs an `accessibilityLabel` \u2014 there is no text for a screen reader to read, so it announces as an unlabelled button.");
471
+ }
472
+ return /* @__PURE__ */_jsxruntime.jsx.call(void 0, ButtonProvider, {
473
+ value: context,
474
+ children: /* @__PURE__ */_jsxruntime.jsx.call(void 0, _chunk4NE3SLTMcjs.PressableFeedback, {
475
+ ref,
476
+ isPressed,
477
+ isDisabled: isDisabled || isLoading,
478
+ asChild,
479
+ accessibilityRole,
480
+ accessibilityState: {
481
+ disabled: isDisabled,
482
+ busy: isLoading,
483
+ ...accessibilityState
484
+ },
485
+ ...rest,
486
+ style: rootStyle,
487
+ onPressIn: press.onPressIn,
488
+ onPressOut: press.onPressOut,
489
+ children: asChild ? children : /* @__PURE__ */_jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, {
490
+ children: [showSpinner ? /* @__PURE__ */_jsxruntime.jsx.call(void 0, ButtonSpinner, {}) : null, text !== null ? /* @__PURE__ */_jsxruntime.jsx.call(void 0, ButtonLabel, {
491
+ children: text
492
+ }) : children]
493
+ })
494
+ })
495
+ });
496
+ });
497
+ ButtonRoot.displayName = "XAUI.Button.Root";
498
+
499
+ // src/components/button/index.ts
500
+ var Button2 = Object.assign(ButtonRoot, {
501
+ Label: ButtonLabel,
502
+ Icon: ButtonIcon,
503
+ Spinner: ButtonSpinner
504
+ });
505
+ exports.useButton = useButton;
506
+ exports.buttonRecipe = buttonRecipe;
507
+ exports.Button = Button2;