@sincpro/mobile-ui 0.5.0 → 0.6.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 (82) hide show
  1. package/dist/Actions/Actions.Button.d.ts +151 -0
  2. package/dist/Actions/Actions.Button.js +217 -0
  3. package/dist/Actions/Actions.FAB.d.ts +10 -0
  4. package/dist/Actions/Actions.FAB.js +17 -0
  5. package/dist/Actions/Actions.FilterButton.d.ts +10 -0
  6. package/dist/Actions/Actions.FilterButton.js +28 -0
  7. package/dist/Actions/Actions.IconButton.d.ts +67 -0
  8. package/dist/Actions/Actions.IconButton.js +38 -0
  9. package/dist/Actions/index.d.ts +22 -0
  10. package/dist/Actions/index.js +17 -0
  11. package/dist/Dialog/BottomSheet/BottomSheet.Root.js +1 -0
  12. package/dist/Dialog/Dialog.Sheet.js +6 -4
  13. package/dist/Display/Display.CircleButton.d.ts +15 -0
  14. package/dist/Display/Display.CircleButton.js +39 -0
  15. package/dist/Display/Display.MenuButton.d.ts +51 -8
  16. package/dist/Display/Display.MenuButton.js +79 -13
  17. package/dist/Display/Display.MenuCard.d.ts +15 -0
  18. package/dist/Display/Display.MenuCard.js +24 -0
  19. package/dist/Display/Display.MenuGrid.d.ts +19 -0
  20. package/dist/Display/Display.MenuGrid.js +7 -0
  21. package/dist/Display/Display.SwipeableRow.js +2 -1
  22. package/dist/Display/Display.Tooltip.d.ts +1 -1
  23. package/dist/Display/Display.Tooltip.js +16 -5
  24. package/dist/Display/index.d.ts +9 -0
  25. package/dist/Display/index.js +6 -0
  26. package/dist/Feedback/Feedback.Empty.js +2 -2
  27. package/dist/Feedback/Feedback.Error.js +2 -2
  28. package/dist/Feedback/Feedback.Progress.js +2 -2
  29. package/dist/Feedback/Feedback.Skeleton.js +2 -2
  30. package/dist/Feedback/Feedback.Splash.js +1 -0
  31. package/dist/Form/Form.Button.d.ts +3 -151
  32. package/dist/Form/Form.Button.js +1 -283
  33. package/dist/Form/Form.FAB.d.ts +3 -10
  34. package/dist/Form/Form.FAB.js +1 -17
  35. package/dist/Form/Form.FilterButton.d.ts +3 -12
  36. package/dist/Form/Form.FilterButton.js +1 -34
  37. package/dist/Form/Form.IconButton.d.ts +3 -67
  38. package/dist/Form/Form.IconButton.js +1 -64
  39. package/dist/Navigation/Navigation.AppBar.d.ts +56 -1
  40. package/dist/Navigation/Navigation.AppBar.js +43 -12
  41. package/dist/Navigation/Navigation.BottomNav.js +2 -1
  42. package/dist/Navigation/Navigation.Header.js +3 -2
  43. package/dist/Navigation/Navigation.Menu.js +6 -3
  44. package/dist/Navigation/Navigation.MenuSection.d.ts +19 -0
  45. package/dist/Navigation/Navigation.MenuSection.js +25 -0
  46. package/dist/Navigation/Navigation.SegmentedControl.d.ts +15 -1
  47. package/dist/Navigation/Navigation.SegmentedControl.js +22 -4
  48. package/dist/Navigation/Navigation.TabIcon.js +1 -2
  49. package/dist/Navigation/Navigation.TabItem.js +2 -2
  50. package/dist/Navigation/Navigation.Tabs.d.ts +8 -3
  51. package/dist/Navigation/Navigation.Tabs.js +19 -6
  52. package/dist/Navigation/index.d.ts +7 -6
  53. package/dist/Navigation/index.js +2 -0
  54. package/dist/index.d.ts +2 -0
  55. package/dist/index.js +2 -0
  56. package/dist/layouts/BottomInset.d.ts +16 -0
  57. package/dist/layouts/BottomInset.js +17 -0
  58. package/dist/layouts/TabNavigatorLayout.js +2 -2
  59. package/dist/primitives/BaseButton.js +3 -3
  60. package/dist/theme/default.js +1 -1
  61. package/dist/views/FormViewV2.d.ts +18 -6
  62. package/dist/views/FormViewV2.js +14 -11
  63. package/dist/views/ListViewV2.d.ts +12 -1
  64. package/dist/views/ListViewV2.js +16 -10
  65. package/dist/widgets/CircleButton.d.ts +3 -19
  66. package/dist/widgets/CircleButton.js +1 -41
  67. package/dist/widgets/JSONViewer.js +7 -7
  68. package/dist/widgets/MenuCard.d.ts +3 -13
  69. package/dist/widgets/MenuCard.js +1 -8
  70. package/dist/widgets/MenuGrid.d.ts +5 -17
  71. package/dist/widgets/MenuGrid.js +1 -6
  72. package/dist/widgets/MenuSection.d.ts +3 -0
  73. package/dist/widgets/MenuSection.js +1 -0
  74. package/dist/widgets/PromoBanner.d.ts +38 -0
  75. package/dist/widgets/PromoBanner.js +61 -0
  76. package/dist/widgets/PromoModal.d.ts +41 -0
  77. package/dist/widgets/PromoModal.js +75 -0
  78. package/dist/widgets/QuickActions.d.ts +26 -0
  79. package/dist/widgets/QuickActions.js +41 -0
  80. package/dist/widgets/index.d.ts +11 -1
  81. package/dist/widgets/index.js +4 -0
  82. package/package.json +2 -1
@@ -1,3 +1,6 @@
1
+ import { type GradientPreset } from "../Display/Display.GradientSurface";
2
+ import { type PatternKind } from "../Display/Display.Pattern";
3
+ import type { LinearGradientPoint } from "expo-linear-gradient";
1
4
  import type { ReactNode } from "react";
