Overflow list
An OverflowList renders as many items as fit in its container and passes the rest to an overflow renderer. It recomputes when its size changes.
Usage#
import { OverflowList } from "@clawscale/react";<OverflowList
items={stages}
visibleItemRenderer={(stage) => <Button key={stage} style={{ flexShrink: 0 }} text={stage} />}
overflowRenderer={(hidden) => <Tag minimal>{hidden.length} more</Tag>}
/>visibleItemRenderer runs once per visible item. Set a key on the element it returns. overflowRenderer runs once with all hidden items.
Items must keep their width. Buttons and tags shrink by default, which hides the overflow from the list. Give them flexShrink: 0.
Examples#
Collapse into a menu#
Hidden items go into a menu behind a button. collapseFrom={Boundary.END} hides items from the end. Drag the lower right corner of the box to resize it.
import { Boundary, Button, Menu, MenuItem, OverflowList, PopoverNext } from "@clawscale/react";
const STAGES = ["Extract", "Validate", "Deduplicate", "Enrich", "Join", "Aggregate", "Publish"];
export default function OverflowListBasic() {
return (
<div
style={{
border: "1px dashed var(--cs-color-border-strong)",
maxWidth: "100%",
minWidth: 96,
overflow: "hidden",
padding: 4,
resize: "horizontal",
width: 400,
}}
>
<OverflowList
items={STAGES}
collapseFrom={Boundary.END}
visibleItemRenderer={(stage) => <Button key={stage} style={{ flexShrink: 0 }} variant="minimal" text={stage} />}
overflowRenderer={(hidden) => (
<PopoverNext
placement="bottom-end"
content={
<Menu>
{hidden.map((stage) => (
<MenuItem key={stage} text={stage} />
))}
</Menu>
}
>
<Button variant="minimal" icon="more" aria-label={`${hidden.length} more stages`} />
</PopoverNext>
)}
/>
</div>
);
}Collapse from the start#
Items collapse from the start by default, and the overflow renders before the visible items. Here the newest runs stay visible. minVisibleItems sets how many items never collapse.
import { type Intent, OverflowList, Tag } from "@clawscale/react";
const RUNS: { id: number; intent: Intent }[] = [
{ id: 1275, intent: "success" },
{ id: 1276, intent: "success" },
{ id: 1277, intent: "danger" },
{ id: 1278, intent: "success" },
{ id: 1279, intent: "success" },
{ id: 1280, intent: "warning" },
{ id: 1281, intent: "success" },
{ id: 1282, intent: "success" },
{ id: 1283, intent: "danger" },
{ id: 1284, intent: "success" },
];
export default function OverflowListCollapseFrom() {
return (
<OverflowList
items={RUNS}
style={{ gap: 4, width: 280 }}
overflowRenderer={(older) => (
<Tag minimal style={{ flexShrink: 0 }}>
{older.length} older
</Tag>
)}
visibleItemRenderer={(run) => (
<Tag key={run.id} minimal intent={run.intent} style={{ flexShrink: 0 }}>
#{run.id}
</Tag>
)}
/>
);
}Props interface#
OverflowList measures itself with ResizeObserver. Set observeParents when a parent can resize without resizing the list.
interface OverflowListProps extends Props@clawscale/react| Props | Description |
|---|---|
alwaysRenderOverflow | boolean = falseWhether to force the overflowRenderer to always be called, even if there are zero items overflowing. This may be useful, for example, if your overflow renderer contains a Popover which you do not want to close as the list is resized. |
className | stringA space-delimited list of class names to pass along to a child element. Inherited from Props |
collapseFrom | Boundary = Boundary.STARTWhich direction the items should collapse from: start or end of the children. This also determines whether overflowRenderer appears before (START) or after (END) the visible items. |
itemsrequired | readonly T[]All items to display in the list. Items that do not fit in the container will be rendered in the overflow instead. |
minVisibleItems | number = 0The minimum number of visible items that should never collapse into the overflow menu, regardless of DOM dimensions. |
navigable | boolean = falseIf true, the overflow list will be wrapped with a nav element. |
navigationAriaLabel | string = ""ARIA label to apply to the nav element. Only used if navigable is true. |
observeParents | boolean = falseIf true, all parent DOM elements of the container will also be observed. If changes to a parent's size is detected, the overflow will be recalculated. |
onOverflow | (overflowItems: T[]) => voidCallback invoked when the overflowed items change. This is called once after the DOM has settled, rather that on every intermediate change. It is not invoked if resizing produces an unchanged overflow state. |
overflowRendererrequired | (overflowItems: T[]) => React.ReactNodeCallback invoked to render the overflowed items. Unlike visibleItemRenderer, this prop is invoked once with all items that do not fit in the container. |
style | React.CSSPropertiesCSS properties to apply to the root element. |
tagName | keyof React.JSX.IntrinsicElements = "div"HTML tag name for the container element. |
visibleItemRendererrequired | (item: T, index: number) => React.ReactNodeCallback invoked to render each visible item. Remember to set a key on the rendered element! |