@avenue-ticketing/ui 0.3.0 → 0.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.
Files changed (74) hide show
  1. package/dist/react/avatar.d.ts +42 -0
  2. package/dist/react/avatar.js +159 -0
  3. package/dist/react/avatar.js.map +1 -0
  4. package/dist/react/badge.d.ts +12 -0
  5. package/dist/react/badge.js +35 -1
  6. package/dist/react/badge.js.map +1 -1
  7. package/dist/react/button.d.ts +1 -1
  8. package/dist/react/button.js +3 -3
  9. package/dist/react/button.js.map +1 -1
  10. package/dist/react/calendar.d.ts +13 -0
  11. package/dist/react/calendar.js +4639 -0
  12. package/dist/react/calendar.js.map +1 -0
  13. package/dist/react/card.d.ts +11 -0
  14. package/dist/react/card.js +113 -0
  15. package/dist/react/card.js.map +1 -0
  16. package/dist/react/checkbox.d.ts +11 -0
  17. package/dist/react/checkbox.js +131 -0
  18. package/dist/react/checkbox.js.map +1 -0
  19. package/dist/react/datetime-picker.d.ts +21 -0
  20. package/dist/react/datetime-picker.js +6124 -0
  21. package/dist/react/datetime-picker.js.map +1 -0
  22. package/dist/react/dialog.d.ts +7 -0
  23. package/dist/react/dialog.js +211 -90
  24. package/dist/react/dialog.js.map +1 -1
  25. package/dist/react/dropdown.d.ts +126 -0
  26. package/dist/react/dropdown.js +1269 -0
  27. package/dist/react/dropdown.js.map +1 -0
  28. package/dist/react/input.d.ts +7 -0
  29. package/dist/react/input.js +15 -2
  30. package/dist/react/input.js.map +1 -1
  31. package/dist/react/pagination.d.ts +28 -0
  32. package/dist/react/pagination.js +262 -0
  33. package/dist/react/pagination.js.map +1 -0
  34. package/dist/react/popover.d.ts +76 -0
  35. package/dist/react/popover.js +564 -0
  36. package/dist/react/popover.js.map +1 -0
  37. package/dist/react/scroll-header.js +13 -1
  38. package/dist/react/scroll-header.js.map +1 -1
  39. package/dist/react/scroll-wheel.d.ts +45 -0
  40. package/dist/react/scroll-wheel.js +557 -0
  41. package/dist/react/scroll-wheel.js.map +1 -0
  42. package/dist/react/select.d.ts +62 -0
  43. package/dist/react/select.js +889 -0
  44. package/dist/react/select.js.map +1 -0
  45. package/dist/react/sheet.js +1 -1
  46. package/dist/react/sheet.js.map +1 -1
  47. package/dist/react/switch.d.ts +38 -0
  48. package/dist/react/switch.js +117 -0
  49. package/dist/react/switch.js.map +1 -0
  50. package/dist/react/table-pagination.d.ts +15 -0
  51. package/dist/react/table-pagination.js +1153 -0
  52. package/dist/react/table-pagination.js.map +1 -0
  53. package/dist/react/table-view/column-menu.d.ts +15 -0
  54. package/dist/react/table-view/column-menu.js +918 -0
  55. package/dist/react/table-view/column-menu.js.map +1 -0
  56. package/dist/react/table-view/index.d.ts +70 -0
  57. package/dist/react/table-view/index.js +2155 -0
  58. package/dist/react/table-view/index.js.map +1 -0
  59. package/dist/react/table.d.ts +86 -0
  60. package/dist/react/table.js +414 -0
  61. package/dist/react/table.js.map +1 -0
  62. package/dist/react/tabs.d.ts +9 -3
  63. package/dist/react/tabs.js +217 -57
  64. package/dist/react/tabs.js.map +1 -1
  65. package/dist/react/textarea.d.ts +6 -0
  66. package/dist/react/textarea.js +33 -0
  67. package/dist/react/textarea.js.map +1 -0
  68. package/dist/react/time-picker.d.ts +22 -0
  69. package/dist/react/time-picker.js +856 -0
  70. package/dist/react/time-picker.js.map +1 -0
  71. package/dist/react/tooltip.d.ts +45 -0
  72. package/dist/react/tooltip.js +540 -0
  73. package/dist/react/tooltip.js.map +1 -0
  74. package/package.json +1 -1
@@ -1,11 +1,12 @@
1
1
  import * as React from 'react';
2
2
  import { clsx } from 'clsx';
3
3
  import { twMerge } from 'tailwind-merge';
4
- import { jsx, jsxs } from 'react/jsx-runtime';
4
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
5
5
 
6
6
  function cn(...inputs) {
7
7
  return twMerge(clsx(inputs));
8
8
  }
9
+ var MD_UP = "(min-width: 768px)";
9
10
  var TabsContext = React.createContext(null);
