@sigep/react 1.0.0 → 1.1.0

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.mjs CHANGED
@@ -35,7 +35,773 @@ var Button = forwardRef(
35
35
  }
36
36
  );
37
37
  Button.displayName = "Button";
38
+
39
+ // src/components/Input/InputString.tsx
40
+ import { forwardRef as forwardRef3, useState } from "react";
41
+
42
+ // src/components/Input/InputWrapper.tsx
43
+ import { forwardRef as forwardRef2 } from "react";
44
+ import { tv as tv2 } from "tailwind-variants";
45
+ import { jsx as jsx2, jsxs } from "react/jsx-runtime";
46
+ var wrapper = tv2({
47
+ base: "flex w-full flex-col gap-1"
48
+ });
49
+ var labelStyle = tv2({
50
+ base: "text-xs text-gray-700 flex items-start gap-0.5"
51
+ });
52
+ var containerStyle = tv2({
53
+ base: "flex items-center w-full rounded-md border bg-white transition-colors",
54
+ variants: {
55
+ size: {
56
+ sm: "h-8 text-sm",
57
+ md: "h-9 text-sm",
58
+ lg: "h-10 text-base"
59
+ },
60
+ error: {
61
+ true: "border-red-500 focus-within:border-red-500 focus-within:ring-1 focus-within:ring-red-500",
62
+ false: "border-gray-300 hover:border-gray-400 focus-within:border-blue-500 focus-within:ring-1 focus-within:ring-blue-500"
63
+ },
64
+ disabled: {
65
+ true: "opacity-50 cursor-not-allowed bg-gray-50"
66
+ }
67
+ },
68
+ defaultVariants: {
69
+ size: "md",
70
+ error: false
71
+ }
72
+ });
73
+ var errorStyle = tv2({
74
+ base: "text-xs text-red-500 mt-0.5"
75
+ });
76
+ var InputWrapper = forwardRef2(
77
+ ({ label, error, errorMessage, required, disabled, size, children, className, classContainer, htmlFor }, ref) => {
78
+ return /* @__PURE__ */ jsxs("div", { ref, className: wrapper({ className }), children: [
79
+ label && /* @__PURE__ */ jsxs("label", { htmlFor, className: labelStyle(), children: [
80
+ /* @__PURE__ */ jsx2("span", { children: label }),
81
+ required && /* @__PURE__ */ jsx2("span", { className: "text-red-500 text-[10px] leading-none mt-0.5", children: "*" })
82
+ ] }),
83
+ /* @__PURE__ */ jsx2("div", { className: containerStyle({ size, error: !!error, disabled: !!disabled, className: classContainer }), children }),
84
+ error && errorMessage && /* @__PURE__ */ jsx2("span", { className: errorStyle(), children: errorMessage })
85
+ ] });
86
+ }
87
+ );
88
+ InputWrapper.displayName = "InputWrapper";
89
+
90
+ // src/components/Input/InputString.tsx
91
+ import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
92
+ var InputString = forwardRef3(
93
+ ({
94
+ label,
95
+ error,
96
+ errorMessage,
97
+ required,
98
+ size,
99
+ showClearButton = true,
100
+ leftIcon,
101
+ rightIcon,
102
+ classContainer,
103
+ classInput,
104
+ value,
105
+ onChange,
106
+ disabled,
107
+ name,
108
+ ...props
109
+ }, ref) => {
110
+ const [hovered, setHovered] = useState(false);
111
+ return /* @__PURE__ */ jsx3(
112
+ "div",
113
+ {
114
+ onMouseEnter: () => setHovered(true),
115
+ onMouseLeave: () => setHovered(false),
116
+ className: "w-full",
117
+ children: /* @__PURE__ */ jsxs2(
118
+ InputWrapper,
119
+ {
120
+ label,
121
+ error,
122
+ errorMessage,
123
+ required,
124
+ disabled,
125
+ size,
126
+ classContainer,
127
+ htmlFor: name,
128
+ children: [
129
+ leftIcon && /* @__PURE__ */ jsx3("span", { className: "pl-2.5 text-gray-400", children: leftIcon }),
130
+ /* @__PURE__ */ jsx3(
131
+ "input",
132
+ {
133
+ ref,
134
+ id: name,
135
+ name,
136
+ type: "text",
137
+ value: value ?? "",
138
+ onChange: (e) => onChange?.(e.target.value),
139
+ disabled,
140
+ "aria-invalid": !!error,
141
+ className: `flex-1 min-w-0 h-full bg-transparent px-2.5 outline-none text-gray-900 placeholder:text-gray-400 disabled:cursor-not-allowed ${classInput ?? ""}`,
142
+ ...props
143
+ }
144
+ ),
145
+ showClearButton && hovered && value && !disabled && !required && /* @__PURE__ */ jsx3(
146
+ "button",
147
+ {
148
+ type: "button",
149
+ tabIndex: -1,
150
+ "aria-label": "Limpar campo",
151
+ className: "px-2 text-gray-400 hover:text-gray-600",
152
+ onMouseDown: (e) => e.preventDefault(),
153
+ onClick: () => onChange?.(""),
154
+ children: /* @__PURE__ */ jsxs2(
155
+ "svg",
156
+ {
157
+ width: "14",
158
+ height: "14",
159
+ viewBox: "0 0 24 24",
160
+ fill: "none",
161
+ stroke: "currentColor",
162
+ strokeWidth: "2",
163
+ strokeLinecap: "round",
164
+ strokeLinejoin: "round",
165
+ children: [
166
+ /* @__PURE__ */ jsx3("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
167
+ /* @__PURE__ */ jsx3("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
168
+ ]
169
+ }
170
+ )
171
+ }
172
+ ),
173
+ rightIcon && /* @__PURE__ */ jsx3("span", { className: "pr-2.5 text-gray-400", children: rightIcon })
174
+ ]
175
+ }
176
+ )
177
+ }
178
+ );
179
+ }
180
+ );
181
+ InputString.displayName = "InputString";
182
+
183
+ // src/components/Input/InputEmail.tsx
184
+ import { forwardRef as forwardRef4 } from "react";
185
+ import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
186
+ var InputEmail = forwardRef4(
187
+ ({ label, error, errorMessage, required, size, leftIcon, rightIcon, classContainer, classInput, value, onChange, disabled, name, ...props }, ref) => {
188
+ return /* @__PURE__ */ jsxs3(
189
+ InputWrapper,
190
+ {
191
+ label,
192
+ error,
193
+ errorMessage,
194
+ required,
195
+ disabled,
196
+ size,
197
+ classContainer,
198
+ htmlFor: name,
199
+ children: [
200
+ leftIcon && /* @__PURE__ */ jsx4("span", { className: "pl-2.5 text-gray-400", children: leftIcon }),
201
+ /* @__PURE__ */ jsx4(
202
+ "input",
203
+ {
204
+ ref,
205
+ id: name,
206
+ name,
207
+ type: "email",
208
+ autoComplete: "email",
209
+ value: value ?? "",
210
+ onChange: (e) => onChange?.(e.target.value),
211
+ disabled,
212
+ "aria-invalid": !!error,
213
+ className: `flex-1 min-w-0 h-full bg-transparent px-2.5 outline-none text-gray-900 placeholder:text-gray-400 disabled:cursor-not-allowed ${classInput ?? ""}`,
214
+ ...props
215
+ }
216
+ ),
217
+ rightIcon && /* @__PURE__ */ jsx4("span", { className: "pr-2.5 text-gray-400", children: rightIcon })
218
+ ]
219
+ }
220
+ );
221
+ }
222
+ );
223
+ InputEmail.displayName = "InputEmail";
224
+
225
+ // src/components/Input/InputPassword.tsx
226
+ import { forwardRef as forwardRef5, useState as useState2 } from "react";
227
+ import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
228
+ var EyeIcon = () => /* @__PURE__ */ jsxs4("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
229
+ /* @__PURE__ */ jsx5("path", { d: "M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z" }),
230
+ /* @__PURE__ */ jsx5("circle", { cx: "12", cy: "12", r: "3" })
231
+ ] });
232
+ var EyeOffIcon = () => /* @__PURE__ */ jsxs4("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
233
+ /* @__PURE__ */ jsx5("path", { d: "M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24" }),
234
+ /* @__PURE__ */ jsx5("line", { x1: "1", y1: "1", x2: "23", y2: "23" })
235
+ ] });
236
+ var InputPassword = forwardRef5(
237
+ ({ label, error, errorMessage, required, size, classContainer, classInput, value, onChange, disabled, name, ...props }, ref) => {
238
+ const [visible, setVisible] = useState2(false);
239
+ return /* @__PURE__ */ jsxs4(
240
+ InputWrapper,
241
+ {
242
+ label,
243
+ error,
244
+ errorMessage,
245
+ required,
246
+ disabled,
247
+ size,
248
+ classContainer,
249
+ htmlFor: name,
250
+ children: [
251
+ /* @__PURE__ */ jsx5(
252
+ "input",
253
+ {
254
+ ref,
255
+ id: name,
256
+ name,
257
+ type: visible ? "text" : "password",
258
+ autoComplete: "current-password",
259
+ value: value ?? "",
260
+ onChange: (e) => onChange?.(e.target.value),
261
+ disabled,
262
+ "aria-invalid": !!error,
263
+ className: `flex-1 min-w-0 h-full bg-transparent px-2.5 outline-none text-gray-900 placeholder:text-gray-400 disabled:cursor-not-allowed ${classInput ?? ""}`,
264
+ ...props
265
+ }
266
+ ),
267
+ /* @__PURE__ */ jsx5(
268
+ "button",
269
+ {
270
+ type: "button",
271
+ tabIndex: -1,
272
+ "aria-label": visible ? "Ocultar senha" : "Mostrar senha",
273
+ className: "px-2.5 text-gray-400 hover:text-gray-600",
274
+ onClick: () => setVisible(!visible),
275
+ children: visible ? /* @__PURE__ */ jsx5(EyeOffIcon, {}) : /* @__PURE__ */ jsx5(EyeIcon, {})
276
+ }
277
+ )
278
+ ]
279
+ }
280
+ );
281
+ }
282
+ );
283
+ InputPassword.displayName = "InputPassword";
284
+
285
+ // src/components/Input/InputNumber.tsx
286
+ import { forwardRef as forwardRef6 } from "react";
287
+ import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
288
+ var allowedKeys = ["Backspace", "Delete", "Tab", "ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown", "Home", "End"];
289
+ var InputNumber = forwardRef6(
290
+ ({ label, error, errorMessage, required, size, leftIcon, rightIcon, classContainer, classInput, value, onChange, disabled, name, min = 0, max, ...props }, ref) => {
291
+ function handleKeyDown(e) {
292
+ if (e.ctrlKey || e.metaKey) return;
293
+ if (allowedKeys.includes(e.key)) return;
294
+ if (!/^[0-9]$/.test(e.key)) {
295
+ e.preventDefault();
296
+ }
297
+ }
298
+ function handleChange(raw) {
299
+ if (raw === "") {
300
+ onChange?.(void 0);
301
+ return;
302
+ }
303
+ const num = Number(raw);
304
+ if (isNaN(num)) return;
305
+ if (min !== void 0 && num < min) return;
306
+ if (max !== void 0 && num > max) return;
307
+ onChange?.(num);
308
+ }
309
+ return /* @__PURE__ */ jsxs5(
310
+ InputWrapper,
311
+ {
312
+ label,
313
+ error,
314
+ errorMessage,
315
+ required,
316
+ disabled,
317
+ size,
318
+ classContainer,
319
+ htmlFor: name,
320
+ children: [
321
+ leftIcon && /* @__PURE__ */ jsx6("span", { className: "pl-2.5 text-gray-400", children: leftIcon }),
322
+ /* @__PURE__ */ jsx6(
323
+ "input",
324
+ {
325
+ ref,
326
+ id: name,
327
+ name,
328
+ type: "text",
329
+ inputMode: "numeric",
330
+ value: value ?? "",
331
+ onChange: (e) => handleChange(e.target.value),
332
+ onKeyDown: handleKeyDown,
333
+ disabled,
334
+ "aria-invalid": !!error,
335
+ className: `flex-1 min-w-0 h-full bg-transparent px-2.5 outline-none text-gray-900 placeholder:text-gray-400 disabled:cursor-not-allowed ${classInput ?? ""}`,
336
+ ...props
337
+ }
338
+ ),
339
+ rightIcon && /* @__PURE__ */ jsx6("span", { className: "pr-2.5 text-gray-400", children: rightIcon })
340
+ ]
341
+ }
342
+ );
343
+ }
344
+ );
345
+ InputNumber.displayName = "InputNumber";
346
+
347
+ // src/components/Input/InputCPF.tsx
348
+ import { forwardRef as forwardRef7 } from "react";
349
+
350
+ // src/components/Input/masks.ts
351
+ function maskCPF(value) {
352
+ const digits = value.replace(/\D/g, "").slice(0, 11);
353
+ return digits.replace(/(\d{3})(\d)/, "$1.$2").replace(/(\d{3})(\d)/, "$1.$2").replace(/(\d{3})(\d{1,2})$/, "$1-$2");
354
+ }
355
+ function maskCNPJ(value) {
356
+ const digits = value.replace(/\D/g, "").slice(0, 14);
357
+ return digits.replace(/(\d{2})(\d)/, "$1.$2").replace(/(\d{3})(\d)/, "$1.$2").replace(/(\d{3})(\d)/, "$1/$2").replace(/(\d{4})(\d{1,2})$/, "$1-$2");
358
+ }
359
+ function maskPhone(value) {
360
+ const digits = value.replace(/\D/g, "").slice(0, 11);
361
+ if (digits.length <= 10) {
362
+ return digits.replace(/(\d{2})(\d)/, "($1) $2").replace(/(\d{4})(\d)/, "$1-$2");
363
+ }
364
+ return digits.replace(/(\d{2})(\d)/, "($1) $2").replace(/(\d{5})(\d)/, "$1-$2");
365
+ }
366
+ function maskCEP(value) {
367
+ const digits = value.replace(/\D/g, "").slice(0, 8);
368
+ return digits.replace(/(\d{5})(\d)/, "$1-$2");
369
+ }
370
+ function unmask(value) {
371
+ return value.replace(/\D/g, "");
372
+ }
373
+ function maskCurrency(value, prefix = "R$ ", decimalScale = 2) {
374
+ return prefix + value.toFixed(decimalScale).replace(".", ",").replace(/\B(?=(\d{3})+(?!\d))/g, ".");
375
+ }
376
+ function unmaskCurrency(value) {
377
+ const cleaned = value.replace(/[^\d,-]/g, "").replace(",", ".");
378
+ return parseFloat(cleaned) || 0;
379
+ }
380
+
381
+ // src/components/Input/InputCPF.tsx
382
+ import { jsx as jsx7 } from "react/jsx-runtime";
383
+ var InputCPF = forwardRef7(
384
+ ({ label, error, errorMessage, required, size, classContainer, classInput, value, onChange, disabled, name, ...props }, ref) => {
385
+ function handleChange(raw) {
386
+ const digits = unmask(raw);
387
+ onChange?.(digits);
388
+ }
389
+ return /* @__PURE__ */ jsx7(
390
+ InputWrapper,
391
+ {
392
+ label,
393
+ error,
394
+ errorMessage,
395
+ required,
396
+ disabled,
397
+ size,
398
+ classContainer,
399
+ htmlFor: name,
400
+ children: /* @__PURE__ */ jsx7(
401
+ "input",
402
+ {
403
+ ref,
404
+ id: name,
405
+ name,
406
+ type: "text",
407
+ inputMode: "numeric",
408
+ maxLength: 14,
409
+ placeholder: "000.000.000-00",
410
+ value: value ? maskCPF(value) : "",
411
+ onChange: (e) => handleChange(e.target.value),
412
+ disabled,
413
+ "aria-invalid": !!error,
414
+ className: `flex-1 min-w-0 h-full bg-transparent px-2.5 outline-none text-gray-900 placeholder:text-gray-400 disabled:cursor-not-allowed ${classInput ?? ""}`,
415
+ ...props
416
+ }
417
+ )
418
+ }
419
+ );
420
+ }
421
+ );
422
+ InputCPF.displayName = "InputCPF";
423
+
424
+ // src/components/Input/InputCNPJ.tsx
425
+ import { forwardRef as forwardRef8 } from "react";
426
+ import { jsx as jsx8 } from "react/jsx-runtime";
427
+ var InputCNPJ = forwardRef8(
428
+ ({ label, error, errorMessage, required, size, classContainer, classInput, value, onChange, disabled, name, ...props }, ref) => {
429
+ function handleChange(raw) {
430
+ const digits = unmask(raw);
431
+ onChange?.(digits);
432
+ }
433
+ return /* @__PURE__ */ jsx8(
434
+ InputWrapper,
435
+ {
436
+ label,
437
+ error,
438
+ errorMessage,
439
+ required,
440
+ disabled,
441
+ size,
442
+ classContainer,
443
+ htmlFor: name,
444
+ children: /* @__PURE__ */ jsx8(
445
+ "input",
446
+ {
447
+ ref,
448
+ id: name,
449
+ name,
450
+ type: "text",
451
+ inputMode: "numeric",
452
+ maxLength: 18,
453
+ placeholder: "00.000.000/0000-00",
454
+ value: value ? maskCNPJ(value) : "",
455
+ onChange: (e) => handleChange(e.target.value),
456
+ disabled,
457
+ "aria-invalid": !!error,
458
+ className: `flex-1 min-w-0 h-full bg-transparent px-2.5 outline-none text-gray-900 placeholder:text-gray-400 disabled:cursor-not-allowed ${classInput ?? ""}`,
459
+ ...props
460
+ }
461
+ )
462
+ }
463
+ );
464
+ }
465
+ );
466
+ InputCNPJ.displayName = "InputCNPJ";
467
+
468
+ // src/components/Input/InputPhone.tsx
469
+ import { forwardRef as forwardRef9 } from "react";
470
+ import { jsx as jsx9 } from "react/jsx-runtime";
471
+ var InputPhone = forwardRef9(
472
+ ({ label, error, errorMessage, required, size, classContainer, classInput, value, onChange, disabled, name, ...props }, ref) => {
473
+ function handleChange(raw) {
474
+ const digits = unmask(raw);
475
+ onChange?.(digits);
476
+ }
477
+ return /* @__PURE__ */ jsx9(
478
+ InputWrapper,
479
+ {
480
+ label,
481
+ error,
482
+ errorMessage,
483
+ required,
484
+ disabled,
485
+ size,
486
+ classContainer,
487
+ htmlFor: name,
488
+ children: /* @__PURE__ */ jsx9(
489
+ "input",
490
+ {
491
+ ref,
492
+ id: name,
493
+ name,
494
+ type: "tel",
495
+ inputMode: "numeric",
496
+ maxLength: 15,
497
+ placeholder: "(00) 00000-0000",
498
+ value: value ? maskPhone(value) : "",
499
+ onChange: (e) => handleChange(e.target.value),
500
+ disabled,
501
+ "aria-invalid": !!error,
502
+ className: `flex-1 min-w-0 h-full bg-transparent px-2.5 outline-none text-gray-900 placeholder:text-gray-400 disabled:cursor-not-allowed ${classInput ?? ""}`,
503
+ ...props
504
+ }
505
+ )
506
+ }
507
+ );
508
+ }
509
+ );
510
+ InputPhone.displayName = "InputPhone";
511
+
512
+ // src/components/Input/InputCurrency.tsx
513
+ import { forwardRef as forwardRef10 } from "react";
514
+ import { jsx as jsx10 } from "react/jsx-runtime";
515
+ function formatCurrency(value, prefix, decimalScale) {
516
+ const fixed = Math.abs(value).toFixed(decimalScale);
517
+ const [intPart, decPart] = fixed.split(".");
518
+ const formatted = intPart.replace(/\B(?=(\d{3})+(?!\d))/g, ".");
519
+ const sign = value < 0 ? "-" : "";
520
+ return `${sign}${prefix}${formatted},${decPart}`;
521
+ }
522
+ var InputCurrency = forwardRef10(
523
+ ({ label, error, errorMessage, required, size, classContainer, classInput, value, onChange, disabled, name, prefix = "R$ ", decimalScale = 2, allowNegative = false, ...props }, ref) => {
524
+ function handleChange(e) {
525
+ const raw = e.target.value;
526
+ const num = unmaskCurrency(raw);
527
+ if (!allowNegative && num < 0) return;
528
+ onChange?.(isNaN(num) ? void 0 : num);
529
+ }
530
+ const displayValue = value !== void 0 && value !== null ? formatCurrency(value, prefix, decimalScale) : "";
531
+ return /* @__PURE__ */ jsx10(
532
+ InputWrapper,
533
+ {
534
+ label,
535
+ error,
536
+ errorMessage,
537
+ required,
538
+ disabled,
539
+ size,
540
+ classContainer,
541
+ htmlFor: name,
542
+ children: /* @__PURE__ */ jsx10(
543
+ "input",
544
+ {
545
+ ref,
546
+ id: name,
547
+ name,
548
+ type: "text",
549
+ inputMode: "decimal",
550
+ value: displayValue,
551
+ onChange: handleChange,
552
+ disabled,
553
+ "aria-invalid": !!error,
554
+ placeholder: `${prefix}0,${"0".repeat(decimalScale)}`,
555
+ className: `flex-1 min-w-0 h-full bg-transparent px-2.5 outline-none text-gray-900 placeholder:text-gray-400 disabled:cursor-not-allowed ${classInput ?? ""}`,
556
+ ...props
557
+ }
558
+ )
559
+ }
560
+ );
561
+ }
562
+ );
563
+ InputCurrency.displayName = "InputCurrency";
564
+
565
+ // src/components/Input/InputCep.tsx
566
+ import { forwardRef as forwardRef11 } from "react";
567
+ import { jsx as jsx11 } from "react/jsx-runtime";
568
+ var InputCep = forwardRef11(
569
+ ({ label, error, errorMessage, required, size, classContainer, classInput, value, onChange, disabled, name, ...props }, ref) => {
570
+ function handleChange(raw) {
571
+ const digits = unmask(raw);
572
+ onChange?.(digits);
573
+ }
574
+ return /* @__PURE__ */ jsx11(
575
+ InputWrapper,
576
+ {
577
+ label,
578
+ error,
579
+ errorMessage,
580
+ required,
581
+ disabled,
582
+ size,
583
+ classContainer,
584
+ htmlFor: name,
585
+ children: /* @__PURE__ */ jsx11(
586
+ "input",
587
+ {
588
+ ref,
589
+ id: name,
590
+ name,
591
+ type: "text",
592
+ inputMode: "numeric",
593
+ autoComplete: "postal-code",
594
+ maxLength: 9,
595
+ placeholder: "00000-000",
596
+ value: value ? maskCEP(value) : "",
597
+ onChange: (e) => handleChange(e.target.value),
598
+ disabled,
599
+ "aria-invalid": !!error,
600
+ className: `flex-1 min-w-0 h-full bg-transparent px-2.5 outline-none text-gray-900 placeholder:text-gray-400 disabled:cursor-not-allowed ${classInput ?? ""}`,
601
+ ...props
602
+ }
603
+ )
604
+ }
605
+ );
606
+ }
607
+ );
608
+ InputCep.displayName = "InputCep";
609
+
610
+ // src/components/Input/InputCheckbox.tsx
611
+ import { forwardRef as forwardRef12 } from "react";
612
+ import { tv as tv3 } from "tailwind-variants";
613
+ import { jsx as jsx12, jsxs as jsxs6 } from "react/jsx-runtime";
614
+ var checkboxContainer = tv3({
615
+ base: "inline-flex items-center justify-center w-[18px] h-[18px] rounded border cursor-pointer transition-colors",
616
+ variants: {
617
+ checked: {
618
+ true: "bg-blue-600 border-blue-600",
619
+ false: "bg-white border-gray-300 hover:border-blue-500 hover:bg-blue-50"
620
+ },
621
+ disabled: {
622
+ true: "opacity-50 cursor-not-allowed"
623
+ },
624
+ error: {
625
+ true: "border-red-500"
626
+ }
627
+ },
628
+ defaultVariants: {
629
+ checked: false
630
+ }
631
+ });
632
+ var CheckIcon = () => /* @__PURE__ */ jsx12("svg", { width: "10", height: "10", viewBox: "0 0 24 24", fill: "none", stroke: "white", strokeWidth: "4", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx12("polyline", { points: "20 6 9 17 4 12" }) });
633
+ var IndeterminateIcon = () => /* @__PURE__ */ jsx12("div", { className: "w-2 h-2 rounded-sm bg-gray-300" });
634
+ var InputCheckbox = forwardRef12(
635
+ ({ label, checked = false, indeterminate = false, onChange, disabled, error, labelPosition = "right", className, name, required }, ref) => {
636
+ function handleClick() {
637
+ if (disabled) return;
638
+ onChange?.(!checked);
639
+ }
640
+ const box = /* @__PURE__ */ jsxs6(
641
+ "button",
642
+ {
643
+ ref,
644
+ type: "button",
645
+ role: "checkbox",
646
+ id: name,
647
+ "aria-checked": indeterminate ? "mixed" : checked,
648
+ "aria-required": required,
649
+ className: checkboxContainer({ checked: checked || indeterminate, disabled: !!disabled, error: !!error }),
650
+ onClick: handleClick,
651
+ disabled,
652
+ children: [
653
+ checked && !indeterminate && /* @__PURE__ */ jsx12(CheckIcon, {}),
654
+ indeterminate && /* @__PURE__ */ jsx12(IndeterminateIcon, {})
655
+ ]
656
+ }
657
+ );
658
+ if (!label) return /* @__PURE__ */ jsx12("div", { className, children: box });
659
+ return /* @__PURE__ */ jsxs6("div", { className: `flex items-center gap-2 ${className ?? ""}`, children: [
660
+ labelPosition === "left" && /* @__PURE__ */ jsx12("label", { htmlFor: name, className: "text-sm text-gray-700 cursor-pointer select-none", children: label }),
661
+ box,
662
+ labelPosition === "right" && /* @__PURE__ */ jsx12("label", { htmlFor: name, className: "text-sm text-gray-700 cursor-pointer select-none", children: label }),
663
+ required && /* @__PURE__ */ jsx12("span", { className: "text-red-500 text-[10px]", children: "*" })
664
+ ] });
665
+ }
666
+ );
667
+ InputCheckbox.displayName = "InputCheckbox";
668
+
669
+ // src/components/Input/InputRadio.tsx
670
+ import { forwardRef as forwardRef13 } from "react";
671
+ import { tv as tv4 } from "tailwind-variants";
672
+ import { jsx as jsx13, jsxs as jsxs7 } from "react/jsx-runtime";
673
+ var radioButton = tv4({
674
+ base: "inline-flex items-center justify-center w-[18px] h-[18px] rounded-full border cursor-pointer transition-colors",
675
+ variants: {
676
+ selected: {
677
+ true: "border-blue-600",
678
+ false: "border-gray-300 hover:border-blue-500 hover:bg-blue-50"
679
+ },
680
+ disabled: {
681
+ true: "opacity-50 cursor-not-allowed"
682
+ },
683
+ error: {
684
+ true: "border-red-500"
685
+ }
686
+ },
687
+ defaultVariants: {
688
+ selected: false
689
+ }
690
+ });
691
+ var InputRadio = forwardRef13(
692
+ ({ label, options, value, onChange, disabled, error, required, name, className, direction = "horizontal" }, ref) => {
693
+ return /* @__PURE__ */ jsxs7("div", { ref, className: `flex w-full flex-col gap-1 ${className ?? ""}`, children: [
694
+ label && /* @__PURE__ */ jsxs7("span", { className: "text-xs text-gray-700 flex items-start gap-0.5", children: [
695
+ /* @__PURE__ */ jsx13("span", { children: label }),
696
+ required && /* @__PURE__ */ jsx13("span", { className: "text-red-500 text-[10px] leading-none mt-0.5", children: "*" })
697
+ ] }),
698
+ /* @__PURE__ */ jsx13(
699
+ "div",
700
+ {
701
+ role: "radiogroup",
702
+ "aria-label": label,
703
+ className: `flex gap-3 ${direction === "vertical" ? "flex-col" : "items-center"}`,
704
+ children: options.map((option) => {
705
+ const isSelected = value === option.value;
706
+ const isDisabled = disabled || option.disabled;
707
+ return /* @__PURE__ */ jsxs7(
708
+ "label",
709
+ {
710
+ className: `flex items-center gap-2 cursor-pointer select-none ${isDisabled ? "opacity-50 cursor-not-allowed" : ""}`,
711
+ children: [
712
+ /* @__PURE__ */ jsx13(
713
+ "button",
714
+ {
715
+ type: "button",
716
+ role: "radio",
717
+ "aria-checked": isSelected,
718
+ className: radioButton({ selected: isSelected, disabled: !!isDisabled, error: !!error }),
719
+ onClick: () => !isDisabled && onChange?.(option.value),
720
+ disabled: isDisabled,
721
+ children: isSelected && /* @__PURE__ */ jsx13("div", { className: "w-[10px] h-[10px] rounded-full bg-blue-600" })
722
+ }
723
+ ),
724
+ /* @__PURE__ */ jsx13("span", { className: "text-sm text-gray-700", children: option.label })
725
+ ]
726
+ },
727
+ String(option.value)
728
+ );
729
+ })
730
+ }
731
+ ),
732
+ error && /* @__PURE__ */ jsx13("span", { className: "text-xs text-red-500 mt-0.5", children: "Selecione uma op\xE7\xE3o" })
733
+ ] });
734
+ }
735
+ );
736
+ InputRadio.displayName = "InputRadio";
737
+
738
+ // src/components/Input/Textarea.tsx
739
+ import { forwardRef as forwardRef14 } from "react";
740
+ import { tv as tv5 } from "tailwind-variants";
741
+ import { jsx as jsx14, jsxs as jsxs8 } from "react/jsx-runtime";
742
+ var textareaStyle = tv5({
743
+ base: "w-full rounded-md border bg-white px-2.5 py-2 text-sm text-gray-900 outline-none placeholder:text-gray-400 resize-vertical transition-colors",
744
+ variants: {
745
+ error: {
746
+ true: "border-red-500 focus:border-red-500 focus:ring-1 focus:ring-red-500",
747
+ false: "border-gray-300 hover:border-gray-400 focus:border-blue-500 focus:ring-1 focus:ring-blue-500"
748
+ },
749
+ disabled: {
750
+ true: "opacity-50 cursor-not-allowed bg-gray-50"
751
+ }
752
+ },
753
+ defaultVariants: {
754
+ error: false
755
+ }
756
+ });
757
+ var Textarea = forwardRef14(
758
+ ({ label, error, errorMessage, required, size, classInput, value, onChange, disabled, name, rows = 4, ...props }, ref) => {
759
+ return /* @__PURE__ */ jsxs8("div", { className: "flex w-full flex-col gap-1", children: [
760
+ label && /* @__PURE__ */ jsxs8("label", { htmlFor: name, className: "text-xs text-gray-700 flex items-start gap-0.5", children: [
761
+ /* @__PURE__ */ jsx14("span", { children: label }),
762
+ required && /* @__PURE__ */ jsx14("span", { className: "text-red-500 text-[10px] leading-none mt-0.5", children: "*" })
763
+ ] }),
764
+ /* @__PURE__ */ jsx14(
765
+ "textarea",
766
+ {
767
+ ref,
768
+ id: name,
769
+ name,
770
+ rows,
771
+ value: value ?? "",
772
+ onChange: (e) => onChange?.(e.target.value),
773
+ disabled,
774
+ "aria-invalid": !!error,
775
+ className: textareaStyle({ error: !!error, disabled: !!disabled, className: classInput }),
776
+ ...props
777
+ }
778
+ ),
779
+ error && errorMessage && /* @__PURE__ */ jsx14("span", { className: "text-xs text-red-500 mt-0.5", children: errorMessage })
780
+ ] });
781
+ }
782
+ );
783
+ Textarea.displayName = "Textarea";
38
784
  export {
39
785
  Button,
40
- button
786
+ InputCNPJ,
787
+ InputCPF,
788
+ InputCep,
789
+ InputCheckbox,
790
+ InputCurrency,
791
+ InputEmail,
792
+ InputNumber,
793
+ InputPassword,
794
+ InputPhone,
795
+ InputRadio,
796
+ InputString,
797
+ InputWrapper,
798
+ Textarea,
799
+ button,
800
+ maskCEP,
801
+ maskCNPJ,
802
+ maskCPF,
803
+ maskCurrency,
804
+ maskPhone,
805
+ unmask,
806
+ unmaskCurrency
41
807
  };