Buzz UI
Open-source React components with Buzz's semantic roles, Inter typography, and Lucide icons. Behavior comes from public Base UI primitives; calendar and resize behavior come from DayPicker and react-resizable-panels. No internal package, font CDN, Storybook server, or native Buzz bridge is required.
From the repository root:
. ./bin/activate-hermit
pnpm install --frozen-lockfile
pnpm --filter buzz-desktop-next dev
# Open http://localhost:1430/design
pnpm --filter @buzz/ui build
Consume
import '@fontsource-variable/inter/index.css';
import '@fontsource/jetbrains-mono/index.css';
import { Button, Field, Input } from '@buzz/ui';
<Field.Root name="name">
<Field.Label>Name</Field.Label>
<Input required />
<Field.Error />
</Field.Root>
<Button variant="primary">Continue</Button>
The workspace export includes the source CSS; use a Tailwind 4 PostCSS pipeline.
For a consumer without Tailwind, build the package and use @buzz/ui/dist plus
@buzz/ui/dist/styles.css. Build output keeps React and behavior libraries external.
The package is intentionally private until package naming and release automation
are agreed; it is fully usable from this open-source workspace.
The stylesheet includes the shared theme and Tailwind reset. Load it once at the
application boundary. Set class="dark" on the document root for dark mode.
Font packages belong to the host, allowing self-hosted subsets without remote requests.
Component contract
Compound families retain Base UI's API: Dialog.Root, Dialog.Trigger,
Dialog.Portal, Dialog.Backdrop, Dialog.Popup, Dialog.Title, and
Dialog.Close. Use render={<Button />} to skin triggers and closes. Supply a
Title and Description for dialogs and popovers. Label inputs with Field.Label;
label standalone controls directly. IconButton requires an accessible name.
Behavioral Root, Portal, and state helpers are direct exports, preserving generics, refs, controlled state, and events. Styled parts merge both string and state-function class names. The underlying libraries own focus management, keyboard navigation, ARIA semantics, and dismissal. Caller-supplied labels and composition still matter.
Place Tabs.Indicator inside Tabs.List for a sliding selection pill.
Use Tabs.List variant="glass" for translucent chrome; it shares the same
selection behavior and motion as the default solid variant. Pointer
selection retargets the shared 120ms transition; keyboard focus and reduced motion
keep selection immediate. Panels update immediately. Toasts use the shared
180ms entrance and 120ms exit transitions, with no movement under reduced motion.
Button variants: primary, secondary, outline, ghost, danger, link. Sizes: sm, md, lg. Loading disables duplicate activation while preserving the accessible name. Color, type, geometry, and motion are roles; components never consume color ramps. BarChart covers nonnegative categorical bars with a semantic data table, not a full chart grammar. Carousel is manually advanced, without autoplay or drag.
Naming differences from shadcn: Menu is DropdownMenu; PreviewCard is HoverCard; OTPField is InputOTP; Field.Label is Label; Toast replaces Sonner's role; BarChart is the initial Chart treatment. Sheet composes Dialog. No shadcn API compatibility or proprietary BlockUI package compatibility is implied.
See ../../desktop-next/OPEN_SOURCE.md for provenance and THIRD_PARTY_NOTICES.md
for upstream notices. New source is covered by the repository's Apache-2.0 license.
Native scroll surfaces use thin scrollbars; custom ScrollArea bars share the
size-scrollbar token. Resize grips use size-grip-length (1rem) for their visible
length while retaining a larger pointer target. Table cells align to the reading
edge, including row and column headings.
Generated responses
GeneratedResponse accepts unknown input and validates it before rendering. The
version 1 schema supports text, notices, metrics, task lists, tables, and action
lists. It caps serialized input at 64,000 characters, 20 blocks, 30 tasks per list,
50 table rows, 8 columns, and 6 actions per action list. IDs must be unique in their
scope, and action IDs are unique across the snapshot. Unknown fields and types fail.
The schema accepts no HTML, URLs, arbitrary styles, or component names. Text is
rendered through React escaping. The host supplies an own-property action allowlist;
unknown actions stay disabled. Rendering never dispatches an action. state="streaming"
and pendingAction prevent activation while a snapshot or request is in flight.
Invalid input renders an error and an optional host-provided retry callback.
The host owns streaming assembly, action authorization, persistence, retries, and network errors. Pass a new immutable complete snapshot when it changes. The renderer is a presentation boundary, not an agent execution engine or an authorization system.