Valora

shadcn/ui components

shadcn-style Tailwind components (@valora-ai/react/shadcn) built on the headless primitives.

@valora-ai/react/shadcn is a shadcn/ui-flavored skin — Tailwind-styled Button, Toggle, and Select — built on the same headless primitives as the Teams design system. If your app already uses shadcn/Tailwind, these drop in with a familiar API.

npm install @valora-ai/react
import { Button, Toggle, Select } from "@valora-ai/react/shadcn";

Tailwind setup

The components ship Tailwind utility class names, so Tailwind must scan the package or it will purge those classes in production. Add the dist bundle to your content:

// tailwind.config.js
export default {
  darkMode: "class",
  content: [
    "./src/**/*.{ts,tsx}",
    "./node_modules/@valora-ai/react/dist/shadcn.js", // ← required
  ],
};

No stylesheet import is needed — Tailwind generates the CSS from the class names.

Components

Button

variant: default · secondary · outline · ghost · destructive · link. size: default · sm · lg · icon. Supports asChild (renders onto your element) and disabled. Built on ControlButtonPrimitive.

<Button>Save</Button>
<Button variant="outline" size="sm">Cancel</Button>
<Button variant="destructive">Leave call</Button>
<Button asChild><a href="/docs">Docs</a></Button>

Toggle

Pressed state, controlled or uncontrolled. Visual state comes from the underlying ControlButtonPrimitive's data-active attribute (data-[active]: Tailwind variants), kept in sync with aria-pressed.

// controlled
<Toggle pressed={muted} onPressedChange={setMuted}>Mute</Toggle>
// uncontrolled
<Toggle defaultPressed variant="outline">Bold</Toggle>

Select

A single-select dropdown built on PopoverPrimitive + ListboxPrimitive — so it includes outside-click + Escape close and Arrow/Home/End keyboard navigation for free. Controlled (value + onValueChange) or uncontrolled (defaultValue).

const voices = [
  { value: "aria", label: "Aria" },
  { value: "atlas", label: "Atlas" },
];

<Select options={voices} value={voice} onValueChange={setVoice} aria-label="Voice" />

cn helper

cn(...classes) (exported) is a dependency-free class joiner. A className you pass to a component is additive — it does not de-conflict Tailwind utilities the way tailwind-merge does. If you need true override semantics, wrap with tailwind-merge in your own cn.

Same behavior, different skin

shadcn componentheadless primitive(s)
ButtonControlButtonPrimitive
ToggleControlButtonPrimitive (data-active)
SelectPopoverPrimitive + ListboxPrimitive

See the runnable examples/shadcn-react app, and the headless layer it's built on.

On this page

Valora is local-first

No API key, no server — everything in this doc runs on-device.

Star on GitHub