@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.d.cts
CHANGED
|
@@ -50,9 +50,40 @@ interface CountdownProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
|
50
50
|
}
|
|
51
51
|
declare const Countdown: React.ForwardRefExoticComponent<CountdownProps & React.RefAttributes<HTMLDivElement>>;
|
|
52
52
|
|
|
53
|
+
interface TagProps extends React.HTMLAttributes<HTMLSpanElement> {
|
|
54
|
+
variant?: "default" | "success" | "warning" | "error" | "info";
|
|
55
|
+
size?: "sm" | "md" | "lg";
|
|
56
|
+
removable?: boolean;
|
|
57
|
+
onRemove?: (e: React.MouseEvent<HTMLButtonElement>) => void;
|
|
58
|
+
removeLabel?: string;
|
|
59
|
+
}
|
|
60
|
+
declare const Tag: React.ForwardRefExoticComponent<TagProps & React.RefAttributes<HTMLSpanElement>>;
|
|
61
|
+
|
|
62
|
+
type SelectItem = {
|
|
63
|
+
value: string;
|
|
64
|
+
label: React.ReactNode;
|
|
65
|
+
icon?: string;
|
|
66
|
+
disabled?: boolean;
|
|
67
|
+
};
|
|
68
|
+
type SelectGroup = {
|
|
69
|
+
label: string;
|
|
70
|
+
items: SelectItem[];
|
|
71
|
+
};
|
|
72
|
+
type SelectSource = SelectItem | SelectGroup;
|
|
73
|
+
interface SelectProps {
|
|
74
|
+
items: SelectSource[];
|
|
75
|
+
placeholder?: string;
|
|
76
|
+
multiselect?: boolean;
|
|
77
|
+
multiline?: boolean;
|
|
78
|
+
value?: string | string[];
|
|
79
|
+
onChange?: (value: string | string[]) => void;
|
|
80
|
+
className?: string;
|
|
81
|
+
}
|
|
82
|
+
declare const Select: React.FC<SelectProps>;
|
|
83
|
+
|
|
53
84
|
/**
|
|
54
85
|
* Utility function to merge class names
|
|
55
86
|
*/
|
|
56
87
|
declare function cn(...classes: (string | undefined | null | false)[]): string;
|
|
57
88
|
|
|
58
|
-
export { Badge, type BadgeProps, Button, type ButtonProps, Card, type CardProps, Countdown, type CountdownProps, Icon, type IconProps, Input, type InputProps, cn };
|
|
89
|
+
export { Badge, type BadgeProps, Button, type ButtonProps, Card, type CardProps, Countdown, type CountdownProps, Icon, type IconProps, Input, type InputProps, Select, type SelectGroup, type SelectItem, type SelectProps, Tag, type TagProps, cn };
|
package/dist/index.d.ts
CHANGED
|
@@ -50,9 +50,40 @@ interface CountdownProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
|
50
50
|
}
|
|
51
51
|
declare const Countdown: React.ForwardRefExoticComponent<CountdownProps & React.RefAttributes<HTMLDivElement>>;
|
|
52
52
|
|
|
53
|
+
interface TagProps extends React.HTMLAttributes<HTMLSpanElement> {
|
|
54
|
+
variant?: "default" | "success" | "warning" | "error" | "info";
|
|
55
|
+
size?: "sm" | "md" | "lg";
|
|
56
|
+
removable?: boolean;
|
|
57
|
+
onRemove?: (e: React.MouseEvent<HTMLButtonElement>) => void;
|
|
58
|
+
removeLabel?: string;
|
|
59
|
+
}
|
|
60
|
+
declare const Tag: React.ForwardRefExoticComponent<TagProps & React.RefAttributes<HTMLSpanElement>>;
|
|
61
|
+
|
|
62
|
+
type SelectItem = {
|
|
63
|
+
value: string;
|
|
64
|
+
label: React.ReactNode;
|
|
65
|
+
icon?: string;
|
|
66
|
+
disabled?: boolean;
|
|
67
|
+
};
|
|
68
|
+
type SelectGroup = {
|
|
69
|
+
label: string;
|
|
70
|
+
items: SelectItem[];
|
|
71
|
+
};
|
|
72
|
+
type SelectSource = SelectItem | SelectGroup;
|
|
73
|
+
interface SelectProps {
|
|
74
|
+
items: SelectSource[];
|
|
75
|
+
placeholder?: string;
|
|
76
|
+
multiselect?: boolean;
|
|
77
|
+
multiline?: boolean;
|
|
78
|
+
value?: string | string[];
|
|
79
|
+
onChange?: (value: string | string[]) => void;
|
|
80
|
+
className?: string;
|
|
81
|
+
}
|
|
82
|
+
declare const Select: React.FC<SelectProps>;
|
|
83
|
+
|
|
53
84
|
/**
|
|
54
85
|
* Utility function to merge class names
|
|
55
86
|
*/
|
|
56
87
|
declare function cn(...classes: (string | undefined | null | false)[]): string;
|
|
57
88
|
|
|
58
|
-
export { Badge, type BadgeProps, Button, type ButtonProps, Card, type CardProps, Countdown, type CountdownProps, Icon, type IconProps, Input, type InputProps, cn };
|
|
89
|
+
export { Badge, type BadgeProps, Button, type ButtonProps, Card, type CardProps, Countdown, type CountdownProps, Icon, type IconProps, Input, type InputProps, Select, type SelectGroup, type SelectItem, type SelectProps, Tag, type TagProps, cn };
|
package/dist/index.js
CHANGED
|
@@ -114,6 +114,21 @@ Button.displayName = "Button";
|
|
|
114
114
|
|
|
115
115
|
// src/components/Card/Card.tsx
|
|
116
116
|
import * as React2 from "react";
|
|
117
|
+
|
|
118
|
+
// src/styles/borders.ts
|
|
119
|
+
var radius = {
|
|
120
|
+
default: "rounded-lg",
|
|
121
|
+
pill: "rounded-full"
|
|
122
|
+
};
|
|
123
|
+
var border = {
|
|
124
|
+
base: "border",
|
|
125
|
+
color: "border-gray-300",
|
|
126
|
+
focus: "focus:border-primary-500 focus:ring-primary-500",
|
|
127
|
+
ring: "focus:outline-none focus:ring-2 focus:ring-offset-0"
|
|
128
|
+
};
|
|
129
|
+
var input = `${border.base} ${border.color}`;
|
|
130
|
+
|
|
131
|
+
// src/components/Card/Card.tsx
|
|
117
132
|
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
118
133
|
var variantStyles2 = {
|
|
119
134
|
default: "bg-white",
|
|
@@ -126,7 +141,7 @@ var Card = React2.forwardRef(
|
|
|
126
141
|
"div",
|
|
127
142
|
{
|
|
128
143
|
ref,
|
|
129
|
-
className: cn("
|
|
144
|
+
className: cn(radius.default, "p-6", variantStyles2[variant], className),
|
|
130
145
|
...props,
|
|
131
146
|
children
|
|
132
147
|
}
|
|
@@ -188,8 +203,10 @@ var Input = React3.forwardRef(
|
|
|
188
203
|
id: inputId,
|
|
189
204
|
ref,
|
|
190
205
|
className: cn(
|
|
191
|
-
"block w-full
|
|
192
|
-
|
|
206
|
+
"block w-full px-4 py-2 text-gray-900 placeholder:text-gray-400 transition-colors",
|
|
207
|
+
radius.default,
|
|
208
|
+
border.base,
|
|
209
|
+
error ? "border-red-500 focus:border-red-500 focus:ring-red-500" : `${border.color} ${border.focus} ${border.ring}`,
|
|
193
210
|
className
|
|
194
211
|
),
|
|
195
212
|
...props
|
|
@@ -284,7 +301,7 @@ function formatRemaining(ms) {
|
|
|
284
301
|
var Countdown = React6.forwardRef(
|
|
285
302
|
({ deadline, onComplete, className, variant = "primary", size = "md", ...props }, ref) => {
|
|
286
303
|
const target = React6.useMemo(() => parseDeadline(deadline), [deadline]);
|
|
287
|
-
const
|
|
304
|
+
const variantStyles5 = {
|
|
288
305
|
primary: "bg-primary-600 text-white",
|
|
289
306
|
secondary: "bg-secondary-600 text-white",
|
|
290
307
|
outline: "border-2 border-primary-600 text-primary-600 bg-transparent",
|
|
@@ -313,7 +330,7 @@ var Countdown = React6.forwardRef(
|
|
|
313
330
|
const remaining = formatRemaining(target - now);
|
|
314
331
|
const appliedVariant = expired ? "expired" : variant;
|
|
315
332
|
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";
|
|
316
|
-
const variantClass = expired ? expiredClass :
|
|
333
|
+
const variantClass = expired ? expiredClass : variantStyles5[variant];
|
|
317
334
|
return /* @__PURE__ */ jsx6(
|
|
318
335
|
"div",
|
|
319
336
|
{
|
|
@@ -331,6 +348,388 @@ var Countdown = React6.forwardRef(
|
|
|
331
348
|
}
|
|
332
349
|
);
|
|
333
350
|
Countdown.displayName = "Countdown";
|
|
351
|
+
|
|
352
|
+
// src/components/Tag/Tag.tsx
|
|
353
|
+
import * as React7 from "react";
|
|
354
|
+
import { jsx as jsx7, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
355
|
+
var variantStyles4 = {
|
|
356
|
+
default: "bg-gray-100 text-gray-800",
|
|
357
|
+
success: "bg-green-100 text-green-800",
|
|
358
|
+
warning: "bg-yellow-100 text-yellow-800",
|
|
359
|
+
error: "bg-red-100 text-red-800",
|
|
360
|
+
info: "bg-blue-100 text-blue-800"
|
|
361
|
+
};
|
|
362
|
+
var sizeStyles3 = {
|
|
363
|
+
sm: "px-2 py-0.5 text-xs",
|
|
364
|
+
md: "px-2.5 py-1 text-sm",
|
|
365
|
+
lg: "px-3 py-1.5 text-base"
|
|
366
|
+
};
|
|
367
|
+
var Tag = React7.forwardRef(
|
|
368
|
+
({
|
|
369
|
+
className,
|
|
370
|
+
variant = "default",
|
|
371
|
+
size = "md",
|
|
372
|
+
removable = false,
|
|
373
|
+
onRemove,
|
|
374
|
+
removeLabel = "Remove",
|
|
375
|
+
children,
|
|
376
|
+
...props
|
|
377
|
+
}, ref) => {
|
|
378
|
+
return /* @__PURE__ */ jsxs3(
|
|
379
|
+
"span",
|
|
380
|
+
{
|
|
381
|
+
ref,
|
|
382
|
+
className: cn(
|
|
383
|
+
"inline-flex items-center font-medium",
|
|
384
|
+
radius.pill,
|
|
385
|
+
variantStyles4[variant],
|
|
386
|
+
sizeStyles3[size],
|
|
387
|
+
className
|
|
388
|
+
),
|
|
389
|
+
...props,
|
|
390
|
+
children: [
|
|
391
|
+
/* @__PURE__ */ jsx7("span", { children }),
|
|
392
|
+
removable && /* @__PURE__ */ jsx7(
|
|
393
|
+
"button",
|
|
394
|
+
{
|
|
395
|
+
type: "button",
|
|
396
|
+
"aria-label": removeLabel,
|
|
397
|
+
onClick: onRemove,
|
|
398
|
+
className: cn(
|
|
399
|
+
"ml-2 inline-flex items-center justify-center",
|
|
400
|
+
radius.pill,
|
|
401
|
+
border.ring,
|
|
402
|
+
size === "sm" ? "h-4 w-4" : size === "md" ? "h-5 w-5" : "h-6 w-6"
|
|
403
|
+
),
|
|
404
|
+
children: /* @__PURE__ */ jsx7(
|
|
405
|
+
"svg",
|
|
406
|
+
{
|
|
407
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
408
|
+
viewBox: "0 0 24 24",
|
|
409
|
+
fill: "none",
|
|
410
|
+
stroke: "currentColor",
|
|
411
|
+
strokeWidth: 2,
|
|
412
|
+
className: cn(size === "sm" ? "h-3 w-3" : size === "md" ? "h-4 w-4" : "h-5 w-5"),
|
|
413
|
+
children: /* @__PURE__ */ jsx7("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M6 18L18 6M6 6l12 12" })
|
|
414
|
+
}
|
|
415
|
+
)
|
|
416
|
+
}
|
|
417
|
+
)
|
|
418
|
+
]
|
|
419
|
+
}
|
|
420
|
+
);
|
|
421
|
+
}
|
|
422
|
+
);
|
|
423
|
+
Tag.displayName = "Tag";
|
|
424
|
+
|
|
425
|
+
// src/components/Select/Select.tsx
|
|
426
|
+
import * as React8 from "react";
|
|
427
|
+
import { jsx as jsx8, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
428
|
+
var Select = ({
|
|
429
|
+
items,
|
|
430
|
+
placeholder = "Select...",
|
|
431
|
+
multiselect = false,
|
|
432
|
+
multiline = false,
|
|
433
|
+
value,
|
|
434
|
+
onChange,
|
|
435
|
+
className
|
|
436
|
+
}) => {
|
|
437
|
+
const [open, setOpen] = React8.useState(false);
|
|
438
|
+
const [internalValue, setInternalValue] = React8.useState(
|
|
439
|
+
Array.isArray(value) ? value : value ? [value] : []
|
|
440
|
+
);
|
|
441
|
+
React8.useEffect(() => {
|
|
442
|
+
if (value !== void 0) {
|
|
443
|
+
setInternalValue(Array.isArray(value) ? value : value ? [value] : []);
|
|
444
|
+
}
|
|
445
|
+
}, [value]);
|
|
446
|
+
React8.useEffect(() => {
|
|
447
|
+
lastEmittedRef.current = null;
|
|
448
|
+
}, [value, multiselect]);
|
|
449
|
+
const containerRef = React8.useRef(null);
|
|
450
|
+
React8.useEffect(() => {
|
|
451
|
+
const onDoc = (e) => {
|
|
452
|
+
if (!containerRef.current) return;
|
|
453
|
+
if (!containerRef.current.contains(e.target)) setOpen(false);
|
|
454
|
+
};
|
|
455
|
+
document.addEventListener("mousedown", onDoc);
|
|
456
|
+
return () => document.removeEventListener("mousedown", onDoc);
|
|
457
|
+
}, []);
|
|
458
|
+
const isSelected = (v) => internalValue.includes(v);
|
|
459
|
+
const lastEmittedRef = React8.useRef(null);
|
|
460
|
+
const emitChange = (next) => {
|
|
461
|
+
const payload = multiselect ? JSON.stringify(next) : next[0] || "";
|
|
462
|
+
if (lastEmittedRef.current === payload) return;
|
|
463
|
+
lastEmittedRef.current = payload;
|
|
464
|
+
if (onChange) onChange(multiselect ? next : next[0] || "");
|
|
465
|
+
};
|
|
466
|
+
const toggleSelect = (v) => {
|
|
467
|
+
let next;
|
|
468
|
+
if (multiselect) {
|
|
469
|
+
next = isSelected(v) ? internalValue.filter((x) => x !== v) : [...internalValue, v];
|
|
470
|
+
} else {
|
|
471
|
+
next = isSelected(v) ? [] : [v];
|
|
472
|
+
setOpen(false);
|
|
473
|
+
}
|
|
474
|
+
emitChange(next);
|
|
475
|
+
if (value === void 0) setInternalValue(next);
|
|
476
|
+
};
|
|
477
|
+
const removeValue = (v) => {
|
|
478
|
+
const next = internalValue.filter((x) => x !== v);
|
|
479
|
+
emitChange(next);
|
|
480
|
+
if (value === void 0) setInternalValue(next);
|
|
481
|
+
};
|
|
482
|
+
const selectedItemsMap = React8.useMemo(() => {
|
|
483
|
+
const map = /* @__PURE__ */ new Map();
|
|
484
|
+
const collect = (src) => {
|
|
485
|
+
src.forEach((s) => {
|
|
486
|
+
if ("items" in s) s.items.forEach((it) => map.set(it.value, it));
|
|
487
|
+
else map.set(s.value, s);
|
|
488
|
+
});
|
|
489
|
+
};
|
|
490
|
+
collect(items);
|
|
491
|
+
return map;
|
|
492
|
+
}, [items]);
|
|
493
|
+
const tagsContainerRef = React8.useRef(null);
|
|
494
|
+
const [visibleCount, setVisibleCount] = React8.useState(null);
|
|
495
|
+
React8.useEffect(() => {
|
|
496
|
+
if (multiline) {
|
|
497
|
+
setVisibleCount(null);
|
|
498
|
+
return;
|
|
499
|
+
}
|
|
500
|
+
let raf;
|
|
501
|
+
let timeout;
|
|
502
|
+
const measure = () => {
|
|
503
|
+
if (raf) cancelAnimationFrame(raf);
|
|
504
|
+
raf = requestAnimationFrame(() => {
|
|
505
|
+
const container = tagsContainerRef.current;
|
|
506
|
+
if (!container) {
|
|
507
|
+
setVisibleCount(null);
|
|
508
|
+
return;
|
|
509
|
+
}
|
|
510
|
+
const containerWidth = container.clientWidth;
|
|
511
|
+
if (containerWidth === 0) {
|
|
512
|
+
setVisibleCount(null);
|
|
513
|
+
return;
|
|
514
|
+
}
|
|
515
|
+
const tagEls = Array.from(
|
|
516
|
+
container.querySelectorAll('[data-role="select-tag"]')
|
|
517
|
+
);
|
|
518
|
+
if (!tagEls.length) {
|
|
519
|
+
setVisibleCount(null);
|
|
520
|
+
return;
|
|
521
|
+
}
|
|
522
|
+
const badgeEl = container.querySelector('[data-role="count-badge"]');
|
|
523
|
+
const containerStyle = window.getComputedStyle(container);
|
|
524
|
+
const gap = parseFloat(containerStyle.gap || containerStyle.columnGap || "0") || 0;
|
|
525
|
+
const tagWidths = tagEls.map((el) => el.offsetWidth);
|
|
526
|
+
let totalWidthAllTags = 0;
|
|
527
|
+
for (const [i, w] of tagWidths.entries()) {
|
|
528
|
+
totalWidthAllTags += w + (i > 0 ? gap : 0);
|
|
529
|
+
}
|
|
530
|
+
if (totalWidthAllTags <= containerWidth) {
|
|
531
|
+
setVisibleCount(tagEls.length);
|
|
532
|
+
return;
|
|
533
|
+
}
|
|
534
|
+
let badgeWidth = badgeEl ? badgeEl.offsetWidth : 40;
|
|
535
|
+
let usedWidth = 0;
|
|
536
|
+
let fitCount = 0;
|
|
537
|
+
for (const [i, tagWidth] of tagWidths.entries()) {
|
|
538
|
+
const gapBeforeTag = i > 0 ? gap : 0;
|
|
539
|
+
const gapBeforeBadge = gap;
|
|
540
|
+
const effectiveTagWidth = tagWidth ?? 0;
|
|
541
|
+
const spaceNeeded = usedWidth + gapBeforeTag + effectiveTagWidth + gapBeforeBadge + badgeWidth;
|
|
542
|
+
if (spaceNeeded <= containerWidth) {
|
|
543
|
+
usedWidth += gapBeforeTag + effectiveTagWidth;
|
|
544
|
+
fitCount = i + 1;
|
|
545
|
+
} else {
|
|
546
|
+
break;
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
fitCount = Math.max(1, fitCount);
|
|
550
|
+
setVisibleCount(fitCount);
|
|
551
|
+
});
|
|
552
|
+
};
|
|
553
|
+
measure();
|
|
554
|
+
const onResize = () => {
|
|
555
|
+
if (timeout) clearTimeout(timeout);
|
|
556
|
+
timeout = window.setTimeout(measure, 50);
|
|
557
|
+
};
|
|
558
|
+
window.addEventListener("resize", onResize);
|
|
559
|
+
let ro;
|
|
560
|
+
if (typeof ResizeObserver !== "undefined" && tagsContainerRef.current) {
|
|
561
|
+
ro = new ResizeObserver(onResize);
|
|
562
|
+
ro.observe(tagsContainerRef.current);
|
|
563
|
+
}
|
|
564
|
+
return () => {
|
|
565
|
+
if (raf) cancelAnimationFrame(raf);
|
|
566
|
+
if (timeout) clearTimeout(timeout);
|
|
567
|
+
window.removeEventListener("resize", onResize);
|
|
568
|
+
ro?.disconnect();
|
|
569
|
+
};
|
|
570
|
+
}, [internalValue, multiline]);
|
|
571
|
+
return /* @__PURE__ */ jsxs4("div", { ref: containerRef, className: cn("relative inline-block w-full", className), children: [
|
|
572
|
+
/* @__PURE__ */ jsx8("div", { className: "flex items-center", children: /* @__PURE__ */ jsxs4(
|
|
573
|
+
"div",
|
|
574
|
+
{
|
|
575
|
+
role: "combobox",
|
|
576
|
+
tabIndex: 0,
|
|
577
|
+
"aria-expanded": open,
|
|
578
|
+
onClick: () => setOpen((s) => !s),
|
|
579
|
+
onKeyDown: (e) => {
|
|
580
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
581
|
+
e.preventDefault();
|
|
582
|
+
setOpen((s) => !s);
|
|
583
|
+
}
|
|
584
|
+
if (e.key === "Escape") setOpen(false);
|
|
585
|
+
},
|
|
586
|
+
className: cn(
|
|
587
|
+
"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",
|
|
588
|
+
multiselect ? "" : "",
|
|
589
|
+
open ? "ring-1 ring-gray-300" : ""
|
|
590
|
+
),
|
|
591
|
+
children: [
|
|
592
|
+
/* @__PURE__ */ jsx8("div", { className: "flex-1", children: multiselect && internalValue.length > 0 ? /* @__PURE__ */ jsxs4(
|
|
593
|
+
"span",
|
|
594
|
+
{
|
|
595
|
+
ref: tagsContainerRef,
|
|
596
|
+
className: cn(
|
|
597
|
+
"relative flex gap-1 items-center",
|
|
598
|
+
multiline ? "flex-wrap" : "overflow-hidden whitespace-nowrap"
|
|
599
|
+
),
|
|
600
|
+
children: [
|
|
601
|
+
internalValue.map((v, index) => {
|
|
602
|
+
const isHidden = !multiline && visibleCount !== null && index >= visibleCount;
|
|
603
|
+
return /* @__PURE__ */ jsx8(
|
|
604
|
+
"span",
|
|
605
|
+
{
|
|
606
|
+
"data-role": "select-tag",
|
|
607
|
+
className: cn(
|
|
608
|
+
"flex-shrink-0 inline-block",
|
|
609
|
+
isHidden && "invisible absolute pointer-events-none"
|
|
610
|
+
),
|
|
611
|
+
children: /* @__PURE__ */ jsx8(
|
|
612
|
+
Tag,
|
|
613
|
+
{
|
|
614
|
+
size: "sm",
|
|
615
|
+
removable: true,
|
|
616
|
+
removeLabel: `Remove ${selectedItemsMap.get(v)?.label ?? v}`,
|
|
617
|
+
onRemove: (e) => {
|
|
618
|
+
e.stopPropagation();
|
|
619
|
+
removeValue(v);
|
|
620
|
+
},
|
|
621
|
+
children: selectedItemsMap.get(v)?.label ?? v
|
|
622
|
+
}
|
|
623
|
+
)
|
|
624
|
+
},
|
|
625
|
+
v
|
|
626
|
+
);
|
|
627
|
+
}),
|
|
628
|
+
!multiline && visibleCount !== null && visibleCount < internalValue.length && /* @__PURE__ */ jsx8("span", { "data-role": "count-badge", className: "flex-shrink-0 inline-block", children: /* @__PURE__ */ jsxs4(Badge, { size: "sm", variant: "info", children: [
|
|
629
|
+
"+",
|
|
630
|
+
internalValue.length - visibleCount
|
|
631
|
+
] }) })
|
|
632
|
+
]
|
|
633
|
+
}
|
|
634
|
+
) : internalValue.length > 0 ? /* @__PURE__ */ jsx8("span", { className: "text-sm text-gray-900", children: selectedItemsMap.get(internalValue[0])?.label ?? placeholder }) : /* @__PURE__ */ jsx8("span", { className: "text-sm text-gray-400", children: placeholder }) }),
|
|
635
|
+
/* @__PURE__ */ jsx8("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__ */ jsx8("path", { d: "M5.5 7.5L10 12l4.5-4.5", stroke: "currentColor", strokeWidth: 1.5, strokeLinecap: "round", strokeLinejoin: "round", fill: "none" }) })
|
|
636
|
+
]
|
|
637
|
+
}
|
|
638
|
+
) }),
|
|
639
|
+
open && /* @__PURE__ */ jsx8("div", { className: "absolute z-40 mt-2 w-56 bg-white border rounded shadow-lg", children: /* @__PURE__ */ jsx8("div", { className: "p-1", children: items.map((groupOrItem, gi) => {
|
|
640
|
+
if ("items" in groupOrItem) {
|
|
641
|
+
return /* @__PURE__ */ jsxs4("div", { className: "mb-2", children: [
|
|
642
|
+
/* @__PURE__ */ jsxs4("div", { className: "flex items-center justify-between px-2 py-1 text-xs text-gray-500 font-medium", children: [
|
|
643
|
+
/* @__PURE__ */ jsx8("div", { children: groupOrItem.label }),
|
|
644
|
+
/* @__PURE__ */ jsx8("div", { children: multiselect && /* @__PURE__ */ jsx8(
|
|
645
|
+
"input",
|
|
646
|
+
{
|
|
647
|
+
type: "checkbox",
|
|
648
|
+
"aria-label": `Select all ${groupOrItem.label}`,
|
|
649
|
+
checked: groupOrItem.items.every((it) => isSelected(it.value)),
|
|
650
|
+
onChange: () => {
|
|
651
|
+
const all = groupOrItem.items.map((it) => it.value);
|
|
652
|
+
const allSelected = all.every((v) => isSelected(v));
|
|
653
|
+
let next;
|
|
654
|
+
if (multiselect) {
|
|
655
|
+
if (allSelected) {
|
|
656
|
+
next = internalValue.filter((v) => !all.includes(v));
|
|
657
|
+
} else {
|
|
658
|
+
next = [...internalValue, ...all.filter((v) => !internalValue.includes(v))];
|
|
659
|
+
}
|
|
660
|
+
} else {
|
|
661
|
+
next = allSelected ? [] : all[0] ? [all[0]] : [];
|
|
662
|
+
setOpen(false);
|
|
663
|
+
}
|
|
664
|
+
emitChange(next);
|
|
665
|
+
if (value === void 0) setInternalValue(next);
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
) })
|
|
669
|
+
] }),
|
|
670
|
+
groupOrItem.items.map((it) => /* @__PURE__ */ jsxs4(
|
|
671
|
+
"button",
|
|
672
|
+
{
|
|
673
|
+
type: "button",
|
|
674
|
+
disabled: it.disabled,
|
|
675
|
+
onClick: () => toggleSelect(it.value),
|
|
676
|
+
className: cn(
|
|
677
|
+
"w-full text-left px-2 py-2 rounded hover:bg-gray-50 flex items-center gap-2",
|
|
678
|
+
isSelected(it.value) ? "bg-gray-100" : ""
|
|
679
|
+
),
|
|
680
|
+
children: [
|
|
681
|
+
it.icon && /* @__PURE__ */ jsx8("img", { src: it.icon, alt: "", className: "h-4 w-4 rounded" }),
|
|
682
|
+
/* @__PURE__ */ jsx8("span", { className: "flex-1", children: it.label }),
|
|
683
|
+
/* @__PURE__ */ jsx8("span", { className: "w-6 flex items-center justify-end", children: isSelected(it.value) && /* @__PURE__ */ jsx8(
|
|
684
|
+
"svg",
|
|
685
|
+
{
|
|
686
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
687
|
+
viewBox: "0 0 24 24",
|
|
688
|
+
fill: "none",
|
|
689
|
+
stroke: "currentColor",
|
|
690
|
+
strokeWidth: 2,
|
|
691
|
+
className: "h-4 w-4",
|
|
692
|
+
children: /* @__PURE__ */ jsx8("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M5 13l4 4L19 7" })
|
|
693
|
+
}
|
|
694
|
+
) })
|
|
695
|
+
]
|
|
696
|
+
},
|
|
697
|
+
it.value
|
|
698
|
+
))
|
|
699
|
+
] }, gi);
|
|
700
|
+
}
|
|
701
|
+
return /* @__PURE__ */ jsxs4(
|
|
702
|
+
"button",
|
|
703
|
+
{
|
|
704
|
+
type: "button",
|
|
705
|
+
disabled: groupOrItem.disabled,
|
|
706
|
+
onClick: () => toggleSelect(groupOrItem.value),
|
|
707
|
+
className: cn(
|
|
708
|
+
"w-full text-left px-2 py-2 rounded hover:bg-gray-50 flex items-center gap-2",
|
|
709
|
+
isSelected(groupOrItem.value) ? "bg-gray-100" : ""
|
|
710
|
+
),
|
|
711
|
+
children: [
|
|
712
|
+
groupOrItem.icon && /* @__PURE__ */ jsx8("img", { src: groupOrItem.icon, alt: "", className: "h-4 w-4 rounded" }),
|
|
713
|
+
/* @__PURE__ */ jsx8("span", { className: "flex-1", children: groupOrItem.label }),
|
|
714
|
+
/* @__PURE__ */ jsx8("span", { className: "w-6 flex items-center justify-end", children: isSelected(groupOrItem.value) && /* @__PURE__ */ jsx8(
|
|
715
|
+
"svg",
|
|
716
|
+
{
|
|
717
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
718
|
+
viewBox: "0 0 24 24",
|
|
719
|
+
fill: "none",
|
|
720
|
+
stroke: "currentColor",
|
|
721
|
+
strokeWidth: 2,
|
|
722
|
+
className: "h-4 w-4",
|
|
723
|
+
children: /* @__PURE__ */ jsx8("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M5 13l4 4L19 7" })
|
|
724
|
+
}
|
|
725
|
+
) })
|
|
726
|
+
]
|
|
727
|
+
},
|
|
728
|
+
groupOrItem.value
|
|
729
|
+
);
|
|
730
|
+
}) }) })
|
|
731
|
+
] });
|
|
732
|
+
};
|
|
334
733
|
export {
|
|
335
734
|
Badge,
|
|
336
735
|
Button,
|
|
@@ -338,6 +737,8 @@ export {
|
|
|
338
737
|
Countdown,
|
|
339
738
|
Icon,
|
|
340
739
|
Input,
|
|
740
|
+
Select,
|
|
741
|
+
Tag,
|
|
341
742
|
cn
|
|
342
743
|
};
|
|
343
744
|
//# sourceMappingURL=index.js.map
|