@homebound/beam 4.59.0 → 4.60.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.js CHANGED
@@ -20100,9 +20100,20 @@ function useMenuSelectField(props) {
20100
20100
  () => menuTree ? menuTree.orderedKeys.filter((key) => disabledKeySet.has(menuTree.nodes.get(key).valueKey)) : disabledKeys,
20101
20101
  [menuTree, disabledKeySet, disabledKeys]
20102
20102
  );
20103
+ const rememberedSelectedRef = useRef36(/* @__PURE__ */ new Map());
20104
+ syncRememberedOptions(rememberedSelectedRef.current, values, optionsByKey);
20103
20105
  const selectedOptions = useMemo28(
20104
- () => menuTree ? selectedTreeOptions(menuTree, selectedKeys) : values.map((v) => optionsByKey.get(valueToKey(v))).filter((o) => o !== void 0),
20105
- [menuTree, selectedKeys, values, optionsByKey]
20106
+ () => resolveSelectedOptions(
20107
+ values,
20108
+ menuTree,
20109
+ selectedKeys,
20110
+ optionsByKey,
20111
+ rememberedSelectedRef.current,
20112
+ getOptionValue
20113
+ ),
20114
+ // getOptionValue is typically an inline lambda
20115
+ // oxlint-disable-next-line react-hooks/exhaustive-deps
20116
+ [values, optionsByKey, menuTree, selectedKeys]
20106
20117
  );
