diff --git a/.changeset/fix-layout-panel-touch-resize.md b/.changeset/fix-layout-panel-touch-resize.md
new file mode 100644
index 000000000..b1e784837
--- /dev/null
+++ b/.changeset/fix-layout-panel-touch-resize.md
@@ -0,0 +1,5 @@
+---
+'@cube-dev/ui-kit': patch
+---
+
+Fix Layout.Panel resize handler not working properly on touch devices by adding `touch-action: none` to prevent browser scroll interference during drag
diff --git a/src/components/content/Layout/LayoutPanel.tsx b/src/components/content/Layout/LayoutPanel.tsx
index 8f21a3ec7..ecb14a335 100644
--- a/src/components/content/Layout/LayoutPanel.tsx
+++ b/src/components/content/Layout/LayoutPanel.tsx
@@ -176,6 +176,10 @@ const ResizeHandlerElement = tasty({
horizontal: 'col-resize',
disabled: 'not-allowed',
},
+ touchAction: {
+ '': 'none',
+ disabled: 'auto',
+ },
padding: 0,
outline: 0,
boxSizing: 'border-box',
diff --git a/src/components/fields/ComboBox/ComboBox.docs.mdx b/src/components/fields/ComboBox/ComboBox.docs.mdx
index 41b024e88..88c77b132 100644
--- a/src/components/fields/ComboBox/ComboBox.docs.mdx
+++ b/src/components/fields/ComboBox/ComboBox.docs.mdx
@@ -296,6 +296,33 @@ const [selectedKey, setSelectedKey] = useState(null);
```
+### With Sections (Dynamic)
+
+
+
+Sections and items can be defined dynamically using the `items` prop with a render function. Pass hierarchical data where each section contains a `children` array.
+
+```jsx
+const categories = [
+ { name: 'Fruits', children: [
+ { key: 'apple', label: 'Apple' },
+ { key: 'banana', label: 'Banana' },
+ ]},
+ { name: 'Vegetables', children: [
+ { key: 'carrot', label: 'Carrot' },
+ { key: 'broccoli', label: 'Broccoli' },
+ ]},
+];
+
+
+ {(category) => (
+
+ {(item) => {item.label}}
+
+ )}
+
+```
+
### With Disabled Items
@@ -442,6 +469,8 @@ const fruits = [
+For large datasets, use the `items` prop with a render function. This enables automatic virtualization — only visible items are rendered in the DOM, providing smooth scrolling even with thousands of items. Virtualization is disabled when sections are present.
+
```jsx
const items = Array.from({ length: 1000 }, (_, i) => ({
key: `item-${i}`,
diff --git a/src/components/fields/ComboBox/ComboBox.stories.tsx b/src/components/fields/ComboBox/ComboBox.stories.tsx
index ecc851758..e22681af8 100644
--- a/src/components/fields/ComboBox/ComboBox.stories.tsx
+++ b/src/components/fields/ComboBox/ComboBox.stories.tsx
@@ -516,6 +516,43 @@ export const WithSections = () => (
);
+export const DynamicSections = () => {
+ const categories = [
+ {
+ name: 'Fruits',
+ children: [
+ { key: 'apple', label: 'Apple' },
+ { key: 'banana', label: 'Banana' },
+ { key: 'cherry', label: 'Cherry' },
+ ],
+ },
+ {
+ name: 'Vegetables',
+ children: [
+ { key: 'carrot', label: 'Carrot' },
+ { key: 'broccoli', label: 'Broccoli' },
+ { key: 'spinach', label: 'Spinach' },
+ ],
+ },
+ ];
+
+ return (
+
+ {(category: any) => (
+
+ {(item: any) => (
+ {item.label}
+ )}
+
+ )}
+
+ );
+};
+
export const WithDisabledItems = () => (
```
+### With Sections (Dynamic)
+
+
+
+Sections and items can be defined dynamically using the `items` prop with a render function. Pass hierarchical data where each section contains a `children` array.
+
+```jsx
+const categories = [
+ { name: 'Fruits', children: [
+ { key: 'apple', label: 'Apple' },
+ { key: 'banana', label: 'Banana' },
+ ]},
+ { name: 'Vegetables', children: [
+ { key: 'carrot', label: 'Carrot' },
+ { key: 'broccoli', label: 'Broccoli' },
+ ]},
+];
+
+
+ {(category) => (
+
+ {(item) => {item.label}}
+
+ )}
+
+```
+
### With Descriptions
diff --git a/src/components/fields/FilterListBox/FilterListBox.stories.tsx b/src/components/fields/FilterListBox/FilterListBox.stories.tsx
index 134864cf6..b90b37cc5 100644
--- a/src/components/fields/FilterListBox/FilterListBox.stories.tsx
+++ b/src/components/fields/FilterListBox/FilterListBox.stories.tsx
@@ -533,6 +533,55 @@ WithSections.args = {
searchPlaceholder: 'Search ingredients...',
};
+export const DynamicSections: StoryFn> = (args) => {
+ const categories = [
+ {
+ name: 'Fruits',
+ children: [
+ { key: 'apple', label: 'Apple' },
+ { key: 'banana', label: 'Banana' },
+ { key: 'cherry', label: 'Cherry' },
+ ],
+ },
+ {
+ name: 'Vegetables',
+ children: [
+ { key: 'carrot', label: 'Carrot' },
+ { key: 'broccoli', label: 'Broccoli' },
+ { key: 'spinach', label: 'Spinach' },
+ ],
+ },
+ {
+ name: 'Herbs',
+ children: [
+ { key: 'basil', label: 'Basil' },
+ { key: 'cilantro', label: 'Cilantro' },
+ { key: 'parsley', label: 'Parsley' },
+ ],
+ },
+ ];
+
+ return (
+
+ {(category: any) => (
+
+ {(item: any) => (
+ {item.label}
+ )}
+
+ )}
+
+ );
+};
+DynamicSections.args = {
+ label: 'Choose an ingredient',
+ searchPlaceholder: 'Search ingredients...',
+};
+
export const WithSectionsAndDescriptions: StoryFn<
CubeFilterListBoxProps
> = (args) => (
diff --git a/src/components/fields/FilterPicker/FilterPicker.docs.mdx b/src/components/fields/FilterPicker/FilterPicker.docs.mdx
index 9b9dcea8f..95d854280 100644
--- a/src/components/fields/FilterPicker/FilterPicker.docs.mdx
+++ b/src/components/fields/FilterPicker/FilterPicker.docs.mdx
@@ -242,6 +242,40 @@ For large datasets or dynamic content, use the `items` prop with a render functi
```
+### Dynamic Sections Pattern
+
+For hierarchical data with sections, use the `items` prop with nested render functions. Each section contains a `children` array of items.
+
+```jsx
+const categories = [
+ { name: 'Fruits', children: [
+ { key: 'apple', label: 'Apple' },
+ { key: 'banana', label: 'Banana' },
+ ]},
+ { name: 'Vegetables', children: [
+ { key: 'carrot', label: 'Carrot' },
+ { key: 'broccoli', label: 'Broccoli' },
+ ]},
+];
+
+
+ {(category) => (
+
+ {(item) => (
+
+ {item.label}
+
+ )}
+
+ )}
+
+```
+
**Key Benefits:**
- **Virtualization**: Automatically enabled for large lists without sections
- **Performance**: Only renders visible items in the DOM
diff --git a/src/components/fields/FilterPicker/FilterPicker.stories.tsx b/src/components/fields/FilterPicker/FilterPicker.stories.tsx
index 5cd2a6c26..c08a68f87 100644
--- a/src/components/fields/FilterPicker/FilterPicker.stories.tsx
+++ b/src/components/fields/FilterPicker/FilterPicker.stories.tsx
@@ -686,6 +686,75 @@ export const WithSections: Story = {
},
};
+export const DynamicSections: Story = {
+ args: {
+ label: 'Organized by Sections',
+ placeholder: 'Choose items...',
+ selectionMode: 'multiple',
+ searchPlaceholder: 'Search ingredients...',
+ width: 'max 30x',
+ },
+ play: async ({ canvasElement }) => {
+ const canvas = within(canvasElement);
+ const trigger = canvas.getByRole('button');
+ await userEvent.click(trigger);
+ },
+ render: (args) => {
+ const categories = [
+ {
+ name: 'Fruits',
+ children: [
+ { key: 'apple', label: 'Apple' },
+ { key: 'banana', label: 'Banana' },
+ { key: 'cherry', label: 'Cherry' },
+ ],
+ },
+ {
+ name: 'Vegetables',
+ children: [
+ { key: 'carrot', label: 'Carrot' },
+ { key: 'broccoli', label: 'Broccoli' },
+ { key: 'spinach', label: 'Spinach' },
+ ],
+ },
+ {
+ name: 'Grains',
+ children: [
+ { key: 'rice', label: 'Rice' },
+ { key: 'oats', label: 'Oats' },
+ { key: 'barley', label: 'Barley' },
+ ],
+ },
+ ];
+
+ return (
+
+ {(category: any) => (
+
+ {(item: any) => (
+
+ {item.label}
+
+ )}
+
+ )}
+
+ );
+ },
+ parameters: {
+ docs: {
+ description: {
+ story:
+ 'Sections and items can be defined dynamically using the `items` prop with a render function. Pass hierarchical data where each section contains a `children` array.',
+ },
+ },
+ },
+};
+
export const CustomSummary: Story = {
args: {
label: 'Custom Summary Display',
diff --git a/src/components/fields/ListBox/ListBox.docs.mdx b/src/components/fields/ListBox/ListBox.docs.mdx
index 952608b73..43dabe810 100644
--- a/src/components/fields/ListBox/ListBox.docs.mdx
+++ b/src/components/fields/ListBox/ListBox.docs.mdx
@@ -327,6 +327,33 @@ Groups related items together with an optional heading.
```
+### With Sections (Dynamic)
+
+
+
+Sections and items can be defined dynamically using the `items` prop with a render function. Pass hierarchical data where each section contains a `children` array.
+
+```jsx
+const categories = [
+ { name: 'Fruits', children: [
+ { key: 'apple', label: 'Apple' },
+ { key: 'banana', label: 'Banana' },
+ ]},
+ { name: 'Vegetables', children: [
+ { key: 'carrot', label: 'Carrot' },
+ { key: 'broccoli', label: 'Broccoli' },
+ ]},
+];
+
+
+ {(category) => (
+
+ {(item) => {item.label}}
+
+ )}
+
+```
+
### Multiple Selection
@@ -736,15 +763,22 @@ This component supports all [Field properties](/docs/getting-started-field-prope
### Virtualization
-ListBox automatically enables virtualization when:
-- No sections are present (sections disable virtualization)
-- Provides smooth scrolling even with large datasets
-- Only visible items are rendered in the DOM
-- Uses `@tanstack/react-virtual` for efficient rendering
-- Automatically measures item heights for consistent scrolling
-- Supports items with varying heights (descriptions, complex content)
+
+
+For large datasets, use the `items` prop with a render function. This enables automatic virtualization — only visible items are rendered in the DOM, providing smooth scrolling even with thousands of items.
+
+```jsx
+const items = Array.from({ length: 1000 }, (_, i) => ({
+ key: `item-${i}`,
+ label: `Item ${i + 1}`,
+}));
+
+
+ {(item) => {item.label}}
+
+```
-**Note**: Virtualization is transparent to the user - no configuration needed. It works automatically when you have a flat list without sections.
+**Note**: Virtualization is disabled when sections are present. For very large datasets, prefer a flat list structure.
### Optimization Tips
diff --git a/src/components/fields/ListBox/ListBox.stories.tsx b/src/components/fields/ListBox/ListBox.stories.tsx
index 67b6c63be..d65ca197f 100644
--- a/src/components/fields/ListBox/ListBox.stories.tsx
+++ b/src/components/fields/ListBox/ListBox.stories.tsx
@@ -408,6 +408,57 @@ WithSections.args = {
selectionMode: 'single',
};
+export const DynamicSections: StoryObj>['render'] = (
+ args,
+) => {
+ const categories = [
+ {
+ name: 'Fruits',
+ children: [
+ { key: 'apple', label: 'Apple' },
+ { key: 'banana', label: 'Banana' },
+ { key: 'cherry', label: 'Cherry' },
+ ],
+ },
+ {
+ name: 'Vegetables',
+ children: [
+ { key: 'carrot', label: 'Carrot' },
+ { key: 'broccoli', label: 'Broccoli' },
+ { key: 'spinach', label: 'Spinach' },
+ ],
+ },
+ {
+ name: 'Grains',
+ children: [
+ { key: 'rice', label: 'Rice' },
+ { key: 'oats', label: 'Oats' },
+ { key: 'barley', label: 'Barley' },
+ ],
+ },
+ ];
+
+ return (
+
+ {(category: any) => (
+
+ {(item: any) => (
+ {item.label}
+ )}
+
+ )}
+
+ );
+};
+DynamicSections.args = {
+ label: 'Select food items',
+ selectionMode: 'single',
+};
+
export const WithHeaderAndFooter: StoryObj>['render'] = (
args,
) => (
diff --git a/src/components/fields/Picker/Picker.docs.mdx b/src/components/fields/Picker/Picker.docs.mdx
index e6fdb3c49..ea4792dbd 100644
--- a/src/components/fields/Picker/Picker.docs.mdx
+++ b/src/components/fields/Picker/Picker.docs.mdx
@@ -445,6 +445,33 @@ Organize items into logical groups with section headers.
```
+### With Sections (Dynamic)
+
+
+
+Sections and items can be defined dynamically using the `items` prop with a render function. Pass hierarchical data where each section contains a `children` array.
+
+```jsx
+const categories = [
+ { name: 'Fruits', children: [
+ { key: 'apple', label: 'Apple' },
+ { key: 'banana', label: 'Banana' },
+ ]},
+ { name: 'Vegetables', children: [
+ { key: 'carrot', label: 'Carrot' },
+ { key: 'broccoli', label: 'Broccoli' },
+ ]},
+];
+
+
+ {(category) => (
+
+ {(item) => {item.label}}
+
+ )}
+
+```
+
### Different Sizes
diff --git a/src/components/fields/Picker/Picker.stories.tsx b/src/components/fields/Picker/Picker.stories.tsx
index 424de7176..2071a1e88 100644
--- a/src/components/fields/Picker/Picker.stories.tsx
+++ b/src/components/fields/Picker/Picker.stories.tsx
@@ -144,6 +144,50 @@ export const WithSections: Story = {
},
};
+export const DynamicSections: Story = {
+ args: {
+ placeholder: 'Select a food',
+ label: 'Favorite Food',
+ selectionMode: 'single',
+ },
+ render: (args) => {
+ const categories = [
+ {
+ name: 'Fruits',
+ children: [
+ { key: 'apple', label: 'Apple' },
+ { key: 'banana', label: 'Banana' },
+ { key: 'orange', label: 'Orange' },
+ ],
+ },
+ {
+ name: 'Vegetables',
+ children: [
+ { key: 'carrot', label: 'Carrot' },
+ { key: 'broccoli', label: 'Broccoli' },
+ { key: 'spinach', label: 'Spinach' },
+ ],
+ },
+ ];
+
+ return (
+
+ {(category: any) => (
+
+ {(item: any) => (
+ {item.label}
+ )}
+
+ )}
+
+ );
+ },
+};
+
export const WithItemsArray: Story = {
args: {
placeholder: 'Select a fruit',
diff --git a/src/components/fields/Select/Select.docs.mdx b/src/components/fields/Select/Select.docs.mdx
index 64cabf4bd..c0258c311 100644
--- a/src/components/fields/Select/Select.docs.mdx
+++ b/src/components/fields/Select/Select.docs.mdx
@@ -417,6 +417,8 @@ Groups related options together with an optional heading.
+Sections and items can be defined dynamically using the `items` prop with a render function.
+
```jsx
const groups = [
{