cuenti-dna 0.1.0-beta.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/README.md +133 -0
- package/dist/index.cjs +1346 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +491 -0
- package/dist/index.d.ts +491 -0
- package/dist/index.js +1295 -0
- package/dist/index.js.map +1 -0
- package/dist/styles.css +2035 -0
- package/package.json +76 -0
- package/scripts/postinstall.cjs +569 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,1295 @@
|
|
|
1
|
+
// src/components/inputs/button.tsx
|
|
2
|
+
import { cva } from "class-variance-authority";
|
|
3
|
+
|
|
4
|
+
// src/utils/cn.ts
|
|
5
|
+
import { clsx } from "clsx";
|
|
6
|
+
import { twMerge } from "tailwind-merge";
|
|
7
|
+
function cn(...inputs) {
|
|
8
|
+
return twMerge(clsx(inputs));
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// src/components/inputs/button.tsx
|
|
12
|
+
import { jsx } from "react/jsx-runtime";
|
|
13
|
+
var baseStyles = "inline-flex items-center justify-center gap-2 whitespace-nowrap text-base transition-all duration-300 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] cursor-pointer disabled:bg-neutral-600 disabled:text-neutral-700 font-bold disabled:cursor-not-allowed";
|
|
14
|
+
var variants = {
|
|
15
|
+
primary: "bg-primary text-primary-foreground hover:bg-primary-600 active:bg-primary-400 aria-pressed:bg-primary-400",
|
|
16
|
+
alt: "bg-primary-400 text-primary-foreground hover:bg-primary-500 active:bg-primary-300 aria-pressed:bg-primary-300",
|
|
17
|
+
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary-600 active:bg-secondary-400 aria-pressed:bg-secondary-400",
|
|
18
|
+
ghost: "bg-transparent hover:bg-neutral-400 active:bg-neutral-500 aria-pressed:bg-neutral-500 text-muted-foreground hover:text-neutral-800",
|
|
19
|
+
"primary-ghost": "bg-transparent hover:bg-primary-50 active:bg-primary-100 aria-pressed:bg-primary-100 text-primary hover:text-primary-600",
|
|
20
|
+
link: "bg-transparent underline-offset-4 hover:underline text-neutral-700 hover:text-info active:text-info-400 aria-pressed:text-info-400",
|
|
21
|
+
destructive: "bg-destructive text-destructive-foreground hover:bg-destructive-600 active:bg-destructive-400 aria-pressed:bg-destructive-400",
|
|
22
|
+
success: "bg-success text-success-foreground hover:bg-success-600 active:bg-success-400 aria-pressed:bg-success-400",
|
|
23
|
+
accent: "bg-accent text-accent-foreground hover:bg-accent-600 active:bg-accent-400 aria-pressed:bg-accent-400 font-bold",
|
|
24
|
+
outline: "border-2 border-neutral-500 bg-transparent text-neutral-700 hover:border-neutral-600 hover:bg-neutral-300 active:bg-neutral-300 active:border-neutral-600 aria-pressed:bg-neutral-300 aria-pressed:border-neutral-600 disabled:bg-transparent disabled:border-neutral-400 disabled:text-neutral-600",
|
|
25
|
+
"secondary-outline": "border-2 border-neutral-500 bg-transparent text-neutral-700 hover:border-secondary-300 hover:bg-secondary-25 hover:text-secondary-300 active:bg-secondary-50 active:border-secondary-200 active:text-secondary-300 aria-pressed:bg-secondary-50 aria-pressed:border-secondary-200 aria-pressed:text-secondary-300 disabled:bg-transparent disabled:border-neutral-400 disabled:text-neutral-600"
|
|
26
|
+
};
|
|
27
|
+
var sizes = {
|
|
28
|
+
md: "h-12 px-5 has-[>svg]:px-3 rounded-md",
|
|
29
|
+
sm: "h-10 gap-1.5 px-5 has-[>svg]:px-3 rounded-sm",
|
|
30
|
+
lg: "h-13 px-5 has-[>svg]:px-5 rounded-lg",
|
|
31
|
+
icon: "size-12 aspect-square rounded-md",
|
|
32
|
+
"icon-sm": "size-10 aspect-square rounded-sm",
|
|
33
|
+
"icon-lg": "size-13 aspect-square rounded-lg"
|
|
34
|
+
};
|
|
35
|
+
var buttonVariants = cva(baseStyles, {
|
|
36
|
+
variants: {
|
|
37
|
+
variant: variants,
|
|
38
|
+
size: sizes
|
|
39
|
+
},
|
|
40
|
+
defaultVariants: {
|
|
41
|
+
variant: "primary",
|
|
42
|
+
size: "md"
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
function Button({
|
|
46
|
+
variant,
|
|
47
|
+
size,
|
|
48
|
+
className,
|
|
49
|
+
children,
|
|
50
|
+
type = "button",
|
|
51
|
+
...props
|
|
52
|
+
}) {
|
|
53
|
+
const classes = cn(buttonVariants({ variant, size }), className);
|
|
54
|
+
return /* @__PURE__ */ jsx("button", { className: classes, type, ...props, children });
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// src/components/inputs/checkbox.tsx
|
|
58
|
+
import { cva as cva2 } from "class-variance-authority";
|
|
59
|
+
import { useEffect, useId, useRef } from "react";
|
|
60
|
+
|
|
61
|
+
// src/components/icons/interface/check.tsx
|
|
62
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
63
|
+
function Check({ className, ...props }) {
|
|
64
|
+
return /* @__PURE__ */ jsx2(
|
|
65
|
+
"svg",
|
|
66
|
+
{
|
|
67
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
68
|
+
fill: "none",
|
|
69
|
+
viewBox: "0 0 20 20",
|
|
70
|
+
className,
|
|
71
|
+
...props,
|
|
72
|
+
children: /* @__PURE__ */ jsx2(
|
|
73
|
+
"path",
|
|
74
|
+
{
|
|
75
|
+
stroke: "currentColor",
|
|
76
|
+
strokeLinecap: "round",
|
|
77
|
+
strokeLinejoin: "round",
|
|
78
|
+
strokeWidth: "2",
|
|
79
|
+
d: "m5 10 3.54 3.54 7.07-7.08"
|
|
80
|
+
}
|
|
81
|
+
)
|
|
82
|
+
}
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// src/components/icons/interface/minus.tsx
|
|
87
|
+
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
88
|
+
function Minus({ ...props }) {
|
|
89
|
+
return /* @__PURE__ */ jsx3(
|
|
90
|
+
"svg",
|
|
91
|
+
{
|
|
92
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
93
|
+
fill: "none",
|
|
94
|
+
viewBox: "0 0 24 24",
|
|
95
|
+
...props,
|
|
96
|
+
children: /* @__PURE__ */ jsx3(
|
|
97
|
+
"path",
|
|
98
|
+
{
|
|
99
|
+
stroke: "currentColor",
|
|
100
|
+
strokeLinecap: "round",
|
|
101
|
+
strokeLinejoin: "round",
|
|
102
|
+
strokeWidth: "2",
|
|
103
|
+
d: "M6 12h12"
|
|
104
|
+
}
|
|
105
|
+
)
|
|
106
|
+
}
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// src/components/inputs/checkbox.tsx
|
|
111
|
+
import { jsx as jsx4, jsxs } from "react/jsx-runtime";
|
|
112
|
+
var baseStyles2 = "size-6 shrink-0 appearance-none border-2 border-neutral-600 bg-transparent transition-all duration-200 outline-none disabled:border-neutral-400 disabled:bg-transparent focus-visible:ring-2 focus-visible:bg-neutral-400 focus-visible:ring-offset-1 cursor-pointer disabled:cursor-not-allowed group-data-[readonly=true]/checkbox:cursor-default";
|
|
113
|
+
var variants2 = {
|
|
114
|
+
default: "hover:border-info-500 hover:bg-info-50 focus-visible:border-info-500 focus-visible:ring-info-500/20 focus-visible:checked:border-info-500 focus-visible:checked:bg-info-500 checked:border-info-500 checked:bg-info-500 checked:hover:border-info-600 checked:hover:bg-info-600 indeterminate:border-info-500 indeterminate:bg-info-500 indeterminate:hover:border-info-600 indeterminate:hover:bg-info-600 disabled:hover:border-neutral-400 disabled:hover:bg-transparent",
|
|
115
|
+
success: "hover:border-success-500 hover:bg-success-50 focus-visible:border-success-500 focus-visible:ring-success-500/20 focus-visible:checked:border-success-500 focus-visible:checked:bg-success-500 checked:border-success-500 checked:bg-success-500 checked:hover:border-success-600 checked:hover:bg-success-600 indeterminate:border-success-500 indeterminate:bg-success-500 indeterminate:hover:border-success-600 indeterminate:hover:bg-success-600 disabled:hover:border-neutral-400 disabled:hover:bg-transparent"
|
|
116
|
+
};
|
|
117
|
+
var sizes2 = {
|
|
118
|
+
square: "rounded-[8px]",
|
|
119
|
+
rounded: "rounded-full"
|
|
120
|
+
};
|
|
121
|
+
var checkboxVariants = cva2(baseStyles2, {
|
|
122
|
+
variants: {
|
|
123
|
+
variant: variants2,
|
|
124
|
+
size: sizes2
|
|
125
|
+
},
|
|
126
|
+
defaultVariants: {
|
|
127
|
+
variant: "default",
|
|
128
|
+
size: "square"
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
function Checkbox({
|
|
132
|
+
variant,
|
|
133
|
+
size,
|
|
134
|
+
indeterminate = false,
|
|
135
|
+
children,
|
|
136
|
+
className,
|
|
137
|
+
classNames,
|
|
138
|
+
readOnly,
|
|
139
|
+
onClick,
|
|
140
|
+
onChange,
|
|
141
|
+
disabled,
|
|
142
|
+
...props
|
|
143
|
+
}) {
|
|
144
|
+
const inputRef = useRef(null);
|
|
145
|
+
const generatedId = useId();
|
|
146
|
+
const id = props.id || generatedId;
|
|
147
|
+
const isReadOnly = Boolean(readOnly);
|
|
148
|
+
useEffect(() => {
|
|
149
|
+
if (inputRef.current) {
|
|
150
|
+
inputRef.current.indeterminate = indeterminate;
|
|
151
|
+
}
|
|
152
|
+
}, [indeterminate]);
|
|
153
|
+
const classes = cn(
|
|
154
|
+
checkboxVariants({ variant, size }),
|
|
155
|
+
className,
|
|
156
|
+
classNames?.input
|
|
157
|
+
);
|
|
158
|
+
const handleClick = (event) => {
|
|
159
|
+
if (isReadOnly || disabled) {
|
|
160
|
+
event.preventDefault();
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
onClick?.(event);
|
|
164
|
+
};
|
|
165
|
+
const handleChange = (event) => {
|
|
166
|
+
if (isReadOnly || disabled) {
|
|
167
|
+
event.preventDefault();
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
onChange?.(event);
|
|
171
|
+
};
|
|
172
|
+
return /* @__PURE__ */ jsxs(
|
|
173
|
+
"div",
|
|
174
|
+
{
|
|
175
|
+
"data-slot": "checkbox",
|
|
176
|
+
"data-disabled": disabled ? "true" : void 0,
|
|
177
|
+
"data-readonly": isReadOnly ? "true" : void 0,
|
|
178
|
+
className: cn(
|
|
179
|
+
"group/checkbox inline-flex cursor-pointer items-center gap-3 data-[disabled=true]:cursor-not-allowed data-[readonly=true]:cursor-default",
|
|
180
|
+
classNames?.root
|
|
181
|
+
),
|
|
182
|
+
children: [
|
|
183
|
+
/* @__PURE__ */ jsxs("span", { className: "group/control relative flex size-6 shrink-0 items-center justify-center text-white", children: [
|
|
184
|
+
/* @__PURE__ */ jsx4(
|
|
185
|
+
"input",
|
|
186
|
+
{
|
|
187
|
+
ref: inputRef,
|
|
188
|
+
id,
|
|
189
|
+
type: "checkbox",
|
|
190
|
+
"aria-checked": indeterminate ? "mixed" : void 0,
|
|
191
|
+
"aria-readonly": isReadOnly || void 0,
|
|
192
|
+
className: classes,
|
|
193
|
+
readOnly: isReadOnly,
|
|
194
|
+
disabled,
|
|
195
|
+
onClick: handleClick,
|
|
196
|
+
onChange: handleChange,
|
|
197
|
+
...props
|
|
198
|
+
}
|
|
199
|
+
),
|
|
200
|
+
/* @__PURE__ */ jsx4(
|
|
201
|
+
Check,
|
|
202
|
+
{
|
|
203
|
+
"aria-hidden": "true",
|
|
204
|
+
className: "pointer-events-none absolute z-10 size-5 opacity-0 transition-opacity group-has-checked/control:opacity-100 group-has-indeterminate/control:opacity-0"
|
|
205
|
+
}
|
|
206
|
+
),
|
|
207
|
+
/* @__PURE__ */ jsx4(
|
|
208
|
+
Minus,
|
|
209
|
+
{
|
|
210
|
+
"aria-hidden": "true",
|
|
211
|
+
className: "pointer-events-none absolute z-10 size-5 opacity-0 transition-opacity group-has-indeterminate/control:opacity-100"
|
|
212
|
+
}
|
|
213
|
+
)
|
|
214
|
+
] }),
|
|
215
|
+
children ? /* @__PURE__ */ jsx4(
|
|
216
|
+
"label",
|
|
217
|
+
{
|
|
218
|
+
"data-slot": "checkbox-label",
|
|
219
|
+
htmlFor: id,
|
|
220
|
+
className: cn(
|
|
221
|
+
"cursor-pointer transition-colors group-data-[disabled=true]/checkbox:cursor-not-allowed group-data-[readonly=true]/checkbox:cursor-default group-data-[disabled=true]/checkbox:text-neutral-600",
|
|
222
|
+
classNames?.label
|
|
223
|
+
),
|
|
224
|
+
children
|
|
225
|
+
}
|
|
226
|
+
) : null
|
|
227
|
+
]
|
|
228
|
+
}
|
|
229
|
+
);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// src/components/inputs/input/input.tsx
|
|
233
|
+
import { cva as cva3 } from "class-variance-authority";
|
|
234
|
+
|
|
235
|
+
// src/components/inputs/input/money-input.tsx
|
|
236
|
+
import { useCallback } from "react";
|
|
237
|
+
|
|
238
|
+
// src/hooks/use-formatted-numeric-input.ts
|
|
239
|
+
import { useEffect as useEffect2, useState } from "react";
|
|
240
|
+
function useFormattedNumericInput({
|
|
241
|
+
value,
|
|
242
|
+
defaultValue,
|
|
243
|
+
onChange,
|
|
244
|
+
onBlur,
|
|
245
|
+
onFocus,
|
|
246
|
+
normalizeRawValue,
|
|
247
|
+
rawToEditableValue,
|
|
248
|
+
rawToDisplayValue,
|
|
249
|
+
editableToRawValue,
|
|
250
|
+
sanitizeEditableValue
|
|
251
|
+
}) {
|
|
252
|
+
const initialRawValue = normalizeRawValue(value ?? defaultValue);
|
|
253
|
+
const [isFocused, setIsFocused] = useState(false);
|
|
254
|
+
const [rawValue, setRawValue] = useState(initialRawValue);
|
|
255
|
+
const [displayValue, setDisplayValue] = useState(
|
|
256
|
+
() => rawToDisplayValue(initialRawValue)
|
|
257
|
+
);
|
|
258
|
+
useEffect2(() => {
|
|
259
|
+
if (value === void 0) {
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
const nextRawValue = normalizeRawValue(value);
|
|
263
|
+
setRawValue(nextRawValue);
|
|
264
|
+
setDisplayValue(
|
|
265
|
+
isFocused ? rawToEditableValue(nextRawValue) : rawToDisplayValue(nextRawValue)
|
|
266
|
+
);
|
|
267
|
+
}, [
|
|
268
|
+
value,
|
|
269
|
+
isFocused,
|
|
270
|
+
normalizeRawValue,
|
|
271
|
+
rawToEditableValue,
|
|
272
|
+
rawToDisplayValue
|
|
273
|
+
]);
|
|
274
|
+
useEffect2(() => {
|
|
275
|
+
if (value !== void 0) {
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
278
|
+
setDisplayValue(
|
|
279
|
+
isFocused ? rawToEditableValue(rawValue) : rawToDisplayValue(rawValue)
|
|
280
|
+
);
|
|
281
|
+
}, [value, isFocused, rawValue, rawToEditableValue, rawToDisplayValue]);
|
|
282
|
+
const normalizeEditableValue = (editableValue) => sanitizeEditableValue ? sanitizeEditableValue(editableValue) : editableValue;
|
|
283
|
+
const emitRawValue = (event, nextRawValue) => {
|
|
284
|
+
event.currentTarget.value = nextRawValue;
|
|
285
|
+
};
|
|
286
|
+
const handleFocus = (event) => {
|
|
287
|
+
setIsFocused(true);
|
|
288
|
+
setDisplayValue(rawToEditableValue(rawValue));
|
|
289
|
+
onFocus?.(event);
|
|
290
|
+
};
|
|
291
|
+
const handleChange = (event) => {
|
|
292
|
+
const editableValue = normalizeEditableValue(event.currentTarget.value);
|
|
293
|
+
const nextRawValue = editableToRawValue(editableValue);
|
|
294
|
+
setRawValue(nextRawValue);
|
|
295
|
+
setDisplayValue(editableValue);
|
|
296
|
+
emitRawValue(event, nextRawValue);
|
|
297
|
+
onChange?.(event);
|
|
298
|
+
};
|
|
299
|
+
const handleBlur = (event) => {
|
|
300
|
+
const editableValue = normalizeEditableValue(displayValue);
|
|
301
|
+
const nextRawValue = editableToRawValue(editableValue);
|
|
302
|
+
setRawValue(nextRawValue);
|
|
303
|
+
setIsFocused(false);
|
|
304
|
+
setDisplayValue(rawToDisplayValue(nextRawValue));
|
|
305
|
+
emitRawValue(event, nextRawValue);
|
|
306
|
+
onBlur?.(event);
|
|
307
|
+
};
|
|
308
|
+
return {
|
|
309
|
+
rawValue,
|
|
310
|
+
displayValue,
|
|
311
|
+
isFocused,
|
|
312
|
+
handleFocus,
|
|
313
|
+
handleChange,
|
|
314
|
+
handleBlur
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// src/utils/input/keyboard.ts
|
|
319
|
+
var NAVIGATION_KEYS = /* @__PURE__ */ new Set([
|
|
320
|
+
"Backspace",
|
|
321
|
+
"Delete",
|
|
322
|
+
"ArrowLeft",
|
|
323
|
+
"ArrowRight",
|
|
324
|
+
"Home",
|
|
325
|
+
"End",
|
|
326
|
+
"Tab"
|
|
327
|
+
]);
|
|
328
|
+
var isControlShortcut = (event) => event.ctrlKey || event.metaKey;
|
|
329
|
+
var isNavigationKey = (key) => NAVIGATION_KEYS.has(key);
|
|
330
|
+
var buildNextValue = (currentValue, selectionStart, selectionEnd, nextText) => `${currentValue.slice(0, selectionStart)}${nextText}${currentValue.slice(selectionEnd)}`;
|
|
331
|
+
|
|
332
|
+
// src/utils/input/money.ts
|
|
333
|
+
var DEFAULT_MONEY_SYMBOL = "$";
|
|
334
|
+
var MONEY_MAX_DECIMALS = 4;
|
|
335
|
+
var MONEY_INPUT_PATTERN = "^([0-9]+)(,[0-9]{0,4})?$";
|
|
336
|
+
var MONEY_ALLOWED_CHAR_REGEX = /[0-9,]/;
|
|
337
|
+
var MONEY_PASTE_REGEX = /^[0-9,]+$/;
|
|
338
|
+
var isAllowedMoneyCharacter = (key) => MONEY_ALLOWED_CHAR_REGEX.test(key);
|
|
339
|
+
var isValidMoneyPaste = (value) => MONEY_PASTE_REGEX.test(value);
|
|
340
|
+
var sanitizeMoneyEditableValue = (value) => {
|
|
341
|
+
const cleaned = value.replace(/[^\d,]/g, "");
|
|
342
|
+
const [integerPart = "", ...decimalParts] = cleaned.split(",");
|
|
343
|
+
const mergedDecimals = decimalParts.join("").slice(0, MONEY_MAX_DECIMALS);
|
|
344
|
+
const normalizedInteger = integerPart.replace(/^0+(?=\d)/, "");
|
|
345
|
+
if (decimalParts.length > 0) {
|
|
346
|
+
return `${normalizedInteger},${mergedDecimals}`;
|
|
347
|
+
}
|
|
348
|
+
return normalizedInteger;
|
|
349
|
+
};
|
|
350
|
+
var editableMoneyToRawValue = (editableValue) => {
|
|
351
|
+
if (!editableValue) {
|
|
352
|
+
return "";
|
|
353
|
+
}
|
|
354
|
+
const [integerPart = "", decimalPart] = editableValue.split(",");
|
|
355
|
+
const normalizedInteger = integerPart || "0";
|
|
356
|
+
if (decimalPart === void 0 || decimalPart.length === 0) {
|
|
357
|
+
return normalizedInteger;
|
|
358
|
+
}
|
|
359
|
+
return `${normalizedInteger}.${decimalPart}`;
|
|
360
|
+
};
|
|
361
|
+
var rawMoneyToEditableValue = (rawValue) => {
|
|
362
|
+
if (!rawValue) {
|
|
363
|
+
return "";
|
|
364
|
+
}
|
|
365
|
+
const [integerPart = "", decimalPart] = rawValue.split(".");
|
|
366
|
+
if (decimalPart === void 0 || decimalPart.length === 0) {
|
|
367
|
+
return integerPart;
|
|
368
|
+
}
|
|
369
|
+
return `${integerPart},${decimalPart.slice(0, MONEY_MAX_DECIMALS)}`;
|
|
370
|
+
};
|
|
371
|
+
var normalizeMoneyRawValue = (value) => {
|
|
372
|
+
const normalized = Array.isArray(value) ? value[0] : value;
|
|
373
|
+
if (normalized === void 0 || normalized === null) {
|
|
374
|
+
return "";
|
|
375
|
+
}
|
|
376
|
+
const asString = String(normalized).trim();
|
|
377
|
+
if (!asString) {
|
|
378
|
+
return "";
|
|
379
|
+
}
|
|
380
|
+
const fromRaw = asString.match(/^(\d+)(?:[.,](\d{0,4}))?$/);
|
|
381
|
+
if (fromRaw) {
|
|
382
|
+
const integerPart = fromRaw[1] ?? "";
|
|
383
|
+
const decimalPart = fromRaw[2] ?? "";
|
|
384
|
+
if (!decimalPart) {
|
|
385
|
+
return integerPart;
|
|
386
|
+
}
|
|
387
|
+
return `${integerPart}.${decimalPart}`;
|
|
388
|
+
}
|
|
389
|
+
return editableMoneyToRawValue(sanitizeMoneyEditableValue(asString));
|
|
390
|
+
};
|
|
391
|
+
var formatMoneyValue = (rawValue, moneySymbol) => {
|
|
392
|
+
if (!rawValue) {
|
|
393
|
+
return "";
|
|
394
|
+
}
|
|
395
|
+
const [integerPart = "0", decimalPart = ""] = rawValue.split(".");
|
|
396
|
+
const integerWithGrouping = integerPart.replace(/\B(?=(\d{3})+(?!\d))/g, ".");
|
|
397
|
+
const decimalSection = decimalPart ? `,${decimalPart}` : "";
|
|
398
|
+
const prefix = moneySymbol.trim();
|
|
399
|
+
if (!prefix) {
|
|
400
|
+
return `${integerWithGrouping}${decimalSection}`;
|
|
401
|
+
}
|
|
402
|
+
return `${prefix} ${integerWithGrouping}${decimalSection}`;
|
|
403
|
+
};
|
|
404
|
+
|
|
405
|
+
// src/components/inputs/input/money-input.tsx
|
|
406
|
+
import { jsx as jsx5, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
407
|
+
function MoneyInput({
|
|
408
|
+
size: _size,
|
|
409
|
+
classNames,
|
|
410
|
+
moneySymbol,
|
|
411
|
+
reset,
|
|
412
|
+
...props
|
|
413
|
+
}) {
|
|
414
|
+
const {
|
|
415
|
+
value,
|
|
416
|
+
defaultValue,
|
|
417
|
+
onChange,
|
|
418
|
+
onKeyDown,
|
|
419
|
+
onBlur,
|
|
420
|
+
onFocus,
|
|
421
|
+
onPaste,
|
|
422
|
+
className,
|
|
423
|
+
inputMode,
|
|
424
|
+
pattern,
|
|
425
|
+
name,
|
|
426
|
+
disabled,
|
|
427
|
+
...restProps
|
|
428
|
+
} = props;
|
|
429
|
+
const symbol = moneySymbol ?? DEFAULT_MONEY_SYMBOL;
|
|
430
|
+
const rawToDisplayValue = useCallback(
|
|
431
|
+
(rawValue2) => formatMoneyValue(rawValue2, symbol),
|
|
432
|
+
[symbol]
|
|
433
|
+
);
|
|
434
|
+
const {
|
|
435
|
+
rawValue,
|
|
436
|
+
displayValue,
|
|
437
|
+
isFocused,
|
|
438
|
+
handleFocus,
|
|
439
|
+
handleChange,
|
|
440
|
+
handleBlur
|
|
441
|
+
} = useFormattedNumericInput({
|
|
442
|
+
value,
|
|
443
|
+
defaultValue,
|
|
444
|
+
onChange,
|
|
445
|
+
onBlur,
|
|
446
|
+
onFocus,
|
|
447
|
+
normalizeRawValue: normalizeMoneyRawValue,
|
|
448
|
+
rawToEditableValue: rawMoneyToEditableValue,
|
|
449
|
+
rawToDisplayValue,
|
|
450
|
+
editableToRawValue: editableMoneyToRawValue,
|
|
451
|
+
sanitizeEditableValue: sanitizeMoneyEditableValue
|
|
452
|
+
});
|
|
453
|
+
const resolvedPattern = pattern ?? (isFocused ? MONEY_INPUT_PATTERN : void 0);
|
|
454
|
+
const handleKeyDown = (event) => {
|
|
455
|
+
if (!isControlShortcut(event) && !isNavigationKey(event.key)) {
|
|
456
|
+
const isAllowed = isAllowedMoneyCharacter(event.key);
|
|
457
|
+
if (!isAllowed) {
|
|
458
|
+
event.preventDefault();
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
onKeyDown?.(event);
|
|
462
|
+
};
|
|
463
|
+
const handlePaste = (event) => {
|
|
464
|
+
const pastedText = event.clipboardData.getData("text");
|
|
465
|
+
if (!isValidMoneyPaste(pastedText)) {
|
|
466
|
+
event.preventDefault();
|
|
467
|
+
}
|
|
468
|
+
onPaste?.(event);
|
|
469
|
+
};
|
|
470
|
+
if (reset) {
|
|
471
|
+
return /* @__PURE__ */ jsx5("div", { className: cn("w-fit", classNames?.root), children: /* @__PURE__ */ jsx5("input", { ...props, className: cn(classNames?.input, className) }) });
|
|
472
|
+
}
|
|
473
|
+
return /* @__PURE__ */ jsxs2("div", { className: cn("w-fit", classNames?.root), children: [
|
|
474
|
+
/* @__PURE__ */ jsx5(
|
|
475
|
+
"input",
|
|
476
|
+
{
|
|
477
|
+
...restProps,
|
|
478
|
+
type: "text",
|
|
479
|
+
name: void 0,
|
|
480
|
+
value: displayValue,
|
|
481
|
+
disabled,
|
|
482
|
+
inputMode: inputMode ?? "decimal",
|
|
483
|
+
pattern: resolvedPattern,
|
|
484
|
+
onFocus: handleFocus,
|
|
485
|
+
onChange: handleChange,
|
|
486
|
+
onBlur: handleBlur,
|
|
487
|
+
onKeyDown: handleKeyDown,
|
|
488
|
+
onPaste: handlePaste,
|
|
489
|
+
className: cn(classNames?.input, className)
|
|
490
|
+
}
|
|
491
|
+
),
|
|
492
|
+
name ? /* @__PURE__ */ jsx5("input", { type: "hidden", name, value: rawValue, disabled }) : null
|
|
493
|
+
] });
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
// src/utils/input/number.ts
|
|
497
|
+
var NUMBER_INPUT_PATTERN = "^([0-9]{1,3}(\\.[0-9]{3})*|[0-9]+)?(,[0-9]*)?$";
|
|
498
|
+
var NUMBER_ALLOWED_CHAR_REGEX = /[0-9.,]/;
|
|
499
|
+
var NUMBER_INPUT_REGEX = /^(\d{1,3}(\.\d{3})*|\d+)?(,\d*)?$/;
|
|
500
|
+
var NUMBER_RAW_REGEX = /^\d+(?:\.\d+)?$/;
|
|
501
|
+
var isAllowedNumberCharacter = (key) => NUMBER_ALLOWED_CHAR_REGEX.test(key);
|
|
502
|
+
var isValidNumberInput = (value) => NUMBER_INPUT_REGEX.test(value);
|
|
503
|
+
var displayNumberToRawValue = (displayValue) => {
|
|
504
|
+
if (!displayValue) {
|
|
505
|
+
return "";
|
|
506
|
+
}
|
|
507
|
+
const cleaned = displayValue.replace(/[^\d.,]/g, "");
|
|
508
|
+
const [integerPart = "", ...decimalParts] = cleaned.split(",");
|
|
509
|
+
const integerWithoutGrouping = integerPart.replace(/\./g, "");
|
|
510
|
+
const decimalPart = decimalParts.join("");
|
|
511
|
+
if (!integerWithoutGrouping && !decimalPart) {
|
|
512
|
+
return "";
|
|
513
|
+
}
|
|
514
|
+
if (!decimalPart) {
|
|
515
|
+
return integerWithoutGrouping;
|
|
516
|
+
}
|
|
517
|
+
return `${integerWithoutGrouping || "0"}.${decimalPart}`;
|
|
518
|
+
};
|
|
519
|
+
var rawNumberToDisplayValue = (rawValue) => {
|
|
520
|
+
if (!rawValue) {
|
|
521
|
+
return "";
|
|
522
|
+
}
|
|
523
|
+
const [integerPart = "0", decimalPart = ""] = rawValue.split(".");
|
|
524
|
+
const integerWithGrouping = integerPart.replace(/\B(?=(\d{3})+(?!\d))/g, ".");
|
|
525
|
+
if (!decimalPart) {
|
|
526
|
+
return integerWithGrouping;
|
|
527
|
+
}
|
|
528
|
+
return `${integerWithGrouping},${decimalPart}`;
|
|
529
|
+
};
|
|
530
|
+
var rawNumberToEditableValue = (rawValue) => {
|
|
531
|
+
if (!rawValue) {
|
|
532
|
+
return "";
|
|
533
|
+
}
|
|
534
|
+
const [integerPart = "", decimalPart] = rawValue.split(".");
|
|
535
|
+
if (decimalPart === void 0 || decimalPart.length === 0) {
|
|
536
|
+
return integerPart;
|
|
537
|
+
}
|
|
538
|
+
return `${integerPart},${decimalPart}`;
|
|
539
|
+
};
|
|
540
|
+
var normalizeNumberRawValue = (value) => {
|
|
541
|
+
const normalized = Array.isArray(value) ? value[0] : value;
|
|
542
|
+
if (normalized === void 0 || normalized === null) {
|
|
543
|
+
return "";
|
|
544
|
+
}
|
|
545
|
+
const asString = String(normalized).trim();
|
|
546
|
+
if (!asString) {
|
|
547
|
+
return "";
|
|
548
|
+
}
|
|
549
|
+
if (NUMBER_RAW_REGEX.test(asString)) {
|
|
550
|
+
return asString;
|
|
551
|
+
}
|
|
552
|
+
if (NUMBER_INPUT_REGEX.test(asString)) {
|
|
553
|
+
return displayNumberToRawValue(asString);
|
|
554
|
+
}
|
|
555
|
+
return displayNumberToRawValue(asString);
|
|
556
|
+
};
|
|
557
|
+
|
|
558
|
+
// src/components/inputs/input/number-input.tsx
|
|
559
|
+
import { jsx as jsx6, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
560
|
+
function NumberInput({
|
|
561
|
+
size: _size,
|
|
562
|
+
classNames,
|
|
563
|
+
reset,
|
|
564
|
+
...props
|
|
565
|
+
}) {
|
|
566
|
+
const {
|
|
567
|
+
value,
|
|
568
|
+
defaultValue,
|
|
569
|
+
onChange,
|
|
570
|
+
onBlur,
|
|
571
|
+
onFocus,
|
|
572
|
+
onKeyDown,
|
|
573
|
+
onPaste,
|
|
574
|
+
inputMode,
|
|
575
|
+
pattern,
|
|
576
|
+
className,
|
|
577
|
+
name,
|
|
578
|
+
disabled,
|
|
579
|
+
...restProps
|
|
580
|
+
} = props;
|
|
581
|
+
const { rawValue, displayValue, handleFocus, handleChange, handleBlur } = useFormattedNumericInput({
|
|
582
|
+
value,
|
|
583
|
+
defaultValue,
|
|
584
|
+
onChange,
|
|
585
|
+
onBlur,
|
|
586
|
+
onFocus,
|
|
587
|
+
normalizeRawValue: normalizeNumberRawValue,
|
|
588
|
+
rawToEditableValue: rawNumberToEditableValue,
|
|
589
|
+
rawToDisplayValue: rawNumberToDisplayValue,
|
|
590
|
+
editableToRawValue: displayNumberToRawValue
|
|
591
|
+
});
|
|
592
|
+
const handleKeyDown = (event) => {
|
|
593
|
+
if (!isControlShortcut(event) && !isNavigationKey(event.key)) {
|
|
594
|
+
const isAllowedChar = isAllowedNumberCharacter(event.key);
|
|
595
|
+
if (!isAllowedChar) {
|
|
596
|
+
event.preventDefault();
|
|
597
|
+
} else {
|
|
598
|
+
const inputElement = event.currentTarget;
|
|
599
|
+
const selectionStart = inputElement.selectionStart ?? 0;
|
|
600
|
+
const selectionEnd = inputElement.selectionEnd ?? selectionStart;
|
|
601
|
+
const nextValue = buildNextValue(
|
|
602
|
+
inputElement.value,
|
|
603
|
+
selectionStart,
|
|
604
|
+
selectionEnd,
|
|
605
|
+
event.key
|
|
606
|
+
);
|
|
607
|
+
if (!isValidNumberInput(nextValue)) {
|
|
608
|
+
event.preventDefault();
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
onKeyDown?.(event);
|
|
613
|
+
};
|
|
614
|
+
const handlePaste = (event) => {
|
|
615
|
+
const pastedText = event.clipboardData.getData("text");
|
|
616
|
+
const inputElement = event.currentTarget;
|
|
617
|
+
const selectionStart = inputElement.selectionStart ?? 0;
|
|
618
|
+
const selectionEnd = inputElement.selectionEnd ?? selectionStart;
|
|
619
|
+
const nextValue = buildNextValue(
|
|
620
|
+
inputElement.value,
|
|
621
|
+
selectionStart,
|
|
622
|
+
selectionEnd,
|
|
623
|
+
pastedText
|
|
624
|
+
);
|
|
625
|
+
if (!isValidNumberInput(nextValue)) {
|
|
626
|
+
event.preventDefault();
|
|
627
|
+
}
|
|
628
|
+
onPaste?.(event);
|
|
629
|
+
};
|
|
630
|
+
if (reset) {
|
|
631
|
+
return /* @__PURE__ */ jsx6("div", { className: cn("w-fit", classNames?.root), children: /* @__PURE__ */ jsx6(
|
|
632
|
+
"input",
|
|
633
|
+
{
|
|
634
|
+
...props,
|
|
635
|
+
type: "number",
|
|
636
|
+
className: cn(classNames?.input, className)
|
|
637
|
+
}
|
|
638
|
+
) });
|
|
639
|
+
}
|
|
640
|
+
return /* @__PURE__ */ jsxs3("div", { className: cn("w-fit", classNames?.root), children: [
|
|
641
|
+
/* @__PURE__ */ jsx6(
|
|
642
|
+
"input",
|
|
643
|
+
{
|
|
644
|
+
...restProps,
|
|
645
|
+
type: "text",
|
|
646
|
+
name: void 0,
|
|
647
|
+
value: displayValue,
|
|
648
|
+
disabled,
|
|
649
|
+
inputMode: inputMode ?? "decimal",
|
|
650
|
+
pattern: pattern ?? NUMBER_INPUT_PATTERN,
|
|
651
|
+
onFocus: handleFocus,
|
|
652
|
+
onChange: handleChange,
|
|
653
|
+
onBlur: handleBlur,
|
|
654
|
+
onKeyDown: handleKeyDown,
|
|
655
|
+
onPaste: handlePaste,
|
|
656
|
+
className: cn(classNames?.input, className)
|
|
657
|
+
}
|
|
658
|
+
),
|
|
659
|
+
name ? /* @__PURE__ */ jsx6("input", { type: "hidden", name, value: rawValue, disabled }) : null
|
|
660
|
+
] });
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
// src/components/inputs/input/password-input.tsx
|
|
664
|
+
import { Eye, EyeOff } from "lucide-react";
|
|
665
|
+
import { useState as useState2 } from "react";
|
|
666
|
+
import { jsx as jsx7, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
667
|
+
var buttonSizeClasses = {
|
|
668
|
+
sm: "size-8 rounded-sm",
|
|
669
|
+
md: "size-10 rounded-sm",
|
|
670
|
+
lg: "size-11 rounded-md"
|
|
671
|
+
};
|
|
672
|
+
var iconSizeClasses = {
|
|
673
|
+
sm: "size-4",
|
|
674
|
+
md: "size-5",
|
|
675
|
+
lg: "size-6"
|
|
676
|
+
};
|
|
677
|
+
function PasswordInput({
|
|
678
|
+
size,
|
|
679
|
+
classNames,
|
|
680
|
+
...props
|
|
681
|
+
}) {
|
|
682
|
+
const [viewPassword, setViewPassword] = useState2(false);
|
|
683
|
+
const EyeIcon = viewPassword ? Eye : EyeOff;
|
|
684
|
+
const { className, ...restProps } = props;
|
|
685
|
+
const currentSize = size ?? "md";
|
|
686
|
+
return /* @__PURE__ */ jsxs4("div", { className: cn("relative w-fit", classNames?.root), children: [
|
|
687
|
+
/* @__PURE__ */ jsx7(
|
|
688
|
+
"input",
|
|
689
|
+
{
|
|
690
|
+
...restProps,
|
|
691
|
+
type: viewPassword ? "text" : "password",
|
|
692
|
+
className: cn(
|
|
693
|
+
"placeholder:tracking-normal [[type='password']]:tracking-[0.16em]",
|
|
694
|
+
classNames?.input,
|
|
695
|
+
className
|
|
696
|
+
)
|
|
697
|
+
}
|
|
698
|
+
),
|
|
699
|
+
/* @__PURE__ */ jsx7(
|
|
700
|
+
Button,
|
|
701
|
+
{
|
|
702
|
+
variant: "ghost",
|
|
703
|
+
size: "icon",
|
|
704
|
+
className: cn(
|
|
705
|
+
"absolute top-1/2 right-1 -translate-y-1/2",
|
|
706
|
+
buttonSizeClasses[currentSize]
|
|
707
|
+
),
|
|
708
|
+
type: "button",
|
|
709
|
+
"aria-label": viewPassword ? "Hide password" : "Show password",
|
|
710
|
+
title: viewPassword ? "Ocultar contrase\xF1a" : "Mostrar contrase\xF1a",
|
|
711
|
+
onClick: () => setViewPassword((prev) => !prev),
|
|
712
|
+
children: /* @__PURE__ */ jsx7(
|
|
713
|
+
EyeIcon,
|
|
714
|
+
{
|
|
715
|
+
"aria-hidden": "true",
|
|
716
|
+
className: cn(iconSizeClasses[currentSize])
|
|
717
|
+
}
|
|
718
|
+
)
|
|
719
|
+
}
|
|
720
|
+
)
|
|
721
|
+
] });
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
// src/types/atoms/inputs/input/input.ts
|
|
725
|
+
var inputTypes = [
|
|
726
|
+
"text",
|
|
727
|
+
"password",
|
|
728
|
+
"email",
|
|
729
|
+
"number",
|
|
730
|
+
"money"
|
|
731
|
+
];
|
|
732
|
+
|
|
733
|
+
// src/components/inputs/input/input.tsx
|
|
734
|
+
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
735
|
+
var baseStyles3 = [
|
|
736
|
+
"bg-transparent transition-colors duration-200 ease-in-out disabled:bg-neutral-200 disabled:text-neutral-600 disabled:border-neutral-400 disabled:cursor-not-allowed"
|
|
737
|
+
];
|
|
738
|
+
var variants3 = {
|
|
739
|
+
default: [
|
|
740
|
+
"border border-neutral-500 text-foreground",
|
|
741
|
+
"placeholder:text-neutral-500",
|
|
742
|
+
"hover:border-neutral-700",
|
|
743
|
+
"focus:border-info-500 focus:ring-0 focus:outline-none"
|
|
744
|
+
],
|
|
745
|
+
error: [
|
|
746
|
+
"border border-destructive text-foreground",
|
|
747
|
+
"placeholder:text-destructive-400/70",
|
|
748
|
+
"hover:border-destructive-600",
|
|
749
|
+
"focus:border-destructive-400 focus:ring-0 focus:outline-none"
|
|
750
|
+
],
|
|
751
|
+
success: [
|
|
752
|
+
"border border-success text-foreground",
|
|
753
|
+
"placeholder:text-success/60",
|
|
754
|
+
"hover:border-success-600",
|
|
755
|
+
"focus:border-success-400 focus:ring-0 focus:outline-none"
|
|
756
|
+
]
|
|
757
|
+
};
|
|
758
|
+
var sizes3 = {
|
|
759
|
+
sm: ["h-10 rounded-[14px] px-3 py-2.5 font-normal text-sm"],
|
|
760
|
+
md: ["h-12 rounded-md px-3 pt-3 pb-3.5 text-base"],
|
|
761
|
+
lg: ["h-13 rounded-lg px-3 py-[15px] text-base"]
|
|
762
|
+
};
|
|
763
|
+
var switchVariants = cva3(baseStyles3, {
|
|
764
|
+
variants: {
|
|
765
|
+
variant: variants3,
|
|
766
|
+
size: sizes3
|
|
767
|
+
},
|
|
768
|
+
defaultVariants: {
|
|
769
|
+
variant: "default",
|
|
770
|
+
size: "md"
|
|
771
|
+
}
|
|
772
|
+
});
|
|
773
|
+
function Input({
|
|
774
|
+
variant,
|
|
775
|
+
size,
|
|
776
|
+
classNames,
|
|
777
|
+
moneySymbol,
|
|
778
|
+
type,
|
|
779
|
+
...props
|
|
780
|
+
}) {
|
|
781
|
+
const inputClasses = cn(switchVariants({ variant, size }), props.className);
|
|
782
|
+
const specializedClassNames = {
|
|
783
|
+
input: cn(inputClasses, classNames?.input),
|
|
784
|
+
root: classNames?.root
|
|
785
|
+
};
|
|
786
|
+
if (type && !inputTypes.includes(type)) {
|
|
787
|
+
throw new Error(
|
|
788
|
+
`Invalid input type: ${type}. Allowed types are: ${inputTypes.join(", ")}`
|
|
789
|
+
);
|
|
790
|
+
}
|
|
791
|
+
if (type !== "password" && type !== "number" && type !== "money") {
|
|
792
|
+
return /* @__PURE__ */ jsx8("div", { className: cn("w-fit", classNames?.root), children: /* @__PURE__ */ jsx8(
|
|
793
|
+
"input",
|
|
794
|
+
{
|
|
795
|
+
...props,
|
|
796
|
+
type,
|
|
797
|
+
className: cn(inputClasses, classNames?.input)
|
|
798
|
+
}
|
|
799
|
+
) });
|
|
800
|
+
}
|
|
801
|
+
if (type === "password") {
|
|
802
|
+
return /* @__PURE__ */ jsx8(
|
|
803
|
+
PasswordInput,
|
|
804
|
+
{
|
|
805
|
+
size,
|
|
806
|
+
classNames: specializedClassNames,
|
|
807
|
+
...props
|
|
808
|
+
}
|
|
809
|
+
);
|
|
810
|
+
}
|
|
811
|
+
if (type === "number") {
|
|
812
|
+
return /* @__PURE__ */ jsx8(NumberInput, { size, classNames: specializedClassNames, ...props });
|
|
813
|
+
}
|
|
814
|
+
if (type === "money") {
|
|
815
|
+
return /* @__PURE__ */ jsx8(
|
|
816
|
+
MoneyInput,
|
|
817
|
+
{
|
|
818
|
+
size,
|
|
819
|
+
moneySymbol,
|
|
820
|
+
classNames: specializedClassNames,
|
|
821
|
+
...props
|
|
822
|
+
}
|
|
823
|
+
);
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
// src/components/inputs/radio.tsx
|
|
828
|
+
import { cva as cva4 } from "class-variance-authority";
|
|
829
|
+
|
|
830
|
+
// src/hooks/use-radio.ts
|
|
831
|
+
import { useId as useId2 } from "react";
|
|
832
|
+
|
|
833
|
+
// src/hooks/context/radio-group.ts
|
|
834
|
+
import { createContext, useContext } from "react";
|
|
835
|
+
var RadioGroupContext = createContext(null);
|
|
836
|
+
function useRadioGroupContext() {
|
|
837
|
+
const context = useContext(RadioGroupContext);
|
|
838
|
+
if (!context) {
|
|
839
|
+
throw new Error("RadioItem must be used within a RadioGroup");
|
|
840
|
+
}
|
|
841
|
+
return context;
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
// src/hooks/use-radio.ts
|
|
845
|
+
function useRadio({
|
|
846
|
+
variant,
|
|
847
|
+
readOnly,
|
|
848
|
+
disabled,
|
|
849
|
+
value,
|
|
850
|
+
onClick,
|
|
851
|
+
onChange,
|
|
852
|
+
id
|
|
853
|
+
}) {
|
|
854
|
+
const context = useRadioGroupContext();
|
|
855
|
+
const generatedId = useId2();
|
|
856
|
+
const finalId = id || generatedId;
|
|
857
|
+
const resolvedVariant = variant || context.variant;
|
|
858
|
+
const isReadOnly = Boolean(readOnly || context.readOnly);
|
|
859
|
+
const isDisabled = Boolean(disabled || context.disabled);
|
|
860
|
+
const isChecked = context.value === value;
|
|
861
|
+
const name = context.name;
|
|
862
|
+
const handleClick = (event) => {
|
|
863
|
+
if (isReadOnly || isDisabled) {
|
|
864
|
+
event.preventDefault();
|
|
865
|
+
return;
|
|
866
|
+
}
|
|
867
|
+
onClick?.(event);
|
|
868
|
+
};
|
|
869
|
+
const handleChange = (event) => {
|
|
870
|
+
if (isReadOnly || isDisabled) {
|
|
871
|
+
event.preventDefault();
|
|
872
|
+
return;
|
|
873
|
+
}
|
|
874
|
+
context.onValueChange(value);
|
|
875
|
+
onChange?.(event);
|
|
876
|
+
};
|
|
877
|
+
return {
|
|
878
|
+
id: finalId,
|
|
879
|
+
name,
|
|
880
|
+
resolvedVariant,
|
|
881
|
+
isReadOnly,
|
|
882
|
+
isDisabled,
|
|
883
|
+
isChecked,
|
|
884
|
+
handleClick,
|
|
885
|
+
handleChange
|
|
886
|
+
};
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
// src/hooks/use-radio-group.ts
|
|
890
|
+
import { useCallback as useCallback2, useId as useId3, useMemo, useState as useState3 } from "react";
|
|
891
|
+
function useRadioGroup({
|
|
892
|
+
value,
|
|
893
|
+
defaultValue,
|
|
894
|
+
onValueChange,
|
|
895
|
+
name,
|
|
896
|
+
variant = "default",
|
|
897
|
+
disabled = false,
|
|
898
|
+
readOnly = false
|
|
899
|
+
}) {
|
|
900
|
+
const generatedName = useId3();
|
|
901
|
+
const groupName = name || generatedName;
|
|
902
|
+
const [internalValue, setInternalValue] = useState3(defaultValue);
|
|
903
|
+
const isControlled = value !== void 0;
|
|
904
|
+
const selectedValue = isControlled ? value : internalValue;
|
|
905
|
+
const handleValueChange = useCallback2(
|
|
906
|
+
(nextValue) => {
|
|
907
|
+
if (disabled || readOnly) {
|
|
908
|
+
return;
|
|
909
|
+
}
|
|
910
|
+
if (!isControlled) {
|
|
911
|
+
setInternalValue(nextValue);
|
|
912
|
+
}
|
|
913
|
+
onValueChange?.(nextValue);
|
|
914
|
+
},
|
|
915
|
+
[disabled, readOnly, isControlled, onValueChange]
|
|
916
|
+
);
|
|
917
|
+
const contextValue = useMemo(
|
|
918
|
+
() => ({
|
|
919
|
+
name: groupName,
|
|
920
|
+
value: selectedValue,
|
|
921
|
+
variant,
|
|
922
|
+
disabled,
|
|
923
|
+
readOnly,
|
|
924
|
+
onValueChange: handleValueChange
|
|
925
|
+
}),
|
|
926
|
+
[groupName, selectedValue, variant, disabled, readOnly, handleValueChange]
|
|
927
|
+
);
|
|
928
|
+
return {
|
|
929
|
+
contextValue
|
|
930
|
+
};
|
|
931
|
+
}
|
|
932
|
+
|
|
933
|
+
// src/providers/radio-group-provider.tsx
|
|
934
|
+
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
935
|
+
function RadioGroupProvider({ value, children }) {
|
|
936
|
+
return /* @__PURE__ */ jsx9(RadioGroupContext.Provider, { value, children });
|
|
937
|
+
}
|
|
938
|
+
|
|
939
|
+
// src/components/inputs/radio.tsx
|
|
940
|
+
import { jsx as jsx10, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
941
|
+
var baseStyles4 = "size-6 shrink-0 appearance-none rounded-full border-2 border-neutral-600 bg-transparent transition-all duration-200 outline-none disabled:border-neutral-400 disabled:bg-transparent focus-visible:ring-2 focus-visible:ring-offset-1 cursor-pointer disabled:cursor-not-allowed group-data-[readonly=true]/radio:cursor-default";
|
|
942
|
+
var variants4 = {
|
|
943
|
+
default: "hover:border-info-500 hover:bg-info-50 focus-visible:border-info-500 focus-visible:ring-info-500/20 checked:border-info-500 checked:hover:border-info-600 disabled:hover:border-neutral-400 disabled:hover:bg-transparent",
|
|
944
|
+
success: "hover:border-success-500 hover:bg-success-50 focus-visible:border-success-500 focus-visible:ring-success-500/20 checked:border-success-500 checked:hover:border-success-600 disabled:hover:border-neutral-400 disabled:hover:bg-transparent"
|
|
945
|
+
};
|
|
946
|
+
var indicatorVariants = cva4(
|
|
947
|
+
"pointer-events-none absolute z-10 size-3 rounded-full opacity-0 transition-opacity group-has-checked/control:opacity-100",
|
|
948
|
+
{
|
|
949
|
+
variants: {
|
|
950
|
+
variant: {
|
|
951
|
+
default: "bg-info-500",
|
|
952
|
+
success: "bg-success-500"
|
|
953
|
+
}
|
|
954
|
+
},
|
|
955
|
+
defaultVariants: {
|
|
956
|
+
variant: "default"
|
|
957
|
+
}
|
|
958
|
+
}
|
|
959
|
+
);
|
|
960
|
+
var radioVariants = cva4(baseStyles4, {
|
|
961
|
+
variants: {
|
|
962
|
+
variant: variants4
|
|
963
|
+
},
|
|
964
|
+
defaultVariants: {
|
|
965
|
+
variant: "default"
|
|
966
|
+
}
|
|
967
|
+
});
|
|
968
|
+
function RadioGroup({
|
|
969
|
+
value,
|
|
970
|
+
defaultValue,
|
|
971
|
+
onValueChange,
|
|
972
|
+
name,
|
|
973
|
+
variant = "default",
|
|
974
|
+
disabled = false,
|
|
975
|
+
readOnly = false,
|
|
976
|
+
className,
|
|
977
|
+
children,
|
|
978
|
+
...props
|
|
979
|
+
}) {
|
|
980
|
+
const { contextValue } = useRadioGroup({
|
|
981
|
+
value,
|
|
982
|
+
defaultValue,
|
|
983
|
+
onValueChange,
|
|
984
|
+
name,
|
|
985
|
+
variant,
|
|
986
|
+
disabled,
|
|
987
|
+
readOnly
|
|
988
|
+
});
|
|
989
|
+
return /* @__PURE__ */ jsx10(RadioGroupProvider, { value: contextValue, children: /* @__PURE__ */ jsx10(
|
|
990
|
+
"div",
|
|
991
|
+
{
|
|
992
|
+
role: "radiogroup",
|
|
993
|
+
"aria-disabled": contextValue.disabled || void 0,
|
|
994
|
+
"aria-readonly": contextValue.readOnly || void 0,
|
|
995
|
+
"data-slot": "radio-group",
|
|
996
|
+
"data-disabled": contextValue.disabled ? "true" : void 0,
|
|
997
|
+
"data-readonly": contextValue.readOnly ? "true" : void 0,
|
|
998
|
+
className: cn("flex flex-col gap-4", className),
|
|
999
|
+
...props,
|
|
1000
|
+
children
|
|
1001
|
+
}
|
|
1002
|
+
) });
|
|
1003
|
+
}
|
|
1004
|
+
function RadioItem({
|
|
1005
|
+
variant,
|
|
1006
|
+
children,
|
|
1007
|
+
className,
|
|
1008
|
+
classNames,
|
|
1009
|
+
readOnly,
|
|
1010
|
+
onClick,
|
|
1011
|
+
onChange,
|
|
1012
|
+
disabled,
|
|
1013
|
+
value,
|
|
1014
|
+
id: propId,
|
|
1015
|
+
...props
|
|
1016
|
+
}) {
|
|
1017
|
+
const {
|
|
1018
|
+
handleChange,
|
|
1019
|
+
handleClick,
|
|
1020
|
+
id,
|
|
1021
|
+
isChecked,
|
|
1022
|
+
isDisabled,
|
|
1023
|
+
isReadOnly,
|
|
1024
|
+
resolvedVariant,
|
|
1025
|
+
name
|
|
1026
|
+
} = useRadio({
|
|
1027
|
+
variant,
|
|
1028
|
+
readOnly,
|
|
1029
|
+
disabled,
|
|
1030
|
+
value,
|
|
1031
|
+
onClick,
|
|
1032
|
+
onChange,
|
|
1033
|
+
id: propId
|
|
1034
|
+
});
|
|
1035
|
+
const classes = cn(
|
|
1036
|
+
radioVariants({ variant: resolvedVariant }),
|
|
1037
|
+
className,
|
|
1038
|
+
classNames?.input
|
|
1039
|
+
);
|
|
1040
|
+
return /* @__PURE__ */ jsxs5(
|
|
1041
|
+
"label",
|
|
1042
|
+
{
|
|
1043
|
+
"data-slot": "radio",
|
|
1044
|
+
"data-state": isChecked ? "checked" : "unchecked",
|
|
1045
|
+
"data-disabled": isDisabled ? "true" : void 0,
|
|
1046
|
+
"data-readonly": isReadOnly ? "true" : void 0,
|
|
1047
|
+
className: cn(
|
|
1048
|
+
"group/radio inline-flex w-fit cursor-pointer items-center gap-3 data-[disabled=true]:cursor-not-allowed data-[readonly=true]:cursor-default",
|
|
1049
|
+
classNames?.root
|
|
1050
|
+
),
|
|
1051
|
+
children: [
|
|
1052
|
+
/* @__PURE__ */ jsxs5(
|
|
1053
|
+
"span",
|
|
1054
|
+
{
|
|
1055
|
+
role: "presentation",
|
|
1056
|
+
className: "group/control relative flex size-6 shrink-0 items-center justify-center",
|
|
1057
|
+
children: [
|
|
1058
|
+
/* @__PURE__ */ jsx10(
|
|
1059
|
+
"input",
|
|
1060
|
+
{
|
|
1061
|
+
id,
|
|
1062
|
+
type: "radio",
|
|
1063
|
+
name,
|
|
1064
|
+
value,
|
|
1065
|
+
checked: isChecked,
|
|
1066
|
+
className: classes,
|
|
1067
|
+
readOnly: isReadOnly,
|
|
1068
|
+
disabled: isDisabled,
|
|
1069
|
+
onClick: handleClick,
|
|
1070
|
+
onChange: handleChange,
|
|
1071
|
+
...props
|
|
1072
|
+
}
|
|
1073
|
+
),
|
|
1074
|
+
/* @__PURE__ */ jsx10(
|
|
1075
|
+
"span",
|
|
1076
|
+
{
|
|
1077
|
+
"aria-hidden": "true",
|
|
1078
|
+
role: "presentation",
|
|
1079
|
+
className: cn(
|
|
1080
|
+
indicatorVariants({ variant: resolvedVariant }),
|
|
1081
|
+
classNames?.indicator
|
|
1082
|
+
)
|
|
1083
|
+
}
|
|
1084
|
+
)
|
|
1085
|
+
]
|
|
1086
|
+
}
|
|
1087
|
+
),
|
|
1088
|
+
children ? /* @__PURE__ */ jsx10(
|
|
1089
|
+
"span",
|
|
1090
|
+
{
|
|
1091
|
+
"data-slot": "radio-label",
|
|
1092
|
+
className: cn(
|
|
1093
|
+
"cursor-pointer transition-colors group-data-[disabled=true]/radio:cursor-not-allowed group-data-[readonly=true]/radio:cursor-default group-data-[disabled=true]/radio:text-neutral-600",
|
|
1094
|
+
classNames?.label
|
|
1095
|
+
),
|
|
1096
|
+
children
|
|
1097
|
+
}
|
|
1098
|
+
) : null
|
|
1099
|
+
]
|
|
1100
|
+
}
|
|
1101
|
+
);
|
|
1102
|
+
}
|
|
1103
|
+
|
|
1104
|
+
// src/components/inputs/switch.tsx
|
|
1105
|
+
import { cva as cva5 } from "class-variance-authority";
|
|
1106
|
+
import { useId as useId4 } from "react";
|
|
1107
|
+
import { jsx as jsx11, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1108
|
+
var baseStyles5 = [
|
|
1109
|
+
"group relative inline-flex h-6 w-11 items-center rounded-sm p-0.5 transition-colors duration-300",
|
|
1110
|
+
"[&_>span]:block [&_>span]:size-5 [&_>span]:rounded-full [&_>span]:transition-all [&_>span]:duration-300 [&_>span]:group-has-checked:translate-x-full",
|
|
1111
|
+
"bg-neutral-300 group-hover:bg-neutral-400",
|
|
1112
|
+
"[&_>span]:bg-neutral-500 group-hover:[&_>span]:bg-neutral-600",
|
|
1113
|
+
"group-has-checked:[&_>span]:bg-neutral-300 group-has-checked:group-hover:[&_>span]:bg-neutral-300",
|
|
1114
|
+
"outline-info-500/20 group-has-focus-visible:outline-3 group-has-focus-visible:ring-0",
|
|
1115
|
+
"group-has-disabled:bg-neutral-200 group-has-disabled:cursor-not-allowed",
|
|
1116
|
+
"group-has-disabled:group-hover:bg-neutral-200 group-has-disabled:[&_>span]:bg-neutral-400 group-has-disabled:group-hover:[&_>span]:bg-neutral-400",
|
|
1117
|
+
"group-has-disabled:group-has-checked:[&_>span]:bg-neutral-200 group-has-disabled:group-has-checked:group-hover:[&_>span]:bg-neutral-200"
|
|
1118
|
+
];
|
|
1119
|
+
var variants5 = {
|
|
1120
|
+
default: [
|
|
1121
|
+
"group-has-checked:bg-info-500 group-has-checked:group-hover:bg-info-700",
|
|
1122
|
+
"group-has-disabled:group-has-checked:bg-info-50 group-has-disabled:group-has-checked:group-hover:bg-info-50"
|
|
1123
|
+
],
|
|
1124
|
+
alt: [
|
|
1125
|
+
"group-has-checked:bg-alt2-500 group-has-checked:group-hover:bg-alt2-700",
|
|
1126
|
+
"group-has-disabled:group-has-checked:bg-alt2-50 group-has-disabled:group-has-checked:group-hover:bg-alt2-50"
|
|
1127
|
+
]
|
|
1128
|
+
};
|
|
1129
|
+
var switchVariants2 = cva5(baseStyles5, {
|
|
1130
|
+
variants: {
|
|
1131
|
+
variant: variants5
|
|
1132
|
+
},
|
|
1133
|
+
defaultVariants: {
|
|
1134
|
+
variant: "default"
|
|
1135
|
+
}
|
|
1136
|
+
});
|
|
1137
|
+
function Switch({
|
|
1138
|
+
variant,
|
|
1139
|
+
classNames,
|
|
1140
|
+
id: propsId,
|
|
1141
|
+
children,
|
|
1142
|
+
className,
|
|
1143
|
+
...props
|
|
1144
|
+
}) {
|
|
1145
|
+
const generatedId = useId4();
|
|
1146
|
+
const id = propsId || generatedId;
|
|
1147
|
+
const classes = cn(switchVariants2({ variant }), classNames?.input);
|
|
1148
|
+
return /* @__PURE__ */ jsxs6(
|
|
1149
|
+
"label",
|
|
1150
|
+
{
|
|
1151
|
+
htmlFor: id,
|
|
1152
|
+
className: cn(
|
|
1153
|
+
"group inline-flex items-center gap-2",
|
|
1154
|
+
props.disabled ? "cursor-not-allowed text-neutral-700" : "cursor-pointer",
|
|
1155
|
+
className,
|
|
1156
|
+
classNames?.root
|
|
1157
|
+
),
|
|
1158
|
+
children: [
|
|
1159
|
+
/* @__PURE__ */ jsxs6("span", { className: classes, children: [
|
|
1160
|
+
/* @__PURE__ */ jsx11("input", { ...props, id, type: "checkbox", className: "sr-only" }),
|
|
1161
|
+
/* @__PURE__ */ jsx11("span", { "aria-hidden": "true", className: cn(classNames?.indicator) })
|
|
1162
|
+
] }),
|
|
1163
|
+
children
|
|
1164
|
+
]
|
|
1165
|
+
}
|
|
1166
|
+
);
|
|
1167
|
+
}
|
|
1168
|
+
|
|
1169
|
+
// src/components/surfaces/card.tsx
|
|
1170
|
+
import { jsx as jsx12 } from "react/jsx-runtime";
|
|
1171
|
+
function Card({ as = "div", className, interactive, ...props }) {
|
|
1172
|
+
const cardClassName = cn(
|
|
1173
|
+
"flex flex-col gap-5 rounded-lg bg-card p-4 text-card-foreground",
|
|
1174
|
+
interactive && "cursor-pointer transition-shadow focus-within:ring-2 focus-within:ring-ring/40 hover:shadow-lg",
|
|
1175
|
+
className
|
|
1176
|
+
);
|
|
1177
|
+
if (as === "article") {
|
|
1178
|
+
return /* @__PURE__ */ jsx12("article", { "data-slot": "card", className: cardClassName, ...props });
|
|
1179
|
+
}
|
|
1180
|
+
if (as === "section") {
|
|
1181
|
+
return /* @__PURE__ */ jsx12("section", { "data-slot": "card", className: cardClassName, ...props });
|
|
1182
|
+
}
|
|
1183
|
+
return /* @__PURE__ */ jsx12("div", { "data-slot": "card", className: cardClassName, ...props });
|
|
1184
|
+
}
|
|
1185
|
+
function CardHeader({ className, ...props }) {
|
|
1186
|
+
return /* @__PURE__ */ jsx12(
|
|
1187
|
+
"header",
|
|
1188
|
+
{
|
|
1189
|
+
"data-slot": "card-header",
|
|
1190
|
+
className: cn(
|
|
1191
|
+
"@container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-1 has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6",
|
|
1192
|
+
className
|
|
1193
|
+
),
|
|
1194
|
+
...props
|
|
1195
|
+
}
|
|
1196
|
+
);
|
|
1197
|
+
}
|
|
1198
|
+
function CardTitle({ className, ...props }) {
|
|
1199
|
+
return /* @__PURE__ */ jsx12(
|
|
1200
|
+
"h3",
|
|
1201
|
+
{
|
|
1202
|
+
"data-slot": "card-title",
|
|
1203
|
+
className: cn("font-semibold leading-none", className),
|
|
1204
|
+
...props
|
|
1205
|
+
}
|
|
1206
|
+
);
|
|
1207
|
+
}
|
|
1208
|
+
function CardDescription({ className, ...props }) {
|
|
1209
|
+
return /* @__PURE__ */ jsx12(
|
|
1210
|
+
"p",
|
|
1211
|
+
{
|
|
1212
|
+
"data-slot": "card-description",
|
|
1213
|
+
className: cn("text-neutral-700 text-sm", className),
|
|
1214
|
+
...props
|
|
1215
|
+
}
|
|
1216
|
+
);
|
|
1217
|
+
}
|
|
1218
|
+
function CardAction({ className, ...props }) {
|
|
1219
|
+
return /* @__PURE__ */ jsx12(
|
|
1220
|
+
"div",
|
|
1221
|
+
{
|
|
1222
|
+
"data-slot": "card-action",
|
|
1223
|
+
className: cn(
|
|
1224
|
+
"col-start-2 row-span-2 row-start-1 self-start justify-self-end",
|
|
1225
|
+
className
|
|
1226
|
+
),
|
|
1227
|
+
...props
|
|
1228
|
+
}
|
|
1229
|
+
);
|
|
1230
|
+
}
|
|
1231
|
+
function CardContent({ className, ...props }) {
|
|
1232
|
+
return /* @__PURE__ */ jsx12("section", { "data-slot": "card-content", className: cn(className), ...props });
|
|
1233
|
+
}
|
|
1234
|
+
function CardFooter({ className, ...props }) {
|
|
1235
|
+
return /* @__PURE__ */ jsx12(
|
|
1236
|
+
"footer",
|
|
1237
|
+
{
|
|
1238
|
+
"data-slot": "card-footer",
|
|
1239
|
+
className: cn("flex items-center px-6 [.border-t]:pt-6", className),
|
|
1240
|
+
...props
|
|
1241
|
+
}
|
|
1242
|
+
);
|
|
1243
|
+
}
|
|
1244
|
+
|
|
1245
|
+
// src/components/icons/menu/closeX.tsx
|
|
1246
|
+
import { jsx as jsx13 } from "react/jsx-runtime";
|
|
1247
|
+
function CloseX({ className, ...props }) {
|
|
1248
|
+
return /* @__PURE__ */ jsx13(
|
|
1249
|
+
"svg",
|
|
1250
|
+
{
|
|
1251
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
1252
|
+
fill: "none",
|
|
1253
|
+
viewBox: "0 0 24 24",
|
|
1254
|
+
className,
|
|
1255
|
+
...props,
|
|
1256
|
+
children: /* @__PURE__ */ jsx13(
|
|
1257
|
+
"path",
|
|
1258
|
+
{
|
|
1259
|
+
stroke: "currentColor",
|
|
1260
|
+
strokeLinecap: "round",
|
|
1261
|
+
strokeLinejoin: "round",
|
|
1262
|
+
d: "m18 18-6-6m0 0L6 6m6 6 6-6m-6 6-6 6"
|
|
1263
|
+
}
|
|
1264
|
+
)
|
|
1265
|
+
}
|
|
1266
|
+
);
|
|
1267
|
+
}
|
|
1268
|
+
export {
|
|
1269
|
+
Button,
|
|
1270
|
+
Card,
|
|
1271
|
+
CardAction,
|
|
1272
|
+
CardContent,
|
|
1273
|
+
CardDescription,
|
|
1274
|
+
CardFooter,
|
|
1275
|
+
CardHeader,
|
|
1276
|
+
CardTitle,
|
|
1277
|
+
Check,
|
|
1278
|
+
Checkbox,
|
|
1279
|
+
CloseX,
|
|
1280
|
+
Input,
|
|
1281
|
+
Minus,
|
|
1282
|
+
MoneyInput,
|
|
1283
|
+
NumberInput,
|
|
1284
|
+
PasswordInput,
|
|
1285
|
+
RadioItem as Radio,
|
|
1286
|
+
RadioGroup,
|
|
1287
|
+
RadioItem,
|
|
1288
|
+
Switch,
|
|
1289
|
+
cn,
|
|
1290
|
+
inputTypes,
|
|
1291
|
+
useFormattedNumericInput,
|
|
1292
|
+
useRadio,
|
|
1293
|
+
useRadioGroup
|
|
1294
|
+
};
|
|
1295
|
+
//# sourceMappingURL=index.js.map
|