@codecrib/ui 0.0.7 → 0.0.9
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 +408 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +32 -1
- package/dist/index.d.ts +32 -1
- package/dist/index.js +406 -5
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -36,6 +36,8 @@ __export(index_exports, {
|
|
|
36
36
|
Countdown: () => Countdown,
|
|
37
37
|
Icon: () => Icon,
|
|
38
38
|
Input: () => Input,
|
|
39
|
+
Select: () => Select,
|
|
40
|
+
Tag: () => Tag,
|
|
39
41
|
cn: () => cn
|
|
40
42
|
});
|
|
41
43
|
module.exports = __toCommonJS(index_exports);
|
|
@@ -156,6 +158,21 @@ Button.displayName = "Button";
|
|
|
156
158
|
|
|
157
159
|
// src/components/Card/Card.tsx
|
|
158
160
|
var React2 = __toESM(require("react"), 1);
|
|
161
|
+
|
|
162
|
+
// src/styles/borders.ts
|
|
163
|
+
var radius = {
|
|
164
|
+
default: "rounded-lg",
|
|
165
|
+
pill: "rounded-full"
|
|
166
|
+
};
|
|
167
|
+
var border = {
|
|
168
|
+
base: "border",
|
|
169
|
+
color: "border-gray-300",
|
|
170
|
+
focus: "focus:border-primary-500 focus:ring-primary-500",
|
|
171
|
+
ring: "focus:outline-none focus:ring-2 focus:ring-offset-0"
|
|
172
|
+
};
|
|
173
|
+
var input = `${border.base} ${border.color}`;
|
|
174
|
+
|
|
175
|
+
// src/components/Card/Card.tsx
|
|
159
176
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
160
177
|
var variantStyles2 = {
|
|
161
178
|
default: "bg-white",
|
|
@@ -168,7 +185,7 @@ var Card = React2.forwardRef(
|
|
|
168
185
|
"div",
|
|
169
186
|
{
|
|
170
187
|
ref,
|
|
171
|
-
className: cn("
|
|
188
|
+
className: cn(radius.default, "p-6", variantStyles2[variant], className),
|
|
172
189
|
...props,
|
|
173
190
|
children
|
|
174
191
|
}
|
|
@@ -230,8 +247,10 @@ var Input = React3.forwardRef(
|
|
|
230
247
|
id: inputId,
|
|
231
248
|
ref,
|
|
232
249
|
className: cn(
|
|
233
|
-
"block w-full
|
|
234
|
-
|
|
250
|
+
"block w-full px-4 py-2 text-gray-900 placeholder:text-gray-400 transition-colors",
|
|
251
|
+
radius.default,
|
|
252
|
+
border.base,
|
|
253
|
+
error ? "border-red-500 focus:border-red-500 focus:ring-red-500" : `${border.color} ${border.focus} ${border.ring}`,
|
|
235
254
|
className
|
|
236
255
|
),
|
|
237
256
|
...props
|
|
@@ -326,7 +345,7 @@ function formatRemaining(ms) {
|
|
|
326
345
|
var Countdown = React6.forwardRef(
|
|
327
346
|
({ deadline, onComplete, className, variant = "primary", size = "md", ...props }, ref) => {
|
|
328
347
|
const target = React6.useMemo(() => parseDeadline(deadline), [deadline]);
|
|
329
|
-
const
|
|
348
|
+
const variantStyles5 = {
|
|
330
349
|
primary: "bg-primary-600 text-white",
|
|
331
350
|
secondary: "bg-secondary-600 text-white",
|
|
332
351
|
outline: "border-2 border-primary-600 text-primary-600 bg-transparent",
|
|
@@ -355,7 +374,7 @@ var Countdown = React6.forwardRef(
|
|
|
355
374
|
const remaining = formatRemaining(target - now);
|
|
356
375
|
const appliedVariant = expired ? "expired" : variant;
|
|
357
376
|
const expiredClass = variant === "ghost" ? "text-red-600 bg-transparent" : variant === "outline" ? "border-2 border-red-600 text-red-600 bg-transparent" : "bg-red-600 text-white";
|
|
358
|
-
const variantClass = expired ? expiredClass :
|
|
377
|
+
const variantClass = expired ? expiredClass : variantStyles5[variant];
|
|
359
378
|
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
360
379
|
"div",
|
|
361
380
|
{
|
|
@@ -373,6 +392,388 @@ var Countdown = React6.forwardRef(
|
|
|
373
392
|
}
|
|
374
393
|
);
|
|
375
394
|
Countdown.displayName = "Countdown";
|
|
395
|
+
|
|
396
|
+
// src/components/Tag/Tag.tsx
|
|
397
|
+
var React7 = __toESM(require("react"), 1);
|
|
398
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
399
|
+
var variantStyles4 = {
|
|
400
|
+
default: "bg-gray-100 text-gray-800",
|
|
401
|
+
success: "bg-green-100 text-green-800",
|
|
402
|
+
warning: "bg-yellow-100 text-yellow-800",
|
|
403
|
+
error: "bg-red-100 text-red-800",
|
|
404
|
+
info: "bg-blue-100 text-blue-800"
|
|
405
|
+
};
|
|
406
|
+
var sizeStyles3 = {
|
|
407
|
+
sm: "px-2 py-0.5 text-xs",
|
|
408
|
+
md: "px-2.5 py-1 text-sm",
|
|
409
|
+
lg: "px-3 py-1.5 text-base"
|
|
410
|
+
};
|
|
411
|
+
var Tag = React7.forwardRef(
|
|
412
|
+
({
|
|
413
|
+
className,
|
|
414
|
+
variant = "default",
|
|
415
|
+
size = "md",
|
|
416
|
+
removable = false,
|
|
417
|
+
onRemove,
|
|
418
|
+
removeLabel = "Remove",
|
|
419
|
+
children,
|
|
420
|
+
...props
|
|
421
|
+
}, ref) => {
|
|
422
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
423
|
+
"span",
|
|
424
|
+
{
|
|
425
|
+
ref,
|
|
426
|
+
className: cn(
|
|
427
|
+
"inline-flex items-center font-medium",
|
|
428
|
+
radius.pill,
|
|
429
|
+
variantStyles4[variant],
|
|
430
|
+
sizeStyles3[size],
|
|
431
|
+
className
|
|
432
|
+
),
|
|
433
|
+
...props,
|
|
434
|
+
children: [
|
|
435
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children }),
|
|
436
|
+
removable && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
437
|
+
"button",
|
|
438
|
+
{
|
|
439
|
+
type: "button",
|
|
440
|
+
"aria-label": removeLabel,
|
|
441
|
+
onClick: onRemove,
|
|
442
|
+
className: cn(
|
|
443
|
+
"ml-2 inline-flex items-center justify-center",
|
|
444
|
+
radius.pill,
|
|
445
|
+
border.ring,
|
|
446
|
+
size === "sm" ? "h-4 w-4" : size === "md" ? "h-5 w-5" : "h-6 w-6"
|
|
447
|
+
),
|
|
448
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
449
|
+
"svg",
|
|
450
|
+
{
|
|
451
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
452
|
+
viewBox: "0 0 24 24",
|
|
453
|
+
fill: "none",
|
|
454
|
+
stroke: "currentColor",
|
|
455
|
+
strokeWidth: 2,
|
|
456
|
+
className: cn(size === "sm" ? "h-3 w-3" : size === "md" ? "h-4 w-4" : "h-5 w-5"),
|
|
457
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M6 18L18 6M6 6l12 12" })
|
|
458
|
+
}
|
|
459
|
+
)
|
|
460
|
+
}
|
|
461
|
+
)
|
|
462
|
+
]
|
|
463
|
+
}
|
|
464
|
+
);
|
|
465
|
+
}
|
|
466
|
+
);
|
|
467
|
+
Tag.displayName = "Tag";
|
|
468
|
+
|
|
469
|
+
// src/components/Select/Select.tsx
|
|
470
|
+
var React8 = __toESM(require("react"), 1);
|
|
471
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
472
|
+
var Select = ({
|
|
473
|
+
items,
|
|
474
|
+
placeholder = "Select...",
|
|
475
|
+
multiselect = false,
|
|
476
|
+
multiline = false,
|
|
477
|
+
value,
|
|
478
|
+
onChange,
|
|
479
|
+
className
|
|
480
|
+
}) => {
|
|
481
|
+
const [open, setOpen] = React8.useState(false);
|
|
482
|
+
const [internalValue, setInternalValue] = React8.useState(
|
|
483
|
+
Array.isArray(value) ? value : value ? [value] : []
|
|
484
|
+
);
|
|
485
|
+
React8.useEffect(() => {
|
|
486
|
+
if (value !== void 0) {
|
|
487
|
+
setInternalValue(Array.isArray(value) ? value : value ? [value] : []);
|
|
488
|
+
}
|
|
489
|
+
}, [value]);
|
|
490
|
+
React8.useEffect(() => {
|
|
491
|
+
lastEmittedRef.current = null;
|
|
492
|
+
}, [value, multiselect]);
|
|
493
|
+
const containerRef = React8.useRef(null);
|
|
494
|
+
React8.useEffect(() => {
|
|
495
|
+
const onDoc = (e) => {
|
|
496
|
+
if (!containerRef.current) return;
|
|
497
|
+
if (!containerRef.current.contains(e.target)) setOpen(false);
|
|
498
|
+
};
|
|
499
|
+
document.addEventListener("mousedown", onDoc);
|
|
500
|
+
return () => document.removeEventListener("mousedown", onDoc);
|
|
501
|
+
}, []);
|
|
502
|
+
const isSelected = (v) => internalValue.includes(v);
|
|
503
|
+
const lastEmittedRef = React8.useRef(null);
|
|
504
|
+
const emitChange = (next) => {
|
|
505
|
+
const payload = multiselect ? JSON.stringify(next) : next[0] || "";
|
|
506
|
+
if (lastEmittedRef.current === payload) return;
|
|
507
|
+
lastEmittedRef.current = payload;
|
|
508
|
+
if (onChange) onChange(multiselect ? next : next[0] || "");
|
|
509
|
+
};
|
|
510
|
+
const toggleSelect = (v) => {
|
|
511
|
+
let next;
|
|
512
|
+
if (multiselect) {
|
|
513
|
+
next = isSelected(v) ? internalValue.filter((x) => x !== v) : [...internalValue, v];
|
|
514
|
+
} else {
|
|
515
|
+
next = isSelected(v) ? [] : [v];
|
|
516
|
+
setOpen(false);
|
|
517
|
+
}
|
|
518
|
+
emitChange(next);
|
|
519
|
+
if (value === void 0) setInternalValue(next);
|
|
520
|
+
};
|
|
521
|
+
const removeValue = (v) => {
|
|
522
|
+
const next = internalValue.filter((x) => x !== v);
|
|
523
|
+
emitChange(next);
|
|
524
|
+
if (value === void 0) setInternalValue(next);
|
|
525
|
+
};
|
|
526
|
+
const selectedItemsMap = React8.useMemo(() => {
|
|
527
|
+
const map = /* @__PURE__ */ new Map();
|
|
528
|
+
const collect = (src) => {
|
|
529
|
+
src.forEach((s) => {
|
|
530
|
+
if ("items" in s) s.items.forEach((it) => map.set(it.value, it));
|
|
531
|
+
else map.set(s.value, s);
|
|
532
|
+
});
|
|
533
|
+
};
|
|
534
|
+
collect(items);
|
|
535
|
+
return map;
|
|
536
|
+
}, [items]);
|
|
537
|
+
const tagsContainerRef = React8.useRef(null);
|
|
538
|
+
const [visibleCount, setVisibleCount] = React8.useState(null);
|
|
539
|
+
React8.useEffect(() => {
|
|
540
|
+
if (multiline) {
|
|
541
|
+
setVisibleCount(null);
|
|
542
|
+
return;
|
|
543
|
+
}
|
|
544
|
+
let raf;
|
|
545
|
+
let timeout;
|
|
546
|
+
const measure = () => {
|
|
547
|
+
if (raf) cancelAnimationFrame(raf);
|
|
548
|
+
raf = requestAnimationFrame(() => {
|
|
549
|
+
const container = tagsContainerRef.current;
|
|
550
|
+
if (!container) {
|
|
551
|
+
setVisibleCount(null);
|
|
552
|
+
return;
|
|
553
|
+
}
|
|
554
|
+
const containerWidth = container.clientWidth;
|
|
555
|
+
if (containerWidth === 0) {
|
|
556
|
+
setVisibleCount(null);
|
|
557
|
+
return;
|
|
558
|
+
}
|
|
559
|
+
const tagEls = Array.from(
|
|
560
|
+
container.querySelectorAll('[data-role="select-tag"]')
|
|
561
|
+
);
|
|
562
|
+
if (!tagEls.length) {
|
|
563
|
+
setVisibleCount(null);
|
|
564
|
+
return;
|
|
565
|
+
}
|
|
566
|
+
const badgeEl = container.querySelector('[data-role="count-badge"]');
|
|
567
|
+
const containerStyle = window.getComputedStyle(container);
|
|
568
|
+
const gap = parseFloat(containerStyle.gap || containerStyle.columnGap || "0") || 0;
|
|
569
|
+
const tagWidths = tagEls.map((el) => el.offsetWidth);
|
|
570
|
+
let totalWidthAllTags = 0;
|
|
571
|
+
for (const [i, w] of tagWidths.entries()) {
|
|
572
|
+
totalWidthAllTags += w + (i > 0 ? gap : 0);
|
|
573
|
+
}
|
|
574
|
+
if (totalWidthAllTags <= containerWidth) {
|
|
575
|
+
setVisibleCount(tagEls.length);
|
|
576
|
+
return;
|
|
577
|
+
}
|
|
578
|
+
let badgeWidth = badgeEl ? badgeEl.offsetWidth : 40;
|
|
579
|
+
let usedWidth = 0;
|
|
580
|
+
let fitCount = 0;
|
|
581
|
+
for (const [i, tagWidth] of tagWidths.entries()) {
|
|
582
|
+
const gapBeforeTag = i > 0 ? gap : 0;
|
|
583
|
+
const gapBeforeBadge = gap;
|
|
584
|
+
const effectiveTagWidth = tagWidth ?? 0;
|
|
585
|
+
const spaceNeeded = usedWidth + gapBeforeTag + effectiveTagWidth + gapBeforeBadge + badgeWidth;
|
|
586
|
+
if (spaceNeeded <= containerWidth) {
|
|
587
|
+
usedWidth += gapBeforeTag + effectiveTagWidth;
|
|
588
|
+
fitCount = i + 1;
|
|
589
|
+
} else {
|
|
590
|
+
break;
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
fitCount = Math.max(1, fitCount);
|
|
594
|
+
setVisibleCount(fitCount);
|
|
595
|
+
});
|
|
596
|
+
};
|
|
597
|
+
measure();
|
|
598
|
+
const onResize = () => {
|
|
599
|
+
if (timeout) clearTimeout(timeout);
|
|
600
|
+
timeout = window.setTimeout(measure, 50);
|
|
601
|
+
};
|
|
602
|
+
window.addEventListener("resize", onResize);
|
|
603
|
+
let ro;
|
|
604
|
+
if (typeof ResizeObserver !== "undefined" && tagsContainerRef.current) {
|
|
605
|
+
ro = new ResizeObserver(onResize);
|
|
606
|
+
ro.observe(tagsContainerRef.current);
|
|
607
|
+
}
|
|
608
|
+
return () => {
|
|
609
|
+
if (raf) cancelAnimationFrame(raf);
|
|
610
|
+
if (timeout) clearTimeout(timeout);
|
|
611
|
+
window.removeEventListener("resize", onResize);
|
|
612
|
+
ro?.disconnect();
|
|
613
|
+
};
|
|
614
|
+
}, [internalValue, multiline]);
|
|
615
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { ref: containerRef, className: cn("relative inline-block w-full", className), children: [
|
|
616
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "flex items-center", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
617
|
+
"div",
|
|
618
|
+
{
|
|
619
|
+
role: "combobox",
|
|
620
|
+
tabIndex: 0,
|
|
621
|
+
"aria-expanded": open,
|
|
622
|
+
onClick: () => setOpen((s) => !s),
|
|
623
|
+
onKeyDown: (e) => {
|
|
624
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
625
|
+
e.preventDefault();
|
|
626
|
+
setOpen((s) => !s);
|
|
627
|
+
}
|
|
628
|
+
if (e.key === "Escape") setOpen(false);
|
|
629
|
+
},
|
|
630
|
+
className: cn(
|
|
631
|
+
"w-full inline-flex items-center justify-between rounded-lg border bg-white px-4 py-2 text-gray-900 text-left cursor-pointer focus:outline-none focus:ring-2 focus:ring-primary-500",
|
|
632
|
+
multiselect ? "" : "",
|
|
633
|
+
open ? "ring-1 ring-gray-300" : ""
|
|
634
|
+
),
|
|
635
|
+
children: [
|
|
636
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "flex-1", children: multiselect && internalValue.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
637
|
+
"span",
|
|
638
|
+
{
|
|
639
|
+
ref: tagsContainerRef,
|
|
640
|
+
className: cn(
|
|
641
|
+
"relative flex gap-1 items-center",
|
|
642
|
+
multiline ? "flex-wrap" : "overflow-hidden whitespace-nowrap"
|
|
643
|
+
),
|
|
644
|
+
children: [
|
|
645
|
+
internalValue.map((v, index) => {
|
|
646
|
+
const isHidden = !multiline && visibleCount !== null && index >= visibleCount;
|
|
647
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
648
|
+
"span",
|
|
649
|
+
{
|
|
650
|
+
"data-role": "select-tag",
|
|
651
|
+
className: cn(
|
|
652
|
+
"flex-shrink-0 inline-block",
|
|
653
|
+
isHidden && "invisible absolute pointer-events-none"
|
|
654
|
+
),
|
|
655
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
656
|
+
Tag,
|
|
657
|
+
{
|
|
658
|
+
size: "sm",
|
|
659
|
+
removable: true,
|
|
660
|
+
removeLabel: `Remove ${selectedItemsMap.get(v)?.label ?? v}`,
|
|
661
|
+
onRemove: (e) => {
|
|
662
|
+
e.stopPropagation();
|
|
663
|
+
removeValue(v);
|
|
664
|
+
},
|
|
665
|
+
children: selectedItemsMap.get(v)?.label ?? v
|
|
666
|
+
}
|
|
667
|
+
)
|
|
668
|
+
},
|
|
669
|
+
v
|
|
670
|
+
);
|
|
671
|
+
}),
|
|
672
|
+
!multiline && visibleCount !== null && visibleCount < internalValue.length && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { "data-role": "count-badge", className: "flex-shrink-0 inline-block", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Badge, { size: "sm", variant: "info", children: [
|
|
673
|
+
"+",
|
|
674
|
+
internalValue.length - visibleCount
|
|
675
|
+
] }) })
|
|
676
|
+
]
|
|
677
|
+
}
|
|
678
|
+
) : internalValue.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "text-sm text-gray-900", children: selectedItemsMap.get(internalValue[0])?.label ?? placeholder }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "text-sm text-gray-400", children: placeholder }) }),
|
|
679
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 20 20", className: "ml-2 h-4 w-4 text-gray-600", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: "M5.5 7.5L10 12l4.5-4.5", stroke: "currentColor", strokeWidth: 1.5, strokeLinecap: "round", strokeLinejoin: "round", fill: "none" }) })
|
|
680
|
+
]
|
|
681
|
+
}
|
|
682
|
+
) }),
|
|
683
|
+
open && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "absolute z-40 mt-2 w-56 bg-white border rounded shadow-lg", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "p-1", children: items.map((groupOrItem, gi) => {
|
|
684
|
+
if ("items" in groupOrItem) {
|
|
685
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "mb-2", children: [
|
|
686
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex items-center justify-between px-2 py-1 text-xs text-gray-500 font-medium", children: [
|
|
687
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { children: groupOrItem.label }),
|
|
688
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { children: multiselect && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
689
|
+
"input",
|
|
690
|
+
{
|
|
691
|
+
type: "checkbox",
|
|
692
|
+
"aria-label": `Select all ${groupOrItem.label}`,
|
|
693
|
+
checked: groupOrItem.items.every((it) => isSelected(it.value)),
|
|
694
|
+
onChange: () => {
|
|
695
|
+
const all = groupOrItem.items.map((it) => it.value);
|
|
696
|
+
const allSelected = all.every((v) => isSelected(v));
|
|
697
|
+
let next;
|
|
698
|
+
if (multiselect) {
|
|
699
|
+
if (allSelected) {
|
|
700
|
+
next = internalValue.filter((v) => !all.includes(v));
|
|
701
|
+
} else {
|
|
702
|
+
next = [...internalValue, ...all.filter((v) => !internalValue.includes(v))];
|
|
703
|
+
}
|
|
704
|
+
} else {
|
|
705
|
+
next = allSelected ? [] : all[0] ? [all[0]] : [];
|
|
706
|
+
setOpen(false);
|
|
707
|
+
}
|
|
708
|
+
emitChange(next);
|
|
709
|
+
if (value === void 0) setInternalValue(next);
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
) })
|
|
713
|
+
] }),
|
|
714
|
+
groupOrItem.items.map((it) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
715
|
+
"button",
|
|
716
|
+
{
|
|
717
|
+
type: "button",
|
|
718
|
+
disabled: it.disabled,
|
|
719
|
+
onClick: () => toggleSelect(it.value),
|
|
720
|
+
className: cn(
|
|
721
|
+
"w-full text-left px-2 py-2 rounded hover:bg-gray-50 flex items-center gap-2",
|
|
722
|
+
isSelected(it.value) ? "bg-gray-100" : ""
|
|
723
|
+
),
|
|
724
|
+
children: [
|
|
725
|
+
it.icon && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("img", { src: it.icon, alt: "", className: "h-4 w-4 rounded" }),
|
|
726
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "flex-1", children: it.label }),
|
|
727
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "w-6 flex items-center justify-end", children: isSelected(it.value) && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
728
|
+
"svg",
|
|
729
|
+
{
|
|
730
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
731
|
+
viewBox: "0 0 24 24",
|
|
732
|
+
fill: "none",
|
|
733
|
+
stroke: "currentColor",
|
|
734
|
+
strokeWidth: 2,
|
|
735
|
+
className: "h-4 w-4",
|
|
736
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M5 13l4 4L19 7" })
|
|
737
|
+
}
|
|
738
|
+
) })
|
|
739
|
+
]
|
|
740
|
+
},
|
|
741
|
+
it.value
|
|
742
|
+
))
|
|
743
|
+
] }, gi);
|
|
744
|
+
}
|
|
745
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
746
|
+
"button",
|
|
747
|
+
{
|
|
748
|
+
type: "button",
|
|
749
|
+
disabled: groupOrItem.disabled,
|
|
750
|
+
onClick: () => toggleSelect(groupOrItem.value),
|
|
751
|
+
className: cn(
|
|
752
|
+
"w-full text-left px-2 py-2 rounded hover:bg-gray-50 flex items-center gap-2",
|
|
753
|
+
isSelected(groupOrItem.value) ? "bg-gray-100" : ""
|
|
754
|
+
),
|
|
755
|
+
children: [
|
|
756
|
+
groupOrItem.icon && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("img", { src: groupOrItem.icon, alt: "", className: "h-4 w-4 rounded" }),
|
|
757
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "flex-1", children: groupOrItem.label }),
|
|
758
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "w-6 flex items-center justify-end", children: isSelected(groupOrItem.value) && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
759
|
+
"svg",
|
|
760
|
+
{
|
|
761
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
762
|
+
viewBox: "0 0 24 24",
|
|
763
|
+
fill: "none",
|
|
764
|
+
stroke: "currentColor",
|
|
765
|
+
strokeWidth: 2,
|
|
766
|
+
className: "h-4 w-4",
|
|
767
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M5 13l4 4L19 7" })
|
|
768
|
+
}
|
|
769
|
+
) })
|
|
770
|
+
]
|
|
771
|
+
},
|
|
772
|
+
groupOrItem.value
|
|
773
|
+
);
|
|
774
|
+
}) }) })
|
|
775
|
+
] });
|
|
776
|
+
};
|
|
376
777
|
// Annotate the CommonJS export names for ESM import in node:
|
|
377
778
|
0 && (module.exports = {
|
|
378
779
|
Badge,
|
|
@@ -381,6 +782,8 @@ Countdown.displayName = "Countdown";
|
|
|
381
782
|
Countdown,
|
|
382
783
|
Icon,
|
|
383
784
|
Input,
|
|
785
|
+
Select,
|
|
786
|
+
Tag,
|
|
384
787
|
cn
|
|
385
788
|
});
|
|
386
789
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/components/Button/Button.tsx","../src/utils/cn.ts","../src/components/Card/Card.tsx","../src/components/Input/Input.tsx","../src/components/Badge/Badge.tsx","../src/components/Icon/Icon.tsx","../src/components/Countdown/Countdown.tsx"],"sourcesContent":["// Components\nexport { Button } from \"./components/Button/Button\";\nexport type { ButtonProps } from \"./components/Button/Button\";\n\nexport { Card } from \"./components/Card/Card\";\nexport type { CardProps } from \"./components/Card/Card\";\n\nexport { Input } from \"./components/Input/Input\";\nexport type { InputProps } from \"./components/Input/Input\";\n\nexport { Badge } from \"./components/Badge/Badge\";\nexport type { BadgeProps } from \"./components/Badge/Badge\";\n\nexport { Icon } from \"./components/Icon/Icon\";\nexport type { IconProps } from \"./components/Icon/Icon\";\n\nexport { Countdown } from \"./components/Countdown/Countdown\";\nexport type { CountdownProps } from \"./components/Countdown/Countdown\";\n\n// Utilities\nexport { cn } from \"./utils/cn\";\n// Icons are exported from a dedicated `@codecrib/ui/icons` entrypoint\n","import * as React from \"react\";\nimport type { IconWeight } from '@codecrib/ui/icons';\nimport { cn } from \"../../utils/cn\";\n\nexport interface ButtonProps\n extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n variant?: \"primary\" | \"secondary\" | \"outline\" | \"ghost\";\n size?: \"sm\" | \"md\" | \"lg\";\n isLoading?: boolean;\n /** Icon element to render inside the button */\n icon?: React.ReactNode;\n /** Position for the icon when `icon` is provided */\n iconPosition?: \"left\" | \"right\";\n}\n\nconst variantStyles = {\n primary:\n \"bg-primary-600 text-white hover:bg-primary-700 focus:ring-primary-500\",\n secondary:\n \"bg-secondary-600 text-white hover:bg-secondary-700 focus:ring-secondary-500\",\n outline:\n \"border-2 border-primary-600 text-primary-600 hover:bg-primary-50 focus:ring-primary-500\",\n ghost: \"text-gray-700 hover:bg-gray-100 focus:ring-gray-500\",\n};\n\nconst sizeStyles = {\n sm: \"px-3 py-1.5 text-sm\",\n md: \"px-4 py-2 text-base\",\n lg: \"px-6 py-3 text-lg\",\n};\n\nexport const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n (\n {\n className,\n variant = \"primary\",\n size = \"md\",\n isLoading = false,\n disabled,\n children,\n icon,\n iconPosition = 'left',\n ...props\n },\n ref\n ) => {\n const iconSizeMap: Record<NonNullable<ButtonProps['size']>, number> = {\n sm: 16,\n md: 20,\n lg: 24,\n } as const;\n\n const iconWeightMap: Record<NonNullable<ButtonProps['size']>, IconWeight> = {\n sm: 'regular',\n md: 'regular',\n lg: 'bold',\n } as const;\n\n const renderIcon = () => {\n if (!icon) return null;\n if (React.isValidElement(icon)) {\n const sizeProp = (icon.props as { size?: number | string })?.size;\n const weightProp = (icon.props as { weight?: IconWeight })?.weight;\n const key = size as NonNullable<ButtonProps['size']>;\n const desired = {\n size: (sizeProp as number | undefined) ?? iconSizeMap[key],\n weight: weightProp ?? iconWeightMap[key],\n };\n try {\n return React.cloneElement(icon as React.ReactElement, desired);\n } catch {\n return icon;\n }\n }\n return icon;\n };\n return (\n <button\n ref={ref}\n className={cn(\n \"inline-flex items-center justify-center font-medium rounded-lg transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed\",\n variantStyles[variant],\n sizeStyles[size],\n className\n )}\n disabled={disabled || isLoading}\n {...props}\n >\n {isLoading && (\n <svg\n className=\"animate-spin -ml-1 mr-2 h-4 w-4\"\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n >\n <circle\n className=\"opacity-25\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n />\n <path\n className=\"opacity-75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n />\n </svg>\n )}\n {icon && iconPosition === 'left' && (\n <span className=\"mr-2 inline-flex items-center\">{renderIcon()}</span>\n )}\n <span className=\"inline-flex items-center\">{children}</span>\n {icon && iconPosition === 'right' && (\n <span className=\"ml-2 inline-flex items-center\">{renderIcon()}</span>\n )}\n </button>\n );\n }\n);\n\nButton.displayName = \"Button\";\n","/**\n * Utility function to merge class names\n */\nexport function cn(...classes: (string | undefined | null | false)[]): string {\n return classes.filter(Boolean).join(\" \");\n}\n","import * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\n\nexport interface CardProps extends React.HTMLAttributes<HTMLDivElement> {\n variant?: \"default\" | \"bordered\" | \"elevated\";\n}\n\nconst variantStyles = {\n default: \"bg-white\",\n bordered: \"bg-white border border-gray-200\",\n elevated: \"bg-white shadow-lg\",\n};\n\nexport const Card = React.forwardRef<HTMLDivElement, CardProps>(\n ({ className, variant = \"bordered\", children, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={cn(\"rounded-xl p-6\", variantStyles[variant], className)}\n {...props}\n >\n {children}\n </div>\n );\n }\n);\n\nCard.displayName = \"Card\";\n\nexport interface CardHeaderProps extends React.HTMLAttributes<HTMLDivElement> {}\n\nexport const CardHeader = React.forwardRef<HTMLDivElement, CardHeaderProps>(\n ({ className, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={cn(\"flex flex-col space-y-1.5 pb-4\", className)}\n {...props}\n />\n );\n }\n);\n\nCardHeader.displayName = \"CardHeader\";\n\nexport interface CardTitleProps\n extends React.HTMLAttributes<HTMLHeadingElement> {}\n\nexport const CardTitle = React.forwardRef<HTMLHeadingElement, CardTitleProps>(\n ({ className, ...props }, ref) => {\n return (\n <h3\n ref={ref}\n className={cn(\"text-xl font-semibold text-gray-900\", className)}\n {...props}\n />\n );\n }\n);\n\nCardTitle.displayName = \"CardTitle\";\n\nexport interface CardContentProps\n extends React.HTMLAttributes<HTMLDivElement> {}\n\nexport const CardContent = React.forwardRef<HTMLDivElement, CardContentProps>(\n ({ className, ...props }, ref) => {\n return <div ref={ref} className={cn(\"text-gray-600\", className)} {...props} />;\n }\n);\n\nCardContent.displayName = \"CardContent\";\n","import * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\n\nexport interface InputProps\n extends React.InputHTMLAttributes<HTMLInputElement> {\n label?: string;\n error?: string;\n helperText?: string;\n}\n\nexport const Input = React.forwardRef<HTMLInputElement, InputProps>(\n ({ className, label, error, helperText, id, ...props }, ref) => {\n const inputId = id || React.useId();\n\n return (\n <div className=\"w-full\">\n {label && (\n <label\n htmlFor={inputId}\n className=\"block text-sm font-medium text-gray-700 mb-1\"\n >\n {label}\n </label>\n )}\n <input\n id={inputId}\n ref={ref}\n className={cn(\n \"block w-full rounded-lg border px-4 py-2 text-gray-900 placeholder:text-gray-400 focus:outline-none focus:ring-2 focus:ring-offset-0 transition-colors\",\n error\n ? \"border-red-500 focus:border-red-500 focus:ring-red-500\"\n : \"border-gray-300 focus:border-primary-500 focus:ring-primary-500\",\n className\n )}\n {...props}\n />\n {error && <p className=\"mt-1 text-sm text-red-600\">{error}</p>}\n {helperText && !error && (\n <p className=\"mt-1 text-sm text-gray-500\">{helperText}</p>\n )}\n </div>\n );\n }\n);\n\nInput.displayName = \"Input\";\n","import * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\n\nexport interface BadgeProps extends React.HTMLAttributes<HTMLSpanElement> {\n variant?: \"default\" | \"success\" | \"warning\" | \"error\" | \"info\";\n size?: \"sm\" | \"md\";\n}\n\nconst variantStyles = {\n default: \"bg-gray-100 text-gray-800\",\n success: \"bg-green-100 text-green-800\",\n warning: \"bg-yellow-100 text-yellow-800\",\n error: \"bg-red-100 text-red-800\",\n info: \"bg-blue-100 text-blue-800\",\n};\n\nconst sizeStyles = {\n sm: \"px-2 py-0.5 text-xs\",\n md: \"px-2.5 py-1 text-sm\",\n};\n\nexport const Badge = React.forwardRef<HTMLSpanElement, BadgeProps>(\n ({ className, variant = \"default\", size = \"md\", ...props }, ref) => {\n return (\n <span\n ref={ref}\n className={cn(\n \"inline-flex items-center font-medium rounded-full\",\n variantStyles[variant],\n sizeStyles[size],\n className\n )}\n {...props}\n />\n );\n }\n);\n\nBadge.displayName = \"Badge\";\n","import * as React from 'react';\nimport type { IconProps as PhosphorIconProps } from 'phosphor-react';\nimport { cn } from '../../utils/cn';\n\nexport interface IconProps extends Omit<PhosphorIconProps, 'weight'> {\n icon: React.ForwardRefExoticComponent<PhosphorIconProps & React.RefAttributes<SVGSVGElement>>;\n weight?: PhosphorIconProps['weight'];\n className?: string;\n color?: string;\n}\n\nexport const Icon = React.forwardRef<SVGSVGElement, IconProps>(\n ({ icon: IconComponent, size = 24, weight = 'regular', className, color, ...props }, ref) => {\n return (\n <IconComponent\n ref={ref}\n size={size}\n weight={weight}\n color={color}\n data-color={color}\n className={cn('inline-block', className)}\n aria-hidden\n {...(props as PhosphorIconProps)}\n />\n );\n }\n);\n\nIcon.displayName = 'Icon';\n\nexport default Icon;\n","import * as React from 'react';\nimport { cn } from '../../utils/cn';\n\nexport interface CountdownProps extends React.HTMLAttributes<HTMLDivElement> {\n /** deadline as Date | timestamp | ISO string */\n deadline: string | number | Date;\n /** optional callback when countdown reaches zero */\n onComplete?: () => void;\n /** visual variant to match Button */\n variant?: 'primary' | 'secondary' | 'outline' | 'ghost';\n /** size to align with Button sizes */\n size?: 'sm' | 'md' | 'lg';\n}\n\nfunction parseDeadline(value: string | number | Date) {\n if (value instanceof Date) return value.getTime();\n const n = Number(value);\n if (!Number.isNaN(n)) return n;\n const d = Date.parse(String(value));\n return Number.isNaN(d) ? NaN : d;\n}\n\nfunction formatRemaining(ms: number) {\n if (ms <= 0) return { expired: true, text: '00:00:00' };\n const total = Math.floor(ms / 1000);\n const days = Math.floor(total / 86400);\n const hours = Math.floor((total % 86400) / 3600);\n const minutes = Math.floor((total % 3600) / 60);\n const seconds = total % 60;\n\n const pad = (n: number) => String(n).padStart(2, '0');\n const h = pad(hours + days * 24);\n const m = pad(minutes);\n const s = pad(seconds);\n const text = days > 0 ? `${days}d ${h}:${m}:${s}` : `${h}:${m}:${s}`;\n return { expired: false, text };\n}\n\nexport const Countdown = React.forwardRef<HTMLDivElement, CountdownProps>(\n ({ deadline, onComplete, className, variant = 'primary', size = 'md', ...props }, ref) => {\n const target = React.useMemo(() => parseDeadline(deadline), [deadline]);\n const variantStyles: Record<string, string> = {\n primary: 'bg-primary-600 text-white',\n secondary: 'bg-secondary-600 text-white',\n outline: 'border-2 border-primary-600 text-primary-600 bg-transparent',\n ghost: 'text-gray-700 bg-transparent',\n };\n\n const sizeTextStyles: Record<NonNullable<CountdownProps['size']>, string> = {\n sm: 'text-sm px-2 py-0.5 rounded',\n md: 'text-base px-3 py-1 rounded',\n lg: 'text-lg px-4 py-1.5 rounded',\n };\n const [now, setNow] = React.useState(() => Date.now());\n const [expired, setExpired] = React.useState(false);\n\n React.useEffect(() => {\n if (Number.isNaN(target)) return undefined;\n setNow(Date.now());\n const id = setInterval(() => setNow(Date.now()), 1000);\n return () => clearInterval(id);\n }, [target]);\n\n React.useEffect(() => {\n if (Number.isNaN(target)) return;\n if (now >= target && !expired) {\n setExpired(true);\n onComplete?.();\n }\n }, [now, target, expired, onComplete]);\n\n const remaining = formatRemaining(target - now);\n const appliedVariant = expired ? 'expired' : variant;\n const expiredClass =\n variant === 'ghost'\n ? 'text-red-600 bg-transparent'\n : variant === 'outline'\n ? 'border-2 border-red-600 text-red-600 bg-transparent'\n : 'bg-red-600 text-white';\n const variantClass = expired ? expiredClass : variantStyles[variant];\n\n return (\n <div\n ref={ref}\n className={cn(\n 'inline-flex items-center font-mono',\n variantClass,\n sizeTextStyles[size],\n className\n )}\n {...props}\n >\n {Number.isNaN(target) ? 'Invalid date' : remaining.text}\n </div>\n );\n }\n);\n\nCountdown.displayName = 'Countdown';\n\nexport default Countdown;\n"],"mappings":"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","names":["React","import_jsx_runtime","variantStyles","React","import_jsx_runtime","React","import_jsx_runtime","variantStyles","sizeStyles","React","import_jsx_runtime","React","import_jsx_runtime","variantStyles"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/components/Button/Button.tsx","../src/utils/cn.ts","../src/components/Card/Card.tsx","../src/styles/borders.ts","../src/components/Input/Input.tsx","../src/components/Badge/Badge.tsx","../src/components/Icon/Icon.tsx","../src/components/Countdown/Countdown.tsx","../src/components/Tag/Tag.tsx","../src/components/Select/Select.tsx"],"sourcesContent":["// Components\nexport { Button } from \"./components/Button/Button\";\nexport type { ButtonProps } from \"./components/Button/Button\";\n\nexport { Card } from \"./components/Card/Card\";\nexport type { CardProps } from \"./components/Card/Card\";\n\nexport { Input } from \"./components/Input/Input\";\nexport type { InputProps } from \"./components/Input/Input\";\n\nexport { Badge } from \"./components/Badge/Badge\";\nexport type { BadgeProps } from \"./components/Badge/Badge\";\n\nexport { Icon } from \"./components/Icon/Icon\";\nexport type { IconProps } from \"./components/Icon/Icon\";\n\nexport { Countdown } from \"./components/Countdown/Countdown\";\nexport type { CountdownProps } from \"./components/Countdown/Countdown\";\n\nexport { Tag } from \"./components/Tag/Tag\";\nexport type { TagProps } from \"./components/Tag/Tag\";\n\nexport { Select } from \"./components/Select/Select\";\nexport type { SelectProps, SelectItem, SelectGroup } from \"./components/Select/Select\";\n\n// Utilities\nexport { cn } from \"./utils/cn\";\n// Icons are exported from a dedicated `@codecrib/ui/icons` entrypoint\n","import * as React from \"react\";\nimport type { IconWeight } from '@codecrib/ui/icons';\nimport { cn } from \"../../utils/cn\";\n\nexport interface ButtonProps\n extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n variant?: \"primary\" | \"secondary\" | \"outline\" | \"ghost\";\n size?: \"sm\" | \"md\" | \"lg\";\n isLoading?: boolean;\n /** Icon element to render inside the button */\n icon?: React.ReactNode;\n /** Position for the icon when `icon` is provided */\n iconPosition?: \"left\" | \"right\";\n}\n\nconst variantStyles = {\n primary:\n \"bg-primary-600 text-white hover:bg-primary-700 focus:ring-primary-500\",\n secondary:\n \"bg-secondary-600 text-white hover:bg-secondary-700 focus:ring-secondary-500\",\n outline:\n \"border-2 border-primary-600 text-primary-600 hover:bg-primary-50 focus:ring-primary-500\",\n ghost: \"text-gray-700 hover:bg-gray-100 focus:ring-gray-500\",\n};\n\nconst sizeStyles = {\n sm: \"px-3 py-1.5 text-sm\",\n md: \"px-4 py-2 text-base\",\n lg: \"px-6 py-3 text-lg\",\n};\n\nexport const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n (\n {\n className,\n variant = \"primary\",\n size = \"md\",\n isLoading = false,\n disabled,\n children,\n icon,\n iconPosition = 'left',\n ...props\n },\n ref\n ) => {\n const iconSizeMap: Record<NonNullable<ButtonProps['size']>, number> = {\n sm: 16,\n md: 20,\n lg: 24,\n } as const;\n\n const iconWeightMap: Record<NonNullable<ButtonProps['size']>, IconWeight> = {\n sm: 'regular',\n md: 'regular',\n lg: 'bold',\n } as const;\n\n const renderIcon = () => {\n if (!icon) return null;\n if (React.isValidElement(icon)) {\n const sizeProp = (icon.props as { size?: number | string })?.size;\n const weightProp = (icon.props as { weight?: IconWeight })?.weight;\n const key = size as NonNullable<ButtonProps['size']>;\n const desired = {\n size: (sizeProp as number | undefined) ?? iconSizeMap[key],\n weight: weightProp ?? iconWeightMap[key],\n };\n try {\n return React.cloneElement(icon as React.ReactElement, desired);\n } catch {\n return icon;\n }\n }\n return icon;\n };\n return (\n <button\n ref={ref}\n className={cn(\n \"inline-flex items-center justify-center font-medium rounded-lg transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed\",\n variantStyles[variant],\n sizeStyles[size],\n className\n )}\n disabled={disabled || isLoading}\n {...props}\n >\n {isLoading && (\n <svg\n className=\"animate-spin -ml-1 mr-2 h-4 w-4\"\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n >\n <circle\n className=\"opacity-25\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n />\n <path\n className=\"opacity-75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n />\n </svg>\n )}\n {icon && iconPosition === 'left' && (\n <span className=\"mr-2 inline-flex items-center\">{renderIcon()}</span>\n )}\n <span className=\"inline-flex items-center\">{children}</span>\n {icon && iconPosition === 'right' && (\n <span className=\"ml-2 inline-flex items-center\">{renderIcon()}</span>\n )}\n </button>\n );\n }\n);\n\nButton.displayName = \"Button\";\n","/**\n * Utility function to merge class names\n */\nexport function cn(...classes: (string | undefined | null | false)[]): string {\n return classes.filter(Boolean).join(\" \");\n}\n","import * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { radius, border } from \"../../styles/borders\";\n\nexport interface CardProps extends React.HTMLAttributes<HTMLDivElement> {\n variant?: \"default\" | \"bordered\" | \"elevated\";\n}\n\nconst variantStyles = {\n default: \"bg-white\",\n bordered: \"bg-white border border-gray-200\",\n elevated: \"bg-white shadow-lg\",\n};\n\nexport const Card = React.forwardRef<HTMLDivElement, CardProps>(\n ({ className, variant = \"bordered\", children, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={cn(radius.default, \"p-6\", variantStyles[variant], className)}\n {...props}\n >\n {children}\n </div>\n );\n }\n);\n\nCard.displayName = \"Card\";\n\nexport interface CardHeaderProps extends React.HTMLAttributes<HTMLDivElement> {}\n\nexport const CardHeader = React.forwardRef<HTMLDivElement, CardHeaderProps>(\n ({ className, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={cn(\"flex flex-col space-y-1.5 pb-4\", className)}\n {...props}\n />\n );\n }\n);\n\nCardHeader.displayName = \"CardHeader\";\n\nexport interface CardTitleProps\n extends React.HTMLAttributes<HTMLHeadingElement> {}\n\nexport const CardTitle = React.forwardRef<HTMLHeadingElement, CardTitleProps>(\n ({ className, ...props }, ref) => {\n return (\n <h3\n ref={ref}\n className={cn(\"text-xl font-semibold text-gray-900\", className)}\n {...props}\n />\n );\n }\n);\n\nCardTitle.displayName = \"CardTitle\";\n\nexport interface CardContentProps\n extends React.HTMLAttributes<HTMLDivElement> {}\n\nexport const CardContent = React.forwardRef<HTMLDivElement, CardContentProps>(\n ({ className, ...props }, ref) => {\n return <div ref={ref} className={cn(\"text-gray-600\", className)} {...props} />;\n }\n);\n\nCardContent.displayName = \"CardContent\";\n","export const radius = {\n default: \"rounded-lg\",\n pill: \"rounded-full\",\n};\n\nexport const border = {\n base: \"border\",\n color: \"border-gray-300\",\n focus: \"focus:border-primary-500 focus:ring-primary-500\",\n ring: \"focus:outline-none focus:ring-2 focus:ring-offset-0\",\n};\n\nexport const input = `${border.base} ${border.color}`;\n\nexport default {\n radius,\n border,\n input,\n};\n","import * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { radius, border } from \"../../styles/borders\";\n\nexport interface InputProps\n extends React.InputHTMLAttributes<HTMLInputElement> {\n label?: string;\n error?: string;\n helperText?: string;\n}\n\nexport const Input = React.forwardRef<HTMLInputElement, InputProps>(\n ({ className, label, error, helperText, id, ...props }, ref) => {\n const inputId = id || React.useId();\n\n return (\n <div className=\"w-full\">\n {label && (\n <label\n htmlFor={inputId}\n className=\"block text-sm font-medium text-gray-700 mb-1\"\n >\n {label}\n </label>\n )}\n <input\n id={inputId}\n ref={ref}\n className={cn(\n \"block w-full px-4 py-2 text-gray-900 placeholder:text-gray-400 transition-colors\",\n radius.default,\n border.base,\n error\n ? \"border-red-500 focus:border-red-500 focus:ring-red-500\"\n : `${border.color} ${border.focus} ${border.ring}`,\n className\n )}\n {...props}\n />\n {error && <p className=\"mt-1 text-sm text-red-600\">{error}</p>}\n {helperText && !error && (\n <p className=\"mt-1 text-sm text-gray-500\">{helperText}</p>\n )}\n </div>\n );\n }\n);\n\nInput.displayName = \"Input\";\n","import * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\n\nexport interface BadgeProps extends React.HTMLAttributes<HTMLSpanElement> {\n variant?: \"default\" | \"success\" | \"warning\" | \"error\" | \"info\";\n size?: \"sm\" | \"md\";\n}\n\nconst variantStyles = {\n default: \"bg-gray-100 text-gray-800\",\n success: \"bg-green-100 text-green-800\",\n warning: \"bg-yellow-100 text-yellow-800\",\n error: \"bg-red-100 text-red-800\",\n info: \"bg-blue-100 text-blue-800\",\n};\n\nconst sizeStyles = {\n sm: \"px-2 py-0.5 text-xs\",\n md: \"px-2.5 py-1 text-sm\",\n};\n\nexport const Badge = React.forwardRef<HTMLSpanElement, BadgeProps>(\n ({ className, variant = \"default\", size = \"md\", ...props }, ref) => {\n return (\n <span\n ref={ref}\n className={cn(\n \"inline-flex items-center font-medium rounded-full\",\n variantStyles[variant],\n sizeStyles[size],\n className\n )}\n {...props}\n />\n );\n }\n);\n\nBadge.displayName = \"Badge\";\n","import * as React from 'react';\nimport type { IconProps as PhosphorIconProps } from 'phosphor-react';\nimport { cn } from '../../utils/cn';\n\nexport interface IconProps extends Omit<PhosphorIconProps, 'weight'> {\n icon: React.ForwardRefExoticComponent<PhosphorIconProps & React.RefAttributes<SVGSVGElement>>;\n weight?: PhosphorIconProps['weight'];\n className?: string;\n color?: string;\n}\n\nexport const Icon = React.forwardRef<SVGSVGElement, IconProps>(\n ({ icon: IconComponent, size = 24, weight = 'regular', className, color, ...props }, ref) => {\n return (\n <IconComponent\n ref={ref}\n size={size}\n weight={weight}\n color={color}\n data-color={color}\n className={cn('inline-block', className)}\n aria-hidden\n {...(props as PhosphorIconProps)}\n />\n );\n }\n);\n\nIcon.displayName = 'Icon';\n\nexport default Icon;\n","import * as React from 'react';\nimport { cn } from '../../utils/cn';\n\nexport interface CountdownProps extends React.HTMLAttributes<HTMLDivElement> {\n /** deadline as Date | timestamp | ISO string */\n deadline: string | number | Date;\n /** optional callback when countdown reaches zero */\n onComplete?: () => void;\n /** visual variant to match Button */\n variant?: 'primary' | 'secondary' | 'outline' | 'ghost';\n /** size to align with Button sizes */\n size?: 'sm' | 'md' | 'lg';\n}\n\nfunction parseDeadline(value: string | number | Date) {\n if (value instanceof Date) return value.getTime();\n const n = Number(value);\n if (!Number.isNaN(n)) return n;\n const d = Date.parse(String(value));\n return Number.isNaN(d) ? NaN : d;\n}\n\nfunction formatRemaining(ms: number) {\n if (ms <= 0) return { expired: true, text: '00:00:00' };\n const total = Math.floor(ms / 1000);\n const days = Math.floor(total / 86400);\n const hours = Math.floor((total % 86400) / 3600);\n const minutes = Math.floor((total % 3600) / 60);\n const seconds = total % 60;\n\n const pad = (n: number) => String(n).padStart(2, '0');\n const h = pad(hours + days * 24);\n const m = pad(minutes);\n const s = pad(seconds);\n const text = days > 0 ? `${days}d ${h}:${m}:${s}` : `${h}:${m}:${s}`;\n return { expired: false, text };\n}\n\nexport const Countdown = React.forwardRef<HTMLDivElement, CountdownProps>(\n ({ deadline, onComplete, className, variant = 'primary', size = 'md', ...props }, ref) => {\n const target = React.useMemo(() => parseDeadline(deadline), [deadline]);\n const variantStyles: Record<string, string> = {\n primary: 'bg-primary-600 text-white',\n secondary: 'bg-secondary-600 text-white',\n outline: 'border-2 border-primary-600 text-primary-600 bg-transparent',\n ghost: 'text-gray-700 bg-transparent',\n };\n\n const sizeTextStyles: Record<NonNullable<CountdownProps['size']>, string> = {\n sm: 'text-sm px-2 py-0.5 rounded',\n md: 'text-base px-3 py-1 rounded',\n lg: 'text-lg px-4 py-1.5 rounded',\n };\n const [now, setNow] = React.useState(() => Date.now());\n const [expired, setExpired] = React.useState(false);\n\n React.useEffect(() => {\n if (Number.isNaN(target)) return undefined;\n setNow(Date.now());\n const id = setInterval(() => setNow(Date.now()), 1000);\n return () => clearInterval(id);\n }, [target]);\n\n React.useEffect(() => {\n if (Number.isNaN(target)) return;\n if (now >= target && !expired) {\n setExpired(true);\n onComplete?.();\n }\n }, [now, target, expired, onComplete]);\n\n const remaining = formatRemaining(target - now);\n const appliedVariant = expired ? 'expired' : variant;\n const expiredClass =\n variant === 'ghost'\n ? 'text-red-600 bg-transparent'\n : variant === 'outline'\n ? 'border-2 border-red-600 text-red-600 bg-transparent'\n : 'bg-red-600 text-white';\n const variantClass = expired ? expiredClass : variantStyles[variant];\n\n return (\n <div\n ref={ref}\n className={cn(\n 'inline-flex items-center font-mono',\n variantClass,\n sizeTextStyles[size],\n className\n )}\n {...props}\n >\n {Number.isNaN(target) ? 'Invalid date' : remaining.text}\n </div>\n );\n }\n);\n\nCountdown.displayName = 'Countdown';\n\nexport default Countdown;\n","import * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { radius, border } from \"../../styles/borders\";\n\nexport interface TagProps extends React.HTMLAttributes<HTMLSpanElement> {\n variant?: \"default\" | \"success\" | \"warning\" | \"error\" | \"info\";\n size?: \"sm\" | \"md\" | \"lg\";\n removable?: boolean;\n onRemove?: (e: React.MouseEvent<HTMLButtonElement>) => void;\n removeLabel?: string;\n}\n\nconst variantStyles = {\n default: \"bg-gray-100 text-gray-800\",\n success: \"bg-green-100 text-green-800\",\n warning: \"bg-yellow-100 text-yellow-800\",\n error: \"bg-red-100 text-red-800\",\n info: \"bg-blue-100 text-blue-800\",\n};\n\nconst sizeStyles = {\n sm: \"px-2 py-0.5 text-xs\",\n md: \"px-2.5 py-1 text-sm\",\n lg: \"px-3 py-1.5 text-base\",\n};\n\nexport const Tag = React.forwardRef<HTMLSpanElement, TagProps>(\n (\n {\n className,\n variant = \"default\",\n size = \"md\",\n removable = false,\n onRemove,\n removeLabel = \"Remove\",\n children,\n ...props\n },\n ref\n ) => {\n return (\n <span\n ref={ref}\n className={cn(\n \"inline-flex items-center font-medium\",\n radius.pill,\n variantStyles[variant],\n sizeStyles[size],\n className\n )}\n {...props}\n >\n <span>{children}</span>\n {removable && (\n <button\n type=\"button\"\n aria-label={removeLabel}\n onClick={onRemove}\n className={cn(\n \"ml-2 inline-flex items-center justify-center\",\n radius.pill,\n border.ring,\n size === \"sm\" ? \"h-4 w-4\" : size === \"md\" ? \"h-5 w-5\" : \"h-6 w-6\"\n )}\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2}\n className={cn(size === \"sm\" ? \"h-3 w-3\" : size === \"md\" ? \"h-4 w-4\" : \"h-5 w-5\")}\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </button>\n )}\n </span>\n );\n }\n);\n\nTag.displayName = \"Tag\";\n\nexport default Tag;\n","import * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { Tag } from \"../Tag/Tag\";\nimport { Badge } from \"../Badge/Badge\";\n\nexport type SelectItem = {\n value: string;\n label: React.ReactNode;\n icon?: string; // optional URL to an icon image\n disabled?: boolean;\n};\n\nexport type SelectGroup = {\n label: string;\n items: SelectItem[];\n};\n\nexport type SelectSource = SelectItem | SelectGroup;\n\nexport interface SelectProps {\n items: SelectSource[];\n placeholder?: string;\n multiselect?: boolean;\n multiline?: boolean;\n value?: string | string[];\n onChange?: (value: string | string[]) => void;\n className?: string;\n}\n\nexport const Select: React.FC<SelectProps> = ({\n items,\n placeholder = \"Select...\",\n multiselect = false,\n multiline = false,\n value,\n onChange,\n className,\n}) => {\n const [open, setOpen] = React.useState(false);\n const [internalValue, setInternalValue] = React.useState<string[]>(\n Array.isArray(value) ? value : value ? [value] : []\n );\n\n React.useEffect(() => {\n if (value !== undefined) {\n setInternalValue(Array.isArray(value) ? value : value ? [value] : []);\n }\n }, [value]);\n\n React.useEffect(() => {\n // Reset last emitted value when controlled `value` changes externally\n lastEmittedRef.current = null;\n }, [value, multiselect]);\n\n const containerRef = React.useRef<HTMLDivElement | null>(null);\n\n React.useEffect(() => {\n const onDoc = (e: MouseEvent) => {\n if (!containerRef.current) return;\n if (!containerRef.current.contains(e.target as Node)) setOpen(false);\n };\n document.addEventListener(\"mousedown\", onDoc);\n return () => document.removeEventListener(\"mousedown\", onDoc);\n }, []);\n\n const isSelected = (v: string) => internalValue.includes(v);\n const lastEmittedRef = React.useRef<string | null>(null);\n\n const emitChange = (next: string[]) => {\n const payload = multiselect ? JSON.stringify(next) : next[0] || \"\";\n if (lastEmittedRef.current === payload) return;\n lastEmittedRef.current = payload;\n if (onChange) onChange(multiselect ? next : next[0] || \"\");\n };\n\n const toggleSelect = (v: string) => {\n let next: string[];\n if (multiselect) {\n next = isSelected(v)\n ? internalValue.filter((x) => x !== v)\n : [...internalValue, v];\n } else {\n next = isSelected(v) ? [] : [v];\n setOpen(false);\n }\n\n emitChange(next);\n if (value === undefined) setInternalValue(next);\n };\n\n const removeValue = (v: string) => {\n const next = internalValue.filter((x) => x !== v);\n emitChange(next);\n if (value === undefined) setInternalValue(next);\n };\n\n const selectedItemsMap = React.useMemo(() => {\n const map = new Map<string, SelectItem>();\n const collect = (src: SelectSource[]) => {\n src.forEach((s) => {\n if (\"items\" in s) s.items.forEach((it) => map.set(it.value, it));\n else map.set(s.value, s);\n });\n };\n collect(items);\n return map;\n }, [items]);\n\n const tagsContainerRef = React.useRef<HTMLSpanElement | null>(null);\n const [visibleCount, setVisibleCount] = React.useState<number | null>(null);\n\n React.useEffect(() => {\n if (multiline) {\n setVisibleCount(null);\n return;\n }\n\n let raf: number | undefined;\n let timeout: number | undefined;\n\n const measure = () => {\n if (raf) cancelAnimationFrame(raf);\n raf = requestAnimationFrame(() => {\n const container = tagsContainerRef.current;\n if (!container) {\n setVisibleCount(null);\n return;\n }\n\n const containerWidth = container.clientWidth;\n if (containerWidth === 0) {\n setVisibleCount(null);\n return;\n }\n\n // Get all tag elements (they're always rendered, some may be hidden)\n const tagEls = Array.from(\n container.querySelectorAll('[data-role=\"select-tag\"]')\n ) as HTMLElement[];\n \n if (!tagEls.length) {\n setVisibleCount(null);\n return;\n }\n\n // Get badge element if present\n const badgeEl = container.querySelector('[data-role=\"count-badge\"]') as HTMLElement | null;\n\n // Compute gap from container\n const containerStyle = window.getComputedStyle(container);\n const gap = parseFloat(containerStyle.gap || containerStyle.columnGap || \"0\") || 0;\n\n // Measure each tag's width\n const tagWidths: number[] = tagEls.map((el) => el.offsetWidth);\n\n // First check: do all tags fit without any badge?\n let totalWidthAllTags = 0;\n for (const [i, w] of tagWidths.entries()) {\n totalWidthAllTags += w + (i > 0 ? gap : 0);\n }\n\n if (totalWidthAllTags <= containerWidth) {\n // All tags fit, no badge needed\n setVisibleCount(tagEls.length);\n return;\n }\n\n // Not all tags fit, so we need a badge. Measure or estimate badge width.\n let badgeWidth = badgeEl ? badgeEl.offsetWidth : 40;\n\n // Calculate how many tags fit WITH space reserved for the badge\n let usedWidth = 0;\n let fitCount = 0;\n\n for (const [i, tagWidth] of tagWidths.entries()) {\n const gapBeforeTag = i > 0 ? gap : 0;\n const gapBeforeBadge = gap;\n const effectiveTagWidth = tagWidth ?? 0;\n\n // Space needed: current tag + gap before badge + badge\n const spaceNeeded = usedWidth + gapBeforeTag + effectiveTagWidth + gapBeforeBadge + badgeWidth;\n\n if (spaceNeeded <= containerWidth) {\n usedWidth += gapBeforeTag + effectiveTagWidth;\n fitCount = i + 1;\n } else {\n break;\n }\n }\n\n // Ensure at least 1 tag is shown\n fitCount = Math.max(1, fitCount);\n\n setVisibleCount(fitCount);\n });\n };\n\n measure();\n\n const onResize = () => {\n if (timeout) clearTimeout(timeout);\n timeout = window.setTimeout(measure, 50);\n };\n window.addEventListener(\"resize\", onResize);\n\n let ro: ResizeObserver | undefined;\n if (typeof ResizeObserver !== \"undefined\" && tagsContainerRef.current) {\n ro = new ResizeObserver(onResize);\n ro.observe(tagsContainerRef.current);\n }\n\n return () => {\n if (raf) cancelAnimationFrame(raf);\n if (timeout) clearTimeout(timeout);\n window.removeEventListener(\"resize\", onResize);\n ro?.disconnect();\n };\n }, [internalValue, multiline]);\n\n return (\n <div ref={containerRef} className={cn(\"relative inline-block w-full\", className)}>\n <div className=\"flex items-center\">\n <div\n role=\"combobox\"\n tabIndex={0}\n aria-expanded={open}\n onClick={() => setOpen((s) => !s)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n setOpen((s) => !s);\n }\n if (e.key === \"Escape\") setOpen(false);\n }}\n className={cn(\n \"w-full inline-flex items-center justify-between rounded-lg border bg-white px-4 py-2 text-gray-900 text-left cursor-pointer focus:outline-none focus:ring-2 focus:ring-primary-500\",\n multiselect ? \"\" : \"\",\n open ? \"ring-1 ring-gray-300\" : \"\"\n )}\n >\n <div className=\"flex-1\">\n {multiselect && internalValue.length > 0 ? (\n <span\n ref={tagsContainerRef}\n className={cn(\n \"relative flex gap-1 items-center\",\n multiline ? \"flex-wrap\" : \"overflow-hidden whitespace-nowrap\",\n )}\n >\n {/* Always render all tags for measurement; hide overflowed ones via CSS */}\n {internalValue.map((v, index) => {\n const isHidden = !multiline && visibleCount !== null && index >= visibleCount;\n return (\n <span\n key={v}\n data-role=\"select-tag\"\n className={cn(\n \"flex-shrink-0 inline-block\",\n isHidden && \"invisible absolute pointer-events-none\"\n )}\n >\n <Tag\n size=\"sm\"\n removable\n removeLabel={`Remove ${selectedItemsMap.get(v)?.label ?? v}`}\n onRemove={(e) => {\n e.stopPropagation();\n removeValue(v);\n }}\n >\n {selectedItemsMap.get(v)?.label ?? v}\n </Tag>\n </span>\n );\n })}\n {/* Show badge when there are hidden tags */}\n {!multiline && visibleCount !== null && visibleCount < internalValue.length && (\n <span data-role=\"count-badge\" className=\"flex-shrink-0 inline-block\">\n <Badge size=\"sm\" variant=\"info\">+{internalValue.length - visibleCount}</Badge>\n </span>\n )}\n </span>\n ) : internalValue.length > 0 ? (\n <span className=\"text-sm text-gray-900\">\n {selectedItemsMap.get(internalValue[0]!)?.label ?? placeholder}\n </span>\n ) : (\n <span className=\"text-sm text-gray-400\">{placeholder}</span>\n )}\n </div>\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" className=\"ml-2 h-4 w-4 text-gray-600\">\n <path d=\"M5.5 7.5L10 12l4.5-4.5\" stroke=\"currentColor\" strokeWidth={1.5} strokeLinecap=\"round\" strokeLinejoin=\"round\" fill=\"none\" />\n </svg>\n </div>\n </div>\n\n {open && (\n <div className=\"absolute z-40 mt-2 w-56 bg-white border rounded shadow-lg\">\n <div className=\"p-1\">\n {items.map((groupOrItem, gi) => {\n if (\"items\" in groupOrItem) {\n return (\n <div key={gi} className=\"mb-2\">\n <div className=\"flex items-center justify-between px-2 py-1 text-xs text-gray-500 font-medium\">\n <div>{groupOrItem.label}</div>\n <div>\n {multiselect && (\n <input\n type=\"checkbox\"\n aria-label={`Select all ${groupOrItem.label}`}\n checked={groupOrItem.items.every((it) => isSelected(it.value))}\n onChange={() => {\n // toggle all in group\n const all = groupOrItem.items.map((it) => it.value);\n const allSelected = all.every((v) => isSelected(v));\n let next: string[];\n if (multiselect) {\n if (allSelected) {\n next = internalValue.filter((v) => !all.includes(v));\n } else {\n next = [...internalValue, ...all.filter((v) => !internalValue.includes(v))];\n }\n } else {\n // single select: select first item or clear\n next = allSelected ? [] : (all[0] ? [all[0]] : []);\n setOpen(false);\n }\n emitChange(next);\n if (value === undefined) setInternalValue(next);\n }}\n />\n )}\n </div>\n </div>\n {groupOrItem.items.map((it) => (\n <button\n key={it.value}\n type=\"button\"\n disabled={it.disabled}\n onClick={() => toggleSelect(it.value)}\n className={cn(\n \"w-full text-left px-2 py-2 rounded hover:bg-gray-50 flex items-center gap-2\",\n isSelected(it.value) ? \"bg-gray-100\" : \"\"\n )}\n >\n {it.icon && (\n <img src={it.icon} alt=\"\" className=\"h-4 w-4 rounded\" />\n )}\n <span className=\"flex-1\">{it.label}</span>\n <span className=\"w-6 flex items-center justify-end\">\n {isSelected(it.value) && (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2}\n className=\"h-4 w-4\"\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M5 13l4 4L19 7\" />\n </svg>\n )}\n </span>\n </button>\n ))}\n </div>\n );\n }\n\n return (\n <button\n key={groupOrItem.value}\n type=\"button\"\n disabled={groupOrItem.disabled}\n onClick={() => toggleSelect(groupOrItem.value)}\n className={cn(\n \"w-full text-left px-2 py-2 rounded hover:bg-gray-50 flex items-center gap-2\",\n isSelected(groupOrItem.value) ? \"bg-gray-100\" : \"\"\n )}\n >\n {groupOrItem.icon && (\n <img src={groupOrItem.icon} alt=\"\" className=\"h-4 w-4 rounded\" />\n )}\n <span className=\"flex-1\">{groupOrItem.label}</span>\n <span className=\"w-6 flex items-center justify-end\">\n {isSelected(groupOrItem.value) && (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2}\n className=\"h-4 w-4\"\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M5 13l4 4L19 7\" />\n </svg>\n )}\n </span>\n </button>\n );\n })}\n </div>\n </div>\n )}\n </div>\n );\n};\n\nexport default Select;\n"],"mappings":"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","names":["React","import_jsx_runtime","variantStyles","React","import_jsx_runtime","React","import_jsx_runtime","variantStyles","sizeStyles","React","import_jsx_runtime","React","import_jsx_runtime","variantStyles","React","import_jsx_runtime","variantStyles","sizeStyles","React","import_jsx_runtime"]}
|