@bubo-squared/ui-framework 0.1.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.js ADDED
@@ -0,0 +1,2582 @@
1
+ // src/components/Buttons/Button.tsx
2
+ import * as React from "react";
3
+ import { Slot } from "@radix-ui/react-slot";
4
+ import { cva } from "class-variance-authority";
5
+
6
+ // src/lib/utils.tsx
7
+ import { clsx } from "clsx";
8
+ import { twMerge } from "tailwind-merge";
9
+ import { jsx } from "react/jsx-runtime";
10
+ function cn(...inputs) {
11
+ return twMerge(clsx(inputs));
12
+ }
13
+
14
+ // src/components/Buttons/Button.tsx
15
+ import { jsx as jsx2, jsxs } from "react/jsx-runtime";
16
+ var buttonVariants = cva(
17
+ "inline-flex items-center justify-center whitespace-nowrap rounded transition-colors disabled:pointer-events-none overflow-hidden cursor-pointer",
18
+ {
19
+ variants: {
20
+ variant: {
21
+ primary: [
22
+ "btn-primary",
23
+ "focus-ring-primary"
24
+ ],
25
+ secondary: [
26
+ "btn-secondary",
27
+ "focus-ring-secondary"
28
+ ],
29
+ outline: [
30
+ "btn-outline",
31
+ "focus-ring-outline"
32
+ ],
33
+ destructive: [
34
+ "btn-destructive",
35
+ "focus-ring-error"
36
+ ]
37
+ },
38
+ size: {
39
+ sm: ["px-1.5", "py-1", "gap-1"],
40
+ md: ["px-2", "py-1", "gap-1.5"],
41
+ lg: ["px-2.5", "py-1", "gap-1.5"],
42
+ xl: ["px-3", "py-0.5", "gap-2"]
43
+ }
44
+ },
45
+ defaultVariants: {
46
+ variant: "primary",
47
+ size: "md"
48
+ }
49
+ }
50
+ );
51
+ var buttonIconVariants = cva("relative", {
52
+ variants: {
53
+ size: {
54
+ sm: ["w-5", "h-5", "*:w-5", "*:h-5"],
55
+ md: ["w-6", "h-6", "*:w-6", "*:h-6"],
56
+ lg: ["w-6", "h-6", "*:w-6", "*:h-6"],
57
+ xl: ["w-8", "h-8", "*:w-8", "*:h-8"]
58
+ }
59
+ }
60
+ });
61
+ var buttonTextVariants = cva("flex text-center justify-center font-normal", {
62
+ variants: {
63
+ size: {
64
+ sm: ["text-xl", "leading-7"],
65
+ md: ["text-2xl", "leading-8"],
66
+ lg: ["h-10", "text-3xl", "leading-9"],
67
+ xl: ["h-11", "text-4xl", "leading-10"]
68
+ }
69
+ }
70
+ });
71
+ var Button = React.forwardRef(
72
+ (props, ref) => {
73
+ const {
74
+ className,
75
+ variant,
76
+ size = "md",
77
+ asChild = false,
78
+ children,
79
+ suffixIcon,
80
+ prefixIcon,
81
+ ...rest
82
+ } = props;
83
+ const Comp = asChild ? Slot : "button";
84
+ return /* @__PURE__ */ jsxs(
85
+ Comp,
86
+ {
87
+ className: cn(buttonVariants({ variant, size, className })),
88
+ ref,
89
+ ...rest,
90
+ children: [
91
+ prefixIcon && /* @__PURE__ */ jsx2("div", { className: cn(buttonIconVariants({ size })), children: prefixIcon }),
92
+ /* @__PURE__ */ jsx2("div", { className: cn(buttonTextVariants({ size })), children }),
93
+ suffixIcon && /* @__PURE__ */ jsx2("div", { className: cn(buttonIconVariants({ size })), children: suffixIcon })
94
+ ]
95
+ }
96
+ );
97
+ }
98
+ );
99
+ Button.displayName = "Button";
100
+
101
+ // src/components/Buttons/ButtonGroup.tsx
102
+ import { cva as cva2 } from "class-variance-authority";
103
+ import { jsx as jsx3 } from "react/jsx-runtime";
104
+ var buttonGroupVariants = cva2(
105
+ "flex items-center justify-center gap-4 pt-4 w-80 min-w-80",
106
+ {
107
+ variants: {
108
+ variant: {
109
+ vertical: ["flex-col"],
110
+ horizontal: ["flex-row"]
111
+ }
112
+ },
113
+ defaultVariants: {
114
+ variant: "horizontal"
115
+ }
116
+ }
117
+ );
118
+ var ButtonGroup = (props) => {
119
+ const { orientation = "horizontal" } = props;
120
+ return /* @__PURE__ */ jsx3("div", { className: buttonGroupVariants({ variant: orientation }), ...props, children: props.children });
121
+ };
122
+
123
+ // src/components/Buttons/IconButton.tsx
124
+ import * as React2 from "react";
125
+ import { Slot as Slot2 } from "@radix-ui/react-slot";
126
+ import { cva as cva3 } from "class-variance-authority";
127
+ import { jsx as jsx4 } from "react/jsx-runtime";
128
+ var iconButtonVariants = cva3(
129
+ "inline-flex items-center justify-center whitespace-nowrap rounded transition-colors disabled:pointer-events-none overflow-hidden p-1.5 cursor-pointer",
130
+ {
131
+ variants: {
132
+ variant: {
133
+ primary: [
134
+ "btn-primary",
135
+ "focus-ring-primary"
136
+ ],
137
+ secondary: [
138
+ "btn-secondary",
139
+ "focus-ring-secondary"
140
+ ],
141
+ outline: [
142
+ "btn-outline",
143
+ "focus-ring-outline"
144
+ ],
145
+ destructive: [
146
+ "btn-destructive-outline",
147
+ "focus-ring-error-outline"
148
+ ]
149
+ },
150
+ size: {
151
+ sm: ["[&>.buttonIcon>svg]:w-5", "[&>.buttonIcon>svg]:h-5"],
152
+ md: ["[&>.buttonIcon>svg]:w-6", "[&>.buttonIcon>svg]:h-6"],
153
+ lg: ["[&>.buttonIcon>svg]:w-8", "[&>.buttonIcon>svg]:h-8"],
154
+ xl: ["[&>.buttonIcon>svg]:w-9", "[&>.buttonIcon>svg]:h-9"]
155
+ }
156
+ },
157
+ defaultVariants: {
158
+ variant: "primary",
159
+ size: "md"
160
+ }
161
+ }
162
+ );
163
+ var IconButton = React2.forwardRef(
164
+ (props, ref) => {
165
+ const {
166
+ className,
167
+ variant,
168
+ size,
169
+ asChild = false,
170
+ icon,
171
+ ...rest
172
+ } = props;
173
+ const Comp = asChild ? Slot2 : "button";
174
+ return /* @__PURE__ */ jsx4(
175
+ Comp,
176
+ {
177
+ className: cn(iconButtonVariants({ variant, size }), className),
178
+ ref,
179
+ ...rest,
180
+ children: /* @__PURE__ */ jsx4("div", { className: "buttonIcon flex items-center justify-center", children: icon })
181
+ }
182
+ );
183
+ }
184
+ );
185
+ IconButton.displayName = "IconButton";
186
+
187
+ // src/components/Buttons/IconButtonGroup.tsx
188
+ import "react";
189
+ import { cva as cva4 } from "class-variance-authority";
190
+ import { jsx as jsx5 } from "react/jsx-runtime";
191
+ var IconGroupLinesClass = "inline-flex items-center justify-center gap-0 [&>button]:outline-none! [&>button]:rounded-none [&>button:focus]:shadow-none [&>button:focus]:bg-(--border-secondary) [&>button:first-child]:rounded-l [&>button:last-child]:rounded-r";
192
+ var IconGroupSizeVariants = cva4("", {
193
+ variants: {
194
+ size: {
195
+ sm: "[&>button]:px-1.5",
196
+ md: "[&>button]:px-2",
197
+ lg: "[&>button]:px-2",
198
+ xl: "[&>button]:px-3"
199
+ }
200
+ },
201
+ defaultVariants: {
202
+ size: "sm"
203
+ }
204
+ });
205
+ var IconButtonGroup = (props) => {
206
+ const { items, size = "sm", className, ...rest } = props;
207
+ if (!items || items.length === 0) {
208
+ return null;
209
+ }
210
+ return /* @__PURE__ */ jsx5(
211
+ "div",
212
+ {
213
+ className: cn(
214
+ IconGroupLinesClass,
215
+ IconGroupSizeVariants({ size }),
216
+ className
217
+ ),
218
+ ...rest,
219
+ children: items.map((item, index) => /* @__PURE__ */ jsx5(
220
+ IconButton,
221
+ {
222
+ variant: "secondary",
223
+ size,
224
+ icon: item.icon,
225
+ "aria-label": item.ariaLabel,
226
+ disabled: item.disabled,
227
+ className: cn(
228
+ "rounded-none border-1 border-(--border-secondary) text-(--text-primary) ",
229
+ index === 0 && "rounded-l-[6px]",
230
+ index === items.length - 1 && "rounded-r-[6px]",
231
+ index > 0 && "-ml-px"
232
+ ),
233
+ onClick: item.onClick
234
+ },
235
+ index
236
+ ))
237
+ }
238
+ );
239
+ };
240
+ IconButtonGroup.displayName = "IconButtonGroup";
241
+
242
+ // src/components/Buttons/LinkButton.tsx
243
+ import * as React4 from "react";
244
+ import { Slot as Slot3 } from "@radix-ui/react-slot";
245
+ import { cva as cva5 } from "class-variance-authority";
246
+ import { jsx as jsx6, jsxs as jsxs2 } from "react/jsx-runtime";
247
+ var linkButtonVariants = cva5(
248
+ "inline-flex items-center justify-center whitespace-nowrap rounded transition-colors disabled:pointer-events-none overflow-hidden gap-2 cursor-pointer",
249
+ {
250
+ variants: {
251
+ variant: {
252
+ primary: ["btn-link-primary"],
253
+ secondary: ["btn-link-secondary"],
254
+ destructive: ["btn-link-destructive"]
255
+ },
256
+ size: {
257
+ sm: ["py-2", "px-1"],
258
+ md: ["py-2.5", "px-2"],
259
+ lg: ["py-2.5", "px-2"],
260
+ xl: ["py-3", "px-3"]
261
+ }
262
+ },
263
+ defaultVariants: {
264
+ variant: "primary",
265
+ size: "md"
266
+ }
267
+ }
268
+ );
269
+ var linkButtonIconVariants = cva5("relative", {
270
+ variants: {
271
+ size: {
272
+ sm: ["w-5", "h-5", "*:w-5", "*:h-5"],
273
+ md: ["w-5", "h-5", "*:w-5", "*:h-5"],
274
+ lg: ["w-6", "h-6", "*:w-6", "*:h-6"],
275
+ xl: ["w-6", "h-6", "*:w-6", "*:h-6"]
276
+ }
277
+ }
278
+ });
279
+ var linkButtonTextVariants = cva5("inline-flex items-center text-center font-medium", {
280
+ variants: {
281
+ size: {
282
+ sm: ["text-sm", "leading-5"],
283
+ md: ["text-sm", "leading-5"],
284
+ lg: ["text-base", "leading-6"],
285
+ xl: ["text-base", "leading-6"]
286
+ }
287
+ }
288
+ });
289
+ var LinkButton = React4.forwardRef(
290
+ (props, ref) => {
291
+ const {
292
+ className,
293
+ variant,
294
+ size = "sm",
295
+ asChild = false,
296
+ children,
297
+ suffixIcon,
298
+ prefixIcon,
299
+ ...rest
300
+ } = props;
301
+ const Comp = asChild ? Slot3 : "button";
302
+ return /* @__PURE__ */ jsxs2(
303
+ Comp,
304
+ {
305
+ className: cn(linkButtonVariants({ variant, size, className })),
306
+ ref,
307
+ ...rest,
308
+ children: [
309
+ prefixIcon && /* @__PURE__ */ jsx6("div", { className: cn(linkButtonIconVariants({ size })), children: prefixIcon }),
310
+ /* @__PURE__ */ jsx6("div", { className: cn(linkButtonTextVariants({ size })), children }),
311
+ suffixIcon && /* @__PURE__ */ jsx6("div", { className: cn(linkButtonIconVariants({ size })), children: suffixIcon })
312
+ ]
313
+ }
314
+ );
315
+ }
316
+ );
317
+ LinkButton.displayName = "LinkButton";
318
+
319
+ // src/components/Buttons/MessageButton.tsx
320
+ import * as React5 from "react";
321
+ import { jsx as jsx7, jsxs as jsxs3 } from "react/jsx-runtime";
322
+ var MessageButton = (props) => {
323
+ const {
324
+ onClick,
325
+ idleLabel = "Save",
326
+ loadingLabel = "Saving\u2026",
327
+ successLabel = "Saved!",
328
+ errorLabel = "Error",
329
+ feedbackDuration = 1500,
330
+ className = "",
331
+ ...buttonProps
332
+ } = props;
333
+ const [status, setStatus] = React5.useState("idle");
334
+ const handleClick = async (_event) => {
335
+ if (status === "loading") return;
336
+ setStatus("loading");
337
+ try {
338
+ await Promise.resolve(onClick?.());
339
+ setStatus("success");
340
+ } catch (err) {
341
+ console.error(err);
342
+ setStatus("error");
343
+ } finally {
344
+ if (feedbackDuration > 0) {
345
+ window.setTimeout(() => setStatus("idle"), feedbackDuration);
346
+ }
347
+ }
348
+ };
349
+ const label = status === "loading" ? loadingLabel : status === "success" ? successLabel : status === "error" ? errorLabel : idleLabel;
350
+ const statusClasses = status === "success" ? "btn-msg-success" : status === "error" ? "btn-destructive" : "btn-outline focus-ring-outline";
351
+ return /* @__PURE__ */ jsxs3(
352
+ "button",
353
+ {
354
+ type: "button",
355
+ ...buttonProps,
356
+ onClick: handleClick,
357
+ className: `inline-flex items-center justify-center rounded px-1.5 py-1 gap-1 text-sm transition-colors cursor-pointer ${statusClasses} ${className}`,
358
+ children: [
359
+ props.icon && /* @__PURE__ */ jsx7("div", { className: "w-5 *:w-5 h-5 *:h-5 relative", children: props.icon }),
360
+ /* @__PURE__ */ jsx7("div", { className: "text-center text-xl font-normal leading-7", children: label })
361
+ ]
362
+ }
363
+ );
364
+ };
365
+ MessageButton.displayName = "MessageButton";
366
+
367
+ // src/components/Content/Avatar.tsx
368
+ import * as React6 from "react";
369
+ import { Slot as Slot4 } from "@radix-ui/react-slot";
370
+ import { cva as cva6 } from "class-variance-authority";
371
+ import { UserIcon } from "@bubo-squared/icons";
372
+ import { jsx as jsx8, jsxs as jsxs4 } from "react/jsx-runtime";
373
+ var avatarVariants = cva6(
374
+ "relative inline-flex items-center justify-center rounded-full border-(--border-secondary) border-1 bg-(--background-primary) text-(--text-primary) overflow-hidden hover:border-(--focus-secondary) focus-visible:border-(--focus-primary) focus-visible:outline-none",
375
+ {
376
+ variants: {
377
+ size: {
378
+ "20": "w-5 h-5 hover:border-2 focus-visible:border-2",
379
+ "24": "w-6 h-6 hover:border-2 focus-visible:border-2",
380
+ "32": "w-8 h-8 hover:border-2 focus-visible:border-2",
381
+ "40": "w-10 h-10 hover:border-2 focus-visible:border-2",
382
+ "48": "w-12 h-12 hover:border-2 focus-visible:border-2",
383
+ "56": "w-14 h-14 hover:border-4 focus-visible:border-4",
384
+ "64": "w-16 h-16 hover:border-4 focus-visible:border-4"
385
+ }
386
+ },
387
+ defaultVariants: {
388
+ size: "32"
389
+ }
390
+ }
391
+ );
392
+ var avatarInitialsVariants = cva6(
393
+ "flex items-center justify-center text-(--text-primary) leading-none ",
394
+ {
395
+ variants: {
396
+ size: {
397
+ "20": "footnote-xs-medium",
398
+ "24": "footnote-medium",
399
+ "32": "paragraph-s font-medium",
400
+ "40": "paragraph-m font-medium",
401
+ "48": "paragraph-l font-medium",
402
+ "56": "subtitle font-medium",
403
+ "64": "h6-title font-medium"
404
+ }
405
+ },
406
+ defaultVariants: {
407
+ size: "32"
408
+ }
409
+ }
410
+ );
411
+ var avatarIconVariants = cva6(
412
+ "flex items-center justify-center text-(--icon-primary)",
413
+ {
414
+ variants: {
415
+ size: {
416
+ "20": "w-3 h-3 [&>svg]:w-3 [&>svg]:h-3",
417
+ "24": "w-3.5 h-3.5 [&>svg]:w-3.5 [&>svg]:h-3.5",
418
+ "32": "w-4 h-4 [&>svg]:w-4 [&>svg]:h-4",
419
+ "40": "w-5 h-5 [&>svg]:w-5 [&>svg]:h-5",
420
+ "48": "w-6 h-6 [&>svg]:w-6 [&>svg]:h-6",
421
+ "56": "w-7 h-7 [&>svg]:w-7 [&>svg]:h-7",
422
+ "64": "w-8 h-8 [&>svg]:w-8 [&>svg]:h-8"
423
+ }
424
+ },
425
+ defaultVariants: {
426
+ size: "32"
427
+ }
428
+ }
429
+ );
430
+ var Avatar = React6.forwardRef(
431
+ (props, ref) => {
432
+ const {
433
+ asChild = false,
434
+ variant = "initial",
435
+ size = "32",
436
+ initials = "RA",
437
+ src,
438
+ alt,
439
+ className,
440
+ ...rest
441
+ } = props;
442
+ const Comp = asChild ? Slot4 : "button";
443
+ const hasImage = variant === "image" && typeof src === "string" && src.length > 0;
444
+ return /* @__PURE__ */ jsxs4(
445
+ Comp,
446
+ {
447
+ ref,
448
+ className: cn(avatarVariants({ size }), className),
449
+ ...rest,
450
+ children: [
451
+ hasImage ? /* @__PURE__ */ jsx8(
452
+ "img",
453
+ {
454
+ src,
455
+ alt,
456
+ className: "w-full h-full object-cover"
457
+ }
458
+ ) : null,
459
+ !hasImage && variant === "initial" && /* @__PURE__ */ jsx8("span", { className: cn(avatarInitialsVariants({ size }), "relative bottom-px"), style: { marginBottom: 0 }, children: initials }),
460
+ !hasImage && variant === "icon" && /* @__PURE__ */ jsx8("span", { className: cn(avatarIconVariants({ size })), children: /* @__PURE__ */ jsx8(UserIcon, {}) })
461
+ ]
462
+ }
463
+ );
464
+ }
465
+ );
466
+ Avatar.displayName = "Avatar";
467
+
468
+ // src/components/Content/Badge.tsx
469
+ import * as React7 from "react";
470
+ import { Slot as Slot5 } from "@radix-ui/react-slot";
471
+ import { cva as cva7 } from "class-variance-authority";
472
+ import { Fragment, jsx as jsx9, jsxs as jsxs5 } from "react/jsx-runtime";
473
+ var badgeVariants = cva7(
474
+ "inline-flex items-center justify-center rounded-[4px] leading-none whitespace-nowrap gap-1 px-1 py-0",
475
+ {
476
+ variants: {
477
+ size: {
478
+ sm: "px-1 paragraph-s",
479
+ md: "px-1 paragraph-m",
480
+ lg: "px-1.5 subtitle",
481
+ xl: "px-2 h6-title"
482
+ },
483
+ variant: {
484
+ primary: "bg-(--background-secondary) text-(--text-primary)",
485
+ secondary: "bg-(--background-primary) border-1 border-(--border-primary) text-(--text-primary)",
486
+ active: "bg-(--color-ac-lilac) text-(--text-neutral-badge-black)",
487
+ informal: "bg-(--color-ac-neon-blue) text-(--text-neutral-badge-black)",
488
+ success: "bg-(--color-ac-neon-green) text-(--text-neutral-badge-black)",
489
+ warning: "bg-(--color-ac-light-orange) text-(--text-neutral-badge-black)",
490
+ error: "bg-(--color-s-error-300) text-(--text-neutral-badge-black)",
491
+ disabled: "bg-(--background-primary-disabled) border-1 border-(--border-primary-disabled) text-(--text-primary-disabled)",
492
+ "double-default": "bg-(--background-secondary) text-(--text-primary)",
493
+ "double-current": "bg-(--color-ac-lilac) text-(--text-neutral-badge-black)"
494
+ }
495
+ },
496
+ defaultVariants: {
497
+ size: "sm",
498
+ variant: "primary"
499
+ }
500
+ }
501
+ );
502
+ var Badge = React7.forwardRef(
503
+ (props, ref) => {
504
+ const {
505
+ asChild = false,
506
+ label,
507
+ value,
508
+ size = "sm",
509
+ variant = "primary",
510
+ className,
511
+ ...rest
512
+ } = props;
513
+ const Comp = asChild ? Slot5 : "div";
514
+ return /* @__PURE__ */ jsx9(
515
+ Comp,
516
+ {
517
+ ref,
518
+ className: cn(badgeVariants({ size, variant }), className),
519
+ ...rest,
520
+ style: { marginBottom: 0 },
521
+ children: value ? /* @__PURE__ */ jsxs5(Fragment, { children: [
522
+ /* @__PURE__ */ jsx9("span", { className: "font-normal", children: label }),
523
+ /* @__PURE__ */ jsx9("span", { className: "font-normal", children: ":" }),
524
+ /* @__PURE__ */ jsx9("span", { className: "font-medium", children: value })
525
+ ] }) : /* @__PURE__ */ jsx9("span", { className: "font-normal", children: label })
526
+ }
527
+ );
528
+ }
529
+ );
530
+ Badge.displayName = "Badge";
531
+
532
+ // src/components/Content/BadgeDigit.tsx
533
+ import * as React8 from "react";
534
+ import { cva as cva8 } from "class-variance-authority";
535
+ import { jsx as jsx10 } from "react/jsx-runtime";
536
+ var badgeDigitVariants = cva8(
537
+ "inline-flex items-center justify-center leading-none whitespace-nowrap text-(--text-primary-inverse)",
538
+ {
539
+ variants: {
540
+ size: {
541
+ sm: "px-[6px] rounded-[2px] caption-medium",
542
+ md: "px-2 py-[2px] rounded-[4px] paragraph-s-medium"
543
+ },
544
+ variant: {
545
+ primary: "bg-(--background-brand)",
546
+ secondary: "bg-(--background-primary) border-1 border-(--border-secondary) text-(--text-secondary)",
547
+ informal: "bg-(--background-informal)",
548
+ success: "bg-(--background-success)",
549
+ warning: "bg-(--background-warning)",
550
+ error: "bg-(--background-error)",
551
+ disabled: "bg-(--background-primary) border-1 border-(--border-primary-disabled) text-(--text-primary-disabled)"
552
+ }
553
+ },
554
+ defaultVariants: {
555
+ size: "sm",
556
+ variant: "primary"
557
+ }
558
+ }
559
+ );
560
+ var BadgeDigit = React8.forwardRef(
561
+ (props, ref) => {
562
+ const {
563
+ value,
564
+ size = "sm",
565
+ variant = "primary",
566
+ className,
567
+ ...rest
568
+ } = props;
569
+ return /* @__PURE__ */ jsx10(
570
+ "div",
571
+ {
572
+ ref,
573
+ className: cn(badgeDigitVariants({ size, variant }), className),
574
+ style: { marginBottom: 0 },
575
+ ...rest,
576
+ children: String(value)
577
+ }
578
+ );
579
+ }
580
+ );
581
+ BadgeDigit.displayName = "BadgeDigit";
582
+
583
+ // src/components/Content/BadgeDot.tsx
584
+ import "react";
585
+ import { cva as cva9 } from "class-variance-authority";
586
+ import { jsx as jsx11 } from "react/jsx-runtime";
587
+ var badgeDotVariants = cva9("rounded-xl w-3 h-3", {
588
+ variants: {
589
+ status: {
590
+ disabled: "bg-(--text-primary)",
591
+ informal: "bg-(--background-informal)",
592
+ "success/online": "bg-(--background-success)",
593
+ warning: "bg-(--background-warning)",
594
+ error: "bg-(--background-error)"
595
+ }
596
+ },
597
+ defaultVariants: {
598
+ status: "disabled"
599
+ }
600
+ });
601
+ var BadgeDot = ({ status, className }) => {
602
+ return /* @__PURE__ */ jsx11("div", { className: cn(badgeDotVariants({ status }), className) });
603
+ };
604
+ BadgeDot.displayName = "BadgeDot";
605
+
606
+ // src/components/Content/BadgeStatus.tsx
607
+ import * as React10 from "react";
608
+ import { jsx as jsx12, jsxs as jsxs6 } from "react/jsx-runtime";
609
+ var BadgeStatus = React10.forwardRef(
610
+ (props, ref) => {
611
+ const {
612
+ label,
613
+ active = true,
614
+ className,
615
+ dotClassName,
616
+ ...rest
617
+ } = props;
618
+ const textClasses = active ? "caption-medium text-(--text-primary)" : "caption-medium text-(--text-primary-disabled)";
619
+ const dotClasses = active ? "bg-(--background-informal)" : "bg-(--background-primary)";
620
+ return /* @__PURE__ */ jsxs6(
621
+ "div",
622
+ {
623
+ ref,
624
+ className: cn("inline-flex items-center gap-2", className),
625
+ ...rest,
626
+ children: [
627
+ /* @__PURE__ */ jsx12(
628
+ "span",
629
+ {
630
+ className: cn(
631
+ "shrink-0 w-3 h-3 rounded-full",
632
+ dotClasses,
633
+ dotClassName
634
+ )
635
+ }
636
+ ),
637
+ /* @__PURE__ */ jsx12("span", { className: textClasses, style: { marginBottom: 0 }, children: label })
638
+ ]
639
+ }
640
+ );
641
+ }
642
+ );
643
+ BadgeStatus.displayName = "BadgeStatus";
644
+
645
+ // src/components/Content/Divider.tsx
646
+ import "react";
647
+ import { TargetIcon } from "@bubo-squared/icons";
648
+ import { jsx as jsx13, jsxs as jsxs7 } from "react/jsx-runtime";
649
+ var lineClass = "h-px flex-1 bg-(--border-secondary)";
650
+ var Divider = (props) => {
651
+ const { type = "line", className, ...rest } = props;
652
+ const showCenter = type !== "line";
653
+ const textLabel = type === "text-lines" && "label" in rest && rest.label ? rest.label : "OR";
654
+ return /* @__PURE__ */ jsxs7(
655
+ "div",
656
+ {
657
+ className: cn(
658
+ "flex w-full items-center",
659
+ showCenter ? "gap-2" : "gap-0",
660
+ className
661
+ ),
662
+ ...rest,
663
+ children: [
664
+ /* @__PURE__ */ jsx13("div", { className: lineClass }),
665
+ type === "text-lines" && /* @__PURE__ */ jsx13(
666
+ "span",
667
+ {
668
+ className: "footnote text-(--text-secondary)",
669
+ style: { marginBottom: 0 },
670
+ children: textLabel
671
+ }
672
+ ),
673
+ type === "icon-lines" && /* @__PURE__ */ jsx13(
674
+ IconButton,
675
+ {
676
+ variant: props.type === "icon-lines" && props.iconButtonVariant ? props.iconButtonVariant : "secondary",
677
+ size: "sm",
678
+ "aria-label": props.type === "icon-lines" && props.ariaLabel ? props.ariaLabel : textLabel || "More options",
679
+ icon: props.type === "icon-lines" ? props.icon : /* @__PURE__ */ jsx13(TargetIcon, {}),
680
+ onClick: props.type === "icon-lines" ? props.onIconClick : void 0
681
+ }
682
+ ),
683
+ type === "icon-group-lines" && (props.type === "icon-group-lines" ? /* @__PURE__ */ jsx13(
684
+ IconButtonGroup,
685
+ {
686
+ items: props.iconGroupItems,
687
+ size: props.iconGroupSize
688
+ }
689
+ ) : null),
690
+ type === "button-lines" && /* @__PURE__ */ jsx13(
691
+ Button,
692
+ {
693
+ variant: props.type === "button-lines" && props.buttonVariant ? props.buttonVariant : "secondary",
694
+ size: "md",
695
+ onClick: props.type === "button-lines" ? props.onButtonClick : void 0,
696
+ children: props.type === "button-lines" ? props.buttonLabel : "Label"
697
+ }
698
+ ),
699
+ showCenter && /* @__PURE__ */ jsx13("div", { className: lineClass })
700
+ ]
701
+ }
702
+ );
703
+ };
704
+ Divider.displayName = "Divider";
705
+
706
+ // src/components/Content/Progress.tsx
707
+ import * as React12 from "react";
708
+ import { jsx as jsx14, jsxs as jsxs8 } from "react/jsx-runtime";
709
+ var sizeToBarClasses = {
710
+ lg: "h-4 rounded-[16px]",
711
+ md: "h-2 rounded-[8px]",
712
+ sm: "h-1 rounded-[4px]"
713
+ };
714
+ var Progress = React12.forwardRef(
715
+ (props, ref) => {
716
+ const {
717
+ value,
718
+ label,
719
+ hint,
720
+ showLabel = true,
721
+ showHint = !!hint,
722
+ size = "lg",
723
+ className,
724
+ ...rest
725
+ } = props;
726
+ const clamped = Number.isFinite(value) ? Math.min(100, Math.max(0, value)) : 0;
727
+ const percentageLabel = `${Math.round(clamped)}%`;
728
+ const barHeightClasses = sizeToBarClasses[size];
729
+ return /* @__PURE__ */ jsxs8(
730
+ "div",
731
+ {
732
+ ref,
733
+ className: cn("flex flex-col gap-2 items-start w-full", className),
734
+ role: "progressbar",
735
+ "aria-valuenow": clamped,
736
+ "aria-valuemin": 0,
737
+ "aria-valuemax": 100,
738
+ "aria-label": label,
739
+ ...rest,
740
+ children: [
741
+ showLabel && label && /* @__PURE__ */ jsxs8("div", { className: "flex w-full items-center justify-between", children: [
742
+ /* @__PURE__ */ jsx14("span", { className: "paragraph-s-bold text-(--text-primary)", style: { marginBottom: 0 }, children: label }),
743
+ /* @__PURE__ */ jsx14("span", { className: "footnote text-(--text-secondary)", style: { marginBottom: 0 }, children: percentageLabel })
744
+ ] }),
745
+ /* @__PURE__ */ jsx14("div", { className: cn("w-full bg-(--chart-mono) overflow-hidden", barHeightClasses), children: /* @__PURE__ */ jsx14(
746
+ "div",
747
+ {
748
+ className: cn(
749
+ "bg-(--chart-brand) h-full",
750
+ size === "lg" ? "rounded-4" : size === "md" ? "rounded-2" : "rounded-1"
751
+ ),
752
+ style: { width: `${clamped}%` }
753
+ }
754
+ ) }),
755
+ showHint && hint && /* @__PURE__ */ jsx14("p", { className: "caption text-(--text-secondary)", style: { marginBottom: 0 }, children: hint })
756
+ ]
757
+ }
758
+ );
759
+ }
760
+ );
761
+ Progress.displayName = "Progress";
762
+
763
+ // src/components/Content/StatusAvatar.tsx
764
+ import * as React13 from "react";
765
+ import { cva as cva10 } from "class-variance-authority";
766
+ import {
767
+ BookmarkCheckIcon,
768
+ CheckIcon,
769
+ CrossIcon,
770
+ PlusIcon,
771
+ StarIcon
772
+ } from "@bubo-squared/icons";
773
+ import { jsx as jsx15, jsxs as jsxs9 } from "react/jsx-runtime";
774
+ var iconStatusVariants = cva10(
775
+ "inline-flex h-5 w-5 items-center justify-center rounded-full border-1 border-(--text-primary-inverse) p-1",
776
+ {
777
+ variants: {
778
+ variant: {
779
+ verified: "bg-(--background-informal)",
780
+ bookmark: "bg-(--background-brand)",
781
+ favorite: "bg-(--background-success)",
782
+ add: "bg-(--background-primary-hover)",
783
+ remove: "bg-(--background-error)"
784
+ }
785
+ },
786
+ defaultVariants: {
787
+ variant: "verified"
788
+ }
789
+ }
790
+ );
791
+ var presenceDotBase = "inline-flex h-5 w-5 items-center justify-center";
792
+ var presenceDotByVariant = {
793
+ offline: "bg-(--background-primary) border-1 border-(--text-primary-inverse)",
794
+ online: "bg-(--background-success) border-1 border-(--text-primary-inverse)",
795
+ away: "bg-(--background-warning) border-1 border-(--text-primary-inverse)",
796
+ busy: "bg-(--background-error) border-1 border-(--text-primary-inverse)"
797
+ };
798
+ var StatusAvatar = React13.forwardRef((props, ref) => {
799
+ const { variant = "verified", className, ...rest } = props;
800
+ if (variant === "offline" || variant === "online" || variant === "away" || variant === "busy") {
801
+ const dotClasses = presenceDotByVariant[variant];
802
+ return /* @__PURE__ */ jsx15(
803
+ "div",
804
+ {
805
+ ref,
806
+ className: cn(
807
+ presenceDotBase,
808
+ className
809
+ ),
810
+ ...rest,
811
+ children: /* @__PURE__ */ jsx15("div", { className: cn(dotClasses, "h-3.5 w-3.5 rounded-full") })
812
+ }
813
+ );
814
+ }
815
+ const iconVariant = variant;
816
+ return /* @__PURE__ */ jsxs9(
817
+ "div",
818
+ {
819
+ ref,
820
+ className: cn(iconStatusVariants({ variant: iconVariant }), className),
821
+ ...rest,
822
+ children: [
823
+ iconVariant === "verified" && /* @__PURE__ */ jsx15(CheckIcon, { className: "h-3 w-3 text-(--text-button-white)" }),
824
+ iconVariant === "bookmark" && /* @__PURE__ */ jsx15(BookmarkCheckIcon, { className: "h-3 w-3 text-(--text-button-white)" }),
825
+ iconVariant === "favorite" && /* @__PURE__ */ jsx15(StarIcon, { className: "h-3 w-3 text-(--text-button-white)" }),
826
+ iconVariant === "add" && /* @__PURE__ */ jsx15(PlusIcon, { className: "h-3 w-3 text-(--text-button-white)" }),
827
+ iconVariant === "remove" && /* @__PURE__ */ jsx15(CrossIcon, { className: "h-3 w-3 text-(--text-button-white)" })
828
+ ]
829
+ }
830
+ );
831
+ });
832
+ StatusAvatar.displayName = "StatusAvatar";
833
+
834
+ // src/components/Content/Tag.tsx
835
+ import * as React14 from "react";
836
+ import { Slot as Slot6 } from "@radix-ui/react-slot";
837
+ import { cva as cva11 } from "class-variance-authority";
838
+ import { jsx as jsx16, jsxs as jsxs10 } from "react/jsx-runtime";
839
+ var tagVariants = cva11(
840
+ "inline-flex flex-row items-center justify-center rounded-[6px] gap-2 px-3 overflow-hidden border-1 border-(--border-secondary) bg-(--background-neutral) hover:border-(--border-secondary-hover) focus:border-(--border-brand) focus-ring-primary ",
841
+ {
842
+ variants: {
843
+ size: {
844
+ sm: "py-0.5",
845
+ md: "py-1.5"
846
+ }
847
+ },
848
+ defaultVariants: {
849
+ size: "sm"
850
+ }
851
+ }
852
+ );
853
+ var disabledTag = "pointer-events-none border-(--border-secondary-disabled) bg-(--background-neutral-disabled) text-(--text-primary-disabled)";
854
+ var iconClasses = "flex items-center justify-center w-5 h-5 [&>*]:w-5 [&>*]:h-5 shrink-0 text-(--text-primary)";
855
+ var Tag = React14.forwardRef(
856
+ (props, ref) => {
857
+ const {
858
+ size = "sm",
859
+ className,
860
+ asChild = false,
861
+ disabled = false,
862
+ label,
863
+ value,
864
+ ...rest
865
+ } = props;
866
+ const Comp = asChild ? Slot6 : "div";
867
+ const leading = props.leadingIcon && React14.isValidElement(props.leadingIcon) ? React14.cloneElement(props.leadingIcon, { disabled, ...props.leadingIcon.props }) : null;
868
+ const trailing = props.trailingIcon && React14.isValidElement(props.trailingIcon) ? React14.cloneElement(props.trailingIcon, { disabled, ...props.trailingIcon.props }) : null;
869
+ return /* @__PURE__ */ jsxs10(
870
+ Comp,
871
+ {
872
+ className: cn(tagVariants({ size }), disabled && disabledTag, className),
873
+ ref,
874
+ ...rest,
875
+ children: [
876
+ leading && /* @__PURE__ */ jsx16("div", { className: iconClasses, children: leading }),
877
+ value ? /* @__PURE__ */ jsxs10("div", { className: "flex flex-row gap-1 items-center", children: [
878
+ /* @__PURE__ */ jsx16("span", { className: "text-(--text-primary) paragraph-l mb-0! cursor-default font-normal", children: label }),
879
+ /* @__PURE__ */ jsx16("span", { className: "text-(--text-primary) paragraph-l mb-0! cursor-default font-normal", children: ":" }),
880
+ /* @__PURE__ */ jsx16("span", { className: "text-(--text-primary) paragraph-l-medium mb-0! cursor-default font-medium", children: value })
881
+ ] }) : /* @__PURE__ */ jsx16("span", { className: "text-(--text-primary) paragraph-l mb-0! cursor-default", children: label }),
882
+ trailing && /* @__PURE__ */ jsx16("div", { className: iconClasses, children: trailing })
883
+ ]
884
+ }
885
+ );
886
+ }
887
+ );
888
+
889
+ // src/components/Inputs/Checkbox.tsx
890
+ import "react";
891
+ import * as CheckboxPrimitive from "@radix-ui/react-checkbox";
892
+ import { CheckIcon as CheckIcon2 } from "@bubo-squared/icons";
893
+ import { MinusIcon } from "@bubo-squared/icons";
894
+ import { jsx as jsx17, jsxs as jsxs11 } from "react/jsx-runtime";
895
+ function Checkbox({ label, className, ...props }) {
896
+ return /* @__PURE__ */ jsxs11("label", { className: "inline-flex items-center gap-(--space-12) cursor-pointer select-none", children: [
897
+ /* @__PURE__ */ jsx17(
898
+ CheckboxPrimitive.Root,
899
+ {
900
+ className: cn(
901
+ "group flex h-5 w-5 items-center justify-center rounded-xs border border-(--border-secondary) bg-(--background-neutral) text-(--text-primary)",
902
+ "data-[state=checked]:bg-(--background-brand) data-[state=checked]:text-(--text-button-white) data-[state=checked]:border-none",
903
+ "data-[state=indeterminate]:bg-(--background-brand) data-[state=indeterminate]:text-(--text-button-white) data-[state=indeterminate]:border-none",
904
+ "data-[state=checked]:hover:bg-(--background-brand-hover) data-[state=indeterminate]:hover:bg-(--background-brand-hover)",
905
+ "focus-visible:border-(--border-brand)",
906
+ "disabled:bg-(--background-primary-disabled) disabled:border-none disabled:text-(--icon-primary-disabled)",
907
+ "data-[state=checked]:disabled:bg-(--background-primary-disabled) data-[state=checked]:disabled:border-none data-[state=checked]:disabled:text-(--icon-primary-disabled)",
908
+ "data-[state=indeterminate]:disabled:bg-(--background-primary-disabled) data-[state=indeterminate]:disabled:border-none data-[state=indeterminate]:disabled:text-(--icon-primary-disabled)",
909
+ "focus-ring-primary hover:cursor-pointer hover:border-(--border-secondary-hover)",
910
+ className
911
+ ),
912
+ ...props,
913
+ children: /* @__PURE__ */ jsxs11(CheckboxPrimitive.Indicator, { className: "flex items-center justify-center text-current", children: [
914
+ /* @__PURE__ */ jsx17(CheckIcon2, { className: "h-5 w-5 hidden group-data-[state=checked]:block" }),
915
+ /* @__PURE__ */ jsx17(MinusIcon, { className: "h-5 w-5 hidden group-data-[state=indeterminate]:block" })
916
+ ] })
917
+ }
918
+ ),
919
+ label && /* @__PURE__ */ jsx17("span", { className: "paragraph-m-medium text-(--text-primary)", style: { marginBottom: 0 }, children: label })
920
+ ] });
921
+ }
922
+
923
+ // src/components/Inputs/Dropdown.tsx
924
+ import * as React16 from "react";
925
+ import { cva as cva12 } from "class-variance-authority";
926
+ import { ChevronDownIcon } from "@bubo-squared/icons";
927
+ import { jsx as jsx18, jsxs as jsxs12 } from "react/jsx-runtime";
928
+ var dropdownWrapperBase = "flex flex-col gap-2 items-start min-w-[343px]";
929
+ var dropdownTriggerVariants = cva12(
930
+ "group flex w-full items-center justify-between rounded border bg-(--background-primary) px-3 py-2 text-left transition-colors cursor-pointer focus-ring-primary focus:border-(--border-brand) hover:bg-(--background-primary-hover) disabled:bg-(--background-primary) disabled:border-(--border-secondary-disabled) disabled:text-(--text-primary-disabled) disabled:cursor-default",
931
+ {
932
+ variants: {
933
+ size: {
934
+ large: "h-11",
935
+ "extra-large": "h-14"
936
+ },
937
+ status: {
938
+ default: "border-(--border-secondary)",
939
+ success: "border-(--border-success)",
940
+ error: "border-(--border-error)"
941
+ }
942
+ },
943
+ defaultVariants: {
944
+ size: "large",
945
+ status: "default"
946
+ }
947
+ }
948
+ );
949
+ var dropdownTextVariants = cva12("truncate", {
950
+ variants: {
951
+ size: {
952
+ large: "subtitle",
953
+ "extra-large": "h6-title"
954
+ },
955
+ hasValue: {
956
+ false: "text-(--text-secondary)",
957
+ true: "text-(--text-primary)"
958
+ },
959
+ disabled: {
960
+ true: "text-(--text-primary-disabled)"
961
+ }
962
+ },
963
+ defaultVariants: {
964
+ size: "large",
965
+ hasValue: false
966
+ }
967
+ });
968
+ var dropdownIconVariants = cva12("flex items-center justify-center shrink-0", {
969
+ variants: {
970
+ size: {
971
+ large: "w-5 h-5",
972
+ "extra-large": "w-6 h-6"
973
+ },
974
+ disabled: {
975
+ false: "text-(--icon-primary)",
976
+ true: "text-(--icon-primary-disabled)"
977
+ }
978
+ },
979
+ defaultVariants: {
980
+ size: "large",
981
+ disabled: false
982
+ }
983
+ });
984
+ var Dropdown = (props) => {
985
+ const {
986
+ label = "Field Label",
987
+ showLabel = true,
988
+ hint = "This is a hint text to help user.",
989
+ showHint = true,
990
+ placeholder = "Placeholder text",
991
+ size = "large",
992
+ status = "default",
993
+ disabled,
994
+ options,
995
+ value,
996
+ defaultValue,
997
+ onChange,
998
+ className,
999
+ showMenu,
1000
+ ...buttonProps
1001
+ } = props;
1002
+ const dropdownRef = React16.useRef(null);
1003
+ const isControlled = value !== void 0;
1004
+ const [internalValue, setInternalValue] = React16.useState(
1005
+ defaultValue
1006
+ );
1007
+ const [open, setOpen] = React16.useState(false);
1008
+ const currentValue = isControlled ? value : internalValue;
1009
+ const selectedOption = options.find((opt) => opt.value === currentValue);
1010
+ const hasValue = !!selectedOption;
1011
+ const isOpen = showMenu ?? open;
1012
+ const handleToggle = () => {
1013
+ if (disabled) return;
1014
+ if (showMenu === void 0) {
1015
+ setOpen((prev) => !prev);
1016
+ }
1017
+ };
1018
+ const handleSelect = (optionValue) => {
1019
+ if (!isControlled) {
1020
+ setInternalValue(optionValue);
1021
+ }
1022
+ onChange?.(optionValue);
1023
+ if (showMenu === void 0) {
1024
+ setOpen(false);
1025
+ }
1026
+ };
1027
+ const triggerId = React16.useId();
1028
+ const labelId = `${triggerId}-label`;
1029
+ const hintId = `${triggerId}-hint`;
1030
+ React16.useEffect(() => {
1031
+ if (showMenu !== void 0) return;
1032
+ const handleClickOutside = (event) => {
1033
+ if (!dropdownRef.current) return;
1034
+ if (!dropdownRef.current.contains(event.target)) {
1035
+ setOpen(false);
1036
+ }
1037
+ };
1038
+ document.addEventListener("mousedown", handleClickOutside);
1039
+ return () => {
1040
+ document.removeEventListener("mousedown", handleClickOutside);
1041
+ };
1042
+ }, [showMenu]);
1043
+ return /* @__PURE__ */ jsxs12("div", { ref: dropdownRef, className: dropdownWrapperBase, children: [
1044
+ showLabel && /* @__PURE__ */ jsx18(
1045
+ "label",
1046
+ {
1047
+ htmlFor: triggerId,
1048
+ id: labelId,
1049
+ className: cn(
1050
+ "paragraph-s",
1051
+ disabled ? "text-(--text-primary-disabled)" : "text-(--text-primary)"
1052
+ ),
1053
+ style: { marginBottom: 0 },
1054
+ children: label
1055
+ }
1056
+ ),
1057
+ /* @__PURE__ */ jsxs12("div", { className: "relative w-full", children: [
1058
+ /* @__PURE__ */ jsxs12(
1059
+ "button",
1060
+ {
1061
+ type: "button",
1062
+ id: triggerId,
1063
+ "aria-haspopup": "listbox",
1064
+ "aria-expanded": isOpen,
1065
+ "aria-labelledby": showLabel ? labelId : void 0,
1066
+ "aria-describedby": showHint ? hintId : void 0,
1067
+ disabled,
1068
+ className: cn(
1069
+ dropdownTriggerVariants({ size, status }),
1070
+ className
1071
+ ),
1072
+ onClick: handleToggle,
1073
+ "data-open": isOpen || void 0,
1074
+ ...buttonProps,
1075
+ children: [
1076
+ /* @__PURE__ */ jsx18(
1077
+ "span",
1078
+ {
1079
+ className: cn(
1080
+ dropdownTextVariants({
1081
+ size,
1082
+ hasValue,
1083
+ disabled: !!disabled
1084
+ })
1085
+ ),
1086
+ style: { marginBottom: 0 },
1087
+ children: hasValue ? selectedOption?.label : placeholder
1088
+ }
1089
+ ),
1090
+ /* @__PURE__ */ jsx18(
1091
+ "span",
1092
+ {
1093
+ className: cn(
1094
+ dropdownIconVariants({ size, disabled: !!disabled })
1095
+ ),
1096
+ children: /* @__PURE__ */ jsx18(ChevronDownIcon, {})
1097
+ }
1098
+ )
1099
+ ]
1100
+ }
1101
+ ),
1102
+ isOpen && options.length > 0 && /* @__PURE__ */ jsx18("div", { className: "absolute z-10 mt-1 w-full min-w-343 rounded-(--border-radius-4) border border-(--border-primary-hover) bg-(--background-neutral) shadow-card-md flex overflow-y-scroll dropdown-scrollbar max-h-[316px]", children: /* @__PURE__ */ jsx18("ul", { role: "listbox", className: "flex flex-1 flex-col", children: options.map((opt) => {
1103
+ const selected = opt.value === currentValue;
1104
+ return /* @__PURE__ */ jsx18(
1105
+ "li",
1106
+ {
1107
+ className: cn(
1108
+ "bg-(--background-neutral) border-b border-(--border-secondary) last:border-b-0",
1109
+ selected && "bg-(--background-secondary)"
1110
+ ),
1111
+ children: /* @__PURE__ */ jsx18(
1112
+ "button",
1113
+ {
1114
+ type: "button",
1115
+ className: "flex w-full items-center gap-2 pl-(--space-8) pr-(--space-16) py-(--space-8) text-left paragraph-l text-(--text-primary) hover:bg-(--background-secondary)",
1116
+ style: { marginBottom: 0 },
1117
+ role: "option",
1118
+ "aria-selected": selected,
1119
+ onClick: () => handleSelect(opt.value),
1120
+ children: opt.label
1121
+ }
1122
+ )
1123
+ },
1124
+ opt.value
1125
+ );
1126
+ }) }) })
1127
+ ] }),
1128
+ showHint && /* @__PURE__ */ jsx18(
1129
+ "p",
1130
+ {
1131
+ id: hintId,
1132
+ className: cn(
1133
+ "caption",
1134
+ disabled ? "text-(--text-primary-disabled)" : "text-(--text-secondary)"
1135
+ ),
1136
+ style: { marginBottom: 0 },
1137
+ children: hint
1138
+ }
1139
+ )
1140
+ ] });
1141
+ };
1142
+ Dropdown.displayName = "Dropdown";
1143
+
1144
+ // src/components/Inputs/PasswordInput.tsx
1145
+ import * as React20 from "react";
1146
+ import { cva as cva14 } from "class-variance-authority";
1147
+
1148
+ // src/components/ui/input.tsx
1149
+ import * as React17 from "react";
1150
+ import { jsx as jsx19 } from "react/jsx-runtime";
1151
+ var Input = React17.forwardRef(
1152
+ ({ className, type, variant = "default", ...props }, ref) => {
1153
+ const base = "text-(--text-primary) placeholder:text-(--text-secondary) disabled:text-(--text-primary-disabled) disabled:placeholder:text-(--text-primary-disabled) selection:bg-primary selection:text-primary-foreground file:text-foreground";
1154
+ const defaultStyles = "dark:bg-input/30 border-input h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 shadow-xs transition-[color,box-shadow] file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 focus-visible:border-ring focus-visible:ring-0 focus-visible:shadow-none aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive";
1155
+ const bareStyles = "bg-transparent outline-none w-full";
1156
+ return /* @__PURE__ */ jsx19(
1157
+ "input",
1158
+ {
1159
+ ref,
1160
+ type,
1161
+ "data-slot": "input",
1162
+ className: cn(
1163
+ base,
1164
+ variant === "default" ? defaultStyles : bareStyles,
1165
+ className
1166
+ ),
1167
+ ...props
1168
+ }
1169
+ );
1170
+ }
1171
+ );
1172
+ Input.displayName = "Input";
1173
+
1174
+ // src/components/Inputs/Field.tsx
1175
+ import * as React18 from "react";
1176
+ import { jsx as jsx20, jsxs as jsxs13 } from "react/jsx-runtime";
1177
+ var fieldBase = "flex flex-col gap-2 items-start min-w-[343px]";
1178
+ var Field = (props) => {
1179
+ const {
1180
+ label,
1181
+ hint,
1182
+ status = "default",
1183
+ disabled,
1184
+ className,
1185
+ children
1186
+ } = props;
1187
+ const fieldId = React18.useId();
1188
+ const labelId = label ? `${fieldId}-label` : void 0;
1189
+ const hintId = hint ? `${fieldId}-hint` : void 0;
1190
+ const hintColorClass = disabled ? "text-(--text-primary-disabled)" : status === "success" ? "text-(--text-success)" : status === "error" ? "text-(--text-error)" : "text-(--text-secondary)";
1191
+ const labelColorClass = disabled ? "text-(--text-primary-disabled)" : "text-(--text-primary)";
1192
+ return /* @__PURE__ */ jsxs13("div", { className: cn(fieldBase, className), children: [
1193
+ label && /* @__PURE__ */ jsx20(
1194
+ "label",
1195
+ {
1196
+ id: labelId,
1197
+ className: cn("paragraph-s", labelColorClass),
1198
+ style: { marginBottom: 0 },
1199
+ children: label
1200
+ }
1201
+ ),
1202
+ /* @__PURE__ */ jsx20("div", { className: "relative w-full", children }),
1203
+ /* @__PURE__ */ jsx20(
1204
+ "p",
1205
+ {
1206
+ id: hint ? hintId : void 0,
1207
+ className: cn("caption", hint ? hintColorClass : "invisible"),
1208
+ style: { marginBottom: 0 },
1209
+ children: hint || "\xA0"
1210
+ }
1211
+ )
1212
+ ] });
1213
+ };
1214
+ Field.displayName = "Field";
1215
+
1216
+ // src/components/Inputs/InputShell.tsx
1217
+ import * as React19 from "react";
1218
+ import { cva as cva13 } from "class-variance-authority";
1219
+ import { jsx as jsx21 } from "react/jsx-runtime";
1220
+ var inputShellVariants = cva13(
1221
+ "group flex w-full items-center rounded border bg-(--background-primary) text-left cursor-text border-(--border-secondary)",
1222
+ {
1223
+ variants: {
1224
+ size: {
1225
+ large: "gap-2 px-2 py-2 h-11",
1226
+ "extra-large": "gap-2 px-[10px] py-2 h-14"
1227
+ },
1228
+ status: {
1229
+ default: "input-default",
1230
+ success: "input-success",
1231
+ error: "input-error"
1232
+ },
1233
+ disabled: {
1234
+ true: "bg-(--background-primary-disabled) border-(--border-secondary-disabled) text-(--text-primary-disabled) cursor-default"
1235
+ }
1236
+ },
1237
+ defaultVariants: {
1238
+ size: "large",
1239
+ status: "default"
1240
+ }
1241
+ }
1242
+ );
1243
+ var InputShell = React19.forwardRef(
1244
+ ({ size, status, disabled, className, ...rest }, ref) => {
1245
+ return /* @__PURE__ */ jsx21(
1246
+ "div",
1247
+ {
1248
+ ref,
1249
+ "aria-disabled": disabled || void 0,
1250
+ className: cn(
1251
+ inputShellVariants({ size, status, disabled }),
1252
+ className
1253
+ ),
1254
+ ...rest
1255
+ }
1256
+ );
1257
+ }
1258
+ );
1259
+ InputShell.displayName = "InputShell";
1260
+
1261
+ // src/components/Inputs/PasswordInput.tsx
1262
+ import { jsx as jsx22, jsxs as jsxs14 } from "react/jsx-runtime";
1263
+ var passwordTextVariants = cva14("truncate", {
1264
+ variants: {
1265
+ size: {
1266
+ large: "subtitle",
1267
+ "extra-large": "h6-title"
1268
+ },
1269
+ disabled: {
1270
+ true: "text-(--text-primary-disabled)",
1271
+ false: "text-(--text-primary)"
1272
+ }
1273
+ },
1274
+ defaultVariants: {
1275
+ size: "large",
1276
+ disabled: false
1277
+ }
1278
+ });
1279
+ var iconWrapperVariants = cva14(
1280
+ "flex items-center justify-center shrink-0 text-(--icon-primary)",
1281
+ {
1282
+ variants: {
1283
+ size: {
1284
+ large: "w-5 h-5 [&>svg]:w-5 [&>svg]:h-5",
1285
+ "extra-large": "w-6 h-6 [&>svg]:w-6 [&>svg]:h-6"
1286
+ },
1287
+ disabled: {
1288
+ true: "text-(--icon-primary-disabled)"
1289
+ }
1290
+ },
1291
+ defaultVariants: {
1292
+ size: "large"
1293
+ }
1294
+ }
1295
+ );
1296
+ var actionButtonVariants = cva14(
1297
+ "flex items-center justify-center shrink-0 cursor-pointer bg-transparent border-0 p-0 text-left paragraph-s text-(--icon-primary) hover:text-(--icon-primary-hover) focus:outline-none ",
1298
+ {
1299
+ variants: {
1300
+ size: {
1301
+ large: "paragraph-s",
1302
+ "extra-large": "paragraph-m"
1303
+ },
1304
+ disabled: {
1305
+ true: "cursor-default text-(--text-primary-disabled) hover:text-(--text-primary-disabled)"
1306
+ }
1307
+ },
1308
+ defaultVariants: {
1309
+ size: "large"
1310
+ }
1311
+ }
1312
+ );
1313
+ var PasswordInput = (props) => {
1314
+ const {
1315
+ label,
1316
+ hint,
1317
+ placeholder = "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022",
1318
+ size = "large",
1319
+ status = "default",
1320
+ variant = "icons",
1321
+ disabled,
1322
+ className,
1323
+ leadingIcon,
1324
+ trailingIcon,
1325
+ actionLabel = "Action",
1326
+ onActionClick,
1327
+ value,
1328
+ defaultValue,
1329
+ onChange,
1330
+ ...inputProps
1331
+ } = props;
1332
+ const isControlled = value !== void 0;
1333
+ const [internalValue, setInternalValue] = React20.useState(
1334
+ defaultValue ?? ""
1335
+ );
1336
+ const currentValue = (isControlled ? value : internalValue) ?? "";
1337
+ const inputRef = React20.useRef(null);
1338
+ const handleContainerClick = () => {
1339
+ if (disabled) return;
1340
+ inputRef.current?.focus();
1341
+ };
1342
+ const handleChange = (event) => {
1343
+ if (!isControlled) {
1344
+ setInternalValue(event.target.value);
1345
+ }
1346
+ onChange?.(event);
1347
+ };
1348
+ const showLeadingIcon = variant === "icons" && !!leadingIcon;
1349
+ const showTrailingIcon = variant === "icons" && !!trailingIcon;
1350
+ const showAction = variant === "action" && !!actionLabel;
1351
+ return /* @__PURE__ */ jsx22(
1352
+ Field,
1353
+ {
1354
+ label,
1355
+ hint,
1356
+ status,
1357
+ disabled,
1358
+ children: /* @__PURE__ */ jsxs14(
1359
+ InputShell,
1360
+ {
1361
+ size,
1362
+ status,
1363
+ disabled,
1364
+ className,
1365
+ onClick: handleContainerClick,
1366
+ children: [
1367
+ showLeadingIcon && /* @__PURE__ */ jsx22(
1368
+ "span",
1369
+ {
1370
+ className: cn(
1371
+ iconWrapperVariants({ size, disabled: !!disabled })
1372
+ ),
1373
+ children: leadingIcon
1374
+ }
1375
+ ),
1376
+ /* @__PURE__ */ jsx22(
1377
+ Input,
1378
+ {
1379
+ ref: inputRef,
1380
+ type: "password",
1381
+ disabled: disabled ?? void 0,
1382
+ placeholder,
1383
+ value: isControlled ? value : currentValue,
1384
+ defaultValue: isControlled ? void 0 : defaultValue,
1385
+ onChange: handleChange,
1386
+ variant: "bare",
1387
+ className: cn(
1388
+ passwordTextVariants({ size, disabled: !!disabled })
1389
+ ),
1390
+ style: { marginBottom: 0 },
1391
+ ...inputProps
1392
+ }
1393
+ ),
1394
+ showTrailingIcon && /* @__PURE__ */ jsx22(
1395
+ "span",
1396
+ {
1397
+ className: cn(
1398
+ iconWrapperVariants({ size, disabled: !!disabled })
1399
+ ),
1400
+ children: trailingIcon
1401
+ }
1402
+ ),
1403
+ showAction && /* @__PURE__ */ jsx22(
1404
+ "button",
1405
+ {
1406
+ type: "button",
1407
+ style: { marginBottom: 0 },
1408
+ className: cn(
1409
+ actionButtonVariants({ size, disabled: !!disabled })
1410
+ ),
1411
+ onClick: disabled ? void 0 : onActionClick,
1412
+ children: actionLabel
1413
+ }
1414
+ )
1415
+ ]
1416
+ }
1417
+ )
1418
+ }
1419
+ );
1420
+ };
1421
+ PasswordInput.displayName = "PasswordInput";
1422
+
1423
+ // src/components/Inputs/RadioGroup.tsx
1424
+ import * as React21 from "react";
1425
+ import * as RadioGroupPrimitive from "@radix-ui/react-radio-group";
1426
+ import { jsx as jsx23, jsxs as jsxs15 } from "react/jsx-runtime";
1427
+ var wrapperBase = "flex flex-col gap-2 items-start min-w-[343px]";
1428
+ var RadioGroup = ({
1429
+ label,
1430
+ hint,
1431
+ options,
1432
+ orientation = "vertical",
1433
+ disabled = false,
1434
+ value,
1435
+ defaultValue,
1436
+ onValueChange,
1437
+ className,
1438
+ ...rootProps
1439
+ }) => {
1440
+ const groupId = React21.useId();
1441
+ const hintId = hint ? `${groupId}-hint` : void 0;
1442
+ const handleValueChange = (next) => {
1443
+ onValueChange?.(next);
1444
+ };
1445
+ const isHorizontal = orientation === "horizontal";
1446
+ return /* @__PURE__ */ jsxs15("div", { className: wrapperBase, children: [
1447
+ label && /* @__PURE__ */ jsx23(
1448
+ "span",
1449
+ {
1450
+ className: cn(
1451
+ "paragraph-s text-(--text-primary)",
1452
+ disabled && "text-(--text-primary-disabled)"
1453
+ ),
1454
+ style: { marginBottom: 0 },
1455
+ children: label
1456
+ }
1457
+ ),
1458
+ /* @__PURE__ */ jsx23(
1459
+ RadioGroupPrimitive.Root,
1460
+ {
1461
+ ...rootProps,
1462
+ value,
1463
+ defaultValue,
1464
+ onValueChange: handleValueChange,
1465
+ "aria-describedby": hintId,
1466
+ className: cn(
1467
+ "flex",
1468
+ isHorizontal ? "flex-row gap-6" : "flex-col gap-2",
1469
+ className
1470
+ ),
1471
+ children: options.map((option) => /* @__PURE__ */ jsx23(
1472
+ RadioGroupPrimitive.Item,
1473
+ {
1474
+ value: option.value,
1475
+ disabled: disabled || option.disabled,
1476
+ asChild: true,
1477
+ children: /* @__PURE__ */ jsxs15(
1478
+ "button",
1479
+ {
1480
+ type: "button",
1481
+ className: cn(
1482
+ "group inline-flex items-center gap-2 outline-none",
1483
+ "data-[disabled]:pointer-events-none",
1484
+ disabled || option.disabled ? "cursor-default" : "cursor-pointer"
1485
+ ),
1486
+ children: [
1487
+ /* @__PURE__ */ jsx23(
1488
+ "span",
1489
+ {
1490
+ className: cn(
1491
+ "flex items-center justify-center shrink-0 h-5 w-5 rounded-full border bg-(--background-primary) transition-all",
1492
+ // 1: enabled, unchecked, unfocused, unhovered
1493
+ "group-data-[state=unchecked]:border-(--border-secondary)",
1494
+ // 2: enabled, checked, unfocused, unhovered
1495
+ "group-data-[state=checked]:border-(--border-brand)",
1496
+ // 3: enabled, unchecked, hovered, unfocused
1497
+ "group-data-[state=unchecked]:group-hover:border-(--border-secondary-hover)",
1498
+ // 4: enabled, checked, hovered, unfocused
1499
+ "group-data-[state=checked]:group-hover:border-(--border-brand-hover)",
1500
+ "group-data-[state=checked]:group-hover:shadow-[0_0_0_var(--focus-ring-spread)_var(--color-b-100)]",
1501
+ // 5: enabled, unchecked, focused (override 1/3)
1502
+ "group-data-[state=unchecked]:group-focus-visible:border-(--border-secondary-hover)",
1503
+ // 6: enabled, checked, focused (override 2/4)
1504
+ "group-data-[state=checked]:group-focus-visible:border-(--border-brand-focus)",
1505
+ "group-data-[state=checked]:group-focus-visible:shadow-[0_0_0_var(--focus-ring-spread)_var(--focus-primary)]",
1506
+ // 7: disabled, unchecked (override everything above)
1507
+ "group-[&[data-disabled][data-state=unchecked]]:border-none",
1508
+ "group-[&[data-disabled][data-state=unchecked]]:bg-(--background-primary-disabled)",
1509
+ // 8: disabled, checked (override everything above)
1510
+ "group-[&[data-disabled][data-state=checked]]:border-(--border-primary-disabled)",
1511
+ "group-[&[data-disabled][data-state=checked]]:bg-(--background-primary-disabled)"
1512
+ ),
1513
+ children: /* @__PURE__ */ jsx23(
1514
+ "span",
1515
+ {
1516
+ className: cn(
1517
+ "h-4 w-4 rounded-full bg-(--background-brand) scale-0 transition-transform",
1518
+ "group-data-[state=checked]:scale-100",
1519
+ "group-data-[state=checked]:group-hover:bg-(--background-brand-hover)",
1520
+ "group-data-[state=checked]:group-focus-visible:bg-(--background-brand-hover)",
1521
+ "group-[&[data-disabled][data-state=checked]]:bg-(--background-brand-disabled)",
1522
+ "group-[&[data-disabled][data-state=unchecked]]:scale-0"
1523
+ )
1524
+ }
1525
+ )
1526
+ }
1527
+ ),
1528
+ /* @__PURE__ */ jsx23(
1529
+ "span",
1530
+ {
1531
+ className: cn(
1532
+ "paragraph-s text-(--text-primary)",
1533
+ "group-data-[disabled]:text-(--text-primary-disabled) whitespace-nowrap"
1534
+ ),
1535
+ style: { marginBottom: 0 },
1536
+ children: option.label
1537
+ }
1538
+ )
1539
+ ]
1540
+ }
1541
+ )
1542
+ },
1543
+ option.value
1544
+ ))
1545
+ }
1546
+ ),
1547
+ /* @__PURE__ */ jsx23(
1548
+ "p",
1549
+ {
1550
+ id: hintId,
1551
+ className: cn(
1552
+ "caption text-(--text-secondary)",
1553
+ disabled && "text-(--text-primary-disabled)"
1554
+ ),
1555
+ style: { marginBottom: 0 },
1556
+ children: hint ?? "\xA0"
1557
+ }
1558
+ )
1559
+ ] });
1560
+ };
1561
+
1562
+ // src/components/Inputs/SearchInput.tsx
1563
+ import * as React22 from "react";
1564
+ import { cva as cva15 } from "class-variance-authority";
1565
+ import { SearchIcon } from "@bubo-squared/icons";
1566
+ import { jsx as jsx24, jsxs as jsxs16 } from "react/jsx-runtime";
1567
+ var searchTextVariants = cva15("truncate", {
1568
+ variants: {
1569
+ size: {
1570
+ large: "subtitle",
1571
+ "extra-large": "h6-title"
1572
+ }
1573
+ },
1574
+ defaultVariants: {
1575
+ size: "large"
1576
+ }
1577
+ });
1578
+ var iconWrapperVariants2 = cva15("flex items-center justify-center shrink-0 text-(--icon-primary)", {
1579
+ variants: {
1580
+ size: {
1581
+ large: "w-5 h-5 [&>svg]:w-5 [&>svg]:h-5",
1582
+ "extra-large": "w-6 h-6 [&>svg]:w-6 [&>svg]:h-6"
1583
+ },
1584
+ disabled: {
1585
+ true: "text-(--icon-primary-disabled)"
1586
+ }
1587
+ },
1588
+ defaultVariants: {
1589
+ size: "large"
1590
+ }
1591
+ });
1592
+ var SearchInput = (props) => {
1593
+ const {
1594
+ placeholder = "Search...",
1595
+ size = "large",
1596
+ disabled,
1597
+ className,
1598
+ leadingIcon,
1599
+ showLeadingIcon = true,
1600
+ ...inputProps
1601
+ } = props;
1602
+ const inputRef = React22.useRef(null);
1603
+ const handleContainerClick = () => {
1604
+ if (disabled) return;
1605
+ inputRef.current?.focus();
1606
+ };
1607
+ return /* @__PURE__ */ jsx24("div", { className: "flex flex-col gap-2 items-start min-w-[343px]", children: /* @__PURE__ */ jsx24("div", { className: "relative w-full", children: /* @__PURE__ */ jsxs16(
1608
+ InputShell,
1609
+ {
1610
+ size,
1611
+ status: "default",
1612
+ disabled,
1613
+ className,
1614
+ onClick: handleContainerClick,
1615
+ children: [
1616
+ showLeadingIcon && /* @__PURE__ */ jsx24("span", { className: cn(iconWrapperVariants2({ size, disabled: !!disabled })), children: leadingIcon ?? /* @__PURE__ */ jsx24(SearchIcon, {}) }),
1617
+ /* @__PURE__ */ jsx24(
1618
+ Input,
1619
+ {
1620
+ ref: inputRef,
1621
+ type: "search",
1622
+ placeholder,
1623
+ disabled: disabled ?? void 0,
1624
+ variant: "bare",
1625
+ className: cn(
1626
+ searchTextVariants({ size })
1627
+ ),
1628
+ style: { marginBottom: 0 },
1629
+ ...inputProps
1630
+ }
1631
+ )
1632
+ ]
1633
+ }
1634
+ ) }) });
1635
+ };
1636
+ SearchInput.displayName = "SearchInput";
1637
+
1638
+ // src/components/Inputs/Slider.tsx
1639
+ import * as React23 from "react";
1640
+ import { jsx as jsx25, jsxs as jsxs17 } from "react/jsx-runtime";
1641
+ var wrapperBase2 = "flex flex-col gap-2 items-start min-w-[343px]";
1642
+ var Slider = (props) => {
1643
+ const {
1644
+ display = "flat",
1645
+ type = "single",
1646
+ tooltipPlacement = "top",
1647
+ tooltipFormatter,
1648
+ showPercentage = true,
1649
+ min = 0,
1650
+ max = 100,
1651
+ step = 1,
1652
+ disabled = false,
1653
+ value,
1654
+ defaultValue,
1655
+ onValueChange,
1656
+ className
1657
+ } = props;
1658
+ const isControlled = value !== void 0;
1659
+ const expectedLength = type === "multi" ? 2 : 1;
1660
+ const normalizeArray = React23.useCallback(
1661
+ (arr, fallback) => {
1662
+ if (!arr || arr.length === 0) return fallback;
1663
+ if (arr.length === expectedLength) return arr;
1664
+ if (arr.length > expectedLength) return arr.slice(0, expectedLength);
1665
+ if (arr.length === 1 && expectedLength === 2) {
1666
+ return [arr[0], max];
1667
+ }
1668
+ return fallback;
1669
+ },
1670
+ [expectedLength, max]
1671
+ );
1672
+ const defaultInternal = React23.useMemo(() => {
1673
+ if (defaultValue) return normalizeArray(defaultValue, []);
1674
+ if (type === "multi") return [min, Math.min(min + (max - min) / 4, max)];
1675
+ return [min + (max - min) / 3];
1676
+ }, [defaultValue, min, max, type, normalizeArray]);
1677
+ const [internalValue, setInternalValue] = React23.useState(
1678
+ () => normalizeArray(isControlled ? value : defaultInternal, defaultInternal)
1679
+ );
1680
+ React23.useEffect(() => {
1681
+ if (isControlled) {
1682
+ setInternalValue(
1683
+ (current2) => normalizeArray(value, current2.length ? current2 : defaultInternal)
1684
+ );
1685
+ }
1686
+ }, [isControlled, value, normalizeArray, defaultInternal]);
1687
+ const current = internalValue;
1688
+ const trackRef = React23.useRef(null);
1689
+ const clamp = (val) => {
1690
+ if (val < min) return min;
1691
+ if (val > max) return max;
1692
+ return val;
1693
+ };
1694
+ React23.useEffect(() => {
1695
+ if (!isControlled) {
1696
+ setInternalValue((prev) => {
1697
+ const clamped = prev.map((v) => clamp(v));
1698
+ if (type === "multi" && clamped.length === 2 && step > 0) {
1699
+ return enforceMinGap(clamped, prev);
1700
+ }
1701
+ return clamped;
1702
+ });
1703
+ }
1704
+ }, [isControlled, min, max]);
1705
+ const snap = (val) => {
1706
+ const range = max - min;
1707
+ if (range <= 0 || step <= 0) return clamp(val);
1708
+ const stepsFromMin = Math.round((val - min) / step);
1709
+ return clamp(min + stepsFromMin * step);
1710
+ };
1711
+ const enforceMinGap = (next, prev) => {
1712
+ if (type !== "multi" || next.length !== 2 || step <= 0) return next;
1713
+ let [low, high] = next;
1714
+ const [prevLow, prevHigh] = prev.length === 2 ? prev : next;
1715
+ if (low > high) {
1716
+ [low, high] = [high, low];
1717
+ }
1718
+ const minGap = step;
1719
+ if (high - low < minGap) {
1720
+ const lowChanged = low !== prevLow;
1721
+ const highChanged = high !== prevHigh;
1722
+ if (lowChanged && !highChanged) {
1723
+ low = clamp(high - minGap);
1724
+ } else if (highChanged && !lowChanged) {
1725
+ high = clamp(low + minGap);
1726
+ } else {
1727
+ high = clamp(low + minGap);
1728
+ }
1729
+ if (high - low < minGap) {
1730
+ low = clamp(high - minGap);
1731
+ }
1732
+ }
1733
+ return [low, high];
1734
+ };
1735
+ const updateValue = (next) => {
1736
+ let normalized = normalizeArray(next, current);
1737
+ if (type === "multi" && normalized.length === 2) {
1738
+ normalized = enforceMinGap(normalized, current);
1739
+ }
1740
+ if (!isControlled) {
1741
+ setInternalValue(normalized);
1742
+ }
1743
+ onValueChange?.(normalized);
1744
+ };
1745
+ const getSnappedValueFromClientX = (clientX, track) => {
1746
+ const rect = track.getBoundingClientRect();
1747
+ const offsetX = clientX - rect.left;
1748
+ const ratio = rect.width === 0 ? 0 : offsetX / rect.width;
1749
+ const rawValue = min + ratio * (max - min);
1750
+ return snap(rawValue);
1751
+ };
1752
+ const startDrag = (thumbIndex, clientX) => {
1753
+ if (disabled) return;
1754
+ const track = trackRef.current;
1755
+ if (!track) return;
1756
+ const handlePointerMove = (event) => {
1757
+ if (disabled) return;
1758
+ const snapped = getSnappedValueFromClientX(event.clientX, track);
1759
+ if (type === "multi" && current.length === 2) {
1760
+ const [a, b] = current;
1761
+ if (thumbIndex === 0) {
1762
+ updateValue([snapped, b]);
1763
+ } else {
1764
+ updateValue([a, snapped]);
1765
+ }
1766
+ } else {
1767
+ updateValue([snapped]);
1768
+ }
1769
+ };
1770
+ const handlePointerUp = () => {
1771
+ window.removeEventListener("pointermove", handlePointerMove);
1772
+ window.removeEventListener("pointerup", handlePointerUp);
1773
+ };
1774
+ const initialSnapped = getSnappedValueFromClientX(clientX, track);
1775
+ if (type === "multi" && current.length === 2) {
1776
+ const [a, b] = current;
1777
+ if (thumbIndex === 0) {
1778
+ updateValue([initialSnapped, b]);
1779
+ } else {
1780
+ updateValue([a, initialSnapped]);
1781
+ }
1782
+ } else {
1783
+ updateValue([initialSnapped]);
1784
+ }
1785
+ window.addEventListener("pointermove", handlePointerMove);
1786
+ window.addEventListener("pointerup", handlePointerUp);
1787
+ };
1788
+ const handleTrackPointerDown = (event) => {
1789
+ if (disabled) return;
1790
+ if (event.button !== 0) return;
1791
+ const track = trackRef.current;
1792
+ if (!track) return;
1793
+ const snapped = getSnappedValueFromClientX(event.clientX, track);
1794
+ let thumbIndex = 0;
1795
+ if (type === "multi" && current.length === 2) {
1796
+ const [a, b] = current;
1797
+ const distToA = Math.abs(snapped - a);
1798
+ const distToB = Math.abs(snapped - b);
1799
+ thumbIndex = distToA <= distToB ? 0 : 1;
1800
+ }
1801
+ event.preventDefault();
1802
+ startDrag(thumbIndex, event.clientX);
1803
+ };
1804
+ const handleThumbKeyDown = (index, event) => {
1805
+ if (disabled) return;
1806
+ const key = event.key;
1807
+ let delta = 0;
1808
+ if (key === "ArrowRight" || key === "ArrowUp") {
1809
+ delta = step;
1810
+ } else if (key === "ArrowLeft" || key === "ArrowDown") {
1811
+ delta = -step;
1812
+ } else if (key === "Home") {
1813
+ updateValue(
1814
+ current.map((v, i) => i === index ? min : v)
1815
+ );
1816
+ event.preventDefault();
1817
+ return;
1818
+ } else if (key === "End") {
1819
+ updateValue(
1820
+ current.map((v, i) => i === index ? max : v)
1821
+ );
1822
+ event.preventDefault();
1823
+ return;
1824
+ }
1825
+ if (delta !== 0) {
1826
+ const next = current.map(
1827
+ (v, i) => i === index ? snap(v + delta) : v
1828
+ );
1829
+ updateValue(next);
1830
+ event.preventDefault();
1831
+ }
1832
+ };
1833
+ const [primary, secondary] = type === "multi" && current.length === 2 ? [current[0], current[1]] : [current[0], void 0];
1834
+ const valueToPercent = (val) => {
1835
+ if (val === void 0) return 0;
1836
+ if (max === min) return 0;
1837
+ const clamped = clamp(val);
1838
+ return (clamped - min) / (max - min) * 100;
1839
+ };
1840
+ const primaryPercent = valueToPercent(primary);
1841
+ const secondaryPercent = valueToPercent(secondary);
1842
+ const showNumeric = display === "numeric";
1843
+ const showTooltip = display === "tooltip";
1844
+ const isTooltipAbove = tooltipPlacement === "top";
1845
+ const isDecimalDomain = !Number.isInteger(step) || !Number.isInteger(min) || !Number.isInteger(max);
1846
+ const formatNumber = (num) => {
1847
+ if (!isDecimalDomain) {
1848
+ return `${Math.round(num)}`;
1849
+ }
1850
+ const rounded = Number(num.toFixed(2));
1851
+ if (Number.isInteger(rounded)) {
1852
+ return `${rounded}`;
1853
+ }
1854
+ return rounded.toFixed(2);
1855
+ };
1856
+ const formatDisplayValue = (val) => {
1857
+ const value2 = val ?? min;
1858
+ if (tooltipFormatter) return tooltipFormatter(value2);
1859
+ if (showPercentage) {
1860
+ const percent = valueToPercent(value2);
1861
+ return `${formatNumber(percent)}%`;
1862
+ }
1863
+ return formatNumber(value2);
1864
+ };
1865
+ const formatNumericLabel = () => {
1866
+ if (type === "multi" && secondary !== void 0) {
1867
+ if (!tooltipFormatter && showPercentage && display === "numeric") {
1868
+ const first = formatNumber(valueToPercent(primary));
1869
+ const second = formatNumber(valueToPercent(secondary));
1870
+ return `${first} - ${second}`;
1871
+ }
1872
+ return `${formatDisplayValue(primary)} - ${formatDisplayValue(secondary)}`;
1873
+ }
1874
+ return formatDisplayValue(primary);
1875
+ };
1876
+ const trackHeight = 32;
1877
+ const thumbWidth = 18;
1878
+ const thumbRadius = thumbWidth / 2;
1879
+ const renderTooltipBubble = (key, percent, labelText) => /* @__PURE__ */ jsx25(
1880
+ "div",
1881
+ {
1882
+ className: "absolute -translate-x-1/2 flex flex-col items-center",
1883
+ style: {
1884
+ left: `${percent}%`,
1885
+ bottom: isTooltipAbove ? "100%" : void 0,
1886
+ top: isTooltipAbove ? void 0 : "100%",
1887
+ marginBottom: isTooltipAbove ? 8 : void 0,
1888
+ marginTop: isTooltipAbove ? void 0 : 8
1889
+ },
1890
+ children: /* @__PURE__ */ jsxs17(
1891
+ "div",
1892
+ {
1893
+ className: cn(
1894
+ "relative rounded-(--border-radius-4) shadow-card-md px-(--space-8) py-(--space-4)",
1895
+ disabled ? "bg-(--background-primary-disabled)" : "bg-(--background-neutral)"
1896
+ ),
1897
+ style: { marginBottom: 0 },
1898
+ children: [
1899
+ /* @__PURE__ */ jsx25(
1900
+ "p",
1901
+ {
1902
+ className: cn(
1903
+ "paragraph-s",
1904
+ disabled ? "text-(--text-primary-disabled)" : "text-(--text-primary)"
1905
+ ),
1906
+ style: { marginBottom: 0 },
1907
+ children: labelText
1908
+ }
1909
+ ),
1910
+ /* @__PURE__ */ jsx25(
1911
+ "div",
1912
+ {
1913
+ className: cn(
1914
+ "absolute left-1/2 -translate-x-1/2 w-2 h-2 rotate-45",
1915
+ disabled ? "bg-(--background-primary-disabled)" : "bg-(--background-neutral)",
1916
+ isTooltipAbove ? "-bottom-1" : "-top-1"
1917
+ )
1918
+ }
1919
+ )
1920
+ ]
1921
+ }
1922
+ )
1923
+ },
1924
+ key
1925
+ );
1926
+ const renderHandle = (index, percent, ariaValueText) => {
1927
+ const val = index === 0 ? primary : secondary;
1928
+ return /* @__PURE__ */ jsx25(
1929
+ "button",
1930
+ {
1931
+ type: "button",
1932
+ role: "slider",
1933
+ "aria-valuemin": min,
1934
+ "aria-valuemax": max,
1935
+ "aria-valuenow": val,
1936
+ "aria-valuetext": ariaValueText,
1937
+ "aria-disabled": disabled || void 0,
1938
+ tabIndex: disabled ? -1 : 0,
1939
+ className: cn(
1940
+ "absolute -translate-x-1/2 flex items-center justify-center",
1941
+ "h-8 w-[18px] rounded-(--border-radius-4)",
1942
+ disabled ? "bg-(--icon-primary-disabled) cursor-default" : "bg-(--icon-primary-hover) outline-none focus-visible:shadow-[0_0_0_var(--focus-ring-spread)_var(--focus-primary)] cursor-pointer"
1943
+ ),
1944
+ style: {
1945
+ left: `${percent}%`,
1946
+ top: `calc(50% - ${trackHeight / 2}px)`
1947
+ },
1948
+ onPointerDown: (event) => {
1949
+ if (disabled) return;
1950
+ if (event.button !== 0) return;
1951
+ event.preventDefault();
1952
+ startDrag(index, event.clientX);
1953
+ },
1954
+ onKeyDown: (event) => handleThumbKeyDown(index, event)
1955
+ },
1956
+ index
1957
+ );
1958
+ };
1959
+ return /* @__PURE__ */ jsx25("div", { className: wrapperBase2, children: /* @__PURE__ */ jsxs17("div", { className: cn("w-[354px] flex flex-col gap-1", className), children: [
1960
+ /* @__PURE__ */ jsxs17("div", { className: "relative w-full", children: [
1961
+ showTooltip && primary !== void 0 && renderTooltipBubble("primary", primaryPercent, formatDisplayValue(primary)),
1962
+ showTooltip && type === "multi" && secondary !== void 0 && renderTooltipBubble("secondary", secondaryPercent, formatDisplayValue(secondary)),
1963
+ /* @__PURE__ */ jsxs17(
1964
+ "div",
1965
+ {
1966
+ className: cn(
1967
+ "relative w-full flex items-center rounded-(--border-radius-4)",
1968
+ disabled ? "bg-(--background-primary-disabled) cursor-default" : "bg-(--background-secondary) cursor-pointer"
1969
+ ),
1970
+ style: { height: `${trackHeight}px` },
1971
+ ref: trackRef,
1972
+ onPointerDown: handleTrackPointerDown,
1973
+ children: [
1974
+ /* @__PURE__ */ jsx25(
1975
+ "div",
1976
+ {
1977
+ className: cn(
1978
+ "absolute h-full",
1979
+ disabled ? "bg-(--background-primary-disabled)" : "bg-(--background-secondary)"
1980
+ ),
1981
+ style: {
1982
+ width: `calc(100% + ${thumbWidth}px)`,
1983
+ left: `-${thumbRadius}px`,
1984
+ borderRadius: "var(--border-radius-4)"
1985
+ }
1986
+ }
1987
+ ),
1988
+ renderHandle(0, primaryPercent, formatDisplayValue(primary)),
1989
+ type === "multi" && secondary !== void 0 && renderHandle(1, secondaryPercent, formatDisplayValue(secondary))
1990
+ ]
1991
+ }
1992
+ )
1993
+ ] }),
1994
+ showNumeric && /* @__PURE__ */ jsx25(
1995
+ "p",
1996
+ {
1997
+ className: cn(
1998
+ "paragraph-s text-(--text-primary)",
1999
+ disabled && "text-(--text-primary-disabled)"
2000
+ ),
2001
+ style: { marginBottom: 0 },
2002
+ children: formatNumericLabel()
2003
+ }
2004
+ )
2005
+ ] }) });
2006
+ };
2007
+ Slider.displayName = "Slider";
2008
+
2009
+ // src/components/Inputs/TextArea.tsx
2010
+ import * as React24 from "react";
2011
+ import { MaximizeIcon } from "@bubo-squared/icons";
2012
+ import { jsx as jsx26, jsxs as jsxs18 } from "react/jsx-runtime";
2013
+ var wrapperBase3 = "flex flex-col gap-2 items-start min-w-[343px]";
2014
+ var TextArea = (props) => {
2015
+ const {
2016
+ label,
2017
+ hint,
2018
+ status = "default",
2019
+ type = "responsive",
2020
+ maxLength,
2021
+ disabled,
2022
+ className,
2023
+ value,
2024
+ defaultValue,
2025
+ onChange,
2026
+ rows = 3,
2027
+ ...textareaProps
2028
+ } = props;
2029
+ const isControlled = value !== void 0;
2030
+ const [internalValue, setInternalValue] = React24.useState(
2031
+ defaultValue ?? ""
2032
+ );
2033
+ const currentValue = (isControlled ? value : internalValue) ?? "";
2034
+ const hasValue = currentValue.length > 0;
2035
+ const currentLength = currentValue.length;
2036
+ const effectiveMaxLength = type === "character-limit" ? maxLength ?? 144 : void 0;
2037
+ const showCharacterLimit = type === "character-limit" && typeof effectiveMaxLength === "number";
2038
+ const textareaRef = React24.useRef(null);
2039
+ const containerRef = React24.useRef(null);
2040
+ const [height, setHeight] = React24.useState(void 0);
2041
+ const [width, setWidth] = React24.useState(void 0);
2042
+ const minHeight = 80;
2043
+ const minWidth = 240;
2044
+ const handleContainerClick = () => {
2045
+ if (disabled) return;
2046
+ textareaRef.current?.focus();
2047
+ };
2048
+ const handleChange = (event) => {
2049
+ if (!isControlled) {
2050
+ setInternalValue(event.target.value);
2051
+ }
2052
+ onChange?.(event);
2053
+ };
2054
+ const inputId = React24.useId();
2055
+ const labelId = `${inputId}-label`;
2056
+ const hintId = `${inputId}-hint`;
2057
+ const statusBorderClass = {
2058
+ default: "",
2059
+ success: "border-(--border-success)",
2060
+ error: "border-(--border-error)"
2061
+ };
2062
+ const statusFocusClass = {
2063
+ default: "focus-within:border-(--border-brand) focus-within:hover:border-(--border-brand) focus-within:shadow-[0_0_0_var(--focus-ring-spread)_var(--focus-primary)]",
2064
+ success: "focus-within:border-(--border-success) focus-within:hover:border-(--border-success) focus-within:shadow-[0_0_0_var(--focus-ring-spread)_var(--focus-success)]",
2065
+ error: "focus-within:border-(--border-error) focus-within:hover:border-(--border-error) focus-within:shadow-[0_0_0_var(--focus-ring-spread)_var(--focus-error)]"
2066
+ };
2067
+ const hintColorClass = disabled ? "text-(--text-primary-disabled)" : status === "success" ? "text-(--text-success)" : status === "error" ? "text-(--text-error)" : "text-(--text-secondary)";
2068
+ const counterColorClass = disabled ? "text-(--text-primary-disabled)" : status === "success" ? "text-(--text-success)" : status === "error" ? "text-(--text-error)" : "text-(--text-primary)";
2069
+ const handleResizePointerDown = (event) => {
2070
+ if (disabled) return;
2071
+ if (event.button !== 0) return;
2072
+ const container = containerRef.current;
2073
+ if (!container) return;
2074
+ event.preventDefault();
2075
+ const startX = event.clientX;
2076
+ const startY = event.clientY;
2077
+ const { height: startHeight, width: startWidth } = container.getBoundingClientRect();
2078
+ const handlePointerMove = (e) => {
2079
+ const deltaX = e.clientX - startX;
2080
+ const deltaY = e.clientY - startY;
2081
+ const nextHeight = Math.max(minHeight, startHeight + deltaY);
2082
+ const nextWidth = Math.max(minWidth, startWidth + deltaX);
2083
+ setHeight(nextHeight);
2084
+ setWidth(nextWidth);
2085
+ };
2086
+ const handlePointerUp = () => {
2087
+ window.removeEventListener("pointermove", handlePointerMove);
2088
+ window.removeEventListener("pointerup", handlePointerUp);
2089
+ };
2090
+ window.addEventListener("pointermove", handlePointerMove);
2091
+ window.addEventListener("pointerup", handlePointerUp);
2092
+ };
2093
+ return /* @__PURE__ */ jsxs18("div", { className: wrapperBase3, children: [
2094
+ label && /* @__PURE__ */ jsx26(
2095
+ "label",
2096
+ {
2097
+ htmlFor: inputId,
2098
+ id: labelId,
2099
+ className: cn(
2100
+ "paragraph-s",
2101
+ disabled ? "text-(--text-primary-disabled)" : "text-(--text-primary)"
2102
+ ),
2103
+ style: { marginBottom: 0 },
2104
+ children: label
2105
+ }
2106
+ ),
2107
+ /* @__PURE__ */ jsx26("div", { className: "relative w-full", children: /* @__PURE__ */ jsxs18(
2108
+ "div",
2109
+ {
2110
+ className: cn(
2111
+ "relative flex w-full rounded border bg-(--background-primary) cursor-text transition-colors",
2112
+ "border-(--border-secondary) hover:border-(--border-secondary-hover) hover:bg-(--background-primary-hover)",
2113
+ disabled && "bg-(--background-primary-disabled) border-(--border-secondary-disabled) cursor-default",
2114
+ statusBorderClass[status],
2115
+ !disabled && statusFocusClass[status],
2116
+ className
2117
+ ),
2118
+ ref: containerRef,
2119
+ style: {
2120
+ ...type === "responsive" && height !== void 0 ? { height } : {},
2121
+ ...type === "responsive" && width !== void 0 ? { width } : {}
2122
+ },
2123
+ onClick: handleContainerClick,
2124
+ "aria-disabled": disabled || void 0,
2125
+ children: [
2126
+ /* @__PURE__ */ jsx26(
2127
+ "textarea",
2128
+ {
2129
+ id: inputId,
2130
+ ref: textareaRef,
2131
+ "aria-labelledby": label ? labelId : void 0,
2132
+ "aria-describedby": hint ? hintId : void 0,
2133
+ disabled: disabled ?? void 0,
2134
+ value: isControlled ? value : currentValue,
2135
+ defaultValue: isControlled ? void 0 : defaultValue,
2136
+ onChange: handleChange,
2137
+ rows,
2138
+ maxLength: effectiveMaxLength,
2139
+ className: cn(
2140
+ "paragraph-m bg-transparent outline-none w-full h-full resize-none px-2 py-2 pr-8",
2141
+ disabled ? "text-(--text-primary-disabled)" : hasValue ? "text-(--text-primary)" : "text-(--text-secondary)",
2142
+ showCharacterLimit && "pr-16"
2143
+ ),
2144
+ style: { marginBottom: 0 },
2145
+ ...textareaProps
2146
+ }
2147
+ ),
2148
+ showCharacterLimit && /* @__PURE__ */ jsxs18(
2149
+ "span",
2150
+ {
2151
+ className: cn(
2152
+ "absolute bottom-1 right-1 footnote mb-0!",
2153
+ counterColorClass
2154
+ ),
2155
+ children: [
2156
+ currentLength,
2157
+ "/",
2158
+ effectiveMaxLength
2159
+ ]
2160
+ }
2161
+ ),
2162
+ type === "responsive" && /* @__PURE__ */ jsx26(
2163
+ "div",
2164
+ {
2165
+ className: "absolute bottom-1 right-1 h-3 w-3 " + (disabled ? "cursor-auto" : "cursor-nwse-resize"),
2166
+ onPointerDown: disabled ? void 0 : handleResizePointerDown,
2167
+ children: /* @__PURE__ */ jsx26(
2168
+ "span",
2169
+ {
2170
+ className: cn(
2171
+ "absolute bottom-0 right-0 flex h-4 w-4 items-center justify-center text-(--icon-primary)",
2172
+ disabled && "text-(--icon-primary-disabled)"
2173
+ ),
2174
+ children: /* @__PURE__ */ jsx26(MaximizeIcon, {})
2175
+ }
2176
+ )
2177
+ }
2178
+ )
2179
+ ]
2180
+ }
2181
+ ) }),
2182
+ /* @__PURE__ */ jsx26(
2183
+ "p",
2184
+ {
2185
+ id: hint ? hintId : void 0,
2186
+ className: cn("caption", hint ? hintColorClass : "invisible"),
2187
+ style: { marginBottom: 0 },
2188
+ children: hint || "\xA0"
2189
+ }
2190
+ )
2191
+ ] });
2192
+ };
2193
+ TextArea.displayName = "TextArea";
2194
+
2195
+ // src/components/Inputs/TextInput.tsx
2196
+ import * as React25 from "react";
2197
+ import { cva as cva16 } from "class-variance-authority";
2198
+ import { jsx as jsx27, jsxs as jsxs19 } from "react/jsx-runtime";
2199
+ var inputTextVariants = cva16("truncate", {
2200
+ variants: {
2201
+ size: {
2202
+ large: "subtitle",
2203
+ "extra-large": "h6-title"
2204
+ }
2205
+ },
2206
+ defaultVariants: {
2207
+ size: "large"
2208
+ }
2209
+ });
2210
+ var iconWrapperVariants3 = cva16(
2211
+ "flex items-center justify-center shrink-0 text-(--icon-primary)",
2212
+ {
2213
+ variants: {
2214
+ size: {
2215
+ large: "w-5 h-5 [&>svg]:w-5 [&>svg]:h-5",
2216
+ "extra-large": "w-6 h-6 [&>svg]:w-6 [&>svg]:h-6"
2217
+ },
2218
+ disabled: {
2219
+ true: "text-(--icon-primary-disabled)"
2220
+ }
2221
+ },
2222
+ defaultVariants: {
2223
+ size: "large"
2224
+ }
2225
+ }
2226
+ );
2227
+ var TextInput = (props) => {
2228
+ const {
2229
+ label,
2230
+ hint,
2231
+ placeholder = "Placeholder text",
2232
+ size = "large",
2233
+ status = "default",
2234
+ disabled = false,
2235
+ className,
2236
+ leadingIcon,
2237
+ trailingIcon,
2238
+ value,
2239
+ defaultValue,
2240
+ onChange,
2241
+ ...inputProps
2242
+ } = props;
2243
+ const isControlled = value !== void 0;
2244
+ const [internalValue, setInternalValue] = React25.useState(
2245
+ defaultValue ?? ""
2246
+ );
2247
+ const currentValue = (isControlled ? value : internalValue) ?? "";
2248
+ const inputRef = React25.useRef(null);
2249
+ const handleContainerClick = () => {
2250
+ if (disabled) return;
2251
+ inputRef.current?.focus();
2252
+ };
2253
+ const handleChange = (event) => {
2254
+ if (!isControlled) {
2255
+ setInternalValue(event.target.value);
2256
+ }
2257
+ onChange?.(event);
2258
+ };
2259
+ const showLeadingIcon = !!leadingIcon;
2260
+ const showTrailingIcon = !!trailingIcon;
2261
+ return /* @__PURE__ */ jsx27(
2262
+ Field,
2263
+ {
2264
+ label,
2265
+ hint,
2266
+ status,
2267
+ disabled,
2268
+ children: /* @__PURE__ */ jsxs19(
2269
+ InputShell,
2270
+ {
2271
+ size,
2272
+ status,
2273
+ disabled,
2274
+ className,
2275
+ onClick: handleContainerClick,
2276
+ children: [
2277
+ showLeadingIcon && /* @__PURE__ */ jsx27(
2278
+ "span",
2279
+ {
2280
+ className: cn(
2281
+ iconWrapperVariants3({ size, disabled })
2282
+ ),
2283
+ children: leadingIcon
2284
+ }
2285
+ ),
2286
+ /* @__PURE__ */ jsx27(
2287
+ Input,
2288
+ {
2289
+ ref: inputRef,
2290
+ type: "text",
2291
+ disabled: disabled ?? void 0,
2292
+ placeholder,
2293
+ value: isControlled ? value : currentValue,
2294
+ defaultValue: isControlled ? void 0 : defaultValue,
2295
+ onChange: handleChange,
2296
+ variant: "bare",
2297
+ className: cn(
2298
+ inputTextVariants({ size }),
2299
+ "bg-transparent outline-none w-full"
2300
+ ),
2301
+ style: { marginBottom: 0 },
2302
+ ...inputProps
2303
+ }
2304
+ ),
2305
+ showTrailingIcon && /* @__PURE__ */ jsx27(
2306
+ "span",
2307
+ {
2308
+ className: cn(
2309
+ iconWrapperVariants3({ size, disabled: !!disabled })
2310
+ ),
2311
+ children: trailingIcon
2312
+ }
2313
+ )
2314
+ ]
2315
+ }
2316
+ )
2317
+ }
2318
+ );
2319
+ };
2320
+ TextInput.displayName = "TextInput";
2321
+
2322
+ // src/components/Inputs/Toggle.tsx
2323
+ import "react";
2324
+ import { jsx as jsx28, jsxs as jsxs20 } from "react/jsx-runtime";
2325
+ var Toggle = (props) => {
2326
+ const { label, className, disabled, ...inputProps } = props;
2327
+ return /* @__PURE__ */ jsxs20(
2328
+ "label",
2329
+ {
2330
+ className: cn(
2331
+ "inline-flex items-center gap-2 select-none",
2332
+ disabled ? "cursor-default" : "cursor-pointer"
2333
+ ),
2334
+ children: [
2335
+ /* @__PURE__ */ jsxs20("span", { className: "relative inline-flex items-center", children: [
2336
+ /* @__PURE__ */ jsx28(
2337
+ "input",
2338
+ {
2339
+ type: "checkbox",
2340
+ disabled,
2341
+ className: "peer sr-only",
2342
+ ...inputProps
2343
+ }
2344
+ ),
2345
+ /* @__PURE__ */ jsx28(
2346
+ "span",
2347
+ {
2348
+ className: cn(
2349
+ // Base track
2350
+ "flex items-center w-9 h-5 rounded-3xl border bg-(--background-primary) p-(--space-2) transition-all",
2351
+ // Knob position
2352
+ "justify-start peer-checked:justify-end",
2353
+ // 1: enabled, unchecked, unhovered, unfocused
2354
+ "border-(--border-secondary)",
2355
+ // 3: enabled, unchecked, hovered, unfocused
2356
+ "hover:border-(--border-secondary-hover)",
2357
+ // 2: enabled, checked, unhovered, unfocused
2358
+ "peer-checked:border-(--border-brand)",
2359
+ // 4: enabled, checked, hovered, unfocused
2360
+ "peer-checked:hover:border-(--border-brand-hover)",
2361
+ "peer-checked:hover:shadow-[0_0_0_var(--focus-ring-spread)_var(--color-b-100)]",
2362
+ // 5: enabled, unchecked, unhovered, focused
2363
+ "peer-focus-visible:border-(--border-brand-focus)",
2364
+ // 6: enabled, checked, unhovered, focused
2365
+ "peer-checked:peer-focus-visible:bg-(--background-brand-focus)",
2366
+ "peer-checked:peer-focus-visible:shadow-[0_0_0_var(--focus-ring-spread)_var(--focus-primary)]",
2367
+ // 7: disabled, unchecked (override)
2368
+ "peer-disabled:bg-(--background-primary-disabled)",
2369
+ "peer-disabled:border-none",
2370
+ "peer-disabled:shadow-none",
2371
+ // 8: disabled, checked (override)
2372
+ "peer-disabled:peer-checked:border-(--border-primary-disabled)",
2373
+ // Disable hover when disabled
2374
+ "peer-disabled:pointer-events-none",
2375
+ // Knob on (enabled)
2376
+ "peer-checked:[&>.knob]:bg-(--background-brand)",
2377
+ // Hover / focus when on
2378
+ "peer-checked:[&>.knob]:hover:bg-(--background-brand-hover)",
2379
+ "peer-checked:peer-focus-visible:[&>.knob]:bg-(--background-neutral)",
2380
+ // Disabled knob (both off and on use disabled brand token)
2381
+ "peer-disabled:[&>.knob]:bg-(--background-primary-hover)",
2382
+ "peer-disabled:[&>.knob]:peer-checked:bg-(--background-primary-hover)",
2383
+ className
2384
+ ),
2385
+ children: /* @__PURE__ */ jsx28(
2386
+ "span",
2387
+ {
2388
+ className: cn(
2389
+ "h-4 w-4 rounded-full transition-colors knob",
2390
+ "bg-b-100"
2391
+ )
2392
+ }
2393
+ )
2394
+ }
2395
+ )
2396
+ ] }),
2397
+ label && /* @__PURE__ */ jsx28(
2398
+ "span",
2399
+ {
2400
+ className: cn(
2401
+ "paragraph-s text-(--text-primary)",
2402
+ disabled && "text-(--text-primary-disabled)"
2403
+ ),
2404
+ style: { marginBottom: 0 },
2405
+ children: label
2406
+ }
2407
+ )
2408
+ ]
2409
+ }
2410
+ );
2411
+ };
2412
+ Toggle.displayName = "Toggle";
2413
+
2414
+ // src/components/Inputs/WebsiteInput.tsx
2415
+ import "react";
2416
+ import { jsx as jsx29, jsxs as jsxs21 } from "react/jsx-runtime";
2417
+ var WebsiteInput = (props) => {
2418
+ const {
2419
+ hierarchy = "prefix",
2420
+ protocolLabel = "http://",
2421
+ icon,
2422
+ size = "large",
2423
+ disabled,
2424
+ className,
2425
+ ...rest
2426
+ } = props;
2427
+ const isPrefix = hierarchy === "prefix";
2428
+ const baseClass = cn(
2429
+ "[&>span]:w-[unset] hover:bg-[unset]",
2430
+ !disabled && "[&:not(:focus-within):hover]:shadow-[0_0_0_var(--focus-ring-spread)_var(--background-secondary-hover)]",
2431
+ disabled && "bg-[unset] hover:shadow-none hover:border-(--border-secondary-disabled) border-(--border-secondary-disabled)",
2432
+ size === "extra-large" ? "[&>span]:h-14!" : "[&>span]:h-11!"
2433
+ );
2434
+ const addonTextClass = cn(
2435
+ "flex mb-0!",
2436
+ size === "extra-large" ? "paragraph-m" : "paragraph-s",
2437
+ disabled ? "text-(--text-primary-disabled)" : "text-(--text-primary) group-hover:text-(--text-primary-hover) group-focus-within:text-(--text-primary-focus)"
2438
+ );
2439
+ const baseAddonClass = cn(
2440
+ "flex items-center gap-2 px-2 h-full",
2441
+ // layout + padding
2442
+ "border-(--border-secondary)",
2443
+ // divider color
2444
+ disabled && "border-(--border-secondary-disabled) hover:border-(--border-secondary-disabled)",
2445
+ isPrefix ? "border-r" : "border-l"
2446
+ );
2447
+ const iconWrapperClass = cn(
2448
+ "flex items-center justify-center shrink-0",
2449
+ size === "extra-large" ? "[&>svg]:w-6 [&>svg]:h-6" : "[&>svg]:w-5 [&>svg]:h-5",
2450
+ disabled ? "text-(--icon-primary-disabled)" : "text-(--icon-primary) group-hover:text-(--icon-primary-hover) group-focus-within:text-(--icon-primary-focus)"
2451
+ );
2452
+ const prefixAddon = /* @__PURE__ */ jsxs21("div", { className: baseAddonClass, children: [
2453
+ /* @__PURE__ */ jsx29("div", { className: addonTextClass, children: protocolLabel }),
2454
+ icon != null && /* @__PURE__ */ jsx29("span", { className: iconWrapperClass, children: icon })
2455
+ ] });
2456
+ const suffixAddon = /* @__PURE__ */ jsxs21("div", { className: baseAddonClass, children: [
2457
+ icon != null && /* @__PURE__ */ jsx29("span", { className: iconWrapperClass, children: icon }),
2458
+ /* @__PURE__ */ jsx29("div", { className: addonTextClass, children: protocolLabel })
2459
+ ] });
2460
+ return /* @__PURE__ */ jsx29(
2461
+ TextInput,
2462
+ {
2463
+ ...rest,
2464
+ size,
2465
+ disabled,
2466
+ className: cn(baseClass, className),
2467
+ leadingIcon: isPrefix ? prefixAddon : void 0,
2468
+ trailingIcon: !isPrefix ? suffixAddon : void 0
2469
+ }
2470
+ );
2471
+ };
2472
+ WebsiteInput.displayName = "WebsiteInput";
2473
+
2474
+ // src/components/Logo/LogoIconExtraLarge.tsx
2475
+ import { LogoIconLIcon } from "@bubo-squared/icons";
2476
+ import { jsx as jsx30 } from "react/jsx-runtime";
2477
+ var LogoIconExtraLarge = () => {
2478
+ return /* @__PURE__ */ jsx30("div", { className: "w-lg h-[512px] relative bg-linear-to-t from-gray-800 to-gray-950 rounded-[80px] overflow-hidden flex justify-center items-center", children: /* @__PURE__ */ jsx30(LogoIconLIcon, { className: "w-96 h-96" }) });
2479
+ };
2480
+ var LogoIconExtraLarge_default = LogoIconExtraLarge;
2481
+
2482
+ // src/components/Logo/LogoIconExtraSmall.tsx
2483
+ import { LogoIconMIcon } from "@bubo-squared/icons";
2484
+ import { jsx as jsx31 } from "react/jsx-runtime";
2485
+ var LogoIconExtraSmall = () => {
2486
+ return /* @__PURE__ */ jsx31("div", { className: "w-8 h-8 relative bg-linear-to-t from-gray-800 to-gray-950 rounded-[5px] overflow-hidden flex justify-center items-center", children: /* @__PURE__ */ jsx31(LogoIconMIcon, { className: "w-6 h-6" }) });
2487
+ };
2488
+ var LogoIconExtraSmall_default = LogoIconExtraSmall;
2489
+
2490
+ // src/components/Logo/LogoIconLarge.tsx
2491
+ import { LogoIconMIcon as LogoIconMIcon2 } from "@bubo-squared/icons";
2492
+ import { jsx as jsx32 } from "react/jsx-runtime";
2493
+ var LogoIconLarge = () => {
2494
+ return /* @__PURE__ */ jsx32("div", { className: "w-64 h-64 relative bg-linear-to-t from-gray-800 to-gray-950 rounded-[40px] overflow-hidden flex justify-center items-center", children: /* @__PURE__ */ jsx32(LogoIconMIcon2, { className: "w-44 h-44" }) });
2495
+ };
2496
+ var LogoIconLarge_default = LogoIconLarge;
2497
+
2498
+ // src/components/Logo/LogoIconMedium.tsx
2499
+ import { LogoIconMIcon as LogoIconMIcon3 } from "@bubo-squared/icons";
2500
+ import { jsx as jsx33 } from "react/jsx-runtime";
2501
+ var LogoIconMedium = () => {
2502
+ return /* @__PURE__ */ jsx33("div", { className: "w-32 h-32 relative bg-linear-to-t from-gray-800 to-gray-950 rounded-[20px] overflow-hidden flex justify-center items-center", children: /* @__PURE__ */ jsx33(LogoIconMIcon3, { className: "w-24 h-24" }) });
2503
+ };
2504
+ var LogoIconMedium_default = LogoIconMedium;
2505
+
2506
+ // src/components/Logo/LogoIconSmall.tsx
2507
+ import { LogoIconMIcon as LogoIconMIcon4 } from "@bubo-squared/icons";
2508
+ import { jsx as jsx34 } from "react/jsx-runtime";
2509
+ var LogoIconSmall = () => {
2510
+ return /* @__PURE__ */ jsx34("div", { className: "w-14 h-14 relative bg-linear-to-t from-gray-800 to-gray-950 rounded-lg overflow-hidden flex justify-center items-center", children: /* @__PURE__ */ jsx34(LogoIconMIcon4, { className: "w-10 h-10" }) });
2511
+ };
2512
+ var LogoIconSmall_default = LogoIconSmall;
2513
+
2514
+ // src/components/Logo/LogoInline.tsx
2515
+ import { LogoIconMIcon as LogoIconMIcon5, LogoTextMIcon } from "@bubo-squared/icons";
2516
+ import { jsx as jsx35, jsxs as jsxs22 } from "react/jsx-runtime";
2517
+ var LogoInline = () => {
2518
+ return /* @__PURE__ */ jsxs22("div", { className: "w-44 h-12 inline-flex justify-start items-center gap-4", children: [
2519
+ /* @__PURE__ */ jsx35(LogoIconMIcon5, { className: "w-12 h-12" }),
2520
+ /* @__PURE__ */ jsx35(LogoTextMIcon, { className: "h-8 w-[110px] text-(--text-primary)" })
2521
+ ] });
2522
+ };
2523
+ var LogoInline_default = LogoInline;
2524
+
2525
+ // src/components/Logo/LogoInlineSmall.tsx
2526
+ import { LogoIconMIcon as LogoIconMIcon6, LogoTextMIcon as LogoTextMIcon2 } from "@bubo-squared/icons";
2527
+ import { jsx as jsx36, jsxs as jsxs23 } from "react/jsx-runtime";
2528
+ var LogoInline2 = () => {
2529
+ return /* @__PURE__ */ jsxs23("div", { className: "w-32 h-9 inline-flex justify-start items-center gap-3", children: [
2530
+ /* @__PURE__ */ jsx36(LogoIconMIcon6, { className: "w-9 h-9" }),
2531
+ /* @__PURE__ */ jsx36(LogoTextMIcon2, { className: "h-6 w-[83px] text-(--text-primary)" })
2532
+ ] });
2533
+ };
2534
+ var LogoInlineSmall_default = LogoInline2;
2535
+
2536
+ // src/components/Logo/LogoMultiline.tsx
2537
+ import { LogoIconMIcon as LogoIconMIcon7, LogoTextMIcon as LogoTextMIcon3 } from "@bubo-squared/icons";
2538
+ import { jsx as jsx37, jsxs as jsxs24 } from "react/jsx-runtime";
2539
+ var LogoMultiline = () => {
2540
+ return /* @__PURE__ */ jsxs24("div", { className: "w-36 inline-flex flex-col justify-start items-start gap-2", children: [
2541
+ /* @__PURE__ */ jsx37(LogoIconMIcon7, { className: "w-12 h-12" }),
2542
+ /* @__PURE__ */ jsx37(LogoTextMIcon3, { className: "h-8 w-[111px] text-(--text-primary)" })
2543
+ ] });
2544
+ };
2545
+ var LogoMultiline_default = LogoMultiline;
2546
+ export {
2547
+ Avatar,
2548
+ Badge,
2549
+ BadgeDigit,
2550
+ BadgeDot,
2551
+ BadgeStatus,
2552
+ Button,
2553
+ ButtonGroup,
2554
+ Checkbox,
2555
+ Divider,
2556
+ Dropdown,
2557
+ IconButton,
2558
+ IconButtonGroup,
2559
+ LinkButton,
2560
+ LogoIconExtraLarge_default as LogoIconExtraLarge,
2561
+ LogoIconExtraSmall_default as LogoIconExtraSmall,
2562
+ LogoIconLarge_default as LogoIconLarge,
2563
+ LogoIconMedium_default as LogoIconMedium,
2564
+ LogoIconSmall_default as LogoIconSmall,
2565
+ LogoInline_default as LogoInline,
2566
+ LogoInlineSmall_default as LogoInlineSmall,
2567
+ LogoMultiline_default as LogoMultiline,
2568
+ MessageButton,
2569
+ PasswordInput,
2570
+ Progress,
2571
+ RadioGroup,
2572
+ SearchInput,
2573
+ Slider,
2574
+ StatusAvatar,
2575
+ Tag,
2576
+ TextArea,
2577
+ TextInput,
2578
+ Toggle,
2579
+ WebsiteInput,
2580
+ cn
2581
+ };
2582
+ //# sourceMappingURL=index.js.map