Description
Currently DepthSelect only accepts items via the data prop:
<DepthSelect data={[
{ value: 'v1', view: <Card>...</Card> },
{ value: 'v2', view: <Card>...</Card> },
]} />
Add support for a declarative children API using a DepthSelect.Item compound component:
<DepthSelect>
<DepthSelect.Item value="v1"><Card>...</Card></DepthSelect.Item>
<DepthSelect.Item value="v2"><Card>...</Card></DepthSelect.Item>
</DepthSelect>
Both APIs coexist. The data prop takes precedence over children — if data is provided and non-empty, DepthSelect.Item children are ignored. This matches Mantine's pattern (e.g., Select with data prop vs Select.Option children).
Implementation Plan
New file: DepthSelectItem.tsx
A "marker" component that doesn't render anything directly — the parent reads its props to build the items array:
export interface DepthSelectItemProps {
value: string | number;
children: React.ReactNode;
}
export function DepthSelectItem(_props: DepthSelectItemProps): null {
return null;
}
DepthSelectItem.displayName = 'DepthSelectItem';
Modify DepthSelect.tsx
Add a utility to collect items from children:
function collectItemsFromChildren(children: React.ReactNode): DepthSelectItem[] {
const items: DepthSelectItem[] = [];
React.Children.forEach(children, (child) => {
if (React.isValidElement(child) && child.type === DepthSelectItem) {
items.push({ value: child.props.value, view: child.props.children });
}
// DepthSelect.Controls and other children are ignored here
});
return items;
}
Then in the component body:
const dataItems = useMemo(() => data ?? [], [data]);
const childItems = useMemo(() => collectItemsFromChildren(children), [children]);
const items = dataItems.length > 0 ? dataItems : childItems;
Update Factory type
staticComponents: {
Item: typeof DepthSelectItem; // NEW
Controls: typeof DepthSelectControls;
};
Attach static component
DepthSelect.Item = DepthSelectItem;
Update exports (index.ts)
export type { DepthSelectItemProps } from './DepthSelectItem';
Precedence rules
data prop |
DepthSelect.Item children |
Result |
| Provided (non-empty) |
Any |
Uses data, children ignored |
undefined or [] |
Present |
Uses children items |
undefined or [] |
None |
Empty state |
This matches Mantine's Select behavior where data prop overrides Select.Option children.
Naming convention
DepthSelect.Item follows the Mantine compound component naming: Tabs.Tab, Select.Option, Accordion.Item, Combobox.Option.
Scope
- New file:
package/src/DepthSelectItem.tsx
- Modified:
package/src/DepthSelect.tsx (Factory type, collectItemsFromChildren, static attachment)
- Modified:
package/src/index.ts (export DepthSelectItemProps)
- New tests for children API
- New Storybook story + docs demo
- Backward compatible — no breaking changes
Description
Currently
DepthSelectonly accepts items via thedataprop:Add support for a declarative children API using a
DepthSelect.Itemcompound component:Both APIs coexist. The
dataprop takes precedence over children — ifdatais provided and non-empty,DepthSelect.Itemchildren are ignored. This matches Mantine's pattern (e.g.,Selectwithdataprop vsSelect.Optionchildren).Implementation Plan
New file:
DepthSelectItem.tsxA "marker" component that doesn't render anything directly — the parent reads its props to build the items array:
Modify
DepthSelect.tsxAdd a utility to collect items from children:
Then in the component body:
Update Factory type
Attach static component
Update exports (
index.ts)Precedence rules
datapropDepthSelect.Itemchildrendata, children ignoredundefinedor[]undefinedor[]This matches Mantine's
Selectbehavior wheredataprop overridesSelect.Optionchildren.Naming convention
DepthSelect.Itemfollows the Mantine compound component naming:Tabs.Tab,Select.Option,Accordion.Item,Combobox.Option.Scope
package/src/DepthSelectItem.tsxpackage/src/DepthSelect.tsx(Factory type, collectItemsFromChildren, static attachment)package/src/index.ts(export DepthSelectItemProps)