@calliopelabs/ui 0.7.0 → 0.11.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.
Files changed (120) hide show
  1. package/README.md +253 -3
  2. package/dist/appearance/AppearancePicker.js +4 -2
  3. package/dist/appearance/AppearanceProvider.d.ts +10 -2
  4. package/dist/appearance/AppearanceProvider.js +6 -2
  5. package/dist/appearance/AppearanceScript.d.ts +15 -4
  6. package/dist/appearance/AppearanceScript.js +11 -5
  7. package/dist/appearance/appearance.js +1 -1
  8. package/dist/appearance/boot.d.ts +13 -2
  9. package/dist/appearance/boot.js +35 -5
  10. package/dist/appearance/product.d.ts +13 -0
  11. package/dist/appearance/product.js +2 -2
  12. package/dist/appearance/runtime-brand.d.ts +106 -0
  13. package/dist/appearance/runtime-brand.js +420 -0
  14. package/dist/css/appearance.js +147 -0
  15. package/dist/css/calliope.css +1221 -0
  16. package/dist/css/components.css +729 -0
  17. package/dist/css/tokens.css +491 -0
  18. package/dist/data/DefinitionList.d.ts +16 -0
  19. package/dist/data/DefinitionList.js +9 -0
  20. package/dist/data/Stat.d.ts +25 -0
  21. package/dist/data/Stat.js +19 -0
  22. package/dist/data/Tag.d.ts +21 -0
  23. package/dist/data/Tag.js +18 -0
  24. package/dist/data/types.d.ts +3 -2
  25. package/dist/data/use-local-table.d.ts +36 -0
  26. package/dist/data/use-local-table.js +127 -0
  27. package/dist/index.d.ts +42 -3
  28. package/dist/index.js +39 -1
  29. package/dist/nav/Nav.d.ts +2 -1
  30. package/dist/nav/Nav.js +34 -15
  31. package/dist/nav/model.d.ts +21 -0
  32. package/dist/page/PageHeader.d.ts +5 -3
  33. package/dist/page/PageHeader.js +5 -4
  34. package/dist/page/Panel.d.ts +19 -0
  35. package/dist/page/Panel.js +12 -0
  36. package/dist/primitives/Avatar.d.ts +37 -0
  37. package/dist/primitives/Avatar.js +43 -0
  38. package/dist/primitives/Field.d.ts +33 -0
  39. package/dist/primitives/Field.js +30 -0
  40. package/dist/primitives/Segmented.d.ts +30 -0
  41. package/dist/primitives/Segmented.js +20 -0
  42. package/dist/primitives/Select.d.ts +40 -0
  43. package/dist/primitives/Select.js +47 -0
  44. package/dist/primitives/Switch.d.ts +7 -0
  45. package/dist/primitives/Switch.js +8 -0
  46. package/dist/primitives/Textarea.d.ts +3 -0
  47. package/dist/primitives/Textarea.js +6 -0
  48. package/dist/provider/messages.d.ts +412 -0
  49. package/dist/provider/messages.js +633 -0
  50. package/dist/shell/BrandMark.d.ts +25 -3
  51. package/dist/shell/BrandMark.js +34 -4
  52. package/dist/shell/RailPanel.js +2 -2
  53. package/dist/shell/RailTree.js +2 -2
  54. package/dist/shell/Sidebar.d.ts +9 -2
  55. package/dist/shell/Sidebar.js +10 -4
  56. package/dist/shell/UserMenu.d.ts +3 -1
  57. package/dist/shell/UserMenu.js +3 -11
  58. package/dist/shell/rail-boot.d.ts +28 -0
  59. package/dist/shell/rail-boot.js +45 -0
  60. package/dist/shell/rail-state.d.ts +6 -1
  61. package/dist/shell/rail-state.js +18 -2
  62. package/dist/styles/preset.css +4 -0
  63. package/dist/styles/theme.css +36 -13
  64. package/dist/theme/css-layer.d.ts +19 -0
  65. package/dist/theme/css-layer.js +171 -0
  66. package/dist/theme/css.d.ts +1 -0
  67. package/dist/theme/css.js +45 -9
  68. package/dist/workflow/ArtifactCard.d.ts +47 -0
  69. package/dist/workflow/ArtifactCard.js +45 -0
  70. package/dist/workflow/DocumentReview.d.ts +74 -0
  71. package/dist/workflow/DocumentReview.js +54 -0
  72. package/dist/workflow/FormReview.d.ts +53 -0
  73. package/dist/workflow/FormReview.js +83 -0
  74. package/dist/workflow/GateBadge.d.ts +11 -0
  75. package/dist/workflow/GateBadge.js +14 -0
  76. package/dist/workflow/MediaReview.d.ts +63 -0
  77. package/dist/workflow/MediaReview.js +166 -0
  78. package/dist/workflow/ReviewPanel.d.ts +41 -0
  79. package/dist/workflow/ReviewPanel.js +59 -0
  80. package/dist/workflow/RunTimeline.d.ts +25 -0
  81. package/dist/workflow/RunTimeline.js +56 -0
  82. package/dist/workflow/WorkflowCard.d.ts +39 -0
  83. package/dist/workflow/WorkflowCard.js +56 -0
  84. package/dist/workflow/WorkflowGallery.d.ts +43 -0
  85. package/dist/workflow/WorkflowGallery.js +69 -0
  86. package/dist/workflow/canvas/WorkflowCanvas.d.ts +39 -0
  87. package/dist/workflow/canvas/WorkflowCanvas.js +648 -0
  88. package/dist/workflow/definition.d.ts +408 -0
  89. package/dist/workflow/definition.js +411 -0
  90. package/dist/workflow/editor/WorkflowDiff.d.ts +17 -0
  91. package/dist/workflow/editor/WorkflowDiff.js +25 -0
  92. package/dist/workflow/editor/WorkflowImportPreview.d.ts +19 -0
  93. package/dist/workflow/editor/WorkflowImportPreview.js +50 -0
  94. package/dist/workflow/editor/WorkflowInspector.d.ts +40 -0
  95. package/dist/workflow/editor/WorkflowInspector.js +349 -0
  96. package/dist/workflow/editor/WorkflowJsonView.d.ts +16 -0
  97. package/dist/workflow/editor/WorkflowJsonView.js +40 -0
  98. package/dist/workflow/editor/WorkflowPalette.d.ts +16 -0
  99. package/dist/workflow/editor/WorkflowPalette.js +36 -0
  100. package/dist/workflow/editor/WorkflowProblems.d.ts +20 -0
  101. package/dist/workflow/editor/WorkflowProblems.js +51 -0
  102. package/dist/workflow/editor/WorkflowWorkspace.d.ts +49 -0
  103. package/dist/workflow/editor/WorkflowWorkspace.js +154 -0
  104. package/dist/workflow/gallery.d.ts +21 -0
  105. package/dist/workflow/gallery.js +29 -0
  106. package/dist/workflow/layout.d.ts +49 -0
  107. package/dist/workflow/layout.js +162 -0
  108. package/dist/workflow/model.d.ts +50 -0
  109. package/dist/workflow/model.js +7 -0
  110. package/dist/workflow/palette.d.ts +34 -0
  111. package/dist/workflow/palette.js +70 -0
  112. package/dist/workflow/portable.d.ts +162 -0
  113. package/dist/workflow/portable.js +547 -0
  114. package/dist/workflow/problems.d.ts +38 -0
  115. package/dist/workflow/problems.js +409 -0
  116. package/dist/workflow/run.d.ts +94 -0
  117. package/dist/workflow/run.js +31 -0
  118. package/dist/workflow/workspace.d.ts +33 -0
  119. package/dist/workflow/workspace.js +17 -0
  120. package/package.json +6 -1
