@elliemae/ds-virtual-list 3.80.0-next.12 → 3.80.0-next.13

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.
@@ -55,7 +55,18 @@ const useVirtualListV3 = (propsFromUser) => {
55
55
  estimateSize
56
56
  });
57
57
  const totalSize = useVirtualHelpers.getTotalSize();
58
- if (actionRef && actionRef.current) actionRef.current.scrollTo = useVirtualHelpers.scrollToIndex;
58
+ if (actionRef && actionRef.current) {
59
+ actionRef.current.scrollTo = useVirtualHelpers.scrollToIndex;
60
+ actionRef.current.measure = useVirtualHelpers.measure;
61
+ actionRef.current.getVisibleItems = () => {
62
+ const range = useVirtualHelpers.calculateRange();
63
+ if (!range) return [];
64
+ const indices = [];
65
+ for (let index = range.startIndex; index <= range.endIndex; index += 1) indices.push(index);
66
+ return indices;
67
+ };
68
+ actionRef.current.getMountedItems = () => useVirtualHelpers.getVirtualItems().map((item) => item.index);
69
+ }
59
70
  const instanceUid = import_react.default.useMemo(() => `ds-virtual-list-${(0, import_uid.uid)(6)}`, []);
60
71
  return import_react.default.useMemo(
61
72
  () => ({
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/hooks/useVirtualList.tsx", "../../../../../../scripts/build/transpile/react-shim.js"],
4
- "sourcesContent": ["import { useMemoMergePropsWithDefault } from '@elliemae/ds-props-helpers';\nimport { useVirtualizer, type Virtualizer } from '@tanstack/react-virtual';\nimport React from 'react';\nimport { uid } from 'uid';\nimport { DSVirtualListPropTypes, defaultProps, type DSVirtualListT } from '../react-desc-prop-types.js';\nimport { useValidateProps } from './useValidateProps.js';\n\nconst estimateSize = () => 50;\n\nexport type VirtualListCTX = {\n instanceUid: string;\n filteredChildren: React.ReactNode[];\n propsWithDefault: DSVirtualListT.InternalProps;\n parentRef: React.MutableRefObject<HTMLDivElement | null>;\n getVirtualItems: Virtualizer<HTMLDivElement, HTMLElement>['getVirtualItems'];\n totalSize: ReturnType<Virtualizer<HTMLDivElement, HTMLElement>['getTotalSize']>;\n measureElement: Virtualizer<HTMLDivElement, HTMLElement>['measureElement'];\n};\nexport const useVirtualListV3 = (propsFromUser: DSVirtualListT.Props): VirtualListCTX => {\n // =============================================================================\n // MERGE WITH DEFAULT AND VALIDATE PROPS\n // =============================================================================\n const propsWithDefault = useMemoMergePropsWithDefault<DSVirtualListT.InternalProps>(propsFromUser, defaultProps);\n useValidateProps(propsWithDefault, DSVirtualListPropTypes);\n // =============================================================================\n // AD HOC PER COMPONENT LOGIC\n // =============================================================================\n const { children, actionRef } = propsWithDefault;\n const parentRef = React.useRef<HTMLDivElement>(null);\n const filteredChildren = React.useMemo(\n () => React.Children.toArray(children).filter((child) => child !== undefined && child !== null),\n [children],\n ) as React.ReactNode[];\n const useVirtualHelpers = useVirtualizer({\n count: filteredChildren.length,\n getScrollElement: () => parentRef.current,\n overscan: 15,\n estimateSize,\n });\n const totalSize = useVirtualHelpers.getTotalSize();\n if (actionRef && actionRef.current) actionRef.current.scrollTo = useVirtualHelpers.scrollToIndex;\n\n const instanceUid = React.useMemo(() => `ds-virtual-list-${uid(6)}`, []);\n return React.useMemo(\n () => ({\n instanceUid,\n filteredChildren,\n propsWithDefault,\n parentRef,\n getVirtualItems: useVirtualHelpers.getVirtualItems,\n totalSize,\n measureElement: useVirtualHelpers.measureElement,\n }),\n [\n useVirtualHelpers.getVirtualItems,\n useVirtualHelpers.measureElement,\n filteredChildren,\n totalSize,\n instanceUid,\n propsWithDefault,\n ],\n );\n};\n", "import * as React from 'react';\nexport { React };\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADAvB,8BAA6C;AAC7C,2BAAiD;AACjD,mBAAkB;AAClB,iBAAoB;AACpB,mCAA0E;AAC1E,8BAAiC;AAEjC,MAAM,eAAe,MAAM;AAWpB,MAAM,mBAAmB,CAAC,kBAAwD;AAIvF,QAAM,uBAAmB,sDAA2D,eAAe,yCAAY;AAC/G,gDAAiB,kBAAkB,mDAAsB;AAIzD,QAAM,EAAE,UAAU,UAAU,IAAI;AAChC,QAAM,YAAY,aAAAA,QAAM,OAAuB,IAAI;AACnD,QAAM,mBAAmB,aAAAA,QAAM;AAAA,IAC7B,MAAM,aAAAA,QAAM,SAAS,QAAQ,QAAQ,EAAE,OAAO,CAAC,UAAU,UAAU,UAAa,UAAU,IAAI;AAAA,IAC9F,CAAC,QAAQ;AAAA,EACX;AACA,QAAM,wBAAoB,qCAAe;AAAA,IACvC,OAAO,iBAAiB;AAAA,IACxB,kBAAkB,MAAM,UAAU;AAAA,IAClC,UAAU;AAAA,IACV;AAAA,EACF,CAAC;AACD,QAAM,YAAY,kBAAkB,aAAa;AACjD,MAAI,aAAa,UAAU,QAAS,WAAU,QAAQ,WAAW,kBAAkB;AAEnF,QAAM,cAAc,aAAAA,QAAM,QAAQ,MAAM,uBAAmB,gBAAI,CAAC,CAAC,IAAI,CAAC,CAAC;AACvE,SAAO,aAAAA,QAAM;AAAA,IACX,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,iBAAiB,kBAAkB;AAAA,MACnC;AAAA,MACA,gBAAgB,kBAAkB;AAAA,IACpC;AAAA,IACA;AAAA,MACE,kBAAkB;AAAA,MAClB,kBAAkB;AAAA,MAClB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;",
4
+ "sourcesContent": ["import { useMemoMergePropsWithDefault } from '@elliemae/ds-props-helpers';\nimport { useVirtualizer, type Virtualizer } from '@tanstack/react-virtual';\nimport React from 'react';\nimport { uid } from 'uid';\nimport { DSVirtualListPropTypes, defaultProps, type DSVirtualListT } from '../react-desc-prop-types.js';\nimport { useValidateProps } from './useValidateProps.js';\n\nconst estimateSize = () => 50;\n\nexport type VirtualListCTX = {\n instanceUid: string;\n filteredChildren: React.ReactNode[];\n propsWithDefault: DSVirtualListT.InternalProps;\n parentRef: React.MutableRefObject<HTMLDivElement | null>;\n getVirtualItems: Virtualizer<HTMLDivElement, HTMLElement>['getVirtualItems'];\n totalSize: ReturnType<Virtualizer<HTMLDivElement, HTMLElement>['getTotalSize']>;\n measureElement: Virtualizer<HTMLDivElement, HTMLElement>['measureElement'];\n};\nexport const useVirtualListV3 = (propsFromUser: DSVirtualListT.Props): VirtualListCTX => {\n // =============================================================================\n // MERGE WITH DEFAULT AND VALIDATE PROPS\n // =============================================================================\n const propsWithDefault = useMemoMergePropsWithDefault<DSVirtualListT.InternalProps>(propsFromUser, defaultProps);\n useValidateProps(propsWithDefault, DSVirtualListPropTypes);\n // =============================================================================\n // AD HOC PER COMPONENT LOGIC\n // =============================================================================\n const { children, actionRef } = propsWithDefault;\n const parentRef = React.useRef<HTMLDivElement>(null);\n const filteredChildren = React.useMemo(\n () => React.Children.toArray(children).filter((child) => child !== undefined && child !== null),\n [children],\n ) as React.ReactNode[];\n const useVirtualHelpers = useVirtualizer({\n count: filteredChildren.length,\n getScrollElement: () => parentRef.current,\n overscan: 15,\n estimateSize,\n });\n const totalSize = useVirtualHelpers.getTotalSize();\n if (actionRef && actionRef.current) {\n actionRef.current.scrollTo = useVirtualHelpers.scrollToIndex;\n actionRef.current.measure = useVirtualHelpers.measure;\n // `getVirtualItems()` includes the overscan buffer on each side \u2014 not what \"visible\" means.\n // `calculateRange()` is the virtualizer's own pre-overscan viewport calculation (pure scroll\n // geometry, no DOM scraping) and is what \"currently visible\" should actually be backed by.\n actionRef.current.getVisibleItems = () => {\n const range = useVirtualHelpers.calculateRange();\n if (!range) return [];\n const indices: number[] = [];\n for (let index = range.startIndex; index <= range.endIndex; index += 1) indices.push(index);\n return indices;\n };\n // The overscanned set (viewport + the 15-item buffer on each side) \u2014 everything currently\n // mounted in the DOM, as opposed to `getVisibleItems()`'s true-viewport-only set above.\n actionRef.current.getMountedItems = () => useVirtualHelpers.getVirtualItems().map((item) => item.index);\n }\n\n const instanceUid = React.useMemo(() => `ds-virtual-list-${uid(6)}`, []);\n return React.useMemo(\n () => ({\n instanceUid,\n filteredChildren,\n propsWithDefault,\n parentRef,\n getVirtualItems: useVirtualHelpers.getVirtualItems,\n totalSize,\n measureElement: useVirtualHelpers.measureElement,\n }),\n [\n useVirtualHelpers.getVirtualItems,\n useVirtualHelpers.measureElement,\n filteredChildren,\n totalSize,\n instanceUid,\n propsWithDefault,\n ],\n );\n};\n", "import * as React from 'react';\nexport { React };\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADAvB,8BAA6C;AAC7C,2BAAiD;AACjD,mBAAkB;AAClB,iBAAoB;AACpB,mCAA0E;AAC1E,8BAAiC;AAEjC,MAAM,eAAe,MAAM;AAWpB,MAAM,mBAAmB,CAAC,kBAAwD;AAIvF,QAAM,uBAAmB,sDAA2D,eAAe,yCAAY;AAC/G,gDAAiB,kBAAkB,mDAAsB;AAIzD,QAAM,EAAE,UAAU,UAAU,IAAI;AAChC,QAAM,YAAY,aAAAA,QAAM,OAAuB,IAAI;AACnD,QAAM,mBAAmB,aAAAA,QAAM;AAAA,IAC7B,MAAM,aAAAA,QAAM,SAAS,QAAQ,QAAQ,EAAE,OAAO,CAAC,UAAU,UAAU,UAAa,UAAU,IAAI;AAAA,IAC9F,CAAC,QAAQ;AAAA,EACX;AACA,QAAM,wBAAoB,qCAAe;AAAA,IACvC,OAAO,iBAAiB;AAAA,IACxB,kBAAkB,MAAM,UAAU;AAAA,IAClC,UAAU;AAAA,IACV;AAAA,EACF,CAAC;AACD,QAAM,YAAY,kBAAkB,aAAa;AACjD,MAAI,aAAa,UAAU,SAAS;AAClC,cAAU,QAAQ,WAAW,kBAAkB;AAC/C,cAAU,QAAQ,UAAU,kBAAkB;AAI9C,cAAU,QAAQ,kBAAkB,MAAM;AACxC,YAAM,QAAQ,kBAAkB,eAAe;AAC/C,UAAI,CAAC,MAAO,QAAO,CAAC;AACpB,YAAM,UAAoB,CAAC;AAC3B,eAAS,QAAQ,MAAM,YAAY,SAAS,MAAM,UAAU,SAAS,EAAG,SAAQ,KAAK,KAAK;AAC1F,aAAO;AAAA,IACT;AAGA,cAAU,QAAQ,kBAAkB,MAAM,kBAAkB,gBAAgB,EAAE,IAAI,CAAC,SAAS,KAAK,KAAK;AAAA,EACxG;AAEA,QAAM,cAAc,aAAAA,QAAM,QAAQ,MAAM,uBAAmB,gBAAI,CAAC,CAAC,IAAI,CAAC,CAAC;AACvE,SAAO,aAAAA,QAAM;AAAA,IACX,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,iBAAiB,kBAAkB;AAAA,MACnC;AAAA,MACA,gBAAgB,kBAAkB;AAAA,IACpC;AAAA,IACA;AAAA,MACE,kBAAkB;AAAA,MAClB,kBAAkB;AAAA,MAClB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;",
6
6
  "names": ["React"]
7
7
  }
@@ -44,7 +44,12 @@ const DSVirtualListPropTypes = {
44
44
  current: import_ds_props_helpers.PropTypes.oneOfType([
45
45
  import_ds_props_helpers.PropTypes.oneOf([null]),
46
46
  import_ds_props_helpers.PropTypes.shape({
47
- scrollTo: import_ds_props_helpers.PropTypes.func.description("Scroll to a index inside the list").signature(`((index: number, { align: 'start' | 'center' | 'end' | 'auto' }) => void)`)
47
+ scrollTo: import_ds_props_helpers.PropTypes.func.description("Scroll to a index inside the list").signature(`((index: number, { align: 'start' | 'center' | 'end' | 'auto' }) => void)`),
48
+ measure: import_ds_props_helpers.PropTypes.func.description(
49
+ "Clears the cached size of every item, falling back to the estimated size until each item is measured again (on its next real layout change or remount) \u2014 does not force an immediate DOM remeasurement"
50
+ ).signature(`(() => void)`),
51
+ getVisibleItems: import_ds_props_helpers.PropTypes.func.description("Returns the indices of the items currently visible in the viewport (no overscan buffer)").signature(`(() => number[])`),
52
+ getMountedItems: import_ds_props_helpers.PropTypes.func.description("Returns the indices of all items currently mounted in the DOM, including the overscan buffer").signature(`(() => number[])`)
48
53
  })
49
54
  ])
50
55
  }).description(`mutable reference where methods will be stored`)
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/react-desc-prop-types.ts", "../../../../../scripts/build/transpile/react-shim.js"],
4
- "sourcesContent": ["import type React from 'react';\nimport { type TypescriptHelpersT } from '@elliemae/ds-typescript-helpers';\nimport type { GlobalAttributesT } from '@elliemae/ds-props-helpers';\nimport { PropTypes, getPropsPerSlotPropTypes, globalAttributesPropTypes } from '@elliemae/ds-props-helpers';\nimport { DSVirtualListName, DSVirtualListSlots } from './constants/index.js';\n\nexport declare namespace DSVirtualListT {\n type ScrollAlignment = 'start' | 'center' | 'end' | 'auto';\n type ScrollToOptions = {\n align: ScrollAlignment;\n };\n\n export type ActionRef = {\n scrollTo?: (index: number, options?: ScrollToOptions | undefined) => void;\n };\n\n export type SlotFunctionArguments = {\n dsVirtuallistRoot: () => object;\n dsVirtuallistListWrapper: () => object;\n dsVirtuallistItemWrapper: () => object;\n };\n\n export interface RequiredProps {\n children: React.ReactNode;\n }\n\n export interface DefaultProps {}\n\n export interface OptionalProps extends TypescriptHelpersT.PropsForGlobalOnSlots<\n typeof DSVirtualListName,\n typeof DSVirtualListSlots\n > {\n actionRef?: React.MutableRefObject<ActionRef>;\n }\n\n export interface Props\n extends\n Partial<DefaultProps>,\n OptionalProps,\n Omit<GlobalAttributesT<HTMLElement>, keyof DefaultProps | keyof RequiredProps>,\n RequiredProps {}\n\n export interface InternalProps\n extends\n DefaultProps,\n OptionalProps,\n Omit<GlobalAttributesT<HTMLElement>, keyof DefaultProps | keyof RequiredProps>,\n RequiredProps {}\n}\n\nexport const defaultProps: DSVirtualListT.DefaultProps = {};\n\nexport const DSVirtualListPropTypes = {\n ...getPropsPerSlotPropTypes(DSVirtualListName, DSVirtualListSlots),\n ...globalAttributesPropTypes,\n children: PropTypes.arrayOf(PropTypes.node).description('Children list').isRequired,\n actionRef: PropTypes.shape({\n current: PropTypes.oneOfType([\n PropTypes.oneOf([null]),\n PropTypes.shape({\n scrollTo: PropTypes.func\n .description('Scroll to a index inside the list')\n .signature(`((index: number, { align: 'start' | 'center' | 'end' | 'auto' }) => void)`),\n }),\n ]),\n }).description(`mutable reference where methods will be stored`),\n} as React.WeakValidationMap<unknown>;\n", "import * as React from 'react';\nexport { React };\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADGvB,8BAA+E;AAC/E,uBAAsD;AA8C/C,MAAM,eAA4C,CAAC;AAEnD,MAAM,yBAAyB;AAAA,EACpC,OAAG,kDAAyB,oCAAmB,mCAAkB;AAAA,EACjE,GAAG;AAAA,EACH,UAAU,kCAAU,QAAQ,kCAAU,IAAI,EAAE,YAAY,eAAe,EAAE;AAAA,EACzE,WAAW,kCAAU,MAAM;AAAA,IACzB,SAAS,kCAAU,UAAU;AAAA,MAC3B,kCAAU,MAAM,CAAC,IAAI,CAAC;AAAA,MACtB,kCAAU,MAAM;AAAA,QACd,UAAU,kCAAU,KACjB,YAAY,mCAAmC,EAC/C,UAAU,2EAA2E;AAAA,MAC1F,CAAC;AAAA,IACH,CAAC;AAAA,EACH,CAAC,EAAE,YAAY,gDAAgD;AACjE;",
4
+ "sourcesContent": ["import type React from 'react';\nimport { type TypescriptHelpersT } from '@elliemae/ds-typescript-helpers';\nimport type { GlobalAttributesT } from '@elliemae/ds-props-helpers';\nimport { PropTypes, getPropsPerSlotPropTypes, globalAttributesPropTypes } from '@elliemae/ds-props-helpers';\nimport { DSVirtualListName, DSVirtualListSlots } from './constants/index.js';\n\nexport declare namespace DSVirtualListT {\n type ScrollAlignment = 'start' | 'center' | 'end' | 'auto';\n type ScrollToOptions = {\n align: ScrollAlignment;\n };\n\n export type ActionRef = {\n scrollTo?: (index: number, options?: ScrollToOptions | undefined) => void;\n measure?: () => void;\n getVisibleItems?: () => number[];\n getMountedItems?: () => number[];\n };\n\n export type SlotFunctionArguments = {\n dsVirtuallistRoot: () => object;\n dsVirtuallistListWrapper: () => object;\n dsVirtuallistItemWrapper: () => object;\n };\n\n export interface RequiredProps {\n children: React.ReactNode;\n }\n\n export interface DefaultProps {}\n\n export interface OptionalProps extends TypescriptHelpersT.PropsForGlobalOnSlots<\n typeof DSVirtualListName,\n typeof DSVirtualListSlots\n > {\n actionRef?: React.MutableRefObject<ActionRef>;\n }\n\n export interface Props\n extends\n Partial<DefaultProps>,\n OptionalProps,\n Omit<GlobalAttributesT<HTMLElement>, keyof DefaultProps | keyof RequiredProps>,\n RequiredProps {}\n\n export interface InternalProps\n extends\n DefaultProps,\n OptionalProps,\n Omit<GlobalAttributesT<HTMLElement>, keyof DefaultProps | keyof RequiredProps>,\n RequiredProps {}\n}\n\nexport const defaultProps: DSVirtualListT.DefaultProps = {};\n\nexport const DSVirtualListPropTypes = {\n ...getPropsPerSlotPropTypes(DSVirtualListName, DSVirtualListSlots),\n ...globalAttributesPropTypes,\n children: PropTypes.arrayOf(PropTypes.node).description('Children list').isRequired,\n actionRef: PropTypes.shape({\n current: PropTypes.oneOfType([\n PropTypes.oneOf([null]),\n PropTypes.shape({\n scrollTo: PropTypes.func\n .description('Scroll to a index inside the list')\n .signature(`((index: number, { align: 'start' | 'center' | 'end' | 'auto' }) => void)`),\n measure: PropTypes.func\n .description(\n 'Clears the cached size of every item, falling back to the estimated size until each item is measured again (on its next real layout change or remount) \u2014 does not force an immediate DOM remeasurement',\n )\n .signature(`(() => void)`),\n getVisibleItems: PropTypes.func\n .description('Returns the indices of the items currently visible in the viewport (no overscan buffer)')\n .signature(`(() => number[])`),\n getMountedItems: PropTypes.func\n .description('Returns the indices of all items currently mounted in the DOM, including the overscan buffer')\n .signature(`(() => number[])`),\n }),\n ]),\n }).description(`mutable reference where methods will be stored`),\n} as React.WeakValidationMap<unknown>;\n", "import * as React from 'react';\nexport { React };\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADGvB,8BAA+E;AAC/E,uBAAsD;AAiD/C,MAAM,eAA4C,CAAC;AAEnD,MAAM,yBAAyB;AAAA,EACpC,OAAG,kDAAyB,oCAAmB,mCAAkB;AAAA,EACjE,GAAG;AAAA,EACH,UAAU,kCAAU,QAAQ,kCAAU,IAAI,EAAE,YAAY,eAAe,EAAE;AAAA,EACzE,WAAW,kCAAU,MAAM;AAAA,IACzB,SAAS,kCAAU,UAAU;AAAA,MAC3B,kCAAU,MAAM,CAAC,IAAI,CAAC;AAAA,MACtB,kCAAU,MAAM;AAAA,QACd,UAAU,kCAAU,KACjB,YAAY,mCAAmC,EAC/C,UAAU,2EAA2E;AAAA,QACxF,SAAS,kCAAU,KAChB;AAAA,UACC;AAAA,QACF,EACC,UAAU,cAAc;AAAA,QAC3B,iBAAiB,kCAAU,KACxB,YAAY,yFAAyF,EACrG,UAAU,kBAAkB;AAAA,QAC/B,iBAAiB,kCAAU,KACxB,YAAY,8FAA8F,EAC1G,UAAU,kBAAkB;AAAA,MACjC,CAAC;AAAA,IACH,CAAC;AAAA,EACH,CAAC,EAAE,YAAY,gDAAgD;AACjE;",
6
6
  "names": []
7
7
  }
@@ -90,6 +90,9 @@ const testSlotPropsAsFunctions = {
90
90
  dsVirtuallistListWrapper: () => ({ "aria-label": "items list wrapper" }),
91
91
  dsVirtuallistItemWrapper: () => ({ "aria-label": "item wrapper" })
92
92
  };
93
+ const handleMeasure = () => actionRef.current.measure?.();
94
+ const handleGetVisibleItems = () => actionRef.current.getVisibleItems?.() ?? [];
95
+ const handleGetMountedItems = () => actionRef.current.getMountedItems?.() ?? [];
93
96
  const ExampleUsageComponent = () => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
94
97
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_VirtualList.DSVirtualList, { ...testExplicitDefinition }),
95
98
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_VirtualList.DSVirtualList, { ...testInferredTypeCompatibility }),
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/typescript-testing/typescript-virtual-list-valid.tsx", "../../../../../../scripts/build/transpile/react-shim.js"],
4
- "sourcesContent": ["/* eslint-disable @typescript-eslint/no-unused-vars, no-unused-vars */\n/* eslint-disable local-rules/custom-rule */\nimport React from 'react';\nimport { DSVirtualList } from '../VirtualList.js';\nimport type { DSVirtualListT } from '../react-desc-prop-types.js';\n\ntype ComponentPropsForApp = DSVirtualListT.Props;\ntype ComponentPropsInternals = DSVirtualListT.InternalProps;\ntype ComponentPropsDefaultProps = DSVirtualListT.DefaultProps;\ntype ComponentPropsOptionalProps = DSVirtualListT.OptionalProps;\ntype ComponentPropsRequiredProps = DSVirtualListT.RequiredProps;\n\n// NOTE: `children` is typed as `React.ReactNode` (accepts a single element or an array), but\n// `DSVirtualListPropTypes.children` is `PropTypes.arrayOf(PropTypes.node).isRequired` \u2014 stricter\n// than the TS type. A single non-array child compiles here but throws at runtime. Every example\n// below passes an array to match the real, enforced contract \u2014 not just what the type permits.\nconst testRequiredProps: ComponentPropsRequiredProps = {\n children: [<div key=\"0\">item 0</div>],\n};\n\nconst testOptionalProps: ComponentPropsOptionalProps = {};\n\nconst testPartialDefaults: Partial<ComponentPropsDefaultProps> = {};\n\nconst testProps: ComponentPropsForApp = {\n ...testRequiredProps,\n ...testOptionalProps,\n ...testPartialDefaults,\n};\n\nconst testPropsAsSyntax = {\n ...testRequiredProps,\n ...testOptionalProps,\n ...testPartialDefaults,\n} as ComponentPropsForApp;\n\nconst testCompleteDefaults: Required<ComponentPropsDefaultProps> = {};\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// Example usages start here\nconst actionRef: React.MutableRefObject<DSVirtualListT.ActionRef> = { current: {} };\n\nconst testExplicitDefinition: ComponentPropsForApp = {\n children: [<div key=\"0\">item 0</div>, <div key=\"1\">item 1</div>],\n actionRef,\n};\n\nconst testInferredTypeCompatibility = {\n children: [<div key=\"0\">item 0</div>, <div key=\"1\">item 1</div>],\n actionRef,\n} as ComponentPropsForApp;\n\nconst testDefinitionAsConst = {\n children: [<div key=\"0\">item 0</div>, <div key=\"1\">item 1</div>],\n} as const;\n\nconst testSlotPropsAsObject: ComponentPropsForApp = {\n children: [<div key=\"0\">item 0</div>],\n dsVirtuallistRoot: { 'aria-label': 'items list' },\n dsVirtuallistListWrapper: { 'aria-label': 'items list wrapper' },\n dsVirtuallistItemWrapper: { 'aria-label': 'item wrapper' },\n};\n\n// Global HTML/ARIA attributes (className, id, aria-*, data-*) work at runtime via\n// useGetGlobalAttributes in List.tsx \u2014 Props/InternalProps extend Omit<GlobalAttributesT<HTMLElement>, ...>\n// specifically so this compiles. Regression here means the type/runtime contract has drifted apart again.\nconst testGlobalAttributes: ComponentPropsForApp = {\n children: [<div key=\"0\">item 0</div>],\n className: 'custom-class',\n id: 'custom-id',\n 'aria-label': 'custom list',\n};\n\nconst testSlotPropsAsFunctions: ComponentPropsForApp = {\n children: [<div key=\"0\">item 0</div>],\n dsVirtuallistRoot: () => ({ 'aria-label': 'items list' }),\n dsVirtuallistListWrapper: () => ({ 'aria-label': 'items list wrapper' }),\n dsVirtuallistItemWrapper: () => ({ 'aria-label': 'item wrapper' }),\n};\n\nconst ExampleUsageComponent = () => (\n <>\n {/* Works with explicitly casted props */}\n <DSVirtualList {...testExplicitDefinition} />\n <DSVirtualList {...testInferredTypeCompatibility} />\n <DSVirtualList {...testDefinitionAsConst} />\n <DSVirtualList {...testSlotPropsAsObject} />\n <DSVirtualList {...testSlotPropsAsFunctions} />\n <DSVirtualList {...testGlobalAttributes} />\n\n {/* Inline props test \u2014 global HTML/ARIA attributes. Array child to match the real, enforced\n runtime contract \u2014 a single child here would compile but throw (see NOTE above). */}\n <DSVirtualList className=\"custom-class\" id=\"custom-id\" aria-label=\"custom list\" data-testid=\"custom-testid\">\n {[<div key=\"0\">item 0</div>]}\n </DSVirtualList>\n\n {/* Inline props test \u2014 required prop only. Two children so JSX itself produces an array;\n a single child here would compile (React.ReactNode) but throw at runtime (see NOTE above). */}\n <DSVirtualList>\n <div>item 0</div>\n <div>item 1</div>\n </DSVirtualList>\n\n {/* Inline props test \u2014 actionRef and slot props */}\n <DSVirtualList actionRef={actionRef} dsVirtuallistRoot={{ tabIndex: 0 }}>\n <div>item 0</div>\n <div>item 1</div>\n </DSVirtualList>\n </>\n);\n\nexport default ExampleUsageComponent;\n", "import * as React from 'react';\nexport { React };\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADiBV;AAdb,yBAA8B;AAa9B,MAAM,oBAAiD;AAAA,EACrD,UAAU,CAAC,4CAAC,SAAY,sBAAJ,GAAU,CAAM;AACtC;AAEA,MAAM,oBAAiD,CAAC;AAExD,MAAM,sBAA2D,CAAC;AAElE,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;AAEA,MAAM,uBAA6D,CAAC;AAEpE,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,YAA8D,EAAE,SAAS,CAAC,EAAE;AAElF,MAAM,yBAA+C;AAAA,EACnD,UAAU,CAAC,4CAAC,SAAY,sBAAJ,GAAU,GAAQ,4CAAC,SAAY,sBAAJ,GAAU,CAAM;AAAA,EAC/D;AACF;AAEA,MAAM,gCAAgC;AAAA,EACpC,UAAU,CAAC,4CAAC,SAAY,sBAAJ,GAAU,GAAQ,4CAAC,SAAY,sBAAJ,GAAU,CAAM;AAAA,EAC/D;AACF;AAEA,MAAM,wBAAwB;AAAA,EAC5B,UAAU,CAAC,4CAAC,SAAY,sBAAJ,GAAU,GAAQ,4CAAC,SAAY,sBAAJ,GAAU,CAAM;AACjE;AAEA,MAAM,wBAA8C;AAAA,EAClD,UAAU,CAAC,4CAAC,SAAY,sBAAJ,GAAU,CAAM;AAAA,EACpC,mBAAmB,EAAE,cAAc,aAAa;AAAA,EAChD,0BAA0B,EAAE,cAAc,qBAAqB;AAAA,EAC/D,0BAA0B,EAAE,cAAc,eAAe;AAC3D;AAKA,MAAM,uBAA6C;AAAA,EACjD,UAAU,CAAC,4CAAC,SAAY,sBAAJ,GAAU,CAAM;AAAA,EACpC,WAAW;AAAA,EACX,IAAI;AAAA,EACJ,cAAc;AAChB;AAEA,MAAM,2BAAiD;AAAA,EACrD,UAAU,CAAC,4CAAC,SAAY,sBAAJ,GAAU,CAAM;AAAA,EACpC,mBAAmB,OAAO,EAAE,cAAc,aAAa;AAAA,EACvD,0BAA0B,OAAO,EAAE,cAAc,qBAAqB;AAAA,EACtE,0BAA0B,OAAO,EAAE,cAAc,eAAe;AAClE;AAEA,MAAM,wBAAwB,MAC5B,4EAEE;AAAA,8CAAC,oCAAe,GAAG,wBAAwB;AAAA,EAC3C,4CAAC,oCAAe,GAAG,+BAA+B;AAAA,EAClD,4CAAC,oCAAe,GAAG,uBAAuB;AAAA,EAC1C,4CAAC,oCAAe,GAAG,uBAAuB;AAAA,EAC1C,4CAAC,oCAAe,GAAG,0BAA0B;AAAA,EAC7C,4CAAC,oCAAe,GAAG,sBAAsB;AAAA,EAIzC,4CAAC,oCAAc,WAAU,gBAAe,IAAG,aAAY,cAAW,eAAc,eAAY,iBACzF,WAAC,4CAAC,SAAY,sBAAJ,GAAU,CAAM,GAC7B;AAAA,EAIA,6CAAC,oCACC;AAAA,gDAAC,SAAI,oBAAM;AAAA,IACX,4CAAC,SAAI,oBAAM;AAAA,KACb;AAAA,EAGA,6CAAC,oCAAc,WAAsB,mBAAmB,EAAE,UAAU,EAAE,GACpE;AAAA,gDAAC,SAAI,oBAAM;AAAA,IACX,4CAAC,SAAI,oBAAM;AAAA,KACb;AAAA,GACF;AAGF,IAAO,wCAAQ;",
4
+ "sourcesContent": ["/* eslint-disable @typescript-eslint/no-unused-vars, no-unused-vars */\n/* eslint-disable local-rules/custom-rule */\nimport React from 'react';\nimport { DSVirtualList } from '../VirtualList.js';\nimport type { DSVirtualListT } from '../react-desc-prop-types.js';\n\ntype ComponentPropsForApp = DSVirtualListT.Props;\ntype ComponentPropsInternals = DSVirtualListT.InternalProps;\ntype ComponentPropsDefaultProps = DSVirtualListT.DefaultProps;\ntype ComponentPropsOptionalProps = DSVirtualListT.OptionalProps;\ntype ComponentPropsRequiredProps = DSVirtualListT.RequiredProps;\n\n// NOTE: `children` is typed as `React.ReactNode` (accepts a single element or an array), but\n// `DSVirtualListPropTypes.children` is `PropTypes.arrayOf(PropTypes.node).isRequired` \u2014 stricter\n// than the TS type. A single non-array child compiles here but throws at runtime. Every example\n// below passes an array to match the real, enforced contract \u2014 not just what the type permits.\nconst testRequiredProps: ComponentPropsRequiredProps = {\n children: [<div key=\"0\">item 0</div>],\n};\n\nconst testOptionalProps: ComponentPropsOptionalProps = {};\n\nconst testPartialDefaults: Partial<ComponentPropsDefaultProps> = {};\n\nconst testProps: ComponentPropsForApp = {\n ...testRequiredProps,\n ...testOptionalProps,\n ...testPartialDefaults,\n};\n\nconst testPropsAsSyntax = {\n ...testRequiredProps,\n ...testOptionalProps,\n ...testPartialDefaults,\n} as ComponentPropsForApp;\n\nconst testCompleteDefaults: Required<ComponentPropsDefaultProps> = {};\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// Example usages start here\nconst actionRef: React.MutableRefObject<DSVirtualListT.ActionRef> = { current: {} };\n\nconst testExplicitDefinition: ComponentPropsForApp = {\n children: [<div key=\"0\">item 0</div>, <div key=\"1\">item 1</div>],\n actionRef,\n};\n\nconst testInferredTypeCompatibility = {\n children: [<div key=\"0\">item 0</div>, <div key=\"1\">item 1</div>],\n actionRef,\n} as ComponentPropsForApp;\n\nconst testDefinitionAsConst = {\n children: [<div key=\"0\">item 0</div>, <div key=\"1\">item 1</div>],\n} as const;\n\nconst testSlotPropsAsObject: ComponentPropsForApp = {\n children: [<div key=\"0\">item 0</div>],\n dsVirtuallistRoot: { 'aria-label': 'items list' },\n dsVirtuallistListWrapper: { 'aria-label': 'items list wrapper' },\n dsVirtuallistItemWrapper: { 'aria-label': 'item wrapper' },\n};\n\n// Global HTML/ARIA attributes (className, id, aria-*, data-*) work at runtime via\n// useGetGlobalAttributes in List.tsx \u2014 Props/InternalProps extend Omit<GlobalAttributesT<HTMLElement>, ...>\n// specifically so this compiles. Regression here means the type/runtime contract has drifted apart again.\nconst testGlobalAttributes: ComponentPropsForApp = {\n children: [<div key=\"0\">item 0</div>],\n className: 'custom-class',\n id: 'custom-id',\n 'aria-label': 'custom list',\n};\n\nconst testSlotPropsAsFunctions: ComponentPropsForApp = {\n children: [<div key=\"0\">item 0</div>],\n dsVirtuallistRoot: () => ({ 'aria-label': 'items list' }),\n dsVirtuallistListWrapper: () => ({ 'aria-label': 'items list wrapper' }),\n dsVirtuallistItemWrapper: () => ({ 'aria-label': 'item wrapper' }),\n};\n\n// actionRef method usages \u2014 measure() and getVisibleItems() (PUI-17898)\nconst handleMeasure = () => actionRef.current.measure?.();\nconst handleGetVisibleItems: () => number[] = () => actionRef.current.getVisibleItems?.() ?? [];\nconst handleGetMountedItems: () => number[] = () => actionRef.current.getMountedItems?.() ?? [];\n\nconst ExampleUsageComponent = () => (\n <>\n {/* Works with explicitly casted props */}\n <DSVirtualList {...testExplicitDefinition} />\n <DSVirtualList {...testInferredTypeCompatibility} />\n <DSVirtualList {...testDefinitionAsConst} />\n <DSVirtualList {...testSlotPropsAsObject} />\n <DSVirtualList {...testSlotPropsAsFunctions} />\n <DSVirtualList {...testGlobalAttributes} />\n\n {/* Inline props test \u2014 global HTML/ARIA attributes. Array child to match the real, enforced\n runtime contract \u2014 a single child here would compile but throw (see NOTE above). */}\n <DSVirtualList className=\"custom-class\" id=\"custom-id\" aria-label=\"custom list\" data-testid=\"custom-testid\">\n {[<div key=\"0\">item 0</div>]}\n </DSVirtualList>\n\n {/* Inline props test \u2014 required prop only. Two children so JSX itself produces an array;\n a single child here would compile (React.ReactNode) but throw at runtime (see NOTE above). */}\n <DSVirtualList>\n <div>item 0</div>\n <div>item 1</div>\n </DSVirtualList>\n\n {/* Inline props test \u2014 actionRef and slot props */}\n <DSVirtualList actionRef={actionRef} dsVirtuallistRoot={{ tabIndex: 0 }}>\n <div>item 0</div>\n <div>item 1</div>\n </DSVirtualList>\n </>\n);\n\nexport default ExampleUsageComponent;\n", "import * as React from 'react';\nexport { React };\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADiBV;AAdb,yBAA8B;AAa9B,MAAM,oBAAiD;AAAA,EACrD,UAAU,CAAC,4CAAC,SAAY,sBAAJ,GAAU,CAAM;AACtC;AAEA,MAAM,oBAAiD,CAAC;AAExD,MAAM,sBAA2D,CAAC;AAElE,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;AAEA,MAAM,uBAA6D,CAAC;AAEpE,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,YAA8D,EAAE,SAAS,CAAC,EAAE;AAElF,MAAM,yBAA+C;AAAA,EACnD,UAAU,CAAC,4CAAC,SAAY,sBAAJ,GAAU,GAAQ,4CAAC,SAAY,sBAAJ,GAAU,CAAM;AAAA,EAC/D;AACF;AAEA,MAAM,gCAAgC;AAAA,EACpC,UAAU,CAAC,4CAAC,SAAY,sBAAJ,GAAU,GAAQ,4CAAC,SAAY,sBAAJ,GAAU,CAAM;AAAA,EAC/D;AACF;AAEA,MAAM,wBAAwB;AAAA,EAC5B,UAAU,CAAC,4CAAC,SAAY,sBAAJ,GAAU,GAAQ,4CAAC,SAAY,sBAAJ,GAAU,CAAM;AACjE;AAEA,MAAM,wBAA8C;AAAA,EAClD,UAAU,CAAC,4CAAC,SAAY,sBAAJ,GAAU,CAAM;AAAA,EACpC,mBAAmB,EAAE,cAAc,aAAa;AAAA,EAChD,0BAA0B,EAAE,cAAc,qBAAqB;AAAA,EAC/D,0BAA0B,EAAE,cAAc,eAAe;AAC3D;AAKA,MAAM,uBAA6C;AAAA,EACjD,UAAU,CAAC,4CAAC,SAAY,sBAAJ,GAAU,CAAM;AAAA,EACpC,WAAW;AAAA,EACX,IAAI;AAAA,EACJ,cAAc;AAChB;AAEA,MAAM,2BAAiD;AAAA,EACrD,UAAU,CAAC,4CAAC,SAAY,sBAAJ,GAAU,CAAM;AAAA,EACpC,mBAAmB,OAAO,EAAE,cAAc,aAAa;AAAA,EACvD,0BAA0B,OAAO,EAAE,cAAc,qBAAqB;AAAA,EACtE,0BAA0B,OAAO,EAAE,cAAc,eAAe;AAClE;AAGA,MAAM,gBAAgB,MAAM,UAAU,QAAQ,UAAU;AACxD,MAAM,wBAAwC,MAAM,UAAU,QAAQ,kBAAkB,KAAK,CAAC;AAC9F,MAAM,wBAAwC,MAAM,UAAU,QAAQ,kBAAkB,KAAK,CAAC;AAE9F,MAAM,wBAAwB,MAC5B,4EAEE;AAAA,8CAAC,oCAAe,GAAG,wBAAwB;AAAA,EAC3C,4CAAC,oCAAe,GAAG,+BAA+B;AAAA,EAClD,4CAAC,oCAAe,GAAG,uBAAuB;AAAA,EAC1C,4CAAC,oCAAe,GAAG,uBAAuB;AAAA,EAC1C,4CAAC,oCAAe,GAAG,0BAA0B;AAAA,EAC7C,4CAAC,oCAAe,GAAG,sBAAsB;AAAA,EAIzC,4CAAC,oCAAc,WAAU,gBAAe,IAAG,aAAY,cAAW,eAAc,eAAY,iBACzF,WAAC,4CAAC,SAAY,sBAAJ,GAAU,CAAM,GAC7B;AAAA,EAIA,6CAAC,oCACC;AAAA,gDAAC,SAAI,oBAAM;AAAA,IACX,4CAAC,SAAI,oBAAM;AAAA,KACb;AAAA,EAGA,6CAAC,oCAAc,WAAsB,mBAAmB,EAAE,UAAU,EAAE,GACpE;AAAA,gDAAC,SAAI,oBAAM;AAAA,IACX,4CAAC,SAAI,oBAAM;AAAA,KACb;AAAA,GACF;AAGF,IAAO,wCAAQ;",
6
6
  "names": []
7
7
  }
@@ -22,7 +22,18 @@ const useVirtualListV3 = (propsFromUser) => {
22
22
  estimateSize
23
23
  });
24
24
  const totalSize = useVirtualHelpers.getTotalSize();
25
- if (actionRef && actionRef.current) actionRef.current.scrollTo = useVirtualHelpers.scrollToIndex;
25
+ if (actionRef && actionRef.current) {
26
+ actionRef.current.scrollTo = useVirtualHelpers.scrollToIndex;
27
+ actionRef.current.measure = useVirtualHelpers.measure;
28
+ actionRef.current.getVisibleItems = () => {
29
+ const range = useVirtualHelpers.calculateRange();
30
+ if (!range) return [];
31
+ const indices = [];
32
+ for (let index = range.startIndex; index <= range.endIndex; index += 1) indices.push(index);
33
+ return indices;
34
+ };
35
+ actionRef.current.getMountedItems = () => useVirtualHelpers.getVirtualItems().map((item) => item.index);
36
+ }
26
37
  const instanceUid = React2.useMemo(() => `ds-virtual-list-${uid(6)}`, []);
27
38
  return React2.useMemo(
28
39
  () => ({
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../scripts/build/transpile/react-shim.js", "../../../src/hooks/useVirtualList.tsx"],
4
- "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "import { useMemoMergePropsWithDefault } from '@elliemae/ds-props-helpers';\nimport { useVirtualizer, type Virtualizer } from '@tanstack/react-virtual';\nimport React from 'react';\nimport { uid } from 'uid';\nimport { DSVirtualListPropTypes, defaultProps, type DSVirtualListT } from '../react-desc-prop-types.js';\nimport { useValidateProps } from './useValidateProps.js';\n\nconst estimateSize = () => 50;\n\nexport type VirtualListCTX = {\n instanceUid: string;\n filteredChildren: React.ReactNode[];\n propsWithDefault: DSVirtualListT.InternalProps;\n parentRef: React.MutableRefObject<HTMLDivElement | null>;\n getVirtualItems: Virtualizer<HTMLDivElement, HTMLElement>['getVirtualItems'];\n totalSize: ReturnType<Virtualizer<HTMLDivElement, HTMLElement>['getTotalSize']>;\n measureElement: Virtualizer<HTMLDivElement, HTMLElement>['measureElement'];\n};\nexport const useVirtualListV3 = (propsFromUser: DSVirtualListT.Props): VirtualListCTX => {\n // =============================================================================\n // MERGE WITH DEFAULT AND VALIDATE PROPS\n // =============================================================================\n const propsWithDefault = useMemoMergePropsWithDefault<DSVirtualListT.InternalProps>(propsFromUser, defaultProps);\n useValidateProps(propsWithDefault, DSVirtualListPropTypes);\n // =============================================================================\n // AD HOC PER COMPONENT LOGIC\n // =============================================================================\n const { children, actionRef } = propsWithDefault;\n const parentRef = React.useRef<HTMLDivElement>(null);\n const filteredChildren = React.useMemo(\n () => React.Children.toArray(children).filter((child) => child !== undefined && child !== null),\n [children],\n ) as React.ReactNode[];\n const useVirtualHelpers = useVirtualizer({\n count: filteredChildren.length,\n getScrollElement: () => parentRef.current,\n overscan: 15,\n estimateSize,\n });\n const totalSize = useVirtualHelpers.getTotalSize();\n if (actionRef && actionRef.current) actionRef.current.scrollTo = useVirtualHelpers.scrollToIndex;\n\n const instanceUid = React.useMemo(() => `ds-virtual-list-${uid(6)}`, []);\n return React.useMemo(\n () => ({\n instanceUid,\n filteredChildren,\n propsWithDefault,\n parentRef,\n getVirtualItems: useVirtualHelpers.getVirtualItems,\n totalSize,\n measureElement: useVirtualHelpers.measureElement,\n }),\n [\n useVirtualHelpers.getVirtualItems,\n useVirtualHelpers.measureElement,\n filteredChildren,\n totalSize,\n instanceUid,\n propsWithDefault,\n ],\n );\n};\n"],
5
- "mappings": "AAAA,YAAY,WAAW;ACAvB,SAAS,oCAAoC;AAC7C,SAAS,sBAAwC;AACjD,OAAOA,YAAW;AAClB,SAAS,WAAW;AACpB,SAAS,wBAAwB,oBAAyC;AAC1E,SAAS,wBAAwB;AAEjC,MAAM,eAAe,MAAM;AAWpB,MAAM,mBAAmB,CAAC,kBAAwD;AAIvF,QAAM,mBAAmB,6BAA2D,eAAe,YAAY;AAC/G,mBAAiB,kBAAkB,sBAAsB;AAIzD,QAAM,EAAE,UAAU,UAAU,IAAI;AAChC,QAAM,YAAYA,OAAM,OAAuB,IAAI;AACnD,QAAM,mBAAmBA,OAAM;AAAA,IAC7B,MAAMA,OAAM,SAAS,QAAQ,QAAQ,EAAE,OAAO,CAAC,UAAU,UAAU,UAAa,UAAU,IAAI;AAAA,IAC9F,CAAC,QAAQ;AAAA,EACX;AACA,QAAM,oBAAoB,eAAe;AAAA,IACvC,OAAO,iBAAiB;AAAA,IACxB,kBAAkB,MAAM,UAAU;AAAA,IAClC,UAAU;AAAA,IACV;AAAA,EACF,CAAC;AACD,QAAM,YAAY,kBAAkB,aAAa;AACjD,MAAI,aAAa,UAAU,QAAS,WAAU,QAAQ,WAAW,kBAAkB;AAEnF,QAAM,cAAcA,OAAM,QAAQ,MAAM,mBAAmB,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC;AACvE,SAAOA,OAAM;AAAA,IACX,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,iBAAiB,kBAAkB;AAAA,MACnC;AAAA,MACA,gBAAgB,kBAAkB;AAAA,IACpC;AAAA,IACA;AAAA,MACE,kBAAkB;AAAA,MAClB,kBAAkB;AAAA,MAClB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;",
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "import { useMemoMergePropsWithDefault } from '@elliemae/ds-props-helpers';\nimport { useVirtualizer, type Virtualizer } from '@tanstack/react-virtual';\nimport React from 'react';\nimport { uid } from 'uid';\nimport { DSVirtualListPropTypes, defaultProps, type DSVirtualListT } from '../react-desc-prop-types.js';\nimport { useValidateProps } from './useValidateProps.js';\n\nconst estimateSize = () => 50;\n\nexport type VirtualListCTX = {\n instanceUid: string;\n filteredChildren: React.ReactNode[];\n propsWithDefault: DSVirtualListT.InternalProps;\n parentRef: React.MutableRefObject<HTMLDivElement | null>;\n getVirtualItems: Virtualizer<HTMLDivElement, HTMLElement>['getVirtualItems'];\n totalSize: ReturnType<Virtualizer<HTMLDivElement, HTMLElement>['getTotalSize']>;\n measureElement: Virtualizer<HTMLDivElement, HTMLElement>['measureElement'];\n};\nexport const useVirtualListV3 = (propsFromUser: DSVirtualListT.Props): VirtualListCTX => {\n // =============================================================================\n // MERGE WITH DEFAULT AND VALIDATE PROPS\n // =============================================================================\n const propsWithDefault = useMemoMergePropsWithDefault<DSVirtualListT.InternalProps>(propsFromUser, defaultProps);\n useValidateProps(propsWithDefault, DSVirtualListPropTypes);\n // =============================================================================\n // AD HOC PER COMPONENT LOGIC\n // =============================================================================\n const { children, actionRef } = propsWithDefault;\n const parentRef = React.useRef<HTMLDivElement>(null);\n const filteredChildren = React.useMemo(\n () => React.Children.toArray(children).filter((child) => child !== undefined && child !== null),\n [children],\n ) as React.ReactNode[];\n const useVirtualHelpers = useVirtualizer({\n count: filteredChildren.length,\n getScrollElement: () => parentRef.current,\n overscan: 15,\n estimateSize,\n });\n const totalSize = useVirtualHelpers.getTotalSize();\n if (actionRef && actionRef.current) {\n actionRef.current.scrollTo = useVirtualHelpers.scrollToIndex;\n actionRef.current.measure = useVirtualHelpers.measure;\n // `getVirtualItems()` includes the overscan buffer on each side \u2014 not what \"visible\" means.\n // `calculateRange()` is the virtualizer's own pre-overscan viewport calculation (pure scroll\n // geometry, no DOM scraping) and is what \"currently visible\" should actually be backed by.\n actionRef.current.getVisibleItems = () => {\n const range = useVirtualHelpers.calculateRange();\n if (!range) return [];\n const indices: number[] = [];\n for (let index = range.startIndex; index <= range.endIndex; index += 1) indices.push(index);\n return indices;\n };\n // The overscanned set (viewport + the 15-item buffer on each side) \u2014 everything currently\n // mounted in the DOM, as opposed to `getVisibleItems()`'s true-viewport-only set above.\n actionRef.current.getMountedItems = () => useVirtualHelpers.getVirtualItems().map((item) => item.index);\n }\n\n const instanceUid = React.useMemo(() => `ds-virtual-list-${uid(6)}`, []);\n return React.useMemo(\n () => ({\n instanceUid,\n filteredChildren,\n propsWithDefault,\n parentRef,\n getVirtualItems: useVirtualHelpers.getVirtualItems,\n totalSize,\n measureElement: useVirtualHelpers.measureElement,\n }),\n [\n useVirtualHelpers.getVirtualItems,\n useVirtualHelpers.measureElement,\n filteredChildren,\n totalSize,\n instanceUid,\n propsWithDefault,\n ],\n );\n};\n"],
5
+ "mappings": "AAAA,YAAY,WAAW;ACAvB,SAAS,oCAAoC;AAC7C,SAAS,sBAAwC;AACjD,OAAOA,YAAW;AAClB,SAAS,WAAW;AACpB,SAAS,wBAAwB,oBAAyC;AAC1E,SAAS,wBAAwB;AAEjC,MAAM,eAAe,MAAM;AAWpB,MAAM,mBAAmB,CAAC,kBAAwD;AAIvF,QAAM,mBAAmB,6BAA2D,eAAe,YAAY;AAC/G,mBAAiB,kBAAkB,sBAAsB;AAIzD,QAAM,EAAE,UAAU,UAAU,IAAI;AAChC,QAAM,YAAYA,OAAM,OAAuB,IAAI;AACnD,QAAM,mBAAmBA,OAAM;AAAA,IAC7B,MAAMA,OAAM,SAAS,QAAQ,QAAQ,EAAE,OAAO,CAAC,UAAU,UAAU,UAAa,UAAU,IAAI;AAAA,IAC9F,CAAC,QAAQ;AAAA,EACX;AACA,QAAM,oBAAoB,eAAe;AAAA,IACvC,OAAO,iBAAiB;AAAA,IACxB,kBAAkB,MAAM,UAAU;AAAA,IAClC,UAAU;AAAA,IACV;AAAA,EACF,CAAC;AACD,QAAM,YAAY,kBAAkB,aAAa;AACjD,MAAI,aAAa,UAAU,SAAS;AAClC,cAAU,QAAQ,WAAW,kBAAkB;AAC/C,cAAU,QAAQ,UAAU,kBAAkB;AAI9C,cAAU,QAAQ,kBAAkB,MAAM;AACxC,YAAM,QAAQ,kBAAkB,eAAe;AAC/C,UAAI,CAAC,MAAO,QAAO,CAAC;AACpB,YAAM,UAAoB,CAAC;AAC3B,eAAS,QAAQ,MAAM,YAAY,SAAS,MAAM,UAAU,SAAS,EAAG,SAAQ,KAAK,KAAK;AAC1F,aAAO;AAAA,IACT;AAGA,cAAU,QAAQ,kBAAkB,MAAM,kBAAkB,gBAAgB,EAAE,IAAI,CAAC,SAAS,KAAK,KAAK;AAAA,EACxG;AAEA,QAAM,cAAcA,OAAM,QAAQ,MAAM,mBAAmB,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC;AACvE,SAAOA,OAAM;AAAA,IACX,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,iBAAiB,kBAAkB;AAAA,MACnC;AAAA,MACA,gBAAgB,kBAAkB;AAAA,IACpC;AAAA,IACA;AAAA,MACE,kBAAkB;AAAA,MAClB,kBAAkB;AAAA,MAClB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;",
6
6
  "names": ["React"]
7
7
  }
@@ -10,7 +10,12 @@ const DSVirtualListPropTypes = {
10
10
  current: PropTypes.oneOfType([
11
11
  PropTypes.oneOf([null]),
12
12
  PropTypes.shape({
13
- scrollTo: PropTypes.func.description("Scroll to a index inside the list").signature(`((index: number, { align: 'start' | 'center' | 'end' | 'auto' }) => void)`)
13
+ scrollTo: PropTypes.func.description("Scroll to a index inside the list").signature(`((index: number, { align: 'start' | 'center' | 'end' | 'auto' }) => void)`),
14
+ measure: PropTypes.func.description(
15
+ "Clears the cached size of every item, falling back to the estimated size until each item is measured again (on its next real layout change or remount) \u2014 does not force an immediate DOM remeasurement"
16
+ ).signature(`(() => void)`),
17
+ getVisibleItems: PropTypes.func.description("Returns the indices of the items currently visible in the viewport (no overscan buffer)").signature(`(() => number[])`),
18
+ getMountedItems: PropTypes.func.description("Returns the indices of all items currently mounted in the DOM, including the overscan buffer").signature(`(() => number[])`)
14
19
  })
15
20
  ])
16
21
  }).description(`mutable reference where methods will be stored`)
@@ -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", "import type React from 'react';\nimport { type TypescriptHelpersT } from '@elliemae/ds-typescript-helpers';\nimport type { GlobalAttributesT } from '@elliemae/ds-props-helpers';\nimport { PropTypes, getPropsPerSlotPropTypes, globalAttributesPropTypes } from '@elliemae/ds-props-helpers';\nimport { DSVirtualListName, DSVirtualListSlots } from './constants/index.js';\n\nexport declare namespace DSVirtualListT {\n type ScrollAlignment = 'start' | 'center' | 'end' | 'auto';\n type ScrollToOptions = {\n align: ScrollAlignment;\n };\n\n export type ActionRef = {\n scrollTo?: (index: number, options?: ScrollToOptions | undefined) => void;\n };\n\n export type SlotFunctionArguments = {\n dsVirtuallistRoot: () => object;\n dsVirtuallistListWrapper: () => object;\n dsVirtuallistItemWrapper: () => object;\n };\n\n export interface RequiredProps {\n children: React.ReactNode;\n }\n\n export interface DefaultProps {}\n\n export interface OptionalProps extends TypescriptHelpersT.PropsForGlobalOnSlots<\n typeof DSVirtualListName,\n typeof DSVirtualListSlots\n > {\n actionRef?: React.MutableRefObject<ActionRef>;\n }\n\n export interface Props\n extends\n Partial<DefaultProps>,\n OptionalProps,\n Omit<GlobalAttributesT<HTMLElement>, keyof DefaultProps | keyof RequiredProps>,\n RequiredProps {}\n\n export interface InternalProps\n extends\n DefaultProps,\n OptionalProps,\n Omit<GlobalAttributesT<HTMLElement>, keyof DefaultProps | keyof RequiredProps>,\n RequiredProps {}\n}\n\nexport const defaultProps: DSVirtualListT.DefaultProps = {};\n\nexport const DSVirtualListPropTypes = {\n ...getPropsPerSlotPropTypes(DSVirtualListName, DSVirtualListSlots),\n ...globalAttributesPropTypes,\n children: PropTypes.arrayOf(PropTypes.node).description('Children list').isRequired,\n actionRef: PropTypes.shape({\n current: PropTypes.oneOfType([\n PropTypes.oneOf([null]),\n PropTypes.shape({\n scrollTo: PropTypes.func\n .description('Scroll to a index inside the list')\n .signature(`((index: number, { align: 'start' | 'center' | 'end' | 'auto' }) => void)`),\n }),\n ]),\n }).description(`mutable reference where methods will be stored`),\n} as React.WeakValidationMap<unknown>;\n"],
5
- "mappings": "AAAA,YAAY,WAAW;ACGvB,SAAS,WAAW,0BAA0B,iCAAiC;AAC/E,SAAS,mBAAmB,0BAA0B;AA8C/C,MAAM,eAA4C,CAAC;AAEnD,MAAM,yBAAyB;AAAA,EACpC,GAAG,yBAAyB,mBAAmB,kBAAkB;AAAA,EACjE,GAAG;AAAA,EACH,UAAU,UAAU,QAAQ,UAAU,IAAI,EAAE,YAAY,eAAe,EAAE;AAAA,EACzE,WAAW,UAAU,MAAM;AAAA,IACzB,SAAS,UAAU,UAAU;AAAA,MAC3B,UAAU,MAAM,CAAC,IAAI,CAAC;AAAA,MACtB,UAAU,MAAM;AAAA,QACd,UAAU,UAAU,KACjB,YAAY,mCAAmC,EAC/C,UAAU,2EAA2E;AAAA,MAC1F,CAAC;AAAA,IACH,CAAC;AAAA,EACH,CAAC,EAAE,YAAY,gDAAgD;AACjE;",
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "import type React from 'react';\nimport { type TypescriptHelpersT } from '@elliemae/ds-typescript-helpers';\nimport type { GlobalAttributesT } from '@elliemae/ds-props-helpers';\nimport { PropTypes, getPropsPerSlotPropTypes, globalAttributesPropTypes } from '@elliemae/ds-props-helpers';\nimport { DSVirtualListName, DSVirtualListSlots } from './constants/index.js';\n\nexport declare namespace DSVirtualListT {\n type ScrollAlignment = 'start' | 'center' | 'end' | 'auto';\n type ScrollToOptions = {\n align: ScrollAlignment;\n };\n\n export type ActionRef = {\n scrollTo?: (index: number, options?: ScrollToOptions | undefined) => void;\n measure?: () => void;\n getVisibleItems?: () => number[];\n getMountedItems?: () => number[];\n };\n\n export type SlotFunctionArguments = {\n dsVirtuallistRoot: () => object;\n dsVirtuallistListWrapper: () => object;\n dsVirtuallistItemWrapper: () => object;\n };\n\n export interface RequiredProps {\n children: React.ReactNode;\n }\n\n export interface DefaultProps {}\n\n export interface OptionalProps extends TypescriptHelpersT.PropsForGlobalOnSlots<\n typeof DSVirtualListName,\n typeof DSVirtualListSlots\n > {\n actionRef?: React.MutableRefObject<ActionRef>;\n }\n\n export interface Props\n extends\n Partial<DefaultProps>,\n OptionalProps,\n Omit<GlobalAttributesT<HTMLElement>, keyof DefaultProps | keyof RequiredProps>,\n RequiredProps {}\n\n export interface InternalProps\n extends\n DefaultProps,\n OptionalProps,\n Omit<GlobalAttributesT<HTMLElement>, keyof DefaultProps | keyof RequiredProps>,\n RequiredProps {}\n}\n\nexport const defaultProps: DSVirtualListT.DefaultProps = {};\n\nexport const DSVirtualListPropTypes = {\n ...getPropsPerSlotPropTypes(DSVirtualListName, DSVirtualListSlots),\n ...globalAttributesPropTypes,\n children: PropTypes.arrayOf(PropTypes.node).description('Children list').isRequired,\n actionRef: PropTypes.shape({\n current: PropTypes.oneOfType([\n PropTypes.oneOf([null]),\n PropTypes.shape({\n scrollTo: PropTypes.func\n .description('Scroll to a index inside the list')\n .signature(`((index: number, { align: 'start' | 'center' | 'end' | 'auto' }) => void)`),\n measure: PropTypes.func\n .description(\n 'Clears the cached size of every item, falling back to the estimated size until each item is measured again (on its next real layout change or remount) \u2014 does not force an immediate DOM remeasurement',\n )\n .signature(`(() => void)`),\n getVisibleItems: PropTypes.func\n .description('Returns the indices of the items currently visible in the viewport (no overscan buffer)')\n .signature(`(() => number[])`),\n getMountedItems: PropTypes.func\n .description('Returns the indices of all items currently mounted in the DOM, including the overscan buffer')\n .signature(`(() => number[])`),\n }),\n ]),\n }).description(`mutable reference where methods will be stored`),\n} as React.WeakValidationMap<unknown>;\n"],
5
+ "mappings": "AAAA,YAAY,WAAW;ACGvB,SAAS,WAAW,0BAA0B,iCAAiC;AAC/E,SAAS,mBAAmB,0BAA0B;AAiD/C,MAAM,eAA4C,CAAC;AAEnD,MAAM,yBAAyB;AAAA,EACpC,GAAG,yBAAyB,mBAAmB,kBAAkB;AAAA,EACjE,GAAG;AAAA,EACH,UAAU,UAAU,QAAQ,UAAU,IAAI,EAAE,YAAY,eAAe,EAAE;AAAA,EACzE,WAAW,UAAU,MAAM;AAAA,IACzB,SAAS,UAAU,UAAU;AAAA,MAC3B,UAAU,MAAM,CAAC,IAAI,CAAC;AAAA,MACtB,UAAU,MAAM;AAAA,QACd,UAAU,UAAU,KACjB,YAAY,mCAAmC,EAC/C,UAAU,2EAA2E;AAAA,QACxF,SAAS,UAAU,KAChB;AAAA,UACC;AAAA,QACF,EACC,UAAU,cAAc;AAAA,QAC3B,iBAAiB,UAAU,KACxB,YAAY,yFAAyF,EACrG,UAAU,kBAAkB;AAAA,QAC/B,iBAAiB,UAAU,KACxB,YAAY,8FAA8F,EAC1G,UAAU,kBAAkB;AAAA,MACjC,CAAC;AAAA,IACH,CAAC;AAAA,EACH,CAAC,EAAE,YAAY,gDAAgD;AACjE;",
6
6
  "names": []
7
7
  }
@@ -57,6 +57,9 @@ const testSlotPropsAsFunctions = {
57
57
  dsVirtuallistListWrapper: () => ({ "aria-label": "items list wrapper" }),
58
58
  dsVirtuallistItemWrapper: () => ({ "aria-label": "item wrapper" })
59
59
  };
60
+ const handleMeasure = () => actionRef.current.measure?.();
61
+ const handleGetVisibleItems = () => actionRef.current.getVisibleItems?.() ?? [];
62
+ const handleGetMountedItems = () => actionRef.current.getMountedItems?.() ?? [];
60
63
  const ExampleUsageComponent = () => /* @__PURE__ */ jsxs(Fragment, { children: [
61
64
  /* @__PURE__ */ jsx(DSVirtualList, { ...testExplicitDefinition }),
62
65
  /* @__PURE__ */ jsx(DSVirtualList, { ...testInferredTypeCompatibility }),
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../scripts/build/transpile/react-shim.js", "../../../src/typescript-testing/typescript-virtual-list-valid.tsx"],
4
- "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable @typescript-eslint/no-unused-vars, no-unused-vars */\n/* eslint-disable local-rules/custom-rule */\nimport React from 'react';\nimport { DSVirtualList } from '../VirtualList.js';\nimport type { DSVirtualListT } from '../react-desc-prop-types.js';\n\ntype ComponentPropsForApp = DSVirtualListT.Props;\ntype ComponentPropsInternals = DSVirtualListT.InternalProps;\ntype ComponentPropsDefaultProps = DSVirtualListT.DefaultProps;\ntype ComponentPropsOptionalProps = DSVirtualListT.OptionalProps;\ntype ComponentPropsRequiredProps = DSVirtualListT.RequiredProps;\n\n// NOTE: `children` is typed as `React.ReactNode` (accepts a single element or an array), but\n// `DSVirtualListPropTypes.children` is `PropTypes.arrayOf(PropTypes.node).isRequired` \u2014 stricter\n// than the TS type. A single non-array child compiles here but throws at runtime. Every example\n// below passes an array to match the real, enforced contract \u2014 not just what the type permits.\nconst testRequiredProps: ComponentPropsRequiredProps = {\n children: [<div key=\"0\">item 0</div>],\n};\n\nconst testOptionalProps: ComponentPropsOptionalProps = {};\n\nconst testPartialDefaults: Partial<ComponentPropsDefaultProps> = {};\n\nconst testProps: ComponentPropsForApp = {\n ...testRequiredProps,\n ...testOptionalProps,\n ...testPartialDefaults,\n};\n\nconst testPropsAsSyntax = {\n ...testRequiredProps,\n ...testOptionalProps,\n ...testPartialDefaults,\n} as ComponentPropsForApp;\n\nconst testCompleteDefaults: Required<ComponentPropsDefaultProps> = {};\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// Example usages start here\nconst actionRef: React.MutableRefObject<DSVirtualListT.ActionRef> = { current: {} };\n\nconst testExplicitDefinition: ComponentPropsForApp = {\n children: [<div key=\"0\">item 0</div>, <div key=\"1\">item 1</div>],\n actionRef,\n};\n\nconst testInferredTypeCompatibility = {\n children: [<div key=\"0\">item 0</div>, <div key=\"1\">item 1</div>],\n actionRef,\n} as ComponentPropsForApp;\n\nconst testDefinitionAsConst = {\n children: [<div key=\"0\">item 0</div>, <div key=\"1\">item 1</div>],\n} as const;\n\nconst testSlotPropsAsObject: ComponentPropsForApp = {\n children: [<div key=\"0\">item 0</div>],\n dsVirtuallistRoot: { 'aria-label': 'items list' },\n dsVirtuallistListWrapper: { 'aria-label': 'items list wrapper' },\n dsVirtuallistItemWrapper: { 'aria-label': 'item wrapper' },\n};\n\n// Global HTML/ARIA attributes (className, id, aria-*, data-*) work at runtime via\n// useGetGlobalAttributes in List.tsx \u2014 Props/InternalProps extend Omit<GlobalAttributesT<HTMLElement>, ...>\n// specifically so this compiles. Regression here means the type/runtime contract has drifted apart again.\nconst testGlobalAttributes: ComponentPropsForApp = {\n children: [<div key=\"0\">item 0</div>],\n className: 'custom-class',\n id: 'custom-id',\n 'aria-label': 'custom list',\n};\n\nconst testSlotPropsAsFunctions: ComponentPropsForApp = {\n children: [<div key=\"0\">item 0</div>],\n dsVirtuallistRoot: () => ({ 'aria-label': 'items list' }),\n dsVirtuallistListWrapper: () => ({ 'aria-label': 'items list wrapper' }),\n dsVirtuallistItemWrapper: () => ({ 'aria-label': 'item wrapper' }),\n};\n\nconst ExampleUsageComponent = () => (\n <>\n {/* Works with explicitly casted props */}\n <DSVirtualList {...testExplicitDefinition} />\n <DSVirtualList {...testInferredTypeCompatibility} />\n <DSVirtualList {...testDefinitionAsConst} />\n <DSVirtualList {...testSlotPropsAsObject} />\n <DSVirtualList {...testSlotPropsAsFunctions} />\n <DSVirtualList {...testGlobalAttributes} />\n\n {/* Inline props test \u2014 global HTML/ARIA attributes. Array child to match the real, enforced\n runtime contract \u2014 a single child here would compile but throw (see NOTE above). */}\n <DSVirtualList className=\"custom-class\" id=\"custom-id\" aria-label=\"custom list\" data-testid=\"custom-testid\">\n {[<div key=\"0\">item 0</div>]}\n </DSVirtualList>\n\n {/* Inline props test \u2014 required prop only. Two children so JSX itself produces an array;\n a single child here would compile (React.ReactNode) but throw at runtime (see NOTE above). */}\n <DSVirtualList>\n <div>item 0</div>\n <div>item 1</div>\n </DSVirtualList>\n\n {/* Inline props test \u2014 actionRef and slot props */}\n <DSVirtualList actionRef={actionRef} dsVirtuallistRoot={{ tabIndex: 0 }}>\n <div>item 0</div>\n <div>item 1</div>\n </DSVirtualList>\n </>\n);\n\nexport default ExampleUsageComponent;\n"],
5
- "mappings": "AAAA,YAAY,WAAW;ACiBV,SA2EX,UA3EW,KA4FT,YA5FS;AAdb,SAAS,qBAAqB;AAa9B,MAAM,oBAAiD;AAAA,EACrD,UAAU,CAAC,oBAAC,SAAY,sBAAJ,GAAU,CAAM;AACtC;AAEA,MAAM,oBAAiD,CAAC;AAExD,MAAM,sBAA2D,CAAC;AAElE,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;AAEA,MAAM,uBAA6D,CAAC;AAEpE,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,YAA8D,EAAE,SAAS,CAAC,EAAE;AAElF,MAAM,yBAA+C;AAAA,EACnD,UAAU,CAAC,oBAAC,SAAY,sBAAJ,GAAU,GAAQ,oBAAC,SAAY,sBAAJ,GAAU,CAAM;AAAA,EAC/D;AACF;AAEA,MAAM,gCAAgC;AAAA,EACpC,UAAU,CAAC,oBAAC,SAAY,sBAAJ,GAAU,GAAQ,oBAAC,SAAY,sBAAJ,GAAU,CAAM;AAAA,EAC/D;AACF;AAEA,MAAM,wBAAwB;AAAA,EAC5B,UAAU,CAAC,oBAAC,SAAY,sBAAJ,GAAU,GAAQ,oBAAC,SAAY,sBAAJ,GAAU,CAAM;AACjE;AAEA,MAAM,wBAA8C;AAAA,EAClD,UAAU,CAAC,oBAAC,SAAY,sBAAJ,GAAU,CAAM;AAAA,EACpC,mBAAmB,EAAE,cAAc,aAAa;AAAA,EAChD,0BAA0B,EAAE,cAAc,qBAAqB;AAAA,EAC/D,0BAA0B,EAAE,cAAc,eAAe;AAC3D;AAKA,MAAM,uBAA6C;AAAA,EACjD,UAAU,CAAC,oBAAC,SAAY,sBAAJ,GAAU,CAAM;AAAA,EACpC,WAAW;AAAA,EACX,IAAI;AAAA,EACJ,cAAc;AAChB;AAEA,MAAM,2BAAiD;AAAA,EACrD,UAAU,CAAC,oBAAC,SAAY,sBAAJ,GAAU,CAAM;AAAA,EACpC,mBAAmB,OAAO,EAAE,cAAc,aAAa;AAAA,EACvD,0BAA0B,OAAO,EAAE,cAAc,qBAAqB;AAAA,EACtE,0BAA0B,OAAO,EAAE,cAAc,eAAe;AAClE;AAEA,MAAM,wBAAwB,MAC5B,iCAEE;AAAA,sBAAC,iBAAe,GAAG,wBAAwB;AAAA,EAC3C,oBAAC,iBAAe,GAAG,+BAA+B;AAAA,EAClD,oBAAC,iBAAe,GAAG,uBAAuB;AAAA,EAC1C,oBAAC,iBAAe,GAAG,uBAAuB;AAAA,EAC1C,oBAAC,iBAAe,GAAG,0BAA0B;AAAA,EAC7C,oBAAC,iBAAe,GAAG,sBAAsB;AAAA,EAIzC,oBAAC,iBAAc,WAAU,gBAAe,IAAG,aAAY,cAAW,eAAc,eAAY,iBACzF,WAAC,oBAAC,SAAY,sBAAJ,GAAU,CAAM,GAC7B;AAAA,EAIA,qBAAC,iBACC;AAAA,wBAAC,SAAI,oBAAM;AAAA,IACX,oBAAC,SAAI,oBAAM;AAAA,KACb;AAAA,EAGA,qBAAC,iBAAc,WAAsB,mBAAmB,EAAE,UAAU,EAAE,GACpE;AAAA,wBAAC,SAAI,oBAAM;AAAA,IACX,oBAAC,SAAI,oBAAM;AAAA,KACb;AAAA,GACF;AAGF,IAAO,wCAAQ;",
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable @typescript-eslint/no-unused-vars, no-unused-vars */\n/* eslint-disable local-rules/custom-rule */\nimport React from 'react';\nimport { DSVirtualList } from '../VirtualList.js';\nimport type { DSVirtualListT } from '../react-desc-prop-types.js';\n\ntype ComponentPropsForApp = DSVirtualListT.Props;\ntype ComponentPropsInternals = DSVirtualListT.InternalProps;\ntype ComponentPropsDefaultProps = DSVirtualListT.DefaultProps;\ntype ComponentPropsOptionalProps = DSVirtualListT.OptionalProps;\ntype ComponentPropsRequiredProps = DSVirtualListT.RequiredProps;\n\n// NOTE: `children` is typed as `React.ReactNode` (accepts a single element or an array), but\n// `DSVirtualListPropTypes.children` is `PropTypes.arrayOf(PropTypes.node).isRequired` \u2014 stricter\n// than the TS type. A single non-array child compiles here but throws at runtime. Every example\n// below passes an array to match the real, enforced contract \u2014 not just what the type permits.\nconst testRequiredProps: ComponentPropsRequiredProps = {\n children: [<div key=\"0\">item 0</div>],\n};\n\nconst testOptionalProps: ComponentPropsOptionalProps = {};\n\nconst testPartialDefaults: Partial<ComponentPropsDefaultProps> = {};\n\nconst testProps: ComponentPropsForApp = {\n ...testRequiredProps,\n ...testOptionalProps,\n ...testPartialDefaults,\n};\n\nconst testPropsAsSyntax = {\n ...testRequiredProps,\n ...testOptionalProps,\n ...testPartialDefaults,\n} as ComponentPropsForApp;\n\nconst testCompleteDefaults: Required<ComponentPropsDefaultProps> = {};\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// Example usages start here\nconst actionRef: React.MutableRefObject<DSVirtualListT.ActionRef> = { current: {} };\n\nconst testExplicitDefinition: ComponentPropsForApp = {\n children: [<div key=\"0\">item 0</div>, <div key=\"1\">item 1</div>],\n actionRef,\n};\n\nconst testInferredTypeCompatibility = {\n children: [<div key=\"0\">item 0</div>, <div key=\"1\">item 1</div>],\n actionRef,\n} as ComponentPropsForApp;\n\nconst testDefinitionAsConst = {\n children: [<div key=\"0\">item 0</div>, <div key=\"1\">item 1</div>],\n} as const;\n\nconst testSlotPropsAsObject: ComponentPropsForApp = {\n children: [<div key=\"0\">item 0</div>],\n dsVirtuallistRoot: { 'aria-label': 'items list' },\n dsVirtuallistListWrapper: { 'aria-label': 'items list wrapper' },\n dsVirtuallistItemWrapper: { 'aria-label': 'item wrapper' },\n};\n\n// Global HTML/ARIA attributes (className, id, aria-*, data-*) work at runtime via\n// useGetGlobalAttributes in List.tsx \u2014 Props/InternalProps extend Omit<GlobalAttributesT<HTMLElement>, ...>\n// specifically so this compiles. Regression here means the type/runtime contract has drifted apart again.\nconst testGlobalAttributes: ComponentPropsForApp = {\n children: [<div key=\"0\">item 0</div>],\n className: 'custom-class',\n id: 'custom-id',\n 'aria-label': 'custom list',\n};\n\nconst testSlotPropsAsFunctions: ComponentPropsForApp = {\n children: [<div key=\"0\">item 0</div>],\n dsVirtuallistRoot: () => ({ 'aria-label': 'items list' }),\n dsVirtuallistListWrapper: () => ({ 'aria-label': 'items list wrapper' }),\n dsVirtuallistItemWrapper: () => ({ 'aria-label': 'item wrapper' }),\n};\n\n// actionRef method usages \u2014 measure() and getVisibleItems() (PUI-17898)\nconst handleMeasure = () => actionRef.current.measure?.();\nconst handleGetVisibleItems: () => number[] = () => actionRef.current.getVisibleItems?.() ?? [];\nconst handleGetMountedItems: () => number[] = () => actionRef.current.getMountedItems?.() ?? [];\n\nconst ExampleUsageComponent = () => (\n <>\n {/* Works with explicitly casted props */}\n <DSVirtualList {...testExplicitDefinition} />\n <DSVirtualList {...testInferredTypeCompatibility} />\n <DSVirtualList {...testDefinitionAsConst} />\n <DSVirtualList {...testSlotPropsAsObject} />\n <DSVirtualList {...testSlotPropsAsFunctions} />\n <DSVirtualList {...testGlobalAttributes} />\n\n {/* Inline props test \u2014 global HTML/ARIA attributes. Array child to match the real, enforced\n runtime contract \u2014 a single child here would compile but throw (see NOTE above). */}\n <DSVirtualList className=\"custom-class\" id=\"custom-id\" aria-label=\"custom list\" data-testid=\"custom-testid\">\n {[<div key=\"0\">item 0</div>]}\n </DSVirtualList>\n\n {/* Inline props test \u2014 required prop only. Two children so JSX itself produces an array;\n a single child here would compile (React.ReactNode) but throw at runtime (see NOTE above). */}\n <DSVirtualList>\n <div>item 0</div>\n <div>item 1</div>\n </DSVirtualList>\n\n {/* Inline props test \u2014 actionRef and slot props */}\n <DSVirtualList actionRef={actionRef} dsVirtuallistRoot={{ tabIndex: 0 }}>\n <div>item 0</div>\n <div>item 1</div>\n </DSVirtualList>\n </>\n);\n\nexport default ExampleUsageComponent;\n"],
5
+ "mappings": "AAAA,YAAY,WAAW;ACiBV,SAgFX,UAhFW,KAiGT,YAjGS;AAdb,SAAS,qBAAqB;AAa9B,MAAM,oBAAiD;AAAA,EACrD,UAAU,CAAC,oBAAC,SAAY,sBAAJ,GAAU,CAAM;AACtC;AAEA,MAAM,oBAAiD,CAAC;AAExD,MAAM,sBAA2D,CAAC;AAElE,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;AAEA,MAAM,uBAA6D,CAAC;AAEpE,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,YAA8D,EAAE,SAAS,CAAC,EAAE;AAElF,MAAM,yBAA+C;AAAA,EACnD,UAAU,CAAC,oBAAC,SAAY,sBAAJ,GAAU,GAAQ,oBAAC,SAAY,sBAAJ,GAAU,CAAM;AAAA,EAC/D;AACF;AAEA,MAAM,gCAAgC;AAAA,EACpC,UAAU,CAAC,oBAAC,SAAY,sBAAJ,GAAU,GAAQ,oBAAC,SAAY,sBAAJ,GAAU,CAAM;AAAA,EAC/D;AACF;AAEA,MAAM,wBAAwB;AAAA,EAC5B,UAAU,CAAC,oBAAC,SAAY,sBAAJ,GAAU,GAAQ,oBAAC,SAAY,sBAAJ,GAAU,CAAM;AACjE;AAEA,MAAM,wBAA8C;AAAA,EAClD,UAAU,CAAC,oBAAC,SAAY,sBAAJ,GAAU,CAAM;AAAA,EACpC,mBAAmB,EAAE,cAAc,aAAa;AAAA,EAChD,0BAA0B,EAAE,cAAc,qBAAqB;AAAA,EAC/D,0BAA0B,EAAE,cAAc,eAAe;AAC3D;AAKA,MAAM,uBAA6C;AAAA,EACjD,UAAU,CAAC,oBAAC,SAAY,sBAAJ,GAAU,CAAM;AAAA,EACpC,WAAW;AAAA,EACX,IAAI;AAAA,EACJ,cAAc;AAChB;AAEA,MAAM,2BAAiD;AAAA,EACrD,UAAU,CAAC,oBAAC,SAAY,sBAAJ,GAAU,CAAM;AAAA,EACpC,mBAAmB,OAAO,EAAE,cAAc,aAAa;AAAA,EACvD,0BAA0B,OAAO,EAAE,cAAc,qBAAqB;AAAA,EACtE,0BAA0B,OAAO,EAAE,cAAc,eAAe;AAClE;AAGA,MAAM,gBAAgB,MAAM,UAAU,QAAQ,UAAU;AACxD,MAAM,wBAAwC,MAAM,UAAU,QAAQ,kBAAkB,KAAK,CAAC;AAC9F,MAAM,wBAAwC,MAAM,UAAU,QAAQ,kBAAkB,KAAK,CAAC;AAE9F,MAAM,wBAAwB,MAC5B,iCAEE;AAAA,sBAAC,iBAAe,GAAG,wBAAwB;AAAA,EAC3C,oBAAC,iBAAe,GAAG,+BAA+B;AAAA,EAClD,oBAAC,iBAAe,GAAG,uBAAuB;AAAA,EAC1C,oBAAC,iBAAe,GAAG,uBAAuB;AAAA,EAC1C,oBAAC,iBAAe,GAAG,0BAA0B;AAAA,EAC7C,oBAAC,iBAAe,GAAG,sBAAsB;AAAA,EAIzC,oBAAC,iBAAc,WAAU,gBAAe,IAAG,aAAY,cAAW,eAAc,eAAY,iBACzF,WAAC,oBAAC,SAAY,sBAAJ,GAAU,CAAM,GAC7B;AAAA,EAIA,qBAAC,iBACC;AAAA,wBAAC,SAAI,oBAAM;AAAA,IACX,oBAAC,SAAI,oBAAM;AAAA,KACb;AAAA,EAGA,qBAAC,iBAAc,WAAsB,mBAAmB,EAAE,UAAU,EAAE,GACpE;AAAA,wBAAC,SAAI,oBAAM;AAAA,IACX,oBAAC,SAAI,oBAAM;AAAA,KACb;AAAA,GACF;AAGF,IAAO,wCAAQ;",
6
6
  "names": []
7
7
  }
@@ -9,6 +9,9 @@ export declare namespace DSVirtualListT {
9
9
  };
10
10
  type ActionRef = {
11
11
  scrollTo?: (index: number, options?: ScrollToOptions | undefined) => void;
12
+ measure?: () => void;
13
+ getVisibleItems?: () => number[];
14
+ getMountedItems?: () => number[];
12
15
  };
13
16
  type SlotFunctionArguments = {
14
17
  dsVirtuallistRoot: () => object;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elliemae/ds-virtual-list",
3
- "version": "3.80.0-next.12",
3
+ "version": "3.80.0-next.13",
4
4
  "license": "MIT",
5
5
  "description": "ICE MT - Dimsum - Virtual List",
6
6
  "files": [
@@ -38,16 +38,16 @@
38
38
  "dependencies": {
39
39
  "@tanstack/react-virtual": "3.13.18",
40
40
  "uid": "^2.0.2",
41
- "@elliemae/ds-props-helpers": "3.80.0-next.12",
42
- "@elliemae/ds-typescript-helpers": "3.80.0-next.12",
43
- "@elliemae/ds-system": "3.80.0-next.12"
41
+ "@elliemae/ds-typescript-helpers": "3.80.0-next.13",
42
+ "@elliemae/ds-props-helpers": "3.80.0-next.13",
43
+ "@elliemae/ds-system": "3.80.0-next.13"
44
44
  },
45
45
  "devDependencies": {
46
46
  "@playwright/experimental-ct-react": "1.61.1",
47
47
  "jest": "^30.0.0",
48
48
  "styled-components": "~5.3.11",
49
- "@elliemae/ds-monorepo-devops": "3.80.0-next.12",
50
- "@elliemae/ds-test-utils": "3.80.0-next.12"
49
+ "@elliemae/ds-monorepo-devops": "3.80.0-next.13",
50
+ "@elliemae/ds-test-utils": "3.80.0-next.13"
51
51
  },
52
52
  "peerDependencies": {
53
53
  "lodash-es": "^4.18.1",