20107
20118
  const dottedKeys = useMemo28(
20108
20119
  () => new Set(mixedValues?.map(valueToKey).filter((key) => optionsByKey.has(key) && !selectedKeys.has(key))),
@@ -20144,9 +20155,8 @@ function useMenuSelectField(props) {
20144
20155
  const valueKey = key === void 0 ? void 0 : menuTree.nodes.get(key)?.valueKey;
20145
20156
  if (valueKey === void 0) return;
20146
20157
  const next2 = toggleTreeSelection(menuTree, selectedKeys, valueKey, added !== void 0, disabledKeySet);
20147
- const nextOptions = selectedTreeOptions(menuTree, next2);
20148
20158
  proposalProps.onUserEdit?.();
20149
- onCommit(nextOptions.map(getOptionValue), nextOptions);
20159
+ commitTree(next2);
20150
20160
  return;
20151
20161
  }
20152
20162
  if (!multiple) {
@@ -20161,16 +20171,17 @@ function useMenuSelectField(props) {
20161
20171
  close({ restoreFocus: true });
20162
20172
  return;
20163
20173
  }
20164
- const next = values.filter((v) => keys.has(valueToKey(v)));
20174
+ const next = values.filter((value) => {
20175
+ const key = valueToKey(value);
20176
+ if (!optionsByKey.has(key)) return true;
20177
+ return keys.has(key);
20178
+ });
20165
20179
  for (const k of keys) {
20166
20180
  const opt = optionsByKey.get(String(k));
20167
20181
  if (opt !== void 0 && !selectedKeys.has(String(k))) next.push(getOptionValue(opt));
20168
20182
  }
20169
20183
  proposalProps.onUserEdit?.();
20170
- onCommit(
20171
- next,
20172
- next.map((v) => optionsByKey.get(valueToKey(v))).filter((o) => o !== void 0)
20173
- );
20184
+ onCommit(next, optionsForValues(next));
20174
20185
  }
20175
20186
  const collectionItems = useMemo28(() => {
20176
20187
  if (treeRows) {
@@ -20382,14 +20393,35 @@ function useMenuSelectField(props) {
20382
20393
  proposalProps.onUserEdit?.();
20383
20394
  if (menuTree) {
20384
20395
  const toggledKeys = toggleTreeSelection(menuTree, selectedKeys, key, false, disabledKeySet);
20385
- const toggledOptions = selectedTreeOptions(menuTree, toggledKeys);
20386
- onCommit(toggledOptions.map(getOptionValue), toggledOptions);
20396
+ commitTree(toggledKeys, key);
20387
20397
  return;
20388
20398
  }
20389
20399
  const next = values.filter((value) => valueToKey(value) !== key);
20400
+ onCommit(next, optionsForValues(next));
20401
+ }
20402
+ function optionsForValues(next) {
20403
+ return next.flatMap((value) => {
20404
+ const option = optionForKey(valueToKey(value), optionsByKey, rememberedSelectedRef.current);
20405
+ return option ? [option] : [];
20406
+ });
20407
+ }
20408
+ function commitTree(nextKeys, clearedKey) {
20409
+ if (!menuTree) return;
20410
+ const selectedInTree = selectedTreeOptions(menuTree, nextKeys);
20411
+ const valueKeysInTree = new Set(menuTree.orderedKeys.map((rowKey) => menuTree.nodes.get(rowKey).valueKey));
20412
+ const seen = /* @__PURE__ */ new Set();
20413
+ const keptSelections = values.flatMap((value) => {
20414
+ const key = valueToKey(value);
20415
+ if (valueKeysInTree.has(key) || key === clearedKey || seen.has(key)) return [];
20416
+ const option = optionForKey(key, optionsByKey, rememberedSelectedRef.current);
20417
+ if (!option) return [];
20418
+ seen.add(key);
20419
+ return [option];
20420
+ });
20421
+ const nextOptions = [...selectedInTree, ...keptSelections];
20390
20422
  onCommit(
20391
- next,
20392
- next.map((value) => optionsByKey.get(valueToKey(value))).filter((option) => option !== void 0)
20423
+ nextOptions.map((option) => getOptionValue(option)),
20424
+ nextOptions
20393
20425
  );
20394
20426
  }
20395
20427
  const triggerProps = {
@@ -20455,6 +20487,41 @@ function useMenuSelectField(props) {
20455
20487
  }
20456
20488
  };
20457
20489
  }
20490
+ function syncRememberedOptions(remembered, values, optionsByKey) {
20491
+ const selected = /* @__PURE__ */ new Set();
20492
+ for (const value of values) {
20493
+ const key = valueToKey(value);
20494
+ selected.add(key);
20495
+ const option = optionsByKey.get(key);
20496
+ if (option) remembered.set(key, option);
20497
+ }
20498
+ for (const key of remembered.keys()) {
20499
+ if (!selected.has(key)) remembered.delete(key);
20500
+ }
20501
+ }
20502
+ function optionForKey(key, optionsByKey, remembered) {
20503
+ return optionsByKey.get(key) ?? remembered.get(key);
20504
+ }
20505
+ function resolveSelectedOptions(values, menuTree, selectedKeys, optionsByKey, remembered, getOptionValue) {
20506
+ if (!menuTree) {
20507
+ return values.flatMap((value) => {
20508
+ const option = optionForKey(valueToKey(value), optionsByKey, remembered);
20509
+ return option ? [option] : [];
20510
+ });
20511
+ }
20512
+ const selectedInTree = selectedTreeOptions(menuTree, selectedKeys);
20513
+ const seen = new Set(selectedInTree.map((option) => valueToKey(getOptionValue(option))));
20514
+ const keptSelections = [];
20515
+ for (const value of values) {
20516
+ const key = valueToKey(value);
20517
+ if (seen.has(key)) continue;
20518
+ const option = optionForKey(key, optionsByKey, remembered);
20519
+ if (!option) continue;
20520
+ seen.add(key);
20521
+ keptSelections.push(option);
20522
+ }
20523
+ return [...selectedInTree, ...keptSelections];
20524
+ }
20458
20525
  function labelsFor(values, options, getOptionValue, getOptionLabel) {
20459
20526
  const keys = new Set(values.map(valueToKey));
20460
20527
  const seen = /* @__PURE__ */ new Set();
@@ -27295,7 +27362,7 @@ function invertSpacing(value) {
27295
27362
  }
27296
27363
 
27297
27364
  // src/components/Layout/GridTableLayout/GridTableLayout.tsx
27298
- import React17, { useCallback as useCallback37, useEffect as useEffect29, useMemo as useMemo50, useRef as useRef66, useState as useState55 } from "react";
27365
+ import React17, { useCallback as useCallback37, useEffect as useEffect29, useMemo as useMemo50, useRef as useRef67, useState as useState56 } from "react";
27299
27366
 
27300
27367
  // src/components/Layout/GridTableLayout/GridTableLayoutActions.tsx
27301
27368
  import { memo as memo2, useMemo as useMemo46, useState as useState48 } from "react";
@@ -27836,7 +27903,7 @@ function SelectionSummaryAction(props) {
27836
27903
 
27837
27904
  // src/components/Layout/GridTableLayout/GridTableLayoutHost.tsx
27838
27905
  import { useResizeObserver as useResizeObserver10 } from "@react-aria/utils";
27839
- import { useCallback as useCallback33, useLayoutEffect as useLayoutEffect14, useRef as useRef64 } from "react";
27906
+ import { useCallback as useCallback33, useImperativeHandle, useLayoutEffect as useLayoutEffect15, useRef as useRef65 } from "react";
27840
27907
 
27841
27908
  // src/components/Layout/RightPaneLayout/DocumentScrollOverlayRightPaneLayout.tsx
27842
27909
  import { useContext as useContext23, useEffect as useEffect27, useLayoutEffect as useLayoutEffect13, useRef as useRef63, useState as useState51 } from "react";
@@ -28308,6 +28375,132 @@ function ModalFullBleed({
28308
28375
  }));
28309
28376
  }
28310
28377
 
28378
+ // src/layouts/useAutoHideOnScroll.ts
28379
+ import { useLayoutEffect as useLayoutEffect14, useRef as useRef64, useState as useState52 } from "react";
28380
+ var THRESHOLD = 80;
28381
+ var HOLD_QUIET_MS = 150;
28382
+ var cancelActiveHold;
28383
+ var holdReleaseListeners = /* @__PURE__ */ new Set();
28384
+ var userScrollEvents = ["wheel", "touchstart"];
28385
+ function holdAutoHideWhile(scroll) {
28386
+ cancelActiveHold?.();
28387
+ let quietTimer;
28388
+ const restartQuietTimer = () => {
28389
+ clearTimeout(quietTimer);
28390
+ quietTimer = setTimeout(release, HOLD_QUIET_MS);
28391
+ };
28392
+ const cancel = () => {
28393
+ clearTimeout(quietTimer);
28394
+ window.removeEventListener("scroll", restartQuietTimer);
28395
+ for (const event of userScrollEvents) window.removeEventListener(event, release);
28396
+ window.removeEventListener("scrollend", release);
28397
+ cancelActiveHold = void 0;
28398
+ };
28399
+ function release() {
28400
+ cancel();
28401
+ holdReleaseListeners.forEach((listener) => listener());
28402
+ }
28403
+ window.addEventListener("scroll", restartQuietTimer, { passive: true });
28404
+ for (const event of userScrollEvents) window.addEventListener(event, release, { passive: true });
28405
+ window.addEventListener("scrollend", release);
28406
+ cancelActiveHold = cancel;
28407
+ restartQuietTimer();
28408
+ scroll();
28409
+ }
28410
+ function getInitialAutoHideState() {
28411
+ if (typeof window === "undefined" || window.scrollY <= 0) {
28412
+ return "resting";
28413
+ }
28414
+ return "hidden";
28415
+ }
28416
+ function useAutoHideOnScroll(spacerRef, enabled, getTopOffset) {
28417
+ const initial = getInitialAutoHideState();
28418
+ const [state, setState] = useState52(initial);
28419
+ const stateRef = useRef64(initial);
28420
+ const getTopOffsetRef = useRef64(getTopOffset);
28421
+ getTopOffsetRef.current = getTopOffset;
28422
+ const lastScrollY = useRef64(Number.POSITIVE_INFINITY);
28423
+ const lastScrollHeight = useRef64(0);
28424
+ useLayoutEffect14(() => {
28425
+ if (!enabled) {
28426
+ stateRef.current = "resting";
28427
+ lastScrollY.current = Number.POSITIVE_INFINITY;
28428
+ lastScrollHeight.current = 0;
28429
+ setState("resting");
28430
+ return;
28431
+ }
28432
+ const commit = (nextState) => {
28433
+ if (nextState !== stateRef.current) {
28434
+ stateRef.current = nextState;
28435
+ setState(nextState);
28436
+ }
28437
+ };
28438
+ const autoHideStateOnLayoutChange = (rect, topOffset) => {
28439
+ const nextAtTop = rect.top >= topOffset;
28440
+ let next = stateRef.current;
28441
+ if (nextAtTop) {
28442
+ next = "resting";
28443
+ } else if (rect.bottom < -THRESHOLD && next !== "revealed") {
28444
+ next = "hidden";
28445
+ }
28446
+ return next;
28447
+ };
28448
+ const updateAutoHideState = () => {
28449
+ const el = spacerRef.current;
28450
+ if (!el) return;
28451
+ const doc = document.documentElement;
28452
+ const currentScrollHeight = doc.scrollHeight;
28453
+ const scrollHeightChanged = lastScrollHeight.current !== 0 && currentScrollHeight !== lastScrollHeight.current;
28454
+ lastScrollHeight.current = currentScrollHeight;
28455
+ if (window.scrollY <= 0) {
28456
+ lastScrollY.current = 0;
28457
+ commit("resting");
28458
+ return;
28459
+ }
28460
+ const currentY = window.scrollY;
28461
+ if (cancelActiveHold) {
28462
+ lastScrollY.current = currentY;
28463
+ return;
28464
+ }
28465
+ const rect = el.getBoundingClientRect();
28466
+ const topOffset = getTopOffsetRef.current?.() ?? 0;
28467
+ if (scrollHeightChanged) {
28468
+ lastScrollY.current = currentY;
28469
+ commit(autoHideStateOnLayoutChange(rect, topOffset));
28470
+ return;
28471
+ }
28472
+ const dy = currentY - lastScrollY.current;
28473
+ lastScrollY.current = currentY;
28474
+ const atBottom = currentY >= doc.scrollHeight - doc.clientHeight;
28475
+ const nextAtTop = rect.top >= topOffset;
28476
+ let next = stateRef.current;
28477
+ if (nextAtTop) {
28478
+ next = "resting";
28479
+ } else if (rect.bottom < -THRESHOLD) {
28480
+ if (dy < 0 && !atBottom) next = "revealed";
28481
+ else if (dy > 0) next = "hidden";
28482
+ }
28483
+ commit(next);
28484
+ };
28485
+ const onHoldRelease = () => {
28486
+ const el = spacerRef.current;
28487
+ if (!el) return;
28488
+ lastScrollY.current = window.scrollY;
28489
+ lastScrollHeight.current = document.documentElement.scrollHeight;
28490
+ if (window.scrollY <= 0) return commit("resting");
28491
+ commit(autoHideStateOnLayoutChange(el.getBoundingClientRect(), getTopOffsetRef.current?.() ?? 0));
28492
+ };
28493
+ updateAutoHideState();
28494
+ window.addEventListener("scroll", updateAutoHideState, { passive: true });
28495
+ holdReleaseListeners.add(onHoldRelease);
28496
+ return () => {
28497
+ window.removeEventListener("scroll", updateAutoHideState);
28498
+ holdReleaseListeners.delete(onHoldRelease);
28499
+ };
28500
+ }, [enabled, spacerRef]);
28501
+ return { state };
28502
+ }
28503
+
28311
28504
  // src/components/Layout/GridTableLayout/GridTableLayoutHost.tsx
28312
28505
  import { trussProps as trussProps118, maybeCssVar as maybeCssVar55 } from "@homebound/truss/runtime";
28313
28506
  import { jsx as jsx206, jsxs as jsxs108 } from "react/jsx-runtime";
@@ -28321,12 +28514,33 @@ function GridTableLayoutHost(props) {
28321
28514
  rightPane,
28322
28515
  isVirtualized,
28323
28516
  testIds,
28517
+ scrollToTopRef,
28324
28518
  children
28325
28519
  } = props;
28326
- const tableWrapperRef = useRef64(null);
28327
- const tableActionsRef = useRef64(null);
28520
+ const tableWrapperRef = useRef65(null);
28521
+ const tableActionsRef = useRef65(null);
28328
28522
  const hasActions = actions !== void 0;
28523
+ const {
28524
+ scrollableEl
28525
+ } = useScrollableParent();
28329
28526
  useSetTableActionsHeight(tableWrapperRef, tableActionsRef, host.kind !== "scrollable-parent" && hasActions);
28527
+ useImperativeHandle(scrollToTopRef, () => () => {
28528
+ const scrollableParent = host.kind === "scrollable-parent" ? scrollableEl?.parentElement : void 0;
28529
+ if (scrollableParent) {
28530
+ scrollableParent.scrollTo?.({
28531
+ top: 0,
28532
+ behavior: "smooth"
28533
+ });
28534
+ } else {
28535
+ const scrollToWrapper = () => tableWrapperRef.current?.scrollIntoView?.({
28536
+ behavior: "smooth",
28537
+ block: "start",
28538
+ inline: "start"
28539
+ });
28540
+ if (host.kind === "modal") scrollToWrapper();
28541
+ else holdAutoHideWhile(scrollToWrapper);
28542
+ }
28543
+ }, [host.kind, scrollableEl]);
28330
28544
  const shared = {
28331
28545
  actions,
28332
28546
  tableWrapperRef,
@@ -28380,29 +28594,49 @@ function DocumentScrollHost(props) {
28380
28594
  "--minWidth": maybeCssVar55(documentScrollRightPaneContentMinCss())
28381
28595
  }]
28382
28596
  }), children }) }) : children;
