@dimaan/ui 0.0.8 → 0.0.10

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/dist/index.d.cts CHANGED
@@ -2,6 +2,7 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import * as react from 'react';
3
3
  import { HTMLAttributes, ReactNode, ReactElement, ButtonHTMLAttributes, InputHTMLAttributes, ChangeEvent, FieldsetHTMLAttributes, AnchorHTMLAttributes, Ref, TextareaHTMLAttributes } from 'react';
4
4
  import { FieldValues, FieldPath, Control } from 'react-hook-form';
5
+ import * as RadixRadioGroup from '@radix-ui/react-radio-group';
5
6
  import { ClassValue } from 'clsx';
6
7
 
7
8
  interface DashboardLayoutContextValue {
@@ -76,6 +77,51 @@ interface AppShellProps extends Pick<DashboardLayoutProps, 'defaultCollapsed' |
76
77
  sidebarFooter?: ReactNode;
77
78
  children: ReactNode;
78
79
  }
80
+ /**
81
+ * Opinionated dashboard shell that combines `<DashboardLayout>` + `<Sidebar>` + `<Header>`
82
+ * with a flat `nav` array. Hosts `<DirectionProvider>` so any Radix-based component
83
+ * inside (Select, future Tooltip/Popover/etc.) auto-detects direction from `<html dir>`.
84
+ *
85
+ * For more complex layouts (custom sections, dividers, multi-row headers), compose
86
+ * the underlying primitives (`Sidebar` + `SidebarNav` + `DashboardHeader`) directly.
87
+ *
88
+ * @example Basic usage
89
+ * ```tsx
90
+ * <AppShell
91
+ * brand={{ logo: <Logo />, name: 'Acme' }}
92
+ * nav={[
93
+ * { key: 'home', label: 'Home', href: '/', icon: <Home /> },
94
+ * {
95
+ * key: 'settings',
96
+ * label: 'Settings',
97
+ * icon: <Settings />,
98
+ * items: [
99
+ * { key: 'profile', label: 'Profile', href: '/settings/profile' },
100
+ * { key: 'team', label: 'Team', href: '/settings/team' },
101
+ * ],
102
+ * },
103
+ * ]}
104
+ * title="Dashboard"
105
+ * searchPlaceholder="Search…"
106
+ * headerActions={<UserMenu />}
107
+ * sidebarFooter={<UserBadge />}
108
+ * >
109
+ * <Routes>...</Routes>
110
+ * </AppShell>
111
+ * ```
112
+ *
113
+ * @example With React Router Link integration via render prop
114
+ * ```tsx
115
+ * const nav = [{
116
+ * key: 'home',
117
+ * label: 'Home',
118
+ * icon: <Home />,
119
+ * render: ({ children, className, ...rest }) => (
120
+ * <Link to="/" className={className} {...rest}>{children}</Link>
121
+ * ),
122
+ * }];
123
+ * ```
124
+ */
79
125
  declare function AppShell({ brand, nav, title, searchPlaceholder, onSearch, headerActions, sidebarFooter, defaultCollapsed, collapsed, onCollapsedChange, children, }: AppShellProps): react_jsx_runtime.JSX.Element;
80
126
 
81
127
  interface AvatarProps extends HTMLAttributes<HTMLSpanElement> {
@@ -111,6 +157,29 @@ interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
111
157
  */
112
158
  asChild?: boolean;
113
159
  }
160
+ /**
161
+ * Polymorphic button with 6 variants, 4 sizes, and a built-in loading state.
162
+ * Supports the `asChild` slot pattern for routing-library `<Link>` integration.
163
+ *
164
+ * @example Default usage
165
+ * ```tsx
166
+ * <Button onClick={handleSave}>Save</Button>
167
+ * ```
168
+ *
169
+ * @example Variant + size + loading
170
+ * ```tsx
171
+ * <Button variant="outline" size="sm" loading={isSubmitting}>
172
+ * Cancel
173
+ * </Button>
174
+ * ```
175
+ *
176
+ * @example asChild — wrap a router Link without a wrapper element
177
+ * ```tsx
178
+ * <Button asChild variant="ghost">
179
+ * <Link to="/settings">Open settings</Link>
180
+ * </Button>
181
+ * ```
182
+ */
114
183
  declare const Button: react.ForwardRefExoticComponent<ButtonProps & react.RefAttributes<HTMLButtonElement>>;
