laif-ds
Version:
Design System di Laif con componenti React basati su principi di Atomic Design
263 lines (262 loc) • 9.66 kB
JavaScript
"use client";
import { jsxs as u, jsx as a } from "react/jsx-runtime";
import { useState as B, useRef as W, useCallback as k, useMemo as b, useLayoutEffect as de } from "react";
import { designTokens as f } from "../design-tokens.js";
import { Icon as E } from "./icon.js";
import { Label as le } from "./label.js";
import { Popover as ce, PopoverTrigger as ue, PopoverContent as me } from "./popover.js";
import { cn as V } from "../../lib/utils.js";
import { Button as X } from "./button.js";
const fe = {
sm: f.sizes.sm,
default: f.sizes.default,
lg: f.sizes.lg
}, ge = {
default: "bg-d-input border-d-border/50",
destructive: "bg-d-destructive/10 border-d-destructive/50 text-d-destructive",
outline: "bg-transparent border-d-foreground",
secondary: "bg-d-secondary border-d-border text-d-secondary-foreground",
ghost: "bg-transparent border-transparent hover:bg-d-accent",
link: "bg-transparent border-transparent text-d-primary underline-offset-4 hover:underline"
}, F = (r) => {
if (!Number.isFinite(r)) return 1;
const l = Math.trunc(r);
return Math.min(59, Math.max(1, l));
};
function D({
options: r,
value: l,
onChange: g,
type: p,
className: T,
disabledValues: w
}) {
const m = W(null);
return de(() => {
m.current && l !== void 0 && m.current.scrollIntoView({
behavior: "instant",
block: "center"
});
}, [l]), /* @__PURE__ */ u(
"div",
{
className: V(
"flex min-h-0 w-14 flex-col items-center overflow-hidden sm:w-16",
T
),
children: [
/* @__PURE__ */ a("div", { className: "text-d-muted-foreground py-2 text-[10px] font-semibold tracking-wider uppercase", children: p === "hour" ? "HH" : p === "minute" ? "MM" : "SS" }),
/* @__PURE__ */ a("div", { className: "flex min-h-0 w-full flex-1 flex-col overflow-auto overscroll-contain px-1.5", children: r.map((c) => {
const N = w?.has(c) ?? !1;
return /* @__PURE__ */ a(
X,
{
ref: l !== void 0 && c === l ? m : void 0,
variant: l !== void 0 && c === l ? "default" : "ghost",
size: "sm",
disabled: N,
onClick: () => g(c),
children: c.toString().padStart(2, "0")
},
c
);
}) })
]
}
);
}
function Ne(r) {
const {
value: l,
onChange: g,
onClear: p,
label: T,
placeholder: w = "Seleziona orario",
disabled: m = !1,
clearable: c = !1,
className: N,
labelClassName: q,
wrpClassName: G,
size: J = "default",
variant: K = "default",
useUtc: d = !1,
withSeconds: M = !1,
minuteStep: O = 1,
secondStep: P = 1,
id: Q,
"data-testid": Y
} = r, [Z, j] = B(
void 0
), [R, $] = B(!1), ee = W(null), v = Object.prototype.hasOwnProperty.call(r, "value"), s = v ? l : Z, A = k(() => {
v || j(void 0), g?.(void 0), p?.();
}, [v, g, p]), I = k(() => {
if (!s) return "";
let e, n, o;
d ? (e = s.getUTCHours(), n = s.getUTCMinutes(), o = s.getUTCSeconds()) : (e = s.getHours(), n = s.getMinutes(), o = s.getSeconds());
const S = [
e.toString().padStart(2, "0"),
n.toString().padStart(2, "0")
];
return M && S.push(o.toString().padStart(2, "0")), S.join(":");
}, [s, d, M])(), H = k(
(e, n) => {
const o = s ? new Date(s) : /* @__PURE__ */ new Date();
d ? (s || o.setUTCHours(0, 0, 0, 0), e === "hour" ? o.setUTCHours(n) : e === "minute" ? o.setUTCMinutes(n) : e === "second" && o.setUTCSeconds(n)) : (s || o.setHours(0, 0, 0, 0), e === "hour" ? o.setHours(n) : e === "minute" ? o.setMinutes(n) : e === "second" && o.setSeconds(n)), v || j(o), g?.(o);
},
[s, g, d, v]
), h = d ? s?.getUTCHours() : s?.getHours(), x = d ? s?.getUTCMinutes() : s?.getMinutes(), te = d ? s?.getUTCSeconds() : s?.getSeconds(), y = b(
() => F(O),
[O]
), U = b(
() => F(P),
[P]
), se = b(
() => Array.from({ length: 24 }, (e, n) => n),
[]
), ne = b(
() => Array.from(
{ length: Math.floor(59 / y) + 1 },
(e, n) => n * y
),
[y]
), oe = b(
() => Array.from(
{ length: Math.floor(59 / U) + 1 },
(e, n) => n * U
),
[U]
), { disabledHours: re, disabledMinutes: ie, disabledSeconds: ae } = b(() => {
const e = /* @__PURE__ */ new Set(), n = /* @__PURE__ */ new Set(), o = /* @__PURE__ */ new Set(), S = d ? (i) => i.getUTCHours() : (i) => i.getHours(), _ = d ? (i) => i.getUTCMinutes() : (i) => i.getMinutes(), L = d ? (i) => i.getUTCSeconds() : (i) => i.getSeconds();
if (r.minTime) {
const i = S(r.minTime), C = _(r.minTime), z = L(r.minTime);
for (let t = 0; t < i; t++) e.add(t);
if (h !== void 0 && h === i) {
for (let t = 0; t < C; t++) n.add(t);
if (x !== void 0 && x === C)
for (let t = 0; t < z; t++) o.add(t);
}
}
if (r.maxTime) {
const i = S(r.maxTime), C = _(r.maxTime), z = L(r.maxTime);
for (let t = i + 1; t < 24; t++) e.add(t);
if (h !== void 0 && h === i) {
for (let t = C + 1; t < 60; t++) n.add(t);
if (x !== void 0 && x === C)
for (let t = z + 1; t < 60; t++) o.add(t);
}
}
return { disabledHours: e, disabledMinutes: n, disabledSeconds: o };
}, [r.minTime, r.maxTime, h, x, d]);
return /* @__PURE__ */ u("div", { className: V("flex flex-col gap-1.5", G), children: [
T && /* @__PURE__ */ a(le, { className: q, children: T }),
/* @__PURE__ */ u(
ce,
{
open: m ? !1 : R,
onOpenChange: (e) => !m && $(e),
modal: !0,
children: [
/* @__PURE__ */ a(ue, { asChild: !0, children: /* @__PURE__ */ u(
"div",
{
ref: ee,
id: Q,
"data-testid": Y,
className: V(
f.input.base,
f.radius.default,
f.focusRingWithin,
"flex w-fit min-w-[120px] cursor-pointer items-center justify-between gap-3 transition-colors",
R && f.activeRing,
fe[J],
ge[K],
m && "cursor-not-allowed opacity-50",
N
),
children: [
/* @__PURE__ */ u("div", { className: "flex items-center gap-2 overflow-hidden", children: [
/* @__PURE__ */ a(E, { name: "Clock", size: "xs", className: "opacity-50" }),
I ? /* @__PURE__ */ a("span", { className: "text-d-foreground truncate font-medium tabular-nums", children: I }) : /* @__PURE__ */ a("span", { className: "text-d-muted-foreground whitespace-nowrap", children: w })
] }),
/* @__PURE__ */ u("div", { className: "text-d-muted-foreground/30 flex items-center gap-1.5", children: [
c && s && /* @__PURE__ */ a(
"div",
{
role: "button",
className: "bg-d-accent hover:bg-d-accent/80 border-d-border flex cursor-pointer items-center justify-center rounded-full border p-1 transition-colors",
onClick: (e) => {
e.stopPropagation(), e.preventDefault(), A();
},
onMouseDown: (e) => e.preventDefault(),
"aria-label": "Clear selection",
children: /* @__PURE__ */ a(
E,
{
name: "X",
size: "xs",
className: "!text-d-foreground opacity-50"
}
)
}
),
d && /* @__PURE__ */ a("span", { className: "text-[10px] font-bold", children: "UTC" })
] })
]
}
) }),
/* @__PURE__ */ u(me, { className: "flex w-auto flex-col p-0", align: "start", children: [
/* @__PURE__ */ u("div", { className: "divide-d-border flex min-h-0 flex-1 items-start divide-x", children: [
/* @__PURE__ */ a(
D,
{
type: "hour",
value: h,
options: se,
onChange: (e) => H("hour", e),
disabledValues: re,
className: "flex max-h-64 flex-1"
}
),
/* @__PURE__ */ a(
D,
{
type: "minute",
value: x,
options: ne,
onChange: (e) => H("minute", e),
disabledValues: ie,
className: "flex max-h-64 flex-1"
}
),
M && /* @__PURE__ */ a(
D,
{
type: "second",
value: te,
options: oe,
onChange: (e) => H("second", e),
disabledValues: ae,
className: "flex max-h-64 flex-1"
}
)
] }),
s && /* @__PURE__ */ a("div", { className: "border-d-border flex border-t p-1", children: /* @__PURE__ */ a(
X,
{
size: "sm",
variant: "ghost",
className: "w-full",
onClick: A,
children: "Clear"
}
) })
] })
]
}
)
] });
}
export {
Ne as AppTimePicker,
D as TimePickerColumn
};