From 17b8fe7ecc592a4965235657e7cb721cb05cf19f Mon Sep 17 00:00:00 2001 From: "ilia.brauer" Date: Thu, 21 May 2026 09:21:25 +0200 Subject: [PATCH] [select] added VirtualList as exported component --- semcore/select/src/Select.jsx | 1 + semcore/select/src/index.d.ts | 1 + .../select/tests/Select.stories.tsx | 5 + .../select/tests/examples/virtualization.tsx | 93 +++++++++++++++++++ 4 files changed, 100 insertions(+) create mode 100644 stories/components/select/tests/examples/virtualization.tsx diff --git a/semcore/select/src/Select.jsx b/semcore/select/src/Select.jsx index 33bb985a02..4d2b47c3ba 100644 --- a/semcore/select/src/Select.jsx +++ b/semcore/select/src/Select.jsx @@ -501,6 +501,7 @@ const Select = createComponent( }, ], Group: Dropdown.Group, + VirtualList: DropdownMenu.VirtualList, Divider, InputSearch: [InputSearchWrapper, InputSearch._______childrenComponents], Input: [InputSearchWrapper, InputSearch._______childrenComponents], diff --git a/semcore/select/src/index.d.ts b/semcore/select/src/index.d.ts index ab57acb032..1ce4c960af 100644 --- a/semcore/select/src/index.d.ts +++ b/semcore/select/src/index.d.ts @@ -143,6 +143,7 @@ declare const Select: IntergalacticSelectComponent & { Popper: typeof DropdownMenu.Popper; List: typeof DropdownMenu.List; Menu: typeof DropdownMenu.Menu; + VirtualList: typeof DropdownMenu.VirtualList; Group: typeof Dropdown.Group; Option: Intergalactic.Component< 'option', diff --git a/stories/components/select/tests/Select.stories.tsx b/stories/components/select/tests/Select.stories.tsx index 73b9dbfe04..848ac64ede 100644 --- a/stories/components/select/tests/Select.stories.tsx +++ b/stories/components/select/tests/Select.stories.tsx @@ -10,6 +10,7 @@ import ProgrammaticallyFocusExample from './examples/programmatically_focus'; import type { defaultProps as SelectWithEllipsisProps } from './examples/select-with-ellipsis'; import SelectWithEllipsisExample from './examples/select-with-ellipsis'; import SubcomponentsExample, { defaultProps as SubcomponentsProps } from './examples/subcomponents_trigger_popper_list_search'; +import VirtualizationExample from './examples/virtualization'; const meta: Meta = { title: 'Components/Select/Test', @@ -217,3 +218,7 @@ export const SubcomponentsTriggerPopperListSearch: StoryObj `project ${index}`); +const rowHeight = 32; + +type ProjectSelectorProps = DropdownMenuProps & DropdownMenuListProps & DropdownMenuItemProps & { + disabledAll?: boolean; + disabledFirstItem?: boolean; + visibleItems?: number; +}; + +const Row = React.memo(({ index, data, row }: RenderRowProps void; disabledAll?: boolean; disabledFirstItem?: boolean }>) => { + const projectName = row; + + return ( + + {projectName} + + ); +}); + +const Demo = (props: ProjectSelectorProps) => { + const [searchValue, setSearchValue] = React.useState(''); + const [visible, setVisible] = React.useState(false); + const [selectedProject, setProject] = React.useState('project 33'); + + const visibleItems = props.visibleItems ?? 10; + const listHeight = visibleItems * rowHeight; + + const normalizedQuery = searchValue.trim().toLowerCase(); + + const filteredProjects = React.useMemo(() => { + if (!normalizedQuery) return projects; + return projects.filter((p) => p.toLowerCase().includes(normalizedQuery)); + }, [normalizedQuery]); + + const handleSetProject = (project: string) => { + setProject(project); + }; + + return ( + + ); +}; + +export const defaultProps: ProjectSelectorProps = { + disabledAll: false, + disabledFirstItem: false, + stretch: undefined, + visibleItems: 4, +}; + +Demo.defaultProps = defaultProps; + +export default Demo;