laif-ds
Version:
Design System di Laif con componenti React basati su principi di Atomic Design
224 lines (223 loc) • 7.22 kB
JavaScript
"use client";
import { jsxs as f, jsx as l } from "react/jsx-runtime";
import { designTokens as o } from "../design-tokens.js";
import { Label as se } from "./label.js";
import { cn as n } from "../../lib/utils.js";
import { cva as j } from "../../node_modules/class-variance-authority/dist/index.js";
import * as a from "react";
import { Icon as N } from "./icon.js";
import { Typo as te } from "./typo.js";
const ae = j(
n(
o.input.base,
o.radius.default,
"items-center gap-2 px-3",
o.focusRingWithin,
o.input.invalid
),
{
variants: {
size: {
default: o.sizes.default,
sm: o.sizes.sm,
lg: o.sizes.lg
}
},
defaultVariants: {
size: "default"
}
}
), re = j(
n(
o.text.base,
"shadow-none flex-1 min-w-0 bg-transparent outline-none border-0 p-0 overflow-hidden text-ellipsis",
"file:text-d-foreground file:inline-flex file:border-0 file:bg-transparent file:text-sm file:font-medium",
o.text.placeholder,
"selection:bg-d-primary selection:text-d-primary-foreground",
o.interaction.disabled,
"[-webkit-autofill]:shadow-[0_0_0_1000px_transparent_inset] [-webkit-autofill]:[-webkit-text-fill-color:inherit]"
),
{
variants: {
size: {
default: "file:h-7",
sm: "text-xs file:h-6",
lg: "text-base file:h-8"
}
},
defaultVariants: {
size: "default"
}
}
), m = {
show: "Mostra password",
hide: "Nascondi password"
}, fe = a.forwardRef(
({
className: A,
type: p,
label: T,
labelClassName: D,
id: G,
iconLeft: v,
iconRight: M,
startContent: S,
endContent: E,
size: g,
disabled: d,
required: C,
onBlur: O,
onChange: _,
onInvalid: z,
"aria-invalid": F,
"aria-describedby": H,
showValidMessage: P = !1,
showValidityMessage: B = !1,
validityI18n: e,
...$
}, J) => {
const [u, K] = a.useState(!1), [h, k] = a.useState(!0), [Q, L] = a.useState(!1), [U, V] = a.useState(""), X = a.useId(), w = G ?? X, R = `${w}-validity`, x = a.useRef(null), b = p === "password", Y = b ? u ? "text" : "password" : p, W = F ?? (!h && Q ? !0 : void 0), Z = [H, B && R].filter(Boolean).join(" ").trim() || void 0;
a.useImperativeHandle(J, () => x.current);
const q = a.useCallback(
(t) => {
if (d) return;
const s = t.target;
if (s.tagName === "INPUT" || s.tagName === "BUTTON") return;
const r = x.current;
r && (r.focus(), !b && p !== "file" && r.select());
},
[d, b, p]
), c = a.useCallback(
(t) => {
const s = t.validity, r = t.validationMessage !== "" ? t.validationMessage : "✓";
if (s.valid)
return {
isValid: !0,
message: P ? e?.valid ?? r : ""
};
if (!e)
return { isValid: !1, message: r };
let i = r;
return s.valueMissing && e.valueMissing ? i = e.valueMissing : s.typeMismatch && e.typeMismatch ? i = e.typeMismatch : s.patternMismatch && e.patternMismatch ? i = e.patternMismatch : s.tooLong && e.tooLong ? i = e.tooLong : s.tooShort && e.tooShort ? i = e.tooShort : s.rangeUnderflow && e.rangeUnderflow ? i = e.rangeUnderflow : s.rangeOverflow && e.rangeOverflow ? i = e.rangeOverflow : s.badInput && e.badInput ? i = e.badInput : s.stepMismatch && e.stepMismatch ? i = e.stepMismatch : s.customError && e.customError && (i = e.customError), { isValid: !1, message: i };
},
[P, e]
);
a.useEffect(() => {
if (x.current) {
const { isValid: t, message: s } = c(x.current);
k(t), V(s);
}
}, [c]);
const y = a.useCallback(
(t) => {
L(!0);
const { isValid: s, message: r } = c(t.currentTarget);
k(s), V(r), _?.(t);
},
[_, c]
), I = a.useCallback(
(t) => {
L(!0), O?.(t);
},
[O, c]
), ee = a.useCallback(
(t) => {
const { isValid: s, message: r } = c(t.currentTarget);
k(s), V(r), z?.(t);
},
[z, c]
);
return /* @__PURE__ */ f("div", { className: n("flex flex-col gap-1.5", A), children: [
T && /* @__PURE__ */ f(se, { htmlFor: w, className: n("gap-0.5", D), children: [
T,
C && h && /* @__PURE__ */ l("div", { children: "*" }),
!h && /* @__PURE__ */ l("div", { className: "text-d-destructive", children: "*" })
] }),
/* @__PURE__ */ f(
"div",
{
className: n(
ae({ size: g }),
d ? "cursor-not-allowed opacity-50" : "cursor-text"
),
"aria-invalid": W,
onClick: q,
children: [
(v || S) && /* @__PURE__ */ f("div", { className: "text-d-muted-foreground flex shrink-0 items-center gap-2", children: [
v && /* @__PURE__ */ l(N, { name: v, size: g === "lg" ? "sm" : "xs" }),
S
] }),
/* @__PURE__ */ l(
"input",
{
id: w,
type: Y,
"data-slot": "input",
className: n(re({ size: g })),
ref: x,
disabled: d,
onChange: y,
onBlur: I,
onInvalid: ee,
"aria-invalid": W,
"aria-describedby": Z,
required: C,
step: p === "number" ? "any" : void 0,
...$
}
),
b ? /* @__PURE__ */ f(
"button",
{
type: "button",
onClick: (t) => {
t.stopPropagation(), t.preventDefault(), K((s) => !s);
},
className: n(
"text-d-muted-foreground flex shrink-0 cursor-pointer items-center",
d && "cursor-not-allowed"
),
"aria-label": u ? m.hide : m.show,
"aria-pressed": u,
"aria-controls": w,
title: u ? m.hide : m.show,
disabled: d,
children: [
/* @__PURE__ */ l(
N,
{
name: u ? "EyeOff" : "Eye",
size: g === "lg" ? "sm" : "xs"
}
),
/* @__PURE__ */ l("span", { className: "sr-only", children: u ? m.hide : m.show })
]
}
) : (M || E) && /* @__PURE__ */ f("div", { className: "text-d-muted-foreground flex shrink-0 items-center gap-2", children: [
E,
M && /* @__PURE__ */ l(N, { name: M, size: g === "lg" ? "sm" : "xs" })
] })
]
}
),
B && U.length > 0 && /* @__PURE__ */ l(
te,
{
variant: "caption",
id: R,
role: h ? "status" : "alert",
"aria-live": "polite",
className: n(
"max-w-full min-w-0 text-wrap",
h ? "text-d-success" : "text-d-destructive"
),
children: U
}
)
] });
}
);
export {
fe as Input,
re as inputVariants
};