Skip to content

Commit d0b1cfd

Browse files
committed
feat: allow custom key for virtualised list items
1 parent a1b8e44 commit d0b1cfd

File tree

1 file changed

+25
-10
lines changed
  • packages/components/base/src/virtualized-list

1 file changed

+25
-10
lines changed

packages/components/base/src/virtualized-list/index.tsx

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import React, { useMemo, useRef } from "react";
22
import { VirtualizedListItem, type VirtualizedListItemProps } from "./VirtualizedListItem";
33
import { useManagerContext } from "@react-ck/manager";
4+
import { megeRefs } from "@react-ck/react-utils";
45

56
const DefaultWrapper: React.FC<React.PropsWithChildren> = ({ children }) => children;
67

@@ -16,13 +17,17 @@ function generateStableKey(item: React.ReactNode, generateUniqueId: () => string
1617
return key;
1718
}
1819

20+
export interface VirtualizedListITem {
21+
element: React.ReactNode;
22+
key?: string;
23+
}
24+
1925
/**
2026
* Props for the VirtualizedList component
2127
*/
22-
export interface VirtualizedListProps
23-
extends Omit<React.ComponentPropsWithoutRef<"div">, "children"> {
28+
export interface VirtualizedListProps extends Omit<React.ComponentPropsWithRef<"div">, "children"> {
2429
/** Array of React nodes to render as list items */
25-
items: React.ReactNode[];
30+
items: React.ReactNode[] | VirtualizedListITem[];
2631
/** Default height for list items in pixels */
2732
defaultItemHeight?: number;
2833
/** Additional props to pass to each VirtualizedListItem */
@@ -36,6 +41,7 @@ export interface VirtualizedListProps
3641
* by only rendering visible items and using stable keys for performance
3742
*/
3843
export const VirtualizedList: React.FC<Readonly<VirtualizedListProps>> = ({
44+
ref,
3945
items,
4046
defaultItemHeight = 40,
4147
itemProps,
@@ -48,23 +54,32 @@ export const VirtualizedList: React.FC<Readonly<VirtualizedListProps>> = ({
4854

4955
const itemsWithKey = useMemo(
5056
() =>
51-
items.map((item) => ({
52-
item,
53-
key: generateStableKey(item, generateUniqueId),
54-
})),
57+
items.map((item) => {
58+
if (typeof item === "object" && item !== null && "element" in item) {
59+
return {
60+
element: item.element,
61+
key: item.key ?? generateStableKey(item.element, generateUniqueId),
62+
};
63+
}
64+
65+
return {
66+
element: item,
67+
key: generateStableKey(item, generateUniqueId),
68+
};
69+
}),
5570
[items, generateUniqueId],
5671
);
5772

5873
return (
59-
<div ref={observerRootRef} {...props}>
74+
<div ref={megeRefs(observerRootRef, ref)} {...props}>
6075
<Wrapper>
61-
{itemsWithKey.map(({ item, key }) => (
76+
{itemsWithKey.map(({ element, key }) => (
6277
<VirtualizedListItem
6378
key={key}
6479
defaultHeight={defaultItemHeight}
6580
observerRootRef={observerRootRef}
6681
{...itemProps}>
67-
{item}
82+
{element}
6883
</VirtualizedListItem>
6984
))}
7085
</Wrapper>

0 commit comments

Comments
 (0)