@elliemae/ds-dropdownmenu-v2 3.80.0-next.3 → 3.80.0-next.30

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.
Files changed (27) hide show
  1. package/dist/cjs/config/useDropdownMenuConfig.js +32 -29
  2. package/dist/cjs/config/useDropdownMenuConfig.js.map +2 -2
  3. package/dist/cjs/parts/DropdownMenuContent.js +8 -2
  4. package/dist/cjs/parts/DropdownMenuContent.js.map +2 -2
  5. package/dist/cjs/parts/DropdownMenuItemFactory.js +6 -2
  6. package/dist/cjs/parts/DropdownMenuItemFactory.js.map +2 -2
  7. package/dist/cjs/parts/DropdownMenuListBox.js +8 -3
  8. package/dist/cjs/parts/DropdownMenuListBox.js.map +2 -2
  9. package/dist/cjs/react-desc-prop-types.js +10 -2
  10. package/dist/cjs/react-desc-prop-types.js.map +2 -2
  11. package/dist/cjs/typescript-testing/typescript-dropdown-v2-valid.js +3 -1
  12. package/dist/cjs/typescript-testing/typescript-dropdown-v2-valid.js.map +2 -2
  13. package/dist/esm/config/useDropdownMenuConfig.js +33 -30
  14. package/dist/esm/config/useDropdownMenuConfig.js.map +2 -2
  15. package/dist/esm/parts/DropdownMenuContent.js +8 -2
  16. package/dist/esm/parts/DropdownMenuContent.js.map +2 -2
  17. package/dist/esm/parts/DropdownMenuItemFactory.js +6 -2
  18. package/dist/esm/parts/DropdownMenuItemFactory.js.map +2 -2
  19. package/dist/esm/parts/DropdownMenuListBox.js +8 -3
  20. package/dist/esm/parts/DropdownMenuListBox.js.map +2 -2
  21. package/dist/esm/react-desc-prop-types.js +10 -2
  22. package/dist/esm/react-desc-prop-types.js.map +2 -2
  23. package/dist/esm/typescript-testing/typescript-dropdown-v2-valid.js +3 -1
  24. package/dist/esm/typescript-testing/typescript-dropdown-v2-valid.js.map +2 -2
  25. package/dist/types/parts/DropdownMenuItemFactory.d.ts +1 -0
  26. package/dist/types/react-desc-prop-types.d.ts +18 -2
  27. package/package.json +14 -14
@@ -1,6 +1,6 @@
1
1
  import * as React from "react";
2
- import { useCallback, useEffect, useMemo, useState } from "react";
3
- import { useVirtual } from "react-virtual";
2
+ import { useCallback, useEffect, useState } from "react";
3
+ import { useVirtualizer } from "@tanstack/react-virtual";
4
4
  import { useMemoMergePropsWithDefault, useValidateTypescriptPropTypes } from "@elliemae/ds-props-helpers";
5
5
  import { defaultProps, DSDropdownMenuV2PropTypes } from "../react-desc-prop-types.js";
6
6
  import { useReferenceConfig } from "./useReferenceConfig.js";
@@ -18,13 +18,27 @@ const useDropdownMenuConfig = (props, self) => {
18
18
  setActiveDescendant(options.find(isOptionFocuseable)?.dsId ?? "");
19
19
  }
20
20
  }, [isOpened, inputValue]);
21
- const virtualListHelpers = useVirtual({
22
- size: options.length,
23
- parentRef: listboxReference,
21
+ const virtualListHelpers = useVirtualizer({
22
+ count: options.length,
23
+ getScrollElement: () => listboxReference.current,
24
24
  overscan: 15,
25
25
  paddingStart: 0,
26
26
  estimateSize
27
27
  });
28
+ if (!("totalSize" in virtualListHelpers)) {
29
+ Object.defineProperty(virtualListHelpers, "totalSize", {
30
+ enumerable: true,
31
+ get() {
32
+ return this.getTotalSize();
33
+ }
34
+ });
35
+ Object.defineProperty(virtualListHelpers, "virtualItems", {
36
+ enumerable: true,
37
+ get() {
38
+ return this.getVirtualItems();
39
+ }
40
+ });
41
+ }
28
42
  const { scrollToIndex } = virtualListHelpers;
29
43
  const scrollToIndexInternal = useCallback(
30
44
  (index, opts) => {
@@ -51,31 +65,20 @@ const useDropdownMenuConfig = (props, self) => {
51
65
  };
52
66
  }
53
67
  }, [actionRef, scrollOptionIntoView, scrollToIndexInternal]);
54
- const ctx = useMemo(
55
- () => ({
56
- props: propsWithDefault,
57
- virtualListHelpers,
58
- triggerReferenceElement,
59
- setTriggerReferenceElement,
60
- listboxReference,
61
- inputReference,
62
- activeDescendant,
63
- setActiveDescendant,
64
- scrollOptionIntoView,
65
- DSDropdownMenuV2: self
66
- }),
67
- [
68
- propsWithDefault,
69
- virtualListHelpers,
70
- triggerReferenceElement,
71
- setTriggerReferenceElement,
72
- listboxReference,
73
- inputReference,
74
- activeDescendant,
75
- scrollOptionIntoView,
76
- self
77
- ]
78
- );
68
+ const ctx = {
69
+ props: propsWithDefault,
70
+ // Cast reflects the `totalSize`/`virtualItems` getters defined above via `Object.defineProperty`
71
+ // — real properties on this object at runtime, just not on `Virtualizer`'s own type.
72
+ virtualListHelpers,
73
+ triggerReferenceElement,
74
+ setTriggerReferenceElement,
75
+ listboxReference,
76
+ inputReference,
77
+ activeDescendant,
78
+ setActiveDescendant,
79
+ scrollOptionIntoView,
80
+ DSDropdownMenuV2: self
81
+ };
79
82
  return ctx;
80
83
  };
81
84
  export {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../scripts/build/transpile/react-shim.js", "../../../src/config/useDropdownMenuConfig.tsx"],
4
- "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "import { useCallback, useEffect, useMemo, useState } from 'react';\nimport { type ScrollToIndexOptions, useVirtual } from 'react-virtual';\nimport { useMemoMergePropsWithDefault, useValidateTypescriptPropTypes } from '@elliemae/ds-props-helpers';\nimport type { DSDropdownMenuT } from '../react-desc-prop-types.js';\nimport { defaultProps, DSDropdownMenuV2PropTypes } from '../react-desc-prop-types.js';\nimport { useReferenceConfig } from './useReferenceConfig.js';\nimport { isOptionFocuseable } from '../utils/index.js';\nimport { DSDropdownMenuName } from '../exported-related/index.js';\n\nconst estimateSize = () => 32;\n\nexport const useDropdownMenuConfig = (\n props: DSDropdownMenuT.Props,\n self: React.ComponentType<DSDropdownMenuT.Props>,\n): DSDropdownMenuT.CTX => {\n const propsWithDefault = useMemoMergePropsWithDefault<DSDropdownMenuT.InternalProps>(props, defaultProps);\n useValidateTypescriptPropTypes(propsWithDefault, DSDropdownMenuV2PropTypes, DSDropdownMenuName);\n\n const { options, inputValue, isOpened, actionRef } = propsWithDefault;\n\n const { triggerReferenceElement, setTriggerReferenceElement, listboxReference, inputReference } =\n useReferenceConfig();\n\n const [activeDescendant, setActiveDescendant] = useState<string>(options.find(isOptionFocuseable)?.dsId ?? '');\n\n // ---------------------------------------------------------------------------\n // Focusing first option when dropdown opens or input changes\n // ---------------------------------------------------------------------------\n useEffect(() => {\n if (isOpened) {\n setActiveDescendant(options.find(isOptionFocuseable)?.dsId ?? '');\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isOpened, inputValue]);\n\n // ===========================================================================\n // Virtualization setup\n // ===========================================================================\n const virtualListHelpers = useVirtual({\n size: options.length,\n parentRef: listboxReference,\n overscan: 15,\n paddingStart: 0,\n estimateSize,\n });\n\n const { scrollToIndex } = virtualListHelpers;\n\n // ===========================================================================\n // Scroll to index function\n // ===========================================================================\n const scrollToIndexInternal = useCallback(\n (index: number, opts?: ScrollToIndexOptions) => {\n // Since we could have dynamic sizing on the options, scrolling to an index may not work correctly sometimes.\n // This is a workaround to ensure that the option is scrolled into view.\n // More info -> https://github.com/TanStack/virtual/issues/381\n scrollToIndex(index, opts);\n window.requestAnimationFrame(() => {\n scrollToIndex(index, opts);\n });\n },\n [scrollToIndex],\n );\n\n // ===========================================================================\n // Scroll into view function\n // ===========================================================================\n const scrollOptionIntoView = useCallback(\n (dsId: string, opts: { align: 'start' | 'center' | 'end' | 'auto' } = { align: 'center' }) => {\n const optionIndex = options.findIndex((opt) => opt.dsId === dsId);\n scrollToIndexInternal(optionIndex, opts);\n },\n [options, scrollToIndexInternal],\n );\n\n // ===========================================================================\n // Action ref setup\n // ===========================================================================\n useEffect(() => {\n if (actionRef?.current) {\n actionRef.current = {\n setActiveDescendant,\n scrollOptionIntoView,\n scrollToIndex: scrollToIndexInternal,\n };\n }\n }, [actionRef, scrollOptionIntoView, scrollToIndexInternal]);\n\n // ===========================================================================\n // Context setup\n // ===========================================================================\n const ctx = useMemo(\n () => ({\n props: propsWithDefault,\n virtualListHelpers,\n triggerReferenceElement,\n setTriggerReferenceElement,\n listboxReference,\n inputReference,\n activeDescendant,\n setActiveDescendant,\n scrollOptionIntoView,\n DSDropdownMenuV2: self,\n }),\n [\n propsWithDefault,\n virtualListHelpers,\n triggerReferenceElement,\n setTriggerReferenceElement,\n listboxReference,\n inputReference,\n activeDescendant,\n scrollOptionIntoView,\n self,\n ],\n );\n\n return ctx;\n};\n"],
5
- "mappings": "AAAA,YAAY,WAAW;ACAvB,SAAS,aAAa,WAAW,SAAS,gBAAgB;AAC1D,SAAoC,kBAAkB;AACtD,SAAS,8BAA8B,sCAAsC;AAE7E,SAAS,cAAc,iCAAiC;AACxD,SAAS,0BAA0B;AACnC,SAAS,0BAA0B;AACnC,SAAS,0BAA0B;AAEnC,MAAM,eAAe,MAAM;AAEpB,MAAM,wBAAwB,CACnC,OACA,SACwB;AACxB,QAAM,mBAAmB,6BAA4D,OAAO,YAAY;AACxG,iCAA+B,kBAAkB,2BAA2B,kBAAkB;AAE9F,QAAM,EAAE,SAAS,YAAY,UAAU,UAAU,IAAI;AAErD,QAAM,EAAE,yBAAyB,4BAA4B,kBAAkB,eAAe,IAC5F,mBAAmB;AAErB,QAAM,CAAC,kBAAkB,mBAAmB,IAAI,SAAiB,QAAQ,KAAK,kBAAkB,GAAG,QAAQ,EAAE;AAK7G,YAAU,MAAM;AACd,QAAI,UAAU;AACZ,0BAAoB,QAAQ,KAAK,kBAAkB,GAAG,QAAQ,EAAE;AAAA,IAClE;AAAA,EAEF,GAAG,CAAC,UAAU,UAAU,CAAC;AAKzB,QAAM,qBAAqB,WAAW;AAAA,IACpC,MAAM,QAAQ;AAAA,IACd,WAAW;AAAA,IACX,UAAU;AAAA,IACV,cAAc;AAAA,IACd;AAAA,EACF,CAAC;AAED,QAAM,EAAE,cAAc,IAAI;AAK1B,QAAM,wBAAwB;AAAA,IAC5B,CAAC,OAAe,SAAgC;AAI9C,oBAAc,OAAO,IAAI;AACzB,aAAO,sBAAsB,MAAM;AACjC,sBAAc,OAAO,IAAI;AAAA,MAC3B,CAAC;AAAA,IACH;AAAA,IACA,CAAC,aAAa;AAAA,EAChB;AAKA,QAAM,uBAAuB;AAAA,IAC3B,CAAC,MAAc,OAAuD,EAAE,OAAO,SAAS,MAAM;AAC5F,YAAM,cAAc,QAAQ,UAAU,CAAC,QAAQ,IAAI,SAAS,IAAI;AAChE,4BAAsB,aAAa,IAAI;AAAA,IACzC;AAAA,IACA,CAAC,SAAS,qBAAqB;AAAA,EACjC;AAKA,YAAU,MAAM;AACd,QAAI,WAAW,SAAS;AACtB,gBAAU,UAAU;AAAA,QAClB;AAAA,QACA;AAAA,QACA,eAAe;AAAA,MACjB;AAAA,IACF;AAAA,EACF,GAAG,CAAC,WAAW,sBAAsB,qBAAqB,CAAC;AAK3D,QAAM,MAAM;AAAA,IACV,OAAO;AAAA,MACL,OAAO;AAAA,MACP;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,kBAAkB;AAAA,IACpB;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;",
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "import { useCallback, useEffect, useState } from 'react';\nimport { type ScrollToOptions, useVirtualizer } from '@tanstack/react-virtual';\nimport { useMemoMergePropsWithDefault, useValidateTypescriptPropTypes } from '@elliemae/ds-props-helpers';\nimport type { DSDropdownMenuT } from '../react-desc-prop-types.js';\nimport { defaultProps, DSDropdownMenuV2PropTypes } from '../react-desc-prop-types.js';\nimport { useReferenceConfig } from './useReferenceConfig.js';\nimport { isOptionFocuseable } from '../utils/index.js';\nimport { DSDropdownMenuName } from '../exported-related/index.js';\n\nconst estimateSize = () => 32;\n\nexport const useDropdownMenuConfig = (\n props: DSDropdownMenuT.Props,\n self: React.ComponentType<DSDropdownMenuT.Props>,\n): DSDropdownMenuT.CTX => {\n const propsWithDefault = useMemoMergePropsWithDefault<DSDropdownMenuT.InternalProps>(props, defaultProps);\n useValidateTypescriptPropTypes(propsWithDefault, DSDropdownMenuV2PropTypes, DSDropdownMenuName);\n\n const { options, inputValue, isOpened, actionRef } = propsWithDefault;\n\n const { triggerReferenceElement, setTriggerReferenceElement, listboxReference, inputReference } =\n useReferenceConfig();\n\n const [activeDescendant, setActiveDescendant] = useState<string>(options.find(isOptionFocuseable)?.dsId ?? '');\n\n // ---------------------------------------------------------------------------\n // Focusing first option when dropdown opens or input changes\n // ---------------------------------------------------------------------------\n useEffect(() => {\n if (isOpened) {\n setActiveDescendant(options.find(isOptionFocuseable)?.dsId ?? '');\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isOpened, inputValue]);\n\n // ===========================================================================\n // Virtualization setup\n // ===========================================================================\n const virtualListHelpers = useVirtualizer<HTMLDivElement, HTMLElement>({\n count: options.length,\n getScrollElement: () => listboxReference.current,\n overscan: 15,\n paddingStart: 0,\n estimateSize,\n });\n\n /**\n * Backward-compatibility shim, not a v3 API: `virtualListHelpers` is handed to consumers\n * wholesale via `HeaderComp={ctx => ...}` (`ctx.virtualListHelpers`). Under react-virtual v2\n * that object exposed `totalSize`/`virtualItems` as plain properties; v3's `Virtualizer`\n * exposes them as `getTotalSize()`/`getVirtualItems()` methods instead. A consumer's existing\n * `HeaderComp` reading the old property names would silently get `undefined` post-migration \u2014\n * defining them as live getters that delegate to the v3 methods keeps both forms working, so\n * this migration doesn't force every `HeaderComp` implementation to update. Guarded so it only\n * runs once per instance (the instance itself persists across renders under v3).\n */\n if (!('totalSize' in virtualListHelpers)) {\n Object.defineProperty(virtualListHelpers, 'totalSize', {\n enumerable: true,\n get(this: typeof virtualListHelpers) {\n return this.getTotalSize();\n },\n });\n Object.defineProperty(virtualListHelpers, 'virtualItems', {\n enumerable: true,\n get(this: typeof virtualListHelpers) {\n return this.getVirtualItems();\n },\n });\n }\n\n const { scrollToIndex } = virtualListHelpers;\n\n // ===========================================================================\n // Scroll to index function\n // ===========================================================================\n const scrollToIndexInternal = useCallback(\n (index: number, opts?: ScrollToOptions) => {\n // Since we could have dynamic sizing on the options, scrolling to an index may not work correctly sometimes.\n // This is a workaround to ensure that the option is scrolled into view.\n // More info -> https://github.com/TanStack/virtual/issues/381\n scrollToIndex(index, opts);\n window.requestAnimationFrame(() => {\n scrollToIndex(index, opts);\n });\n },\n [scrollToIndex],\n );\n\n // ===========================================================================\n // Scroll into view function\n // ===========================================================================\n const scrollOptionIntoView = useCallback(\n (dsId: string, opts: { align: 'start' | 'center' | 'end' | 'auto' } = { align: 'center' }) => {\n const optionIndex = options.findIndex((opt) => opt.dsId === dsId);\n scrollToIndexInternal(optionIndex, opts);\n },\n [options, scrollToIndexInternal],\n );\n\n // ===========================================================================\n // Action ref setup\n // ===========================================================================\n useEffect(() => {\n if (actionRef?.current) {\n actionRef.current = {\n setActiveDescendant,\n scrollOptionIntoView,\n scrollToIndex: scrollToIndexInternal,\n };\n }\n }, [actionRef, scrollOptionIntoView, scrollToIndexInternal]);\n\n // ===========================================================================\n // Context setup\n // ===========================================================================\n // Not memoized: `virtualListHelpers` was always the dependency that mattered here, and under\n // v2 it was a brand-new object every render, so this useMemo never actually bailed out in\n // practice. Under v3 the same instance is returned forever, which would make a memoized `ctx`\n // silently go stale on a render triggered purely by the virtualizer's own internal state (e.g.\n // a scroll or a remeasurement) \u2014 recomputing plainly every render preserves v2's real-world\n // behavior exactly, with no risk of that staleness.\n const ctx: DSDropdownMenuT.CTX = {\n props: propsWithDefault,\n // Cast reflects the `totalSize`/`virtualItems` getters defined above via `Object.defineProperty`\n // \u2014 real properties on this object at runtime, just not on `Virtualizer`'s own type.\n virtualListHelpers: virtualListHelpers as DSDropdownMenuT.CTX['virtualListHelpers'],\n triggerReferenceElement,\n setTriggerReferenceElement,\n listboxReference,\n inputReference,\n activeDescendant,\n setActiveDescendant,\n scrollOptionIntoView,\n DSDropdownMenuV2: self,\n };\n\n return ctx;\n};\n"],
5
+ "mappings": "AAAA,YAAY,WAAW;ACAvB,SAAS,aAAa,WAAW,gBAAgB;AACjD,SAA+B,sBAAsB;AACrD,SAAS,8BAA8B,sCAAsC;AAE7E,SAAS,cAAc,iCAAiC;AACxD,SAAS,0BAA0B;AACnC,SAAS,0BAA0B;AACnC,SAAS,0BAA0B;AAEnC,MAAM,eAAe,MAAM;AAEpB,MAAM,wBAAwB,CACnC,OACA,SACwB;AACxB,QAAM,mBAAmB,6BAA4D,OAAO,YAAY;AACxG,iCAA+B,kBAAkB,2BAA2B,kBAAkB;AAE9F,QAAM,EAAE,SAAS,YAAY,UAAU,UAAU,IAAI;AAErD,QAAM,EAAE,yBAAyB,4BAA4B,kBAAkB,eAAe,IAC5F,mBAAmB;AAErB,QAAM,CAAC,kBAAkB,mBAAmB,IAAI,SAAiB,QAAQ,KAAK,kBAAkB,GAAG,QAAQ,EAAE;AAK7G,YAAU,MAAM;AACd,QAAI,UAAU;AACZ,0BAAoB,QAAQ,KAAK,kBAAkB,GAAG,QAAQ,EAAE;AAAA,IAClE;AAAA,EAEF,GAAG,CAAC,UAAU,UAAU,CAAC;AAKzB,QAAM,qBAAqB,eAA4C;AAAA,IACrE,OAAO,QAAQ;AAAA,IACf,kBAAkB,MAAM,iBAAiB;AAAA,IACzC,UAAU;AAAA,IACV,cAAc;AAAA,IACd;AAAA,EACF,CAAC;AAYD,MAAI,EAAE,eAAe,qBAAqB;AACxC,WAAO,eAAe,oBAAoB,aAAa;AAAA,MACrD,YAAY;AAAA,MACZ,MAAqC;AACnC,eAAO,KAAK,aAAa;AAAA,MAC3B;AAAA,IACF,CAAC;AACD,WAAO,eAAe,oBAAoB,gBAAgB;AAAA,MACxD,YAAY;AAAA,MACZ,MAAqC;AACnC,eAAO,KAAK,gBAAgB;AAAA,MAC9B;AAAA,IACF,CAAC;AAAA,EACH;AAEA,QAAM,EAAE,cAAc,IAAI;AAK1B,QAAM,wBAAwB;AAAA,IAC5B,CAAC,OAAe,SAA2B;AAIzC,oBAAc,OAAO,IAAI;AACzB,aAAO,sBAAsB,MAAM;AACjC,sBAAc,OAAO,IAAI;AAAA,MAC3B,CAAC;AAAA,IACH;AAAA,IACA,CAAC,aAAa;AAAA,EAChB;AAKA,QAAM,uBAAuB;AAAA,IAC3B,CAAC,MAAc,OAAuD,EAAE,OAAO,SAAS,MAAM;AAC5F,YAAM,cAAc,QAAQ,UAAU,CAAC,QAAQ,IAAI,SAAS,IAAI;AAChE,4BAAsB,aAAa,IAAI;AAAA,IACzC;AAAA,IACA,CAAC,SAAS,qBAAqB;AAAA,EACjC;AAKA,YAAU,MAAM;AACd,QAAI,WAAW,SAAS;AACtB,gBAAU,UAAU;AAAA,QAClB;AAAA,QACA;AAAA,QACA,eAAe;AAAA,MACjB;AAAA,IACF;AAAA,EACF,GAAG,CAAC,WAAW,sBAAsB,qBAAqB,CAAC;AAW3D,QAAM,MAA2B;AAAA,IAC/B,OAAO;AAAA;AAAA;AAAA,IAGP;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,kBAAkB;AAAA,EACpB;AAEA,SAAO;AACT;",
6
6
  "names": []
7
7
  }