@@ -0,0 +1,33 @@
1
+ import * as React from "react";
2
+ /** The props a Field hands its control. Input, Textarea, Select, Switch and Checkbox all take them. */
3
+ export interface FieldControlProps {
4
+ id?: string;
5
+ "aria-describedby"?: string;
6
+ "aria-invalid"?: boolean;
7
+ required?: boolean;
8
+ }
9
+ export interface FieldProps {
10
+ label: React.ReactNode;
11
+ /** Under the label: what the value means or how it is used. */
12
+ hint?: React.ReactNode;
13
+ /** Why the value is refused. Marks the control invalid and is read with it. */
14
+ error?: React.ReactNode;
15
+ required?: boolean;
16
+ /** The control's id; generated when absent. */
17
+ id?: string;
18
+ /**
19
+ * `vertical` (the default): label, hint, control, error. `horizontal`: the
20
+ * label and hint beside the control, for a Switch or a Checkbox.
21
+ */
22
+ orientation?: "vertical" | "horizontal";
23
+ /** The control. It receives the id, the description, the invalid state and `required`. */
24
+ children: React.ReactElement<FieldControlProps>;
25
+ className?: string;
26
+ }
27
+ /**
28
+ * A labelled form control with its hint and error, wired for screen readers:
29
+ * the label's `for` is the control's id, the hint and error are its
30
+ * description (`aria-describedby`), and an error sets `aria-invalid`. A
31
+ * description the control already has is kept.
32
+ */
33
+ export declare function Field({ label, hint, error, required, id: idProp, orientation, children, className, }: FieldProps): React.JSX.Element;
@@ -0,0 +1,30 @@
1
+ "use client";
2
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
3
+ import * as React from "react";
4
+ import { cn } from "../lib/cn.js";
5
+ /**
6
+ * A labelled form control with its hint and error, wired for screen readers:
7
+ * the label's `for` is the control's id, the hint and error are its
8
+ * description (`aria-describedby`), and an error sets `aria-invalid`. A
9
+ * description the control already has is kept.
10
+ */
11
+ export function Field({ label, hint, error, required, id: idProp, orientation = "vertical", children, className, }) {
12
+ const generated = React.useId();
13
+ const id = idProp ?? children.props.id ?? generated;
14
+ const hintId = hint ? `${id}-hint` : undefined;
15
+ const errorId = error ? `${id}-error` : undefined;
16
+ const describedBy = [children.props["aria-describedby"], hintId, errorId].filter(Boolean).join(" ") || undefined;
17
+ const control = React.cloneElement(children, {
18
+ id,
19
+ "aria-describedby": describedBy,
20
+ "aria-invalid": error ? true : children.props["aria-invalid"],
21
+ required: required ?? children.props.required,
22
+ });
23
+ const labelEl = (_jsxs("label", { htmlFor: id, className: "text-sm leading-snug font-medium", children: [label, required && (_jsxs("span", { "aria-hidden": true, className: "text-muted-foreground", children: [" ", "*"] }))] }));
24
+ const hintEl = hint && (_jsx("p", { id: hintId, className: "text-xs text-muted-foreground", children: hint }));
25
+ const errorEl = error && (_jsx("p", { id: errorId, className: "text-xs text-danger-fg", children: error }));
26
+ if (orientation === "horizontal") {
27
+ return (_jsxs("div", { "data-slot": "field", className: cn("flex min-w-0 flex-col gap-1.5", className), children: [_jsxs("div", { className: "flex min-w-0 items-start justify-between gap-3", children: [_jsxs("div", { className: "flex min-w-0 flex-col gap-0.5", children: [labelEl, hintEl] }), control] }), errorEl] }));
28
+ }
29
+ return (_jsxs("div", { "data-slot": "field", className: cn("flex min-w-0 flex-col gap-1.5", className), children: [labelEl, hintEl, control, errorEl] }));
30
+ }
@@ -0,0 +1,30 @@
1
+ import type * as React from "react";
2
+ export interface SegmentedOption<TValue extends string = string> {
3
+ value: TValue;
4
+ label: string;
5
+ /** An icon before the label; with `iconOnly`, the label becomes its accessible name. */
6
+ icon?: React.ComponentType<{
7
+ className?: string;
8
+ "aria-hidden"?: boolean;
9
+ }>;
10
+ disabled?: boolean;
11
+ }
12
+ export interface SegmentedProps<TValue extends string = string> {
13
+ /** Names the group ("View", "Range"). */
14
+ label: string;
15
+ options: readonly SegmentedOption<TValue>[];
16
+ value: TValue;
17
+ onValueChange: (value: TValue) => void;
18
+ size?: "sm" | "default";
19
+ /** Icons alone, each named by its label. */
20
+ iconOnly?: boolean;
21
+ disabled?: boolean;
22
+ className?: string;
23
+ }
24
+ /**
25
+ * One of a few mutually exclusive options, side by side: a view (list or
26
+ * grid), a range (24h, 7d, 30d), a mode. Always one chosen; pressing the
27
+ * chosen one leaves it chosen. Arrow keys move between options. For views
28
+ * that are pages of their own, use TabNav (links) instead.
29
+ */
30
+ export declare function Segmented<TValue extends string = string>({ label, options, value, onValueChange, size, iconOnly, disabled, className, }: SegmentedProps<TValue>): React.JSX.Element;
@@ -0,0 +1,20 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { ToggleGroup as ToggleGroupPrimitive } from "radix-ui";
4
+ import { cn } from "../lib/cn.js";
5
+ /**
6
+ * One of a few mutually exclusive options, side by side: a view (list or
7
+ * grid), a range (24h, 7d, 30d), a mode. Always one chosen; pressing the
8
+ * chosen one leaves it chosen. Arrow keys move between options. For views
9
+ * that are pages of their own, use TabNav (links) instead.
10
+ */
11
+ export function Segmented({ label, options, value, onValueChange, size = "default", iconOnly = false, disabled, className, }) {
12
+ return (_jsx(ToggleGroupPrimitive.Root, { type: "single", "aria-label": label, value: value, disabled: disabled, onValueChange: (next) => {
13
+ // Radix clears a single group when the chosen item is pressed again; keep it chosen.
14
+ if (next)
15
+ onValueChange(next);
16
+ }, "data-slot": "segmented", "data-size": size, className: cn("inline-flex w-fit max-w-full items-center gap-0.5 rounded-lg border bg-muted/40 p-0.5", className), children: options.map((option) => {
17
+ const Icon = option.icon;
18
+ return (_jsxs(ToggleGroupPrimitive.Item, { value: option.value, disabled: option.disabled, "aria-label": iconOnly ? option.label : undefined, title: iconOnly ? option.label : undefined, className: cn("inline-flex min-w-0 items-center justify-center gap-1.5 rounded-md text-sm whitespace-nowrap text-muted-foreground transition-colors outline-none hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-background data-[state=on]:font-medium data-[state=on]:text-foreground data-[state=on]:shadow-xs", size === "sm" ? "h-6 px-2" : "h-7 px-2.5", iconOnly && (size === "sm" ? "w-6 px-0" : "w-7 px-0")), children: [Icon && _jsx(Icon, { className: "size-4 shrink-0", "aria-hidden": true }), !iconOnly && _jsx("span", { className: "truncate", children: option.label })] }, option.value));
19
+ }) }));
20
+ }
@@ -0,0 +1,40 @@
1
+ import { Select as SelectPrimitive } from "radix-ui";
2
+ import * as React from "react";
3
+ export interface SelectOption {
4
+ value: string;
5
+ label: string;
6
+ disabled?: boolean;
7
+ }
8
+ /** What a Field hands its control, passed on to the trigger (the element that takes focus and the label). */
9
+ type TriggerWiring = Pick<React.ComponentProps<"button">, "id" | "aria-describedby" | "aria-invalid" | "aria-label" | "aria-labelledby">;
10
+ export interface SelectProps extends React.ComponentProps<typeof SelectPrimitive.Root>, TriggerWiring {
11
+ /**
12
+ * The options, for the common case: the trigger, the value and the list are
13
+ * drawn for you. Leave it out to compose SelectTrigger, SelectContent and
14
+ * SelectItem yourself.
15
+ */
16
+ options?: readonly SelectOption[];
17
+ /** Shown in the trigger while nothing is chosen (with `options`). */
18
+ placeholder?: string;
19
+ /** The trigger's size (with `options`). */
20
+ size?: "sm" | "default";
21
+ /** Classes for the trigger (with `options`). */
22
+ className?: string;
23
+ }
24
+ /**
25
+ * A single choice from a list (Radix Select). Inside a Field, the field's
26
+ * id, description and invalid state reach the trigger, so the label names it.
27
+ * Radix does not allow an option whose value is the empty string: to offer
28
+ * "any", give it a value of its own.
29
+ */
30
+ export declare function Select({ options, placeholder, size, className, id, "aria-describedby": describedBy, "aria-invalid": invalid, "aria-label": label, "aria-labelledby": labelledBy, children, ...props }: SelectProps): React.JSX.Element;
31
+ export declare function SelectValue(props: React.ComponentProps<typeof SelectPrimitive.Value>): React.JSX.Element;
32
+ export declare function SelectTrigger({ className, size, children, ...props }: React.ComponentProps<typeof SelectPrimitive.Trigger> & {
33
+ size?: "sm" | "default";
34
+ }): React.JSX.Element;
35
+ export declare function SelectContent({ className, children, position, ...props }: React.ComponentProps<typeof SelectPrimitive.Content>): React.JSX.Element;
36
+ export declare function SelectItem({ className, children, ...props }: React.ComponentProps<typeof SelectPrimitive.Item>): React.JSX.Element;
37
+ export declare function SelectGroup(props: React.ComponentProps<typeof SelectPrimitive.Group>): React.JSX.Element;
38
+ export declare function SelectLabel({ className, ...props }: React.ComponentProps<typeof SelectPrimitive.Label>): React.JSX.Element;
39
+ export declare function SelectSeparator({ className, ...props }: React.ComponentProps<typeof SelectPrimitive.Separator>): React.JSX.Element;
40
+ export {};
@@ -0,0 +1,47 @@
1
+ "use client";
2
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { CheckIcon, ChevronDownIcon, ChevronUpIcon } from "lucide-react";
4
+ import { Select as SelectPrimitive } from "radix-ui";
5
+ import * as React from "react";
6
+ import { cn } from "../lib/cn.js";
7
+ const TriggerWiringContext = React.createContext({});
8
+ /**
9
+ * A single choice from a list (Radix Select). Inside a Field, the field's
10
+ * id, description and invalid state reach the trigger, so the label names it.
11
+ * Radix does not allow an option whose value is the empty string: to offer
12
+ * "any", give it a value of its own.
13
+ */
14
+ export function Select({ options, placeholder, size, className, id, "aria-describedby": describedBy, "aria-invalid": invalid, "aria-label": label, "aria-labelledby": labelledBy, children, ...props }) {
15
+ const wiring = React.useMemo(() => ({
16
+ id,
17
+ "aria-describedby": describedBy,
18
+ "aria-invalid": invalid,
19
+ "aria-label": label,
20
+ "aria-labelledby": labelledBy,
21
+ }), [id, describedBy, invalid, label, labelledBy]);
22
+ return (_jsx(TriggerWiringContext.Provider, { value: wiring, children: _jsx(SelectPrimitive.Root, { "data-slot": "select", ...props, children: options ? (_jsxs(_Fragment, { children: [_jsx(SelectTrigger, { size: size, className: className, children: _jsx(SelectValue, { placeholder: placeholder }) }), _jsx(SelectContent, { children: options.map((option) => (_jsx(SelectItem, { value: option.value, disabled: option.disabled, children: option.label }, option.value))) })] })) : (children) }) }));
23
+ }
24
+ export function SelectValue(props) {
25
+ return _jsx(SelectPrimitive.Value, { "data-slot": "select-value", ...props });
26
+ }
27
+ export function SelectTrigger({ className, size = "default", children, ...props }) {
28
+ const wiring = React.useContext(TriggerWiringContext);
29
+ const defined = Object.fromEntries(Object.entries(wiring).filter(([, v]) => v !== undefined));
30
+ return (_jsxs(SelectPrimitive.Trigger, { "data-slot": "select-trigger", "data-size": size, ...defined, ...props, className: cn("flex w-fit max-w-full min-w-0 items-center justify-between gap-1.5 rounded-lg border border-input bg-transparent py-1 pr-2 pl-2.5 text-sm whitespace-nowrap transition-colors outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-placeholder:text-muted-foreground data-[size=default]:h-8 data-[size=sm]:h-7 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-1.5 dark:bg-input/30 dark:hover:bg-input/50 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0", className), children: [children, _jsx(SelectPrimitive.Icon, { asChild: true, children: _jsx(ChevronDownIcon, { className: "size-4 text-muted-foreground", "aria-hidden": true }) })] }));
31
+ }
32
+ export function SelectContent({ className, children, position = "popper", ...props }) {
33
+ return (_jsx(SelectPrimitive.Portal, { children: _jsxs(SelectPrimitive.Content, { "data-slot": "select-content", position: position, className: cn("relative z-50 max-h-(--radix-select-content-available-height) min-w-36 origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-lg bg-popover text-popover-foreground shadow-md ring-1 ring-foreground/10", position === "popper" &&
34
+ "min-w-(--radix-select-trigger-width) data-[side=bottom]:translate-y-1 data-[side=top]:-translate-y-1", className), ...props, children: [_jsx(SelectPrimitive.ScrollUpButton, { className: "flex cursor-default items-center justify-center py-1", children: _jsx(ChevronUpIcon, { className: "size-4", "aria-hidden": true }) }), _jsx(SelectPrimitive.Viewport, { className: "p-1", children: children }), _jsx(SelectPrimitive.ScrollDownButton, { className: "flex cursor-default items-center justify-center py-1", children: _jsx(ChevronDownIcon, { className: "size-4", "aria-hidden": true }) })] }) }));
35
+ }
36
+ export function SelectItem({ className, children, ...props }) {
37
+ return (_jsxs(SelectPrimitive.Item, { "data-slot": "select-item", className: cn("relative flex w-full cursor-default items-center gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50", className), ...props, children: [_jsx("span", { className: "pointer-events-none absolute right-2 flex size-4 items-center justify-center", children: _jsx(SelectPrimitive.ItemIndicator, { children: _jsx(CheckIcon, { className: "size-4", "aria-hidden": true }) }) }), _jsx(SelectPrimitive.ItemText, { children: children })] }));
38
+ }
39
+ export function SelectGroup(props) {
40
+ return _jsx(SelectPrimitive.Group, { "data-slot": "select-group", ...props });
41
+ }
42
+ export function SelectLabel({ className, ...props }) {
43
+ return (_jsx(SelectPrimitive.Label, { "data-slot": "select-label", className: cn("px-1.5 py-1 text-xs text-muted-foreground", className), ...props }));
44
+ }
45
+ export function SelectSeparator({ className, ...props }) {
46
+ return (_jsx(SelectPrimitive.Separator, { "data-slot": "select-separator", className: cn("pointer-events-none -mx-1 my-1 h-px bg-border", className), ...props }));
47
+ }
@@ -0,0 +1,7 @@
1
+ import { Switch as SwitchPrimitive } from "radix-ui";
2
+ import type * as React from "react";
3
+ export interface SwitchProps extends React.ComponentProps<typeof SwitchPrimitive.Root> {
4
+ size?: "sm" | "default";
5
+ }
6
+ /** An on/off setting that applies at once. For a choice submitted with a form, prefer Checkbox. */
7
+ export declare function Switch({ className, size, ...props }: SwitchProps): React.JSX.Element;
@@ -0,0 +1,8 @@
1
+ "use client";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { Switch as SwitchPrimitive } from "radix-ui";
4
+ import { cn } from "../lib/cn.js";
5
+ /** An on/off setting that applies at once. For a choice submitted with a form, prefer Checkbox. */
6
+ export function Switch({ className, size = "default", ...props }) {
7
+ return (_jsx(SwitchPrimitive.Root, { "data-slot": "switch", "data-size": size, className: cn("peer inline-flex shrink-0 items-center rounded-full border border-transparent transition-colors outline-none focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-[size=default]:h-5 data-[size=default]:w-9 data-[size=sm]:h-4 data-[size=sm]:w-7 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input dark:data-[state=unchecked]:bg-input/80", className), ...props, children: _jsx(SwitchPrimitive.Thumb, { "data-slot": "switch-thumb", className: "pointer-events-none block rounded-full bg-background shadow-sm ring-0 transition-transform in-data-[size=default]:size-4 in-data-[size=sm]:size-3 in-data-[size=default]:data-[state=checked]:translate-x-4 in-data-[size=sm]:data-[state=checked]:translate-x-3 data-[state=unchecked]:translate-x-0.5 dark:data-[state=checked]:bg-primary-foreground dark:data-[state=unchecked]:bg-foreground" }) }));
8
+ }
@@ -0,0 +1,3 @@
1
+ import type * as React from "react";
2
+ /** Multi-line text, on the same tokens as Input; grows with its content where the browser can. */
3
+ export declare function Textarea({ className, ...props }: React.ComponentProps<"textarea">): React.JSX.Element;
@@ -0,0 +1,6 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { cn } from "../lib/cn.js";
3
+ /** Multi-line text, on the same tokens as Input; grows with its content where the browser can. */
4
+ export function Textarea({ className, ...props }) {
5
+ return (_jsx("textarea", { "data-slot": "textarea", className: cn("flex field-sizing-content min-h-16 w-full min-w-0 rounded-lg border border-input bg-transparent px-2.5 py-2 text-base transition-colors outline-none placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40", className), ...props }));
6
+ }