@elliemae/ds-shuttle-v2 3.57.0-next.40 → 3.57.0-next.41

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.
@@ -71,6 +71,9 @@ const PanelContentMiddleSection = import_react.default.memo((panelMetaInfo) => {
71
71
  const itemsLength = (0, import_useStore.usePropsStore)(
72
72
  (state) => isDestinationPanel ? state.destinationData.length : state.sourceData.length
73
73
  );
74
+ const headerProps = (0, import_useStore.usePropsStore)(
75
+ (state) => isDestinationPanel ? state.destinationHeaderProps : state.sourceHeaderProps
76
+ );
74
77
  const itemList = (0, import_useStore.usePropsStore)(
75
78
  (state) => isDestinationPanel ? state.destinationConfiguredData : state.sourceConfiguredData
76
79
  );
@@ -175,7 +178,7 @@ const PanelContentMiddleSection = import_react.default.memo((panelMetaInfo) => {
175
178
  innerRef: innerRefHandlerParentItem,
176
179
  children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_ds_grid.Grid, { cols, rows, children: [
177
180
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_styles.StyledA11yNoVisible, { id: uidDescribedBy, children: defaultAriaDescribedBy }),
178
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ShuttleLoadingAnnouncement.ShuttleLoadingAnnouncement, { isLoading }),
181
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ShuttleLoadingAnnouncement.ShuttleLoadingAnnouncement, { isLoading, headerProps }),
179
182
  isLoading ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_LoadingItems.LoadingItems, { ...panelMetaInfo }) : null,
180
183
  showEmptyMessage ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_EmptyItems.EmptyItems, { ...panelMetaInfo }) : null,
181
184
  showItems ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_Index.ItemListWrapperWithContext, { ...panelMetaInfo }) : null,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/parts/Panel/middle/PanelContentMiddleSection.tsx", "../../../../../../../../scripts/build/transpile/react-shim.js"],
