erp-pro-ui 0.1.2 → 0.1.3
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/calendar.cjs +1 -1
- package/dist/calendar.mjs +1 -1
- package/dist/card.cjs +1 -1
- package/dist/card.mjs +1 -1
- package/dist/carousel.cjs +1 -1
- package/dist/carousel.mjs +1 -1
- package/dist/catalog.cjs +6 -0
- package/dist/catalog.cjs.map +1 -1
- package/dist/catalog.d.ts +11 -1
- package/dist/catalog.d.ts.map +1 -1
- package/dist/catalog.mjs +6 -0
- package/dist/catalog.mjs.map +1 -1
- package/dist/charts.cjs +2 -1
- package/dist/charts.mjs +2 -2
- package/dist/checkbox.cjs +1 -1
- package/dist/checkbox.mjs +1 -1
- package/dist/chip.cjs +1 -1
- package/dist/chip.mjs +1 -1
- package/dist/chroma-grid.cjs +1 -1
- package/dist/chroma-grid.mjs +1 -1
- package/dist/chunks/{calendar-xrGmvukr.cjs → calendar-Cpp_Rc7T.cjs} +58 -17
- package/dist/chunks/calendar-Cpp_Rc7T.cjs.map +1 -0
- package/dist/chunks/{calendar-BarcG6x_.mjs → calendar-DrCgT_pj.mjs} +58 -17
- package/dist/chunks/calendar-DrCgT_pj.mjs.map +1 -0
- package/dist/chunks/{card-gt-HZh0h.cjs → card-C5_tFK6Q.cjs} +1 -1
- package/dist/chunks/{card-gt-HZh0h.cjs.map → card-C5_tFK6Q.cjs.map} +1 -1
- package/dist/chunks/{card-CcIF6z2H.mjs → card-Dh8wNv8N.mjs} +1 -1
- package/dist/chunks/{card-CcIF6z2H.mjs.map → card-Dh8wNv8N.mjs.map} +1 -1
- package/dist/chunks/{carousel-DJdqBVRK.mjs → carousel-BYwqI4cA.mjs} +1 -1
- package/dist/chunks/{carousel-DJdqBVRK.mjs.map → carousel-BYwqI4cA.mjs.map} +1 -1
- package/dist/chunks/{carousel-Cq5uwqQt.cjs → carousel-C1338X8h.cjs} +1 -1
- package/dist/chunks/{carousel-Cq5uwqQt.cjs.map → carousel-C1338X8h.cjs.map} +1 -1
- package/dist/chunks/{charts-DugYWvEf.mjs → charts-BYvM4TMG.mjs} +371 -117
- package/dist/chunks/charts-BYvM4TMG.mjs.map +1 -0
- package/dist/chunks/{charts-BpElnsoR.cjs → charts-DbxyHtlX.cjs} +375 -115
- package/dist/chunks/charts-DbxyHtlX.cjs.map +1 -0
- package/dist/chunks/{checkbox-yHuSw-hV.cjs → checkbox-CxOcjoGP.cjs} +1 -1
- package/dist/chunks/{checkbox-yHuSw-hV.cjs.map → checkbox-CxOcjoGP.cjs.map} +1 -1
- package/dist/chunks/{checkbox-DvwlGwWe.mjs → checkbox-Pr49U9F1.mjs} +1 -1
- package/dist/chunks/{checkbox-DvwlGwWe.mjs.map → checkbox-Pr49U9F1.mjs.map} +1 -1
- package/dist/chunks/{chip-DcBji__g.cjs → chip-B4ol1yPk.cjs} +1 -1
- package/dist/chunks/{chip-DcBji__g.cjs.map → chip-B4ol1yPk.cjs.map} +1 -1
- package/dist/chunks/{chip-BGSUmnlO.mjs → chip-DdnBLdpl.mjs} +1 -1
- package/dist/chunks/{chip-BGSUmnlO.mjs.map → chip-DdnBLdpl.mjs.map} +1 -1
- package/dist/chunks/{chroma-grid-Cdeql_2C.mjs → chroma-grid-BAo6V5A7.mjs} +1 -1
- package/dist/chunks/{chroma-grid-Cdeql_2C.mjs.map → chroma-grid-BAo6V5A7.mjs.map} +1 -1
- package/dist/chunks/{chroma-grid-9E9j1s9I.cjs → chroma-grid-CIk0dsNS.cjs} +1 -1
- package/dist/chunks/{chroma-grid-9E9j1s9I.cjs.map → chroma-grid-CIk0dsNS.cjs.map} +1 -1
- package/dist/chunks/{color-palette-BLvDnCOD.cjs → color-palette-2TuEMkAn.cjs} +1 -1
- package/dist/chunks/{color-palette-BLvDnCOD.cjs.map → color-palette-2TuEMkAn.cjs.map} +1 -1
- package/dist/chunks/{color-palette-CXlCDiZz.mjs → color-palette-euKQMWlV.mjs} +1 -1
- package/dist/chunks/{color-palette-CXlCDiZz.mjs.map → color-palette-euKQMWlV.mjs.map} +1 -1
- package/dist/chunks/{combobox-BXu3s0dt.cjs → combobox-CwGubKTt.cjs} +2 -2
- package/dist/chunks/combobox-CwGubKTt.cjs.map +1 -0
- package/dist/chunks/{combobox-CjK-qG4k.mjs → combobox-DrFmkI0F.mjs} +2 -2
- package/dist/chunks/combobox-DrFmkI0F.mjs.map +1 -0
- package/dist/chunks/{data-table-DyEQn9Yj.mjs → data-table-Bo80m7qV.mjs} +8 -8
- package/dist/chunks/{data-table-DyEQn9Yj.mjs.map → data-table-Bo80m7qV.mjs.map} +1 -1
- package/dist/chunks/{data-table-9HELVsYR.cjs → data-table-W1sK5tkL.cjs} +8 -8
- package/dist/chunks/{data-table-9HELVsYR.cjs.map → data-table-W1sK5tkL.cjs.map} +1 -1
- package/dist/chunks/{date-picker-D8gaaMlJ.mjs → date-picker-CNPORxhv.mjs} +87 -17
- package/dist/chunks/date-picker-CNPORxhv.mjs.map +1 -0
- package/dist/chunks/{date-picker-W9om1j7A.cjs → date-picker-CZo68Fkl.cjs} +87 -17
- package/dist/chunks/date-picker-CZo68Fkl.cjs.map +1 -0
- package/dist/chunks/input-BWM6G7jq.cjs +117 -0
- package/dist/chunks/input-BWM6G7jq.cjs.map +1 -0
- package/dist/chunks/input-Bt_r_B_c.mjs +105 -0
- package/dist/chunks/input-Bt_r_B_c.mjs.map +1 -0
- package/dist/chunks/{multi-select-combobox-ELSH_Xr4.mjs → multi-select-combobox-D46M-AN9.mjs} +2 -2
- package/dist/chunks/multi-select-combobox-D46M-AN9.mjs.map +1 -0
- package/dist/chunks/{multi-select-combobox-UW0X15W7.cjs → multi-select-combobox-dS6bJE_e.cjs} +2 -2
- package/dist/chunks/multi-select-combobox-dS6bJE_e.cjs.map +1 -0
- package/dist/chunks/{otp-input-B6zzOEqw.cjs → otp-input-DSW9Ca_D.cjs} +2 -2
- package/dist/chunks/otp-input-DSW9Ca_D.cjs.map +1 -0
- package/dist/chunks/{otp-input-Bg4nQG6x.mjs → otp-input-DeAi4nJ_.mjs} +2 -2
- package/dist/chunks/otp-input-DeAi4nJ_.mjs.map +1 -0
- package/dist/chunks/{progress-bar-C9FZDrju.mjs → progress-bar-B9sy7WBT.mjs} +1 -1
- package/dist/chunks/{progress-bar-C9FZDrju.mjs.map → progress-bar-B9sy7WBT.mjs.map} +1 -1
- package/dist/chunks/{progress-bar-C1OvQ-NI.cjs → progress-bar-BdvQtpm3.cjs} +1 -1
- package/dist/chunks/{progress-bar-C1OvQ-NI.cjs.map → progress-bar-BdvQtpm3.cjs.map} +1 -1
- package/dist/chunks/select-B8UQ6Uq5.mjs +170 -0
- package/dist/chunks/select-B8UQ6Uq5.mjs.map +1 -0
- package/dist/chunks/select-CCUSMvfS.cjs +176 -0
- package/dist/chunks/select-CCUSMvfS.cjs.map +1 -0
- package/dist/chunks/stepper-D6qQbZdg.cjs +642 -0
- package/dist/chunks/stepper-D6qQbZdg.cjs.map +1 -0
- package/dist/chunks/stepper-DUknuW2E.mjs +618 -0
- package/dist/chunks/stepper-DUknuW2E.mjs.map +1 -0
- package/dist/chunks/{textarea-CU5C-Zw9.mjs → textarea-Blky_fLK.mjs} +2 -2
- package/dist/chunks/{textarea-CU5C-Zw9.mjs.map → textarea-Blky_fLK.mjs.map} +1 -1
- package/dist/chunks/{textarea-CAUsyu4-.cjs → textarea-ok_NlE2p.cjs} +2 -2
- package/dist/chunks/textarea-ok_NlE2p.cjs.map +1 -0
- package/dist/color-palette.cjs +1 -1
- package/dist/color-palette.mjs +1 -1
- package/dist/colors.css +3 -0
- package/dist/combobox.cjs +1 -1
- package/dist/combobox.mjs +1 -1
- package/dist/components/data-display/charts/AreaChart.d.ts.map +1 -1
- package/dist/components/data-display/charts/BarChart.d.ts +1 -0
- package/dist/components/data-display/charts/BarChart.d.ts.map +1 -1
- package/dist/components/data-display/charts/NeonLineChart.d.ts.map +1 -1
- package/dist/components/data-display/charts/PieChart.d.ts +18 -2
- package/dist/components/data-display/charts/PieChart.d.ts.map +1 -1
- package/dist/components/data-display/charts/PositiveNegativeBarChart.d.ts +21 -0
- package/dist/components/data-display/charts/PositiveNegativeBarChart.d.ts.map +1 -0
- package/dist/components/data-display/charts/StackedBarChart.d.ts.map +1 -1
- package/dist/components/data-display/charts/ThinBreakdownBar.d.ts +3 -0
- package/dist/components/data-display/charts/ThinBreakdownBar.d.ts.map +1 -1
- package/dist/components/data-display/charts/chartStyles.d.ts +24 -0
- package/dist/components/data-display/charts/chartStyles.d.ts.map +1 -0
- package/dist/components/data-display/charts/index.d.ts +2 -0
- package/dist/components/data-display/charts/index.d.ts.map +1 -1
- package/dist/components/forms/calendar/Calendar.d.ts.map +1 -1
- package/dist/components/forms/date-picker/DatePicker.d.ts.map +1 -1
- package/dist/components/forms/input/Input.d.ts.map +1 -1
- package/dist/components/forms/input/types.d.ts +5 -0
- package/dist/components/forms/input/types.d.ts.map +1 -1
- package/dist/components/forms/select/Select.d.ts.map +1 -1
- package/dist/components/forms/select/types.d.ts +7 -1
- package/dist/components/forms/select/types.d.ts.map +1 -1
- package/dist/components/navigation/stepper/Stepper1.d.ts +4 -0
- package/dist/components/navigation/stepper/Stepper1.d.ts.map +1 -0
- package/dist/components/navigation/stepper/Stepper2.d.ts +5 -0
- package/dist/components/navigation/stepper/Stepper2.d.ts.map +1 -0
- package/dist/components/navigation/stepper/index.d.ts +4 -1
- package/dist/components/navigation/stepper/index.d.ts.map +1 -1
- package/dist/components/navigation/stepper/types.d.ts +85 -0
- package/dist/components/navigation/stepper/types.d.ts.map +1 -1
- package/dist/data-table.cjs +1 -1
- package/dist/data-table.mjs +1 -1
- package/dist/date-picker.cjs +1 -1
- package/dist/date-picker.mjs +1 -1
- package/dist/docs.cjs +10 -0
- package/dist/docs.cjs.map +1 -1
- package/dist/docs.d.ts.map +1 -1
- package/dist/docs.mjs +10 -0
- package/dist/docs.mjs.map +1 -1
- package/dist/foundation.css +7 -0
- package/dist/index.cjs +23 -18
- package/dist/index.d.ts +5 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +19 -19
- package/dist/input.cjs +1 -1
- package/dist/input.mjs +1 -1
- package/dist/multi-select-combobox.cjs +1 -1
- package/dist/multi-select-combobox.mjs +1 -1
- package/dist/otp-input.cjs +1 -1
- package/dist/otp-input.mjs +1 -1
- package/dist/progress-bar.cjs +1 -1
- package/dist/progress-bar.mjs +1 -1
- package/dist/select.cjs +1 -1
- package/dist/select.mjs +1 -1
- package/dist/stepper.cjs +5 -1
- package/dist/stepper.mjs +2 -2
- package/dist/textarea.cjs +1 -1
- package/dist/textarea.mjs +1 -1
- package/dist/tokens.css +11 -2
- package/package.json +4 -4
- package/dist/chunks/calendar-BarcG6x_.mjs.map +0 -1
- package/dist/chunks/calendar-xrGmvukr.cjs.map +0 -1
- package/dist/chunks/charts-BpElnsoR.cjs.map +0 -1
- package/dist/chunks/charts-DugYWvEf.mjs.map +0 -1
- package/dist/chunks/combobox-BXu3s0dt.cjs.map +0 -1
- package/dist/chunks/combobox-CjK-qG4k.mjs.map +0 -1
- package/dist/chunks/date-picker-D8gaaMlJ.mjs.map +0 -1
- package/dist/chunks/date-picker-W9om1j7A.cjs.map +0 -1
- package/dist/chunks/input-D9qZNqXV.cjs +0 -99
- package/dist/chunks/input-D9qZNqXV.cjs.map +0 -1
- package/dist/chunks/input-wNqevfQ4.mjs +0 -87
- package/dist/chunks/input-wNqevfQ4.mjs.map +0 -1
- package/dist/chunks/multi-select-combobox-ELSH_Xr4.mjs.map +0 -1
- package/dist/chunks/multi-select-combobox-UW0X15W7.cjs.map +0 -1
- package/dist/chunks/otp-input-B6zzOEqw.cjs.map +0 -1
- package/dist/chunks/otp-input-Bg4nQG6x.mjs.map +0 -1
- package/dist/chunks/select-D71tk6-I.mjs +0 -152
- package/dist/chunks/select-D71tk6-I.mjs.map +0 -1
- package/dist/chunks/select-WC_kPqUP.cjs +0 -158
- package/dist/chunks/select-WC_kPqUP.cjs.map +0 -1
- package/dist/chunks/stepper-D4yQsQB0.mjs +0 -261
- package/dist/chunks/stepper-D4yQsQB0.mjs.map +0 -1
- package/dist/chunks/stepper-fY-Sx72k.cjs +0 -267
- package/dist/chunks/stepper-fY-Sx72k.cjs.map +0 -1
- package/dist/chunks/textarea-CAUsyu4-.cjs.map +0 -1
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
require("./chunk-B_GkZjkl.cjs");
|
|
2
|
-
const require_utils = require("./utils-B4SmmY4J.cjs");
|
|
3
|
-
let react = require("react");
|
|
4
|
-
let react_jsx_runtime = require("react/jsx-runtime");
|
|
5
|
-
let framer_motion = require("framer-motion");
|
|
6
|
-
//#region src/components/forms/input/types.ts
|
|
7
|
-
var InputState = /* @__PURE__ */ function(InputState) {
|
|
8
|
-
InputState["DEFAULT"] = "default";
|
|
9
|
-
InputState["DISABLED"] = "disabled";
|
|
10
|
-
InputState["ERROR"] = "error";
|
|
11
|
-
InputState["SUCCESS"] = "success";
|
|
12
|
-
return InputState;
|
|
13
|
-
}({});
|
|
14
|
-
//#endregion
|
|
15
|
-
//#region src/components/forms/input/Input.tsx
|
|
16
|
-
var Input = (0, react.forwardRef)(({ className = "", label, error, helperText, id, extra, placeholder, state = InputState.DEFAULT, disabled, message, icon, iconClassName, bgClassName = "bg-background-secondary", ...props }, ref) => {
|
|
17
|
-
const radius = 100;
|
|
18
|
-
const [visible, setVisible] = (0, react.useState)(false);
|
|
19
|
-
const mouseX = (0, framer_motion.useMotionValue)(0);
|
|
20
|
-
const mouseY = (0, framer_motion.useMotionValue)(0);
|
|
21
|
-
const handleMouseMove = (event) => {
|
|
22
|
-
const { left, top } = event.currentTarget.getBoundingClientRect();
|
|
23
|
-
mouseX.set(event.clientX - left);
|
|
24
|
-
mouseY.set(event.clientY - top);
|
|
25
|
-
};
|
|
26
|
-
const wrapperStateStyles = {
|
|
27
|
-
[InputState.DISABLED]: "bg-muted border-none",
|
|
28
|
-
[InputState.ERROR]: "border-destructive ",
|
|
29
|
-
[InputState.SUCCESS]: "border-success-border ",
|
|
30
|
-
[InputState.DEFAULT]: "border-border "
|
|
31
|
-
};
|
|
32
|
-
const inputStateStyles = {
|
|
33
|
-
[InputState.DISABLED]: "placeholder:!text-muted-foreground",
|
|
34
|
-
[InputState.ERROR]: "text-destructive placeholder:text-destructive",
|
|
35
|
-
[InputState.SUCCESS]: "text-success placeholder:text-success",
|
|
36
|
-
[InputState.DEFAULT]: "text-foreground"
|
|
37
|
-
};
|
|
38
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
39
|
-
className: "w-full",
|
|
40
|
-
children: [
|
|
41
|
-
label && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
42
|
-
className: "text-sm font-medium text-foreground leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70 mb-2 block",
|
|
43
|
-
children: label
|
|
44
|
-
}),
|
|
45
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(framer_motion.motion.div, {
|
|
46
|
-
style: { backgroundImage: disabled ? "none" : framer_motion.useMotionTemplate`
|
|
47
|
-
radial-gradient(
|
|
48
|
-
${visible ? `${radius}px` : "0px"} circle at ${mouseX}px ${mouseY}px,
|
|
49
|
-
var(--ds-color-accent),
|
|
50
|
-
transparent 90%
|
|
51
|
-
)
|
|
52
|
-
` },
|
|
53
|
-
onMouseMove: !disabled ? handleMouseMove : void 0,
|
|
54
|
-
onMouseEnter: !disabled ? () => setVisible(true) : void 0,
|
|
55
|
-
onMouseLeave: !disabled ? () => setVisible(false) : void 0,
|
|
56
|
-
className: require_utils.mergeClassNames("group/input rounded-lg p-[2px] transition duration-300 hover:border-accent", wrapperStateStyles[state], extra),
|
|
57
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
58
|
-
className: "relative flex items-center ",
|
|
59
|
-
children: [icon && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
60
|
-
className: require_utils.mergeClassNames("pointer-events-none absolute inset-y-0 right-0 flex items-center pr-3", iconClassName),
|
|
61
|
-
children: icon
|
|
62
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
63
|
-
ref,
|
|
64
|
-
id,
|
|
65
|
-
placeholder,
|
|
66
|
-
disabled,
|
|
67
|
-
className: require_utils.mergeClassNames("shadow-input flex h-10 w-full rounded-md border border-input px-3 py-2 text-sm text-foreground transition duration-400 ease-in-out group-hover/input:shadow-none file:border-0 file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:ring-2 focus-visible:ring-accent focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50", bgClassName, inputStateStyles[state], className),
|
|
68
|
-
...props,
|
|
69
|
-
autoComplete: "off"
|
|
70
|
-
})]
|
|
71
|
-
})
|
|
72
|
-
}),
|
|
73
|
-
(error || message) && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
74
|
-
className: require_utils.mergeClassNames("text-sm font-medium mt-1", error ? "text-destructive" : "text-muted-foreground"),
|
|
75
|
-
children: error || message
|
|
76
|
-
}),
|
|
77
|
-
helperText && !error && !message && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
78
|
-
className: "text-sm text-neutral-500 dark:text-neutral-400 mt-1",
|
|
79
|
-
children: helperText
|
|
80
|
-
})
|
|
81
|
-
]
|
|
82
|
-
});
|
|
83
|
-
});
|
|
84
|
-
Input.displayName = "Input";
|
|
85
|
-
//#endregion
|
|
86
|
-
Object.defineProperty(exports, "Input", {
|
|
87
|
-
enumerable: true,
|
|
88
|
-
get: function() {
|
|
89
|
-
return Input;
|
|
90
|
-
}
|
|
91
|
-
});
|
|
92
|
-
Object.defineProperty(exports, "InputState", {
|
|
93
|
-
enumerable: true,
|
|
94
|
-
get: function() {
|
|
95
|
-
return InputState;
|
|
96
|
-
}
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
//# sourceMappingURL=input-D9qZNqXV.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"input-D9qZNqXV.cjs","names":[],"sources":["../../src/components/forms/input/types.ts","../../src/components/forms/input/Input.tsx"],"sourcesContent":["import type { InputHTMLAttributes, ReactNode } from \"react\";\n\nexport enum InputState {\n DEFAULT = \"default\",\n DISABLED = \"disabled\",\n ERROR = \"error\",\n SUCCESS = \"success\",\n}\n\nexport interface InputProps extends InputHTMLAttributes<HTMLInputElement> {\n label?: string;\n error?: string;\n helperText?: string;\n id?: string;\n extra?: string;\n state?: InputState;\n message?: string;\n icon?: ReactNode;\n iconClassName?: string;\n /** Custom background classes for light/dark mode (e.g. \"ui:bg-white ui:dark:bg-zinc-900\") */\n bgClassName?: string;\n}\n","import { forwardRef, useState } from \"react\";\nimport { type InputProps, InputState } from \"./types\";\nimport { motion, useMotionTemplate, useMotionValue } from \"framer-motion\";\nimport { mergeClassNames } from \"../../../utils\";\n\nexport const Input = forwardRef<HTMLInputElement, InputProps>(\n (\n {\n className = \"\",\n label,\n error,\n helperText,\n id,\n extra,\n placeholder,\n state = InputState.DEFAULT,\n disabled,\n message,\n icon,\n iconClassName,\n // bgClassName = \"bg-zinc-950/40\",\n bgClassName = \"bg-background-secondary\",\n // bgClassName = \"bg-white/40 dark:bg-zinc-950/40 backdrop-blur-xl\",\n ...props\n },\n ref,\n ) => {\n const radius = 100; // Radius for the hover effect\n const [visible, setVisible] = useState(false);\n const mouseX = useMotionValue(0);\n const mouseY = useMotionValue(0);\n\n const handleMouseMove = (event: React.MouseEvent<HTMLDivElement>) => {\n const { left, top } = event.currentTarget.getBoundingClientRect();\n mouseX.set(event.clientX - left);\n mouseY.set(event.clientY - top);\n };\n\n const wrapperStateStyles: Record<InputState, string> = {\n [InputState.DISABLED]: \"bg-muted border-none\",\n [InputState.ERROR]: \"border-destructive \",\n [InputState.SUCCESS]: \"border-success-border \",\n [InputState.DEFAULT]: \"border-border \",\n };\n\n const inputStateStyles: Record<InputState, string> = {\n [InputState.DISABLED]: \"placeholder:!text-muted-foreground\",\n [InputState.ERROR]: \"text-destructive placeholder:text-destructive\",\n [InputState.SUCCESS]: \"text-success placeholder:text-success\",\n [InputState.DEFAULT]: \"text-foreground\",\n };\n\n return (\n <div className=\"w-full\">\n {label && (\n <label className=\"text-sm font-medium text-foreground leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70 mb-2 block\">\n {label}\n </label>\n )}\n\n <motion.div\n style={{\n backgroundImage: disabled\n ? \"none\"\n : useMotionTemplate`\n radial-gradient(\n ${\n visible ? `${radius}px` : \"0px\"\n } circle at ${mouseX}px ${mouseY}px,\n var(--ds-color-accent),\n transparent 90%\n )\n `,\n }}\n onMouseMove={!disabled ? handleMouseMove : undefined}\n onMouseEnter={!disabled ? () => setVisible(true) : undefined}\n onMouseLeave={!disabled ? () => setVisible(false) : undefined}\n className={mergeClassNames(\n \"group/input rounded-lg p-[2px] transition duration-300 hover:border-accent\",\n wrapperStateStyles[state],\n extra,\n )}\n >\n <div className=\"relative flex items-center \">\n {icon && (\n <div\n className={mergeClassNames(\n \"pointer-events-none absolute inset-y-0 right-0 flex items-center pr-3\",\n iconClassName,\n )}\n >\n {icon}\n </div>\n )}\n <input\n ref={ref}\n id={id}\n placeholder={placeholder}\n disabled={disabled}\n className={mergeClassNames(\n \"shadow-input flex h-10 w-full rounded-md border border-input px-3 py-2 text-sm text-foreground transition duration-400 ease-in-out group-hover/input:shadow-none file:border-0 file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:ring-2 focus-visible:ring-accent focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50\",\n bgClassName,\n inputStateStyles[state],\n className,\n )}\n {...props}\n autoComplete=\"off\"\n />\n </div>\n </motion.div>\n\n {(error || message) && (\n <p\n className={mergeClassNames(\n \"text-sm font-medium mt-1\",\n error ? \"text-destructive\" : \"text-muted-foreground\",\n )}\n >\n {error || message}\n </p>\n )}\n {helperText && !error && !message && (\n <p className=\"text-sm text-neutral-500 dark:text-neutral-400 mt-1\">\n {helperText}\n </p>\n )}\n </div>\n );\n },\n);\n\nInput.displayName = \"Input\";\n"],"mappings":";;;;;;AAEA,IAAY,aAAL,yBAAA,YAAA;AACL,YAAA,aAAA;AACA,YAAA,cAAA;AACA,YAAA,WAAA;AACA,YAAA,aAAA;;KACD;;;ACFD,IAAa,SAAA,GAAA,MAAA,aAET,EACE,YAAY,IACZ,OACA,OACA,YACA,IACA,OACA,aACA,QAAQ,WAAW,SACnB,UACA,SACA,MACA,eAEA,cAAc,2BAEd,GAAG,SAEL,QACG;CACH,MAAM,SAAS;CACf,MAAM,CAAC,SAAS,eAAA,GAAA,MAAA,UAAuB,MAAM;CAC7C,MAAM,UAAA,GAAA,cAAA,gBAAwB,EAAE;CAChC,MAAM,UAAA,GAAA,cAAA,gBAAwB,EAAE;CAEhC,MAAM,mBAAmB,UAA4C;EACnE,MAAM,EAAE,MAAM,QAAQ,MAAM,cAAc,uBAAuB;AACjE,SAAO,IAAI,MAAM,UAAU,KAAK;AAChC,SAAO,IAAI,MAAM,UAAU,IAAI;;CAGjC,MAAM,qBAAiD;GACpD,WAAW,WAAW;GACtB,WAAW,QAAQ;GACnB,WAAW,UAAU;GACrB,WAAW,UAAU;EACvB;CAED,MAAM,mBAA+C;GAClD,WAAW,WAAW;GACtB,WAAW,QAAQ;GACnB,WAAW,UAAU;GACrB,WAAW,UAAU;EACvB;AAED,QACE,iBAAA,GAAA,kBAAA,MAAC,OAAD;EAAK,WAAU;YAAf;GACG,SACC,iBAAA,GAAA,kBAAA,KAAC,SAAD;IAAO,WAAU;cACd;IACK,CAAA;GAGV,iBAAA,GAAA,kBAAA,KAAC,cAAA,OAAO,KAAR;IACE,OAAO,EACL,iBAAiB,WACb,SACA,cAAA,iBAAiB;;sBAGX,UAAU,GAAG,OAAO,MAAM,MAC3B,aAAa,OAAO,KAAK,OAAO;;;;mBAK1C;IACD,aAAa,CAAC,WAAW,kBAAkB,KAAA;IAC3C,cAAc,CAAC,iBAAiB,WAAW,KAAK,GAAG,KAAA;IACnD,cAAc,CAAC,iBAAiB,WAAW,MAAM,GAAG,KAAA;IACpD,WAAW,cAAA,gBACT,8EACA,mBAAmB,QACnB,MACD;cAED,iBAAA,GAAA,kBAAA,MAAC,OAAD;KAAK,WAAU;eAAf,CACG,QACC,iBAAA,GAAA,kBAAA,KAAC,OAAD;MACE,WAAW,cAAA,gBACT,yEACA,cACD;gBAEA;MACG,CAAA,EAER,iBAAA,GAAA,kBAAA,KAAC,SAAD;MACO;MACD;MACS;MACH;MACV,WAAW,cAAA,gBACT,6WACA,aACA,iBAAiB,QACjB,UACD;MACD,GAAI;MACJ,cAAa;MACb,CAAA,CACE;;IACK,CAAA;IAEX,SAAS,YACT,iBAAA,GAAA,kBAAA,KAAC,KAAD;IACE,WAAW,cAAA,gBACT,4BACA,QAAQ,qBAAqB,wBAC9B;cAEA,SAAS;IACR,CAAA;GAEL,cAAc,CAAC,SAAS,CAAC,WACxB,iBAAA,GAAA,kBAAA,KAAC,KAAD;IAAG,WAAU;cACV;IACC,CAAA;GAEF;;EAGX;AAED,MAAM,cAAc"}
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
import { n as mergeClassNames } from "./utils-ati1KkDb.mjs";
|
|
2
|
-
import { forwardRef, useState } from "react";
|
|
3
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
|
-
import { motion, useMotionTemplate, useMotionValue } from "framer-motion";
|
|
5
|
-
//#region src/components/forms/input/types.ts
|
|
6
|
-
var InputState = /* @__PURE__ */ function(InputState) {
|
|
7
|
-
InputState["DEFAULT"] = "default";
|
|
8
|
-
InputState["DISABLED"] = "disabled";
|
|
9
|
-
InputState["ERROR"] = "error";
|
|
10
|
-
InputState["SUCCESS"] = "success";
|
|
11
|
-
return InputState;
|
|
12
|
-
}({});
|
|
13
|
-
//#endregion
|
|
14
|
-
//#region src/components/forms/input/Input.tsx
|
|
15
|
-
var Input = forwardRef(({ className = "", label, error, helperText, id, extra, placeholder, state = InputState.DEFAULT, disabled, message, icon, iconClassName, bgClassName = "bg-background-secondary", ...props }, ref) => {
|
|
16
|
-
const radius = 100;
|
|
17
|
-
const [visible, setVisible] = useState(false);
|
|
18
|
-
const mouseX = useMotionValue(0);
|
|
19
|
-
const mouseY = useMotionValue(0);
|
|
20
|
-
const handleMouseMove = (event) => {
|
|
21
|
-
const { left, top } = event.currentTarget.getBoundingClientRect();
|
|
22
|
-
mouseX.set(event.clientX - left);
|
|
23
|
-
mouseY.set(event.clientY - top);
|
|
24
|
-
};
|
|
25
|
-
const wrapperStateStyles = {
|
|
26
|
-
[InputState.DISABLED]: "bg-muted border-none",
|
|
27
|
-
[InputState.ERROR]: "border-destructive ",
|
|
28
|
-
[InputState.SUCCESS]: "border-success-border ",
|
|
29
|
-
[InputState.DEFAULT]: "border-border "
|
|
30
|
-
};
|
|
31
|
-
const inputStateStyles = {
|
|
32
|
-
[InputState.DISABLED]: "placeholder:!text-muted-foreground",
|
|
33
|
-
[InputState.ERROR]: "text-destructive placeholder:text-destructive",
|
|
34
|
-
[InputState.SUCCESS]: "text-success placeholder:text-success",
|
|
35
|
-
[InputState.DEFAULT]: "text-foreground"
|
|
36
|
-
};
|
|
37
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
38
|
-
className: "w-full",
|
|
39
|
-
children: [
|
|
40
|
-
label && /* @__PURE__ */ jsx("label", {
|
|
41
|
-
className: "text-sm font-medium text-foreground leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70 mb-2 block",
|
|
42
|
-
children: label
|
|
43
|
-
}),
|
|
44
|
-
/* @__PURE__ */ jsx(motion.div, {
|
|
45
|
-
style: { backgroundImage: disabled ? "none" : useMotionTemplate`
|
|
46
|
-
radial-gradient(
|
|
47
|
-
${visible ? `${radius}px` : "0px"} circle at ${mouseX}px ${mouseY}px,
|
|
48
|
-
var(--ds-color-accent),
|
|
49
|
-
transparent 90%
|
|
50
|
-
)
|
|
51
|
-
` },
|
|
52
|
-
onMouseMove: !disabled ? handleMouseMove : void 0,
|
|
53
|
-
onMouseEnter: !disabled ? () => setVisible(true) : void 0,
|
|
54
|
-
onMouseLeave: !disabled ? () => setVisible(false) : void 0,
|
|
55
|
-
className: mergeClassNames("group/input rounded-lg p-[2px] transition duration-300 hover:border-accent", wrapperStateStyles[state], extra),
|
|
56
|
-
children: /* @__PURE__ */ jsxs("div", {
|
|
57
|
-
className: "relative flex items-center ",
|
|
58
|
-
children: [icon && /* @__PURE__ */ jsx("div", {
|
|
59
|
-
className: mergeClassNames("pointer-events-none absolute inset-y-0 right-0 flex items-center pr-3", iconClassName),
|
|
60
|
-
children: icon
|
|
61
|
-
}), /* @__PURE__ */ jsx("input", {
|
|
62
|
-
ref,
|
|
63
|
-
id,
|
|
64
|
-
placeholder,
|
|
65
|
-
disabled,
|
|
66
|
-
className: mergeClassNames("shadow-input flex h-10 w-full rounded-md border border-input px-3 py-2 text-sm text-foreground transition duration-400 ease-in-out group-hover/input:shadow-none file:border-0 file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:ring-2 focus-visible:ring-accent focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50", bgClassName, inputStateStyles[state], className),
|
|
67
|
-
...props,
|
|
68
|
-
autoComplete: "off"
|
|
69
|
-
})]
|
|
70
|
-
})
|
|
71
|
-
}),
|
|
72
|
-
(error || message) && /* @__PURE__ */ jsx("p", {
|
|
73
|
-
className: mergeClassNames("text-sm font-medium mt-1", error ? "text-destructive" : "text-muted-foreground"),
|
|
74
|
-
children: error || message
|
|
75
|
-
}),
|
|
76
|
-
helperText && !error && !message && /* @__PURE__ */ jsx("p", {
|
|
77
|
-
className: "text-sm text-neutral-500 dark:text-neutral-400 mt-1",
|
|
78
|
-
children: helperText
|
|
79
|
-
})
|
|
80
|
-
]
|
|
81
|
-
});
|
|
82
|
-
});
|
|
83
|
-
Input.displayName = "Input";
|
|
84
|
-
//#endregion
|
|
85
|
-
export { InputState as n, Input as t };
|
|
86
|
-
|
|
87
|
-
//# sourceMappingURL=input-wNqevfQ4.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"input-wNqevfQ4.mjs","names":[],"sources":["../../src/components/forms/input/types.ts","../../src/components/forms/input/Input.tsx"],"sourcesContent":["import type { InputHTMLAttributes, ReactNode } from \"react\";\n\nexport enum InputState {\n DEFAULT = \"default\",\n DISABLED = \"disabled\",\n ERROR = \"error\",\n SUCCESS = \"success\",\n}\n\nexport interface InputProps extends InputHTMLAttributes<HTMLInputElement> {\n label?: string;\n error?: string;\n helperText?: string;\n id?: string;\n extra?: string;\n state?: InputState;\n message?: string;\n icon?: ReactNode;\n iconClassName?: string;\n /** Custom background classes for light/dark mode (e.g. \"ui:bg-white ui:dark:bg-zinc-900\") */\n bgClassName?: string;\n}\n","import { forwardRef, useState } from \"react\";\nimport { type InputProps, InputState } from \"./types\";\nimport { motion, useMotionTemplate, useMotionValue } from \"framer-motion\";\nimport { mergeClassNames } from \"../../../utils\";\n\nexport const Input = forwardRef<HTMLInputElement, InputProps>(\n (\n {\n className = \"\",\n label,\n error,\n helperText,\n id,\n extra,\n placeholder,\n state = InputState.DEFAULT,\n disabled,\n message,\n icon,\n iconClassName,\n // bgClassName = \"bg-zinc-950/40\",\n bgClassName = \"bg-background-secondary\",\n // bgClassName = \"bg-white/40 dark:bg-zinc-950/40 backdrop-blur-xl\",\n ...props\n },\n ref,\n ) => {\n const radius = 100; // Radius for the hover effect\n const [visible, setVisible] = useState(false);\n const mouseX = useMotionValue(0);\n const mouseY = useMotionValue(0);\n\n const handleMouseMove = (event: React.MouseEvent<HTMLDivElement>) => {\n const { left, top } = event.currentTarget.getBoundingClientRect();\n mouseX.set(event.clientX - left);\n mouseY.set(event.clientY - top);\n };\n\n const wrapperStateStyles: Record<InputState, string> = {\n [InputState.DISABLED]: \"bg-muted border-none\",\n [InputState.ERROR]: \"border-destructive \",\n [InputState.SUCCESS]: \"border-success-border \",\n [InputState.DEFAULT]: \"border-border \",\n };\n\n const inputStateStyles: Record<InputState, string> = {\n [InputState.DISABLED]: \"placeholder:!text-muted-foreground\",\n [InputState.ERROR]: \"text-destructive placeholder:text-destructive\",\n [InputState.SUCCESS]: \"text-success placeholder:text-success\",\n [InputState.DEFAULT]: \"text-foreground\",\n };\n\n return (\n <div className=\"w-full\">\n {label && (\n <label className=\"text-sm font-medium text-foreground leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70 mb-2 block\">\n {label}\n </label>\n )}\n\n <motion.div\n style={{\n backgroundImage: disabled\n ? \"none\"\n : useMotionTemplate`\n radial-gradient(\n ${\n visible ? `${radius}px` : \"0px\"\n } circle at ${mouseX}px ${mouseY}px,\n var(--ds-color-accent),\n transparent 90%\n )\n `,\n }}\n onMouseMove={!disabled ? handleMouseMove : undefined}\n onMouseEnter={!disabled ? () => setVisible(true) : undefined}\n onMouseLeave={!disabled ? () => setVisible(false) : undefined}\n className={mergeClassNames(\n \"group/input rounded-lg p-[2px] transition duration-300 hover:border-accent\",\n wrapperStateStyles[state],\n extra,\n )}\n >\n <div className=\"relative flex items-center \">\n {icon && (\n <div\n className={mergeClassNames(\n \"pointer-events-none absolute inset-y-0 right-0 flex items-center pr-3\",\n iconClassName,\n )}\n >\n {icon}\n </div>\n )}\n <input\n ref={ref}\n id={id}\n placeholder={placeholder}\n disabled={disabled}\n className={mergeClassNames(\n \"shadow-input flex h-10 w-full rounded-md border border-input px-3 py-2 text-sm text-foreground transition duration-400 ease-in-out group-hover/input:shadow-none file:border-0 file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:ring-2 focus-visible:ring-accent focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50\",\n bgClassName,\n inputStateStyles[state],\n className,\n )}\n {...props}\n autoComplete=\"off\"\n />\n </div>\n </motion.div>\n\n {(error || message) && (\n <p\n className={mergeClassNames(\n \"text-sm font-medium mt-1\",\n error ? \"text-destructive\" : \"text-muted-foreground\",\n )}\n >\n {error || message}\n </p>\n )}\n {helperText && !error && !message && (\n <p className=\"text-sm text-neutral-500 dark:text-neutral-400 mt-1\">\n {helperText}\n </p>\n )}\n </div>\n );\n },\n);\n\nInput.displayName = \"Input\";\n"],"mappings":";;;;;AAEA,IAAY,aAAL,yBAAA,YAAA;AACL,YAAA,aAAA;AACA,YAAA,cAAA;AACA,YAAA,WAAA;AACA,YAAA,aAAA;;KACD;;;ACFD,IAAa,QAAQ,YAEjB,EACE,YAAY,IACZ,OACA,OACA,YACA,IACA,OACA,aACA,QAAQ,WAAW,SACnB,UACA,SACA,MACA,eAEA,cAAc,2BAEd,GAAG,SAEL,QACG;CACH,MAAM,SAAS;CACf,MAAM,CAAC,SAAS,cAAc,SAAS,MAAM;CAC7C,MAAM,SAAS,eAAe,EAAE;CAChC,MAAM,SAAS,eAAe,EAAE;CAEhC,MAAM,mBAAmB,UAA4C;EACnE,MAAM,EAAE,MAAM,QAAQ,MAAM,cAAc,uBAAuB;AACjE,SAAO,IAAI,MAAM,UAAU,KAAK;AAChC,SAAO,IAAI,MAAM,UAAU,IAAI;;CAGjC,MAAM,qBAAiD;GACpD,WAAW,WAAW;GACtB,WAAW,QAAQ;GACnB,WAAW,UAAU;GACrB,WAAW,UAAU;EACvB;CAED,MAAM,mBAA+C;GAClD,WAAW,WAAW;GACtB,WAAW,QAAQ;GACnB,WAAW,UAAU;GACrB,WAAW,UAAU;EACvB;AAED,QACE,qBAAC,OAAD;EAAK,WAAU;YAAf;GACG,SACC,oBAAC,SAAD;IAAO,WAAU;cACd;IACK,CAAA;GAGV,oBAAC,OAAO,KAAR;IACE,OAAO,EACL,iBAAiB,WACb,SACA,iBAAiB;;sBAGX,UAAU,GAAG,OAAO,MAAM,MAC3B,aAAa,OAAO,KAAK,OAAO;;;;mBAK1C;IACD,aAAa,CAAC,WAAW,kBAAkB,KAAA;IAC3C,cAAc,CAAC,iBAAiB,WAAW,KAAK,GAAG,KAAA;IACnD,cAAc,CAAC,iBAAiB,WAAW,MAAM,GAAG,KAAA;IACpD,WAAW,gBACT,8EACA,mBAAmB,QACnB,MACD;cAED,qBAAC,OAAD;KAAK,WAAU;eAAf,CACG,QACC,oBAAC,OAAD;MACE,WAAW,gBACT,yEACA,cACD;gBAEA;MACG,CAAA,EAER,oBAAC,SAAD;MACO;MACD;MACS;MACH;MACV,WAAW,gBACT,6WACA,aACA,iBAAiB,QACjB,UACD;MACD,GAAI;MACJ,cAAa;MACb,CAAA,CACE;;IACK,CAAA;IAEX,SAAS,YACT,oBAAC,KAAD;IACE,WAAW,gBACT,4BACA,QAAQ,qBAAqB,wBAC9B;cAEA,SAAS;IACR,CAAA;GAEL,cAAc,CAAC,SAAS,CAAC,WACxB,oBAAC,KAAD;IAAG,WAAU;cACV;IACC,CAAA;GAEF;;EAGX;AAED,MAAM,cAAc"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"multi-select-combobox-ELSH_Xr4.mjs","names":[],"sources":["../../src/components/forms/multi-select-combobox/MultiSelectCombobox.tsx"],"sourcesContent":["import React, { useEffect, useRef, useState } from \"react\";\nimport { motion, useMotionTemplate, useMotionValue } from \"framer-motion\";\n\nimport { CheckIcon, ChevronDownIcon, CloseIcon } from \"../../icons\";\nimport { mergeClassNames } from \"../../../utils\";\n\nexport interface MultiSelectOption {\n label: string;\n value: string;\n}\n\nexport interface MultiSelectComboboxProps {\n options: MultiSelectOption[];\n value: string[];\n onChange: (values: string[]) => void;\n placeholder?: string;\n className?: string;\n bgClassName?: string;\n}\n\nconst MultiSelectCombobox: React.FC<MultiSelectComboboxProps> = ({\n options,\n value = [],\n onChange,\n placeholder = \"Select...\",\n className,\n bgClassName = \"bg-background-secondary\",\n}) => {\n const [open, setOpen] = useState(false);\n const [search, setSearch] = useState(\"\");\n const [visible, setVisible] = useState(false);\n const ref = useRef<HTMLDivElement>(null);\n const mouseX = useMotionValue(0);\n const mouseY = useMotionValue(0);\n const radius = 100;\n\n // Filter options by search\n const filteredOptions = options.filter((opt) =>\n opt.label.toLowerCase().includes(search.toLowerCase()),\n );\n\n // Close dropdown on outside click\n useEffect(() => {\n const handleClick = (e: MouseEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node)) {\n setOpen(false);\n setSearch(\"\");\n }\n };\n if (open) {\n document.addEventListener(\"mousedown\", handleClick);\n }\n return () => document.removeEventListener(\"mousedown\", handleClick);\n }, [open]);\n\n const handleMouseMove = (event: React.MouseEvent<HTMLDivElement>) => {\n const { left, top } = event.currentTarget.getBoundingClientRect();\n mouseX.set(event.clientX - left);\n mouseY.set(event.clientY - top);\n };\n\n const handleOptionClick = (optionValue: string) => {\n if (value.includes(optionValue)) {\n onChange(value.filter((v) => v !== optionValue));\n } else {\n onChange([...value, optionValue]);\n }\n };\n\n const handleRemoveTag = (optionValue: string, e: React.MouseEvent) => {\n e.stopPropagation();\n onChange(value.filter((v) => v !== optionValue));\n };\n\n const selectedLabels = value\n .map((v) => options.find((opt) => opt.value === v)?.label)\n .filter(Boolean);\n\n return (\n <div\n ref={ref}\n className={mergeClassNames(\"relative w-full\", className)}\n tabIndex={0}\n >\n <motion.div\n style={{\n backgroundImage: useMotionTemplate`\n radial-gradient(\n ${visible ? `${radius}px` : \"0px\"} circle at ${mouseX}px ${mouseY}px,\n var(--ds-color-accent),\n transparent 90%\n )\n `,\n }}\n onMouseMove={handleMouseMove}\n onMouseEnter={() => setVisible(true)}\n onMouseLeave={() => setVisible(false)}\n className=\"group/multi-combobox rounded-lg border-border p-[2px] transition duration-300 hover:border-accent\"\n >\n <div\n className={mergeClassNames(\n \"shadow-input flex min-h-10 w-full cursor-pointer items-center justify-between rounded-md border border-input px-3 py-2 text-sm text-foreground transition duration-400 ease-in-out group-hover/multi-combobox:shadow-none\",\n bgClassName,\n )}\n onClick={() => {\n setOpen((o) => {\n if (o) setSearch(\"\");\n return !o;\n });\n }}\n >\n <div className=\"flex flex-1 flex-wrap gap-1\">\n {selectedLabels.length > 0 ? (\n selectedLabels.map((label, index) => (\n <span\n key={value[index]}\n className=\"inline-flex items-center gap-1 rounded-md bg-accent-subtle px-2 py-0.5 text-xs font-medium text-accent\"\n >\n {label}\n <button\n type=\"button\"\n onClick={(e) => handleRemoveTag(value[index], e)}\n className=\"ml-0.5 rounded-full p-0.5 transition-colors hover:bg-accent/10\"\n >\n <CloseIcon className=\"w-3 h-3\" aria-hidden=\"true\" />\n </button>\n </span>\n ))\n ) : (\n <span className=\"text-muted-foreground\">{placeholder}</span>\n )}\n </div>\n <span\n className={mergeClassNames(\n \"ml-2 shrink-0 text-muted-foreground transition-transform duration-300\",\n open ? \"rotate-180\" : \"rotate-0\",\n )}\n >\n <ChevronDownIcon\n width={24}\n height={24}\n color=\"currentColor\"\n className=\"h-5 w-5\"\n />\n </span>\n </div>\n </motion.div>\n {open && (\n <div className=\"absolute right-0 left-0 z-20 mt-1 flex max-h-60 flex-col rounded-lg border border-border bg-background-secondary shadow-3 backdrop-blur-xl transition\">\n {/* Sticky search input */}\n <div className=\"sticky top-0 z-10 rounded-t-lg border-b border-border-muted bg-elevated/95 backdrop-blur-sm\">\n <input\n autoFocus\n className=\"w-full bg-transparent px-3 py-2 text-sm text-foreground outline-none placeholder:text-muted-foreground focus-visible:ring-2 focus-visible:ring-accent\"\n placeholder=\"Type to search...\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n onClick={(e) => e.stopPropagation()}\n />\n </div>\n {/* Scrollable options */}\n <div className=\"max-h-80 flex-1 overflow-auto\">\n {filteredOptions.length === 0 && (\n <div className=\"p-3 text-center text-muted-foreground text-sm\">\n No options found\n </div>\n )}\n {filteredOptions.map((option) => {\n const isSelected = value.includes(option.value);\n return (\n <div\n key={option.value}\n className={mergeClassNames(\n \"flex cursor-pointer items-center gap-2 px-3 py-2 text-sm transition\",\n isSelected\n ? \"bg-accent-subtle text-accent\"\n : \"text-foreground hover:bg-accent hover:text-on-accent\",\n )}\n onClick={() => handleOptionClick(option.value)}\n >\n <span\n className={mergeClassNames(\n \"flex h-4 w-4 items-center justify-center rounded border transition\",\n isSelected\n ? \"border-accent bg-accent text-on-accent\"\n : \"border-border\",\n )}\n >\n {isSelected && <CheckIcon width={12} height={12} />}\n </span>\n <span className=\"flex-1\">{option.label}</span>\n </div>\n );\n })}\n </div>\n </div>\n )}\n </div>\n );\n};\n\nexport default MultiSelectCombobox;\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"multi-select-combobox-UW0X15W7.cjs","names":[],"sources":["../../src/components/forms/multi-select-combobox/MultiSelectCombobox.tsx"],"sourcesContent":["import React, { useEffect, useRef, useState } from \"react\";\nimport { motion, useMotionTemplate, useMotionValue } from \"framer-motion\";\n\nimport { CheckIcon, ChevronDownIcon, CloseIcon } from \"../../icons\";\nimport { mergeClassNames } from \"../../../utils\";\n\nexport interface MultiSelectOption {\n label: string;\n value: string;\n}\n\nexport interface MultiSelectComboboxProps {\n options: MultiSelectOption[];\n value: string[];\n onChange: (values: string[]) => void;\n placeholder?: string;\n className?: string;\n bgClassName?: string;\n}\n\nconst MultiSelectCombobox: React.FC<MultiSelectComboboxProps> = ({\n options,\n value = [],\n onChange,\n placeholder = \"Select...\",\n className,\n bgClassName = \"bg-background-secondary\",\n}) => {\n const [open, setOpen] = useState(false);\n const [search, setSearch] = useState(\"\");\n const [visible, setVisible] = useState(false);\n const ref = useRef<HTMLDivElement>(null);\n const mouseX = useMotionValue(0);\n const mouseY = useMotionValue(0);\n const radius = 100;\n\n // Filter options by search\n const filteredOptions = options.filter((opt) =>\n opt.label.toLowerCase().includes(search.toLowerCase()),\n );\n\n // Close dropdown on outside click\n useEffect(() => {\n const handleClick = (e: MouseEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node)) {\n setOpen(false);\n setSearch(\"\");\n }\n };\n if (open) {\n document.addEventListener(\"mousedown\", handleClick);\n }\n return () => document.removeEventListener(\"mousedown\", handleClick);\n }, [open]);\n\n const handleMouseMove = (event: React.MouseEvent<HTMLDivElement>) => {\n const { left, top } = event.currentTarget.getBoundingClientRect();\n mouseX.set(event.clientX - left);\n mouseY.set(event.clientY - top);\n };\n\n const handleOptionClick = (optionValue: string) => {\n if (value.includes(optionValue)) {\n onChange(value.filter((v) => v !== optionValue));\n } else {\n onChange([...value, optionValue]);\n }\n };\n\n const handleRemoveTag = (optionValue: string, e: React.MouseEvent) => {\n e.stopPropagation();\n onChange(value.filter((v) => v !== optionValue));\n };\n\n const selectedLabels = value\n .map((v) => options.find((opt) => opt.value === v)?.label)\n .filter(Boolean);\n\n return (\n <div\n ref={ref}\n className={mergeClassNames(\"relative w-full\", className)}\n tabIndex={0}\n >\n <motion.div\n style={{\n backgroundImage: useMotionTemplate`\n radial-gradient(\n ${visible ? `${radius}px` : \"0px\"} circle at ${mouseX}px ${mouseY}px,\n var(--ds-color-accent),\n transparent 90%\n )\n `,\n }}\n onMouseMove={handleMouseMove}\n onMouseEnter={() => setVisible(true)}\n onMouseLeave={() => setVisible(false)}\n className=\"group/multi-combobox rounded-lg border-border p-[2px] transition duration-300 hover:border-accent\"\n >\n <div\n className={mergeClassNames(\n \"shadow-input flex min-h-10 w-full cursor-pointer items-center justify-between rounded-md border border-input px-3 py-2 text-sm text-foreground transition duration-400 ease-in-out group-hover/multi-combobox:shadow-none\",\n bgClassName,\n )}\n onClick={() => {\n setOpen((o) => {\n if (o) setSearch(\"\");\n return !o;\n });\n }}\n >\n <div className=\"flex flex-1 flex-wrap gap-1\">\n {selectedLabels.length > 0 ? (\n selectedLabels.map((label, index) => (\n <span\n key={value[index]}\n className=\"inline-flex items-center gap-1 rounded-md bg-accent-subtle px-2 py-0.5 text-xs font-medium text-accent\"\n >\n {label}\n <button\n type=\"button\"\n onClick={(e) => handleRemoveTag(value[index], e)}\n className=\"ml-0.5 rounded-full p-0.5 transition-colors hover:bg-accent/10\"\n >\n <CloseIcon className=\"w-3 h-3\" aria-hidden=\"true\" />\n </button>\n </span>\n ))\n ) : (\n <span className=\"text-muted-foreground\">{placeholder}</span>\n )}\n </div>\n <span\n className={mergeClassNames(\n \"ml-2 shrink-0 text-muted-foreground transition-transform duration-300\",\n open ? \"rotate-180\" : \"rotate-0\",\n )}\n >\n <ChevronDownIcon\n width={24}\n height={24}\n color=\"currentColor\"\n className=\"h-5 w-5\"\n />\n </span>\n </div>\n </motion.div>\n {open && (\n <div className=\"absolute right-0 left-0 z-20 mt-1 flex max-h-60 flex-col rounded-lg border border-border bg-background-secondary shadow-3 backdrop-blur-xl transition\">\n {/* Sticky search input */}\n <div className=\"sticky top-0 z-10 rounded-t-lg border-b border-border-muted bg-elevated/95 backdrop-blur-sm\">\n <input\n autoFocus\n className=\"w-full bg-transparent px-3 py-2 text-sm text-foreground outline-none placeholder:text-muted-foreground focus-visible:ring-2 focus-visible:ring-accent\"\n placeholder=\"Type to search...\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n onClick={(e) => e.stopPropagation()}\n />\n </div>\n {/* Scrollable options */}\n <div className=\"max-h-80 flex-1 overflow-auto\">\n {filteredOptions.length === 0 && (\n <div className=\"p-3 text-center text-muted-foreground text-sm\">\n No options found\n </div>\n )}\n {filteredOptions.map((option) => {\n const isSelected = value.includes(option.value);\n return (\n <div\n key={option.value}\n className={mergeClassNames(\n \"flex cursor-pointer items-center gap-2 px-3 py-2 text-sm transition\",\n isSelected\n ? \"bg-accent-subtle text-accent\"\n : \"text-foreground hover:bg-accent hover:text-on-accent\",\n )}\n onClick={() => handleOptionClick(option.value)}\n >\n <span\n className={mergeClassNames(\n \"flex h-4 w-4 items-center justify-center rounded border transition\",\n isSelected\n ? \"border-accent bg-accent text-on-accent\"\n : \"border-border\",\n )}\n >\n {isSelected && <CheckIcon width={12} height={12} />}\n </span>\n <span className=\"flex-1\">{option.label}</span>\n </div>\n );\n })}\n </div>\n </div>\n )}\n </div>\n );\n};\n\nexport default MultiSelectCombobox;\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"otp-input-B6zzOEqw.cjs","names":[],"sources":["../../src/components/forms/otp-input/OTPInput.tsx"],"sourcesContent":["import {\n forwardRef,\n useState,\n useRef,\n useCallback,\n useEffect,\n type KeyboardEvent,\n type ClipboardEvent,\n type ChangeEvent,\n} from \"react\";\n\nexport type OTPInputSize = \"sm\" | \"md\" | \"lg\";\nexport type OTPInputVariant = \"outlined\" | \"filled\" | \"underlined\";\n\nexport interface OTPInputProps {\n /** Number of OTP digits */\n length?: number;\n /** Callback when OTP value changes */\n onChange?: (value: string) => void;\n /** Callback when all digits are filled */\n onComplete?: (value: string) => void;\n /** The current value (controlled) */\n value?: string;\n /** Default value (uncontrolled) */\n defaultValue?: string;\n /** Size of the input boxes */\n size?: OTPInputSize;\n /** Visual variant */\n variant?: OTPInputVariant;\n /** Whether the input is disabled */\n disabled?: boolean;\n /** Whether there's an error */\n error?: boolean;\n /** Error message to display */\n errorMessage?: string;\n /** Placeholder character */\n placeholder?: string;\n /** Whether to mask the input (like password) */\n mask?: boolean;\n /** Whether to auto-focus the first input */\n autoFocus?: boolean;\n /** Input type - number only or alphanumeric */\n type?: \"number\" | \"text\";\n /** Custom className for the container */\n className?: string;\n /** Custom className for each input box */\n inputClassName?: string;\n /** Separator to show between groups of digits */\n separator?: React.ReactNode;\n /** Position(s) to show separator (e.g., [3] means after 3rd digit) */\n separatorPositions?: number[];\n /** Accessible label */\n \"aria-label\"?: string;\n}\n\nconst sizeStyles: Record<OTPInputSize, string> = {\n sm: \"w-9 h-10 text-base\",\n md: \"w-12 h-14 text-xl\",\n lg: \"w-14 h-16 text-2xl\",\n};\n\nconst variantStyles: Record<\n OTPInputVariant,\n { base: string; focus: string; error: string }\n> = {\n outlined: {\n base: \"border border-input bg-background-secondary rounded-lg shadow-input text-foreground\",\n focus: \"focus:border-accent focus:ring-2 focus:ring-accent\",\n error: \"border-destructive\",\n },\n filled: {\n base: \"border border-transparent bg-accent-subtle rounded-lg text-foreground\",\n focus:\n \"focus:border-accent focus:bg-background-secondary focus:ring-2 focus:ring-accent\",\n error: \"bg-danger-subtle border-danger-border\",\n },\n underlined: {\n base: \"border-b-2 border-border-strong bg-transparent rounded-none text-foreground\",\n focus: \"focus:border-accent\",\n error: \"border-destructive\",\n },\n};\n\nconst OTPInput = forwardRef<HTMLDivElement, OTPInputProps>(\n (\n {\n length = 6,\n onChange,\n onComplete,\n value: controlledValue,\n defaultValue = \"\",\n size = \"md\",\n variant = \"outlined\",\n disabled = false,\n error = false,\n errorMessage,\n placeholder = \"\",\n mask = false,\n autoFocus = false,\n type = \"number\",\n className = \"\",\n inputClassName = \"\",\n separator = <span className=\"text-neutral-400 text-2xl mx-2\">—</span>,\n separatorPositions = [],\n \"aria-label\": ariaLabel = \"One-time password\",\n },\n ref,\n ) => {\n const [values, setValues] = useState<string[]>(() => {\n const initial = controlledValue ?? defaultValue;\n return initial\n .split(\"\")\n .slice(0, length)\n .concat(Array(length).fill(\"\"))\n .slice(0, length);\n });\n\n const inputRefs = useRef<(HTMLInputElement | null)[]>([]);\n\n // Sync with controlled value\n useEffect(() => {\n if (controlledValue !== undefined) {\n const newValues = controlledValue\n .split(\"\")\n .slice(0, length)\n .concat(Array(length).fill(\"\"))\n .slice(0, length);\n setValues(newValues);\n }\n }, [controlledValue, length]);\n\n // Auto-focus first input\n useEffect(() => {\n if (autoFocus && inputRefs.current[0]) {\n inputRefs.current[0].focus();\n }\n }, [autoFocus]);\n\n const focusInput = useCallback(\n (index: number) => {\n if (index >= 0 && index < length && inputRefs.current[index]) {\n inputRefs.current[index]?.focus();\n inputRefs.current[index]?.select();\n }\n },\n [length],\n );\n\n const handleChange = useCallback(\n (index: number, e: ChangeEvent<HTMLInputElement>) => {\n const inputValue = e.target.value;\n const char = inputValue.slice(-1);\n\n // Validate input based on type\n if (type === \"number\" && char && !/^\\d$/.test(char)) {\n return;\n }\n\n const newValues = [...values];\n newValues[index] = char;\n setValues(newValues);\n\n const otpValue = newValues.join(\"\");\n onChange?.(otpValue);\n\n // Move to next input if value entered\n if (char && index < length - 1) {\n focusInput(index + 1);\n }\n\n // Check if complete\n if (newValues.every((v) => v !== \"\") && newValues.length === length) {\n onComplete?.(otpValue);\n }\n },\n [values, onChange, onComplete, length, type, focusInput],\n );\n\n const handleKeyDown = useCallback(\n (index: number, e: KeyboardEvent<HTMLInputElement>) => {\n switch (e.key) {\n case \"Backspace\":\n e.preventDefault();\n const newValues = [...values];\n if (values[index]) {\n // Clear current value\n newValues[index] = \"\";\n setValues(newValues);\n onChange?.(newValues.join(\"\"));\n } else if (index > 0) {\n // Move to previous and clear\n newValues[index - 1] = \"\";\n setValues(newValues);\n onChange?.(newValues.join(\"\"));\n focusInput(index - 1);\n }\n break;\n case \"ArrowLeft\":\n e.preventDefault();\n focusInput(index - 1);\n break;\n case \"ArrowRight\":\n e.preventDefault();\n focusInput(index + 1);\n break;\n case \"Delete\":\n e.preventDefault();\n const deleteValues = [...values];\n deleteValues[index] = \"\";\n setValues(deleteValues);\n onChange?.(deleteValues.join(\"\"));\n break;\n }\n },\n [values, onChange, focusInput],\n );\n\n const handlePaste = useCallback(\n (e: ClipboardEvent<HTMLInputElement>) => {\n e.preventDefault();\n const pastedData = e.clipboardData.getData(\"text\").slice(0, length);\n\n // Validate pasted content\n if (type === \"number\" && !/^\\d*$/.test(pastedData)) {\n return;\n }\n\n const newValues = pastedData\n .split(\"\")\n .slice(0, length)\n .concat(Array(length).fill(\"\"))\n .slice(0, length);\n\n setValues(newValues);\n const otpValue = newValues.join(\"\");\n onChange?.(otpValue);\n\n // Focus last filled input or last input\n const lastFilledIndex = newValues.findLastIndex((v) => v !== \"\");\n focusInput(Math.min(lastFilledIndex + 1, length - 1));\n\n // Check if complete\n if (newValues.every((v) => v !== \"\") && pastedData.length >= length) {\n onComplete?.(otpValue);\n }\n },\n [length, type, onChange, onComplete, focusInput],\n );\n\n const handleFocus = useCallback((e: React.FocusEvent<HTMLInputElement>) => {\n e.target.select();\n }, []);\n\n const renderInputs = () => {\n const inputs: React.ReactNode[] = [];\n\n for (let i = 0; i < length; i++) {\n // Add separator if needed\n if (separatorPositions.includes(i) && i > 0) {\n inputs.push(\n <div key={`separator-${i}`} className=\"flex items-center\">\n {separator}\n </div>,\n );\n }\n\n inputs.push(\n <input\n key={i}\n ref={(el) => {\n inputRefs.current[i] = el;\n // React 19: Return cleanup function\n return () => {\n inputRefs.current[i] = null;\n };\n }}\n type={mask ? \"password\" : \"text\"}\n inputMode={type === \"number\" ? \"numeric\" : \"text\"}\n pattern={type === \"number\" ? \"\\\\d*\" : undefined}\n maxLength={1}\n value={values[i] || \"\"}\n placeholder={placeholder}\n disabled={disabled}\n onChange={(e) => handleChange(i, e)}\n onKeyDown={(e) => handleKeyDown(i, e)}\n onPaste={handlePaste}\n onFocus={handleFocus}\n aria-label={`${ariaLabel} digit ${i + 1}`}\n className={`\n text-center font-semibold outline-none transition-all\n placeholder:text-muted-foreground\n ${sizeStyles[size]}\n ${variantStyles[variant].base}\n ${!error ? variantStyles[variant].focus : \"\"}\n ${error ? variantStyles[variant].error : \"\"}\n ${disabled ? \"opacity-50 cursor-not-allowed bg-muted\" : \"\"}\n ${inputClassName}\n `}\n />,\n );\n }\n\n return inputs;\n };\n\n return (\n <div ref={ref} className={`flex flex-col gap-2 ${className}`}>\n <div\n className=\"flex items-center gap-2\"\n role=\"group\"\n aria-label={ariaLabel}\n >\n {renderInputs()}\n </div>\n {error && errorMessage && (\n <span className=\"text-sm text-destructive\">{errorMessage}</span>\n )}\n </div>\n );\n },\n);\n\nOTPInput.displayName = \"OTPInput\";\n\nexport default OTPInput;\nexport { OTPInput };\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"otp-input-Bg4nQG6x.mjs","names":[],"sources":["../../src/components/forms/otp-input/OTPInput.tsx"],"sourcesContent":["import {\n forwardRef,\n useState,\n useRef,\n useCallback,\n useEffect,\n type KeyboardEvent,\n type ClipboardEvent,\n type ChangeEvent,\n} from \"react\";\n\nexport type OTPInputSize = \"sm\" | \"md\" | \"lg\";\nexport type OTPInputVariant = \"outlined\" | \"filled\" | \"underlined\";\n\nexport interface OTPInputProps {\n /** Number of OTP digits */\n length?: number;\n /** Callback when OTP value changes */\n onChange?: (value: string) => void;\n /** Callback when all digits are filled */\n onComplete?: (value: string) => void;\n /** The current value (controlled) */\n value?: string;\n /** Default value (uncontrolled) */\n defaultValue?: string;\n /** Size of the input boxes */\n size?: OTPInputSize;\n /** Visual variant */\n variant?: OTPInputVariant;\n /** Whether the input is disabled */\n disabled?: boolean;\n /** Whether there's an error */\n error?: boolean;\n /** Error message to display */\n errorMessage?: string;\n /** Placeholder character */\n placeholder?: string;\n /** Whether to mask the input (like password) */\n mask?: boolean;\n /** Whether to auto-focus the first input */\n autoFocus?: boolean;\n /** Input type - number only or alphanumeric */\n type?: \"number\" | \"text\";\n /** Custom className for the container */\n className?: string;\n /** Custom className for each input box */\n inputClassName?: string;\n /** Separator to show between groups of digits */\n separator?: React.ReactNode;\n /** Position(s) to show separator (e.g., [3] means after 3rd digit) */\n separatorPositions?: number[];\n /** Accessible label */\n \"aria-label\"?: string;\n}\n\nconst sizeStyles: Record<OTPInputSize, string> = {\n sm: \"w-9 h-10 text-base\",\n md: \"w-12 h-14 text-xl\",\n lg: \"w-14 h-16 text-2xl\",\n};\n\nconst variantStyles: Record<\n OTPInputVariant,\n { base: string; focus: string; error: string }\n> = {\n outlined: {\n base: \"border border-input bg-background-secondary rounded-lg shadow-input text-foreground\",\n focus: \"focus:border-accent focus:ring-2 focus:ring-accent\",\n error: \"border-destructive\",\n },\n filled: {\n base: \"border border-transparent bg-accent-subtle rounded-lg text-foreground\",\n focus:\n \"focus:border-accent focus:bg-background-secondary focus:ring-2 focus:ring-accent\",\n error: \"bg-danger-subtle border-danger-border\",\n },\n underlined: {\n base: \"border-b-2 border-border-strong bg-transparent rounded-none text-foreground\",\n focus: \"focus:border-accent\",\n error: \"border-destructive\",\n },\n};\n\nconst OTPInput = forwardRef<HTMLDivElement, OTPInputProps>(\n (\n {\n length = 6,\n onChange,\n onComplete,\n value: controlledValue,\n defaultValue = \"\",\n size = \"md\",\n variant = \"outlined\",\n disabled = false,\n error = false,\n errorMessage,\n placeholder = \"\",\n mask = false,\n autoFocus = false,\n type = \"number\",\n className = \"\",\n inputClassName = \"\",\n separator = <span className=\"text-neutral-400 text-2xl mx-2\">—</span>,\n separatorPositions = [],\n \"aria-label\": ariaLabel = \"One-time password\",\n },\n ref,\n ) => {\n const [values, setValues] = useState<string[]>(() => {\n const initial = controlledValue ?? defaultValue;\n return initial\n .split(\"\")\n .slice(0, length)\n .concat(Array(length).fill(\"\"))\n .slice(0, length);\n });\n\n const inputRefs = useRef<(HTMLInputElement | null)[]>([]);\n\n // Sync with controlled value\n useEffect(() => {\n if (controlledValue !== undefined) {\n const newValues = controlledValue\n .split(\"\")\n .slice(0, length)\n .concat(Array(length).fill(\"\"))\n .slice(0, length);\n setValues(newValues);\n }\n }, [controlledValue, length]);\n\n // Auto-focus first input\n useEffect(() => {\n if (autoFocus && inputRefs.current[0]) {\n inputRefs.current[0].focus();\n }\n }, [autoFocus]);\n\n const focusInput = useCallback(\n (index: number) => {\n if (index >= 0 && index < length && inputRefs.current[index]) {\n inputRefs.current[index]?.focus();\n inputRefs.current[index]?.select();\n }\n },\n [length],\n );\n\n const handleChange = useCallback(\n (index: number, e: ChangeEvent<HTMLInputElement>) => {\n const inputValue = e.target.value;\n const char = inputValue.slice(-1);\n\n // Validate input based on type\n if (type === \"number\" && char && !/^\\d$/.test(char)) {\n return;\n }\n\n const newValues = [...values];\n newValues[index] = char;\n setValues(newValues);\n\n const otpValue = newValues.join(\"\");\n onChange?.(otpValue);\n\n // Move to next input if value entered\n if (char && index < length - 1) {\n focusInput(index + 1);\n }\n\n // Check if complete\n if (newValues.every((v) => v !== \"\") && newValues.length === length) {\n onComplete?.(otpValue);\n }\n },\n [values, onChange, onComplete, length, type, focusInput],\n );\n\n const handleKeyDown = useCallback(\n (index: number, e: KeyboardEvent<HTMLInputElement>) => {\n switch (e.key) {\n case \"Backspace\":\n e.preventDefault();\n const newValues = [...values];\n if (values[index]) {\n // Clear current value\n newValues[index] = \"\";\n setValues(newValues);\n onChange?.(newValues.join(\"\"));\n } else if (index > 0) {\n // Move to previous and clear\n newValues[index - 1] = \"\";\n setValues(newValues);\n onChange?.(newValues.join(\"\"));\n focusInput(index - 1);\n }\n break;\n case \"ArrowLeft\":\n e.preventDefault();\n focusInput(index - 1);\n break;\n case \"ArrowRight\":\n e.preventDefault();\n focusInput(index + 1);\n break;\n case \"Delete\":\n e.preventDefault();\n const deleteValues = [...values];\n deleteValues[index] = \"\";\n setValues(deleteValues);\n onChange?.(deleteValues.join(\"\"));\n break;\n }\n },\n [values, onChange, focusInput],\n );\n\n const handlePaste = useCallback(\n (e: ClipboardEvent<HTMLInputElement>) => {\n e.preventDefault();\n const pastedData = e.clipboardData.getData(\"text\").slice(0, length);\n\n // Validate pasted content\n if (type === \"number\" && !/^\\d*$/.test(pastedData)) {\n return;\n }\n\n const newValues = pastedData\n .split(\"\")\n .slice(0, length)\n .concat(Array(length).fill(\"\"))\n .slice(0, length);\n\n setValues(newValues);\n const otpValue = newValues.join(\"\");\n onChange?.(otpValue);\n\n // Focus last filled input or last input\n const lastFilledIndex = newValues.findLastIndex((v) => v !== \"\");\n focusInput(Math.min(lastFilledIndex + 1, length - 1));\n\n // Check if complete\n if (newValues.every((v) => v !== \"\") && pastedData.length >= length) {\n onComplete?.(otpValue);\n }\n },\n [length, type, onChange, onComplete, focusInput],\n );\n\n const handleFocus = useCallback((e: React.FocusEvent<HTMLInputElement>) => {\n e.target.select();\n }, []);\n\n const renderInputs = () => {\n const inputs: React.ReactNode[] = [];\n\n for (let i = 0; i < length; i++) {\n // Add separator if needed\n if (separatorPositions.includes(i) && i > 0) {\n inputs.push(\n <div key={`separator-${i}`} className=\"flex items-center\">\n {separator}\n </div>,\n );\n }\n\n inputs.push(\n <input\n key={i}\n ref={(el) => {\n inputRefs.current[i] = el;\n // React 19: Return cleanup function\n return () => {\n inputRefs.current[i] = null;\n };\n }}\n type={mask ? \"password\" : \"text\"}\n inputMode={type === \"number\" ? \"numeric\" : \"text\"}\n pattern={type === \"number\" ? \"\\\\d*\" : undefined}\n maxLength={1}\n value={values[i] || \"\"}\n placeholder={placeholder}\n disabled={disabled}\n onChange={(e) => handleChange(i, e)}\n onKeyDown={(e) => handleKeyDown(i, e)}\n onPaste={handlePaste}\n onFocus={handleFocus}\n aria-label={`${ariaLabel} digit ${i + 1}`}\n className={`\n text-center font-semibold outline-none transition-all\n placeholder:text-muted-foreground\n ${sizeStyles[size]}\n ${variantStyles[variant].base}\n ${!error ? variantStyles[variant].focus : \"\"}\n ${error ? variantStyles[variant].error : \"\"}\n ${disabled ? \"opacity-50 cursor-not-allowed bg-muted\" : \"\"}\n ${inputClassName}\n `}\n />,\n );\n }\n\n return inputs;\n };\n\n return (\n <div ref={ref} className={`flex flex-col gap-2 ${className}`}>\n <div\n className=\"flex items-center gap-2\"\n role=\"group\"\n aria-label={ariaLabel}\n >\n {renderInputs()}\n </div>\n {error && errorMessage && (\n <span className=\"text-sm text-destructive\">{errorMessage}</span>\n )}\n </div>\n );\n },\n);\n\nOTPInput.displayName = \"OTPInput\";\n\nexport default OTPInput;\nexport { OTPInput };\n"],"mappings":"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"}
|
|
@@ -1,152 +0,0 @@
|
|
|
1
|
-
import { n as mergeClassNames } from "./utils-ati1KkDb.mjs";
|
|
2
|
-
import { J as CheckIcon, N as ChevronDownIcon } from "./icons-DuumN7z-.mjs";
|
|
3
|
-
import { forwardRef, useEffect, useRef, useState } from "react";
|
|
4
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
-
import { motion, useMotionTemplate, useMotionValue } from "framer-motion";
|
|
6
|
-
//#region src/components/forms/select/Select.tsx
|
|
7
|
-
var Select = forwardRef(({ className = "", containerClassName = "", triggerClassName = "", label, error, helperText, options, value, onChange, placeholder = "Select...", disabled, bgClassName = "bg-background-secondary", ...props }, ref) => {
|
|
8
|
-
const [open, setOpen] = useState(false);
|
|
9
|
-
const [visible, setVisible] = useState(false);
|
|
10
|
-
const containerRef = useRef(null);
|
|
11
|
-
const hiddenSelectRef = useRef(null);
|
|
12
|
-
const mouseX = useMotionValue(0);
|
|
13
|
-
const mouseY = useMotionValue(0);
|
|
14
|
-
const radius = 100;
|
|
15
|
-
useEffect(() => {
|
|
16
|
-
if (ref && typeof ref === "function") ref(hiddenSelectRef.current);
|
|
17
|
-
else if (ref) ref.current = hiddenSelectRef.current;
|
|
18
|
-
}, [ref]);
|
|
19
|
-
useEffect(() => {
|
|
20
|
-
const handleClick = (e) => {
|
|
21
|
-
if (containerRef.current && !containerRef.current.contains(e.target)) setOpen(false);
|
|
22
|
-
};
|
|
23
|
-
if (open) document.addEventListener("mousedown", handleClick);
|
|
24
|
-
return () => document.removeEventListener("mousedown", handleClick);
|
|
25
|
-
}, [open]);
|
|
26
|
-
const handleMouseMove = (event) => {
|
|
27
|
-
const { left, top } = event.currentTarget.getBoundingClientRect();
|
|
28
|
-
mouseX.set(event.clientX - left);
|
|
29
|
-
mouseY.set(event.clientY - top);
|
|
30
|
-
};
|
|
31
|
-
const selectedOption = options.find((opt) => opt.value === value);
|
|
32
|
-
const handleSelect = (optValue) => {
|
|
33
|
-
if (onChange && hiddenSelectRef.current) onChange({
|
|
34
|
-
target: {
|
|
35
|
-
value: optValue,
|
|
36
|
-
name: props.name
|
|
37
|
-
},
|
|
38
|
-
currentTarget: {
|
|
39
|
-
value: optValue,
|
|
40
|
-
name: props.name
|
|
41
|
-
}
|
|
42
|
-
});
|
|
43
|
-
setOpen(false);
|
|
44
|
-
};
|
|
45
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
46
|
-
className: mergeClassNames("w-full min-w-48", containerClassName),
|
|
47
|
-
children: [
|
|
48
|
-
label && /* @__PURE__ */ jsx("label", {
|
|
49
|
-
className: "mb-2 block text-sm leading-none font-medium text-foreground peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
|
|
50
|
-
children: label
|
|
51
|
-
}),
|
|
52
|
-
/* @__PURE__ */ jsxs("select", {
|
|
53
|
-
ref: hiddenSelectRef,
|
|
54
|
-
className: "sr-only",
|
|
55
|
-
value,
|
|
56
|
-
onChange,
|
|
57
|
-
disabled,
|
|
58
|
-
...props,
|
|
59
|
-
children: [/* @__PURE__ */ jsx("option", {
|
|
60
|
-
value: "",
|
|
61
|
-
children: placeholder
|
|
62
|
-
}), options.map((option) => /* @__PURE__ */ jsx("option", {
|
|
63
|
-
value: option.value,
|
|
64
|
-
children: option.label
|
|
65
|
-
}, option.value))]
|
|
66
|
-
}),
|
|
67
|
-
/* @__PURE__ */ jsxs("div", {
|
|
68
|
-
ref: containerRef,
|
|
69
|
-
className: mergeClassNames("relative w-full", className),
|
|
70
|
-
children: [/* @__PURE__ */ jsx(motion.div, {
|
|
71
|
-
style: { backgroundImage: disabled ? "none" : useMotionTemplate`
|
|
72
|
-
radial-gradient(
|
|
73
|
-
${visible ? `${radius}px` : "0px"} circle at ${mouseX}px ${mouseY}px,
|
|
74
|
-
var(--ds-color-accent),
|
|
75
|
-
transparent 90%
|
|
76
|
-
)
|
|
77
|
-
` },
|
|
78
|
-
onMouseMove: !disabled ? handleMouseMove : void 0,
|
|
79
|
-
onMouseEnter: !disabled ? () => setVisible(true) : void 0,
|
|
80
|
-
onMouseLeave: !disabled ? () => setVisible(false) : void 0,
|
|
81
|
-
className: mergeClassNames("group/select rounded-lg p-[2px] transition duration-300 hover:border-accent", disabled ? "bg-muted border-none" : error ? "border-destructive" : "border-border"),
|
|
82
|
-
children: /* @__PURE__ */ jsxs("div", {
|
|
83
|
-
className: mergeClassNames("shadow-input flex h-10 w-full cursor-pointer items-center justify-between rounded-md border border-input px-3 py-2 text-sm transition duration-400 ease-in-out group-hover/select:shadow-none", bgClassName, disabled ? "cursor-not-allowed opacity-50" : "text-foreground", error && "border-destructive text-destructive focus-visible:ring-destructive", triggerClassName),
|
|
84
|
-
onClick: () => {
|
|
85
|
-
if (!disabled) setOpen((o) => !o);
|
|
86
|
-
},
|
|
87
|
-
onKeyDown: (event) => {
|
|
88
|
-
if (disabled) return;
|
|
89
|
-
if (event.key === "Enter" || event.key === " ") {
|
|
90
|
-
event.preventDefault();
|
|
91
|
-
setOpen((current) => !current);
|
|
92
|
-
}
|
|
93
|
-
if (event.key === "Escape") setOpen(false);
|
|
94
|
-
},
|
|
95
|
-
role: "button",
|
|
96
|
-
tabIndex: disabled ? -1 : 0,
|
|
97
|
-
"aria-haspopup": "listbox",
|
|
98
|
-
"aria-expanded": open,
|
|
99
|
-
children: [selectedOption ? /* @__PURE__ */ jsx("span", {
|
|
100
|
-
className: "flex-1 truncate text-foreground",
|
|
101
|
-
children: selectedOption.label
|
|
102
|
-
}) : /* @__PURE__ */ jsx("span", {
|
|
103
|
-
className: "flex-1 text-muted-foreground",
|
|
104
|
-
children: placeholder
|
|
105
|
-
}), /* @__PURE__ */ jsx("span", {
|
|
106
|
-
className: mergeClassNames("ml-2 text-muted-foreground transition-transform duration-300", open ? "rotate-180" : "rotate-0"),
|
|
107
|
-
children: /* @__PURE__ */ jsx(ChevronDownIcon, {
|
|
108
|
-
width: 24,
|
|
109
|
-
height: 24,
|
|
110
|
-
color: "currentColor",
|
|
111
|
-
className: "h-5 w-5"
|
|
112
|
-
})
|
|
113
|
-
})]
|
|
114
|
-
})
|
|
115
|
-
}), open && !disabled && /* @__PURE__ */ jsxs("div", {
|
|
116
|
-
className: mergeClassNames("absolute right-0 left-0 z-20 mt-1 flex max-h-60 flex-col overflow-auto rounded-lg border border-border bg-background-secondary shadow-3 backdrop-blur-xl transition"),
|
|
117
|
-
children: [options.length === 0 && /* @__PURE__ */ jsx("div", {
|
|
118
|
-
className: "px-3 py-2 text-muted-foreground",
|
|
119
|
-
children: "No options"
|
|
120
|
-
}), options.map((opt) => /* @__PURE__ */ jsxs("div", {
|
|
121
|
-
className: mergeClassNames("mx-1 my-1 flex cursor-pointer items-center gap-2 rounded-md px-3 py-2 text-sm text-foreground transition", opt.value === value ? "bg-accent-subtle text-accent font-semibold" : "", "hover:bg-accent hover:text-on-accent"),
|
|
122
|
-
onClick: () => handleSelect(opt.value),
|
|
123
|
-
children: [/* @__PURE__ */ jsx("span", {
|
|
124
|
-
className: "flex w-5 items-center justify-center",
|
|
125
|
-
children: opt.value === value && /* @__PURE__ */ jsx(CheckIcon, {
|
|
126
|
-
className: "text-accent",
|
|
127
|
-
width: 18,
|
|
128
|
-
height: 18
|
|
129
|
-
})
|
|
130
|
-
}), /* @__PURE__ */ jsx("span", {
|
|
131
|
-
className: "min-w-0 flex-1 truncate",
|
|
132
|
-
children: opt.label
|
|
133
|
-
})]
|
|
134
|
-
}, opt.value))]
|
|
135
|
-
})]
|
|
136
|
-
}),
|
|
137
|
-
error && /* @__PURE__ */ jsx("p", {
|
|
138
|
-
className: "mt-1 text-sm font-medium text-destructive",
|
|
139
|
-
children: error
|
|
140
|
-
}),
|
|
141
|
-
helperText && !error && /* @__PURE__ */ jsx("p", {
|
|
142
|
-
className: "mt-1 text-sm text-muted-foreground",
|
|
143
|
-
children: helperText
|
|
144
|
-
})
|
|
145
|
-
]
|
|
146
|
-
});
|
|
147
|
-
});
|
|
148
|
-
Select.displayName = "Select";
|
|
149
|
-
//#endregion
|
|
150
|
-
export { Select as t };
|
|
151
|
-
|
|
152
|
-
//# sourceMappingURL=select-D71tk6-I.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"select-D71tk6-I.mjs","names":[],"sources":["../../src/components/forms/select/Select.tsx"],"sourcesContent":["import type { SelectProps } from \"./types\";\nimport { forwardRef, useState, useRef, useEffect } from \"react\";\nimport { motion, useMotionTemplate, useMotionValue } from \"framer-motion\";\n\nimport { CheckIcon, ChevronDownIcon } from \"../../icons\";\nimport { mergeClassNames } from \"../../../utils\";\n\nexport const Select = forwardRef<HTMLSelectElement, SelectProps>(\n (\n {\n className = \"\",\n containerClassName = \"\",\n triggerClassName = \"\",\n label,\n error,\n helperText,\n options,\n value,\n onChange,\n placeholder = \"Select...\",\n disabled,\n bgClassName = \"bg-background-secondary\",\n ...props\n },\n ref,\n ) => {\n const [open, setOpen] = useState(false);\n const [visible, setVisible] = useState(false);\n const containerRef = useRef<HTMLDivElement>(null);\n const hiddenSelectRef = useRef<HTMLSelectElement>(null);\n const mouseX = useMotionValue(0);\n const mouseY = useMotionValue(0);\n const radius = 100;\n\n // Combine refs\n useEffect(() => {\n if (ref && typeof ref === \"function\") {\n ref(hiddenSelectRef.current);\n } else if (ref) {\n (ref as React.MutableRefObject<HTMLSelectElement | null>).current =\n hiddenSelectRef.current;\n }\n }, [ref]);\n\n // Close dropdown on outside click\n useEffect(() => {\n const handleClick = (e: MouseEvent) => {\n if (\n containerRef.current &&\n !containerRef.current.contains(e.target as Node)\n ) {\n setOpen(false);\n }\n };\n if (open) {\n document.addEventListener(\"mousedown\", handleClick);\n }\n return () => document.removeEventListener(\"mousedown\", handleClick);\n }, [open]);\n\n const handleMouseMove = (event: React.MouseEvent<HTMLDivElement>) => {\n const { left, top } = event.currentTarget.getBoundingClientRect();\n mouseX.set(event.clientX - left);\n mouseY.set(event.clientY - top);\n };\n\n const selectedOption = options.find((opt) => opt.value === value);\n\n const handleSelect = (optValue: string) => {\n // Trigger onChange with a synthetic event\n if (onChange && hiddenSelectRef.current) {\n const event = {\n target: { value: optValue, name: props.name },\n currentTarget: { value: optValue, name: props.name },\n } as React.ChangeEvent<HTMLSelectElement>;\n onChange(event);\n }\n setOpen(false);\n };\n\n return (\n <div className={mergeClassNames(\"w-full min-w-48\", containerClassName)}>\n {label && (\n <label className=\"mb-2 block text-sm leading-none font-medium text-foreground peer-disabled:cursor-not-allowed peer-disabled:opacity-70\">\n {label}\n </label>\n )}\n\n {/* Hidden native select for form compatibility */}\n <select\n ref={hiddenSelectRef}\n className=\"sr-only\"\n value={value}\n onChange={onChange}\n disabled={disabled}\n {...props}\n >\n <option value=\"\">{placeholder}</option>\n {options.map((option) => (\n <option key={option.value} value={option.value}>\n {option.label}\n </option>\n ))}\n </select>\n\n {/* Custom styled dropdown */}\n <div\n ref={containerRef}\n className={mergeClassNames(\"relative w-full\", className)}\n >\n <motion.div\n style={{\n backgroundImage: disabled\n ? \"none\"\n : useMotionTemplate`\n radial-gradient(\n ${\n visible ? `${radius}px` : \"0px\"\n } circle at ${mouseX}px ${mouseY}px,\n var(--ds-color-accent),\n transparent 90%\n )\n `,\n }}\n onMouseMove={!disabled ? handleMouseMove : undefined}\n onMouseEnter={!disabled ? () => setVisible(true) : undefined}\n onMouseLeave={!disabled ? () => setVisible(false) : undefined}\n className={mergeClassNames(\n \"group/select rounded-lg p-[2px] transition duration-300 hover:border-accent\",\n disabled\n ? \"bg-muted border-none\"\n : error\n ? \"border-destructive\"\n : \"border-border\",\n )}\n >\n <div\n className={mergeClassNames(\n \"shadow-input flex h-10 w-full cursor-pointer items-center justify-between rounded-md border border-input px-3 py-2 text-sm transition duration-400 ease-in-out group-hover/select:shadow-none\",\n bgClassName,\n disabled ? \"cursor-not-allowed opacity-50\" : \"text-foreground\",\n error &&\n \"border-destructive text-destructive focus-visible:ring-destructive\",\n triggerClassName,\n )}\n onClick={() => {\n if (!disabled) {\n setOpen((o) => !o);\n }\n }}\n onKeyDown={(event) => {\n if (disabled) {\n return;\n }\n\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n setOpen((current) => !current);\n }\n\n if (event.key === \"Escape\") {\n setOpen(false);\n }\n }}\n role=\"button\"\n tabIndex={disabled ? -1 : 0}\n aria-haspopup=\"listbox\"\n aria-expanded={open}\n >\n {selectedOption ? (\n <span className=\"flex-1 truncate text-foreground\">\n {selectedOption.label}\n </span>\n ) : (\n <span className=\"flex-1 text-muted-foreground\">\n {placeholder}\n </span>\n )}\n <span\n className={mergeClassNames(\n \"ml-2 text-muted-foreground transition-transform duration-300\",\n open ? \"rotate-180\" : \"rotate-0\",\n )}\n >\n <ChevronDownIcon\n width={24}\n height={24}\n color=\"currentColor\"\n className=\"h-5 w-5\"\n />\n </span>\n </div>\n </motion.div>\n\n {open && !disabled && (\n <div\n className={mergeClassNames(\n \"absolute right-0 left-0 z-20 mt-1 flex max-h-60 flex-col overflow-auto rounded-lg border border-border bg-background-secondary shadow-3 backdrop-blur-xl transition\",\n )}\n >\n {options.length === 0 && (\n <div className=\"px-3 py-2 text-muted-foreground\">\n No options\n </div>\n )}\n {options.map((opt) => (\n <div\n key={opt.value}\n className={mergeClassNames(\n \"mx-1 my-1 flex cursor-pointer items-center gap-2 rounded-md px-3 py-2 text-sm text-foreground transition\",\n opt.value === value\n ? \"bg-accent-subtle text-accent font-semibold\"\n : \"\",\n \"hover:bg-accent hover:text-on-accent\",\n )}\n onClick={() => handleSelect(opt.value)}\n >\n <span className=\"flex w-5 items-center justify-center\">\n {opt.value === value && (\n <CheckIcon\n className=\"text-accent\"\n width={18}\n height={18}\n />\n )}\n </span>\n <span className=\"min-w-0 flex-1 truncate\">{opt.label}</span>\n </div>\n ))}\n </div>\n )}\n </div>\n\n {error && (\n <p className=\"mt-1 text-sm font-medium text-destructive\">{error}</p>\n )}\n {helperText && !error && (\n <p className=\"mt-1 text-sm text-muted-foreground\">{helperText}</p>\n )}\n </div>\n );\n },\n);\n\nSelect.displayName = \"Select\";\n"],"mappings":"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"}
|