@onlynative/components 0.1.0-alpha.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 (87) hide show
  1. package/README.md +99 -0
  2. package/dist/appbar/index.d.ts +71 -0
  3. package/dist/appbar/index.js +952 -0
  4. package/dist/button/index.d.ts +41 -0
  5. package/dist/button/index.js +454 -0
  6. package/dist/card/index.d.ts +31 -0
  7. package/dist/card/index.js +264 -0
  8. package/dist/checkbox/index.d.ts +25 -0
  9. package/dist/checkbox/index.js +291 -0
  10. package/dist/chip/index.d.ts +62 -0
  11. package/dist/chip/index.js +452 -0
  12. package/dist/icon-button/index.d.ts +10 -0
  13. package/dist/icon-button/index.js +575 -0
  14. package/dist/index.d.ts +19 -0
  15. package/dist/index.js +3374 -0
  16. package/dist/layout/index.d.ts +98 -0
  17. package/dist/layout/index.js +282 -0
  18. package/dist/list/index.d.ts +60 -0
  19. package/dist/list/index.js +300 -0
  20. package/dist/radio/index.d.ts +25 -0
  21. package/dist/radio/index.js +250 -0
  22. package/dist/switch/index.d.ts +37 -0
  23. package/dist/switch/index.js +315 -0
  24. package/dist/text-field/index.d.ts +52 -0
  25. package/dist/text-field/index.js +496 -0
  26. package/dist/types-D3hlyvz-.d.ts +51 -0
  27. package/dist/typography/index.d.ts +28 -0
  28. package/dist/typography/index.js +69 -0
  29. package/package.json +166 -0
  30. package/src/appbar/AppBar.tsx +302 -0
  31. package/src/appbar/index.ts +2 -0
  32. package/src/appbar/styles.ts +92 -0
  33. package/src/appbar/types.ts +67 -0
  34. package/src/button/Button.tsx +130 -0
  35. package/src/button/index.ts +2 -0
  36. package/src/button/styles.ts +288 -0
  37. package/src/button/types.ts +42 -0
  38. package/src/card/Card.tsx +69 -0
  39. package/src/card/index.ts +2 -0
  40. package/src/card/styles.ts +151 -0
  41. package/src/card/types.ts +27 -0
  42. package/src/checkbox/Checkbox.tsx +109 -0
  43. package/src/checkbox/index.ts +2 -0
  44. package/src/checkbox/styles.ts +155 -0
  45. package/src/checkbox/types.ts +20 -0
  46. package/src/chip/Chip.tsx +182 -0
  47. package/src/chip/index.ts +2 -0
  48. package/src/chip/styles.ts +240 -0
  49. package/src/chip/types.ts +58 -0
  50. package/src/icon-button/IconButton.tsx +358 -0
  51. package/src/icon-button/index.ts +6 -0
  52. package/src/icon-button/styles.ts +259 -0
  53. package/src/icon-button/types.ts +55 -0
  54. package/src/index.ts +51 -0
  55. package/src/layout/Box.tsx +99 -0
  56. package/src/layout/Column.tsx +16 -0
  57. package/src/layout/Grid.tsx +49 -0
  58. package/src/layout/Layout.tsx +81 -0
  59. package/src/layout/Row.tsx +22 -0
  60. package/src/layout/index.ts +13 -0
  61. package/src/layout/resolveSpacing.ts +11 -0
  62. package/src/layout/types.ts +82 -0
  63. package/src/list/List.tsx +17 -0
  64. package/src/list/ListDivider.tsx +20 -0
  65. package/src/list/ListItem.tsx +128 -0
  66. package/src/list/index.ts +9 -0
  67. package/src/list/styles.ts +132 -0
  68. package/src/list/types.ts +54 -0
  69. package/src/radio/Radio.tsx +103 -0
  70. package/src/radio/index.ts +2 -0
  71. package/src/radio/styles.ts +139 -0
  72. package/src/radio/types.ts +20 -0
  73. package/src/switch/Switch.tsx +118 -0
  74. package/src/switch/index.ts +2 -0
  75. package/src/switch/styles.ts +172 -0
  76. package/src/switch/types.ts +32 -0
  77. package/src/test-utils/render-with-theme.tsx +13 -0
  78. package/src/text-field/TextField.tsx +298 -0
  79. package/src/text-field/index.ts +2 -0
  80. package/src/text-field/styles.ts +240 -0
  81. package/src/text-field/types.ts +49 -0
  82. package/src/typography/Typography.tsx +65 -0
  83. package/src/typography/index.ts +3 -0
  84. package/src/typography/types.ts +17 -0
  85. package/src/utils/color.ts +64 -0
  86. package/src/utils/elevation.ts +33 -0
  87. package/src/utils/rtl.ts +19 -0