4
- "sourcesContent": ["/* eslint-disable max-statements */\n/* eslint-disable complexity */\nimport React, { useCallback } from 'react';\nimport { styled } from '@elliemae/ds-system';\nimport { Grid } from '@elliemae/ds-grid';\nimport { useOnSpecificFocus } from './useOnSpecificFocus.js';\nimport { usePropsStore, useInternalStore } from '../../../config/useStore/index.js';\nimport { type DSShuttleV2T } from '../../../react-desc-prop-types.js';\nimport { ItemListWrapperWithContext } from './ItemListWrapper/Index.js';\nimport { EmptyItems } from './EmptyItems.js';\nimport { useFocusTracker } from '../../../config/useFocusTracker/index.js';\nimport { LoadingItems } from './LoadingItems.js';\nimport { MultipleSelectionAction } from './MultipleSelectionAction.js';\nimport { DSShuttleV2Name, REGIONS_FOCUSES, DSShuttleV2Slots } from '../../../constants/index.js';\nimport { StyledA11yNoVisible } from '../../../styles.js';\nimport { ShuttleLoadingAnnouncement } from './ShuttleLoadingAnnouncement.js';\n\nconst useInnerRefHandlers = (isDestinationPanel: boolean) => {\n const setZustandRef = useInternalStore((state) => state.setZustandRef);\n const currRegion = isDestinationPanel ? REGIONS_FOCUSES.DESTINATION_PANEL : REGIONS_FOCUSES.SOURCE_PANEL;\n\n const innerRefHandlerParentItem = React.useCallback(\n (node: HTMLDivElement | null) => {\n setZustandRef([currRegion, '', ''], node);\n },\n [currRegion, setZustandRef],\n );\n return React.useMemo(() => ({ innerRefHandlerParentItem }), [innerRefHandlerParentItem]);\n};\n\nconst rows = [1];\n\nconst StyledListWrapperMid = styled(Grid, { name: DSShuttleV2Name, slot: DSShuttleV2Slots.LIST_WRAPPER_MID })`\n overflow: hidden;\n position: relative;\n :focus,\n :focus-visible {\n outline: 2px solid brand-700;\n }\n`;\n\nexport const PanelContentMiddleSection = React.memo((panelMetaInfo: DSShuttleV2T.PanelMetaInfo) => {\n const { isDestinationPanel = false, hasMultipleSelection } = panelMetaInfo;\n const itemsLength = usePropsStore((state) =>\n isDestinationPanel ? state.destinationData.length : state.sourceData.length,\n );\n\n const itemList = usePropsStore((state) =>\n isDestinationPanel ? state.destinationConfiguredData : state.sourceConfiguredData,\n );\n const isLoading = usePropsStore((state) => (isDestinationPanel ? state.destinationIsLoading : state.sourceIsLoading));\n const showEmptyMessage = !isLoading && itemsLength === 0;\n const showItems = !isLoading && !showEmptyMessage;\n\n const actionRef = usePropsStore((state) =>\n isDestinationPanel ? state.destinationVirtualRef : state.sourceVirtualRef,\n );\n\n const getIsDragAndDropHappening = useInternalStore((state) => state.getIsDragAndDropHappening);\n const withLoadMore = usePropsStore((state) =>\n isDestinationPanel ? state.destinationWithLoadMore : state.sourceWithLoadMore,\n );\n const { innerRefHandlerParentItem } = useInnerRefHandlers(isDestinationPanel);\n const {\n trackFocusRegionPanel,\n trackFocusItemFirst,\n trackFocusItemLast,\n trackFocusActionParent,\n trackFocusRegionPanelItem,\n trackFocusLoadMoreBtnDestination,\n trackFocusLoadMoreBtn,\n } = useFocusTracker();\n const config = React.useMemo(\n () => ({\n onFocus: () => {\n trackFocusRegionPanel(isDestinationPanel);\n },\n }),\n [trackFocusRegionPanel, isDestinationPanel],\n );\n const onPanelFocus = useOnSpecificFocus(config);\n\n const onPanelKeyDown = React.useCallback<React.KeyboardEventHandler<HTMLDivElement>>(\n (e) => {\n const { key } = e;\n // we need to invoke \"getIsDragAndDropHappening\" here to ensure we have the latest info at the moment of the event\n const isDragAndDropHappening = getIsDragAndDropHappening();\n if (isDragAndDropHappening) {\n e.preventDefault();\n return;\n }\n if (['Home', 'End', 'ArrowUp', 'ArrowDown'].includes(key)) {\n e.preventDefault();\n e.stopPropagation();\n trackFocusRegionPanelItem(isDestinationPanel);\n trackFocusActionParent();\n // we won't receive ArrowUp/ArrowDown if this happens in a child because children are stopping propagation\n if ((key === 'ArrowDown' || key === 'Home') && itemList.length > 0) {\n actionRef.current.scrollTo(0);\n trackFocusItemFirst(panelMetaInfo);\n }\n if ((key === 'ArrowUp' || key === 'End') && itemList.length > 0) {\n if (withLoadMore) {\n if (isDestinationPanel) trackFocusLoadMoreBtnDestination();\n else trackFocusLoadMoreBtn();\n } else {\n trackFocusItemLast(panelMetaInfo);\n actionRef.current.scrollTo(itemsLength - 1);\n }\n }\n }\n },\n [\n getIsDragAndDropHappening,\n trackFocusRegionPanelItem,\n isDestinationPanel,\n trackFocusActionParent,\n itemList.length,\n actionRef,\n trackFocusItemFirst,\n panelMetaInfo,\n withLoadMore,\n trackFocusLoadMoreBtnDestination,\n trackFocusLoadMoreBtn,\n trackFocusItemLast,\n itemsLength,\n ],\n );\n\n const cols = React.useMemo(() => {\n if (hasMultipleSelection) return ['1fr', '5rem'];\n return ['auto'];\n }, [hasMultipleSelection]);\n\n const getOwnerProps = usePropsStore((store) => store.get);\n const getOwnerPropsArguments = useCallback(() => panelMetaInfo, [panelMetaInfo]);\n\n const defaultAriaDescribedBy =\n itemList.length > 0\n ? 'Press Up and Down arrow to navigate the options list and Press Right and Left arrow to access items actions'\n : 'No items available in the panel';\n\n const uidDescribedBy = useInternalStore((state) => state.shuttleInternalId);\n\n const defaultAriaLabel = React.useMemo(\n () => `Entering ${isDestinationPanel ? 'destination' : 'source'} panel.`,\n [isDestinationPanel],\n );\n\n return (\n <StyledListWrapperMid\n onFocus={onPanelFocus}\n onKeyDown={onPanelKeyDown}\n role=\"group\"\n tabIndex={0}\n rows={rows}\n aria-label={defaultAriaLabel}\n aria-describedby={uidDescribedBy}\n aria-roledescription={isDestinationPanel ? 'shuttle destination panel' : 'shuttle source panel'}\n getOwnerProps={getOwnerProps}\n getOwnerPropsArguments={getOwnerPropsArguments}\n innerRef={innerRefHandlerParentItem}\n >\n <Grid cols={cols} rows={rows}>\n <StyledA11yNoVisible id={uidDescribedBy}>{defaultAriaDescribedBy}</StyledA11yNoVisible>\n <ShuttleLoadingAnnouncement isLoading={isLoading} />\n {isLoading ? <LoadingItems {...panelMetaInfo} /> : null}\n {showEmptyMessage ? <EmptyItems {...panelMetaInfo} /> : null}\n {showItems ? <ItemListWrapperWithContext {...panelMetaInfo} /> : null}\n {hasMultipleSelection ? <MultipleSelectionAction {...panelMetaInfo} /> : null}\n </Grid>\n </StyledListWrapperMid>\n );\n});\n", "import * as React from 'react';\nexport { React };\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/* eslint-disable max-statements */\n/* eslint-disable complexity */\nimport React, { useCallback } from 'react';\nimport { styled } from '@elliemae/ds-system';\nimport { Grid } from '@elliemae/ds-grid';\nimport { useOnSpecificFocus } from './useOnSpecificFocus.js';\nimport { usePropsStore, useInternalStore } from '../../../config/useStore/index.js';\nimport { type DSShuttleV2T } from '../../../react-desc-prop-types.js';\nimport { ItemListWrapperWithContext } from './ItemListWrapper/Index.js';\nimport { EmptyItems } from './EmptyItems.js';\nimport { useFocusTracker } from '../../../config/useFocusTracker/index.js';\nimport { LoadingItems } from './LoadingItems.js';\nimport { MultipleSelectionAction } from './MultipleSelectionAction.js';\nimport { DSShuttleV2Name, REGIONS_FOCUSES, DSShuttleV2Slots } from '../../../constants/index.js';\nimport { StyledA11yNoVisible } from '../../../styles.js';\nimport { ShuttleLoadingAnnouncement } from './ShuttleLoadingAnnouncement.js';\n\nconst useInnerRefHandlers = (isDestinationPanel: boolean) => {\n const setZustandRef = useInternalStore((state) => state.setZustandRef);\n const currRegion = isDestinationPanel ? REGIONS_FOCUSES.DESTINATION_PANEL : REGIONS_FOCUSES.SOURCE_PANEL;\n\n const innerRefHandlerParentItem = React.useCallback(\n (node: HTMLDivElement | null) => {\n setZustandRef([currRegion, '', ''], node);\n },\n [currRegion, setZustandRef],\n );\n return React.useMemo(() => ({ innerRefHandlerParentItem }), [innerRefHandlerParentItem]);\n};\n\nconst rows = [1];\n\nconst StyledListWrapperMid = styled(Grid, { name: DSShuttleV2Name, slot: DSShuttleV2Slots.LIST_WRAPPER_MID })`\n overflow: hidden;\n position: relative;\n :focus,\n :focus-visible {\n outline: 2px solid brand-700;\n }\n`;\n\nexport const PanelContentMiddleSection = React.memo((panelMetaInfo: DSShuttleV2T.PanelMetaInfo) => {\n const { isDestinationPanel = false, hasMultipleSelection } = panelMetaInfo;\n const itemsLength = usePropsStore((state) =>\n isDestinationPanel ? state.destinationData.length : state.sourceData.length,\n );\n\n const headerProps = usePropsStore((state) =>\n isDestinationPanel ? state.destinationHeaderProps : state.sourceHeaderProps,\n );\n\n const itemList = usePropsStore((state) =>\n isDestinationPanel ? state.destinationConfiguredData : state.sourceConfiguredData,\n );\n const isLoading = usePropsStore((state) => (isDestinationPanel ? state.destinationIsLoading : state.sourceIsLoading));\n const showEmptyMessage = !isLoading && itemsLength === 0;\n const showItems = !isLoading && !showEmptyMessage;\n\n const actionRef = usePropsStore((state) =>\n isDestinationPanel ? state.destinationVirtualRef : state.sourceVirtualRef,\n );\n\n const getIsDragAndDropHappening = useInternalStore((state) => state.getIsDragAndDropHappening);\n const withLoadMore = usePropsStore((state) =>\n isDestinationPanel ? state.destinationWithLoadMore : state.sourceWithLoadMore,\n );\n const { innerRefHandlerParentItem } = useInnerRefHandlers(isDestinationPanel);\n const {\n trackFocusRegionPanel,\n trackFocusItemFirst,\n trackFocusItemLast,\n trackFocusActionParent,\n trackFocusRegionPanelItem,\n trackFocusLoadMoreBtnDestination,\n trackFocusLoadMoreBtn,\n } = useFocusTracker();\n const config = React.useMemo(\n () => ({\n onFocus: () => {\n trackFocusRegionPanel(isDestinationPanel);\n },\n }),\n [trackFocusRegionPanel, isDestinationPanel],\n );\n const onPanelFocus = useOnSpecificFocus(config);\n\n const onPanelKeyDown = React.useCallback<React.KeyboardEventHandler<HTMLDivElement>>(\n (e) => {\n const { key } = e;\n // we need to invoke \"getIsDragAndDropHappening\" here to ensure we have the latest info at the moment of the event\n const isDragAndDropHappening = getIsDragAndDropHappening();\n if (isDragAndDropHappening) {\n e.preventDefault();\n return;\n }\n if (['Home', 'End', 'ArrowUp', 'ArrowDown'].includes(key)) {\n e.preventDefault();\n e.stopPropagation();\n trackFocusRegionPanelItem(isDestinationPanel);\n trackFocusActionParent();\n // we won't receive ArrowUp/ArrowDown if this happens in a child because children are stopping propagation\n if ((key === 'ArrowDown' || key === 'Home') && itemList.length > 0) {\n actionRef.current.scrollTo(0);\n trackFocusItemFirst(panelMetaInfo);\n }\n if ((key === 'ArrowUp' || key === 'End') && itemList.length > 0) {\n if (withLoadMore) {\n if (isDestinationPanel) trackFocusLoadMoreBtnDestination();\n else trackFocusLoadMoreBtn();\n } else {\n trackFocusItemLast(panelMetaInfo);\n actionRef.current.scrollTo(itemsLength - 1);\n }\n }\n }\n },\n [\n getIsDragAndDropHappening,\n trackFocusRegionPanelItem,\n isDestinationPanel,\n trackFocusActionParent,\n itemList.length,\n actionRef,\n trackFocusItemFirst,\n panelMetaInfo,\n withLoadMore,\n trackFocusLoadMoreBtnDestination,\n trackFocusLoadMoreBtn,\n trackFocusItemLast,\n itemsLength,\n ],\n );\n\n const cols = React.useMemo(() => {\n if (hasMultipleSelection) return ['1fr', '5rem'];\n return ['auto'];\n }, [hasMultipleSelection]);\n\n const getOwnerProps = usePropsStore((store) => store.get);\n const getOwnerPropsArguments = useCallback(() => panelMetaInfo, [panelMetaInfo]);\n\n const defaultAriaDescribedBy =\n itemList.length > 0\n ? 'Press Up and Down arrow to navigate the options list and Press Right and Left arrow to access items actions'\n : 'No items available in the panel';\n\n const uidDescribedBy = useInternalStore((state) => state.shuttleInternalId);\n\n const defaultAriaLabel = React.useMemo(\n () => `Entering ${isDestinationPanel ? 'destination' : 'source'} panel.`,\n [isDestinationPanel],\n );\n\n return (\n <StyledListWrapperMid\n onFocus={onPanelFocus}\n onKeyDown={onPanelKeyDown}\n role=\"group\"\n tabIndex={0}\n rows={rows}\n aria-label={defaultAriaLabel}\n aria-describedby={uidDescribedBy}\n aria-roledescription={isDestinationPanel ? 'shuttle destination panel' : 'shuttle source panel'}\n getOwnerProps={getOwnerProps}\n getOwnerPropsArguments={getOwnerPropsArguments}\n innerRef={innerRefHandlerParentItem}\n >\n <Grid cols={cols} rows={rows}>\n <StyledA11yNoVisible id={uidDescribedBy}>{defaultAriaDescribedBy}</StyledA11yNoVisible>\n <ShuttleLoadingAnnouncement isLoading={isLoading} headerProps={headerProps} />\n {isLoading ? <LoadingItems {...panelMetaInfo} /> : null}\n {showEmptyMessage ? <EmptyItems {...panelMetaInfo} /> : null}\n {showItems ? <ItemListWrapperWithContext {...panelMetaInfo} /> : null}\n {hasMultipleSelection ? <MultipleSelectionAction {...panelMetaInfo} /> : null}\n </Grid>\n </StyledListWrapperMid>\n );\n});\n", "import * as React from 'react';\nexport { React };\n"],
5
+ "mappings": "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",
6
6
  "names": ["React"]
