@dloizides/ui-nav 1.18.0 → 1.20.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/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import React, { useState, useCallback, useMemo, useEffect, useRef } from 'react';
2
- import { Platform, StyleSheet, Pressable, Text, View, TextInput, useWindowDimensions, ActivityIndicator, ScrollView } from 'react-native';
2
+ import { Platform, StyleSheet, Pressable, Text, View, TextInput, useWindowDimensions, ScrollView, ActivityIndicator } from 'react-native';
3
3
  import { useUi, UiProvider } from '@dloizides/ui-feedback';
4
4
  import { jsxs, jsx } from 'react/jsx-runtime';
5
5
  import { Collapse } from '@dloizides/ui-motion';
@@ -1068,6 +1068,7 @@ var NavBarLink = ({
1068
1068
  };
1069
1069
  var TEXT_ON_PRIMARY3 = "#ffffff";
1070
1070
  var NO_ACTIVE_ROUTE = "";
1071
+ var OVERFLOW_MENU_MIN_WIDTH = 200;
1071
1072
  var NavOverflowMenu = ({
1072
1073
  items,
1073
1074
  pathname,
@@ -1095,6 +1096,7 @@ var NavOverflowMenu = ({
1095
1096
  {
1096
1097
  accessibilityHint: hint,
1097
1098
  accessibilityLabel: label,
1099
+ menuMinWidth: OVERFLOW_MENU_MIN_WIDTH,
1098
1100
  optionTestID,
1099
1101
  options,
1100
1102
  testID,
@@ -1336,7 +1338,22 @@ var CARD_TITLE_FONT_SIZE = 16;
1336
1338
  var CARD_MESSAGE_FONT_SIZE = 14;
1337
1339
  var CARD_TITLE_MARGIN_BOTTOM = 8;
1338
1340
  var styles3 = StyleSheet.create({
1339
- centerFill: { flex: 1, justifyContent: "center", alignItems: "center" },
1341
+ // Loading is a TRANSITIONAL state: the spinner is an absolute overlay ON TOP of
1342
+ // stably-mounted children, never a replacement for them. Replacing children here
1343
+ // would unmount whatever they host (e.g. a navigator), and on remount React
1344
+ // Navigation re-derives its default route — silently discarding a deep link.
1345
+ // The host wraps children whenever a `state` is passed (not only while loading),
1346
+ // so its element type is invariant across the loading toggle — see `useContentBody`.
1347
+ loadingHost: { flex: 1 },
1348
+ loadingOverlay: {
1349
+ alignItems: "center",
1350
+ bottom: 0,
1351
+ justifyContent: "center",
1352
+ left: 0,
1353
+ position: "absolute",
1354
+ right: 0,
1355
+ top: 0
1356
+ },
1340
1357
  card: {
1341
1358
  padding: CARD_PADDING,
1342
1359
  borderRadius: CARD_BORDER_RADIUS,
@@ -1361,13 +1378,22 @@ function useContentBody(state, children, testID) {
1361
1378
  const { theme } = useUi();
1362
1379
  const primary = theme.palette.primary["500"];
1363
1380
  const errorColor = theme.semantic.error["500"];
1364
- if (state?.forbidden)
1381
+ if (!state) return children;
1382
+ if (state.forbidden)
1365
1383
  return /* @__PURE__ */ jsx(MessageCard, { accentColor: errorColor, message: state.forbidden, testID: `${testID}${APP_SHELL_SUFFIX.forbidden}` });
1366
- if (state?.error)
1384
+ if (state.error)
1367
1385
  return /* @__PURE__ */ jsx(MessageCard, { accentColor: errorColor, message: state.error, testID: `${testID}${APP_SHELL_SUFFIX.error}` });
1368
- if (state?.loading === true)
1369
- return /* @__PURE__ */ jsx(View, { style: styles3.centerFill, testID: `${testID}${APP_SHELL_SUFFIX.loading}`, children: /* @__PURE__ */ jsx(ActivityIndicator, { color: primary, size: "large" }) });
1370
- return children;
1386
+ return /* @__PURE__ */ jsxs(View, { style: styles3.loadingHost, children: [
1387
+ children,
1388
+ state.loading === true ? /* @__PURE__ */ jsx(
1389
+ View,
1390
+ {
1391
+ style: [styles3.loadingOverlay, { backgroundColor: theme.colors.background }],
1392
+ testID: `${testID}${APP_SHELL_SUFFIX.loading}`,
1393
+ children: /* @__PURE__ */ jsx(ActivityIndicator, { color: primary, size: "large" })
1394
+ }
1395
+ ) : null
1396
+ ] });
1371
1397
  }
1372
1398
  var SCRIM_COLOR = "rgba(0, 0, 0, 0.5)";
1373
1399
  var MENU_GLYPH2 = "\u2630";
@@ -1505,7 +1531,10 @@ function useContentMaxWidth(width) {
1505
1531
  var DEFAULT_CONTENT_PADDING = 24;
1506
1532
  var styles5 = StyleSheet.create({
1507
1533
  root: { flex: 1 },
1508
- centerFill: { flex: 1, justifyContent: "center", alignItems: "center" },
1534
+ // Auth-pending spinner: an opaque absolute overlay over the mounted shell, so
1535
+ // `children` (and any navigator they host) are never unmounted while the gate
1536
+ // resolves. See the `gatePending` note in the render body.
1537
+ pendingOverlay: { alignItems: "center", bottom: 0, justifyContent: "center", left: 0, position: "absolute", right: 0, top: 0 },
1509
1538
  scroll: { flex: 1 },
1510
1539
  scrollContent: { flexGrow: 1 },
1511
1540
  // Mobile back-office header: the hamburger sits inline before the header slot.
@@ -1559,8 +1588,7 @@ var AppShell = ({
1559
1588
  useEffect(() => {
1560
1589
  if (isUnauthenticated && gate !== void 0) gate.onRedirect();
1561
1590
  }, [isUnauthenticated, gate]);
1562
- if (gate?.pending === true)
1563
- return /* @__PURE__ */ jsx(View, { style: [styles5.root, styles5.centerFill, { backgroundColor: theme.colors.background }], testID: `${testID}${APP_SHELL_SUFFIX.pending}`, children: /* @__PURE__ */ jsx(ActivityIndicator, { color: primary, size: "large" }) });
1591
+ const gatePending = gate?.pending === true;
1564
1592
  if (isUnauthenticated) return null;
1565
1593
  const columnStyle = maxWidth === "full" ? styles5.columnFull : [styles5.columnCapped, { maxWidth }];
1566
1594
  const navInnerStyle = chromeAlignment === "content" && maxWidth !== "full" ? [styles5.chromeCapped, { maxWidth, paddingHorizontal: contentPadding }] : void 0;
@@ -1603,6 +1631,14 @@ var AppShell = ({
1603
1631
  sidebar,
1604
1632
  onClose: closeDrawer
1605
1633
  }
1634
+ ) : null,
1635
+ gatePending ? /* @__PURE__ */ jsx(
1636
+ View,
1637
+ {
1638
+ style: [styles5.pendingOverlay, { backgroundColor: theme.colors.background }],
1639
+ testID: `${testID}${APP_SHELL_SUFFIX.pending}`,
1640
+ children: /* @__PURE__ */ jsx(ActivityIndicator, { color: primary, size: "large" })
1641
+ }
1606
1642
  ) : null
1607
1643
  ] });
1608
1644
  };