10
11
  function useTabs() {
11
12
  const context = React.useContext(TabsContext);
@@ -21,11 +22,21 @@ var Tabs = ({
21
22
  children,
22
23
  className,
23
24
  variant = "pill",
25
+ alignment = "horizontal",
24
26
  ...props
25
27
  }) => {
26
28
  const [internalValue, setInternalValue] = React.useState(defaultValue);
29
+ const [isMdUp, setIsMdUp] = React.useState(false);
27
30
  const isControlled = controlledValue !== void 0;
28
31
  const value = isControlled ? controlledValue : internalValue;
32
+ React.useEffect(() => {
33
+ const mq = window.matchMedia(MD_UP);
34
+ const sync = () => setIsMdUp(mq.matches);
35
+ sync();
36
+ mq.addEventListener("change", sync);
37
+ return () => mq.removeEventListener("change", sync);
38
+ }, []);
39
+ const effectiveAlignment = alignment === "vertical" && isMdUp ? "vertical" : "horizontal";
29
40
  const handleValueChange = React.useCallback(
30
41
  (newValue) => {
31
42
  if (!isControlled) {
@@ -38,8 +49,24 @@ var Tabs = ({
38
49
  return /* @__PURE__ */ jsx(
39
50
  TabsContext.Provider,
40
51
  {
41
- value: { value, onValueChange: handleValueChange, variant },
42
- children: /* @__PURE__ */ jsx("div", { className: cn("flex flex-col gap-4", className), ...props, children })
52
+ value: {
53
+ value,
54
+ onValueChange: handleValueChange,
55
+ variant,
56
+ alignment: effectiveAlignment
57
+ },
58
+ children: /* @__PURE__ */ jsx(
59
+ "div",
60
+ {
61
+ className: cn(
62
+ "flex gap-4",
63
+ effectiveAlignment === "vertical" ? "flex-col md:flex-row md:items-stretch" : "flex-col",
64
+ className
65
+ ),
66
+ ...props,
67
+ children
68
+ }
69
+ )
43
70
  }
44
71
  );
45
72
  };
@@ -48,35 +75,84 @@ var TabsList = ({
48
75
  className,
49
76
  ...props
50
77
  }) => {
51
- const { value: activeValue, onValueChange, variant } = useTabs();
78
+ const { value: activeValue, onValueChange, variant, alignment } = useTabs();
79
+ const isVertical = alignment === "vertical";
52
80
  const rowRef = React.useRef(null);
81
+ const scrollRef = React.useRef(null);
82
+ const [scrollEdgesX, setScrollEdgesX] = React.useState("none");
83
+ const [scrollEdgesY, setScrollEdgesY] = React.useState("none");
84
+ const updateScrollEdges = React.useCallback(() => {
85
+ const el = scrollRef.current;
86
+ if (!el) return;
87
+ if (isVertical) {
88
+ const scrollRange = el.scrollHeight - el.clientHeight;
89
+ if (scrollRange < 8) {
90
+ setScrollEdgesY((prev) => prev === "none" ? prev : "none");
91
+ return;
92
+ }
93
+ const canUp = el.scrollTop > 1;
94
+ const canDown = el.scrollTop < scrollRange - 1;
95
+ const next = canUp && canDown ? "both" : canUp ? "up" : canDown ? "down" : "none";
96
+ setScrollEdgesY((prev) => prev === next ? prev : next);
97
+ } else {
98
+ const scrollRange = el.scrollWidth - el.clientWidth;
99
+ if (scrollRange < 8) {
100
+ setScrollEdgesX((prev) => prev === "none" ? prev : "none");
101
+ return;
102
+ }
103
+ const canLeft = el.scrollLeft > 1;
104
+ const canRight = el.scrollLeft < scrollRange - 1;
105
+ const next = canLeft && canRight ? "both" : canLeft ? "left" : canRight ? "right" : "none";
106
+ setScrollEdgesX((prev) => prev === next ? prev : next);
107
+ }
108
+ }, [isVertical]);
109
+ React.useEffect(() => {
110
+ const el = scrollRef.current;
111
+ if (!el) return;
112
+ updateScrollEdges();
113
+ el.addEventListener("scroll", updateScrollEdges, { passive: true });
114
+ window.addEventListener("resize", updateScrollEdges, { passive: true });
115
+ return () => {
116
+ el.removeEventListener("scroll", updateScrollEdges);
117
+ window.removeEventListener("resize", updateScrollEdges);
118
+ };
119
+ }, [updateScrollEdges, children, isVertical]);
53
120
  const updateIndicatorClip = React.useCallback(() => {
54
121
  const row = rowRef.current;
55
- if (!row || variant !== "pill" && variant !== "underline") return;
122
+ if (!row || variant !== "pill" && variant !== "underline" && variant !== "box")
123
+ return;
56
124
  const tab = row.querySelector(
57
- '[role="tab"][aria-selected="true"]'
125
+ '[role="tab"][aria-selected="true"]:not(:disabled)'
58
126
  );
59
127
  if (!tab) {
60
128
  row.style.setProperty("--tab-indicator-start", "0px");
61
129
  row.style.setProperty("--tab-indicator-end", "0px");
62
130
  return;
63
131
  }
64
- const start = tab.offsetLeft;
65
- const end = tab.offsetLeft + tab.offsetWidth;
66
- row.style.setProperty("--tab-indicator-start", `${start}px`);
67
- row.style.setProperty("--tab-indicator-end", `${end}px`);
68
- }, [variant]);
132
+ if (isVertical) {
133
+ const start = tab.offsetTop;
134
+ const end = tab.offsetTop + tab.offsetHeight;
135
+ row.style.setProperty("--tab-indicator-start", `${start}px`);
136
+ row.style.setProperty("--tab-indicator-end", `${end}px`);
137
+ } else {
138
+ const start = tab.offsetLeft;
139
+ const end = tab.offsetLeft + tab.offsetWidth;
140
+ row.style.setProperty("--tab-indicator-start", `${start}px`);
141
+ row.style.setProperty("--tab-indicator-end", `${end}px`);
142
+ }
143
+ }, [variant, isVertical]);
69
144
  React.useLayoutEffect(() => {
70
- if (variant === "pill" || variant === "underline") updateIndicatorClip();
145
+ if (variant === "pill" || variant === "underline" || variant === "box")
146
+ updateIndicatorClip();
71
147
  }, [activeValue, children, updateIndicatorClip, variant]);
72
148
  React.useEffect(() => {
73
- if (variant !== "pill" && variant !== "underline") return;
149
+ if (variant !== "pill" && variant !== "underline" && variant !== "box") return;
74
150
  const onResize = () => updateIndicatorClip();
75
151
  window.addEventListener("resize", onResize, { passive: true });
76
152
  return () => window.removeEventListener("resize", onResize);
77
153
  }, [updateIndicatorClip, activeValue, variant]);
78
154
  React.useEffect(() => {
79
- if (variant !== "pill" && variant !== "underline") return;
155
+ if (variant !== "pill" && variant !== "underline" && variant !== "box") return;
80
156
  const el = rowRef.current;
81
157
  if (!el || typeof ResizeObserver === "undefined") return;
82
158
  const ro = new ResizeObserver(() => updateIndicatorClip());
@@ -85,13 +161,13 @@ var TabsList = ({
85
161
  }, [updateIndicatorClip, variant]);
86
162
  const handleKeyDown = React.useCallback(
87
163
  (e) => {
88
- const dir = e.key === "ArrowRight" ? 1 : e.key === "ArrowLeft" ? -1 : 0;
164
+ const dir = isVertical ? e.key === "ArrowDown" ? 1 : e.key === "ArrowUp" ? -1 : 0 : e.key === "ArrowRight" ? 1 : e.key === "ArrowLeft" ? -1 : 0;
89
165
  if (!dir) return;
90
166
  const row = rowRef.current;
91
167
  if (!row) return;
92
168
  const tabs = Array.from(
93
169
  row.querySelectorAll('[role="tab"][data-tab-value]')
94
- );
170
+ ).filter((t) => !t.disabled);
95
171
  if (tabs.length === 0) return;
96
172
  const values = tabs.map((t) => t.dataset.tabValue);
97
173
  let idx = activeValue ? values.indexOf(activeValue) : 0;
@@ -104,28 +180,75 @@ var TabsList = ({
104
180
  tabs[next]?.focus();
105
181
  }
106
182
  },
107
- [activeValue, onValueChange]
183
+ [activeValue, onValueChange, isVertical]
108
184
  );
185
+ const maskStyle = React.useMemo(() => {
186
+ const fade = "24px";
187
+ if (isVertical) {
188
+ if (scrollEdgesY === "none") return void 0;
189
+ const masks2 = {
190
+ down: `linear-gradient(to bottom, black calc(100% - ${fade}), transparent)`,
191
+ up: `linear-gradient(to top, black calc(100% - ${fade}), transparent)`,
192
+ both: `linear-gradient(to bottom, transparent, black ${fade}, black calc(100% - ${fade}), transparent)`,
193
+ none: ""
194
+ };
195
+ return {
196
+ WebkitMaskImage: masks2[scrollEdgesY],
197
+ maskImage: masks2[scrollEdgesY]
198
+ };
199
+ }
200
+ if (scrollEdgesX === "none") return void 0;
201
+ const masks = {
202
+ right: `linear-gradient(to right, black calc(100% - ${fade}), transparent)`,
203
+ left: `linear-gradient(to left, black calc(100% - ${fade}), transparent)`,
204
+ both: `linear-gradient(to right, transparent, black ${fade}, black calc(100% - ${fade}), transparent)`,
205
+ none: ""
206
+ };
207
+ return {
208
+ WebkitMaskImage: masks[scrollEdgesX],
209
+ maskImage: masks[scrollEdgesX]
210
+ };
211
+ }, [scrollEdgesX, scrollEdgesY, isVertical]);
212
+ const pillClipHorizontal = "inset(0 calc(100% - var(--tab-indicator-end, 0px)) 0 var(--tab-indicator-start, 0px) round 9999px)";
213
+ const pillClipVertical = "inset(var(--tab-indicator-start, 0px) 0 calc(100% - var(--tab-indicator-end, 0px)) 0 round 9999px)";
214
+ const boxClipHorizontal = "inset(0 calc(100% - var(--tab-indicator-end, 0px)) 0 var(--tab-indicator-start, 0px) round 12px)";
215
+ const boxClipVertical = "inset(var(--tab-indicator-start, 0px) 0 calc(100% - var(--tab-indicator-end, 0px)) 0 round 12px)";
216
+ const underlineClipHorizontal = "inset(0 calc(100% - var(--tab-indicator-end, 0px)) 0 var(--tab-indicator-start, 0px))";
217
+ const underlineClipVertical = "inset(var(--tab-indicator-start, 0px) 0 calc(100% - var(--tab-indicator-end, 0px)) 0)";
109
218
  return /* @__PURE__ */ jsx(
110
219
  "div",
111
220
  {
221
+ ref: scrollRef,
112
222
  onKeyDown: handleKeyDown,
113
223
  className: cn(
114
- "max-w-full overflow-x-auto no-scrollbar",
115
- variant === "pill" ? "pb-1" : "pb-0",
224
+ isVertical ? "max-h-72 min-h-0 w-full max-w-52 shrink-0 overflow-x-hidden overflow-y-auto md:max-h-none md:max-w-56" : "max-w-full overflow-x-auto",
225
+ "[scrollbar-width:none] [-ms-overflow-style:none] [&::-webkit-scrollbar]:hidden",
226
+ variant === "pill" && !isVertical && "pb-1",
227
+ variant === "box" && !isVertical && "pb-1",
228
+ variant === "underline" && !isVertical && "pb-0",
229
+ variant === "underline" && isVertical && "pr-0",
116
230
  className
117
231
  ),
232
+ style: maskStyle,
118
233
  ...props,
119
234
  children: /* @__PURE__ */ jsxs(
120
235
  "div",
121
236
  {
122
237
  ref: rowRef,
123
238
  role: "tablist",
239
+ "aria-orientation": isVertical ? "vertical" : "horizontal",
124
240
  className: cn(
125
- "inline-flex w-max min-w-full items-center",
126
- (variant === "pill" || variant === "underline") && "relative",
241
+ "flex",
242
+ isVertical ? "w-full flex-col items-stretch" : cn(
243
+ "inline-flex w-max min-w-full",
244
+ variant === "box" ? "items-stretch" : "items-center"
245
+ ),
246
+ (variant === "pill" || variant === "underline" || variant === "box") && "relative",
127
247
  variant === "pill" && "gap-1",
128
- variant === "underline" && "gap-2 rounded-none border-b border-border bg-transparent py-0"
248
+ variant === "box" && "gap-2",
249
+ variant === "pill" && isVertical && "px-1 py-1",
250
+ variant === "box" && isVertical && "px-1 py-1",
251
+ variant === "underline" && (isVertical ? "gap-0 rounded-none border-l border-border bg-transparent py-0 pl-0" : "gap-2 rounded-none border-b border-border bg-transparent py-0")
129
252
  ),
130
253
  children: [
131
254
  variant === "pill" && /* @__PURE__ */ jsx(
@@ -134,10 +257,26 @@ var TabsList = ({
134
257
  "aria-hidden": "true",
135
258
  "data-slot": "tabs-indicator",
136
259
  style: {
137
- clipPath: "inset(0 calc(100% - var(--tab-indicator-end, 0px)) 0 var(--tab-indicator-start, 0px) round 9999px)"
260
+ clipPath: isVertical ? pillClipVertical : pillClipHorizontal
138
261
  },
139
262
  className: cn(
140
- "pointer-events-none absolute inset-x-0 top-0 z-0 h-9 rounded-full bg-primary",
263
+ "pointer-events-none absolute z-0 bg-primary",
264
+ "motion-reduce:transition-none",
265
+ "motion-safe:transition-[clip-path] motion-safe:duration-300 motion-safe:ease-[cubic-bezier(0,0.55,0.45,1)]",
266
+ isVertical ? "inset-y-0 left-0 right-0" : "inset-x-0 top-0 h-9 rounded-full"
267
+ )
268
+ }
269
+ ),
270
+ variant === "box" && /* @__PURE__ */ jsx(
271
+ "div",
272
+ {
273
+ "aria-hidden": "true",
274
+ "data-slot": "tabs-box-indicator",
275
+ style: {
276
+ clipPath: isVertical ? boxClipVertical : boxClipHorizontal
277
+ },
278
+ className: cn(
279
+ "pointer-events-none absolute inset-y-0 left-0 right-0 z-0 bg-primary",
141
280
  "motion-reduce:transition-none",
142
281
  "motion-safe:transition-[clip-path] motion-safe:duration-300 motion-safe:ease-[cubic-bezier(0,0.55,0.45,1)]"
143
282
  )
@@ -149,12 +288,13 @@ var TabsList = ({
149
288
  "aria-hidden": "true",
150
289
  "data-slot": "tabs-underline-indicator",
151
290
  style: {
152
- clipPath: "inset(0 calc(100% - var(--tab-indicator-end, 0px)) 0 var(--tab-indicator-start, 0px))"
291
+ clipPath: isVertical ? underlineClipVertical : underlineClipHorizontal
153
292
  },
154
293
  className: cn(
155
- "pointer-events-none absolute inset-x-0 bottom-0 z-0 h-0.5 bg-primary",
294
+ "pointer-events-none absolute z-0 bg-primary",
156
295
  "motion-reduce:transition-none",
157
- "motion-safe:transition-[clip-path] motion-safe:duration-300 motion-safe:ease-[cubic-bezier(0,0.55,0.45,1)]"
296
+ "motion-safe:transition-[clip-path] motion-safe:duration-300 motion-safe:ease-[cubic-bezier(0,0.55,0.45,1)]",
297
+ isVertical ? "inset-y-0 left-0 w-0.5" : "inset-x-0 bottom-0 h-0.5"
158
298
  )
159
299
  }
160
300
  ),
@@ -170,67 +310,84 @@ var TabsTrigger = ({
170
310
  children,
171
311
  icon,
172
312
  iconPosition = "left",
313
+ layout = "row",
173
314
  onClick,
174
315
  className,
175
316
  disabled,
176
317
  ...props
177
318
  }) => {
178
- const { value: activeValue, onValueChange, variant } = useTabs();
319
+ const { value: activeValue, onValueChange, variant, alignment } = useTabs();
320
+ const isVertical = alignment === "vertical";
179
321
  const isActive = value ? activeValue === value : false;
322
+ const showSelected = isActive && !disabled;
323
+ const isStacked = layout === "stacked" && Boolean(icon);
324
+ const iconWrapClass = "inline-flex shrink-0 items-center justify-center [&_svg]:shrink-0";
325
+ const labelWrapClass = "block min-w-0 w-full text-left leading-snug";
180
326
  return /* @__PURE__ */ jsxs(
181
327
  "button",
182
328
  {
183
329
  type: "button",
184
330
  role: "tab",
185
331
  "aria-selected": isActive,
186
- tabIndex: value !== void 0 ? isActive ? 0 : -1 : void 0,
332
+ "aria-disabled": disabled || void 0,
333
+ tabIndex: value !== void 0 ? isActive && !disabled ? 0 : -1 : void 0,
187
334
  disabled,
188
335
  "data-tab-value": value,
189
336
  onClick: (e) => {
337
+ if (disabled) return;
190
338
  if (value) onValueChange(value);
191
339
  onClick?.(e);
192
340
  },
193
341
  className: cn(
194
- "relative z-1 inline-flex shrink-0 cursor-pointer select-none items-center justify-center gap-2 whitespace-nowrap touch-manipulation [-webkit-tap-highlight-color:transparent]",
342
+ "relative z-1 inline-flex shrink-0 select-none touch-manipulation [-webkit-tap-highlight-color:transparent]",
343
+ "cursor-pointer disabled:cursor-not-allowed",
344
+ isStacked ? "flex-col items-start justify-start gap-1.5 whitespace-normal" : "items-center justify-center gap-2 whitespace-nowrap",
345
+ isVertical && "w-full justify-start",
195
346
  variant === "pill" && [
196
347
  "h-9 rounded-full px-4 font-semibold leading-5 text-[13px] md:text-[15px]",
197
348
  "[transition:background-color_var(--duration-short-s,0.1s)_var(--ease-out,cubic-bezier(0,.55,.45,1)),border-color_var(--duration-short-s,0.1s)_var(--ease-out,cubic-bezier(0,.55,.45,1)),scale_var(--duration-short-s,0.1s)_var(--ease-out,cubic-bezier(0,.55,.45,1)),color_var(--duration-short-m,0.2s)_var(--ease-in-out,cubic-bezier(.85,0,.15,1))]",
198
- "active:scale-[0.96] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
199
- isActive ? [
349
+ !isVertical && "enabled:active:scale-[0.96]",
350
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
351
+ showSelected ? [
352
+ "text-background",
353
+ "**:data-[slot=badge]:border-none **:data-[slot=badge]:bg-background/20 **:data-[slot=badge]:text-background"
354
+ ] : "bg-primary/4 text-primary/50 enabled:[@media(hover:hover)_and_(pointer:fine)]:hover:bg-primary/10 enabled:active:bg-primary/10"
355
+ ],
356
+ variant === "box" && [
357
+ "min-h-11 rounded-xl px-4 pt-1.5 pb-2 font-semibold leading-5 text-[13px] md:text-[15px]",
358
+ isVertical ? "justify-start text-left" : "justify-center text-center",
359
+ "[transition:background-color_var(--duration-short-s,0.1s)_var(--ease-out,cubic-bezier(0,.55,.45,1)),color_var(--duration-short-m,0.2s)_var(--ease-in-out,cubic-bezier(.85,0,.15,1))]",
360
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
361
+ showSelected ? [
200
362
  "text-background",
201
363
  "**:data-[slot=badge]:border-none **:data-[slot=badge]:bg-background/20 **:data-[slot=badge]:text-background"
202
- ] : "bg-primary/4 text-primary/50 [@media(hover:hover)_and_(pointer:fine)]:hover:bg-primary/10 active:bg-primary/10"
364
+ ] : "bg-transparent text-primary/55 enabled:[@media(hover:hover)_and_(pointer:fine)]:hover:bg-primary/[0.07] enabled:[@media(hover:hover)_and_(pointer:fine)]:hover:text-primary/75"
203
365
  ],
204
366
  variant === "underline" && [
205
- "h-auto rounded-none border-0 bg-transparent px-2 py-2 text-sm font-medium shadow-none",
367
+ "h-auto rounded-none border-0 bg-transparent py-2 text-sm font-medium shadow-none",
368
+ isVertical ? isStacked ? "pl-6 pr-2" : "pl-5 pr-2" : "px-2",
206
369
  "transition-[color,transform] duration-200 ease-in-out",
207
- "motion-reduce:transition-colors motion-reduce:active:scale-100",
208
- "active:scale-[0.98]",
370
+ "motion-reduce:transition-colors motion-reduce:enabled:active:scale-100",
371
+ "enabled:active:scale-[0.98]",
209
372
  "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
210
- isActive ? "text-primary" : "text-primary/50 [@media(hover:hover)_and_(pointer:fine)]:hover:text-primary/70"
373
+ showSelected ? "text-primary" : "text-primary/50 enabled:[@media(hover:hover)_and_(pointer:fine)]:hover:text-primary/70"
211
374
  ],
212
- "disabled:cursor-not-allowed disabled:opacity-50",
375
+ "disabled:opacity-50",
213
376
  className
214
377
  ),
215
378
  ...props,
216
379
  children: [
217
- icon && iconPosition === "left" && /* @__PURE__ */ jsx(
218
- "span",
219
- {
220
- className: "flex size-4 shrink-0 items-center justify-center",
221
- "aria-hidden": true,
222
- children: icon
223
- }
224
- ),
225
- children,
226
- icon && iconPosition === "right" && /* @__PURE__ */ jsx(
227
- "span",
228
- {
229
- className: "flex size-4 shrink-0 items-center justify-center",
230
- "aria-hidden": true,
231
- children: icon
232
- }
233
- )
380
+ isStacked && icon && iconPosition === "left" && /* @__PURE__ */ jsxs(Fragment, { children: [
381
+ /* @__PURE__ */ jsx("span", { className: iconWrapClass, "aria-hidden": true, children: icon }),
382
+ /* @__PURE__ */ jsx("span", { className: labelWrapClass, children })
383
+ ] }),
384
+ isStacked && icon && iconPosition === "right" && /* @__PURE__ */ jsxs(Fragment, { children: [
385
+ /* @__PURE__ */ jsx("span", { className: labelWrapClass, children }),
386
+ /* @__PURE__ */ jsx("span", { className: iconWrapClass, "aria-hidden": true, children: icon })
387
+ ] }),
388
+ !isStacked && icon && iconPosition === "left" && /* @__PURE__ */ jsx("span", { className: iconWrapClass, "aria-hidden": true, children: icon }),
389
+ !isStacked && children,
390
+ !isStacked && icon && iconPosition === "right" && /* @__PURE__ */ jsx("span", { className: iconWrapClass, "aria-hidden": true, children: icon })
234
391
  ]
235
392
  }
236
393
  );
@@ -241,15 +398,18 @@ var TabsContent = ({
241
398
  className,
242
399
  ...props
243
400
  }) => {
244
- const { value: activeValue } = useTabs();
401
+ const { value: activeValue, alignment } = useTabs();
402
+ const isVertical = alignment === "vertical";
245
403
  if (activeValue !== value) return null;
246
404
  return /* @__PURE__ */ jsx(
247
405
  "div",
248
406
  {
249
407
  role: "tabpanel",
250
408
  className: cn(
251
- "animate-in fade-in-0 slide-in-from-top-1 duration-200",
409
+ "animate-in fade-in-0 duration-200",
410
+ isVertical ? "slide-in-from-left-1" : "slide-in-from-top-1",
252
411
  "ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
412
+ isVertical && "min-w-0 flex-1",
253
413
  className
254
414
  ),
255
415
  ...props,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/lib/utils.ts","../../src/react/tabs.tsx"],"names":[],"mappings":";;;;;AAGO,SAAS,MAAM,MAAA,EAAsB;AAC1C,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC7B;ACaA,IAAM,WAAA,GAAoB,oBAIhB,IAAI,CAAA;AAEd,SAAS,OAAA,GAAU;AACjB,EAAA,MAAM,OAAA,GAAgB,iBAAW,WAAW,CAAA;AAC5C,EAAA,IAAI,CAAC,OAAA,EAAS;AACZ,IAAA,MAAM,IAAI,MAAM,gDAAgD,CAAA;AAAA,EAClE;AACA,EAAA,OAAO,OAAA;AACT;AAEO,IAAM,OAA4B,CAAC;AAAA,EACxC,YAAA;AAAA,EACA,KAAA,EAAO,eAAA;AAAA,EACP,aAAA;AAAA,EACA,QAAA;AAAA,EACA,SAAA;AAAA,EACA,OAAA,GAAU,MAAA;AAAA,EACV,GAAG;AACL,CAAA,KAAM;AACJ,EAAA,MAAM,CAAC,aAAA,EAAe,gBAAgB,CAAA,GAAU,eAAS,YAAY,CAAA;AACrE,EAAA,MAAM,eAAe,eAAA,KAAoB,MAAA;AACzC,EAAA,MAAM,KAAA,GAAQ,eAAe,eAAA,GAAkB,aAAA;AAE/C,EAAA,MAAM,iBAAA,GAA0B,KAAA,CAAA,WAAA;AAAA,IAC9B,CAAC,QAAA,KAAqB;AACpB,MAAA,IAAI,CAAC,YAAA,EAAc;AACjB,QAAA,gBAAA,CAAiB,QAAQ,CAAA;AAAA,MAC3B;AACA,MAAA,aAAA,GAAgB,QAAQ,CAAA;AAAA,IAC1B,CAAA;AAAA,IACA,CAAC,cAAc,aAAa;AAAA,GAC9B;AAEA,EAAA,uBACE,GAAA;AAAA,IAAC,WAAA,CAAY,QAAA;AAAA,IAAZ;AAAA,MACC,KAAA,EAAO,EAAE,KAAA,EAAO,aAAA,EAAe,mBAAmB,OAAA,EAAQ;AAAA,MAE1D,QAAA,kBAAA,GAAA,CAAC,SAAI,SAAA,EAAW,EAAA,CAAG,uBAAuB,SAAS,CAAA,EAAI,GAAG,KAAA,EACvD,QAAA,EACH;AAAA;AAAA,GACF;AAEJ;AAIO,IAAM,WAAoC,CAAC;AAAA,EAChD,QAAA;AAAA,EACA,SAAA;AAAA,EACA,GAAG;AACL,CAAA,KAAM;AACJ,EAAA,MAAM,EAAE,KAAA,EAAO,WAAA,EAAa,aAAA,EAAe,OAAA,KAAY,OAAA,EAAQ;AAC/D,EAAA,MAAM,MAAA,GAAe,aAAuB,IAAI,CAAA;AAGhD,EAAA,MAAM,mBAAA,GAA4B,kBAAY,MAAM;AAClD,IAAA,MAAM,MAAM,MAAA,CAAO,OAAA;AACnB,IAAA,IAAI,CAAC,GAAA,IAAQ,OAAA,KAAY,MAAA,IAAU,YAAY,WAAA,EAAc;AAE7D,IAAA,MAAM,MAAM,GAAA,CAAI,aAAA;AAAA,MACd;AAAA,KACF;AACA,IAAA,IAAI,CAAC,GAAA,EAAK;AACR,MAAA,GAAA,CAAI,KAAA,CAAM,WAAA,CAAY,uBAAA,EAAyB,KAAK,CAAA;AACpD,MAAA,GAAA,CAAI,KAAA,CAAM,WAAA,CAAY,qBAAA,EAAuB,KAAK,CAAA;AAClD,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,QAAQ,GAAA,CAAI,UAAA;AAClB,IAAA,MAAM,GAAA,GAAM,GAAA,CAAI,UAAA,GAAa,GAAA,CAAI,WAAA;AACjC,IAAA,GAAA,CAAI,KAAA,CAAM,WAAA,CAAY,uBAAA,EAAyB,CAAA,EAAG,KAAK,CAAA,EAAA,CAAI,CAAA;AAC3D,IAAA,GAAA,CAAI,KAAA,CAAM,WAAA,CAAY,qBAAA,EAAuB,CAAA,EAAG,GAAG,CAAA,EAAA,CAAI,CAAA;AAAA,EACzD,CAAA,EAAG,CAAC,OAAO,CAAC,CAAA;AAEZ,EAAM,sBAAgB,MAAM;AAC1B,IAAA,IAAI,OAAA,KAAY,MAAA,IAAU,OAAA,KAAY,WAAA,EAAa,mBAAA,EAAoB;AAAA,EACzE,GAAG,CAAC,WAAA,EAAa,QAAA,EAAU,mBAAA,EAAqB,OAAO,CAAC,CAAA;AAExD,EAAM,gBAAU,MAAM;AACpB,IAAA,IAAI,OAAA,KAAY,MAAA,IAAU,OAAA,KAAY,WAAA,EAAa;AACnD,IAAA,MAAM,QAAA,GAAW,MAAM,mBAAA,EAAoB;AAC3C,IAAA,MAAA,CAAO,iBAAiB,QAAA,EAAU,QAAA,EAAU,EAAE,OAAA,EAAS,MAAM,CAAA;AAC7D,IAAA,OAAO,MAAM,MAAA,CAAO,mBAAA,CAAoB,QAAA,EAAU,QAAQ,CAAA;AAAA,EAC5D,CAAA,EAAG,CAAC,mBAAA,EAAqB,WAAA,EAAa,OAAO,CAAC,CAAA;AAE9C,EAAM,gBAAU,MAAM;AACpB,IAAA,IAAI,OAAA,KAAY,MAAA,IAAU,OAAA,KAAY,WAAA,EAAa;AACnD,IAAA,MAAM,KAAK,MAAA,CAAO,OAAA;AAClB,IAAA,IAAI,CAAC,EAAA,IAAM,OAAO,cAAA,KAAmB,WAAA,EAAa;AAClD,IAAA,MAAM,EAAA,GAAK,IAAI,cAAA,CAAe,MAAM,qBAAqB,CAAA;AACzD,IAAA,EAAA,CAAG,QAAQ,EAAE,CAAA;AACb,IAAA,OAAO,MAAM,GAAG,UAAA,EAAW;AAAA,EAC7B,CAAA,EAAG,CAAC,mBAAA,EAAqB,OAAO,CAAC,CAAA;AAEjC,EAAA,MAAM,aAAA,GAAsB,KAAA,CAAA,WAAA;AAAA,IAC1B,CAAC,CAAA,KAA2C;AAC1C,MAAA,MAAM,GAAA,GAAM,EAAE,GAAA,KAAQ,YAAA,GAAe,IAAI,CAAA,CAAE,GAAA,KAAQ,cAAc,EAAA,GAAK,CAAA;AACtE,MAAA,IAAI,CAAC,GAAA,EAAK;AACV,MAAA,MAAM,MAAM,MAAA,CAAO,OAAA;AACnB,MAAA,IAAI,CAAC,GAAA,EAAK;AACV,MAAA,MAAM,OAAO,KAAA,CAAM,IAAA;AAAA,QACjB,GAAA,CAAI,iBAAoC,8BAA8B;AAAA,OACxE;AACA,MAAA,IAAI,IAAA,CAAK,WAAW,CAAA,EAAG;AACvB,MAAA,MAAM,SAAS,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,QAAQ,QAAS,CAAA;AAClD,MAAA,IAAI,GAAA,GAAM,WAAA,GAAc,MAAA,CAAO,OAAA,CAAQ,WAAW,CAAA,GAAI,CAAA;AACtD,MAAA,IAAI,GAAA,GAAM,GAAG,GAAA,GAAM,CAAA;AACnB,MAAA,MAAM,IAAA,GAAA,CAAQ,GAAA,GAAM,GAAA,GAAM,MAAA,CAAO,UAAU,MAAA,CAAO,MAAA;AAClD,MAAA,MAAM,SAAA,GAAY,OAAO,IAAI,CAAA;AAC7B,MAAA,IAAI,SAAA,EAAW;AACb,QAAA,CAAA,CAAE,cAAA,EAAe;AACjB,QAAA,aAAA,CAAc,SAAS,CAAA;AACvB,QAAA,IAAA,CAAK,IAAI,GAAG,KAAA,EAAM;AAAA,MACpB;AAAA,IACF,CAAA;AAAA,IACA,CAAC,aAAa,aAAa;AAAA,GAC7B;AAEA,EAAA,uBACE,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,aAAA;AAAA,MACX,SAAA,EAAW,EAAA;AAAA,QACT,yCAAA;AAAA,QACA,OAAA,KAAY,SAAS,MAAA,GAAS,MAAA;AAAA,QAC9B;AAAA,OACF;AAAA,MACC,GAAG,KAAA;AAAA,MAEJ,QAAA,kBAAA,IAAA;AAAA,QAAC,KAAA;AAAA,QAAA;AAAA,UACC,GAAA,EAAK,MAAA;AAAA,UACL,IAAA,EAAK,SAAA;AAAA,UACL,SAAA,EAAW,EAAA;AAAA,YACT,2CAAA;AAAA,YAAA,CACC,OAAA,KAAY,MAAA,IAAU,OAAA,KAAY,WAAA,KAAgB,UAAA;AAAA,YACnD,YAAY,MAAA,IAAU,OAAA;AAAA,YACtB,YAAY,WAAA,IACV;AAAA,WACJ;AAAA,UAEC,QAAA,EAAA;AAAA,YAAA,OAAA,KAAY,MAAA,oBACX,GAAA;AAAA,cAAC,KAAA;AAAA,cAAA;AAAA,gBACC,aAAA,EAAY,MAAA;AAAA,gBACZ,WAAA,EAAU,gBAAA;AAAA,gBACV,KAAA,EAAO;AAAA,kBACL,QAAA,EACE;AAAA,iBACJ;AAAA,gBACA,SAAA,EAAW,EAAA;AAAA,kBACT,8EAAA;AAAA,kBACA,+BAAA;AAAA,kBACA;AAAA;AACF;AAAA,aACF;AAAA,YAED,YAAY,WAAA,oBACX,GAAA;AAAA,cAAC,KAAA;AAAA,cAAA;AAAA,gBACC,aAAA,EAAY,MAAA;AAAA,gBACZ,WAAA,EAAU,0BAAA;AAAA,gBACV,KAAA,EAAO;AAAA,kBACL,QAAA,EACE;AAAA,iBACJ;AAAA,gBACA,SAAA,EAAW,EAAA;AAAA,kBACT,sEAAA;AAAA,kBACA,+BAAA;AAAA,kBACA;AAAA;AACF;AAAA,aACF;AAAA,YAED;AAAA;AAAA;AAAA;AACH;AAAA,GACF;AAEJ;AAYO,IAAM,cAA0C,CAAC;AAAA,EACtD,KAAA;AAAA,EACA,QAAA;AAAA,EACA,IAAA;AAAA,EACA,YAAA,GAAe,MAAA;AAAA,EACf,OAAA;AAAA,EACA,SAAA;AAAA,EACA,QAAA;AAAA,EACA,GAAG;AACL,CAAA,KAAM;AACJ,EAAA,MAAM,EAAE,KAAA,EAAO,WAAA,EAAa,aAAA,EAAe,OAAA,KAAY,OAAA,EAAQ;AAC/D,EAAA,MAAM,QAAA,GAAW,KAAA,GAAQ,WAAA,KAAgB,KAAA,GAAQ,KAAA;AAEjD,EAAA,uBACE,IAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAK,QAAA;AAAA,MACL,IAAA,EAAK,KAAA;AAAA,MACL,eAAA,EAAe,QAAA;AAAA,MACf,QAAA,EAAU,KAAA,KAAU,MAAA,GAAa,QAAA,GAAW,IAAI,EAAA,GAAM,MAAA;AAAA,MACtD,QAAA;AAAA,MACA,gBAAA,EAAgB,KAAA;AAAA,MAChB,OAAA,EAAS,CAAC,CAAA,KAAM;AACd,QAAA,IAAI,KAAA,gBAAqB,KAAK,CAAA;AAC9B,QAAA,OAAA,GAAU,CAAC,CAAA;AAAA,MACb,CAAA;AAAA,MACA,SAAA,EAAW,EAAA;AAAA,QACT,+KAAA;AAAA,QACA,YAAY,MAAA,IAAU;AAAA,UACpB,0EAAA;AAAA,UACA,uVAAA;AAAA,UACA,yHAAA;AAAA,UACA,QAAA,GACI;AAAA,YACE,iBAAA;AAAA,YACA;AAAA,WACF,GACA;AAAA,SACN;AAAA,QACA,YAAY,WAAA,IAAe;AAAA,UACzB,uFAAA;AAAA,UACA,uDAAA;AAAA,UACA,gEAAA;AAAA,UACA,qBAAA;AAAA,UACA,qGAAA;AAAA,UACA,WACI,cAAA,GACA;AAAA,SACN;AAAA,QACA,iDAAA;AAAA,QACA;AAAA,OACF;AAAA,MACC,GAAG,KAAA;AAAA,MAEH,QAAA,EAAA;AAAA,QAAA,IAAA,IAAQ,iBAAiB,MAAA,oBACxB,GAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACC,SAAA,EAAU,kDAAA;AAAA,YACV,aAAA,EAAW,IAAA;AAAA,YAEV,QAAA,EAAA;AAAA;AAAA,SACH;AAAA,QAED,QAAA;AAAA,QACA,IAAA,IAAQ,iBAAiB,OAAA,oBACxB,GAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACC,SAAA,EAAU,kDAAA;AAAA,YACV,aAAA,EAAW,IAAA;AAAA,YAEV,QAAA,EAAA;AAAA;AAAA;AACH;AAAA;AAAA,GAEJ;AAEJ;AAMO,IAAM,cAA0C,CAAC;AAAA,EACtD,KAAA;AAAA,EACA,QAAA;AAAA,EACA,SAAA;AAAA,EACA,GAAG;AACL,CAAA,KAAM;AACJ,EAAA,MAAM,EAAE,KAAA,EAAO,WAAA,EAAY,GAAI,OAAA,EAAQ;AAEvC,EAAA,IAAI,WAAA,KAAgB,OAAO,OAAO,IAAA;AAElC,EAAA,uBACE,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAK,UAAA;AAAA,MACL,SAAA,EAAW,EAAA;AAAA,QACT,uDAAA;AAAA,QACA,4HAAA;AAAA,QACA;AAAA,OACF;AAAA,MACC,GAAG,KAAA;AAAA,MAEH;AAAA;AAAA,GACH;AAEJ","file":"tabs.js","sourcesContent":["import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"@/lib/utils\";\n\n//////////////////////////////////////////////// CONTEXT\n\nexport type TabsVariant = \"pill\" | \"underline\";\n\ninterface TabsProps extends React.HTMLAttributes<HTMLDivElement> {\n defaultValue?: string;\n value?: string;\n onValueChange?: (value: string) => void;\n /** `pill` — segmented control with sliding primary fill (default). `underline` — bottom border row + clip-path sliding primary underline. */\n variant?: TabsVariant;\n children: React.ReactNode;\n}\n\nconst TabsContext = React.createContext<{\n value?: string;\n onValueChange: (value: string) => void;\n variant: TabsVariant;\n} | null>(null);\n\nfunction useTabs() {\n const context = React.useContext(TabsContext);\n if (!context) {\n throw new Error(\"Tabs components must be used within a <Tabs />\");\n }\n return context;\n}\n\nexport const Tabs: React.FC<TabsProps> = ({\n defaultValue,\n value: controlledValue,\n onValueChange,\n children,\n className,\n variant = \"pill\",\n ...props\n}) => {\n const [internalValue, setInternalValue] = React.useState(defaultValue);\n const isControlled = controlledValue !== undefined;\n const value = isControlled ? controlledValue : internalValue;\n\n const handleValueChange = React.useCallback(\n (newValue: string) => {\n if (!isControlled) {\n setInternalValue(newValue);\n }\n onValueChange?.(newValue);\n },\n [isControlled, onValueChange],\n );\n\n return (\n <TabsContext.Provider\n value={{ value, onValueChange: handleValueChange, variant }}\n >\n <div className={cn(\"flex flex-col gap-4\", className)} {...props}>\n {children}\n </div>\n </TabsContext.Provider>\n );\n};\n\ninterface TabsListProps extends React.HTMLAttributes<HTMLDivElement> {}\n\nexport const TabsList: React.FC<TabsListProps> = ({\n children,\n className,\n ...props\n}) => {\n const { value: activeValue, onValueChange, variant } = useTabs();\n const rowRef = React.useRef<HTMLDivElement>(null);\n\n /** Drives horizontal `clip-path` via `--tab-indicator-start` / `--tab-indicator-end` (px from row left). */\n const updateIndicatorClip = React.useCallback(() => {\n const row = rowRef.current;\n if (!row || (variant !== \"pill\" && variant !== \"underline\")) return;\n\n const tab = row.querySelector<HTMLElement>(\n '[role=\"tab\"][aria-selected=\"true\"]',\n );\n if (!tab) {\n row.style.setProperty(\"--tab-indicator-start\", \"0px\");\n row.style.setProperty(\"--tab-indicator-end\", \"0px\");\n return;\n }\n\n const start = tab.offsetLeft;\n const end = tab.offsetLeft + tab.offsetWidth;\n row.style.setProperty(\"--tab-indicator-start\", `${start}px`);\n row.style.setProperty(\"--tab-indicator-end\", `${end}px`);\n }, [variant]);\n\n React.useLayoutEffect(() => {\n if (variant === \"pill\" || variant === \"underline\") updateIndicatorClip();\n }, [activeValue, children, updateIndicatorClip, variant]);\n\n React.useEffect(() => {\n if (variant !== \"pill\" && variant !== \"underline\") return;\n const onResize = () => updateIndicatorClip();\n window.addEventListener(\"resize\", onResize, { passive: true });\n return () => window.removeEventListener(\"resize\", onResize);\n }, [updateIndicatorClip, activeValue, variant]);\n\n React.useEffect(() => {\n if (variant !== \"pill\" && variant !== \"underline\") return;\n const el = rowRef.current;\n if (!el || typeof ResizeObserver === \"undefined\") return;\n const ro = new ResizeObserver(() => updateIndicatorClip());\n ro.observe(el);\n return () => ro.disconnect();\n }, [updateIndicatorClip, variant]);\n\n const handleKeyDown = React.useCallback(\n (e: React.KeyboardEvent<HTMLDivElement>) => {\n const dir = e.key === \"ArrowRight\" ? 1 : e.key === \"ArrowLeft\" ? -1 : 0;\n if (!dir) return;\n const row = rowRef.current;\n if (!row) return;\n const tabs = Array.from(\n row.querySelectorAll<HTMLButtonElement>('[role=\"tab\"][data-tab-value]'),\n );\n if (tabs.length === 0) return;\n const values = tabs.map((t) => t.dataset.tabValue!);\n let idx = activeValue ? values.indexOf(activeValue) : 0;\n if (idx < 0) idx = 0;\n const next = (idx + dir + values.length) % values.length;\n const nextValue = values[next];\n if (nextValue) {\n e.preventDefault();\n onValueChange(nextValue);\n tabs[next]?.focus();\n }\n },\n [activeValue, onValueChange],\n );\n\n return (\n <div\n onKeyDown={handleKeyDown}\n className={cn(\n \"max-w-full overflow-x-auto no-scrollbar\",\n variant === \"pill\" ? \"pb-1\" : \"pb-0\",\n className,\n )}\n {...props}\n >\n <div\n ref={rowRef}\n role=\"tablist\"\n className={cn(\n \"inline-flex w-max min-w-full items-center\",\n (variant === \"pill\" || variant === \"underline\") && \"relative\",\n variant === \"pill\" && \"gap-1\",\n variant === \"underline\" &&\n \"gap-2 rounded-none border-b border-border bg-transparent py-0\",\n )}\n >\n {variant === \"pill\" && (\n <div\n aria-hidden=\"true\"\n data-slot=\"tabs-indicator\"\n style={{\n clipPath:\n \"inset(0 calc(100% - var(--tab-indicator-end, 0px)) 0 var(--tab-indicator-start, 0px) round 9999px)\",\n }}\n className={cn(\n \"pointer-events-none absolute inset-x-0 top-0 z-0 h-9 rounded-full bg-primary\",\n \"motion-reduce:transition-none\",\n \"motion-safe:transition-[clip-path] motion-safe:duration-300 motion-safe:ease-[cubic-bezier(0,0.55,0.45,1)]\",\n )}\n />\n )}\n {variant === \"underline\" && (\n <div\n aria-hidden=\"true\"\n data-slot=\"tabs-underline-indicator\"\n style={{\n clipPath:\n \"inset(0 calc(100% - var(--tab-indicator-end, 0px)) 0 var(--tab-indicator-start, 0px))\",\n }}\n className={cn(\n \"pointer-events-none absolute inset-x-0 bottom-0 z-0 h-0.5 bg-primary\",\n \"motion-reduce:transition-none\",\n \"motion-safe:transition-[clip-path] motion-safe:duration-300 motion-safe:ease-[cubic-bezier(0,0.55,0.45,1)]\",\n )}\n />\n )}\n {children}\n </div>\n </div>\n );\n};\n\ninterface TabsTriggerProps extends Omit<\n React.ButtonHTMLAttributes<HTMLButtonElement>,\n \"onClick\"\n> {\n value?: string;\n icon?: React.ReactNode;\n iconPosition?: \"left\" | \"right\";\n onClick?: React.MouseEventHandler<HTMLButtonElement>;\n}\n\nexport const TabsTrigger: React.FC<TabsTriggerProps> = ({\n value,\n children,\n icon,\n iconPosition = \"left\",\n onClick,\n className,\n disabled,\n ...props\n}) => {\n const { value: activeValue, onValueChange, variant } = useTabs();\n const isActive = value ? activeValue === value : false;\n\n return (\n <button\n type=\"button\"\n role=\"tab\"\n aria-selected={isActive}\n tabIndex={value !== undefined ? (isActive ? 0 : -1) : undefined}\n disabled={disabled}\n data-tab-value={value}\n onClick={(e) => {\n if (value) onValueChange(value);\n onClick?.(e);\n }}\n className={cn(\n \"relative z-1 inline-flex shrink-0 cursor-pointer select-none items-center justify-center gap-2 whitespace-nowrap touch-manipulation [-webkit-tap-highlight-color:transparent]\",\n variant === \"pill\" && [\n \"h-9 rounded-full px-4 font-semibold leading-5 text-[13px] md:text-[15px]\",\n \"[transition:background-color_var(--duration-short-s,0.1s)_var(--ease-out,cubic-bezier(0,.55,.45,1)),border-color_var(--duration-short-s,0.1s)_var(--ease-out,cubic-bezier(0,.55,.45,1)),scale_var(--duration-short-s,0.1s)_var(--ease-out,cubic-bezier(0,.55,.45,1)),color_var(--duration-short-m,0.2s)_var(--ease-in-out,cubic-bezier(.85,0,.15,1))]\",\n \"active:scale-[0.96] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\",\n isActive\n ? [\n \"text-background\",\n \"**:data-[slot=badge]:border-none **:data-[slot=badge]:bg-background/20 **:data-[slot=badge]:text-background\",\n ]\n : \"bg-primary/4 text-primary/50 [@media(hover:hover)_and_(pointer:fine)]:hover:bg-primary/10 active:bg-primary/10\",\n ],\n variant === \"underline\" && [\n \"h-auto rounded-none border-0 bg-transparent px-2 py-2 text-sm font-medium shadow-none\",\n \"transition-[color,transform] duration-200 ease-in-out\",\n \"motion-reduce:transition-colors motion-reduce:active:scale-100\",\n \"active:scale-[0.98]\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\",\n isActive\n ? \"text-primary\"\n : \"text-primary/50 [@media(hover:hover)_and_(pointer:fine)]:hover:text-primary/70\",\n ],\n \"disabled:cursor-not-allowed disabled:opacity-50\",\n className,\n )}\n {...props}\n >\n {icon && iconPosition === \"left\" && (\n <span\n className=\"flex size-4 shrink-0 items-center justify-center\"\n aria-hidden\n >\n {icon}\n </span>\n )}\n {children}\n {icon && iconPosition === \"right\" && (\n <span\n className=\"flex size-4 shrink-0 items-center justify-center\"\n aria-hidden\n >\n {icon}\n </span>\n )}\n </button>\n );\n};\n\ninterface TabsContentProps extends React.HTMLAttributes<HTMLDivElement> {\n value: string;\n}\n\nexport const TabsContent: React.FC<TabsContentProps> = ({\n value,\n children,\n className,\n ...props\n}) => {\n const { value: activeValue } = useTabs();\n\n if (activeValue !== value) return null;\n\n return (\n <div\n role=\"tabpanel\"\n className={cn(\n \"animate-in fade-in-0 slide-in-from-top-1 duration-200\",\n \"ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\",\n className,\n )}\n {...props}\n >\n {children}\n </div>\n );\n};\n"]}
1
+ {"version":3,"sources":["../../src/lib/utils.ts","../../src/react/tabs.tsx"],"names":["masks"],"mappings":"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","file":"tabs.js","sourcesContent":["import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"@/lib/utils\";\n\nconst MD_UP = \"(min-width: 768px)\";\n\n//////////////////////////////////////////////// CONTEXT\n\nexport type TabsVariant = \"pill\" | \"underline\" | \"box\";\nexport type TabsAlignment = \"horizontal\" | \"vertical\";\nexport type TabsTriggerLayout = \"row\" | \"stacked\";\n\ninterface TabsProps extends React.HTMLAttributes<HTMLDivElement> {\n defaultValue?: string;\n value?: string;\n onValueChange?: (value: string) => void;\n /** `pill` — compact pill track (default). `box` — larger padding, `rounded-xl` sliding fill. `underline` — border row + clip-path bar. */\n variant?: TabsVariant;\n /** Tab list layout: row (default) or stacked sidebar with panel beside it from `md` up; below `md`, vertical is shown as horizontal. */\n alignment?: TabsAlignment;\n children: React.ReactNode;\n}\n\nconst TabsContext = React.createContext<{\n value?: string;\n onValueChange: (value: string) => void;\n variant: TabsVariant;\n alignment: TabsAlignment;\n} | null>(null);\n\nfunction useTabs() {\n const context = React.useContext(TabsContext);\n if (!context) {\n throw new Error(\"Tabs components must be used within a <Tabs />\");\n }\n return context;\n}\n\nexport const Tabs: React.FC<TabsProps> = ({\n defaultValue,\n value: controlledValue,\n onValueChange,\n children,\n className,\n variant = \"pill\",\n alignment = \"horizontal\",\n ...props\n}) => {\n const [internalValue, setInternalValue] = React.useState(defaultValue);\n const [isMdUp, setIsMdUp] = React.useState(false);\n const isControlled = controlledValue !== undefined;\n const value = isControlled ? controlledValue : internalValue;\n\n React.useEffect(() => {\n const mq = window.matchMedia(MD_UP);\n const sync = () => setIsMdUp(mq.matches);\n sync();\n mq.addEventListener(\"change\", sync);\n return () => mq.removeEventListener(\"change\", sync);\n }, []);\n\n const effectiveAlignment: TabsAlignment =\n alignment === \"vertical\" && isMdUp ? \"vertical\" : \"horizontal\";\n\n const handleValueChange = React.useCallback(\n (newValue: string) => {\n if (!isControlled) {\n setInternalValue(newValue);\n }\n onValueChange?.(newValue);\n },\n [isControlled, onValueChange],\n );\n\n return (\n <TabsContext.Provider\n value={{\n value,\n onValueChange: handleValueChange,\n variant,\n alignment: effectiveAlignment,\n }}\n >\n <div\n className={cn(\n \"flex gap-4\",\n effectiveAlignment === \"vertical\"\n ? \"flex-col md:flex-row md:items-stretch\"\n : \"flex-col\",\n className,\n )}\n {...props}\n >\n {children}\n </div>\n </TabsContext.Provider>\n );\n};\n\ninterface TabsListProps extends React.HTMLAttributes<HTMLDivElement> {}\n\ntype ScrollFadeX = \"none\" | \"right\" | \"left\" | \"both\";\ntype ScrollFadeY = \"none\" | \"down\" | \"up\" | \"both\";\n\nexport const TabsList: React.FC<TabsListProps> = ({\n children,\n className,\n ...props\n}) => {\n const { value: activeValue, onValueChange, variant, alignment } = useTabs();\n const isVertical = alignment === \"vertical\";\n const rowRef = React.useRef<HTMLDivElement>(null);\n const scrollRef = React.useRef<HTMLDivElement>(null);\n const [scrollEdgesX, setScrollEdgesX] = React.useState<ScrollFadeX>(\"none\");\n const [scrollEdgesY, setScrollEdgesY] = React.useState<ScrollFadeY>(\"none\");\n\n const updateScrollEdges = React.useCallback(() => {\n const el = scrollRef.current;\n if (!el) return;\n if (isVertical) {\n const scrollRange = el.scrollHeight - el.clientHeight;\n if (scrollRange < 8) {\n setScrollEdgesY((prev) => (prev === \"none\" ? prev : \"none\"));\n return;\n }\n const canUp = el.scrollTop > 1;\n const canDown = el.scrollTop < scrollRange - 1;\n const next: ScrollFadeY =\n canUp && canDown\n ? \"both\"\n : canUp\n ? \"up\"\n : canDown\n ? \"down\"\n : \"none\";\n setScrollEdgesY((prev) => (prev === next ? prev : next));\n } else {\n const scrollRange = el.scrollWidth - el.clientWidth;\n if (scrollRange < 8) {\n setScrollEdgesX((prev) => (prev === \"none\" ? prev : \"none\"));\n return;\n }\n const canLeft = el.scrollLeft > 1;\n const canRight = el.scrollLeft < scrollRange - 1;\n const next: ScrollFadeX =\n canLeft && canRight\n ? \"both\"\n : canLeft\n ? \"left\"\n : canRight\n ? \"right\"\n : \"none\";\n setScrollEdgesX((prev) => (prev === next ? prev : next));\n }\n }, [isVertical]);\n\n React.useEffect(() => {\n const el = scrollRef.current;\n if (!el) return;\n updateScrollEdges();\n el.addEventListener(\"scroll\", updateScrollEdges, { passive: true });\n window.addEventListener(\"resize\", updateScrollEdges, { passive: true });\n return () => {\n el.removeEventListener(\"scroll\", updateScrollEdges);\n window.removeEventListener(\"resize\", updateScrollEdges);\n };\n }, [updateScrollEdges, children, isVertical]);\n\n const updateIndicatorClip = React.useCallback(() => {\n const row = rowRef.current;\n if (!row || (variant !== \"pill\" && variant !== \"underline\" && variant !== \"box\"))\n return;\n\n const tab = row.querySelector<HTMLElement>(\n '[role=\"tab\"][aria-selected=\"true\"]:not(:disabled)',\n );\n if (!tab) {\n row.style.setProperty(\"--tab-indicator-start\", \"0px\");\n row.style.setProperty(\"--tab-indicator-end\", \"0px\");\n return;\n }\n\n if (isVertical) {\n const start = tab.offsetTop;\n const end = tab.offsetTop + tab.offsetHeight;\n row.style.setProperty(\"--tab-indicator-start\", `${start}px`);\n row.style.setProperty(\"--tab-indicator-end\", `${end}px`);\n } else {\n const start = tab.offsetLeft;\n const end = tab.offsetLeft + tab.offsetWidth;\n row.style.setProperty(\"--tab-indicator-start\", `${start}px`);\n row.style.setProperty(\"--tab-indicator-end\", `${end}px`);\n }\n }, [variant, isVertical]);\n\n React.useLayoutEffect(() => {\n if (variant === \"pill\" || variant === \"underline\" || variant === \"box\")\n updateIndicatorClip();\n }, [activeValue, children, updateIndicatorClip, variant]);\n\n React.useEffect(() => {\n if (variant !== \"pill\" && variant !== \"underline\" && variant !== \"box\") return;\n const onResize = () => updateIndicatorClip();\n window.addEventListener(\"resize\", onResize, { passive: true });\n return () => window.removeEventListener(\"resize\", onResize);\n }, [updateIndicatorClip, activeValue, variant]);\n\n React.useEffect(() => {\n if (variant !== \"pill\" && variant !== \"underline\" && variant !== \"box\") return;\n const el = rowRef.current;\n if (!el || typeof ResizeObserver === \"undefined\") return;\n const ro = new ResizeObserver(() => updateIndicatorClip());\n ro.observe(el);\n return () => ro.disconnect();\n }, [updateIndicatorClip, variant]);\n\n const handleKeyDown = React.useCallback(\n (e: React.KeyboardEvent<HTMLDivElement>) => {\n const dir = isVertical\n ? e.key === \"ArrowDown\"\n ? 1\n : e.key === \"ArrowUp\"\n ? -1\n : 0\n : e.key === \"ArrowRight\"\n ? 1\n : e.key === \"ArrowLeft\"\n ? -1\n : 0;\n if (!dir) return;\n const row = rowRef.current;\n if (!row) return;\n const tabs = Array.from(\n row.querySelectorAll<HTMLButtonElement>('[role=\"tab\"][data-tab-value]'),\n ).filter((t) => !t.disabled);\n if (tabs.length === 0) return;\n const values = tabs.map((t) => t.dataset.tabValue!);\n let idx = activeValue ? values.indexOf(activeValue) : 0;\n if (idx < 0) idx = 0;\n const next = (idx + dir + values.length) % values.length;\n const nextValue = values[next];\n if (nextValue) {\n e.preventDefault();\n onValueChange(nextValue);\n tabs[next]?.focus();\n }\n },\n [activeValue, onValueChange, isVertical],\n );\n\n const maskStyle = React.useMemo<React.CSSProperties | undefined>(() => {\n const fade = \"24px\";\n if (isVertical) {\n if (scrollEdgesY === \"none\") return undefined;\n const masks: Record<ScrollFadeY, string> = {\n down: `linear-gradient(to bottom, black calc(100% - ${fade}), transparent)`,\n up: `linear-gradient(to top, black calc(100% - ${fade}), transparent)`,\n both: `linear-gradient(to bottom, transparent, black ${fade}, black calc(100% - ${fade}), transparent)`,\n none: \"\",\n };\n return {\n WebkitMaskImage: masks[scrollEdgesY],\n maskImage: masks[scrollEdgesY],\n };\n }\n if (scrollEdgesX === \"none\") return undefined;\n const masks: Record<ScrollFadeX, string> = {\n right: `linear-gradient(to right, black calc(100% - ${fade}), transparent)`,\n left: `linear-gradient(to left, black calc(100% - ${fade}), transparent)`,\n both: `linear-gradient(to right, transparent, black ${fade}, black calc(100% - ${fade}), transparent)`,\n none: \"\",\n };\n return {\n WebkitMaskImage: masks[scrollEdgesX],\n maskImage: masks[scrollEdgesX],\n };\n }, [scrollEdgesX, scrollEdgesY, isVertical]);\n\n const pillClipHorizontal =\n \"inset(0 calc(100% - var(--tab-indicator-end, 0px)) 0 var(--tab-indicator-start, 0px) round 9999px)\";\n const pillClipVertical =\n \"inset(var(--tab-indicator-start, 0px) 0 calc(100% - var(--tab-indicator-end, 0px)) 0 round 9999px)\";\n const boxClipHorizontal =\n \"inset(0 calc(100% - var(--tab-indicator-end, 0px)) 0 var(--tab-indicator-start, 0px) round 12px)\";\n const boxClipVertical =\n \"inset(var(--tab-indicator-start, 0px) 0 calc(100% - var(--tab-indicator-end, 0px)) 0 round 12px)\";\n const underlineClipHorizontal =\n \"inset(0 calc(100% - var(--tab-indicator-end, 0px)) 0 var(--tab-indicator-start, 0px))\";\n const underlineClipVertical =\n \"inset(var(--tab-indicator-start, 0px) 0 calc(100% - var(--tab-indicator-end, 0px)) 0)\";\n\n return (\n <div\n ref={scrollRef}\n onKeyDown={handleKeyDown}\n className={cn(\n isVertical\n ? \"max-h-72 min-h-0 w-full max-w-52 shrink-0 overflow-x-hidden overflow-y-auto md:max-h-none md:max-w-56\"\n : \"max-w-full overflow-x-auto\",\n \"[scrollbar-width:none] [-ms-overflow-style:none] [&::-webkit-scrollbar]:hidden\",\n variant === \"pill\" && !isVertical && \"pb-1\",\n variant === \"box\" && !isVertical && \"pb-1\",\n variant === \"underline\" && !isVertical && \"pb-0\",\n variant === \"underline\" && isVertical && \"pr-0\",\n className,\n )}\n style={maskStyle}\n {...props}\n >\n <div\n ref={rowRef}\n role=\"tablist\"\n aria-orientation={isVertical ? \"vertical\" : \"horizontal\"}\n className={cn(\n \"flex\",\n isVertical\n ? \"w-full flex-col items-stretch\"\n : cn(\n \"inline-flex w-max min-w-full\",\n variant === \"box\" ? \"items-stretch\" : \"items-center\",\n ),\n (variant === \"pill\" || variant === \"underline\" || variant === \"box\") &&\n \"relative\",\n variant === \"pill\" && \"gap-1\",\n variant === \"box\" && \"gap-2\",\n variant === \"pill\" && isVertical && \"px-1 py-1\",\n variant === \"box\" && isVertical && \"px-1 py-1\",\n variant === \"underline\" &&\n (isVertical\n ? \"gap-0 rounded-none border-l border-border bg-transparent py-0 pl-0\"\n : \"gap-2 rounded-none border-b border-border bg-transparent py-0\"),\n )}\n >\n {variant === \"pill\" && (\n <div\n aria-hidden=\"true\"\n data-slot=\"tabs-indicator\"\n style={{\n clipPath: isVertical ? pillClipVertical : pillClipHorizontal,\n }}\n className={cn(\n \"pointer-events-none absolute z-0 bg-primary\",\n \"motion-reduce:transition-none\",\n \"motion-safe:transition-[clip-path] motion-safe:duration-300 motion-safe:ease-[cubic-bezier(0,0.55,0.45,1)]\",\n isVertical\n ? \"inset-y-0 left-0 right-0\"\n : \"inset-x-0 top-0 h-9 rounded-full\",\n )}\n />\n )}\n {variant === \"box\" && (\n <div\n aria-hidden=\"true\"\n data-slot=\"tabs-box-indicator\"\n style={{\n clipPath: isVertical ? boxClipVertical : boxClipHorizontal,\n }}\n className={cn(\n \"pointer-events-none absolute inset-y-0 left-0 right-0 z-0 bg-primary\",\n \"motion-reduce:transition-none\",\n \"motion-safe:transition-[clip-path] motion-safe:duration-300 motion-safe:ease-[cubic-bezier(0,0.55,0.45,1)]\",\n )}\n />\n )}\n {variant === \"underline\" && (\n <div\n aria-hidden=\"true\"\n data-slot=\"tabs-underline-indicator\"\n style={{\n clipPath: isVertical\n ? underlineClipVertical\n : underlineClipHorizontal,\n }}\n className={cn(\n \"pointer-events-none absolute z-0 bg-primary\",\n \"motion-reduce:transition-none\",\n \"motion-safe:transition-[clip-path] motion-safe:duration-300 motion-safe:ease-[cubic-bezier(0,0.55,0.45,1)]\",\n isVertical\n ? \"inset-y-0 left-0 w-0.5\"\n : \"inset-x-0 bottom-0 h-0.5\",\n )}\n />\n )}\n {children}\n </div>\n </div>\n );\n};\n\ninterface TabsTriggerProps extends Omit<\n React.ButtonHTMLAttributes<HTMLButtonElement>,\n \"onClick\"\n> {\n value?: string;\n icon?: React.ReactNode;\n iconPosition?: \"left\" | \"right\";\n /** `stacked` — icon above label (needs `icon`). `row` — default inline row. */\n layout?: TabsTriggerLayout;\n onClick?: React.MouseEventHandler<HTMLButtonElement>;\n}\n\nexport const TabsTrigger: React.FC<TabsTriggerProps> = ({\n value,\n children,\n icon,\n iconPosition = \"left\",\n layout = \"row\",\n onClick,\n className,\n disabled,\n ...props\n}) => {\n const { value: activeValue, onValueChange, variant, alignment } = useTabs();\n const isVertical = alignment === \"vertical\";\n const isActive = value ? activeValue === value : false;\n const showSelected = isActive && !disabled;\n const isStacked = layout === \"stacked\" && Boolean(icon);\n const iconWrapClass =\n \"inline-flex shrink-0 items-center justify-center [&_svg]:shrink-0\";\n const labelWrapClass = \"block min-w-0 w-full text-left leading-snug\";\n\n return (\n <button\n type=\"button\"\n role=\"tab\"\n aria-selected={isActive}\n aria-disabled={disabled || undefined}\n tabIndex={\n value !== undefined ? (isActive && !disabled ? 0 : -1) : undefined\n }\n disabled={disabled}\n data-tab-value={value}\n onClick={(e) => {\n if (disabled) return;\n if (value) onValueChange(value);\n onClick?.(e);\n }}\n className={cn(\n \"relative z-1 inline-flex shrink-0 select-none touch-manipulation [-webkit-tap-highlight-color:transparent]\",\n \"cursor-pointer disabled:cursor-not-allowed\",\n isStacked\n ? \"flex-col items-start justify-start gap-1.5 whitespace-normal\"\n : \"items-center justify-center gap-2 whitespace-nowrap\",\n isVertical && \"w-full justify-start\",\n variant === \"pill\" && [\n \"h-9 rounded-full px-4 font-semibold leading-5 text-[13px] md:text-[15px]\",\n \"[transition:background-color_var(--duration-short-s,0.1s)_var(--ease-out,cubic-bezier(0,.55,.45,1)),border-color_var(--duration-short-s,0.1s)_var(--ease-out,cubic-bezier(0,.55,.45,1)),scale_var(--duration-short-s,0.1s)_var(--ease-out,cubic-bezier(0,.55,.45,1)),color_var(--duration-short-m,0.2s)_var(--ease-in-out,cubic-bezier(.85,0,.15,1))]\",\n !isVertical && \"enabled:active:scale-[0.96]\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\",\n showSelected\n ? [\n \"text-background\",\n \"**:data-[slot=badge]:border-none **:data-[slot=badge]:bg-background/20 **:data-[slot=badge]:text-background\",\n ]\n : \"bg-primary/4 text-primary/50 enabled:[@media(hover:hover)_and_(pointer:fine)]:hover:bg-primary/10 enabled:active:bg-primary/10\",\n ],\n variant === \"box\" && [\n \"min-h-11 rounded-xl px-4 pt-1.5 pb-2 font-semibold leading-5 text-[13px] md:text-[15px]\",\n isVertical\n ? \"justify-start text-left\"\n : \"justify-center text-center\",\n \"[transition:background-color_var(--duration-short-s,0.1s)_var(--ease-out,cubic-bezier(0,.55,.45,1)),color_var(--duration-short-m,0.2s)_var(--ease-in-out,cubic-bezier(.85,0,.15,1))]\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\",\n showSelected\n ? [\n \"text-background\",\n \"**:data-[slot=badge]:border-none **:data-[slot=badge]:bg-background/20 **:data-[slot=badge]:text-background\",\n ]\n : \"bg-transparent text-primary/55 enabled:[@media(hover:hover)_and_(pointer:fine)]:hover:bg-primary/[0.07] enabled:[@media(hover:hover)_and_(pointer:fine)]:hover:text-primary/75\",\n ],\n variant === \"underline\" && [\n \"h-auto rounded-none border-0 bg-transparent py-2 text-sm font-medium shadow-none\",\n isVertical\n ? isStacked\n ? \"pl-6 pr-2\"\n : \"pl-5 pr-2\"\n : \"px-2\",\n \"transition-[color,transform] duration-200 ease-in-out\",\n \"motion-reduce:transition-colors motion-reduce:enabled:active:scale-100\",\n \"enabled:active:scale-[0.98]\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\",\n showSelected\n ? \"text-primary\"\n : \"text-primary/50 enabled:[@media(hover:hover)_and_(pointer:fine)]:hover:text-primary/70\",\n ],\n \"disabled:opacity-50\",\n className,\n )}\n {...props}\n >\n {isStacked && icon && iconPosition === \"left\" && (\n <>\n <span className={iconWrapClass} aria-hidden>\n {icon}\n </span>\n <span className={labelWrapClass}>{children}</span>\n </>\n )}\n {isStacked && icon && iconPosition === \"right\" && (\n <>\n <span className={labelWrapClass}>{children}</span>\n <span className={iconWrapClass} aria-hidden>\n {icon}\n </span>\n </>\n )}\n {!isStacked && icon && iconPosition === \"left\" && (\n <span className={iconWrapClass} aria-hidden>\n {icon}\n </span>\n )}\n {!isStacked && children}\n {!isStacked && icon && iconPosition === \"right\" && (\n <span className={iconWrapClass} aria-hidden>\n {icon}\n </span>\n )}\n </button>\n );\n};\n\ninterface TabsContentProps extends React.HTMLAttributes<HTMLDivElement> {\n value: string;\n}\n\nexport const TabsContent: React.FC<TabsContentProps> = ({\n value,\n children,\n className,\n ...props\n}) => {\n const { value: activeValue, alignment } = useTabs();\n const isVertical = alignment === \"vertical\";\n\n if (activeValue !== value) return null;\n\n return (\n <div\n role=\"tabpanel\"\n className={cn(\n \"animate-in fade-in-0 duration-200\",\n isVertical ? \"slide-in-from-left-1\" : \"slide-in-from-top-1\",\n \"ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\",\n isVertical && \"min-w-0 flex-1\",\n className,\n )}\n {...props}\n >\n {children}\n </div>\n );\n};\n"]}
@@ -0,0 +1,6 @@
1
+ import * as React from 'react';
2
+
3
+ type TextareaProps = React.ComponentProps<"textarea">;
4
+ declare const Textarea: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.TextareaHTMLAttributes<HTMLTextAreaElement>, HTMLTextAreaElement>, "ref"> & React.RefAttributes<HTMLTextAreaElement>>;
5
+
6
+ export { Textarea, type TextareaProps };
@@ -0,0 +1,33 @@
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/react/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
+ ref,
16
+ "data-slot": "textarea",
17
+ className: cn(
18
+ "border-input bg-background text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground flex min-h-20 w-full min-w-0 rounded-md border px-3 py-2 text-sm outline-none transition-[color,box-shadow]",
19
+ "disabled:cursor-not-allowed disabled:opacity-50",
20
+ "focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
21
+ "aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40",
22
+ className
23
+ ),
24
+ ...props
25
+ }
26
+ );
27
+ }
28
+ );
29
+ Textarea.displayName = "Textarea";
30
+
31
+ export { Textarea };
32
+ //# sourceMappingURL=textarea.js.map
33
+ //# sourceMappingURL=textarea.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/lib/utils.ts","../../src/react/textarea.tsx"],"names":[],"mappings":";;;;;;AAGO,SAAS,MAAM,MAAA,EAAsB;AAC1C,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC7B;ACCA,IAAM,QAAA,GAAiB,KAAA,CAAA,UAAA;AAAA,EACrB,CAAC,EAAE,SAAA,EAAW,GAAG,KAAA,IAAS,GAAA,KAAQ;AAChC,IAAA,uBACE,GAAA;AAAA,MAAC,UAAA;AAAA,MAAA;AAAA,QACC,GAAA;AAAA,QACA,WAAA,EAAU,UAAA;AAAA,QACV,SAAA,EAAW,EAAA;AAAA,UACT,iPAAA;AAAA,UACA,iDAAA;AAAA,UACA,+EAAA;AAAA,UACA,wGAAA;AAAA,UACA;AAAA,SACF;AAAA,QACC,GAAG;AAAA;AAAA,KACN;AAAA,EAEJ;AACF;AACA,QAAA,CAAS,WAAA,GAAc,UAAA","file":"textarea.js","sourcesContent":["import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","import * as React from \"react\";\n\nimport { cn } from \"@/lib/utils\";\n\nexport type TextareaProps = React.ComponentProps<\"textarea\">;\n\nconst Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(\n ({ className, ...props }, ref) => {\n return (\n <textarea\n ref={ref}\n data-slot=\"textarea\"\n className={cn(\n \"border-input bg-background text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground flex min-h-20 w-full min-w-0 rounded-md border px-3 py-2 text-sm outline-none transition-[color,box-shadow]\",\n \"disabled:cursor-not-allowed disabled:opacity-50\",\n \"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]\",\n \"aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40\",\n className,\n )}\n {...props}\n />\n );\n },\n);\nTextarea.displayName = \"Textarea\";\n\nexport { Textarea };\n"]}
@@ -0,0 +1,22 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+
3
+ /** When no time base exists yet, use today at local midnight. */
4
+ declare function baseDateForTimePick(value: Date | undefined): Date;
5
+ type TimePickerProps = {
6
+ value: Date | undefined;
7
+ onChange: (next: Date) => void;
8
+ disabled?: boolean;
9
+ /**
10
+ * `vertical` (default): three columns with `scrollTop`.
11
+ * `horizontal`: three stacked strips with `scrollLeft` — use on narrow viewports (e.g. under a calendar).
12
+ */
13
+ orientation?: "vertical" | "horizontal";
14
+ className?: string;
15
+ };
16
+ /**
17
+ * Three linked scroll columns (12h clock, 5‑minute steps, AM/PM) sharing a center highlight.
18
+ * Built from {@link ScrollWheel}; use inside popovers or any fixed-height row.
19
+ */
20
+ declare function TimePicker({ value, onChange, disabled, orientation, className, }: TimePickerProps): react_jsx_runtime.JSX.Element;
21
+
22
+ export { TimePicker, type TimePickerProps, baseDateForTimePick };