Data
Panel blocks
One header for every block of a side panel: collapse, reorder by drag or keyboard, remembered.
Live example
Import
Each family is its own entry point, so a page loads only what it uses.
import { Block, BlockStack } from "@nibapp/ui/components/block-stack";import { Button } from "@nibapp/ui/components/button";import { Progress, ProgressRing } from "@nibapp/ui/components/progress";Props
Each component's own props and variants, read from its source. What it also takes from an element or a Base UI part is named below its table.
Block
One block of a `BlockStack`: the shared header (title and caret, meta, grip), then its body.
| Prop | Type | Default | Description |
|---|---|---|---|
| id (required) | string | — | Stable id: the key in `BlockLayout`. |
| title (required) | string | — | Heading text ("Context"). Names the region and the grip. |
| meta | ReactNode | — | Quiet trailing summary in the header ("48 % used", "2 running"), shown collapsed too. Text only: a block header holds no buttons besides its own; actions live in the body. |
Also takes the props of a <section> element, except title and id.
BlockStack
| Prop | Type | Default | Description |
|---|---|---|---|
| layout (required) | BlockLayout | — | |
| onLayoutChange (required) | (layout: BlockLayout) => void | — | |
| children (required) | ReactNode | — | `<Block>`s; their order on screen is `layout.order` (blocks it doesn't list follow, as given). |
Also takes the props of a <div> element, except children.
Button
| Prop | Type | Default | Description |
|---|---|---|---|
| variant | "primary" | "secondary" | "ghost" | "quiet" | "danger" | "danger-ghost" | "link" | "secondary" |
|
| size | "xs" | "sm" | "md" | "lg" | "md" | |
| block | boolean | — | |
| truncate | boolean | — | The button may shrink below its label's width; the label then truncates with an ellipsis. |
| wrap | boolean | — | The label wraps onto more lines and the button grows, its `leading` icon on the first line: for words that are an action and may run long in another language (a tip). One line keeps the size. |
| loading | boolean | false | Shows a spinner, keeps the button's width, and blocks interaction. |
| leading | ReactNode | — | Icon rendered before the label. |
| trailing | ReactNode | — | Icon or hint (e.g. <Kbd>) rendered after the label. |
| disabledReason | string | undefined | — | Disables the button and says why: the reason is its tooltip and its accessible description, and the button stays focusable (`aria-disabled`) so a keyboard reaches it. |
Also takes .
Progress
Linear progress for long-running tasks. Determinate fill or an indeterminate sliding sheen.
| Prop | Type | Default | Description |
|---|---|---|---|
| tone | "ink" | "accent" | "success" | "warning" | "danger" | "ink" | Ink by default. `accent` is a sanctioned blue micro-moment — use it for the hero task only. |
| size | "sm" | "md" | "lg" | "md" | |
| value (required) | number | null | — | Current value; `null` renders the indeterminate sheen. |
| label | ReactNode | — | Visible label, wired to the progressbar's accessible name. |
| showValue | boolean | false | Show the formatted value (e.g. "42%") opposite the label. |
Also takes the props of Base UI's Progress.Root, except children and value.
ProgressRing
Tiny circular meter for token / context-window usage. Escalates at warning & danger thresholds.
| Prop | Type | Default | Description |
|---|---|---|---|
| size | "sm" | "md" | "lg" | "xl" | "md" |
|
| value (required) | number | — | |
| warningAt | number | 75 | Percentage at which the ring turns amber. |
| dangerAt | number | 90 | Percentage at which the ring turns red. |
| level | ProgressRingLevel | — | Force a level instead of deriving it from the thresholds. |
| showValue | boolean | false | Show the formatted value next to the ring — keeps the state legible without color. |
| aria-label (required) | string | — | Required accessible name, e.g. "Context window". |
Also takes ComponentProps<typeof Meter.Root>, except children and render.