@dloizides/ui-nav 1.6.0 → 1.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.
- package/CHANGELOG.md +42 -0
- package/README.md +30 -0
- package/dist/index.d.mts +130 -3
- package/dist/index.d.ts +130 -3
- package/dist/index.js +211 -47
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +183 -26
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -1
package/dist/index.js
CHANGED
|
@@ -2,10 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
var reactNative = require('react-native');
|
|
4
4
|
var uiFeedback = require('@dloizides/ui-feedback');
|
|
5
|
-
var
|
|
5
|
+
var React5 = require('react');
|
|
6
6
|
var jsxRuntime = require('react/jsx-runtime');
|
|
7
|
+
var uiLayout = require('@dloizides/ui-layout');
|
|
7
8
|
var authWeb = require('@dloizides/auth-web');
|
|
8
9
|
|
|
10
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
11
|
+
|
|
12
|
+
var React5__default = /*#__PURE__*/_interopDefault(React5);
|
|
13
|
+
|
|
9
14
|
// src/Sidebar.tsx
|
|
10
15
|
|
|
11
16
|
// src/isRouteActive.ts
|
|
@@ -14,6 +19,7 @@ function isRouteActive(pathname, route) {
|
|
|
14
19
|
return pathname === route || pathname.startsWith(`${route}/`);
|
|
15
20
|
}
|
|
16
21
|
var ACTIVE_BORDER_RADIUS = 4;
|
|
22
|
+
var NAV_LINK_GAP = 4;
|
|
17
23
|
var navStyles = reactNative.StyleSheet.create({
|
|
18
24
|
// --- Sidebar ---
|
|
19
25
|
sidebarContainer: {
|
|
@@ -76,6 +82,13 @@ var navBarStyles = reactNative.StyleSheet.create({
|
|
|
76
82
|
rowGap: 4,
|
|
77
83
|
paddingVertical: 8
|
|
78
84
|
},
|
|
85
|
+
// EXPANDED: the row must NOT wrap — otherwise flexbox drops the right slot onto a 2nd line the
|
|
86
|
+
// moment brand+links+right overflow, instead of SHRINKING the (scrollable) links. `flex-shrink`
|
|
87
|
+
// only distributes negative space on a `nowrap` line; with `wrap` it wraps first and never shrinks.
|
|
88
|
+
// Collapsed keeps `wrap` so the stacked links/right (width:100%) can drop to their own lines.
|
|
89
|
+
innerNoWrap: {
|
|
90
|
+
flexWrap: "nowrap"
|
|
91
|
+
},
|
|
79
92
|
brand: { marginRight: 16, flexShrink: 0 },
|
|
80
93
|
toggle: {
|
|
81
94
|
marginLeft: "auto",
|
|
@@ -89,22 +102,26 @@ var navBarStyles = reactNative.StyleSheet.create({
|
|
|
89
102
|
justifyContent: "center"
|
|
90
103
|
},
|
|
91
104
|
toggleGlyph: { fontSize: 20, fontWeight: "700" },
|
|
92
|
-
// Expanded links live
|
|
93
|
-
//
|
|
94
|
-
//
|
|
95
|
-
//
|
|
96
|
-
|
|
105
|
+
// Expanded links live on ONE ROW that never wraps: it is a shrinkable/growable flex child that
|
|
106
|
+
// fills the space between the pinned brand (left) and right slot, and CLIPS overflow. A measure
|
|
107
|
+
// pass (priority+) then keeps only the leading items that fit inline and collapses the rest behind
|
|
108
|
+
// the "More ▾" overflow trigger — so no item is ever cut off; the surplus moves into a dropdown.
|
|
109
|
+
// `overflow:'hidden'` only masks the single unmeasured first frame before the fit resolves.
|
|
110
|
+
linksRow: {
|
|
97
111
|
flexGrow: 1,
|
|
98
112
|
flexShrink: 1,
|
|
99
|
-
minWidth: 0
|
|
100
|
-
},
|
|
101
|
-
links: {
|
|
113
|
+
minWidth: 0,
|
|
102
114
|
flexDirection: "row",
|
|
103
115
|
alignItems: "center",
|
|
104
116
|
flexWrap: "nowrap",
|
|
105
|
-
columnGap:
|
|
106
|
-
|
|
117
|
+
columnGap: NAV_LINK_GAP,
|
|
118
|
+
overflow: "hidden"
|
|
107
119
|
},
|
|
120
|
+
// Each inline link + the overflow trigger sit in a natural-width cell that never shrinks, so their
|
|
121
|
+
// measured widths are their true content widths (what the priority+ fit computation reasons about).
|
|
122
|
+
linkCell: { flexShrink: 0 },
|
|
123
|
+
overflowTrigger: { columnGap: 4 },
|
|
124
|
+
overflowChevron: { fontSize: 12, fontWeight: "700" },
|
|
108
125
|
// Collapsed (below breakpoint): links drop onto their own full-width line,
|
|
109
126
|
// stacked vertically — mirrors the v1 `.gn-links` responsive behaviour.
|
|
110
127
|
linksStacked: {
|
|
@@ -202,21 +219,21 @@ var NavExpandableItem = ({
|
|
|
202
219
|
renderChevron,
|
|
203
220
|
depth = 0
|
|
204
221
|
}) => {
|
|
205
|
-
const [expanded, setExpanded] =
|
|
206
|
-
const [focused, setFocused] =
|
|
222
|
+
const [expanded, setExpanded] = React5.useState(false);
|
|
223
|
+
const [focused, setFocused] = React5.useState(false);
|
|
207
224
|
const { theme } = uiFeedback.useUi();
|
|
208
225
|
const colors = theme.colors;
|
|
209
226
|
const primaryColor = theme.palette.primary["500"];
|
|
210
|
-
const toggle =
|
|
227
|
+
const toggle = React5.useCallback(() => setExpanded((v) => !v), []);
|
|
211
228
|
const indent = depth * BASE_INDENT;
|
|
212
229
|
const hasChildren = Array.isArray(item.children) && item.children.length > 0;
|
|
213
230
|
const isActive = isRouteActive(pathname, item.route);
|
|
214
|
-
const activeItemStyle =
|
|
231
|
+
const activeItemStyle = React5.useMemo(
|
|
215
232
|
() => ({ backgroundColor: colors.border, borderRadius: ACTIVE_BORDER_RADIUS }),
|
|
216
233
|
[colors.border]
|
|
217
234
|
);
|
|
218
|
-
const paddingStyle =
|
|
219
|
-
const headerPaddingStyle =
|
|
235
|
+
const paddingStyle = React5.useMemo(() => ({ paddingLeft: indent + BASE_INDENT }), [indent]);
|
|
236
|
+
const headerPaddingStyle = React5.useMemo(() => ({ paddingLeft: indent }), [indent]);
|
|
220
237
|
if (!hasChildren)
|
|
221
238
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
222
239
|
reactNative.TouchableOpacity,
|
|
@@ -350,7 +367,9 @@ var NAV_TEST_IDS = {
|
|
|
350
367
|
/** responsive hamburger toggle in the horizontal NavBar (shown below the breakpoint). */
|
|
351
368
|
navBarToggle: "navbar-toggle",
|
|
352
369
|
/** links container in the horizontal NavBar. */
|
|
353
|
-
navBarLinks: "navbar-links"
|
|
370
|
+
navBarLinks: "navbar-links",
|
|
371
|
+
/** the "More ▾" priority+ overflow trigger in the horizontal NavBar (shown when items spill). */
|
|
372
|
+
navBarOverflow: "navbar-overflow"
|
|
354
373
|
};
|
|
355
374
|
var APP_SHELL_SUFFIX = {
|
|
356
375
|
content: "-content",
|
|
@@ -380,7 +399,7 @@ var FocusableTouchable = ({
|
|
|
380
399
|
testID,
|
|
381
400
|
children
|
|
382
401
|
}) => {
|
|
383
|
-
const [focused, setFocused] =
|
|
402
|
+
const [focused, setFocused] = React5.useState(false);
|
|
384
403
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
385
404
|
reactNative.Pressable,
|
|
386
405
|
{
|
|
@@ -532,8 +551,8 @@ var NavBarLink = ({
|
|
|
532
551
|
navigateHint,
|
|
533
552
|
onPress
|
|
534
553
|
}) => {
|
|
535
|
-
const [hovered, setHovered] =
|
|
536
|
-
const [focused, setFocused] =
|
|
554
|
+
const [hovered, setHovered] = React5.useState(false);
|
|
555
|
+
const [focused, setFocused] = React5.useState(false);
|
|
537
556
|
const isHovered = hovered && !isActive;
|
|
538
557
|
const textColor = isActive ? TEXT_ON_PRIMARY2 : isHovered ? colors.hoverText : colors.rest;
|
|
539
558
|
const pillStyle = isActive ? { backgroundColor: colors.activeBg } : isHovered ? { backgroundColor: colors.hoverBg } : void 0;
|
|
@@ -565,14 +584,116 @@ var NavBarLink = ({
|
|
|
565
584
|
}
|
|
566
585
|
);
|
|
567
586
|
};
|
|
587
|
+
var TEXT_ON_PRIMARY3 = "#ffffff";
|
|
588
|
+
var NO_ACTIVE_ROUTE = "";
|
|
589
|
+
var NavOverflowMenu = ({
|
|
590
|
+
items,
|
|
591
|
+
pathname,
|
|
592
|
+
onNavigate,
|
|
593
|
+
colors,
|
|
594
|
+
label,
|
|
595
|
+
hint,
|
|
596
|
+
testID,
|
|
597
|
+
variant
|
|
598
|
+
}) => {
|
|
599
|
+
const options = React5.useMemo(() => items.map((item) => ({ label: item.label, value: item.route })), [items]);
|
|
600
|
+
const activeRoute = React5.useMemo(
|
|
601
|
+
() => items.find((item) => isRouteActive(pathname, item.route))?.route ?? NO_ACTIVE_ROUTE,
|
|
602
|
+
[items, pathname]
|
|
603
|
+
);
|
|
604
|
+
const optionTestID = React5.useMemo(() => {
|
|
605
|
+
const byRoute = new Map(items.map((item) => [item.route, item.testID ?? item.key]));
|
|
606
|
+
return (route) => byRoute.get(route) ?? `${testID}-option-${route}`;
|
|
607
|
+
}, [items, testID]);
|
|
608
|
+
const hasActive = activeRoute !== NO_ACTIVE_ROUTE;
|
|
609
|
+
const textColor = hasActive ? TEXT_ON_PRIMARY3 : colors.rest;
|
|
610
|
+
const pillStyle = hasActive ? { backgroundColor: colors.activeBg } : void 0;
|
|
611
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
612
|
+
uiLayout.ModalDropdown,
|
|
613
|
+
{
|
|
614
|
+
accessibilityHint: hint,
|
|
615
|
+
accessibilityLabel: label,
|
|
616
|
+
optionTestID,
|
|
617
|
+
options,
|
|
618
|
+
testID,
|
|
619
|
+
value: activeRoute,
|
|
620
|
+
variant,
|
|
621
|
+
onChange: onNavigate,
|
|
622
|
+
renderTrigger: ({ isOpen }) => /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: [navBarStyles.link, navBarStyles.overflowTrigger, pillStyle], children: [
|
|
623
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [navBarStyles.linkText, { color: textColor }], children: label }),
|
|
624
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [navBarStyles.overflowChevron, { color: textColor }], children: isOpen ? "\u25B4" : "\u25BE" })
|
|
625
|
+
] })
|
|
626
|
+
}
|
|
627
|
+
);
|
|
628
|
+
};
|
|
629
|
+
|
|
630
|
+
// src/computeVisibleCount.ts
|
|
631
|
+
function sum(values) {
|
|
632
|
+
return values.reduce((acc, value) => acc + value, 0);
|
|
633
|
+
}
|
|
634
|
+
function computeVisibleCount({ availableWidth, itemWidths, moreWidth, gap }) {
|
|
635
|
+
const total = itemWidths.length;
|
|
636
|
+
if (total === 0) return 0;
|
|
637
|
+
if (availableWidth <= 0 || itemWidths.some((width) => width <= 0)) return total;
|
|
638
|
+
const fullRowWidth = sum(itemWidths) + gap * (total - 1);
|
|
639
|
+
if (fullRowWidth <= availableWidth) return total;
|
|
640
|
+
const reservedForMore = moreWidth + gap;
|
|
641
|
+
let used = 0;
|
|
642
|
+
let count = 0;
|
|
643
|
+
for (let index = 0; index < total; index += 1) {
|
|
644
|
+
const width = itemWidths[index] ?? 0;
|
|
645
|
+
const withGap = used + (count > 0 ? gap : 0) + width;
|
|
646
|
+
if (withGap + reservedForMore > availableWidth) break;
|
|
647
|
+
used = withGap;
|
|
648
|
+
count += 1;
|
|
649
|
+
}
|
|
650
|
+
return count;
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
// src/useNavOverflow.ts
|
|
654
|
+
function resizeWidthBuffer(previous, count) {
|
|
655
|
+
const next = new Array(count).fill(0);
|
|
656
|
+
const shared = Math.min(previous.length, count);
|
|
657
|
+
for (let index = 0; index < shared; index += 1) next[index] = previous[index] ?? 0;
|
|
658
|
+
return next;
|
|
659
|
+
}
|
|
660
|
+
function useNavOverflow(itemCount, gap) {
|
|
661
|
+
const [availableWidth, setAvailableWidthState] = React5.useState(0);
|
|
662
|
+
const [moreWidth, setMoreWidthState] = React5.useState(0);
|
|
663
|
+
const [itemWidths, setItemWidths] = React5.useState(() => new Array(itemCount).fill(0));
|
|
664
|
+
React5.useEffect(() => {
|
|
665
|
+
setItemWidths((previous) => previous.length === itemCount ? previous : resizeWidthBuffer(previous, itemCount));
|
|
666
|
+
}, [itemCount]);
|
|
667
|
+
const setItemWidth = React5.useCallback((index, width) => {
|
|
668
|
+
setItemWidths((previous) => {
|
|
669
|
+
if (index < 0 || index >= previous.length || previous[index] === width) return previous;
|
|
670
|
+
const next = previous.slice();
|
|
671
|
+
next[index] = width;
|
|
672
|
+
return next;
|
|
673
|
+
});
|
|
674
|
+
}, []);
|
|
675
|
+
const setAvailableWidth = React5.useCallback(
|
|
676
|
+
(width) => setAvailableWidthState((previous) => previous === width ? previous : width),
|
|
677
|
+
[]
|
|
678
|
+
);
|
|
679
|
+
const setMoreWidth = React5.useCallback(
|
|
680
|
+
(width) => setMoreWidthState((previous) => previous === width ? previous : width),
|
|
681
|
+
[]
|
|
682
|
+
);
|
|
683
|
+
const visibleCount = React5.useMemo(
|
|
684
|
+
() => computeVisibleCount({ availableWidth, itemWidths, moreWidth, gap }),
|
|
685
|
+
[availableWidth, itemWidths, moreWidth, gap]
|
|
686
|
+
);
|
|
687
|
+
return { visibleCount, setAvailableWidth, setItemWidth, setMoreWidth };
|
|
688
|
+
}
|
|
568
689
|
var REDUCED_MOTION_QUERY = "(prefers-reduced-motion: reduce)";
|
|
569
690
|
function getReducedMotionQuery() {
|
|
570
691
|
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return void 0;
|
|
571
692
|
return window.matchMedia(REDUCED_MOTION_QUERY);
|
|
572
693
|
}
|
|
573
694
|
function useReducedMotion() {
|
|
574
|
-
const [reduced, setReduced] =
|
|
575
|
-
|
|
695
|
+
const [reduced, setReduced] = React5.useState(() => getReducedMotionQuery()?.matches ?? false);
|
|
696
|
+
React5.useEffect(() => {
|
|
576
697
|
const mql = getReducedMotionQuery();
|
|
577
698
|
if (mql === void 0 || mql.addEventListener === void 0) return void 0;
|
|
578
699
|
const onChange = () => setReduced(mql.matches);
|
|
@@ -601,6 +722,8 @@ var NavBar = ({
|
|
|
601
722
|
menuHint = "",
|
|
602
723
|
renderMenuIcon,
|
|
603
724
|
collapseBelow = DEFAULT_COLLAPSE_BELOW,
|
|
725
|
+
overflowLabel = "More",
|
|
726
|
+
overflowHint = "",
|
|
604
727
|
containerStyle
|
|
605
728
|
}) => {
|
|
606
729
|
const { theme } = uiFeedback.useUi();
|
|
@@ -608,19 +731,20 @@ var NavBar = ({
|
|
|
608
731
|
const primaryColor = theme.palette.primary["500"];
|
|
609
732
|
const { width } = reactNative.useWindowDimensions();
|
|
610
733
|
const reducedMotion = useReducedMotion();
|
|
611
|
-
const [open, setOpen] =
|
|
612
|
-
const [toggleFocused, setToggleFocused] =
|
|
734
|
+
const [open, setOpen] = React5.useState(false);
|
|
735
|
+
const [toggleFocused, setToggleFocused] = React5.useState(false);
|
|
736
|
+
const { visibleCount, setAvailableWidth, setItemWidth, setMoreWidth } = useNavOverflow(items.length, NAV_LINK_GAP);
|
|
613
737
|
const collapsed = width < collapseBelow;
|
|
614
738
|
const showLinks = !collapsed || open;
|
|
615
|
-
const toggleMenu =
|
|
616
|
-
const handlePress =
|
|
739
|
+
const toggleMenu = React5.useCallback(() => setOpen((v) => !v), []);
|
|
740
|
+
const handlePress = React5.useCallback(
|
|
617
741
|
(route) => {
|
|
618
742
|
setOpen(false);
|
|
619
743
|
onNavigate(route);
|
|
620
744
|
},
|
|
621
745
|
[onNavigate]
|
|
622
746
|
);
|
|
623
|
-
const linkColors =
|
|
747
|
+
const linkColors = React5.useMemo(
|
|
624
748
|
() => ({
|
|
625
749
|
rest: colors.textSecondary,
|
|
626
750
|
hoverText: colors.text,
|
|
@@ -641,7 +765,7 @@ var NavBar = ({
|
|
|
641
765
|
{ backgroundColor: colors.surface, borderBottomColor: colors.border },
|
|
642
766
|
containerStyle
|
|
643
767
|
],
|
|
644
|
-
children: /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: navBarStyles.inner, children: [
|
|
768
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: [navBarStyles.inner, collapsed ? null : navBarStyles.innerNoWrap], children: [
|
|
645
769
|
brand !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: navBarStyles.brand, children: brand }) : null,
|
|
646
770
|
collapsed ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
647
771
|
reactNative.Pressable,
|
|
@@ -661,7 +785,7 @@ var NavBar = ({
|
|
|
661
785
|
}
|
|
662
786
|
) : null,
|
|
663
787
|
showLinks ? (() => {
|
|
664
|
-
const
|
|
788
|
+
const renderLink = (item) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
665
789
|
NavBarLink,
|
|
666
790
|
{
|
|
667
791
|
collapsed,
|
|
@@ -672,19 +796,50 @@ var NavBar = ({
|
|
|
672
796
|
navigateHint,
|
|
673
797
|
reducedMotion,
|
|
674
798
|
onPress: handlePress
|
|
675
|
-
}
|
|
676
|
-
|
|
677
|
-
)
|
|
678
|
-
|
|
679
|
-
|
|
799
|
+
}
|
|
800
|
+
);
|
|
801
|
+
if (collapsed) {
|
|
802
|
+
return /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { nativeID: LINKS_REGION_ID, style: navBarStyles.linksStacked, testID: NAV_TEST_IDS.navBarLinks, children: items.map((item) => /* @__PURE__ */ jsxRuntime.jsx(React5__default.default.Fragment, { children: renderLink(item) }, item.key)) });
|
|
803
|
+
}
|
|
804
|
+
const visibleItems = items.slice(0, visibleCount);
|
|
805
|
+
const overflowItems = items.slice(visibleCount);
|
|
806
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
807
|
+
reactNative.View,
|
|
680
808
|
{
|
|
681
|
-
horizontal: true,
|
|
682
|
-
showsHorizontalScrollIndicator: false,
|
|
683
809
|
nativeID: LINKS_REGION_ID,
|
|
684
|
-
style: navBarStyles.
|
|
685
|
-
contentContainerStyle: navBarStyles.links,
|
|
810
|
+
style: navBarStyles.linksRow,
|
|
686
811
|
testID: NAV_TEST_IDS.navBarLinks,
|
|
687
|
-
|
|
812
|
+
onLayout: (event) => setAvailableWidth(event.nativeEvent.layout.width),
|
|
813
|
+
children: [
|
|
814
|
+
visibleItems.map((item, index) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
815
|
+
reactNative.View,
|
|
816
|
+
{
|
|
817
|
+
style: navBarStyles.linkCell,
|
|
818
|
+
onLayout: (event) => setItemWidth(index, event.nativeEvent.layout.width),
|
|
819
|
+
children: renderLink(item)
|
|
820
|
+
},
|
|
821
|
+
item.key
|
|
822
|
+
)),
|
|
823
|
+
overflowItems.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
824
|
+
reactNative.View,
|
|
825
|
+
{
|
|
826
|
+
style: navBarStyles.linkCell,
|
|
827
|
+
onLayout: (event) => setMoreWidth(event.nativeEvent.layout.width),
|
|
828
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
829
|
+
NavOverflowMenu,
|
|
830
|
+
{
|
|
831
|
+
colors: linkColors,
|
|
832
|
+
hint: overflowHint,
|
|
833
|
+
items: overflowItems,
|
|
834
|
+
label: overflowLabel,
|
|
835
|
+
pathname,
|
|
836
|
+
testID: NAV_TEST_IDS.navBarOverflow,
|
|
837
|
+
onNavigate: handlePress
|
|
838
|
+
}
|
|
839
|
+
)
|
|
840
|
+
}
|
|
841
|
+
) : null
|
|
842
|
+
]
|
|
688
843
|
}
|
|
689
844
|
);
|
|
690
845
|
})() : null,
|
|
@@ -693,6 +848,12 @@ var NavBar = ({
|
|
|
693
848
|
}
|
|
694
849
|
);
|
|
695
850
|
};
|
|
851
|
+
var Nav = (props) => {
|
|
852
|
+
if (props.orientation === "vertical") {
|
|
853
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Sidebar, { ...props });
|
|
854
|
+
}
|
|
855
|
+
return /* @__PURE__ */ jsxRuntime.jsx(NavBar, { ...props });
|
|
856
|
+
};
|
|
696
857
|
var MOBILE_BREAKPOINT = 768;
|
|
697
858
|
var SCRIM_COLOR = "rgba(0, 0, 0, 0.5)";
|
|
698
859
|
var MENU_GLYPH2 = "\u2630";
|
|
@@ -742,8 +903,8 @@ var MobileDrawer = ({
|
|
|
742
903
|
drawerTestID,
|
|
743
904
|
scrimTestID
|
|
744
905
|
}) => {
|
|
745
|
-
const panelRef =
|
|
746
|
-
|
|
906
|
+
const panelRef = React5.useRef(null);
|
|
907
|
+
React5.useEffect(() => {
|
|
747
908
|
const node = panelRef.current;
|
|
748
909
|
if (node === null || typeof node.addEventListener !== "function") return void 0;
|
|
749
910
|
const handleClick = (event) => {
|
|
@@ -861,15 +1022,15 @@ var AppShell = ({
|
|
|
861
1022
|
const { width: viewportWidth } = reactNative.useWindowDimensions();
|
|
862
1023
|
const isNarrow = viewportWidth < MOBILE_BREAKPOINT;
|
|
863
1024
|
const useDrawer = sidebar !== void 0 && isNarrow;
|
|
864
|
-
const [drawerOpen, setDrawerOpen] =
|
|
865
|
-
const openDrawer =
|
|
866
|
-
const closeDrawer =
|
|
867
|
-
|
|
1025
|
+
const [drawerOpen, setDrawerOpen] = React5.useState(false);
|
|
1026
|
+
const openDrawer = React5.useCallback(() => setDrawerOpen(true), []);
|
|
1027
|
+
const closeDrawer = React5.useCallback(() => setDrawerOpen(false), []);
|
|
1028
|
+
React5.useEffect(() => {
|
|
868
1029
|
if (!isNarrow && drawerOpen) setDrawerOpen(false);
|
|
869
1030
|
}, [isNarrow, drawerOpen]);
|
|
870
1031
|
const drawerLabels = { ...DEFAULT_DRAWER_LABELS, ...mobileMenu };
|
|
871
1032
|
const isUnauthenticated = gate !== void 0 && !gate.pending && !gate.authenticated;
|
|
872
|
-
|
|
1033
|
+
React5.useEffect(() => {
|
|
873
1034
|
if (isUnauthenticated && gate !== void 0) gate.onRedirect();
|
|
874
1035
|
}, [isUnauthenticated, gate]);
|
|
875
1036
|
if (gate?.pending === true)
|
|
@@ -936,9 +1097,12 @@ exports.AppShell = AppShell;
|
|
|
936
1097
|
exports.BASE_INDENT = BASE_INDENT;
|
|
937
1098
|
exports.CHEVRON_ICON_SIZE = CHEVRON_ICON_SIZE;
|
|
938
1099
|
exports.NAV_ICON_SIZE = NAV_ICON_SIZE;
|
|
1100
|
+
exports.NAV_LINK_GAP = NAV_LINK_GAP;
|
|
939
1101
|
exports.NAV_TEST_IDS = NAV_TEST_IDS;
|
|
1102
|
+
exports.Nav = Nav;
|
|
940
1103
|
exports.NavBar = NavBar;
|
|
941
1104
|
exports.NavExpandableItem = NavExpandableItem;
|
|
1105
|
+
exports.NavOverflowMenu = NavOverflowMenu;
|
|
942
1106
|
exports.Sidebar = Sidebar;
|
|
943
1107
|
exports.Topbar = Topbar;
|
|
944
1108
|
exports.accessibleNavItems = accessibleNavItems;
|