@kanso-labs/react-native-kanso-ui 0.5.0 → 0.7.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 (125) hide show
  1. package/README.md +4 -1
  2. package/dist/badge/index.js +74 -0
  3. package/dist/badge/index.js.map +1 -0
  4. package/dist/badge/styles.js +51 -0
  5. package/dist/badge/styles.js.map +1 -0
  6. package/dist/button/index.d.ts +1 -1
  7. package/dist/button/index.js +1 -1
  8. package/dist/button/pending.js +1 -1
  9. package/dist/button/slots.d.ts +2 -2
  10. package/dist/calendar/index.js +1182 -0
  11. package/dist/calendar/index.js.map +1 -0
  12. package/dist/calendar/styles.js +120 -0
  13. package/dist/calendar/styles.js.map +1 -0
  14. package/dist/chip/index.js +2 -2
  15. package/dist/components/app-bar/index.d.ts +111 -0
  16. package/dist/components/app-bar/index.js +341 -0
  17. package/dist/components/app-bar/index.js.map +1 -0
  18. package/dist/components/avatar/index.d.ts +1 -1
  19. package/dist/components/button/index.d.ts +1 -1
  20. package/dist/components/button/index.js +2 -2
  21. package/dist/components/calendar/index.d.ts +51 -0
  22. package/dist/components/calendar/index.js +82 -0
  23. package/dist/components/calendar/index.js.map +1 -0
  24. package/dist/components/card/index.d.ts +1 -1
  25. package/dist/components/card/index.js +3 -3
  26. package/dist/components/checkbox/index.d.ts +1 -1
  27. package/dist/components/checkbox/index.js +1 -1
  28. package/dist/components/chip/index.d.ts +1 -1
  29. package/dist/components/chip/index.js +1 -1
  30. package/dist/components/chip-group/index.d.ts +1 -1
  31. package/dist/components/chip-group/index.js +4 -4
  32. package/dist/components/copy-field/index.d.ts +1 -1
  33. package/dist/components/copy-field/index.js +1 -1
  34. package/dist/components/currency/index.d.ts +1 -1
  35. package/dist/components/currency/index.js +1 -1
  36. package/dist/components/dialog/index.d.ts +1 -1
  37. package/dist/components/dialog/index.js +2 -2
  38. package/dist/components/icon-button/index.d.ts +1 -1
  39. package/dist/components/icon-button/index.js +2 -2
  40. package/dist/components/link/index.d.ts +1 -1
  41. package/dist/components/link/index.js +3 -3
  42. package/dist/components/list/index.d.ts +1 -1
  43. package/dist/components/list/index.js +5 -5
  44. package/dist/components/list-detail/index.d.ts +56 -0
  45. package/dist/components/list-detail/index.js +169 -0
  46. package/dist/components/list-detail/index.js.map +1 -0
  47. package/dist/components/list-item/index.d.ts +1 -1
  48. package/dist/components/list-item/index.js +1 -1
  49. package/dist/components/menu/index.d.ts +1 -1
  50. package/dist/components/menu/index.js +7 -7
  51. package/dist/components/meter/index.d.ts +1 -1
  52. package/dist/components/meter/index.js +1 -1
  53. package/dist/components/navigation-bar/index.d.ts +164 -0
  54. package/dist/components/navigation-bar/index.js +470 -0
  55. package/dist/components/navigation-bar/index.js.map +1 -0
  56. package/dist/components/navigation-rail/index.d.ts +68 -0
  57. package/dist/components/navigation-rail/index.js +294 -0
  58. package/dist/components/navigation-rail/index.js.map +1 -0
  59. package/dist/components/number-field/index.d.ts +1 -1
  60. package/dist/components/number-field/index.js +5 -5
  61. package/dist/components/popover/index.d.ts +1 -1
  62. package/dist/components/popover/index.js +3 -3
  63. package/dist/components/product-icon/index.d.ts +1 -1
  64. package/dist/components/progress-indicator/index.d.ts +1 -1
  65. package/dist/components/progress-indicator/index.js +3 -3
  66. package/dist/components/radio-group/index.d.ts +1 -1
  67. package/dist/components/radio-group/index.js +3 -3
  68. package/dist/components/search-field/index.d.ts +1 -1
  69. package/dist/components/search-field/index.js +5 -5
  70. package/dist/components/segmented-button/index.d.ts +1 -1
  71. package/dist/components/segmented-button/index.js +5 -5
  72. package/dist/components/separator/index.d.ts +1 -1
  73. package/dist/components/separator/index.js +1 -1
  74. package/dist/components/sheet/index.d.ts +1 -1
  75. package/dist/components/sheet/index.js +3 -3
  76. package/dist/components/snackbar/index.d.ts +1 -1
  77. package/dist/components/snackbar/index.js +4 -4
  78. package/dist/components/stack/index.d.ts +1 -1
  79. package/dist/components/stack/index.js +1 -1
  80. package/dist/components/switch/index.d.ts +1 -1
  81. package/dist/components/switch/index.js +4 -4
  82. package/dist/components/text/index.d.ts +1 -1
  83. package/dist/components/text/index.js +1 -1
  84. package/dist/components/text-field/index.d.ts +1 -1
  85. package/dist/components/text-field/index.js +1 -1
  86. package/dist/control/checkbox-box.js +2 -2
  87. package/dist/control/index.js +1 -1
  88. package/dist/field/index.d.ts +1 -1
  89. package/dist/field/index.js +4 -4
  90. package/dist/form/index.d.ts +1 -1
  91. package/dist/glyphs/index.js +21 -3
  92. package/dist/glyphs/index.js.map +1 -1
  93. package/dist/hooks/useAppBarScroll.d.ts +56 -0
  94. package/dist/hooks/useAppBarScroll.js +87 -0
  95. package/dist/hooks/useAppBarScroll.js.map +1 -0
  96. package/dist/i18n/messages.js +374 -0
  97. package/dist/i18n/messages.js.map +1 -1
  98. package/dist/index.d.ts +9 -3
  99. package/dist/index.js +10 -4
  100. package/dist/indicator/index.d.ts +2 -2
  101. package/dist/indicator/index.js +3 -3
  102. package/dist/indicator/motion.js +1 -1
  103. package/dist/mark/index.d.ts +1 -1
  104. package/dist/mark/index.js +2 -2
  105. package/dist/modal/index.d.ts +1 -1
  106. package/dist/modal/index.js +2 -2
  107. package/dist/navigation/index.d.ts +36 -0
  108. package/dist/navigation/index.js +454 -0
  109. package/dist/navigation/index.js.map +1 -0
  110. package/dist/navigation/styles.js +83 -0
  111. package/dist/navigation/styles.js.map +1 -0
  112. package/dist/overlay/anchored.d.ts +2 -2
  113. package/dist/overlay/anchored.js +1 -1
  114. package/dist/overlay/host.d.ts +2 -2
  115. package/dist/overlay/host.js +1 -1
  116. package/dist/overlay/panel.js +2 -2
  117. package/dist/press/index.js +75 -69
  118. package/dist/press/index.js.map +1 -1
  119. package/dist/router/index.js +1 -1
  120. package/dist/row/index.js +1 -1
  121. package/dist/theme/scope.js +1 -1
  122. package/dist/theme-scope.d.ts +1 -1
  123. package/dist/theme-scope.js +1 -1
  124. package/dist/typography/fonts.js +1 -1
  125. package/package.json +4 -3