115
184
 
116
185
  type CheckboxSize = 'sm' | 'md';
@@ -134,8 +203,16 @@ interface FieldRHFProps<TValues extends FieldValues = FieldValues, TName extends
134
203
  /** Path to the field within the form values. */
135
204
  name: TName;
136
205
  }
206
+ /**
207
+ * `vertical` (default) — label on top, control below, helper/error under.
208
+ * `horizontal` — label on start, control on end (same row); helper/error below.
209
+ *
210
+ * Use `horizontal` for boolean controls (Switch, Checkbox) where the universal
211
+ * pattern is "label · toggle" rather than "label / toggle below".
212
+ */
213
+ type FieldOrientation = 'vertical' | 'horizontal';
137
214
  interface FieldLayoutProps {
138
- /** Label rendered above the control. */
215
+ /** Label rendered with the control. Position depends on `orientation`. */
139
216
  label?: ReactNode;
140
217
  /** Helper text rendered under the control when there's no error. */
141
218
  description?: ReactNode;
@@ -145,6 +222,8 @@ interface FieldLayoutProps {
145
222
  disabled?: boolean;
146
223
  /** Stretch the wrapper to fill its parent. Defaults to `true`. */
147
224
  fullWidth?: boolean;
225
+ /** Layout direction. `vertical` (default) for inputs; `horizontal` for switches/checkboxes. */
226
+ orientation?: FieldOrientation;
148
227
  /** Class applied to the outer wrapper. */
149
228
  className?: string;
150
229
  /** The single control element to wrap. Receives id + aria + (in RHF mode) field props. */
@@ -236,23 +315,47 @@ declare const inputBaseClass = "group/input relative inline-flex w-full items-ce
236
315
  interface InputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'size' | 'prefix'> {
237
316
  variant?: InputVariant;
238
317
  inputSize?: InputSize;
239
- /** Optional label rendered above the field. */
240
- label?: ReactNode;
241
- /** Helper text rendered under the field when not in an error state. */
242
- helperText?: ReactNode;
243
- /** Error message — renders in destructive style and sets aria-invalid. */
244
- error?: ReactNode;
245
318
  /** Element rendered before the input (icon, prefix text, etc.). */
246
319
  leadingIcon?: ReactNode;
247
320
  /** Element rendered after the input (icon, suffix text, etc.). */
248
321
  trailingIcon?: ReactNode;
249
- /** Stretch the wrapper to fill the parent's inline width. Defaults to `true`. */
250
- fullWidth?: boolean;
251
322
  /** Class applied to the outer wrapper that holds the icons + input. */
252
323
  wrapperClassName?: string;
253
- /** Class applied to the field container (`<label>` block). */
254
- containerClassName?: string;
255
324
  }
325
+ /**
326
+ * Bare text input — renders the wrapper + native `<input>` + optional leading /
327
+ * trailing icons. **No label/helperText/error props by design** (per ADR-007:
328
+ * Field owns all form layout). Wrap in `<Field label="…">` for label, helper,
329
+ * error rendering and full a11y wiring.
330
+ *
331
+ * @example Inside a Field (RHF + Zod)
332
+ * ```tsx
333
+ * <Field name="email" label="Email" description="…" required>
334
+ * <Input type="email" />
335
+ * </Field>
336
+ * ```
337
+ *
338
+ * @example With icons
339
+ * ```tsx
340
+ * <Field label="Search">
341
+ * <Input
342
+ * leadingIcon={<Search />}
343
+ * trailingIcon={<X onClick={clear} />}
344
+ * placeholder="Type to search…"
345
+ * />
346
+ * </Field>
347
+ * ```
348
+ *
349
+ * @example Bare in a filter bar (no Field)
350
+ * ```tsx
351
+ * <Input
352
+ * value={search}
353
+ * onChange={(e) => setSearch(e.target.value)}
354
+ * placeholder="Search…"
355
+ * aria-label="Search products"
356
+ * />
357
+ * ```
358
+ */
256
359
  declare const Input: react.ForwardRefExoticComponent<InputProps & react.RefAttributes<HTMLInputElement>>;
257
360
 
258
361
  interface LanguageOption<TCode extends string = string> {
@@ -268,6 +371,221 @@ interface LanguageSwitcherProps<TCode extends string = string> extends Omit<Fiel
268
371
  }
269
372
  declare function LanguageSwitcher<TCode extends string = string>({ languages, value, onChange, ariaLabel, className, ...props }: LanguageSwitcherProps<TCode>): react_jsx_runtime.JSX.Element;
270
373
 
374
+ type RadioGroupSize = 'sm' | 'md' | 'lg';
375
+ /** Outer circle (radio button itself) — sized + bordered. */
376
+ declare const radioItemSizeClass: Record<RadioGroupSize, string>;
377
+ /** Inner indicator (the filled dot when selected). Centred via flex on the parent. */
378
+ declare const radioIndicatorSizeClass: Record<RadioGroupSize, string>;
379
+ /** Label text size that pairs naturally with each radio size. */
380
+ declare const radioLabelSizeClass: Record<RadioGroupSize, string>;
381
+ declare const radioItemBaseClass = "aspect-square shrink-0 rounded-full border border-input bg-background text-primary outline-none transition-colors focus-visible:ring-2 focus-visible:ring-ring/40 focus-visible:ring-offset-2 focus-visible:ring-offset-background hover:border-ring disabled:cursor-not-allowed disabled:opacity-50 aria-[invalid=true]:border-destructive aria-[invalid=true]:focus-visible:ring-destructive/40 data-[state=checked]:border-primary";
382
+ declare const radioIndicatorBaseClass = "flex h-full w-full items-center justify-center";
383
+ declare const radioIndicatorDotClass = "rounded-full bg-primary";
384
+ /** Each option row: radio + label + optional description. */
385
+ declare const radioOptionRowClass = "flex cursor-pointer items-start gap-2 has-[button:disabled]:cursor-not-allowed";
386
+ /** The group container — vertical stack by default, horizontal row when orientation="horizontal". */
387
+ declare const radioGroupBaseClass = "flex gap-3";
388
+ declare const radioGroupOrientationClass: {
389
+ readonly vertical: "flex-col";
390
+ readonly horizontal: "flex-row flex-wrap";
391
+ };
392
+
393
+ interface RadioGroupOption {
394
+ value: string;
395
+ /** Visible label rendered next to the radio button. */
396
+ label: ReactNode;
397
+ /** Optional secondary text rendered below the label (e.g. plan description). */
398
+ description?: ReactNode;
399
+ disabled?: boolean;
400
+ }
401
+ type RadioGroupOrientation = 'vertical' | 'horizontal';
402
+ interface RadioGroupProps {
403
+ /** Visual size of each radio + label. */
404
+ radioSize?: RadioGroupSize;
405
+ /** Layout direction within the group. `'vertical'` (default) stacks options; `'horizontal'` lays them out in a row. */
406
+ orientation?: RadioGroupOrientation;
407
+ /** Controlled selected value (Radix-style). */
408
+ value?: string;
409
+ /** Initial selected value for uncontrolled usage. */
410
+ defaultValue?: string;
411
+ /** Radix-style change handler — receives the new value directly. */
412
+ onValueChange?: (value: string) => void;
413
+ /** Synthetic-event handler for `react-hook-form`'s `field.onChange` and other consumers. */
414
+ onChange?: (event: ChangeEvent<HTMLInputElement>) => void;
415
+ /** Called when focus leaves the group. */
416
+ onBlur?: () => void;
417
+ /** Form name (for native form submission). */
418
+ name?: string;
419
+ /** Disables the entire group. */
420
+ disabled?: boolean;
421
+ /** Marks the group as required. */
422
+ required?: boolean;
423
+ /** Override id (otherwise auto-generated via useId). */
424
+ id?: string;
425
+ /** Declarative options. When `children` is provided it wins (escape hatch for custom content). */
426
+ options?: RadioGroupOption[];
427
+ /** Class on the outer group container. */
428
+ className?: string;
429
+ 'aria-label'?: string;
430
+ 'aria-labelledby'?: string;
431
+ 'aria-describedby'?: string;
432
+ 'aria-invalid'?: boolean | 'true' | 'false';
433
+ /** Radix children — used for advanced composition (custom RadioGroupItem layouts). */
434
+ children?: ReactNode;
435
+ }
436
+ /**
437
+ * Group of mutually-exclusive radio buttons built on `@radix-ui/react-radio-group`.
438
+ * Use for **3–5 options** where Select would be overkill (pricing tier, privacy
439
+ * level, single-choice settings). Bare component — wrap in `<Field label="…">`
440
+ * for the GROUP label, helper, and error rendering.
441
+ *
442
+ * Each option carries its own per-radio `label` (and optional `description`).
443
+ * The Field's outer label names the group; the option labels name each choice.
444
+ *
445
+ * @example Inside a Field (RHF + Zod)
446
+ * ```tsx
447
+ * <Field name="plan" label="Subscription plan" description="You can change anytime.">
448
+ * <RadioGroup
449
+ * options={[
450
+ * { value: 'free', label: 'Free', description: 'Up to 3 projects' },
451
+ * { value: 'pro', label: 'Pro', description: 'Unlimited projects' },
452
+ * { value: 'enterprise', label: 'Enterprise', description: 'Custom limits' },
453
+ * ]}
454
+ * />
455
+ * </Field>
456
+ * ```
457
+ *
458
+ * @example Horizontal row in a settings card
459
+ * ```tsx
460
+ * <Field label="Visibility" orientation="horizontal">
461
+ * <RadioGroup
462
+ * orientation="horizontal"
463
+ * value={visibility}
464
+ * onValueChange={setVisibility}
465
+ * options={[
466
+ * { value: 'public', label: 'Public' },
467
+ * { value: 'private', label: 'Private' },
468
+ * ]}
469
+ * />
470
+ * </Field>
471
+ * ```
472
+ */
473
+ declare const RadioGroup: react.ForwardRefExoticComponent<RadioGroupProps & react.RefAttributes<HTMLDivElement>>;
474
+ /**
475
+ * `<RadioGroupItem>` — re-exported for consumers building custom option layouts
476
+ * (icons, badges, etc.) via the `children` escape hatch.
477
+ *
478
+ * @example
479
+ * ```tsx
480
+ * <RadioGroup value={plan} onValueChange={setPlan}>
481
+ * {plans.map((p) => (
482
+ * <label key={p.value} htmlFor={p.value} className="flex items-center gap-2">
483
+ * <RadioGroupItem id={p.value} value={p.value} />
484
+ * <PlanCard {...p} />
485
+ * </label>
486
+ * ))}
487
+ * </RadioGroup>
488
+ * ```
489
+ */
490
+ declare const RadioGroupItem: react.ForwardRefExoticComponent<Omit<RadixRadioGroup.RadioGroupItemProps & react.RefAttributes<HTMLButtonElement>, "ref"> & {
491
+ radioSize?: RadioGroupSize;
492
+ } & react.RefAttributes<HTMLButtonElement>>;
493
+
494
+ type SelectVariant = 'default' | 'filled' | 'ghost';
495
+ type SelectSize = 'sm' | 'md' | 'lg';
496
+ declare const selectVariantClass: Record<SelectVariant, string>;
497
+ /**
498
+ * `pe-*` is wider than `ps-*` to leave room for the chevron icon. Logical
499
+ * properties keep RTL working free.
500
+ */
501
+ declare const selectSizeClass: Record<SelectSize, string>;
502
+ declare const selectBaseClass = "group/select relative inline-flex w-full items-center text-foreground outline-none transition-[background-color,border-color,box-shadow] focus:ring-2 focus:ring-ring/40 focus:ring-offset-1 focus:ring-offset-background aria-[invalid=true]:border-destructive aria-[invalid=true]:focus:ring-destructive/40 disabled:pointer-events-none disabled:opacity-50 cursor-pointer data-[placeholder]:text-muted-foreground";
503
+
504
+ interface SelectOption {
505
+ value: string;
506
+ label: string;
507
+ disabled?: boolean;
508
+ }
509
+ interface SelectGroup {
510
+ label: string;
511
+ options: SelectOption[];
512
+ }
513
+ /**
514
+ * `options` accepts either a flat list of options OR a list of groups.
515
+ * Use `children` for full Radix composition (Select.Item, Select.Separator…).
516
+ */
517
+ type SelectOptions = SelectOption[] | SelectGroup[];
518
+ interface SelectProps {
519
+ variant?: SelectVariant;
520
+ /** Visual size. Named `selectSize` to mirror Input's `inputSize`. */
521
+ selectSize?: SelectSize;
522
+ /** Declarative options (flat or grouped). When `children` is provided it wins. */
523
+ options?: SelectOptions;
524
+ /** Placeholder shown when no value is selected. */
525
+ placeholder?: string;
526
+ /** Controlled value. */
527
+ value?: string;
528
+ /** Initial value for uncontrolled usage. */
529
+ defaultValue?: string;
530
+ /** Radix-style change handler — receives the new value directly. */
531
+ onValueChange?: (value: string) => void;
532
+ /**
533
+ * Synthetic-event handler for compatibility with `react-hook-form`'s
534
+ * `field.onChange` and other consumers that expect a `ChangeEvent`-shaped
535
+ * object. Both this and `onValueChange` fire on selection.
536
+ */
537
+ onChange?: (event: ChangeEvent<HTMLSelectElement>) => void;
538
+ /** Called when focus leaves the trigger. */
539
+ onBlur?: () => void;
540
+ /** Form name (for native form submission). */
541
+ name?: string;
542
+ /** Disables the trigger. */
543
+ disabled?: boolean;
544
+ /** Marks the underlying form input as required. */
545
+ required?: boolean;
546
+ /** Override id (otherwise auto-generated via useId). */
547
+ id?: string;
548
+ /** Class applied to the trigger button. */
549
+ className?: string;
550
+ 'aria-invalid'?: boolean | 'true' | 'false';
551
+ 'aria-describedby'?: string;
552
+ 'aria-label'?: string;
553
+ /** Radix children — used for advanced composition (Select.Group, etc.). */
554
+ children?: ReactNode;
555
+ }
556
+ /**
557
+ * Dropdown select built on `@radix-ui/react-select`. Renders only the trigger
558
+ * button + Radix popup — wrap it in `<Field label="…">` to add a label, helper
559
+ * text, error, and aria wiring.
560
+ *
561
+ * @example Inside a Field (RHF + Zod)
562
+ * ```tsx
563
+ * <Field name="country" label="Country" required>
564
+ * <Select options={COUNTRIES} placeholder="Pick one" />
565
+ * </Field>
566
+ * ```
567
+ *
568
+ * @example Bare in a filter bar (no label)
569
+ * ```tsx
570
+ * <Select
571
+ * value={status}
572
+ * onValueChange={setStatus}
573
+ * options={STATUS_OPTIONS}
574
+ * placeholder="Status"
575
+ * aria-label="Status filter"
576
+ * />
577
+ * ```
578
+ *
579
+ * @example Grouped options
580
+ * ```tsx
581
+ * <Select options={[
582
+ * { label: 'GCC', options: [{ value: 'sa', label: 'Saudi Arabia' }] },
583
+ * { label: 'Levant', options: [{ value: 'jo', label: 'Jordan' }] },
584
+ * ]} />
585
+ * ```
586
+ */
587
+ declare const Select: react.ForwardRefExoticComponent<SelectProps & react.RefAttributes<HTMLButtonElement>>;
588
+
271
589
  type SidebarProps = HTMLAttributes<HTMLElement>;
272
590
  declare function Sidebar({ className, children, ...props }: SidebarProps): react_jsx_runtime.JSX.Element;
273
591
 
@@ -320,6 +638,82 @@ interface SidebarNavItemProps extends AnchorHTMLAttributes<HTMLAnchorElement> {
320
638
  }
321
639
  declare function SidebarNavItem({ icon, active, label, endSlot, className, children, render, ...props }: SidebarNavItemProps): react_jsx_runtime.JSX.Element;
322
640
 
641
+ type SwitchSize = 'sm' | 'md' | 'lg';
642
+ /**
643
+ * Each size is a tuple: track dimensions + thumb size + thumb travel distance.
644
+ * Track is `w` x `h`; thumb is `w/h size-X`; travel is the translation distance
645
+ * when checked (= track width − thumb size − padding).
646
+ */
647
+ declare const switchTrackClass: Record<SwitchSize, string>;
648
+ declare const switchThumbClass: Record<SwitchSize, string>;
649
+ declare const switchTrackBaseClass = "relative inline-flex shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent bg-input transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/40 focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary aria-[invalid=true]:ring-2 aria-[invalid=true]:ring-destructive/40";
650
+ declare const switchThumbBaseClass = "pointer-events-none block rounded-full bg-background shadow-sm ring-0 transition-transform";
651
+
652
+ interface SwitchProps {
653
+ /** Visual size. */
654
+ switchSize?: SwitchSize;
655
+ /** Controlled checked state (Radix-style). */
656
+ checked?: boolean;
657
+ /** Initial checked state for uncontrolled usage. */
658
+ defaultChecked?: boolean;
659
+ /** Radix-style change handler — receives the new boolean directly. */
660
+ onCheckedChange?: (checked: boolean) => void;
661
+ /**
662
+ * Form-library compatibility props. `value` mirrors what `<Field>` injects
663
+ * (RHF passes `field.value` as a boolean). `onChange` fires alongside
664
+ * `onCheckedChange` with a synthetic event so `field.onChange` works too.
665
+ */
666
+ value?: boolean | string | number;
667
+ onChange?: (event: ChangeEvent<HTMLButtonElement>) => void;
668
+ onBlur?: () => void;
669
+ /** Form name for native form submission. */
670
+ name?: string;
671
+ /** Disable interaction. */
672
+ disabled?: boolean;
673
+ /** Mark required for form validation. */
674
+ required?: boolean;
675
+ /** Override id (otherwise auto-generated via useId). */
676
+ id?: string;
677
+ /** Class on the track (the switch itself). */
678
+ className?: string;
679
+ 'aria-label'?: string;
680
+ 'aria-describedby'?: string;
681
+ 'aria-invalid'?: boolean | 'true' | 'false';
682
+ }
683
+ /**
684
+ * Boolean toggle built on `@radix-ui/react-switch`. Renders only the track +
685
+ * thumb — wrap it in `<Field orientation="horizontal" label="…">` to add a
686
+ * label, helper text, error, and aria wiring without duplicating that logic
687
+ * inside every form control.
688
+ *
689
+ * @example Inside a Field (RHF + Zod)
690
+ * ```tsx
691
+ * <Field name="darkMode" label="Dark mode" orientation="horizontal">
692
+ * <Switch />
693
+ * </Field>
694
+ * ```
695
+ *
696
+ * @example Bare in a settings list (custom layout)
697
+ * ```tsx
698
+ * <ul className="divide-y divide-border">
699
+ * <li className="flex items-center justify-between py-3">
700
+ * <span>Email digest</span>
701
+ * <Switch checked={digest} onCheckedChange={setDigest} aria-label="Email digest" />
702
+ * </li>
703
+ * </ul>
704
+ * ```
705
+ *
706
+ * @example Standalone controlled
707
+ * ```tsx
708
+ * <Switch
709
+ * checked={enabled}
710
+ * onCheckedChange={setEnabled}
711
+ * aria-label="Enable notifications"
712
+ * />
713
+ * ```
714
+ */
715
+ declare const Switch: react.ForwardRefExoticComponent<SwitchProps & react.RefAttributes<HTMLButtonElement>>;
716
+
323
717
  type TableSize = 'sm' | 'md' | 'lg';
324
718
  interface TableSizeClasses {
325
719
  /** Applied to <tr> when needed (currently empty — present for symmetry). */
@@ -444,19 +838,29 @@ interface TextareaProps extends Omit<TextareaHTMLAttributes<HTMLTextAreaElement>
444
838
  textareaSize?: TextareaSize;
445
839
  /** Controls the native CSS `resize` behaviour. Defaults to `'vertical'`. */
446
840
  resize?: TextareaResize;
447
- /** Optional label rendered above the field. */
448
- label?: ReactNode;
449
- /** Helper text rendered under the field when not in an error state. */
450
- helperText?: ReactNode;
451
- /** Error message — renders in destructive style and sets aria-invalid. */
452
- error?: ReactNode;
453
- /** Stretch the wrapper to fill the parent's inline width. Defaults to `true`. */
454
- fullWidth?: boolean;
455
841
  /** Class applied to the outer wrapper that frames the textarea. */
456
842
  wrapperClassName?: string;
457
- /** Class applied to the field container (`<label>` block). */
458
- containerClassName?: string;
459
843
  }
844
+ /**
845
+ * Bare multi-line text input — renders the wrapper + native `<textarea>`. **No
846
+ * label/helperText/error props by design** (per ADR-007: Field owns all form
847
+ * layout). Wrap in `<Field label="…">` for label, helper, error rendering and
848
+ * full a11y wiring.
849
+ *
850
+ * @example Inside a Field (RHF + Zod)
851
+ * ```tsx
852
+ * <Field name="bio" label="Bio" description="Up to 280 characters.">
853
+ * <Textarea rows={4} />
854
+ * </Field>
855
+ * ```
856
+ *
857
+ * @example Custom resize behaviour
858
+ * ```tsx
859
+ * <Field label="Notes">
860
+ * <Textarea resize="none" rows={6} />
861
+ * </Field>
862
+ * ```
863
+ */
460
864
  declare const Textarea: react.ForwardRefExoticComponent<TextareaProps & react.RefAttributes<HTMLTextAreaElement>>;
461
865
 
462
866
  type Direction = 'ltr' | 'rtl';
@@ -464,4 +868,4 @@ declare function useDirection(): Direction;
464
868
 
465
869
  declare function cn(...inputs: ClassValue[]): string;
466
870
 
467
- export { AppShell, type AppShellBrand, type AppShellNavGroup, type AppShellNavItem, type AppShellProps, Avatar, type AvatarProps, Button, type ButtonProps, type ButtonSize, type ButtonVariant, Checkbox, type CheckboxProps, type CheckboxSize, type Column, type ColumnAlign, DashboardContent, type DashboardContentProps, DashboardHeader, type DashboardHeaderProps, DashboardLayout, type DashboardLayoutContextValue, type DashboardLayoutProps, DashboardMain, type DashboardMainProps, type Direction, Field, type FieldProps, type FieldRHFProps, HeaderActions, type HeaderActionsProps, HeaderCollapseTrigger, type HeaderCollapseTriggerProps, HeaderMobileTrigger, type HeaderMobileTriggerProps, HeaderSearch, type HeaderSearchProps, HeaderTitle, type HeaderTitleProps, Input, type InputProps, type InputSize, type InputVariant, type LanguageOption, LanguageSwitcher, type LanguageSwitcherProps, type PaginationState, type RowSelectionState, Sidebar, SidebarFooter, type SidebarFooterProps, SidebarGroup, type SidebarGroupProps, SidebarHeader, type SidebarHeaderProps, SidebarNav, SidebarNavGroup, type SidebarNavGroupProps, SidebarNavItem, type SidebarNavItemProps, type SidebarNavItemRenderProps, type SidebarNavProps, type SidebarProps, type SortDirection, type SortState, type SortableValue, Table, type TableProps, type TableSize, type TableSizeClasses, Textarea, type TextareaProps, type TextareaResize, type TextareaSize, type TextareaVariant, buttonBaseClass, buttonSizeClass, buttonVariantClass, cn, inputBaseClass, inputSizeClass, inputVariantClass, alignClass as tableAlignClass, tableBaseClass, selectedRowClass as tableSelectedRowClass, tableSizeClass, sortIconClass as tableSortIconClass, textareaBaseClass, textareaResizeClass, textareaSizeClass, textareaVariantClass, useDashboardLayout, useDirection };
871
+ export { AppShell, type AppShellBrand, type AppShellNavGroup, type AppShellNavItem, type AppShellProps, Avatar, type AvatarProps, Button, type ButtonProps, type ButtonSize, type ButtonVariant, Checkbox, type CheckboxProps, type CheckboxSize, type Column, type ColumnAlign, DashboardContent, type DashboardContentProps, DashboardHeader, type DashboardHeaderProps, DashboardLayout, type DashboardLayoutContextValue, type DashboardLayoutProps, DashboardMain, type DashboardMainProps, type Direction, Field, type FieldOrientation, type FieldProps, type FieldRHFProps, HeaderActions, type HeaderActionsProps, HeaderCollapseTrigger, type HeaderCollapseTriggerProps, HeaderMobileTrigger, type HeaderMobileTriggerProps, HeaderSearch, type HeaderSearchProps, HeaderTitle, type HeaderTitleProps, Input, type InputProps, type InputSize, type InputVariant, type LanguageOption, LanguageSwitcher, type LanguageSwitcherProps, type PaginationState, RadioGroup, RadioGroupItem, type RadioGroupOption, type RadioGroupOrientation, type RadioGroupProps, type RadioGroupSize, type RowSelectionState, Select, type SelectOption, type SelectProps, type SelectSize, type SelectVariant, Sidebar, SidebarFooter, type SidebarFooterProps, SidebarGroup, type SidebarGroupProps, SidebarHeader, type SidebarHeaderProps, SidebarNav, SidebarNavGroup, type SidebarNavGroupProps, SidebarNavItem, type SidebarNavItemProps, type SidebarNavItemRenderProps, type SidebarNavProps, type SidebarProps, type SortDirection, type SortState, type SortableValue, Switch, type SwitchProps, type SwitchSize, Table, type TableProps, type TableSize, type TableSizeClasses, Textarea, type TextareaProps, type TextareaResize, type TextareaSize, type TextareaVariant, buttonBaseClass, buttonSizeClass, buttonVariantClass, cn, inputBaseClass, inputSizeClass, inputVariantClass, radioGroupBaseClass, radioGroupOrientationClass, radioIndicatorBaseClass, radioIndicatorDotClass, radioIndicatorSizeClass, radioItemBaseClass, radioItemSizeClass, radioLabelSizeClass, radioOptionRowClass, selectBaseClass, selectSizeClass, selectVariantClass, switchThumbBaseClass, switchThumbClass, switchTrackBaseClass, switchTrackClass, alignClass as tableAlignClass, tableBaseClass, selectedRowClass as tableSelectedRowClass, tableSizeClass, sortIconClass as tableSortIconClass, textareaBaseClass, textareaResizeClass, textareaSizeClass, textareaVariantClass, useDashboardLayout, useDirection };