@@ -2,6 +2,7 @@ import * as React from "react";
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
3
  import { useCallback, useContext } from "react";
4
4
  import { useFloatingContext, FloatingWrapper } from "@elliemae/ds-floating-context";
5
+ import { setMultipleRefs } from "@elliemae/ds-system";
5
6
  import { useGetGlobalAttributes, useGetXstyledProps } from "@elliemae/ds-props-helpers";
6
7
  import { DropdownMenuDataTestId } from "../DropdownMenuDataTestId.js";
7
8
  import { StyledTriggerWrapper } from "../styled.js";
@@ -20,7 +21,8 @@ const DropdownMenuContent = () => {
20
21
  wrapperStyles,
21
22
  isLoading,
22
23
  zIndex,
23
- as
24
+ as,
25
+ innerRef
24
26
  } = props;
25
27
  const {
26
28
  "data-popover-label": dataPopoverLabel,
@@ -54,11 +56,15 @@ const DropdownMenuContent = () => {
54
56
  placementOrderPreference,
55
57
  onClickOutside: handleClickOutside
56
58
  });
59
+ const setTriggerRootRef = useCallback(
60
+ (node) => setMultipleRefs([(el) => setTriggerReferenceElement(el), innerRef])(node),
61
+ [setTriggerReferenceElement, innerRef]
62
+ );
57
63
  return /* @__PURE__ */ jsxs(
58
64
  StyledTriggerWrapper,
59
65
  {
60
66
  "data-testid": `${DropdownMenuDataTestId.TRIGGER_WRAPPER}`,
61
- innerRef: setTriggerReferenceElement,
67
+ innerRef: setTriggerRootRef,
62
68
  "aria-haspopup": "listbox",
63
69
  ...wrapperStyles,
64
70
  ...globalAttributes,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../scripts/build/transpile/react-shim.js", "../../../src/parts/DropdownMenuContent.tsx"],
4
- "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable no-unused-vars */\nimport React, { useCallback, useContext } from 'react';\nimport { useFloatingContext, FloatingWrapper } from '@elliemae/ds-floating-context';\nimport { useGetGlobalAttributes, useGetXstyledProps } from '@elliemae/ds-props-helpers';\nimport { DropdownMenuDataTestId } from '../DropdownMenuDataTestId.js';\nimport { StyledTriggerWrapper } from '../styled.js';\nimport { DropdownMenuListBox } from './DropdownMenuListBox.js';\nimport { DSDropdownMenuContext } from '../DropdownMenuContext.js';\nimport { DropdownMenuLoading } from './DropdownMenuLoading.js';\n\nexport const DropdownMenuContent: React.ComponentType<Record<string, never>> = () => {\n const { props, triggerReferenceElement, setTriggerReferenceElement } = useContext(DSDropdownMenuContext);\n\n const {\n children,\n isOpened,\n onClickOutside,\n startPlacementPreference,\n placementOrderPreference,\n customOffset,\n wrapperStyles,\n isLoading,\n zIndex,\n as,\n } = props;\n const {\n 'data-popover-label': dataPopoverLabel,\n ...globalAttributes\n }: ReturnType<typeof useGetGlobalAttributes> & { 'data-popover-label'?: string } = useGetGlobalAttributes(props);\n // we need to exclude this props from the xstyled props because there is a conflict\n // using submenus items with the name of the prop of ddmenu and xstyled\n const { minWidth, minHeight, ...restXstyledProps } = useGetXstyledProps(props);\n\n // Click-outside: close only when the click is not inside any child dropdown listbox.\n // The hook's onClickOutside already excludes the floating + reference elements; we add\n // a check for sibling submenu listboxes that may be portaled elsewhere in the document.\n const handleClickOutside = useCallback(\n (event: MouseEvent | TouchEvent) => {\n const target = event.target as Node | null;\n if (!target) return;\n const dropdownListboxes = [\n ...document.body.querySelectorAll(`[data-testid=\"${DropdownMenuDataTestId.MENU_WRAPPER}\"]`),\n ];\n if (dropdownListboxes.every((listbox) => !listbox.contains(target))) {\n onClickOutside(event);\n }\n },\n [onClickOutside],\n );\n\n const {\n refs,\n floatingStyles,\n context,\n isOpen: isFloatingOpen,\n } = useFloatingContext({\n externallyControlledIsOpen: isOpened,\n externalReferenceElement: triggerReferenceElement,\n withoutAnimation: true,\n customOffset,\n placement: startPlacementPreference,\n placementOrderPreference,\n onClickOutside: handleClickOutside,\n });\n\n return (\n <StyledTriggerWrapper\n data-testid={`${DropdownMenuDataTestId.TRIGGER_WRAPPER}`}\n innerRef={setTriggerReferenceElement}\n aria-haspopup=\"listbox\"\n {...wrapperStyles}\n {...globalAttributes}\n {...restXstyledProps}\n as={as}\n >\n {children}\n {triggerReferenceElement && (\n <FloatingWrapper\n innerRef={refs.setFloating}\n isOpen={isFloatingOpen}\n floatingStyles={{ ...floatingStyles, ...(zIndex !== undefined && { zIndex }) }}\n context={context}\n role=\"region\"\n aria-label={(dataPopoverLabel as string) || 'dropdown-menu popover'}\n >\n {isLoading ? <DropdownMenuLoading /> : <DropdownMenuListBox />}\n </FloatingWrapper>\n )}\n </StyledTriggerWrapper>\n );\n};\n"],
5
- "mappings": "AAAA,YAAY,WAAW;ACkEnB,SAmBmB,KAnBnB;AAjEJ,SAAgB,aAAa,kBAAkB;AAC/C,SAAS,oBAAoB,uBAAuB;AACpD,SAAS,wBAAwB,0BAA0B;AAC3D,SAAS,8BAA8B;AACvC,SAAS,4BAA4B;AACrC,SAAS,2BAA2B;AACpC,SAAS,6BAA6B;AACtC,SAAS,2BAA2B;AAE7B,MAAM,sBAAkE,MAAM;AACnF,QAAM,EAAE,OAAO,yBAAyB,2BAA2B,IAAI,WAAW,qBAAqB;AAEvG,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AACJ,QAAM;AAAA,IACJ,sBAAsB;AAAA,IACtB,GAAG;AAAA,EACL,IAAmF,uBAAuB,KAAK;AAG/G,QAAM,EAAE,UAAU,WAAW,GAAG,iBAAiB,IAAI,mBAAmB,KAAK;AAK7E,QAAM,qBAAqB;AAAA,IACzB,CAAC,UAAmC;AAClC,YAAM,SAAS,MAAM;AACrB,UAAI,CAAC,OAAQ;AACb,YAAM,oBAAoB;AAAA,QACxB,GAAG,SAAS,KAAK,iBAAiB,iBAAiB,uBAAuB,YAAY,IAAI;AAAA,MAC5F;AACA,UAAI,kBAAkB,MAAM,CAAC,YAAY,CAAC,QAAQ,SAAS,MAAM,CAAC,GAAG;AACnE,uBAAe,KAAK;AAAA,MACtB;AAAA,IACF;AAAA,IACA,CAAC,cAAc;AAAA,EACjB;AAEA,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,EACV,IAAI,mBAAmB;AAAA,IACrB,4BAA4B;AAAA,IAC5B,0BAA0B;AAAA,IAC1B,kBAAkB;AAAA,IAClB;AAAA,IACA,WAAW;AAAA,IACX;AAAA,IACA,gBAAgB;AAAA,EAClB,CAAC;AAED,SACE;AAAA,IAAC;AAAA;AAAA,MACC,eAAa,GAAG,uBAAuB,eAAe;AAAA,MACtD,UAAU;AAAA,MACV,iBAAc;AAAA,MACb,GAAG;AAAA,MACH,GAAG;AAAA,MACH,GAAG;AAAA,MACJ;AAAA,MAEC;AAAA;AAAA,QACA,2BACC;AAAA,UAAC;AAAA;AAAA,YACC,UAAU,KAAK;AAAA,YACf,QAAQ;AAAA,YACR,gBAAgB,EAAE,GAAG,gBAAgB,GAAI,WAAW,UAAa,EAAE,OAAO,EAAG;AAAA,YAC7E;AAAA,YACA,MAAK;AAAA,YACL,cAAa,oBAA+B;AAAA,YAE3C,sBAAY,oBAAC,uBAAoB,IAAK,oBAAC,uBAAoB;AAAA;AAAA,QAC9D;AAAA;AAAA;AAAA,EAEJ;AAEJ;",
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable no-unused-vars */\nimport React, { useCallback, useContext } from 'react';\nimport { useFloatingContext, FloatingWrapper } from '@elliemae/ds-floating-context';\nimport { setMultipleRefs } from '@elliemae/ds-system';\nimport { useGetGlobalAttributes, useGetXstyledProps } from '@elliemae/ds-props-helpers';\nimport { DropdownMenuDataTestId } from '../DropdownMenuDataTestId.js';\nimport { StyledTriggerWrapper } from '../styled.js';\nimport { DropdownMenuListBox } from './DropdownMenuListBox.js';\nimport { DSDropdownMenuContext } from '../DropdownMenuContext.js';\nimport { DropdownMenuLoading } from './DropdownMenuLoading.js';\n\nexport const DropdownMenuContent: React.ComponentType<Record<string, never>> = () => {\n const { props, triggerReferenceElement, setTriggerReferenceElement } = useContext(DSDropdownMenuContext);\n\n const {\n children,\n isOpened,\n onClickOutside,\n startPlacementPreference,\n placementOrderPreference,\n customOffset,\n wrapperStyles,\n isLoading,\n zIndex,\n as,\n innerRef,\n } = props;\n const {\n 'data-popover-label': dataPopoverLabel,\n ...globalAttributes\n }: ReturnType<typeof useGetGlobalAttributes> & { 'data-popover-label'?: string } = useGetGlobalAttributes(props);\n // we need to exclude this props from the xstyled props because there is a conflict\n // using submenus items with the name of the prop of ddmenu and xstyled\n const { minWidth, minHeight, ...restXstyledProps } = useGetXstyledProps(props);\n\n // Click-outside: close only when the click is not inside any child dropdown listbox.\n // The hook's onClickOutside already excludes the floating + reference elements; we add\n // a check for sibling submenu listboxes that may be portaled elsewhere in the document.\n const handleClickOutside = useCallback(\n (event: MouseEvent | TouchEvent) => {\n const target = event.target as Node | null;\n if (!target) return;\n const dropdownListboxes = [\n ...document.body.querySelectorAll(`[data-testid=\"${DropdownMenuDataTestId.MENU_WRAPPER}\"]`),\n ];\n if (dropdownListboxes.every((listbox) => !listbox.contains(target))) {\n onClickOutside(event);\n }\n },\n [onClickOutside],\n );\n\n const {\n refs,\n floatingStyles,\n context,\n isOpen: isFloatingOpen,\n } = useFloatingContext({\n externallyControlledIsOpen: isOpened,\n externalReferenceElement: triggerReferenceElement,\n withoutAnimation: true,\n customOffset,\n placement: startPlacementPreference,\n placementOrderPreference,\n onClickOutside: handleClickOutside,\n });\n\n /**\n * `setMultipleRefs`, not `mergeRefs` \u2014 `mergeRefs` skips forwarding `null`, so a consumer's\n * `innerRef` would never clear when this root unmounts or is replaced. `innerRef` is a public\n * prop now, so it needs normal ref cleanup semantics. Wrapped in an adapter because\n * `setTriggerReferenceElement`'s state is typed `HTMLDivElement | null` (this root's default\n * `as`), while the public `innerRef` is typed against the wider `HTMLElement` to match every\n * `as` this root can actually render.\n */\n const setTriggerRootRef = useCallback(\n (node: HTMLElement | null) =>\n setMultipleRefs<HTMLElement>([(el) => setTriggerReferenceElement(el as HTMLDivElement | null), innerRef])(node),\n [setTriggerReferenceElement, innerRef],\n );\n\n return (\n <StyledTriggerWrapper\n data-testid={`${DropdownMenuDataTestId.TRIGGER_WRAPPER}`}\n innerRef={setTriggerRootRef}\n aria-haspopup=\"listbox\"\n {...wrapperStyles}\n {...globalAttributes}\n {...restXstyledProps}\n as={as}\n >\n {children}\n {triggerReferenceElement && (\n <FloatingWrapper\n innerRef={refs.setFloating}\n isOpen={isFloatingOpen}\n floatingStyles={{ ...floatingStyles, ...(zIndex !== undefined && { zIndex }) }}\n context={context}\n role=\"region\"\n aria-label={(dataPopoverLabel as string) || 'dropdown-menu popover'}\n >\n {isLoading ? <DropdownMenuLoading /> : <DropdownMenuListBox />}\n </FloatingWrapper>\n )}\n </StyledTriggerWrapper>\n );\n};\n"],
5
+ "mappings": "AAAA,YAAY,WAAW;ACkFnB,SAmBmB,KAnBnB;AAjFJ,SAAgB,aAAa,kBAAkB;AAC/C,SAAS,oBAAoB,uBAAuB;AACpD,SAAS,uBAAuB;AAChC,SAAS,wBAAwB,0BAA0B;AAC3D,SAAS,8BAA8B;AACvC,SAAS,4BAA4B;AACrC,SAAS,2BAA2B;AACpC,SAAS,6BAA6B;AACtC,SAAS,2BAA2B;AAE7B,MAAM,sBAAkE,MAAM;AACnF,QAAM,EAAE,OAAO,yBAAyB,2BAA2B,IAAI,WAAW,qBAAqB;AAEvG,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AACJ,QAAM;AAAA,IACJ,sBAAsB;AAAA,IACtB,GAAG;AAAA,EACL,IAAmF,uBAAuB,KAAK;AAG/G,QAAM,EAAE,UAAU,WAAW,GAAG,iBAAiB,IAAI,mBAAmB,KAAK;AAK7E,QAAM,qBAAqB;AAAA,IACzB,CAAC,UAAmC;AAClC,YAAM,SAAS,MAAM;AACrB,UAAI,CAAC,OAAQ;AACb,YAAM,oBAAoB;AAAA,QACxB,GAAG,SAAS,KAAK,iBAAiB,iBAAiB,uBAAuB,YAAY,IAAI;AAAA,MAC5F;AACA,UAAI,kBAAkB,MAAM,CAAC,YAAY,CAAC,QAAQ,SAAS,MAAM,CAAC,GAAG;AACnE,uBAAe,KAAK;AAAA,MACtB;AAAA,IACF;AAAA,IACA,CAAC,cAAc;AAAA,EACjB;AAEA,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,EACV,IAAI,mBAAmB;AAAA,IACrB,4BAA4B;AAAA,IAC5B,0BAA0B;AAAA,IAC1B,kBAAkB;AAAA,IAClB;AAAA,IACA,WAAW;AAAA,IACX;AAAA,IACA,gBAAgB;AAAA,EAClB,CAAC;AAUD,QAAM,oBAAoB;AAAA,IACxB,CAAC,SACC,gBAA6B,CAAC,CAAC,OAAO,2BAA2B,EAA2B,GAAG,QAAQ,CAAC,EAAE,IAAI;AAAA,IAChH,CAAC,4BAA4B,QAAQ;AAAA,EACvC;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,eAAa,GAAG,uBAAuB,eAAe;AAAA,MACtD,UAAU;AAAA,MACV,iBAAc;AAAA,MACb,GAAG;AAAA,MACH,GAAG;AAAA,MACH,GAAG;AAAA,MACJ;AAAA,MAEC;AAAA;AAAA,QACA,2BACC;AAAA,UAAC;AAAA;AAAA,YACC,UAAU,KAAK;AAAA,YACf,QAAQ;AAAA,YACR,gBAAgB,EAAE,GAAG,gBAAgB,GAAI,WAAW,UAAa,EAAE,OAAO,EAAG;AAAA,YAC7E;AAAA,YACA,MAAK;AAAA,YACL,cAAa,oBAA+B;AAAA,YAE3C,sBAAY,oBAAC,uBAAoB,IAAK,oBAAC,uBAAoB;AAAA;AAAA,QAC9D;AAAA;AAAA;AAAA,EAEJ;AAEJ;",
6
6
  "names": []
7
7
  }
@@ -47,17 +47,19 @@ const Component = (props) => {
47
47
  throw new Error(`Provided option type (${type}) is not valid. Please provide one of: ${menuItemMap.join(", ")}`);
48
48
  }
49
49
  };
