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/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