@dloizides/ui-nav 1.22.0 → 1.23.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 CHANGED
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.23.0
4
+
5
+ **The NavBar's stacked mobile menu now scrolls within the viewport (SHOWCASE-1).**
6
+
7
+ Below `collapseBelow` the open hamburger menu grew to its natural height (734px with ~15 items on
8
+ ui.dloizides.com at 360x640). Portals set `body { overflow: hidden }`, so the last items sat below
9
+ the fold and neither wheel nor touch could reach them — in every portal with more than ~10 items.
10
+
11
+ - The stacked links region is now a `ScrollView` capped to `windowHeight - closedBarHeight -
12
+ stackedRightSlot - chrome` (pure `computeStackedMenuMaxHeight`, unit-tested; floor of three 44px
13
+ rows). Rows keep their 44px minimum; nothing depends on hover.
14
+
3
15
  ## 1.20.0
4
16
 
5
17
  **The auth-pending and page-loading spinners now OVERLAY stably-mounted children instead of
package/dist/index.js CHANGED
@@ -148,13 +148,19 @@ var navBarStyles = reactNative.StyleSheet.create({
148
148
  overflowChevron: { fontSize: 12, fontWeight: "700" },
149
149
  // Collapsed (below breakpoint): links drop onto their own full-width line,
150
150
  // stacked vertically — mirrors the v1 `.gn-links` responsive behaviour.
151
+ // SHOWCASE-1: this is a ScrollView — `maxHeight` (viewport minus bar) is applied at render time,
152
+ // so a long menu scrolls within the viewport instead of running off a body:overflow:hidden page.
151
153
  linksStacked: {
152
154
  width: "100%",
153
155
  flexBasis: "100%",
156
+ flexGrow: 0,
157
+ flexShrink: 0,
158
+ marginTop: 8
159
+ },
160
+ linksStackedContent: {
154
161
  flexDirection: "column",
155
162
  alignItems: "stretch",
156
- rowGap: 2,
157
- marginTop: 8
163
+ rowGap: 2
158
164
  },
159
165
  link: {
160
166
  paddingVertical: 8,
@@ -1184,9 +1190,24 @@ function useNavOverflow(itemCount, gap) {
1184
1190
  );
1185
1191
  return { visibleCount, setAvailableWidth, setItemWidth, setMoreWidth };
1186
1192
  }
1193
+
1194
+ // src/stackedMenuMaxHeight.ts
1195
+ var DEFAULT_BAR_HEIGHT = 64;
1196
+ var MIN_STACKED_MENU_HEIGHT = 3 * 44;
1197
+ function computeStackedMenuMaxHeight({
1198
+ windowHeight,
1199
+ barHeight,
1200
+ reservedBelow
1201
+ }) {
1202
+ const bar = barHeight > 0 ? barHeight : DEFAULT_BAR_HEIGHT;
1203
+ const reserved = Math.max(0, reservedBelow);
1204
+ return Math.max(MIN_STACKED_MENU_HEIGHT, windowHeight - bar - reserved);
1205
+ }
1187
1206
  var LINKS_REGION_ID = "navbar-links-region";
1188
1207
  var DEFAULT_COLLAPSE_BELOW = 760;
1189
1208
  var MENU_GLYPH = "\u2630";
1209
+ var STACKED_MENU_CHROME = 12;
1210
+ var STACKED_RIGHT_CHROME = 8;
1190
1211
  function ariaControlsProps(id) {
1191
1212
  return { "aria-controls": id };
1192
1213
  }
@@ -1210,13 +1231,22 @@ var NavBarInner = ({
1210
1231
  const { theme } = uiFeedback.useUi();
1211
1232
  const colors = theme.colors;
1212
1233
  const primaryColor = theme.palette.primary["500"];
1213
- const { width } = reactNative.useWindowDimensions();
1234
+ const { width, height } = reactNative.useWindowDimensions();
1214
1235
  const reducedMotion = useReducedMotion();
1215
1236
  const [open, setOpen] = React.useState(false);
1216
1237
  const [toggleFocused, setToggleFocused] = React.useState(false);
1217
1238
  const { visibleCount, setAvailableWidth, setItemWidth, setMoreWidth } = useNavOverflow(items.length, NAV_LINK_GAP);
1218
1239
  const collapsed = width < collapseBelow;
1219
1240
  const showLinks = !collapsed || open;
1241
+ const [barHeight, setBarHeight] = React.useState(0);
1242
+ const [rightHeight, setRightHeight] = React.useState(0);
1243
+ const hasRight = right !== void 0;
1244
+ const stackedMaxHeight = computeStackedMenuMaxHeight({
1245
+ windowHeight: height,
1246
+ barHeight,
1247
+ reservedBelow: STACKED_MENU_CHROME + (hasRight ? STACKED_RIGHT_CHROME + rightHeight : 0)
1248
+ });
1249
+ const measureBar = collapsed && !open;
1220
1250
  const innerCapStyle = React.useMemo(
1221
1251
  () => contentMaxWidth === void 0 ? null : { maxWidth: contentMaxWidth, width: "100%", alignSelf: "center" },
1222
1252
  [contentMaxWidth]
@@ -1251,6 +1281,7 @@ var NavBarInner = ({
1251
1281
  { backgroundColor: colors.surface, borderBottomColor: colors.border },
1252
1282
  containerStyle
1253
1283
  ],
1284
+ onLayout: measureBar ? (event) => setBarHeight(event.nativeEvent.layout.height) : void 0,
1254
1285
  children: /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: [navBarStyles.inner, collapsed ? null : navBarStyles.innerNoWrap, innerCapStyle], children: [
1255
1286
  brand !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: navBarStyles.brand, children: renderTextSlot(brand, { color: colors.text }) }) : null,
1256
1287
  collapsed ? /* @__PURE__ */ jsxRuntime.jsx(
@@ -1285,7 +1316,16 @@ var NavBarInner = ({
1285
1316
  }
1286
1317
  );
1287
1318
  if (collapsed) {
1288
- 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(React__default.default.Fragment, { children: renderLink(item) }, item.key)) });
1319
+ return /* @__PURE__ */ jsxRuntime.jsx(
1320
+ reactNative.ScrollView,
1321
+ {
1322
+ contentContainerStyle: navBarStyles.linksStackedContent,
1323
+ nativeID: LINKS_REGION_ID,
1324
+ style: [navBarStyles.linksStacked, { maxHeight: stackedMaxHeight }],
1325
+ testID: NAV_TEST_IDS.navBarLinks,
1326
+ children: items.map((item) => /* @__PURE__ */ jsxRuntime.jsx(React__default.default.Fragment, { children: renderLink(item) }, item.key))
1327
+ }
1328
+ );
1289
1329
  }
1290
1330
  const visibleItems = items.slice(0, visibleCount);
1291
1331
  const overflowItems = items.slice(visibleCount);
@@ -1329,7 +1369,14 @@ var NavBarInner = ({
1329
1369
  }
1330
1370
  );
1331
1371
  })() : null,
1332
- showLinks && right !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: collapsed ? navBarStyles.rightStacked : navBarStyles.right, children: renderTextSlot(right, { color: colors.text }) }) : null
1372
+ showLinks && hasRight ? /* @__PURE__ */ jsxRuntime.jsx(
1373
+ reactNative.View,
1374
+ {
1375
+ style: collapsed ? navBarStyles.rightStacked : navBarStyles.right,
1376
+ onLayout: collapsed ? (event) => setRightHeight(event.nativeEvent.layout.height) : void 0,
1377
+ children: renderTextSlot(right, { color: colors.text })
1378
+ }
1379
+ ) : null
1333
1380
  ] })
1334
1381
  }
1335
1382
  );