@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/dist/index.mjs CHANGED
@@ -142,13 +142,19 @@ var navBarStyles = StyleSheet.create({
142
142
  overflowChevron: { fontSize: 12, fontWeight: "700" },
143
143
  // Collapsed (below breakpoint): links drop onto their own full-width line,
144
144
  // stacked vertically — mirrors the v1 `.gn-links` responsive behaviour.
145
+ // SHOWCASE-1: this is a ScrollView — `maxHeight` (viewport minus bar) is applied at render time,
146
+ // so a long menu scrolls within the viewport instead of running off a body:overflow:hidden page.
145
147
  linksStacked: {
146
148
  width: "100%",
147
149
  flexBasis: "100%",
150
+ flexGrow: 0,
151
+ flexShrink: 0,
152
+ marginTop: 8
153
+ },
154
+ linksStackedContent: {
148
155
  flexDirection: "column",
149
156
  alignItems: "stretch",
150
- rowGap: 2,
151
- marginTop: 8
157
+ rowGap: 2
152
158
  },
153
159
  link: {
154
160
  paddingVertical: 8,
@@ -1178,9 +1184,24 @@ function useNavOverflow(itemCount, gap) {
1178
1184
  );
1179
1185
  return { visibleCount, setAvailableWidth, setItemWidth, setMoreWidth };
1180
1186
  }
1187
+
1188
+ // src/stackedMenuMaxHeight.ts
1189
+ var DEFAULT_BAR_HEIGHT = 64;
1190
+ var MIN_STACKED_MENU_HEIGHT = 3 * 44;
1191
+ function computeStackedMenuMaxHeight({
1192
+ windowHeight,
1193
+ barHeight,
1194
+ reservedBelow
1195
+ }) {
1196
+ const bar = barHeight > 0 ? barHeight : DEFAULT_BAR_HEIGHT;
1197
+ const reserved = Math.max(0, reservedBelow);
1198
+ return Math.max(MIN_STACKED_MENU_HEIGHT, windowHeight - bar - reserved);
1199
+ }
1181
1200
  var LINKS_REGION_ID = "navbar-links-region";
1182
1201
  var DEFAULT_COLLAPSE_BELOW = 760;
1183
1202
  var MENU_GLYPH = "\u2630";
1203
+ var STACKED_MENU_CHROME = 12;
1204
+ var STACKED_RIGHT_CHROME = 8;
1184
1205
  function ariaControlsProps(id) {
1185
1206
  return { "aria-controls": id };
1186
1207
  }
@@ -1204,13 +1225,22 @@ var NavBarInner = ({
1204
1225
  const { theme } = useUi();
1205
1226
  const colors = theme.colors;
1206
1227
  const primaryColor = theme.palette.primary["500"];
1207
- const { width } = useWindowDimensions();
1228
+ const { width, height } = useWindowDimensions();
1208
1229
  const reducedMotion = useReducedMotion();
1209
1230
  const [open, setOpen] = useState(false);
1210
1231
  const [toggleFocused, setToggleFocused] = useState(false);
1211
1232
  const { visibleCount, setAvailableWidth, setItemWidth, setMoreWidth } = useNavOverflow(items.length, NAV_LINK_GAP);
1212
1233
  const collapsed = width < collapseBelow;
1213
1234
  const showLinks = !collapsed || open;
1235
+ const [barHeight, setBarHeight] = useState(0);
1236
+ const [rightHeight, setRightHeight] = useState(0);
1237
+ const hasRight = right !== void 0;
1238
+ const stackedMaxHeight = computeStackedMenuMaxHeight({
1239
+ windowHeight: height,
1240
+ barHeight,
1241
+ reservedBelow: STACKED_MENU_CHROME + (hasRight ? STACKED_RIGHT_CHROME + rightHeight : 0)
1242
+ });
1243
+ const measureBar = collapsed && !open;
1214
1244
  const innerCapStyle = useMemo(
1215
1245
  () => contentMaxWidth === void 0 ? null : { maxWidth: contentMaxWidth, width: "100%", alignSelf: "center" },
1216
1246
  [contentMaxWidth]
@@ -1245,6 +1275,7 @@ var NavBarInner = ({
1245
1275
  { backgroundColor: colors.surface, borderBottomColor: colors.border },
1246
1276
  containerStyle
1247
1277
  ],
1278
+ onLayout: measureBar ? (event) => setBarHeight(event.nativeEvent.layout.height) : void 0,
1248
1279
  children: /* @__PURE__ */ jsxs(View, { style: [navBarStyles.inner, collapsed ? null : navBarStyles.innerNoWrap, innerCapStyle], children: [
1249
1280
  brand !== void 0 ? /* @__PURE__ */ jsx(View, { style: navBarStyles.brand, children: renderTextSlot(brand, { color: colors.text }) }) : null,
1250
1281
  collapsed ? /* @__PURE__ */ jsx(
@@ -1279,7 +1310,16 @@ var NavBarInner = ({
1279
1310
  }
1280
1311
  );
1281
1312
  if (collapsed) {
1282
- return /* @__PURE__ */ jsx(View, { nativeID: LINKS_REGION_ID, style: navBarStyles.linksStacked, testID: NAV_TEST_IDS.navBarLinks, children: items.map((item) => /* @__PURE__ */ jsx(React.Fragment, { children: renderLink(item) }, item.key)) });
1313
+ return /* @__PURE__ */ jsx(
1314
+ ScrollView,
1315
+ {
1316
+ contentContainerStyle: navBarStyles.linksStackedContent,
1317
+ nativeID: LINKS_REGION_ID,
1318
+ style: [navBarStyles.linksStacked, { maxHeight: stackedMaxHeight }],
1319
+ testID: NAV_TEST_IDS.navBarLinks,
1320
+ children: items.map((item) => /* @__PURE__ */ jsx(React.Fragment, { children: renderLink(item) }, item.key))
1321
+ }
1322
+ );
1283
1323
  }
1284
1324
  const visibleItems = items.slice(0, visibleCount);
1285
1325
  const overflowItems = items.slice(visibleCount);
@@ -1323,7 +1363,14 @@ var NavBarInner = ({
1323
1363
  }
1324
1364
  );
1325
1365
  })() : null,
1326
- showLinks && right !== void 0 ? /* @__PURE__ */ jsx(View, { style: collapsed ? navBarStyles.rightStacked : navBarStyles.right, children: renderTextSlot(right, { color: colors.text }) }) : null
1366
+ showLinks && hasRight ? /* @__PURE__ */ jsx(
1367
+ View,
1368
+ {
1369
+ style: collapsed ? navBarStyles.rightStacked : navBarStyles.right,
1370
+ onLayout: collapsed ? (event) => setRightHeight(event.nativeEvent.layout.height) : void 0,
1371
+ children: renderTextSlot(right, { color: colors.text })
1372
+ }
1373
+ ) : null
1327
1374
  ] })
1328
1375
  }
1329
1376
  );