first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,72 @@
# `<Rack>`
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
`<Rack>` is the grouping primitive that models a hardware-rack frame — a
horizontal (default) or vertical sequence of fixed-width slots. It is
specifically designed for surfaces that mimic 19-inch rack-mount audio
gear, where the visible unit count and slot positioning carry semantic
weight that maps onto stage hardware. Each rack advertises its slot count
through `aria-colcount` (horizontal) or `aria-rowcount` (vertical) so
screen readers can announce the user's progress through the frame.
The component is presentational only. It does not enforce that children
are uniformly sized or that the rack actually contains the advertised
number of slots — those checks live at the schema validation layer in
`@suaveplan/control-surface-schema`.
## Features
- Horizontal or vertical orientation.
- Configurable unit count with sensible default (8).
- ARIA grid metadata via `aria-colcount` / `aria-rowcount`.
- `data-rack-id` attribute mirroring the schema id.
- Default gap of 4 pixels between slots.
## Usage: Basic
```tsx
<Rack id="effects" label="Effects rack" units={4}>
<Reverb />
<Delay />
<Chorus />
<Compressor />
</Rack>
```
## Usage: Advanced
```tsx
<Rack
id="patchbay"
label="Patchbay"
orientation="vertical"
units={12}
className="dark"
style={{ padding: 8, background: "#0a0a0d" }}
>
{channels.map((c) => (
<PatchRow key={c.id} {...c} />
))}
</Rack>
```
## API Reference
- `<Rack>` props: `id`, `label?`, `units?` (default 8), `orientation?`
(default `"horizontal"`), `className?`, `style?`, `children?`.
- `rackStyle(orientation, units)` — pure helper returning the inline
`style`.
## Implementation Notes
The minimum size (`minWidth` or `minHeight`) is computed as `units * 24`
to reserve space for the announced slot count even when the rack is
empty. Consumers needing different slot pitches override the value via
the merged `style` prop. The rack uses `role="group"`; the more specific
`role="grid"` would imply selectable cells with row/column navigation,
which is not how a hardware rack behaves.