@dloizides/ui-nav 1.1.1 → 1.3.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/CHANGELOG.md +35 -0
- package/README.md +44 -0
- package/dist/index.d.mts +55 -1
- package/dist/index.d.ts +55 -1
- package/dist/index.js +323 -14
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +324 -16
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -61,6 +61,79 @@ var navStyles = reactNative.StyleSheet.create({
|
|
|
61
61
|
planBadge: { marginTop: 2, paddingHorizontal: 8, paddingVertical: 2, borderRadius: 10, alignSelf: "flex-end" },
|
|
62
62
|
planBadgeText: { fontSize: 11, fontWeight: "700" }
|
|
63
63
|
});
|
|
64
|
+
var navBarStyles = reactNative.StyleSheet.create({
|
|
65
|
+
// --- Horizontal top NavBar ---
|
|
66
|
+
container: {
|
|
67
|
+
borderBottomWidth: 1,
|
|
68
|
+
paddingHorizontal: 12
|
|
69
|
+
},
|
|
70
|
+
inner: {
|
|
71
|
+
minHeight: 56,
|
|
72
|
+
flexDirection: "row",
|
|
73
|
+
alignItems: "center",
|
|
74
|
+
flexWrap: "wrap",
|
|
75
|
+
columnGap: 8,
|
|
76
|
+
rowGap: 4,
|
|
77
|
+
paddingVertical: 8
|
|
78
|
+
},
|
|
79
|
+
brand: { marginRight: 16 },
|
|
80
|
+
toggle: {
|
|
81
|
+
marginLeft: "auto",
|
|
82
|
+
paddingHorizontal: 10,
|
|
83
|
+
paddingVertical: 6,
|
|
84
|
+
borderRadius: 4,
|
|
85
|
+
// a11y: keep the hamburger a comfortable ≥44×44 touch target.
|
|
86
|
+
minWidth: 44,
|
|
87
|
+
minHeight: 44,
|
|
88
|
+
alignItems: "center",
|
|
89
|
+
justifyContent: "center"
|
|
90
|
+
},
|
|
91
|
+
toggleGlyph: { fontSize: 20, fontWeight: "700" },
|
|
92
|
+
links: {
|
|
93
|
+
flexDirection: "row",
|
|
94
|
+
alignItems: "center",
|
|
95
|
+
flexWrap: "wrap",
|
|
96
|
+
columnGap: 4,
|
|
97
|
+
rowGap: 4
|
|
98
|
+
},
|
|
99
|
+
// Collapsed (below breakpoint): links drop onto their own full-width line,
|
|
100
|
+
// stacked vertically — mirrors the v1 `.gn-links` responsive behaviour.
|
|
101
|
+
linksStacked: {
|
|
102
|
+
width: "100%",
|
|
103
|
+
flexBasis: "100%",
|
|
104
|
+
flexDirection: "column",
|
|
105
|
+
alignItems: "stretch",
|
|
106
|
+
rowGap: 2,
|
|
107
|
+
marginTop: 8
|
|
108
|
+
},
|
|
109
|
+
link: {
|
|
110
|
+
paddingVertical: 8,
|
|
111
|
+
paddingHorizontal: 14,
|
|
112
|
+
borderRadius: 8,
|
|
113
|
+
flexDirection: "row",
|
|
114
|
+
alignItems: "center",
|
|
115
|
+
// a11y: comfortable ≥44 tall touch target (rounded-pill hover/active affordance).
|
|
116
|
+
minHeight: 44,
|
|
117
|
+
justifyContent: "center"
|
|
118
|
+
},
|
|
119
|
+
linkStacked: { paddingVertical: 10 },
|
|
120
|
+
linkIcon: { marginRight: 6 },
|
|
121
|
+
linkText: { fontSize: 15, fontWeight: "600" },
|
|
122
|
+
right: {
|
|
123
|
+
marginLeft: "auto",
|
|
124
|
+
flexDirection: "row",
|
|
125
|
+
alignItems: "center",
|
|
126
|
+
columnGap: 8
|
|
127
|
+
},
|
|
128
|
+
rightStacked: {
|
|
129
|
+
width: "100%",
|
|
130
|
+
flexBasis: "100%",
|
|
131
|
+
marginTop: 4,
|
|
132
|
+
flexDirection: "row",
|
|
133
|
+
alignItems: "center",
|
|
134
|
+
columnGap: 8
|
|
135
|
+
}
|
|
136
|
+
});
|
|
64
137
|
var expandableStyles = reactNative.StyleSheet.create({
|
|
65
138
|
childItem: {
|
|
66
139
|
borderRadius: 4,
|
|
@@ -84,6 +157,31 @@ var expandableStyles = reactNative.StyleSheet.create({
|
|
|
84
157
|
var BASE_INDENT = 12;
|
|
85
158
|
var NAV_ICON_SIZE = 14;
|
|
86
159
|
var CHEVRON_ICON_SIZE = 12;
|
|
160
|
+
var IS_WEB = reactNative.Platform.OS === "web";
|
|
161
|
+
var FOCUS_RING_WIDTH = 2;
|
|
162
|
+
var FOCUS_RING_OFFSET = 2;
|
|
163
|
+
var HOVER_TRANSITION_MS = 150;
|
|
164
|
+
function focusRingStyle(focused, ringColor) {
|
|
165
|
+
if (!IS_WEB || !focused) return void 0;
|
|
166
|
+
const ring = {
|
|
167
|
+
outlineWidth: FOCUS_RING_WIDTH,
|
|
168
|
+
outlineStyle: "solid",
|
|
169
|
+
outlineColor: ringColor,
|
|
170
|
+
outlineOffset: FOCUS_RING_OFFSET
|
|
171
|
+
};
|
|
172
|
+
return ring;
|
|
173
|
+
}
|
|
174
|
+
function hoverTransitionStyle(reducedMotion) {
|
|
175
|
+
if (!IS_WEB) return void 0;
|
|
176
|
+
const transition = {
|
|
177
|
+
transitionProperty: "color, background-color",
|
|
178
|
+
transitionDuration: reducedMotion ? "0ms" : `${HOVER_TRANSITION_MS}ms`
|
|
179
|
+
};
|
|
180
|
+
return transition;
|
|
181
|
+
}
|
|
182
|
+
function ariaCurrentProps(isActive) {
|
|
183
|
+
return isActive ? { "aria-current": "page" } : {};
|
|
184
|
+
}
|
|
87
185
|
var NavExpandableItem = ({
|
|
88
186
|
item,
|
|
89
187
|
pathname,
|
|
@@ -95,6 +193,7 @@ var NavExpandableItem = ({
|
|
|
95
193
|
depth = 0
|
|
96
194
|
}) => {
|
|
97
195
|
const [expanded, setExpanded] = react.useState(false);
|
|
196
|
+
const [focused, setFocused] = react.useState(false);
|
|
98
197
|
const { theme } = uiFeedback.useUi();
|
|
99
198
|
const colors = theme.colors;
|
|
100
199
|
const primaryColor = theme.palette.primary["500"];
|
|
@@ -115,9 +214,18 @@ var NavExpandableItem = ({
|
|
|
115
214
|
accessibilityHint: navigateHint(item.label),
|
|
116
215
|
accessibilityLabel: item.label,
|
|
117
216
|
accessibilityRole: "button",
|
|
118
|
-
|
|
217
|
+
accessibilityState: { selected: isActive },
|
|
218
|
+
style: [
|
|
219
|
+
expandableStyles.childItem,
|
|
220
|
+
paddingStyle,
|
|
221
|
+
isActive ? activeItemStyle : void 0,
|
|
222
|
+
focusRingStyle(focused, primaryColor)
|
|
223
|
+
],
|
|
119
224
|
testID: item.testID ?? item.key,
|
|
225
|
+
onBlur: () => setFocused(false),
|
|
226
|
+
onFocus: () => setFocused(true),
|
|
120
227
|
onPress: () => onNavigate(item.route),
|
|
228
|
+
...ariaCurrentProps(isActive),
|
|
121
229
|
children: [
|
|
122
230
|
typeof item.renderIcon === "function" ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: expandableStyles.iconWrapper, children: item.renderIcon(colors.textSecondary, NAV_ICON_SIZE) }) : null,
|
|
123
231
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -141,8 +249,10 @@ var NavExpandableItem = ({
|
|
|
141
249
|
accessibilityLabel: item.label,
|
|
142
250
|
accessibilityRole: "button",
|
|
143
251
|
accessibilityState: { expanded },
|
|
144
|
-
style: [expandableStyles.header, headerPaddingStyle],
|
|
252
|
+
style: [expandableStyles.header, headerPaddingStyle, focusRingStyle(focused, primaryColor)],
|
|
145
253
|
testID: item.testID ?? item.key,
|
|
254
|
+
onBlur: () => setFocused(false),
|
|
255
|
+
onFocus: () => setFocused(true),
|
|
146
256
|
onPress: toggle,
|
|
147
257
|
children: [
|
|
148
258
|
typeof item.renderIcon === "function" ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: expandableStyles.iconWrapper, children: item.renderIcon(colors.text, NAV_ICON_SIZE) }) : null,
|
|
@@ -226,7 +336,11 @@ var NAV_TEST_IDS = {
|
|
|
226
336
|
/** small plan badge (free / pro / enterprise). */
|
|
227
337
|
accountPlan: "topbar-account-plan",
|
|
228
338
|
/** default testID for the rich header's upgrade action (overridable per-action). */
|
|
229
|
-
accountUpgrade: "topbar-account-upgrade"
|
|
339
|
+
accountUpgrade: "topbar-account-upgrade",
|
|
340
|
+
/** responsive hamburger toggle in the horizontal NavBar (shown below the breakpoint). */
|
|
341
|
+
navBarToggle: "navbar-toggle",
|
|
342
|
+
/** links container in the horizontal NavBar. */
|
|
343
|
+
navBarLinks: "navbar-links"
|
|
230
344
|
};
|
|
231
345
|
var APP_SHELL_SUFFIX = {
|
|
232
346
|
content: "-content",
|
|
@@ -238,6 +352,32 @@ var APP_SHELL_SUFFIX = {
|
|
|
238
352
|
error: "-error",
|
|
239
353
|
forbidden: "-forbidden"
|
|
240
354
|
};
|
|
355
|
+
var FocusableTouchable = ({
|
|
356
|
+
onPress,
|
|
357
|
+
accessibilityLabel,
|
|
358
|
+
accessibilityHint,
|
|
359
|
+
accessibilityRole = "button",
|
|
360
|
+
ringColor,
|
|
361
|
+
style,
|
|
362
|
+
testID,
|
|
363
|
+
children
|
|
364
|
+
}) => {
|
|
365
|
+
const [focused, setFocused] = react.useState(false);
|
|
366
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
367
|
+
reactNative.Pressable,
|
|
368
|
+
{
|
|
369
|
+
accessibilityHint,
|
|
370
|
+
accessibilityLabel,
|
|
371
|
+
accessibilityRole,
|
|
372
|
+
style: [style, focusRingStyle(focused, ringColor)],
|
|
373
|
+
testID,
|
|
374
|
+
onBlur: () => setFocused(false),
|
|
375
|
+
onFocus: () => setFocused(true),
|
|
376
|
+
onPress,
|
|
377
|
+
children
|
|
378
|
+
}
|
|
379
|
+
);
|
|
380
|
+
};
|
|
241
381
|
var TEXT_ON_PRIMARY = "#ffffff";
|
|
242
382
|
function isAccountState(account) {
|
|
243
383
|
return "displayName" in account;
|
|
@@ -275,11 +415,11 @@ var Topbar = ({
|
|
|
275
415
|
/* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: navStyles.topbarLeft, children: left }),
|
|
276
416
|
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: navStyles.topbarRight, children: [
|
|
277
417
|
language ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
278
|
-
|
|
418
|
+
FocusableTouchable,
|
|
279
419
|
{
|
|
280
420
|
accessibilityHint: language.hint,
|
|
281
421
|
accessibilityLabel: language.label,
|
|
282
|
-
|
|
422
|
+
ringColor: primaryColor,
|
|
283
423
|
style: navStyles.topbarRowItem,
|
|
284
424
|
onPress: language.onPress,
|
|
285
425
|
children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [navStyles.topbarLabel, { color: colors.text }], children: language.label })
|
|
@@ -292,11 +432,11 @@ var Topbar = ({
|
|
|
292
432
|
] }) : null,
|
|
293
433
|
richAccount ? /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: navStyles.userBlock, children: [
|
|
294
434
|
richAccount.onAccount ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
295
|
-
|
|
435
|
+
FocusableTouchable,
|
|
296
436
|
{
|
|
297
437
|
accessibilityHint: richAccount.displayName,
|
|
298
438
|
accessibilityLabel: richAccount.displayName,
|
|
299
|
-
|
|
439
|
+
ringColor: primaryColor,
|
|
300
440
|
testID: NAV_TEST_IDS.accountName,
|
|
301
441
|
onPress: richAccount.onAccount,
|
|
302
442
|
children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [navStyles.userName, { color: colors.text }], children: richAccount.displayName })
|
|
@@ -320,11 +460,11 @@ var Topbar = ({
|
|
|
320
460
|
) : null
|
|
321
461
|
] }) : null,
|
|
322
462
|
legacyAccount ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
323
|
-
|
|
463
|
+
FocusableTouchable,
|
|
324
464
|
{
|
|
325
465
|
accessibilityHint: legacyAccount.hint,
|
|
326
466
|
accessibilityLabel: legacyAccount.label,
|
|
327
|
-
|
|
467
|
+
ringColor: primaryColor,
|
|
328
468
|
style: [navStyles.accountBtn, { backgroundColor: primaryColor }],
|
|
329
469
|
testID: legacyAccount.testID,
|
|
330
470
|
onPress: legacyAccount.onPress,
|
|
@@ -332,11 +472,11 @@ var Topbar = ({
|
|
|
332
472
|
}
|
|
333
473
|
) : null,
|
|
334
474
|
upgrade ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
335
|
-
|
|
475
|
+
FocusableTouchable,
|
|
336
476
|
{
|
|
337
477
|
accessibilityHint: upgrade.hint,
|
|
338
478
|
accessibilityLabel: upgrade.label,
|
|
339
|
-
|
|
479
|
+
ringColor: primaryColor,
|
|
340
480
|
style: [navStyles.accountBtn, { backgroundColor: primaryColor }],
|
|
341
481
|
testID: upgrade.testID ?? NAV_TEST_IDS.accountUpgrade,
|
|
342
482
|
onPress: upgrade.onPress,
|
|
@@ -344,12 +484,11 @@ var Topbar = ({
|
|
|
344
484
|
}
|
|
345
485
|
) : null,
|
|
346
486
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
347
|
-
|
|
487
|
+
FocusableTouchable,
|
|
348
488
|
{
|
|
349
|
-
accessible: true,
|
|
350
489
|
accessibilityHint: logout.hint,
|
|
351
490
|
accessibilityLabel: logout.label,
|
|
352
|
-
|
|
491
|
+
ringColor: primaryColor,
|
|
353
492
|
style: [navStyles.accountBtn, { backgroundColor: primaryColor }],
|
|
354
493
|
testID: logout.testID,
|
|
355
494
|
onPress: richAccount ? richAccount.onLogout : logout.onPress,
|
|
@@ -361,6 +500,175 @@ var Topbar = ({
|
|
|
361
500
|
}
|
|
362
501
|
);
|
|
363
502
|
};
|
|
503
|
+
var TEXT_ON_PRIMARY2 = "#ffffff";
|
|
504
|
+
function ariaCurrentProps2(isActive) {
|
|
505
|
+
return isActive ? { "aria-current": "page" } : {};
|
|
506
|
+
}
|
|
507
|
+
var NavBarLink = ({
|
|
508
|
+
item,
|
|
509
|
+
isActive,
|
|
510
|
+
collapsed,
|
|
511
|
+
iconSize,
|
|
512
|
+
reducedMotion,
|
|
513
|
+
colors,
|
|
514
|
+
navigateHint,
|
|
515
|
+
onPress
|
|
516
|
+
}) => {
|
|
517
|
+
const [hovered, setHovered] = react.useState(false);
|
|
518
|
+
const [focused, setFocused] = react.useState(false);
|
|
519
|
+
const isHovered = hovered && !isActive;
|
|
520
|
+
const textColor = isActive ? TEXT_ON_PRIMARY2 : isHovered ? colors.hoverText : colors.rest;
|
|
521
|
+
const pillStyle = isActive ? { backgroundColor: colors.activeBg } : isHovered ? { backgroundColor: colors.hoverBg } : void 0;
|
|
522
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
523
|
+
reactNative.Pressable,
|
|
524
|
+
{
|
|
525
|
+
accessibilityHint: navigateHint(item.label),
|
|
526
|
+
accessibilityLabel: item.label,
|
|
527
|
+
accessibilityRole: "link",
|
|
528
|
+
accessibilityState: { selected: isActive },
|
|
529
|
+
style: [
|
|
530
|
+
navBarStyles.link,
|
|
531
|
+
collapsed ? navBarStyles.linkStacked : void 0,
|
|
532
|
+
pillStyle,
|
|
533
|
+
hoverTransitionStyle(reducedMotion),
|
|
534
|
+
focusRingStyle(focused, colors.ring)
|
|
535
|
+
],
|
|
536
|
+
testID: item.testID ?? item.key,
|
|
537
|
+
onBlur: () => setFocused(false),
|
|
538
|
+
onFocus: () => setFocused(true),
|
|
539
|
+
onHoverIn: () => setHovered(true),
|
|
540
|
+
onHoverOut: () => setHovered(false),
|
|
541
|
+
onPress: () => onPress(item.route),
|
|
542
|
+
...ariaCurrentProps2(isActive),
|
|
543
|
+
children: [
|
|
544
|
+
typeof item.renderIcon === "function" ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: navBarStyles.linkIcon, children: item.renderIcon(textColor, iconSize) }) : null,
|
|
545
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [navBarStyles.linkText, { color: textColor }], children: item.label })
|
|
546
|
+
]
|
|
547
|
+
}
|
|
548
|
+
);
|
|
549
|
+
};
|
|
550
|
+
var REDUCED_MOTION_QUERY = "(prefers-reduced-motion: reduce)";
|
|
551
|
+
function getReducedMotionQuery() {
|
|
552
|
+
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return void 0;
|
|
553
|
+
return window.matchMedia(REDUCED_MOTION_QUERY);
|
|
554
|
+
}
|
|
555
|
+
function useReducedMotion() {
|
|
556
|
+
const [reduced, setReduced] = react.useState(() => getReducedMotionQuery()?.matches ?? false);
|
|
557
|
+
react.useEffect(() => {
|
|
558
|
+
const mql = getReducedMotionQuery();
|
|
559
|
+
if (mql === void 0 || mql.addEventListener === void 0) return void 0;
|
|
560
|
+
const onChange = () => setReduced(mql.matches);
|
|
561
|
+
mql.addEventListener("change", onChange);
|
|
562
|
+
return () => {
|
|
563
|
+
mql.removeEventListener?.("change", onChange);
|
|
564
|
+
};
|
|
565
|
+
}, []);
|
|
566
|
+
return reduced;
|
|
567
|
+
}
|
|
568
|
+
var LINKS_REGION_ID = "navbar-links-region";
|
|
569
|
+
var DEFAULT_COLLAPSE_BELOW = 760;
|
|
570
|
+
var MENU_GLYPH = "\u2630";
|
|
571
|
+
function ariaControlsProps(id) {
|
|
572
|
+
return { "aria-controls": id };
|
|
573
|
+
}
|
|
574
|
+
var NavBar = ({
|
|
575
|
+
items,
|
|
576
|
+
pathname,
|
|
577
|
+
onNavigate,
|
|
578
|
+
regionLabel,
|
|
579
|
+
navigateHint = (label) => label,
|
|
580
|
+
brand,
|
|
581
|
+
right,
|
|
582
|
+
menuLabel = "Menu",
|
|
583
|
+
menuHint = "",
|
|
584
|
+
renderMenuIcon,
|
|
585
|
+
collapseBelow = DEFAULT_COLLAPSE_BELOW,
|
|
586
|
+
containerStyle
|
|
587
|
+
}) => {
|
|
588
|
+
const { theme } = uiFeedback.useUi();
|
|
589
|
+
const colors = theme.colors;
|
|
590
|
+
const primaryColor = theme.palette.primary["500"];
|
|
591
|
+
const { width } = reactNative.useWindowDimensions();
|
|
592
|
+
const reducedMotion = useReducedMotion();
|
|
593
|
+
const [open, setOpen] = react.useState(false);
|
|
594
|
+
const [toggleFocused, setToggleFocused] = react.useState(false);
|
|
595
|
+
const collapsed = width < collapseBelow;
|
|
596
|
+
const showLinks = !collapsed || open;
|
|
597
|
+
const toggleMenu = react.useCallback(() => setOpen((v) => !v), []);
|
|
598
|
+
const handlePress = react.useCallback(
|
|
599
|
+
(route) => {
|
|
600
|
+
setOpen(false);
|
|
601
|
+
onNavigate(route);
|
|
602
|
+
},
|
|
603
|
+
[onNavigate]
|
|
604
|
+
);
|
|
605
|
+
const linkColors = react.useMemo(
|
|
606
|
+
() => ({
|
|
607
|
+
rest: colors.textSecondary,
|
|
608
|
+
hoverText: colors.text,
|
|
609
|
+
hoverBg: colors.surfaceElevated,
|
|
610
|
+
activeBg: primaryColor,
|
|
611
|
+
ring: primaryColor
|
|
612
|
+
}),
|
|
613
|
+
[colors.textSecondary, colors.text, colors.surfaceElevated, primaryColor]
|
|
614
|
+
);
|
|
615
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
616
|
+
reactNative.View,
|
|
617
|
+
{
|
|
618
|
+
accessibilityRole: "none",
|
|
619
|
+
"aria-label": regionLabel,
|
|
620
|
+
role: "navigation",
|
|
621
|
+
style: [
|
|
622
|
+
navBarStyles.container,
|
|
623
|
+
{ backgroundColor: colors.surface, borderBottomColor: colors.border },
|
|
624
|
+
containerStyle
|
|
625
|
+
],
|
|
626
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: navBarStyles.inner, children: [
|
|
627
|
+
brand !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: navBarStyles.brand, children: brand }) : null,
|
|
628
|
+
collapsed ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
629
|
+
reactNative.Pressable,
|
|
630
|
+
{
|
|
631
|
+
accessibilityHint: menuHint,
|
|
632
|
+
accessibilityLabel: menuLabel,
|
|
633
|
+
accessibilityRole: "button",
|
|
634
|
+
accessibilityState: { expanded: open },
|
|
635
|
+
"aria-expanded": open,
|
|
636
|
+
style: [navBarStyles.toggle, focusRingStyle(toggleFocused, primaryColor)],
|
|
637
|
+
testID: NAV_TEST_IDS.navBarToggle,
|
|
638
|
+
onBlur: () => setToggleFocused(false),
|
|
639
|
+
onFocus: () => setToggleFocused(true),
|
|
640
|
+
onPress: toggleMenu,
|
|
641
|
+
...ariaControlsProps(LINKS_REGION_ID),
|
|
642
|
+
children: typeof renderMenuIcon === "function" ? renderMenuIcon(colors.text, open) : /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [navBarStyles.toggleGlyph, { color: colors.text }], children: MENU_GLYPH })
|
|
643
|
+
}
|
|
644
|
+
) : null,
|
|
645
|
+
showLinks ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
646
|
+
reactNative.View,
|
|
647
|
+
{
|
|
648
|
+
nativeID: LINKS_REGION_ID,
|
|
649
|
+
style: collapsed ? navBarStyles.linksStacked : navBarStyles.links,
|
|
650
|
+
testID: NAV_TEST_IDS.navBarLinks,
|
|
651
|
+
children: items.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
652
|
+
NavBarLink,
|
|
653
|
+
{
|
|
654
|
+
collapsed,
|
|
655
|
+
colors: linkColors,
|
|
656
|
+
iconSize: NAV_ICON_SIZE,
|
|
657
|
+
isActive: isRouteActive(pathname, item.route),
|
|
658
|
+
item,
|
|
659
|
+
navigateHint,
|
|
660
|
+
reducedMotion,
|
|
661
|
+
onPress: handlePress
|
|
662
|
+
},
|
|
663
|
+
item.key
|
|
664
|
+
))
|
|
665
|
+
}
|
|
666
|
+
) : null,
|
|
667
|
+
showLinks && right !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: collapsed ? navBarStyles.rightStacked : navBarStyles.right, children: right }) : null
|
|
668
|
+
] })
|
|
669
|
+
}
|
|
670
|
+
);
|
|
671
|
+
};
|
|
364
672
|
function resolveContentMaxWidth(width, viewport) {
|
|
365
673
|
if (width === "full") return "full";
|
|
366
674
|
const wideMinViewport = width.wideMinViewport ?? Number.POSITIVE_INFINITY;
|
|
@@ -485,6 +793,7 @@ exports.BASE_INDENT = BASE_INDENT;
|
|
|
485
793
|
exports.CHEVRON_ICON_SIZE = CHEVRON_ICON_SIZE;
|
|
486
794
|
exports.NAV_ICON_SIZE = NAV_ICON_SIZE;
|
|
487
795
|
exports.NAV_TEST_IDS = NAV_TEST_IDS;
|
|
796
|
+
exports.NavBar = NavBar;
|
|
488
797
|
exports.NavExpandableItem = NavExpandableItem;
|
|
489
798
|
exports.Sidebar = Sidebar;
|
|
490
799
|
exports.Topbar = Topbar;
|