avt-rct-lib 1.0.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/dist/index.cjs ADDED
@@ -0,0 +1,1341 @@
1
+ 'use strict';
2
+
3
+ var React3 = require('react');
4
+ var jsxRuntime = require('react/jsx-runtime');
5
+ var reactDom = require('react-dom');
6
+
7
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
8
+
9
+ var React3__default = /*#__PURE__*/_interopDefault(React3);
10
+
11
+ // src/components/Button.tsx
12
+
13
+ // src/lib/utils.ts
14
+ function cn(...inputs) {
15
+ const result = [];
16
+ for (const input of inputs) {
17
+ if (!input && input !== 0) continue;
18
+ if (typeof input === "string" || typeof input === "number") {
19
+ result.push(String(input));
20
+ } else if (Array.isArray(input)) {
21
+ const inner = cn(...input);
22
+ if (inner) result.push(inner);
23
+ } else if (typeof input === "object") {
24
+ for (const [key, val] of Object.entries(input)) {
25
+ if (val) result.push(key);
26
+ }
27
+ }
28
+ }
29
+ return result.join(" ");
30
+ }
31
+ var colors = {
32
+ blue: "#007AFF",
33
+ green: "#34C759",
34
+ red: "#FF3B30",
35
+ orange: "#FF9500",
36
+ purple: "#AF52DE",
37
+ teal: "#5AC8FA",
38
+ indigo: "#5856D6",
39
+ bg: "#F2F2F7",
40
+ card: "#FFFFFF",
41
+ label: "#1C1C1E",
42
+ label2: "#3C3C43",
43
+ label3: "#8E8E93",
44
+ sep: "#E5E5EA",
45
+ fill: "#F2F2F7",
46
+ fill2: "#E5E5EA",
47
+ fill3: "#D1D1D6"
48
+ };
49
+ function generateId() {
50
+ return Math.random().toString(36).slice(2, 9);
51
+ }
52
+ var base = [
53
+ "inline-flex items-center justify-center gap-2 font-medium select-none",
54
+ "transition-all duration-150 focus-visible:outline-none",
55
+ "focus-visible:ring-2 focus-visible:ring-[#007AFF]/40 focus-visible:ring-offset-1",
56
+ "disabled:pointer-events-none disabled:opacity-40",
57
+ "active:scale-[0.97]"
58
+ ].join(" ");
59
+ var variants = {
60
+ primary: "bg-[#007AFF] text-white rounded-xl shadow-[0_2px_8px_rgba(0,122,255,0.28)] hover:bg-[#0071EB] hover:shadow-[0_4px_12px_rgba(0,122,255,0.35)]",
61
+ secondary: "bg-[#F2F2F7] text-[#1C1C1E] rounded-xl hover:bg-[#E5E5EA]",
62
+ ghost: "text-[#007AFF] rounded-xl hover:bg-[#007AFF]/10",
63
+ outline: "border border-[#E5E5EA] bg-white text-[#1C1C1E] rounded-xl hover:bg-[#F2F2F7] shadow-[0_1px_3px_rgba(0,0,0,0.06)]",
64
+ destructive: "bg-[#FF3B30] text-white rounded-xl shadow-[0_2px_8px_rgba(255,59,48,0.25)] hover:bg-[#E0352B]",
65
+ link: "text-[#007AFF] underline-offset-4 hover:underline p-0 h-auto"
66
+ };
67
+ var sizes = {
68
+ xs: "h-7 px-3 text-xs",
69
+ sm: "h-8 px-4 text-sm",
70
+ md: "h-10 px-5 text-sm",
71
+ lg: "h-12 px-7 text-[15px]",
72
+ icon: "h-9 w-9 rounded-xl"
73
+ };
74
+ var Spinner = () => /* @__PURE__ */ jsxRuntime.jsxs("svg", { className: "h-4 w-4 animate-spin", viewBox: "0 0 24 24", fill: "none", children: [
75
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "3" }),
76
+ /* @__PURE__ */ jsxRuntime.jsx("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8v4a4 4 0 00-4 4H4z" })
77
+ ] });
78
+ var Button = React3__default.default.forwardRef(
79
+ ({
80
+ variant = "primary",
81
+ size = "md",
82
+ loading = false,
83
+ leftIcon,
84
+ rightIcon,
85
+ fullWidth = false,
86
+ className,
87
+ children,
88
+ disabled,
89
+ ...props
90
+ }, ref) => /* @__PURE__ */ jsxRuntime.jsxs(
91
+ "button",
92
+ {
93
+ ref,
94
+ disabled: disabled || loading,
95
+ className: cn(base, variants[variant], sizes[size], fullWidth && "w-full", className),
96
+ ...props,
97
+ children: [
98
+ loading ? /* @__PURE__ */ jsxRuntime.jsx(Spinner, {}) : leftIcon,
99
+ children,
100
+ !loading && rightIcon
101
+ ]
102
+ }
103
+ )
104
+ );
105
+ Button.displayName = "Button";
106
+ var variants2 = {
107
+ default: "bg-[#007AFF]/10 text-[#007AFF]",
108
+ secondary: "bg-[#F2F2F7] text-[#3C3C43]",
109
+ success: "bg-[#34C759]/12 text-[#1A8C39]",
110
+ warning: "bg-[#FF9500]/12 text-[#B86800]",
111
+ destructive: "bg-[#FF3B30]/10 text-[#D0302A]",
112
+ purple: "bg-[#AF52DE]/10 text-[#8B3BB5]",
113
+ outline: "border border-[#E5E5EA] bg-transparent text-[#3C3C43]"
114
+ };
115
+ var dotColors = {
116
+ default: "bg-[#007AFF]",
117
+ secondary: "bg-[#8E8E93]",
118
+ success: "bg-[#34C759]",
119
+ warning: "bg-[#FF9500]",
120
+ destructive: "bg-[#FF3B30]",
121
+ purple: "bg-[#AF52DE]",
122
+ outline: "bg-[#8E8E93]"
123
+ };
124
+ function Badge({ variant = "default", dot = false, className, children, ...props }) {
125
+ return /* @__PURE__ */ jsxRuntime.jsxs(
126
+ "span",
127
+ {
128
+ className: cn(
129
+ "inline-flex items-center gap-1.5 rounded-full px-2.5 py-0.5 text-xs font-medium select-none",
130
+ variants2[variant],
131
+ className
132
+ ),
133
+ ...props,
134
+ children: [
135
+ dot && /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("h-1.5 w-1.5 flex-shrink-0 rounded-full", dotColors[variant]) }),
136
+ children
137
+ ]
138
+ }
139
+ );
140
+ }
141
+ var Input = React3__default.default.forwardRef(
142
+ ({ label, hint, error, leftAddon, rightAddon, containerClassName, className, id, ...props }, ref) => {
143
+ const inputId = id ?? label?.toLowerCase().replace(/\s+/g, "-");
144
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col gap-1.5", containerClassName), children: [
145
+ label && /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: inputId, className: "text-[13px] font-medium text-[#3C3C43]", children: label }),
146
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex items-center", children: [
147
+ leftAddon && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute left-3.5 flex items-center text-[#8E8E93]", children: leftAddon }),
148
+ /* @__PURE__ */ jsxRuntime.jsx(
149
+ "input",
150
+ {
151
+ id: inputId,
152
+ ref,
153
+ className: cn(
154
+ "flex h-11 w-full rounded-xl bg-[#F2F2F7] text-sm text-[#1C1C1E]",
155
+ "px-4 placeholder:text-[#8E8E93]",
156
+ "border-0 outline-none",
157
+ "transition-all duration-150",
158
+ "focus:bg-white focus:shadow-[0_0_0_2px_rgba(0,122,255,0.22)]",
159
+ "disabled:cursor-not-allowed disabled:opacity-50",
160
+ error && "bg-[#FF3B30]/6 focus:shadow-[0_0_0_2px_rgba(255,59,48,0.22)]",
161
+ leftAddon && "pl-9",
162
+ rightAddon && "pr-9",
163
+ className
164
+ ),
165
+ ...props
166
+ }
167
+ ),
168
+ rightAddon && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute right-3.5 flex items-center text-[#8E8E93]", children: rightAddon })
169
+ ] }),
170
+ error ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-[#FF3B30]", children: error }) : hint ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-[#8E8E93]", children: hint }) : null
171
+ ] });
172
+ }
173
+ );
174
+ Input.displayName = "Input";
175
+ var Textarea = React3__default.default.forwardRef(
176
+ ({ label, hint, error, containerClassName, className, id, ...props }, ref) => {
177
+ const inputId = id ?? label?.toLowerCase().replace(/\s+/g, "-");
178
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col gap-1.5", containerClassName), children: [
179
+ label && /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: inputId, className: "text-[13px] font-medium text-[#3C3C43]", children: label }),
180
+ /* @__PURE__ */ jsxRuntime.jsx(
181
+ "textarea",
182
+ {
183
+ id: inputId,
184
+ ref,
185
+ className: cn(
186
+ "w-full rounded-xl bg-[#F2F2F7] px-4 py-3 text-sm text-[#1C1C1E]",
187
+ "placeholder:text-[#8E8E93] border-0 outline-none resize-none",
188
+ "transition-all duration-150",
189
+ "focus:bg-white focus:shadow-[0_0_0_2px_rgba(0,122,255,0.22)]",
190
+ "disabled:cursor-not-allowed disabled:opacity-50",
191
+ error && "bg-[#FF3B30]/6 focus:shadow-[0_0_0_2px_rgba(255,59,48,0.22)]",
192
+ className
193
+ ),
194
+ ...props
195
+ }
196
+ ),
197
+ error ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-[#FF3B30]", children: error }) : hint ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-[#8E8E93]", children: hint }) : null
198
+ ] });
199
+ }
200
+ );
201
+ Textarea.displayName = "Textarea";
202
+ function Card({ hover = false, glass = false, padding = "none", className, ...props }) {
203
+ const paddings = { none: "", sm: "p-4", md: "p-5", lg: "p-6" };
204
+ return /* @__PURE__ */ jsxRuntime.jsx(
205
+ "div",
206
+ {
207
+ className: cn(
208
+ "rounded-2xl border border-[#E5E5EA]/60",
209
+ glass ? "bg-white/75 backdrop-blur-2xl" : "bg-white",
210
+ "shadow-[0_2px_8px_rgba(0,0,0,0.07),_0_0_1px_rgba(0,0,0,0.04)]",
211
+ hover && "transition-shadow duration-200 hover:shadow-[0_4px_16px_rgba(0,0,0,0.10)] cursor-pointer",
212
+ paddings[padding],
213
+ className
214
+ ),
215
+ ...props
216
+ }
217
+ );
218
+ }
219
+ function CardHeader({ className, ...props }) {
220
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("px-5 pt-5 pb-4", className), ...props });
221
+ }
222
+ function CardTitle({ className, ...props }) {
223
+ return /* @__PURE__ */ jsxRuntime.jsx(
224
+ "h3",
225
+ {
226
+ className: cn("text-[15px] font-semibold tracking-[-0.01em] text-[#1C1C1E]", className),
227
+ ...props
228
+ }
229
+ );
230
+ }
231
+ function CardDescription({ className, ...props }) {
232
+ return /* @__PURE__ */ jsxRuntime.jsx("p", { className: cn("mt-0.5 text-[13px] text-[#8E8E93]", className), ...props });
233
+ }
234
+ function CardContent({ className, ...props }) {
235
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("px-5 pb-5", className), ...props });
236
+ }
237
+ function CardFooter({ className, ...props }) {
238
+ return /* @__PURE__ */ jsxRuntime.jsx(
239
+ "div",
240
+ {
241
+ className: cn(
242
+ "flex items-center justify-between px-5 py-3.5",
243
+ "border-t border-[#F2F2F7] bg-[#FAFAFA] rounded-b-2xl",
244
+ className
245
+ ),
246
+ ...props
247
+ }
248
+ );
249
+ }
250
+ function CardDivider({ className, ...props }) {
251
+ return /* @__PURE__ */ jsxRuntime.jsx("hr", { className: cn("border-0 border-t border-[#F2F2F7]", className), ...props });
252
+ }
253
+ function Table({ card = true, className, children, ...props }) {
254
+ const childArray = React3__default.default.Children.toArray(children);
255
+ const toolbars = childArray.filter((c) => React3__default.default.isValidElement(c) && c.type === TableToolbar);
256
+ const paginations = childArray.filter((c) => React3__default.default.isValidElement(c) && c.type === TablePagination);
257
+ const tableNodes = childArray.filter(
258
+ (c) => React3__default.default.isValidElement(c) && c.type !== TableToolbar && c.type !== TablePagination
259
+ );
260
+ const inner = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
261
+ toolbars,
262
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full overflow-x-auto avt-scroll", children: /* @__PURE__ */ jsxRuntime.jsx("table", { className: "w-full caption-bottom text-sm", children: tableNodes }) }),
263
+ paginations
264
+ ] });
265
+ if (!card) return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: inner });
266
+ return /* @__PURE__ */ jsxRuntime.jsx(
267
+ "div",
268
+ {
269
+ className: cn(
270
+ "rounded-2xl border border-[#E5E5EA]/60 bg-white overflow-hidden",
271
+ "shadow-[0_2px_8px_rgba(0,0,0,0.07)]",
272
+ className
273
+ ),
274
+ ...props,
275
+ children: inner
276
+ }
277
+ );
278
+ }
279
+ function TableHeader({ className, ...props }) {
280
+ return /* @__PURE__ */ jsxRuntime.jsx(
281
+ "thead",
282
+ {
283
+ className: cn("bg-[#F9F9F9] border-b border-[#F2F2F7]", className),
284
+ ...props
285
+ }
286
+ );
287
+ }
288
+ function TableBody({ className, ...props }) {
289
+ return /* @__PURE__ */ jsxRuntime.jsx("tbody", { className: cn("[&_tr:last-child]:border-0", className), ...props });
290
+ }
291
+ function TableFooter({ className, ...props }) {
292
+ return /* @__PURE__ */ jsxRuntime.jsx(
293
+ "tfoot",
294
+ {
295
+ className: cn("border-t border-[#F2F2F7] bg-[#FAFAFA] font-medium", className),
296
+ ...props
297
+ }
298
+ );
299
+ }
300
+ function TableRow({ className, ...props }) {
301
+ return /* @__PURE__ */ jsxRuntime.jsx(
302
+ "tr",
303
+ {
304
+ className: cn(
305
+ "border-b border-[#F2F2F7] transition-colors duration-100",
306
+ "hover:bg-[#007AFF]/[0.03]",
307
+ className
308
+ ),
309
+ ...props
310
+ }
311
+ );
312
+ }
313
+ function TableHead({ className, ...props }) {
314
+ return /* @__PURE__ */ jsxRuntime.jsx(
315
+ "th",
316
+ {
317
+ className: cn(
318
+ "h-10 px-4 text-left align-middle",
319
+ "text-[11px] font-semibold text-[#8E8E93] uppercase tracking-wider",
320
+ className
321
+ ),
322
+ ...props
323
+ }
324
+ );
325
+ }
326
+ function TableCell({ className, ...props }) {
327
+ return /* @__PURE__ */ jsxRuntime.jsx("td", { className: cn("px-4 py-3.5 align-middle text-[13px] text-[#1C1C1E]", className), ...props });
328
+ }
329
+ function TableCaption({ className, ...props }) {
330
+ return /* @__PURE__ */ jsxRuntime.jsx("caption", { className: cn("mt-4 text-xs text-[#8E8E93]", className), ...props });
331
+ }
332
+ function TableToolbar({ className, ...props }) {
333
+ return /* @__PURE__ */ jsxRuntime.jsx(
334
+ "div",
335
+ {
336
+ className: cn("flex items-center gap-3 px-5 py-3.5 border-b border-[#F2F2F7]", className),
337
+ ...props
338
+ }
339
+ );
340
+ }
341
+ function TablePagination({
342
+ page,
343
+ pageCount,
344
+ canPrev,
345
+ canNext,
346
+ onPrev,
347
+ onNext,
348
+ className
349
+ }) {
350
+ const Btn = ({
351
+ onClick,
352
+ disabled,
353
+ children
354
+ }) => /* @__PURE__ */ jsxRuntime.jsx(
355
+ "button",
356
+ {
357
+ onClick,
358
+ disabled,
359
+ className: "flex h-7 w-7 items-center justify-center rounded-lg bg-[#F2F2F7] text-[#3C3C43] hover:bg-[#E5E5EA] disabled:opacity-40 transition-colors",
360
+ children
361
+ }
362
+ );
363
+ return /* @__PURE__ */ jsxRuntime.jsxs(
364
+ "div",
365
+ {
366
+ className: cn(
367
+ "flex items-center justify-between border-t border-[#F2F2F7] px-5 py-3",
368
+ className
369
+ ),
370
+ children: [
371
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-[12px] text-[#8E8E93]", children: [
372
+ "Halaman ",
373
+ page,
374
+ " dari ",
375
+ pageCount || 1
376
+ ] }),
377
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-1.5", children: [
378
+ /* @__PURE__ */ jsxRuntime.jsx(Btn, { onClick: onPrev, disabled: !canPrev, children: /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "h-4 w-4", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M15 18l-6-6 6-6" }) }) }),
379
+ /* @__PURE__ */ jsxRuntime.jsx(Btn, { onClick: onNext, disabled: !canNext, children: /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "h-4 w-4", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M9 18l6-6-6-6" }) }) })
380
+ ] })
381
+ ]
382
+ }
383
+ );
384
+ }
385
+ var TabsContext = React3.createContext({
386
+ active: "",
387
+ setActive: () => {
388
+ },
389
+ variant: "pills"
390
+ });
391
+ var useTabs = () => React3.useContext(TabsContext);
392
+ function Tabs({
393
+ defaultValue = "",
394
+ value,
395
+ onValueChange,
396
+ variant = "pills",
397
+ children,
398
+ className
399
+ }) {
400
+ const [internalActive, setInternalActive] = React3.useState(defaultValue);
401
+ const active = value ?? internalActive;
402
+ const setActive = (v) => {
403
+ setInternalActive(v);
404
+ onValueChange?.(v);
405
+ };
406
+ return /* @__PURE__ */ jsxRuntime.jsx(TabsContext.Provider, { value: { active, setActive, variant }, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("flex flex-col", className), children }) });
407
+ }
408
+ function TabsList({ className, children, ...props }) {
409
+ const { variant } = useTabs();
410
+ return /* @__PURE__ */ jsxRuntime.jsx(
411
+ "div",
412
+ {
413
+ role: "tablist",
414
+ className: cn(
415
+ "flex items-center overflow-x-auto avt-scroll",
416
+ variant === "segment" && "gap-0.5 rounded-xl bg-[#E5E5EA] p-1 min-w-0 flex-shrink-0",
417
+ variant === "pills" && "gap-1",
418
+ variant === "underline" && "gap-0 border-b border-[#E5E5EA]",
419
+ className
420
+ ),
421
+ ...props,
422
+ children
423
+ }
424
+ );
425
+ }
426
+ function TabsTrigger({ value, icon, className, children, ...props }) {
427
+ const { active, setActive, variant } = useTabs();
428
+ const isActive = active === value;
429
+ return /* @__PURE__ */ jsxRuntime.jsxs(
430
+ "button",
431
+ {
432
+ role: "tab",
433
+ "aria-selected": isActive,
434
+ onClick: () => setActive(value),
435
+ className: cn(
436
+ "inline-flex flex-shrink-0 items-center gap-1.5 text-[13px] font-medium transition-all duration-150 select-none whitespace-nowrap",
437
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#007AFF]/30",
438
+ "disabled:pointer-events-none disabled:opacity-50",
439
+ variant === "segment" && [
440
+ "flex-1 justify-center rounded-lg px-3 py-2 min-h-[36px]",
441
+ isActive ? "bg-white text-[#1C1C1E] shadow-[0_1px_3px_rgba(0,0,0,0.12)]" : "text-[#8E8E93] hover:text-[#3C3C43]"
442
+ ],
443
+ variant === "pills" && [
444
+ "rounded-lg px-3.5 py-2 min-h-[36px]",
445
+ isActive ? "bg-[#007AFF] text-white shadow-[0_2px_6px_rgba(0,122,255,0.25)]" : "text-[#8E8E93] hover:bg-[#F2F2F7] hover:text-[#1C1C1E]"
446
+ ],
447
+ variant === "underline" && [
448
+ "relative px-4 py-3 border-b-2 -mb-px min-h-[44px]",
449
+ isActive ? "border-[#007AFF] text-[#007AFF]" : "border-transparent text-[#8E8E93] hover:text-[#3C3C43]"
450
+ ],
451
+ className
452
+ ),
453
+ ...props,
454
+ children: [
455
+ icon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-shrink-0", children: icon }),
456
+ children
457
+ ]
458
+ }
459
+ );
460
+ }
461
+ function TabsContent({
462
+ value,
463
+ keepMounted = false,
464
+ className,
465
+ children,
466
+ ...props
467
+ }) {
468
+ const { active } = useTabs();
469
+ const isActive = active === value;
470
+ if (!keepMounted && !isActive) return null;
471
+ return /* @__PURE__ */ jsxRuntime.jsx(
472
+ "div",
473
+ {
474
+ role: "tabpanel",
475
+ hidden: !isActive,
476
+ className: cn("avt-animate-fade-in", isActive && "block", className),
477
+ ...props,
478
+ children
479
+ }
480
+ );
481
+ }
482
+ function Scrollbar({
483
+ maxHeight,
484
+ maxWidth,
485
+ direction = "vertical",
486
+ always = false,
487
+ className,
488
+ style,
489
+ ...props
490
+ }) {
491
+ const overflow = {
492
+ vertical: "overflow-y-auto overflow-x-hidden",
493
+ horizontal: "overflow-x-auto overflow-y-hidden",
494
+ both: "overflow-auto"
495
+ }[direction];
496
+ return /* @__PURE__ */ jsxRuntime.jsx(
497
+ "div",
498
+ {
499
+ className: cn(
500
+ "avt-scroll",
501
+ overflow,
502
+ // On hover scroll trick (webkit only - fallback gracefully)
503
+ !always && "hover:avt-scroll",
504
+ className
505
+ ),
506
+ style: {
507
+ maxHeight: typeof maxHeight === "number" ? `${maxHeight}px` : maxHeight,
508
+ maxWidth: typeof maxWidth === "number" ? `${maxWidth}px` : maxWidth,
509
+ ...style
510
+ },
511
+ ...props
512
+ }
513
+ );
514
+ }
515
+ function withScrollbar(Component, scrollbarProps) {
516
+ return function ScrollbarWrapped(props) {
517
+ return /* @__PURE__ */ jsxRuntime.jsx(Scrollbar, { ...scrollbarProps, children: /* @__PURE__ */ jsxRuntime.jsx(Component, { ...props }) });
518
+ };
519
+ }
520
+ var storeState = [];
521
+ var storeListeners = /* @__PURE__ */ new Set();
522
+ var timers = /* @__PURE__ */ new Map();
523
+ function dispatch(action) {
524
+ if (action.type === "ADD") {
525
+ storeState = [...storeState, action.payload];
526
+ } else if (action.type === "REMOVE") {
527
+ storeState = storeState.filter((t) => t.id !== action.payload.id);
528
+ const timer = timers.get(action.payload.id);
529
+ if (timer) {
530
+ clearTimeout(timer);
531
+ timers.delete(action.payload.id);
532
+ }
533
+ }
534
+ storeListeners.forEach((l) => l());
535
+ }
536
+ function toast(options) {
537
+ const id = generateId();
538
+ const duration = options.duration ?? 4e3;
539
+ dispatch({ type: "ADD", payload: { id, duration, ...options } });
540
+ if (duration !== Infinity) {
541
+ timers.set(id, setTimeout(() => dispatch({ type: "REMOVE", payload: { id } }), duration));
542
+ }
543
+ return id;
544
+ }
545
+ function dismissToast(id) {
546
+ dispatch({ type: "REMOVE", payload: { id } });
547
+ }
548
+ function useToast() {
549
+ const [, forceUpdate] = React3.useReducer((x) => x + 1, 0);
550
+ React3.useEffect(() => {
551
+ storeListeners.add(forceUpdate);
552
+ return () => {
553
+ storeListeners.delete(forceUpdate);
554
+ };
555
+ }, []);
556
+ return {
557
+ toasts: storeState,
558
+ toast,
559
+ dismiss: dismissToast
560
+ };
561
+ }
562
+ var IconCheck = () => /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "h-4 w-4 flex-shrink-0 mt-0.5", viewBox: "0 0 24 24", fill: "none", stroke: "#34C759", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M20 6L9 17l-5-5" }) });
563
+ var IconX = () => /* @__PURE__ */ jsxRuntime.jsxs("svg", { className: "h-4 w-4 flex-shrink-0 mt-0.5", viewBox: "0 0 24 24", fill: "none", stroke: "#FF3B30", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
564
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "12", cy: "12", r: "10" }),
565
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M15 9l-6 6M9 9l6 6" })
566
+ ] });
567
+ var IconInfo = () => /* @__PURE__ */ jsxRuntime.jsxs("svg", { className: "h-4 w-4 flex-shrink-0 mt-0.5", viewBox: "0 0 24 24", fill: "none", stroke: "#007AFF", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
568
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "12", cy: "12", r: "10" }),
569
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M12 16v-4M12 8h.01" })
570
+ ] });
571
+ var IconWarn = () => /* @__PURE__ */ jsxRuntime.jsxs("svg", { className: "h-4 w-4 flex-shrink-0 mt-0.5", viewBox: "0 0 24 24", fill: "none", stroke: "#FF9500", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
572
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z" }),
573
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M12 9v4M12 17h.01" })
574
+ ] });
575
+ var defaultIcons = {
576
+ default: /* @__PURE__ */ jsxRuntime.jsx(IconInfo, {}),
577
+ success: /* @__PURE__ */ jsxRuntime.jsx(IconCheck, {}),
578
+ destructive: /* @__PURE__ */ jsxRuntime.jsx(IconX, {}),
579
+ warning: /* @__PURE__ */ jsxRuntime.jsx(IconWarn, {})
580
+ };
581
+ function ToastItemComp({ item, onDismiss }) {
582
+ return /* @__PURE__ */ jsxRuntime.jsxs(
583
+ "div",
584
+ {
585
+ className: cn(
586
+ "avt-animate-toast",
587
+ "flex w-[calc(100vw-2rem)] sm:w-full max-w-[360px] items-start gap-3 rounded-2xl",
588
+ "border border-[#E5E5EA]/60 bg-white/95 backdrop-blur-2xl",
589
+ "px-4 py-3.5 shadow-[0_8px_24px_rgba(0,0,0,0.12),_0_0_1px_rgba(0,0,0,0.06)]",
590
+ "group cursor-default select-none"
591
+ ),
592
+ role: "alert",
593
+ children: [
594
+ item.icon ?? defaultIcons[item.variant ?? "default"],
595
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [
596
+ item.title && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[13px] font-semibold text-[#1C1C1E] leading-snug", children: item.title }),
597
+ item.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-0.5 text-[12px] text-[#8E8E93] leading-snug", children: item.description })
598
+ ] }),
599
+ /* @__PURE__ */ jsxRuntime.jsx(
600
+ "button",
601
+ {
602
+ onClick: () => onDismiss(item.id),
603
+ className: cn(
604
+ "flex h-5 w-5 flex-shrink-0 items-center justify-center rounded-full",
605
+ "bg-[#F2F2F7] text-[#8E8E93]",
606
+ "opacity-0 group-hover:opacity-100 transition-opacity",
607
+ "hover:bg-[#E5E5EA] hover:text-[#1C1C1E]"
608
+ ),
609
+ "aria-label": "Tutup",
610
+ children: /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "h-3 w-3", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M18 6L6 18M6 6l12 12" }) })
611
+ }
612
+ )
613
+ ]
614
+ }
615
+ );
616
+ }
617
+ var positionClasses = {
618
+ "top-right": "top-4 right-4 items-end",
619
+ "top-left": "top-4 left-4 items-start",
620
+ "top-center": "top-4 left-1/2 -translate-x-1/2 items-center",
621
+ "bottom-right": "bottom-4 right-4 sm:right-4 left-4 sm:left-auto items-end",
622
+ "bottom-left": "bottom-4 left-4 items-start",
623
+ "bottom-center": "bottom-4 left-1/2 -translate-x-1/2 items-center"
624
+ };
625
+ function Toaster({ position = "bottom-right" }) {
626
+ const { toasts, dismiss } = useToast();
627
+ if (typeof document === "undefined") return null;
628
+ return reactDom.createPortal(
629
+ /* @__PURE__ */ jsxRuntime.jsx(
630
+ "div",
631
+ {
632
+ className: cn(
633
+ "fixed z-[9999] flex flex-col gap-2 pointer-events-none",
634
+ positionClasses[position]
635
+ ),
636
+ "aria-live": "polite",
637
+ "aria-label": "Notifications",
638
+ children: toasts.map((item) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pointer-events-auto", children: /* @__PURE__ */ jsxRuntime.jsx(ToastItemComp, { item, onDismiss: dismiss }) }, item.id))
639
+ }
640
+ ),
641
+ document.body
642
+ );
643
+ }
644
+ function useKeydown(key, handler, enabled = true) {
645
+ React3.useEffect(() => {
646
+ if (!enabled) return;
647
+ const listener = (e) => {
648
+ if (e.key === key) handler();
649
+ };
650
+ document.addEventListener("keydown", listener);
651
+ return () => document.removeEventListener("keydown", listener);
652
+ }, [key, handler, enabled]);
653
+ }
654
+ var MenuContext = React3.createContext({
655
+ open: false,
656
+ close: () => {
657
+ },
658
+ rootRef: { current: null },
659
+ contentRef: { current: null }
660
+ });
661
+ var useMenu = () => React3.useContext(MenuContext);
662
+ function MenuRoot({ children, open: controlledOpen, onOpenChange }) {
663
+ const [internalOpen, setInternalOpen] = React3.useState(false);
664
+ const open = controlledOpen ?? internalOpen;
665
+ const setOpen = (v) => {
666
+ setInternalOpen(v);
667
+ onOpenChange?.(v);
668
+ };
669
+ const close = React3.useCallback(() => setOpen(false), []);
670
+ const toggle = () => setOpen(!open);
671
+ const rootRef = React3.useRef(null);
672
+ const contentRef = React3.useRef(null);
673
+ useKeydown("Escape", close, open);
674
+ React3.useEffect(() => {
675
+ if (!open) return;
676
+ const handler = (e) => {
677
+ const target = e.target;
678
+ if (rootRef.current?.contains(target)) return;
679
+ if (contentRef.current?.contains(target)) return;
680
+ close();
681
+ };
682
+ document.addEventListener("mousedown", handler, true);
683
+ document.addEventListener("touchstart", handler, true);
684
+ return () => {
685
+ document.removeEventListener("mousedown", handler, true);
686
+ document.removeEventListener("touchstart", handler, true);
687
+ };
688
+ }, [open, close]);
689
+ React3.useEffect(() => {
690
+ const el = rootRef.current;
691
+ if (!el) return;
692
+ const handler = () => toggle();
693
+ el.addEventListener("avt-menu-toggle", handler);
694
+ return () => el.removeEventListener("avt-menu-toggle", handler);
695
+ }, [open]);
696
+ return /* @__PURE__ */ jsxRuntime.jsx(MenuContext.Provider, { value: { open, close, rootRef, contentRef }, children: /* @__PURE__ */ jsxRuntime.jsx("div", { ref: rootRef, "data-avt-menu": "", className: "relative inline-block", children }) });
697
+ }
698
+ function MenuButton({
699
+ className,
700
+ children,
701
+ ...props
702
+ }) {
703
+ const { open } = useMenu();
704
+ const handleClick = (e) => {
705
+ e.stopPropagation();
706
+ props.onClick?.(e);
707
+ const el = e.currentTarget.closest("[data-avt-menu]");
708
+ el?.dispatchEvent(new CustomEvent("avt-menu-toggle", { bubbles: false }));
709
+ };
710
+ return /* @__PURE__ */ jsxRuntime.jsx(
711
+ "button",
712
+ {
713
+ type: "button",
714
+ "aria-haspopup": "menu",
715
+ "aria-expanded": open,
716
+ className: cn("select-none", className),
717
+ ...props,
718
+ onClick: handleClick,
719
+ children
720
+ }
721
+ );
722
+ }
723
+ function MenuContent({
724
+ align = "start",
725
+ sideOffset = 6,
726
+ minWidth = 180,
727
+ className,
728
+ children,
729
+ style,
730
+ ...props
731
+ }) {
732
+ const { open, rootRef, contentRef } = useMenu();
733
+ const [pos, setPos] = React3.useState(null);
734
+ React3.useEffect(() => {
735
+ if (!open) {
736
+ setPos(null);
737
+ return;
738
+ }
739
+ const update = () => {
740
+ if (!rootRef.current) return;
741
+ const rect = rootRef.current.getBoundingClientRect();
742
+ const vw = window.innerWidth;
743
+ const vh = window.innerHeight;
744
+ let left;
745
+ if (align === "end") left = rect.right - minWidth;
746
+ else if (align === "center") left = rect.left + rect.width / 2 - minWidth / 2;
747
+ else left = rect.left;
748
+ left = Math.max(8, Math.min(left, vw - minWidth - 8));
749
+ const spaceBelow = vh - rect.bottom - sideOffset - 8;
750
+ const spaceAbove = rect.top - sideOffset - 8;
751
+ const flipUp = spaceBelow < 100 && spaceAbove > spaceBelow;
752
+ const top = flipUp ? rect.top - sideOffset - Math.min(320, spaceAbove) : rect.bottom + sideOffset;
753
+ const maxH = flipUp ? Math.max(60, spaceAbove) : Math.max(60, spaceBelow);
754
+ setPos({ top, left, maxH });
755
+ };
756
+ update();
757
+ window.addEventListener("scroll", update, true);
758
+ window.addEventListener("resize", update);
759
+ return () => {
760
+ window.removeEventListener("scroll", update, true);
761
+ window.removeEventListener("resize", update);
762
+ };
763
+ }, [open, align, sideOffset, minWidth]);
764
+ if (!open || !pos || typeof document === "undefined") return null;
765
+ return reactDom.createPortal(
766
+ /* @__PURE__ */ jsxRuntime.jsx(
767
+ "div",
768
+ {
769
+ ref: contentRef,
770
+ role: "menu",
771
+ className: cn(
772
+ "fixed z-[9999] avt-animate-slide-up overflow-y-auto avt-scroll",
773
+ "rounded-xl border border-[#E5E5EA]/60 bg-white/95 backdrop-blur-2xl",
774
+ "shadow-[0_8px_24px_rgba(0,0,0,0.10),_0_0_1px_rgba(0,0,0,0.06)]",
775
+ "py-1.5",
776
+ className
777
+ ),
778
+ style: { top: pos.top, left: pos.left, minWidth, maxHeight: pos.maxH, ...style },
779
+ ...props,
780
+ children
781
+ }
782
+ ),
783
+ document.body
784
+ );
785
+ }
786
+ function MenuItem({
787
+ icon,
788
+ rightSlot,
789
+ variant = "default",
790
+ disabled,
791
+ className,
792
+ children,
793
+ onClick,
794
+ ...props
795
+ }) {
796
+ const { close } = useMenu();
797
+ return /* @__PURE__ */ jsxRuntime.jsxs(
798
+ "button",
799
+ {
800
+ role: "menuitem",
801
+ type: "button",
802
+ disabled,
803
+ className: cn(
804
+ "flex w-full items-center gap-2.5 px-3.5 py-2.5 text-[13px] font-medium",
805
+ "transition-colors duration-100 outline-none select-none",
806
+ "focus-visible:bg-[#F2F2F7]",
807
+ // Mobile: min touch target
808
+ "min-h-[44px] sm:min-h-0",
809
+ variant === "default" ? "text-[#1C1C1E] hover:bg-[#F2F2F7]" : "text-[#FF3B30] hover:bg-[#FF3B30]/8",
810
+ disabled && "pointer-events-none opacity-40",
811
+ className
812
+ ),
813
+ onClick: (e) => {
814
+ onClick?.(e);
815
+ close();
816
+ },
817
+ ...props,
818
+ children: [
819
+ icon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("flex-shrink-0", variant === "default" ? "text-[#8E8E93]" : "text-[#FF3B30]"), children: icon }),
820
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1 text-left", children }),
821
+ rightSlot && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-auto text-[#8E8E93]", children: rightSlot })
822
+ ]
823
+ }
824
+ );
825
+ }
826
+ function MenuSeparator({ className }) {
827
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("my-1 h-px bg-[#F2F2F7]", className), role: "separator" });
828
+ }
829
+ function MenuLabel({ className, children }) {
830
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("px-3.5 py-1.5 text-[11px] font-semibold uppercase tracking-wider text-[#8E8E93]", className), children });
831
+ }
832
+ function MenuTrigger({ children }) {
833
+ return children;
834
+ }
835
+ var slideAnim = {
836
+ right: "avt-animate-slide-right",
837
+ left: "avt-animate-slide-left",
838
+ bottom: "avt-animate-slide-bottom"
839
+ };
840
+ var positionClasses2 = {
841
+ right: "right-0 top-0 h-full",
842
+ left: "left-0 top-0 h-full",
843
+ bottom: "bottom-0 left-0 w-full"
844
+ };
845
+ function Sheet({
846
+ open,
847
+ onClose,
848
+ side = "right",
849
+ width = "420px",
850
+ height = "60vh",
851
+ closeOnOverlay = true,
852
+ children
853
+ }) {
854
+ useKeydown("Escape", onClose, open);
855
+ React3.useEffect(() => {
856
+ if (open) document.body.style.overflow = "hidden";
857
+ else document.body.style.overflow = "";
858
+ return () => {
859
+ document.body.style.overflow = "";
860
+ };
861
+ }, [open]);
862
+ if (!open || typeof document === "undefined") return null;
863
+ const panelStyle = {
864
+ ...side !== "bottom" ? { width } : { height }
865
+ };
866
+ return reactDom.createPortal(
867
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "fixed inset-0 z-[999] flex", "aria-modal": "true", role: "dialog", children: [
868
+ /* @__PURE__ */ jsxRuntime.jsx(
869
+ "div",
870
+ {
871
+ className: "absolute inset-0 bg-black/30 backdrop-blur-[2px] avt-animate-fade-in",
872
+ onClick: closeOnOverlay ? onClose : void 0,
873
+ "aria-hidden": "true"
874
+ }
875
+ ),
876
+ /* @__PURE__ */ jsxRuntime.jsx(
877
+ "div",
878
+ {
879
+ className: cn(
880
+ "absolute z-10 flex flex-col bg-white/95 backdrop-blur-2xl",
881
+ "border-[#E5E5EA]/60 shadow-[0_16px_48px_rgba(0,0,0,0.16)]",
882
+ side === "right" && "border-l rounded-l-2xl",
883
+ side === "left" && "border-r rounded-r-2xl",
884
+ side === "bottom" && "border-t rounded-t-2xl",
885
+ positionClasses2[side],
886
+ slideAnim[side]
887
+ ),
888
+ style: panelStyle,
889
+ onClick: (e) => e.stopPropagation(),
890
+ children
891
+ }
892
+ )
893
+ ] }),
894
+ document.body
895
+ );
896
+ }
897
+ function SheetHeader({ showClose, onClose, className, children, ...props }) {
898
+ return /* @__PURE__ */ jsxRuntime.jsxs(
899
+ "div",
900
+ {
901
+ className: cn("flex items-start justify-between px-6 pt-6 pb-4 border-b border-[#F2F2F7]", className),
902
+ ...props,
903
+ children: [
904
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 min-w-0 pr-3", children }),
905
+ showClose && onClose && /* @__PURE__ */ jsxRuntime.jsx(
906
+ "button",
907
+ {
908
+ onClick: onClose,
909
+ className: cn(
910
+ "flex h-7 w-7 flex-shrink-0 items-center justify-center rounded-full",
911
+ "bg-[#F2F2F7] text-[#8E8E93] hover:bg-[#E5E5EA] hover:text-[#1C1C1E]",
912
+ "transition-colors duration-150"
913
+ ),
914
+ "aria-label": "Tutup",
915
+ children: /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "h-3.5 w-3.5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M18 6L6 18M6 6l12 12" }) })
916
+ }
917
+ )
918
+ ]
919
+ }
920
+ );
921
+ }
922
+ function SheetTitle({ className, ...props }) {
923
+ return /* @__PURE__ */ jsxRuntime.jsx(
924
+ "h2",
925
+ {
926
+ className: cn("text-[15px] font-semibold tracking-[-0.01em] text-[#1C1C1E]", className),
927
+ ...props
928
+ }
929
+ );
930
+ }
931
+ function SheetDescription({ className, ...props }) {
932
+ return /* @__PURE__ */ jsxRuntime.jsx("p", { className: cn("mt-0.5 text-[13px] text-[#8E8E93]", className), ...props });
933
+ }
934
+ function SheetContent({ className, ...props }) {
935
+ return /* @__PURE__ */ jsxRuntime.jsx(
936
+ "div",
937
+ {
938
+ className: cn("flex-1 overflow-y-auto px-6 py-5 avt-scroll", className),
939
+ ...props
940
+ }
941
+ );
942
+ }
943
+ function SheetFooter({ className, ...props }) {
944
+ return /* @__PURE__ */ jsxRuntime.jsx(
945
+ "div",
946
+ {
947
+ className: cn(
948
+ "flex items-center justify-end gap-2 px-6 py-4",
949
+ "border-t border-[#F2F2F7] bg-[#FAFAFA]",
950
+ className
951
+ ),
952
+ ...props
953
+ }
954
+ );
955
+ }
956
+ function Drawer({ children, ...props }) {
957
+ return /* @__PURE__ */ jsxRuntime.jsx(Sheet, { side: "bottom", ...props, children });
958
+ }
959
+ function Navbar({
960
+ glass = true,
961
+ border = true,
962
+ sticky = true,
963
+ height = "h-14",
964
+ className,
965
+ children,
966
+ ...props
967
+ }) {
968
+ return /* @__PURE__ */ jsxRuntime.jsx(
969
+ "header",
970
+ {
971
+ className: cn(
972
+ "w-full z-40",
973
+ sticky && "sticky top-0",
974
+ glass ? "bg-white/80 backdrop-blur-2xl" : "bg-white",
975
+ border && "border-b border-[#E5E5EA]/70",
976
+ height,
977
+ className
978
+ ),
979
+ ...props,
980
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-full items-center px-5 gap-4", children })
981
+ }
982
+ );
983
+ }
984
+ function NavbarLeft({ className, ...props }) {
985
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("flex items-center gap-3 flex-shrink-0", className), ...props });
986
+ }
987
+ function NavbarCenter({ className, ...props }) {
988
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("flex flex-1 items-center justify-center", className), ...props });
989
+ }
990
+ function NavbarRight({ className, ...props }) {
991
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("flex items-center gap-2 flex-shrink-0 ml-auto", className), ...props });
992
+ }
993
+ function NavbarBrand({ logo, title, subtitle, className, ...props }) {
994
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex items-center gap-2.5", className), ...props, children: [
995
+ logo && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-shrink-0", children: logo }),
996
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
997
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[14px] font-semibold tracking-[-0.01em] text-[#1C1C1E] leading-none", children: title }),
998
+ subtitle && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[11px] text-[#8E8E93] mt-0.5 leading-none", children: subtitle })
999
+ ] })
1000
+ ] });
1001
+ }
1002
+ var SearchIcon = () => /* @__PURE__ */ jsxRuntime.jsxs("svg", { className: "h-4 w-4", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round", strokeLinejoin: "round", children: [
1003
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "11", cy: "11", r: "8" }),
1004
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M21 21l-4.35-4.35" })
1005
+ ] });
1006
+ function NavbarSearch({ icon, className, ...props }) {
1007
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative w-64", children: [
1008
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute left-3 top-1/2 -translate-y-1/2 text-[#8E8E93]", children: icon ?? /* @__PURE__ */ jsxRuntime.jsx(SearchIcon, {}) }),
1009
+ /* @__PURE__ */ jsxRuntime.jsx(
1010
+ "input",
1011
+ {
1012
+ type: "search",
1013
+ className: cn(
1014
+ "h-9 w-full rounded-xl bg-[#F2F2F7] pl-9 pr-4 text-sm text-[#1C1C1E]",
1015
+ "placeholder:text-[#8E8E93] border-0 outline-none",
1016
+ "focus:bg-white focus:shadow-[0_0_0_2px_rgba(0,122,255,0.22)] transition-all duration-150",
1017
+ className
1018
+ ),
1019
+ ...props
1020
+ }
1021
+ )
1022
+ ] });
1023
+ }
1024
+ function NavbarIconButton({
1025
+ badge,
1026
+ tooltip,
1027
+ className,
1028
+ children,
1029
+ ...props
1030
+ }) {
1031
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", title: tooltip, children: [
1032
+ /* @__PURE__ */ jsxRuntime.jsx(
1033
+ "button",
1034
+ {
1035
+ type: "button",
1036
+ className: cn(
1037
+ "flex h-9 w-9 items-center justify-center rounded-xl text-[#3C3C43]",
1038
+ "hover:bg-[#F2F2F7] transition-colors duration-150",
1039
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#007AFF]/30",
1040
+ className
1041
+ ),
1042
+ ...props,
1043
+ children
1044
+ }
1045
+ ),
1046
+ badge !== void 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute -top-0.5 -right-0.5 flex h-4 min-w-4 items-center justify-center rounded-full bg-[#FF3B30] px-1 text-[10px] font-bold text-white", children: badge })
1047
+ ] });
1048
+ }
1049
+ function NavbarDivider({ className }) {
1050
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("h-5 w-px bg-[#E5E5EA]", className) });
1051
+ }
1052
+ var SidebarContext = React3.createContext({ collapsed: false });
1053
+ var useSidebar = () => React3.useContext(SidebarContext);
1054
+ function Sidebar({
1055
+ collapsed = false,
1056
+ glass = true,
1057
+ width = "240px",
1058
+ collapsedWidth = "64px",
1059
+ overlay = false,
1060
+ onOverlayClose,
1061
+ className,
1062
+ children,
1063
+ style,
1064
+ ...props
1065
+ }) {
1066
+ if (overlay) {
1067
+ return /* @__PURE__ */ jsxRuntime.jsxs(SidebarContext.Provider, { value: { collapsed: false }, children: [
1068
+ /* @__PURE__ */ jsxRuntime.jsx(
1069
+ "div",
1070
+ {
1071
+ className: cn(
1072
+ "fixed inset-0 z-40 transition-opacity duration-300",
1073
+ collapsed ? "pointer-events-none opacity-0" : "bg-black/30 backdrop-blur-[2px]"
1074
+ ),
1075
+ onClick: onOverlayClose,
1076
+ "aria-hidden": "true"
1077
+ }
1078
+ ),
1079
+ /* @__PURE__ */ jsxRuntime.jsx(
1080
+ "aside",
1081
+ {
1082
+ className: cn(
1083
+ "fixed left-0 top-0 z-50 flex h-full flex-col",
1084
+ "border-r border-[#E5E5EA]/70",
1085
+ glass ? "bg-white/90 backdrop-blur-2xl" : "bg-white",
1086
+ "transition-transform duration-300 ease-[cubic-bezier(0.16,1,0.3,1)]",
1087
+ collapsed ? "-translate-x-full" : "translate-x-0",
1088
+ className
1089
+ ),
1090
+ style: { width, ...style },
1091
+ ...props,
1092
+ children
1093
+ }
1094
+ )
1095
+ ] });
1096
+ }
1097
+ return /* @__PURE__ */ jsxRuntime.jsx(SidebarContext.Provider, { value: { collapsed }, children: /* @__PURE__ */ jsxRuntime.jsx(
1098
+ "aside",
1099
+ {
1100
+ className: cn(
1101
+ "flex h-full flex-shrink-0 flex-col",
1102
+ "border-r border-[#E5E5EA]/70",
1103
+ glass ? "bg-white/80 backdrop-blur-2xl" : "bg-white",
1104
+ "transition-[width] duration-200",
1105
+ className
1106
+ ),
1107
+ style: { width: collapsed ? collapsedWidth : width, ...style },
1108
+ ...props,
1109
+ children
1110
+ }
1111
+ ) });
1112
+ }
1113
+ function SidebarHeader({ className, ...props }) {
1114
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("flex-shrink-0", className), ...props });
1115
+ }
1116
+ function SidebarBrand({ logo, title, subtitle, className, ...props }) {
1117
+ const { collapsed } = useSidebar();
1118
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1119
+ "div",
1120
+ {
1121
+ className: cn("flex items-center gap-3 px-4 py-5", collapsed && "justify-center px-0", className),
1122
+ ...props,
1123
+ children: [
1124
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-shrink-0", children: logo }),
1125
+ !collapsed && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 overflow-hidden", children: [
1126
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "truncate text-[13px] font-semibold tracking-[-0.01em] text-[#1C1C1E]", children: title }),
1127
+ subtitle && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "truncate text-[11px] text-[#8E8E93]", children: subtitle })
1128
+ ] })
1129
+ ]
1130
+ }
1131
+ );
1132
+ }
1133
+ function SidebarDivider({ className }) {
1134
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("mx-3 my-1 h-px bg-[#E5E5EA]", className) });
1135
+ }
1136
+ function SidebarContent({ className, ...props }) {
1137
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("flex-1 overflow-y-auto px-2 py-2 avt-scroll space-y-0.5", className), ...props });
1138
+ }
1139
+ function SidebarGroup({ label, className, children, ...props }) {
1140
+ const { collapsed } = useSidebar();
1141
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("mb-1", className), ...props, children: [
1142
+ label && !collapsed && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mb-1 px-3 text-[10px] font-semibold uppercase tracking-widest text-[#C7C7CC]", children: label }),
1143
+ children
1144
+ ] });
1145
+ }
1146
+ function SidebarItem({
1147
+ icon,
1148
+ label,
1149
+ active = false,
1150
+ badge,
1151
+ href,
1152
+ as: Tag = "button",
1153
+ className,
1154
+ ...props
1155
+ }) {
1156
+ const { collapsed } = useSidebar();
1157
+ const tagProps = href ? { href } : { type: "button" };
1158
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1159
+ Tag,
1160
+ {
1161
+ ...tagProps,
1162
+ title: collapsed ? label : void 0,
1163
+ className: cn(
1164
+ "flex w-full items-center gap-2.5 rounded-xl transition-all duration-150",
1165
+ "text-[13px] font-medium select-none outline-none",
1166
+ "focus-visible:ring-2 focus-visible:ring-[#007AFF]/30",
1167
+ // Mobile-friendly touch target
1168
+ collapsed ? "justify-center px-0 mx-auto w-10 h-10 min-h-[44px] min-w-[44px]" : "px-3 py-2.5 min-h-[44px]",
1169
+ active ? "bg-[#007AFF] text-white shadow-[0_2px_8px_rgba(0,122,255,0.28)]" : "text-[#3C3C43] hover:bg-[#007AFF]/8 hover:text-[#007AFF]",
1170
+ className
1171
+ ),
1172
+ ...props,
1173
+ children: [
1174
+ icon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("flex-shrink-0", !active && "text-[#8E8E93]"), children: icon }),
1175
+ !collapsed && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1 truncate text-left", children: label }),
1176
+ !collapsed && badge !== void 0 && /* @__PURE__ */ jsxRuntime.jsx(
1177
+ "span",
1178
+ {
1179
+ className: cn(
1180
+ "ml-auto flex h-5 min-w-5 items-center justify-center rounded-full px-1.5",
1181
+ "text-[10px] font-bold",
1182
+ active ? "bg-white/20 text-white" : "bg-[#E5E5EA] text-[#8E8E93]"
1183
+ ),
1184
+ children: badge
1185
+ }
1186
+ )
1187
+ ]
1188
+ }
1189
+ );
1190
+ }
1191
+ function SidebarFooter({ className, ...props }) {
1192
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("flex-shrink-0 p-3", className), ...props });
1193
+ }
1194
+ function SidebarUser({
1195
+ name,
1196
+ subtitle,
1197
+ avatar,
1198
+ avatarFallback,
1199
+ avatarColor = "from-[#5856D6] to-[#AF52DE]",
1200
+ actions,
1201
+ className,
1202
+ ...props
1203
+ }) {
1204
+ const { collapsed } = useSidebar();
1205
+ const avatarNode = avatar ?? /* @__PURE__ */ jsxRuntime.jsx(
1206
+ "div",
1207
+ {
1208
+ className: cn(
1209
+ "flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-full",
1210
+ `bg-gradient-to-br ${avatarColor} text-white text-xs font-semibold`
1211
+ ),
1212
+ children: avatarFallback ?? name.charAt(0).toUpperCase()
1213
+ }
1214
+ );
1215
+ if (collapsed) {
1216
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("flex justify-center", className), ...props, children: avatarNode });
1217
+ }
1218
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("rounded-xl bg-[#F2F2F7] p-3", className), ...props, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2.5", children: [
1219
+ avatarNode,
1220
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1", children: [
1221
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "truncate text-[12px] font-semibold text-[#1C1C1E]", children: name }),
1222
+ subtitle && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "truncate text-[11px] text-[#8E8E93]", children: subtitle })
1223
+ ] }),
1224
+ actions && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-shrink-0", children: actions })
1225
+ ] }) });
1226
+ }
1227
+ function SidebarToggle({ collapsed, className, ...props }) {
1228
+ return /* @__PURE__ */ jsxRuntime.jsx(
1229
+ "button",
1230
+ {
1231
+ type: "button",
1232
+ className: cn(
1233
+ "flex h-7 w-7 items-center justify-center rounded-lg",
1234
+ "text-[#8E8E93] hover:bg-[#F2F2F7] hover:text-[#3C3C43]",
1235
+ "transition-colors duration-150",
1236
+ className
1237
+ ),
1238
+ "aria-label": collapsed ? "Expand sidebar" : "Collapse sidebar",
1239
+ ...props,
1240
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1241
+ "svg",
1242
+ {
1243
+ className: cn("h-4 w-4 transition-transform duration-200", collapsed && "rotate-180"),
1244
+ viewBox: "0 0 24 24",
1245
+ fill: "none",
1246
+ stroke: "currentColor",
1247
+ strokeWidth: "2",
1248
+ strokeLinecap: "round",
1249
+ strokeLinejoin: "round",
1250
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M15 18l-6-6 6-6" })
1251
+ }
1252
+ )
1253
+ }
1254
+ );
1255
+ }
1256
+ function useClickOutside(ref, handler, enabled = true) {
1257
+ React3.useEffect(() => {
1258
+ if (!enabled) return;
1259
+ const listener = (event) => {
1260
+ if (!ref.current || ref.current.contains(event.target)) return;
1261
+ handler(event);
1262
+ };
1263
+ document.addEventListener("mousedown", listener, true);
1264
+ document.addEventListener("touchstart", listener, true);
1265
+ return () => {
1266
+ document.removeEventListener("mousedown", listener, true);
1267
+ document.removeEventListener("touchstart", listener, true);
1268
+ };
1269
+ }, [ref, handler, enabled]);
1270
+ }
1271
+
1272
+ exports.Badge = Badge;
1273
+ exports.Button = Button;
1274
+ exports.Card = Card;
1275
+ exports.CardContent = CardContent;
1276
+ exports.CardDescription = CardDescription;
1277
+ exports.CardDivider = CardDivider;
1278
+ exports.CardFooter = CardFooter;
1279
+ exports.CardHeader = CardHeader;
1280
+ exports.CardTitle = CardTitle;
1281
+ exports.Drawer = Drawer;
1282
+ exports.Input = Input;
1283
+ exports.Menu = MenuRoot;
1284
+ exports.MenuButton = MenuButton;
1285
+ exports.MenuContent = MenuContent;
1286
+ exports.MenuDropdown = MenuRoot;
1287
+ exports.MenuItem = MenuItem;
1288
+ exports.MenuLabel = MenuLabel;
1289
+ exports.MenuRoot = MenuRoot;
1290
+ exports.MenuSeparator = MenuSeparator;
1291
+ exports.MenuTrigger = MenuTrigger;
1292
+ exports.Navbar = Navbar;
1293
+ exports.NavbarBrand = NavbarBrand;
1294
+ exports.NavbarCenter = NavbarCenter;
1295
+ exports.NavbarDivider = NavbarDivider;
1296
+ exports.NavbarIconButton = NavbarIconButton;
1297
+ exports.NavbarLeft = NavbarLeft;
1298
+ exports.NavbarRight = NavbarRight;
1299
+ exports.NavbarSearch = NavbarSearch;
1300
+ exports.Scrollbar = Scrollbar;
1301
+ exports.Sheet = Sheet;
1302
+ exports.SheetContent = SheetContent;
1303
+ exports.SheetDescription = SheetDescription;
1304
+ exports.SheetFooter = SheetFooter;
1305
+ exports.SheetHeader = SheetHeader;
1306
+ exports.SheetTitle = SheetTitle;
1307
+ exports.Sidebar = Sidebar;
1308
+ exports.SidebarBrand = SidebarBrand;
1309
+ exports.SidebarContent = SidebarContent;
1310
+ exports.SidebarDivider = SidebarDivider;
1311
+ exports.SidebarFooter = SidebarFooter;
1312
+ exports.SidebarGroup = SidebarGroup;
1313
+ exports.SidebarHeader = SidebarHeader;
1314
+ exports.SidebarItem = SidebarItem;
1315
+ exports.SidebarToggle = SidebarToggle;
1316
+ exports.SidebarUser = SidebarUser;
1317
+ exports.Table = Table;
1318
+ exports.TableBody = TableBody;
1319
+ exports.TableCaption = TableCaption;
1320
+ exports.TableCell = TableCell;
1321
+ exports.TableFooter = TableFooter;
1322
+ exports.TableHead = TableHead;
1323
+ exports.TableHeader = TableHeader;
1324
+ exports.TablePagination = TablePagination;
1325
+ exports.TableRow = TableRow;
1326
+ exports.TableToolbar = TableToolbar;
1327
+ exports.Tabs = Tabs;
1328
+ exports.TabsContent = TabsContent;
1329
+ exports.TabsList = TabsList;
1330
+ exports.TabsTrigger = TabsTrigger;
1331
+ exports.Textarea = Textarea;
1332
+ exports.Toaster = Toaster;
1333
+ exports.cn = cn;
1334
+ exports.colors = colors;
1335
+ exports.dismissToast = dismissToast;
1336
+ exports.generateId = generateId;
1337
+ exports.toast = toast;
1338
+ exports.useClickOutside = useClickOutside;
1339
+ exports.useKeydown = useKeydown;
1340
+ exports.useToast = useToast;
1341
+ exports.withScrollbar = withScrollbar;