@hex-core/components 1.3.1 → 1.5.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/README.md +183 -9
- package/dist/_tsup-dts-rollup.d.ts +3105 -0
- package/dist/accordion.d.ts +4 -0
- package/dist/accordion.js +62 -0
- package/dist/accordion.js.map +1 -0
- package/dist/alert-dialog.d.ts +11 -0
- package/dist/alert-dialog.js +125 -0
- package/dist/alert-dialog.js.map +1 -0
- package/dist/alert.d.ts +4 -0
- package/dist/alert.js +54 -0
- package/dist/alert.js.map +1 -0
- package/dist/aspect-ratio.d.ts +1 -0
- package/dist/aspect-ratio.js +8 -0
- package/dist/aspect-ratio.js.map +1 -0
- package/dist/avatar.d.ts +3 -0
- package/dist/avatar.js +44 -0
- package/dist/avatar.js.map +1 -0
- package/dist/badge.d.ts +3 -0
- package/dist/badge.js +36 -0
- package/dist/badge.js.map +1 -0
- package/dist/breadcrumb.d.ts +7 -0
- package/dist/breadcrumb.js +120 -0
- package/dist/breadcrumb.js.map +1 -0
- package/dist/button.d.ts +3 -0
- package/dist/button.js +113 -0
- package/dist/button.js.map +1 -0
- package/dist/calendar.d.ts +1 -0
- package/dist/calendar.js +126 -0
- package/dist/calendar.js.map +1 -0
- package/dist/card.d.ts +6 -0
- package/dist/card.js +68 -0
- package/dist/card.js.map +1 -0
- package/dist/checkbox.d.ts +2 -0
- package/dist/checkbox.js +65 -0
- package/dist/checkbox.js.map +1 -0
- package/dist/citation.d.ts +2 -0
- package/dist/citation.js +70 -0
- package/dist/citation.js.map +1 -0
- package/dist/cluster.d.ts +3 -0
- package/dist/cluster.js +50 -0
- package/dist/cluster.js.map +1 -0
- package/dist/code-block-copy.d.ts +2 -0
- package/dist/code-block-copy.js +108 -0
- package/dist/code-block-copy.js.map +1 -0
- package/dist/code-block.d.ts +3 -0
- package/dist/code-block.js +90 -0
- package/dist/code-block.js.map +1 -0
- package/dist/collapsible.d.ts +3 -0
- package/dist/collapsible.js +10 -0
- package/dist/collapsible.js.map +1 -0
- package/dist/color-picker.d.ts +2 -0
- package/dist/color-picker.js +321 -0
- package/dist/color-picker.js.map +1 -0
- package/dist/combobox.d.ts +3 -0
- package/dist/combobox.js +226 -0
- package/dist/combobox.js.map +1 -0
- package/dist/command.d.ts +9 -0
- package/dist/command.js +232 -0
- package/dist/command.js.map +1 -0
- package/dist/composer.d.ts +2 -0
- package/dist/composer.js +75 -0
- package/dist/composer.js.map +1 -0
- package/dist/container.d.ts +3 -0
- package/dist/container.js +39 -0
- package/dist/container.js.map +1 -0
- package/dist/context-menu.d.ts +12 -0
- package/dist/context-menu.js +130 -0
- package/dist/context-menu.js.map +1 -0
- package/dist/data-table.d.ts +2 -0
- package/dist/data-table.js +103 -0
- package/dist/data-table.js.map +1 -0
- package/dist/date-picker.d.ts +2 -0
- package/dist/date-picker.js +221 -0
- package/dist/date-picker.js.map +1 -0
- package/dist/dialog.d.ts +11 -0
- package/dist/dialog.js +125 -0
- package/dist/dialog.js.map +1 -0
- package/dist/drawer.d.ts +10 -0
- package/dist/drawer.js +82 -0
- package/dist/drawer.js.map +1 -0
- package/dist/dropdown-menu.d.ts +13 -0
- package/dist/dropdown-menu.js +133 -0
- package/dist/dropdown-menu.js.map +1 -0
- package/dist/dropzone.d.ts +3 -0
- package/dist/dropzone.js +194 -0
- package/dist/dropzone.js.map +1 -0
- package/dist/file-tree.d.ts +3 -0
- package/dist/file-tree.js +322 -0
- package/dist/file-tree.js.map +1 -0
- package/dist/form.d.ts +8 -0
- package/dist/form.js +114 -0
- package/dist/form.js.map +1 -0
- package/dist/grid.d.ts +3 -0
- package/dist/grid.js +58 -0
- package/dist/grid.js.map +1 -0
- package/dist/hover-card.d.ts +3 -0
- package/dist/hover-card.js +34 -0
- package/dist/hover-card.js.map +1 -0
- package/dist/index.d.ts +298 -1652
- package/dist/index.js +1157 -5493
- package/dist/index.js.map +1 -1
- package/dist/input-otp.d.ts +5 -0
- package/dist/input-otp.js +71 -0
- package/dist/input-otp.js.map +1 -0
- package/dist/input.d.ts +2 -0
- package/dist/input.js +40 -0
- package/dist/input.js.map +1 -0
- package/dist/label.d.ts +2 -0
- package/dist/label.js +22 -0
- package/dist/label.js.map +1 -0
- package/dist/loading-indicator.d.ts +3 -0
- package/dist/loading-indicator.js +64 -0
- package/dist/loading-indicator.js.map +1 -0
- package/dist/markdown.d.ts +2 -0
- package/dist/markdown.js +28 -0
- package/dist/markdown.js.map +1 -0
- package/dist/menubar.d.ts +11 -0
- package/dist/menubar.js +106 -0
- package/dist/menubar.js.map +1 -0
- package/dist/message-actions.d.ts +2 -0
- package/dist/message-actions.js +28 -0
- package/dist/message-actions.js.map +1 -0
- package/dist/message-list.d.ts +2 -0
- package/dist/message-list.js +49 -0
- package/dist/message-list.js.map +1 -0
- package/dist/message.d.ts +3 -0
- package/dist/message.js +35 -0
- package/dist/message.js.map +1 -0
- package/dist/multi-combobox.d.ts +3 -0
- package/dist/multi-combobox.js +258 -0
- package/dist/multi-combobox.js.map +1 -0
- package/dist/navigation-menu.d.ts +9 -0
- package/dist/navigation-menu.js +108 -0
- package/dist/navigation-menu.js.map +1 -0
- package/dist/pagination.d.ts +7 -0
- package/dist/pagination.js +195 -0
- package/dist/pagination.js.map +1 -0
- package/dist/popover.d.ts +4 -0
- package/dist/popover.js +35 -0
- package/dist/popover.js.map +1 -0
- package/dist/progress.d.ts +1 -0
- package/dist/progress.js +38 -0
- package/dist/progress.js.map +1 -0
- package/dist/radio-group.d.ts +2 -0
- package/dist/radio-group.js +44 -0
- package/dist/radio-group.js.map +1 -0
- package/dist/reasoning.d.ts +2 -0
- package/dist/reasoning.js +90 -0
- package/dist/reasoning.js.map +1 -0
- package/dist/resizable.d.ts +3 -0
- package/dist/resizable.js +66 -0
- package/dist/resizable.js.map +1 -0
- package/dist/schemas.d.ts +72 -0
- package/dist/schemas.js +5491 -0
- package/dist/schemas.js.map +1 -0
- package/dist/scroll-area.d.ts +3 -0
- package/dist/scroll-area.js +55 -0
- package/dist/scroll-area.js.map +1 -0
- package/dist/select.d.ts +8 -0
- package/dist/select.js +136 -0
- package/dist/select.js.map +1 -0
- package/dist/separator.d.ts +2 -0
- package/dist/separator.js +29 -0
- package/dist/separator.js.map +1 -0
- package/dist/sheet.d.ts +10 -0
- package/dist/sheet.js +140 -0
- package/dist/sheet.js.map +1 -0
- package/dist/sidebar.d.ts +8 -0
- package/dist/sidebar.js +201 -0
- package/dist/sidebar.js.map +1 -0
- package/dist/skeleton.d.ts +1 -0
- package/dist/skeleton.js +21 -0
- package/dist/skeleton.js.map +1 -0
- package/dist/slider.d.ts +2 -0
- package/dist/slider.js +55 -0
- package/dist/slider.js.map +1 -0
- package/dist/sonner.d.ts +2 -0
- package/dist/sonner.js +27 -0
- package/dist/sonner.js.map +1 -0
- package/dist/spacer.d.ts +3 -0
- package/dist/spacer.js +43 -0
- package/dist/spacer.js.map +1 -0
- package/dist/stack.d.ts +3 -0
- package/dist/stack.js +49 -0
- package/dist/stack.js.map +1 -0
- package/dist/stepper.d.ts +4 -0
- package/dist/stepper.js +226 -0
- package/dist/stepper.js.map +1 -0
- package/dist/suggestion.d.ts +2 -0
- package/dist/suggestion.js +55 -0
- package/dist/suggestion.js.map +1 -0
- package/dist/switch.d.ts +2 -0
- package/dist/switch.js +47 -0
- package/dist/switch.js.map +1 -0
- package/dist/table.d.ts +8 -0
- package/dist/table.js +85 -0
- package/dist/table.js.map +1 -0
- package/dist/tabs.d.ts +4 -0
- package/dist/tabs.js +57 -0
- package/dist/tabs.js.map +1 -0
- package/dist/textarea.d.ts +2 -0
- package/dist/textarea.js +36 -0
- package/dist/textarea.js.map +1 -0
- package/dist/time-picker.d.ts +2 -0
- package/dist/time-picker.js +50 -0
- package/dist/time-picker.js.map +1 -0
- package/dist/timeline.d.ts +4 -0
- package/dist/timeline.js +84 -0
- package/dist/timeline.js.map +1 -0
- package/dist/toggle-group.d.ts +2 -0
- package/dist/toggle-group.js +83 -0
- package/dist/toggle-group.js.map +1 -0
- package/dist/toggle.d.ts +2 -0
- package/dist/toggle.js +49 -0
- package/dist/toggle.js.map +1 -0
- package/dist/tool-call.d.ts +2 -0
- package/dist/tool-call.js +133 -0
- package/dist/tool-call.js.map +1 -0
- package/dist/tooltip.d.ts +4 -0
- package/dist/tooltip.js +33 -0
- package/dist/tooltip.js.map +1 -0
- package/package.json +71 -16
package/dist/stepper.js
ADDED
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cva } from 'class-variance-authority';
|
|
3
|
+
import { clsx } from 'clsx';
|
|
4
|
+
import { twMerge } from 'tailwind-merge';
|
|
5
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
6
|
+
|
|
7
|
+
function cn(...inputs) {
|
|
8
|
+
return twMerge(clsx(inputs));
|
|
9
|
+
}
|
|
10
|
+
var stepperRoot = cva(
|
|
11
|
+
"flex w-full gap-[var(--gap-md,1rem)] list-none p-0 m-0",
|
|
12
|
+
{
|
|
13
|
+
variants: {
|
|
14
|
+
orientation: {
|
|
15
|
+
horizontal: "flex-row items-start",
|
|
16
|
+
vertical: "flex-col items-stretch"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
defaultVariants: { orientation: "horizontal" }
|
|
20
|
+
}
|
|
21
|
+
);
|
|
22
|
+
var stepItem = cva("flex gap-[var(--space-3,0.75rem)]", {
|
|
23
|
+
variants: {
|
|
24
|
+
orientation: {
|
|
25
|
+
horizontal: "flex-row items-center",
|
|
26
|
+
vertical: "flex-row items-start w-full"
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
defaultVariants: { orientation: "horizontal" }
|
|
30
|
+
});
|
|
31
|
+
var stepIndicator = cva(
|
|
32
|
+
"inline-flex shrink-0 items-center justify-center rounded-full border-2 font-medium transition-colors duration-[var(--duration-normal,200ms)] ease-out",
|
|
33
|
+
{
|
|
34
|
+
variants: {
|
|
35
|
+
size: {
|
|
36
|
+
sm: "h-7 w-7 text-xs",
|
|
37
|
+
md: "h-[var(--control-height-sm,2.25rem)] w-[var(--control-height-sm,2.25rem)] text-sm"
|
|
38
|
+
},
|
|
39
|
+
status: {
|
|
40
|
+
complete: "bg-primary border-primary text-primary-foreground",
|
|
41
|
+
current: "bg-background border-primary text-primary",
|
|
42
|
+
upcoming: "bg-background border-input text-muted-foreground",
|
|
43
|
+
error: "bg-destructive border-destructive text-destructive-foreground"
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
defaultVariants: { size: "md", status: "upcoming" }
|
|
47
|
+
}
|
|
48
|
+
);
|
|
49
|
+
var stepConnector = cva("bg-input transition-colors", {
|
|
50
|
+
variants: {
|
|
51
|
+
orientation: {
|
|
52
|
+
horizontal: "h-px flex-1 min-w-[var(--space-6,1.5rem)] mx-[var(--space-2,0.5rem)]",
|
|
53
|
+
vertical: "w-px self-stretch ml-[1.0625rem] my-[var(--space-1,0.25rem)] min-h-[var(--space-6,1.5rem)]"
|
|
54
|
+
},
|
|
55
|
+
complete: {
|
|
56
|
+
true: "bg-primary",
|
|
57
|
+
false: ""
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
defaultVariants: { orientation: "horizontal", complete: false }
|
|
61
|
+
});
|
|
62
|
+
function deriveStatus(index, current) {
|
|
63
|
+
if (index < current) return "complete";
|
|
64
|
+
if (index === current) return "current";
|
|
65
|
+
return "upcoming";
|
|
66
|
+
}
|
|
67
|
+
function StepCheck() {
|
|
68
|
+
return /* @__PURE__ */ jsx(
|
|
69
|
+
"svg",
|
|
70
|
+
{
|
|
71
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
72
|
+
viewBox: "0 0 24 24",
|
|
73
|
+
fill: "none",
|
|
74
|
+
stroke: "currentColor",
|
|
75
|
+
strokeWidth: "3",
|
|
76
|
+
strokeLinecap: "round",
|
|
77
|
+
strokeLinejoin: "round",
|
|
78
|
+
className: "h-4 w-4",
|
|
79
|
+
"aria-hidden": "true",
|
|
80
|
+
children: /* @__PURE__ */ jsx("polyline", { points: "20 6 9 17 4 12" })
|
|
81
|
+
}
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
function StepError() {
|
|
85
|
+
return /* @__PURE__ */ jsxs(
|
|
86
|
+
"svg",
|
|
87
|
+
{
|
|
88
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
89
|
+
viewBox: "0 0 24 24",
|
|
90
|
+
fill: "none",
|
|
91
|
+
stroke: "currentColor",
|
|
92
|
+
strokeWidth: "3",
|
|
93
|
+
strokeLinecap: "round",
|
|
94
|
+
strokeLinejoin: "round",
|
|
95
|
+
className: "h-4 w-4",
|
|
96
|
+
"aria-hidden": "true",
|
|
97
|
+
children: [
|
|
98
|
+
/* @__PURE__ */ jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" }),
|
|
99
|
+
/* @__PURE__ */ jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" })
|
|
100
|
+
]
|
|
101
|
+
}
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
function StepIndicator({ index, status, size }) {
|
|
105
|
+
return /* @__PURE__ */ jsx(
|
|
106
|
+
"span",
|
|
107
|
+
{
|
|
108
|
+
className: stepIndicator({ size, status }),
|
|
109
|
+
"aria-invalid": status === "error" ? true : void 0,
|
|
110
|
+
children: status === "complete" ? /* @__PURE__ */ jsx(StepCheck, {}) : status === "error" ? /* @__PURE__ */ jsx(StepError, {}) : index + 1
|
|
111
|
+
}
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
function Stepper({
|
|
115
|
+
steps,
|
|
116
|
+
current,
|
|
117
|
+
orientation = "horizontal",
|
|
118
|
+
size = "md",
|
|
119
|
+
onStepClick,
|
|
120
|
+
"aria-label": ariaLabel,
|
|
121
|
+
className,
|
|
122
|
+
...rest
|
|
123
|
+
}) {
|
|
124
|
+
const interactive = typeof onStepClick === "function";
|
|
125
|
+
return /* @__PURE__ */ jsx(
|
|
126
|
+
"ol",
|
|
127
|
+
{
|
|
128
|
+
"aria-label": ariaLabel,
|
|
129
|
+
className: cn(stepperRoot({ orientation }), className),
|
|
130
|
+
...rest,
|
|
131
|
+
children: steps.map((step, index) => {
|
|
132
|
+
const status = step.status ?? deriveStatus(index, current);
|
|
133
|
+
const isCurrent = status === "current";
|
|
134
|
+
const isLast = index === steps.length - 1;
|
|
135
|
+
const labelNode = /* @__PURE__ */ jsxs("span", { className: "flex flex-col gap-[var(--space-1,0.25rem)]", children: [
|
|
136
|
+
/* @__PURE__ */ jsxs(
|
|
137
|
+
"span",
|
|
138
|
+
{
|
|
139
|
+
className: cn(
|
|
140
|
+
"text-sm font-medium whitespace-nowrap",
|
|
141
|
+
isCurrent && "text-foreground",
|
|
142
|
+
status === "complete" && "text-foreground",
|
|
143
|
+
status === "upcoming" && "text-muted-foreground",
|
|
144
|
+
status === "error" && "text-destructive"
|
|
145
|
+
),
|
|
146
|
+
children: [
|
|
147
|
+
status === "complete" && /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Completed: " }),
|
|
148
|
+
status === "error" && /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Error: " }),
|
|
149
|
+
step.label
|
|
150
|
+
]
|
|
151
|
+
}
|
|
152
|
+
),
|
|
153
|
+
step.description ? /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: step.description }) : null
|
|
154
|
+
] });
|
|
155
|
+
const innerContent = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
156
|
+
/* @__PURE__ */ jsx(StepIndicator, { index, status, size }),
|
|
157
|
+
labelNode
|
|
158
|
+
] });
|
|
159
|
+
return (
|
|
160
|
+
/*
|
|
161
|
+
* `aria-current="step"` lives on the <li> itself so screen
|
|
162
|
+
* readers announce it as part of the listitem's intro
|
|
163
|
+
* (per WAI guidance for "step" lists), not buried on an
|
|
164
|
+
* interior span/button.
|
|
165
|
+
*/
|
|
166
|
+
/* @__PURE__ */ jsxs(
|
|
167
|
+
"li",
|
|
168
|
+
{
|
|
169
|
+
"aria-current": isCurrent ? "step" : void 0,
|
|
170
|
+
className: cn(
|
|
171
|
+
stepItem({ orientation }),
|
|
172
|
+
/*
|
|
173
|
+
* Grow only when there's a connector after this step.
|
|
174
|
+
* The connector inside takes the extra space via
|
|
175
|
+
* `flex-1` so the line spans to the next step.
|
|
176
|
+
*/
|
|
177
|
+
!isLast && orientation === "horizontal" && "flex-1",
|
|
178
|
+
!isLast && orientation === "vertical" && "flex-col"
|
|
179
|
+
),
|
|
180
|
+
children: [
|
|
181
|
+
interactive ? /* @__PURE__ */ jsx(
|
|
182
|
+
"button",
|
|
183
|
+
{
|
|
184
|
+
type: "button",
|
|
185
|
+
disabled: step.disabled,
|
|
186
|
+
onClick: () => onStepClick?.(index),
|
|
187
|
+
className: cn(
|
|
188
|
+
"flex items-center gap-[var(--space-3,0.75rem)] text-left rounded-md transition-colors duration-[var(--duration-normal,200ms)] ease-out",
|
|
189
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
|
190
|
+
"disabled:opacity-50 disabled:pointer-events-none"
|
|
191
|
+
),
|
|
192
|
+
children: innerContent
|
|
193
|
+
}
|
|
194
|
+
) : /* @__PURE__ */ jsx("span", { className: "flex items-center gap-[var(--space-3,0.75rem)]", children: innerContent }),
|
|
195
|
+
!isLast ? (
|
|
196
|
+
/*
|
|
197
|
+
* Connector "complete" iff THIS step is finished. An
|
|
198
|
+
* explicit "error" status on the current step never
|
|
199
|
+
* fills the gap to the next step — the user hasn't
|
|
200
|
+
* cleared this milestone.
|
|
201
|
+
*/
|
|
202
|
+
/* @__PURE__ */ jsx(
|
|
203
|
+
"span",
|
|
204
|
+
{
|
|
205
|
+
"aria-hidden": "true",
|
|
206
|
+
className: stepConnector({
|
|
207
|
+
orientation,
|
|
208
|
+
complete: index < current && step.status !== "error"
|
|
209
|
+
})
|
|
210
|
+
}
|
|
211
|
+
)
|
|
212
|
+
) : null
|
|
213
|
+
]
|
|
214
|
+
},
|
|
215
|
+
step.id
|
|
216
|
+
)
|
|
217
|
+
);
|
|
218
|
+
})
|
|
219
|
+
}
|
|
220
|
+
);
|
|
221
|
+
}
|
|
222
|
+
Stepper.displayName = "Stepper";
|
|
223
|
+
|
|
224
|
+
export { Stepper };
|
|
225
|
+
//# sourceMappingURL=stepper.js.map
|
|
226
|
+
//# sourceMappingURL=stepper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/utils.ts","../src/components/stepper/stepper.tsx"],"names":[],"mappings":"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","file":"stepper.js","sourcesContent":["import { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\n/**\n * Merge class names with Tailwind CSS conflict resolution.\n * @param inputs - Class values (strings, arrays, objects) to merge\n * @returns A single merged class string with Tailwind conflicts resolved\n */\nexport function cn(...inputs: ClassValue[]) {\n\treturn twMerge(clsx(inputs));\n}\n","\"use client\";\n\nimport { cva } from \"class-variance-authority\";\nimport * as React from \"react\";\nimport { cn } from \"../../lib/utils.js\";\n\ntype StepStatus = \"complete\" | \"current\" | \"upcoming\" | \"error\";\n\ninterface StepperStep {\n\t/** Stable unique id used as the React key. */\n\tid: string;\n\t/** Step name shown next to the indicator. */\n\tlabel: string;\n\t/** Optional secondary text under the label. */\n\tdescription?: string;\n\t/** Disable the step (only applies when onStepClick is provided). */\n\tdisabled?: boolean;\n\t/**\n\t * Override the index-derived status. Use `\"error\"` to mark a failed step\n\t * (e.g. validation failure in a form wizard); `\"complete\"` / `\"current\"` /\n\t * `\"upcoming\"` are derived from `current` by default.\n\t */\n\tstatus?: StepStatus;\n}\n\nconst stepperRoot = cva(\n\t\"flex w-full gap-[var(--gap-md,1rem)] list-none p-0 m-0\",\n\t{\n\t\tvariants: {\n\t\t\torientation: {\n\t\t\t\thorizontal: \"flex-row items-start\",\n\t\t\t\tvertical: \"flex-col items-stretch\",\n\t\t\t},\n\t\t},\n\t\tdefaultVariants: { orientation: \"horizontal\" },\n\t},\n);\n\n/*\n * Horizontal: each step sizes to its content; the connector (`flex-1`) fills\n * the gap between steps. Going `flex-1` on the step item itself would shrink\n * labels to the point of `text-overflow: ellipsis` (\"Account\" → \"A...\").\n * Vertical: items take the full width so multi-line descriptions wrap\n * naturally below the indicator.\n */\nconst stepItem = cva(\"flex gap-[var(--space-3,0.75rem)]\", {\n\tvariants: {\n\t\torientation: {\n\t\t\thorizontal: \"flex-row items-center\",\n\t\t\tvertical: \"flex-row items-start w-full\",\n\t\t},\n\t},\n\tdefaultVariants: { orientation: \"horizontal\" },\n});\n\nconst stepIndicator = cva(\n\t\"inline-flex shrink-0 items-center justify-center rounded-full border-2 font-medium transition-colors duration-[var(--duration-normal,200ms)] ease-out\",\n\t{\n\t\tvariants: {\n\t\t\tsize: {\n\t\t\t\tsm: \"h-7 w-7 text-xs\",\n\t\t\t\tmd: \"h-[var(--control-height-sm,2.25rem)] w-[var(--control-height-sm,2.25rem)] text-sm\",\n\t\t\t},\n\t\t\tstatus: {\n\t\t\t\tcomplete: \"bg-primary border-primary text-primary-foreground\",\n\t\t\t\tcurrent: \"bg-background border-primary text-primary\",\n\t\t\t\tupcoming: \"bg-background border-input text-muted-foreground\",\n\t\t\t\terror:\n\t\t\t\t\t\"bg-destructive border-destructive text-destructive-foreground\",\n\t\t\t},\n\t\t},\n\t\tdefaultVariants: { size: \"md\", status: \"upcoming\" },\n\t},\n);\n\nconst stepConnector = cva(\"bg-input transition-colors\", {\n\tvariants: {\n\t\torientation: {\n\t\t\thorizontal: \"h-px flex-1 min-w-[var(--space-6,1.5rem)] mx-[var(--space-2,0.5rem)]\",\n\t\t\tvertical: \"w-px self-stretch ml-[1.0625rem] my-[var(--space-1,0.25rem)] min-h-[var(--space-6,1.5rem)]\",\n\t\t},\n\t\tcomplete: {\n\t\t\ttrue: \"bg-primary\",\n\t\t\tfalse: \"\",\n\t\t},\n\t},\n\tdefaultVariants: { orientation: \"horizontal\", complete: false },\n});\n\ninterface StepperProps\n\textends Omit<\n\t\tReact.HTMLAttributes<HTMLOListElement>,\n\t\t\"aria-label\" | \"onClick\"\n\t> {\n\t/** Ordered list of steps. */\n\tsteps: StepperStep[];\n\t/** Index of the current step (controlled). */\n\tcurrent: number;\n\t/** Layout direction. */\n\torientation?: \"horizontal\" | \"vertical\";\n\t/** Indicator size. */\n\tsize?: \"sm\" | \"md\";\n\t/** When provided, each step is rendered as a clickable button. */\n\tonStepClick?: (index: number) => void;\n\t/** Required accessible name for the ordered list. */\n\t\"aria-label\": string;\n}\n\n/** Map a step index against the current pointer to a `StepStatus`. */\nfunction deriveStatus(index: number, current: number): StepStatus {\n\tif (index < current) return \"complete\";\n\tif (index === current) return \"current\";\n\treturn \"upcoming\";\n}\n\n/** Checkmark glyph rendered inside the indicator for completed steps. */\nfunction StepCheck() {\n\treturn (\n\t\t<svg\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tfill=\"none\"\n\t\t\tstroke=\"currentColor\"\n\t\t\tstrokeWidth=\"3\"\n\t\t\tstrokeLinecap=\"round\"\n\t\t\tstrokeLinejoin=\"round\"\n\t\t\tclassName=\"h-4 w-4\"\n\t\t\taria-hidden=\"true\"\n\t\t>\n\t\t\t<polyline points=\"20 6 9 17 4 12\" />\n\t\t</svg>\n\t);\n}\n\n/** Cross glyph rendered inside the indicator for steps with status=\"error\". */\nfunction StepError() {\n\treturn (\n\t\t<svg\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tfill=\"none\"\n\t\t\tstroke=\"currentColor\"\n\t\t\tstrokeWidth=\"3\"\n\t\t\tstrokeLinecap=\"round\"\n\t\t\tstrokeLinejoin=\"round\"\n\t\t\tclassName=\"h-4 w-4\"\n\t\t\taria-hidden=\"true\"\n\t\t>\n\t\t\t<line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n\t\t\t<line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n\t\t</svg>\n\t);\n}\n\ninterface StepIndicatorProps {\n\tindex: number;\n\tstatus: StepStatus;\n\tsize: \"sm\" | \"md\";\n}\n\n/** Circular indicator that flips between number, check, and cross by `status`. */\nfunction StepIndicator({ index, status, size }: StepIndicatorProps) {\n\treturn (\n\t\t<span\n\t\t\tclassName={stepIndicator({ size, status })}\n\t\t\taria-invalid={status === \"error\" ? true : undefined}\n\t\t>\n\t\t\t{status === \"complete\" ? (\n\t\t\t\t<StepCheck />\n\t\t\t) : status === \"error\" ? (\n\t\t\t\t<StepError />\n\t\t\t) : (\n\t\t\t\tindex + 1\n\t\t\t)}\n\t\t</span>\n\t);\n}\n\n/**\n * Linear progress indicator for multi-step flows (form wizards, onboarding,\n * checkout). Pure semantic HTML — `<ol>` of `<li>` with `aria-current=\"step\"`\n * on the current item; per-step `status` overrides allow marking \"error\".\n *\n * Pass `onStepClick` to make completed/non-disabled steps interactive.\n * @returns An accessible ordered step list.\n */\nfunction Stepper({\n\tsteps,\n\tcurrent,\n\torientation = \"horizontal\",\n\tsize = \"md\",\n\tonStepClick,\n\t\"aria-label\": ariaLabel,\n\tclassName,\n\t...rest\n}: StepperProps) {\n\tconst interactive = typeof onStepClick === \"function\";\n\treturn (\n\t\t<ol\n\t\t\taria-label={ariaLabel}\n\t\t\tclassName={cn(stepperRoot({ orientation }), className)}\n\t\t\t{...rest}\n\t\t>\n\t\t\t{steps.map((step, index) => {\n\t\t\t\tconst status = step.status ?? deriveStatus(index, current);\n\t\t\t\tconst isCurrent = status === \"current\";\n\t\t\t\tconst isLast = index === steps.length - 1;\n\t\t\t\tconst labelNode = (\n\t\t\t\t\t<span className=\"flex flex-col gap-[var(--space-1,0.25rem)]\">\n\t\t\t\t\t\t<span\n\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\"text-sm font-medium whitespace-nowrap\",\n\t\t\t\t\t\t\t\tisCurrent && \"text-foreground\",\n\t\t\t\t\t\t\t\tstatus === \"complete\" && \"text-foreground\",\n\t\t\t\t\t\t\t\tstatus === \"upcoming\" && \"text-muted-foreground\",\n\t\t\t\t\t\t\t\tstatus === \"error\" && \"text-destructive\",\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{status === \"complete\" && (\n\t\t\t\t\t\t\t\t<span className=\"sr-only\">Completed: </span>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t{status === \"error\" && (\n\t\t\t\t\t\t\t\t<span className=\"sr-only\">Error: </span>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t{step.label}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t\t{step.description ? (\n\t\t\t\t\t\t\t<span className=\"text-xs text-muted-foreground\">\n\t\t\t\t\t\t\t\t{step.description}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t</span>\n\t\t\t\t);\n\n\t\t\t\tconst innerContent = (\n\t\t\t\t\t<>\n\t\t\t\t\t\t<StepIndicator index={index} status={status} size={size} />\n\t\t\t\t\t\t{labelNode}\n\t\t\t\t\t</>\n\t\t\t\t);\n\n\t\t\t\treturn (\n\t\t\t\t\t/*\n\t\t\t\t\t * `aria-current=\"step\"` lives on the <li> itself so screen\n\t\t\t\t\t * readers announce it as part of the listitem's intro\n\t\t\t\t\t * (per WAI guidance for \"step\" lists), not buried on an\n\t\t\t\t\t * interior span/button.\n\t\t\t\t\t */\n\t\t\t\t\t<li\n\t\t\t\t\t\tkey={step.id}\n\t\t\t\t\t\taria-current={isCurrent ? \"step\" : undefined}\n\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\tstepItem({ orientation }),\n\t\t\t\t\t\t\t/*\n\t\t\t\t\t\t\t * Grow only when there's a connector after this step.\n\t\t\t\t\t\t\t * The connector inside takes the extra space via\n\t\t\t\t\t\t\t * `flex-1` so the line spans to the next step.\n\t\t\t\t\t\t\t */\n\t\t\t\t\t\t\t!isLast && orientation === \"horizontal\" && \"flex-1\",\n\t\t\t\t\t\t\t!isLast && orientation === \"vertical\" && \"flex-col\",\n\t\t\t\t\t\t)}\n\t\t\t\t\t>\n\t\t\t\t\t\t{interactive ? (\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tdisabled={step.disabled}\n\t\t\t\t\t\t\t\tonClick={() => onStepClick?.(index)}\n\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t\"flex items-center gap-[var(--space-3,0.75rem)] text-left rounded-md transition-colors duration-[var(--duration-normal,200ms)] ease-out\",\n\t\t\t\t\t\t\t\t\t\"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\",\n\t\t\t\t\t\t\t\t\t\"disabled:opacity-50 disabled:pointer-events-none\",\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{innerContent}\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<span className=\"flex items-center gap-[var(--space-3,0.75rem)]\">\n\t\t\t\t\t\t\t\t{innerContent}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t{!isLast ? (\n\t\t\t\t\t\t\t/*\n\t\t\t\t\t\t\t * Connector \"complete\" iff THIS step is finished. An\n\t\t\t\t\t\t\t * explicit \"error\" status on the current step never\n\t\t\t\t\t\t\t * fills the gap to the next step — the user hasn't\n\t\t\t\t\t\t\t * cleared this milestone.\n\t\t\t\t\t\t\t */\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t\t\tclassName={stepConnector({\n\t\t\t\t\t\t\t\t\torientation,\n\t\t\t\t\t\t\t\t\tcomplete: index < current && step.status !== \"error\",\n\t\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t</li>\n\t\t\t\t);\n\t\t\t})}\n\t\t</ol>\n\t);\n}\nStepper.displayName = \"Stepper\";\n\nexport { Stepper };\nexport type { StepperProps, StepperStep, StepStatus };\n"]}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { clsx } from 'clsx';
|
|
4
|
+
import { twMerge } from 'tailwind-merge';
|
|
5
|
+
import { jsx } from 'react/jsx-runtime';
|
|
6
|
+
|
|
7
|
+
function cn(...inputs) {
|
|
8
|
+
return twMerge(clsx(inputs));
|
|
9
|
+
}
|
|
10
|
+
function Suggestion({
|
|
11
|
+
value,
|
|
12
|
+
onSelect,
|
|
13
|
+
children,
|
|
14
|
+
className,
|
|
15
|
+
type = "button",
|
|
16
|
+
onClick,
|
|
17
|
+
...props
|
|
18
|
+
}) {
|
|
19
|
+
function handleClick(event) {
|
|
20
|
+
const payload = value ?? extractText(children);
|
|
21
|
+
onSelect(payload);
|
|
22
|
+
onClick?.(event);
|
|
23
|
+
}
|
|
24
|
+
return /* @__PURE__ */ jsx(
|
|
25
|
+
"button",
|
|
26
|
+
{
|
|
27
|
+
type,
|
|
28
|
+
onClick: handleClick,
|
|
29
|
+
className: cn(
|
|
30
|
+
"inline-flex items-center rounded-full border border-foreground/15 bg-background px-3 py-1.5 text-sm",
|
|
31
|
+
"transition-all duration-[var(--duration-normal,200ms)] ease-out",
|
|
32
|
+
"hover:border-foreground/30 hover:bg-secondary/40 hover:shadow-sm",
|
|
33
|
+
"active:scale-[0.98]",
|
|
34
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
|
35
|
+
"disabled:cursor-not-allowed disabled:opacity-50",
|
|
36
|
+
className
|
|
37
|
+
),
|
|
38
|
+
...props,
|
|
39
|
+
children
|
|
40
|
+
}
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
function extractText(node) {
|
|
44
|
+
if (node == null || typeof node === "boolean") return "";
|
|
45
|
+
if (typeof node === "string" || typeof node === "number") return String(node);
|
|
46
|
+
if (Array.isArray(node)) return node.map(extractText).join(" ").replace(/\s+/g, " ").trim();
|
|
47
|
+
if (React.isValidElement(node)) {
|
|
48
|
+
return extractText(node.props.children);
|
|
49
|
+
}
|
|
50
|
+
return "";
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export { Suggestion };
|
|
54
|
+
//# sourceMappingURL=suggestion.js.map
|
|
55
|
+
//# sourceMappingURL=suggestion.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/utils.ts","../src/ai/suggestion/suggestion.tsx"],"names":[],"mappings":";;;;;AAQO,SAAS,MAAM,MAAA,EAAsB;AAC3C,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC5B;ACuBA,SAAS,UAAA,CAAW;AAAA,EACnB,KAAA;AAAA,EACA,QAAA;AAAA,EACA,QAAA;AAAA,EACA,SAAA;AAAA,EACA,IAAA,GAAO,QAAA;AAAA,EACP,OAAA;AAAA,EACA,GAAG;AACJ,CAAA,EAAoB;AACnB,EAAA,SAAS,YAAY,KAAA,EAA4C;AAChE,IAAA,MAAM,OAAA,GAAU,KAAA,IAAS,WAAA,CAAY,QAAQ,CAAA;AAC7C,IAAA,QAAA,CAAS,OAAO,CAAA;AAChB,IAAA,OAAA,GAAU,KAAK,CAAA;AAAA,EAChB;AAEA,EAAA,uBACC,GAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACA,IAAA;AAAA,MACA,OAAA,EAAS,WAAA;AAAA,MACT,SAAA,EAAW,EAAA;AAAA,QACV,qGAAA;AAAA,QACA,iEAAA;AAAA,QACA,kEAAA;AAAA,QACA,qBAAA;AAAA,QACA,qGAAA;AAAA,QACA,iDAAA;AAAA,QACA;AAAA,OACD;AAAA,MACC,GAAG,KAAA;AAAA,MAEH;AAAA;AAAA,GACF;AAEF;AAUA,SAAS,YAAY,IAAA,EAA+B;AACnD,EAAA,IAAI,IAAA,IAAQ,IAAA,IAAQ,OAAO,IAAA,KAAS,WAAW,OAAO,EAAA;AACtD,EAAA,IAAI,OAAO,SAAS,QAAA,IAAY,OAAO,SAAS,QAAA,EAAU,OAAO,OAAO,IAAI,CAAA;AAC5E,EAAA,IAAI,MAAM,OAAA,CAAQ,IAAI,CAAA,EAAG,OAAO,KAAK,GAAA,CAAI,WAAW,CAAA,CAAE,IAAA,CAAK,GAAG,CAAA,CAAE,OAAA,CAAQ,MAAA,EAAQ,GAAG,EAAE,IAAA,EAAK;AAC1F,EAAA,IAAU,KAAA,CAAA,cAAA,CAA+C,IAAI,CAAA,EAAG;AAC/D,IAAA,OAAO,WAAA,CAAY,IAAA,CAAK,KAAA,CAAM,QAAQ,CAAA;AAAA,EACvC;AACA,EAAA,OAAO,EAAA;AACR","file":"suggestion.js","sourcesContent":["import { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\n/**\n * Merge class names with Tailwind CSS conflict resolution.\n * @param inputs - Class values (strings, arrays, objects) to merge\n * @returns A single merged class string with Tailwind conflicts resolved\n */\nexport function cn(...inputs: ClassValue[]) {\n\treturn twMerge(clsx(inputs));\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"../../lib/utils.js\";\n\n/**\n * Prompt pill / quick-action chip. Click forwards `value` (or the rendered\n * string children) to `onSelect` — typically wired to drop the suggestion\n * into a `Composer` or fire it directly through `useChat.append`.\n *\n * Stateless: no submission logic, no networking. Composer (or its parent)\n * decides whether `onSelect` populates the input or auto-sends.\n *\n * @example\n * <Cluster gap=\"sm\">\n * {prompts.map((p) => (\n * <Suggestion key={p} value={p} onSelect={setInput}>{p}</Suggestion>\n * ))}\n * </Cluster>\n */\nexport interface SuggestionProps\n\textends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, \"onSelect\" | \"value\"> {\n\t/** Payload passed to `onSelect`. Defaults to the rendered children if a string. */\n\tvalue?: string;\n\tonSelect: (value: string) => void;\n\tchildren: React.ReactNode;\n}\n\n/**\n * Renders a clickable suggestion chip.\n * @param props - value/onSelect + children\n * @returns A styled button element\n */\nfunction Suggestion({\n\tvalue,\n\tonSelect,\n\tchildren,\n\tclassName,\n\ttype = \"button\",\n\tonClick,\n\t...props\n}: SuggestionProps) {\n\tfunction handleClick(event: React.MouseEvent<HTMLButtonElement>) {\n\t\tconst payload = value ?? extractText(children);\n\t\tonSelect(payload);\n\t\tonClick?.(event);\n\t}\n\n\treturn (\n\t\t<button\n\t\t\ttype={type}\n\t\t\tonClick={handleClick}\n\t\t\tclassName={cn(\n\t\t\t\t\"inline-flex items-center rounded-full border border-foreground/15 bg-background px-3 py-1.5 text-sm\",\n\t\t\t\t\"transition-all duration-[var(--duration-normal,200ms)] ease-out\",\n\t\t\t\t\"hover:border-foreground/30 hover:bg-secondary/40 hover:shadow-sm\",\n\t\t\t\t\"active:scale-[0.98]\",\n\t\t\t\t\"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\",\n\t\t\t\t\"disabled:cursor-not-allowed disabled:opacity-50\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t>\n\t\t\t{children}\n\t\t</button>\n\t);\n}\n\n/**\n * Recursively pull plain-text out of a ReactNode tree so a `<Suggestion>`\n * with JSX children (e.g. `<Icon /> Try this`) still resolves to the\n * visible label when no `value` prop was set.\n *\n * @param node - children ReactNode\n * @returns The concatenated text content, trimmed of incidental whitespace\n */\nfunction extractText(node: React.ReactNode): string {\n\tif (node == null || typeof node === \"boolean\") return \"\";\n\tif (typeof node === \"string\" || typeof node === \"number\") return String(node);\n\tif (Array.isArray(node)) return node.map(extractText).join(\" \").replace(/\\s+/g, \" \").trim();\n\tif (React.isValidElement<{ children?: React.ReactNode }>(node)) {\n\t\treturn extractText(node.props.children);\n\t}\n\treturn \"\";\n}\n\nexport { Suggestion };\n"]}
|
package/dist/switch.d.ts
ADDED
package/dist/switch.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import * as SwitchPrimitive from '@radix-ui/react-switch';
|
|
4
|
+
import { clsx } from 'clsx';
|
|
5
|
+
import { twMerge } from 'tailwind-merge';
|
|
6
|
+
import { jsx } from 'react/jsx-runtime';
|
|
7
|
+
|
|
8
|
+
function cn(...inputs) {
|
|
9
|
+
return twMerge(clsx(inputs));
|
|
10
|
+
}
|
|
11
|
+
var Switch = React.forwardRef(
|
|
12
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
13
|
+
SwitchPrimitive.Root,
|
|
14
|
+
{
|
|
15
|
+
className: cn(
|
|
16
|
+
"peer inline-flex h-6 w-[var(--control-height-lg,2.75rem)] shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent",
|
|
17
|
+
"transition-all duration-[var(--duration-normal,200ms)] ease-out",
|
|
18
|
+
"shadow-sm",
|
|
19
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
|
|
20
|
+
"disabled:cursor-not-allowed disabled:opacity-50",
|
|
21
|
+
"data-[state=checked]:bg-primary data-[state=unchecked]:bg-input",
|
|
22
|
+
// Unchecked track shares --color-input with form borders (~1.27:1 vs white) so
|
|
23
|
+
// add an inset ring to make the track visible on flat surfaces.
|
|
24
|
+
"data-[state=unchecked]:inset-ring-1 data-[state=unchecked]:inset-ring-foreground/[0.08]",
|
|
25
|
+
"hover:shadow-md",
|
|
26
|
+
className
|
|
27
|
+
),
|
|
28
|
+
...props,
|
|
29
|
+
ref,
|
|
30
|
+
children: /* @__PURE__ */ jsx(
|
|
31
|
+
SwitchPrimitive.Thumb,
|
|
32
|
+
{
|
|
33
|
+
className: cn(
|
|
34
|
+
"pointer-events-none block h-5 w-5 rounded-full bg-background shadow-lg ring-0",
|
|
35
|
+
"transition-transform duration-[var(--duration-normal,200ms)] ease-out",
|
|
36
|
+
"data-[state=checked]:translate-x-5 data-[state=unchecked]:translate-x-0"
|
|
37
|
+
)
|
|
38
|
+
}
|
|
39
|
+
)
|
|
40
|
+
}
|
|
41
|
+
)
|
|
42
|
+
);
|
|
43
|
+
Switch.displayName = "Switch";
|
|
44
|
+
|
|
45
|
+
export { Switch };
|
|
46
|
+
//# sourceMappingURL=switch.js.map
|
|
47
|
+
//# sourceMappingURL=switch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/utils.ts","../src/primitives/switch/switch.tsx"],"names":[],"mappings":";;;;;;AAQO,SAAS,MAAM,MAAA,EAAsB;AAC3C,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC5B;ACEA,IAAM,MAAA,GAAe,KAAA,CAAA,UAAA;AAAA,EACpB,CAAC,EAAE,SAAA,EAAW,GAAG,KAAA,IAAS,GAAA,qBACzB,GAAA;AAAA,IAAiB,eAAA,CAAA,IAAA;AAAA,IAAhB;AAAA,MACA,SAAA,EAAW,EAAA;AAAA,QACV,yIAAA;AAAA,QACA,iEAAA;AAAA,QACA,WAAA;AAAA,QACA,0IAAA;AAAA,QACA,iDAAA;AAAA,QACA,iEAAA;AAAA;AAAA;AAAA,QAGA,yFAAA;AAAA,QACA,iBAAA;AAAA,QACA;AAAA,OACD;AAAA,MACC,GAAG,KAAA;AAAA,MACJ,GAAA;AAAA,MAEA,QAAA,kBAAA,GAAA;AAAA,QAAiB,eAAA,CAAA,KAAA;AAAA,QAAhB;AAAA,UACA,SAAA,EAAW,EAAA;AAAA,YACV,+EAAA;AAAA,YACA,uEAAA;AAAA,YACA;AAAA;AACD;AAAA;AACD;AAAA;AAGH;AACA,MAAA,CAAO,WAAA,GAAc,QAAA","file":"switch.js","sourcesContent":["import { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\n/**\n * Merge class names with Tailwind CSS conflict resolution.\n * @param inputs - Class values (strings, arrays, objects) to merge\n * @returns A single merged class string with Tailwind conflicts resolved\n */\nexport function cn(...inputs: ClassValue[]) {\n\treturn twMerge(clsx(inputs));\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport * as SwitchPrimitive from \"@radix-ui/react-switch\";\nimport { cn } from \"../../lib/utils.js\";\n\n/**\n * An accessible toggle switch built on Radix UI.\n * Use for instant on/off settings that take effect immediately.\n */\nexport type SwitchProps = React.ComponentPropsWithoutRef<typeof SwitchPrimitive.Root>;\n\nconst Switch = React.forwardRef<React.ComponentRef<typeof SwitchPrimitive.Root>, SwitchProps>(\n\t({ className, ...props }, ref) => (\n\t\t<SwitchPrimitive.Root\n\t\t\tclassName={cn(\n\t\t\t\t\"peer inline-flex h-6 w-[var(--control-height-lg,2.75rem)] shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent\",\n\t\t\t\t\"transition-all duration-[var(--duration-normal,200ms)] ease-out\",\n\t\t\t\t\"shadow-sm\",\n\t\t\t\t\"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background\",\n\t\t\t\t\"disabled:cursor-not-allowed disabled:opacity-50\",\n\t\t\t\t\"data-[state=checked]:bg-primary data-[state=unchecked]:bg-input\",\n\t\t\t\t// Unchecked track shares --color-input with form borders (~1.27:1 vs white) so\n\t\t\t\t// add an inset ring to make the track visible on flat surfaces.\n\t\t\t\t\"data-[state=unchecked]:inset-ring-1 data-[state=unchecked]:inset-ring-foreground/[0.08]\",\n\t\t\t\t\"hover:shadow-md\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t\tref={ref}\n\t\t>\n\t\t\t<SwitchPrimitive.Thumb\n\t\t\t\tclassName={cn(\n\t\t\t\t\t\"pointer-events-none block h-5 w-5 rounded-full bg-background shadow-lg ring-0\",\n\t\t\t\t\t\"transition-transform duration-[var(--duration-normal,200ms)] ease-out\",\n\t\t\t\t\t\"data-[state=checked]:translate-x-5 data-[state=unchecked]:translate-x-0\",\n\t\t\t\t)}\n\t\t\t/>\n\t\t</SwitchPrimitive.Root>\n\t),\n);\nSwitch.displayName = \"Switch\";\n\nexport { Switch };\n"]}
|
package/dist/table.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { Table_alias_1 as Table } from './_tsup-dts-rollup.js';
|
|
2
|
+
export { TableHeader_alias_1 as TableHeader } from './_tsup-dts-rollup.js';
|
|
3
|
+
export { TableBody_alias_1 as TableBody } from './_tsup-dts-rollup.js';
|
|
4
|
+
export { TableFooter_alias_1 as TableFooter } from './_tsup-dts-rollup.js';
|
|
5
|
+
export { TableHead_alias_1 as TableHead } from './_tsup-dts-rollup.js';
|
|
6
|
+
export { TableRow_alias_1 as TableRow } from './_tsup-dts-rollup.js';
|
|
7
|
+
export { TableCell_alias_1 as TableCell } from './_tsup-dts-rollup.js';
|
|
8
|
+
export { TableCaption_alias_1 as TableCaption } from './_tsup-dts-rollup.js';
|
package/dist/table.js
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { clsx } from 'clsx';
|
|
3
|
+
import { twMerge } from 'tailwind-merge';
|
|
4
|
+
import { jsx } from 'react/jsx-runtime';
|
|
5
|
+
|
|
6
|
+
// src/components/table/table.tsx
|
|
7
|
+
function cn(...inputs) {
|
|
8
|
+
return twMerge(clsx(inputs));
|
|
9
|
+
}
|
|
10
|
+
var Table = React.forwardRef(
|
|
11
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { className: "relative w-full overflow-auto", children: /* @__PURE__ */ jsx(
|
|
12
|
+
"table",
|
|
13
|
+
{
|
|
14
|
+
ref,
|
|
15
|
+
className: cn("w-full caption-bottom text-sm", className),
|
|
16
|
+
...props
|
|
17
|
+
}
|
|
18
|
+
) })
|
|
19
|
+
);
|
|
20
|
+
Table.displayName = "Table";
|
|
21
|
+
var TableHeader = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("thead", { ref, className: cn("[&_tr]:border-b [&_tr]:border-b-foreground/[0.08]", className), ...props }));
|
|
22
|
+
TableHeader.displayName = "TableHeader";
|
|
23
|
+
var TableBody = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("tbody", { ref, className: cn("[&_tr:last-child]:border-0", className), ...props }));
|
|
24
|
+
TableBody.displayName = "TableBody";
|
|
25
|
+
var TableFooter = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
26
|
+
"tfoot",
|
|
27
|
+
{
|
|
28
|
+
ref,
|
|
29
|
+
className: cn(
|
|
30
|
+
"border-t border-t-foreground/[0.08] bg-muted/50 font-medium [&>tr]:last:border-b-0",
|
|
31
|
+
className
|
|
32
|
+
),
|
|
33
|
+
...props
|
|
34
|
+
}
|
|
35
|
+
));
|
|
36
|
+
TableFooter.displayName = "TableFooter";
|
|
37
|
+
var TableRow = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
38
|
+
"tr",
|
|
39
|
+
{
|
|
40
|
+
ref,
|
|
41
|
+
className: cn(
|
|
42
|
+
"border-b border-b-foreground/[0.08] transition-all duration-[var(--duration-normal,200ms)] ease-out hover:bg-muted/50 data-[state=selected]:bg-muted",
|
|
43
|
+
className
|
|
44
|
+
),
|
|
45
|
+
...props
|
|
46
|
+
}
|
|
47
|
+
));
|
|
48
|
+
TableRow.displayName = "TableRow";
|
|
49
|
+
var TableHead = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
50
|
+
"th",
|
|
51
|
+
{
|
|
52
|
+
ref,
|
|
53
|
+
className: cn(
|
|
54
|
+
"h-[var(--control-height-md,2.5rem)] px-[var(--space-4,1rem)] text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0",
|
|
55
|
+
className
|
|
56
|
+
),
|
|
57
|
+
...props
|
|
58
|
+
}
|
|
59
|
+
));
|
|
60
|
+
TableHead.displayName = "TableHead";
|
|
61
|
+
var TableCell = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
62
|
+
"td",
|
|
63
|
+
{
|
|
64
|
+
ref,
|
|
65
|
+
className: cn("p-[var(--space-4,1rem)] align-middle [&:has([role=checkbox])]:pr-0", className),
|
|
66
|
+
...props
|
|
67
|
+
}
|
|
68
|
+
));
|
|
69
|
+
TableCell.displayName = "TableCell";
|
|
70
|
+
var TableCaption = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
71
|
+
"caption",
|
|
72
|
+
{
|
|
73
|
+
ref,
|
|
74
|
+
className: cn(
|
|
75
|
+
"caption-bottom mt-[var(--space-4,1rem)] text-sm text-muted-foreground",
|
|
76
|
+
className
|
|
77
|
+
),
|
|
78
|
+
...props
|
|
79
|
+
}
|
|
80
|
+
));
|
|
81
|
+
TableCaption.displayName = "TableCaption";
|
|
82
|
+
|
|
83
|
+
export { Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow };
|
|
84
|
+
//# sourceMappingURL=table.js.map
|
|
85
|
+
//# sourceMappingURL=table.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/utils.ts","../src/components/table/table.tsx"],"names":[],"mappings":";;;;;;AAQO,SAAS,MAAM,MAAA,EAAsB;AAC3C,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC5B;ACNA,IAAM,KAAA,GAAc,KAAA,CAAA,UAAA;AAAA,EACnB,CAAC,EAAE,SAAA,EAAW,GAAG,KAAA,IAAS,GAAA,qBACzB,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,+BAAA,EACd,QAAA,kBAAA,GAAA;AAAA,IAAC,OAAA;AAAA,IAAA;AAAA,MACA,GAAA;AAAA,MACA,SAAA,EAAW,EAAA,CAAG,+BAAA,EAAiC,SAAS,CAAA;AAAA,MACvD,GAAG;AAAA;AAAA,GACL,EACD;AAEF;AACA,KAAA,CAAM,WAAA,GAAc,OAAA;AAGpB,IAAM,cAAoB,KAAA,CAAA,UAAA,CAGxB,CAAC,EAAE,SAAA,EAAW,GAAG,OAAM,EAAG,GAAA,yBAC1B,OAAA,EAAA,EAAM,GAAA,EAAU,WAAW,EAAA,CAAG,mDAAA,EAAqD,SAAS,CAAA,EAAI,GAAG,OAAO,CAC3G;AACD,WAAA,CAAY,WAAA,GAAc,aAAA;AAG1B,IAAM,YAAkB,KAAA,CAAA,UAAA,CAGtB,CAAC,EAAE,SAAA,EAAW,GAAG,OAAM,EAAG,GAAA,yBAC1B,OAAA,EAAA,EAAM,GAAA,EAAU,WAAW,EAAA,CAAG,4BAAA,EAA8B,SAAS,CAAA,EAAI,GAAG,OAAO,CACpF;AACD,SAAA,CAAU,WAAA,GAAc,WAAA;AAGxB,IAAM,WAAA,GAAoB,iBAGxB,CAAC,EAAE,WAAW,GAAG,KAAA,IAAS,GAAA,qBAC3B,GAAA;AAAA,EAAC,OAAA;AAAA,EAAA;AAAA,IACA,GAAA;AAAA,IACA,SAAA,EAAW,EAAA;AAAA,MACV,oFAAA;AAAA,MACA;AAAA,KACD;AAAA,IACC,GAAG;AAAA;AACL,CACA;AACD,WAAA,CAAY,WAAA,GAAc,aAAA;AAG1B,IAAM,QAAA,GAAiB,iBAGrB,CAAC,EAAE,WAAW,GAAG,KAAA,IAAS,GAAA,qBAC3B,GAAA;AAAA,EAAC,IAAA;AAAA,EAAA;AAAA,IACA,GAAA;AAAA,IACA,SAAA,EAAW,EAAA;AAAA,MACV,sJAAA;AAAA,MACA;AAAA,KACD;AAAA,IACC,GAAG;AAAA;AACL,CACA;AACD,QAAA,CAAS,WAAA,GAAc,UAAA;AAGvB,IAAM,SAAA,GAAkB,iBAGtB,CAAC,EAAE,WAAW,GAAG,KAAA,IAAS,GAAA,qBAC3B,GAAA;AAAA,EAAC,IAAA;AAAA,EAAA;AAAA,IACA,GAAA;AAAA,IACA,SAAA,EAAW,EAAA;AAAA,MACV,qJAAA;AAAA,MACA;AAAA,KACD;AAAA,IACC,GAAG;AAAA;AACL,CACA;AACD,SAAA,CAAU,WAAA,GAAc,WAAA;AAGxB,IAAM,SAAA,GAAkB,iBAGtB,CAAC,EAAE,WAAW,GAAG,KAAA,IAAS,GAAA,qBAC3B,GAAA;AAAA,EAAC,IAAA;AAAA,EAAA;AAAA,IACA,GAAA;AAAA,IACA,SAAA,EAAW,EAAA,CAAG,oEAAA,EAAsE,SAAS,CAAA;AAAA,IAC5F,GAAG;AAAA;AACL,CACA;AACD,SAAA,CAAU,WAAA,GAAc,WAAA;AAOxB,IAAM,YAAA,GAAqB,iBAGzB,CAAC,EAAE,WAAW,GAAG,KAAA,IAAS,GAAA,qBAC3B,GAAA;AAAA,EAAC,SAAA;AAAA,EAAA;AAAA,IACA,GAAA;AAAA,IACA,SAAA,EAAW,EAAA;AAAA,MACV,uEAAA;AAAA,MACA;AAAA,KACD;AAAA,IACC,GAAG;AAAA;AACL,CACA;AACD,YAAA,CAAa,WAAA,GAAc,cAAA","file":"table.js","sourcesContent":["import { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\n/**\n * Merge class names with Tailwind CSS conflict resolution.\n * @param inputs - Class values (strings, arrays, objects) to merge\n * @returns A single merged class string with Tailwind conflicts resolved\n */\nexport function cn(...inputs: ClassValue[]) {\n\treturn twMerge(clsx(inputs));\n}\n","import * as React from \"react\";\nimport { cn } from \"../../lib/utils.js\";\n\n/** A responsive container + styled HTML table. */\nconst Table = React.forwardRef<HTMLTableElement, React.HTMLAttributes<HTMLTableElement>>(\n\t({ className, ...props }, ref) => (\n\t\t<div className=\"relative w-full overflow-auto\">\n\t\t\t<table\n\t\t\t\tref={ref}\n\t\t\t\tclassName={cn(\"w-full caption-bottom text-sm\", className)}\n\t\t\t\t{...props}\n\t\t\t/>\n\t\t</div>\n\t),\n);\nTable.displayName = \"Table\";\n\n/** `<thead>` wrapper with bottom border. */\nconst TableHeader = React.forwardRef<\n\tHTMLTableSectionElement,\n\tReact.HTMLAttributes<HTMLTableSectionElement>\n>(({ className, ...props }, ref) => (\n\t<thead ref={ref} className={cn(\"[&_tr]:border-b [&_tr]:border-b-foreground/[0.08]\", className)} {...props} />\n));\nTableHeader.displayName = \"TableHeader\";\n\n/** `<tbody>` wrapper removing bottom border on last row. */\nconst TableBody = React.forwardRef<\n\tHTMLTableSectionElement,\n\tReact.HTMLAttributes<HTMLTableSectionElement>\n>(({ className, ...props }, ref) => (\n\t<tbody ref={ref} className={cn(\"[&_tr:last-child]:border-0\", className)} {...props} />\n));\nTableBody.displayName = \"TableBody\";\n\n/** `<tfoot>` wrapper with muted background. */\nconst TableFooter = React.forwardRef<\n\tHTMLTableSectionElement,\n\tReact.HTMLAttributes<HTMLTableSectionElement>\n>(({ className, ...props }, ref) => (\n\t<tfoot\n\t\tref={ref}\n\t\tclassName={cn(\n\t\t\t\"border-t border-t-foreground/[0.08] bg-muted/50 font-medium [&>tr]:last:border-b-0\",\n\t\t\tclassName,\n\t\t)}\n\t\t{...props}\n\t/>\n));\nTableFooter.displayName = \"TableFooter\";\n\n/** `<tr>` with hover + selected states. */\nconst TableRow = React.forwardRef<\n\tHTMLTableRowElement,\n\tReact.HTMLAttributes<HTMLTableRowElement>\n>(({ className, ...props }, ref) => (\n\t<tr\n\t\tref={ref}\n\t\tclassName={cn(\n\t\t\t\"border-b border-b-foreground/[0.08] transition-all duration-[var(--duration-normal,200ms)] ease-out hover:bg-muted/50 data-[state=selected]:bg-muted\",\n\t\t\tclassName,\n\t\t)}\n\t\t{...props}\n\t/>\n));\nTableRow.displayName = \"TableRow\";\n\n/** `<th>` with left-aligned muted text. */\nconst TableHead = React.forwardRef<\n\tHTMLTableCellElement,\n\tReact.ThHTMLAttributes<HTMLTableCellElement>\n>(({ className, ...props }, ref) => (\n\t<th\n\t\tref={ref}\n\t\tclassName={cn(\n\t\t\t\"h-[var(--control-height-md,2.5rem)] px-[var(--space-4,1rem)] text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0\",\n\t\t\tclassName,\n\t\t)}\n\t\t{...props}\n\t/>\n));\nTableHead.displayName = \"TableHead\";\n\n/** `<td>` with consistent padding. */\nconst TableCell = React.forwardRef<\n\tHTMLTableCellElement,\n\tReact.TdHTMLAttributes<HTMLTableCellElement>\n>(({ className, ...props }, ref) => (\n\t<td\n\t\tref={ref}\n\t\tclassName={cn(\"p-[var(--space-4,1rem)] align-middle [&:has([role=checkbox])]:pr-0\", className)}\n\t\t{...props}\n\t/>\n));\nTableCell.displayName = \"TableCell\";\n\n/**\n * Visible `<caption>` rendered below the table. The parent `<Table>` sets\n * `caption-bottom`, so the caption is announced first by screen readers when\n * entering the table, then visually placed below the rows.\n */\nconst TableCaption = React.forwardRef<\n\tHTMLTableCaptionElement,\n\tReact.HTMLAttributes<HTMLTableCaptionElement>\n>(({ className, ...props }, ref) => (\n\t<caption\n\t\tref={ref}\n\t\tclassName={cn(\n\t\t\t\"caption-bottom mt-[var(--space-4,1rem)] text-sm text-muted-foreground\",\n\t\t\tclassName,\n\t\t)}\n\t\t{...props}\n\t/>\n));\nTableCaption.displayName = \"TableCaption\";\n\nexport {\n\tTable,\n\tTableHeader,\n\tTableBody,\n\tTableFooter,\n\tTableHead,\n\tTableRow,\n\tTableCell,\n\tTableCaption,\n};\n"]}
|
package/dist/tabs.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { Tabs_alias_1 as Tabs } from './_tsup-dts-rollup.js';
|
|
2
|
+
export { TabsList_alias_1 as TabsList } from './_tsup-dts-rollup.js';
|
|
3
|
+
export { TabsTrigger_alias_1 as TabsTrigger } from './_tsup-dts-rollup.js';
|
|
4
|
+
export { TabsContent_alias_1 as TabsContent } from './_tsup-dts-rollup.js';
|
package/dist/tabs.js
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import * as TabsPrimitive from '@radix-ui/react-tabs';
|
|
4
|
+
import { clsx } from 'clsx';
|
|
5
|
+
import { twMerge } from 'tailwind-merge';
|
|
6
|
+
import { jsx } from 'react/jsx-runtime';
|
|
7
|
+
|
|
8
|
+
function cn(...inputs) {
|
|
9
|
+
return twMerge(clsx(inputs));
|
|
10
|
+
}
|
|
11
|
+
var Tabs = TabsPrimitive.Root;
|
|
12
|
+
var TabsList = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
13
|
+
TabsPrimitive.List,
|
|
14
|
+
{
|
|
15
|
+
ref,
|
|
16
|
+
className: cn(
|
|
17
|
+
"inline-flex h-[var(--control-height-md,2.5rem)] items-center justify-center rounded-md border border-foreground/[0.06] bg-muted p-[var(--space-1,0.25rem)] text-muted-foreground",
|
|
18
|
+
className
|
|
19
|
+
),
|
|
20
|
+
...props
|
|
21
|
+
}
|
|
22
|
+
));
|
|
23
|
+
TabsList.displayName = "TabsList";
|
|
24
|
+
var TabsTrigger = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
25
|
+
TabsPrimitive.Trigger,
|
|
26
|
+
{
|
|
27
|
+
ref,
|
|
28
|
+
className: cn(
|
|
29
|
+
"inline-flex items-center justify-center whitespace-nowrap rounded-sm px-[var(--space-3,0.75rem)] py-1.5 text-sm font-medium",
|
|
30
|
+
"transition-all duration-[var(--duration-normal,200ms)] ease-out",
|
|
31
|
+
"ring-offset-background hover:text-foreground",
|
|
32
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
|
33
|
+
"disabled:pointer-events-none disabled:opacity-50",
|
|
34
|
+
"data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm",
|
|
35
|
+
className
|
|
36
|
+
),
|
|
37
|
+
...props
|
|
38
|
+
}
|
|
39
|
+
));
|
|
40
|
+
TabsTrigger.displayName = "TabsTrigger";
|
|
41
|
+
var TabsContent = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
42
|
+
TabsPrimitive.Content,
|
|
43
|
+
{
|
|
44
|
+
ref,
|
|
45
|
+
className: cn(
|
|
46
|
+
"mt-[var(--space-2,0.5rem)] ring-offset-background",
|
|
47
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
|
48
|
+
className
|
|
49
|
+
),
|
|
50
|
+
...props
|
|
51
|
+
}
|
|
52
|
+
));
|
|
53
|
+
TabsContent.displayName = "TabsContent";
|
|
54
|
+
|
|
55
|
+
export { Tabs, TabsContent, TabsList, TabsTrigger };
|
|
56
|
+
//# sourceMappingURL=tabs.js.map
|
|
57
|
+
//# sourceMappingURL=tabs.js.map
|
package/dist/tabs.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/utils.ts","../src/components/tabs/tabs.tsx"],"names":[],"mappings":";;;;;;AAQO,SAAS,MAAM,MAAA,EAAsB;AAC3C,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC5B;ACHA,IAAM,IAAA,GAAqB,aAAA,CAAA;AAG3B,IAAM,QAAA,GAAiB,iBAGrB,CAAC,EAAE,WAAW,GAAG,KAAA,IAAS,GAAA,qBAC3B,GAAA;AAAA,EAAe,aAAA,CAAA,IAAA;AAAA,EAAd;AAAA,IACA,GAAA;AAAA,IACA,SAAA,EAAW,EAAA;AAAA,MACV,kLAAA;AAAA,MACA;AAAA,KACD;AAAA,IACC,GAAG;AAAA;AACL,CACA;AACD,QAAA,CAAS,WAAA,GAAc,UAAA;AAGvB,IAAM,WAAA,GAAoB,iBAGxB,CAAC,EAAE,WAAW,GAAG,KAAA,IAAS,GAAA,qBAC3B,GAAA;AAAA,EAAe,aAAA,CAAA,OAAA;AAAA,EAAd;AAAA,IACA,GAAA;AAAA,IACA,SAAA,EAAW,EAAA;AAAA,MACV,6HAAA;AAAA,MACA,iEAAA;AAAA,MACA,8CAAA;AAAA,MACA,qGAAA;AAAA,MACA,kDAAA;AAAA,MACA,qGAAA;AAAA,MACA;AAAA,KACD;AAAA,IACC,GAAG;AAAA;AACL,CACA;AACD,WAAA,CAAY,WAAA,GAAc,aAAA;AAG1B,IAAM,WAAA,GAAoB,iBAGxB,CAAC,EAAE,WAAW,GAAG,KAAA,IAAS,GAAA,qBAC3B,GAAA;AAAA,EAAe,aAAA,CAAA,OAAA;AAAA,EAAd;AAAA,IACA,GAAA;AAAA,IACA,SAAA,EAAW,EAAA;AAAA,MACV,mDAAA;AAAA,MACA,qGAAA;AAAA,MACA;AAAA,KACD;AAAA,IACC,GAAG;AAAA;AACL,CACA;AACD,WAAA,CAAY,WAAA,GAAc,aAAA","file":"tabs.js","sourcesContent":["import { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\n/**\n * Merge class names with Tailwind CSS conflict resolution.\n * @param inputs - Class values (strings, arrays, objects) to merge\n * @returns A single merged class string with Tailwind conflicts resolved\n */\nexport function cn(...inputs: ClassValue[]) {\n\treturn twMerge(clsx(inputs));\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport * as TabsPrimitive from \"@radix-ui/react-tabs\";\nimport { cn } from \"../../lib/utils.js\";\n\n/** Root container for a tabbed interface. */\nconst Tabs = TabsPrimitive.Root;\n\n/** A horizontal list of tab triggers. */\nconst TabsList = React.forwardRef<\n\tReact.ComponentRef<typeof TabsPrimitive.List>,\n\tReact.ComponentPropsWithoutRef<typeof TabsPrimitive.List>\n>(({ className, ...props }, ref) => (\n\t<TabsPrimitive.List\n\t\tref={ref}\n\t\tclassName={cn(\n\t\t\t\"inline-flex h-[var(--control-height-md,2.5rem)] items-center justify-center rounded-md border border-foreground/[0.06] bg-muted p-[var(--space-1,0.25rem)] text-muted-foreground\",\n\t\t\tclassName,\n\t\t)}\n\t\t{...props}\n\t/>\n));\nTabsList.displayName = \"TabsList\";\n\n/** A clickable tab trigger that activates its associated content panel. */\nconst TabsTrigger = React.forwardRef<\n\tReact.ComponentRef<typeof TabsPrimitive.Trigger>,\n\tReact.ComponentPropsWithoutRef<typeof TabsPrimitive.Trigger>\n>(({ className, ...props }, ref) => (\n\t<TabsPrimitive.Trigger\n\t\tref={ref}\n\t\tclassName={cn(\n\t\t\t\"inline-flex items-center justify-center whitespace-nowrap rounded-sm px-[var(--space-3,0.75rem)] py-1.5 text-sm font-medium\",\n\t\t\t\"transition-all duration-[var(--duration-normal,200ms)] ease-out\",\n\t\t\t\"ring-offset-background hover:text-foreground\",\n\t\t\t\"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\",\n\t\t\t\"disabled:pointer-events-none disabled:opacity-50\",\n\t\t\t\"data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm\",\n\t\t\tclassName,\n\t\t)}\n\t\t{...props}\n\t/>\n));\nTabsTrigger.displayName = \"TabsTrigger\";\n\n/** The content panel associated with a tab trigger. */\nconst TabsContent = React.forwardRef<\n\tReact.ComponentRef<typeof TabsPrimitive.Content>,\n\tReact.ComponentPropsWithoutRef<typeof TabsPrimitive.Content>\n>(({ className, ...props }, ref) => (\n\t<TabsPrimitive.Content\n\t\tref={ref}\n\t\tclassName={cn(\n\t\t\t\"mt-[var(--space-2,0.5rem)] ring-offset-background\",\n\t\t\t\"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\",\n\t\t\tclassName,\n\t\t)}\n\t\t{...props}\n\t/>\n));\nTabsContent.displayName = \"TabsContent\";\n\nexport { Tabs, TabsList, TabsTrigger, TabsContent };\n"]}
|
package/dist/textarea.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { clsx } from 'clsx';
|
|
3
|
+
import { twMerge } from 'tailwind-merge';
|
|
4
|
+
import { jsx } from 'react/jsx-runtime';
|
|
5
|
+
|
|
6
|
+
// src/primitives/textarea/textarea.tsx
|
|
7
|
+
function cn(...inputs) {
|
|
8
|
+
return twMerge(clsx(inputs));
|
|
9
|
+
}
|
|
10
|
+
var Textarea = React.forwardRef(
|
|
11
|
+
({ className, ...props }, ref) => {
|
|
12
|
+
return /* @__PURE__ */ jsx(
|
|
13
|
+
"textarea",
|
|
14
|
+
{
|
|
15
|
+
className: cn(
|
|
16
|
+
"flex min-h-[80px] w-full rounded-md border border-input bg-background px-[var(--space-3,0.75rem)] py-[var(--space-2,0.5rem)] text-sm",
|
|
17
|
+
"transition-all duration-[var(--duration-normal,200ms)] ease-out",
|
|
18
|
+
"shadow-sm inset-ring-1 inset-ring-foreground/[0.06]",
|
|
19
|
+
"placeholder:text-muted-foreground",
|
|
20
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
|
21
|
+
"focus-visible:shadow-md focus-visible:border-ring/50",
|
|
22
|
+
"hover:border-ring/30 hover:shadow-md",
|
|
23
|
+
"disabled:cursor-not-allowed disabled:opacity-50",
|
|
24
|
+
className
|
|
25
|
+
),
|
|
26
|
+
ref,
|
|
27
|
+
...props
|
|
28
|
+
}
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
);
|
|
32
|
+
Textarea.displayName = "Textarea";
|
|
33
|
+
|
|
34
|
+
export { Textarea };
|
|
35
|
+
//# sourceMappingURL=textarea.js.map
|
|
36
|
+
//# sourceMappingURL=textarea.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/utils.ts","../src/primitives/textarea/textarea.tsx"],"names":[],"mappings":";;;;;;AAQO,SAAS,MAAM,MAAA,EAAsB;AAC3C,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC5B;ACDA,IAAM,QAAA,GAAiB,KAAA,CAAA,UAAA;AAAA,EACtB,CAAC,EAAE,SAAA,EAAW,GAAG,KAAA,IAAS,GAAA,KAAQ;AACjC,IAAA,uBACC,GAAA;AAAA,MAAC,UAAA;AAAA,MAAA;AAAA,QACA,SAAA,EAAW,EAAA;AAAA,UACV,sIAAA;AAAA,UACA,iEAAA;AAAA,UACA,qDAAA;AAAA,UACA,mCAAA;AAAA,UACA,qGAAA;AAAA,UACA,sDAAA;AAAA,UACA,sCAAA;AAAA,UACA,iDAAA;AAAA,UACA;AAAA,SACD;AAAA,QACA,GAAA;AAAA,QACC,GAAG;AAAA;AAAA,KACL;AAAA,EAEF;AACD;AACA,QAAA,CAAS,WAAA,GAAc,UAAA","file":"textarea.js","sourcesContent":["import { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\n/**\n * Merge class names with Tailwind CSS conflict resolution.\n * @param inputs - Class values (strings, arrays, objects) to merge\n * @returns A single merged class string with Tailwind conflicts resolved\n */\nexport function cn(...inputs: ClassValue[]) {\n\treturn twMerge(clsx(inputs));\n}\n","import * as React from \"react\";\nimport { cn } from \"../../lib/utils.js\";\n\n/**\n * A styled multi-line text input with smooth focus transitions and shadow effects.\n * Extends the native HTML textarea element with Hex UI styling.\n */\nexport type TextareaProps = React.TextareaHTMLAttributes<HTMLTextAreaElement>;\n\nconst Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(\n\t({ className, ...props }, ref) => {\n\t\treturn (\n\t\t\t<textarea\n\t\t\t\tclassName={cn(\n\t\t\t\t\t\"flex min-h-[80px] w-full rounded-md border border-input bg-background px-[var(--space-3,0.75rem)] py-[var(--space-2,0.5rem)] text-sm\",\n\t\t\t\t\t\"transition-all duration-[var(--duration-normal,200ms)] ease-out\",\n\t\t\t\t\t\"shadow-sm inset-ring-1 inset-ring-foreground/[0.06]\",\n\t\t\t\t\t\"placeholder:text-muted-foreground\",\n\t\t\t\t\t\"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\",\n\t\t\t\t\t\"focus-visible:shadow-md focus-visible:border-ring/50\",\n\t\t\t\t\t\"hover:border-ring/30 hover:shadow-md\",\n\t\t\t\t\t\"disabled:cursor-not-allowed disabled:opacity-50\",\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\tref={ref}\n\t\t\t\t{...props}\n\t\t\t/>\n\t\t);\n\t},\n);\nTextarea.displayName = \"Textarea\";\n\nexport { Textarea };\n"]}
|