@muja-ui/native 0.3.0 → 0.4.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.
- package/README.md +44 -10
- package/dist/index.cjs +467 -137
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +110 -18
- package/dist/index.d.ts +110 -18
- package/dist/index.js +465 -140
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.cjs
CHANGED
|
@@ -14,6 +14,25 @@ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
|
14
14
|
var Svg__default = /*#__PURE__*/_interopDefault(Svg);
|
|
15
15
|
|
|
16
16
|
// src/components/Box.tsx
|
|
17
|
+
function isIOS() {
|
|
18
|
+
return reactNative.Platform.OS === "ios";
|
|
19
|
+
}
|
|
20
|
+
var iosThemeOverride = {
|
|
21
|
+
typography: {
|
|
22
|
+
fontSize: { xs: 13, sm: 15, md: 17, lg: 20, xl: 22, "2xl": 28, "3xl": 34, "4xl": 40 }
|
|
23
|
+
},
|
|
24
|
+
radius: { sm: 6, md: 10, lg: 12, xl: 14, "2xl": 20 }
|
|
25
|
+
};
|
|
26
|
+
function adaptThemeToPlatform(theme) {
|
|
27
|
+
return isIOS() ? core.createTheme(theme, iosThemeOverride) : theme;
|
|
28
|
+
}
|
|
29
|
+
var IOS_PRESSED_OPACITY = 0.6;
|
|
30
|
+
var sheetSpring = {
|
|
31
|
+
stiffness: 320,
|
|
32
|
+
damping: 34,
|
|
33
|
+
mass: 1,
|
|
34
|
+
overshootClamping: true
|
|
35
|
+
};
|
|
17
36
|
var ThemeContext = react.createContext(null);
|
|
18
37
|
function ThemeProvider({
|
|
19
38
|
theme = core.lightTheme,
|
|
@@ -21,6 +40,7 @@ function ThemeProvider({
|
|
|
21
40
|
defaultColorMode = "system",
|
|
22
41
|
colorMode: colorModeProp,
|
|
23
42
|
onColorModeChange,
|
|
43
|
+
platformAdaptive = true,
|
|
24
44
|
children
|
|
25
45
|
}) {
|
|
26
46
|
const [uncontrolledMode, setUncontrolledMode] = react.useState(defaultColorMode);
|
|
@@ -37,15 +57,20 @@ function ThemeProvider({
|
|
|
37
57
|
const toggleColorMode = react.useCallback(() => {
|
|
38
58
|
setColorMode(resolvedColorMode === "dark" ? "light" : "dark");
|
|
39
59
|
}, [resolvedColorMode, setColorMode]);
|
|
60
|
+
const activeTheme = resolvedColorMode === "dark" ? darkTheme2 : theme;
|
|
61
|
+
const renderedTheme = react.useMemo(
|
|
62
|
+
() => platformAdaptive ? adaptThemeToPlatform(activeTheme) : activeTheme,
|
|
63
|
+
[activeTheme, platformAdaptive]
|
|
64
|
+
);
|
|
40
65
|
const value = react.useMemo(
|
|
41
66
|
() => ({
|
|
42
|
-
theme:
|
|
67
|
+
theme: renderedTheme,
|
|
43
68
|
colorMode,
|
|
44
69
|
resolvedColorMode,
|
|
45
70
|
setColorMode,
|
|
46
71
|
toggleColorMode
|
|
47
72
|
}),
|
|
48
|
-
[
|
|
73
|
+
[renderedTheme, colorMode, resolvedColorMode, setColorMode, toggleColorMode]
|
|
49
74
|
);
|
|
50
75
|
return /* @__PURE__ */ jsxRuntime.jsx(ThemeContext.Provider, { value, children });
|
|
51
76
|
}
|
|
@@ -204,6 +229,50 @@ function Divider({ orientation = "horizontal", color = "border", style }) {
|
|
|
204
229
|
}
|
|
205
230
|
);
|
|
206
231
|
}
|
|
232
|
+
var SYSTEM_SANS = /* @__PURE__ */ new Set([
|
|
233
|
+
"-apple-system",
|
|
234
|
+
"blinkmacsystemfont",
|
|
235
|
+
"system-ui",
|
|
236
|
+
"ui-sans-serif",
|
|
237
|
+
"ui-rounded",
|
|
238
|
+
"sans-serif",
|
|
239
|
+
"system",
|
|
240
|
+
"roboto"
|
|
241
|
+
]);
|
|
242
|
+
var SYSTEM_MONO = /* @__PURE__ */ new Set(["ui-monospace", "monospace"]);
|
|
243
|
+
var SYSTEM_SERIF = /* @__PURE__ */ new Set(["ui-serif", "serif"]);
|
|
244
|
+
var IOS_ONLY = /* @__PURE__ */ new Set([
|
|
245
|
+
"helvetica neue",
|
|
246
|
+
"georgia",
|
|
247
|
+
"menlo",
|
|
248
|
+
"times new roman",
|
|
249
|
+
"times",
|
|
250
|
+
"arial"
|
|
251
|
+
]);
|
|
252
|
+
var NEVER_INSTALLED = /* @__PURE__ */ new Set([
|
|
253
|
+
"segoe ui",
|
|
254
|
+
"sfmono-regular",
|
|
255
|
+
"sf mono",
|
|
256
|
+
"liberation mono",
|
|
257
|
+
"consolas",
|
|
258
|
+
"cambria"
|
|
259
|
+
]);
|
|
260
|
+
function nativeFontFamily(stack) {
|
|
261
|
+
if (!stack) return void 0;
|
|
262
|
+
const ios = reactNative.Platform.OS === "ios";
|
|
263
|
+
for (const raw of stack.split(",")) {
|
|
264
|
+
const name = raw.trim().replace(/^['"]|['"]$/g, "");
|
|
265
|
+
if (!name) continue;
|
|
266
|
+
const key = name.toLowerCase();
|
|
267
|
+
if (SYSTEM_SANS.has(key)) return void 0;
|
|
268
|
+
if (SYSTEM_MONO.has(key)) return ios ? "Menlo" : "monospace";
|
|
269
|
+
if (SYSTEM_SERIF.has(key)) return ios ? "Georgia" : "serif";
|
|
270
|
+
if (NEVER_INSTALLED.has(key)) continue;
|
|
271
|
+
if (!ios && IOS_ONLY.has(key)) continue;
|
|
272
|
+
return name;
|
|
273
|
+
}
|
|
274
|
+
return void 0;
|
|
275
|
+
}
|
|
207
276
|
var Text = react.forwardRef(function Text2(props, ref) {
|
|
208
277
|
const theme = useTheme();
|
|
209
278
|
const {
|
|
@@ -219,13 +288,10 @@ var Text = react.forwardRef(function Text2(props, ref) {
|
|
|
219
288
|
numberOfLines,
|
|
220
289
|
...restProps
|
|
221
290
|
} = props;
|
|
222
|
-
const { style: tokenStyle, rest } = splitStyleProps(
|
|
223
|
-
restProps,
|
|
224
|
-
theme
|
|
225
|
-
);
|
|
291
|
+
const { style: tokenStyle, rest } = splitStyleProps(restProps, theme);
|
|
226
292
|
const fontSize = theme.typography.fontSize[size];
|
|
227
293
|
const textStyle = {
|
|
228
|
-
fontFamily: theme.typography.fontFamily[family],
|
|
294
|
+
fontFamily: nativeFontFamily(theme.typography.fontFamily[family]),
|
|
229
295
|
fontSize,
|
|
230
296
|
color: theme.colors[color],
|
|
231
297
|
fontWeight: weight ? theme.typography.fontWeight[weight] : void 0,
|
|
@@ -252,7 +318,8 @@ var defaultSize = {
|
|
|
252
318
|
5: "md",
|
|
253
319
|
6: "sm"
|
|
254
320
|
};
|
|
255
|
-
var Heading = react.forwardRef(function Heading2({ level = 2, size, weight
|
|
321
|
+
var Heading = react.forwardRef(function Heading2({ level = 2, size, weight, leading = "tight", ...rest }, ref) {
|
|
322
|
+
const resolvedWeight = weight ?? (isIOS() && level <= 2 ? "bold" : "semibold");
|
|
256
323
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
257
324
|
Text,
|
|
258
325
|
{
|
|
@@ -260,7 +327,7 @@ var Heading = react.forwardRef(function Heading2({ level = 2, size, weight = "se
|
|
|
260
327
|
accessibilityRole: "header",
|
|
261
328
|
"aria-level": level,
|
|
262
329
|
size: size ?? defaultSize[level],
|
|
263
|
-
weight,
|
|
330
|
+
weight: resolvedWeight,
|
|
264
331
|
leading,
|
|
265
332
|
...rest
|
|
266
333
|
}
|
|
@@ -313,6 +380,7 @@ function Icon({
|
|
|
313
380
|
// src/system/variants.ts
|
|
314
381
|
function variantColors(variant, theme) {
|
|
315
382
|
const { colors, borderWidth } = theme;
|
|
383
|
+
const ios = isIOS();
|
|
316
384
|
switch (variant) {
|
|
317
385
|
case "primary":
|
|
318
386
|
return {
|
|
@@ -339,6 +407,13 @@ function variantColors(variant, theme) {
|
|
|
339
407
|
foreground: "onDanger"
|
|
340
408
|
};
|
|
341
409
|
case "outline":
|
|
410
|
+
if (ios) {
|
|
411
|
+
return {
|
|
412
|
+
background: colors.primarySubtle,
|
|
413
|
+
backgroundPressed: colors.primarySubtleHover,
|
|
414
|
+
foreground: "primaryText"
|
|
415
|
+
};
|
|
416
|
+
}
|
|
342
417
|
return {
|
|
343
418
|
background: "transparent",
|
|
344
419
|
backgroundPressed: colors.surfaceActive,
|
|
@@ -349,8 +424,8 @@ function variantColors(variant, theme) {
|
|
|
349
424
|
case "ghost":
|
|
350
425
|
return {
|
|
351
426
|
background: "transparent",
|
|
352
|
-
backgroundPressed: colors.surfaceActive,
|
|
353
|
-
foreground: "text"
|
|
427
|
+
backgroundPressed: ios ? "transparent" : colors.surfaceActive,
|
|
428
|
+
foreground: ios ? "primaryText" : "text"
|
|
354
429
|
};
|
|
355
430
|
case "link":
|
|
356
431
|
return {
|
|
@@ -361,6 +436,10 @@ function variantColors(variant, theme) {
|
|
|
361
436
|
};
|
|
362
437
|
}
|
|
363
438
|
}
|
|
439
|
+
function pressFeedback(pressed, colors) {
|
|
440
|
+
if (!pressed) return { backgroundColor: colors.background, opacity: 1 };
|
|
441
|
+
return isIOS() ? { backgroundColor: colors.background, opacity: IOS_PRESSED_OPACITY } : { backgroundColor: colors.backgroundPressed, opacity: 1 };
|
|
442
|
+
}
|
|
364
443
|
function sizeMetrics(size, theme) {
|
|
365
444
|
switch (size) {
|
|
366
445
|
case "sm":
|
|
@@ -408,6 +487,7 @@ var Button = react.forwardRef(function Button2({
|
|
|
408
487
|
const metrics = sizeMetrics(size, theme);
|
|
409
488
|
const isInert = disabled || loading;
|
|
410
489
|
const isLink = variant === "link";
|
|
490
|
+
const slop = metrics.height < 44 ? (44 - metrics.height) / 2 : 0;
|
|
411
491
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
412
492
|
reactNative.Pressable,
|
|
413
493
|
{
|
|
@@ -416,23 +496,27 @@ var Button = react.forwardRef(function Button2({
|
|
|
416
496
|
accessibilityState: { disabled: isInert, busy: loading },
|
|
417
497
|
accessibilityLabel,
|
|
418
498
|
disabled: isInert,
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
499
|
+
hitSlop: slop > 0 ? { top: slop, bottom: slop } : void 0,
|
|
500
|
+
style: ({ pressed }) => {
|
|
501
|
+
const feedback = pressFeedback(pressed, colors);
|
|
502
|
+
return [
|
|
503
|
+
{
|
|
504
|
+
flexDirection: "row",
|
|
505
|
+
alignItems: "center",
|
|
506
|
+
justifyContent: "center",
|
|
507
|
+
gap: metrics.gap,
|
|
508
|
+
minHeight: isLink ? void 0 : metrics.height,
|
|
509
|
+
paddingHorizontal: isLink ? 0 : metrics.paddingHorizontal,
|
|
510
|
+
borderRadius: isLink ? 0 : size === "lg" ? theme.radius.lg : theme.radius.md,
|
|
511
|
+
backgroundColor: feedback.backgroundColor,
|
|
512
|
+
borderColor: colors.borderColor,
|
|
513
|
+
borderWidth: colors.borderWidth,
|
|
514
|
+
alignSelf: fullWidth ? "stretch" : "flex-start",
|
|
515
|
+
opacity: isInert ? theme.opacity.disabled : feedback.opacity
|
|
516
|
+
},
|
|
517
|
+
style
|
|
518
|
+
];
|
|
519
|
+
},
|
|
436
520
|
...rest,
|
|
437
521
|
children: [
|
|
438
522
|
loading ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.ActivityIndicator, { size: "small", color: theme.colors[colors.foreground] }) : leftIcon ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { children: leftIcon }) : null,
|
|
@@ -474,20 +558,23 @@ var IconButton = react.forwardRef(function IconButton2({
|
|
|
474
558
|
accessibilityState: { disabled: isInert, busy: loading },
|
|
475
559
|
disabled: isInert,
|
|
476
560
|
hitSlop: dimension < 44 ? (44 - dimension) / 2 : void 0,
|
|
477
|
-
style: ({ pressed }) =>
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
561
|
+
style: ({ pressed }) => {
|
|
562
|
+
const feedback = pressFeedback(pressed, colors);
|
|
563
|
+
return [
|
|
564
|
+
{
|
|
565
|
+
width: dimension,
|
|
566
|
+
height: dimension,
|
|
567
|
+
alignItems: "center",
|
|
568
|
+
justifyContent: "center",
|
|
569
|
+
borderRadius: round ? theme.radius.full : theme.radius.md,
|
|
570
|
+
backgroundColor: feedback.backgroundColor,
|
|
571
|
+
borderColor: colors.borderColor,
|
|
572
|
+
borderWidth: colors.borderWidth,
|
|
573
|
+
opacity: isInert ? theme.opacity.disabled : feedback.opacity
|
|
574
|
+
},
|
|
575
|
+
style
|
|
576
|
+
];
|
|
577
|
+
},
|
|
491
578
|
...rest,
|
|
492
579
|
children: loading ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.ActivityIndicator, { size: "small", color: theme.colors[colors.foreground] }) : icon
|
|
493
580
|
}
|
|
@@ -505,9 +592,13 @@ var Input = react.forwardRef(function Input2({
|
|
|
505
592
|
...rest
|
|
506
593
|
}, ref) {
|
|
507
594
|
const theme = useTheme();
|
|
595
|
+
const { resolvedColorMode } = useColorMode();
|
|
508
596
|
const metrics = sizeMetrics(size, theme);
|
|
509
597
|
const [focused, setFocused] = react.useState(false);
|
|
598
|
+
const ios = isIOS();
|
|
510
599
|
const borderColor = invalid ? theme.colors.danger : focused ? theme.colors.focusRing : theme.colors.border;
|
|
600
|
+
const borderWidth = ios ? focused || invalid ? theme.borderWidth.thin : 0 : focused || invalid ? theme.borderWidth.medium : theme.borderWidth.thin;
|
|
601
|
+
const backgroundColor = ios ? disabled ? theme.colors.bgSubtle : theme.colors.bgMuted : disabled ? theme.colors.bgMuted : theme.colors.surface;
|
|
511
602
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
512
603
|
reactNative.View,
|
|
513
604
|
{
|
|
@@ -516,12 +607,12 @@ var Input = react.forwardRef(function Input2({
|
|
|
516
607
|
flexDirection: "row",
|
|
517
608
|
alignItems: "center",
|
|
518
609
|
gap: metrics.gap,
|
|
519
|
-
|
|
610
|
+
minHeight: metrics.height,
|
|
520
611
|
paddingHorizontal: metrics.paddingHorizontal,
|
|
521
612
|
borderRadius: theme.radius.md,
|
|
522
|
-
borderWidth
|
|
613
|
+
borderWidth,
|
|
523
614
|
borderColor,
|
|
524
|
-
backgroundColor
|
|
615
|
+
backgroundColor
|
|
525
616
|
},
|
|
526
617
|
style
|
|
527
618
|
],
|
|
@@ -536,6 +627,8 @@ var Input = react.forwardRef(function Input2({
|
|
|
536
627
|
"aria-disabled": disabled || void 0,
|
|
537
628
|
placeholderTextColor: theme.colors.textMuted,
|
|
538
629
|
selectionColor: theme.colors.primary,
|
|
630
|
+
keyboardAppearance: resolvedColorMode,
|
|
631
|
+
clearButtonMode: ios && !rightElement ? "while-editing" : void 0,
|
|
539
632
|
onFocus: (event) => {
|
|
540
633
|
setFocused(true);
|
|
541
634
|
onFocus?.(event);
|
|
@@ -546,9 +639,9 @@ var Input = react.forwardRef(function Input2({
|
|
|
546
639
|
},
|
|
547
640
|
style: {
|
|
548
641
|
flex: 1,
|
|
549
|
-
// Android adds its own vertical padding; zero it so `
|
|
642
|
+
// Android adds its own vertical padding; zero it so `minHeight` wins.
|
|
550
643
|
paddingVertical: 0,
|
|
551
|
-
fontFamily: theme.typography.fontFamily.sans,
|
|
644
|
+
fontFamily: nativeFontFamily(theme.typography.fontFamily.sans),
|
|
552
645
|
fontSize: theme.typography.fontSize[metrics.fontSize],
|
|
553
646
|
color: disabled ? theme.colors.textDisabled : theme.colors.text
|
|
554
647
|
},
|
|
@@ -562,10 +655,12 @@ var Input = react.forwardRef(function Input2({
|
|
|
562
655
|
});
|
|
563
656
|
var Textarea = react.forwardRef(function Textarea2({ invalid = false, disabled = false, rows = 4, style, onFocus, onBlur, ...rest }, ref) {
|
|
564
657
|
const theme = useTheme();
|
|
658
|
+
const { resolvedColorMode } = useColorMode();
|
|
565
659
|
const [focused, setFocused] = react.useState(false);
|
|
566
|
-
const
|
|
567
|
-
|
|
568
|
-
|
|
660
|
+
const ios = isIOS();
|
|
661
|
+
const lineHeight = Math.round(theme.typography.fontSize.md * theme.typography.lineHeight.normal);
|
|
662
|
+
const borderWidth = ios ? focused || invalid ? theme.borderWidth.thin : 0 : focused || invalid ? theme.borderWidth.medium : theme.borderWidth.thin;
|
|
663
|
+
const backgroundColor = ios ? disabled ? theme.colors.bgSubtle : theme.colors.bgMuted : disabled ? theme.colors.bgMuted : theme.colors.surface;
|
|
569
664
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
570
665
|
reactNative.TextInput,
|
|
571
666
|
{
|
|
@@ -576,6 +671,7 @@ var Textarea = react.forwardRef(function Textarea2({ invalid = false, disabled =
|
|
|
576
671
|
"aria-invalid": invalid || void 0,
|
|
577
672
|
placeholderTextColor: theme.colors.textMuted,
|
|
578
673
|
selectionColor: theme.colors.primary,
|
|
674
|
+
keyboardAppearance: resolvedColorMode,
|
|
579
675
|
onFocus: (event) => {
|
|
580
676
|
setFocused(true);
|
|
581
677
|
onFocus?.(event);
|
|
@@ -589,10 +685,10 @@ var Textarea = react.forwardRef(function Textarea2({ invalid = false, disabled =
|
|
|
589
685
|
minHeight: rows * lineHeight + theme.space[4],
|
|
590
686
|
padding: theme.space[3],
|
|
591
687
|
borderRadius: theme.radius.md,
|
|
592
|
-
borderWidth
|
|
688
|
+
borderWidth,
|
|
593
689
|
borderColor: invalid ? theme.colors.danger : focused ? theme.colors.focusRing : theme.colors.border,
|
|
594
|
-
backgroundColor
|
|
595
|
-
fontFamily: theme.typography.fontFamily.sans,
|
|
690
|
+
backgroundColor,
|
|
691
|
+
fontFamily: nativeFontFamily(theme.typography.fontFamily.sans),
|
|
596
692
|
fontSize: theme.typography.fontSize.md,
|
|
597
693
|
lineHeight,
|
|
598
694
|
color: disabled ? theme.colors.textDisabled : theme.colors.text
|
|
@@ -649,13 +745,10 @@ function Checkbox({
|
|
|
649
745
|
style
|
|
650
746
|
}) {
|
|
651
747
|
const theme = useTheme();
|
|
652
|
-
const [checked, setChecked] = useControllableState(
|
|
653
|
-
controlledChecked,
|
|
654
|
-
defaultChecked,
|
|
655
|
-
onChange
|
|
656
|
-
);
|
|
748
|
+
const [checked, setChecked] = useControllableState(controlledChecked, defaultChecked, onChange);
|
|
657
749
|
const dimension = boxSize2[size];
|
|
658
750
|
const filled = checked || indeterminate;
|
|
751
|
+
const ios = isIOS();
|
|
659
752
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
660
753
|
reactNative.Pressable,
|
|
661
754
|
{
|
|
@@ -685,7 +778,7 @@ function Checkbox({
|
|
|
685
778
|
height: dimension,
|
|
686
779
|
alignItems: "center",
|
|
687
780
|
justifyContent: "center",
|
|
688
|
-
borderRadius: theme.radius.sm,
|
|
781
|
+
borderRadius: ios ? theme.radius.full : theme.radius.sm,
|
|
689
782
|
borderWidth: theme.borderWidth.medium,
|
|
690
783
|
borderColor: invalid ? theme.colors.danger : filled ? theme.colors.primary : theme.colors.borderStrong,
|
|
691
784
|
backgroundColor: filled ? theme.colors.primary : theme.colors.surface
|
|
@@ -701,7 +794,7 @@ function Checkbox({
|
|
|
701
794
|
) : null
|
|
702
795
|
}
|
|
703
796
|
),
|
|
704
|
-
children != null ? typeof children === "string" ? /* @__PURE__ */ jsxRuntime.jsx(Text, { size: size === "lg" ? "md" : "sm", style: { flexShrink: 1 }, children }) : children : null
|
|
797
|
+
children != null ? typeof children === "string" ? /* @__PURE__ */ jsxRuntime.jsx(Text, { size: size === "lg" || ios ? "md" : "sm", style: { flexShrink: 1 }, children }) : children : null
|
|
705
798
|
]
|
|
706
799
|
}
|
|
707
800
|
);
|
|
@@ -711,6 +804,7 @@ var track = {
|
|
|
711
804
|
md: { width: 44, height: 26, thumb: 22 },
|
|
712
805
|
lg: { width: 52, height: 32, thumb: 28 }
|
|
713
806
|
};
|
|
807
|
+
var iosScale = { sm: 0.8, md: 1, lg: 1 };
|
|
714
808
|
function Switch({
|
|
715
809
|
checked: controlledChecked,
|
|
716
810
|
defaultChecked = false,
|
|
@@ -721,11 +815,40 @@ function Switch({
|
|
|
721
815
|
style
|
|
722
816
|
}) {
|
|
723
817
|
const theme = useTheme();
|
|
724
|
-
const [checked, setChecked] = useControllableState(
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
818
|
+
const [checked, setChecked] = useControllableState(controlledChecked, defaultChecked, onChange);
|
|
819
|
+
const row = {
|
|
820
|
+
flexDirection: "row",
|
|
821
|
+
alignItems: "center",
|
|
822
|
+
justifyContent: "space-between",
|
|
823
|
+
gap: theme.space[3]
|
|
824
|
+
};
|
|
825
|
+
if (isIOS()) {
|
|
826
|
+
const label = typeof children === "string" ? children : void 0;
|
|
827
|
+
const scale = iosScale[size];
|
|
828
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: [row, style], children: [
|
|
829
|
+
children != null ? label !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
830
|
+
Text,
|
|
831
|
+
{
|
|
832
|
+
size: "md",
|
|
833
|
+
style: { flexShrink: 1, opacity: disabled ? theme.opacity.disabled : 1 },
|
|
834
|
+
children: label
|
|
835
|
+
}
|
|
836
|
+
) : children : null,
|
|
837
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
838
|
+
reactNative.Switch,
|
|
839
|
+
{
|
|
840
|
+
value: checked,
|
|
841
|
+
onValueChange: setChecked,
|
|
842
|
+
disabled,
|
|
843
|
+
accessibilityLabel: label,
|
|
844
|
+
trackColor: { false: theme.colors.secondaryActive, true: theme.colors.primary },
|
|
845
|
+
thumbColor: theme.colors.onPrimary,
|
|
846
|
+
ios_backgroundColor: theme.colors.secondaryActive,
|
|
847
|
+
style: scale !== 1 ? { transform: [{ scale }] } : void 0
|
|
848
|
+
}
|
|
849
|
+
)
|
|
850
|
+
] });
|
|
851
|
+
}
|
|
729
852
|
const metrics = track[size];
|
|
730
853
|
const inset = (metrics.height - metrics.thumb) / 2;
|
|
731
854
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -735,16 +858,7 @@ function Switch({
|
|
|
735
858
|
accessibilityState: { checked, disabled },
|
|
736
859
|
disabled,
|
|
737
860
|
onPress: () => setChecked(!checked),
|
|
738
|
-
style: [
|
|
739
|
-
{
|
|
740
|
-
flexDirection: "row",
|
|
741
|
-
alignItems: "center",
|
|
742
|
-
justifyContent: "space-between",
|
|
743
|
-
gap: theme.space[3],
|
|
744
|
-
opacity: disabled ? theme.opacity.disabled : 1
|
|
745
|
-
},
|
|
746
|
-
style
|
|
747
|
-
],
|
|
861
|
+
style: [row, { opacity: disabled ? theme.opacity.disabled : 1 }, style],
|
|
748
862
|
children: [
|
|
749
863
|
children != null ? typeof children === "string" ? /* @__PURE__ */ jsxRuntime.jsx(Text, { size: "sm", style: { flexShrink: 1 }, children }) : children : null,
|
|
750
864
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -871,11 +985,42 @@ function Radio({ value, disabled = false, children, style }) {
|
|
|
871
985
|
) : null
|
|
872
986
|
}
|
|
873
987
|
),
|
|
874
|
-
children != null ? typeof children === "string" ? /* @__PURE__ */ jsxRuntime.jsx(Text, { size: group.size === "lg" ? "md" : "sm", style: { flexShrink: 1 }, children }) : children : null
|
|
988
|
+
children != null ? typeof children === "string" ? /* @__PURE__ */ jsxRuntime.jsx(Text, { size: group.size === "lg" || isIOS() ? "md" : "sm", style: { flexShrink: 1 }, children }) : children : null
|
|
875
989
|
]
|
|
876
990
|
}
|
|
877
991
|
);
|
|
878
992
|
}
|
|
993
|
+
function useSheetTransition(open, distance) {
|
|
994
|
+
const theme = useTheme();
|
|
995
|
+
const translateY = react.useRef(new reactNative.Animated.Value(distance)).current;
|
|
996
|
+
const backdrop = react.useRef(new reactNative.Animated.Value(0)).current;
|
|
997
|
+
react.useEffect(() => {
|
|
998
|
+
const animation = open ? reactNative.Animated.parallel([
|
|
999
|
+
reactNative.Animated.spring(translateY, { toValue: 0, ...sheetSpring, useNativeDriver: true }),
|
|
1000
|
+
reactNative.Animated.timing(backdrop, {
|
|
1001
|
+
toValue: 1,
|
|
1002
|
+
duration: theme.motion.duration.normal,
|
|
1003
|
+
easing: reactNative.Easing.out(reactNative.Easing.quad),
|
|
1004
|
+
useNativeDriver: true
|
|
1005
|
+
})
|
|
1006
|
+
]) : reactNative.Animated.parallel([
|
|
1007
|
+
reactNative.Animated.timing(translateY, {
|
|
1008
|
+
toValue: distance,
|
|
1009
|
+
duration: theme.motion.duration.fast,
|
|
1010
|
+
easing: reactNative.Easing.in(reactNative.Easing.cubic),
|
|
1011
|
+
useNativeDriver: true
|
|
1012
|
+
}),
|
|
1013
|
+
reactNative.Animated.timing(backdrop, {
|
|
1014
|
+
toValue: 0,
|
|
1015
|
+
duration: theme.motion.duration.fast,
|
|
1016
|
+
useNativeDriver: true
|
|
1017
|
+
})
|
|
1018
|
+
]);
|
|
1019
|
+
animation.start();
|
|
1020
|
+
return () => animation.stop();
|
|
1021
|
+
}, [open, distance, translateY, backdrop, theme.motion.duration]);
|
|
1022
|
+
return { translateY, backdrop };
|
|
1023
|
+
}
|
|
879
1024
|
var DISMISS_THRESHOLD = 96;
|
|
880
1025
|
function BottomSheet({
|
|
881
1026
|
open,
|
|
@@ -890,16 +1035,9 @@ function BottomSheet({
|
|
|
890
1035
|
const theme = useTheme();
|
|
891
1036
|
const insets = reactNativeSafeAreaContext.useSafeAreaInsets();
|
|
892
1037
|
const { height } = reactNative.useWindowDimensions();
|
|
893
|
-
const translateY =
|
|
1038
|
+
const { translateY, backdrop } = useSheetTransition(open, height);
|
|
894
1039
|
const dragY = react.useRef(0);
|
|
895
|
-
|
|
896
|
-
reactNative.Animated.timing(translateY, {
|
|
897
|
-
toValue: open ? 0 : height,
|
|
898
|
-
duration: open ? theme.motion.duration.normal : theme.motion.duration.fast,
|
|
899
|
-
easing: reactNative.Easing.out(reactNative.Easing.cubic),
|
|
900
|
-
useNativeDriver: true
|
|
901
|
-
}).start();
|
|
902
|
-
}, [open, height, translateY, theme.motion.duration]);
|
|
1040
|
+
const ios = isIOS();
|
|
903
1041
|
const panResponder = react.useRef(
|
|
904
1042
|
reactNative.PanResponder.create({
|
|
905
1043
|
onMoveShouldSetPanResponder: (_event, gesture) => gesture.dy > 4,
|
|
@@ -913,7 +1051,11 @@ function BottomSheet({
|
|
|
913
1051
|
if (dragY.current > DISMISS_THRESHOLD) {
|
|
914
1052
|
onClose();
|
|
915
1053
|
} else {
|
|
916
|
-
reactNative.Animated.spring(translateY, {
|
|
1054
|
+
reactNative.Animated.spring(translateY, {
|
|
1055
|
+
toValue: 0,
|
|
1056
|
+
...sheetSpring,
|
|
1057
|
+
useNativeDriver: true
|
|
1058
|
+
}).start();
|
|
917
1059
|
}
|
|
918
1060
|
dragY.current = 0;
|
|
919
1061
|
}
|
|
@@ -929,11 +1071,17 @@ function BottomSheet({
|
|
|
929
1071
|
onRequestClose: onClose,
|
|
930
1072
|
children: /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: { flex: 1, justifyContent: "flex-end" }, children: [
|
|
931
1073
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
932
|
-
reactNative.
|
|
1074
|
+
reactNative.Animated.View,
|
|
933
1075
|
{
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
1076
|
+
style: { flex: 1, backgroundColor: theme.colors.overlay, opacity: backdrop },
|
|
1077
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1078
|
+
reactNative.Pressable,
|
|
1079
|
+
{
|
|
1080
|
+
accessibilityLabel: closeOnOverlayPress ? "Close" : void 0,
|
|
1081
|
+
onPress: closeOnOverlayPress ? onClose : void 0,
|
|
1082
|
+
style: { flex: 1 }
|
|
1083
|
+
}
|
|
1084
|
+
)
|
|
937
1085
|
}
|
|
938
1086
|
),
|
|
939
1087
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -953,32 +1101,39 @@ function BottomSheet({
|
|
|
953
1101
|
style
|
|
954
1102
|
],
|
|
955
1103
|
children: [
|
|
956
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
1104
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1105
|
+
reactNative.View,
|
|
1106
|
+
{
|
|
1107
|
+
...panResponder.panHandlers,
|
|
1108
|
+
style: { paddingTop: ios ? theme.space[1.5] : theme.space[3] },
|
|
1109
|
+
children: [
|
|
1110
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1111
|
+
reactNative.View,
|
|
1112
|
+
{
|
|
1113
|
+
style: {
|
|
1114
|
+
alignSelf: "center",
|
|
1115
|
+
width: ios ? 36 : 40,
|
|
1116
|
+
height: ios ? 5 : 4,
|
|
1117
|
+
borderRadius: theme.radius.full,
|
|
1118
|
+
backgroundColor: theme.colors.borderStrong
|
|
1119
|
+
}
|
|
1120
|
+
}
|
|
1121
|
+
),
|
|
1122
|
+
title ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
1123
|
+
Heading,
|
|
1124
|
+
{
|
|
1125
|
+
level: 3,
|
|
1126
|
+
size: "lg",
|
|
1127
|
+
style: {
|
|
1128
|
+
paddingHorizontal: theme.space[5],
|
|
1129
|
+
paddingTop: theme.space[4]
|
|
1130
|
+
},
|
|
1131
|
+
children: title
|
|
1132
|
+
}
|
|
1133
|
+
) : null
|
|
1134
|
+
]
|
|
1135
|
+
}
|
|
1136
|
+
),
|
|
982
1137
|
children
|
|
983
1138
|
]
|
|
984
1139
|
}
|
|
@@ -1003,6 +1158,7 @@ function Select({
|
|
|
1003
1158
|
const metrics = sizeMetrics(size, theme);
|
|
1004
1159
|
const [open, setOpen] = react.useState(false);
|
|
1005
1160
|
const selected = options.find((option) => option.value === value);
|
|
1161
|
+
const ios = isIOS();
|
|
1006
1162
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1007
1163
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1008
1164
|
reactNative.Pressable,
|
|
@@ -1020,12 +1176,13 @@ function Select({
|
|
|
1020
1176
|
alignItems: "center",
|
|
1021
1177
|
justifyContent: "space-between",
|
|
1022
1178
|
gap: metrics.gap,
|
|
1023
|
-
|
|
1179
|
+
minHeight: metrics.height,
|
|
1024
1180
|
paddingHorizontal: metrics.paddingHorizontal,
|
|
1025
1181
|
borderRadius: theme.radius.md,
|
|
1026
|
-
|
|
1182
|
+
// Mirrors Input: iOS is a filled rect that only gains a stroke when invalid.
|
|
1183
|
+
borderWidth: invalid ? ios ? theme.borderWidth.thin : theme.borderWidth.medium : ios ? 0 : theme.borderWidth.thin,
|
|
1027
1184
|
borderColor: invalid ? theme.colors.danger : theme.colors.border,
|
|
1028
|
-
backgroundColor: disabled ? theme.colors.bgMuted : theme.colors.surface,
|
|
1185
|
+
backgroundColor: ios ? disabled ? theme.colors.bgSubtle : theme.colors.bgMuted : disabled ? theme.colors.bgMuted : theme.colors.surface,
|
|
1029
1186
|
opacity: disabled ? theme.opacity.disabled : 1
|
|
1030
1187
|
},
|
|
1031
1188
|
style
|
|
@@ -1249,6 +1406,7 @@ function ToastCard({
|
|
|
1249
1406
|
const theme = useTheme();
|
|
1250
1407
|
const tone = entry.tone ?? "neutral";
|
|
1251
1408
|
const enter = react.useRef(new reactNative.Animated.Value(0)).current;
|
|
1409
|
+
const ios = isIOS();
|
|
1252
1410
|
react.useEffect(() => {
|
|
1253
1411
|
reactNative.Animated.timing(enter, {
|
|
1254
1412
|
toValue: 1,
|
|
@@ -1273,8 +1431,8 @@ function ToastCard({
|
|
|
1273
1431
|
alignItems: "flex-start",
|
|
1274
1432
|
gap: theme.space[3],
|
|
1275
1433
|
padding: theme.space[3.5],
|
|
1276
|
-
borderRadius: theme.radius.lg,
|
|
1277
|
-
borderWidth: theme.borderWidth.thin,
|
|
1434
|
+
borderRadius: ios ? theme.radius.xl : theme.radius.lg,
|
|
1435
|
+
borderWidth: ios ? 0 : theme.borderWidth.thin,
|
|
1278
1436
|
borderColor: theme.colors.border,
|
|
1279
1437
|
backgroundColor: theme.colors.surface,
|
|
1280
1438
|
opacity: enter,
|
|
@@ -1470,7 +1628,7 @@ var Card = react.forwardRef(function Card2({ variant = "outline", onPress, acces
|
|
|
1470
1628
|
const base = {
|
|
1471
1629
|
borderRadius: theme.radius.lg,
|
|
1472
1630
|
backgroundColor: variant === "filled" ? theme.colors.bgSubtle : theme.colors.surface,
|
|
1473
|
-
borderWidth: variant === "outline" ? theme.borderWidth.thin : 0,
|
|
1631
|
+
borderWidth: variant === "outline" ? isIOS() ? reactNative.StyleSheet.hairlineWidth : theme.borderWidth.thin : 0,
|
|
1474
1632
|
borderColor: theme.colors.border,
|
|
1475
1633
|
...variant === "elevated" ? shadowStyle(theme.shadow.sm) : null
|
|
1476
1634
|
};
|
|
@@ -1495,7 +1653,16 @@ var Card = react.forwardRef(function Card2({ variant = "outline", onPress, acces
|
|
|
1495
1653
|
});
|
|
1496
1654
|
function CardHeader({ children, style }) {
|
|
1497
1655
|
const theme = useTheme();
|
|
1498
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1656
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1657
|
+
reactNative.View,
|
|
1658
|
+
{
|
|
1659
|
+
style: [
|
|
1660
|
+
{ padding: theme.space[4], paddingBottom: theme.space[2], gap: theme.space[1] },
|
|
1661
|
+
style
|
|
1662
|
+
],
|
|
1663
|
+
children
|
|
1664
|
+
}
|
|
1665
|
+
);
|
|
1499
1666
|
}
|
|
1500
1667
|
function CardTitle({ children, style }) {
|
|
1501
1668
|
return /* @__PURE__ */ jsxRuntime.jsx(Heading, { level: 3, size: "md", style, children });
|
|
@@ -1594,6 +1761,7 @@ function Screen({
|
|
|
1594
1761
|
style: [{ flex: 1, backgroundColor: theme.colors[bg] }, style],
|
|
1595
1762
|
contentContainerStyle: [padding, contentContainerStyle],
|
|
1596
1763
|
keyboardShouldPersistTaps: "handled",
|
|
1764
|
+
keyboardDismissMode: isIOS() ? "interactive" : "on-drag",
|
|
1597
1765
|
refreshControl: onRefresh ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
1598
1766
|
reactNative.RefreshControl,
|
|
1599
1767
|
{
|
|
@@ -1618,21 +1786,30 @@ function ListRow({
|
|
|
1618
1786
|
style
|
|
1619
1787
|
}) {
|
|
1620
1788
|
const theme = useTheme();
|
|
1789
|
+
const ios = isIOS();
|
|
1621
1790
|
const content = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1622
1791
|
left,
|
|
1623
1792
|
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: { flex: 1, gap: theme.space[0.5] }, children: [
|
|
1624
1793
|
/* @__PURE__ */ jsxRuntime.jsx(Text, { size: "md", numberOfLines: 1, children: title }),
|
|
1625
|
-
subtitle ? /* @__PURE__ */ jsxRuntime.jsx(Text, { size: "sm", color: "textMuted", numberOfLines: 2, children: subtitle }) : null
|
|
1794
|
+
subtitle ? /* @__PURE__ */ jsxRuntime.jsx(Text, { size: "sm", color: ios ? "textSecondary" : "textMuted", numberOfLines: 2, children: subtitle }) : null
|
|
1626
1795
|
] }),
|
|
1627
|
-
right ?? (onPress && !hideChevron ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
1796
|
+
right ?? (onPress && !hideChevron ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
1797
|
+
Icon,
|
|
1798
|
+
{
|
|
1799
|
+
icon: icons.ChevronRightIcon,
|
|
1800
|
+
size: ios ? 16 : 18,
|
|
1801
|
+
strokeWidth: ios ? 2.5 : 2,
|
|
1802
|
+
color: "textMuted"
|
|
1803
|
+
}
|
|
1804
|
+
) : null)
|
|
1628
1805
|
] });
|
|
1629
1806
|
const layout = {
|
|
1630
1807
|
flexDirection: "row",
|
|
1631
1808
|
alignItems: "center",
|
|
1632
1809
|
gap: theme.space[3],
|
|
1633
1810
|
paddingHorizontal: theme.space[4],
|
|
1634
|
-
paddingVertical: theme.space[3.5],
|
|
1635
|
-
minHeight: 56,
|
|
1811
|
+
paddingVertical: ios ? theme.space[2.5] : theme.space[3.5],
|
|
1812
|
+
minHeight: ios ? 44 : 56,
|
|
1636
1813
|
opacity: disabled ? theme.opacity.disabled : 1
|
|
1637
1814
|
};
|
|
1638
1815
|
if (!onPress) return /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [layout, style], children: content });
|
|
@@ -1714,6 +1891,7 @@ function Tabs({
|
|
|
1714
1891
|
onChange
|
|
1715
1892
|
);
|
|
1716
1893
|
const isSegmented = variant === "segmented";
|
|
1894
|
+
const iosSegmented = isSegmented && isIOS();
|
|
1717
1895
|
const tabs = items.map((item) => {
|
|
1718
1896
|
const selected = item.value === value;
|
|
1719
1897
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -1728,20 +1906,22 @@ function Tabs({
|
|
|
1728
1906
|
alignItems: "center",
|
|
1729
1907
|
justifyContent: "center",
|
|
1730
1908
|
gap: theme.space[1.5],
|
|
1909
|
+
minHeight: iosSegmented ? 28 : void 0,
|
|
1731
1910
|
paddingHorizontal: theme.space[3],
|
|
1732
|
-
paddingVertical: isSegmented ? theme.space[2] : theme.space[3],
|
|
1733
|
-
borderRadius: isSegmented ? theme.radius.md : 0,
|
|
1911
|
+
paddingVertical: iosSegmented ? theme.space[1] : isSegmented ? theme.space[2] : theme.space[3],
|
|
1912
|
+
borderRadius: iosSegmented ? theme.radius.md - 2 : isSegmented ? theme.radius.md : 0,
|
|
1734
1913
|
backgroundColor: isSegmented && selected ? theme.colors.surface : "transparent",
|
|
1735
1914
|
borderBottomWidth: isSegmented ? 0 : theme.borderWidth.medium,
|
|
1736
|
-
borderBottomColor: selected ? theme.colors.primary : "transparent"
|
|
1915
|
+
borderBottomColor: selected ? theme.colors.primary : "transparent",
|
|
1916
|
+
...iosSegmented && selected ? shadowStyle(theme.shadow.sm) : null
|
|
1737
1917
|
},
|
|
1738
1918
|
children: [
|
|
1739
1919
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1740
1920
|
Text,
|
|
1741
1921
|
{
|
|
1742
|
-
size: "sm",
|
|
1922
|
+
size: iosSegmented ? "xs" : "sm",
|
|
1743
1923
|
weight: selected ? "semibold" : "medium",
|
|
1744
|
-
color: selected ? isSegmented ? "text" : "primaryText" : "textMuted",
|
|
1924
|
+
color: selected ? isSegmented ? "text" : "primaryText" : iosSegmented ? "text" : "textMuted",
|
|
1745
1925
|
numberOfLines: 1,
|
|
1746
1926
|
children: item.label
|
|
1747
1927
|
}
|
|
@@ -1752,7 +1932,12 @@ function Tabs({
|
|
|
1752
1932
|
item.value
|
|
1753
1933
|
);
|
|
1754
1934
|
});
|
|
1755
|
-
const container =
|
|
1935
|
+
const container = iosSegmented ? {
|
|
1936
|
+
flexDirection: "row",
|
|
1937
|
+
padding: theme.space[0.5],
|
|
1938
|
+
borderRadius: theme.radius.md,
|
|
1939
|
+
backgroundColor: theme.colors.bgMuted
|
|
1940
|
+
} : isSegmented ? {
|
|
1756
1941
|
flexDirection: "row",
|
|
1757
1942
|
gap: theme.space[1],
|
|
1758
1943
|
padding: theme.space[1],
|
|
@@ -1776,7 +1961,15 @@ function Tabs({
|
|
|
1776
1961
|
}
|
|
1777
1962
|
);
|
|
1778
1963
|
}
|
|
1779
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1964
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1965
|
+
reactNative.View,
|
|
1966
|
+
{
|
|
1967
|
+
accessibilityRole: "tablist",
|
|
1968
|
+
accessibilityLabel,
|
|
1969
|
+
style: [container, style],
|
|
1970
|
+
children: tabs
|
|
1971
|
+
}
|
|
1972
|
+
);
|
|
1780
1973
|
}
|
|
1781
1974
|
function Accordion({
|
|
1782
1975
|
items,
|
|
@@ -2225,6 +2418,7 @@ function ModalFooter({
|
|
|
2225
2418
|
style
|
|
2226
2419
|
}) {
|
|
2227
2420
|
const theme = useTheme();
|
|
2421
|
+
const ios = isIOS();
|
|
2228
2422
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2229
2423
|
reactNative.View,
|
|
2230
2424
|
{
|
|
@@ -2234,8 +2428,10 @@ function ModalFooter({
|
|
|
2234
2428
|
justifyContent: "flex-end",
|
|
2235
2429
|
gap: theme.space[2],
|
|
2236
2430
|
paddingHorizontal: theme.space[5],
|
|
2237
|
-
paddingTop: theme.space[3],
|
|
2238
|
-
paddingBottom: theme.space[5]
|
|
2431
|
+
paddingTop: ios ? theme.space[4] : theme.space[3],
|
|
2432
|
+
paddingBottom: theme.space[5],
|
|
2433
|
+
borderTopWidth: ios ? reactNative.StyleSheet.hairlineWidth : 0,
|
|
2434
|
+
borderTopColor: theme.colors.border
|
|
2239
2435
|
},
|
|
2240
2436
|
style
|
|
2241
2437
|
],
|
|
@@ -2334,7 +2530,136 @@ function Drawer({
|
|
|
2334
2530
|
}
|
|
2335
2531
|
);
|
|
2336
2532
|
}
|
|
2337
|
-
function ActionSheet({
|
|
2533
|
+
function ActionSheet(props) {
|
|
2534
|
+
return isIOS() ? /* @__PURE__ */ jsxRuntime.jsx(IOSActionSheet, { ...props }) : /* @__PURE__ */ jsxRuntime.jsx(SheetActionSheet, { ...props });
|
|
2535
|
+
}
|
|
2536
|
+
function IOSActionSheet({
|
|
2537
|
+
open,
|
|
2538
|
+
onClose,
|
|
2539
|
+
title,
|
|
2540
|
+
description,
|
|
2541
|
+
actions,
|
|
2542
|
+
cancelLabel = "Cancel",
|
|
2543
|
+
style
|
|
2544
|
+
}) {
|
|
2545
|
+
const theme = useTheme();
|
|
2546
|
+
const insets = reactNativeSafeAreaContext.useSafeAreaInsets();
|
|
2547
|
+
const { height } = reactNative.useWindowDimensions();
|
|
2548
|
+
const { translateY, backdrop } = useSheetTransition(open, height);
|
|
2549
|
+
const hasHeader = Boolean(title || description);
|
|
2550
|
+
const group = {
|
|
2551
|
+
borderRadius: theme.radius.xl,
|
|
2552
|
+
backgroundColor: theme.colors.surface,
|
|
2553
|
+
overflow: "hidden"
|
|
2554
|
+
};
|
|
2555
|
+
const separator = {
|
|
2556
|
+
borderTopWidth: reactNative.StyleSheet.hairlineWidth,
|
|
2557
|
+
borderTopColor: theme.colors.border
|
|
2558
|
+
};
|
|
2559
|
+
const row = (pressed, leading) => ({
|
|
2560
|
+
minHeight: 56,
|
|
2561
|
+
flexDirection: "row",
|
|
2562
|
+
alignItems: "center",
|
|
2563
|
+
justifyContent: leading ? "flex-start" : "center",
|
|
2564
|
+
gap: theme.space[3],
|
|
2565
|
+
paddingHorizontal: theme.space[4],
|
|
2566
|
+
backgroundColor: pressed ? theme.colors.surfaceActive : "transparent"
|
|
2567
|
+
});
|
|
2568
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2569
|
+
reactNative.Modal,
|
|
2570
|
+
{
|
|
2571
|
+
visible: open,
|
|
2572
|
+
transparent: true,
|
|
2573
|
+
animationType: "none",
|
|
2574
|
+
statusBarTranslucent: true,
|
|
2575
|
+
onRequestClose: onClose,
|
|
2576
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: { flex: 1, justifyContent: "flex-end" }, children: [
|
|
2577
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2578
|
+
reactNative.Animated.View,
|
|
2579
|
+
{
|
|
2580
|
+
style: { flex: 1, backgroundColor: theme.colors.overlay, opacity: backdrop },
|
|
2581
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Pressable, { accessibilityLabel: "Close", onPress: onClose, style: { flex: 1 } })
|
|
2582
|
+
}
|
|
2583
|
+
),
|
|
2584
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2585
|
+
reactNative.Animated.View,
|
|
2586
|
+
{
|
|
2587
|
+
accessibilityViewIsModal: true,
|
|
2588
|
+
accessibilityLabel: title,
|
|
2589
|
+
style: [
|
|
2590
|
+
{
|
|
2591
|
+
paddingHorizontal: theme.space[2],
|
|
2592
|
+
paddingBottom: insets.bottom + theme.space[2],
|
|
2593
|
+
gap: theme.space[2],
|
|
2594
|
+
transform: [{ translateY }]
|
|
2595
|
+
},
|
|
2596
|
+
style
|
|
2597
|
+
],
|
|
2598
|
+
children: [
|
|
2599
|
+
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: group, accessibilityRole: "menu", children: [
|
|
2600
|
+
hasHeader ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2601
|
+
reactNative.View,
|
|
2602
|
+
{
|
|
2603
|
+
style: {
|
|
2604
|
+
alignItems: "center",
|
|
2605
|
+
gap: theme.space[1],
|
|
2606
|
+
paddingHorizontal: theme.space[4],
|
|
2607
|
+
paddingVertical: theme.space[3.5]
|
|
2608
|
+
},
|
|
2609
|
+
children: [
|
|
2610
|
+
title ? /* @__PURE__ */ jsxRuntime.jsx(Text, { size: "xs", weight: "semibold", color: "textSecondary", align: "center", children: title }) : null,
|
|
2611
|
+
description ? /* @__PURE__ */ jsxRuntime.jsx(Text, { size: "xs", color: "textSecondary", align: "center", children: description }) : null
|
|
2612
|
+
]
|
|
2613
|
+
}
|
|
2614
|
+
) : null,
|
|
2615
|
+
actions.map((action, index) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2616
|
+
reactNative.Pressable,
|
|
2617
|
+
{
|
|
2618
|
+
accessibilityRole: "menuitem",
|
|
2619
|
+
accessibilityState: { disabled: action.disabled },
|
|
2620
|
+
disabled: action.disabled,
|
|
2621
|
+
onPress: () => {
|
|
2622
|
+
onClose();
|
|
2623
|
+
action.onPress();
|
|
2624
|
+
},
|
|
2625
|
+
style: ({ pressed }) => [
|
|
2626
|
+
row(pressed, action.icon != null),
|
|
2627
|
+
index > 0 || hasHeader ? separator : null,
|
|
2628
|
+
action.disabled ? { opacity: theme.opacity.disabled } : null
|
|
2629
|
+
],
|
|
2630
|
+
children: [
|
|
2631
|
+
action.icon,
|
|
2632
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2633
|
+
Text,
|
|
2634
|
+
{
|
|
2635
|
+
size: "lg",
|
|
2636
|
+
color: action.destructive ? "dangerText" : "primaryText",
|
|
2637
|
+
numberOfLines: 1,
|
|
2638
|
+
children: action.label
|
|
2639
|
+
}
|
|
2640
|
+
)
|
|
2641
|
+
]
|
|
2642
|
+
},
|
|
2643
|
+
action.label
|
|
2644
|
+
))
|
|
2645
|
+
] }),
|
|
2646
|
+
cancelLabel ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2647
|
+
reactNative.Pressable,
|
|
2648
|
+
{
|
|
2649
|
+
accessibilityRole: "button",
|
|
2650
|
+
onPress: onClose,
|
|
2651
|
+
style: ({ pressed }) => [group, row(pressed, false)],
|
|
2652
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Text, { size: "lg", weight: "semibold", color: "primaryText", children: cancelLabel })
|
|
2653
|
+
}
|
|
2654
|
+
) : null
|
|
2655
|
+
]
|
|
2656
|
+
}
|
|
2657
|
+
)
|
|
2658
|
+
] })
|
|
2659
|
+
}
|
|
2660
|
+
);
|
|
2661
|
+
}
|
|
2662
|
+
function SheetActionSheet({
|
|
2338
2663
|
open,
|
|
2339
2664
|
onClose,
|
|
2340
2665
|
title,
|
|
@@ -2469,11 +2794,16 @@ exports.Textarea = Textarea;
|
|
|
2469
2794
|
exports.ThemeProvider = ThemeProvider;
|
|
2470
2795
|
exports.ToastProvider = ToastProvider;
|
|
2471
2796
|
exports.Tooltip = Tooltip;
|
|
2797
|
+
exports.adaptThemeToPlatform = adaptThemeToPlatform;
|
|
2472
2798
|
exports.addDays = addDays;
|
|
2473
2799
|
exports.addMonths = addMonths;
|
|
2474
2800
|
exports.dayKey = dayKey;
|
|
2801
|
+
exports.iosThemeOverride = iosThemeOverride;
|
|
2802
|
+
exports.isIOS = isIOS;
|
|
2475
2803
|
exports.isSameDay = isSameDay;
|
|
2476
2804
|
exports.monthGrid = monthGrid;
|
|
2805
|
+
exports.nativeFontFamily = nativeFontFamily;
|
|
2806
|
+
exports.pressFeedback = pressFeedback;
|
|
2477
2807
|
exports.shadowStyle = shadowStyle;
|
|
2478
2808
|
exports.sizeMetrics = sizeMetrics;
|
|
2479
2809
|
exports.splitStyleProps = splitStyleProps;
|