ComponentsPickers

Capacity finder

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.

components/capacity-finder.tsxtheme · material · accent · density · font
Layout

3 of 4 take 40 people theatre-style.

  • Atrium

    Ground floor · 240 m²
    Fits · up to 180
  • North Room

    Floor 2 · 110 m²
    Fits · up to 90
  • The Loft

    Floor 3 · 70 m²
    Fits · up to 50
  • Studio 4

    Floor 3 · 32 m²
    Too small · up to 20

Installation

$ pnpm add @vamos-ui/react

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.

Layout

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

PropTypeDefault
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 / onCountChange
Head count, controlled or not. Default: min.
number—
arrangement / defaultArrangement / onArrangementChange
Selected layout. Default: the first.
string—
min / max / step
Slider bounds.
number1 / largest capacity / 1
sortByFit
Fitting options first, then too small, then unavailable.
booleanfalse
showAllCapacities
Capacity grid per option.
booleanfalse
renderAction
Trailing content per option.
({ option, status, capacity }) => ReactNode—
noneFitMessage
Shown when nothing fits.
ReactNode—
labels
Dictionary namespace "capacityFinder": arrangement, count, countInput, result, resultNone, largest, fits, tooSmall, unavailable, upTo.
Partial<CapacityFinderLabels>—

capacityFit(options, arrangement, count)

PropTypeDefault
returns
status: "fits" | "too-small" | "unavailable". For server-side filtering or your own layout.
{ option, status, capacity }[]—