2
5
  export interface AppBarActionProps {
3
6
  /** Ionicon name. Optional when `label` is set (text-only CTA). */
@@ -44,16 +47,68 @@ export interface AppBarProps {
44
47
  border?: boolean;
45
48
  /** Reserves the status-bar space (insets.top). `false` to embed/demo. */
46
49
  safeArea?: boolean;
50
+ /**
51
+ * [large variant] Extra top padding (px) above the large title row.
52
+ * Default is 8. Use ~16–24 on root/home screens without a back button.
53
+ */
54
+ topSpacing?: number;
55
+ /**
56
+ * Decorative gradient + texture surface. When set, automatically renders white text/icons
57
+ * (no need to also set `tone="dark"`). Overrides the solid `tone` background.
58
+ *
59
+ * Preset: `background={{ surface: "mesh" }}`
60
+ * Custom: `background={{ colors: ["#0B1410", "#10B981", "#1E1B8A"] }}`
61
+ * With texture: `background={{ surface: "night-green", pattern: "dots" }}`
62
+ */
63
+ background?: AppBarBackground;
64
+ /**
65
+ * Visual treatment at the bottom edge of the AppBar.
66
+ * - `"line"` — hairline border separator (default for light-surface variants)
67
+ * - `"shadow"` — drop-shadow only, no border (floating/elevated feel)
68
+ * - `"rounded"` — rounded bottom corners (24 px); gradient is clipped inside
69
+ * - `"wave"` — inverse-arc cutout: page-bg arch at the bottom creates a wave illusion
70
+ * - `"none"` — hard edge, no decoration
71
+ */
72
+ bottomDivider?: "none" | "line" | "shadow" | "rounded" | "wave";
47
73
  className?: string;
48
74
  testID?: string;
49
75
  }
76
+ /**
77
+ * Gradient + texture surface descriptor for AppBar headers.
78
+ * Pass as the `background` prop — white text/icons are activated automatically.
79
+ */
80
+ export interface AppBarBackground {
81
+ /** Named gradient preset: `"mesh"` (dark aurora), `"night-green"`, `"neon-teal"`, `"emerald"`. */
82
+ surface?: GradientPreset;
83
+ /** Custom color stops — overrides `surface`. Minimum 2 colors. */
84
+ colors?: readonly [string, string, ...string[]];
85
+ /** Gradient start point. Default: top-left `{ x: 0, y: 0 }`. */
86
+ start?: LinearGradientPoint;
87
+ /** Gradient end point. Default: bottom-right `{ x: 1, y: 1 }`. */
88
+ end?: LinearGradientPoint;
89
+ /** SVG texture overlay kind. */
90
+ pattern?: PatternKind;
91
+ /** Texture opacity (0–1). Default 0.18. */
92
+ patternOpacity?: number;
93
+ /**
94
+ * Text and icon color rendered over this gradient surface.
95
+ * Defaults to `"#FFFFFF"` since gradient AppBar surfaces are typically dark.
96
+ * Pass a dark color (e.g. `theme.text.primary`) for light-colored gradients.
97
+ */
98
+ textColor?: string;
99
+ /**
100
+ * SVG texture pattern tint color. Defaults to `"#FFFFFF"`.
101
+ * Override when using a light gradient that needs a dark dot/grid texture.
102
+ */
103
+ patternColor?: string;
104
+ }
50
105
  /**
51
106
  * Flat, modern top bar (merge of Material 3 + iOS 26): tokenized surface, left-aligned
52
107
  * title + subtitle, **contained** icon-buttons (back and actions with a circular area),
53
108
  * a `subheader` slot (for SearchBar/Segmented below the title), and a `large` variant.
54
109
  * Replaces the gradient look of `Navigation.Header`/`ScreenHeader`.
55
110
  */
56
- declare function AppBar({ title, subtitle, onBack, leading, actions, subheader, variant, tone, accentBar, backVariant, border, safeArea, className, testID, }: AppBarProps): import("react").JSX.Element;
111
+ declare function AppBar({ title, subtitle, onBack, leading, actions, subheader, variant, tone, accentBar, backVariant, border, safeArea, topSpacing, background, bottomDivider, className, testID, }: AppBarProps): import("react").JSX.Element;
57
112
  declare const AppBarWithAction: typeof AppBar & {
58
113
  Action: typeof AppBarAction;
59
114
  };
@@ -1,8 +1,9 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "nativewind/jsx-runtime";
2
2
  import GradientSurface from "../Display/Display.GradientSurface";
3
3
  import Icon from "../Display/Display.Icon";
4
+ import { Pattern } from "../Display/Display.Pattern";
4
5
  import Pressable from "../primitives/Pressable";
5
- import { theme } from "../theme";
6
+ import { useTheme } from "../theme";
6
7
  import { cn } from "../theme/tw";
7
8
  import { Typography } from "../Typography";
8
9
  import { StyleSheet, View } from "react-native";
@@ -15,6 +16,7 @@ const HERO_DARK_FALLBACK = "#0E1714";
15
16
  * With `label`, renders a text pill CTA instead (for "Editar"/"Nuevo"/"Guardar").
16
17
  */
17
18
  function AppBarAction({ icon, label, onPress, badge, accessibilityLabel, tone = "plain", onDark = false, bare = false, testID, }) {
19
+ const theme = useTheme();
18
20
  const bg = bare
19
21
  ? "transparent"
20
22
  : onDark
@@ -25,7 +27,7 @@ function AppBarAction({ icon, label, onPress, badge, accessibilityLabel, tone =
25
27
  const iconColor = tone === "tinted"
26
28
  ? theme.text.onAccent // dark token on green surface
27
29
  : onDark
28
- ? theme.icon.inverse
30
+ ? "#FFFFFF" // always white on tone="dark"/gradient surfaces; icon.inverse flips dark in dark-mode
29
31
  : theme.icon.primary;
30
32
  // Plain (white) squircle gets a hairline so it reads as a contained button on a light bar.
31
33
  const showBorder = !bare && !onDark && tone !== "tinted";
@@ -54,39 +56,68 @@ function AppBarAction({ icon, label, onPress, badge, accessibilityLabel, tone =
54
56
  * a `subheader` slot (for SearchBar/Segmented below the title), and a `large` variant.
55
57
  * Replaces the gradient look of `Navigation.Header`/`ScreenHeader`.
56
58
  */
57
- function AppBar({ title, subtitle, onBack, leading, actions, subheader, variant = "default", tone = "default", accentBar = false, backVariant = "contained", border = true, safeArea = true, className, testID, }) {
59
+ function AppBar({ title, subtitle, onBack, leading, actions, subheader, variant = "default", tone = "default", accentBar = false, backVariant = "contained", border = true, safeArea = true, topSpacing, background, bottomDivider, className, testID, }) {
60
+ const theme = useTheme();
58
61
  const insets = useSafeAreaInsets();
59
62
  const centered = variant === "center";
60
63
  const large = variant === "large";
61
64
  const dark = tone === "dark";
62
65
  const gradient = tone === "gradient";
66
+ const hasBackground = !!background;
63
67
  // Large variant: back/leading + actions all live ON the big-title row (single cohesive
64
68
  // block — no separate top toolbar that would push the title to a new line). The compact
65
69
  // top toolbar is only for default/center.
66
70
  const largeHasNav = large && (!!onBack || !!leading);
67
71
  const showTopBar = !large;
68
- // Both `dark` and `gradient` are colored surfaces: no card bg, no hairline, light/dark text.
69
- const colored = dark || gradient;
70
- const onColoredText = gradient ? theme.text.onAccent : theme.text.inverse;
72
+ // Colored = any rich surface. `background` alone activates colored mode (white text/icons).
73
+ const colored = dark || gradient || hasBackground;
74
+ // gradient (neon green) → dark text via onAccent. background → textColor prop (default white, since
75
+ // gradient surfaces are dark). dark tone → white always. text.inverse is NOT used here: it flips to
76
+ // near-black in dark-mode themes (semantic: "text on light surfaces"), wrong for dark gradient AppBars.
77
+ const onColoredText = gradient && !hasBackground
78
+ ? theme.text.onAccent
79
+ : hasBackground
80
+ ? (background?.textColor ?? "#FFFFFF")
81
+ : "#FFFFFF";
71
82
  const titleStyle = colored ? { color: onColoredText } : undefined;
72
- const subtitleStyle = gradient
83
+ const subtitleStyle = gradient && !hasBackground
73
84
  ? { color: theme.text.onAccent, opacity: 0.72 }
74
- : dark
85
+ : colored
75
86
  ? { color: "rgba(255,255,255,0.7)" }
76
87
  : undefined;
77
88
  // Large variant on a plain surface should feel like the page itself (no card surface, no
78
89
  // hairline). Compact variants (default/center) keep the card surface for detail screens.
79
90
  const largePlain = large && !colored;
80
- return (_jsxs(View, { className: cn(colored ? "" : largePlain ? "bg-bg-page" : "bg-bg-card", !colored && !largePlain && border && "border-b border-border-light", className), style: {
91
+ // bottomDivider controls the bottom edge decoration. When not set, fall back to the
92
+ // legacy border prop (hairline for default/center on plain surfaces).
93
+ const showBorder = bottomDivider
94
+ ? bottomDivider === "line"
95
+ : !colored && !largePlain && border;
96
+ const showRounded = bottomDivider === "rounded";
97
+ const showShadow = bottomDivider === "shadow";
98
+ const showWave = bottomDivider === "wave";
99
+ return (_jsxs(View, { className: cn(colored ? "" : largePlain ? "bg-bg-page" : "bg-bg-card", showBorder && "border-b border-border-light", className), style: {
81
100
  paddingTop: safeArea ? insets.top : 0,
82
- ...(dark ? { backgroundColor: theme.bg.inverse ?? HERO_DARK_FALLBACK } : null),
83
- }, testID: testID, children: [gradient ? (_jsx(GradientSurface, { colors: theme.gradient.accent, padding: "none", radius: "none", style: StyleSheet.absoluteFill })) : null, showTopBar ? (_jsxs(View, { className: "flex-row items-center px-3 gap-2 min-h-[56px]", children: [_jsxs(View, { className: "flex-row items-center gap-2", style: { minWidth: 38 }, children: [onBack ? (_jsx(AppBarAction, { accessibilityLabel: "Volver", bare: backVariant === "plain", icon: "chevron-back", onDark: dark, onPress: onBack })) : null, leading] }), _jsxs(View, { className: cn("flex-1", centered && "items-center"), children: [title ? (_jsx(Typography.Text, { className: colored ? "" : "text-text-primary", numberOfLines: 1, semibold: true, style: titleStyle, variant: "subtitle", children: title })) : null, subtitle ? (_jsx(Typography.Text, { className: colored ? "" : "text-text-secondary", numberOfLines: 1, style: subtitleStyle, variant: "caption", children: subtitle })) : null] }), _jsx(View, { className: "flex-row items-center justify-end gap-2", style: { minWidth: 38 }, children: actions })] })) : null, large && title ? (_jsxs(View, { className: cn("flex-row px-4 pt-2 pb-3", largeHasNav ? "items-center gap-2" : ""), children: [onBack ? (_jsx(AppBarAction, { accessibilityLabel: "Volver", bare: backVariant === "plain", icon: "chevron-back", onDark: dark, onPress: onBack })) : null, leading, accentBar && !largeHasNav ? (_jsx(View, { style: {
101
+ // dark tone without a background → solid inverse bg; background prop → GradientSurface handles it
102
+ ...(dark && !hasBackground
103
+ ? { backgroundColor: theme.bg.inverse ?? HERO_DARK_FALLBACK }
104
+ : null),
105
+ ...(showRounded
106
+ ? { borderBottomLeftRadius: 24, borderBottomRightRadius: 24, overflow: "hidden" }
107
+ : null),
108
+ ...(showShadow ? theme.shadow.md : null),
109
+ }, testID: testID, children: [hasBackground ? (_jsx(GradientSurface, { colors: background.colors, end: background.end, padding: "none", preset: background.surface ?? "neon-teal", radius: "none", start: background.start, style: StyleSheet.absoluteFill })) : gradient ? (_jsx(GradientSurface, { colors: theme.gradient.accent, padding: "none", radius: "none", style: StyleSheet.absoluteFill })) : null, background?.pattern ? (_jsx(Pattern, { color: background.patternColor ?? "#FFFFFF", kind: background.pattern, opacity: background.patternOpacity ?? 0.18 })) : null, showTopBar ? (_jsxs(View, { className: "flex-row items-center px-3 gap-2 min-h-[56px]", children: [_jsxs(View, { className: "flex-row items-center gap-2", style: { minWidth: 38 }, children: [onBack ? (_jsx(AppBarAction, { accessibilityLabel: "Volver", bare: backVariant === "plain", icon: "chevron-back", onDark: dark || gradient || hasBackground, onPress: onBack })) : null, leading] }), _jsxs(View, { className: cn("flex-1", centered && "items-center"), children: [title ? (_jsx(Typography.Text, { className: colored ? "" : "text-text-primary", numberOfLines: 1, semibold: true, style: titleStyle, variant: "subtitle", children: title })) : null, subtitle ? (_jsx(Typography.Text, { className: colored ? "" : "text-text-secondary", numberOfLines: 1, style: subtitleStyle, variant: "caption", children: subtitle })) : null] }), _jsx(View, { className: "flex-row items-center justify-end gap-2", style: { minWidth: 38 }, children: actions })] })) : null, large && title ? (_jsxs(View, { className: cn("flex-row px-4 pb-3", largeHasNav ? "items-center gap-2" : ""), style: { paddingTop: topSpacing != null ? topSpacing : 8 }, children: [onBack ? (_jsx(AppBarAction, { accessibilityLabel: "Volver", bare: backVariant === "plain", icon: "chevron-back", onDark: dark || gradient || hasBackground, onPress: onBack })) : null, leading, accentBar && !largeHasNav ? (_jsx(View, { style: {
84
110
  width: 4,
85
111
  marginRight: 10,
86
112
  marginVertical: 2,
87
113
  borderRadius: 999,
88
114
  backgroundColor: theme.accent,
89
- } })) : null, _jsxs(View, { className: "flex-1", children: [_jsx(Typography.Text, { className: colored ? "" : "text-text-primary", style: titleStyle, variant: "h2", children: title }), subtitle ? (_jsx(Typography.Text, { className: colored ? "" : "text-text-secondary", style: subtitleStyle, variant: "bodySmall", children: subtitle })) : null] }), actions ? (_jsx(View, { className: cn("flex-row items-center justify-end gap-2 pl-2", largeHasNav ? "" : "self-center"), children: actions })) : null] })) : null, subheader ? _jsx(View, { className: "px-3 pb-3 pt-0.5", children: subheader }) : null] }));
115
+ } })) : null, _jsxs(View, { className: "flex-1", children: [_jsx(Typography.Text, { className: colored ? "" : "text-text-primary", style: titleStyle, variant: "h2", children: title }), subtitle ? (_jsx(Typography.Text, { className: colored ? "" : "text-text-secondary", style: subtitleStyle, variant: "bodySmall", children: subtitle })) : null] }), actions ? (_jsx(View, { className: cn("flex-row items-center justify-end gap-2 pl-2", largeHasNav ? "" : "self-center"), children: actions })) : null] })) : null, subheader ? _jsx(View, { className: "px-3 pb-3 pt-0.5", children: subheader }) : null, showWave ? (_jsx(View, { style: {
116
+ height: 24,
117
+ backgroundColor: theme.bg.page,
118
+ borderTopLeftRadius: 24,
119
+ borderTopRightRadius: 24,
120
+ } })) : null] }));
90
121
  }
91
122
  const AppBarWithAction = Object.assign(AppBar, { Action: AppBarAction });
92
123
  export default AppBarWithAction;
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "nativewind/jsx-runtime";
2
2
  import Icon from "../Display/Display.Icon";
3
3
  import Pressable from "../primitives/Pressable";
4
- import { theme } from "../theme";
4
+ import { useTheme } from "../theme";
5
5
  import { cn } from "../theme/tw";
6
6
  import { Typography } from "../Typography";
7
7
  import { View } from "react-native";
@@ -14,6 +14,7 @@ const DARK_SURFACE = "#15181B";
14
14
  */
15
15
  function BottomNav({ items, value, onChange, showLabels = true, centerAction, safeArea = true, shape = "bar", tone = "light", indicator = "none", bordered = true, activeColor = "primary", className, testID, }) {
16
16
  const insets = useSafeAreaInsets();
17
+ const theme = useTheme();
17
18
  const dark = tone === "dark";
18
19
  const rounded = shape === "floating" || dark;
19
20
  const bottomPad = rounded ? 6 : safeArea ? insets.bottom : 0;
@@ -1,5 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "nativewind/jsx-runtime";
2
- import { Display } from "../Display";
2
+ import Icon from "../Display/Display.Icon";
3
+ import Logo from "../Display/Display.Logo";
3
4
  import GradientContainer from "../layouts/GradientContainer";
4
5
  import { theme } from "../theme";
5
6
  import { cn } from "../theme/tw";
@@ -11,6 +12,6 @@ import { TouchableOpacity, View } from "react-native";
11
12
  */
12
13
  const Header = ({ title, logo, logoSource, backButton, handleBackButton, className, }) => {
13
14
  const onBackPress = handleBackButton ?? (() => { });
14
- return (_jsx(GradientContainer, { className: cn("pt-10 pb-3.5 px-4", className), children: _jsxs(View, { className: "relative items-center justify-center", children: [backButton && (_jsx(TouchableOpacity, { className: "absolute top-0 left-0 z-10 border border-white p-1.5 rounded", onPress: onBackPress, children: _jsx(Display.Icon, { color: theme.text.inverse, name: "chevron-back", size: 25, type: "ionicons" }) })), _jsxs(View, { className: "items-center justify-center", children: [logo || _jsx(Display.Logo, { size: "medium", source: logoSource }), title && (_jsx(Typography.Text, { className: "text-white", variant: "h4", children: title }))] })] }) }));
15
+ return (_jsx(GradientContainer, { className: cn("pt-10 pb-3.5 px-4", className), children: _jsxs(View, { className: "relative items-center justify-center", children: [backButton && (_jsx(TouchableOpacity, { className: "absolute top-0 left-0 z-10 border border-white p-1.5 rounded", onPress: onBackPress, children: _jsx(Icon, { color: theme.text.inverse, name: "chevron-back", size: 25, type: "ionicons" }) })), _jsxs(View, { className: "items-center justify-center", children: [logo || _jsx(Logo, { size: "medium", source: logoSource }), title && (_jsx(Typography.Text, { className: "text-white", variant: "h4", children: title }))] })] }) }));
15
16
  };
16
17
  export default Header;
@@ -1,12 +1,13 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "nativewind/jsx-runtime";
2
2
  import Icon from "../Display/Display.Icon";
3
3
  import Pressable from "../primitives/Pressable";
4
- import { theme } from "../theme";
4
+ import { useTheme } from "../theme";
5
5
  import { cn } from "../theme/tw";
6
6
  import { Typography } from "../Typography";
7
- import { useRef, useState } from "react";
7
+ import { cloneElement, useRef, useState } from "react";
8
8
  import { Dimensions, Modal, Pressable as RNPressable, View } from "react-native";
9
9
  function Menu({ items, trigger, menuWidth = 220, testID }) {
10
+ const theme = useTheme();
10
11
  const triggerRef = useRef(null);
11
12
  const [anchor, setAnchor] = useState(null);
12
13
  const open = () => {
@@ -18,7 +19,9 @@ function Menu({ items, trigger, menuWidth = 220, testID }) {
18
19
  const screen = Dimensions.get("window");
19
20
  const right = anchor ? Math.max(8, screen.width - (anchor.x + anchor.width)) : 8;
20
21
  const top = anchor ? anchor.y + anchor.height + 4 : 0;
21
- return (_jsxs(View, { collapsable: false, ref: triggerRef, testID: testID, children: [_jsx(Pressable, { accessibilityLabel: "M\u00E1s opciones", accessibilityRole: "button", onPress: open, children: trigger ?? _jsx(Icon, { color: theme.icon.secondary, name: "ellipsis-vertical", size: 22 }) }), _jsx(Modal, { animationType: "fade", onRequestClose: close, transparent: true, visible: anchor !== null, children: _jsx(RNPressable, { onPress: close, style: { flex: 1 }, children: _jsx(View, { className: "rounded-lg py-1", style: {
22
+ return (_jsxs(View, { collapsable: false, ref: triggerRef, testID: testID, children: [trigger ? (
23
+ // eslint-disable-next-line react-hooks/refs
24
+ cloneElement(trigger, { onPress: open })) : (_jsx(Pressable, { accessibilityLabel: "M\u00E1s opciones", accessibilityRole: "button", onPress: open, children: _jsx(Icon, { color: theme.icon.secondary, name: "ellipsis-vertical", size: 22 }) })), _jsx(Modal, { animationType: "fade", onRequestClose: close, transparent: true, visible: anchor !== null, children: _jsx(RNPressable, { onPress: close, style: { flex: 1 }, children: _jsx(View, { className: "rounded-lg py-1", style: {
22
25
  position: "absolute",
23
26
  top,
24
27
  right,
@@ -0,0 +1,19 @@
1
+ import { ReactNode } from "react";
2
+ export interface MenuSectionProps {
3
+ /** Section heading above the card. */
4
+ title?: string;
5
+ /** Footer note below the card (hints, disclaimers). */
6
+ footer?: string;
7
+ children: ReactNode;
8
+ }
9
+ /**
10
+ * Titled card that groups `Display.MenuButton` rows into a visual section.
11
+ * Mirrors iOS grouped-table-view style: title above, card surface, optional footer note.
12
+ *
13
+ * Usage:
14
+ * <MenuSection title="General">
15
+ * <Display.MenuButton label="Impresora" icon={PrinterIcon} onPress={...} />
16
+ * <Display.MenuButton label="Ajustes" icon={SettingsIcon} onPress={...} showDivider={false} />
17
+ * </MenuSection>
18
+ */
19
+ export declare function MenuSection({ title, footer, children }: MenuSectionProps): import("react").JSX.Element;
@@ -0,0 +1,25 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "nativewind/jsx-runtime";
2
+ import { useTheme } from "../theme";
3
+ import { Typography } from "../Typography";
4
+ import { View } from "react-native";
5
+ /**
6
+ * Titled card that groups `Display.MenuButton` rows into a visual section.
7
+ * Mirrors iOS grouped-table-view style: title above, card surface, optional footer note.
8
+ *
9
+ * Usage:
10
+ * <MenuSection title="General">
11
+ * <Display.MenuButton label="Impresora" icon={PrinterIcon} onPress={...} />
12
+ * <Display.MenuButton label="Ajustes" icon={SettingsIcon} onPress={...} showDivider={false} />
13
+ * </MenuSection>
14
+ */
15
+ export function MenuSection({ title, footer, children }) {
16
+ const theme = useTheme();
17
+ return (_jsxs(View, { style: { marginHorizontal: 16, marginBottom: 20 }, children: [title ? (_jsx(Typography.Text, { semibold: true, style: { color: theme.text.secondary, marginBottom: 6, paddingHorizontal: 4 }, variant: "caption", children: title.toUpperCase() })) : null, _jsx(View, { style: {
18
+ backgroundColor: theme.bg.card,
19
+ borderRadius: 14,
20
+ borderWidth: 1,
21
+ borderColor: theme.border.default,
22
+ overflow: "hidden",
23
+ ...theme.shadow.sm,
24
+ }, children: children }), footer ? (_jsx(Typography.Text, { style: { color: theme.text.tertiary, marginTop: 6, paddingHorizontal: 4 }, variant: "caption", children: footer })) : null] }));
25
+ }
@@ -1,14 +1,28 @@
1
+ import { ComponentType } from "react";
1
2
  export interface SegmentedOption<T extends string> {
2
3
  label: string;
3
4
  value: T;
5
+ /** Ionicon name rendered above (or before) the label. */
6
+ icon?: string;
7
+ /** Custom icon component — takes precedence over `icon`. */
8
+ customIcon?: ComponentType<{
9
+ size?: number;
10
+ color?: string;
11
+ }>;
4
12
  }
5
13
  export interface SegmentedControlProps<T extends string> {
6
14
  options: SegmentedOption<T>[];
7
15
  value: T;
8
16
  onChange: (value: T) => void;
17
+ /**
18
+ * Icon layout when options have icons:
19
+ * - `"top"` (default) — icon stacked above the label (taller pill).
20
+ * - `"left"` — icon inline left of the label (compact, single-line).
21
+ */
22
+ iconLayout?: "top" | "left";
9
23
  className?: string;
10
24
  testID?: string;
11
25
  }
12
- declare function SegmentedControl<T extends string>({ options, value, onChange, className, testID, }: SegmentedControlProps<T>): import("react").JSX.Element;
26
+ declare function SegmentedControl<T extends string>({ options, value, onChange, iconLayout, className, testID, }: SegmentedControlProps<T>): import("react").JSX.Element;
13
27
  export default SegmentedControl;
14
28
  export { SegmentedControl };
@@ -1,12 +1,30 @@
1
- import { jsx as _jsx } from "nativewind/jsx-runtime";
2
- import { theme } from "../theme";
1
+ import { jsx as _jsx, jsxs as _jsxs } from "nativewind/jsx-runtime";
2
+ import Icon from "../Display/Display.Icon";
3
+ import { useTheme } from "../theme";
3
4
  import { cn } from "../theme/tw";
4
5
  import { Typography } from "../Typography";
5
6
  import { TouchableOpacity, View } from "react-native";
6
- function SegmentedControl({ options, value, onChange, className, testID, }) {
7
+ function SegmentedControl({ options, value, onChange, iconLayout = "top", className, testID, }) {
8
+ const theme = useTheme();
9
+ const hasIcons = options.some((o) => o.icon || o.customIcon);
7
10
  return (_jsx(View, { accessibilityRole: "tablist", className: cn("flex-row bg-bg-muted rounded-lg p-1 gap-1", className), testID: testID, children: options.map((option) => {
8
11
  const selected = option.value === value;
9
- return (_jsx(TouchableOpacity, { accessibilityLabel: option.label, accessibilityRole: "tab", accessibilityState: { selected }, activeOpacity: 0.7, className: "flex-1 items-center justify-center py-2 rounded-md", onPress: () => onChange(option.value), style: selected ? { backgroundColor: theme.bg.card, ...theme.shadow.sm } : undefined, children: _jsx(Typography.Text, { numberOfLines: 1, semibold: selected, style: { color: selected ? theme.text.primary : theme.text.secondary }, children: option.label }) }, option.value));
12
+ const iconColor = selected ? theme.text.primary : theme.text.secondary;
13
+ const hasIcon = !!(option.icon || option.customIcon);
14
+ const inline = hasIcons && iconLayout === "left";
15
+ return (_jsxs(TouchableOpacity, { accessibilityLabel: option.label, accessibilityRole: "tab", accessibilityState: { selected }, activeOpacity: 0.7, onPress: () => onChange(option.value), style: {
16
+ flex: 1,
17
+ flexDirection: inline ? "row" : "column",
18
+ alignItems: "center",
19
+ justifyContent: "center",
20
+ gap: hasIcon ? 4 : 0,
21
+ paddingVertical: hasIcons && !inline ? 8 : 8,
22
+ paddingHorizontal: 4,
23
+ borderRadius: 8,
24
+ ...(selected
25
+ ? { backgroundColor: theme.bg.card, ...theme.shadow.sm }
26
+ : undefined),
27
+ }, children: [hasIcon ? (_jsx(Icon, { color: iconColor, customIcon: option.customIcon, name: option.icon, size: 16, type: option.customIcon ? "custom" : "ionicons" })) : null, _jsx(Typography.Text, { numberOfLines: 1, semibold: selected, style: { color: iconColor, fontSize: 12 }, variant: "caption", children: option.label })] }, option.value));
10
28
  }) }));
11
29
  }
12
30
  export default SegmentedControl;
@@ -1,8 +1,7 @@
1
1
  import { jsx as _jsx } from "nativewind/jsx-runtime";
2
- import { Display } from "../Display";
2
+ import Icon from "../Display/Display.Icon";
3
3
  import { cn } from "../theme/tw";
4
4
  import { View } from "react-native";
5
- const Icon = Display.Icon;
6
5
  /**
7
6
  * @deprecated Orphan tab-bar icon piece (unused). Use `Navigation.BottomNav` (single source
8
7
  * of truth for the bottom tab bar). Kept for backwards compatibility; removed in the next major.
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx } from "nativewind/jsx-runtime";
2
- import { Display } from "../Display";
2
+ import Icon from "../Display/Display.Icon";
3
3
  import { cn } from "../theme/tw";
4
4
  import { View } from "react-native";
5
5
  /**
@@ -8,6 +8,6 @@ import { View } from "react-native";
8
8
  * compatibility; removed in the next major.
9
9
  */
10
10
  const TabIcon = ({ focused, size = 24, customIcon, type = "custom", name, className, }) => {
11
- return (_jsx(View, { className: cn("justify-center items-center w-12 h-12 rounded-full", focused ? "bg-primary shadow-md" : "bg-transparent", className), children: _jsx(Display.Icon, { color: focused ? "#FFFFFF" : "#6B7280", customIcon: customIcon, name: name, size: size, type: type }) }));
11
+ return (_jsx(View, { className: cn("justify-center items-center w-12 h-12 rounded-full", focused ? "bg-primary shadow-md" : "bg-transparent", className), children: _jsx(Icon, { color: focused ? "#FFFFFF" : "#6B7280", customIcon: customIcon, name: name, size: size, type: type }) }));
12
12
  };
13
13
  export default TabIcon;
@@ -1,20 +1,25 @@
1
1
  import { type ReactNode } from "react";
2
+ type TabsVariant = "underline" | "filled";
2
3
  export interface TabsProps {
3
4
  value?: string;
4
5
  defaultValue?: string;
5
6
  onValueChange?: (value: string) => void;
7
+ variant?: TabsVariant;
6
8
  className?: string;
7
9
  children: ReactNode;
8
10
  }
9
- declare function TabsRoot({ value, defaultValue, onValueChange, className, children }: TabsProps): import("react").JSX.Element;
11
+ declare function TabsRoot({ value, defaultValue, onValueChange, variant, className, children, }: TabsProps): import("react").JSX.Element;
10
12
  declare function TabsList({ children, className }: {
11
13
  children: ReactNode;
12
14
  className?: string;
13
15
  }): import("react").JSX.Element;
14
- declare function TabsTrigger({ value, children }: {
16
+ export interface TabsTriggerProps {
15
17
  value: string;
16
18
  children: ReactNode;
17
- }): import("react").JSX.Element;
19
+ icon?: string;
20
+ iconLayout?: "top" | "left";
21
+ }
22
+ declare function TabsTrigger({ value, children, icon, iconLayout }: TabsTriggerProps): import("react").JSX.Element;
18
23
  declare function TabsContent({ value, children }: {
19
24
  value: string;
20
25
  children: ReactNode;
@@ -1,5 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "nativewind/jsx-runtime";
2
- import { theme } from "../theme";
2
+ import Icon from "../Display/Display.Icon";
3
+ import { useTheme } from "../theme";
3
4
  import { cn } from "../theme/tw";
4
5
  import { Typography } from "../Typography";
5
6
  import { createContext, useCallback, useContext, useState } from "react";
@@ -12,7 +13,7 @@ function useTabs() {
12
13
  }
13
14
  return ctx;
14
15
  }
15
- function TabsRoot({ value, defaultValue, onValueChange, className, children }) {
16
+ function TabsRoot({ value, defaultValue, onValueChange, variant = "underline", className, children, }) {
16
17
  const [internal, setInternal] = useState(defaultValue ?? "");
17
18
  const current = value ?? internal;
18
19
  const setValue = useCallback((next) => {
@@ -20,15 +21,27 @@ function TabsRoot({ value, defaultValue, onValueChange, className, children }) {
20
21
  setInternal(next);
21
22
  onValueChange?.(next);
22
23
  }, [value, onValueChange]);
23
- return (_jsx(TabsContext.Provider, { value: { value: current, setValue }, children: _jsx(View, { className: cn("flex-1", className), children: children }) }));
24
+ return (_jsx(TabsContext.Provider, { value: { value: current, setValue, variant }, children: _jsx(View, { className: cn("flex-1", className), children: children }) }));
24
25
  }
25
26
  function TabsList({ children, className }) {
27
+ const { variant } = useTabs();
28
+ if (variant === "filled") {
29
+ return (_jsx(View, { accessibilityRole: "tablist", className: cn("flex-row rounded-xl p-1", className), style: { backgroundColor: "#E5E7EB" }, children: children }));
30
+ }
26
31
  return (_jsx(View, { accessibilityRole: "tablist", className: cn("flex-row border-b border-border-default", className), children: children }));
27
32
  }
28
- function TabsTrigger({ value, children }) {
29
- const { value: active, setValue } = useTabs();
33
+ function TabsTrigger({ value, children, icon, iconLayout = "left" }) {
34
+ const theme = useTheme();
35
+ const { value: active, setValue, variant } = useTabs();
30
36
  const selected = active === value;
31
- return (_jsxs(TouchableOpacity, { accessibilityRole: "tab", accessibilityState: { selected }, activeOpacity: 0.7, className: "flex-1 items-center", onPress: () => setValue(value), children: [_jsx(View, { className: "py-3", children: _jsx(Typography.Text, { semibold: selected, style: { color: selected ? theme.primary : theme.text.secondary }, children: children }) }), _jsx(View, { className: "h-0.5 w-full", style: { backgroundColor: selected ? theme.primary : "transparent" } })] }));
37
+ const iconColor = selected ? theme.primary : theme.text.secondary;
38
+ if (variant === "filled") {
39
+ return (_jsx(TouchableOpacity, { accessibilityRole: "tab", accessibilityState: { selected }, activeOpacity: 0.7, className: "flex-1 items-center justify-center rounded-lg py-2", onPress: () => setValue(value), style: selected ? { backgroundColor: theme.bg.card, ...theme.shadow.sm } : {}, children: _jsxs(View, { className: cn("items-center", iconLayout === "left" && icon ? "flex-row gap-1.5" : "gap-1"), children: [icon && iconLayout === "top" && _jsx(Icon, { color: iconColor, name: icon, size: 16 }), icon && iconLayout === "left" && _jsx(Icon, { color: iconColor, name: icon, size: 14 }), _jsx(Typography.Text, { semibold: selected, style: { color: iconColor }, variant: "bodySmall", children: children })] }) }));
40
+ }
41
+ // underline variant
42
+ return (_jsxs(TouchableOpacity, { accessibilityRole: "tab", accessibilityState: { selected }, activeOpacity: 0.7, className: "flex-1 items-center", onPress: () => setValue(value), children: [_jsxs(View, { className: cn("py-3", iconLayout === "top" && icon
43
+ ? "items-center gap-1"
44
+ : "flex-row items-center gap-1.5"), children: [icon && iconLayout === "top" && _jsx(Icon, { color: iconColor, name: icon, size: 18 }), icon && iconLayout === "left" && _jsx(Icon, { color: iconColor, name: icon, size: 14 }), _jsx(Typography.Text, { semibold: selected, style: { color: iconColor }, children: children })] }), _jsx(View, { className: "h-0.5 w-full", style: { backgroundColor: selected ? theme.primary : "transparent" } })] }));
32
45
  }
33
46
  function TabsContent({ value, children }) {
34
47
  const { value: active } = useTabs();
@@ -3,13 +3,16 @@ import CollapsingHeader from "../Navigation/Navigation.CollapsingHeader";
3
3
  import FloatingBar from "../Navigation/Navigation.FloatingBar";
4
4
  import HeaderToolbar from "../Navigation/Navigation.HeaderToolbar";
5
5
  import Menu from "../Navigation/Navigation.Menu";
6
+ import { MenuSection } from "../Navigation/Navigation.MenuSection";
6
7
  import RowItem from "../Navigation/Navigation.RowItem";
7
8
  import SearchBar from "../Navigation/Navigation.SearchBar";
8
9
  import SegmentedControl from "../Navigation/Navigation.SegmentedControl";
9
10
  import Steps from "../Navigation/Navigation.Steps";
10
11
  import TabIcon from "../Navigation/Navigation.TabIcon";
12
+ export type { AppBarBackground } from "../Navigation/Navigation.AppBar";
13
+ export type { MenuSectionProps } from "../Navigation/Navigation.MenuSection";
11
14
  export declare const Navigation: {
12
- AppBar: (({ title, subtitle, onBack, leading, actions, subheader, variant, tone, accentBar, backVariant, border, safeArea, className, testID, }: import("../Navigation/Navigation.AppBar").AppBarProps) => import("react").JSX.Element) & {
15
+ AppBar: (({ title, subtitle, onBack, leading, actions, subheader, variant, tone, accentBar, backVariant, border, safeArea, topSpacing, background, bottomDivider, className, testID, }: import("../Navigation/Navigation.AppBar").AppBarProps) => import("react").JSX.Element) & {
13
16
  Action: ({ icon, label, onPress, badge, accessibilityLabel, tone, onDark, bare, testID, }: import("../Navigation/Navigation.AppBar").AppBarActionProps) => import("react").JSX.Element;
14
17
  };
15
18
  BottomNav: typeof BottomNav;
@@ -22,21 +25,19 @@ export declare const Navigation: {
22
25
  TabIcon: typeof TabIcon;
23
26
  RowItem: typeof RowItem;
24
27
  SegmentedControl: typeof SegmentedControl;
25
- Tabs: (({ value, defaultValue, onValueChange, className, children }: import("../Navigation/Navigation.Tabs").TabsProps) => import("react").JSX.Element) & {
28
+ Tabs: (({ value, defaultValue, onValueChange, variant, className, children, }: import("../Navigation/Navigation.Tabs").TabsProps) => import("react").JSX.Element) & {
26
29
  List: ({ children, className }: {
27
30
  children: import("react").ReactNode;
28
31
  className?: string;
29
32
  }) => import("react").JSX.Element;
30
- Trigger: ({ value, children }: {
31
- value: string;
32
- children: import("react").ReactNode;
33
- }) => import("react").JSX.Element;
33
+ Trigger: ({ value, children, icon, iconLayout }: import("../Navigation/Navigation.Tabs").TabsTriggerProps) => import("react").JSX.Element;
34
34
  Content: ({ value, children }: {
35
35
  value: string;
36
36
  children: import("react").ReactNode;
37
37
  }) => import("react").JSX.Element | null;
38
38
  };
39
39
  Menu: typeof Menu;
40
+ MenuSection: typeof MenuSection;
40
41
  Steps: typeof Steps;
41
42
  };
42
43
  export default Navigation;
@@ -5,6 +5,7 @@ import FloatingBar from "../Navigation/Navigation.FloatingBar";
5
5
  import Header from "../Navigation/Navigation.Header";
6
6
  import HeaderToolbar from "../Navigation/Navigation.HeaderToolbar";
7
7
  import Menu from "../Navigation/Navigation.Menu";
8
+ import { MenuSection } from "../Navigation/Navigation.MenuSection";
8
9
  import RowItem from "../Navigation/Navigation.RowItem";
9
10
  import SearchBar from "../Navigation/Navigation.SearchBar";
10
11
  import SegmentedControl from "../Navigation/Navigation.SegmentedControl";
@@ -26,6 +27,7 @@ export const Navigation = {
26
27
  SegmentedControl,
27
28
  Tabs,
28
29
  Menu,
30
+ MenuSection,
29
31
  Steps,
30
32
  };
31
33
  export default Navigation;
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ export { Actions } from "./Actions";
1
2
  export { Dialog } from "./Dialog";
2
3
  export { Display } from "./Display";
3
4
  export { Feedback } from "./Feedback";
@@ -8,6 +9,7 @@ export { Box, Row, Stack } from "./primitives";
8
9
  export { type BrandingConfig, getBrandingLogo, setBranding, } from "./branding";
9
10
  export { cn, tv, type VariantProps } from "./theme/tw";
10
11
  export { fontFamilies, fontSizes, fontWeights, letterSpacing, lineHeights, typographyVariants, } from "./theme/typography";
12
+ export { BottomInsetContext } from "./layouts/BottomInset";
11
13
  export { default as Container } from "./layouts/Container";
12
14
  export { default as GradientContainer } from "./layouts/GradientContainer";
13
15
  export { default as PlainLayout } from "./layouts/PlainLayout";
package/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  // Design System - Compound Components
2
+ export { Actions } from "./Actions";
2
3
  export { Dialog } from "./Dialog";
3
4
  export { Display } from "./Display";
4
5
  export { Feedback } from "./Feedback";
@@ -13,6 +14,7 @@ export { getBrandingLogo, setBranding, } from "./branding";
13
14
  export { cn, tv } from "./theme/tw";
14
15
  export { fontFamilies, fontSizes, fontWeights, letterSpacing, lineHeights, typographyVariants, } from "./theme/typography";
15
16
  // Layouts
17
+ export { BottomInsetContext } from "./layouts/BottomInset";
16
18
  export { default as Container } from "./layouts/Container";
17
19
  export { default as GradientContainer } from "./layouts/GradientContainer";
18
20
  export { default as PlainLayout } from "./layouts/PlainLayout";
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Extra bottom inset for scroll views, provided by the host app when a floating
3
+ * element (e.g. position:absolute tab bar) sits above the native safe area.
4
+ *
5
+ * FormViewV2.Content and ListViewV2.Content add this value as extra
6
+ * `contentContainerStyle.paddingBottom` so content can scroll fully above the bar.
7
+ *
8
+ * Usage in the host app:
9
+ * <BottomInsetContext.Provider value={72}>
10
+ * <Tabs.Navigator ...>
11
+ *
12
+ * Default: 0 — no extra inset (backwards compatible).
13
+ * The native safe-area inset is already handled by Container (SafeAreaView edges=["bottom"]).
14
+ */
15
+ export declare const BottomInsetContext: import("react").Context<number>;
16
+ export declare const useBottomInset: () => number;
@@ -0,0 +1,17 @@
1
+ import { createContext, useContext } from "react";
2
+ /**
3
+ * Extra bottom inset for scroll views, provided by the host app when a floating
4
+ * element (e.g. position:absolute tab bar) sits above the native safe area.
5
+ *
6
+ * FormViewV2.Content and ListViewV2.Content add this value as extra
7
+ * `contentContainerStyle.paddingBottom` so content can scroll fully above the bar.
8
+ *
9
+ * Usage in the host app:
10
+ * <BottomInsetContext.Provider value={72}>
11
+ * <Tabs.Navigator ...>
12
+ *
13
+ * Default: 0 — no extra inset (backwards compatible).
14
+ * The native safe-area inset is already handled by Container (SafeAreaView edges=["bottom"]).
15
+ */
16
+ export const BottomInsetContext = createContext(0);
17
+ export const useBottomInset = () => useContext(BottomInsetContext);
@@ -1,12 +1,12 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "nativewind/jsx-runtime";
2
- import { Display } from "../Display";
2
+ import DisplayIcon from "../Display/Display.Icon";
3
3
  import Container from "../layouts/Container";
4
4
  import { Typography } from "../Typography";
5
5
  import { Children, isValidElement } from "react";
6
6
  import { TouchableOpacity, View } from "react-native";
7
7
  import { useSafeAreaInsets } from "react-native-safe-area-context";
8
8
  function TabIcon({ focused, Icon }) {
9
- return (_jsxs(View, { className: "justify-center items-center w-10 h-10", children: [focused && _jsx(View, { className: "absolute w-10 h-10 rounded-full bg-primary" }), _jsx(Display.Icon, { color: focused ? "#FFFFFF" : "#6B7280", customIcon: Icon, size: 24, type: "custom" })] }));
9
+ return (_jsxs(View, { className: "justify-center items-center w-10 h-10", children: [focused && _jsx(View, { className: "absolute w-10 h-10 rounded-full bg-primary" }), _jsx(DisplayIcon, { color: focused ? "#FFFFFF" : "#6B7280", customIcon: Icon, size: 24, type: "custom" })] }));
10
10
  }
11
11
  function TabNavigator({ items, currentPath, onTabPress, }) {
12
12
  const insets = useSafeAreaInsets();