50
- const DropdownMenuItemFactory = ({ option, style, innerRef, optionsShouldHavePadding }) => {
50
+ const DropdownMenuItemFactory = ({ option, style, index, innerRef, optionsShouldHavePadding }) => {
51
51
  const {
52
52
  props: { selectedOptions, onOptionClick, openedSubmenus, onSubmenuToggle, onClickOutside },
53
53
  activeDescendant,
54
54
  DSDropdownMenuV2
55
55
  } = useContext(DSDropdownMenuContext);
56
56
  const { onDropdownKeyDown, ...handlers } = useDropdownMenuItemHandlers(option);
57
+ const isRecursiveDropdownItem = option.type === "submenu" || option.type === "singleWithSubmenu";
57
58
  const itemProps = useMemo(
58
59
  () => ({
59
60
  ...handlers,
60
- innerRef,
61
+ ...isRecursiveDropdownItem ? { dropdownMeasureRef: innerRef } : { innerRef },
62
+ "data-index": index,
61
63
  isActive: activeDescendant === option.dsId,
62
64
  isSelected: selectedOptions ? !!selectedOptions[option.dsId] : false,
63
65
  isSubmenuOpened: openedSubmenus ? !!openedSubmenus[option.dsId] : false,
@@ -79,6 +81,8 @@ const DropdownMenuItemFactory = ({ option, style, innerRef, optionsShouldHavePad
79
81
  [
80
82
  handlers,
81
83
  innerRef,
84
+ isRecursiveDropdownItem,
85
+ index,
82
86
  activeDescendant,
83
87
  option,
84
88
  selectedOptions,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../scripts/build/transpile/react-shim.js", "../../../src/parts/DropdownMenuItemFactory.tsx"],
4
- "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "import React, { useContext, useMemo } from 'react';\nimport {\n ActionMenuItem,\n SingleMenuItem,\n MultiMenuItem,\n SubmenuItem,\n Separator,\n Section,\n SingleWithSubmenuItem,\n SkeletonMenuItem,\n} from '@elliemae/ds-menu-items';\nimport type { DSDropdownMenuT } from '../react-desc-prop-types.js';\nimport { DSDropdownMenuContext } from '../DropdownMenuContext.js';\nimport { useDropdownMenuItemHandlers } from '../hooks/index.js';\n\nconst menuItemMap = [\n 'action',\n 'single',\n 'checkbox',\n 'submenu',\n 'separator',\n 'section',\n 'singleWithSubmenu',\n 'skeleton',\n] as const;\n\nconst Component = (props: DSDropdownMenuT.Item) => {\n const { type } = props;\n switch (type) {\n case 'action':\n return <ActionMenuItem {...props} />;\n case 'single':\n return <SingleMenuItem {...props} />;\n case 'checkbox':\n return <MultiMenuItem {...props} />;\n case 'submenu':\n return <SubmenuItem {...props} />;\n case 'separator':\n return <Separator {...props} />;\n case 'section':\n return <Section {...props} />;\n case 'singleWithSubmenu':\n return <SingleWithSubmenuItem {...props} />;\n case 'skeleton':\n return <SkeletonMenuItem {...props} />;\n default:\n // The purpose of 'UnexpectedOptionType' is to make sure that whenever we reach the default case, the type must be never\n // If it isn't, we forgot to add a case for a new option type that was added to DSDropdownMenuT.Item\n // this way tslint will be used to catch this mistake\n // eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars, no-case-declarations\n const UnexpectedOptionType: never = type;\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions,\n throw new Error(`Provided option type (${type}) is not valid. Please provide one of: ${menuItemMap.join(', ')}`);\n }\n};\n\nexport const DropdownMenuItemFactory: React.ComponentType<{\n option: DSDropdownMenuT.Item;\n style?: Record<string, unknown>;\n innerRef?: (el: HTMLElement) => void;\n optionsShouldHavePadding: boolean;\n}> = ({ option, style, innerRef, optionsShouldHavePadding }): JSX.Element => {\n const {\n props: { selectedOptions, onOptionClick, openedSubmenus, onSubmenuToggle, onClickOutside },\n activeDescendant,\n DSDropdownMenuV2,\n } = useContext(DSDropdownMenuContext);\n\n const { onDropdownKeyDown, ...handlers } = useDropdownMenuItemHandlers(option);\n\n const itemProps = useMemo(\n () => ({\n ...handlers,\n innerRef,\n isActive: activeDescendant === option.dsId,\n isSelected: selectedOptions ? !!selectedOptions[option.dsId] : false,\n isSubmenuOpened: openedSubmenus ? !!openedSubmenus[option.dsId] : false,\n tabIndex: -1 as const,\n optionsShouldHavePadding,\n wrapperStyles: style,\n Dropdown: DSDropdownMenuV2,\n dropdownProps: {\n ...option,\n options: option.type === 'submenu' || option.type === 'singleWithSubmenu' ? option.options : [],\n onClickOutside,\n onOptionClick,\n onSubmenuToggle,\n selectedOptions,\n openedSubmenus,\n onKeyDown: onDropdownKeyDown,\n },\n }),\n [\n handlers,\n innerRef,\n activeDescendant,\n option,\n selectedOptions,\n openedSubmenus,\n optionsShouldHavePadding,\n style,\n DSDropdownMenuV2,\n onClickOutside,\n onOptionClick,\n onSubmenuToggle,\n onDropdownKeyDown,\n ],\n );\n\n return <Component {...option} {...itemProps} />;\n};\n"],
5
- "mappings": "AAAA,YAAY,WAAW;AC8BV;AA9Bb,SAAgB,YAAY,eAAe;AAC3C;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP,SAAS,6BAA6B;AACtC,SAAS,mCAAmC;AAE5C,MAAM,cAAc;AAAA,EAClB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,MAAM,YAAY,CAAC,UAAgC;AACjD,QAAM,EAAE,KAAK,IAAI;AACjB,UAAQ,MAAM;AAAA,IACZ,KAAK;AACH,aAAO,oBAAC,kBAAgB,GAAG,OAAO;AAAA,IACpC,KAAK;AACH,aAAO,oBAAC,kBAAgB,GAAG,OAAO;AAAA,IACpC,KAAK;AACH,aAAO,oBAAC,iBAAe,GAAG,OAAO;AAAA,IACnC,KAAK;AACH,aAAO,oBAAC,eAAa,GAAG,OAAO;AAAA,IACjC,KAAK;AACH,aAAO,oBAAC,aAAW,GAAG,OAAO;AAAA,IAC/B,KAAK;AACH,aAAO,oBAAC,WAAS,GAAG,OAAO;AAAA,IAC7B,KAAK;AACH,aAAO,oBAAC,yBAAuB,GAAG,OAAO;AAAA,IAC3C,KAAK;AACH,aAAO,oBAAC,oBAAkB,GAAG,OAAO;AAAA,IACtC;AAKE,YAAM,uBAA8B;AAEpC,YAAM,IAAI,MAAM,yBAAyB,IAAI,0CAA0C,YAAY,KAAK,IAAI,CAAC,EAAE;AAAA,EACnH;AACF;AAEO,MAAM,0BAKR,CAAC,EAAE,QAAQ,OAAO,UAAU,yBAAyB,MAAmB;AAC3E,QAAM;AAAA,IACJ,OAAO,EAAE,iBAAiB,eAAe,gBAAgB,iBAAiB,eAAe;AAAA,IACzF;AAAA,IACA;AAAA,EACF,IAAI,WAAW,qBAAqB;AAEpC,QAAM,EAAE,mBAAmB,GAAG,SAAS,IAAI,4BAA4B,MAAM;AAE7E,QAAM,YAAY;AAAA,IAChB,OAAO;AAAA,MACL,GAAG;AAAA,MACH;AAAA,MACA,UAAU,qBAAqB,OAAO;AAAA,MACtC,YAAY,kBAAkB,CAAC,CAAC,gBAAgB,OAAO,IAAI,IAAI;AAAA,MAC/D,iBAAiB,iBAAiB,CAAC,CAAC,eAAe,OAAO,IAAI,IAAI;AAAA,MAClE,UAAU;AAAA,MACV;AAAA,MACA,eAAe;AAAA,MACf,UAAU;AAAA,MACV,eAAe;AAAA,QACb,GAAG;AAAA,QACH,SAAS,OAAO,SAAS,aAAa,OAAO,SAAS,sBAAsB,OAAO,UAAU,CAAC;AAAA,QAC9F;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,WAAW;AAAA,MACb;AAAA,IACF;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,SAAO,oBAAC,aAAW,GAAG,QAAS,GAAG,WAAW;AAC/C;",
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "import React, { useContext, useMemo } from 'react';\nimport {\n ActionMenuItem,\n SingleMenuItem,\n MultiMenuItem,\n SubmenuItem,\n Separator,\n Section,\n SingleWithSubmenuItem,\n SkeletonMenuItem,\n} from '@elliemae/ds-menu-items';\nimport type { DSDropdownMenuT } from '../react-desc-prop-types.js';\nimport { DSDropdownMenuContext } from '../DropdownMenuContext.js';\nimport { useDropdownMenuItemHandlers } from '../hooks/index.js';\n\nconst menuItemMap = [\n 'action',\n 'single',\n 'checkbox',\n 'submenu',\n 'separator',\n 'section',\n 'singleWithSubmenu',\n 'skeleton',\n] as const;\n\nconst Component = (props: DSDropdownMenuT.Item) => {\n const { type } = props;\n switch (type) {\n case 'action':\n return <ActionMenuItem {...props} />;\n case 'single':\n return <SingleMenuItem {...props} />;\n case 'checkbox':\n return <MultiMenuItem {...props} />;\n case 'submenu':\n return <SubmenuItem {...props} />;\n case 'separator':\n return <Separator {...props} />;\n case 'section':\n return <Section {...props} />;\n case 'singleWithSubmenu':\n return <SingleWithSubmenuItem {...props} />;\n case 'skeleton':\n return <SkeletonMenuItem {...props} />;\n default:\n // The purpose of 'UnexpectedOptionType' is to make sure that whenever we reach the default case, the type must be never\n // If it isn't, we forgot to add a case for a new option type that was added to DSDropdownMenuT.Item\n // this way tslint will be used to catch this mistake\n // eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars, no-case-declarations\n const UnexpectedOptionType: never = type;\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions,\n throw new Error(`Provided option type (${type}) is not valid. Please provide one of: ${menuItemMap.join(', ')}`);\n }\n};\n\nexport const DropdownMenuItemFactory: React.ComponentType<{\n option: DSDropdownMenuT.Item;\n style?: Record<string, unknown>;\n index: number;\n innerRef?: (el: HTMLElement) => void;\n optionsShouldHavePadding: boolean;\n}> = ({ option, style, index, innerRef, optionsShouldHavePadding }): JSX.Element => {\n const {\n props: { selectedOptions, onOptionClick, openedSubmenus, onSubmenuToggle, onClickOutside },\n activeDescendant,\n DSDropdownMenuV2,\n } = useContext(DSDropdownMenuContext);\n\n const { onDropdownKeyDown, ...handlers } = useDropdownMenuItemHandlers(option);\n\n /**\n * `submenu`/`singleWithSubmenu` render a recursive `DSDropdownMenuV2` as their own outer,\n * absolutely-positioned root \u2014 the one the virtualizer actually needs to measure \u2014 while their\n * OWN pre-existing public `innerRef` prop targets a different, inner node\n * (`StyledGlobalMenuItemWrapper`) and must keep doing so unchanged (it predates this migration).\n * So the shared measurement ref goes through a separate, internal-only `dropdownMeasureRef` key\n * for these two types only; every other type still measures through its own `innerRef`, exactly\n * as before \u2014 there's only one rendered root there, no ref to preserve separately.\n */\n const isRecursiveDropdownItem = option.type === 'submenu' || option.type === 'singleWithSubmenu';\n\n const itemProps = useMemo(\n () => ({\n ...handlers,\n ...(isRecursiveDropdownItem ? { dropdownMeasureRef: innerRef } : { innerRef }),\n 'data-index': index,\n isActive: activeDescendant === option.dsId,\n isSelected: selectedOptions ? !!selectedOptions[option.dsId] : false,\n isSubmenuOpened: openedSubmenus ? !!openedSubmenus[option.dsId] : false,\n tabIndex: -1 as const,\n optionsShouldHavePadding,\n wrapperStyles: style,\n Dropdown: DSDropdownMenuV2,\n dropdownProps: {\n ...option,\n options: option.type === 'submenu' || option.type === 'singleWithSubmenu' ? option.options : [],\n onClickOutside,\n onOptionClick,\n onSubmenuToggle,\n selectedOptions,\n openedSubmenus,\n onKeyDown: onDropdownKeyDown,\n },\n }),\n [\n handlers,\n innerRef,\n isRecursiveDropdownItem,\n index,\n activeDescendant,\n option,\n selectedOptions,\n openedSubmenus,\n optionsShouldHavePadding,\n style,\n DSDropdownMenuV2,\n onClickOutside,\n onOptionClick,\n onSubmenuToggle,\n onDropdownKeyDown,\n ],\n );\n\n return <Component {...option} {...itemProps} />;\n};\n"],
5
+ "mappings": "AAAA,YAAY,WAAW;AC8BV;AA9Bb,SAAgB,YAAY,eAAe;AAC3C;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP,SAAS,6BAA6B;AACtC,SAAS,mCAAmC;AAE5C,MAAM,cAAc;AAAA,EAClB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,MAAM,YAAY,CAAC,UAAgC;AACjD,QAAM,EAAE,KAAK,IAAI;AACjB,UAAQ,MAAM;AAAA,IACZ,KAAK;AACH,aAAO,oBAAC,kBAAgB,GAAG,OAAO;AAAA,IACpC,KAAK;AACH,aAAO,oBAAC,kBAAgB,GAAG,OAAO;AAAA,IACpC,KAAK;AACH,aAAO,oBAAC,iBAAe,GAAG,OAAO;AAAA,IACnC,KAAK;AACH,aAAO,oBAAC,eAAa,GAAG,OAAO;AAAA,IACjC,KAAK;AACH,aAAO,oBAAC,aAAW,GAAG,OAAO;AAAA,IAC/B,KAAK;AACH,aAAO,oBAAC,WAAS,GAAG,OAAO;AAAA,IAC7B,KAAK;AACH,aAAO,oBAAC,yBAAuB,GAAG,OAAO;AAAA,IAC3C,KAAK;AACH,aAAO,oBAAC,oBAAkB,GAAG,OAAO;AAAA,IACtC;AAKE,YAAM,uBAA8B;AAEpC,YAAM,IAAI,MAAM,yBAAyB,IAAI,0CAA0C,YAAY,KAAK,IAAI,CAAC,EAAE;AAAA,EACnH;AACF;AAEO,MAAM,0BAMR,CAAC,EAAE,QAAQ,OAAO,OAAO,UAAU,yBAAyB,MAAmB;AAClF,QAAM;AAAA,IACJ,OAAO,EAAE,iBAAiB,eAAe,gBAAgB,iBAAiB,eAAe;AAAA,IACzF;AAAA,IACA;AAAA,EACF,IAAI,WAAW,qBAAqB;AAEpC,QAAM,EAAE,mBAAmB,GAAG,SAAS,IAAI,4BAA4B,MAAM;AAW7E,QAAM,0BAA0B,OAAO,SAAS,aAAa,OAAO,SAAS;AAE7E,QAAM,YAAY;AAAA,IAChB,OAAO;AAAA,MACL,GAAG;AAAA,MACH,GAAI,0BAA0B,EAAE,oBAAoB,SAAS,IAAI,EAAE,SAAS;AAAA,MAC5E,cAAc;AAAA,MACd,UAAU,qBAAqB,OAAO;AAAA,MACtC,YAAY,kBAAkB,CAAC,CAAC,gBAAgB,OAAO,IAAI,IAAI;AAAA,MAC/D,iBAAiB,iBAAiB,CAAC,CAAC,eAAe,OAAO,IAAI,IAAI;AAAA,MAClE,UAAU;AAAA,MACV;AAAA,MACA,eAAe;AAAA,MACf,UAAU;AAAA,MACV,eAAe;AAAA,QACb,GAAG;AAAA,QACH,SAAS,OAAO,SAAS,aAAa,OAAO,SAAS,sBAAsB,OAAO,UAAU,CAAC;AAAA,QAC9F;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,WAAW;AAAA,MACb;AAAA,IACF;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,SAAO,oBAAC,aAAW,GAAG,QAAS,GAAG,WAAW;AAC/C;",
6
6
  "names": []
7
7
  }
@@ -27,8 +27,11 @@ const DropdownMenuListBox = () => {
27
27
  activeDescendant,
28
28
  listboxReference,
29
29
  inputReference,
30
- virtualListHelpers: { totalSize, virtualItems }
30
+ virtualListHelpers
31
31
  } = ctx;
32
+ const totalSize = virtualListHelpers.getTotalSize();
33
+ const virtualItems = virtualListHelpers.getVirtualItems();
34
+ const { measureElement } = virtualListHelpers;
32
35
  useAutofocusContainerOnOpen();
33
36
  const { onKeyDown, onMouseEnter, onMouseLeave } = useDropdownListboxHandlers();
34
37
  const { optionsShouldHavePadding } = useGetOptionSpecialAttributes();
@@ -37,7 +40,7 @@ const DropdownMenuListBox = () => {
37
40
  [triggerReferenceElement?.offsetWidth, userMinWidth]
38
41
  );
39
42
  return useMemo(() => {
40
- if (virtualItems.length === 0) {
43
+ if (options.length === 0) {
41
44
  return /* @__PURE__ */ jsx(DropdownMenuEmptyState, { minWidth, maxHeight: userMaxHeight || 400 });
42
45
  }
43
46
  return /* @__PURE__ */ jsx(
@@ -68,7 +71,8 @@ const DropdownMenuListBox = () => {
68
71
  {
69
72
  option: options[vItem.index],
70
73
  style: { position: "absolute", top: vItem.start, left: 0, width: "100%" },
71
- innerRef: vItem.measureRef,
74
+ index: vItem.index,
75
+ innerRef: measureElement,
72
76
  optionsShouldHavePadding
73
77
  },
74
78
  `dropdown-listbox-option-${options[vItem.index].dsId}`
@@ -87,6 +91,7 @@ const DropdownMenuListBox = () => {
87
91
  inputValue,
88
92
  isSkeleton,
89
93
  listboxReference,
94
+ measureElement,
90
95
  minWidth,
91
96
  onInputChange,
92
97
  onKeyDown,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../scripts/build/transpile/react-shim.js", "../../../src/parts/DropdownMenuListBox.tsx"],
4
- "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "import React, { useContext, useMemo } from 'react';\nimport { DSInputText } from '@elliemae/ds-form-input-text';\nimport { DSDropdownMenuContext } from '../DropdownMenuContext.js';\nimport { DropdownMenuDataTestId } from '../DropdownMenuDataTestId.js';\nimport { useDropdownListboxHandlers } from '../hooks/useDropdownListboxHandlers.js';\nimport { StyledInputWrapper, StyledListBoxWrapper, StyledHeaderWrapper, StyledOptionListWrapper } from '../styled.js';\nimport { DropdownMenuEmptyState } from './DropdownMenuEmptyState.js';\nimport { DropdownMenuItemFactory } from './DropdownMenuItemFactory.js';\nimport { DropdownMenuSkeleton } from './DropdownMenuSkeleton.js';\n\nimport { useAutofocusContainerOnOpen, useGetOptionSpecialAttributes } from '../hooks/index.js';\n\nexport const DropdownMenuListBox: React.ComponentType<Record<string, never>> = () => {\n const ctx = useContext(DSDropdownMenuContext);\n const {\n triggerReferenceElement,\n props: {\n isSkeleton,\n options,\n hasInput,\n inputValue,\n onInputChange,\n HeaderComp,\n minWidth: userMinWidth,\n maxHeight: userMaxHeight,\n },\n activeDescendant,\n listboxReference,\n inputReference,\n virtualListHelpers: { totalSize, virtualItems },\n } = ctx;\n\n useAutofocusContainerOnOpen();\n\n const { onKeyDown, onMouseEnter, onMouseLeave } = useDropdownListboxHandlers();\n\n const { optionsShouldHavePadding } = useGetOptionSpecialAttributes();\n\n const minWidth = useMemo(\n () => (userMinWidth !== undefined ? userMinWidth : Math.max(triggerReferenceElement?.offsetWidth ?? 0, 162)),\n [triggerReferenceElement?.offsetWidth, userMinWidth],\n );\n\n return useMemo(() => {\n if (virtualItems.length === 0) {\n return <DropdownMenuEmptyState minWidth={minWidth} maxHeight={userMaxHeight || 400} />;\n }\n return (\n <StyledListBoxWrapper\n minWidth={minWidth}\n maxHeight={userMaxHeight || 400}\n innerRef={listboxReference}\n tabIndex={0}\n data-testid={DropdownMenuDataTestId.MENU_WRAPPER}\n onKeyDown={onKeyDown}\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n hasHeader={!!HeaderComp}\n >\n {isSkeleton ? (\n <DropdownMenuSkeleton />\n ) : (\n <>\n {HeaderComp && (\n <StyledHeaderWrapper alignItems=\"center\">\n <HeaderComp ctx={ctx} />\n </StyledHeaderWrapper>\n )}\n {hasInput && (\n <StyledInputWrapper key=\"dropdown-listbox-input-wrapper\" hasHeader={!!HeaderComp}>\n <DSInputText value={inputValue} onChange={onInputChange} innerRef={inputReference} />\n </StyledInputWrapper>\n )}\n <StyledOptionListWrapper\n aria-activedescendant={activeDescendant}\n data-testid={DropdownMenuDataTestId.LISTBOX}\n role=\"listbox\"\n aria-label=\"List of options\"\n style={{ height: totalSize || 16 }}\n >\n {virtualItems.map((vItem) => (\n <DropdownMenuItemFactory\n option={options[vItem.index]}\n style={{ position: 'absolute', top: vItem.start, left: 0, width: '100%' }}\n key={`dropdown-listbox-option-${options[vItem.index].dsId}`}\n innerRef={vItem.measureRef}\n optionsShouldHavePadding={optionsShouldHavePadding}\n />\n ))}\n </StyledOptionListWrapper>\n </>\n )}\n </StyledListBoxWrapper>\n );\n }, [\n HeaderComp,\n activeDescendant,\n ctx,\n hasInput,\n inputReference,\n inputValue,\n isSkeleton,\n listboxReference,\n minWidth,\n onInputChange,\n onKeyDown,\n onMouseEnter,\n onMouseLeave,\n options,\n optionsShouldHavePadding,\n totalSize,\n userMaxHeight,\n virtualItems,\n ]);\n};\n"],
5
- "mappings": "AAAA,YAAY,WAAW;AC6CV,SAiBH,UAjBG,KAiBH,YAjBG;AA7Cb,SAAgB,YAAY,eAAe;AAC3C,SAAS,mBAAmB;AAC5B,SAAS,6BAA6B;AACtC,SAAS,8BAA8B;AACvC,SAAS,kCAAkC;AAC3C,SAAS,oBAAoB,sBAAsB,qBAAqB,+BAA+B;AACvG,SAAS,8BAA8B;AACvC,SAAS,+BAA+B;AACxC,SAAS,4BAA4B;AAErC,SAAS,6BAA6B,qCAAqC;AAEpE,MAAM,sBAAkE,MAAM;AACnF,QAAM,MAAM,WAAW,qBAAqB;AAC5C,QAAM;AAAA,IACJ;AAAA,IACA,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,UAAU;AAAA,MACV,WAAW;AAAA,IACb;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,oBAAoB,EAAE,WAAW,aAAa;AAAA,EAChD,IAAI;AAEJ,8BAA4B;AAE5B,QAAM,EAAE,WAAW,cAAc,aAAa,IAAI,2BAA2B;AAE7E,QAAM,EAAE,yBAAyB,IAAI,8BAA8B;AAEnE,QAAM,WAAW;AAAA,IACf,MAAO,iBAAiB,SAAY,eAAe,KAAK,IAAI,yBAAyB,eAAe,GAAG,GAAG;AAAA,IAC1G,CAAC,yBAAyB,aAAa,YAAY;AAAA,EACrD;AAEA,SAAO,QAAQ,MAAM;AACnB,QAAI,aAAa,WAAW,GAAG;AAC7B,aAAO,oBAAC,0BAAuB,UAAoB,WAAW,iBAAiB,KAAK;AAAA,IACtF;AACA,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,WAAW,iBAAiB;AAAA,QAC5B,UAAU;AAAA,QACV,UAAU;AAAA,QACV,eAAa,uBAAuB;AAAA,QACpC;AAAA,QACA;AAAA,QACA;AAAA,QACA,WAAW,CAAC,CAAC;AAAA,QAEZ,uBACC,oBAAC,wBAAqB,IAEtB,iCACG;AAAA,wBACC,oBAAC,uBAAoB,YAAW,UAC9B,8BAAC,cAAW,KAAU,GACxB;AAAA,UAED,YACC,oBAAC,sBAAwD,WAAW,CAAC,CAAC,YACpE,8BAAC,eAAY,OAAO,YAAY,UAAU,eAAe,UAAU,gBAAgB,KAD7D,gCAExB;AAAA,UAEF;AAAA,YAAC;AAAA;AAAA,cACC,yBAAuB;AAAA,cACvB,eAAa,uBAAuB;AAAA,cACpC,MAAK;AAAA,cACL,cAAW;AAAA,cACX,OAAO,EAAE,QAAQ,aAAa,GAAG;AAAA,cAEhC,uBAAa,IAAI,CAAC,UACjB;AAAA,gBAAC;AAAA;AAAA,kBACC,QAAQ,QAAQ,MAAM,KAAK;AAAA,kBAC3B,OAAO,EAAE,UAAU,YAAY,KAAK,MAAM,OAAO,MAAM,GAAG,OAAO,OAAO;AAAA,kBAExE,UAAU,MAAM;AAAA,kBAChB;AAAA;AAAA,gBAFK,2BAA2B,QAAQ,MAAM,KAAK,EAAE,IAAI;AAAA,cAG3D,CACD;AAAA;AAAA,UACH;AAAA,WACF;AAAA;AAAA,IAEJ;AAAA,EAEJ,GAAG;AAAA,IACD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AACH;",
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "import React, { useContext, useMemo } from 'react';\nimport { DSInputText } from '@elliemae/ds-form-input-text';\nimport { DSDropdownMenuContext } from '../DropdownMenuContext.js';\nimport { DropdownMenuDataTestId } from '../DropdownMenuDataTestId.js';\nimport { useDropdownListboxHandlers } from '../hooks/useDropdownListboxHandlers.js';\nimport { StyledInputWrapper, StyledListBoxWrapper, StyledHeaderWrapper, StyledOptionListWrapper } from '../styled.js';\nimport { DropdownMenuEmptyState } from './DropdownMenuEmptyState.js';\nimport { DropdownMenuItemFactory } from './DropdownMenuItemFactory.js';\nimport { DropdownMenuSkeleton } from './DropdownMenuSkeleton.js';\n\nimport { useAutofocusContainerOnOpen, useGetOptionSpecialAttributes } from '../hooks/index.js';\n\nexport const DropdownMenuListBox: React.ComponentType<Record<string, never>> = () => {\n const ctx = useContext(DSDropdownMenuContext);\n const {\n triggerReferenceElement,\n props: {\n isSkeleton,\n options,\n hasInput,\n inputValue,\n onInputChange,\n HeaderComp,\n minWidth: userMinWidth,\n maxHeight: userMaxHeight,\n },\n activeDescendant,\n listboxReference,\n inputReference,\n virtualListHelpers,\n } = ctx;\n\n const totalSize = virtualListHelpers.getTotalSize();\n const virtualItems = virtualListHelpers.getVirtualItems();\n const { measureElement } = virtualListHelpers;\n\n useAutofocusContainerOnOpen();\n\n const { onKeyDown, onMouseEnter, onMouseLeave } = useDropdownListboxHandlers();\n\n const { optionsShouldHavePadding } = useGetOptionSpecialAttributes();\n\n const minWidth = useMemo(\n () => (userMinWidth !== undefined ? userMinWidth : Math.max(triggerReferenceElement?.offsetWidth ?? 0, 162)),\n [triggerReferenceElement?.offsetWidth, userMinWidth],\n );\n\n return useMemo(() => {\n /**\n * Gated on `options.length`, not `virtualItems.length`. v3's `getVirtualItems()` is empty\n * until the scroll element has been measured (`outerSize > 0` in @tanstack/virtual-core's\n * `calculateRange`), and the scroll element only gets measured once `listboxReference`\n * attaches to a real DOM node \u2014 which only happens inside the non-empty branch below. Gating\n * on `virtualItems.length` instead would mean: on the very first render (before any\n * measurement), fall into the empty-state branch, never attach `listboxReference`, and never\n * get a chance to measure \u2014 permanently stuck on \"No content available\" even with options.\n */\n if (options.length === 0) {\n return <DropdownMenuEmptyState minWidth={minWidth} maxHeight={userMaxHeight || 400} />;\n }\n return (\n <StyledListBoxWrapper\n minWidth={minWidth}\n maxHeight={userMaxHeight || 400}\n innerRef={listboxReference}\n tabIndex={0}\n data-testid={DropdownMenuDataTestId.MENU_WRAPPER}\n onKeyDown={onKeyDown}\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n hasHeader={!!HeaderComp}\n >\n {isSkeleton ? (\n <DropdownMenuSkeleton />\n ) : (\n <>\n {HeaderComp && (\n <StyledHeaderWrapper alignItems=\"center\">\n <HeaderComp ctx={ctx} />\n </StyledHeaderWrapper>\n )}\n {hasInput && (\n <StyledInputWrapper key=\"dropdown-listbox-input-wrapper\" hasHeader={!!HeaderComp}>\n <DSInputText value={inputValue} onChange={onInputChange} innerRef={inputReference} />\n </StyledInputWrapper>\n )}\n <StyledOptionListWrapper\n aria-activedescendant={activeDescendant}\n data-testid={DropdownMenuDataTestId.LISTBOX}\n role=\"listbox\"\n aria-label=\"List of options\"\n style={{ height: totalSize || 16 }}\n >\n {virtualItems.map((vItem) => (\n <DropdownMenuItemFactory\n option={options[vItem.index]}\n style={{ position: 'absolute', top: vItem.start, left: 0, width: '100%' }}\n key={`dropdown-listbox-option-${options[vItem.index].dsId}`}\n index={vItem.index}\n innerRef={measureElement}\n optionsShouldHavePadding={optionsShouldHavePadding}\n />\n ))}\n </StyledOptionListWrapper>\n </>\n )}\n </StyledListBoxWrapper>\n );\n }, [\n HeaderComp,\n activeDescendant,\n ctx,\n hasInput,\n inputReference,\n inputValue,\n isSkeleton,\n listboxReference,\n measureElement,\n minWidth,\n onInputChange,\n onKeyDown,\n onMouseEnter,\n onMouseLeave,\n options,\n optionsShouldHavePadding,\n totalSize,\n userMaxHeight,\n virtualItems,\n ]);\n};\n"],
5
+ "mappings": "AAAA,YAAY,WAAW;AC0DV,SAiBH,UAjBG,KAiBH,YAjBG;AA1Db,SAAgB,YAAY,eAAe;AAC3C,SAAS,mBAAmB;AAC5B,SAAS,6BAA6B;AACtC,SAAS,8BAA8B;AACvC,SAAS,kCAAkC;AAC3C,SAAS,oBAAoB,sBAAsB,qBAAqB,+BAA+B;AACvG,SAAS,8BAA8B;AACvC,SAAS,+BAA+B;AACxC,SAAS,4BAA4B;AAErC,SAAS,6BAA6B,qCAAqC;AAEpE,MAAM,sBAAkE,MAAM;AACnF,QAAM,MAAM,WAAW,qBAAqB;AAC5C,QAAM;AAAA,IACJ;AAAA,IACA,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,UAAU;AAAA,MACV,WAAW;AAAA,IACb;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AAEJ,QAAM,YAAY,mBAAmB,aAAa;AAClD,QAAM,eAAe,mBAAmB,gBAAgB;AACxD,QAAM,EAAE,eAAe,IAAI;AAE3B,8BAA4B;AAE5B,QAAM,EAAE,WAAW,cAAc,aAAa,IAAI,2BAA2B;AAE7E,QAAM,EAAE,yBAAyB,IAAI,8BAA8B;AAEnE,QAAM,WAAW;AAAA,IACf,MAAO,iBAAiB,SAAY,eAAe,KAAK,IAAI,yBAAyB,eAAe,GAAG,GAAG;AAAA,IAC1G,CAAC,yBAAyB,aAAa,YAAY;AAAA,EACrD;AAEA,SAAO,QAAQ,MAAM;AAUnB,QAAI,QAAQ,WAAW,GAAG;AACxB,aAAO,oBAAC,0BAAuB,UAAoB,WAAW,iBAAiB,KAAK;AAAA,IACtF;AACA,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,WAAW,iBAAiB;AAAA,QAC5B,UAAU;AAAA,QACV,UAAU;AAAA,QACV,eAAa,uBAAuB;AAAA,QACpC;AAAA,QACA;AAAA,QACA;AAAA,QACA,WAAW,CAAC,CAAC;AAAA,QAEZ,uBACC,oBAAC,wBAAqB,IAEtB,iCACG;AAAA,wBACC,oBAAC,uBAAoB,YAAW,UAC9B,8BAAC,cAAW,KAAU,GACxB;AAAA,UAED,YACC,oBAAC,sBAAwD,WAAW,CAAC,CAAC,YACpE,8BAAC,eAAY,OAAO,YAAY,UAAU,eAAe,UAAU,gBAAgB,KAD7D,gCAExB;AAAA,UAEF;AAAA,YAAC;AAAA;AAAA,cACC,yBAAuB;AAAA,cACvB,eAAa,uBAAuB;AAAA,cACpC,MAAK;AAAA,cACL,cAAW;AAAA,cACX,OAAO,EAAE,QAAQ,aAAa,GAAG;AAAA,cAEhC,uBAAa,IAAI,CAAC,UACjB;AAAA,gBAAC;AAAA;AAAA,kBACC,QAAQ,QAAQ,MAAM,KAAK;AAAA,kBAC3B,OAAO,EAAE,UAAU,YAAY,KAAK,MAAM,OAAO,MAAM,GAAG,OAAO,OAAO;AAAA,kBAExE,OAAO,MAAM;AAAA,kBACb,UAAU;AAAA,kBACV;AAAA;AAAA,gBAHK,2BAA2B,QAAQ,MAAM,KAAK,EAAE,IAAI;AAAA,cAI3D,CACD;AAAA;AAAA,UACH;AAAA,WACF;AAAA;AAAA,IAEJ;AAAA,EAEJ,GAAG;AAAA,IACD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AACH;",
6
6
  "names": []
7
7
  }
@@ -106,7 +106,13 @@ const DSDropdownMenuV2PropTypes = {
106
106
  onKeyDown: PropTypes.func.description("Callback executed when a key is pressed").defaultValue(() => null),
107
107
  onMouseEnter: PropTypes.func.description("Callback executed when the mouse enter the dropdown menu").defaultValue(() => null),
108
108
  onMouseLeave: PropTypes.func.description("Callback executed when the mouse leaves the dropdown menu").defaultValue(() => null),
109
- isSkeleton: PropTypes.bool.description("Whether the dropdown menu should render the skeleton").defaultValue(false)
109
+ isSkeleton: PropTypes.bool.description("Whether the dropdown menu should render the skeleton").defaultValue(false),
110
+ innerRef: PropTypes.oneOfType([
111
+ PropTypes.shape({
112
+ current: PropTypes.node
113
+ }),
114
+ PropTypes.func.description("A ref object or callback function to access the dropdown menu root DOM element.")
115
+ ]).defaultValue(`(() => {})`)
110
116
  };
111
117
  const defaultProps = {
112
118
  onClickOutside: () => null,
@@ -128,7 +134,9 @@ const defaultProps = {
128
134
  wrapperStyles: {},
129
135
  actionRef: { current: {} },
130
136
  as: "div",
131
- isSkeleton: false
137
+ isSkeleton: false,
138
+ innerRef: () => {
139
+ }
132
140
  };
133
141
  export {
134
142
  DSDropdownMenuV2PropTypes,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../scripts/build/transpile/react-shim.js", "../../src/react-desc-prop-types.ts"],
4
- "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable max-lines */\nimport type React from 'react';\nimport type { useVirtual } from 'react-virtual';\nimport {\n type GlobalAttributesT,\n PropTypes,\n type XstyledProps,\n globalAttributesPropTypes,\n type ValidationMap,\n} from '@elliemae/ds-props-helpers';\nimport type { SizingProps } from '@elliemae/ds-system';\n\nexport namespace DSDropdownMenuT {\n export type PopperPlacementsT =\n | 'top-start'\n | 'top'\n | 'top-end'\n | 'right-start'\n | 'right'\n | 'right-end'\n | 'bottom-end'\n | 'bottom'\n | 'bottom-start'\n | 'left-end'\n | 'left'\n | 'left-start';\n\n export interface RequiredProps {\n options: Item[] | readonly Item[];\n isOpened: boolean;\n }\n\n export interface DefaultProps {\n onClickOutside: (e: MouseEvent | React.KeyboardEvent | TouchEvent) => void;\n onKeyDown: React.KeyboardEventHandler;\n onMouseEnter: React.MouseEventHandler;\n onMouseLeave: React.MouseEventHandler;\n selectedOptions: Record<string, boolean>;\n onOptionClick: (\n nextSelectedOptions: Record<string, boolean>,\n clickedOption: Item,\n e: React.MouseEvent | React.KeyboardEvent,\n ) => void;\n openedSubmenus: Record<string, boolean>;\n onSubmenuToggle: (\n nextOpenedSubmenus: Record<string, boolean>,\n submenu: Item,\n e: React.MouseEvent | React.KeyboardEvent,\n ) => void;\n isLoading: boolean;\n hasInput: boolean;\n inputValue: string;\n inputPlaceholder: string;\n onInputChange: React.FormEventHandler<HTMLInputElement>;\n startPlacementPreference: PopperPlacementsT;\n placementOrderPreference: PopperPlacementsT[];\n customOffset: [number, number];\n wrapperStyles: Record<string, unknown>;\n actionRef: React.MutableRefObject<Record<string, unknown>>;\n as: keyof React.JSX.IntrinsicElements;\n children?: React.ReactNode;\n isSkeleton: boolean;\n }\n\n export interface OptionalProps {\n zIndex?: number;\n minWidth?: SizingProps['minWidth'];\n maxHeight?: SizingProps['maxHeight'];\n HeaderComp?: React.ComponentType<{ ctx?: DSDropdownMenuT.CTX }>;\n }\n\n export interface Props\n extends Partial<DefaultProps>,\n OptionalProps,\n Omit<GlobalAttributesT<HTMLButtonElement>, keyof DefaultProps | keyof OptionalProps | keyof RequiredProps>,\n Omit<XstyledProps, 'zIndex'>,\n RequiredProps {}\n\n export interface InternalProps\n extends DefaultProps,\n OptionalProps,\n Omit<GlobalAttributesT<HTMLButtonElement>, keyof DefaultProps | keyof OptionalProps | keyof RequiredProps>,\n Omit<XstyledProps, 'zIndex'>,\n RequiredProps {}\n\n export interface CTX {\n props: React.PropsWithChildren<InternalProps>;\n triggerReferenceElement: HTMLDivElement | null;\n setTriggerReferenceElement: React.Dispatch<React.SetStateAction<HTMLDivElement | null>>;\n listboxReference: React.RefObject<HTMLDivElement>;\n inputReference: React.RefObject<HTMLInputElement>;\n activeDescendant: string;\n setActiveDescendant: React.Dispatch<React.SetStateAction<string>>;\n scrollOptionIntoView: (dsId: string) => void;\n virtualListHelpers: ReturnType<typeof useVirtual>;\n DSDropdownMenuV2: React.ComponentType<Props>;\n }\n\n interface CommonItemOptions extends Omit<GlobalAttributesT, 'value'>, XstyledProps {\n dsId: string;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n render?: React.ComponentType<any>;\n onClick?: (e: React.MouseEvent | React.KeyboardEvent) => void;\n onKeyDown?: (e: React.KeyboardEvent) => null;\n }\n\n export interface ItemActionOptions extends CommonItemOptions {\n type: 'action';\n label: string;\n value: unknown;\n disabled?: boolean;\n applyAriaDisabled?: boolean;\n }\n\n export interface ItemSingleOptions extends CommonItemOptions {\n type: 'single';\n label: string;\n value: unknown;\n disabled?: boolean;\n applyAriaDisabled?: boolean;\n }\n\n export interface ItemSingleWithSubmenuOptions extends CommonItemOptions {\n type: 'singleWithSubmenu';\n label: string;\n value: unknown;\n disabled?: boolean;\n applyAriaDisabled?: boolean;\n rightAddon?: 'chevron' | 'ellipsis';\n options: Item[];\n }\n\n export interface ItemCheckboxOptions extends CommonItemOptions {\n type: 'checkbox';\n label: string;\n value: unknown;\n disabled?: boolean;\n applyAriaDisabled?: boolean;\n }\n\n export interface ItemSubmenuOptions extends CommonItemOptions {\n type: 'submenu';\n label: string;\n value: unknown;\n disabled?: boolean;\n applyAriaDisabled?: boolean;\n rightAddon?: 'chevron' | 'ellipsis';\n options: Item[];\n }\n\n export interface ItemSeparatorOptions extends CommonItemOptions {\n type: 'separator';\n }\n\n export interface ItemSectionOptions extends CommonItemOptions {\n type: 'section';\n label: string;\n }\n\n export interface ItemSkeletonOptions extends CommonItemOptions {\n type: 'skeleton';\n }\n\n export type Item =\n | ItemActionOptions\n | ItemSingleOptions\n | ItemCheckboxOptions\n | ItemSubmenuOptions\n | ItemSingleWithSubmenuOptions\n | ItemSeparatorOptions\n | ItemSectionOptions\n | ItemSkeletonOptions;\n\n export interface ItemDictionary {\n [dsId: string]: {\n original: Item;\n containerRef: React.RefObject<HTMLDivElement>;\n parent: string | null;\n };\n }\n}\n\nexport const actionOptionSchema = PropTypes.shape({\n dsId: PropTypes.string.isRequired,\n type: PropTypes.oneOf(['action']),\n label: PropTypes.string.isRequired,\n secondaryLabel: PropTypes.string,\n disabled: PropTypes.bool,\n render: PropTypes.func,\n});\nexport const singleOptionSchema = PropTypes.shape({\n dsId: PropTypes.string.isRequired,\n type: PropTypes.oneOf(['single']),\n label: PropTypes.string.isRequired,\n secondaryLabel: PropTypes.string,\n value: PropTypes.any.isRequired,\n disabled: PropTypes.bool,\n render: PropTypes.func,\n});\nexport const checkboxOptionSchema = PropTypes.shape({\n dsId: PropTypes.string.isRequired,\n type: PropTypes.oneOf(['checkbox']),\n label: PropTypes.string.isRequired,\n secondaryLabel: PropTypes.string,\n value: PropTypes.any.isRequired,\n disabled: PropTypes.bool,\n render: PropTypes.func,\n});\nexport const submenuOptionSchema = PropTypes.shape({\n dsId: PropTypes.string.isRequired,\n type: PropTypes.oneOf(['submenu']),\n label: PropTypes.string.isRequired,\n secondaryLabel: PropTypes.string,\n value: PropTypes.any.isRequired,\n disabled: PropTypes.bool,\n rightAddon: PropTypes.oneOf(['chevron', 'ellipsis']),\n options: PropTypes.array,\n minWidth: PropTypes.any,\n maxHeight: PropTypes.any,\n render: PropTypes.func,\n});\nexport const singleWithSubmenuOptionSchema = PropTypes.shape({\n dsId: PropTypes.string.isRequired,\n type: PropTypes.oneOf(['singleWithSubmenu']),\n label: PropTypes.string.isRequired,\n secondaryLabel: PropTypes.string,\n value: PropTypes.any.isRequired,\n disabled: PropTypes.bool,\n rightAddon: PropTypes.oneOf(['chevron', 'ellipsis']),\n options: PropTypes.array,\n minWidth: PropTypes.any,\n maxHeight: PropTypes.any,\n render: PropTypes.func,\n});\nexport const separatorOptionSchema = PropTypes.shape({\n dsId: PropTypes.string.isRequired,\n type: PropTypes.oneOf(['separator']),\n label: PropTypes.string.isRequired,\n render: PropTypes.func,\n});\nexport const sectionOptionSchema = PropTypes.shape({\n dsId: PropTypes.string.isRequired,\n type: PropTypes.oneOf(['section']),\n label: PropTypes.string.isRequired,\n render: PropTypes.func,\n});\n\nexport const optionTypesSchemas = PropTypes.oneOfType([\n actionOptionSchema,\n singleOptionSchema,\n checkboxOptionSchema,\n submenuOptionSchema,\n singleWithSubmenuOptionSchema,\n separatorOptionSchema,\n sectionOptionSchema,\n]);\n\nexport const DSDropdownMenuV2PropTypes = {\n options: PropTypes.arrayOf(optionTypesSchemas).description('The array of option for the menu').omitValidation()\n .isRequired,\n isOpened: PropTypes.bool.description('Whether the dropdown menu is opened or not').isRequired,\n onClickOutside: PropTypes.func\n .description('Callback executed when you click outside the dropdown menu, or press the Esc key')\n .defaultValue(() => null),\n selectedOptions: PropTypes.object\n .description(\n 'Object with the ids of the options as keys, and booleans as keys. Represents the state of the current selection in the dropdown menu',\n )\n .defaultValue({}),\n onOptionClick: PropTypes.func\n .description(\n 'Callback triggered when an item is clicked or pressed. We provide the next selected options, the clicked option and the event, in that order',\n )\n .defaultValue(() => null),\n openedSubmenus: PropTypes.object\n .description(\n 'Object with the ids of the submenus as keys, and booleans as keys. Represents the state of the current opened submenus',\n )\n .defaultValue({}),\n onSubmenuToggle: PropTypes.func\n .description(\n 'Callback triggered when a submenu is opened or closed. We provide the next opened submenus, the clicked one and the event, in that order',\n )\n .defaultValue(() => null),\n startPlacementPreference: PropTypes.string\n .description('Where to place the popper for the dropdown menu')\n .defaultValue('bottom-start'),\n placementOrderPreference: PropTypes.arrayOf(PropTypes.string)\n .description('Placement priorities for the dropdown menu')\n .defaultValue(['bottom-start', 'top-start', 'right-start', 'right-end', 'left-start', 'left-end']),\n customOffset: PropTypes.arrayOf(PropTypes.number)\n .description('Custom offset for the dropdown menu')\n .defaultValue([0, 4]),\n wrapperStyles: PropTypes.object.description('Styling for the dropdown menu wrapper').defaultValue({}),\n isLoading: PropTypes.bool\n .description('Whether the dropdown menu should render the loading indicator')\n .defaultValue(false),\n zIndex: PropTypes.number.description('ZIndex for the popper').defaultValue(10),\n HeaderComp: PropTypes.func\n .description('Component to render as a header for the dropdown menu')\n .defaultValue(undefined),\n actionRef: PropTypes.object.description('Reference where all the exposed action callbacks will be exposed'),\n minWidth: PropTypes.any.description('Minimum width for the dropdown menu').defaultValue(undefined),\n maxHeight: PropTypes.any.description('Maximum height for the dropdown menu').defaultValue(undefined),\n ...globalAttributesPropTypes,\n onKeyDown: PropTypes.func.description('Callback executed when a key is pressed').defaultValue(() => null),\n onMouseEnter: PropTypes.func\n .description('Callback executed when the mouse enter the dropdown menu')\n .defaultValue(() => null),\n onMouseLeave: PropTypes.func\n .description('Callback executed when the mouse leaves the dropdown menu')\n .defaultValue(() => null),\n isSkeleton: PropTypes.bool.description('Whether the dropdown menu should render the skeleton').defaultValue(false),\n} as ValidationMap<unknown>;\n\nexport const defaultProps: DSDropdownMenuT.DefaultProps = {\n onClickOutside: () => null,\n onKeyDown: () => null,\n onMouseEnter: () => null,\n onMouseLeave: () => null,\n selectedOptions: {},\n onOptionClick: () => null,\n openedSubmenus: {},\n onSubmenuToggle: () => null,\n isLoading: false,\n hasInput: false,\n inputValue: '',\n inputPlaceholder: 'Hint text',\n onInputChange: () => null,\n startPlacementPreference: 'bottom-start',\n placementOrderPreference: ['bottom-start', 'top-start', 'right-start', 'right-end', 'left-start', 'left-end'],\n customOffset: [0, 4],\n wrapperStyles: {},\n actionRef: { current: {} },\n as: 'div',\n isSkeleton: false,\n};\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable max-lines */\nimport type React from 'react';\nimport type { useVirtualizer, VirtualItem } from '@tanstack/react-virtual';\nimport {\n type GlobalAttributesT,\n PropTypes,\n type XstyledProps,\n globalAttributesPropTypes,\n type ValidationMap,\n} from '@elliemae/ds-props-helpers';\nimport type { SizingProps } from '@elliemae/ds-system';\n\nexport namespace DSDropdownMenuT {\n export type PopperPlacementsT =\n | 'top-start'\n | 'top'\n | 'top-end'\n | 'right-start'\n | 'right'\n | 'right-end'\n | 'bottom-end'\n | 'bottom'\n | 'bottom-start'\n | 'left-end'\n | 'left'\n | 'left-start';\n\n export interface RequiredProps {\n options: Item[] | readonly Item[];\n isOpened: boolean;\n }\n\n export interface DefaultProps {\n onClickOutside: (e: MouseEvent | React.KeyboardEvent | TouchEvent) => void;\n onKeyDown: React.KeyboardEventHandler;\n onMouseEnter: React.MouseEventHandler;\n onMouseLeave: React.MouseEventHandler;\n selectedOptions: Record<string, boolean>;\n onOptionClick: (\n nextSelectedOptions: Record<string, boolean>,\n clickedOption: Item,\n e: React.MouseEvent | React.KeyboardEvent,\n ) => void;\n openedSubmenus: Record<string, boolean>;\n onSubmenuToggle: (\n nextOpenedSubmenus: Record<string, boolean>,\n submenu: Item,\n e: React.MouseEvent | React.KeyboardEvent,\n ) => void;\n isLoading: boolean;\n hasInput: boolean;\n inputValue: string;\n inputPlaceholder: string;\n onInputChange: React.FormEventHandler<HTMLInputElement>;\n startPlacementPreference: PopperPlacementsT;\n placementOrderPreference: PopperPlacementsT[];\n customOffset: [number, number];\n wrapperStyles: Record<string, unknown>;\n actionRef: React.MutableRefObject<Record<string, unknown>>;\n as: keyof React.JSX.IntrinsicElements;\n children?: React.ReactNode;\n isSkeleton: boolean;\n /**\n * A ref object or callback function to access the dropdown menu's root DOM element\n * (the same node the internal floating-context anchor uses). Typed against `HTMLElement`,\n * not a specific tag \u2014 the root's actual element depends on the `as` prop (submenu/\n * singleWithSubmenu render it with `as=\"li\"`, the default is `as=\"div\"`).\n */\n innerRef: React.RefObject<HTMLElement> | ((el: HTMLElement | null) => void);\n }\n\n export interface OptionalProps {\n zIndex?: number;\n minWidth?: SizingProps['minWidth'];\n maxHeight?: SizingProps['maxHeight'];\n HeaderComp?: React.ComponentType<{ ctx?: DSDropdownMenuT.CTX }>;\n }\n\n export interface Props\n extends\n Partial<DefaultProps>,\n OptionalProps,\n Omit<GlobalAttributesT<HTMLButtonElement>, keyof DefaultProps | keyof OptionalProps | keyof RequiredProps>,\n Omit<XstyledProps, 'zIndex'>,\n RequiredProps {}\n\n export interface InternalProps\n extends\n DefaultProps,\n OptionalProps,\n Omit<GlobalAttributesT<HTMLButtonElement>, keyof DefaultProps | keyof OptionalProps | keyof RequiredProps>,\n Omit<XstyledProps, 'zIndex'>,\n RequiredProps {}\n\n export interface CTX {\n props: React.PropsWithChildren<InternalProps>;\n triggerReferenceElement: HTMLDivElement | null;\n setTriggerReferenceElement: React.Dispatch<React.SetStateAction<HTMLDivElement | null>>;\n listboxReference: React.RefObject<HTMLDivElement>;\n inputReference: React.RefObject<HTMLInputElement>;\n activeDescendant: string;\n setActiveDescendant: React.Dispatch<React.SetStateAction<string>>;\n scrollOptionIntoView: (dsId: string) => void;\n /**\n * `totalSize`/`virtualItems` are a v2-compatibility shim (getters delegating to\n * `getTotalSize()`/`getVirtualItems()`) defined in `useDropdownMenuConfig`, not part of v3's\n * own `Virtualizer` type \u2014 declared here so a `HeaderComp` written against either API shape\n * type-checks.\n */\n virtualListHelpers: ReturnType<typeof useVirtualizer<HTMLDivElement, HTMLElement>> & {\n totalSize: number;\n virtualItems: VirtualItem[];\n };\n DSDropdownMenuV2: React.ComponentType<Props>;\n }\n\n interface CommonItemOptions extends Omit<GlobalAttributesT, 'value'>, XstyledProps {\n dsId: string;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n render?: React.ComponentType<any>;\n onClick?: (e: React.MouseEvent | React.KeyboardEvent) => void;\n onKeyDown?: (e: React.KeyboardEvent) => null;\n }\n\n export interface ItemActionOptions extends CommonItemOptions {\n type: 'action';\n label: string;\n value: unknown;\n disabled?: boolean;\n applyAriaDisabled?: boolean;\n }\n\n export interface ItemSingleOptions extends CommonItemOptions {\n type: 'single';\n label: string;\n value: unknown;\n disabled?: boolean;\n applyAriaDisabled?: boolean;\n }\n\n export interface ItemSingleWithSubmenuOptions extends CommonItemOptions {\n type: 'singleWithSubmenu';\n label: string;\n value: unknown;\n disabled?: boolean;\n applyAriaDisabled?: boolean;\n rightAddon?: 'chevron' | 'ellipsis';\n options: Item[];\n }\n\n export interface ItemCheckboxOptions extends CommonItemOptions {\n type: 'checkbox';\n label: string;\n value: unknown;\n disabled?: boolean;\n applyAriaDisabled?: boolean;\n }\n\n export interface ItemSubmenuOptions extends CommonItemOptions {\n type: 'submenu';\n label: string;\n value: unknown;\n disabled?: boolean;\n applyAriaDisabled?: boolean;\n rightAddon?: 'chevron' | 'ellipsis';\n options: Item[];\n }\n\n export interface ItemSeparatorOptions extends CommonItemOptions {\n type: 'separator';\n }\n\n export interface ItemSectionOptions extends CommonItemOptions {\n type: 'section';\n label: string;\n }\n\n export interface ItemSkeletonOptions extends CommonItemOptions {\n type: 'skeleton';\n }\n\n export type Item =\n | ItemActionOptions\n | ItemSingleOptions\n | ItemCheckboxOptions\n | ItemSubmenuOptions\n | ItemSingleWithSubmenuOptions\n | ItemSeparatorOptions\n | ItemSectionOptions\n | ItemSkeletonOptions;\n\n export interface ItemDictionary {\n [dsId: string]: {\n original: Item;\n containerRef: React.RefObject<HTMLDivElement>;\n parent: string | null;\n };\n }\n}\n\nexport const actionOptionSchema = PropTypes.shape({\n dsId: PropTypes.string.isRequired,\n type: PropTypes.oneOf(['action']),\n label: PropTypes.string.isRequired,\n secondaryLabel: PropTypes.string,\n disabled: PropTypes.bool,\n render: PropTypes.func,\n});\nexport const singleOptionSchema = PropTypes.shape({\n dsId: PropTypes.string.isRequired,\n type: PropTypes.oneOf(['single']),\n label: PropTypes.string.isRequired,\n secondaryLabel: PropTypes.string,\n value: PropTypes.any.isRequired,\n disabled: PropTypes.bool,\n render: PropTypes.func,\n});\nexport const checkboxOptionSchema = PropTypes.shape({\n dsId: PropTypes.string.isRequired,\n type: PropTypes.oneOf(['checkbox']),\n label: PropTypes.string.isRequired,\n secondaryLabel: PropTypes.string,\n value: PropTypes.any.isRequired,\n disabled: PropTypes.bool,\n render: PropTypes.func,\n});\nexport const submenuOptionSchema = PropTypes.shape({\n dsId: PropTypes.string.isRequired,\n type: PropTypes.oneOf(['submenu']),\n label: PropTypes.string.isRequired,\n secondaryLabel: PropTypes.string,\n value: PropTypes.any.isRequired,\n disabled: PropTypes.bool,\n rightAddon: PropTypes.oneOf(['chevron', 'ellipsis']),\n options: PropTypes.array,\n minWidth: PropTypes.any,\n maxHeight: PropTypes.any,\n render: PropTypes.func,\n});\nexport const singleWithSubmenuOptionSchema = PropTypes.shape({\n dsId: PropTypes.string.isRequired,\n type: PropTypes.oneOf(['singleWithSubmenu']),\n label: PropTypes.string.isRequired,\n secondaryLabel: PropTypes.string,\n value: PropTypes.any.isRequired,\n disabled: PropTypes.bool,\n rightAddon: PropTypes.oneOf(['chevron', 'ellipsis']),\n options: PropTypes.array,\n minWidth: PropTypes.any,\n maxHeight: PropTypes.any,\n render: PropTypes.func,\n});\nexport const separatorOptionSchema = PropTypes.shape({\n dsId: PropTypes.string.isRequired,\n type: PropTypes.oneOf(['separator']),\n label: PropTypes.string.isRequired,\n render: PropTypes.func,\n});\nexport const sectionOptionSchema = PropTypes.shape({\n dsId: PropTypes.string.isRequired,\n type: PropTypes.oneOf(['section']),\n label: PropTypes.string.isRequired,\n render: PropTypes.func,\n});\n\nexport const optionTypesSchemas = PropTypes.oneOfType([\n actionOptionSchema,\n singleOptionSchema,\n checkboxOptionSchema,\n submenuOptionSchema,\n singleWithSubmenuOptionSchema,\n separatorOptionSchema,\n sectionOptionSchema,\n]);\n\nexport const DSDropdownMenuV2PropTypes = {\n options: PropTypes.arrayOf(optionTypesSchemas).description('The array of option for the menu').omitValidation()\n .isRequired,\n isOpened: PropTypes.bool.description('Whether the dropdown menu is opened or not').isRequired,\n onClickOutside: PropTypes.func\n .description('Callback executed when you click outside the dropdown menu, or press the Esc key')\n .defaultValue(() => null),\n selectedOptions: PropTypes.object\n .description(\n 'Object with the ids of the options as keys, and booleans as keys. Represents the state of the current selection in the dropdown menu',\n )\n .defaultValue({}),\n onOptionClick: PropTypes.func\n .description(\n 'Callback triggered when an item is clicked or pressed. We provide the next selected options, the clicked option and the event, in that order',\n )\n .defaultValue(() => null),\n openedSubmenus: PropTypes.object\n .description(\n 'Object with the ids of the submenus as keys, and booleans as keys. Represents the state of the current opened submenus',\n )\n .defaultValue({}),\n onSubmenuToggle: PropTypes.func\n .description(\n 'Callback triggered when a submenu is opened or closed. We provide the next opened submenus, the clicked one and the event, in that order',\n )\n .defaultValue(() => null),\n startPlacementPreference: PropTypes.string\n .description('Where to place the popper for the dropdown menu')\n .defaultValue('bottom-start'),\n placementOrderPreference: PropTypes.arrayOf(PropTypes.string)\n .description('Placement priorities for the dropdown menu')\n .defaultValue(['bottom-start', 'top-start', 'right-start', 'right-end', 'left-start', 'left-end']),\n customOffset: PropTypes.arrayOf(PropTypes.number)\n .description('Custom offset for the dropdown menu')\n .defaultValue([0, 4]),\n wrapperStyles: PropTypes.object.description('Styling for the dropdown menu wrapper').defaultValue({}),\n isLoading: PropTypes.bool\n .description('Whether the dropdown menu should render the loading indicator')\n .defaultValue(false),\n zIndex: PropTypes.number.description('ZIndex for the popper').defaultValue(10),\n HeaderComp: PropTypes.func\n .description('Component to render as a header for the dropdown menu')\n .defaultValue(undefined),\n actionRef: PropTypes.object.description('Reference where all the exposed action callbacks will be exposed'),\n minWidth: PropTypes.any.description('Minimum width for the dropdown menu').defaultValue(undefined),\n maxHeight: PropTypes.any.description('Maximum height for the dropdown menu').defaultValue(undefined),\n ...globalAttributesPropTypes,\n onKeyDown: PropTypes.func.description('Callback executed when a key is pressed').defaultValue(() => null),\n onMouseEnter: PropTypes.func\n .description('Callback executed when the mouse enter the dropdown menu')\n .defaultValue(() => null),\n onMouseLeave: PropTypes.func\n .description('Callback executed when the mouse leaves the dropdown menu')\n .defaultValue(() => null),\n isSkeleton: PropTypes.bool.description('Whether the dropdown menu should render the skeleton').defaultValue(false),\n innerRef: PropTypes.oneOfType([\n PropTypes.shape({\n current: PropTypes.node,\n }),\n PropTypes.func.description('A ref object or callback function to access the dropdown menu root DOM element.'),\n ]).defaultValue(`(() => {})`),\n} as ValidationMap<unknown>;\n\nexport const defaultProps: DSDropdownMenuT.DefaultProps = {\n onClickOutside: () => null,\n onKeyDown: () => null,\n onMouseEnter: () => null,\n onMouseLeave: () => null,\n selectedOptions: {},\n onOptionClick: () => null,\n openedSubmenus: {},\n onSubmenuToggle: () => null,\n isLoading: false,\n hasInput: false,\n inputValue: '',\n inputPlaceholder: 'Hint text',\n onInputChange: () => null,\n startPlacementPreference: 'bottom-start',\n placementOrderPreference: ['bottom-start', 'top-start', 'right-start', 'right-end', 'left-start', 'left-end'],\n customOffset: [0, 4],\n wrapperStyles: {},\n actionRef: { current: {} },\n as: 'div',\n isSkeleton: false,\n innerRef: () => {},\n};\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -145,7 +145,9 @@ const testCompleteDefaults = {
145
145
  actionRef: { current: {} },
146
146
  as: "div",
147
147
  children: "",
148
- isSkeleton: false
148
+ isSkeleton: false,
149
+ innerRef: () => {
150
+ }
149
151
  };
150
152
  const testInternalProps = {
151
153
  ...testRequiredProps,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../scripts/build/transpile/react-shim.js", "../../../src/typescript-testing/typescript-dropdown-v2-valid.tsx"],
4
- "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable max-lines */\n/* eslint-disable @typescript-eslint/no-unused-vars, no-unused-vars */\nimport { createRef } from 'react';\nimport { DSDropdownMenuV2 } from '../index.js';\nimport type { DSDropdownMenuT } from '../index.js';\n\n// test we expose the namespace and the namespace follows our deliverable conventions\ntype ComponentPropsForApp = DSDropdownMenuT.Props;\ntype ComponentPropsInternals = DSDropdownMenuT.InternalProps;\ntype ComponentPropsDefaultProps = DSDropdownMenuT.DefaultProps;\ntype ComponentPropsOptionalProps = DSDropdownMenuT.OptionalProps;\ntype ComponentPropsRequiredProps = DSDropdownMenuT.RequiredProps;\n\nconst placementOrderPreference: DSDropdownMenuT.PopperPlacementsT[] = ['bottom', 'bottom-end', 'bottom-start'];\nconst customOffset: DSDropdownMenuT.DefaultProps['customOffset'] = [0, 0];\n\nconst submenuOptions: DSDropdownMenuT.Item[] = [\n {\n type: 'single',\n dsId: 'id4.1',\n value: 'id4.1',\n label: 'Single Subitem 1',\n },\n {\n type: 'single',\n dsId: 'id4.1',\n value: 'id4.1',\n label: 'Single Subitem 2',\n },\n {\n type: 'single',\n dsId: 'id4.3',\n value: 'id4.3',\n label: 'Single Subitem 3',\n },\n];\n\nconst options: DSDropdownMenuT.Item[] = [\n // Action Menu Item\n {\n type: 'action',\n dsId: 'id1',\n value: 'id1',\n label: 'Action Item',\n disabled: false,\n },\n // Single Menu Item\n {\n type: 'single',\n dsId: 'id2',\n value: 'id2',\n label: 'Single Item',\n disabled: false,\n },\n // Multi MenuItem Item\n {\n type: 'checkbox',\n dsId: 'id3',\n value: 'id3',\n label: 'Multi Menu Item',\n disabled: false,\n },\n // Submenu Item\n {\n type: 'submenu',\n dsId: 'id4',\n value: 'id4',\n label: 'Submenu Item',\n disabled: false,\n rightAddon: 'ellipsis',\n options: submenuOptions,\n },\n // Separator\n {\n type: 'separator',\n dsId: '1d5',\n },\n // section\n {\n type: 'section',\n dsId: '1d6',\n label: 'Section',\n },\n // Single With Submenu Item\n {\n type: 'singleWithSubmenu',\n dsId: 'id7',\n value: 'id7',\n label: 'Single With Submenu',\n disabled: false,\n rightAddon: 'chevron',\n options: submenuOptions,\n },\n // Skeleton\n {\n type: 'skeleton',\n dsId: 'id8',\n },\n];\n\nconst testRequiredProps: ComponentPropsRequiredProps = {\n isOpened: false,\n options,\n};\nconst testOptionalProps: ComponentPropsOptionalProps = {\n HeaderComp: () => 'Header',\n maxHeight: 500,\n minWidth: 100,\n zIndex: 99,\n};\n\n// difference Props and InternalProps is that InternalProps has all the default props filled in\n// Props allows for partial defaults\nconst testPartialDefaults: Partial<ComponentPropsDefaultProps> = {\n onClickOutside: () => {},\n onMouseEnter: () => {},\n isLoading: false,\n hasInput: true,\n inputValue: '',\n inputPlaceholder: '',\n customOffset,\n isSkeleton: false,\n};\n\nconst testProps: ComponentPropsForApp = {\n ...testRequiredProps,\n ...testOptionalProps,\n ...testPartialDefaults,\n};\n\nconst testPropsAsSyntax = {\n ...testRequiredProps,\n ...testOptionalProps,\n ...testPartialDefaults,\n} as ComponentPropsForApp;\n\n// InternalProps requires all defaults to be filled in\nconst testCompleteDefaults: Required<ComponentPropsDefaultProps> = {\n onClickOutside: () => {},\n onKeyDown: () => {},\n onMouseEnter: () => {},\n onMouseLeave: () => {},\n selectedOptions: { id1: true, id2: false, id3: false },\n onOptionClick: () => {},\n openedSubmenus: { 'id1.1': true, 'id2.2': false, 'id3.3': false },\n onSubmenuToggle: () => {},\n isLoading: false,\n hasInput: false,\n inputValue: '',\n inputPlaceholder: '',\n onInputChange: () => {},\n startPlacementPreference: 'bottom',\n placementOrderPreference,\n customOffset,\n wrapperStyles: { color: 'red' },\n actionRef: { current: {} },\n as: 'div',\n children: '',\n isSkeleton: false,\n};\n\nconst testInternalProps: ComponentPropsInternals = {\n ...testRequiredProps,\n ...testOptionalProps,\n ...testCompleteDefaults,\n};\n\nconst testInternalPropsAsSyntax = {\n ...testRequiredProps,\n ...testOptionalProps,\n ...testCompleteDefaults,\n} as ComponentPropsInternals;\n\n// using the explicit type definition, if there is an error, it will be marked on the key that is wrong\nconst testExplicitDefinition: ComponentPropsForApp = {\n isOpened: false,\n options,\n onClickOutside: () => {},\n onKeyDown: () => {},\n onMouseEnter: () => {},\n onMouseLeave: () => {},\n selectedOptions: { id1: true, id2: false, id3: false },\n onOptionClick: () => {},\n openedSubmenus: { 'id1.1': true, 'id2.2': false, 'id3.3': false },\n onSubmenuToggle: () => {},\n isLoading: false,\n hasInput: false,\n inputValue: '',\n inputPlaceholder: '',\n onInputChange: () => {},\n startPlacementPreference: 'bottom',\n placementOrderPreference,\n customOffset,\n wrapperStyles: { color: 'red' },\n actionRef: { current: {} },\n as: 'div',\n children: '',\n isSkeleton: false,\n HeaderComp: () => 'Header',\n maxHeight: 500,\n minWidth: 100,\n zIndex: 99,\n};\n\n// using the \"as\" syntax, if there is an error, it will be marking the whole object as wrong because it is not compatible with the type\nconst testInferedTypeCompatibility = {\n isOpened: false,\n options,\n onClickOutside: () => {},\n onKeyDown: () => {},\n onMouseEnter: () => {},\n onMouseLeave: () => {},\n selectedOptions: { id1: true, id2: false, id3: false },\n onOptionClick: () => {},\n openedSubmenus: { 'id1.1': true, 'id2.2': false, 'id3.3': false },\n onSubmenuToggle: () => {},\n isLoading: false,\n hasInput: false,\n inputValue: '',\n inputPlaceholder: '',\n onInputChange: () => {},\n startPlacementPreference: 'bottom',\n placementOrderPreference,\n customOffset,\n wrapperStyles: { color: 'red' },\n actionRef: { current: {} },\n as: 'div',\n children: '',\n isSkeleton: false,\n HeaderComp: () => 'Header',\n maxHeight: 500,\n minWidth: 100,\n zIndex: 99,\n} as ComponentPropsForApp;\n\nconst testDefinitionAsConst = {\n isOpened: false,\n options,\n onClickOutside: () => {},\n onKeyDown: () => {},\n onMouseEnter: () => {},\n onMouseLeave: () => {},\n selectedOptions: { id1: true, id2: false, id3: false },\n onOptionClick: () => {},\n openedSubmenus: { 'id1.1': true, 'id2.2': false, 'id3.3': false },\n onSubmenuToggle: () => {},\n isLoading: false,\n hasInput: false,\n inputValue: '',\n inputPlaceholder: '',\n onInputChange: () => {},\n startPlacementPreference: 'bottom',\n placementOrderPreference,\n customOffset,\n wrapperStyles: { color: 'red' },\n actionRef: { current: {} },\n as: 'div',\n children: '',\n isSkeleton: false,\n HeaderComp: () => 'Header',\n maxHeight: 500,\n minWidth: 100,\n zIndex: 99,\n} as const;\n\nconst ExampleUsageComponent = () => (\n <>\n {/* works with explicitly casted props, all syntaxes */}\n <DSDropdownMenuV2 {...testExplicitDefinition} />\n <DSDropdownMenuV2 {...testInferedTypeCompatibility} />\n <DSDropdownMenuV2 {...testDefinitionAsConst} />\n {/* works with inline values */}\n <DSDropdownMenuV2\n isOpened={false}\n options={options}\n onClickOutside={() => {}}\n onKeyDown={() => {}}\n onMouseEnter={() => {}}\n onMouseLeave={() => {}}\n selectedOptions={{ id1: true, id2: false, id3: false }}\n onOptionClick={() => {}}\n openedSubmenus={{ 'id1.1': true, 'id2.2': false, 'id3.3': false }}\n onSubmenuToggle={() => {}}\n isLoading={false}\n hasInput={false}\n inputValue=\"\"\n inputPlaceholder=\"\"\n onInputChange={() => {}}\n startPlacementPreference=\"bottom\"\n placementOrderPreference={placementOrderPreference}\n customOffset={customOffset}\n wrapperStyles={{ color: 'red' }}\n actionRef={{ current: {} }}\n as=\"div\"\n isSkeleton={false}\n HeaderComp={() => 'Header'}\n maxHeight={500}\n minWidth={100}\n zIndex={99}\n ></DSDropdownMenuV2>\n </>\n);\n"],
5
- "mappings": "AAAA,YAAY,WAAW;AC0QrB,mBAEE,KAFF;AAvQF,SAAS,wBAAwB;AAUjC,MAAM,2BAAgE,CAAC,UAAU,cAAc,cAAc;AAC7G,MAAM,eAA6D,CAAC,GAAG,CAAC;AAExE,MAAM,iBAAyC;AAAA,EAC7C;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,OAAO;AAAA,IACP,OAAO;AAAA,EACT;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,OAAO;AAAA,IACP,OAAO;AAAA,EACT;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,OAAO;AAAA,IACP,OAAO;AAAA,EACT;AACF;AAEA,MAAM,UAAkC;AAAA;AAAA,EAEtC;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,OAAO;AAAA,IACP,OAAO;AAAA,IACP,UAAU;AAAA,EACZ;AAAA;AAAA,EAEA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,OAAO;AAAA,IACP,OAAO;AAAA,IACP,UAAU;AAAA,EACZ;AAAA;AAAA,EAEA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,OAAO;AAAA,IACP,OAAO;AAAA,IACP,UAAU;AAAA,EACZ;AAAA;AAAA,EAEA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,OAAO;AAAA,IACP,OAAO;AAAA,IACP,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,SAAS;AAAA,EACX;AAAA;AAAA,EAEA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA;AAAA,EAEA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,OAAO;AAAA,EACT;AAAA;AAAA,EAEA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,OAAO;AAAA,IACP,OAAO;AAAA,IACP,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,SAAS;AAAA,EACX;AAAA;AAAA,EAEA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AACF;AAEA,MAAM,oBAAiD;AAAA,EACrD,UAAU;AAAA,EACV;AACF;AACA,MAAM,oBAAiD;AAAA,EACrD,YAAY,MAAM;AAAA,EAClB,WAAW;AAAA,EACX,UAAU;AAAA,EACV,QAAQ;AACV;AAIA,MAAM,sBAA2D;AAAA,EAC/D,gBAAgB,MAAM;AAAA,EAAC;AAAA,EACvB,cAAc,MAAM;AAAA,EAAC;AAAA,EACrB,WAAW;AAAA,EACX,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,kBAAkB;AAAA,EAClB;AAAA,EACA,YAAY;AACd;AAEA,MAAM,YAAkC;AAAA,EACtC,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AACL;AAEA,MAAM,oBAAoB;AAAA,EACxB,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AACL;AAGA,MAAM,uBAA6D;AAAA,EACjE,gBAAgB,MAAM;AAAA,EAAC;AAAA,EACvB,WAAW,MAAM;AAAA,EAAC;AAAA,EAClB,cAAc,MAAM;AAAA,EAAC;AAAA,EACrB,cAAc,MAAM;AAAA,EAAC;AAAA,EACrB,iBAAiB,EAAE,KAAK,MAAM,KAAK,OAAO,KAAK,MAAM;AAAA,EACrD,eAAe,MAAM;AAAA,EAAC;AAAA,EACtB,gBAAgB,EAAE,SAAS,MAAM,SAAS,OAAO,SAAS,MAAM;AAAA,EAChE,iBAAiB,MAAM;AAAA,EAAC;AAAA,EACxB,WAAW;AAAA,EACX,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,kBAAkB;AAAA,EAClB,eAAe,MAAM;AAAA,EAAC;AAAA,EACtB,0BAA0B;AAAA,EAC1B;AAAA,EACA;AAAA,EACA,eAAe,EAAE,OAAO,MAAM;AAAA,EAC9B,WAAW,EAAE,SAAS,CAAC,EAAE;AAAA,EACzB,IAAI;AAAA,EACJ,UAAU;AAAA,EACV,YAAY;AACd;AAEA,MAAM,oBAA6C;AAAA,EACjD,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AACL;AAEA,MAAM,4BAA4B;AAAA,EAChC,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AACL;AAGA,MAAM,yBAA+C;AAAA,EACnD,UAAU;AAAA,EACV;AAAA,EACA,gBAAgB,MAAM;AAAA,EAAC;AAAA,EACvB,WAAW,MAAM;AAAA,EAAC;AAAA,EAClB,cAAc,MAAM;AAAA,EAAC;AAAA,EACrB,cAAc,MAAM;AAAA,EAAC;AAAA,EACrB,iBAAiB,EAAE,KAAK,MAAM,KAAK,OAAO,KAAK,MAAM;AAAA,EACrD,eAAe,MAAM;AAAA,EAAC;AAAA,EACtB,gBAAgB,EAAE,SAAS,MAAM,SAAS,OAAO,SAAS,MAAM;AAAA,EAChE,iBAAiB,MAAM;AAAA,EAAC;AAAA,EACxB,WAAW;AAAA,EACX,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,kBAAkB;AAAA,EAClB,eAAe,MAAM;AAAA,EAAC;AAAA,EACtB,0BAA0B;AAAA,EAC1B;AAAA,EACA;AAAA,EACA,eAAe,EAAE,OAAO,MAAM;AAAA,EAC9B,WAAW,EAAE,SAAS,CAAC,EAAE;AAAA,EACzB,IAAI;AAAA,EACJ,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,YAAY,MAAM;AAAA,EAClB,WAAW;AAAA,EACX,UAAU;AAAA,EACV,QAAQ;AACV;AAGA,MAAM,+BAA+B;AAAA,EACnC,UAAU;AAAA,EACV;AAAA,EACA,gBAAgB,MAAM;AAAA,EAAC;AAAA,EACvB,WAAW,MAAM;AAAA,EAAC;AAAA,EAClB,cAAc,MAAM;AAAA,EAAC;AAAA,EACrB,cAAc,MAAM;AAAA,EAAC;AAAA,EACrB,iBAAiB,EAAE,KAAK,MAAM,KAAK,OAAO,KAAK,MAAM;AAAA,EACrD,eAAe,MAAM;AAAA,EAAC;AAAA,EACtB,gBAAgB,EAAE,SAAS,MAAM,SAAS,OAAO,SAAS,MAAM;AAAA,EAChE,iBAAiB,MAAM;AAAA,EAAC;AAAA,EACxB,WAAW;AAAA,EACX,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,kBAAkB;AAAA,EAClB,eAAe,MAAM;AAAA,EAAC;AAAA,EACtB,0BAA0B;AAAA,EAC1B;AAAA,EACA;AAAA,EACA,eAAe,EAAE,OAAO,MAAM;AAAA,EAC9B,WAAW,EAAE,SAAS,CAAC,EAAE;AAAA,EACzB,IAAI;AAAA,EACJ,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,YAAY,MAAM;AAAA,EAClB,WAAW;AAAA,EACX,UAAU;AAAA,EACV,QAAQ;AACV;AAEA,MAAM,wBAAwB;AAAA,EAC5B,UAAU;AAAA,EACV;AAAA,EACA,gBAAgB,MAAM;AAAA,EAAC;AAAA,EACvB,WAAW,MAAM;AAAA,EAAC;AAAA,EAClB,cAAc,MAAM;AAAA,EAAC;AAAA,EACrB,cAAc,MAAM;AAAA,EAAC;AAAA,EACrB,iBAAiB,EAAE,KAAK,MAAM,KAAK,OAAO,KAAK,MAAM;AAAA,EACrD,eAAe,MAAM;AAAA,EAAC;AAAA,EACtB,gBAAgB,EAAE,SAAS,MAAM,SAAS,OAAO,SAAS,MAAM;AAAA,EAChE,iBAAiB,MAAM;AAAA,EAAC;AAAA,EACxB,WAAW;AAAA,EACX,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,kBAAkB;AAAA,EAClB,eAAe,MAAM;AAAA,EAAC;AAAA,EACtB,0BAA0B;AAAA,EAC1B;AAAA,EACA;AAAA,EACA,eAAe,EAAE,OAAO,MAAM;AAAA,EAC9B,WAAW,EAAE,SAAS,CAAC,EAAE;AAAA,EACzB,IAAI;AAAA,EACJ,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,YAAY,MAAM;AAAA,EAClB,WAAW;AAAA,EACX,UAAU;AAAA,EACV,QAAQ;AACV;AAEA,MAAM,wBAAwB,MAC5B,iCAEE;AAAA,sBAAC,oBAAkB,GAAG,wBAAwB;AAAA,EAC9C,oBAAC,oBAAkB,GAAG,8BAA8B;AAAA,EACpD,oBAAC,oBAAkB,GAAG,uBAAuB;AAAA,EAE7C;AAAA,IAAC;AAAA;AAAA,MACC,UAAU;AAAA,MACV;AAAA,MACA,gBAAgB,MAAM;AAAA,MAAC;AAAA,MACvB,WAAW,MAAM;AAAA,MAAC;AAAA,MAClB,cAAc,MAAM;AAAA,MAAC;AAAA,MACrB,cAAc,MAAM;AAAA,MAAC;AAAA,MACrB,iBAAiB,EAAE,KAAK,MAAM,KAAK,OAAO,KAAK,MAAM;AAAA,MACrD,eAAe,MAAM;AAAA,MAAC;AAAA,MACtB,gBAAgB,EAAE,SAAS,MAAM,SAAS,OAAO,SAAS,MAAM;AAAA,MAChE,iBAAiB,MAAM;AAAA,MAAC;AAAA,MACxB,WAAW;AAAA,MACX,UAAU;AAAA,MACV,YAAW;AAAA,MACX,kBAAiB;AAAA,MACjB,eAAe,MAAM;AAAA,MAAC;AAAA,MACtB,0BAAyB;AAAA,MACzB;AAAA,MACA;AAAA,MACA,eAAe,EAAE,OAAO,MAAM;AAAA,MAC9B,WAAW,EAAE,SAAS,CAAC,EAAE;AAAA,MACzB,IAAG;AAAA,MACH,YAAY;AAAA,MACZ,YAAY,MAAM;AAAA,MAClB,WAAW;AAAA,MACX,UAAU;AAAA,MACV,QAAQ;AAAA;AAAA,EACT;AAAA,GACH;",
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable max-lines */\n/* eslint-disable @typescript-eslint/no-unused-vars, no-unused-vars */\nimport { createRef } from 'react';\nimport { DSDropdownMenuV2 } from '../index.js';\nimport type { DSDropdownMenuT } from '../index.js';\n\n// test we expose the namespace and the namespace follows our deliverable conventions\ntype ComponentPropsForApp = DSDropdownMenuT.Props;\ntype ComponentPropsInternals = DSDropdownMenuT.InternalProps;\ntype ComponentPropsDefaultProps = DSDropdownMenuT.DefaultProps;\ntype ComponentPropsOptionalProps = DSDropdownMenuT.OptionalProps;\ntype ComponentPropsRequiredProps = DSDropdownMenuT.RequiredProps;\n\nconst placementOrderPreference: DSDropdownMenuT.PopperPlacementsT[] = ['bottom', 'bottom-end', 'bottom-start'];\nconst customOffset: DSDropdownMenuT.DefaultProps['customOffset'] = [0, 0];\n\nconst submenuOptions: DSDropdownMenuT.Item[] = [\n {\n type: 'single',\n dsId: 'id4.1',\n value: 'id4.1',\n label: 'Single Subitem 1',\n },\n {\n type: 'single',\n dsId: 'id4.1',\n value: 'id4.1',\n label: 'Single Subitem 2',\n },\n {\n type: 'single',\n dsId: 'id4.3',\n value: 'id4.3',\n label: 'Single Subitem 3',\n },\n];\n\nconst options: DSDropdownMenuT.Item[] = [\n // Action Menu Item\n {\n type: 'action',\n dsId: 'id1',\n value: 'id1',\n label: 'Action Item',\n disabled: false,\n },\n // Single Menu Item\n {\n type: 'single',\n dsId: 'id2',\n value: 'id2',\n label: 'Single Item',\n disabled: false,\n },\n // Multi MenuItem Item\n {\n type: 'checkbox',\n dsId: 'id3',\n value: 'id3',\n label: 'Multi Menu Item',\n disabled: false,\n },\n // Submenu Item\n {\n type: 'submenu',\n dsId: 'id4',\n value: 'id4',\n label: 'Submenu Item',\n disabled: false,\n rightAddon: 'ellipsis',\n options: submenuOptions,\n },\n // Separator\n {\n type: 'separator',\n dsId: '1d5',\n },\n // section\n {\n type: 'section',\n dsId: '1d6',\n label: 'Section',\n },\n // Single With Submenu Item\n {\n type: 'singleWithSubmenu',\n dsId: 'id7',\n value: 'id7',\n label: 'Single With Submenu',\n disabled: false,\n rightAddon: 'chevron',\n options: submenuOptions,\n },\n // Skeleton\n {\n type: 'skeleton',\n dsId: 'id8',\n },\n];\n\nconst testRequiredProps: ComponentPropsRequiredProps = {\n isOpened: false,\n options,\n};\nconst testOptionalProps: ComponentPropsOptionalProps = {\n HeaderComp: () => 'Header',\n maxHeight: 500,\n minWidth: 100,\n zIndex: 99,\n};\n\n// difference Props and InternalProps is that InternalProps has all the default props filled in\n// Props allows for partial defaults\nconst testPartialDefaults: Partial<ComponentPropsDefaultProps> = {\n onClickOutside: () => {},\n onMouseEnter: () => {},\n isLoading: false,\n hasInput: true,\n inputValue: '',\n inputPlaceholder: '',\n customOffset,\n isSkeleton: false,\n};\n\nconst testProps: ComponentPropsForApp = {\n ...testRequiredProps,\n ...testOptionalProps,\n ...testPartialDefaults,\n};\n\nconst testPropsAsSyntax = {\n ...testRequiredProps,\n ...testOptionalProps,\n ...testPartialDefaults,\n} as ComponentPropsForApp;\n\n// InternalProps requires all defaults to be filled in\nconst testCompleteDefaults: Required<ComponentPropsDefaultProps> = {\n onClickOutside: () => {},\n onKeyDown: () => {},\n onMouseEnter: () => {},\n onMouseLeave: () => {},\n selectedOptions: { id1: true, id2: false, id3: false },\n onOptionClick: () => {},\n openedSubmenus: { 'id1.1': true, 'id2.2': false, 'id3.3': false },\n onSubmenuToggle: () => {},\n isLoading: false,\n hasInput: false,\n inputValue: '',\n inputPlaceholder: '',\n onInputChange: () => {},\n startPlacementPreference: 'bottom',\n placementOrderPreference,\n customOffset,\n wrapperStyles: { color: 'red' },\n actionRef: { current: {} },\n as: 'div',\n children: '',\n isSkeleton: false,\n innerRef: () => {},\n};\n\nconst testInternalProps: ComponentPropsInternals = {\n ...testRequiredProps,\n ...testOptionalProps,\n ...testCompleteDefaults,\n};\n\nconst testInternalPropsAsSyntax = {\n ...testRequiredProps,\n ...testOptionalProps,\n ...testCompleteDefaults,\n} as ComponentPropsInternals;\n\n// using the explicit type definition, if there is an error, it will be marked on the key that is wrong\nconst testExplicitDefinition: ComponentPropsForApp = {\n isOpened: false,\n options,\n onClickOutside: () => {},\n onKeyDown: () => {},\n onMouseEnter: () => {},\n onMouseLeave: () => {},\n selectedOptions: { id1: true, id2: false, id3: false },\n onOptionClick: () => {},\n openedSubmenus: { 'id1.1': true, 'id2.2': false, 'id3.3': false },\n onSubmenuToggle: () => {},\n isLoading: false,\n hasInput: false,\n inputValue: '',\n inputPlaceholder: '',\n onInputChange: () => {},\n startPlacementPreference: 'bottom',\n placementOrderPreference,\n customOffset,\n wrapperStyles: { color: 'red' },\n actionRef: { current: {} },\n as: 'div',\n children: '',\n isSkeleton: false,\n HeaderComp: () => 'Header',\n maxHeight: 500,\n minWidth: 100,\n zIndex: 99,\n};\n\n// using the \"as\" syntax, if there is an error, it will be marking the whole object as wrong because it is not compatible with the type\nconst testInferedTypeCompatibility = {\n isOpened: false,\n options,\n onClickOutside: () => {},\n onKeyDown: () => {},\n onMouseEnter: () => {},\n onMouseLeave: () => {},\n selectedOptions: { id1: true, id2: false, id3: false },\n onOptionClick: () => {},\n openedSubmenus: { 'id1.1': true, 'id2.2': false, 'id3.3': false },\n onSubmenuToggle: () => {},\n isLoading: false,\n hasInput: false,\n inputValue: '',\n inputPlaceholder: '',\n onInputChange: () => {},\n startPlacementPreference: 'bottom',\n placementOrderPreference,\n customOffset,\n wrapperStyles: { color: 'red' },\n actionRef: { current: {} },\n as: 'div',\n children: '',\n isSkeleton: false,\n HeaderComp: () => 'Header',\n maxHeight: 500,\n minWidth: 100,\n zIndex: 99,\n} as ComponentPropsForApp;\n\nconst testDefinitionAsConst = {\n isOpened: false,\n options,\n onClickOutside: () => {},\n onKeyDown: () => {},\n onMouseEnter: () => {},\n onMouseLeave: () => {},\n selectedOptions: { id1: true, id2: false, id3: false },\n onOptionClick: () => {},\n openedSubmenus: { 'id1.1': true, 'id2.2': false, 'id3.3': false },\n onSubmenuToggle: () => {},\n isLoading: false,\n hasInput: false,\n inputValue: '',\n inputPlaceholder: '',\n onInputChange: () => {},\n startPlacementPreference: 'bottom',\n placementOrderPreference,\n customOffset,\n wrapperStyles: { color: 'red' },\n actionRef: { current: {} },\n as: 'div',\n children: '',\n isSkeleton: false,\n HeaderComp: () => 'Header',\n maxHeight: 500,\n minWidth: 100,\n zIndex: 99,\n} as const;\n\nconst ExampleUsageComponent = () => (\n <>\n {/* works with explicitly casted props, all syntaxes */}\n <DSDropdownMenuV2 {...testExplicitDefinition} />\n <DSDropdownMenuV2 {...testInferedTypeCompatibility} />\n <DSDropdownMenuV2 {...testDefinitionAsConst} />\n {/* works with inline values */}\n <DSDropdownMenuV2\n isOpened={false}\n options={options}\n onClickOutside={() => {}}\n onKeyDown={() => {}}\n onMouseEnter={() => {}}\n onMouseLeave={() => {}}\n selectedOptions={{ id1: true, id2: false, id3: false }}\n onOptionClick={() => {}}\n openedSubmenus={{ 'id1.1': true, 'id2.2': false, 'id3.3': false }}\n onSubmenuToggle={() => {}}\n isLoading={false}\n hasInput={false}\n inputValue=\"\"\n inputPlaceholder=\"\"\n onInputChange={() => {}}\n startPlacementPreference=\"bottom\"\n placementOrderPreference={placementOrderPreference}\n customOffset={customOffset}\n wrapperStyles={{ color: 'red' }}\n actionRef={{ current: {} }}\n as=\"div\"\n isSkeleton={false}\n HeaderComp={() => 'Header'}\n maxHeight={500}\n minWidth={100}\n zIndex={99}\n ></DSDropdownMenuV2>\n </>\n);\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -3,6 +3,7 @@ import type { DSDropdownMenuT } from '../react-desc-prop-types.js';
3
3
  export declare const DropdownMenuItemFactory: React.ComponentType<{
4
4
  option: DSDropdownMenuT.Item;
5
5
  style?: Record<string, unknown>;
6
+ index: number;
6
7
  innerRef?: (el: HTMLElement) => void;
7
8
  optionsShouldHavePadding: boolean;
8
9
  }>;
@@ -1,5 +1,5 @@
1
1
  import type React from 'react';
2
- import type { useVirtual } from 'react-virtual';
2
+ import type { useVirtualizer, VirtualItem } from '@tanstack/react-virtual';
3
3
  import { type GlobalAttributesT, type XstyledProps, type ValidationMap } from '@elliemae/ds-props-helpers';
4
4
  import type { SizingProps } from '@elliemae/ds-system';
5
5
  export declare namespace DSDropdownMenuT {
@@ -30,6 +30,13 @@ export declare namespace DSDropdownMenuT {
30
30
  as: keyof React.JSX.IntrinsicElements;
31
31
  children?: React.ReactNode;
32
32
  isSkeleton: boolean;
33
+ /**
34
+ * A ref object or callback function to access the dropdown menu's root DOM element
35
+ * (the same node the internal floating-context anchor uses). Typed against `HTMLElement`,
36
+ * not a specific tag — the root's actual element depends on the `as` prop (submenu/
37
+ * singleWithSubmenu render it with `as="li"`, the default is `as="div"`).
38
+ */
39
+ innerRef: React.RefObject<HTMLElement> | ((el: HTMLElement | null) => void);
33
40
  }
34
41
  export interface OptionalProps {
35
42
  zIndex?: number;
@@ -52,7 +59,16 @@ export declare namespace DSDropdownMenuT {
52
59
  activeDescendant: string;
53
60
  setActiveDescendant: React.Dispatch<React.SetStateAction<string>>;
54
61
  scrollOptionIntoView: (dsId: string) => void;
55
- virtualListHelpers: ReturnType<typeof useVirtual>;
62
+ /**
63
+ * `totalSize`/`virtualItems` are a v2-compatibility shim (getters delegating to
64
+ * `getTotalSize()`/`getVirtualItems()`) defined in `useDropdownMenuConfig`, not part of v3's
65
+ * own `Virtualizer` type — declared here so a `HeaderComp` written against either API shape
66
+ * type-checks.
67
+ */
68
+ virtualListHelpers: ReturnType<typeof useVirtualizer<HTMLDivElement, HTMLElement>> & {
69
+ totalSize: number;
70
+ virtualItems: VirtualItem[];
71
+ };
56
72
  DSDropdownMenuV2: React.ComponentType<Props>;
57
73
  }
58
74
  interface CommonItemOptions extends Omit<GlobalAttributesT, 'value'>, XstyledProps {