Selection
Turns a set of anything — cards, rows, list items — into a selectable collection: a checkbox on each one, shift-click for a range, and a bulk-action bar that arrives once something is ticked. The selection is controlled and ordered by items, so what comes back follows the list rather than the order of clicks, and ids no longer present in items are kept rather than dropped — a selection can outlive a page change, and clearing it is the caller's decision.
Usage
Examples
With select all
SelectionAll is the header checkbox — indeterminate while the selection is partial, and
a press while everything is selected clears it rather than reselecting.
Grid
The same machinery over a three-column grid: Selection lays nothing out, so the
arrangement stays entirely yours.
With disabled
A disabled item leaves both select-all and any shift range, so "all" means all the ones
this user is allowed to touch — and the header checkbox counts only those.
Range selection
Shift-click selects everything between the last checkbox you touched and this one,
following the order of items rather than the order you clicked in.
Bulk actions
Three actions in one bar. Only the destructive one is solid, so a bar with several verbs still has a single obvious primary.
Empty and partial
Emptying the list strands the ids that were selected, because the component keeps them on purpose — the effect here is the cleanup pattern, dropping any id the list no longer has.
Without bulk bar
No bar at all: the selection still works and the count is rendered from state, for a page that acts on the selection somewhere else entirely.
Compound bulk bar
Composing the summary — count, select-all, clear — instead of taking the default. It has to be a direct child of the bar; a wrapper component hides it and the default appears too.
Inside drawer
Inside a Drawer, placement='absolute' pins the bar to the bottom of the panel instead
of the viewport, and the actions step up to large to match the surface.