package/dist/index.js ADDED
@@ -0,0 +1,3374 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ AppBar: () => AppBar,
34
+ Box: () => Box,
35
+ Button: () => Button,
36
+ Card: () => Card,
37
+ Checkbox: () => Checkbox,
38
+ Chip: () => Chip,
39
+ Column: () => Column,
40
+ Grid: () => Grid,
41
+ IconButton: () => IconButton,
42
+ Layout: () => Layout,
43
+ List: () => List,
44
+ ListDivider: () => ListDivider,
45
+ ListItem: () => ListItem,
46
+ Radio: () => Radio,
47
+ Row: () => Row,
48
+ Switch: () => Switch,
49
+ TextField: () => TextField,
50
+ Typography: () => Typography
51
+ });
52
+ module.exports = __toCommonJS(index_exports);
53
+
54
+ // src/typography/Typography.tsx
55
+ var import_react = require("react");
56
+ var import_react_native = require("react-native");
57
+ var import_core = require("@onlynative/core");
58
+ var import_jsx_runtime = require("react/jsx-runtime");
59
+ var HEADING_VARIANTS = /* @__PURE__ */ new Set([
60
+ "displayLarge",
61
+ "displayMedium",
62
+ "displaySmall",
63
+ "headlineLarge",
64
+ "headlineMedium",
65
+ "headlineSmall"
66
+ ]);
67
+ function Typography({
68
+ children,
69
+ variant = "bodyMedium",
70
+ color,
71
+ style,
72
+ as: Component = import_react_native.Text,
73
+ accessibilityRole,
74
+ ...textProps
75
+ }) {
76
+ const theme = (0, import_core.useTheme)();
77
+ const typographyStyle = theme.typography[variant];
78
+ const colorStyle = (0, import_react.useMemo)(
79
+ () => ({ color: color != null ? color : theme.colors.onSurface }),
80
+ [color, theme.colors.onSurface]
81
+ );
82
+ const resolvedRole = accessibilityRole != null ? accessibilityRole : HEADING_VARIANTS.has(variant) ? "header" : void 0;
83
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
84
+ Component,
85
+ {
86
+ ...textProps,
87
+ accessibilityRole: resolvedRole,
88
+ style: [typographyStyle, colorStyle, style],
89
+ children
90
+ }
91
+ );
92
+ }
93
+
94
+ // src/layout/Layout.tsx
95
+ var import_react2 = require("react");
96
+ var import_react_native2 = require("react-native");
97
+ var import_react_native_safe_area_context = require("react-native-safe-area-context");
98
+ var import_core2 = require("@onlynative/core");
99
+ var import_jsx_runtime2 = require("react/jsx-runtime");
100
+ var defaultEdges = ["bottom"];
101
+ function resolveEdges(immersive, edges) {
102
+ if (edges) {
103
+ return edges;
104
+ }
105
+ if (immersive) {
106
+ return [];
107
+ }
108
+ return defaultEdges;
109
+ }
110
+ var styles = import_react_native2.StyleSheet.create({
111
+ root: {
112
+ flex: 1
113
+ }
114
+ });
115
+ function removeBackgroundColor(style) {
116
+ if (!style) {
117
+ return void 0;
118
+ }
119
+ const flattenedStyle = import_react_native2.StyleSheet.flatten(style);
120
+ if (!flattenedStyle || flattenedStyle.backgroundColor === void 0) {
121
+ return style;
122
+ }
123
+ const styleWithoutBackground = { ...flattenedStyle };
124
+ delete styleWithoutBackground.backgroundColor;
125
+ return styleWithoutBackground;
126
+ }
127
+ function Layout({ immersive, edges, children, style }) {
128
+ const theme = (0, import_core2.useTheme)();
129
+ const themeBackgroundStyle = (0, import_react2.useMemo)(
130
+ () => ({ backgroundColor: theme.colors.background }),
131
+ [theme.colors.background]
132
+ );
133
+ const styleWithoutBackground = (0, import_react2.useMemo)(
134
+ () => removeBackgroundColor(style),
135
+ [style]
136
+ );
137
+ const safeAreaEdges = (0, import_react2.useMemo)(
138
+ () => resolveEdges(immersive, edges),
139
+ [immersive, edges]
140
+ );
141
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
142
+ import_react_native_safe_area_context.SafeAreaView,
143
+ {
144
+ style: [styles.root, themeBackgroundStyle, styleWithoutBackground],
145
+ edges: safeAreaEdges,
146
+ children
147
+ }
148
+ );
149
+ }
150
+
151
+ // src/layout/Box.tsx
152
+ var import_react3 = require("react");
153
+ var import_react_native3 = require("react-native");
154
+ var import_core3 = require("@onlynative/core");
155
+
156
+ // src/layout/resolveSpacing.ts
157
+ function resolveSpacing(spacing, value) {
158
+ if (value === void 0) return void 0;
159
+ if (typeof value === "number") return value;
160
+ return spacing[value];
161
+ }
162
+
163
+ // src/layout/Box.tsx
164
+ var import_jsx_runtime3 = require("react/jsx-runtime");
165
+ function Box({
166
+ p,
167
+ px,
168
+ py,
169
+ pt,
170
+ pb,
171
+ ps,
172
+ pe,
173
+ m,
174
+ mx,
175
+ my,
176
+ mt,
177
+ mb,
178
+ ms,
179
+ me,
180
+ gap,
181
+ rowGap,
182
+ columnGap,
183
+ flex,
184
+ align,
185
+ justify,
186
+ bg,
187
+ style,
188
+ ...viewProps
189
+ }) {
190
+ const { spacing } = (0, import_core3.useTheme)();
191
+ const layoutStyle = (0, import_react3.useMemo)(() => {
192
+ const s = (v) => resolveSpacing(spacing, v);
193
+ return {
194
+ ...p !== void 0 && { padding: s(p) },
195
+ ...px !== void 0 && {
196
+ paddingStart: s(px),
197
+ paddingEnd: s(px)
198
+ },
199
+ ...py !== void 0 && {
200
+ paddingTop: s(py),
201
+ paddingBottom: s(py)
202
+ },
203
+ ...pt !== void 0 && { paddingTop: s(pt) },
204
+ ...pb !== void 0 && { paddingBottom: s(pb) },
205
+ ...ps !== void 0 && { paddingStart: s(ps) },
206
+ ...pe !== void 0 && { paddingEnd: s(pe) },
207
+ ...m !== void 0 && { margin: s(m) },
208
+ ...mx !== void 0 && {
209
+ marginStart: s(mx),
210
+ marginEnd: s(mx)
211
+ },
212
+ ...my !== void 0 && {
213
+ marginTop: s(my),
214
+ marginBottom: s(my)
215
+ },
216
+ ...mt !== void 0 && { marginTop: s(mt) },
217
+ ...mb !== void 0 && { marginBottom: s(mb) },
218
+ ...ms !== void 0 && { marginStart: s(ms) },
219
+ ...me !== void 0 && { marginEnd: s(me) },
220
+ ...gap !== void 0 && { gap: s(gap) },
221
+ ...rowGap !== void 0 && { rowGap: s(rowGap) },
222
+ ...columnGap !== void 0 && { columnGap: s(columnGap) },
223
+ ...flex !== void 0 && { flex },
224
+ ...align !== void 0 && { alignItems: align },
225
+ ...justify !== void 0 && { justifyContent: justify },
226
+ ...bg !== void 0 && { backgroundColor: bg }
227
+ };
228
+ }, [
229
+ spacing,
230
+ p,
231
+ px,
232
+ py,
233
+ pt,
234
+ pb,
235
+ ps,
236
+ pe,
237
+ m,
238
+ mx,
239
+ my,
240
+ mt,
241
+ mb,
242
+ ms,
243
+ me,
244
+ gap,
245
+ rowGap,
246
+ columnGap,
247
+ flex,
248
+ align,
249
+ justify,
250
+ bg
251
+ ]);
252
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native3.View, { ...viewProps, style: [layoutStyle, style] });
253
+ }
254
+
255
+ // src/layout/Column.tsx
256
+ var import_react4 = require("react");
257
+ var import_jsx_runtime4 = require("react/jsx-runtime");
258
+ function Column({ inverted = false, style, ...boxProps }) {
259
+ const directionStyle = (0, import_react4.useMemo)(
260
+ () => ({
261
+ flexDirection: inverted ? "column-reverse" : "column"
262
+ }),
263
+ [inverted]
264
+ );
265
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Box, { ...boxProps, style: [directionStyle, style] });
266
+ }
267
+
268
+ // src/layout/Grid.tsx
269
+ var import_react6 = __toESM(require("react"));
270
+ var import_react_native4 = require("react-native");
271
+ var import_core4 = require("@onlynative/core");
272
+
273
+ // src/layout/Row.tsx
274
+ var import_react5 = require("react");
275
+ var import_jsx_runtime5 = require("react/jsx-runtime");
276
+ function Row({
277
+ wrap = false,
278
+ inverted = false,
279
+ style,
280
+ ...boxProps
281
+ }) {
282
+ const directionStyle = (0, import_react5.useMemo)(
283
+ () => ({
284
+ flexDirection: inverted ? "row-reverse" : "row",
285
+ ...wrap && { flexWrap: "wrap" }
286
+ }),
287
+ [wrap, inverted]
288
+ );
289
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Box, { ...boxProps, style: [directionStyle, style] });
290
+ }
291
+
292
+ // src/layout/Grid.tsx
293
+ var import_jsx_runtime6 = require("react/jsx-runtime");
294
+ function Grid({
295
+ columns,
296
+ gap,
297
+ columnGap,
298
+ rowGap,
299
+ children,
300
+ style,
301
+ ...rowProps
302
+ }) {
303
+ const { spacing } = (0, import_core4.useTheme)();
304
+ const resolvedColumnGap = resolveSpacing(spacing, columnGap != null ? columnGap : gap);
305
+ const resolvedRowGap = resolveSpacing(spacing, rowGap != null ? rowGap : gap);
306
+ const halfGap = resolvedColumnGap ? resolvedColumnGap / 2 : 0;
307
+ const cellStyle = (0, import_react6.useMemo)(
308
+ () => ({
309
+ flexBasis: `${100 / columns}%`,
310
+ flexShrink: 1,
311
+ paddingLeft: halfGap,
312
+ paddingRight: halfGap
313
+ }),
314
+ [columns, halfGap]
315
+ );
316
+ const rowStyle = (0, import_react6.useMemo)(
317
+ () => ({
318
+ marginLeft: -halfGap,
319
+ marginRight: -halfGap
320
+ }),
321
+ [halfGap]
322
+ );
323
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Row, { wrap: true, rowGap: resolvedRowGap, ...rowProps, style: [rowStyle, style], children: import_react6.default.Children.map(
324
+ children,
325
+ (child) => child != null ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_native4.View, { style: cellStyle, children: child }) : null
326
+ ) });
327
+ }
328
+
329
+ // src/button/Button.tsx
330
+ var import_MaterialCommunityIcons = __toESM(require("@expo/vector-icons/MaterialCommunityIcons"));
331
+ var import_react7 = require("react");
332
+ var import_react_native7 = require("react-native");
333
+ var import_react_native8 = require("react-native");
334
+ var import_react_native9 = require("react-native");
335
+ var import_core5 = require("@onlynative/core");
336
+
337
+ // src/button/styles.ts
338
+ var import_react_native6 = require("react-native");
339
+
340
+ // src/utils/color.ts
341
+ function parseHexColor(color) {
342
+ const normalized = color.replace("#", "");
343
+ if (normalized.length !== 6 && normalized.length !== 8) {
344
+ return null;
345
+ }
346
+ const r = Number.parseInt(normalized.slice(0, 2), 16);
347
+ const g = Number.parseInt(normalized.slice(2, 4), 16);
348
+ const b = Number.parseInt(normalized.slice(4, 6), 16);
349
+ if (Number.isNaN(r) || Number.isNaN(g) || Number.isNaN(b)) {
350
+ return null;
351
+ }
352
+ return { r, g, b };
353
+ }
354
+ function clampAlpha(alpha) {
355
+ return Math.max(0, Math.min(1, alpha));
356
+ }
357
+ function alphaColor(color, alpha) {
358
+ const channels = parseHexColor(color);
359
+ const boundedAlpha = clampAlpha(alpha);
360
+ if (!channels) {
361
+ return color;
362
+ }
363
+ return `rgba(${channels.r}, ${channels.g}, ${channels.b}, ${boundedAlpha})`;
364
+ }
365
+ function blendColor(base, overlay, overlayAlpha) {
366
+ const baseChannels = parseHexColor(base);
367
+ const overlayChannels = parseHexColor(overlay);
368
+ const boundedAlpha = clampAlpha(overlayAlpha);
369
+ if (!baseChannels || !overlayChannels) {
370
+ return alphaColor(overlay, boundedAlpha);
371
+ }
372
+ const r = Math.round(
373
+ (1 - boundedAlpha) * baseChannels.r + boundedAlpha * overlayChannels.r
374
+ );
375
+ const g = Math.round(
376
+ (1 - boundedAlpha) * baseChannels.g + boundedAlpha * overlayChannels.g
377
+ );
378
+ const b = Math.round(
379
+ (1 - boundedAlpha) * baseChannels.b + boundedAlpha * overlayChannels.b
380
+ );
381
+ return `rgb(${r}, ${g}, ${b})`;
382
+ }
383
+
384
+ // src/utils/elevation.ts
385
+ var import_react_native5 = require("react-native");
386
+ function elevationStyle(level) {
387
+ if (import_react_native5.Platform.OS === "web") {
388
+ const { shadowOffset, shadowOpacity, shadowRadius } = level;
389
+ if (shadowOpacity === 0) {
390
+ return { boxShadow: "none" };
391
+ }
392
+ return {
393
+ boxShadow: `${shadowOffset.width}px ${shadowOffset.height}px ${shadowRadius}px rgba(0, 0, 0, ${shadowOpacity})`
394
+ };
395
+ }
396
+ return {
397
+ shadowColor: level.shadowColor,
398
+ shadowOffset: {
399
+ width: level.shadowOffset.width,
400
+ height: level.shadowOffset.height
401
+ },
402
+ shadowOpacity: level.shadowOpacity,
403
+ shadowRadius: level.shadowRadius,
404
+ elevation: level.elevation
405
+ };
406
+ }
407
+
408
+ // src/button/styles.ts
409
+ function getVariantColors(theme, variant) {
410
+ const disabledContainerColor = alphaColor(theme.colors.onSurface, 0.12);
411
+ const disabledLabelColor = alphaColor(theme.colors.onSurface, 0.38);
412
+ const disabledOutlineColor = alphaColor(theme.colors.onSurface, 0.12);
413
+ if (variant === "outlined") {
414
+ return {
415
+ backgroundColor: "transparent",
416
+ textColor: theme.colors.primary,
417
+ borderColor: theme.colors.outline,
418
+ borderWidth: 1,
419
+ hoveredBackgroundColor: alphaColor(
420
+ theme.colors.primary,
421
+ theme.stateLayer.hoveredOpacity
422
+ ),
423
+ pressedBackgroundColor: alphaColor(
424
+ theme.colors.primary,
425
+ theme.stateLayer.pressedOpacity
426
+ ),
427
+ disabledBackgroundColor: "transparent",
428
+ disabledTextColor: disabledLabelColor,
429
+ disabledBorderColor: disabledOutlineColor
430
+ };
431
+ }
432
+ if (variant === "text") {
433
+ return {
434
+ backgroundColor: "transparent",
435
+ textColor: theme.colors.primary,
436
+ borderColor: "transparent",
437
+ borderWidth: 0,
438
+ hoveredBackgroundColor: alphaColor(
439
+ theme.colors.primary,
440
+ theme.stateLayer.hoveredOpacity
441
+ ),
442
+ pressedBackgroundColor: alphaColor(
443
+ theme.colors.primary,
444
+ theme.stateLayer.pressedOpacity
445
+ ),
446
+ disabledBackgroundColor: "transparent",
447
+ disabledTextColor: disabledLabelColor,
448
+ disabledBorderColor: "transparent"
449
+ };
450
+ }
451
+ if (variant === "elevated") {
452
+ return {
453
+ backgroundColor: theme.colors.surfaceContainerLow,
454
+ textColor: theme.colors.primary,
455
+ borderColor: theme.colors.surfaceContainerLow,
456
+ borderWidth: 0,
457
+ hoveredBackgroundColor: blendColor(
458
+ theme.colors.surfaceContainerLow,
459
+ theme.colors.primary,
460
+ theme.stateLayer.hoveredOpacity
461
+ ),
462
+ pressedBackgroundColor: blendColor(
463
+ theme.colors.surfaceContainerLow,
464
+ theme.colors.primary,
465
+ theme.stateLayer.pressedOpacity
466
+ ),
467
+ disabledBackgroundColor: disabledContainerColor,
468
+ disabledTextColor: disabledLabelColor,
469
+ disabledBorderColor: disabledContainerColor
470
+ };
471
+ }
472
+ if (variant === "tonal") {
473
+ return {
474
+ backgroundColor: theme.colors.secondaryContainer,
475
+ textColor: theme.colors.onSecondaryContainer,
476
+ borderColor: theme.colors.secondaryContainer,
477
+ borderWidth: 0,
478
+ hoveredBackgroundColor: blendColor(
479
+ theme.colors.secondaryContainer,
480
+ theme.colors.onSecondaryContainer,
481
+ theme.stateLayer.hoveredOpacity
482
+ ),
483
+ pressedBackgroundColor: blendColor(
484
+ theme.colors.secondaryContainer,
485
+ theme.colors.onSecondaryContainer,
486
+ theme.stateLayer.pressedOpacity
487
+ ),
488
+ disabledBackgroundColor: disabledContainerColor,
489
+ disabledTextColor: disabledLabelColor,
490
+ disabledBorderColor: disabledContainerColor
491
+ };
492
+ }
493
+ return {
494
+ backgroundColor: theme.colors.primary,
495
+ textColor: theme.colors.onPrimary,
496
+ borderColor: theme.colors.primary,
497
+ borderWidth: 0,
498
+ hoveredBackgroundColor: blendColor(
499
+ theme.colors.primary,
500
+ theme.colors.onPrimary,
501
+ theme.stateLayer.hoveredOpacity
502
+ ),
503
+ pressedBackgroundColor: blendColor(
504
+ theme.colors.primary,
505
+ theme.colors.onPrimary,
506
+ theme.stateLayer.pressedOpacity
507
+ ),
508
+ disabledBackgroundColor: disabledContainerColor,
509
+ disabledTextColor: disabledLabelColor,
510
+ disabledBorderColor: disabledContainerColor
511
+ };
512
+ }
513
+ function getHorizontalPadding(theme, variant, hasLeadingIcon, hasTrailingIcon) {
514
+ if (variant === "text") {
515
+ return {
516
+ paddingStart: hasLeadingIcon ? 12 : hasTrailingIcon ? theme.spacing.md : 12,
517
+ paddingEnd: hasTrailingIcon ? 12 : hasLeadingIcon ? theme.spacing.md : 12
518
+ };
519
+ }
520
+ return {
521
+ paddingStart: hasLeadingIcon ? theme.spacing.md : theme.spacing.lg,
522
+ paddingEnd: hasTrailingIcon ? theme.spacing.md : theme.spacing.lg
523
+ };
524
+ }
525
+ function applyColorOverrides(theme, colors, containerColor, contentColor) {
526
+ if (!containerColor && !contentColor) return colors;
527
+ const result = { ...colors };
528
+ if (contentColor) {
529
+ result.textColor = contentColor;
530
+ }
531
+ if (containerColor) {
532
+ const overlay = contentColor != null ? contentColor : colors.textColor;
533
+ result.backgroundColor = containerColor;
534
+ result.borderColor = containerColor;
535
+ result.hoveredBackgroundColor = blendColor(
536
+ containerColor,
537
+ overlay,
538
+ theme.stateLayer.hoveredOpacity
539
+ );
540
+ result.pressedBackgroundColor = blendColor(
541
+ containerColor,
542
+ overlay,
543
+ theme.stateLayer.pressedOpacity
544
+ );
545
+ } else if (contentColor) {
546
+ if (colors.backgroundColor === "transparent") {
547
+ result.hoveredBackgroundColor = alphaColor(
548
+ contentColor,
549
+ theme.stateLayer.hoveredOpacity
550
+ );
551
+ result.pressedBackgroundColor = alphaColor(
552
+ contentColor,
553
+ theme.stateLayer.pressedOpacity
554
+ );
555
+ } else {
556
+ result.hoveredBackgroundColor = blendColor(
557
+ colors.backgroundColor,
558
+ contentColor,
559
+ theme.stateLayer.hoveredOpacity
560
+ );
561
+ result.pressedBackgroundColor = blendColor(
562
+ colors.backgroundColor,
563
+ contentColor,
564
+ theme.stateLayer.pressedOpacity
565
+ );
566
+ }
567
+ }
568
+ return result;
569
+ }
570
+ function createStyles(theme, variant, hasLeadingIcon, hasTrailingIcon, containerColor, contentColor) {
571
+ const baseColors = getVariantColors(theme, variant);
572
+ const colors = applyColorOverrides(
573
+ theme,
574
+ baseColors,
575
+ containerColor,
576
+ contentColor
577
+ );
578
+ const labelStyle = theme.typography.labelLarge;
579
+ const padding = getHorizontalPadding(
580
+ theme,
581
+ variant,
582
+ hasLeadingIcon,
583
+ hasTrailingIcon
584
+ );
585
+ const elevationLevel0 = elevationStyle(theme.elevation.level0);
586
+ const elevationLevel1 = elevationStyle(theme.elevation.level1);
587
+ const elevationLevel2 = elevationStyle(theme.elevation.level2);
588
+ const baseElevation = variant === "elevated" ? elevationLevel1 : elevationLevel0;
589
+ return import_react_native6.StyleSheet.create({
590
+ container: {
591
+ alignSelf: "flex-start",
592
+ alignItems: "center",
593
+ flexDirection: "row",
594
+ justifyContent: "center",
595
+ minWidth: 58,
596
+ minHeight: 40,
597
+ paddingStart: padding.paddingStart,
598
+ paddingEnd: padding.paddingEnd,
599
+ paddingVertical: 10,
600
+ borderRadius: theme.shape.cornerFull,
601
+ backgroundColor: colors.backgroundColor,
602
+ borderColor: colors.borderColor,
603
+ borderWidth: colors.borderWidth,
604
+ cursor: "pointer",
605
+ ...baseElevation
606
+ },
607
+ hoveredContainer: {
608
+ backgroundColor: colors.hoveredBackgroundColor,
609
+ ...variant === "elevated" ? elevationLevel2 : void 0
610
+ },
611
+ pressedContainer: {
612
+ backgroundColor: colors.pressedBackgroundColor
613
+ },
614
+ disabledContainer: {
615
+ backgroundColor: colors.disabledBackgroundColor,
616
+ borderColor: colors.disabledBorderColor,
617
+ cursor: "auto",
618
+ ...elevationLevel0
619
+ },
620
+ label: {
621
+ fontFamily: labelStyle.fontFamily,
622
+ fontSize: labelStyle.fontSize,
623
+ lineHeight: labelStyle.lineHeight,
624
+ fontWeight: labelStyle.fontWeight,
625
+ letterSpacing: labelStyle.letterSpacing,
626
+ color: colors.textColor
627
+ },
628
+ leadingIcon: {
629
+ marginEnd: theme.spacing.sm
630
+ },
631
+ trailingIcon: {
632
+ marginStart: theme.spacing.sm
633
+ },
634
+ disabledLabel: {
635
+ color: colors.disabledTextColor
636
+ }
637
+ });
638
+ }
639
+
640
+ // src/button/Button.tsx
641
+ var import_jsx_runtime7 = require("react/jsx-runtime");
642
+ function resolveStyle(containerStyle, hoveredContainerStyle, pressedContainerStyle, disabledContainerStyle, disabled, style) {
643
+ if (typeof style === "function") {
644
+ return (state) => [
645
+ containerStyle,
646
+ state.hovered && !state.pressed && !disabled ? hoveredContainerStyle : void 0,
647
+ state.pressed && !disabled ? pressedContainerStyle : void 0,
648
+ disabled ? disabledContainerStyle : void 0,
649
+ style(state)
650
+ ];
651
+ }
652
+ return (state) => [
653
+ containerStyle,
654
+ state.hovered && !state.pressed && !disabled ? hoveredContainerStyle : void 0,
655
+ state.pressed && !disabled ? pressedContainerStyle : void 0,
656
+ disabled ? disabledContainerStyle : void 0,
657
+ style
658
+ ];
659
+ }
660
+ function Button({
661
+ children,
662
+ style,
663
+ variant = "filled",
664
+ leadingIcon,
665
+ trailingIcon,
666
+ iconSize = 18,
667
+ containerColor,
668
+ contentColor,
669
+ labelStyle: labelStyleOverride,
670
+ disabled = false,
671
+ ...props
672
+ }) {
673
+ const isDisabled = Boolean(disabled);
674
+ const hasLeading = Boolean(leadingIcon);
675
+ const hasTrailing = Boolean(trailingIcon);
676
+ const theme = (0, import_core5.useTheme)();
677
+ const styles2 = (0, import_react7.useMemo)(
678
+ () => createStyles(
679
+ theme,
680
+ variant,
681
+ hasLeading,
682
+ hasTrailing,
683
+ containerColor,
684
+ contentColor
685
+ ),
686
+ [theme, variant, hasLeading, hasTrailing, containerColor, contentColor]
687
+ );
688
+ const resolvedIconColor = (0, import_react7.useMemo)(() => {
689
+ const base = import_react_native8.StyleSheet.flatten([
690
+ styles2.label,
691
+ isDisabled ? styles2.disabledLabel : void 0
692
+ ]);
693
+ return typeof (base == null ? void 0 : base.color) === "string" ? base.color : void 0;
694
+ }, [styles2.label, styles2.disabledLabel, isDisabled]);
695
+ const computedLabelStyle = (0, import_react7.useMemo)(
696
+ () => [
697
+ styles2.label,
698
+ isDisabled ? styles2.disabledLabel : void 0,
699
+ labelStyleOverride
700
+ ],
701
+ [isDisabled, styles2.disabledLabel, styles2.label, labelStyleOverride]
702
+ );
703
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
704
+ import_react_native7.Pressable,
705
+ {
706
+ ...props,
707
+ accessibilityRole: "button",
708
+ accessibilityState: { disabled: isDisabled },
709
+ hitSlop: import_react_native7.Platform.OS === "web" ? void 0 : 4,
710
+ disabled: isDisabled,
711
+ style: resolveStyle(
712
+ styles2.container,
713
+ styles2.hoveredContainer,
714
+ styles2.pressedContainer,
715
+ styles2.disabledContainer,
716
+ isDisabled,
717
+ style
718
+ ),
719
+ children: [
720
+ leadingIcon ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
721
+ import_MaterialCommunityIcons.default,
722
+ {
723
+ name: leadingIcon,
724
+ size: iconSize,
725
+ color: resolvedIconColor,
726
+ style: styles2.leadingIcon
727
+ }
728
+ ) : null,
729
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native9.Text, { style: computedLabelStyle, children }),
730
+ trailingIcon ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
731
+ import_MaterialCommunityIcons.default,
732
+ {
733
+ name: trailingIcon,
734
+ size: iconSize,
735
+ color: resolvedIconColor,
736
+ style: styles2.trailingIcon
737
+ }
738
+ ) : null
739
+ ]
740
+ }
741
+ );
742
+ }
743
+
744
+ // src/icon-button/IconButton.tsx
745
+ var import_MaterialCommunityIcons2 = __toESM(require("@expo/vector-icons/MaterialCommunityIcons"));
746
+ var import_react8 = require("react");
747
+ var import_react_native11 = require("react-native");
748
+ var import_core6 = require("@onlynative/core");
749
+
750
+ // src/icon-button/styles.ts
751
+ var import_react_native10 = require("react-native");
752
+ function createStyles2(theme) {
753
+ const disabledContainerColor = alphaColor(theme.colors.onSurface, 0.12);
754
+ const disabledOutlineColor = alphaColor(theme.colors.onSurface, 0.12);
755
+ const toggleUnselectedContainerColor = theme.colors.surfaceContainerHighest;
756
+ return import_react_native10.StyleSheet.create({
757
+ container: {
758
+ borderRadius: theme.shape.cornerFull,
759
+ alignItems: "center",
760
+ justifyContent: "center",
761
+ cursor: "pointer"
762
+ },
763
+ sizeSmall: {
764
+ width: 32,
765
+ height: 32
766
+ },
767
+ sizeMedium: {
768
+ width: 40,
769
+ height: 40
770
+ },
771
+ sizeLarge: {
772
+ width: 48,
773
+ height: 48
774
+ },
775
+ colorFilled: {
776
+ backgroundColor: theme.colors.primary,
777
+ borderColor: theme.colors.primary,
778
+ borderWidth: 0
779
+ },
780
+ colorFilledToggleUnselected: {
781
+ backgroundColor: toggleUnselectedContainerColor,
782
+ borderColor: toggleUnselectedContainerColor,
783
+ borderWidth: 0
784
+ },
785
+ colorFilledToggleSelected: {
786
+ backgroundColor: theme.colors.primary,
787
+ borderColor: theme.colors.primary,
788
+ borderWidth: 0
789
+ },
790
+ colorTonal: {
791
+ backgroundColor: theme.colors.secondaryContainer,
792
+ borderColor: theme.colors.secondaryContainer,
793
+ borderWidth: 0
794
+ },
795
+ colorTonalToggleUnselected: {
796
+ backgroundColor: toggleUnselectedContainerColor,
797
+ borderColor: toggleUnselectedContainerColor,
798
+ borderWidth: 0
799
+ },
800
+ colorTonalToggleSelected: {
801
+ backgroundColor: theme.colors.secondaryContainer,
802
+ borderColor: theme.colors.secondaryContainer,
803
+ borderWidth: 0
804
+ },
805
+ colorOutlined: {
806
+ borderColor: theme.colors.outline,
807
+ borderWidth: 1
808
+ },
809
+ colorOutlinedToggleSelected: {
810
+ backgroundColor: theme.colors.inverseSurface,
811
+ borderColor: theme.colors.inverseSurface,
812
+ borderWidth: 0
813
+ },
814
+ colorStandard: {
815
+ borderWidth: 0
816
+ },
817
+ colorStandardToggleSelected: {
818
+ borderWidth: 0
819
+ },
820
+ // Hover states (M3: 8% state layer)
821
+ hoveredFilled: {
822
+ backgroundColor: blendColor(
823
+ theme.colors.primary,
824
+ theme.colors.onPrimary,
825
+ theme.stateLayer.hoveredOpacity
826
+ )
827
+ },
828
+ hoveredFilledToggleUnselected: {
829
+ backgroundColor: blendColor(
830
+ toggleUnselectedContainerColor,
831
+ theme.colors.primary,
832
+ theme.stateLayer.hoveredOpacity
833
+ )
834
+ },
835
+ hoveredFilledToggleSelected: {
836
+ backgroundColor: blendColor(
837
+ theme.colors.primary,
838
+ theme.colors.onPrimary,
839
+ theme.stateLayer.hoveredOpacity
840
+ )
841
+ },
842
+ hoveredTonal: {
843
+ backgroundColor: blendColor(
844
+ theme.colors.secondaryContainer,
845
+ theme.colors.onSecondaryContainer,
846
+ theme.stateLayer.hoveredOpacity
847
+ )
848
+ },
849
+ hoveredTonalToggleUnselected: {
850
+ backgroundColor: blendColor(
851
+ toggleUnselectedContainerColor,
852
+ theme.colors.onSurfaceVariant,
853
+ theme.stateLayer.hoveredOpacity
854
+ )
855
+ },
856
+ hoveredTonalToggleSelected: {
857
+ backgroundColor: blendColor(
858
+ theme.colors.secondaryContainer,
859
+ theme.colors.onSecondaryContainer,
860
+ theme.stateLayer.hoveredOpacity
861
+ )
862
+ },
863
+ hoveredOutlined: {
864
+ backgroundColor: alphaColor(
865
+ theme.colors.onSurfaceVariant,
866
+ theme.stateLayer.hoveredOpacity
867
+ )
868
+ },
869
+ hoveredOutlinedToggleUnselected: {
870
+ backgroundColor: alphaColor(
871
+ theme.colors.onSurfaceVariant,
872
+ theme.stateLayer.hoveredOpacity
873
+ )
874
+ },
875
+ hoveredOutlinedToggleSelected: {
876
+ backgroundColor: blendColor(
877
+ theme.colors.inverseSurface,
878
+ theme.colors.inverseOnSurface,
879
+ theme.stateLayer.hoveredOpacity
880
+ )
881
+ },
882
+ hoveredStandard: {
883
+ backgroundColor: alphaColor(
884
+ theme.colors.onSurfaceVariant,
885
+ theme.stateLayer.hoveredOpacity
886
+ )
887
+ },
888
+ hoveredStandardToggleUnselected: {
889
+ backgroundColor: alphaColor(
890
+ theme.colors.onSurfaceVariant,
891
+ theme.stateLayer.hoveredOpacity
892
+ )
893
+ },
894
+ hoveredStandardToggleSelected: {
895
+ backgroundColor: alphaColor(
896
+ theme.colors.primary,
897
+ theme.stateLayer.hoveredOpacity
898
+ )
899
+ },
900
+ // Pressed states (M3: 12% state layer)
901
+ pressedFilled: {
902
+ backgroundColor: blendColor(
903
+ theme.colors.primary,
904
+ theme.colors.onPrimary,
905
+ theme.stateLayer.pressedOpacity
906
+ )
907
+ },
908
+ pressedFilledToggleUnselected: {
909
+ backgroundColor: blendColor(
910
+ toggleUnselectedContainerColor,
911
+ theme.colors.primary,
912
+ theme.stateLayer.pressedOpacity
913
+ )
914
+ },
915
+ pressedFilledToggleSelected: {
916
+ backgroundColor: blendColor(
917
+ theme.colors.primary,
918
+ theme.colors.onPrimary,
919
+ theme.stateLayer.pressedOpacity
920
+ )
921
+ },
922
+ pressedTonal: {
923
+ backgroundColor: blendColor(
924
+ theme.colors.secondaryContainer,
925
+ theme.colors.onSecondaryContainer,
926
+ theme.stateLayer.pressedOpacity
927
+ )
928
+ },
929
+ pressedTonalToggleUnselected: {
930
+ backgroundColor: blendColor(
931
+ toggleUnselectedContainerColor,
932
+ theme.colors.onSurfaceVariant,
933
+ theme.stateLayer.pressedOpacity
934
+ )
935
+ },
936
+ pressedTonalToggleSelected: {
937
+ backgroundColor: blendColor(
938
+ theme.colors.secondaryContainer,
939
+ theme.colors.onSecondaryContainer,
940
+ theme.stateLayer.pressedOpacity
941
+ )
942
+ },
943
+ pressedOutlined: {
944
+ backgroundColor: alphaColor(
945
+ theme.colors.onSurfaceVariant,
946
+ theme.stateLayer.pressedOpacity
947
+ )
948
+ },
949
+ pressedOutlinedToggleUnselected: {
950
+ backgroundColor: alphaColor(
951
+ theme.colors.onSurfaceVariant,
952
+ theme.stateLayer.pressedOpacity
953
+ )
954
+ },
955
+ pressedOutlinedToggleSelected: {
956
+ backgroundColor: blendColor(
957
+ theme.colors.inverseSurface,
958
+ theme.colors.inverseOnSurface,
959
+ theme.stateLayer.pressedOpacity
960
+ )
961
+ },
962
+ pressedStandard: {
963
+ backgroundColor: alphaColor(
964
+ theme.colors.onSurfaceVariant,
965
+ theme.stateLayer.pressedOpacity
966
+ )
967
+ },
968
+ pressedStandardToggleUnselected: {
969
+ backgroundColor: alphaColor(
970
+ theme.colors.onSurfaceVariant,
971
+ theme.stateLayer.pressedOpacity
972
+ )
973
+ },
974
+ pressedStandardToggleSelected: {
975
+ backgroundColor: alphaColor(
976
+ theme.colors.primary,
977
+ theme.stateLayer.pressedOpacity
978
+ )
979
+ },
980
+ // Disabled states
981
+ disabledFilled: {
982
+ backgroundColor: disabledContainerColor,
983
+ borderColor: disabledContainerColor,
984
+ cursor: "auto"
985
+ },
986
+ disabledTonal: {
987
+ backgroundColor: disabledContainerColor,
988
+ borderColor: disabledContainerColor,
989
+ cursor: "auto"
990
+ },
991
+ disabledOutlined: {
992
+ backgroundColor: "transparent",
993
+ borderColor: disabledOutlineColor,
994
+ cursor: "auto"
995
+ },
996
+ disabledStandard: {
997
+ backgroundColor: "transparent",
998
+ borderColor: "transparent",
999
+ cursor: "auto"
1000
+ }
1001
+ });
1002
+ }
1003
+
1004
+ // src/icon-button/IconButton.tsx
1005
+ var import_jsx_runtime8 = require("react/jsx-runtime");
1006
+ function getIconColor(variant, theme, disabled, isToggle, selected) {
1007
+ if (disabled) {
1008
+ return alphaColor(theme.colors.onSurface, 0.38);
1009
+ }
1010
+ if (isToggle) {
1011
+ if (variant === "filled") {
1012
+ return selected ? theme.colors.onPrimary : theme.colors.primary;
1013
+ }
1014
+ if (variant === "tonal") {
1015
+ return selected ? theme.colors.onSecondaryContainer : theme.colors.onSurfaceVariant;
1016
+ }
1017
+ if (variant === "outlined") {
1018
+ return selected ? theme.colors.inverseOnSurface : theme.colors.onSurfaceVariant;
1019
+ }
1020
+ return selected ? theme.colors.primary : theme.colors.onSurfaceVariant;
1021
+ }
1022
+ if (variant === "filled") {
1023
+ return theme.colors.onPrimary;
1024
+ }
1025
+ if (variant === "tonal") {
1026
+ return theme.colors.onSecondaryContainer;
1027
+ }
1028
+ return theme.colors.onSurfaceVariant;
1029
+ }
1030
+ function getColorStyle(styles2, variant, isToggle, selected) {
1031
+ if (isToggle) {
1032
+ if (variant === "tonal") {
1033
+ return selected ? styles2.colorTonalToggleSelected : styles2.colorTonalToggleUnselected;
1034
+ }
1035
+ if (variant === "outlined") {
1036
+ return selected ? styles2.colorOutlinedToggleSelected : styles2.colorOutlined;
1037
+ }
1038
+ if (variant === "standard") {
1039
+ return selected ? styles2.colorStandardToggleSelected : styles2.colorStandard;
1040
+ }
1041
+ return selected ? styles2.colorFilledToggleSelected : styles2.colorFilledToggleUnselected;
1042
+ }
1043
+ if (variant === "tonal") {
1044
+ return styles2.colorTonal;
1045
+ }
1046
+ if (variant === "outlined") {
1047
+ return styles2.colorOutlined;
1048
+ }
1049
+ if (variant === "standard") {
1050
+ return styles2.colorStandard;
1051
+ }
1052
+ return styles2.colorFilled;
1053
+ }
1054
+ function getSizeStyle(styles2, size) {
1055
+ if (size === "small") {
1056
+ return styles2.sizeSmall;
1057
+ }
1058
+ if (size === "large") {
1059
+ return styles2.sizeLarge;
1060
+ }
1061
+ return styles2.sizeMedium;
1062
+ }
1063
+ function getIconPixelSize(size) {
1064
+ if (size === "small") {
1065
+ return 18;
1066
+ }
1067
+ if (size === "large") {
1068
+ return 28;
1069
+ }
1070
+ return 24;
1071
+ }
1072
+ function getDefaultHitSlop(size) {
1073
+ if (size === "small") {
1074
+ return 8;
1075
+ }
1076
+ if (size === "large") {
1077
+ return 0;
1078
+ }
1079
+ return 4;
1080
+ }
1081
+ function getHoveredStyle(styles2, variant, isToggle, selected) {
1082
+ if (isToggle) {
1083
+ if (variant === "tonal") {
1084
+ return selected ? styles2.hoveredTonalToggleSelected : styles2.hoveredTonalToggleUnselected;
1085
+ }
1086
+ if (variant === "outlined") {
1087
+ return selected ? styles2.hoveredOutlinedToggleSelected : styles2.hoveredOutlinedToggleUnselected;
1088
+ }
1089
+ if (variant === "standard") {
1090
+ return selected ? styles2.hoveredStandardToggleSelected : styles2.hoveredStandardToggleUnselected;
1091
+ }
1092
+ return selected ? styles2.hoveredFilledToggleSelected : styles2.hoveredFilledToggleUnselected;
1093
+ }
1094
+ if (variant === "tonal") {
1095
+ return styles2.hoveredTonal;
1096
+ }
1097
+ if (variant === "outlined") {
1098
+ return styles2.hoveredOutlined;
1099
+ }
1100
+ if (variant === "standard") {
1101
+ return styles2.hoveredStandard;
1102
+ }
1103
+ return styles2.hoveredFilled;
1104
+ }
1105
+ function getPressedStyle(styles2, variant, isToggle, selected) {
1106
+ if (isToggle) {
1107
+ if (variant === "tonal") {
1108
+ return selected ? styles2.pressedTonalToggleSelected : styles2.pressedTonalToggleUnselected;
1109
+ }
1110
+ if (variant === "outlined") {
1111
+ return selected ? styles2.pressedOutlinedToggleSelected : styles2.pressedOutlinedToggleUnselected;
1112
+ }
1113
+ if (variant === "standard") {
1114
+ return selected ? styles2.pressedStandardToggleSelected : styles2.pressedStandardToggleUnselected;
1115
+ }
1116
+ return selected ? styles2.pressedFilledToggleSelected : styles2.pressedFilledToggleUnselected;
1117
+ }
1118
+ if (variant === "tonal") {
1119
+ return styles2.pressedTonal;
1120
+ }
1121
+ if (variant === "outlined") {
1122
+ return styles2.pressedOutlined;
1123
+ }
1124
+ if (variant === "standard") {
1125
+ return styles2.pressedStandard;
1126
+ }
1127
+ return styles2.pressedFilled;
1128
+ }
1129
+ function getDisabledStyle(styles2, variant) {
1130
+ if (variant === "tonal") {
1131
+ return styles2.disabledTonal;
1132
+ }
1133
+ if (variant === "outlined") {
1134
+ return styles2.disabledOutlined;
1135
+ }
1136
+ if (variant === "standard") {
1137
+ return styles2.disabledStandard;
1138
+ }
1139
+ return styles2.disabledFilled;
1140
+ }
1141
+ function IconButton({
1142
+ icon,
1143
+ selectedIcon,
1144
+ iconColor,
1145
+ contentColor,
1146
+ containerColor,
1147
+ style,
1148
+ onPress,
1149
+ disabled = false,
1150
+ variant = "filled",
1151
+ selected,
1152
+ size = "medium",
1153
+ hitSlop,
1154
+ accessibilityLabel,
1155
+ ...props
1156
+ }) {
1157
+ var _a;
1158
+ const theme = (0, import_core6.useTheme)();
1159
+ const styles2 = (0, import_react8.useMemo)(() => createStyles2(theme), [theme]);
1160
+ const isDisabled = Boolean(disabled);
1161
+ const isToggle = selected !== void 0;
1162
+ const isSelected = Boolean(selected);
1163
+ const resolvedIconColor = (_a = contentColor != null ? contentColor : iconColor) != null ? _a : getIconColor(variant, theme, isDisabled, isToggle, isSelected);
1164
+ const displayIcon = isToggle && isSelected && selectedIcon ? selectedIcon : icon;
1165
+ const iconPixelSize = getIconPixelSize(size);
1166
+ const accessibilityState = isToggle ? { disabled: isDisabled, selected: isSelected } : { disabled: isDisabled };
1167
+ const containerOverrides = (0, import_react8.useMemo)(() => {
1168
+ if (!containerColor) return null;
1169
+ const overlay = resolvedIconColor;
1170
+ return {
1171
+ base: {
1172
+ backgroundColor: containerColor,
1173
+ borderColor: containerColor,
1174
+ borderWidth: 0
1175
+ },
1176
+ hovered: {
1177
+ backgroundColor: blendColor(
1178
+ containerColor,
1179
+ overlay,
1180
+ theme.stateLayer.hoveredOpacity
1181
+ )
1182
+ },
1183
+ pressed: {
1184
+ backgroundColor: blendColor(
1185
+ containerColor,
1186
+ overlay,
1187
+ theme.stateLayer.pressedOpacity
1188
+ )
1189
+ }
1190
+ };
1191
+ }, [containerColor, resolvedIconColor, theme.stateLayer]);
1192
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1193
+ import_react_native11.Pressable,
1194
+ {
1195
+ ...props,
1196
+ accessibilityRole: "button",
1197
+ accessibilityLabel,
1198
+ accessibilityState,
1199
+ disabled: isDisabled,
1200
+ hitSlop: hitSlop != null ? hitSlop : getDefaultHitSlop(size),
1201
+ onPress,
1202
+ style: ({
1203
+ pressed,
1204
+ hovered
1205
+ }) => {
1206
+ const base = [
1207
+ styles2.container,
1208
+ getSizeStyle(styles2, size),
1209
+ getColorStyle(styles2, variant, isToggle, isSelected),
1210
+ containerOverrides == null ? void 0 : containerOverrides.base,
1211
+ hovered && !pressed && !isDisabled ? containerOverrides ? containerOverrides.hovered : getHoveredStyle(styles2, variant, isToggle, isSelected) : void 0,
1212
+ pressed && !isDisabled ? containerOverrides ? containerOverrides.pressed : getPressedStyle(styles2, variant, isToggle, isSelected) : void 0,
1213
+ isDisabled ? getDisabledStyle(styles2, variant) : void 0
1214
+ ];
1215
+ if (typeof style === "function") {
1216
+ base.push(style({ pressed }));
1217
+ } else if (style) {
1218
+ base.push(style);
1219
+ }
1220
+ return base;
1221
+ },
1222
+ children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1223
+ import_MaterialCommunityIcons2.default,
1224
+ {
1225
+ name: displayIcon,
1226
+ size: iconPixelSize,
1227
+ color: resolvedIconColor
1228
+ }
1229
+ )
1230
+ }
1231
+ );
1232
+ }
1233
+
1234
+ // src/appbar/AppBar.tsx
1235
+ var import_react9 = require("react");
1236
+ var import_react_native14 = require("react-native");
1237
+ var import_react_native_safe_area_context2 = require("react-native-safe-area-context");
1238
+ var import_core8 = require("@onlynative/core");
1239
+
1240
+ // src/utils/rtl.ts
1241
+ var import_react_native12 = require("react-native");
1242
+ function transformOrigin(vertical = "top") {
1243
+ return import_react_native12.I18nManager.isRTL ? `right ${vertical}` : `left ${vertical}`;
1244
+ }
1245
+ function selectRTL(ltr, rtl) {
1246
+ return import_react_native12.I18nManager.isRTL ? rtl : ltr;
1247
+ }
1248
+
1249
+ // src/appbar/styles.ts
1250
+ var import_react_native13 = require("react-native");
1251
+ var import_core7 = require("@onlynative/core");
1252
+ function createStyles3(theme) {
1253
+ var _a;
1254
+ const topAppBar = (_a = theme.topAppBar) != null ? _a : import_core7.defaultTopAppBarTokens;
1255
+ return import_react_native13.StyleSheet.create({
1256
+ root: {
1257
+ backgroundColor: theme.colors.surface
1258
+ },
1259
+ safeArea: {
1260
+ backgroundColor: theme.colors.surface
1261
+ },
1262
+ elevatedRoot: {
1263
+ backgroundColor: theme.colors.surfaceContainer
1264
+ },
1265
+ elevatedSafeArea: {
1266
+ backgroundColor: theme.colors.surfaceContainer
1267
+ },
1268
+ smallContainer: {
1269
+ height: topAppBar.smallContainerHeight,
1270
+ position: "relative"
1271
+ },
1272
+ mediumContainer: {
1273
+ height: topAppBar.mediumContainerHeight
1274
+ },
1275
+ largeContainer: {
1276
+ height: topAppBar.largeContainerHeight
1277
+ },
1278
+ expandedContainer: {
1279
+ position: "relative"
1280
+ },
1281
+ topRow: {
1282
+ height: topAppBar.topRowHeight,
1283
+ paddingHorizontal: topAppBar.horizontalPadding,
1284
+ flexDirection: "row",
1285
+ alignItems: "center"
1286
+ },
1287
+ expandedTitleContainer: {
1288
+ flex: 1,
1289
+ justifyContent: "flex-end",
1290
+ minWidth: 0,
1291
+ paddingEnd: theme.spacing.md,
1292
+ pointerEvents: "none"
1293
+ },
1294
+ topRowSpacer: {
1295
+ flex: 1
1296
+ },
1297
+ sideSlot: {
1298
+ flexDirection: "row",
1299
+ alignItems: "center",
1300
+ minHeight: topAppBar.sideSlotMinHeight
1301
+ },
1302
+ actionsRow: {
1303
+ flexDirection: "row",
1304
+ alignItems: "center"
1305
+ },
1306
+ iconFrame: {
1307
+ width: topAppBar.iconFrameSize,
1308
+ height: topAppBar.iconFrameSize,
1309
+ alignItems: "center",
1310
+ justifyContent: "center"
1311
+ },
1312
+ overlayTitleContainer: {
1313
+ position: "absolute",
1314
+ top: 0,
1315
+ bottom: 0,
1316
+ justifyContent: "center",
1317
+ minWidth: 0,
1318
+ pointerEvents: "none"
1319
+ },
1320
+ centeredTitle: {
1321
+ textAlign: "center"
1322
+ },
1323
+ startAlignedTitle: {
1324
+ textAlign: "auto"
1325
+ },
1326
+ mediumTitlePadding: {
1327
+ paddingBottom: topAppBar.mediumTitleBottomPadding
1328
+ },
1329
+ largeTitlePadding: {
1330
+ paddingBottom: topAppBar.largeTitleBottomPadding
1331
+ },
1332
+ title: {
1333
+ flexShrink: 1,
1334
+ maxWidth: "100%",
1335
+ includeFontPadding: false,
1336
+ textAlignVertical: "center"
1337
+ }
1338
+ });
1339
+ }
1340
+
1341
+ // src/appbar/AppBar.tsx
1342
+ var import_jsx_runtime9 = require("react/jsx-runtime");
1343
+ function getBackIcon() {
1344
+ if (import_react_native14.Platform.OS === "ios") {
1345
+ return selectRTL("chevron-left", "chevron-right");
1346
+ }
1347
+ return selectRTL("arrow-left", "arrow-right");
1348
+ }
1349
+ var titleVariantBySize = {
1350
+ small: "titleLarge",
1351
+ medium: "headlineSmall",
1352
+ large: "headlineMedium"
1353
+ };
1354
+ var APP_BAR_TITLE_TEXT_PROPS = {
1355
+ numberOfLines: 1,
1356
+ ellipsizeMode: "tail",
1357
+ accessibilityRole: "header"
1358
+ };
1359
+ function resolveSize(variant) {
1360
+ if (variant === "medium" || variant === "large") {
1361
+ return variant;
1362
+ }
1363
+ return "small";
1364
+ }
1365
+ function getSizeStyle2(styles2, size) {
1366
+ if (size === "large") {
1367
+ return styles2.largeContainer;
1368
+ }
1369
+ return styles2.mediumContainer;
1370
+ }
1371
+ function withTopInset(enabled, content, style) {
1372
+ if (enabled) {
1373
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native_safe_area_context2.SafeAreaView, { edges: ["top"], style, children: content });
1374
+ }
1375
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native14.View, { style, children: content });
1376
+ }
1377
+ function measureWidth(event) {
1378
+ return Math.round(event.nativeEvent.layout.width);
1379
+ }
1380
+ function AppBar({
1381
+ title,
1382
+ variant = "small",
1383
+ canGoBack = false,
1384
+ onBackPress,
1385
+ insetTop = false,
1386
+ elevated = false,
1387
+ leading,
1388
+ trailing,
1389
+ actions,
1390
+ containerColor,
1391
+ contentColor,
1392
+ titleStyle,
1393
+ style
1394
+ }) {
1395
+ var _a;
1396
+ const theme = (0, import_core8.useTheme)();
1397
+ const topAppBar = (_a = theme.topAppBar) != null ? _a : import_core8.defaultTopAppBarTokens;
1398
+ const styles2 = (0, import_react9.useMemo)(() => createStyles3(theme), [theme]);
1399
+ const [leadingWidth, setLeadingWidth] = (0, import_react9.useState)(0);
1400
+ const [actionsWidth, setActionsWidth] = (0, import_react9.useState)(0);
1401
+ const titleColorStyle = (0, import_react9.useMemo)(
1402
+ () => ({ color: contentColor != null ? contentColor : theme.colors.onSurface }),
1403
+ [contentColor, theme.colors.onSurface]
1404
+ );
1405
+ const size = resolveSize(variant);
1406
+ const titleVariant = titleVariantBySize[size];
1407
+ const isCenterAligned = variant === "center-aligned";
1408
+ const isExpanded = size !== "small";
1409
+ const titleStartInset = topAppBar.horizontalPadding + Math.max(topAppBar.titleStartInset, leadingWidth);
1410
+ const compactTitleEndInset = topAppBar.horizontalPadding + actionsWidth;
1411
+ const centeredSideInset = topAppBar.horizontalPadding + Math.max(leadingWidth, actionsWidth);
1412
+ const expandedTitleInsetStyle = (0, import_react9.useMemo)(
1413
+ () => ({ paddingStart: titleStartInset }),
1414
+ [titleStartInset]
1415
+ );
1416
+ const overlayTitleInsetStyle = (0, import_react9.useMemo)(
1417
+ () => isCenterAligned ? { start: centeredSideInset, end: centeredSideInset } : { start: titleStartInset, end: compactTitleEndInset },
1418
+ [centeredSideInset, compactTitleEndInset, isCenterAligned, titleStartInset]
1419
+ );
1420
+ const leadingContent = (0, import_react9.useMemo)(() => {
1421
+ if (leading) {
1422
+ return leading;
1423
+ }
1424
+ if (!canGoBack) {
1425
+ return null;
1426
+ }
1427
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native14.View, { style: styles2.iconFrame, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1428
+ IconButton,
1429
+ {
1430
+ icon: getBackIcon(),
1431
+ size: "medium",
1432
+ variant: "standard",
1433
+ iconColor: contentColor != null ? contentColor : theme.colors.onSurface,
1434
+ accessibilityLabel: "Go back",
1435
+ onPress: onBackPress
1436
+ }
1437
+ ) });
1438
+ }, [
1439
+ canGoBack,
1440
+ contentColor,
1441
+ leading,
1442
+ onBackPress,
1443
+ styles2.iconFrame,
1444
+ theme.colors.onSurface
1445
+ ]);
1446
+ const actionsContent = (0, import_react9.useMemo)(() => {
1447
+ if (trailing) {
1448
+ return trailing;
1449
+ }
1450
+ if (!actions || actions.length === 0) {
1451
+ return null;
1452
+ }
1453
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native14.View, { style: styles2.actionsRow, children: actions.map((action, index) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1454
+ import_react_native14.View,
1455
+ {
1456
+ style: styles2.iconFrame,
1457
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1458
+ IconButton,
1459
+ {
1460
+ icon: action.icon,
1461
+ size: "medium",
1462
+ variant: "standard",
1463
+ iconColor: contentColor,
1464
+ accessibilityLabel: action.accessibilityLabel,
1465
+ onPress: action.onPress,
1466
+ disabled: action.disabled
1467
+ }
1468
+ )
1469
+ },
1470
+ `${String(action.icon)}-${index}`
1471
+ )) });
1472
+ }, [actions, contentColor, styles2.actionsRow, styles2.iconFrame, trailing]);
1473
+ const onLeadingLayout = (0, import_react9.useCallback)((event) => {
1474
+ const nextWidth = measureWidth(event);
1475
+ setLeadingWidth((currentWidth) => {
1476
+ if (currentWidth === nextWidth) {
1477
+ return currentWidth;
1478
+ }
1479
+ return nextWidth;
1480
+ });
1481
+ }, []);
1482
+ const onActionsLayout = (0, import_react9.useCallback)((event) => {
1483
+ const nextWidth = measureWidth(event);
1484
+ setActionsWidth((currentWidth) => {
1485
+ if (currentWidth === nextWidth) {
1486
+ return currentWidth;
1487
+ }
1488
+ return nextWidth;
1489
+ });
1490
+ }, []);
1491
+ const topRow = /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native14.View, { style: styles2.topRow, children: [
1492
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1493
+ import_react_native14.View,
1494
+ {
1495
+ collapsable: false,
1496
+ onLayout: onLeadingLayout,
1497
+ style: styles2.sideSlot,
1498
+ children: leadingContent
1499
+ }
1500
+ ),
1501
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native14.View, { style: styles2.topRowSpacer }),
1502
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1503
+ import_react_native14.View,
1504
+ {
1505
+ collapsable: false,
1506
+ onLayout: onActionsLayout,
1507
+ style: styles2.sideSlot,
1508
+ children: actionsContent
1509
+ }
1510
+ )
1511
+ ] });
1512
+ const containerOverride = containerColor ? { backgroundColor: containerColor } : void 0;
1513
+ const rootStyle = [
1514
+ styles2.root,
1515
+ elevated ? styles2.elevatedRoot : void 0,
1516
+ containerOverride,
1517
+ style
1518
+ ];
1519
+ const safeAreaStyle = [
1520
+ styles2.safeArea,
1521
+ elevated ? styles2.elevatedSafeArea : void 0,
1522
+ containerOverride
1523
+ ];
1524
+ if (isExpanded) {
1525
+ const content2 = /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native14.View, { style: [styles2.expandedContainer, getSizeStyle2(styles2, size)], children: [
1526
+ topRow,
1527
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1528
+ import_react_native14.View,
1529
+ {
1530
+ style: [
1531
+ styles2.expandedTitleContainer,
1532
+ size === "large" ? styles2.largeTitlePadding : styles2.mediumTitlePadding,
1533
+ expandedTitleInsetStyle
1534
+ ],
1535
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1536
+ Typography,
1537
+ {
1538
+ ...APP_BAR_TITLE_TEXT_PROPS,
1539
+ variant: titleVariant,
1540
+ style: [
1541
+ styles2.title,
1542
+ titleColorStyle,
1543
+ styles2.startAlignedTitle,
1544
+ titleStyle
1545
+ ],
1546
+ children: title
1547
+ }
1548
+ )
1549
+ }
1550
+ )
1551
+ ] });
1552
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native14.View, { style: rootStyle, children: withTopInset(insetTop, content2, safeAreaStyle) });
1553
+ }
1554
+ const content = /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native14.View, { style: styles2.smallContainer, children: [
1555
+ topRow,
1556
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native14.View, { style: [styles2.overlayTitleContainer, overlayTitleInsetStyle], children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1557
+ Typography,
1558
+ {
1559
+ ...APP_BAR_TITLE_TEXT_PROPS,
1560
+ variant: titleVariant,
1561
+ style: [
1562
+ styles2.title,
1563
+ titleColorStyle,
1564
+ isCenterAligned ? styles2.centeredTitle : styles2.startAlignedTitle,
1565
+ titleStyle
1566
+ ],
1567
+ children: title
1568
+ }
1569
+ ) })
1570
+ ] });
1571
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native14.View, { style: rootStyle, children: withTopInset(insetTop, content, safeAreaStyle) });
1572
+ }
1573
+
1574
+ // src/card/Card.tsx
1575
+ var import_react10 = require("react");
1576
+ var import_react_native16 = require("react-native");
1577
+ var import_core9 = require("@onlynative/core");
1578
+
1579
+ // src/card/styles.ts
1580
+ var import_react_native15 = require("react-native");
1581
+ function getVariantColors2(theme, variant) {
1582
+ const disabledContainerColor = alphaColor(theme.colors.onSurface, 0.12);
1583
+ const disabledOutlineColor = alphaColor(theme.colors.onSurface, 0.12);
1584
+ if (variant === "outlined") {
1585
+ return {
1586
+ backgroundColor: theme.colors.surface,
1587
+ borderColor: theme.colors.outline,
1588
+ borderWidth: 1,
1589
+ hoveredBackgroundColor: alphaColor(
1590
+ theme.colors.onSurface,
1591
+ theme.stateLayer.hoveredOpacity
1592
+ ),
1593
+ pressedBackgroundColor: alphaColor(
1594
+ theme.colors.onSurface,
1595
+ theme.stateLayer.pressedOpacity
1596
+ ),
1597
+ disabledBackgroundColor: theme.colors.surface,
1598
+ disabledBorderColor: disabledOutlineColor
1599
+ };
1600
+ }
1601
+ if (variant === "filled") {
1602
+ return {
1603
+ backgroundColor: theme.colors.surfaceContainerHighest,
1604
+ borderColor: "transparent",
1605
+ borderWidth: 0,
1606
+ hoveredBackgroundColor: blendColor(
1607
+ theme.colors.surfaceContainerHighest,
1608
+ theme.colors.onSurface,
1609
+ theme.stateLayer.hoveredOpacity
1610
+ ),
1611
+ pressedBackgroundColor: blendColor(
1612
+ theme.colors.surfaceContainerHighest,
1613
+ theme.colors.onSurface,
1614
+ theme.stateLayer.pressedOpacity
1615
+ ),
1616
+ disabledBackgroundColor: disabledContainerColor,
1617
+ disabledBorderColor: "transparent"
1618
+ };
1619
+ }
1620
+ return {
1621
+ backgroundColor: theme.colors.surface,
1622
+ borderColor: "transparent",
1623
+ borderWidth: 0,
1624
+ hoveredBackgroundColor: blendColor(
1625
+ theme.colors.surface,
1626
+ theme.colors.onSurface,
1627
+ theme.stateLayer.hoveredOpacity
1628
+ ),
1629
+ pressedBackgroundColor: blendColor(
1630
+ theme.colors.surface,
1631
+ theme.colors.onSurface,
1632
+ theme.stateLayer.pressedOpacity
1633
+ ),
1634
+ disabledBackgroundColor: disabledContainerColor,
1635
+ disabledBorderColor: "transparent"
1636
+ };
1637
+ }
1638
+ function applyColorOverrides2(theme, colors, containerColor) {
1639
+ if (!containerColor) return colors;
1640
+ return {
1641
+ ...colors,
1642
+ backgroundColor: containerColor,
1643
+ borderColor: containerColor,
1644
+ borderWidth: 0,
1645
+ hoveredBackgroundColor: blendColor(
1646
+ containerColor,
1647
+ theme.colors.onSurface,
1648
+ theme.stateLayer.hoveredOpacity
1649
+ ),
1650
+ pressedBackgroundColor: blendColor(
1651
+ containerColor,
1652
+ theme.colors.onSurface,
1653
+ theme.stateLayer.pressedOpacity
1654
+ )
1655
+ };
1656
+ }
1657
+ function createStyles4(theme, variant, containerColor) {
1658
+ const baseColors = getVariantColors2(theme, variant);
1659
+ const colors = applyColorOverrides2(theme, baseColors, containerColor);
1660
+ const elevationLevel0 = elevationStyle(theme.elevation.level0);
1661
+ const elevationLevel1 = elevationStyle(theme.elevation.level1);
1662
+ const elevationLevel2 = elevationStyle(theme.elevation.level2);
1663
+ const baseElevation = variant === "elevated" ? elevationLevel1 : elevationLevel0;
1664
+ return import_react_native15.StyleSheet.create({
1665
+ container: {
1666
+ borderRadius: theme.shape.cornerMedium,
1667
+ backgroundColor: colors.backgroundColor,
1668
+ borderColor: colors.borderColor,
1669
+ borderWidth: colors.borderWidth,
1670
+ overflow: "hidden",
1671
+ ...baseElevation
1672
+ },
1673
+ interactiveContainer: {
1674
+ cursor: "pointer"
1675
+ },
1676
+ hoveredContainer: {
1677
+ backgroundColor: colors.hoveredBackgroundColor,
1678
+ ...variant === "elevated" ? elevationLevel2 : variant === "filled" ? elevationLevel1 : void 0
1679
+ },
1680
+ pressedContainer: {
1681
+ backgroundColor: colors.pressedBackgroundColor
1682
+ },
1683
+ disabledContainer: {
1684
+ backgroundColor: colors.disabledBackgroundColor,
1685
+ borderColor: colors.disabledBorderColor,
1686
+ cursor: "auto",
1687
+ ...elevationLevel0
1688
+ },
1689
+ disabledContent: {
1690
+ opacity: theme.stateLayer.disabledOpacity
1691
+ }
1692
+ });
1693
+ }
1694
+
1695
+ // src/card/Card.tsx
1696
+ var import_jsx_runtime10 = require("react/jsx-runtime");
1697
+ function Card({
1698
+ children,
1699
+ style,
1700
+ variant = "elevated",
1701
+ onPress,
1702
+ disabled = false,
1703
+ containerColor,
1704
+ ...props
1705
+ }) {
1706
+ const isDisabled = Boolean(disabled);
1707
+ const isInteractive = onPress !== void 0;
1708
+ const theme = (0, import_core9.useTheme)();
1709
+ const styles2 = (0, import_react10.useMemo)(
1710
+ () => createStyles4(theme, variant, containerColor),
1711
+ [theme, variant, containerColor]
1712
+ );
1713
+ if (!isInteractive) {
1714
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native16.View, { ...props, style: [styles2.container, style], children });
1715
+ }
1716
+ const resolvedStyle = (state) => [
1717
+ styles2.container,
1718
+ styles2.interactiveContainer,
1719
+ state.hovered && !state.pressed && !isDisabled ? styles2.hoveredContainer : void 0,
1720
+ state.pressed && !isDisabled ? styles2.pressedContainer : void 0,
1721
+ isDisabled ? styles2.disabledContainer : void 0,
1722
+ typeof style === "function" ? style(state) : style
1723
+ ];
1724
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1725
+ import_react_native16.Pressable,
1726
+ {
1727
+ ...props,
1728
+ role: "button",
1729
+ accessibilityState: { disabled: isDisabled },
1730
+ hitSlop: import_react_native16.Platform.OS === "web" ? void 0 : 4,
1731
+ disabled: isDisabled,
1732
+ onPress,
1733
+ style: resolvedStyle,
1734
+ children: isDisabled ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native16.View, { style: styles2.disabledContent, children }) : children
1735
+ }
1736
+ );
1737
+ }
1738
+
1739
+ // src/chip/Chip.tsx
1740
+ var import_MaterialCommunityIcons3 = __toESM(require("@expo/vector-icons/MaterialCommunityIcons"));
1741
+ var import_react11 = require("react");
1742
+ var import_react_native18 = require("react-native");
1743
+ var import_core10 = require("@onlynative/core");
1744
+
1745
+ // src/chip/styles.ts
1746
+ var import_react_native17 = require("react-native");
1747
+ function getVariantColors3(theme, variant, elevated, selected) {
1748
+ const disabledContainerColor = alphaColor(theme.colors.onSurface, 0.12);
1749
+ const disabledLabelColor = alphaColor(theme.colors.onSurface, 0.38);
1750
+ const disabledOutlineColor = alphaColor(theme.colors.onSurface, 0.12);
1751
+ if (variant === "filter" && selected) {
1752
+ return {
1753
+ backgroundColor: theme.colors.secondaryContainer,
1754
+ textColor: theme.colors.onSecondaryContainer,
1755
+ borderColor: "transparent",
1756
+ borderWidth: 0,
1757
+ hoveredBackgroundColor: blendColor(
1758
+ theme.colors.secondaryContainer,
1759
+ theme.colors.onSecondaryContainer,
1760
+ theme.stateLayer.hoveredOpacity
1761
+ ),
1762
+ pressedBackgroundColor: blendColor(
1763
+ theme.colors.secondaryContainer,
1764
+ theme.colors.onSecondaryContainer,
1765
+ theme.stateLayer.pressedOpacity
1766
+ ),
1767
+ disabledBackgroundColor: disabledContainerColor,
1768
+ disabledTextColor: disabledLabelColor,
1769
+ disabledBorderColor: "transparent"
1770
+ };
1771
+ }
1772
+ if (elevated && variant !== "input") {
1773
+ const textColor2 = variant === "assist" ? theme.colors.onSurface : theme.colors.onSurfaceVariant;
1774
+ return {
1775
+ backgroundColor: theme.colors.surfaceContainerLow,
1776
+ textColor: textColor2,
1777
+ borderColor: "transparent",
1778
+ borderWidth: 0,
1779
+ hoveredBackgroundColor: blendColor(
1780
+ theme.colors.surfaceContainerLow,
1781
+ textColor2,
1782
+ theme.stateLayer.hoveredOpacity
1783
+ ),
1784
+ pressedBackgroundColor: blendColor(
1785
+ theme.colors.surfaceContainerLow,
1786
+ textColor2,
1787
+ theme.stateLayer.pressedOpacity
1788
+ ),
1789
+ disabledBackgroundColor: disabledContainerColor,
1790
+ disabledTextColor: disabledLabelColor,
1791
+ disabledBorderColor: "transparent"
1792
+ };
1793
+ }
1794
+ const textColor = variant === "assist" ? theme.colors.onSurface : theme.colors.onSurfaceVariant;
1795
+ return {
1796
+ backgroundColor: theme.colors.surface,
1797
+ textColor,
1798
+ borderColor: theme.colors.outline,
1799
+ borderWidth: 1,
1800
+ hoveredBackgroundColor: blendColor(
1801
+ theme.colors.surface,
1802
+ textColor,
1803
+ theme.stateLayer.hoveredOpacity
1804
+ ),
1805
+ pressedBackgroundColor: blendColor(
1806
+ theme.colors.surface,
1807
+ textColor,
1808
+ theme.stateLayer.pressedOpacity
1809
+ ),
1810
+ disabledBackgroundColor: disabledContainerColor,
1811
+ disabledTextColor: disabledLabelColor,
1812
+ disabledBorderColor: disabledOutlineColor
1813
+ };
1814
+ }
1815
+ function applyColorOverrides3(theme, colors, containerColor, contentColor) {
1816
+ if (!containerColor && !contentColor) return colors;
1817
+ const result = { ...colors };
1818
+ if (contentColor) {
1819
+ result.textColor = contentColor;
1820
+ }
1821
+ if (containerColor) {
1822
+ const overlay = contentColor != null ? contentColor : colors.textColor;
1823
+ result.backgroundColor = containerColor;
1824
+ result.borderColor = containerColor;
1825
+ result.hoveredBackgroundColor = blendColor(
1826
+ containerColor,
1827
+ overlay,
1828
+ theme.stateLayer.hoveredOpacity
1829
+ );
1830
+ result.pressedBackgroundColor = blendColor(
1831
+ containerColor,
1832
+ overlay,
1833
+ theme.stateLayer.pressedOpacity
1834
+ );
1835
+ } else if (contentColor) {
1836
+ if (colors.backgroundColor === "transparent") {
1837
+ result.hoveredBackgroundColor = alphaColor(
1838
+ contentColor,
1839
+ theme.stateLayer.hoveredOpacity
1840
+ );
1841
+ result.pressedBackgroundColor = alphaColor(
1842
+ contentColor,
1843
+ theme.stateLayer.pressedOpacity
1844
+ );
1845
+ } else {
1846
+ result.hoveredBackgroundColor = blendColor(
1847
+ colors.backgroundColor,
1848
+ contentColor,
1849
+ theme.stateLayer.hoveredOpacity
1850
+ );
1851
+ result.pressedBackgroundColor = blendColor(
1852
+ colors.backgroundColor,
1853
+ contentColor,
1854
+ theme.stateLayer.pressedOpacity
1855
+ );
1856
+ }
1857
+ }
1858
+ return result;
1859
+ }
1860
+ function createStyles5(theme, variant, elevated, selected, hasLeadingContent, hasTrailingContent, containerColor, contentColor) {
1861
+ const baseColors = getVariantColors3(theme, variant, elevated, selected);
1862
+ const colors = applyColorOverrides3(
1863
+ theme,
1864
+ baseColors,
1865
+ containerColor,
1866
+ contentColor
1867
+ );
1868
+ const labelStyle = theme.typography.labelLarge;
1869
+ const elevationLevel0 = elevationStyle(theme.elevation.level0);
1870
+ const elevationLevel1 = elevationStyle(theme.elevation.level1);
1871
+ const elevationLevel2 = elevationStyle(theme.elevation.level2);
1872
+ const isElevated = elevated && variant !== "input";
1873
+ const baseElevation = isElevated ? elevationLevel1 : elevationLevel0;
1874
+ return import_react_native17.StyleSheet.create({
1875
+ container: {
1876
+ alignSelf: "flex-start",
1877
+ alignItems: "center",
1878
+ flexDirection: "row",
1879
+ height: 32,
1880
+ paddingStart: hasLeadingContent ? 8 : 16,
1881
+ paddingEnd: hasTrailingContent ? 8 : 16,
1882
+ borderRadius: theme.shape.cornerSmall,
1883
+ backgroundColor: colors.backgroundColor,
1884
+ borderColor: colors.borderColor,
1885
+ borderWidth: colors.borderWidth,
1886
+ cursor: "pointer",
1887
+ ...baseElevation
1888
+ },
1889
+ hoveredContainer: {
1890
+ backgroundColor: colors.hoveredBackgroundColor,
1891
+ ...isElevated ? elevationLevel2 : void 0
1892
+ },
1893
+ pressedContainer: {
1894
+ backgroundColor: colors.pressedBackgroundColor
1895
+ },
1896
+ disabledContainer: {
1897
+ backgroundColor: colors.disabledBackgroundColor,
1898
+ borderColor: colors.disabledBorderColor,
1899
+ cursor: "auto",
1900
+ ...elevationLevel0
1901
+ },
1902
+ label: {
1903
+ fontFamily: labelStyle.fontFamily,
1904
+ fontSize: labelStyle.fontSize,
1905
+ lineHeight: labelStyle.lineHeight,
1906
+ fontWeight: labelStyle.fontWeight,
1907
+ letterSpacing: labelStyle.letterSpacing,
1908
+ color: colors.textColor
1909
+ },
1910
+ disabledLabel: {
1911
+ color: colors.disabledTextColor
1912
+ },
1913
+ leadingIcon: {
1914
+ marginEnd: theme.spacing.sm
1915
+ },
1916
+ avatar: {
1917
+ marginEnd: theme.spacing.sm,
1918
+ width: 24,
1919
+ height: 24,
1920
+ borderRadius: 12,
1921
+ overflow: "hidden"
1922
+ },
1923
+ closeButton: {
1924
+ marginStart: theme.spacing.sm
1925
+ }
1926
+ });
1927
+ }
1928
+
1929
+ // src/chip/Chip.tsx
1930
+ var import_jsx_runtime11 = require("react/jsx-runtime");
1931
+ function resolveStyle2(containerStyle, hoveredContainerStyle, pressedContainerStyle, disabledContainerStyle, disabled, style) {
1932
+ if (typeof style === "function") {
1933
+ return (state) => [
1934
+ containerStyle,
1935
+ state.hovered && !state.pressed && !disabled ? hoveredContainerStyle : void 0,
1936
+ state.pressed && !disabled ? pressedContainerStyle : void 0,
1937
+ disabled ? disabledContainerStyle : void 0,
1938
+ style(state)
1939
+ ];
1940
+ }
1941
+ return (state) => [
1942
+ containerStyle,
1943
+ state.hovered && !state.pressed && !disabled ? hoveredContainerStyle : void 0,
1944
+ state.pressed && !disabled ? pressedContainerStyle : void 0,
1945
+ disabled ? disabledContainerStyle : void 0,
1946
+ style
1947
+ ];
1948
+ }
1949
+ function Chip({
1950
+ children,
1951
+ style,
1952
+ variant = "assist",
1953
+ elevated = false,
1954
+ selected = false,
1955
+ leadingIcon,
1956
+ iconSize = 18,
1957
+ avatar,
1958
+ onClose,
1959
+ containerColor,
1960
+ contentColor,
1961
+ labelStyle: labelStyleOverride,
1962
+ disabled = false,
1963
+ ...props
1964
+ }) {
1965
+ const isDisabled = Boolean(disabled);
1966
+ const isSelected = variant === "filter" ? Boolean(selected) : false;
1967
+ const showCloseIcon = onClose !== void 0 && (variant === "input" || variant === "filter" && isSelected);
1968
+ const hasLeadingContent = Boolean(
1969
+ variant === "input" && avatar || leadingIcon || variant === "filter" && isSelected
1970
+ );
1971
+ const theme = (0, import_core10.useTheme)();
1972
+ const styles2 = (0, import_react11.useMemo)(
1973
+ () => createStyles5(
1974
+ theme,
1975
+ variant,
1976
+ elevated,
1977
+ isSelected,
1978
+ hasLeadingContent,
1979
+ showCloseIcon,
1980
+ containerColor,
1981
+ contentColor
1982
+ ),
1983
+ [
1984
+ theme,
1985
+ variant,
1986
+ elevated,
1987
+ isSelected,
1988
+ hasLeadingContent,
1989
+ showCloseIcon,
1990
+ containerColor,
1991
+ contentColor
1992
+ ]
1993
+ );
1994
+ const resolvedIconColor = (0, import_react11.useMemo)(() => {
1995
+ const base = import_react_native18.StyleSheet.flatten([
1996
+ styles2.label,
1997
+ isDisabled ? styles2.disabledLabel : void 0
1998
+ ]);
1999
+ return typeof (base == null ? void 0 : base.color) === "string" ? base.color : void 0;
2000
+ }, [styles2.label, styles2.disabledLabel, isDisabled]);
2001
+ const computedLabelStyle = (0, import_react11.useMemo)(
2002
+ () => [
2003
+ styles2.label,
2004
+ isDisabled ? styles2.disabledLabel : void 0,
2005
+ labelStyleOverride
2006
+ ],
2007
+ [isDisabled, styles2.disabledLabel, styles2.label, labelStyleOverride]
2008
+ );
2009
+ const renderLeadingContent = () => {
2010
+ if (variant === "input" && avatar) {
2011
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native18.View, { style: styles2.avatar, children: avatar });
2012
+ }
2013
+ if (leadingIcon) {
2014
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2015
+ import_MaterialCommunityIcons3.default,
2016
+ {
2017
+ name: leadingIcon,
2018
+ size: iconSize,
2019
+ color: resolvedIconColor,
2020
+ style: styles2.leadingIcon
2021
+ }
2022
+ );
2023
+ }
2024
+ if (variant === "filter" && isSelected) {
2025
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2026
+ import_MaterialCommunityIcons3.default,
2027
+ {
2028
+ name: "check",
2029
+ size: iconSize,
2030
+ color: resolvedIconColor,
2031
+ style: styles2.leadingIcon
2032
+ }
2033
+ );
2034
+ }
2035
+ return null;
2036
+ };
2037
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
2038
+ import_react_native18.Pressable,
2039
+ {
2040
+ ...props,
2041
+ accessibilityRole: "button",
2042
+ accessibilityState: {
2043
+ disabled: isDisabled,
2044
+ ...variant === "filter" ? { selected: isSelected } : void 0
2045
+ },
2046
+ hitSlop: import_react_native18.Platform.OS === "web" ? void 0 : 4,
2047
+ disabled: isDisabled,
2048
+ style: resolveStyle2(
2049
+ styles2.container,
2050
+ styles2.hoveredContainer,
2051
+ styles2.pressedContainer,
2052
+ styles2.disabledContainer,
2053
+ isDisabled,
2054
+ style
2055
+ ),
2056
+ children: [
2057
+ renderLeadingContent(),
2058
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native18.Text, { style: computedLabelStyle, children }),
2059
+ showCloseIcon ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2060
+ import_react_native18.Pressable,
2061
+ {
2062
+ onPress: onClose,
2063
+ accessibilityRole: "button",
2064
+ accessibilityLabel: "Remove",
2065
+ hitSlop: 4,
2066
+ style: styles2.closeButton,
2067
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2068
+ import_MaterialCommunityIcons3.default,
2069
+ {
2070
+ name: "close",
2071
+ size: iconSize,
2072
+ color: resolvedIconColor
2073
+ }
2074
+ )
2075
+ }
2076
+ ) : null
2077
+ ]
2078
+ }
2079
+ );
2080
+ }
2081
+
2082
+ // src/checkbox/Checkbox.tsx
2083
+ var import_MaterialCommunityIcons4 = __toESM(require("@expo/vector-icons/MaterialCommunityIcons"));
2084
+ var import_react12 = require("react");
2085
+ var import_react_native20 = require("react-native");
2086
+ var import_core11 = require("@onlynative/core");
2087
+
2088
+ // src/checkbox/styles.ts
2089
+ var import_react_native19 = require("react-native");
2090
+ function getColors(theme, checked) {
2091
+ const disabledOnSurface38 = alphaColor(theme.colors.onSurface, 0.38);
2092
+ if (checked) {
2093
+ return {
2094
+ backgroundColor: theme.colors.primary,
2095
+ borderColor: "transparent",
2096
+ borderWidth: 0,
2097
+ iconColor: theme.colors.onPrimary,
2098
+ hoveredBackgroundColor: blendColor(
2099
+ theme.colors.primary,
2100
+ theme.colors.onPrimary,
2101
+ theme.stateLayer.hoveredOpacity
2102
+ ),
2103
+ pressedBackgroundColor: blendColor(
2104
+ theme.colors.primary,
2105
+ theme.colors.onPrimary,
2106
+ theme.stateLayer.pressedOpacity
2107
+ ),
2108
+ disabledBackgroundColor: disabledOnSurface38,
2109
+ disabledBorderColor: "transparent",
2110
+ disabledBorderWidth: 0,
2111
+ disabledIconColor: theme.colors.surface
2112
+ };
2113
+ }
2114
+ return {
2115
+ backgroundColor: "transparent",
2116
+ borderColor: theme.colors.onSurfaceVariant,
2117
+ borderWidth: 2,
2118
+ iconColor: "transparent",
2119
+ hoveredBackgroundColor: alphaColor(
2120
+ theme.colors.onSurface,
2121
+ theme.stateLayer.hoveredOpacity
2122
+ ),
2123
+ pressedBackgroundColor: alphaColor(
2124
+ theme.colors.onSurface,
2125
+ theme.stateLayer.pressedOpacity
2126
+ ),
2127
+ disabledBackgroundColor: "transparent",
2128
+ disabledBorderColor: disabledOnSurface38,
2129
+ disabledBorderWidth: 2,
2130
+ disabledIconColor: "transparent"
2131
+ };
2132
+ }
2133
+ function applyColorOverrides4(theme, colors, containerColor, contentColor) {
2134
+ if (!containerColor && !contentColor) return colors;
2135
+ const result = { ...colors };
2136
+ if (contentColor) {
2137
+ result.iconColor = contentColor;
2138
+ }
2139
+ if (containerColor) {
2140
+ const overlay = contentColor != null ? contentColor : colors.iconColor;
2141
+ result.backgroundColor = containerColor;
2142
+ result.borderColor = containerColor;
2143
+ result.hoveredBackgroundColor = blendColor(
2144
+ containerColor,
2145
+ overlay,
2146
+ theme.stateLayer.hoveredOpacity
2147
+ );
2148
+ result.pressedBackgroundColor = blendColor(
2149
+ containerColor,
2150
+ overlay,
2151
+ theme.stateLayer.pressedOpacity
2152
+ );
2153
+ }
2154
+ return result;
2155
+ }
2156
+ function createStyles6(theme, checked, containerColor, contentColor) {
2157
+ const colors = applyColorOverrides4(
2158
+ theme,
2159
+ getColors(theme, checked),
2160
+ containerColor,
2161
+ contentColor
2162
+ );
2163
+ const size = 18;
2164
+ const touchTarget = 48;
2165
+ return import_react_native19.StyleSheet.create({
2166
+ container: {
2167
+ width: touchTarget,
2168
+ height: touchTarget,
2169
+ alignItems: "center",
2170
+ justifyContent: "center",
2171
+ cursor: "pointer"
2172
+ },
2173
+ hoveredContainer: {
2174
+ borderRadius: touchTarget / 2,
2175
+ backgroundColor: colors.hoveredBackgroundColor
2176
+ },
2177
+ pressedContainer: {
2178
+ borderRadius: touchTarget / 2,
2179
+ backgroundColor: colors.pressedBackgroundColor
2180
+ },
2181
+ disabledContainer: {
2182
+ cursor: "auto"
2183
+ },
2184
+ box: {
2185
+ width: size,
2186
+ height: size,
2187
+ borderRadius: theme.shape.cornerExtraSmall,
2188
+ backgroundColor: colors.backgroundColor,
2189
+ borderColor: colors.borderColor,
2190
+ borderWidth: colors.borderWidth,
2191
+ alignItems: "center",
2192
+ justifyContent: "center"
2193
+ },
2194
+ disabledBox: {
2195
+ backgroundColor: colors.disabledBackgroundColor,
2196
+ borderColor: colors.disabledBorderColor,
2197
+ borderWidth: colors.disabledBorderWidth
2198
+ },
2199
+ iconColor: {
2200
+ color: colors.iconColor
2201
+ },
2202
+ disabledIconColor: {
2203
+ color: colors.disabledIconColor
2204
+ }
2205
+ });
2206
+ }
2207
+
2208
+ // src/checkbox/Checkbox.tsx
2209
+ var import_jsx_runtime12 = require("react/jsx-runtime");
2210
+ function resolveStyle3(containerStyle, hoveredContainerStyle, pressedContainerStyle, disabledContainerStyle, disabled, style) {
2211
+ if (typeof style === "function") {
2212
+ return (state) => [
2213
+ containerStyle,
2214
+ state.hovered && !state.pressed && !disabled ? hoveredContainerStyle : void 0,
2215
+ state.pressed && !disabled ? pressedContainerStyle : void 0,
2216
+ disabled ? disabledContainerStyle : void 0,
2217
+ style(state)
2218
+ ];
2219
+ }
2220
+ return (state) => [
2221
+ containerStyle,
2222
+ state.hovered && !state.pressed && !disabled ? hoveredContainerStyle : void 0,
2223
+ state.pressed && !disabled ? pressedContainerStyle : void 0,
2224
+ disabled ? disabledContainerStyle : void 0,
2225
+ style
2226
+ ];
2227
+ }
2228
+ function Checkbox({
2229
+ style,
2230
+ value = false,
2231
+ onValueChange,
2232
+ containerColor,
2233
+ contentColor,
2234
+ disabled = false,
2235
+ ...props
2236
+ }) {
2237
+ const isDisabled = Boolean(disabled);
2238
+ const isChecked = Boolean(value);
2239
+ const theme = (0, import_core11.useTheme)();
2240
+ const styles2 = (0, import_react12.useMemo)(
2241
+ () => createStyles6(theme, isChecked, containerColor, contentColor),
2242
+ [theme, isChecked, containerColor, contentColor]
2243
+ );
2244
+ const resolvedIconColor = (0, import_react12.useMemo)(() => {
2245
+ const base = import_react_native20.StyleSheet.flatten([
2246
+ styles2.iconColor,
2247
+ isDisabled ? styles2.disabledIconColor : void 0
2248
+ ]);
2249
+ return typeof (base == null ? void 0 : base.color) === "string" ? base.color : void 0;
2250
+ }, [styles2.iconColor, styles2.disabledIconColor, isDisabled]);
2251
+ const handlePress = () => {
2252
+ if (!isDisabled) {
2253
+ onValueChange == null ? void 0 : onValueChange(!isChecked);
2254
+ }
2255
+ };
2256
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2257
+ import_react_native20.Pressable,
2258
+ {
2259
+ ...props,
2260
+ accessibilityRole: "checkbox",
2261
+ accessibilityState: {
2262
+ disabled: isDisabled,
2263
+ checked: isChecked
2264
+ },
2265
+ hitSlop: import_react_native20.Platform.OS === "web" ? void 0 : 4,
2266
+ disabled: isDisabled,
2267
+ onPress: handlePress,
2268
+ style: resolveStyle3(
2269
+ styles2.container,
2270
+ styles2.hoveredContainer,
2271
+ styles2.pressedContainer,
2272
+ styles2.disabledContainer,
2273
+ isDisabled,
2274
+ style
2275
+ ),
2276
+ children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native20.View, { style: [styles2.box, isDisabled ? styles2.disabledBox : void 0], children: isChecked ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2277
+ import_MaterialCommunityIcons4.default,
2278
+ {
2279
+ name: "check",
2280
+ size: 14,
2281
+ color: resolvedIconColor
2282
+ }
2283
+ ) : null })
2284
+ }
2285
+ );
2286
+ }
2287
+
2288
+ // src/radio/Radio.tsx
2289
+ var import_react13 = require("react");
2290
+ var import_react_native22 = require("react-native");
2291
+ var import_core12 = require("@onlynative/core");
2292
+
2293
+ // src/radio/styles.ts
2294
+ var import_react_native21 = require("react-native");
2295
+ function getColors2(theme, selected) {
2296
+ const disabledOnSurface38 = alphaColor(theme.colors.onSurface, 0.38);
2297
+ if (selected) {
2298
+ return {
2299
+ borderColor: theme.colors.primary,
2300
+ dotColor: theme.colors.primary,
2301
+ hoveredBackgroundColor: alphaColor(
2302
+ theme.colors.primary,
2303
+ theme.stateLayer.hoveredOpacity
2304
+ ),
2305
+ pressedBackgroundColor: alphaColor(
2306
+ theme.colors.primary,
2307
+ theme.stateLayer.pressedOpacity
2308
+ ),
2309
+ disabledBorderColor: disabledOnSurface38,
2310
+ disabledDotColor: disabledOnSurface38
2311
+ };
2312
+ }
2313
+ return {
2314
+ borderColor: theme.colors.onSurfaceVariant,
2315
+ dotColor: "transparent",
2316
+ hoveredBackgroundColor: alphaColor(
2317
+ theme.colors.onSurface,
2318
+ theme.stateLayer.hoveredOpacity
2319
+ ),
2320
+ pressedBackgroundColor: alphaColor(
2321
+ theme.colors.onSurface,
2322
+ theme.stateLayer.pressedOpacity
2323
+ ),
2324
+ disabledBorderColor: disabledOnSurface38,
2325
+ disabledDotColor: "transparent"
2326
+ };
2327
+ }
2328
+ function applyColorOverrides5(theme, colors, containerColor, contentColor) {
2329
+ if (!containerColor && !contentColor) return colors;
2330
+ const result = { ...colors };
2331
+ if (containerColor) {
2332
+ result.borderColor = containerColor;
2333
+ result.dotColor = containerColor;
2334
+ result.hoveredBackgroundColor = alphaColor(
2335
+ containerColor,
2336
+ theme.stateLayer.hoveredOpacity
2337
+ );
2338
+ result.pressedBackgroundColor = alphaColor(
2339
+ containerColor,
2340
+ theme.stateLayer.pressedOpacity
2341
+ );
2342
+ }
2343
+ if (contentColor) {
2344
+ result.borderColor = contentColor;
2345
+ }
2346
+ return result;
2347
+ }
2348
+ function createStyles7(theme, selected, containerColor, contentColor) {
2349
+ const colors = applyColorOverrides5(
2350
+ theme,
2351
+ getColors2(theme, selected),
2352
+ containerColor,
2353
+ contentColor
2354
+ );
2355
+ const outerSize = 20;
2356
+ const innerSize = 10;
2357
+ const touchTarget = 48;
2358
+ return import_react_native21.StyleSheet.create({
2359
+ container: {
2360
+ width: touchTarget,
2361
+ height: touchTarget,
2362
+ alignItems: "center",
2363
+ justifyContent: "center",
2364
+ cursor: "pointer"
2365
+ },
2366
+ hoveredContainer: {
2367
+ borderRadius: touchTarget / 2,
2368
+ backgroundColor: colors.hoveredBackgroundColor
2369
+ },
2370
+ pressedContainer: {
2371
+ borderRadius: touchTarget / 2,
2372
+ backgroundColor: colors.pressedBackgroundColor
2373
+ },
2374
+ disabledContainer: {
2375
+ cursor: "auto"
2376
+ },
2377
+ outer: {
2378
+ width: outerSize,
2379
+ height: outerSize,
2380
+ borderRadius: outerSize / 2,
2381
+ borderWidth: 2,
2382
+ borderColor: colors.borderColor,
2383
+ alignItems: "center",
2384
+ justifyContent: "center"
2385
+ },
2386
+ disabledOuter: {
2387
+ borderColor: colors.disabledBorderColor
2388
+ },
2389
+ inner: {
2390
+ width: innerSize,
2391
+ height: innerSize,
2392
+ borderRadius: innerSize / 2,
2393
+ backgroundColor: colors.dotColor
2394
+ },
2395
+ disabledInner: {
2396
+ backgroundColor: colors.disabledDotColor
2397
+ }
2398
+ });
2399
+ }
2400
+
2401
+ // src/radio/Radio.tsx
2402
+ var import_jsx_runtime13 = require("react/jsx-runtime");
2403
+ function resolveStyle4(containerStyle, hoveredContainerStyle, pressedContainerStyle, disabledContainerStyle, disabled, style) {
2404
+ if (typeof style === "function") {
2405
+ return (state) => [
2406
+ containerStyle,
2407
+ state.hovered && !state.pressed && !disabled ? hoveredContainerStyle : void 0,
2408
+ state.pressed && !disabled ? pressedContainerStyle : void 0,
2409
+ disabled ? disabledContainerStyle : void 0,
2410
+ style(state)
2411
+ ];
2412
+ }
2413
+ return (state) => [
2414
+ containerStyle,
2415
+ state.hovered && !state.pressed && !disabled ? hoveredContainerStyle : void 0,
2416
+ state.pressed && !disabled ? pressedContainerStyle : void 0,
2417
+ disabled ? disabledContainerStyle : void 0,
2418
+ style
2419
+ ];
2420
+ }
2421
+ function Radio({
2422
+ style,
2423
+ value = false,
2424
+ onValueChange,
2425
+ containerColor,
2426
+ contentColor,
2427
+ disabled = false,
2428
+ ...props
2429
+ }) {
2430
+ const isDisabled = Boolean(disabled);
2431
+ const isSelected = Boolean(value);
2432
+ const theme = (0, import_core12.useTheme)();
2433
+ const styles2 = (0, import_react13.useMemo)(
2434
+ () => createStyles7(theme, isSelected, containerColor, contentColor),
2435
+ [theme, isSelected, containerColor, contentColor]
2436
+ );
2437
+ const handlePress = () => {
2438
+ if (!isDisabled) {
2439
+ onValueChange == null ? void 0 : onValueChange(!isSelected);
2440
+ }
2441
+ };
2442
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2443
+ import_react_native22.Pressable,
2444
+ {
2445
+ ...props,
2446
+ accessibilityRole: "radio",
2447
+ accessibilityState: {
2448
+ disabled: isDisabled,
2449
+ checked: isSelected
2450
+ },
2451
+ hitSlop: import_react_native22.Platform.OS === "web" ? void 0 : 4,
2452
+ disabled: isDisabled,
2453
+ onPress: handlePress,
2454
+ style: resolveStyle4(
2455
+ styles2.container,
2456
+ styles2.hoveredContainer,
2457
+ styles2.pressedContainer,
2458
+ styles2.disabledContainer,
2459
+ isDisabled,
2460
+ style
2461
+ ),
2462
+ children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2463
+ import_react_native22.View,
2464
+ {
2465
+ style: [styles2.outer, isDisabled ? styles2.disabledOuter : void 0],
2466
+ children: isSelected ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2467
+ import_react_native22.View,
2468
+ {
2469
+ style: [
2470
+ styles2.inner,
2471
+ isDisabled ? styles2.disabledInner : void 0
2472
+ ]
2473
+ }
2474
+ ) : null
2475
+ }
2476
+ )
2477
+ }
2478
+ );
2479
+ }
2480
+
2481
+ // src/switch/Switch.tsx
2482
+ var import_MaterialCommunityIcons5 = __toESM(require("@expo/vector-icons/MaterialCommunityIcons"));
2483
+ var import_react14 = require("react");
2484
+ var import_react_native24 = require("react-native");
2485
+ var import_core13 = require("@onlynative/core");
2486
+
2487
+ // src/switch/styles.ts
2488
+ var import_react_native23 = require("react-native");
2489
+ function getColors3(theme, selected) {
2490
+ const disabledOnSurface12 = alphaColor(theme.colors.onSurface, 0.12);
2491
+ const disabledOnSurface38 = alphaColor(theme.colors.onSurface, 0.38);
2492
+ if (selected) {
2493
+ return {
2494
+ trackColor: theme.colors.primary,
2495
+ thumbColor: theme.colors.onPrimary,
2496
+ iconColor: theme.colors.onPrimaryContainer,
2497
+ hoveredTrackColor: blendColor(
2498
+ theme.colors.primary,
2499
+ theme.colors.onPrimary,
2500
+ theme.stateLayer.hoveredOpacity
2501
+ ),
2502
+ pressedTrackColor: blendColor(
2503
+ theme.colors.primary,
2504
+ theme.colors.onPrimary,
2505
+ theme.stateLayer.pressedOpacity
2506
+ ),
2507
+ borderColor: "transparent",
2508
+ borderWidth: 0,
2509
+ disabledTrackColor: disabledOnSurface12,
2510
+ disabledThumbColor: theme.colors.surface,
2511
+ disabledBorderColor: "transparent",
2512
+ disabledBorderWidth: 0
2513
+ };
2514
+ }
2515
+ return {
2516
+ trackColor: theme.colors.surfaceContainerHighest,
2517
+ thumbColor: theme.colors.outline,
2518
+ iconColor: theme.colors.surfaceContainerHighest,
2519
+ hoveredTrackColor: blendColor(
2520
+ theme.colors.surfaceContainerHighest,
2521
+ theme.colors.onSurface,
2522
+ theme.stateLayer.hoveredOpacity
2523
+ ),
2524
+ pressedTrackColor: blendColor(
2525
+ theme.colors.surfaceContainerHighest,
2526
+ theme.colors.onSurface,
2527
+ theme.stateLayer.pressedOpacity
2528
+ ),
2529
+ borderColor: theme.colors.outline,
2530
+ borderWidth: 2,
2531
+ disabledTrackColor: disabledOnSurface12,
2532
+ disabledThumbColor: disabledOnSurface38,
2533
+ disabledBorderColor: disabledOnSurface12,
2534
+ disabledBorderWidth: 2
2535
+ };
2536
+ }
2537
+ function applyColorOverrides6(theme, colors, containerColor, contentColor) {
2538
+ if (!containerColor && !contentColor) return colors;
2539
+ const result = { ...colors };
2540
+ if (contentColor) {
2541
+ result.thumbColor = contentColor;
2542
+ result.iconColor = contentColor;
2543
+ }
2544
+ if (containerColor) {
2545
+ const overlay = contentColor != null ? contentColor : colors.thumbColor;
2546
+ result.trackColor = containerColor;
2547
+ result.borderColor = containerColor;
2548
+ result.hoveredTrackColor = blendColor(
2549
+ containerColor,
2550
+ overlay,
2551
+ theme.stateLayer.hoveredOpacity
2552
+ );
2553
+ result.pressedTrackColor = blendColor(
2554
+ containerColor,
2555
+ overlay,
2556
+ theme.stateLayer.pressedOpacity
2557
+ );
2558
+ if (contentColor) {
2559
+ result.iconColor = containerColor;
2560
+ }
2561
+ }
2562
+ return result;
2563
+ }
2564
+ function createStyles8(theme, selected, hasIcon, containerColor, contentColor) {
2565
+ const colors = applyColorOverrides6(
2566
+ theme,
2567
+ getColors3(theme, selected),
2568
+ containerColor,
2569
+ contentColor
2570
+ );
2571
+ const thumbSize = selected || hasIcon ? 24 : 16;
2572
+ const trackWidth = 52;
2573
+ const trackHeight = 32;
2574
+ const trackPadding = 4;
2575
+ const thumbOffset = selected ? trackWidth - trackPadding - thumbSize : trackPadding;
2576
+ return import_react_native23.StyleSheet.create({
2577
+ track: {
2578
+ width: trackWidth,
2579
+ height: trackHeight,
2580
+ borderRadius: trackHeight / 2,
2581
+ backgroundColor: colors.trackColor,
2582
+ borderColor: colors.borderColor,
2583
+ borderWidth: colors.borderWidth,
2584
+ justifyContent: "center",
2585
+ cursor: "pointer"
2586
+ },
2587
+ hoveredTrack: {
2588
+ backgroundColor: colors.hoveredTrackColor
2589
+ },
2590
+ pressedTrack: {
2591
+ backgroundColor: colors.pressedTrackColor
2592
+ },
2593
+ disabledTrack: {
2594
+ backgroundColor: colors.disabledTrackColor,
2595
+ borderColor: colors.disabledBorderColor,
2596
+ borderWidth: colors.disabledBorderWidth,
2597
+ cursor: "auto"
2598
+ },
2599
+ thumb: {
2600
+ width: thumbSize,
2601
+ height: thumbSize,
2602
+ borderRadius: thumbSize / 2,
2603
+ backgroundColor: colors.thumbColor,
2604
+ marginStart: thumbOffset,
2605
+ alignItems: "center",
2606
+ justifyContent: "center"
2607
+ },
2608
+ disabledThumb: {
2609
+ backgroundColor: colors.disabledThumbColor
2610
+ },
2611
+ iconColor: {
2612
+ color: colors.iconColor
2613
+ },
2614
+ disabledIconColor: {
2615
+ color: alphaColor(theme.colors.onSurface, 0.38)
2616
+ }
2617
+ });
2618
+ }
2619
+
2620
+ // src/switch/Switch.tsx
2621
+ var import_jsx_runtime14 = require("react/jsx-runtime");
2622
+ function resolveStyle5(trackStyle, hoveredTrackStyle, pressedTrackStyle, disabledTrackStyle, disabled, style) {
2623
+ if (typeof style === "function") {
2624
+ return (state) => [
2625
+ trackStyle,
2626
+ state.hovered && !state.pressed && !disabled ? hoveredTrackStyle : void 0,
2627
+ state.pressed && !disabled ? pressedTrackStyle : void 0,
2628
+ disabled ? disabledTrackStyle : void 0,
2629
+ style(state)
2630
+ ];
2631
+ }
2632
+ return (state) => [
2633
+ trackStyle,
2634
+ state.hovered && !state.pressed && !disabled ? hoveredTrackStyle : void 0,
2635
+ state.pressed && !disabled ? pressedTrackStyle : void 0,
2636
+ disabled ? disabledTrackStyle : void 0,
2637
+ style
2638
+ ];
2639
+ }
2640
+ function Switch({
2641
+ style,
2642
+ value = false,
2643
+ onValueChange,
2644
+ selectedIcon = "check",
2645
+ unselectedIcon,
2646
+ containerColor,
2647
+ contentColor,
2648
+ disabled = false,
2649
+ ...props
2650
+ }) {
2651
+ const isDisabled = Boolean(disabled);
2652
+ const isSelected = Boolean(value);
2653
+ const hasIcon = isSelected || Boolean(unselectedIcon);
2654
+ const theme = (0, import_core13.useTheme)();
2655
+ const styles2 = (0, import_react14.useMemo)(
2656
+ () => createStyles8(theme, isSelected, hasIcon, containerColor, contentColor),
2657
+ [theme, isSelected, hasIcon, containerColor, contentColor]
2658
+ );
2659
+ const resolvedIconColor = (0, import_react14.useMemo)(() => {
2660
+ const base = import_react_native24.StyleSheet.flatten([
2661
+ styles2.iconColor,
2662
+ isDisabled ? styles2.disabledIconColor : void 0
2663
+ ]);
2664
+ return typeof (base == null ? void 0 : base.color) === "string" ? base.color : void 0;
2665
+ }, [styles2.iconColor, styles2.disabledIconColor, isDisabled]);
2666
+ const handlePress = () => {
2667
+ if (!isDisabled) {
2668
+ onValueChange == null ? void 0 : onValueChange(!isSelected);
2669
+ }
2670
+ };
2671
+ const iconName = isSelected ? selectedIcon : unselectedIcon;
2672
+ const iconSize = 16;
2673
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2674
+ import_react_native24.Pressable,
2675
+ {
2676
+ ...props,
2677
+ accessibilityRole: "switch",
2678
+ accessibilityState: {
2679
+ disabled: isDisabled,
2680
+ checked: isSelected
2681
+ },
2682
+ hitSlop: import_react_native24.Platform.OS === "web" ? void 0 : 4,
2683
+ disabled: isDisabled,
2684
+ onPress: handlePress,
2685
+ style: resolveStyle5(
2686
+ styles2.track,
2687
+ styles2.hoveredTrack,
2688
+ styles2.pressedTrack,
2689
+ styles2.disabledTrack,
2690
+ isDisabled,
2691
+ style
2692
+ ),
2693
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2694
+ import_react_native24.View,
2695
+ {
2696
+ style: [styles2.thumb, isDisabled ? styles2.disabledThumb : void 0],
2697
+ children: iconName ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2698
+ import_MaterialCommunityIcons5.default,
2699
+ {
2700
+ name: iconName,
2701
+ size: iconSize,
2702
+ color: resolvedIconColor
2703
+ }
2704
+ ) : null
2705
+ }
2706
+ )
2707
+ }
2708
+ );
2709
+ }
2710
+
2711
+ // src/text-field/TextField.tsx
2712
+ var import_MaterialCommunityIcons6 = __toESM(require("@expo/vector-icons/MaterialCommunityIcons"));
2713
+ var import_react15 = require("react");
2714
+ var import_react_native26 = require("react-native");
2715
+ var import_core14 = require("@onlynative/core");
2716
+
2717
+ // src/text-field/styles.ts
2718
+ var import_react_native25 = require("react-native");
2719
+ var CONTAINER_HEIGHT = 56;
2720
+ var ICON_SIZE = 24;
2721
+ var LABEL_FLOATED_LINE_HEIGHT = 16;
2722
+ var FILLED_LABEL_RESTING_TOP = 16;
2723
+ var FILLED_LABEL_FLOATED_TOP = 8;
2724
+ var FILLED_INPUT_TOP = 24;
2725
+ var FILLED_INPUT_BOTTOM = 8;
2726
+ var OUTLINED_INPUT_VERTICAL = 16;
2727
+ var OUTLINED_LABEL_RESTING_TOP = 16;
2728
+ var OUTLINED_LABEL_FLOATED_TOP = -(LABEL_FLOATED_LINE_HEIGHT / 2);
2729
+ var labelPositions = {
2730
+ filledRestingTop: FILLED_LABEL_RESTING_TOP,
2731
+ filledFloatedTop: FILLED_LABEL_FLOATED_TOP,
2732
+ outlinedRestingTop: OUTLINED_LABEL_RESTING_TOP,
2733
+ outlinedFloatedTop: OUTLINED_LABEL_FLOATED_TOP
2734
+ };
2735
+ function getVariantColors4(theme, variant) {
2736
+ const disabledOpacity = theme.stateLayer.disabledOpacity;
2737
+ const common = {
2738
+ focusedBorderColor: theme.colors.primary,
2739
+ errorBorderColor: theme.colors.error,
2740
+ focusedLabelColor: theme.colors.primary,
2741
+ errorLabelColor: theme.colors.error,
2742
+ textColor: theme.colors.onSurface,
2743
+ disabledTextColor: alphaColor(theme.colors.onSurface, disabledOpacity),
2744
+ disabledLabelColor: alphaColor(theme.colors.onSurface, disabledOpacity),
2745
+ disabledBorderColor: alphaColor(theme.colors.onSurface, 0.12),
2746
+ placeholderColor: theme.colors.onSurfaceVariant,
2747
+ supportingTextColor: theme.colors.onSurfaceVariant,
2748
+ errorSupportingTextColor: theme.colors.error,
2749
+ iconColor: theme.colors.onSurfaceVariant,
2750
+ errorIconColor: theme.colors.error,
2751
+ disabledIconColor: alphaColor(theme.colors.onSurface, disabledOpacity)
2752
+ };
2753
+ if (variant === "outlined") {
2754
+ return {
2755
+ ...common,
2756
+ backgroundColor: "transparent",
2757
+ borderColor: theme.colors.outline,
2758
+ disabledBackgroundColor: "transparent",
2759
+ labelColor: theme.colors.onSurfaceVariant
2760
+ };
2761
+ }
2762
+ return {
2763
+ ...common,
2764
+ backgroundColor: theme.colors.surfaceContainerHighest,
2765
+ borderColor: theme.colors.onSurfaceVariant,
2766
+ disabledBackgroundColor: alphaColor(theme.colors.onSurface, 0.04),
2767
+ labelColor: theme.colors.onSurfaceVariant
2768
+ };
2769
+ }
2770
+ function createStyles9(theme, variant) {
2771
+ const colors = getVariantColors4(theme, variant);
2772
+ const bodyLarge = theme.typography.bodyLarge;
2773
+ const bodySmall = theme.typography.bodySmall;
2774
+ const isFilled = variant === "filled";
2775
+ return {
2776
+ colors,
2777
+ styles: import_react_native25.StyleSheet.create({
2778
+ root: {
2779
+ alignSelf: "stretch"
2780
+ },
2781
+ container: {
2782
+ minHeight: CONTAINER_HEIGHT,
2783
+ flexDirection: "row",
2784
+ alignItems: "stretch",
2785
+ backgroundColor: colors.backgroundColor,
2786
+ paddingHorizontal: theme.spacing.md,
2787
+ ...isFilled ? {
2788
+ borderTopStartRadius: theme.shape.cornerExtraSmall,
2789
+ borderTopEndRadius: theme.shape.cornerExtraSmall
2790
+ } : {
2791
+ borderRadius: theme.shape.cornerExtraSmall,
2792
+ borderWidth: 1,
2793
+ borderColor: colors.borderColor
2794
+ }
2795
+ },
2796
+ containerFocused: isFilled ? {} : {
2797
+ borderWidth: 2,
2798
+ borderColor: colors.focusedBorderColor,
2799
+ paddingHorizontal: theme.spacing.md - 1
2800
+ },
2801
+ containerError: isFilled ? {} : {
2802
+ borderWidth: 2,
2803
+ borderColor: colors.errorBorderColor,
2804
+ paddingHorizontal: theme.spacing.md - 1
2805
+ },
2806
+ containerDisabled: isFilled ? { backgroundColor: colors.disabledBackgroundColor } : {
2807
+ borderColor: colors.disabledBorderColor
2808
+ },
2809
+ indicator: {
2810
+ position: "absolute",
2811
+ start: 0,
2812
+ end: 0,
2813
+ bottom: 0,
2814
+ height: 1,
2815
+ backgroundColor: colors.borderColor
2816
+ },
2817
+ indicatorFocused: {
2818
+ height: 2,
2819
+ backgroundColor: colors.focusedBorderColor
2820
+ },
2821
+ indicatorError: {
2822
+ height: 2,
2823
+ backgroundColor: colors.errorBorderColor
2824
+ },
2825
+ indicatorDisabled: {
2826
+ backgroundColor: colors.disabledBorderColor
2827
+ },
2828
+ inputWrapper: {
2829
+ flex: 1,
2830
+ justifyContent: "center"
2831
+ },
2832
+ // When label is present, use explicit padding so the input position
2833
+ // matches the label resting top exactly.
2834
+ inputWrapperWithLabel: {
2835
+ justifyContent: "flex-start",
2836
+ paddingTop: isFilled ? FILLED_INPUT_TOP : OUTLINED_INPUT_VERTICAL,
2837
+ paddingBottom: isFilled ? FILLED_INPUT_BOTTOM : OUTLINED_INPUT_VERTICAL
2838
+ },
2839
+ label: {
2840
+ position: "absolute",
2841
+ zIndex: 1,
2842
+ fontFamily: bodySmall.fontFamily,
2843
+ fontSize: bodySmall.fontSize,
2844
+ lineHeight: bodySmall.lineHeight,
2845
+ fontWeight: bodySmall.fontWeight,
2846
+ letterSpacing: bodySmall.letterSpacing,
2847
+ color: colors.labelColor,
2848
+ transformOrigin: transformOrigin("top")
2849
+ },
2850
+ labelNotch: {
2851
+ paddingHorizontal: 4
2852
+ },
2853
+ input: {
2854
+ fontFamily: bodyLarge.fontFamily,
2855
+ fontSize: bodyLarge.fontSize,
2856
+ lineHeight: bodyLarge.lineHeight,
2857
+ fontWeight: bodyLarge.fontWeight,
2858
+ letterSpacing: bodyLarge.letterSpacing,
2859
+ color: colors.textColor,
2860
+ paddingVertical: 0,
2861
+ paddingHorizontal: 0,
2862
+ margin: 0,
2863
+ includeFontPadding: false
2864
+ },
2865
+ inputDisabled: {
2866
+ color: colors.disabledTextColor
2867
+ },
2868
+ leadingIcon: {
2869
+ alignSelf: "center",
2870
+ marginStart: -4,
2871
+ // 16dp container padding → 12dp icon inset per M3
2872
+ marginEnd: theme.spacing.md,
2873
+ width: ICON_SIZE,
2874
+ height: ICON_SIZE,
2875
+ alignItems: "center",
2876
+ justifyContent: "center"
2877
+ },
2878
+ trailingIcon: {
2879
+ alignSelf: "center",
2880
+ marginStart: theme.spacing.md,
2881
+ marginEnd: -4,
2882
+ // 16dp container padding → 12dp icon inset per M3
2883
+ width: ICON_SIZE,
2884
+ height: ICON_SIZE,
2885
+ alignItems: "center",
2886
+ justifyContent: "center"
2887
+ },
2888
+ trailingIconPressable: {
2889
+ alignSelf: "center"
2890
+ },
2891
+ supportingTextRow: {
2892
+ paddingHorizontal: theme.spacing.md,
2893
+ paddingTop: theme.spacing.xs
2894
+ },
2895
+ supportingText: {
2896
+ fontFamily: bodySmall.fontFamily,
2897
+ fontSize: bodySmall.fontSize,
2898
+ lineHeight: bodySmall.lineHeight,
2899
+ fontWeight: bodySmall.fontWeight,
2900
+ letterSpacing: bodySmall.letterSpacing,
2901
+ color: colors.supportingTextColor
2902
+ },
2903
+ errorSupportingText: {
2904
+ color: colors.errorSupportingTextColor
2905
+ }
2906
+ })
2907
+ };
2908
+ }
2909
+
2910
+ // src/text-field/TextField.tsx
2911
+ var import_jsx_runtime15 = require("react/jsx-runtime");
2912
+ var ICON_SIZE2 = 24;
2913
+ var ICON_WITH_GAP = 12 + 24 + 16;
2914
+ function TextField({
2915
+ value,
2916
+ onChangeText,
2917
+ label,
2918
+ placeholder,
2919
+ variant = "filled",
2920
+ supportingText,
2921
+ errorText,
2922
+ error = false,
2923
+ disabled = false,
2924
+ leadingIcon,
2925
+ trailingIcon,
2926
+ onTrailingIconPress,
2927
+ multiline = false,
2928
+ onFocus,
2929
+ onBlur,
2930
+ style,
2931
+ containerColor,
2932
+ contentColor,
2933
+ inputStyle,
2934
+ ...textInputProps
2935
+ }) {
2936
+ const theme = (0, import_core14.useTheme)();
2937
+ const isDisabled = Boolean(disabled);
2938
+ const isError = Boolean(error) || Boolean(errorText);
2939
+ const isFilled = variant === "filled";
2940
+ const hasLeadingIcon = Boolean(leadingIcon);
2941
+ const { colors, styles: styles2 } = (0, import_react15.useMemo)(
2942
+ () => createStyles9(theme, variant),
2943
+ [theme, variant]
2944
+ );
2945
+ const [isFocused, setIsFocused] = (0, import_react15.useState)(false);
2946
+ const [internalHasText, setInternalHasText] = (0, import_react15.useState)(
2947
+ () => value !== void 0 && value !== ""
2948
+ );
2949
+ const inputRef = (0, import_react15.useRef)(null);
2950
+ const isControlled = value !== void 0;
2951
+ const hasValue = isControlled ? value !== "" : internalHasText;
2952
+ const isLabelFloated = isFocused || hasValue;
2953
+ const labelAnimRef = (0, import_react15.useRef)(new import_react_native26.Animated.Value(isLabelFloated ? 1 : 0));
2954
+ const labelAnim = labelAnimRef.current;
2955
+ (0, import_react15.useEffect)(() => {
2956
+ import_react_native26.Animated.timing(labelAnim, {
2957
+ toValue: isLabelFloated ? 1 : 0,
2958
+ duration: 150,
2959
+ useNativeDriver: import_react_native26.Platform.OS !== "web"
2960
+ }).start();
2961
+ }, [isLabelFloated, labelAnim]);
2962
+ const labelScale = (0, import_react15.useMemo)(() => {
2963
+ const restingScale = theme.typography.bodyLarge.fontSize / theme.typography.bodySmall.fontSize;
2964
+ return labelAnim.interpolate({
2965
+ inputRange: [0, 1],
2966
+ outputRange: [restingScale, 1]
2967
+ });
2968
+ }, [
2969
+ labelAnim,
2970
+ theme.typography.bodyLarge.fontSize,
2971
+ theme.typography.bodySmall.fontSize
2972
+ ]);
2973
+ const labelTranslateY = (0, import_react15.useMemo)(() => {
2974
+ const restingTop = isFilled ? labelPositions.filledRestingTop : labelPositions.outlinedRestingTop;
2975
+ const floatedTop = isFilled ? labelPositions.filledFloatedTop : labelPositions.outlinedFloatedTop;
2976
+ const restingOffset = restingTop - floatedTop;
2977
+ return labelAnim.interpolate({
2978
+ inputRange: [0, 1],
2979
+ outputRange: [restingOffset, 0]
2980
+ });
2981
+ }, [isFilled, labelAnim]);
2982
+ const labelStart = theme.spacing.md + (hasLeadingIcon ? ICON_WITH_GAP - theme.spacing.md : 0);
2983
+ const labelStaticTop = isFilled ? labelPositions.filledFloatedTop : labelPositions.outlinedFloatedTop;
2984
+ const handleChangeText = (0, import_react15.useCallback)(
2985
+ (text) => {
2986
+ if (!isControlled) {
2987
+ setInternalHasText(text !== "");
2988
+ }
2989
+ onChangeText == null ? void 0 : onChangeText(text);
2990
+ },
2991
+ [isControlled, onChangeText]
2992
+ );
2993
+ const handleFocus = (0, import_react15.useCallback)(
2994
+ (event) => {
2995
+ if (isDisabled) return;
2996
+ setIsFocused(true);
2997
+ onFocus == null ? void 0 : onFocus(event);
2998
+ },
2999
+ [isDisabled, onFocus]
3000
+ );
3001
+ const handleBlur = (0, import_react15.useCallback)(
3002
+ (event) => {
3003
+ setIsFocused(false);
3004
+ onBlur == null ? void 0 : onBlur(event);
3005
+ },
3006
+ [onBlur]
3007
+ );
3008
+ const handleContainerPress = (0, import_react15.useCallback)(() => {
3009
+ var _a;
3010
+ if (!isDisabled) {
3011
+ (_a = inputRef.current) == null ? void 0 : _a.focus();
3012
+ }
3013
+ }, [isDisabled]);
3014
+ const labelColor = isDisabled ? colors.disabledLabelColor : isError ? colors.errorLabelColor : isFocused ? colors.focusedLabelColor : colors.labelColor;
3015
+ const labelBackgroundColor = variant === "outlined" && isLabelFloated ? theme.colors.surface : "transparent";
3016
+ const iconColor = isDisabled ? colors.disabledIconColor : isError ? colors.errorIconColor : contentColor != null ? contentColor : colors.iconColor;
3017
+ const containerStyle = (0, import_react15.useMemo)(
3018
+ () => [
3019
+ styles2.container,
3020
+ containerColor && !isDisabled ? { backgroundColor: containerColor } : void 0,
3021
+ isFocused && styles2.containerFocused,
3022
+ isError && !isFocused && styles2.containerError,
3023
+ isDisabled && styles2.containerDisabled
3024
+ ],
3025
+ [styles2, isFocused, isError, isDisabled, containerColor]
3026
+ );
3027
+ const indicatorStyle = (0, import_react15.useMemo)(
3028
+ () => [
3029
+ styles2.indicator,
3030
+ isFocused && styles2.indicatorFocused,
3031
+ isError && !isFocused && styles2.indicatorError,
3032
+ isDisabled && styles2.indicatorDisabled
3033
+ ],
3034
+ [styles2, isFocused, isError, isDisabled]
3035
+ );
3036
+ const displaySupportingText = isError ? errorText : supportingText;
3037
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_react_native26.View, { style: [styles2.root, style], children: [
3038
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_native26.Pressable, { onPress: handleContainerPress, disabled: isDisabled, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_react_native26.View, { style: containerStyle, children: [
3039
+ leadingIcon ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_native26.View, { style: styles2.leadingIcon, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3040
+ import_MaterialCommunityIcons6.default,
3041
+ {
3042
+ name: leadingIcon,
3043
+ size: ICON_SIZE2,
3044
+ color: iconColor
3045
+ }
3046
+ ) }) : null,
3047
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3048
+ import_react_native26.View,
3049
+ {
3050
+ style: [
3051
+ styles2.inputWrapper,
3052
+ label ? styles2.inputWrapperWithLabel : void 0
3053
+ ],
3054
+ children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3055
+ import_react_native26.TextInput,
3056
+ {
3057
+ ref: inputRef,
3058
+ ...textInputProps,
3059
+ value,
3060
+ onChangeText: handleChangeText,
3061
+ editable: !isDisabled,
3062
+ onFocus: handleFocus,
3063
+ onBlur: handleBlur,
3064
+ placeholder: isLabelFloated || !label ? placeholder : void 0,
3065
+ placeholderTextColor: colors.placeholderColor,
3066
+ multiline,
3067
+ style: [
3068
+ styles2.input,
3069
+ isDisabled ? styles2.inputDisabled : void 0,
3070
+ contentColor && !isDisabled ? { color: contentColor } : void 0,
3071
+ inputStyle
3072
+ ],
3073
+ accessibilityLabel: label || void 0,
3074
+ accessibilityState: { disabled: isDisabled },
3075
+ accessibilityHint: isError && errorText ? errorText : void 0
3076
+ }
3077
+ )
3078
+ }
3079
+ ),
3080
+ trailingIcon ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3081
+ import_react_native26.Pressable,
3082
+ {
3083
+ onPress: onTrailingIconPress,
3084
+ disabled: isDisabled || !onTrailingIconPress,
3085
+ accessibilityRole: "button",
3086
+ hitSlop: 12,
3087
+ style: styles2.trailingIconPressable,
3088
+ children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_native26.View, { style: styles2.trailingIcon, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3089
+ import_MaterialCommunityIcons6.default,
3090
+ {
3091
+ name: trailingIcon,
3092
+ size: ICON_SIZE2,
3093
+ color: iconColor
3094
+ }
3095
+ ) })
3096
+ }
3097
+ ) : null,
3098
+ label ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3099
+ import_react_native26.Animated.Text,
3100
+ {
3101
+ numberOfLines: 1,
3102
+ style: [
3103
+ styles2.label,
3104
+ {
3105
+ top: labelStaticTop,
3106
+ start: labelStart,
3107
+ color: labelColor,
3108
+ backgroundColor: labelBackgroundColor,
3109
+ transform: [
3110
+ { translateY: labelTranslateY },
3111
+ { scale: labelScale }
3112
+ ]
3113
+ },
3114
+ variant === "outlined" && isLabelFloated ? styles2.labelNotch : void 0
3115
+ ],
3116
+ children: label
3117
+ }
3118
+ ) : null,
3119
+ isFilled ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_native26.View, { style: indicatorStyle }) : null
3120
+ ] }) }),
3121
+ displaySupportingText ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_native26.View, { style: styles2.supportingTextRow, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3122
+ import_react_native26.Text,
3123
+ {
3124
+ style: [
3125
+ styles2.supportingText,
3126
+ isError ? styles2.errorSupportingText : void 0
3127
+ ],
3128
+ children: displaySupportingText
3129
+ }
3130
+ ) }) : null
3131
+ ] });
3132
+ }
3133
+
3134
+ // src/list/List.tsx
3135
+ var import_react16 = require("react");
3136
+ var import_react_native28 = require("react-native");
3137
+ var import_core15 = require("@onlynative/core");
3138
+
3139
+ // src/list/styles.ts
3140
+ var import_react_native27 = require("react-native");
3141
+ var ITEM_PADDING_VERTICAL = 12;
3142
+ var INSET_START = 56;
3143
+ var MIN_HEIGHT = {
3144
+ 1: 56,
3145
+ 2: 72,
3146
+ 3: 88
3147
+ };
3148
+ function createListStyles(theme) {
3149
+ return import_react_native27.StyleSheet.create({
3150
+ container: {
3151
+ paddingVertical: theme.spacing.sm
3152
+ }
3153
+ });
3154
+ }
3155
+ function getItemColors(theme, containerColor) {
3156
+ const base = containerColor != null ? containerColor : "transparent";
3157
+ if (containerColor) {
3158
+ return {
3159
+ backgroundColor: containerColor,
3160
+ hoveredBackgroundColor: blendColor(
3161
+ containerColor,
3162
+ theme.colors.onSurface,
3163
+ theme.stateLayer.hoveredOpacity
3164
+ ),
3165
+ pressedBackgroundColor: blendColor(
3166
+ containerColor,
3167
+ theme.colors.onSurface,
3168
+ theme.stateLayer.pressedOpacity
3169
+ )
3170
+ };
3171
+ }
3172
+ return {
3173
+ backgroundColor: base,
3174
+ hoveredBackgroundColor: alphaColor(
3175
+ theme.colors.onSurface,
3176
+ theme.stateLayer.hoveredOpacity
3177
+ ),
3178
+ pressedBackgroundColor: alphaColor(
3179
+ theme.colors.onSurface,
3180
+ theme.stateLayer.pressedOpacity
3181
+ )
3182
+ };
3183
+ }
3184
+ function createListItemStyles(theme, lines, containerColor) {
3185
+ const colors = getItemColors(theme, containerColor);
3186
+ return import_react_native27.StyleSheet.create({
3187
+ container: {
3188
+ flexDirection: "row",
3189
+ alignItems: lines === 3 ? "flex-start" : "center",
3190
+ minHeight: MIN_HEIGHT[lines],
3191
+ paddingHorizontal: theme.spacing.md,
3192
+ paddingVertical: ITEM_PADDING_VERTICAL,
3193
+ backgroundColor: colors.backgroundColor
3194
+ },
3195
+ interactiveContainer: {
3196
+ cursor: "pointer"
3197
+ },
3198
+ hoveredContainer: {
3199
+ backgroundColor: colors.hoveredBackgroundColor
3200
+ },
3201
+ pressedContainer: {
3202
+ backgroundColor: colors.pressedBackgroundColor
3203
+ },
3204
+ disabledContainer: {
3205
+ cursor: "auto"
3206
+ },
3207
+ disabledContentWrapper: {
3208
+ flexDirection: "row",
3209
+ flex: 1,
3210
+ opacity: theme.stateLayer.disabledOpacity
3211
+ },
3212
+ leadingContent: {
3213
+ marginEnd: theme.spacing.md
3214
+ },
3215
+ textBlock: {
3216
+ flex: 1
3217
+ },
3218
+ overlineText: {
3219
+ ...theme.typography.labelSmall,
3220
+ color: theme.colors.onSurfaceVariant
3221
+ },
3222
+ headlineText: {
3223
+ ...theme.typography.bodyLarge,
3224
+ color: theme.colors.onSurface
3225
+ },
3226
+ supportingText: {
3227
+ ...theme.typography.bodyMedium,
3228
+ color: theme.colors.onSurfaceVariant
3229
+ },
3230
+ trailingBlock: {
3231
+ marginStart: theme.spacing.md,
3232
+ alignItems: "flex-end"
3233
+ },
3234
+ trailingSupportingText: {
3235
+ ...theme.typography.labelSmall,
3236
+ color: theme.colors.onSurfaceVariant
3237
+ }
3238
+ });
3239
+ }
3240
+ function createDividerStyles(theme, inset) {
3241
+ return import_react_native27.StyleSheet.create({
3242
+ divider: {
3243
+ height: 1,
3244
+ backgroundColor: theme.colors.outlineVariant,
3245
+ ...inset ? { marginStart: INSET_START } : void 0
3246
+ }
3247
+ });
3248
+ }
3249
+
3250
+ // src/list/List.tsx
3251
+ var import_jsx_runtime16 = require("react/jsx-runtime");
3252
+ function List({ children, style, ...props }) {
3253
+ const theme = (0, import_core15.useTheme)();
3254
+ const styles2 = (0, import_react16.useMemo)(() => createListStyles(theme), [theme]);
3255
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_native28.View, { ...props, style: [styles2.container, style], children });
3256
+ }
3257
+
3258
+ // src/list/ListItem.tsx
3259
+ var import_react17 = require("react");
3260
+ var import_react_native29 = require("react-native");
3261
+ var import_core16 = require("@onlynative/core");
3262
+ var import_jsx_runtime17 = require("react/jsx-runtime");
3263
+ function getLines(supportingText, overlineText, supportingTextNumberOfLines) {
3264
+ if (supportingText && overlineText || supportingText && supportingTextNumberOfLines && supportingTextNumberOfLines > 1) {
3265
+ return 3;
3266
+ }
3267
+ if (supportingText || overlineText) return 2;
3268
+ return 1;
3269
+ }
3270
+ function ListItem({
3271
+ headlineText,
3272
+ supportingText,
3273
+ overlineText,
3274
+ trailingSupportingText,
3275
+ leadingContent,
3276
+ trailingContent,
3277
+ onPress,
3278
+ disabled = false,
3279
+ containerColor,
3280
+ supportingTextNumberOfLines = 1,
3281
+ style,
3282
+ ...props
3283
+ }) {
3284
+ const isDisabled = Boolean(disabled);
3285
+ const isInteractive = onPress !== void 0;
3286
+ const theme = (0, import_core16.useTheme)();
3287
+ const lines = getLines(supportingText, overlineText, supportingTextNumberOfLines);
3288
+ const styles2 = (0, import_react17.useMemo)(
3289
+ () => createListItemStyles(theme, lines, containerColor),
3290
+ [theme, lines, containerColor]
3291
+ );
3292
+ const content = /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
3293
+ leadingContent != null && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_react_native29.View, { style: styles2.leadingContent, children: leadingContent }),
3294
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_react_native29.View, { style: styles2.textBlock, children: [
3295
+ overlineText != null && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_react_native29.Text, { style: styles2.overlineText, numberOfLines: 1, children: overlineText }),
3296
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_react_native29.Text, { style: styles2.headlineText, numberOfLines: 1, children: headlineText }),
3297
+ supportingText != null && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3298
+ import_react_native29.Text,
3299
+ {
3300
+ style: styles2.supportingText,
3301
+ numberOfLines: supportingTextNumberOfLines,
3302
+ children: supportingText
3303
+ }
3304
+ )
3305
+ ] }),
3306
+ (trailingContent != null || trailingSupportingText != null) && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_react_native29.View, { style: styles2.trailingBlock, children: [
3307
+ trailingSupportingText != null && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_react_native29.Text, { style: styles2.trailingSupportingText, numberOfLines: 1, children: trailingSupportingText }),
3308
+ trailingContent
3309
+ ] })
3310
+ ] });
3311
+ if (!isInteractive) {
3312
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_react_native29.View, { ...props, style: [styles2.container, style], children: content });
3313
+ }
3314
+ const resolvedStyle = (state) => [
3315
+ styles2.container,
3316
+ styles2.interactiveContainer,
3317
+ state.hovered && !state.pressed && !isDisabled ? styles2.hoveredContainer : void 0,
3318
+ state.pressed && !isDisabled ? styles2.pressedContainer : void 0,
3319
+ isDisabled ? styles2.disabledContainer : void 0,
3320
+ typeof style === "function" ? style(state) : style
3321
+ ];
3322
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3323
+ import_react_native29.Pressable,
3324
+ {
3325
+ ...props,
3326
+ role: "button",
3327
+ accessibilityState: { disabled: isDisabled },
3328
+ hitSlop: import_react_native29.Platform.OS === "web" ? void 0 : 4,
3329
+ disabled: isDisabled,
3330
+ onPress,
3331
+ style: resolvedStyle,
3332
+ children: isDisabled ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_react_native29.View, { style: styles2.disabledContentWrapper, children: content }) : content
3333
+ }
3334
+ );
3335
+ }
3336
+
3337
+ // src/list/ListDivider.tsx
3338
+ var import_react18 = require("react");
3339
+ var import_react_native30 = require("react-native");
3340
+ var import_core17 = require("@onlynative/core");
3341
+ var import_jsx_runtime18 = require("react/jsx-runtime");
3342
+ function ListDivider({
3343
+ inset = false,
3344
+ style,
3345
+ ...props
3346
+ }) {
3347
+ const theme = (0, import_core17.useTheme)();
3348
+ const styles2 = (0, import_react18.useMemo)(
3349
+ () => createDividerStyles(theme, inset),
3350
+ [theme, inset]
3351
+ );
3352
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native30.View, { ...props, style: [styles2.divider, style] });
3353
+ }
3354
+ // Annotate the CommonJS export names for ESM import in node:
3355
+ 0 && (module.exports = {
3356
+ AppBar,
3357
+ Box,
3358
+ Button,
3359
+ Card,
3360
+ Checkbox,
3361
+ Chip,
3362
+ Column,
3363
+ Grid,
3364
+ IconButton,
3365
+ Layout,
3366
+ List,
3367
+ ListDivider,
3368
+ ListItem,
3369
+ Radio,
3370
+ Row,
3371
+ Switch,
3372
+ TextField,
3373
+ Typography
3374
+ });