Filter a set of options by head count and layout and see which fit and why — meeting rooms by seating style, tables by party size, vehicles by seat configuration, sessions by format. A layout switch and a count slider with a synced number field drive a live summary and a list where every option shows its capacity against the number.
3 of 4 take 40 people theatre-style.
Atrium
Ground floor · 240 m²Fits · up to 180North Room
Floor 2 · 110 m²Fits · up to 90The Loft
Floor 3 · 70 m²Fits · up to 50Studio 4
Floor 3 · 32 m²Too small · up to 20
Installation
The whole kit as one package — get updates by bumping the version. Add the styles to globals.css: @import "@vamos-ui/react/styles.css";
Usage
import { CapacityFinder } from "@vamos-ui/react";
<CapacityFinder
arrangements={[{ id: "theatre", label: "Theatre", phrase: "theatre-style" }, { id: "boardroom", label: "Boardroom", phrase: "around one table" }]}
options={[{ id: "north", name: "North Room", meta: "Floor 2", capacities: { theatre: 90, boardroom: 28 } }]}
renderAction={({ option }) => <Button size="sm">Request {option.name}</Button>}
/>The summary is a polite live region, so moving the slider or switching layout is announced once it settles.
Status is in text ("Fits · up to 90"), not only in the bar colour.
Examples
Sorted, every layout
sortByFit puts the options that fit first; showAllCapacities adds each option's capacity in every layout, the current one marked.
1 of 4 take 20 people around one table.
North Room
Floor 2 · 110 m²Fits · up to 28- Theatre
- 90
- Classroom
- 48
- Boardroom
- 28
- Standing
- 120
The Loft
Floor 3 · 70 m²Too small · up to 18- Theatre
- 50
- Classroom
- 24
- Boardroom
- 18
- Standing
- 70
Studio 4
Floor 3 · 32 m²Too small · up to 10- Theatre
- 20
- Classroom
- 12
- Boardroom
- 10
- Standing
- 25
Atrium
Ground floor · 240 m²Not in this layout- Theatre
- 180
- Classroom
- 96
- Boardroom
- —
- Standing
- 260
API
CapacityFinder
| Prop | Type | Default |
|---|---|---|
options{ id, name, capacities: Record<arrangementId, number | null>, meta?, description?, media? }. null or missing = not possible in that layout. | CapacityOption[] | — |
arrangements{ id, label, phrase?, hint? } — phrase is used in the summary ("theatre-style"). | CapacityArrangement[] | — |
count / defaultCount / onCountChangeHead count, controlled or not. Default: min. | number | — |
arrangement / defaultArrangement / onArrangementChangeSelected layout. Default: the first. | string | — |
min / max / stepSlider bounds. | number | 1 / largest capacity / 1 |
sortByFitFitting options first, then too small, then unavailable. | boolean | false |
showAllCapacitiesCapacity grid per option. | boolean | false |
renderActionTrailing content per option. | ({ option, status, capacity }) => ReactNode | — |
noneFitMessageShown when nothing fits. | ReactNode | — |
labelsDictionary namespace "capacityFinder": arrangement, count, countInput, result, resultNone, largest, fits, tooSmall, unavailable, upTo. | Partial<CapacityFinderLabels> | — |
capacityFit(options, arrangement, count)
| Prop | Type | Default |
|---|---|---|
returnsstatus: "fits" | "too-small" | "unavailable". For server-side filtering or your own layout. | { option, status, capacity }[] | — |