7
7
  }
@@ -33,6 +33,26 @@ __export(ShuttleLoadingAnnouncement_exports, {
33
33
  module.exports = __toCommonJS(ShuttleLoadingAnnouncement_exports);
34
34
  var React = __toESM(require("react"));
35
35
  var import_jsx_runtime = require("react/jsx-runtime");
36
+ var import_react = __toESM(require("react"));
36
37
  var import_styles = require("../../../styles.js");
37
- const ShuttleLoadingAnnouncement = ({ isLoading }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_styles.StyledA11yNoVisible, { role: "status", "aria-atomic": "true", children: isLoading ? "Loading items\u2026" : "Content loaded" });
38
+ const ShuttleLoadingAnnouncement = import_react.default.memo(({ isLoading, headerProps }) => {
39
+ const myHeaderProp = headerProps;
40
+ const label = myHeaderProp?.currentNode?.plainItem?.label || "current level";
41
+ const previousNodeRef = import_react.default.useRef("");
42
+ import_react.default.useEffect(() => {
43
+ if (!isLoading) {
44
+ previousNodeRef.current = label;
45
+ }
46
+ }, [isLoading, label]);
47
+ const messageLabel = import_react.default.useMemo(() => {
48
+ if (isLoading) {
49
+ return "Loading items";
50
+ }
51
+ if (previousNodeRef.current !== label) {
52
+ return `Content loaded for ${label}`;
53
+ }
54
+ return "";
55
+ }, [isLoading, label]);
56
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_styles.StyledA11yNoVisible, { role: "status", "aria-live": "polite", children: messageLabel });
57
+ });
38
58
  //# sourceMappingURL=ShuttleLoadingAnnouncement.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/parts/Panel/middle/ShuttleLoadingAnnouncement.tsx", "../../../../../../../../scripts/build/transpile/react-shim.js"],
4
- "sourcesContent": ["import React from 'react';\nimport { StyledA11yNoVisible } from '../../../styles.js';\n\nexport const ShuttleLoadingAnnouncement = ({ isLoading }: { isLoading: boolean }) => (\n <StyledA11yNoVisible role=\"status\" aria-atomic=\"true\">\n {isLoading ? 'Loading items\u2026' : 'Content loaded'}\n </StyledA11yNoVisible>\n);\n", "import * as React from 'react';\nexport { React };\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADIrB;AAHF,oBAAoC;AAE7B,MAAM,6BAA6B,CAAC,EAAE,UAAU,MACrD,4CAAC,qCAAoB,MAAK,UAAS,eAAY,QAC5C,sBAAY,wBAAmB,kBAClC;",
6
- "names": []
4
+ "sourcesContent": ["import React from 'react';\nimport { StyledA11yNoVisible } from '../../../styles.js';\n\ninterface ShuttleLoadingAnnouncementProps {\n isLoading: boolean;\n headerProps?: Record<string, unknown>;\n}\n\n// NOTE ABOUT `headerProps` SHAPE\n// -------------------------------------\n// The shuttle panel header is fully **customizable**. Consumers can render\n// *anything* in the header area to represent the \u201Ccurrent level\u201D, therefore we\n// cannot enforce a strict type here. For that reason, `headerProps` is typed as\n// `Record<string, unknown>`.\n//\n// However, **all of our Storybook examples** use the DimSum Bredcrumb and TreeModel\n// component as the header. In that scenario, the structure is predictable:\n//\n// headerProps.currentNode.plainItem.label\n//\n// This gives us access to the label of the current breadcrumb node, which we\n// use to announce:\n// - \"Loading items\" while the panel fetches data\n// - \"Content loaded for {label}\" once loading completes\n//\n// Consumers using a different header implementation will not rely on this\n// internal structure, but our fallback (\u201Ccurrent level\u201D) ensures the region\n// still announces meaningful information.\n\nexport const ShuttleLoadingAnnouncement = React.memo(({ isLoading, headerProps }: ShuttleLoadingAnnouncementProps) => {\n const myHeaderProp = headerProps as { currentNode?: { plainItem?: { label?: string } } };\n\n const label = myHeaderProp?.currentNode?.plainItem?.label || 'current level';\n const previousNodeRef = React.useRef('');\n\n React.useEffect(() => {\n if (!isLoading) {\n previousNodeRef.current = label;\n }\n }, [isLoading, label]);\n\n const messageLabel = React.useMemo(() => {\n if (isLoading) {\n return 'Loading items';\n }\n if (previousNodeRef.current !== label) {\n return `Content loaded for ${label}`;\n }\n return '';\n }, [isLoading, label]);\n return (\n <StyledA11yNoVisible role=\"status\" aria-live=\"polite\">\n {messageLabel}\n </StyledA11yNoVisible>\n );\n});\n", "import * as React from 'react';\nexport { React };\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADmDnB;AAnDJ,mBAAkB;AAClB,oBAAoC;AA4B7B,MAAM,6BAA6B,aAAAA,QAAM,KAAK,CAAC,EAAE,WAAW,YAAY,MAAuC;AACpH,QAAM,eAAe;AAErB,QAAM,QAAQ,cAAc,aAAa,WAAW,SAAS;AAC7D,QAAM,kBAAkB,aAAAA,QAAM,OAAO,EAAE;AAEvC,eAAAA,QAAM,UAAU,MAAM;AACpB,QAAI,CAAC,WAAW;AACd,sBAAgB,UAAU;AAAA,IAC5B;AAAA,EACF,GAAG,CAAC,WAAW,KAAK,CAAC;AAErB,QAAM,eAAe,aAAAA,QAAM,QAAQ,MAAM;AACvC,QAAI,WAAW;AACb,aAAO;AAAA,IACT;AACA,QAAI,gBAAgB,YAAY,OAAO;AACrC,aAAO,sBAAsB,KAAK;AAAA,IACpC;AACA,WAAO;AAAA,EACT,GAAG,CAAC,WAAW,KAAK,CAAC;AACrB,SACE,4CAAC,qCAAoB,MAAK,UAAS,aAAU,UAC1C,wBACH;AAEJ,CAAC;",
6
+ "names": ["React"]
7
7
  }
@@ -38,6 +38,9 @@ const PanelContentMiddleSection = React2.memo((panelMetaInfo) => {
38
38
  const itemsLength = usePropsStore(
39
39
  (state) => isDestinationPanel ? state.destinationData.length : state.sourceData.length
40
40
  );
41
+ const headerProps = usePropsStore(
42
+ (state) => isDestinationPanel ? state.destinationHeaderProps : state.sourceHeaderProps
43
+ );
41
44
  const itemList = usePropsStore(
42
45
  (state) => isDestinationPanel ? state.destinationConfiguredData : state.sourceConfiguredData
43
46
  );
@@ -142,7 +145,7 @@ const PanelContentMiddleSection = React2.memo((panelMetaInfo) => {
142
145
  innerRef: innerRefHandlerParentItem,
143
146
  children: /* @__PURE__ */ jsxs(Grid, { cols, rows, children: [
144
147
  /* @__PURE__ */ jsx(StyledA11yNoVisible, { id: uidDescribedBy, children: defaultAriaDescribedBy }),
145
- /* @__PURE__ */ jsx(ShuttleLoadingAnnouncement, { isLoading }),
148
+ /* @__PURE__ */ jsx(ShuttleLoadingAnnouncement, { isLoading, headerProps }),
146
149
  isLoading ? /* @__PURE__ */ jsx(LoadingItems, { ...panelMetaInfo }) : null,
147
150
  showEmptyMessage ? /* @__PURE__ */ jsx(EmptyItems, { ...panelMetaInfo }) : null,
148
151
  showItems ? /* @__PURE__ */ jsx(ItemListWrapperWithContext, { ...panelMetaInfo }) : null,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../../../scripts/build/transpile/react-shim.js", "../../../../../src/parts/Panel/middle/PanelContentMiddleSection.tsx"],
4
- "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable max-statements */\n/* eslint-disable complexity */\nimport React, { useCallback } from 'react';\nimport { styled } from '@elliemae/ds-system';\nimport { Grid } from '@elliemae/ds-grid';\nimport { useOnSpecificFocus } from './useOnSpecificFocus.js';\nimport { usePropsStore, useInternalStore } from '../../../config/useStore/index.js';\nimport { type DSShuttleV2T } from '../../../react-desc-prop-types.js';\nimport { ItemListWrapperWithContext } from './ItemListWrapper/Index.js';\nimport { EmptyItems } from './EmptyItems.js';\nimport { useFocusTracker } from '../../../config/useFocusTracker/index.js';\nimport { LoadingItems } from './LoadingItems.js';\nimport { MultipleSelectionAction } from './MultipleSelectionAction.js';\nimport { DSShuttleV2Name, REGIONS_FOCUSES, DSShuttleV2Slots } from '../../../constants/index.js';\nimport { StyledA11yNoVisible } from '../../../styles.js';\nimport { ShuttleLoadingAnnouncement } from './ShuttleLoadingAnnouncement.js';\n\nconst useInnerRefHandlers = (isDestinationPanel: boolean) => {\n const setZustandRef = useInternalStore((state) => state.setZustandRef);\n const currRegion = isDestinationPanel ? REGIONS_FOCUSES.DESTINATION_PANEL : REGIONS_FOCUSES.SOURCE_PANEL;\n\n const innerRefHandlerParentItem = React.useCallback(\n (node: HTMLDivElement | null) => {\n setZustandRef([currRegion, '', ''], node);\n },\n [currRegion, setZustandRef],\n );\n return React.useMemo(() => ({ innerRefHandlerParentItem }), [innerRefHandlerParentItem]);\n};\n\nconst rows = [1];\n\nconst StyledListWrapperMid = styled(Grid, { name: DSShuttleV2Name, slot: DSShuttleV2Slots.LIST_WRAPPER_MID })`\n overflow: hidden;\n position: relative;\n :focus,\n :focus-visible {\n outline: 2px solid brand-700;\n }\n`;\n\nexport const PanelContentMiddleSection = React.memo((panelMetaInfo: DSShuttleV2T.PanelMetaInfo) => {\n const { isDestinationPanel = false, hasMultipleSelection } = panelMetaInfo;\n const itemsLength = usePropsStore((state) =>\n isDestinationPanel ? state.destinationData.length : state.sourceData.length,\n );\n\n const itemList = usePropsStore((state) =>\n isDestinationPanel ? state.destinationConfiguredData : state.sourceConfiguredData,\n );\n const isLoading = usePropsStore((state) => (isDestinationPanel ? state.destinationIsLoading : state.sourceIsLoading));\n const showEmptyMessage = !isLoading && itemsLength === 0;\n const showItems = !isLoading && !showEmptyMessage;\n\n const actionRef = usePropsStore((state) =>\n isDestinationPanel ? state.destinationVirtualRef : state.sourceVirtualRef,\n );\n\n const getIsDragAndDropHappening = useInternalStore((state) => state.getIsDragAndDropHappening);\n const withLoadMore = usePropsStore((state) =>\n isDestinationPanel ? state.destinationWithLoadMore : state.sourceWithLoadMore,\n );\n const { innerRefHandlerParentItem } = useInnerRefHandlers(isDestinationPanel);\n const {\n trackFocusRegionPanel,\n trackFocusItemFirst,\n trackFocusItemLast,\n trackFocusActionParent,\n trackFocusRegionPanelItem,\n trackFocusLoadMoreBtnDestination,\n trackFocusLoadMoreBtn,\n } = useFocusTracker();\n const config = React.useMemo(\n () => ({\n onFocus: () => {\n trackFocusRegionPanel(isDestinationPanel);\n },\n }),\n [trackFocusRegionPanel, isDestinationPanel],\n );\n const onPanelFocus = useOnSpecificFocus(config);\n\n const onPanelKeyDown = React.useCallback<React.KeyboardEventHandler<HTMLDivElement>>(\n (e) => {\n const { key } = e;\n // we need to invoke \"getIsDragAndDropHappening\" here to ensure we have the latest info at the moment of the event\n const isDragAndDropHappening = getIsDragAndDropHappening();\n if (isDragAndDropHappening) {\n e.preventDefault();\n return;\n }\n if (['Home', 'End', 'ArrowUp', 'ArrowDown'].includes(key)) {\n e.preventDefault();\n e.stopPropagation();\n trackFocusRegionPanelItem(isDestinationPanel);\n trackFocusActionParent();\n // we won't receive ArrowUp/ArrowDown if this happens in a child because children are stopping propagation\n if ((key === 'ArrowDown' || key === 'Home') && itemList.length > 0) {\n actionRef.current.scrollTo(0);\n trackFocusItemFirst(panelMetaInfo);\n }\n if ((key === 'ArrowUp' || key === 'End') && itemList.length > 0) {\n if (withLoadMore) {\n if (isDestinationPanel) trackFocusLoadMoreBtnDestination();\n else trackFocusLoadMoreBtn();\n } else {\n trackFocusItemLast(panelMetaInfo);\n actionRef.current.scrollTo(itemsLength - 1);\n }\n }\n }\n },\n [\n getIsDragAndDropHappening,\n trackFocusRegionPanelItem,\n isDestinationPanel,\n trackFocusActionParent,\n itemList.length,\n actionRef,\n trackFocusItemFirst,\n panelMetaInfo,\n withLoadMore,\n trackFocusLoadMoreBtnDestination,\n trackFocusLoadMoreBtn,\n trackFocusItemLast,\n itemsLength,\n ],\n );\n\n const cols = React.useMemo(() => {\n if (hasMultipleSelection) return ['1fr', '5rem'];\n return ['auto'];\n }, [hasMultipleSelection]);\n\n const getOwnerProps = usePropsStore((store) => store.get);\n const getOwnerPropsArguments = useCallback(() => panelMetaInfo, [panelMetaInfo]);\n\n const defaultAriaDescribedBy =\n itemList.length > 0\n ? 'Press Up and Down arrow to navigate the options list and Press Right and Left arrow to access items actions'\n : 'No items available in the panel';\n\n const uidDescribedBy = useInternalStore((state) => state.shuttleInternalId);\n\n const defaultAriaLabel = React.useMemo(\n () => `Entering ${isDestinationPanel ? 'destination' : 'source'} panel.`,\n [isDestinationPanel],\n );\n\n return (\n <StyledListWrapperMid\n onFocus={onPanelFocus}\n onKeyDown={onPanelKeyDown}\n role=\"group\"\n tabIndex={0}\n rows={rows}\n aria-label={defaultAriaLabel}\n aria-describedby={uidDescribedBy}\n aria-roledescription={isDestinationPanel ? 'shuttle destination panel' : 'shuttle source panel'}\n getOwnerProps={getOwnerProps}\n getOwnerPropsArguments={getOwnerPropsArguments}\n innerRef={innerRefHandlerParentItem}\n >\n <Grid cols={cols} rows={rows}>\n <StyledA11yNoVisible id={uidDescribedBy}>{defaultAriaDescribedBy}</StyledA11yNoVisible>\n <ShuttleLoadingAnnouncement isLoading={isLoading} />\n {isLoading ? <LoadingItems {...panelMetaInfo} /> : null}\n {showEmptyMessage ? <EmptyItems {...panelMetaInfo} /> : null}\n {showItems ? <ItemListWrapperWithContext {...panelMetaInfo} /> : null}\n {hasMultipleSelection ? <MultipleSelectionAction {...panelMetaInfo} /> : null}\n </Grid>\n </StyledListWrapperMid>\n );\n});\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable max-statements */\n/* eslint-disable complexity */\nimport React, { useCallback } from 'react';\nimport { styled } from '@elliemae/ds-system';\nimport { Grid } from '@elliemae/ds-grid';\nimport { useOnSpecificFocus } from './useOnSpecificFocus.js';\nimport { usePropsStore, useInternalStore } from '../../../config/useStore/index.js';\nimport { type DSShuttleV2T } from '../../../react-desc-prop-types.js';\nimport { ItemListWrapperWithContext } from './ItemListWrapper/Index.js';\nimport { EmptyItems } from './EmptyItems.js';\nimport { useFocusTracker } from '../../../config/useFocusTracker/index.js';\nimport { LoadingItems } from './LoadingItems.js';\nimport { MultipleSelectionAction } from './MultipleSelectionAction.js';\nimport { DSShuttleV2Name, REGIONS_FOCUSES, DSShuttleV2Slots } from '../../../constants/index.js';\nimport { StyledA11yNoVisible } from '../../../styles.js';\nimport { ShuttleLoadingAnnouncement } from './ShuttleLoadingAnnouncement.js';\n\nconst useInnerRefHandlers = (isDestinationPanel: boolean) => {\n const setZustandRef = useInternalStore((state) => state.setZustandRef);\n const currRegion = isDestinationPanel ? REGIONS_FOCUSES.DESTINATION_PANEL : REGIONS_FOCUSES.SOURCE_PANEL;\n\n const innerRefHandlerParentItem = React.useCallback(\n (node: HTMLDivElement | null) => {\n setZustandRef([currRegion, '', ''], node);\n },\n [currRegion, setZustandRef],\n );\n return React.useMemo(() => ({ innerRefHandlerParentItem }), [innerRefHandlerParentItem]);\n};\n\nconst rows = [1];\n\nconst StyledListWrapperMid = styled(Grid, { name: DSShuttleV2Name, slot: DSShuttleV2Slots.LIST_WRAPPER_MID })`\n overflow: hidden;\n position: relative;\n :focus,\n :focus-visible {\n outline: 2px solid brand-700;\n }\n`;\n\nexport const PanelContentMiddleSection = React.memo((panelMetaInfo: DSShuttleV2T.PanelMetaInfo) => {\n const { isDestinationPanel = false, hasMultipleSelection } = panelMetaInfo;\n const itemsLength = usePropsStore((state) =>\n isDestinationPanel ? state.destinationData.length : state.sourceData.length,\n );\n\n const headerProps = usePropsStore((state) =>\n isDestinationPanel ? state.destinationHeaderProps : state.sourceHeaderProps,\n );\n\n const itemList = usePropsStore((state) =>\n isDestinationPanel ? state.destinationConfiguredData : state.sourceConfiguredData,\n );\n const isLoading = usePropsStore((state) => (isDestinationPanel ? state.destinationIsLoading : state.sourceIsLoading));\n const showEmptyMessage = !isLoading && itemsLength === 0;\n const showItems = !isLoading && !showEmptyMessage;\n\n const actionRef = usePropsStore((state) =>\n isDestinationPanel ? state.destinationVirtualRef : state.sourceVirtualRef,\n );\n\n const getIsDragAndDropHappening = useInternalStore((state) => state.getIsDragAndDropHappening);\n const withLoadMore = usePropsStore((state) =>\n isDestinationPanel ? state.destinationWithLoadMore : state.sourceWithLoadMore,\n );\n const { innerRefHandlerParentItem } = useInnerRefHandlers(isDestinationPanel);\n const {\n trackFocusRegionPanel,\n trackFocusItemFirst,\n trackFocusItemLast,\n trackFocusActionParent,\n trackFocusRegionPanelItem,\n trackFocusLoadMoreBtnDestination,\n trackFocusLoadMoreBtn,\n } = useFocusTracker();\n const config = React.useMemo(\n () => ({\n onFocus: () => {\n trackFocusRegionPanel(isDestinationPanel);\n },\n }),\n [trackFocusRegionPanel, isDestinationPanel],\n );\n const onPanelFocus = useOnSpecificFocus(config);\n\n const onPanelKeyDown = React.useCallback<React.KeyboardEventHandler<HTMLDivElement>>(\n (e) => {\n const { key } = e;\n // we need to invoke \"getIsDragAndDropHappening\" here to ensure we have the latest info at the moment of the event\n const isDragAndDropHappening = getIsDragAndDropHappening();\n if (isDragAndDropHappening) {\n e.preventDefault();\n return;\n }\n if (['Home', 'End', 'ArrowUp', 'ArrowDown'].includes(key)) {\n e.preventDefault();\n e.stopPropagation();\n trackFocusRegionPanelItem(isDestinationPanel);\n trackFocusActionParent();\n // we won't receive ArrowUp/ArrowDown if this happens in a child because children are stopping propagation\n if ((key === 'ArrowDown' || key === 'Home') && itemList.length > 0) {\n actionRef.current.scrollTo(0);\n trackFocusItemFirst(panelMetaInfo);\n }\n if ((key === 'ArrowUp' || key === 'End') && itemList.length > 0) {\n if (withLoadMore) {\n if (isDestinationPanel) trackFocusLoadMoreBtnDestination();\n else trackFocusLoadMoreBtn();\n } else {\n trackFocusItemLast(panelMetaInfo);\n actionRef.current.scrollTo(itemsLength - 1);\n }\n }\n }\n },\n [\n getIsDragAndDropHappening,\n trackFocusRegionPanelItem,\n isDestinationPanel,\n trackFocusActionParent,\n itemList.length,\n actionRef,\n trackFocusItemFirst,\n panelMetaInfo,\n withLoadMore,\n trackFocusLoadMoreBtnDestination,\n trackFocusLoadMoreBtn,\n trackFocusItemLast,\n itemsLength,\n ],\n );\n\n const cols = React.useMemo(() => {\n if (hasMultipleSelection) return ['1fr', '5rem'];\n return ['auto'];\n }, [hasMultipleSelection]);\n\n const getOwnerProps = usePropsStore((store) => store.get);\n const getOwnerPropsArguments = useCallback(() => panelMetaInfo, [panelMetaInfo]);\n\n const defaultAriaDescribedBy =\n itemList.length > 0\n ? 'Press Up and Down arrow to navigate the options list and Press Right and Left arrow to access items actions'\n : 'No items available in the panel';\n\n const uidDescribedBy = useInternalStore((state) => state.shuttleInternalId);\n\n const defaultAriaLabel = React.useMemo(\n () => `Entering ${isDestinationPanel ? 'destination' : 'source'} panel.`,\n [isDestinationPanel],\n );\n\n return (\n <StyledListWrapperMid\n onFocus={onPanelFocus}\n onKeyDown={onPanelKeyDown}\n role=\"group\"\n tabIndex={0}\n rows={rows}\n aria-label={defaultAriaLabel}\n aria-describedby={uidDescribedBy}\n aria-roledescription={isDestinationPanel ? 'shuttle destination panel' : 'shuttle source panel'}\n getOwnerProps={getOwnerProps}\n getOwnerPropsArguments={getOwnerPropsArguments}\n innerRef={innerRefHandlerParentItem}\n >\n <Grid cols={cols} rows={rows}>\n <StyledA11yNoVisible id={uidDescribedBy}>{defaultAriaDescribedBy}</StyledA11yNoVisible>\n <ShuttleLoadingAnnouncement isLoading={isLoading} headerProps={headerProps} />\n {isLoading ? <LoadingItems {...panelMetaInfo} /> : null}\n {showEmptyMessage ? <EmptyItems {...panelMetaInfo} /> : null}\n {showItems ? <ItemListWrapperWithContext {...panelMetaInfo} /> : null}\n {hasMultipleSelection ? <MultipleSelectionAction {...panelMetaInfo} /> : null}\n </Grid>\n </StyledListWrapperMid>\n );\n});\n"],
5
+ "mappings": "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",
6
6
  "names": ["React"]
7
7
  }
@@ -1,7 +1,27 @@
1
1
  import * as React from "react";
2
2
  import { jsx } from "react/jsx-runtime";
3
+ import React2 from "react";
3
4
  import { StyledA11yNoVisible } from "../../../styles.js";
4
- const ShuttleLoadingAnnouncement = ({ isLoading }) => /* @__PURE__ */ jsx(StyledA11yNoVisible, { role: "status", "aria-atomic": "true", children: isLoading ? "Loading items\u2026" : "Content loaded" });
5
+ const ShuttleLoadingAnnouncement = React2.memo(({ isLoading, headerProps }) => {
6
+ const myHeaderProp = headerProps;
7
+ const label = myHeaderProp?.currentNode?.plainItem?.label || "current level";
8
+ const previousNodeRef = React2.useRef("");
9
+ React2.useEffect(() => {
10
+ if (!isLoading) {
11
+ previousNodeRef.current = label;
12
+ }
13
+ }, [isLoading, label]);
14
+ const messageLabel = React2.useMemo(() => {
15
+ if (isLoading) {
16
+ return "Loading items";
17
+ }
18
+ if (previousNodeRef.current !== label) {
19
+ return `Content loaded for ${label}`;
20
+ }
21
+ return "";
22
+ }, [isLoading, label]);
23
+ return /* @__PURE__ */ jsx(StyledA11yNoVisible, { role: "status", "aria-live": "polite", children: messageLabel });
24
+ });
5
25
  export {
6
26
  ShuttleLoadingAnnouncement
7
27
  };
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../../../scripts/build/transpile/react-shim.js", "../../../../../src/parts/Panel/middle/ShuttleLoadingAnnouncement.tsx"],
4
- "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "import React from 'react';\nimport { StyledA11yNoVisible } from '../../../styles.js';\n\nexport const ShuttleLoadingAnnouncement = ({ isLoading }: { isLoading: boolean }) => (\n <StyledA11yNoVisible role=\"status\" aria-atomic=\"true\">\n {isLoading ? 'Loading items\u2026' : 'Content loaded'}\n </StyledA11yNoVisible>\n);\n"],
5
- "mappings": "AAAA,YAAY,WAAW;ACIrB;AAHF,SAAS,2BAA2B;AAE7B,MAAM,6BAA6B,CAAC,EAAE,UAAU,MACrD,oBAAC,uBAAoB,MAAK,UAAS,eAAY,QAC5C,sBAAY,wBAAmB,kBAClC;",
6
- "names": []
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "import React from 'react';\nimport { StyledA11yNoVisible } from '../../../styles.js';\n\ninterface ShuttleLoadingAnnouncementProps {\n isLoading: boolean;\n headerProps?: Record<string, unknown>;\n}\n\n// NOTE ABOUT `headerProps` SHAPE\n// -------------------------------------\n// The shuttle panel header is fully **customizable**. Consumers can render\n// *anything* in the header area to represent the \u201Ccurrent level\u201D, therefore we\n// cannot enforce a strict type here. For that reason, `headerProps` is typed as\n// `Record<string, unknown>`.\n//\n// However, **all of our Storybook examples** use the DimSum Bredcrumb and TreeModel\n// component as the header. In that scenario, the structure is predictable:\n//\n// headerProps.currentNode.plainItem.label\n//\n// This gives us access to the label of the current breadcrumb node, which we\n// use to announce:\n// - \"Loading items\" while the panel fetches data\n// - \"Content loaded for {label}\" once loading completes\n//\n// Consumers using a different header implementation will not rely on this\n// internal structure, but our fallback (\u201Ccurrent level\u201D) ensures the region\n// still announces meaningful information.\n\nexport const ShuttleLoadingAnnouncement = React.memo(({ isLoading, headerProps }: ShuttleLoadingAnnouncementProps) => {\n const myHeaderProp = headerProps as { currentNode?: { plainItem?: { label?: string } } };\n\n const label = myHeaderProp?.currentNode?.plainItem?.label || 'current level';\n const previousNodeRef = React.useRef('');\n\n React.useEffect(() => {\n if (!isLoading) {\n previousNodeRef.current = label;\n }\n }, [isLoading, label]);\n\n const messageLabel = React.useMemo(() => {\n if (isLoading) {\n return 'Loading items';\n }\n if (previousNodeRef.current !== label) {\n return `Content loaded for ${label}`;\n }\n return '';\n }, [isLoading, label]);\n return (\n <StyledA11yNoVisible role=\"status\" aria-live=\"polite\">\n {messageLabel}\n </StyledA11yNoVisible>\n );\n});\n"],
5
+ "mappings": "AAAA,YAAY,WAAW;ACmDnB;AAnDJ,OAAOA,YAAW;AAClB,SAAS,2BAA2B;AA4B7B,MAAM,6BAA6BA,OAAM,KAAK,CAAC,EAAE,WAAW,YAAY,MAAuC;AACpH,QAAM,eAAe;AAErB,QAAM,QAAQ,cAAc,aAAa,WAAW,SAAS;AAC7D,QAAM,kBAAkBA,OAAM,OAAO,EAAE;AAEvC,EAAAA,OAAM,UAAU,MAAM;AACpB,QAAI,CAAC,WAAW;AACd,sBAAgB,UAAU;AAAA,IAC5B;AAAA,EACF,GAAG,CAAC,WAAW,KAAK,CAAC;AAErB,QAAM,eAAeA,OAAM,QAAQ,MAAM;AACvC,QAAI,WAAW;AACb,aAAO;AAAA,IACT;AACA,QAAI,gBAAgB,YAAY,OAAO;AACrC,aAAO,sBAAsB,KAAK;AAAA,IACpC;AACA,WAAO;AAAA,EACT,GAAG,CAAC,WAAW,KAAK,CAAC;AACrB,SACE,oBAAC,uBAAoB,MAAK,UAAS,aAAU,UAC1C,wBACH;AAEJ,CAAC;",
6
+ "names": ["React"]
7
7
  }
@@ -1,3 +1,7 @@
1
- export declare const ShuttleLoadingAnnouncement: ({ isLoading }: {
1
+ import React from 'react';
2
+ interface ShuttleLoadingAnnouncementProps {
2
3
  isLoading: boolean;
3
- }) => import("react/jsx-runtime.js").JSX.Element;
4
+ headerProps?: Record<string, unknown>;
5
+ }
6
+ export declare const ShuttleLoadingAnnouncement: React.MemoExoticComponent<({ isLoading, headerProps }: ShuttleLoadingAnnouncementProps) => import("react/jsx-runtime.js").JSX.Element>;
7
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elliemae/ds-shuttle-v2",
3
- "version": "3.57.0-next.40",
3
+ "version": "3.57.0-next.41",
4
4
  "license": "MIT",
5
5
  "description": "ICE MT - Dimsum - Shuttle v2",
6
6
  "files": [
@@ -45,33 +45,33 @@
45
45
  "checkDeps": "npm exec ../../util/ds-codemods -- check-missing-packages --projectFolderPath=\"./\" --ignorePackagesGlobPattern=\"\" --ignoreFilesGlobPattern=\"**/test-ables/*,**/tests/*\""
46
46
  },
47
47
  "dependencies": {
48
- "@elliemae/ds-button-v2": "3.57.0-next.40",
49
- "@elliemae/ds-circular-progress-indicator": "3.57.0-next.40",
50
- "@elliemae/ds-drag-and-drop": "3.57.0-next.40",
51
- "@elliemae/ds-fast-list": "3.57.0-next.40",
52
- "@elliemae/ds-form-checkbox": "3.57.0-next.40",
53
- "@elliemae/ds-form-input-text": "3.57.0-next.40",
54
- "@elliemae/ds-grid": "3.57.0-next.40",
55
- "@elliemae/ds-hooks-fontsize-detector": "3.57.0-next.40",
56
- "@elliemae/ds-hooks-headless-tooltip": "3.57.0-next.40",
57
- "@elliemae/ds-hooks-on-blur-out": "3.57.0-next.40",
58
- "@elliemae/ds-icons": "3.57.0-next.40",
59
- "@elliemae/ds-indeterminate-progress-indicator": "3.57.0-next.40",
60
- "@elliemae/ds-popperjs": "3.57.0-next.40",
61
- "@elliemae/ds-props-helpers": "3.57.0-next.40",
62
- "@elliemae/ds-system": "3.57.0-next.40",
63
- "@elliemae/ds-typescript-helpers": "3.57.0-next.40",
64
- "@elliemae/ds-typography": "3.57.0-next.40",
65
- "@elliemae/ds-zustand-helpers": "3.57.0-next.40",
48
+ "@elliemae/ds-button-v2": "3.57.0-next.41",
49
+ "@elliemae/ds-circular-progress-indicator": "3.57.0-next.41",
50
+ "@elliemae/ds-drag-and-drop": "3.57.0-next.41",
51
+ "@elliemae/ds-fast-list": "3.57.0-next.41",
52
+ "@elliemae/ds-form-checkbox": "3.57.0-next.41",
53
+ "@elliemae/ds-form-input-text": "3.57.0-next.41",
54
+ "@elliemae/ds-grid": "3.57.0-next.41",
55
+ "@elliemae/ds-hooks-fontsize-detector": "3.57.0-next.41",
56
+ "@elliemae/ds-hooks-headless-tooltip": "3.57.0-next.41",
57
+ "@elliemae/ds-hooks-on-blur-out": "3.57.0-next.41",
58
+ "@elliemae/ds-icons": "3.57.0-next.41",
59
+ "@elliemae/ds-indeterminate-progress-indicator": "3.57.0-next.41",
60
+ "@elliemae/ds-popperjs": "3.57.0-next.41",
61
+ "@elliemae/ds-props-helpers": "3.57.0-next.41",
62
+ "@elliemae/ds-system": "3.57.0-next.41",
63
+ "@elliemae/ds-typescript-helpers": "3.57.0-next.41",
64
+ "@elliemae/ds-typography": "3.57.0-next.41",
65
+ "@elliemae/ds-zustand-helpers": "3.57.0-next.41",
66
66
  "@xstyled/styled-components": "catalog:",
67
67
  "fast-deep-equal": "catalog:",
68
68
  "uid": "catalog:"
69
69
  },
70
70
  "devDependencies": {
71
- "@elliemae/ds-breadcrumb": "3.57.0-next.40",
72
- "@elliemae/ds-monorepo-devops": "3.57.0-next.40",
73
- "@elliemae/ds-test-utils": "3.57.0-next.40",
74
- "@elliemae/ds-tree-model": "3.57.0-next.40",
71
+ "@elliemae/ds-breadcrumb": "3.57.0-next.41",
72
+ "@elliemae/ds-monorepo-devops": "3.57.0-next.41",
73
+ "@elliemae/ds-test-utils": "3.57.0-next.41",
74
+ "@elliemae/ds-tree-model": "3.57.0-next.41",
75
75
  "@elliemae/pui-cli": "catalog:",
76
76
  "jest": "catalog:",
77
77
  "lodash-es": "catalog:",
@@ -87,5 +87,5 @@
87
87
  "access": "public",
88
88
  "typeSafety": true
89
89
  },
90
- "gitHead": "bca00298d99085d3c808728c40f45c0627810bda"
90
+ "gitHead": "18ae25814ee005325f5acce1789ac2d97a919b20"
91
91
  }