28383
- return /* @__PURE__ */ jsxs108("div", { ref: tableWrapperRef, className: "df fdc wfc mw100", ...actions !== void 0 ? selfTopSpaced : {}, ...testIds.tableWrapper, children: [
28384
- /* @__PURE__ */ jsx206(ActionsBar, { actionsRef: tableActionsRef, xss: {
28385
- transition: "transitionTop",
28386
- position: "sticky",
28387
- top: ["top_var", {
28388
- "--top": maybeCssVar55(__maybeInc21(stickyNavAndHeaderOffset()))
28389
- }],
28390
- left: ["left_var", {
28391
- "--left": maybeCssVar55(__maybeInc21(documentScrollChromeLeft()))
28392
- }],
28393
- width: ["w_var", {
28394
- "--width": maybeCssVar55(__maybeInc21(`min(100%, ${documentScrollChromeWidth()})`))
28395
- }],
28396
- contain: "ctn_inline_size",
28397
- zIndex: ["z_var", {
28398
- "--zIndex": maybeCssVar55(zIndices.tableActions)
28399
- }],
28400
- backgroundColor: ["bgColor_var", {
28401
- "--backgroundColor": "var(--b-surface)"
28402
- }]
28403
- }, testIds, children: actions }),
28404
- tableBody
28405
- ] });
28597
+ return /* @__PURE__ */ jsxs108(
28598
+ "div",
28599
+ {
28600
+ ref: tableWrapperRef,
28601
+ ...trussProps118({
28602
+ display: "df",
28603
+ flexDirection: "fdc",
28604
+ width: "wfc",
28605
+ minWidth: "mw100",
28606
+ scrollMarginTop: ["scrollMarginTop_var", {
28607
+ "--scrollMarginTop": maybeCssVar55(stickyNavAndHeaderOffset())
28608
+ }],
28609
+ scrollMarginLeft: ["scrollMarginLeft_var", {
28610
+ "--scrollMarginLeft": maybeCssVar55(documentScrollContentLeft())
28611
+ }]
28612
+ }),
28613
+ ...actions !== void 0 ? selfTopSpaced : {},
28614
+ ...testIds.tableWrapper,
28615
+ children: [
28616
+ /* @__PURE__ */ jsx206(ActionsBar, { actionsRef: tableActionsRef, xss: {
28617
+ transition: "transitionTop",
28618
+ position: "sticky",
28619
+ top: ["top_var", {
28620
+ "--top": maybeCssVar55(__maybeInc21(stickyNavAndHeaderOffset()))
28621
+ }],
28622
+ left: ["left_var", {
28623
+ "--left": maybeCssVar55(__maybeInc21(documentScrollChromeLeft()))
28624
+ }],
28625
+ width: ["w_var", {
28626
+ "--width": maybeCssVar55(__maybeInc21(`min(100%, ${documentScrollChromeWidth()})`))
28627
+ }],
28628
+ contain: "ctn_inline_size",
28629
+ zIndex: ["z_var", {
28630
+ "--zIndex": maybeCssVar55(zIndices.tableActions)
28631
+ }],
28632
+ backgroundColor: ["bgColor_var", {
28633
+ "--backgroundColor": "var(--b-surface)"
28634
+ }]
28635
+ }, testIds, children: actions }),
28636
+ tableBody
28637
+ ]
28638
+ }
28639
+ );
28406
28640
  }
