@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
@@ -0,0 +1,952 @@
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/appbar/index.ts
31
+ var appbar_exports = {};
32
+ __export(appbar_exports, {
33
+ AppBar: () => AppBar
34
+ });
35
+ module.exports = __toCommonJS(appbar_exports);
36
+
37
+ // src/appbar/AppBar.tsx
38
+ var import_react3 = require("react");
39
+ var import_react_native6 = require("react-native");
40
+ var import_react_native_safe_area_context = require("react-native-safe-area-context");
41
+ var import_core4 = require("@onlynative/core");
42
+
43
+ // src/icon-button/IconButton.tsx
44
+ var import_MaterialCommunityIcons = __toESM(require("@expo/vector-icons/MaterialCommunityIcons"));
45
+ var import_react = require("react");
46
+ var import_react_native2 = require("react-native");
47
+ var import_core = require("@onlynative/core");
48
+
49
+ // src/icon-button/styles.ts
50
+ var import_react_native = require("react-native");
51
+
52
+ // src/utils/color.ts
53
+ function parseHexColor(color) {
54
+ const normalized = color.replace("#", "");
55
+ if (normalized.length !== 6 && normalized.length !== 8) {
56
+ return null;
57
+ }
58
+ const r = Number.parseInt(normalized.slice(0, 2), 16);
59
+ const g = Number.parseInt(normalized.slice(2, 4), 16);
60
+ const b = Number.parseInt(normalized.slice(4, 6), 16);
61
+ if (Number.isNaN(r) || Number.isNaN(g) || Number.isNaN(b)) {
62
+ return null;
63
+ }
64
+ return { r, g, b };
65
+ }
66
+ function clampAlpha(alpha) {
67
+ return Math.max(0, Math.min(1, alpha));
68
+ }
69
+ function alphaColor(color, alpha) {
70
+ const channels = parseHexColor(color);
71
+ const boundedAlpha = clampAlpha(alpha);
72
+ if (!channels) {
73
+ return color;
74
+ }
75
+ return `rgba(${channels.r}, ${channels.g}, ${channels.b}, ${boundedAlpha})`;
76
+ }
77
+ function blendColor(base, overlay, overlayAlpha) {
78
+ const baseChannels = parseHexColor(base);
79
+ const overlayChannels = parseHexColor(overlay);
80
+ const boundedAlpha = clampAlpha(overlayAlpha);
81
+ if (!baseChannels || !overlayChannels) {
82
+ return alphaColor(overlay, boundedAlpha);
83
+ }
84
+ const r = Math.round(
85
+ (1 - boundedAlpha) * baseChannels.r + boundedAlpha * overlayChannels.r
86
+ );
87
+ const g = Math.round(
88
+ (1 - boundedAlpha) * baseChannels.g + boundedAlpha * overlayChannels.g
89
+ );
90
+ const b = Math.round(
91
+ (1 - boundedAlpha) * baseChannels.b + boundedAlpha * overlayChannels.b
92
+ );
93
+ return `rgb(${r}, ${g}, ${b})`;
94
+ }
95
+
96
+ // src/icon-button/styles.ts
97
+ function createStyles(theme) {
98
+ const disabledContainerColor = alphaColor(theme.colors.onSurface, 0.12);
99
+ const disabledOutlineColor = alphaColor(theme.colors.onSurface, 0.12);
100
+ const toggleUnselectedContainerColor = theme.colors.surfaceContainerHighest;
101
+ return import_react_native.StyleSheet.create({
102
+ container: {
103
+ borderRadius: theme.shape.cornerFull,
104
+ alignItems: "center",
105
+ justifyContent: "center",
106
+ cursor: "pointer"
107
+ },
108
+ sizeSmall: {
109
+ width: 32,
110
+ height: 32
111
+ },
112
+ sizeMedium: {
113
+ width: 40,
114
+ height: 40
115
+ },
116
+ sizeLarge: {
117
+ width: 48,
118
+ height: 48
119
+ },
120
+ colorFilled: {
121
+ backgroundColor: theme.colors.primary,
122
+ borderColor: theme.colors.primary,
123
+ borderWidth: 0
124
+ },
125
+ colorFilledToggleUnselected: {
126
+ backgroundColor: toggleUnselectedContainerColor,
127
+ borderColor: toggleUnselectedContainerColor,
128
+ borderWidth: 0
129
+ },
130
+ colorFilledToggleSelected: {
131
+ backgroundColor: theme.colors.primary,
132
+ borderColor: theme.colors.primary,
133
+ borderWidth: 0
134
+ },
135
+ colorTonal: {
136
+ backgroundColor: theme.colors.secondaryContainer,
137
+ borderColor: theme.colors.secondaryContainer,
138
+ borderWidth: 0
139
+ },
140
+ colorTonalToggleUnselected: {
141
+ backgroundColor: toggleUnselectedContainerColor,
142
+ borderColor: toggleUnselectedContainerColor,
143
+ borderWidth: 0
144
+ },
145
+ colorTonalToggleSelected: {
146
+ backgroundColor: theme.colors.secondaryContainer,
147
+ borderColor: theme.colors.secondaryContainer,
148
+ borderWidth: 0
149
+ },
150
+ colorOutlined: {
151
+ borderColor: theme.colors.outline,
152
+ borderWidth: 1
153
+ },
154
+ colorOutlinedToggleSelected: {
155
+ backgroundColor: theme.colors.inverseSurface,
156
+ borderColor: theme.colors.inverseSurface,
157
+ borderWidth: 0
158
+ },
159
+ colorStandard: {
160
+ borderWidth: 0
161
+ },
162
+ colorStandardToggleSelected: {
163
+ borderWidth: 0
164
+ },
165
+ // Hover states (M3: 8% state layer)
166
+ hoveredFilled: {
167
+ backgroundColor: blendColor(
168
+ theme.colors.primary,
169
+ theme.colors.onPrimary,
170
+ theme.stateLayer.hoveredOpacity
171
+ )
172
+ },
173
+ hoveredFilledToggleUnselected: {
174
+ backgroundColor: blendColor(
175
+ toggleUnselectedContainerColor,
176
+ theme.colors.primary,
177
+ theme.stateLayer.hoveredOpacity
178
+ )
179
+ },
180
+ hoveredFilledToggleSelected: {
181
+ backgroundColor: blendColor(
182
+ theme.colors.primary,
183
+ theme.colors.onPrimary,
184
+ theme.stateLayer.hoveredOpacity
185
+ )
186
+ },
187
+ hoveredTonal: {
188
+ backgroundColor: blendColor(
189
+ theme.colors.secondaryContainer,
190
+ theme.colors.onSecondaryContainer,
191
+ theme.stateLayer.hoveredOpacity
192
+ )
193
+ },
194
+ hoveredTonalToggleUnselected: {
195
+ backgroundColor: blendColor(
196
+ toggleUnselectedContainerColor,
197
+ theme.colors.onSurfaceVariant,
198
+ theme.stateLayer.hoveredOpacity
199
+ )
200
+ },
201
+ hoveredTonalToggleSelected: {
202
+ backgroundColor: blendColor(
203
+ theme.colors.secondaryContainer,
204
+ theme.colors.onSecondaryContainer,
205
+ theme.stateLayer.hoveredOpacity
206
+ )
207
+ },
208
+ hoveredOutlined: {
209
+ backgroundColor: alphaColor(
210
+ theme.colors.onSurfaceVariant,
211
+ theme.stateLayer.hoveredOpacity
212
+ )
213
+ },
214
+ hoveredOutlinedToggleUnselected: {
215
+ backgroundColor: alphaColor(
216
+ theme.colors.onSurfaceVariant,
217
+ theme.stateLayer.hoveredOpacity
218
+ )
219
+ },
220
+ hoveredOutlinedToggleSelected: {
221
+ backgroundColor: blendColor(
222
+ theme.colors.inverseSurface,
223
+ theme.colors.inverseOnSurface,
224
+ theme.stateLayer.hoveredOpacity
225
+ )
226
+ },
227
+ hoveredStandard: {
228
+ backgroundColor: alphaColor(
229
+ theme.colors.onSurfaceVariant,
230
+ theme.stateLayer.hoveredOpacity
231
+ )
232
+ },
233
+ hoveredStandardToggleUnselected: {
234
+ backgroundColor: alphaColor(
235
+ theme.colors.onSurfaceVariant,
236
+ theme.stateLayer.hoveredOpacity
237
+ )
238
+ },
239
+ hoveredStandardToggleSelected: {
240
+ backgroundColor: alphaColor(
241
+ theme.colors.primary,
242
+ theme.stateLayer.hoveredOpacity
243
+ )
244
+ },
245
+ // Pressed states (M3: 12% state layer)
246
+ pressedFilled: {
247
+ backgroundColor: blendColor(
248
+ theme.colors.primary,
249
+ theme.colors.onPrimary,
250
+ theme.stateLayer.pressedOpacity
251
+ )
252
+ },
253
+ pressedFilledToggleUnselected: {
254
+ backgroundColor: blendColor(
255
+ toggleUnselectedContainerColor,
256
+ theme.colors.primary,
257
+ theme.stateLayer.pressedOpacity
258
+ )
259
+ },
260
+ pressedFilledToggleSelected: {
261
+ backgroundColor: blendColor(
262
+ theme.colors.primary,
263
+ theme.colors.onPrimary,
264
+ theme.stateLayer.pressedOpacity
265
+ )
266
+ },
267
+ pressedTonal: {
268
+ backgroundColor: blendColor(
269
+ theme.colors.secondaryContainer,
270
+ theme.colors.onSecondaryContainer,
271
+ theme.stateLayer.pressedOpacity
272
+ )
273
+ },
274
+ pressedTonalToggleUnselected: {
275
+ backgroundColor: blendColor(
276
+ toggleUnselectedContainerColor,
277
+ theme.colors.onSurfaceVariant,
278
+ theme.stateLayer.pressedOpacity
279
+ )
280
+ },
281
+ pressedTonalToggleSelected: {
282
+ backgroundColor: blendColor(
283
+ theme.colors.secondaryContainer,
284
+ theme.colors.onSecondaryContainer,
285
+ theme.stateLayer.pressedOpacity
286
+ )
287
+ },
288
+ pressedOutlined: {
289
+ backgroundColor: alphaColor(
290
+ theme.colors.onSurfaceVariant,
291
+ theme.stateLayer.pressedOpacity
292
+ )
293
+ },
294
+ pressedOutlinedToggleUnselected: {
295
+ backgroundColor: alphaColor(
296
+ theme.colors.onSurfaceVariant,
297
+ theme.stateLayer.pressedOpacity
298
+ )
299
+ },
300
+ pressedOutlinedToggleSelected: {
301
+ backgroundColor: blendColor(
302
+ theme.colors.inverseSurface,
303
+ theme.colors.inverseOnSurface,
304
+ theme.stateLayer.pressedOpacity
305
+ )
306
+ },
307
+ pressedStandard: {
308
+ backgroundColor: alphaColor(
309
+ theme.colors.onSurfaceVariant,
310
+ theme.stateLayer.pressedOpacity
311
+ )
312
+ },
313
+ pressedStandardToggleUnselected: {
314
+ backgroundColor: alphaColor(
315
+ theme.colors.onSurfaceVariant,
316
+ theme.stateLayer.pressedOpacity
317
+ )
318
+ },
319
+ pressedStandardToggleSelected: {
320
+ backgroundColor: alphaColor(
321
+ theme.colors.primary,
322
+ theme.stateLayer.pressedOpacity
323
+ )
324
+ },
325
+ // Disabled states
326
+ disabledFilled: {
327
+ backgroundColor: disabledContainerColor,
328
+ borderColor: disabledContainerColor,
329
+ cursor: "auto"
330
+ },
331
+ disabledTonal: {
332
+ backgroundColor: disabledContainerColor,
333
+ borderColor: disabledContainerColor,
334
+ cursor: "auto"
335
+ },
336
+ disabledOutlined: {
337
+ backgroundColor: "transparent",
338
+ borderColor: disabledOutlineColor,
339
+ cursor: "auto"
340
+ },
341
+ disabledStandard: {
342
+ backgroundColor: "transparent",
343
+ borderColor: "transparent",
344
+ cursor: "auto"
345
+ }
346
+ });
347
+ }
348
+
349
+ // src/icon-button/IconButton.tsx
350
+ var import_jsx_runtime = require("react/jsx-runtime");
351
+ function getIconColor(variant, theme, disabled, isToggle, selected) {
352
+ if (disabled) {
353
+ return alphaColor(theme.colors.onSurface, 0.38);
354
+ }
355
+ if (isToggle) {
356
+ if (variant === "filled") {
357
+ return selected ? theme.colors.onPrimary : theme.colors.primary;
358
+ }
359
+ if (variant === "tonal") {
360
+ return selected ? theme.colors.onSecondaryContainer : theme.colors.onSurfaceVariant;
361
+ }
362
+ if (variant === "outlined") {
363
+ return selected ? theme.colors.inverseOnSurface : theme.colors.onSurfaceVariant;
364
+ }
365
+ return selected ? theme.colors.primary : theme.colors.onSurfaceVariant;
366
+ }
367
+ if (variant === "filled") {
368
+ return theme.colors.onPrimary;
369
+ }
370
+ if (variant === "tonal") {
371
+ return theme.colors.onSecondaryContainer;
372
+ }
373
+ return theme.colors.onSurfaceVariant;
374
+ }
375
+ function getColorStyle(styles, variant, isToggle, selected) {
376
+ if (isToggle) {
377
+ if (variant === "tonal") {
378
+ return selected ? styles.colorTonalToggleSelected : styles.colorTonalToggleUnselected;
379
+ }
380
+ if (variant === "outlined") {
381
+ return selected ? styles.colorOutlinedToggleSelected : styles.colorOutlined;
382
+ }
383
+ if (variant === "standard") {
384
+ return selected ? styles.colorStandardToggleSelected : styles.colorStandard;
385
+ }
386
+ return selected ? styles.colorFilledToggleSelected : styles.colorFilledToggleUnselected;
387
+ }
388
+ if (variant === "tonal") {
389
+ return styles.colorTonal;
390
+ }
391
+ if (variant === "outlined") {
392
+ return styles.colorOutlined;
393
+ }
394
+ if (variant === "standard") {
395
+ return styles.colorStandard;
396
+ }
397
+ return styles.colorFilled;
398
+ }
399
+ function getSizeStyle(styles, size) {
400
+ if (size === "small") {
401
+ return styles.sizeSmall;
402
+ }
403
+ if (size === "large") {
404
+ return styles.sizeLarge;
405
+ }
406
+ return styles.sizeMedium;
407
+ }
408
+ function getIconPixelSize(size) {
409
+ if (size === "small") {
410
+ return 18;
411
+ }
412
+ if (size === "large") {
413
+ return 28;
414
+ }
415
+ return 24;
416
+ }
417
+ function getDefaultHitSlop(size) {
418
+ if (size === "small") {
419
+ return 8;
420
+ }
421
+ if (size === "large") {
422
+ return 0;
423
+ }
424
+ return 4;
425
+ }
426
+ function getHoveredStyle(styles, variant, isToggle, selected) {
427
+ if (isToggle) {
428
+ if (variant === "tonal") {
429
+ return selected ? styles.hoveredTonalToggleSelected : styles.hoveredTonalToggleUnselected;
430
+ }
431
+ if (variant === "outlined") {
432
+ return selected ? styles.hoveredOutlinedToggleSelected : styles.hoveredOutlinedToggleUnselected;
433
+ }
434
+ if (variant === "standard") {
435
+ return selected ? styles.hoveredStandardToggleSelected : styles.hoveredStandardToggleUnselected;
436
+ }
437
+ return selected ? styles.hoveredFilledToggleSelected : styles.hoveredFilledToggleUnselected;
438
+ }
439
+ if (variant === "tonal") {
440
+ return styles.hoveredTonal;
441
+ }
442
+ if (variant === "outlined") {
443
+ return styles.hoveredOutlined;
444
+ }
445
+ if (variant === "standard") {
446
+ return styles.hoveredStandard;
447
+ }
448
+ return styles.hoveredFilled;
449
+ }
450
+ function getPressedStyle(styles, variant, isToggle, selected) {
451
+ if (isToggle) {
452
+ if (variant === "tonal") {
453
+ return selected ? styles.pressedTonalToggleSelected : styles.pressedTonalToggleUnselected;
454
+ }
455
+ if (variant === "outlined") {
456
+ return selected ? styles.pressedOutlinedToggleSelected : styles.pressedOutlinedToggleUnselected;
457
+ }
458
+ if (variant === "standard") {
459
+ return selected ? styles.pressedStandardToggleSelected : styles.pressedStandardToggleUnselected;
460
+ }
461
+ return selected ? styles.pressedFilledToggleSelected : styles.pressedFilledToggleUnselected;
462
+ }
463
+ if (variant === "tonal") {
464
+ return styles.pressedTonal;
465
+ }
466
+ if (variant === "outlined") {
467
+ return styles.pressedOutlined;
468
+ }
469
+ if (variant === "standard") {
470
+ return styles.pressedStandard;
471
+ }
472
+ return styles.pressedFilled;
473
+ }
474
+ function getDisabledStyle(styles, variant) {
475
+ if (variant === "tonal") {
476
+ return styles.disabledTonal;
477
+ }
478
+ if (variant === "outlined") {
479
+ return styles.disabledOutlined;
480
+ }
481
+ if (variant === "standard") {
482
+ return styles.disabledStandard;
483
+ }
484
+ return styles.disabledFilled;
485
+ }
486
+ function IconButton({
487
+ icon,
488
+ selectedIcon,
489
+ iconColor,
490
+ contentColor,
491
+ containerColor,
492
+ style,
493
+ onPress,
494
+ disabled = false,
495
+ variant = "filled",
496
+ selected,
497
+ size = "medium",
498
+ hitSlop,
499
+ accessibilityLabel,
500
+ ...props
501
+ }) {
502
+ var _a;
503
+ const theme = (0, import_core.useTheme)();
504
+ const styles = (0, import_react.useMemo)(() => createStyles(theme), [theme]);
505
+ const isDisabled = Boolean(disabled);
506
+ const isToggle = selected !== void 0;
507
+ const isSelected = Boolean(selected);
508
+ const resolvedIconColor = (_a = contentColor != null ? contentColor : iconColor) != null ? _a : getIconColor(variant, theme, isDisabled, isToggle, isSelected);
509
+ const displayIcon = isToggle && isSelected && selectedIcon ? selectedIcon : icon;
510
+ const iconPixelSize = getIconPixelSize(size);
511
+ const accessibilityState = isToggle ? { disabled: isDisabled, selected: isSelected } : { disabled: isDisabled };
512
+ const containerOverrides = (0, import_react.useMemo)(() => {
513
+ if (!containerColor) return null;
514
+ const overlay = resolvedIconColor;
515
+ return {
516
+ base: {
517
+ backgroundColor: containerColor,
518
+ borderColor: containerColor,
519
+ borderWidth: 0
520
+ },
521
+ hovered: {
522
+ backgroundColor: blendColor(
523
+ containerColor,
524
+ overlay,
525
+ theme.stateLayer.hoveredOpacity
526
+ )
527
+ },
528
+ pressed: {
529
+ backgroundColor: blendColor(
530
+ containerColor,
531
+ overlay,
532
+ theme.stateLayer.pressedOpacity
533
+ )
534
+ }
535
+ };
536
+ }, [containerColor, resolvedIconColor, theme.stateLayer]);
537
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
538
+ import_react_native2.Pressable,
539
+ {
540
+ ...props,
541
+ accessibilityRole: "button",
542
+ accessibilityLabel,
543
+ accessibilityState,
544
+ disabled: isDisabled,
545
+ hitSlop: hitSlop != null ? hitSlop : getDefaultHitSlop(size),
546
+ onPress,
547
+ style: ({
548
+ pressed,
549
+ hovered
550
+ }) => {
551
+ const base = [
552
+ styles.container,
553
+ getSizeStyle(styles, size),
554
+ getColorStyle(styles, variant, isToggle, isSelected),
555
+ containerOverrides == null ? void 0 : containerOverrides.base,
556
+ hovered && !pressed && !isDisabled ? containerOverrides ? containerOverrides.hovered : getHoveredStyle(styles, variant, isToggle, isSelected) : void 0,
557
+ pressed && !isDisabled ? containerOverrides ? containerOverrides.pressed : getPressedStyle(styles, variant, isToggle, isSelected) : void 0,
558
+ isDisabled ? getDisabledStyle(styles, variant) : void 0
559
+ ];
560
+ if (typeof style === "function") {
561
+ base.push(style({ pressed }));
562
+ } else if (style) {
563
+ base.push(style);
564
+ }
565
+ return base;
566
+ },
567
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
568
+ import_MaterialCommunityIcons.default,
569
+ {
570
+ name: displayIcon,
571
+ size: iconPixelSize,
572
+ color: resolvedIconColor
573
+ }
574
+ )
575
+ }
576
+ );
577
+ }
578
+
579
+ // src/typography/Typography.tsx
580
+ var import_react2 = require("react");
581
+ var import_react_native3 = require("react-native");
582
+ var import_core2 = require("@onlynative/core");
583
+ var import_jsx_runtime2 = require("react/jsx-runtime");
584
+ var HEADING_VARIANTS = /* @__PURE__ */ new Set([
585
+ "displayLarge",
586
+ "displayMedium",
587
+ "displaySmall",
588
+ "headlineLarge",
589
+ "headlineMedium",
590
+ "headlineSmall"
591
+ ]);
592
+ function Typography({
593
+ children,
594
+ variant = "bodyMedium",
595
+ color,
596
+ style,
597
+ as: Component = import_react_native3.Text,
598
+ accessibilityRole,
599
+ ...textProps
600
+ }) {
601
+ const theme = (0, import_core2.useTheme)();
602
+ const typographyStyle = theme.typography[variant];
603
+ const colorStyle = (0, import_react2.useMemo)(
604
+ () => ({ color: color != null ? color : theme.colors.onSurface }),
605
+ [color, theme.colors.onSurface]
606
+ );
607
+ const resolvedRole = accessibilityRole != null ? accessibilityRole : HEADING_VARIANTS.has(variant) ? "header" : void 0;
608
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
609
+ Component,
610
+ {
611
+ ...textProps,
612
+ accessibilityRole: resolvedRole,
613
+ style: [typographyStyle, colorStyle, style],
614
+ children
615
+ }
616
+ );
617
+ }
618
+
619
+ // src/utils/rtl.ts
620
+ var import_react_native4 = require("react-native");
621
+ function selectRTL(ltr, rtl) {
622
+ return import_react_native4.I18nManager.isRTL ? rtl : ltr;
623
+ }
624
+
625
+ // src/appbar/styles.ts
626
+ var import_react_native5 = require("react-native");
627
+ var import_core3 = require("@onlynative/core");
628
+ function createStyles2(theme) {
629
+ var _a;
630
+ const topAppBar = (_a = theme.topAppBar) != null ? _a : import_core3.defaultTopAppBarTokens;
631
+ return import_react_native5.StyleSheet.create({
632
+ root: {
633
+ backgroundColor: theme.colors.surface
634
+ },
635
+ safeArea: {
636
+ backgroundColor: theme.colors.surface
637
+ },
638
+ elevatedRoot: {
639
+ backgroundColor: theme.colors.surfaceContainer
640
+ },
641
+ elevatedSafeArea: {
642
+ backgroundColor: theme.colors.surfaceContainer
643
+ },
644
+ smallContainer: {
645
+ height: topAppBar.smallContainerHeight,
646
+ position: "relative"
647
+ },
648
+ mediumContainer: {
649
+ height: topAppBar.mediumContainerHeight
650
+ },
651
+ largeContainer: {
652
+ height: topAppBar.largeContainerHeight
653
+ },
654
+ expandedContainer: {
655
+ position: "relative"
656
+ },
657
+ topRow: {
658
+ height: topAppBar.topRowHeight,
659
+ paddingHorizontal: topAppBar.horizontalPadding,
660
+ flexDirection: "row",
661
+ alignItems: "center"
662
+ },
663
+ expandedTitleContainer: {
664
+ flex: 1,
665
+ justifyContent: "flex-end",
666
+ minWidth: 0,
667
+ paddingEnd: theme.spacing.md,
668
+ pointerEvents: "none"
669
+ },
670
+ topRowSpacer: {
671
+ flex: 1
672
+ },
673
+ sideSlot: {
674
+ flexDirection: "row",
675
+ alignItems: "center",
676
+ minHeight: topAppBar.sideSlotMinHeight
677
+ },
678
+ actionsRow: {
679
+ flexDirection: "row",
680
+ alignItems: "center"
681
+ },
682
+ iconFrame: {
683
+ width: topAppBar.iconFrameSize,
684
+ height: topAppBar.iconFrameSize,
685
+ alignItems: "center",
686
+ justifyContent: "center"
687
+ },
688
+ overlayTitleContainer: {
689
+ position: "absolute",
690
+ top: 0,
691
+ bottom: 0,
692
+ justifyContent: "center",
693
+ minWidth: 0,
694
+ pointerEvents: "none"
695
+ },
696
+ centeredTitle: {
697
+ textAlign: "center"
698
+ },
699
+ startAlignedTitle: {
700
+ textAlign: "auto"
701
+ },
702
+ mediumTitlePadding: {
703
+ paddingBottom: topAppBar.mediumTitleBottomPadding
704
+ },
705
+ largeTitlePadding: {
706
+ paddingBottom: topAppBar.largeTitleBottomPadding
707
+ },
708
+ title: {
709
+ flexShrink: 1,
710
+ maxWidth: "100%",
711
+ includeFontPadding: false,
712
+ textAlignVertical: "center"
713
+ }
714
+ });
715
+ }
716
+
717
+ // src/appbar/AppBar.tsx
718
+ var import_jsx_runtime3 = require("react/jsx-runtime");
719
+ function getBackIcon() {
720
+ if (import_react_native6.Platform.OS === "ios") {
721
+ return selectRTL("chevron-left", "chevron-right");
722
+ }
723
+ return selectRTL("arrow-left", "arrow-right");
724
+ }
725
+ var titleVariantBySize = {
726
+ small: "titleLarge",
727
+ medium: "headlineSmall",
728
+ large: "headlineMedium"
729
+ };
730
+ var APP_BAR_TITLE_TEXT_PROPS = {
731
+ numberOfLines: 1,
732
+ ellipsizeMode: "tail",
733
+ accessibilityRole: "header"
734
+ };
735
+ function resolveSize(variant) {
736
+ if (variant === "medium" || variant === "large") {
737
+ return variant;
738
+ }
739
+ return "small";
740
+ }
741
+ function getSizeStyle2(styles, size) {
742
+ if (size === "large") {
743
+ return styles.largeContainer;
744
+ }
745
+ return styles.mediumContainer;
746
+ }
747
+ function withTopInset(enabled, content, style) {
748
+ if (enabled) {
749
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_safe_area_context.SafeAreaView, { edges: ["top"], style, children: content });
750
+ }
751
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native6.View, { style, children: content });
752
+ }
753
+ function measureWidth(event) {
754
+ return Math.round(event.nativeEvent.layout.width);
755
+ }
756
+ function AppBar({
757
+ title,
758
+ variant = "small",
759
+ canGoBack = false,
760
+ onBackPress,
761
+ insetTop = false,
762
+ elevated = false,
763
+ leading,
764
+ trailing,
765
+ actions,
766
+ containerColor,
767
+ contentColor,
768
+ titleStyle,
769
+ style
770
+ }) {
771
+ var _a;
772
+ const theme = (0, import_core4.useTheme)();
773
+ const topAppBar = (_a = theme.topAppBar) != null ? _a : import_core4.defaultTopAppBarTokens;
774
+ const styles = (0, import_react3.useMemo)(() => createStyles2(theme), [theme]);
775
+ const [leadingWidth, setLeadingWidth] = (0, import_react3.useState)(0);
776
+ const [actionsWidth, setActionsWidth] = (0, import_react3.useState)(0);
777
+ const titleColorStyle = (0, import_react3.useMemo)(
778
+ () => ({ color: contentColor != null ? contentColor : theme.colors.onSurface }),
779
+ [contentColor, theme.colors.onSurface]
780
+ );
781
+ const size = resolveSize(variant);
782
+ const titleVariant = titleVariantBySize[size];
783
+ const isCenterAligned = variant === "center-aligned";
784
+ const isExpanded = size !== "small";
785
+ const titleStartInset = topAppBar.horizontalPadding + Math.max(topAppBar.titleStartInset, leadingWidth);
786
+ const compactTitleEndInset = topAppBar.horizontalPadding + actionsWidth;
787
+ const centeredSideInset = topAppBar.horizontalPadding + Math.max(leadingWidth, actionsWidth);
788
+ const expandedTitleInsetStyle = (0, import_react3.useMemo)(
789
+ () => ({ paddingStart: titleStartInset }),
790
+ [titleStartInset]
791
+ );
792
+ const overlayTitleInsetStyle = (0, import_react3.useMemo)(
793
+ () => isCenterAligned ? { start: centeredSideInset, end: centeredSideInset } : { start: titleStartInset, end: compactTitleEndInset },
794
+ [centeredSideInset, compactTitleEndInset, isCenterAligned, titleStartInset]
795
+ );
796
+ const leadingContent = (0, import_react3.useMemo)(() => {
797
+ if (leading) {
798
+ return leading;
799
+ }
800
+ if (!canGoBack) {
801
+ return null;
802
+ }
803
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native6.View, { style: styles.iconFrame, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
804
+ IconButton,
805
+ {
806
+ icon: getBackIcon(),
807
+ size: "medium",
808
+ variant: "standard",
809
+ iconColor: contentColor != null ? contentColor : theme.colors.onSurface,
810
+ accessibilityLabel: "Go back",
811
+ onPress: onBackPress
812
+ }
813
+ ) });
814
+ }, [
815
+ canGoBack,
816
+ contentColor,
817
+ leading,
818
+ onBackPress,
819
+ styles.iconFrame,
820
+ theme.colors.onSurface
821
+ ]);
822
+ const actionsContent = (0, import_react3.useMemo)(() => {
823
+ if (trailing) {
824
+ return trailing;
825
+ }
826
+ if (!actions || actions.length === 0) {
827
+ return null;
828
+ }
829
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native6.View, { style: styles.actionsRow, children: actions.map((action, index) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
830
+ import_react_native6.View,
831
+ {
832
+ style: styles.iconFrame,
833
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
834
+ IconButton,
835
+ {
836
+ icon: action.icon,
837
+ size: "medium",
838
+ variant: "standard",
839
+ iconColor: contentColor,
840
+ accessibilityLabel: action.accessibilityLabel,
841
+ onPress: action.onPress,
842
+ disabled: action.disabled
843
+ }
844
+ )
845
+ },
846
+ `${String(action.icon)}-${index}`
847
+ )) });
848
+ }, [actions, contentColor, styles.actionsRow, styles.iconFrame, trailing]);
849
+ const onLeadingLayout = (0, import_react3.useCallback)((event) => {
850
+ const nextWidth = measureWidth(event);
851
+ setLeadingWidth((currentWidth) => {
852
+ if (currentWidth === nextWidth) {
853
+ return currentWidth;
854
+ }
855
+ return nextWidth;
856
+ });
857
+ }, []);
858
+ const onActionsLayout = (0, import_react3.useCallback)((event) => {
859
+ const nextWidth = measureWidth(event);
860
+ setActionsWidth((currentWidth) => {
861
+ if (currentWidth === nextWidth) {
862
+ return currentWidth;
863
+ }
864
+ return nextWidth;
865
+ });
866
+ }, []);
867
+ const topRow = /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native6.View, { style: styles.topRow, children: [
868
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
869
+ import_react_native6.View,
870
+ {
871
+ collapsable: false,
872
+ onLayout: onLeadingLayout,
873
+ style: styles.sideSlot,
874
+ children: leadingContent
875
+ }
876
+ ),
877
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native6.View, { style: styles.topRowSpacer }),
878
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
879
+ import_react_native6.View,
880
+ {
881
+ collapsable: false,
882
+ onLayout: onActionsLayout,
883
+ style: styles.sideSlot,
884
+ children: actionsContent
885
+ }
886
+ )
887
+ ] });
888
+ const containerOverride = containerColor ? { backgroundColor: containerColor } : void 0;
889
+ const rootStyle = [
890
+ styles.root,
891
+ elevated ? styles.elevatedRoot : void 0,
892
+ containerOverride,
893
+ style
894
+ ];
895
+ const safeAreaStyle = [
896
+ styles.safeArea,
897
+ elevated ? styles.elevatedSafeArea : void 0,
898
+ containerOverride
899
+ ];
900
+ if (isExpanded) {
901
+ const content2 = /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native6.View, { style: [styles.expandedContainer, getSizeStyle2(styles, size)], children: [
902
+ topRow,
903
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
904
+ import_react_native6.View,
905
+ {
906
+ style: [
907
+ styles.expandedTitleContainer,
908
+ size === "large" ? styles.largeTitlePadding : styles.mediumTitlePadding,
909
+ expandedTitleInsetStyle
910
+ ],
911
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
912
+ Typography,
913
+ {
914
+ ...APP_BAR_TITLE_TEXT_PROPS,
915
+ variant: titleVariant,
916
+ style: [
917
+ styles.title,
918
+ titleColorStyle,
919
+ styles.startAlignedTitle,
920
+ titleStyle
921
+ ],
922
+ children: title
923
+ }
924
+ )
925
+ }
926
+ )
927
+ ] });
928
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native6.View, { style: rootStyle, children: withTopInset(insetTop, content2, safeAreaStyle) });
929
+ }
930
+ const content = /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native6.View, { style: styles.smallContainer, children: [
931
+ topRow,
932
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native6.View, { style: [styles.overlayTitleContainer, overlayTitleInsetStyle], children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
933
+ Typography,
934
+ {
935
+ ...APP_BAR_TITLE_TEXT_PROPS,
936
+ variant: titleVariant,
937
+ style: [
938
+ styles.title,
939
+ titleColorStyle,
940
+ isCenterAligned ? styles.centeredTitle : styles.startAlignedTitle,
941
+ titleStyle
942
+ ],
943
+ children: title
944
+ }
945
+ ) })
946
+ ] });
947
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native6.View, { style: rootStyle, children: withTopInset(insetTop, content, safeAreaStyle) });
948
+ }
949
+ // Annotate the CommonJS export names for ESM import in node:
950
+ 0 && (module.exports = {
951
+ AppBar
952
+ });