@homebound/beam 4.45.1 → 4.46.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.d.cts CHANGED
@@ -5888,6 +5888,8 @@ declare class RowState<R extends Kinded> {
5888
5888
  get isSelected(): boolean;
5889
5889
  /** This row's share of `TableState.selectedLeafRowCount`, see `GridDataRow.childrenCount`. */
5890
5890
  get selectedLeafRowCount(): number;
5891
+ /** Whether a checked ancestor's `childrenCount` already includes this row. */
5892
+ private get isCountedByParent();
5891
5893
  /** The UI state for checked/unchecked + "partially checked" for parents. */
5892
5894
  get selectedState(): SelectedState;
5893
5895
  /**
@@ -6035,7 +6037,7 @@ type GridDataRow<R extends Kinded> = {
6035
6037
  selectable?: false;
6036
6038
  /** Whether this row should infer its selected state based on its children's selected state */
6037
6039
  inferSelectedState?: false;
6038
- /** Total children, e.g. when they load lazily; a selected row counts as this many in `getSelectedLeafRowCount`. */
6040
+ /** Total children, e.g. when they load lazily; a checked row counts as this many in `getSelectedLeafRowCount`. */
6039
6041
  childrenCount?: number;
6040
6042
  /** Whether this row is draggable, usually to allow drag & drop reordering of rows */
6041
6043
  draggable?: boolean;
@@ -9712,6 +9714,8 @@ type RightPanePanelProps = {
9712
9714
  children: ReactNode;
9713
9715
  /** Type or status tag on the close-button row; the title moves to its own row below. */
9714
9716
  tag?: RightPaneTag;
9717
+ /** When it returns true, closing the pane or opening content with another type or `key` asks to discard changes first. */
9718
+ isDirty?: () => boolean;
9715
9719
  /** When false, omit the built-in close control (caller provides their own). Default true. */
9716
9720
  withClose?: boolean;
9717
9721
  /** Variant defaults to primary */
@@ -9757,9 +9761,9 @@ type RightPaneOpenState = RightPaneOpenActions & {
9757
9761
  isRightPaneOpen: boolean;
9758
9762
  };
9759
9763
  type UseRightPaneHook = {
9760
- /** Opens a right pane */
9764
+ /** Opens a right pane; asks first if the open panel is dirty and the new content would replace it. */
9761
9765
  openRightPane: (opts: OpenRightPaneOpts) => void;
9762
- /** Closes the right pane */
9766
+ /** Closes the right pane; asks first if the open panel is dirty. */
9763
9767
  closeRightPane: () => void;
9764
9768
  /** Whether the right pane is currently open. */
9765
9769
  isRightPaneOpen: boolean;
package/dist/index.d.ts CHANGED
@@ -5888,6 +5888,8 @@ declare class RowState<R extends Kinded> {
5888
5888
  get isSelected(): boolean;
5889
5889
  /** This row's share of `TableState.selectedLeafRowCount`, see `GridDataRow.childrenCount`. */
5890
5890
  get selectedLeafRowCount(): number;
5891
+ /** Whether a checked ancestor's `childrenCount` already includes this row. */
5892
+ private get isCountedByParent();
5891
5893
  /** The UI state for checked/unchecked + "partially checked" for parents. */
5892
5894
  get selectedState(): SelectedState;
5893
5895
  /**
@@ -6035,7 +6037,7 @@ type GridDataRow<R extends Kinded> = {
6035
6037
  selectable?: false;
6036
6038
  /** Whether this row should infer its selected state based on its children's selected state */
6037
6039
  inferSelectedState?: false;
6038
- /** Total children, e.g. when they load lazily; a selected row counts as this many in `getSelectedLeafRowCount`. */
6040
+ /** Total children, e.g. when they load lazily; a checked row counts as this many in `getSelectedLeafRowCount`. */
6039
6041
  childrenCount?: number;
6040
6042
  /** Whether this row is draggable, usually to allow drag & drop reordering of rows */
6041
6043
  draggable?: boolean;
@@ -9712,6 +9714,8 @@ type RightPanePanelProps = {
9712
9714
  children: ReactNode;
9713
9715
  /** Type or status tag on the close-button row; the title moves to its own row below. */
9714
9716
  tag?: RightPaneTag;
9717
+ /** When it returns true, closing the pane or opening content with another type or `key` asks to discard changes first. */
9718
+ isDirty?: () => boolean;
9715
9719
  /** When false, omit the built-in close control (caller provides their own). Default true. */
9716
9720
  withClose?: boolean;
9717
9721
  /** Variant defaults to primary */
@@ -9757,9 +9761,9 @@ type RightPaneOpenState = RightPaneOpenActions & {
9757
9761
  isRightPaneOpen: boolean;
9758
9762
  };
9759
9763
  type UseRightPaneHook = {
9760
- /** Opens a right pane */
9764
+ /** Opens a right pane; asks first if the open panel is dirty and the new content would replace it. */
9761
9765
  openRightPane: (opts: OpenRightPaneOpts) => void;
9762
- /** Closes the right pane */
9766
+ /** Closes the right pane; asks first if the open panel is dirty. */
9763
9767
  closeRightPane: () => void;
9764
9768
  /** Whether the right pane is currently open. */
9765
9769
  isRightPaneOpen: boolean;
package/dist/index.js CHANGED
@@ -8035,9 +8035,18 @@ var RowState = class {
8035
8035
  }
8036
8036
  /** This row's share of `TableState.selectedLeafRowCount`, see `GridDataRow.childrenCount`. */
8037
8037
  get selectedLeafRowCount() {
8038
- if (this.isReservedKind || !this.selected) return 0;
8038
+ if (this.isReservedKind) return 0;
8039
+ const { childrenCount } = this.row;
8040
+ if (childrenCount !== void 0 && this.isSelected) return this.isCountedByParent ? 0 : childrenCount;
8041
+ if (!this.selected) return 0;
8039
8042
  if (this.children?.some((c) => c.row.selectable !== false)) return 0;
8040
- return this.row.childrenCount ?? 1;
8043
+ return this.isCountedByParent ? 0 : 1;
8044
+ }
8045
+ /** Whether a checked ancestor's `childrenCount` already includes this row. */
8046
+ get isCountedByParent() {
8047
+ const { parent } = this;
8048
+ if (!parent || this.removed) return false;
8049
+ return parent.row.childrenCount !== void 0 && parent.isSelected || parent.isCountedByParent;
8041
8050
  }
8042
8051
  /** The UI state for checked/unchecked + "partially checked" for parents. */
8043
8052
  get selectedState() {
@@ -26854,8 +26863,10 @@ function useScrollPinnedViewportBounds(anchorRef, enabled, getPinTopPx) {
26854
26863
  import { useSyncExternalStore } from "react";
26855
26864
 
26856
26865
  // src/components/Layout/RightPaneLayout/rightPaneStore.ts
26866
+ import { isValidElement as isValidElement2 } from "react";
26857
26867
  var isOpen = false;
26858
26868
  var content;
26869
+ var discardPrompt;
26859
26870
  var openListeners = /* @__PURE__ */ new Set();
26860
26871
  var contentListeners = /* @__PURE__ */ new Set();
26861
26872
  var rightPaneOpenStore = {
@@ -26879,6 +26890,17 @@ function notifyContentListeners() {
26879
26890
  contentListeners.forEach((listener) => listener());
26880
26891
  }
26881
26892
  function openInPane(opts) {
26893
+ if (isOpen && wouldRemount(content, opts.content)) return confirmDiscard(() => showInPane(opts));
26894
+ if (isOpen && discardPrompt) warnIfUnkeyed(opts.content);
26895
+ showInPane(opts);
26896
+ }
26897
+ function warnIfUnkeyed(next) {
26898
+ if (process.env.NODE_ENV === "production" || !isValidElement2(next) || next.key !== null) return;
26899
+ console.warn(
26900
+ "[openRightPane] Opened unkeyed content of the same type over a panel with `isDirty`, so it didn't ask and that panel's edits carry over. Key pane content per item, e.g. `<Panel key={id} />`."
26901
+ );
26902
+ }
26903
+ function showInPane(opts) {
26882
26904
  content = opts.content;
26883
26905
  notifyContentListeners();
26884
26906
  if (isOpen) return;
@@ -26886,9 +26908,14 @@ function openInPane(opts) {
26886
26908
  notifyOpenListeners();
26887
26909
  }
26888
26910
  function closePane() {
26889
- if (!isOpen) return;
26890
- isOpen = false;
26891
- notifyOpenListeners();
26911
+ if (isOpen) confirmDiscard(hideRightPane);
26912
+ }
26913
+ function confirmDiscard(proceed) {
26914
+ if (discardPrompt) discardPrompt(proceed);
26915
+ else proceed();
26916
+ }
26917
+ function wouldRemount(prev, next) {
26918
+ return !isValidElement2(prev) || !isValidElement2(next) || prev.type !== next.type || prev.key !== next.key;
26892
26919
  }
26893
26920
  function clearPane() {
26894
26921
  content = void 0;
@@ -26899,9 +26926,28 @@ var rightPaneOpenActions = {
26899
26926
  closePane,
26900
26927
  clearPane
26901
26928
  };
26929
+ function setRightPaneDiscardPrompt(fn) {
26930
+ discardPrompt = fn;
26931
+ return () => {
26932
+ if (discardPrompt === fn) discardPrompt = void 0;
26933
+ };
26934
+ }
26935
+ function closeRightPaneThen(next) {
26936
+ if (!isOpen) return next();
26937
+ confirmDiscard(() => {
26938
+ hideRightPane();
26939
+ next();
26940
+ });
26941
+ }
26942
+ function hideRightPane() {
26943
+ if (!isOpen) return;
26944
+ isOpen = false;
26945
+ notifyOpenListeners();
26946
+ }
26902
26947
  function resetRightPaneStore() {
26903
26948
  isOpen = false;
26904
26949
  content = void 0;
26950
+ discardPrompt = void 0;
26905
26951
  notifyOpenListeners();
26906
26952
  notifyContentListeners();
26907
26953
  }
@@ -27109,17 +27155,13 @@ function DocumentScrollRightPaneLayoutRoot(props) {
27109
27155
  // src/components/Layout/RightPaneLayout/useDocumentScrollRightPaneAnchorRef.ts
27110
27156
  import { useCallback as useCallback30, useRef as useRef61 } from "react";
27111
27157
  function useDocumentScrollRightPaneAnchorRef() {
27112
- const { closePane: closePane2 } = useRightPaneOpenActions();
27113
27158
  const ref = useRef61(null);
27114
- const setRef = useCallback30(
27115
- (node) => {
27116
- if (!node && ref.current) {
27117
- closePane2();
27118
- }
27119
- ref.current = node;
27120
- },
27121
- [closePane2]
27122
- );
27159
+ const setRef = useCallback30((node) => {
27160
+ if (!node && ref.current) {
27161
+ hideRightPane();
27162
+ }
27163
+ ref.current = node;
27164
+ }, []);
27123
27165
  return { ref, setRef };
27124
27166
  }
27125
27167
 
@@ -27844,11 +27886,10 @@ function RightPaneLayout(props) {
27844
27886
  } = props;
27845
27887
  const {
27846
27888
  isRightPaneOpen,
27847
- clearPane: clearPane2,
27848
- closePane: closePane2
27889
+ clearPane: clearPane2
27849
27890
  } = useRightPaneOpenState();
27850
27891
  const rightPaneContent = useRightPaneContent();
27851
- useEffect30(() => closePane2, [closePane2]);
27892
+ useEffect30(() => hideRightPane, []);
27852
27893
  return /* @__PURE__ */ jsx206("div", { className: "h100 df oxh", children: /* @__PURE__ */ jsxs107(Fragment45, { children: [
27853
27894
  /* @__PURE__ */ jsx206("div", { ...trussProps116({
27854
27895
  ...{
@@ -27938,7 +27979,7 @@ function RightPaneLayout(props) {
27938
27979
  }
27939
27980
 
27940
27981
  // src/components/Layout/RightPaneLayout/RightPanePanel.tsx
27941
- import { createContext as createContext14, useContext as useContext24, useState as useState55 } from "react";
27982
+ import { createContext as createContext14, useContext as useContext24, useEffect as useEffect31, useState as useState55 } from "react";
27942
27983
  import { createPortal as createPortal8 } from "react-dom";
27943
27984
 
27944
27985
  // src/components/Layout/RightPaneLayout/internal/DeleteAction.tsx
@@ -28019,6 +28060,7 @@ function RightPanePanel(props) {
28019
28060
  title,
28020
28061
  children,
28021
28062
  tag,
28063
+ isDirty,
28022
28064
  withClose = true,
28023
28065
  primaryAction,
28024
28066
  secondaryAction,
@@ -28029,6 +28071,18 @@ function RightPanePanel(props) {
28029
28071
  closeRightPane
28030
28072
  } = useRightPaneActions();
28031
28073
  const [bannerSlot, setBannerSlot] = useState55(null);
28074
+ const {
28075
+ openModal
28076
+ } = useModal();
28077
+ useEffect31(() => {
28078
+ if (!isDirty) return;
28079
+ return setRightPaneDiscardPrompt((proceed) => {
28080
+ if (!isDirty()) return proceed();
28081
+ openModal({
28082
+ content: /* @__PURE__ */ jsx208(ConfirmCloseModal, { title: "Discard unsaved changes?", onClose: proceed })
28083
+ });
28084
+ });
28085
+ }, [isDirty, openModal]);
28032
28086
  const tagEl = tag && (tag.kind === "status" ? /* @__PURE__ */ jsx208(Tag, { ...tag, ...tid.tag }) : /* @__PURE__ */ jsx208(ContextTag, { ...tag, ...tid.tag }));
28033
28087
  const titleEl = /* @__PURE__ */ jsx208("div", { className: "fw6 fz_16px lh_24px oh d_negwebkit_box wbo_vertical to_ellipsis wlc_2", ...tid.title, children: title });
28034
28088
  const closeEl = withClose && /* @__PURE__ */ jsx208(IconButton, { icon: "x", label: "Close", autoFocus: true, onClick: closeRightPane, ...tid.close });
@@ -28103,7 +28157,7 @@ function ScrollableFooter(props) {
28103
28157
 
28104
28158
  // src/components/Layout/TableReviewLayout/TableReviewLayout.tsx
28105
28159
  import { AnimatePresence as AnimatePresence5, motion as motion5 } from "framer-motion";
28106
- import { useEffect as useEffect31, useState as useState56 } from "react";
28160
+ import { useEffect as useEffect32, useState as useState56 } from "react";
28107
28161
 
28108
28162
  // src/components/Layout/TableReviewLayout/SidePanel.tsx
28109
28163
  import { jsx as jsx210, jsxs as jsxs110 } from "react/jsx-runtime";
@@ -28144,7 +28198,7 @@ function TableReviewLayout(props) {
28144
28198
  } = props;
28145
28199
  const tid = useTestIds(props, "tableReviewLayout");
28146
28200
  const [isPanelVisible, setIsPanelVisible] = useState56(!!panelContent);
28147
- useEffect31(() => {
28201
+ useEffect32(() => {
28148
28202
  setIsPanelVisible(!!panelContent);
28149
28203
  }, [panelContent]);
28150
28204
  function handleClosePanel() {
@@ -28304,7 +28358,7 @@ function HomeboundLogo(props) {
28304
28358
 
28305
28359
  // src/components/MaxLines.tsx
28306
28360
  import { useLayoutEffect as useLayoutEffect14, useResizeObserver as useResizeObserver10 } from "@react-aria/utils";
28307
- import { useCallback as useCallback36, useEffect as useEffect32, useRef as useRef67, useState as useState57 } from "react";
28361
+ import { useCallback as useCallback36, useEffect as useEffect33, useRef as useRef67, useState as useState57 } from "react";
28308
28362
  import { trussProps as trussProps122, maybeCssVar as maybeCssVar57 } from "@homebound/truss/runtime";
28309
28363
  import { jsx as jsx214, jsxs as jsxs113 } from "react/jsx-runtime";
28310
28364
  function MaxLines({
@@ -28318,7 +28372,7 @@ function MaxLines({
28318
28372
  if (!elRef.current) return;
28319
28373
  setHasMore(elRef.current.scrollHeight > elRef.current.clientHeight);
28320
28374
  }, []);
28321
- useEffect32(() => {
28375
+ useEffect33(() => {
28322
28376
  setExpanded(false);
28323
28377
  }, [children]);
28324
28378
  const onResize = useCallback36(() => {
@@ -28577,7 +28631,7 @@ import { camelCase as camelCase7 } from "change-case";
28577
28631
  // src/components/AppNav/AppNavGroup.tsx
28578
28632
  import { useResizeObserver as useResizeObserver12 } from "@react-aria/utils";
28579
28633
  import { camelCase as camelCase6, kebabCase } from "change-case";
28580
- import { useCallback as useCallback39, useEffect as useEffect33, useMemo as useMemo52, useState as useState60 } from "react";
28634
+ import { useCallback as useCallback39, useEffect as useEffect34, useMemo as useMemo52, useState as useState60 } from "react";
28581
28635
 
28582
28636
  // src/components/AppNav/AppNavGroupTrigger.tsx
28583
28637
  import { useMemo as useMemo51, useRef as useRef69 } from "react";
@@ -28817,7 +28871,7 @@ function AppNavGroupDisclosure(props) {
28817
28871
  current: contentEl
28818
28872
  }), [contentEl]);
28819
28873
  const [contentHeight, setContentHeight] = useState60(expanded ? "auto" : "0");
28820
- useEffect33(() => {
28874
+ useEffect34(() => {
28821
28875
  setContentHeight(expanded && contentEl ? `${contentEl.scrollHeight}px` : "0");
28822
28876
  }, [expanded, contentEl]);
28823
28877
  const onResize = useCallback39(() => {
@@ -28970,7 +29024,7 @@ import {
28970
29024
  createContext as createContext15,
28971
29025
  useCallback as useCallback40,
28972
29026
  useContext as useContext25,
28973
- useEffect as useEffect34,
29027
+ useEffect as useEffect35,
28974
29028
  useMemo as useMemo53,
28975
29029
  useRef as useRef70,
28976
29030
  useState as useState61
@@ -29004,7 +29058,7 @@ function SideNavLayoutProvider(props) {
29004
29058
  );
29005
29059
  const bp = useBreakpoint();
29006
29060
  const prevMdAndUp = useRef70(bp.mdAndUp);
29007
- useEffect34(() => {
29061
+ useEffect35(() => {
29008
29062
  if (prevMdAndUp.current && !bp.mdAndUp) {
29009
29063
  setNavStateInternal((prev) => prev === "expanded" ? "collapse" : prev);
29010
29064
  }
@@ -29840,7 +29894,7 @@ function MetricButton(props) {
29840
29894
 
29841
29895
  // src/components/DnDGrid/DnDGrid.tsx
29842
29896
  import equal2 from "fast-deep-equal";
29843
- import { useCallback as useCallback41, useEffect as useEffect35, useRef as useRef74 } from "react";
29897
+ import { useCallback as useCallback41, useEffect as useEffect36, useRef as useRef74 } from "react";
29844
29898
 
29845
29899
  // src/utils/inlineStyles.ts
29846
29900
  function isInlineStyleValue(value) {
@@ -30011,7 +30065,7 @@ function DnDGrid(props) {
30011
30065
  addPointerDragListeners(onMove, onDragEnd);
30012
30066
  }
30013
30067
  }, [initReorder, onMove, onDragEnd]);
30014
- useEffect35(() => {
30068
+ useEffect36(() => {
30015
30069
  return () => removePointerDragListeners(onMove, onDragEnd);
30016
30070
  }, [onMove, onDragEnd]);
30017
30071
  const onDragHandleKeyDown = useCallback41((e) => {
@@ -30768,7 +30822,7 @@ import { mergeProps as mergeProps40 } from "react-aria";
30768
30822
  import { trussProps as trussProps139 } from "@homebound/truss/runtime";
30769
30823
 
30770
30824
  // src/components/Grid/useResponsiveGridItem.ts
30771
- import { useContext as useContext27, useEffect as useEffect36, useMemo as useMemo57 } from "react";
30825
+ import { useContext as useContext27, useEffect as useEffect37, useMemo as useMemo57 } from "react";
30772
30826
  var injectedResponsiveGridClasses = /* @__PURE__ */ new Set();
30773
30827
  var responsiveGridStyleEl;
30774
30828
  function useResponsiveGridItem(props) {
@@ -30798,7 +30852,7 @@ function useResponsiveGridItem(props) {
30798
30852
  };
30799
30853
  }
30800
30854
  function useResponsiveGridItemStyle(className, cssText) {
30801
- useEffect36(
30855
+ useEffect37(
30802
30856
  function() {
30803
30857
  if (!className || !cssText || typeof document === "undefined") return;
30804
30858
  if (!responsiveGridStyleEl) {
@@ -30897,12 +30951,12 @@ function HbSpinnerProvider({
30897
30951
  }
30898
30952
 
30899
30953
  // src/components/Modal/OpenModal.tsx
30900
- import { useEffect as useEffect37 } from "react";
30954
+ import { useEffect as useEffect38 } from "react";
30901
30955
  import { jsx as jsx246 } from "react/jsx-runtime";
30902
30956
  function OpenModal(props) {
30903
30957
  const { openModal } = useModal();
30904
30958
  const { size, children, keepOpen, aiMode } = props;
30905
- useEffect37(() => {
30959
+ useEffect38(() => {
30906
30960
  if (!keepOpen) {
30907
30961
  openModal({ size, content: children, aiMode });
30908
30962
  }
@@ -30916,7 +30970,7 @@ function OpenModal(props) {
30916
30970
 
30917
30971
  // src/components/Navbar/NavbarMobileMenu.tsx
30918
30972
  import { AnimatePresence as AnimatePresence6, motion as motion7 } from "framer-motion";
30919
- import { useEffect as useEffect38, useState as useState63 } from "react";
30973
+ import { useEffect as useEffect39, useState as useState63 } from "react";
30920
30974
  import { FocusScope as FocusScope7, usePreventScroll as usePreventScroll4 } from "react-aria";
30921
30975
  import { createPortal as createPortal11 } from "react-dom";
30922
30976
  import { useLocation } from "react-router-dom";
@@ -30968,7 +31022,7 @@ function NavbarMobileMenu(props) {
30968
31022
  isDisabled: !isOpen2
30969
31023
  });
30970
31024
  const close = () => setIsOpen(false);
30971
- useEffect38(() => {
31025
+ useEffect39(() => {
30972
31026
  close();
30973
31027
  }, [pathname, search]);
30974
31028
  return /* @__PURE__ */ jsxs131(Fragment54, { children: [
@@ -31218,7 +31272,7 @@ function NavbarUserMenu({
31218
31272
  }
31219
31273
 
31220
31274
  // src/components/Snackbar/useSnackbar.tsx
31221
- import { useCallback as useCallback43, useEffect as useEffect39 } from "react";
31275
+ import { useCallback as useCallback43, useEffect as useEffect40 } from "react";
31222
31276
  function useSnackbar() {
31223
31277
  const { setNotices, setOffset } = useSnackbarContext();
31224
31278
  const onClose = useCallback43(
@@ -31268,7 +31322,7 @@ function useSnackbar() {
31268
31322
  [onClose, setNotices]
31269
31323
  );
31270
31324
  const closeNotice = useCallback43((id) => onClose(id), [onClose]);
31271
- const useSnackbarOffset = ({ bottom }) => useEffect39(() => {
31325
+ const useSnackbarOffset = ({ bottom }) => useEffect40(() => {
31272
31326
  setOffset({ bottom });
31273
31327
  return () => setOffset({});
31274
31328
  }, [bottom]);
@@ -31317,7 +31371,7 @@ function simpleDataRows(data = []) {
31317
31371
 
31318
31372
  // src/components/Tabs.tsx
31319
31373
  import { camelCase as camelCase8 } from "change-case";
31320
- import { useEffect as useEffect40, useMemo as useMemo60, useRef as useRef76, useState as useState65 } from "react";
31374
+ import { useEffect as useEffect41, useMemo as useMemo60, useRef as useRef76, useState as useState65 } from "react";
31321
31375
  import { mergeProps as mergeProps42, useFocusRing as useFocusRing22, useHover as useHover27 } from "react-aria";
31322
31376
  import { matchPath } from "react-router";
31323
31377
  import { Link as Link7, useLocation as useLocation2 } from "react-router-dom";
@@ -31399,7 +31453,7 @@ function Tabs(props) {
31399
31453
  const tid = useTestIds(others, "tabs");
31400
31454
  const [active, setActive] = useState65(selected);
31401
31455
  const ref = useRef76(null);
31402
- useEffect40(() => setActive(selected), [selected]);
31456
+ useEffect41(() => setActive(selected), [selected]);
31403
31457
  function onKeyUp(e) {
31404
31458
  if (e.key === "ArrowLeft" || e.key === "ArrowRight") {
31405
31459
  const nextTabValue = getNextTabValue(active, e.key, tabs);
@@ -32267,7 +32321,7 @@ function FormSectionLayout(props) {
32267
32321
  }
32268
32322
 
32269
32323
  // src/layouts/PageBanner/usePageBanner.tsx
32270
- import { useEffect as useEffect41, useId as useId5, useLayoutEffect as useLayoutEffect18 } from "react";
32324
+ import { useEffect as useEffect42, useId as useId5, useLayoutEffect as useLayoutEffect18 } from "react";
32271
32325
 
32272
32326
  // src/layouts/PageBanner/pageBannerStore.ts
32273
32327
  var current;
@@ -32310,7 +32364,7 @@ function usePageBanner(banner) {
32310
32364
  setPageBanner(id, banner);
32311
32365
  return () => clearPageBanner(id);
32312
32366
  }, [id, banner]);
32313
- useEffect41(() => {
32367
+ useEffect42(() => {
32314
32368
  if (!banner || hasPageBannerSubscriber() || process.env.NODE_ENV === "production") return;
32315
32369
  console.warn("[usePageBanner] No page layout above this component; the banner will not render.");
32316
32370
  }, [banner]);
@@ -32830,7 +32884,7 @@ function WorkflowPageRightPaneTriggers(props) {
32830
32884
  }
32831
32885
 
32832
32886
  // src/layouts/Workflow/useUnsavedChangesGuard.tsx
32833
- import { useEffect as useEffect42, useRef as useRef82 } from "react";
32887
+ import { useEffect as useEffect43, useRef as useRef82 } from "react";
32834
32888
  import { useBlocker } from "react-router-dom";
32835
32889
  import { jsx as jsx268 } from "react/jsx-runtime";
32836
32890
  function useUnsavedChangesGuard(options) {
@@ -32841,7 +32895,7 @@ function useUnsavedChangesGuard(options) {
32841
32895
  const allowNavigationRef = useRef82(allowNavigation);
32842
32896
  allowNavigationRef.current = allowNavigation;
32843
32897
  const allowCancelNavigationRef = useRef82(false);
32844
- useEffect42(() => {
32898
+ useEffect43(() => {
32845
32899
  const onBeforeUnload = (e) => {
32846
32900
  if (isDirtyRef.current?.()) {
32847
32901
  e.preventDefault();
@@ -32908,7 +32962,7 @@ function useUnsavedChangesGuard(options) {
32908
32962
  function UnsavedChangesNavigationModal(props) {
32909
32963
  const { proceed, cancelNavigation } = props;
32910
32964
  const { openModal, closeModal } = useModal();
32911
- useEffect42(() => {
32965
+ useEffect43(() => {
32912
32966
  openModal({
32913
32967
  allowClosing: false,
32914
32968
  content: /* @__PURE__ */ jsx268(ConfirmCloseModal, { title: "Leave page?", onClose: proceed, onContinue: cancelNavigation })
@@ -33166,15 +33220,13 @@ function StepperLayout(props) {
33166
33220
  const stepTabs = steps.map((step) => ({ ...step, value: defaultTestId(step.label) }));
33167
33221
  const [currentStep, setCurrentStep] = useState70(() => getInitialStep(stepTabs, defaultStep));
33168
33222
  const tid = useTestIds(props, "stepperLayout");
33169
- const { closeRightPane } = useRightPaneActions();
33170
33223
  const currentIndex = hasStep(stepTabs, currentStep) ? stepTabs.findIndex((step) => step.value === currentStep) : 0;
33171
33224
  const isFirstStep = currentIndex <= 0;
33172
33225
  const isLastStep = currentIndex >= stepTabs.length - 1;
33173
33226
  const activeStep = stepTabs[currentIndex];
33174
33227
  function goToStep(value) {
33175
33228
  if (value === currentStep) return;
33176
- closeRightPane();
33177
- setCurrentStep(value);
33229
+ closeRightPaneThen(() => setCurrentStep(value));
33178
33230
  }
33179
33231
  return /* @__PURE__ */ jsx272(
33180
33232
  WorkflowPageLayout,