@geomak/ui 5.4.0 → 5.5.1
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 +831 -182
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +202 -11
- package/dist/index.d.ts +202 -11
- package/dist/index.js +827 -183
- package/dist/index.js.map +1 -1
- package/dist/styles.css +59 -23
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1800,8 +1800,8 @@ function CatalogCarousel({ items, buttonText, onOpen }) {
|
|
|
1800
1800
|
)
|
|
1801
1801
|
] }) });
|
|
1802
1802
|
}
|
|
1803
|
-
function Catalog({ display = "grid", items = [], buttonText, onOpen }) {
|
|
1804
|
-
return /* @__PURE__ */ jsx("div", { className: "w-full h-full", children:
|
|
1803
|
+
function Catalog({ display: display2 = "grid", items = [], buttonText, onOpen }) {
|
|
1804
|
+
return /* @__PURE__ */ jsx("div", { className: "w-full h-full", children: display2 === "grid" ? /* @__PURE__ */ jsx(CatalogGrid, { items, buttonText, onOpen }) : /* @__PURE__ */ jsx(CatalogCarousel, { items, buttonText, onOpen }) });
|
|
1805
1805
|
}
|
|
1806
1806
|
function ContextMenu({ items, children }) {
|
|
1807
1807
|
return /* @__PURE__ */ jsxs(ContextMenuPrimitive.Root, { children: [
|
|
@@ -2140,9 +2140,9 @@ var FIELD_SIZE = {
|
|
|
2140
2140
|
lg: { control: "h-control-lg", text: "text-sm", padX: "px-3.5", gap: "gap-2.5" }
|
|
2141
2141
|
};
|
|
2142
2142
|
var FOCUS_WITHIN = "focus-within:outline-none focus-within:border-accent focus-within:ring-[3px] focus-within:ring-focus-ring";
|
|
2143
|
-
var
|
|
2143
|
+
var FOCUS_ELEMENT = "focus:outline-none focus:border-accent focus:ring-[3px] focus:ring-focus-ring data-[state=open]:border-accent data-[state=open]:ring-[3px] data-[state=open]:ring-focus-ring";
|
|
2144
2144
|
var FOCUS_WITHIN_ERROR = "focus-within:border-status-error focus-within:ring-focus-ring-error";
|
|
2145
|
-
var
|
|
2145
|
+
var FOCUS_ELEMENT_ERROR = "focus:border-status-error focus:ring-focus-ring-error data-[state=open]:border-status-error data-[state=open]:ring-focus-ring-error";
|
|
2146
2146
|
function fieldShell({
|
|
2147
2147
|
size = "md",
|
|
2148
2148
|
hasError = false,
|
|
@@ -2161,8 +2161,8 @@ function fieldShell({
|
|
|
2161
2161
|
// hover (only when interactive + no error)
|
|
2162
2162
|
disabled ? "bg-surface-raised text-foreground-muted cursor-not-allowed" : hasError ? "" : "hover:border-border-strong",
|
|
2163
2163
|
// focus
|
|
2164
|
-
focusWithin ? FOCUS_WITHIN :
|
|
2165
|
-
hasError ? focusWithin ? FOCUS_WITHIN_ERROR :
|
|
2164
|
+
focusWithin ? FOCUS_WITHIN : FOCUS_ELEMENT,
|
|
2165
|
+
hasError ? focusWithin ? FOCUS_WITHIN_ERROR : FOCUS_ELEMENT_ERROR : "",
|
|
2166
2166
|
// placeholder colour for native inputs
|
|
2167
2167
|
"placeholder:text-foreground-muted"
|
|
2168
2168
|
].filter(Boolean).join(" ");
|
|
@@ -2197,7 +2197,9 @@ function Field({
|
|
|
2197
2197
|
style: { width: horizontal ? labelWidth : void 0, ...labelStyle },
|
|
2198
2198
|
className: [
|
|
2199
2199
|
"text-sm font-medium text-foreground select-none",
|
|
2200
|
-
horizontal
|
|
2200
|
+
// In horizontal layout the label must not wrap onto
|
|
2201
|
+
// multiple lines (e.g. "Report date", "Select option").
|
|
2202
|
+
horizontal ? "mt-2 flex-shrink-0 whitespace-nowrap" : ""
|
|
2201
2203
|
].filter(Boolean).join(" "),
|
|
2202
2204
|
children: [
|
|
2203
2205
|
label,
|
|
@@ -2243,14 +2245,24 @@ var SearchInput = React8.forwardRef(function SearchInput2({ value, onChange, dis
|
|
|
2243
2245
|
) });
|
|
2244
2246
|
});
|
|
2245
2247
|
var SearchInput_default = SearchInput;
|
|
2246
|
-
function
|
|
2247
|
-
return /* @__PURE__ */
|
|
2248
|
-
"
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2248
|
+
function Tag({ children, onRemove, removeLabel, disabled }) {
|
|
2249
|
+
return /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1 rounded-md border border-border bg-surface-raised text-foreground text-xs pl-2 pr-1 py-0.5 max-w-full", children: [
|
|
2250
|
+
/* @__PURE__ */ jsx("span", { className: "truncate", children }),
|
|
2251
|
+
onRemove && /* @__PURE__ */ jsx(
|
|
2252
|
+
"button",
|
|
2253
|
+
{
|
|
2254
|
+
type: "button",
|
|
2255
|
+
disabled,
|
|
2256
|
+
onClick: (e) => {
|
|
2257
|
+
e.stopPropagation();
|
|
2258
|
+
onRemove();
|
|
2259
|
+
},
|
|
2260
|
+
"aria-label": removeLabel ?? "Remove",
|
|
2261
|
+
className: "inline-flex items-center justify-center w-4 h-4 flex-shrink-0 rounded text-foreground-muted hover:text-status-error hover:bg-surface transition-colors focus:outline-none focus-visible:ring-1 focus-visible:ring-accent disabled:cursor-not-allowed",
|
|
2262
|
+
children: /* @__PURE__ */ jsx("svg", { width: "10", height: "10", viewBox: "0 0 20 20", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx("path", { d: "M15 5L5 15M5 5l10 10", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }) })
|
|
2263
|
+
}
|
|
2264
|
+
)
|
|
2265
|
+
] });
|
|
2254
2266
|
}
|
|
2255
2267
|
function Dropdown({
|
|
2256
2268
|
isMultiselect = false,
|
|
@@ -2267,7 +2279,6 @@ function Dropdown({
|
|
|
2267
2279
|
items = [],
|
|
2268
2280
|
labelStyle = {},
|
|
2269
2281
|
placeholder,
|
|
2270
|
-
showSelectedCount = false,
|
|
2271
2282
|
size = "md"
|
|
2272
2283
|
}) {
|
|
2273
2284
|
const [open, setOpen] = useState(false);
|
|
@@ -2295,6 +2306,17 @@ function Dropdown({
|
|
|
2295
2306
|
setOpen(false);
|
|
2296
2307
|
}
|
|
2297
2308
|
};
|
|
2309
|
+
const removeSelected = (key) => {
|
|
2310
|
+
if (isMultiselect) {
|
|
2311
|
+
const next = selectedItems.filter((it) => it !== key);
|
|
2312
|
+
setSelectedItems(next);
|
|
2313
|
+
onChange?.({ target: { value: next, id: htmlFor, name } });
|
|
2314
|
+
} else {
|
|
2315
|
+
setSelectedItems([]);
|
|
2316
|
+
onChange?.({ target: { value: "", id: htmlFor, name } });
|
|
2317
|
+
}
|
|
2318
|
+
};
|
|
2319
|
+
const labelFor = (key) => innerItems.find((it) => it.key === key)?.label ?? String(key);
|
|
2298
2320
|
const onSearchChange = (e) => {
|
|
2299
2321
|
const term = e.target.value;
|
|
2300
2322
|
setSearchTerm(term);
|
|
@@ -2305,16 +2327,16 @@ function Dropdown({
|
|
|
2305
2327
|
);
|
|
2306
2328
|
};
|
|
2307
2329
|
const isSelected = (key) => Array.isArray(value) ? value.includes(key) : value === key;
|
|
2308
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
2330
|
+
return /* @__PURE__ */ jsxs("div", { children: [
|
|
2309
2331
|
/* @__PURE__ */ jsxs(
|
|
2310
2332
|
"div",
|
|
2311
2333
|
{
|
|
2312
|
-
className: `flex ${layout === "vertical" ? "flex-col" : "flex-row items-
|
|
2334
|
+
className: `flex ${layout === "vertical" ? "flex-col gap-1.5" : "flex-row items-start gap-3"}`,
|
|
2313
2335
|
children: [
|
|
2314
2336
|
label && /* @__PURE__ */ jsx(
|
|
2315
2337
|
"label",
|
|
2316
2338
|
{
|
|
2317
|
-
className:
|
|
2339
|
+
className: `text-sm font-medium select-none text-foreground ${layout === "horizontal" ? "mt-2 flex-shrink-0 whitespace-nowrap" : ""}`,
|
|
2318
2340
|
htmlFor,
|
|
2319
2341
|
style: labelStyle,
|
|
2320
2342
|
children: label
|
|
@@ -2331,7 +2353,7 @@ function Dropdown({
|
|
|
2331
2353
|
"aria-invalid": hasError || void 0,
|
|
2332
2354
|
"aria-describedby": hasError ? errorId : void 0,
|
|
2333
2355
|
style,
|
|
2334
|
-
className: `flex items-center justify-between cursor-pointer select-none ${fieldShell({ size, hasError, disabled })}`,
|
|
2356
|
+
className: `flex items-center justify-between gap-1 cursor-pointer select-none min-h-[36px] px-3 py-1.5 ${fieldShell({ size, hasError, disabled, sized: false })}`,
|
|
2335
2357
|
tabIndex: disabled ? -1 : 0,
|
|
2336
2358
|
onKeyDown: (e) => {
|
|
2337
2359
|
if (disabled) return;
|
|
@@ -2344,18 +2366,25 @@ function Dropdown({
|
|
|
2344
2366
|
/* @__PURE__ */ jsx(
|
|
2345
2367
|
"div",
|
|
2346
2368
|
{
|
|
2347
|
-
className: `${!style?.width ? "min-w-[200px]" : ""} flex items-center gap-1
|
|
2348
|
-
children: !value || Array.isArray(value) && value.length === 0 ? /* @__PURE__ */ jsx("span", { className: "text-foreground-muted text-sm", children: placeholder }) : Array.isArray(value) ? /* @__PURE__ */
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
)
|
|
2357
|
-
|
|
2358
|
-
|
|
2369
|
+
className: `${!style?.width ? "min-w-[200px]" : ""} flex flex-wrap items-center gap-1.5`,
|
|
2370
|
+
children: !value || Array.isArray(value) && value.length === 0 ? /* @__PURE__ */ jsx("span", { className: "text-foreground-muted text-sm", children: placeholder }) : Array.isArray(value) ? value.map((val) => /* @__PURE__ */ jsx(
|
|
2371
|
+
Tag,
|
|
2372
|
+
{
|
|
2373
|
+
disabled,
|
|
2374
|
+
removeLabel: `Remove ${labelFor(val)}`,
|
|
2375
|
+
onRemove: () => removeSelected(val),
|
|
2376
|
+
children: labelFor(val)
|
|
2377
|
+
},
|
|
2378
|
+
String(val)
|
|
2379
|
+
)) : /* @__PURE__ */ jsx(
|
|
2380
|
+
Tag,
|
|
2381
|
+
{
|
|
2382
|
+
disabled,
|
|
2383
|
+
removeLabel: `Remove ${labelFor(value)}`,
|
|
2384
|
+
onRemove: () => removeSelected(value),
|
|
2385
|
+
children: labelFor(value)
|
|
2386
|
+
}
|
|
2387
|
+
)
|
|
2359
2388
|
}
|
|
2360
2389
|
),
|
|
2361
2390
|
/* @__PURE__ */ jsx("div", { className: `flex-shrink-0 ml-2 text-foreground-muted transition-transform duration-200 ${open ? "rotate-180" : "rotate-0"}`, "aria-hidden": "true", children: /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, className: "h-4 w-4", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M19 9l-7 7-7-7" }) }) })
|
|
@@ -3549,74 +3578,54 @@ function Checkbox({
|
|
|
3549
3578
|
name,
|
|
3550
3579
|
htmlFor,
|
|
3551
3580
|
errorMessage,
|
|
3552
|
-
disabled = false
|
|
3581
|
+
disabled = false,
|
|
3582
|
+
layout = "horizontal",
|
|
3583
|
+
labelPosition = "right"
|
|
3553
3584
|
}) {
|
|
3554
3585
|
const isChecked = checked ?? value ?? false;
|
|
3586
|
+
const labelFirst = labelPosition === "left";
|
|
3587
|
+
const box = /* @__PURE__ */ jsx(
|
|
3588
|
+
CheckboxPrimitive.Root,
|
|
3589
|
+
{
|
|
3590
|
+
id: htmlFor,
|
|
3591
|
+
name,
|
|
3592
|
+
checked: isChecked,
|
|
3593
|
+
disabled,
|
|
3594
|
+
onCheckedChange: (c) => onChange?.({ target: { checked: !!c, id: htmlFor, name } }),
|
|
3595
|
+
className: [
|
|
3596
|
+
"relative flex h-[18px] w-[18px] flex-shrink-0 items-center justify-center",
|
|
3597
|
+
"rounded-sm border transition-colors duration-150",
|
|
3598
|
+
"border-border-strong bg-surface",
|
|
3599
|
+
"data-[state=checked]:bg-accent data-[state=checked]:border-accent",
|
|
3600
|
+
// Focus halo matches the field tokens for a consistent look.
|
|
3601
|
+
"focus:outline-none focus-visible:ring-[3px] focus-visible:ring-focus-ring",
|
|
3602
|
+
"disabled:cursor-not-allowed"
|
|
3603
|
+
].join(" "),
|
|
3604
|
+
"aria-label": typeof label === "string" ? label : void 0,
|
|
3605
|
+
children: /* @__PURE__ */ jsx(CheckboxPrimitive.Indicator, { className: "flex items-center justify-center data-[state=checked]:animate-check-pop", children: /* @__PURE__ */ jsx("svg", { width: "11", height: "9", viewBox: "0 0 11 9", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx("path", { d: "M1 4.5L4 7.5L10 1", stroke: "white", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round" }) }) })
|
|
3606
|
+
}
|
|
3607
|
+
);
|
|
3608
|
+
const labelEl = label && /* @__PURE__ */ jsx("span", { className: "text-sm text-foreground-secondary select-none leading-snug", children: label });
|
|
3555
3609
|
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
3556
|
-
/* @__PURE__ */
|
|
3610
|
+
/* @__PURE__ */ jsx(
|
|
3557
3611
|
"label",
|
|
3558
3612
|
{
|
|
3559
3613
|
htmlFor,
|
|
3560
3614
|
className: [
|
|
3561
|
-
"inline-flex
|
|
3615
|
+
"inline-flex",
|
|
3616
|
+
layout === "vertical" ? "flex-col items-start gap-1.5" : "flex-row items-center gap-2.5",
|
|
3562
3617
|
disabled ? "cursor-not-allowed opacity-50" : "cursor-pointer"
|
|
3563
3618
|
].join(" "),
|
|
3564
|
-
children: [
|
|
3565
|
-
|
|
3566
|
-
|
|
3567
|
-
|
|
3568
|
-
|
|
3569
|
-
|
|
3570
|
-
|
|
3571
|
-
disabled,
|
|
3572
|
-
onCheckedChange: (c) => onChange?.({ target: { checked: !!c, id: htmlFor, name } }),
|
|
3573
|
-
className: [
|
|
3574
|
-
// Box
|
|
3575
|
-
"relative flex h-[18px] w-[18px] flex-shrink-0 items-center justify-center",
|
|
3576
|
-
"rounded-sm border transition-colors duration-150",
|
|
3577
|
-
// Unchecked
|
|
3578
|
-
"border-border-strong bg-surface",
|
|
3579
|
-
// Checked
|
|
3580
|
-
"data-[state=checked]:bg-accent data-[state=checked]:border-accent",
|
|
3581
|
-
// Focus
|
|
3582
|
-
"focus:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-1",
|
|
3583
|
-
// Disabled
|
|
3584
|
-
"disabled:cursor-not-allowed"
|
|
3585
|
-
].join(" "),
|
|
3586
|
-
"aria-label": typeof label === "string" ? label : void 0,
|
|
3587
|
-
children: /* @__PURE__ */ jsx(
|
|
3588
|
-
CheckboxPrimitive.Indicator,
|
|
3589
|
-
{
|
|
3590
|
-
className: "flex items-center justify-center data-[state=checked]:animate-check-pop",
|
|
3591
|
-
children: /* @__PURE__ */ jsx(
|
|
3592
|
-
"svg",
|
|
3593
|
-
{
|
|
3594
|
-
width: "11",
|
|
3595
|
-
height: "9",
|
|
3596
|
-
viewBox: "0 0 11 9",
|
|
3597
|
-
fill: "none",
|
|
3598
|
-
"aria-hidden": "true",
|
|
3599
|
-
children: /* @__PURE__ */ jsx(
|
|
3600
|
-
"path",
|
|
3601
|
-
{
|
|
3602
|
-
d: "M1 4.5L4 7.5L10 1",
|
|
3603
|
-
stroke: "white",
|
|
3604
|
-
strokeWidth: "1.8",
|
|
3605
|
-
strokeLinecap: "round",
|
|
3606
|
-
strokeLinejoin: "round"
|
|
3607
|
-
}
|
|
3608
|
-
)
|
|
3609
|
-
}
|
|
3610
|
-
)
|
|
3611
|
-
}
|
|
3612
|
-
)
|
|
3613
|
-
}
|
|
3614
|
-
),
|
|
3615
|
-
label && /* @__PURE__ */ jsx("span", { className: "text-sm text-foreground-secondary select-none leading-snug", children: label })
|
|
3616
|
-
]
|
|
3619
|
+
children: labelFirst ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3620
|
+
labelEl,
|
|
3621
|
+
box
|
|
3622
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3623
|
+
box,
|
|
3624
|
+
labelEl
|
|
3625
|
+
] })
|
|
3617
3626
|
}
|
|
3618
3627
|
),
|
|
3619
|
-
errorMessage && /* @__PURE__ */ jsx("span", { className: "text-xs text-status-error
|
|
3628
|
+
errorMessage && /* @__PURE__ */ jsx("span", { className: "text-xs text-status-error mt-0.5", children: errorMessage })
|
|
3620
3629
|
] });
|
|
3621
3630
|
}
|
|
3622
3631
|
var DOT_SIZE = {
|
|
@@ -3722,12 +3731,12 @@ function Switch({
|
|
|
3722
3731
|
id,
|
|
3723
3732
|
checked,
|
|
3724
3733
|
onCheckedChange: (c) => onChange?.({ target: { checked: c } }),
|
|
3725
|
-
className: "relative inline-flex h-6 w-
|
|
3734
|
+
className: "relative inline-flex h-6 w-11 flex-shrink-0 items-center rounded-full bg-foreground-secondary data-[state=checked]:bg-accent transition-colors focus:outline-none focus-visible:ring-[3px] focus-visible:ring-focus-ring",
|
|
3726
3735
|
children: /* @__PURE__ */ jsx(
|
|
3727
3736
|
SwitchPrimitive.Thumb,
|
|
3728
3737
|
{
|
|
3729
|
-
className: "pointer-events-none
|
|
3730
|
-
children: checkedIcon && uncheckedIcon ? checked ? checkedIcon : uncheckedIcon : null
|
|
3738
|
+
className: "pointer-events-none flex h-5 w-5 items-center justify-center rounded-full bg-background text-foreground shadow transition-transform duration-200 data-[state=checked]:translate-x-[22px] data-[state=unchecked]:translate-x-[2px]",
|
|
3739
|
+
children: checkedIcon && uncheckedIcon ? checked ? /* @__PURE__ */ jsx("span", { className: "flex items-center justify-center w-3 h-3", children: checkedIcon }) : /* @__PURE__ */ jsx("span", { className: "flex items-center justify-center w-3 h-3", children: uncheckedIcon }) : null
|
|
3731
3740
|
}
|
|
3732
3741
|
)
|
|
3733
3742
|
}
|
|
@@ -3748,8 +3757,13 @@ function AutoComplete({
|
|
|
3748
3757
|
emptyText = "No results found",
|
|
3749
3758
|
loadingText = "Searching\u2026",
|
|
3750
3759
|
size = "md",
|
|
3751
|
-
icon
|
|
3760
|
+
icon,
|
|
3761
|
+
errorMessage,
|
|
3762
|
+
required,
|
|
3763
|
+
htmlFor
|
|
3752
3764
|
}) {
|
|
3765
|
+
const errorId = useId();
|
|
3766
|
+
const hasError = errorMessage != null;
|
|
3753
3767
|
const [term, setTerm] = useState("");
|
|
3754
3768
|
const [open, setOpen] = useState(false);
|
|
3755
3769
|
const [asyncItems, setAsyncItems] = useState([]);
|
|
@@ -3796,78 +3810,82 @@ function AutoComplete({
|
|
|
3796
3810
|
onItemClick?.(item.value);
|
|
3797
3811
|
setOpen(false);
|
|
3798
3812
|
};
|
|
3799
|
-
return /* @__PURE__ */
|
|
3800
|
-
|
|
3813
|
+
return /* @__PURE__ */ jsx(
|
|
3814
|
+
Field,
|
|
3801
3815
|
{
|
|
3802
|
-
|
|
3803
|
-
|
|
3804
|
-
|
|
3805
|
-
|
|
3806
|
-
|
|
3807
|
-
|
|
3808
|
-
|
|
3809
|
-
|
|
3810
|
-
|
|
3811
|
-
|
|
3812
|
-
value: term,
|
|
3813
|
-
onChange: (e) => {
|
|
3814
|
-
setTerm(e.target.value);
|
|
3815
|
-
setOpen(true);
|
|
3816
|
-
},
|
|
3817
|
-
onFocus: () => setOpen(true),
|
|
3818
|
-
type: "text",
|
|
3819
|
-
name,
|
|
3820
|
-
className: "min-w-0 flex-1 bg-transparent outline-none disabled:cursor-not-allowed placeholder:text-foreground-muted",
|
|
3821
|
-
style: inputStyle,
|
|
3822
|
-
placeholder: placeholder ?? "",
|
|
3823
|
-
autoComplete: "off",
|
|
3824
|
-
"aria-haspopup": "listbox",
|
|
3825
|
-
"aria-expanded": open,
|
|
3826
|
-
"aria-autocomplete": "list",
|
|
3827
|
-
"aria-busy": loading || void 0
|
|
3828
|
-
}
|
|
3829
|
-
),
|
|
3830
|
-
loading ? /* @__PURE__ */ jsx("span", { className: "ml-2 w-4 h-4 flex-shrink-0 flex items-center justify-center text-accent", "aria-hidden": "true", children: /* @__PURE__ */ jsx(LoadingSpinner, { inline: true, size: "xs", spinnerColor: "currentColor" }) }) : /* @__PURE__ */ jsx("span", { className: "ml-2 flex-shrink-0 text-foreground-muted", children: icon ?? /* @__PURE__ */ jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", className: "w-4 h-4", "aria-hidden": "true", children: /* @__PURE__ */ jsx("path", { fillRule: "evenodd", d: "M10.5 3.75a6.75 6.75 0 100 13.5 6.75 6.75 0 000-13.5zM2.25 10.5a8.25 8.25 0 1114.59 5.28l4.69 4.69a.75.75 0 11-1.06 1.06l-4.69-4.69A8.25 8.25 0 012.25 10.5z", clipRule: "evenodd" }) }) })
|
|
3831
|
-
] }) }),
|
|
3832
|
-
/* @__PURE__ */ jsx(Popover.Portal, { children: /* @__PURE__ */ jsx(
|
|
3833
|
-
Popover.Content,
|
|
3816
|
+
label,
|
|
3817
|
+
htmlFor,
|
|
3818
|
+
errorId,
|
|
3819
|
+
errorMessage,
|
|
3820
|
+
layout,
|
|
3821
|
+
required,
|
|
3822
|
+
children: /* @__PURE__ */ jsxs(Popover.Root, { open: open && !disabled, onOpenChange: (o) => !disabled && setOpen(o), children: [
|
|
3823
|
+
/* @__PURE__ */ jsx(Popover.Anchor, { asChild: true, children: /* @__PURE__ */ jsxs("div", { className: `flex items-center ${fieldShell({ size, hasError, disabled, focusWithin: true })}`, style, children: [
|
|
3824
|
+
/* @__PURE__ */ jsx(
|
|
3825
|
+
"input",
|
|
3834
3826
|
{
|
|
3835
|
-
|
|
3836
|
-
|
|
3837
|
-
|
|
3838
|
-
|
|
3839
|
-
|
|
3840
|
-
|
|
3841
|
-
|
|
3842
|
-
|
|
3843
|
-
|
|
3844
|
-
|
|
3845
|
-
|
|
3846
|
-
|
|
3847
|
-
|
|
3848
|
-
|
|
3849
|
-
|
|
3850
|
-
|
|
3851
|
-
|
|
3852
|
-
|
|
3853
|
-
|
|
3854
|
-
|
|
3855
|
-
children: [
|
|
3856
|
-
item.icon,
|
|
3857
|
-
/* @__PURE__ */ jsxs("span", { children: [
|
|
3858
|
-
item.label,
|
|
3859
|
-
" (",
|
|
3860
|
-
item.value,
|
|
3861
|
-
")"
|
|
3862
|
-
] })
|
|
3863
|
-
]
|
|
3864
|
-
},
|
|
3865
|
-
item.key
|
|
3866
|
-
)) })
|
|
3827
|
+
id: htmlFor,
|
|
3828
|
+
disabled,
|
|
3829
|
+
value: term,
|
|
3830
|
+
onChange: (e) => {
|
|
3831
|
+
setTerm(e.target.value);
|
|
3832
|
+
setOpen(true);
|
|
3833
|
+
},
|
|
3834
|
+
onFocus: () => setOpen(true),
|
|
3835
|
+
type: "text",
|
|
3836
|
+
name,
|
|
3837
|
+
className: "min-w-0 flex-1 bg-transparent outline-none disabled:cursor-not-allowed placeholder:text-foreground-muted",
|
|
3838
|
+
style: inputStyle,
|
|
3839
|
+
placeholder: placeholder ?? "",
|
|
3840
|
+
autoComplete: "off",
|
|
3841
|
+
"aria-haspopup": "listbox",
|
|
3842
|
+
"aria-expanded": open,
|
|
3843
|
+
"aria-autocomplete": "list",
|
|
3844
|
+
"aria-busy": loading || void 0,
|
|
3845
|
+
"aria-invalid": hasError || void 0,
|
|
3846
|
+
"aria-describedby": hasError ? errorId : void 0
|
|
3867
3847
|
}
|
|
3868
|
-
)
|
|
3869
|
-
|
|
3870
|
-
|
|
3848
|
+
),
|
|
3849
|
+
loading ? /* @__PURE__ */ jsx("span", { className: "ml-2 w-4 h-4 flex-shrink-0 flex items-center justify-center text-accent", "aria-hidden": "true", children: /* @__PURE__ */ jsx(LoadingSpinner, { inline: true, size: "xs", spinnerColor: "currentColor" }) }) : /* @__PURE__ */ jsx("span", { className: "ml-2 flex-shrink-0 text-foreground-muted", children: icon ?? /* @__PURE__ */ jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", className: "w-4 h-4", "aria-hidden": "true", children: /* @__PURE__ */ jsx("path", { fillRule: "evenodd", d: "M10.5 3.75a6.75 6.75 0 100 13.5 6.75 6.75 0 000-13.5zM2.25 10.5a8.25 8.25 0 1114.59 5.28l4.69 4.69a.75.75 0 11-1.06 1.06l-4.69-4.69A8.25 8.25 0 012.25 10.5z", clipRule: "evenodd" }) }) })
|
|
3850
|
+
] }) }),
|
|
3851
|
+
/* @__PURE__ */ jsx(Popover.Portal, { children: /* @__PURE__ */ jsx(
|
|
3852
|
+
Popover.Content,
|
|
3853
|
+
{
|
|
3854
|
+
align: "start",
|
|
3855
|
+
sideOffset: 4,
|
|
3856
|
+
onOpenAutoFocus: (e) => e.preventDefault(),
|
|
3857
|
+
className: "w-64 bg-surface border border-border rounded-lg mt-1 shadow-md z-50 overflow-y-auto max-h-36 animate-in fade-in-0 zoom-in-95",
|
|
3858
|
+
children: loading ? /* @__PURE__ */ jsxs("div", { className: "h-full w-full flex items-center justify-center gap-2 py-4 text-sm text-foreground-secondary", children: [
|
|
3859
|
+
/* @__PURE__ */ jsx(LoadingSpinner, { inline: true, size: "xs" }),
|
|
3860
|
+
/* @__PURE__ */ jsx("span", { children: loadingText })
|
|
3861
|
+
] }) : foundItems.length === 0 ? /* @__PURE__ */ jsx("div", { className: "h-full w-full flex flex-col items-center justify-center py-4 text-sm text-foreground-secondary", children: emptyText }) : /* @__PURE__ */ jsx("div", { role: "listbox", children: foundItems.map((item) => /* @__PURE__ */ jsxs(
|
|
3862
|
+
"div",
|
|
3863
|
+
{
|
|
3864
|
+
role: "option",
|
|
3865
|
+
tabIndex: 0,
|
|
3866
|
+
className: "text-sm flex items-center gap-2 p-2 transition-colors duration-150 hover:bg-surface-raised cursor-pointer text-foreground focus:outline-none focus-visible:ring-2 focus-visible:ring-accent",
|
|
3867
|
+
onClick: () => handleSelect(item),
|
|
3868
|
+
onKeyDown: (e) => {
|
|
3869
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
3870
|
+
e.preventDefault();
|
|
3871
|
+
handleSelect(item);
|
|
3872
|
+
}
|
|
3873
|
+
},
|
|
3874
|
+
children: [
|
|
3875
|
+
item.icon,
|
|
3876
|
+
/* @__PURE__ */ jsxs("span", { children: [
|
|
3877
|
+
item.label,
|
|
3878
|
+
" (",
|
|
3879
|
+
item.value,
|
|
3880
|
+
")"
|
|
3881
|
+
] })
|
|
3882
|
+
]
|
|
3883
|
+
},
|
|
3884
|
+
item.key
|
|
3885
|
+
)) })
|
|
3886
|
+
}
|
|
3887
|
+
) })
|
|
3888
|
+
] })
|
|
3871
3889
|
}
|
|
3872
3890
|
);
|
|
3873
3891
|
}
|
|
@@ -4947,27 +4965,13 @@ function TagsInput({
|
|
|
4947
4965
|
className: `flex flex-wrap items-center gap-1.5 min-h-[36px] ${fieldShell({ size, hasError, disabled, focusWithin: true, sized: false })} px-2 py-1.5`,
|
|
4948
4966
|
onClick: () => inputRef.current?.focus(),
|
|
4949
4967
|
children: [
|
|
4950
|
-
tags.map((tag, idx) => /* @__PURE__ */
|
|
4951
|
-
|
|
4968
|
+
tags.map((tag, idx) => /* @__PURE__ */ jsx(
|
|
4969
|
+
Tag,
|
|
4952
4970
|
{
|
|
4953
|
-
|
|
4954
|
-
|
|
4955
|
-
|
|
4956
|
-
|
|
4957
|
-
"button",
|
|
4958
|
-
{
|
|
4959
|
-
type: "button",
|
|
4960
|
-
disabled,
|
|
4961
|
-
onClick: (e) => {
|
|
4962
|
-
e.stopPropagation();
|
|
4963
|
-
removeTag(idx);
|
|
4964
|
-
},
|
|
4965
|
-
"aria-label": `Remove ${tag}`,
|
|
4966
|
-
className: "inline-flex items-center justify-center w-4 h-4 rounded text-foreground-muted hover:text-status-error hover:bg-surface transition-colors focus:outline-none focus-visible:ring-1 focus-visible:ring-accent",
|
|
4967
|
-
children: /* @__PURE__ */ jsx("svg", { width: "10", height: "10", viewBox: "0 0 20 20", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx("path", { d: "M15 5L5 15M5 5l10 10", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }) })
|
|
4968
|
-
}
|
|
4969
|
-
)
|
|
4970
|
-
]
|
|
4971
|
+
disabled,
|
|
4972
|
+
removeLabel: `Remove ${tag}`,
|
|
4973
|
+
onRemove: () => removeTag(idx),
|
|
4974
|
+
children: tag
|
|
4971
4975
|
},
|
|
4972
4976
|
`${tag}-${idx}`
|
|
4973
4977
|
)),
|
|
@@ -5001,7 +5005,647 @@ function TagsInput({
|
|
|
5001
5005
|
}
|
|
5002
5006
|
);
|
|
5003
5007
|
}
|
|
5008
|
+
var BOX_SIZE = {
|
|
5009
|
+
sm: "h-9 w-8 text-sm",
|
|
5010
|
+
md: "h-11 w-10 text-base",
|
|
5011
|
+
lg: "h-14 w-12 text-lg"
|
|
5012
|
+
};
|
|
5013
|
+
function OtpInput({
|
|
5014
|
+
length = 6,
|
|
5015
|
+
value = "",
|
|
5016
|
+
onChange,
|
|
5017
|
+
onComplete,
|
|
5018
|
+
label,
|
|
5019
|
+
htmlFor,
|
|
5020
|
+
name,
|
|
5021
|
+
mode = "numeric",
|
|
5022
|
+
masked = false,
|
|
5023
|
+
size = "md",
|
|
5024
|
+
disabled,
|
|
5025
|
+
errorMessage,
|
|
5026
|
+
required,
|
|
5027
|
+
groupAfter
|
|
5028
|
+
}) {
|
|
5029
|
+
const errorId = useId();
|
|
5030
|
+
const hasError = errorMessage != null;
|
|
5031
|
+
const refs = useRef([]);
|
|
5032
|
+
const chars = Array.from({ length }, (_, i) => value[i] ?? "");
|
|
5033
|
+
const pattern = mode === "numeric" ? /[0-9]/ : /[a-zA-Z0-9]/;
|
|
5034
|
+
const emit = (next) => {
|
|
5035
|
+
onChange?.(next);
|
|
5036
|
+
if (next.length === length && !next.includes(" ") && [...next].every(Boolean)) {
|
|
5037
|
+
onComplete?.(next);
|
|
5038
|
+
}
|
|
5039
|
+
};
|
|
5040
|
+
const setCharAt = (idx, char) => {
|
|
5041
|
+
const arr = chars.slice();
|
|
5042
|
+
arr[idx] = char;
|
|
5043
|
+
emit(arr.join(""));
|
|
5044
|
+
};
|
|
5045
|
+
const focusBox = (idx) => {
|
|
5046
|
+
const el = refs.current[Math.max(0, Math.min(length - 1, idx))];
|
|
5047
|
+
el?.focus();
|
|
5048
|
+
el?.select();
|
|
5049
|
+
};
|
|
5050
|
+
const onBoxChange = (idx, raw) => {
|
|
5051
|
+
const char = raw.slice(-1);
|
|
5052
|
+
if (char && !pattern.test(char)) return;
|
|
5053
|
+
setCharAt(idx, char);
|
|
5054
|
+
if (char) focusBox(idx + 1);
|
|
5055
|
+
};
|
|
5056
|
+
const onKeyDown = (idx, e) => {
|
|
5057
|
+
if (e.key === "Backspace") {
|
|
5058
|
+
if (chars[idx]) {
|
|
5059
|
+
setCharAt(idx, "");
|
|
5060
|
+
} else if (idx > 0) {
|
|
5061
|
+
setCharAt(idx - 1, "");
|
|
5062
|
+
focusBox(idx - 1);
|
|
5063
|
+
}
|
|
5064
|
+
} else if (e.key === "ArrowLeft") {
|
|
5065
|
+
e.preventDefault();
|
|
5066
|
+
focusBox(idx - 1);
|
|
5067
|
+
} else if (e.key === "ArrowRight") {
|
|
5068
|
+
e.preventDefault();
|
|
5069
|
+
focusBox(idx + 1);
|
|
5070
|
+
}
|
|
5071
|
+
};
|
|
5072
|
+
const onPaste = (e) => {
|
|
5073
|
+
e.preventDefault();
|
|
5074
|
+
const text = e.clipboardData.getData("text").trim();
|
|
5075
|
+
const valid = [...text].filter((c) => pattern.test(c)).slice(0, length);
|
|
5076
|
+
if (valid.length === 0) return;
|
|
5077
|
+
emit(valid.join(""));
|
|
5078
|
+
focusBox(valid.length);
|
|
5079
|
+
};
|
|
5080
|
+
return /* @__PURE__ */ jsx(Field, { label, htmlFor, errorId, errorMessage, required, children: /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2", role: "group", "aria-label": typeof label === "string" ? label : "One-time code", children: chars.map((char, idx) => /* @__PURE__ */ jsxs(React8.Fragment, { children: [
|
|
5081
|
+
/* @__PURE__ */ jsx(
|
|
5082
|
+
"input",
|
|
5083
|
+
{
|
|
5084
|
+
ref: (el) => {
|
|
5085
|
+
refs.current[idx] = el;
|
|
5086
|
+
},
|
|
5087
|
+
id: idx === 0 ? htmlFor : void 0,
|
|
5088
|
+
name: idx === 0 ? name : void 0,
|
|
5089
|
+
value: char,
|
|
5090
|
+
disabled,
|
|
5091
|
+
inputMode: mode === "numeric" ? "numeric" : "text",
|
|
5092
|
+
autoComplete: idx === 0 ? "one-time-code" : "off",
|
|
5093
|
+
type: masked && char ? "password" : "text",
|
|
5094
|
+
maxLength: 1,
|
|
5095
|
+
"aria-label": `Digit ${idx + 1}`,
|
|
5096
|
+
"aria-invalid": hasError || void 0,
|
|
5097
|
+
"aria-describedby": hasError ? errorId : void 0,
|
|
5098
|
+
onChange: (e) => onBoxChange(idx, e.target.value),
|
|
5099
|
+
onKeyDown: (e) => onKeyDown(idx, e),
|
|
5100
|
+
onPaste,
|
|
5101
|
+
onFocus: (e) => e.target.select(),
|
|
5102
|
+
className: [
|
|
5103
|
+
BOX_SIZE[size],
|
|
5104
|
+
"text-center font-medium rounded-lg border bg-surface text-foreground",
|
|
5105
|
+
"transition-[border-color,box-shadow] duration-150",
|
|
5106
|
+
hasError ? "border-status-error" : "border-border",
|
|
5107
|
+
"hover:border-border-strong",
|
|
5108
|
+
"focus:outline-none focus:border-accent focus:ring-[3px] focus:ring-focus-ring",
|
|
5109
|
+
"disabled:bg-surface-raised disabled:text-foreground-muted disabled:cursor-not-allowed"
|
|
5110
|
+
].join(" ")
|
|
5111
|
+
}
|
|
5112
|
+
),
|
|
5113
|
+
groupAfter && (idx + 1) % groupAfter === 0 && idx < length - 1 && /* @__PURE__ */ jsx("span", { className: "w-2 text-center text-foreground-muted", "aria-hidden": "true", children: "\xB7" })
|
|
5114
|
+
] }, idx)) }) });
|
|
5115
|
+
}
|
|
5116
|
+
var ICON_SIZE = { sm: "w-4 h-4", md: "w-5 h-5", lg: "w-7 h-7" };
|
|
5117
|
+
var Star = (filled) => /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: filled ? "currentColor" : "none", stroke: "currentColor", strokeWidth: filled ? 0 : 1.5, className: "w-full h-full", "aria-hidden": "true", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M11.48 3.5a.56.56 0 011.04 0l2.13 4.77 5.18.5a.56.56 0 01.32.97l-3.9 3.46 1.15 5.1a.56.56 0 01-.83.6L12 16.8l-4.57 2.6a.56.56 0 01-.83-.6l1.15-5.1-3.9-3.46a.56.56 0 01.32-.97l5.18-.5L11.48 3.5z" }) });
|
|
5118
|
+
function Rating({
|
|
5119
|
+
value,
|
|
5120
|
+
defaultValue = 0,
|
|
5121
|
+
onChange,
|
|
5122
|
+
count = 5,
|
|
5123
|
+
allowHalf = false,
|
|
5124
|
+
readOnly = false,
|
|
5125
|
+
clearable = true,
|
|
5126
|
+
label,
|
|
5127
|
+
size = "md",
|
|
5128
|
+
disabled,
|
|
5129
|
+
icon = Star,
|
|
5130
|
+
errorMessage,
|
|
5131
|
+
name
|
|
5132
|
+
}) {
|
|
5133
|
+
const errorId = useId();
|
|
5134
|
+
const [internal, setInternal] = useState(defaultValue);
|
|
5135
|
+
const [hover, setHover] = useState(null);
|
|
5136
|
+
const current = value ?? internal;
|
|
5137
|
+
const display2 = hover ?? current;
|
|
5138
|
+
const interactive = !readOnly && !disabled;
|
|
5139
|
+
const commit = (next) => {
|
|
5140
|
+
const v = clearable && next === current ? 0 : next;
|
|
5141
|
+
setInternal(v);
|
|
5142
|
+
onChange?.(v);
|
|
5143
|
+
};
|
|
5144
|
+
const onKeyDown = (e) => {
|
|
5145
|
+
if (!interactive) return;
|
|
5146
|
+
const step = allowHalf ? 0.5 : 1;
|
|
5147
|
+
if (e.key === "ArrowRight" || e.key === "ArrowUp") {
|
|
5148
|
+
e.preventDefault();
|
|
5149
|
+
commit(Math.min(count, current + step));
|
|
5150
|
+
} else if (e.key === "ArrowLeft" || e.key === "ArrowDown") {
|
|
5151
|
+
e.preventDefault();
|
|
5152
|
+
commit(Math.max(0, current - step));
|
|
5153
|
+
} else if (e.key === "Home") {
|
|
5154
|
+
e.preventDefault();
|
|
5155
|
+
commit(0);
|
|
5156
|
+
} else if (e.key === "End") {
|
|
5157
|
+
e.preventDefault();
|
|
5158
|
+
commit(count);
|
|
5159
|
+
}
|
|
5160
|
+
};
|
|
5161
|
+
return /* @__PURE__ */ jsx(Field, { label, errorId, errorMessage, children: /* @__PURE__ */ jsxs(
|
|
5162
|
+
"div",
|
|
5163
|
+
{
|
|
5164
|
+
role: interactive ? "slider" : "img",
|
|
5165
|
+
"aria-label": typeof label === "string" ? label : "Rating",
|
|
5166
|
+
"aria-valuenow": interactive ? current : void 0,
|
|
5167
|
+
"aria-valuemin": interactive ? 0 : void 0,
|
|
5168
|
+
"aria-valuemax": interactive ? count : void 0,
|
|
5169
|
+
"aria-valuetext": `${current} of ${count}`,
|
|
5170
|
+
tabIndex: interactive ? 0 : -1,
|
|
5171
|
+
onKeyDown,
|
|
5172
|
+
onMouseLeave: () => setHover(null),
|
|
5173
|
+
className: "inline-flex items-center gap-1 text-accent focus:outline-none focus-visible:ring-[3px] focus-visible:ring-focus-ring rounded-md w-max",
|
|
5174
|
+
children: [
|
|
5175
|
+
name && /* @__PURE__ */ jsx("input", { type: "hidden", name, value: current }),
|
|
5176
|
+
Array.from({ length: count }, (_, i) => {
|
|
5177
|
+
const starValue = i + 1;
|
|
5178
|
+
const fillFraction = Math.max(0, Math.min(1, display2 - i));
|
|
5179
|
+
return /* @__PURE__ */ jsxs(
|
|
5180
|
+
"span",
|
|
5181
|
+
{
|
|
5182
|
+
className: `relative ${ICON_SIZE[size]} ${interactive ? "cursor-pointer" : ""} ${disabled ? "opacity-50" : ""}`,
|
|
5183
|
+
onMouseMove: (e) => {
|
|
5184
|
+
if (!interactive) return;
|
|
5185
|
+
if (allowHalf) {
|
|
5186
|
+
const rect = e.currentTarget.getBoundingClientRect();
|
|
5187
|
+
const half = e.clientX - rect.left < rect.width / 2;
|
|
5188
|
+
setHover(i + (half ? 0.5 : 1));
|
|
5189
|
+
} else {
|
|
5190
|
+
setHover(starValue);
|
|
5191
|
+
}
|
|
5192
|
+
},
|
|
5193
|
+
onClick: (e) => {
|
|
5194
|
+
if (!interactive) return;
|
|
5195
|
+
if (allowHalf) {
|
|
5196
|
+
const rect = e.currentTarget.getBoundingClientRect();
|
|
5197
|
+
const half = e.clientX - rect.left < rect.width / 2;
|
|
5198
|
+
commit(i + (half ? 0.5 : 1));
|
|
5199
|
+
} else {
|
|
5200
|
+
commit(starValue);
|
|
5201
|
+
}
|
|
5202
|
+
},
|
|
5203
|
+
children: [
|
|
5204
|
+
/* @__PURE__ */ jsx("span", { className: "absolute inset-0 text-foreground-muted", children: icon(false) }),
|
|
5205
|
+
/* @__PURE__ */ jsx(
|
|
5206
|
+
"span",
|
|
5207
|
+
{
|
|
5208
|
+
className: "absolute inset-y-0 left-0 overflow-hidden",
|
|
5209
|
+
style: { width: `${fillFraction * 100}%` },
|
|
5210
|
+
children: /* @__PURE__ */ jsx("span", { className: `block absolute inset-y-0 left-0 ${ICON_SIZE[size]} max-w-none`, children: icon(true) })
|
|
5211
|
+
}
|
|
5212
|
+
)
|
|
5213
|
+
]
|
|
5214
|
+
},
|
|
5215
|
+
i
|
|
5216
|
+
);
|
|
5217
|
+
})
|
|
5218
|
+
]
|
|
5219
|
+
}
|
|
5220
|
+
) });
|
|
5221
|
+
}
|
|
5222
|
+
var pad = (n) => n.toString().padStart(2, "0");
|
|
5223
|
+
function parse(value) {
|
|
5224
|
+
if (!value) return null;
|
|
5225
|
+
const [h, m, s] = value.split(":").map(Number);
|
|
5226
|
+
if (Number.isNaN(h) || Number.isNaN(m)) return null;
|
|
5227
|
+
return { h, m, s: Number.isNaN(s) ? 0 : s };
|
|
5228
|
+
}
|
|
5229
|
+
function display(value, use12, withSeconds) {
|
|
5230
|
+
const p = parse(value);
|
|
5231
|
+
if (!p) return "";
|
|
5232
|
+
if (use12) {
|
|
5233
|
+
const period = p.h >= 12 ? "PM" : "AM";
|
|
5234
|
+
const h12 = p.h % 12 === 0 ? 12 : p.h % 12;
|
|
5235
|
+
return `${h12}:${pad(p.m)}${withSeconds ? `:${pad(p.s)}` : ""} ${period}`;
|
|
5236
|
+
}
|
|
5237
|
+
return `${pad(p.h)}:${pad(p.m)}${withSeconds ? `:${pad(p.s)}` : ""}`;
|
|
5238
|
+
}
|
|
5239
|
+
function TimePicker({
|
|
5240
|
+
value,
|
|
5241
|
+
onChange,
|
|
5242
|
+
label,
|
|
5243
|
+
htmlFor,
|
|
5244
|
+
name,
|
|
5245
|
+
placeholder = "Select a time\u2026",
|
|
5246
|
+
layout = "vertical",
|
|
5247
|
+
size = "md",
|
|
5248
|
+
use12Hours = false,
|
|
5249
|
+
withSeconds = false,
|
|
5250
|
+
minuteStep = 1,
|
|
5251
|
+
disabled,
|
|
5252
|
+
errorMessage,
|
|
5253
|
+
required,
|
|
5254
|
+
style
|
|
5255
|
+
}) {
|
|
5256
|
+
const errorId = useId();
|
|
5257
|
+
const hasError = errorMessage != null;
|
|
5258
|
+
const [open, setOpen] = useState(false);
|
|
5259
|
+
const parsed = parse(value) ?? { h: 0, m: 0, s: 0 };
|
|
5260
|
+
const update = (next) => {
|
|
5261
|
+
const merged = { ...parsed, ...next };
|
|
5262
|
+
onChange?.(`${pad(merged.h)}:${pad(merged.m)}${withSeconds ? `:${pad(merged.s)}` : ""}`);
|
|
5263
|
+
};
|
|
5264
|
+
const hours = use12Hours ? Array.from({ length: 12 }, (_, i) => i + 1) : Array.from({ length: 24 }, (_, i) => i);
|
|
5265
|
+
const minutes = Array.from({ length: Math.ceil(60 / minuteStep) }, (_, i) => i * minuteStep);
|
|
5266
|
+
const seconds = Array.from({ length: 60 }, (_, i) => i);
|
|
5267
|
+
const selectedHourCol = use12Hours ? parsed.h % 12 === 0 ? 12 : parsed.h % 12 : parsed.h;
|
|
5268
|
+
const period = parsed.h >= 12 ? "PM" : "AM";
|
|
5269
|
+
const setHour12 = (h12, p) => {
|
|
5270
|
+
const h24 = p === "AM" ? h12 === 12 ? 0 : h12 : h12 === 12 ? 12 : h12 + 12;
|
|
5271
|
+
update({ h: h24 });
|
|
5272
|
+
};
|
|
5273
|
+
const Column = ({ items, selected, onPick, fmt }) => /* @__PURE__ */ jsx("div", { className: "flex flex-col overflow-y-auto max-h-48 w-14 hidden-scrollbar", role: "listbox", children: items.map((n) => /* @__PURE__ */ jsx(
|
|
5274
|
+
"button",
|
|
5275
|
+
{
|
|
5276
|
+
type: "button",
|
|
5277
|
+
role: "option",
|
|
5278
|
+
"aria-selected": selected === n,
|
|
5279
|
+
onClick: () => onPick(n),
|
|
5280
|
+
className: `py-1.5 text-sm rounded-md text-center transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-accent ${selected === n ? "bg-accent text-accent-fg" : "text-foreground hover:bg-surface-raised"}`,
|
|
5281
|
+
children: fmt ? fmt(n) : pad(n)
|
|
5282
|
+
},
|
|
5283
|
+
n
|
|
5284
|
+
)) });
|
|
5285
|
+
return /* @__PURE__ */ jsxs(Field, { label, htmlFor, errorId, errorMessage, layout, required, children: [
|
|
5286
|
+
/* @__PURE__ */ jsxs(Popover.Root, { open: open && !disabled, onOpenChange: (o) => !disabled && setOpen(o), children: [
|
|
5287
|
+
/* @__PURE__ */ jsx(Popover.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs(
|
|
5288
|
+
"button",
|
|
5289
|
+
{
|
|
5290
|
+
id: htmlFor,
|
|
5291
|
+
type: "button",
|
|
5292
|
+
disabled,
|
|
5293
|
+
style,
|
|
5294
|
+
"aria-invalid": hasError || void 0,
|
|
5295
|
+
"aria-describedby": hasError ? errorId : void 0,
|
|
5296
|
+
className: `flex items-center justify-between cursor-pointer select-none ${!style?.width ? "min-w-[160px]" : ""} ${fieldShell({ size, hasError, disabled })}`,
|
|
5297
|
+
children: [
|
|
5298
|
+
/* @__PURE__ */ jsx("span", { className: `text-sm truncate ${value ? "" : "text-foreground-muted"}`, children: display(value, use12Hours, withSeconds) || placeholder }),
|
|
5299
|
+
/* @__PURE__ */ jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 1.75, className: "w-4 h-4 flex-shrink-0 text-foreground-muted ml-2", "aria-hidden": "true", children: [
|
|
5300
|
+
/* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "9" }),
|
|
5301
|
+
/* @__PURE__ */ jsx("path", { d: "M12 7v5l3 2", strokeLinecap: "round" })
|
|
5302
|
+
] })
|
|
5303
|
+
]
|
|
5304
|
+
}
|
|
5305
|
+
) }),
|
|
5306
|
+
/* @__PURE__ */ jsx(Popover.Portal, { children: /* @__PURE__ */ jsxs(
|
|
5307
|
+
Popover.Content,
|
|
5308
|
+
{
|
|
5309
|
+
align: "start",
|
|
5310
|
+
sideOffset: 4,
|
|
5311
|
+
className: "bg-surface text-foreground border border-border rounded-lg shadow-md z-50 p-2 flex gap-1 animate-in fade-in-0 zoom-in-95",
|
|
5312
|
+
children: [
|
|
5313
|
+
/* @__PURE__ */ jsx(
|
|
5314
|
+
Column,
|
|
5315
|
+
{
|
|
5316
|
+
items: hours,
|
|
5317
|
+
selected: selectedHourCol,
|
|
5318
|
+
onPick: (h) => use12Hours ? setHour12(h, period) : update({ h }),
|
|
5319
|
+
fmt: use12Hours ? (n) => String(n) : pad
|
|
5320
|
+
}
|
|
5321
|
+
),
|
|
5322
|
+
/* @__PURE__ */ jsx(Column, { items: minutes, selected: parsed.m, onPick: (m) => update({ m }) }),
|
|
5323
|
+
withSeconds && /* @__PURE__ */ jsx(Column, { items: seconds, selected: parsed.s, onPick: (s) => update({ s }) }),
|
|
5324
|
+
use12Hours && /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-1 w-12", children: ["AM", "PM"].map((p) => /* @__PURE__ */ jsx(
|
|
5325
|
+
"button",
|
|
5326
|
+
{
|
|
5327
|
+
type: "button",
|
|
5328
|
+
onClick: () => setHour12(selectedHourCol, p),
|
|
5329
|
+
className: `py-1.5 text-sm rounded-md transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-accent ${period === p ? "bg-accent text-accent-fg" : "text-foreground hover:bg-surface-raised"}`,
|
|
5330
|
+
children: p
|
|
5331
|
+
},
|
|
5332
|
+
p
|
|
5333
|
+
)) })
|
|
5334
|
+
]
|
|
5335
|
+
}
|
|
5336
|
+
) })
|
|
5337
|
+
] }),
|
|
5338
|
+
name && /* @__PURE__ */ jsx("input", { type: "hidden", name, value: value ?? "" })
|
|
5339
|
+
] });
|
|
5340
|
+
}
|
|
5341
|
+
var MONTH_NAMES2 = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
|
|
5342
|
+
var WEEKDAY = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
|
5343
|
+
var startOfMonth2 = (d) => new Date(d.getFullYear(), d.getMonth(), 1);
|
|
5344
|
+
var addMonths2 = (d, n) => new Date(d.getFullYear(), d.getMonth() + n, 1);
|
|
5345
|
+
var addDays2 = (d, n) => {
|
|
5346
|
+
const c = new Date(d);
|
|
5347
|
+
c.setDate(c.getDate() + n);
|
|
5348
|
+
return c;
|
|
5349
|
+
};
|
|
5350
|
+
var isSameDay2 = (a, b) => a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
|
|
5351
|
+
var startOfDay = (d) => new Date(d.getFullYear(), d.getMonth(), d.getDate());
|
|
5352
|
+
var defaultFmt = (d) => `${d.getFullYear()}-${`${d.getMonth() + 1}`.padStart(2, "0")}-${`${d.getDate()}`.padStart(2, "0")}`;
|
|
5353
|
+
function buildGrid2(viewMonth, weekStartsOn) {
|
|
5354
|
+
const first = startOfMonth2(viewMonth);
|
|
5355
|
+
const offset = (first.getDay() - weekStartsOn + 7) % 7;
|
|
5356
|
+
const gridStart = addDays2(first, -offset);
|
|
5357
|
+
return Array.from({ length: 42 }, (_, i) => {
|
|
5358
|
+
const d = addDays2(gridStart, i);
|
|
5359
|
+
return { date: d, outside: d.getMonth() !== viewMonth.getMonth() };
|
|
5360
|
+
});
|
|
5361
|
+
}
|
|
5362
|
+
function DateRangePicker({
|
|
5363
|
+
value = { start: null, end: null },
|
|
5364
|
+
onChange,
|
|
5365
|
+
label,
|
|
5366
|
+
htmlFor,
|
|
5367
|
+
placeholder = "Select a date range\u2026",
|
|
5368
|
+
layout = "vertical",
|
|
5369
|
+
size = "md",
|
|
5370
|
+
min,
|
|
5371
|
+
max,
|
|
5372
|
+
weekStartsOn = 0,
|
|
5373
|
+
presets,
|
|
5374
|
+
format = defaultFmt,
|
|
5375
|
+
disabled,
|
|
5376
|
+
errorMessage,
|
|
5377
|
+
required,
|
|
5378
|
+
style
|
|
5379
|
+
}) {
|
|
5380
|
+
const errorId = useId();
|
|
5381
|
+
const hasError = errorMessage != null;
|
|
5382
|
+
const [open, setOpen] = useState(false);
|
|
5383
|
+
const [leftMonth, setLeftMonth] = useState(() => startOfMonth2(value.start ?? /* @__PURE__ */ new Date()));
|
|
5384
|
+
const [pendingStart, setPendingStart] = useState(null);
|
|
5385
|
+
const [hoverDate, setHoverDate] = useState(null);
|
|
5386
|
+
const weekdays = useMemo(
|
|
5387
|
+
() => WEEKDAY.slice(weekStartsOn).concat(WEEKDAY.slice(0, weekStartsOn)),
|
|
5388
|
+
[weekStartsOn]
|
|
5389
|
+
);
|
|
5390
|
+
const isDisabled = (d) => min && d < startOfDay(min) || max && d > startOfDay(max);
|
|
5391
|
+
const effective = pendingStart ? { start: pendingStart, end: hoverDate } : value;
|
|
5392
|
+
const inRange = (d) => {
|
|
5393
|
+
const { start, end } = effective;
|
|
5394
|
+
if (!start || !end) return false;
|
|
5395
|
+
const [a, b] = start <= end ? [start, end] : [end, start];
|
|
5396
|
+
return d >= startOfDay(a) && d <= startOfDay(b);
|
|
5397
|
+
};
|
|
5398
|
+
const onDayClick = (d) => {
|
|
5399
|
+
if (isDisabled(d)) return;
|
|
5400
|
+
if (!pendingStart) {
|
|
5401
|
+
setPendingStart(d);
|
|
5402
|
+
setHoverDate(d);
|
|
5403
|
+
onChange?.({ start: d, end: null });
|
|
5404
|
+
} else {
|
|
5405
|
+
const [start, end] = pendingStart <= d ? [pendingStart, d] : [d, pendingStart];
|
|
5406
|
+
onChange?.({ start, end });
|
|
5407
|
+
setPendingStart(null);
|
|
5408
|
+
setHoverDate(null);
|
|
5409
|
+
setOpen(false);
|
|
5410
|
+
}
|
|
5411
|
+
};
|
|
5412
|
+
const triggerText = value.start && value.end ? `${format(value.start)} \u2013 ${format(value.end)}` : value.start ? `${format(value.start)} \u2013 \u2026` : "";
|
|
5413
|
+
const renderMonth = (viewMonth) => {
|
|
5414
|
+
const cells = buildGrid2(viewMonth, weekStartsOn);
|
|
5415
|
+
return /* @__PURE__ */ jsxs("div", { children: [
|
|
5416
|
+
/* @__PURE__ */ jsxs("div", { className: "text-sm font-semibold text-center mb-2 select-none", children: [
|
|
5417
|
+
MONTH_NAMES2[viewMonth.getMonth()],
|
|
5418
|
+
" ",
|
|
5419
|
+
viewMonth.getFullYear()
|
|
5420
|
+
] }),
|
|
5421
|
+
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-7 gap-y-1", children: [
|
|
5422
|
+
weekdays.map((w) => /* @__PURE__ */ jsx("div", { className: "text-[11px] font-medium text-foreground-muted uppercase text-center", children: w }, w)),
|
|
5423
|
+
cells.map(({ date, outside }) => {
|
|
5424
|
+
const dis = isDisabled(date);
|
|
5425
|
+
const isStart = effective.start && isSameDay2(date, effective.start);
|
|
5426
|
+
const isEnd = effective.end && isSameDay2(date, effective.end);
|
|
5427
|
+
const within = inRange(date) && !isStart && !isEnd;
|
|
5428
|
+
return /* @__PURE__ */ jsx(
|
|
5429
|
+
"button",
|
|
5430
|
+
{
|
|
5431
|
+
type: "button",
|
|
5432
|
+
disabled: dis,
|
|
5433
|
+
onMouseEnter: () => pendingStart && setHoverDate(date),
|
|
5434
|
+
onClick: () => onDayClick(date),
|
|
5435
|
+
className: [
|
|
5436
|
+
"h-8 text-xs font-medium transition-colors",
|
|
5437
|
+
"focus:outline-none focus-visible:ring-2 focus-visible:ring-accent",
|
|
5438
|
+
"disabled:opacity-30 disabled:cursor-not-allowed",
|
|
5439
|
+
isStart || isEnd ? "bg-accent text-accent-fg rounded-md" : within ? "bg-surface-raised text-foreground rounded-none" : outside ? "text-foreground-muted hover:bg-surface-raised rounded-md" : "text-foreground hover:bg-surface-raised rounded-md"
|
|
5440
|
+
].join(" "),
|
|
5441
|
+
children: date.getDate()
|
|
5442
|
+
},
|
|
5443
|
+
defaultFmt(date)
|
|
5444
|
+
);
|
|
5445
|
+
})
|
|
5446
|
+
] })
|
|
5447
|
+
] });
|
|
5448
|
+
};
|
|
5449
|
+
return /* @__PURE__ */ jsx(Field, { label, htmlFor, errorId, errorMessage, layout, required, children: /* @__PURE__ */ jsxs(Popover.Root, { open: open && !disabled, onOpenChange: (o) => {
|
|
5450
|
+
if (!disabled) {
|
|
5451
|
+
setOpen(o);
|
|
5452
|
+
if (!o) {
|
|
5453
|
+
setPendingStart(null);
|
|
5454
|
+
setHoverDate(null);
|
|
5455
|
+
}
|
|
5456
|
+
}
|
|
5457
|
+
}, children: [
|
|
5458
|
+
/* @__PURE__ */ jsx(Popover.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs(
|
|
5459
|
+
"button",
|
|
5460
|
+
{
|
|
5461
|
+
id: htmlFor,
|
|
5462
|
+
type: "button",
|
|
5463
|
+
disabled,
|
|
5464
|
+
style,
|
|
5465
|
+
"aria-invalid": hasError || void 0,
|
|
5466
|
+
"aria-describedby": hasError ? errorId : void 0,
|
|
5467
|
+
className: `flex items-center justify-between cursor-pointer select-none ${!style?.width ? "min-w-[240px]" : ""} ${fieldShell({ size, hasError, disabled })}`,
|
|
5468
|
+
children: [
|
|
5469
|
+
/* @__PURE__ */ jsx("span", { className: `text-sm truncate ${triggerText ? "" : "text-foreground-muted"}`, children: triggerText || placeholder }),
|
|
5470
|
+
/* @__PURE__ */ jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 1.75, className: "w-4 h-4 flex-shrink-0 text-foreground-muted ml-2", "aria-hidden": "true", children: [
|
|
5471
|
+
/* @__PURE__ */ jsx("rect", { x: "3", y: "5", width: "18", height: "16", rx: "2" }),
|
|
5472
|
+
/* @__PURE__ */ jsx("path", { d: "M3 9h18M8 3v4M16 3v4", strokeLinecap: "round" })
|
|
5473
|
+
] })
|
|
5474
|
+
]
|
|
5475
|
+
}
|
|
5476
|
+
) }),
|
|
5477
|
+
/* @__PURE__ */ jsx(Popover.Portal, { children: /* @__PURE__ */ jsxs(
|
|
5478
|
+
Popover.Content,
|
|
5479
|
+
{
|
|
5480
|
+
align: "start",
|
|
5481
|
+
sideOffset: 4,
|
|
5482
|
+
className: "bg-surface text-foreground border border-border rounded-lg shadow-md z-50 p-3 flex gap-3 animate-in fade-in-0 zoom-in-95",
|
|
5483
|
+
children: [
|
|
5484
|
+
presets && presets.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-1 pr-3 border-r border-border min-w-[120px]", children: presets.map((p) => /* @__PURE__ */ jsx(
|
|
5485
|
+
"button",
|
|
5486
|
+
{
|
|
5487
|
+
type: "button",
|
|
5488
|
+
onClick: () => {
|
|
5489
|
+
onChange?.(p.range());
|
|
5490
|
+
setOpen(false);
|
|
5491
|
+
},
|
|
5492
|
+
className: "text-left text-xs px-2 py-1.5 rounded-md text-foreground-secondary hover:bg-surface-raised hover:text-foreground transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-accent",
|
|
5493
|
+
children: p.label
|
|
5494
|
+
},
|
|
5495
|
+
p.label
|
|
5496
|
+
)) }),
|
|
5497
|
+
/* @__PURE__ */ jsxs("div", { className: "flex gap-4", children: [
|
|
5498
|
+
/* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
5499
|
+
/* @__PURE__ */ jsx(
|
|
5500
|
+
"button",
|
|
5501
|
+
{
|
|
5502
|
+
type: "button",
|
|
5503
|
+
onClick: () => setLeftMonth(addMonths2(leftMonth, -1)),
|
|
5504
|
+
"aria-label": "Previous month",
|
|
5505
|
+
className: "absolute -top-1 left-0 w-7 h-7 inline-flex items-center justify-center rounded-md hover:bg-surface-raised focus:outline-none focus-visible:ring-2 focus-visible:ring-accent",
|
|
5506
|
+
children: /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, className: "w-4 h-4", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M15 19l-7-7 7-7" }) })
|
|
5507
|
+
}
|
|
5508
|
+
),
|
|
5509
|
+
renderMonth(leftMonth)
|
|
5510
|
+
] }),
|
|
5511
|
+
/* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
5512
|
+
/* @__PURE__ */ jsx(
|
|
5513
|
+
"button",
|
|
5514
|
+
{
|
|
5515
|
+
type: "button",
|
|
5516
|
+
onClick: () => setLeftMonth(addMonths2(leftMonth, 1)),
|
|
5517
|
+
"aria-label": "Next month",
|
|
5518
|
+
className: "absolute -top-1 right-0 w-7 h-7 inline-flex items-center justify-center rounded-md hover:bg-surface-raised focus:outline-none focus-visible:ring-2 focus-visible:ring-accent",
|
|
5519
|
+
children: /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, className: "w-4 h-4", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M9 5l7 7-7 7" }) })
|
|
5520
|
+
}
|
|
5521
|
+
),
|
|
5522
|
+
renderMonth(addMonths2(leftMonth, 1))
|
|
5523
|
+
] })
|
|
5524
|
+
] })
|
|
5525
|
+
]
|
|
5526
|
+
}
|
|
5527
|
+
) })
|
|
5528
|
+
] }) });
|
|
5529
|
+
}
|
|
5530
|
+
var DEFAULT_SWATCHES = [
|
|
5531
|
+
"#0466c8",
|
|
5532
|
+
"#1e8449",
|
|
5533
|
+
"#d68910",
|
|
5534
|
+
"#c0392b",
|
|
5535
|
+
"#8e44ad",
|
|
5536
|
+
"#16a085",
|
|
5537
|
+
"#2c3e50",
|
|
5538
|
+
"#7f8c8d",
|
|
5539
|
+
"#e84393",
|
|
5540
|
+
"#00b894",
|
|
5541
|
+
"#fdcb6e",
|
|
5542
|
+
"#0a1929"
|
|
5543
|
+
];
|
|
5544
|
+
var HEX_RE = /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/;
|
|
5545
|
+
function ColorPicker({
|
|
5546
|
+
value = "",
|
|
5547
|
+
onChange,
|
|
5548
|
+
label,
|
|
5549
|
+
htmlFor,
|
|
5550
|
+
name,
|
|
5551
|
+
layout = "vertical",
|
|
5552
|
+
size = "md",
|
|
5553
|
+
swatches = DEFAULT_SWATCHES,
|
|
5554
|
+
allowCustom = true,
|
|
5555
|
+
disabled,
|
|
5556
|
+
errorMessage,
|
|
5557
|
+
required,
|
|
5558
|
+
placeholder = "Pick a colour\u2026"
|
|
5559
|
+
}) {
|
|
5560
|
+
const errorId = useId();
|
|
5561
|
+
const hasError = errorMessage != null;
|
|
5562
|
+
const [open, setOpen] = useState(false);
|
|
5563
|
+
const [draft, setDraft] = useState(value);
|
|
5564
|
+
const valid = HEX_RE.test(value);
|
|
5565
|
+
const pick = (hex) => {
|
|
5566
|
+
onChange?.(hex);
|
|
5567
|
+
setDraft(hex);
|
|
5568
|
+
};
|
|
5569
|
+
const commitDraft = (raw) => {
|
|
5570
|
+
const hex = raw.startsWith("#") ? raw : `#${raw}`;
|
|
5571
|
+
setDraft(hex);
|
|
5572
|
+
if (HEX_RE.test(hex)) onChange?.(hex);
|
|
5573
|
+
};
|
|
5574
|
+
return /* @__PURE__ */ jsxs(Field, { label, htmlFor, errorId, errorMessage, layout, required, children: [
|
|
5575
|
+
/* @__PURE__ */ jsxs(Popover.Root, { open: open && !disabled, onOpenChange: (o) => !disabled && setOpen(o), children: [
|
|
5576
|
+
/* @__PURE__ */ jsx(Popover.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs(
|
|
5577
|
+
"button",
|
|
5578
|
+
{
|
|
5579
|
+
id: htmlFor,
|
|
5580
|
+
type: "button",
|
|
5581
|
+
disabled,
|
|
5582
|
+
"aria-invalid": hasError || void 0,
|
|
5583
|
+
"aria-describedby": hasError ? errorId : void 0,
|
|
5584
|
+
className: `flex items-center gap-2 cursor-pointer select-none ${fieldShell({ size, hasError, disabled })}`,
|
|
5585
|
+
children: [
|
|
5586
|
+
/* @__PURE__ */ jsx(
|
|
5587
|
+
"span",
|
|
5588
|
+
{
|
|
5589
|
+
className: "h-4 w-4 flex-shrink-0 rounded border border-border",
|
|
5590
|
+
style: { backgroundColor: valid ? value : "transparent" },
|
|
5591
|
+
"aria-hidden": "true"
|
|
5592
|
+
}
|
|
5593
|
+
),
|
|
5594
|
+
/* @__PURE__ */ jsx("span", { className: `flex-1 text-left text-sm truncate ${valid ? "text-foreground" : "text-foreground-muted"}`, children: valid ? value.toLowerCase() : placeholder })
|
|
5595
|
+
]
|
|
5596
|
+
}
|
|
5597
|
+
) }),
|
|
5598
|
+
/* @__PURE__ */ jsx(Popover.Portal, { children: /* @__PURE__ */ jsxs(
|
|
5599
|
+
Popover.Content,
|
|
5600
|
+
{
|
|
5601
|
+
align: "start",
|
|
5602
|
+
sideOffset: 4,
|
|
5603
|
+
className: "bg-surface text-foreground border border-border rounded-lg shadow-md z-50 p-3 w-56 animate-in fade-in-0 zoom-in-95",
|
|
5604
|
+
children: [
|
|
5605
|
+
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-6 gap-2 mb-3", children: swatches.map((sw) => /* @__PURE__ */ jsx(
|
|
5606
|
+
"button",
|
|
5607
|
+
{
|
|
5608
|
+
type: "button",
|
|
5609
|
+
onClick: () => {
|
|
5610
|
+
pick(sw);
|
|
5611
|
+
setOpen(false);
|
|
5612
|
+
},
|
|
5613
|
+
"aria-label": sw,
|
|
5614
|
+
className: `h-7 w-7 rounded-md border transition-transform hover:scale-110 focus:outline-none focus-visible:ring-2 focus-visible:ring-accent ${value.toLowerCase() === sw.toLowerCase() ? "border-accent ring-2 ring-focus-ring" : "border-border"}`,
|
|
5615
|
+
style: { backgroundColor: sw }
|
|
5616
|
+
},
|
|
5617
|
+
sw
|
|
5618
|
+
)) }),
|
|
5619
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
5620
|
+
/* @__PURE__ */ jsx(
|
|
5621
|
+
"input",
|
|
5622
|
+
{
|
|
5623
|
+
value: draft,
|
|
5624
|
+
onChange: (e) => commitDraft(e.target.value),
|
|
5625
|
+
placeholder: "#0466c8",
|
|
5626
|
+
"aria-label": "Hex colour",
|
|
5627
|
+
className: `flex-1 ${fieldShell({ size: "sm" })}`
|
|
5628
|
+
}
|
|
5629
|
+
),
|
|
5630
|
+
allowCustom && /* @__PURE__ */ jsx(
|
|
5631
|
+
"input",
|
|
5632
|
+
{
|
|
5633
|
+
type: "color",
|
|
5634
|
+
value: valid ? value : "#000000",
|
|
5635
|
+
onChange: (e) => pick(e.target.value),
|
|
5636
|
+
"aria-label": "Custom colour",
|
|
5637
|
+
className: "h-7 w-9 rounded-md border border-border bg-surface cursor-pointer p-0.5"
|
|
5638
|
+
}
|
|
5639
|
+
)
|
|
5640
|
+
] })
|
|
5641
|
+
]
|
|
5642
|
+
}
|
|
5643
|
+
) })
|
|
5644
|
+
] }),
|
|
5645
|
+
name && /* @__PURE__ */ jsx("input", { type: "hidden", name, value: valid ? value : "" })
|
|
5646
|
+
] });
|
|
5647
|
+
}
|
|
5004
5648
|
|
|
5005
|
-
export { AppShell, AutoComplete, Avatar, Box, Button, Catalog, CatalogCarousel, CatalogGrid, Checkbox, ContextMenu, Drawer, Dropdown, FadingBase, Field, FileInput, Flex, Grid2 as Grid, GridCard, icons_default as Icon, IconButton, List2 as List, LoadingSpinner, Modal, NotificationProvider, NumberInput, OpaqueGridCard, Password, Portal, RadioGroup, ScalableContainer, SearchInput_default as SearchInput, SegmentedControl, Sidebar, SkeletonBox, SkeletonCard, SkeletonCircle, SkeletonText, Slider, Switch, Table, Tabs, TagsInput, DatePicker as Temporal, TextArea, TextInput, ThemeProvider, ThemeSwitch, ToggleButton, Tooltip, TooltipProvider, TopBar, Tree, TreeSelect, Typography, Wizard, fieldShell, useNotification };
|
|
5649
|
+
export { AppShell, AutoComplete, Avatar, Box, Button, Catalog, CatalogCarousel, CatalogGrid, Checkbox, ColorPicker, ContextMenu, DateRangePicker, Drawer, Dropdown, FadingBase, Field, FileInput, Flex, Grid2 as Grid, GridCard, icons_default as Icon, IconButton, List2 as List, LoadingSpinner, Modal, NotificationProvider, NumberInput, OpaqueGridCard, OtpInput, Password, Portal, RadioGroup, Rating, ScalableContainer, SearchInput_default as SearchInput, SegmentedControl, Sidebar, SkeletonBox, SkeletonCard, SkeletonCircle, SkeletonText, Slider, Switch, Table, Tabs, TagsInput, DatePicker as Temporal, TextArea, TextInput, ThemeProvider, ThemeSwitch, TimePicker, ToggleButton, Tooltip, TooltipProvider, TopBar, Tree, TreeSelect, Typography, Wizard, fieldShell, useNotification };
|
|
5006
5650
|
//# sourceMappingURL=index.js.map
|
|
5007
5651
|
//# sourceMappingURL=index.js.map
|