28407
28641
  function ScrollableParentHost(props) {
28408
28642
  const {
@@ -28446,7 +28680,7 @@ function useSetTableActionsHeight(tableWrapperRef, tableActionsRef, enabled) {
28446
28680
  ref: tableActionsRef,
28447
28681
  onResize: enabled ? syncHeightVar : noop
28448
28682
  });
28449
- useLayoutEffect14(() => {
28683
+ useLayoutEffect15(() => {
28450
28684
  syncHeightVar();
28451
28685
  const tableWrapper = tableWrapperRef.current;
28452
28686
  return () => {
@@ -28492,10 +28726,10 @@ function useGridTableLayoutHost() {
28492
28726
  }
28493
28727
 
28494
28728
  // src/components/Layout/GridTableLayout/usePersistedTableView.ts
28495
- import { useCallback as useCallback34, useState as useState52 } from "react";
28729
+ import { useCallback as useCallback34, useState as useState53 } from "react";
28496
28730
  function usePersistedTableView(defaultView, persist) {
28497
28731
  const storageKey = persist ? getGridTableViewStorageKey(window.location.pathname) : void 0;
28498
- const [view, setView] = useState52(() => {
28732
+ const [view, setView] = useState53(() => {
28499
28733
  if (!storageKey) return defaultView;
28500
28734
  try {
28501
28735
  return parseStoredTableView(localStorage.getItem(storageKey)) ?? defaultView;
@@ -28530,7 +28764,7 @@ function isGridTableProps(props) {
28530
28764
  }
28531
28765
 
28532
28766
  // src/hooks/useGroupBy.ts
28533
- import { useMemo as useMemo48, useState as useState53 } from "react";
28767
+ import { useMemo as useMemo48, useState as useState54 } from "react";
28534
28768
 
28535
28769
  // src/hooks/useQueryState.ts
28536
28770
  import { useCallback as useCallback35 } from "react";
@@ -28551,7 +28785,7 @@ function useGroupBy(opts) {
28551
28785
  []
28552
28786
  );
28553
28787
  const [queryValue, setQueryValue] = useQueryState("groupBy", options[0].id);
28554
- const [localValue, setLocalValue] = useState53(options[0].id);
28788
+ const [localValue, setLocalValue] = useState54(options[0].id);
28555
28789
  return {
28556
28790
  value: inModal ? localValue : queryValue,
28557
28791
  setValue: inModal ? setLocalValue : setQueryValue,
@@ -28560,17 +28794,17 @@ function useGroupBy(opts) {
28560
28794
  }
28561
28795
 
28562
28796
  // src/hooks/usePersistedFilter.ts
28563
- import { useEffect as useEffect28, useMemo as useMemo49, useRef as useRef65 } from "react";
28797
+ import { useEffect as useEffect28, useMemo as useMemo49, useRef as useRef66 } from "react";
28564
28798
 
28565
28799
  // src/hooks/useSessionStorage.ts
28566
- import { useCallback as useCallback36, useState as useState54 } from "react";
28800
+ import { useCallback as useCallback36, useState as useState55 } from "react";
28567
28801
  function useSessionStorage(key, defaultValue) {
28568
28802
  let hasSessionStorage = false;
28569
28803
  try {
28570
28804
  hasSessionStorage = !!window.sessionStorage;
28571
28805
  } catch (e) {
28572
28806
  }
28573
- const [state, setState] = useState54(() => {
28807
+ const [state, setState] = useState55(() => {
28574
28808
  if (!hasSessionStorage) {
28575
28809
  return defaultValue;
28576
28810
  }
@@ -28697,8 +28931,8 @@ function parseSerializedValue(value) {
28697
28931
  return value === void 0 ? void 0 : JSON.parse(value);
28698
28932
  }
28699
28933
  function useStableValue(value) {
28700
- const stableValue = useRef65(value);
28701
- const stableKey = useRef65(JSON.stringify(value));
28934
+ const stableValue = useRef66(value);
28935
+ const stableKey = useRef66(JSON.stringify(value));
28702
28936
  const nextKey = JSON.stringify(value);
28703
28937
  if (stableKey.current !== nextKey) {
28704
28938
  stableValue.current = value;
@@ -28721,7 +28955,8 @@ function GridTableLayoutComponent(props) {
28721
28955
  withCardView,
28722
28956
  defaultView = "list",
28723
28957
  emptyFallback: layoutEmptyFallback,
28724
- withRightPane
28958
+ withRightPane,
28959
+ scrollToTopOnFilterChange = false
28725
28960
  } = props;
28726
28961
  const tid = useTestIds(props);
28727
28962
  const host = useGridTableLayoutHost();
@@ -28753,11 +28988,18 @@ function GridTableLayoutComponent(props) {
28753
28988
  () => layoutState?.search ? { onSearch: layoutState.setSearchString } : void 0,
28754
28989
  [layoutState?.search, layoutState?.setSearchString]
28755
28990
  );
28756
- const searchApiRef = useRef66(void 0);
28991
+ const searchApiRef = useRef67(void 0);
28757
28992
  const clearFilters = useCallback37(() => {
28758
28993
  layoutState?.clearFilters();
28759
28994
  searchApiRef.current?.clear();
28760
28995
  }, [layoutState]);
28996
+ const scrollToTopRef = useRef67(void 0);
28997
+ useScrollToTopOnFilterChange({
28998
+ enabled: scrollToTopOnFilterChange,
28999
+ layoutState,
29000
+ loading: isGridTableProps(tableProps) ? !!tableProps.loading : tableProps.query.loading,
29001
+ scrollToTopRef
29002
+ });
28761
29003
  const emptyState = useMemo50(
28762
29004
  () => composeEmptyState(tableProps, layoutState, layoutEmptyFallback, clearFilters),
28763
29005
  [layoutEmptyFallback, layoutState, tableProps, clearFilters]
@@ -28823,11 +29065,25 @@ function GridTableLayoutComponent(props) {
28823
29065
  rightPane: withRightPane,
28824
29066
  isVirtualized,
28825
29067
  testIds: tid,
29068
+ scrollToTopRef,
28826
29069
  children: tableBody
28827
29070
  }
28828
29071
  );
28829
29072
  }
28830
29073
  var GridTableLayout = React17.memo(GridTableLayoutComponent);
29074
+ function useScrollToTopOnFilterChange(opts) {
29075
+ const { enabled, layoutState, loading, scrollToTopRef } = opts;
29076
+ const { filter, searchString } = layoutState ?? {};
29077
+ const currentFiltersRef = useRef67({ filter, searchString });
29078
+ useEffect29(() => {
29079
+ const scrolledFor = currentFiltersRef.current;
29080
+ if (scrolledFor.filter === filter && scrolledFor.searchString === searchString) return;
29081
+ if (!enabled) return void (currentFiltersRef.current = { filter, searchString });
29082
+ if (loading) return;
29083
+ currentFiltersRef.current = { filter, searchString };
29084
+ scrollToTopRef.current?.();
29085
+ }, [enabled, filter, searchString, loading, scrollToTopRef]);
29086
+ }
28831
29087
  function getDefaultStyle(style, insetHandled) {
28832
29088
  if (style !== void 0 && !isGridStyleDef(style)) return style;
28833
29089
  return { allWhite: true, ...!insetHandled && { bordered: "top" }, ...style };
@@ -28848,7 +29104,7 @@ function useGridTableLayoutState({
28848
29104
  const filterFallback = { filterDefs: {}, storageKey: "unset-filter" };
28849
29105
  const { filter, setFilter } = usePersistedFilter(persistedFilter ?? filterFallback);
28850
29106
  const groupBy = useGroupBy(maybeGroupBy ?? { none: "none" });
28851
- const [searchString, setSearchString] = useState55("");
29107
+ const [searchString, setSearchString] = useState56("");
28852
29108
  const columnsFallback = "unset-columns";
28853
29109
  const [visibleColumnIds, setVisibleColumnIds] = useSessionStorage(
28854
29110
  persistedColumns?.storageKey ?? columnsFallback,
@@ -29010,12 +29266,12 @@ function RightPaneLayout(props) {
29010
29266
  }
29011
29267
 
29012
29268
  // src/components/Layout/RightPaneLayout/RightPanePanel.tsx
29013
- import { createContext as createContext14, useContext as useContext24, useEffect as useEffect31, useState as useState57 } from "react";
29269
+ import { createContext as createContext14, useContext as useContext24, useEffect as useEffect31, useState as useState58 } from "react";
29014
29270
  import { createPortal as createPortal8 } from "react-dom";
29015
29271
 
29016
29272
  // src/components/Layout/RightPaneLayout/internal/DeleteAction.tsx
29017
29273
  import { useResizeObserver as useResizeObserver11 } from "@react-aria/utils";
29018
- import { useRef as useRef67, useState as useState56 } from "react";
29274
+ import { useRef as useRef68, useState as useState57 } from "react";
29019
29275
  import { trussProps as trussProps120 } from "@homebound/truss/runtime";
29020
29276
  import { jsx as jsx211, jsxs as jsxs111 } from "react/jsx-runtime";
29021
29277
  function MaybeDeleteAction(props) {
@@ -29032,9 +29288,9 @@ function BulkDeleteAction(props) {
29032
29288
  count,
29033
29289
  ...buttonProps
29034
29290
  } = props;
29035
- const containerRef = useRef67(null);
29036
- const contentRef = useRef67(null);
29037
- const [overflows, setOverflows] = useState56(false);
29291
+ const containerRef = useRef68(null);
29292
+ const contentRef = useRef68(null);
29293
+ const [overflows, setOverflows] = useState57(false);
29038
29294
  const onResize = () => {
29039
29295
  if (!containerRef.current || !contentRef.current) return;
29040
29296
  setOverflows(contentRef.current.offsetWidth > containerRef.current.clientWidth);
@@ -29101,7 +29357,7 @@ function RightPanePanel(props) {
29101
29357
  const {
29102
29358
  closeRightPane
29103
29359
  } = useRightPaneActions();
29104
- const [bannerSlot, setBannerSlot] = useState57(null);
29360
+ const [bannerSlot, setBannerSlot] = useState58(null);
29105
29361
  const {
29106
29362
  openModal
29107
29363
  } = useModal();
@@ -29188,7 +29444,7 @@ function ScrollableFooter(props) {
29188
29444
 
29189
29445
  // src/components/Layout/TableReviewLayout/TableReviewLayout.tsx
29190
29446
  import { AnimatePresence as AnimatePresence5, motion as motion5 } from "framer-motion";
29191
- import { useEffect as useEffect32, useState as useState58 } from "react";
29447
+ import { useEffect as useEffect32, useState as useState59 } from "react";
29192
29448
 
29193
29449
  // src/components/Layout/TableReviewLayout/SidePanel.tsx
29194
29450
  import { jsx as jsx214, jsxs as jsxs113 } from "react/jsx-runtime";
@@ -29228,7 +29484,7 @@ function TableReviewLayout(props) {
29228
29484
  rightPaneWidth = defaultRightPaneWidth
29229
29485
  } = props;
29230
29486
  const tid = useTestIds(props, "tableReviewLayout");
29231
- const [isPanelVisible, setIsPanelVisible] = useState58(!!panelContent);
29487
+ const [isPanelVisible, setIsPanelVisible] = useState59(!!panelContent);
29232
29488
  useEffect32(() => {
29233
29489
  setIsPanelVisible(!!panelContent);
29234
29490
  }, [panelContent]);
@@ -29388,18 +29644,18 @@ function HomeboundLogo(props) {
29388
29644
  }
29389
29645
 
29390
29646
  // src/components/MaxLines.tsx
29391
- import { useLayoutEffect as useLayoutEffect15, useResizeObserver as useResizeObserver12 } from "@react-aria/utils";
29392
- import { useCallback as useCallback38, useEffect as useEffect33, useRef as useRef68, useState as useState59 } from "react";
29647
+ import { useLayoutEffect as useLayoutEffect16, useResizeObserver as useResizeObserver12 } from "@react-aria/utils";
29648
+ import { useCallback as useCallback38, useEffect as useEffect33, useRef as useRef69, useState as useState60 } from "react";
29393
29649
  import { trussProps as trussProps125, maybeCssVar as maybeCssVar60 } from "@homebound/truss/runtime";
29394
29650
  import { jsx as jsx218, jsxs as jsxs116 } from "react/jsx-runtime";
29395
29651
  function MaxLines({
29396
29652
  maxLines,
29397
29653
  children
29398
29654
  }) {
29399
- const elRef = useRef68(null);
29400
- const [hasMore, setHasMore] = useState59(false);
29401
- const [expanded, setExpanded] = useState59(false);
29402
- useLayoutEffect15(() => {
29655
+ const elRef = useRef69(null);
29656
+ const [hasMore, setHasMore] = useState60(false);
29657
+ const [expanded, setExpanded] = useState60(false);
29658
+ useLayoutEffect16(() => {
29403
29659
  if (!elRef.current) return;
29404
29660
  setHasMore(elRef.current.scrollHeight > elRef.current.clientHeight);
29405
29661
  }, []);
@@ -29521,7 +29777,7 @@ function toPageNumberSize(page) {
29521
29777
 
29522
29778
  // src/components/ScrollShadows.tsx
29523
29779
  import { useResizeObserver as useResizeObserver13 } from "@react-aria/utils";
29524
- import { useCallback as useCallback39, useMemo as useMemo51, useRef as useRef69, useState as useState60 } from "react";
29780
+ import { useCallback as useCallback39, useMemo as useMemo51, useRef as useRef70, useState as useState61 } from "react";
29525
29781
  import { trussProps as trussProps127, maybeCssVar as maybeCssVar61 } from "@homebound/truss/runtime";
29526
29782
  import { jsx as jsx220, jsxs as jsxs118 } from "react/jsx-runtime";
29527
29783
  function ScrollShadows(props) {
@@ -29539,9 +29795,9 @@ function ScrollShadows(props) {
29539
29795
  if (!bgColor.includes("rgba")) {
29540
29796
  throw new Error("ScrollShadows: bgColor prop must be in the format 'rgba(255, 255, 255, 1)'");
29541
29797
  }
29542
- const [showStartShadow, setShowStartShadow] = useState60(false);
29543
- const [showEndShadow, setShowEndShadow] = useState60(false);
29544
- const scrollRef = useRef69(null);
29798
+ const [showStartShadow, setShowStartShadow] = useState61(false);
29799
+ const [showEndShadow, setShowEndShadow] = useState61(false);
29800
+ const scrollRef = useRef70(null);
29545
29801
  const [startShadowStyles, endShadowStyles] = useMemo51(() => {
29546
29802
  const transparentBgColor = bgColor.replace(/,1\)$/, ",0)");
29547
29803
  const commonStyles = {
@@ -29662,10 +29918,10 @@ import { camelCase as camelCase7 } from "change-case";
29662
29918
  // src/components/AppNav/AppNavGroup.tsx
29663
29919
  import { useResizeObserver as useResizeObserver14 } from "@react-aria/utils";
29664
29920
  import { camelCase as camelCase6, kebabCase } from "change-case";
29665
- import { useCallback as useCallback41, useEffect as useEffect34, useMemo as useMemo53, useState as useState62 } from "react";
29921
+ import { useCallback as useCallback41, useEffect as useEffect34, useMemo as useMemo53, useState as useState63 } from "react";
29666
29922
 
29667
29923
  // src/components/AppNav/AppNavGroupTrigger.tsx
29668
- import { useMemo as useMemo52, useRef as useRef70 } from "react";
29924
+ import { useMemo as useMemo52, useRef as useRef71 } from "react";
29669
29925
  import { mergeProps as mergeProps35, useButton as useButton11, useFocusRing as useFocusRing17, useHover as useHover22 } from "react-aria";
29670
29926
  import { trussProps as trussProps128, mergeProps as mergeProps_15 } from "@homebound/truss/runtime";
29671
29927
  import { jsx as jsx221, jsxs as jsxs119 } from "react/jsx-runtime";
@@ -29678,7 +29934,7 @@ function AppNavGroupTrigger(props) {
29678
29934
  active = false
29679
29935
  } = props;
29680
29936
  const tid = useTestIds(props, "trigger");
29681
- const ref = useRef70(null);
29937
+ const ref = useRef71(null);
29682
29938
  const {
29683
29939
  buttonProps,
29684
29940
  isPressed
@@ -29837,7 +30093,7 @@ function entryHasIcons(item) {
29837
30093
  }
29838
30094
 
29839
30095
  // src/components/AppNav/useAppNavGroupExpanded.ts
29840
- import { useCallback as useCallback40, useState as useState61 } from "react";
30096
+ import { useCallback as useCallback40, useState as useState62 } from "react";
29841
30097
  var APP_NAV_EXPANDED_LINK_GROUPS_STORAGE_KEY = "beam.appNav.expandedLinkGroups";
29842
30098
  function loadStored() {
29843
30099
  try {
@@ -29856,7 +30112,7 @@ function persistLabel(label, expanded) {
29856
30112
  }
29857
30113
  function useAppNavGroupExpanded(linkGroup) {
29858
30114
  const { label } = linkGroup;
29859
- const [userExpanded, setUserExpanded] = useState61(() => {
30115
+ const [userExpanded, setUserExpanded] = useState62(() => {
29860
30116
  const stored = loadStored();
29861
30117
  return label in stored ? stored[label] : null;
29862
30118
  });
@@ -29897,11 +30153,11 @@ function AppNavGroupDisclosure(props) {
29897
30153
  } = useAppNavGroupExpanded(linkGroup);
29898
30154
  const tid = useTestIds(props, "linkGroup");
29899
30155
  const navGroupId = `nav-group-${kebabCase(linkGroup.label)}`;
29900
- const [contentEl, setContentEl] = useState62(null);
30156
+ const [contentEl, setContentEl] = useState63(null);
29901
30157
  const contentRef = useMemo53(() => ({
29902
30158
  current: contentEl
29903
30159
  }), [contentEl]);
29904
- const [contentHeight, setContentHeight] = useState62(expanded ? "auto" : "0");
30160
+ const [contentHeight, setContentHeight] = useState63(expanded ? "auto" : "0");
29905
30161
  useEffect34(() => {
29906
30162
  setContentHeight(expanded && contentEl ? `${contentEl.scrollHeight}px` : "0");
29907
30163
  }, [expanded, contentEl]);
@@ -30057,8 +30313,8 @@ import {
30057
30313
  useContext as useContext25,
30058
30314
  useEffect as useEffect35,
30059
30315
  useMemo as useMemo54,
30060
- useRef as useRef71,
30061
- useState as useState63
30316
+ useRef as useRef72,
30317
+ useState as useState64
30062
30318
  } from "react";
30063
30319
  import { jsx as jsx226 } from "react/jsx-runtime";
30064
30320
  var SIDE_NAV_LAYOUT_STATE_STORAGE_KEY = "beam.sideNavLayout.navState";
@@ -30084,11 +30340,11 @@ function resolveInitialNavState(defaultNavState) {
30084
30340
  }
30085
30341
  var SideNavLayoutContext = createContext15(void 0);
30086
30342
  function SideNavLayoutProvider(props) {
30087
- const [navState, setNavStateInternal] = useState63(
30343
+ const [navState, setNavStateInternal] = useState64(
30088
30344
  () => resolveInitialNavState(props.defaultNavState)
30089
30345
  );
30090
30346
  const bp = useBreakpoint();
30091
- const prevMdAndUp = useRef71(bp.mdAndUp);
30347
+ const prevMdAndUp = useRef72(bp.mdAndUp);
30092
30348
  useEffect35(() => {
30093
30349
  if (prevMdAndUp.current && !bp.mdAndUp) {
30094
30350
  setNavStateInternal((prev) => prev === "expanded" ? "collapse" : prev);
@@ -30176,7 +30432,7 @@ function SideNav(props) {
30176
30432
  }
30177
30433
 
30178
30434
  // src/components/Stepper.tsx
30179
- import { useRef as useRef72 } from "react";
30435
+ import { useRef as useRef73 } from "react";
30180
30436
  import { useButton as useButton12, useFocusRing as useFocusRing18, useHover as useHover23 } from "react-aria";
30181
30437
  import { trussProps as trussProps132, maybeCssVar as maybeCssVar63 } from "@homebound/truss/runtime";
30182
30438
  import { jsx as jsx228, jsxs as jsxs123 } from "react/jsx-runtime";
@@ -30258,7 +30514,7 @@ function StepButton(props) {
30258
30514
  onPress: onClick,
30259
30515
  isDisabled: disabled
30260
30516
  };
30261
- const ref = useRef72(null);
30517
+ const ref = useRef73(null);
30262
30518
  const {
30263
30519
  buttonProps,
30264
30520
  isPressed
@@ -30368,7 +30624,7 @@ function StepIcon({
30368
30624
  }
30369
30625
 
30370
30626
  // src/components/StepperTabs/StepperTab.tsx
30371
- import { useRef as useRef73 } from "react";
30627
+ import { useRef as useRef74 } from "react";
30372
30628
  import { mergeProps as mergeProps36, useButton as useButton13, useFocusRing as useFocusRing19, useHover as useHover24, VisuallyHidden as VisuallyHidden10 } from "react-aria";
30373
30629
  import { trussProps as trussProps133 } from "@homebound/truss/runtime";
30374
30630
  import { Fragment as Fragment49, jsx as jsx229, jsxs as jsxs124 } from "react/jsx-runtime";
@@ -30387,7 +30643,7 @@ function StepperTab(props) {
30387
30643
  onPress: () => onClick(value),
30388
30644
  isDisabled: disabled || collapsed
30389
30645
  };
30390
- const ref = useRef73(null);
30646
+ const ref = useRef74(null);
30391
30647
  const {
30392
30648
  buttonProps
30393
30649
  } = useButton13(ariaProps, ref);
@@ -30788,7 +31044,7 @@ function segmentWidth(count, total) {
30788
31044
  }
30789
31045
 
30790
31046
  // src/components/TableSummary/TableSummary.tsx
30791
- import { useRef as useRef74 } from "react";
31047
+ import { useRef as useRef75 } from "react";
30792
31048
  import { mergeProps as mergeProps38, useButton as useButton14, useFocusRing as useFocusRing20, useHover as useHover25 } from "react-aria";
30793
31049
  import { trussProps as trussProps138, maybeCssVar as maybeCssVar65 } from "@homebound/truss/runtime";
30794
31050
  import { jsx as jsx235, jsxs as jsxs129 } from "react/jsx-runtime";
@@ -30848,7 +31104,7 @@ function MetricButton(props) {
30848
31104
  metric,
30849
31105
  divider
30850
31106
  } = props;
30851
- const ref = useRef74(null);
31107
+ const ref = useRef75(null);
30852
31108
  const {
30853
31109
  buttonProps
30854
31110
  } = useButton14({
@@ -30925,7 +31181,7 @@ function MetricButton(props) {
30925
31181
 
30926
31182
  // src/components/DnDGrid/DnDGrid.tsx
30927
31183
  import equal2 from "fast-deep-equal";
30928
- import { useCallback as useCallback43, useEffect as useEffect36, useRef as useRef75 } from "react";
31184
+ import { useCallback as useCallback43, useEffect as useEffect36, useRef as useRef76 } from "react";
30929
31185
 
30930
31186
  // src/utils/inlineStyles.ts
30931
31187
  function isInlineStyleValue(value) {
@@ -30975,13 +31231,13 @@ function DnDGrid(props) {
30975
31231
  activeItemStyles,
30976
31232
  lockAxis
30977
31233
  } = props;
30978
- const gridEl = useRef75(null);
30979
- const dragEl = useRef75(void 0);
30980
- const cloneEl = useRef75(void 0);
30981
- const initialOrder = useRef75(void 0);
30982
- const styleSnapshot = useRef75(void 0);
30983
- const reorderViaKeyboard = useRef75(false);
30984
- const transformFrom = useRef75({
31234
+ const gridEl = useRef76(null);
31235
+ const dragEl = useRef76(void 0);
31236
+ const cloneEl = useRef76(void 0);
31237
+ const initialOrder = useRef76(void 0);
31238
+ const styleSnapshot = useRef76(void 0);
31239
+ const reorderViaKeyboard = useRef76(false);
31240
+ const transformFrom = useRef76({
30985
31241
  x: 0,
30986
31242
  y: 0
30987
31243
  });
@@ -32010,17 +32266,17 @@ function OpenModal(props) {
32010
32266
 
32011
32267
  // src/components/Navbar/NavbarMobileMenu.tsx
32012
32268
  import { AnimatePresence as AnimatePresence6, motion as motion7 } from "framer-motion";
32013
- import { useEffect as useEffect39, useState as useState65 } from "react";
32269
+ import { useEffect as useEffect39, useState as useState66 } from "react";
32014
32270
  import { FocusScope as FocusScope7, usePreventScroll as usePreventScroll4 } from "react-aria";
32015
32271
  import { createPortal as createPortal11 } from "react-dom";
32016
32272
  import { useLocation } from "react-router-dom";
32017
32273
 
32018
32274
  // src/layouts/NavbarLayout/MobileSubNavContext.tsx
32019
- import { createContext as createContext18, useContext as useContext29, useLayoutEffect as useLayoutEffect16, useMemo as useMemo60, useState as useState64 } from "react";
32275
+ import { createContext as createContext18, useContext as useContext29, useLayoutEffect as useLayoutEffect17, useMemo as useMemo60, useState as useState65 } from "react";
32020
32276
  import { jsx as jsx251 } from "react/jsx-runtime";
32021
32277
  var MobileSubNavContext = createContext18(void 0);
32022
32278
  function MobileSubNavProvider(props) {
32023
- const [mobileSubNav, setMobileSubNav] = useState64(null);
32279
+ const [mobileSubNav, setMobileSubNav] = useState65(null);
32024
32280
  const value = useMemo60(() => ({ mobileSubNav, setMobileSubNav }), [mobileSubNav]);
32025
32281
  return /* @__PURE__ */ jsx251(MobileSubNavContext.Provider, { value, children: props.children });
32026
32282
  }
@@ -32032,11 +32288,11 @@ function useRegisterMobileSubNav(content2) {
32032
32288
  const setMobileSubNav = ctx?.setMobileSubNav;
32033
32289
  const enabled = !useBreakpoint().mdAndUp;
32034
32290
  const { top, items, footer } = content2;
32035
- useLayoutEffect16(() => {
32291
+ useLayoutEffect17(() => {
32036
32292
  if (!setMobileSubNav || !enabled) return;
32037
32293
  setMobileSubNav({ top, items, footer });
32038
32294
  }, [setMobileSubNav, enabled, top, items, footer]);
32039
- useLayoutEffect16(() => {
32295
+ useLayoutEffect17(() => {
32040
32296
  if (!setMobileSubNav || !enabled) return;
32041
32297
  return () => setMobileSubNav(null);
32042
32298
  }, [setMobileSubNav, enabled]);
@@ -32051,8 +32307,8 @@ function NavbarMobileMenu(props) {
32051
32307
  items
32052
32308
  } = props;
32053
32309
  const tid = useTestIds(props, "navbar");
32054
- const [isOpen2, setIsOpen] = useState65(false);
32055
- const [level, setLevel] = useState65("sub");
32310
+ const [isOpen2, setIsOpen] = useState66(false);
32311
+ const [level, setLevel] = useState66("sub");
32056
32312
  const {
32057
32313
  pathname,
32058
32314
  search
@@ -32211,11 +32467,11 @@ function NavbarMobileDrawer({
32211
32467
  }
32212
32468
 
32213
32469
  // src/hooks/useContentOverflow.ts
32214
- import { useCallback as useCallback44, useLayoutEffect as useLayoutEffect17, useRef as useRef76, useState as useState66 } from "react";
32470
+ import { useCallback as useCallback44, useLayoutEffect as useLayoutEffect18, useRef as useRef77, useState as useState67 } from "react";
32215
32471
  function useContentOverflow(enabled = true) {
32216
- const containerRef = useRef76(null);
32217
- const contentRef = useRef76(null);
32218
- const [overflows, setOverflows] = useState66(false);
32472
+ const containerRef = useRef77(null);
32473
+ const contentRef = useRef77(null);
32474
+ const [overflows, setOverflows] = useState67(false);
32219
32475
  const checkContentOverflow = useCallback44(() => {
32220
32476
  const container = containerRef.current;
32221
32477
  const content2 = contentRef.current;
@@ -32225,7 +32481,7 @@ function useContentOverflow(enabled = true) {
32225
32481
  }
32226
32482
  setOverflows(content2.offsetWidth > container.clientWidth);
32227
32483
  }, [enabled]);
32228
- useLayoutEffect17(() => {
32484
+ useLayoutEffect18(() => {
32229
32485
  checkContentOverflow();
32230
32486
  window.addEventListener("resize", checkContentOverflow);
32231
32487
  return () => window.removeEventListener("resize", checkContentOverflow);
@@ -32411,7 +32667,7 @@ function simpleDataRows(data = []) {
32411
32667
 
32412
32668
  // src/components/Tabs.tsx
32413
32669
  import { camelCase as camelCase8 } from "change-case";
32414
- import { useEffect as useEffect41, useMemo as useMemo61, useRef as useRef77, useState as useState67 } from "react";
32670
+ import { useEffect as useEffect41, useMemo as useMemo61, useRef as useRef78, useState as useState68 } from "react";
32415
32671
  import { mergeProps as mergeProps42, useFocusRing as useFocusRing22, useHover as useHover27 } from "react-aria";
32416
32672
  import { matchPath } from "react-router";
32417
32673
  import { Link as Link7, useLocation as useLocation2 } from "react-router-dom";
@@ -32491,8 +32747,8 @@ function Tabs(props) {
32491
32747
  focusProps
32492
32748
  } = useFocusRing22();
32493
32749
  const tid = useTestIds(others, "tabs");
32494
- const [active, setActive] = useState67(selected);
32495
- const ref = useRef77(null);
32750
+ const [active, setActive] = useState68(selected);
32751
+ const ref = useRef78(null);
32496
32752
  useEffect41(() => setActive(selected), [selected]);
32497
32753
  function onKeyUp(e) {
32498
32754
  if (e.key === "ArrowLeft" || e.key === "ArrowRight") {
@@ -33003,7 +33259,7 @@ import { useCheckboxGroupState as useCheckboxGroupState4, useRadioGroupState as
33003
33259
  import { trussProps as trussProps151, maybeCssVar as maybeCssVar71 } from "@homebound/truss/runtime";
33004
33260
 
33005
33261
  // src/forms/FormSection/FormSectionChild.tsx
33006
- import { useRef as useRef78 } from "react";
33262
+ import { useRef as useRef79 } from "react";
33007
33263
  import { mergeProps as mergeProps46, useCheckboxGroupItem as useCheckboxGroupItem4, useFocusRing as useFocusRing23, useRadio as useRadio3, VisuallyHidden as VisuallyHidden11 } from "react-aria";
33008
33264
  import { trussProps as trussProps150 } from "@homebound/truss/runtime";
33009
33265
  import { Fragment as Fragment56, jsx as jsx260, jsxs as jsxs141 } from "react/jsx-runtime";
@@ -33020,7 +33276,7 @@ function FormSectionChild(props) {
33020
33276
  group
33021
33277
  } = props;
33022
33278
  const tid = useTestIds(props, "formSectionChild");
33023
- const itemRef = useRef78(null);
33279
+ const itemRef = useRef79(null);
33024
33280
  const isDraggable = !!orderField;
33025
33281
  const {
33026
33282
  dragItemProps,
@@ -33062,7 +33318,7 @@ function FormSectionChildRadio(props) {
33062
33318
  value,
33063
33319
  label
33064
33320
  } = props;
33065
- const ref = useRef78(null);
33321
+ const ref = useRef79(null);
33066
33322
  const {
33067
33323
  inputProps,
33068
33324
  isDisabled,
@@ -33088,7 +33344,7 @@ function FormSectionChildCheckbox(props) {
33088
33344
  value,
33089
33345
  label
33090
33346
  } = props;
33091
- const ref = useRef78(null);
33347
+ const ref = useRef79(null);
33092
33348
  const {
33093
33349
  inputProps,
33094
33350
  isDisabled,
@@ -33281,12 +33537,12 @@ var railAndShellPx = centeredShellMaxPx.sm + jumpLinksRailWidthPx;
33281
33537
  var jumpLinksRailReservation = `clamp(0px, 100% - ${railAndShellPx}px, ${jumpLinksRailWidthPx}px)`;
33282
33538
 
33283
33539
  // src/layouts/FormSectionLayout/useActiveJumpLink.ts
33284
- import { useLayoutEffect as useLayoutEffect18, useState as useState68 } from "react";
33540
+ import { useLayoutEffect as useLayoutEffect19, useState as useState69 } from "react";
33285
33541
  var activationLeadPx = 120;
33286
33542
  function useActiveJumpLink(sectionIds) {
33287
33543
  const idsKey = sectionIds.join("\0");
33288
- const [activeId, setActiveId] = useState68(sectionIds[0]);
33289
- useLayoutEffect18(() => {
33544
+ const [activeId, setActiveId] = useState69(sectionIds[0]);
33545
+ useLayoutEffect19(() => {
33290
33546
  const ids = idsKey.length === 0 ? [] : idsKey.split("\0");
33291
33547
  if (ids.length === 0) return;
33292
33548
  const update = () => {
@@ -33387,7 +33643,7 @@ function FormSectionLayout(props) {
33387
33643
  }
33388
33644
 
33389
33645
  // src/layouts/PageBanner/usePageBanner.tsx
33390
- import { useEffect as useEffect42, useId as useId5, useLayoutEffect as useLayoutEffect19 } from "react";
33646
+ import { useEffect as useEffect42, useId as useId5, useLayoutEffect as useLayoutEffect20 } from "react";
33391
33647
 
33392
33648
  // src/layouts/PageBanner/pageBannerStore.ts
33393
33649
  var current;
@@ -33425,7 +33681,7 @@ function clearPageBanner(id) {
33425
33681
  // src/layouts/PageBanner/usePageBanner.tsx
33426
33682
  function usePageBanner(banner) {
33427
33683
  const id = useId5();
33428
- useLayoutEffect19(() => {
33684
+ useLayoutEffect20(() => {
33429
33685
  if (!banner) return;
33430
33686
  setPageBanner(id, banner);
33431
33687
  return () => clearPageBanner(id);
@@ -33444,87 +33700,6 @@ function PageBanner(props) {
33444
33700
  import { useMemo as useMemo62, useRef as useRef80 } from "react";
33445
33701
  import { mergeProps as mergeProps47, maybeCssVar as maybeCssVar74 } from "@homebound/truss/runtime";
33446
33702
 
33447
- // src/layouts/useAutoHideOnScroll.ts
33448
- import { useLayoutEffect as useLayoutEffect20, useRef as useRef79, useState as useState69 } from "react";
33449
- var THRESHOLD = 80;
33450
- function getInitialAutoHideState() {
33451
- if (typeof window === "undefined" || window.scrollY <= 0) {
33452
- return "resting";
33453
- }
33454
- return "hidden";
33455
- }
33456
- function useAutoHideOnScroll(spacerRef, enabled, getTopOffset) {
33457
- const initial = getInitialAutoHideState();
33458
- const [state, setState] = useState69(initial);
33459
- const stateRef = useRef79(initial);
33460
- const getTopOffsetRef = useRef79(getTopOffset);
33461
- getTopOffsetRef.current = getTopOffset;
33462
- const lastScrollY = useRef79(Number.POSITIVE_INFINITY);
33463
- const lastScrollHeight = useRef79(0);
33464
- useLayoutEffect20(() => {
33465
- if (!enabled) {
33466
- stateRef.current = "resting";
33467
- lastScrollY.current = Number.POSITIVE_INFINITY;
33468
- lastScrollHeight.current = 0;
33469
- setState("resting");
33470
- return;
33471
- }
33472
- const commit = (nextState) => {
33473
- if (nextState !== stateRef.current) {
33474
- stateRef.current = nextState;
33475
- setState(nextState);
33476
- }
33477
- };
33478
- const autoHideStateOnLayoutChange = (rect, topOffset) => {
33479
- const nextAtTop = rect.top >= topOffset;
33480
- let next = stateRef.current;
33481
- if (nextAtTop) {
33482
- next = "resting";
33483
- } else if (rect.bottom < -THRESHOLD && next !== "revealed") {
33484
- next = "hidden";
33485
- }
33486
- return next;
33487
- };
33488
- const updateAutoHideState = () => {
33489
- const el = spacerRef.current;
33490
- if (!el) return;
33491
- const doc = document.documentElement;
33492
- const currentScrollHeight = doc.scrollHeight;
33493
- const scrollHeightChanged = lastScrollHeight.current !== 0 && currentScrollHeight !== lastScrollHeight.current;
33494
- lastScrollHeight.current = currentScrollHeight;
33495
- if (window.scrollY <= 0) {
33496
- lastScrollY.current = 0;
33497
- commit("resting");
33498
- return;
33499
- }
33500
- const currentY = window.scrollY;
33501
- const rect = el.getBoundingClientRect();
33502
- const topOffset = getTopOffsetRef.current?.() ?? 0;
33503
- if (scrollHeightChanged) {
33504
- lastScrollY.current = currentY;
33505
- commit(autoHideStateOnLayoutChange(rect, topOffset));
33506
- return;
33507
- }
33508
- const dy = currentY - lastScrollY.current;
33509
- lastScrollY.current = currentY;
33510
- const atBottom = currentY >= doc.scrollHeight - doc.clientHeight;
33511
- const nextAtTop = rect.top >= topOffset;
33512
- let next = stateRef.current;
33513
- if (nextAtTop) {
33514
- next = "resting";
33515
- } else if (rect.bottom < -THRESHOLD) {
33516
- if (dy < 0 && !atBottom) next = "revealed";
33517
- else if (dy > 0) next = "hidden";
33518
- }
33519
- commit(next);
33520
- };
33521
- updateAutoHideState();
33522
- window.addEventListener("scroll", updateAutoHideState, { passive: true });
33523
- return () => window.removeEventListener("scroll", updateAutoHideState);
33524
- }, [enabled, spacerRef]);
33525
- return { state };
33526
- }
33527
-
33528
33703
  // src/layouts/useMeasuredHeight.ts
33529
33704
  import { useResizeObserver as useResizeObserver15 } from "@react-aria/utils";
33530
33705
  import { useCallback as useCallback47, useLayoutEffect as useLayoutEffect21, useState as useState70 } from "react";