@@ -0,0 +1,164 @@
1
+ import { NavigationItemProps } from "../../navigation/index.js";
2
+ import { StyleProp, View, ViewProps, ViewStyle } from "react-native";
3
+ import { ComponentRef, ReactNode, Ref } from "react";
4
+ //#region src/components/navigation-bar/index.d.ts
5
+ type NavigationBarItemProps = NavigationItemProps;
6
+ type NavigationBarProps = Omit<ViewProps, 'children' | 'style'> & {
7
+ /** The destinations, each a `NavigationBar.Item`. */
8
+ readonly children?: ReactNode;
9
+ readonly ref?: Ref<ComponentRef<typeof View>>;
10
+ /**
11
+ * The route of the current destination, matched against each
12
+ * destination's `href`. The match is the selected tab, and draws the
13
+ * active indicator.
14
+ */
15
+ readonly selectedRoute?: string | undefined;
16
+ readonly style?: StyleProp<ViewStyle>;
17
+ };
18
+ /** The routes a tab navigator hands its tab bar, as both navigators do. */
19
+ type NavigationTabBarProps = Omit<NavigationBarProps, 'children' | 'selectedRoute'> & TabNavigatorProps & {
20
+ /** Each route's options, by the route's key. */
21
+ readonly descriptors: Readonly<Partial<Record<string, {
22
+ readonly options: TabOptions;
23
+ }>>>;
24
+ /**
25
+ * The insets the navigator measured, which the bar measures for itself
26
+ * instead.
27
+ */
28
+ readonly insets?: unknown;
29
+ /** The navigator's routes, and which of them is focused. */
30
+ readonly state: {
31
+ readonly index: number;
32
+ readonly routes: readonly TabRoute[];
33
+ };
34
+ };
35
+ /**
36
+ * What hears a tab bar's events: React Navigation's `navigation` and Expo
37
+ * Router's `emitter` alike.
38
+ */
39
+ type TabEmitter = {
40
+ emit(event: TabEvent): unknown;
41
+ };
42
+ /** The events a tab bar reports, as both navigators name them. */
43
+ type TabEvent = {
44
+ readonly canPreventDefault: true;
45
+ readonly target: string;
46
+ readonly type: 'tabPress';
47
+ } | {
48
+ readonly target: string;
49
+ readonly type: 'tabLongPress';
50
+ };
51
+ /**
52
+ * How a tab bar moves to a tab: through React Navigation's `navigation`, or
53
+ * through Expo Router's `navigateToTab`.
54
+ */
55
+ type TabNavigatorProps = {
56
+ readonly emitter: TabEmitter;
57
+ readonly navigateToTab: (routeKey: string) => void;
58
+ readonly navigation?: never;
59
+ } | {
60
+ readonly emitter?: never;
61
+ readonly navigateToTab?: never;
62
+ readonly navigation: TabEmitter & {
63
+ navigate(name: string, params?: object): void;
64
+ };
65
+ };
66
+ /**
67
+ * A tab's options the bar reads, as React Navigation's bottom tabs and Expo
68
+ * Router's tabs both hand them to a tab bar. Options they take that are not
69
+ * listed here are left to them.
70
+ */
71
+ type TabOptions = {
72
+ /** The tab's name for a screen reader, where it differs from its label. */
73
+ readonly tabBarAccessibilityLabel?: string | undefined;
74
+ /**
75
+ * The badge on the tab's icon. A number, or a string of digits, is the
76
+ * large badge's count; any other string is the small dot, since a badge
77
+ * draws a count and nothing else.
78
+ */
79
+ readonly tabBarBadge?: number | string | undefined;
80
+ readonly tabBarButtonTestID?: string | undefined;
81
+ /** The tab's icon, drawn at the size and in the colour it is handed. */
82
+ readonly tabBarIcon?: ((props: {
83
+ readonly color: string;
84
+ readonly focused: boolean;
85
+ readonly size: number;
86
+ }) => ReactNode) | undefined;
87
+ /** The tab's label, in place of its title. */
88
+ readonly tabBarLabel?: ((props: {
89
+ readonly children: string;
90
+ readonly color: string;
91
+ readonly focused: boolean;
92
+ readonly position: 'below-icon' | 'beside-icon';
93
+ }) => ReactNode) | string | undefined;
94
+ readonly title?: string | undefined;
95
+ };
96
+ type TabRoute = {
97
+ readonly key: string;
98
+ readonly name: string;
99
+ readonly params?: object | undefined;
100
+ };
101
+ /**
102
+ * The bar of three to five top-level destinations a compact window keeps at
103
+ * its bottom edge. Each destination goes to its `href` through the app's
104
+ * router, see `RouterProvider`.
105
+ *
106
+ * ```tsx
107
+ * <NavigationBar selectedRoute="/first">
108
+ * <NavigationBar.Item href="/first" icon={<FirstIcon />}>
109
+ * First item
110
+ * </NavigationBar.Item>
111
+ * <NavigationBar.Item href="/second" icon={<SecondIcon />}>
112
+ * Second item
113
+ * </NavigationBar.Item>
114
+ * <NavigationBar.Item href="/third" icon={<ThirdIcon />}>
115
+ * Third item
116
+ * </NavigationBar.Item>
117
+ * </NavigationBar>
118
+ * ```
119
+ *
120
+ * Draw it below the screen's content, at the bottom of the window: it paints
121
+ * its surface to the bottom edge and keeps its destinations clear of the home
122
+ * indicator itself. From the medium window size class each destination puts
123
+ * its label beside its icon, where the bar is wide enough for every label.
124
+ *
125
+ * `style`, `ref` and `testID` land on the bar's own view, which is announced
126
+ * as a tab list.
127
+ */
128
+ declare function NavigationBar({ children, selectedRoute, style, ...props }: NavigationBarProps): import("react").JSX.Element;
129
+ declare namespace NavigationBar {
130
+ var Item: typeof NavigationBarItem;
131
+ }
132
+ /**
133
+ * One destination of a navigation bar: an icon, a label and, while it is the
134
+ * current one, the active indicator behind the icon. Pressing it calls
135
+ * `onPress`, then goes to its `href`. Renders nothing of its own outside a
136
+ * `NavigationBar`, whose `selectedRoute` says whether it is selected.
137
+ *
138
+ * `style`, `ref` and `testID` land on the destination's `Pressable`.
139
+ */
140
+ declare function NavigationBarItem(props: NavigationBarItemProps): import("react").JSX.Element;
141
+ /**
142
+ * A navigation bar drawing a tab navigator's routes, for the `tabBar` prop of
143
+ * React Navigation's bottom tabs and of Expo Router's `Tabs` alike.
144
+ *
145
+ * ```tsx
146
+ * <Tabs tabBar={(props) => <NavigationTabBar {...props} />}>
147
+ * <Tabs.Screen name="index" options={{ tabBarIcon: () => <FirstIcon />, title: 'First item' }} />
148
+ * </Tabs>
149
+ * ```
150
+ *
151
+ * Each route is a destination, labelled by its `tabBarLabel` or its title,
152
+ * with the icon `tabBarIcon` draws and the badge `tabBarBadge` asks for, and
153
+ * the focused route is the selected one. Pressing a destination reports
154
+ * `tabPress` to the navigator and moves to its route unless a listener
155
+ * prevents it, and a long press reports `tabLongPress`, as the navigators'
156
+ * own tab bars do.
157
+ *
158
+ * `style`, `ref` and `testID` land on the bar's own view, as on a
159
+ * `NavigationBar`.
160
+ */
161
+ declare function NavigationTabBar({ descriptors, emitter, insets: _insets, navigateToTab, navigation, state, ...props }: NavigationTabBarProps): import("react").JSX.Element;
162
+ //#endregion
163
+ export { NavigationBar, NavigationBarItem, type NavigationBarItemProps, type NavigationBarProps, NavigationTabBar, type NavigationTabBarProps };
164
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,470 @@
1
+ import { useTheme } from "../../theme/scope.js";
2
+ import { composeStyles, themedStyles } from "../../theme/styles.js";
3
+ import { useWindowSizeClass } from "../../hooks/useWindowSizeClass.js";
4
+ import { NavigationContext, NavigationDestination, NavigationItem, iconColorOf, labelColorOf } from "../../navigation/index.js";
5
+ import { c } from "react/compiler-runtime";
6
+ import { StyleSheet, View } from "react-native";
7
+ import { SafeAreaView } from "react-native-safe-area-context";
8
+ import { use, useState } from "react";
9
+ import { jsx, jsxs } from "react/jsx-runtime";
10
+ //#region src/components/navigation-bar/index.tsx
11
+ const MEASURING_ROOM = 1e4;
12
+ const ICON_SIZE = 24;
13
+ const NO_OPTIONS = {};
14
+ const DIGITS = /^\d+$/u;
15
+ const EDGES = [
16
+ "bottom",
17
+ "left",
18
+ "right"
19
+ ];
20
+ const styles = StyleSheet.create({
21
+ measurer: {
22
+ height: 0,
23
+ overflow: "hidden",
24
+ pointerEvents: "none",
25
+ position: "absolute",
26
+ start: 0,
27
+ top: 0,
28
+ width: 0
29
+ },
30
+ room: {
31
+ alignItems: "flex-start",
32
+ width: MEASURING_ROOM
33
+ },
34
+ vertical: { alignItems: "stretch" }
35
+ });
36
+ const stylesOf = themedStyles(({ colors, spacing }) => StyleSheet.create({
37
+ bar: { backgroundColor: colors.surfaceContainer },
38
+ horizontal: {
39
+ alignItems: "center",
40
+ gap: spacing.sm
41
+ },
42
+ measured: {
43
+ flexDirection: "row",
44
+ gap: spacing.sm
45
+ },
46
+ row: {
47
+ flexDirection: "row",
48
+ justifyContent: "center",
49
+ minHeight: 64
50
+ }
51
+ }));
52
+ /**
53
+ * What the bar tells the navigator and how it moves, from whichever of the
54
+ * two navigators drew it.
55
+ */
56
+ function actionsOf(emitter, navigateToTab, navigation) {
57
+ if (navigation !== void 0) return {
58
+ emit: (event) => navigation.emit(event),
59
+ go: (route) => {
60
+ navigation.navigate(route.name, route.params);
61
+ }
62
+ };
63
+ return {
64
+ emit: (event) => emitter?.emit(event),
65
+ go: (route) => {
66
+ navigateToTab?.(route.key);
67
+ }
68
+ };
69
+ }
70
+ /**
71
+ * The badge a tab's `tabBarBadge` draws: the count of a number or a string of
72
+ * digits, and the small dot for any other string.
73
+ */
74
+ function badgeOf(badge) {
75
+ if (typeof badge === "number") return badge;
76
+ if (badge === void 0 || badge === "") return;
77
+ return DIGITS.test(badge) ? Number(badge) : true;
78
+ }
79
+ /**
80
+ * Reports a long press on a tab. Built by a call rather than written inline
81
+ * at the prop, for the reason `widthThen` gives.
82
+ */
83
+ function longPressThen(actions, route) {
84
+ return () => {
85
+ actions.emit({
86
+ target: route.key,
87
+ type: "tabLongPress"
88
+ });
89
+ };
90
+ }
91
+ /**
92
+ * The bar of three to five top-level destinations a compact window keeps at
93
+ * its bottom edge. Each destination goes to its `href` through the app's
94
+ * router, see `RouterProvider`.
95
+ *
96
+ * ```tsx
97
+ * <NavigationBar selectedRoute="/first">
98
+ * <NavigationBar.Item href="/first" icon={<FirstIcon />}>
99
+ * First item
100
+ * </NavigationBar.Item>
101
+ * <NavigationBar.Item href="/second" icon={<SecondIcon />}>
102
+ * Second item
103
+ * </NavigationBar.Item>
104
+ * <NavigationBar.Item href="/third" icon={<ThirdIcon />}>
105
+ * Third item
106
+ * </NavigationBar.Item>
107
+ * </NavigationBar>
108
+ * ```
109
+ *
110
+ * Draw it below the screen's content, at the bottom of the window: it paints
111
+ * its surface to the bottom edge and keeps its destinations clear of the home
112
+ * indicator itself. From the medium window size class each destination puts
113
+ * its label beside its icon, where the bar is wide enough for every label.
114
+ *
115
+ * `style`, `ref` and `testID` land on the bar's own view, which is announced
116
+ * as a tab list.
117
+ */
118
+ function NavigationBar(t0) {
119
+ const $ = c(35);
120
+ let children;
121
+ let props;
122
+ let selectedRoute;
123
+ let style;
124
+ if ($[0] !== t0) {
125
+ ({children, selectedRoute, style, ...props} = t0);
126
+ $[0] = t0;
127
+ $[1] = children;
128
+ $[2] = props;
129
+ $[3] = selectedRoute;
130
+ $[4] = style;
131
+ } else {
132
+ children = $[1];
133
+ props = $[2];
134
+ selectedRoute = $[3];
135
+ style = $[4];
136
+ }
137
+ const theme = useTheme();
138
+ const own = stylesOf(theme);
139
+ const sizeClass = useWindowSizeClass();
140
+ const [room, setRoom] = useState(void 0);
141
+ const [needed, setNeeded] = useState(void 0);
142
+ const wide = sizeClass !== "compact";
143
+ const horizontal = wide && (room === void 0 || needed === void 0 || needed <= room);
144
+ const t1 = horizontal ? "horizontal" : "vertical";
145
+ let t2;
146
+ if ($[5] !== selectedRoute || $[6] !== t1) {
147
+ t2 = {
148
+ form: t1,
149
+ measuring: false,
150
+ selectedRoute
151
+ };
152
+ $[5] = selectedRoute;
153
+ $[6] = t1;
154
+ $[7] = t2;
155
+ } else t2 = $[7];
156
+ const context = t2;
157
+ let t3;
158
+ if ($[8] !== selectedRoute) {
159
+ t3 = {
160
+ form: "horizontal",
161
+ measuring: true,
162
+ selectedRoute
163
+ };
164
+ $[8] = selectedRoute;
165
+ $[9] = t3;
166
+ } else t3 = $[9];
167
+ const measuring = t3;
168
+ const T0 = View;
169
+ const t4 = "tablist";
170
+ const t5 = composeStyles(own.bar, style);
171
+ const T1 = SafeAreaView;
172
+ const t6 = EDGES;
173
+ const T2 = View;
174
+ let t7;
175
+ if ($[10] === Symbol.for("react.memo_cache_sentinel")) {
176
+ t7 = widthThen(setRoom);
177
+ $[10] = t7;
178
+ } else t7 = $[10];
179
+ const t8 = composeStyles(own.row, horizontal ? own.horizontal : styles.vertical);
180
+ let t9;
181
+ if ($[11] !== children || $[12] !== context) {
182
+ t9 = /* @__PURE__ */ jsx(NavigationContext, {
183
+ value: context,
184
+ children
185
+ });
186
+ $[11] = children;
187
+ $[12] = context;
188
+ $[13] = t9;
189
+ } else t9 = $[13];
190
+ let t10;
191
+ if ($[14] !== T2 || $[15] !== t7 || $[16] !== t8 || $[17] !== t9) {
192
+ t10 = /* @__PURE__ */ jsx(T2, {
193
+ onLayout: t7,
194
+ style: t8,
195
+ children: t9
196
+ });
197
+ $[14] = T2;
198
+ $[15] = t7;
199
+ $[16] = t8;
200
+ $[17] = t9;
201
+ $[18] = t10;
202
+ } else t10 = $[18];
203
+ let t11;
204
+ if ($[19] !== T1 || $[20] !== t10 || $[21] !== t6) {
205
+ t11 = /* @__PURE__ */ jsx(T1, {
206
+ edges: t6,
207
+ children: t10
208
+ });
209
+ $[19] = T1;
210
+ $[20] = t10;
211
+ $[21] = t6;
212
+ $[22] = t11;
213
+ } else t11 = $[22];
214
+ let t12;
215
+ if ($[23] !== children || $[24] !== measuring || $[25] !== own || $[26] !== setNeeded || $[27] !== wide) {
216
+ t12 = wide ? /* @__PURE__ */ jsx(View, {
217
+ "aria-hidden": true,
218
+ style: styles.measurer,
219
+ children: /* @__PURE__ */ jsx(View, {
220
+ style: styles.room,
221
+ children: /* @__PURE__ */ jsx(View, {
222
+ onLayout: widthThen(setNeeded),
223
+ style: own.measured,
224
+ children: /* @__PURE__ */ jsx(NavigationContext, {
225
+ value: measuring,
226
+ children
227
+ })
228
+ })
229
+ })
230
+ }) : null;
231
+ $[23] = children;
232
+ $[24] = measuring;
233
+ $[25] = own;
234
+ $[26] = setNeeded;
235
+ $[27] = wide;
236
+ $[28] = t12;
237
+ } else t12 = $[28];
238
+ let t13;
239
+ if ($[29] !== T0 || $[30] !== props || $[31] !== t11 || $[32] !== t12 || $[33] !== t5) {
240
+ t13 = /* @__PURE__ */ jsxs(T0, {
241
+ role: t4,
242
+ ...props,
243
+ style: t5,
244
+ children: [t11, t12]
245
+ });
246
+ $[29] = T0;
247
+ $[30] = props;
248
+ $[31] = t11;
249
+ $[32] = t12;
250
+ $[33] = t5;
251
+ $[34] = t13;
252
+ } else t13 = $[34];
253
+ return t13;
254
+ }
255
+ /**
256
+ * One destination of a navigation bar: an icon, a label and, while it is the
257
+ * current one, the active indicator behind the icon. Pressing it calls
258
+ * `onPress`, then goes to its `href`. Renders nothing of its own outside a
259
+ * `NavigationBar`, whose `selectedRoute` says whether it is selected.
260
+ *
261
+ * `style`, `ref` and `testID` land on the destination's `Pressable`.
262
+ */
263
+ function NavigationBarItem(props) {
264
+ const $ = c(2);
265
+ let t0;
266
+ if ($[0] !== props) {
267
+ t0 = /* @__PURE__ */ jsx(NavigationItem, { ...props });
268
+ $[0] = props;
269
+ $[1] = t0;
270
+ } else t0 = $[1];
271
+ return t0;
272
+ }
273
+ /**
274
+ * A navigation bar drawing a tab navigator's routes, for the `tabBar` prop of
275
+ * React Navigation's bottom tabs and of Expo Router's `Tabs` alike.
276
+ *
277
+ * ```tsx
278
+ * <Tabs tabBar={(props) => <NavigationTabBar {...props} />}>
279
+ * <Tabs.Screen name="index" options={{ tabBarIcon: () => <FirstIcon />, title: 'First item' }} />
280
+ * </Tabs>
281
+ * ```
282
+ *
283
+ * Each route is a destination, labelled by its `tabBarLabel` or its title,
284
+ * with the icon `tabBarIcon` draws and the badge `tabBarBadge` asks for, and
285
+ * the focused route is the selected one. Pressing a destination reports
286
+ * `tabPress` to the navigator and moves to its route unless a listener
287
+ * prevents it, and a long press reports `tabLongPress`, as the navigators'
288
+ * own tab bars do.
289
+ *
290
+ * `style`, `ref` and `testID` land on the bar's own view, as on a
291
+ * `NavigationBar`.
292
+ */
293
+ function NavigationTabBar(t0) {
294
+ const $ = c(21);
295
+ let descriptors;
296
+ let emitter;
297
+ let navigateToTab;
298
+ let navigation;
299
+ let props;
300
+ let state;
301
+ if ($[0] !== t0) {
302
+ const { descriptors: t1, emitter: t2, insets: _insets, navigateToTab: t3, navigation: t4, state: t5, ...t6 } = t0;
303
+ descriptors = t1;
304
+ emitter = t2;
305
+ navigateToTab = t3;
306
+ navigation = t4;
307
+ state = t5;
308
+ props = t6;
309
+ $[0] = t0;
310
+ $[1] = descriptors;
311
+ $[2] = emitter;
312
+ $[3] = navigateToTab;
313
+ $[4] = navigation;
314
+ $[5] = props;
315
+ $[6] = state;
316
+ } else {
317
+ descriptors = $[1];
318
+ emitter = $[2];
319
+ navigateToTab = $[3];
320
+ navigation = $[4];
321
+ props = $[5];
322
+ state = $[6];
323
+ }
324
+ let T0;
325
+ let t1;
326
+ let t2;
327
+ if ($[7] !== descriptors || $[8] !== emitter || $[9] !== navigateToTab || $[10] !== navigation || $[11] !== props || $[12] !== state.index || $[13] !== state.routes) {
328
+ const actions = actionsOf(emitter, navigateToTab, navigation);
329
+ const focused = state.routes[state.index]?.key;
330
+ T0 = NavigationBar;
331
+ t1 = props;
332
+ t2 = state.routes.map((route) => /* @__PURE__ */ jsx(TabDestination, {
333
+ focused: route.key === focused,
334
+ onLongPress: longPressThen(actions, route),
335
+ onPress: pressThen(actions, route, route.key === focused),
336
+ options: descriptors[route.key]?.options ?? NO_OPTIONS,
337
+ route
338
+ }, route.key));
339
+ $[7] = descriptors;
340
+ $[8] = emitter;
341
+ $[9] = navigateToTab;
342
+ $[10] = navigation;
343
+ $[11] = props;
344
+ $[12] = state.index;
345
+ $[13] = state.routes;
346
+ $[14] = T0;
347
+ $[15] = t1;
348
+ $[16] = t2;
349
+ } else {
350
+ T0 = $[14];
351
+ t1 = $[15];
352
+ t2 = $[16];
353
+ }
354
+ let t3;
355
+ if ($[17] !== T0 || $[18] !== t1 || $[19] !== t2) {
356
+ t3 = /* @__PURE__ */ jsx(T0, {
357
+ ...t1,
358
+ children: t2
359
+ });
360
+ $[17] = T0;
361
+ $[18] = t1;
362
+ $[19] = t2;
363
+ $[20] = t3;
364
+ } else t3 = $[20];
365
+ return t3;
366
+ }
367
+ /**
368
+ * Moves to a tab once the navigator has heard the press, unless a listener
369
+ * prevented it or the tab is already focused. Built by a call rather than
370
+ * written inline at the prop, for the reason `widthThen` gives.
371
+ */
372
+ function pressThen(actions, route, focused) {
373
+ return () => {
374
+ const event = actions.emit({
375
+ canPreventDefault: true,
376
+ target: route.key,
377
+ type: "tabPress"
378
+ });
379
+ if (!focused && !prevented(event)) actions.go(route);
380
+ };
381
+ }
382
+ function prevented(event) {
383
+ return typeof event === "object" && event !== null && "defaultPrevented" in event && event.defaultPrevented === true;
384
+ }
385
+ /**
386
+ * One route's destination. Its colours are the destination's own for the
387
+ * form the bar draws, which is why it reads them inside the bar rather than
388
+ * the bar computing them for it.
389
+ */
390
+ function TabDestination(t0) {
391
+ const $ = c(21);
392
+ const { focused, onLongPress, onPress, options, route } = t0;
393
+ const theme = useTheme();
394
+ const { form } = use(NavigationContext);
395
+ const { tabBarLabel } = options;
396
+ const title = typeof tabBarLabel === "string" ? tabBarLabel : options.title ?? route.name;
397
+ const t1 = options.tabBarAccessibilityLabel ?? title;
398
+ let t2;
399
+ if ($[0] !== options.tabBarBadge) {
400
+ t2 = badgeOf(options.tabBarBadge);
401
+ $[0] = options.tabBarBadge;
402
+ $[1] = t2;
403
+ } else t2 = $[1];
404
+ let t3;
405
+ if ($[2] !== focused || $[3] !== options || $[4] !== theme) {
406
+ t3 = options.tabBarIcon?.({
407
+ color: iconColorOf(theme, false, focused),
408
+ focused,
409
+ size: ICON_SIZE
410
+ });
411
+ $[2] = focused;
412
+ $[3] = options;
413
+ $[4] = theme;
414
+ $[5] = t3;
415
+ } else t3 = $[5];
416
+ let t4;
417
+ if ($[6] !== focused || $[7] !== form || $[8] !== tabBarLabel || $[9] !== theme || $[10] !== title) {
418
+ t4 = typeof tabBarLabel === "function" ? tabBarLabel({
419
+ children: title,
420
+ color: labelColorOf(theme, form, false, focused),
421
+ focused,
422
+ position: form === "horizontal" ? "beside-icon" : "below-icon"
423
+ }) : title;
424
+ $[6] = focused;
425
+ $[7] = form;
426
+ $[8] = tabBarLabel;
427
+ $[9] = theme;
428
+ $[10] = title;
429
+ $[11] = t4;
430
+ } else t4 = $[11];
431
+ let t5;
432
+ if ($[12] !== focused || $[13] !== onLongPress || $[14] !== onPress || $[15] !== options.tabBarButtonTestID || $[16] !== t1 || $[17] !== t2 || $[18] !== t3 || $[19] !== t4) {
433
+ t5 = /* @__PURE__ */ jsx(NavigationDestination, {
434
+ "aria-label": t1,
435
+ badge: t2,
436
+ icon: t3,
437
+ onLongPress,
438
+ onPress,
439
+ selected: focused,
440
+ testID: options.tabBarButtonTestID,
441
+ children: t4
442
+ });
443
+ $[12] = focused;
444
+ $[13] = onLongPress;
445
+ $[14] = onPress;
446
+ $[15] = options.tabBarButtonTestID;
447
+ $[16] = t1;
448
+ $[17] = t2;
449
+ $[18] = t3;
450
+ $[19] = t4;
451
+ $[20] = t5;
452
+ } else t5 = $[20];
453
+ return t5;
454
+ }
455
+ /**
456
+ * Records a view's width, as React Native lays it out. Built by a call
457
+ * rather than written inline at the prop, which is what react-perf's
458
+ * jsx-no-new-function-as-prop is after; the React Compiler memoises the
459
+ * result on its inputs.
460
+ */
461
+ function widthThen(setWidth) {
462
+ return (event) => {
463
+ setWidth(event.nativeEvent.layout.width);
464
+ };
465
+ }
466
+ NavigationBar.Item = NavigationBarItem;
467
+ //#endregion
468
+ export { NavigationBar, NavigationBarItem, NavigationTabBar };
469
+
470
+ //# sourceMappingURL=index.js.map