@usetheo/ui 0.1.0-next.1 → 0.3.0-next.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -7,6 +7,54 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.3.0-next.0] - 2026-05-22
11
+
12
+ Minor bump — visual defaults realigned to FAANG-modern density baseline
13
+ (shadcn / Linear / Vercel / Stripe). Public API unchanged; no type/prop
14
+ signatures touched. Every consumer in 0.2.x will see tighter form controls,
15
+ smaller body text, and a less-padded Card after upgrading.
16
+
17
+ ### Migration from 0.2.x
18
+
19
+ If you depended on the prior visual defaults (Button 40px, Card 24px
20
+ padding, body-md 15px), you have two options:
21
+
22
+ 1. **Per-component** — pass explicit `size="lg"` to Button/Input/Select/
23
+ Textarea/Card. These render the prior dimensions.
24
+ 2. **Global override** — set `<ThemeProvider defaultDensity="spacious">`
25
+ at the app root. All form controls bump to 44px globally.
26
+
27
+ No code change required if you accept the new defaults. Type-only
28
+ exports added: `Density`, `DensityContextValue`.
29
+
30
+ ### Added
31
+
32
+ - **`useDensity()` hook + `data-density` attribute (2026-05-22, RFC 0006)** — Global density override without rewriting `size` props per call site. Three tiers: `compact` (32px), `comfortable` (36px, default), `spacious` (44px). `<ThemeProvider defaultDensity="compact">` at the app root flips the entire surface. Persisted to localStorage. **EC-1 fix**: density implemented via CSS variables on `:root` (`--theo-control-h`, `--theo-control-px`) injected by ThemeProvider, not Tailwind class modifiers. Only the `md` cva variant reads the var; `sm` and `lg` stay hardcoded so explicit `size` prop always overrides density. (#TBD)
33
+ - **`docs/design-system.md > Density policy` section** — declares default heights per component + WCAG 2.5.8 AA tap-target policy + density override patterns. Closes the style-guide gap (previously implicit in source). (#TBD)
34
+ - **`playground/density-demo.tsx`** — live preview with 3-way density toggle. Mount via `?view=density` in the Vite playground. (#TBD)
35
+
36
+ ### Changed (BREAKING visual default, not API)
37
+
38
+ - **Form-control `md` defaults: 40px → 36px** (FAANG-tier modern density). Affects `Button`, `Input`, `Select.Trigger`, `Textarea`. `sm` stays 32px, `lg` recalibrated to 44px. (#TBD)
39
+ - **`body-md` typescale: 15px → 14px** (shadcn / Vercel Geist / Linear standard). `body-sm` recalibrated 14px → 13px to preserve a distinct tier. `validateDesignSystemFidelity` gate updated atomically with `tailwind-preset.ts`. (#TBD)
40
+ - **Card `md` padding: 24px → 20px** (`p-6` → `p-5`). `sm` unchanged (`p-3`); `lg` recalibrated 28px → 24px (`p-7` → `p-6`). (#TBD)
41
+ - **Bundle baseline rebased** for the new defaults (~+700 bytes total — CSS-var class strings + Density type union). Engines (whiteboard / slide / slide-deck) untouched. (#TBD)
42
+
43
+ ## [0.2.0-next.0] - 2026-05-20
44
+
45
+ Minor bump (not patch) because public API surface grew: new `defineTheme` /
46
+ `hex` / `rgb` exports plus `size` prop standardized across 9 primitives.
47
+ All additions are backwards-compatible — `defaultVariants.size = "md"`
48
+ preserves rendered markup for callers that don't pass `size`.
49
+
50
+ ### Added
51
+ - **`defineTheme(partial)` + `hex()` / `rgb()` helpers (2026-05-20, theming-and-sizes plan, Phase 2)** — Reduzem o atrito de criar tema customizado de "58 cor keys obrigatórias" para "só sobrescreva o que mudar". `defineTheme({ name, light: { primary: hex('#FF5722') } })` merja partial overrides em `violetForge` e retorna um `Theme` completo. `hex('#7C3AED')` e `rgb(124, 58, 237)` retornam HSL string-tuple (`"262 83% 58%"`) drop-in compatível com `ColorScale`. Suporta short hex (#abc), 8-char alpha (alpha descartado), case-insensitive. **EC-3** (last-writer-wins): passar `defineTheme({ name: 'violet-forge', ... })` sobrescreve o built-in, comportamento documentado em teste. **EC-4** (case-insensitive) e **EC-5** (4-char alpha) cobertos por testes. **EC-7** (override só light/dark): nota em JSDoc lembra o consumer que se omitir um modo, ele herda violetForge — pode gerar inconsistência visual intencional. Drop-in: `<ThemeProvider themes={[defineTheme({ name: 'corp' })]}>` funciona sem mudança no provider. (#TBD)
52
+ - **9 primitives expose `size` prop (2026-05-20, theming-and-sizes plan, Phase 1)** — `Input`, `Badge`, `Toast`, `Checkbox`, `Switch`, `Card`, `FormField`, `Textarea`, `Select.Trigger` agora aceitam `size?: 'sm' | 'md' | 'lg'` (default `md`, backwards-compat preservada). Compounds `Card` e `FormField` propagam size via React Context para os subparts. **EC-1**: `Input` usa `Omit<InputHTMLAttributes<HTMLInputElement>, 'size'>` no extends para evitar conflict com o HTML attribute nativo (`size: number` = text-input columns); type-test garantido via `@ts-expect-error`. **EC-2**: `Select.Trigger` confirmado Radix-button (sem `SelectHTMLAttributes` conflict). Subparts de Card/FormField não aceitam `size` próprio — use `className` para per-subpart tweaks (EC-8 documentado em JSDoc). (#TBD)
53
+ - **`cn()` ensina tailwind-merge sobre o Violet Forge typescale (2026-05-20)** — `src/lib/cn.ts` substitui `twMerge` direto por `extendTailwindMerge` declarando o `font-size` classGroup com as 16 typescale tokens (`display-2xl`/`display-xl`/`headline`/`title-lg`/`body-md`/`label-caps`/`code-md`/etc.). Sem essa extensão, classes como `text-label` (font-size) e `text-accent` (color) colapsavam ambas no mesmo `text-*` group, e o último vencia — quebrando size+color em CVA variants. (#TBD)
54
+ - **Registry descriptors for the engine surface (2026-05-19)** — Seven new shadcn-compatible registry items so `docs.usetheo.dev/theoui` and the `npx shadcn add` flow can deliver the engines as copy-paste components: `whiteboard` (14 files under `components/ui/whiteboard/`), `slide` (16 files under `components/ui/slide/`, including 3 CSS theme files), `slide-deck` (19 files under `components/blocks/slide-deck/`), and four Tier 2 plugins — `slide-plugin-shiki`, `slide-plugin-math`, `slide-plugin-mermaid`, `slide-plugin-emoji` — each shipping its own subpath under `components/ui/slide/plugins/<name>/`. Cross-item references resolved via `registryDependencies` (each plugin + slide-deck depend on `slide`). Honest install: dependencies arrays list every static or dynamic peer-dep a copy-paste consumer needs (`roughjs`, `perfect-freehand`, `zod` for whiteboard; the full markdown / mdast / hast stack for slide; `shiki` / `katex` / `mermaid` per plugin). Total: 121 registry items (was 114). (#TBD)
55
+ - **`scripts/build-registry.ts` strips source ESM extensions on external imports** — `rewriteRegistryImports` now drops `.js` / `.jsx` / `.ts` / `.tsx` from non-relative specifiers (e.g. `roughjs/bin/generator.js` → `roughjs/bin/generator`). Previously only relative imports were normalized; engines that import third-party submodules with the explicit ESM extension (whiteboard does this for `roughjs/bin/*`) would fail `validate-registry`'s `consumer-unsafe extension` gate. Limited to known source extensions so basenames that happen to end in `.js` inside URLs are untouched. (#TBD)
56
+ - **`scripts/validate-quality-gates.ts > validateRegistryStoriesAndTests` is entry-aware** — When a descriptor lists multiple files (engines like whiteboard / slide / slide-deck), the gate now only checks `<descriptor.name>.test.tsx` / `.stories.tsx` next to the entry file (`<name>.tsx` or `<name>.ts`), not every internal module. Internal helpers carry their own focused tests but don't need a story sibling. Single-file registry items are unaffected. (#TBD)
57
+
10
58
  ## [0.1.0-next.1] - 2026-05-19
11
59
 
12
60
  ### Added
package/dist/index.d.ts CHANGED
@@ -86,6 +86,17 @@ interface Theme {
86
86
  fontUrls?: string[];
87
87
  }
88
88
 
89
+ type Density = "compact" | "comfortable" | "spacious";
90
+ interface DensityContextValue {
91
+ density: Density;
92
+ setDensity: (next: Density) => void;
93
+ }
94
+ /**
95
+ * Read the current density from the active ThemeProvider context. Throws
96
+ * outside the provider so misuse fails loud — analogous to `useTheme`.
97
+ */
98
+ declare function useDensity(): DensityContextValue;
99
+
89
100
  interface ThemeContextValue {
90
101
  /** Active theme (full descriptor). */
91
102
  theme: Theme;
@@ -127,6 +138,13 @@ interface ThemeProviderProps {
127
138
  * Default: "theo-ui:theme".
128
139
  */
129
140
  storageKey?: string | null;
141
+ /**
142
+ * Initial density. Drives `data-density` on `<html>` and the `--theo-control-h`
143
+ * / `--theo-control-px` CSS vars consumed by form-control `md` variants.
144
+ * Defaults to `"comfortable"` (36px controls — FAANG-tier modern density).
145
+ * Plan: faang-density-tightening (D3).
146
+ */
147
+ defaultDensity?: Density;
130
148
  }
131
149
  /**
132
150
  * ThemeProvider — central registry + runtime switcher for Theo themes.
@@ -139,7 +157,7 @@ interface ThemeProviderProps {
139
157
  * 3. Lazy-loads theme font URLs by injecting `<link rel="stylesheet">`.
140
158
  * 4. Optionally persists choice in localStorage.
141
159
  */
142
- declare function ThemeProvider({ children, defaultTheme, defaultMode, themes: themesProp, storageKey, }: ThemeProviderProps): JSX.Element;
160
+ declare function ThemeProvider({ children, defaultTheme, defaultMode, themes: themesProp, storageKey, defaultDensity, }: ThemeProviderProps): JSX.Element;
143
161
  /**
144
162
  * useTheme — access theme state from any component inside <ThemeProvider>.
145
163
  * Throws if used outside the provider — fail-fast.
@@ -234,6 +252,116 @@ declare const classicPaper: Theme;
234
252
  */
235
253
  declare const auroraTerminal: Theme;
236
254
 
255
+ /**
256
+ * `defineTheme(input)` — build a `Theme` from a partial override.
257
+ *
258
+ * Reduces the boilerplate of authoring a custom theme from 58 colour
259
+ * keys (`light` × 29 + `dark` × 29) to "just what you want to change".
260
+ * The merge always uses `violetForge` as the base — this is a pure,
261
+ * deterministic helper that does not depend on whatever theme is active
262
+ * at the call site.
263
+ *
264
+ * The `Theme` object it returns is drop-in compatible with
265
+ * `<ThemeProvider themes={[...]}>` — same shape as `violetForge`,
266
+ * `classicPaper`, and `auroraTerminal`.
267
+ *
268
+ * Honest caveat: if you override `light.primary` but NOT `dark.primary`,
269
+ * the two modes will use different colours — your override in light,
270
+ * Violet Forge's default in dark. That's intentional. Pass both sides
271
+ * to keep them in sync.
272
+ *
273
+ * @example
274
+ * import { defineTheme, hex } from "@usetheo/ui";
275
+ * export const corp = defineTheme({
276
+ * name: "corp",
277
+ * light: { primary: hex("#0EA5E9") },
278
+ * dark: { primary: hex("#38BDF8") },
279
+ * });
280
+ *
281
+ * Plan: `.claude/knowledge-base/plans/theming-and-sizes-plan.md` T2.1.
282
+ */
283
+
284
+ interface DefineThemeInput {
285
+ /**
286
+ * Stable id used in `data-theme="<name>"` on the root element. Must
287
+ * match `/^[a-z][a-z0-9-]*$/i` (CSS-identifier-safe). Required.
288
+ */
289
+ name: string;
290
+ /**
291
+ * Human-readable label for theme switchers. Defaults to the
292
+ * capitalized version of `name` (e.g. "corp" → "Corp").
293
+ */
294
+ label?: string;
295
+ /** Optional one-line description shown in switchers. */
296
+ description?: string;
297
+ /**
298
+ * Override light-mode colours. Any key omitted is inherited from
299
+ * `violetForge.light`. See `ColorScale` for the full list.
300
+ */
301
+ light?: Partial<ColorScale>;
302
+ /**
303
+ * Override dark-mode colours. Any key omitted is inherited from
304
+ * `violetForge.dark`.
305
+ */
306
+ dark?: Partial<ColorScale>;
307
+ /**
308
+ * Override fonts (`display`, `body`, `mono`). Any key omitted is
309
+ * inherited from `violetForge.fonts`.
310
+ */
311
+ fonts?: Partial<ThemeFonts>;
312
+ /**
313
+ * Replace the default remote font URLs. Pass an empty array to skip
314
+ * font fetching entirely. Defaults to `violetForge.fontUrls` when
315
+ * omitted (so consumers that don't care still get Geist preloaded).
316
+ */
317
+ fontUrls?: string[];
318
+ }
319
+ declare function defineTheme(input: DefineThemeInput): Theme;
320
+
321
+ /**
322
+ * Color helpers that return values in the HSL string-tuple format the
323
+ * `ColorScale` shape expects (e.g. `"262 83% 58%"`).
324
+ *
325
+ * Why this format: matches the shadcn / Violet Forge convention where
326
+ * CSS variables hold the H S% L% components and consumers write
327
+ * `hsl(var(--primary))` (allowing alpha overlays via
328
+ * `hsl(var(--primary) / 0.5)`). Returning an object would force callers
329
+ * to write `${theme.light.primary.h} ${theme.light.primary.s}% …` —
330
+ * exactly the friction `hex()` is meant to remove.
331
+ *
332
+ * No external dependency: vanilla algorithm from CSS Color spec.
333
+ * Alpha channels are intentionally discarded — `ColorScale` is opaque;
334
+ * use `hsl(var(--primary) / 0.5)` in CSS for transparency.
335
+ *
336
+ * Plan: `.claude/knowledge-base/plans/theming-and-sizes-plan.md` T2.2.
337
+ */
338
+ /**
339
+ * Convert a hex color string to the HSL string-tuple format used by
340
+ * `ColorScale` ("`H S% L%`", e.g. `"262 83% 58%"`).
341
+ *
342
+ * Accepts `#rgb`, `#rgba`, `#rrggbb`, `#rrggbbaa`. Case-insensitive.
343
+ * Alpha bytes are silently dropped — use `hsl(var(--primary) / 0.5)`
344
+ * in CSS for transparency.
345
+ *
346
+ * @throws if the input is malformed.
347
+ *
348
+ * @example
349
+ * hex("#7C3AED") // "262 83% 58%"
350
+ * hex("#7c3aed") // "262 83% 58%" (same)
351
+ * hex("#abc") // expanded to "#aabbcc"
352
+ */
353
+ declare function hex(input: string): string;
354
+ /**
355
+ * Convert an RGB triplet (each in `[0, 255]`) to the HSL string-tuple
356
+ * format used by `ColorScale`.
357
+ *
358
+ * @throws if any channel is out of `[0, 255]`.
359
+ *
360
+ * @example
361
+ * rgb(124, 58, 237) // "262 83% 58%"
362
+ */
363
+ declare function rgb(r: number, g: number, b: number): string;
364
+
237
365
  /**
238
366
  * All themes bundled with Theo UI. Pass to `<ThemeProvider themes={builtinThemes}>`
239
367
  * if you want all of them available out of the box.
@@ -257,6 +385,7 @@ declare const builtinThemes: Theme[];
257
385
  */
258
386
  declare const toastVariants: (props?: ({
259
387
  variant?: "success" | "warning" | "destructive" | "info" | "default" | null | undefined;
388
+ size?: "sm" | "md" | "lg" | null | undefined;
260
389
  } & class_variance_authority_types.ClassProp) | undefined) => string;
261
390
  type ToastVariant = NonNullable<VariantProps<typeof toastVariants>["variant"]>;
262
391
  interface ToastProps extends ComponentPropsWithoutRef<typeof ToastPrimitive.Root>, VariantProps<typeof toastVariants> {
@@ -428,7 +557,7 @@ interface TaskStep {
428
557
  * `asChild` swaps the root for the consumer's element (Radix Slot pattern).
429
558
  */
430
559
  declare const buttonVariants: (props?: ({
431
- variant?: "primary" | "secondary" | "accent" | "destructive" | "link" | "ghost" | null | undefined;
560
+ variant?: "accent" | "link" | "primary" | "secondary" | "destructive" | "ghost" | null | undefined;
432
561
  size?: "sm" | "md" | "lg" | "icon" | null | undefined;
433
562
  } & class_variance_authority_types.ClassProp) | undefined) => string;
434
563
  interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {
@@ -452,7 +581,8 @@ declare const Button: react.ForwardRefExoticComponent<ButtonProps & react.RefAtt
452
581
  * "Running", "Failed" rows in deployment lists.
453
582
  */
454
583
  declare const badgeVariants: (props?: ({
455
- variant?: "primary" | "accent" | "success" | "warning" | "destructive" | "default" | "outline" | null | undefined;
584
+ variant?: "accent" | "primary" | "success" | "warning" | "destructive" | "default" | "outline" | null | undefined;
585
+ size?: "sm" | "md" | "lg" | null | undefined;
456
586
  } & class_variance_authority_types.ClassProp) | undefined) => string;
457
587
  interface BadgeProps extends HTMLAttributes<HTMLSpanElement>, VariantProps<typeof badgeVariants> {
458
588
  }
@@ -466,6 +596,29 @@ declare const BadgeWithDot: typeof Badge & {
466
596
  Dot: typeof Dot;
467
597
  };
468
598
 
599
+ /**
600
+ * Card — surface container for grouping related content.
601
+ *
602
+ * Composition pattern (shadcn-style):
603
+ * <Card>
604
+ * <Card.Header>
605
+ * <Card.Title>…</Card.Title>
606
+ * <Card.Description>…</Card.Description>
607
+ * </Card.Header>
608
+ * <Card.Body>…</Card.Body>
609
+ * <Card.Footer>…</Card.Footer>
610
+ * </Card>
611
+ *
612
+ * The `size` prop on the root propagates to subparts via Context, so a
613
+ * single declaration controls padding + heading scale across the compound.
614
+ * Subparts used in isolation default to `md`. Subparts do NOT accept a `size`
615
+ * prop of their own — use `className` for granular per-subpart tweaks.
616
+ * (EC-8, edge-case review 2026-05-20.)
617
+ */
618
+ type CardSize = "sm" | "md" | "lg";
619
+ interface CardRootProps extends HTMLAttributes<HTMLDivElement> {
620
+ size?: CardSize;
621
+ }
469
622
  interface TitleProps extends HTMLAttributes<HTMLHeadingElement> {
470
623
  /**
471
624
  * When true, renders the child element with the Card.Title styles applied
@@ -474,7 +627,7 @@ interface TitleProps extends HTMLAttributes<HTMLHeadingElement> {
474
627
  */
475
628
  asChild?: boolean;
476
629
  }
477
- declare const Card: react.ForwardRefExoticComponent<HTMLAttributes<HTMLDivElement> & react.RefAttributes<HTMLDivElement>> & {
630
+ declare const Card: react.ForwardRefExoticComponent<CardRootProps & react.RefAttributes<HTMLDivElement>> & {
478
631
  Header: react.ForwardRefExoticComponent<HTMLAttributes<HTMLDivElement> & react.RefAttributes<HTMLDivElement>>;
479
632
  Title: react.ForwardRefExoticComponent<TitleProps & react.RefAttributes<HTMLHeadingElement>>;
480
633
  Description: react.ForwardRefExoticComponent<HTMLAttributes<HTMLParagraphElement> & react.RefAttributes<HTMLParagraphElement>>;
@@ -482,8 +635,9 @@ declare const Card: react.ForwardRefExoticComponent<HTMLAttributes<HTMLDivElemen
482
635
  Footer: react.ForwardRefExoticComponent<HTMLAttributes<HTMLDivElement> & react.RefAttributes<HTMLDivElement>>;
483
636
  };
484
637
 
485
- interface InputProps extends InputHTMLAttributes<HTMLInputElement> {
486
- }
638
+ declare const inputVariants: (props?: ({
639
+ size?: "sm" | "md" | "lg" | null | undefined;
640
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
487
641
  /**
488
642
  * Input — text input primitive.
489
643
  *
@@ -492,7 +646,15 @@ interface InputProps extends InputHTMLAttributes<HTMLInputElement> {
492
646
  * - rounded-md (6px) — slightly less than buttons to differentiate.
493
647
  * - focus uses violet ring (--ring).
494
648
  * - placeholder uses --muted-foreground.
649
+ *
650
+ * The `size` prop accepts `"sm" | "md" | "lg"`. Default `md` preserves the
651
+ * 40px tall input from before this prop existed. EC-1 (edge-case review):
652
+ * this overrides the native HTML `size` attribute (text-input columns) —
653
+ * use `{...{ size: 20 } as any}` if you genuinely need the HTML attribute,
654
+ * which is exceedingly rare.
495
655
  */
656
+ interface InputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "size">, VariantProps<typeof inputVariants> {
657
+ }
496
658
  declare const Input: react.ForwardRefExoticComponent<InputProps & react.RefAttributes<HTMLInputElement>>;
497
659
 
498
660
  interface ContentProps$1 extends ComponentPropsWithoutRef<typeof DialogPrimitive.Content> {
@@ -628,7 +790,7 @@ declare const Skeleton: react.ForwardRefExoticComponent<HTMLAttributes<HTMLDivEl
628
790
  */
629
791
  declare const avatarVariants: (props?: ({
630
792
  size?: "sm" | "md" | "lg" | "xs" | "xl" | null | undefined;
631
- tone?: "primary" | "accent" | "muted" | null | undefined;
793
+ tone?: "accent" | "primary" | "muted" | null | undefined;
632
794
  } & class_variance_authority_types.ClassProp) | undefined) => string;
633
795
  interface AvatarProps extends ComponentPropsWithoutRef<typeof AvatarPrimitive.Root>, VariantProps<typeof avatarVariants> {
634
796
  }
@@ -650,11 +812,37 @@ interface LabelProps extends ComponentPropsWithoutRef<typeof LabelPrimitive.Root
650
812
  }
651
813
  declare const Label: react.ForwardRefExoticComponent<LabelProps & react.RefAttributes<HTMLLabelElement>>;
652
814
 
815
+ /**
816
+ * FormField — composition wrapper for accessible form rows.
817
+ *
818
+ * Provides context with a generated `id`, so children (Label, Input, Hint,
819
+ * Error) wire themselves via `htmlFor` / `id` / `aria-describedby` without
820
+ * the consumer having to thread IDs manually.
821
+ *
822
+ * Composition:
823
+ * <FormField>
824
+ * <FormField.Label required>Email</FormField.Label>
825
+ * <FormField.Control>
826
+ * <Input type="email" placeholder="…" />
827
+ * </FormField.Control>
828
+ * <FormField.Hint>We never share your email.</FormField.Hint>
829
+ * <FormField.Error>{error}</FormField.Error>
830
+ * </FormField>
831
+ *
832
+ * Errors take precedence over hints (only one of them shows at once).
833
+ */
834
+ type FormFieldSize = "sm" | "md" | "lg";
653
835
  interface FormFieldProps extends HTMLAttributes<HTMLDivElement> {
654
836
  /** Optional explicit id override. */
655
837
  id?: string;
656
838
  /** Marks the field as invalid; switches Hint → Error and toggles aria. */
657
839
  invalid?: boolean;
840
+ /**
841
+ * Size scale propagated to Label / Hint / Error subparts via Context.
842
+ * Default `md` preserves prior behavior. Subparts do NOT accept a `size`
843
+ * prop of their own — use `className` for granular tweaks (EC-8).
844
+ */
845
+ size?: FormFieldSize;
658
846
  }
659
847
  interface FormFieldLabelProps extends ComponentPropsWithoutRef<typeof LabelPrimitive.Root> {
660
848
  required?: boolean;
@@ -696,6 +884,17 @@ interface EmptyStateProps extends Omit<HTMLAttributes<HTMLDivElement>, "title">
696
884
  */
697
885
  declare const EmptyState: react.ForwardRefExoticComponent<EmptyStateProps & react.RefAttributes<HTMLDivElement>>;
698
886
 
887
+ /**
888
+ * Trigger size variant (theming-and-sizes plan T1.9).
889
+ * Items inside Select.Content stay md-equivalent regardless — the floating
890
+ * menu is isolated from the trigger context (documented decision).
891
+ *
892
+ * EC-2 guard: `<Select.Trigger>` is a Radix `<button>` — no SelectHTMLAttributes
893
+ * conflict to Omit. Verified before implementation.
894
+ */
895
+ declare const selectTriggerVariants: (props?: ({
896
+ size?: "sm" | "md" | "lg" | null | undefined;
897
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
699
898
  /**
700
899
  * Select — styled wrapper around Radix Select.
701
900
  *
@@ -715,7 +914,9 @@ declare const EmptyState: react.ForwardRefExoticComponent<EmptyStateProps & reac
715
914
  * Trigger matches Input height + violet focus ring. Content uses popover
716
915
  * surface with check on the selected item.
717
916
  */
718
- declare const SelectTrigger: react.ForwardRefExoticComponent<Omit<SelectPrimitive.SelectTriggerProps & react.RefAttributes<HTMLButtonElement>, "ref"> & react.RefAttributes<HTMLButtonElement>>;
917
+ interface SelectTriggerProps extends ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger>, VariantProps<typeof selectTriggerVariants> {
918
+ }
919
+ declare const SelectTrigger: react.ForwardRefExoticComponent<SelectTriggerProps & react.RefAttributes<HTMLButtonElement>>;
719
920
  declare const SelectContent: react.ForwardRefExoticComponent<Omit<SelectPrimitive.SelectContentProps & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
720
921
  declare const SelectLabel: react.ForwardRefExoticComponent<Omit<SelectPrimitive.SelectLabelProps & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
721
922
  declare const SelectItem: react.ForwardRefExoticComponent<Omit<SelectPrimitive.SelectItemProps & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
@@ -735,8 +936,17 @@ declare const Select: typeof SelectPrimitive.Root & {
735
936
  *
736
937
  * Supports tri-state via `checked="indeterminate"`. Violet fill when on,
737
938
  * border-only when off. Themed via tokens (--primary, --background).
939
+ *
940
+ * The `size` prop accepts `"sm" | "md" | "lg"`. Default `md` preserves the
941
+ * 16px box from before this prop existed. The `sm` size keeps a >=24px
942
+ * effective tap target via an invisible expanded hit area (WCAG 2.5.5).
738
943
  */
739
- declare const Checkbox: react.ForwardRefExoticComponent<Omit<CheckboxPrimitive.CheckboxProps & react.RefAttributes<HTMLButtonElement>, "ref"> & react.RefAttributes<HTMLButtonElement>>;
944
+ declare const checkboxVariants: (props?: ({
945
+ size?: "sm" | "md" | "lg" | null | undefined;
946
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
947
+ interface CheckboxProps extends ComponentPropsWithoutRef<typeof CheckboxPrimitive.Root>, VariantProps<typeof checkboxVariants> {
948
+ }
949
+ declare const Checkbox: react.ForwardRefExoticComponent<CheckboxProps & react.RefAttributes<HTMLButtonElement>>;
740
950
 
741
951
  declare const RadioGroup: react.ForwardRefExoticComponent<Omit<RadioGroupPrimitive.RadioGroupProps & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>> & {
742
952
  Item: react.ForwardRefExoticComponent<Omit<RadioGroupPrimitive.RadioGroupItemProps & react.RefAttributes<HTMLButtonElement>, "ref"> & react.RefAttributes<HTMLButtonElement>>;
@@ -748,17 +958,33 @@ declare const RadioGroup: react.ForwardRefExoticComponent<Omit<RadioGroupPrimiti
748
958
  *
749
959
  * Off-state uses --muted, on-state uses --primary with a subtle glow shadow
750
960
  * to mark "this is active" in the violet brand language.
961
+ *
962
+ * The `size` prop accepts `"sm" | "md" | "lg"`. Default `md` preserves the
963
+ * 20×36 track from before this prop existed.
751
964
  */
752
- declare const Switch: react.ForwardRefExoticComponent<Omit<SwitchPrimitive.SwitchProps & react.RefAttributes<HTMLButtonElement>, "ref"> & react.RefAttributes<HTMLButtonElement>>;
753
-
754
- interface TextareaProps extends TextareaHTMLAttributes<HTMLTextAreaElement> {
965
+ declare const switchVariants: (props?: ({
966
+ size?: "sm" | "md" | "lg" | null | undefined;
967
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
968
+ interface SwitchProps extends ComponentPropsWithoutRef<typeof SwitchPrimitive.Root>, VariantProps<typeof switchVariants> {
755
969
  }
970
+ declare const Switch: react.ForwardRefExoticComponent<SwitchProps & react.RefAttributes<HTMLButtonElement>>;
971
+
756
972
  /**
757
973
  * Textarea — multi-line input mirror of Input.
758
974
  *
759
975
  * Matches Input visuals (violet focus ring, --input border, --card bg).
760
- * Default minimum height of 96px; consumer can override via className.
976
+ * The `size` prop accepts `"sm" | "md" | "lg"`. Default `md` preserves the
977
+ * 80px (5rem) min-height + body-md text from before this prop existed.
978
+ *
979
+ * Note: `TextareaHTMLAttributes<HTMLTextAreaElement>` does NOT declare a
980
+ * native `size` attribute (textareas use `rows` / `cols`), so no Omit is
981
+ * needed — contrast with `<Input>` which had EC-1 collision.
761
982
  */
983
+ declare const textareaVariants: (props?: ({
984
+ size?: "sm" | "md" | "lg" | null | undefined;
985
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
986
+ interface TextareaProps extends TextareaHTMLAttributes<HTMLTextAreaElement>, VariantProps<typeof textareaVariants> {
987
+ }
762
988
  declare const Textarea: react.ForwardRefExoticComponent<TextareaProps & react.RefAttributes<HTMLTextAreaElement>>;
763
989
 
764
990
  interface ContextWindowBarProps extends HTMLAttributes<HTMLDivElement> {
@@ -1635,7 +1861,7 @@ declare const TopNav: react.ForwardRefExoticComponent<HTMLAttributes<HTMLElement
1635
1861
  */
1636
1862
  declare const Overlay: react.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogOverlayProps & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
1637
1863
  declare const sheetVariants: (props?: ({
1638
- side?: "right" | "left" | "top" | "bottom" | null | undefined;
1864
+ side?: "bottom" | "left" | "right" | "top" | null | undefined;
1639
1865
  } & class_variance_authority_types.ClassProp) | undefined) => string;
1640
1866
  interface ContentProps extends ComponentPropsWithoutRef<typeof DialogPrimitive.Content>, VariantProps<typeof sheetVariants> {
1641
1867
  hideCloseButton?: boolean;
@@ -3060,4 +3286,4 @@ interface CommandPaletteProps {
3060
3286
  */
3061
3287
  declare function CommandPalette({ open, onOpenChange, items, onSelect, placeholder, emptyMessage, filter, }: CommandPaletteProps): react_jsx_runtime.JSX.Element;
3062
3288
 
3063
- export { ALL_MODES, AgentComposer, type AgentDraft, AgentEditor, AgentErrorCard, type AgentErrorKind, AgentEvent, type AgentEvent$1 as AgentEventModel, type AgentEventStatus, type AgentEventType, AgentHandoff, AgentProfile, type AgentProfileDescriptor, AgentStartingState, AgentStream, type AgentStreamItem, AgentStreaming, AgentTimeline, ApprovalCard, type ApprovalSeverity, ArtifactPreview, type Attachment, AttachmentChip, type AuditActorKind, type AuditEntry, AuditLogEntry, type AuditSeverity, AutoCompactNotice, Avatar, BadgeWithDot as Badge, type BadgeProps, BrowserControls, BuildLogStream, Button, type ButtonProps, type Capability, CapabilityIndicator, type CapabilityState, Card, ChatComposer, ChatMessage, ChatThread, Checkbox, type ColorScale, type CommandItem, CommandPalette, type ComposerMode, ContextCard, ContextWindowBar, CostMeter, type CreatedFile, CreatedFilesCard, type CronJob, CronJobCard, type CronJobStatus, CronJobsList, type Deployment, DeploymentRow, type DeploymentStatus, Dialog, type DiffHunk, type DiffLine, type DiffLineKind, DiffViewer, type Domain, DomainConfig, type DomainStatus, EmptyState, type EnvScope, type EnvVar, EnvVarEditor, FolderContextCard, type FolderEntry, FolderSelector, FormField, HOOK_EVENTS, type HandoffParty, HookConfig, type HookEntry, type HookEvent, type HookEventEntry, HookEventLog, type HookEventResult, Input, type InputProps, type IntentOption, IntentSelector, Label, type Lane, LaneBoard, type LaneCard, type LaneState, type LogLevel, type LogLine, LoginSplit, type MCPServer, MCPServerCard, MCPServerList, type MCPServerStatus, MODE_LABEL, MemoryEditor, type MemoryLayer, type MemoryScope, type MentionItem, MentionMenu, type MentionTrigger, type Message, type MessageRole, type Metric, MetricsPanel, type Mode, type ModelCapabilityFlag, ModelCard, type ModelInfo, type ModelOption, ModelSelector, type PermissionDecision, type PermissionDecisionKind, PermissionMatrix, PermissionModal, type PermissionOperation, type PermissionRequest, type PermissionRule, type PlanNode, type PlanNodeStatus, type PreviewEnv, PreviewEnvCard, PreviewPanel, type PreviewService, ProgressChecklist, type Project, ProjectCard, type ProjectStatus, ProjectSwitcher, type QuickAction, QuickActionChips, RadioGroup, type RailStep, type RecentFolder, RecentFoldersList, type RollbackTarget, RollbackUI, type Rule, RuleCard, RuleEditor, type RuleScope, type RuleState, RunStats, type RunningTaskItem, type RunningTaskStatus, RunningTasksPanel, ScrollArea, Select, SessionListItem, type SessionMode, type SessionRunStatus, type SessionStatus, type SessionSummary, SessionTimeline, Sheet, Sidebar, Skeleton, type Skill, SkillCard, SkillEditor, type SkillSource, type SkillState, SkillsList, SocialAuthRow, type SocialProvider, StepsRail, SubAgentDispatch, type SubAgentRun, type SubAgentState, Switch, SystemPromptEditor, Tabs, TaskHeader, TaskNode, TaskPlan, type TaskSource, type TaskStatus, type TaskStep, type TaskStepStatus, type TerminalLine, TerminalPanel, Textarea, type TextareaProps, type Theme, type ThemeFonts, type ThemeMode, ThemeProvider, ThemeScript, ThemeSwitcher, TheoUIProvider, type TheoUIProviderProps, Toast, type ToastVariant, Toaster, TokenUsageChart, type TokenUsagePoint, ToolCall, ToolCallCard, type ToolCallStatus, type ToolEnablement, type ToolEntry, ToolResult, ToolsList, TooltipWithStatics as Tooltip, TopNav, auroraTerminal, avatarVariants, badgeVariants, builtinThemes, buttonVariants, capabilityPresets, classicPaper, cn, modelCapabilityPresets, sheetVariants, useTheme, useToast, violetForge };
3289
+ export { ALL_MODES, AgentComposer, type AgentDraft, AgentEditor, AgentErrorCard, type AgentErrorKind, AgentEvent, type AgentEvent$1 as AgentEventModel, type AgentEventStatus, type AgentEventType, AgentHandoff, AgentProfile, type AgentProfileDescriptor, AgentStartingState, AgentStream, type AgentStreamItem, AgentStreaming, AgentTimeline, ApprovalCard, type ApprovalSeverity, ArtifactPreview, type Attachment, AttachmentChip, type AuditActorKind, type AuditEntry, AuditLogEntry, type AuditSeverity, AutoCompactNotice, Avatar, BadgeWithDot as Badge, type BadgeProps, BrowserControls, BuildLogStream, Button, type ButtonProps, type Capability, CapabilityIndicator, type CapabilityState, Card, ChatComposer, ChatMessage, ChatThread, Checkbox, type ColorScale, type CommandItem, CommandPalette, type ComposerMode, ContextCard, ContextWindowBar, CostMeter, type CreatedFile, CreatedFilesCard, type CronJob, CronJobCard, type CronJobStatus, CronJobsList, type DefineThemeInput, type Density, type DensityContextValue, type Deployment, DeploymentRow, type DeploymentStatus, Dialog, type DiffHunk, type DiffLine, type DiffLineKind, DiffViewer, type Domain, DomainConfig, type DomainStatus, EmptyState, type EnvScope, type EnvVar, EnvVarEditor, FolderContextCard, type FolderEntry, FolderSelector, FormField, HOOK_EVENTS, type HandoffParty, HookConfig, type HookEntry, type HookEvent, type HookEventEntry, HookEventLog, type HookEventResult, Input, type InputProps, type IntentOption, IntentSelector, Label, type Lane, LaneBoard, type LaneCard, type LaneState, type LogLevel, type LogLine, LoginSplit, type MCPServer, MCPServerCard, MCPServerList, type MCPServerStatus, MODE_LABEL, MemoryEditor, type MemoryLayer, type MemoryScope, type MentionItem, MentionMenu, type MentionTrigger, type Message, type MessageRole, type Metric, MetricsPanel, type Mode, type ModelCapabilityFlag, ModelCard, type ModelInfo, type ModelOption, ModelSelector, type PermissionDecision, type PermissionDecisionKind, PermissionMatrix, PermissionModal, type PermissionOperation, type PermissionRequest, type PermissionRule, type PlanNode, type PlanNodeStatus, type PreviewEnv, PreviewEnvCard, PreviewPanel, type PreviewService, ProgressChecklist, type Project, ProjectCard, type ProjectStatus, ProjectSwitcher, type QuickAction, QuickActionChips, RadioGroup, type RailStep, type RecentFolder, RecentFoldersList, type RollbackTarget, RollbackUI, type Rule, RuleCard, RuleEditor, type RuleScope, type RuleState, RunStats, type RunningTaskItem, type RunningTaskStatus, RunningTasksPanel, ScrollArea, Select, SessionListItem, type SessionMode, type SessionRunStatus, type SessionStatus, type SessionSummary, SessionTimeline, Sheet, Sidebar, Skeleton, type Skill, SkillCard, SkillEditor, type SkillSource, type SkillState, SkillsList, SocialAuthRow, type SocialProvider, StepsRail, SubAgentDispatch, type SubAgentRun, type SubAgentState, Switch, SystemPromptEditor, Tabs, TaskHeader, TaskNode, TaskPlan, type TaskSource, type TaskStatus, type TaskStep, type TaskStepStatus, type TerminalLine, TerminalPanel, Textarea, type TextareaProps, type Theme, type ThemeFonts, type ThemeMode, ThemeProvider, ThemeScript, ThemeSwitcher, TheoUIProvider, type TheoUIProviderProps, Toast, type ToastVariant, Toaster, TokenUsageChart, type TokenUsagePoint, ToolCall, ToolCallCard, type ToolCallStatus, type ToolEnablement, type ToolEntry, ToolResult, ToolsList, TooltipWithStatics as Tooltip, TopNav, auroraTerminal, avatarVariants, badgeVariants, builtinThemes, buttonVariants, capabilityPresets, classicPaper, cn, defineTheme, hex, modelCapabilityPresets, rgb, sheetVariants, useDensity, useTheme, useToast, violetForge };