@conatel-sa/react-ui 0.2.3 → 0.2.5

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.
@@ -0,0 +1,626 @@
1
+ "use strict";
2
+ var ReactLibraryForms = (() => {
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+
21
+ // src/forms-entry.ts
22
+ var forms_entry_exports = {};
23
+ __export(forms_entry_exports, {
24
+ EmailInput: () => EmailInput,
25
+ MultiSelectDropdown: () => MultiSelectDropdown,
26
+ PASSWORD_HINT: () => PASSWORD_HINT,
27
+ PASSWORD_RULES: () => PASSWORD_RULES,
28
+ PasswordInput: () => PasswordInput,
29
+ SingleSelectDropdown: () => SingleSelectDropdown,
30
+ getPasswordValid: () => getPasswordValid,
31
+ isPasswordValid: () => isPasswordValid,
32
+ validatePassword: () => validatePassword
33
+ });
34
+
35
+ // tools/react-shim.mjs
36
+ var R = typeof window !== "undefined" && window.React ? window.React : {};
37
+ var react_shim_default = R;
38
+ var {
39
+ useContext,
40
+ useEffect,
41
+ useLayoutEffect,
42
+ useMemo,
43
+ useState,
44
+ useRef,
45
+ useCallback,
46
+ useId,
47
+ createContext,
48
+ Fragment
49
+ } = R;
50
+
51
+ // src/components/forms/passwordValidation.ts
52
+ var SPECIAL_REGEX = /[!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?~`]/;
53
+ function validatePassword(password) {
54
+ return {
55
+ minLength: password.length >= 8,
56
+ hasLower: /[a-z]/.test(password),
57
+ hasUpper: /[A-Z]/.test(password),
58
+ hasDigit: /[0-9]/.test(password),
59
+ hasSpecial: SPECIAL_REGEX.test(password)
60
+ };
61
+ }
62
+ function isPasswordValid(checks) {
63
+ return checks.minLength && checks.hasLower && checks.hasUpper && checks.hasDigit && checks.hasSpecial;
64
+ }
65
+ function getPasswordValid(password) {
66
+ return isPasswordValid(validatePassword(password));
67
+ }
68
+ var PASSWORD_RULES = [
69
+ { key: "minLength", label: "M\xEDnimo 8 caracteres", ok: (c) => c.minLength },
70
+ { key: "hasLower", label: "Al menos una min\xFAscula", ok: (c) => c.hasLower },
71
+ { key: "hasUpper", label: "Al menos una may\xFAscula", ok: (c) => c.hasUpper },
72
+ { key: "hasDigit", label: "Al menos un n\xFAmero", ok: (c) => c.hasDigit },
73
+ { key: "hasSpecial", label: "Al menos un car\xE1cter especial (!@#$%^&* etc.)", ok: (c) => c.hasSpecial }
74
+ ];
75
+ var PASSWORD_HINT = "M\xEDn. 8 caracteres, may\xFAscula, min\xFAscula, n\xFAmero y un car\xE1cter especial.";
76
+
77
+ // tools/jsx-runtime-shim.mjs
78
+ function jsx(type, props, key) {
79
+ const p = key != null ? { ...props, key } : props;
80
+ return react_shim_default.createElement(type, p);
81
+ }
82
+ function jsxs(type, props, key) {
83
+ return jsx(type, props, key);
84
+ }
85
+ var Fragment2 = react_shim_default.Fragment;
86
+
87
+ // src/components/forms/PasswordInput.tsx
88
+ function PasswordInput({
89
+ value,
90
+ onChange,
91
+ placeholder = "Contrase\xF1a",
92
+ label,
93
+ hint,
94
+ error,
95
+ disabled,
96
+ required,
97
+ ariaLabel,
98
+ showValidation = false,
99
+ id: idProp,
100
+ inputClassName = "form-input",
101
+ className = "form-group",
102
+ minLength = 8,
103
+ "data-testid": dataTestId,
104
+ leftIcon = "lock"
105
+ }) {
106
+ const [revealed, setRevealed] = useState(false);
107
+ const genId = useId();
108
+ const id = idProp ?? genId;
109
+ const checks = validatePassword(value);
110
+ const wrapClass = `${inputClassName} input-password-wrap`.trim();
111
+ return /* @__PURE__ */ jsxs("div", { className, children: [
112
+ label ? /* @__PURE__ */ jsxs("label", { className: "form-label-app", htmlFor: id, children: [
113
+ label,
114
+ required ? /* @__PURE__ */ jsxs("span", { className: "required-mark", "aria-hidden": true, children: [
115
+ " ",
116
+ "*"
117
+ ] }) : null
118
+ ] }) : null,
119
+ /* @__PURE__ */ jsxs(
120
+ "div",
121
+ {
122
+ className: wrapClass,
123
+ style: {
124
+ position: "relative",
125
+ display: "flex",
126
+ alignItems: "center",
127
+ padding: "0.75rem 2.5rem 0.75rem 3rem"
128
+ },
129
+ children: [
130
+ /* @__PURE__ */ jsx(
131
+ "span",
132
+ {
133
+ className: "material-symbols-outlined",
134
+ style: {
135
+ position: "absolute",
136
+ left: "1rem",
137
+ color: "var(--color-text-muted)",
138
+ fontSize: "1.25rem",
139
+ pointerEvents: "none"
140
+ },
141
+ "aria-hidden": true,
142
+ children: leftIcon
143
+ }
144
+ ),
145
+ /* @__PURE__ */ jsx(
146
+ "input",
147
+ {
148
+ type: revealed ? "text" : "password",
149
+ id,
150
+ "data-testid": dataTestId,
151
+ value,
152
+ disabled,
153
+ onChange: (e) => onChange(e.target.value),
154
+ placeholder,
155
+ title: PASSWORD_HINT,
156
+ minLength,
157
+ required,
158
+ "aria-label": ariaLabel ?? label ?? "Password",
159
+ style: {
160
+ border: "none",
161
+ background: "transparent",
162
+ flex: 1,
163
+ minWidth: 0,
164
+ padding: 0,
165
+ fontSize: "inherit",
166
+ outline: "none"
167
+ }
168
+ }
169
+ ),
170
+ /* @__PURE__ */ jsx(
171
+ "button",
172
+ {
173
+ type: "button",
174
+ onClick: () => setRevealed((v) => !v),
175
+ tabIndex: -1,
176
+ title: revealed ? "Ocultar contrase\xF1a" : "Mostrar contrase\xF1a",
177
+ disabled,
178
+ style: {
179
+ position: "absolute",
180
+ right: "0.5rem",
181
+ background: "none",
182
+ border: "none",
183
+ padding: "0.25rem",
184
+ cursor: disabled ? "not-allowed" : "pointer",
185
+ color: "var(--color-text-muted)"
186
+ },
187
+ children: /* @__PURE__ */ jsx("span", { className: "material-symbols-outlined", style: { fontSize: "1.25rem" }, children: revealed ? "visibility_off" : "visibility" })
188
+ }
189
+ )
190
+ ]
191
+ }
192
+ ),
193
+ showValidation ? /* @__PURE__ */ jsxs("p", { style: { marginTop: "0.5rem", fontSize: "0.75rem", color: "var(--color-text-muted)" }, children: [
194
+ "* ",
195
+ PASSWORD_HINT
196
+ ] }) : null,
197
+ showValidation && value.length > 0 ? /* @__PURE__ */ jsx(
198
+ "ul",
199
+ {
200
+ style: {
201
+ marginTop: "0.5rem",
202
+ paddingLeft: "1.25rem",
203
+ fontSize: "0.75rem",
204
+ color: "var(--color-text-muted)"
205
+ },
206
+ children: PASSWORD_RULES.map((rule) => /* @__PURE__ */ jsxs(
207
+ "li",
208
+ {
209
+ style: {
210
+ listStyle: "none",
211
+ marginLeft: "-1.25rem",
212
+ marginBottom: "0.25rem",
213
+ display: "flex",
214
+ alignItems: "center",
215
+ gap: "0.35rem"
216
+ },
217
+ children: [
218
+ /* @__PURE__ */ jsx(
219
+ "span",
220
+ {
221
+ style: {
222
+ color: rule.ok(checks) ? "var(--color-success)" : "var(--color-text-muted)",
223
+ fontWeight: rule.ok(checks) ? 600 : 400
224
+ },
225
+ children: rule.ok(checks) ? "\u2713" : "\u25CB"
226
+ }
227
+ ),
228
+ /* @__PURE__ */ jsx("span", { style: rule.ok(checks) ? { color: "var(--color-success)" } : void 0, children: rule.label })
229
+ ]
230
+ },
231
+ rule.key
232
+ ))
233
+ }
234
+ ) : null,
235
+ error ? /* @__PURE__ */ jsx("p", { role: "alert", style: { marginTop: "0.35rem", fontSize: "0.8125rem", color: "var(--color-error)" }, children: error }) : hint ? /* @__PURE__ */ jsx("p", { style: { marginTop: "0.35rem", fontSize: "0.8125rem", color: "var(--color-text-muted)" }, children: hint }) : null
236
+ ] });
237
+ }
238
+
239
+ // src/components/forms/MultiSelectDropdown.tsx
240
+ function MultiSelectDropdown({
241
+ label,
242
+ options,
243
+ value,
244
+ selected,
245
+ onChange,
246
+ placeholder = "Seleccionar\u2026",
247
+ emptyLabel,
248
+ disabled,
249
+ allowAllNone = true,
250
+ allLabel = "Todos",
251
+ noneLabel = "Ninguno",
252
+ style,
253
+ buttonClassName = "form-select",
254
+ className = "form-group"
255
+ }) {
256
+ const [open, setOpen] = useState(false);
257
+ const rootRef = useRef(null);
258
+ const selectedValues = value ?? selected ?? [];
259
+ const effectivePlaceholder = emptyLabel ?? placeholder;
260
+ const isAllSelected = options.length > 0 && selectedValues.length === options.length;
261
+ const isNoneSelected = selectedValues.length === 0;
262
+ useEffect(() => {
263
+ if (!open) return;
264
+ const onDown = (e) => {
265
+ const el = rootRef.current;
266
+ if (!el) return;
267
+ const target = e.target;
268
+ if (target && el.contains(target)) return;
269
+ setOpen(false);
270
+ };
271
+ document.addEventListener("mousedown", onDown);
272
+ return () => document.removeEventListener("mousedown", onDown);
273
+ }, [open]);
274
+ const toggleValue = (v) => {
275
+ if (disabled) return;
276
+ if (selectedValues.includes(v)) onChange(selectedValues.filter((x) => x !== v));
277
+ else onChange([...selectedValues, v]);
278
+ };
279
+ const buttonLabel = selectedValues.length === 0 ? effectivePlaceholder : selectedValues.map((v) => options.find((o) => o.value === v)?.label ?? v).join(", ");
280
+ return /* @__PURE__ */ jsxs("div", { ref: rootRef, className, style: { position: "relative", ...style ?? {} }, children: [
281
+ label ? /* @__PURE__ */ jsx("label", { className: "form-label-dropdown", children: label }) : null,
282
+ /* @__PURE__ */ jsxs(
283
+ "button",
284
+ {
285
+ type: "button",
286
+ className: buttonClassName,
287
+ onClick: () => {
288
+ if (disabled) return;
289
+ setOpen((o) => !o);
290
+ },
291
+ disabled,
292
+ style: {
293
+ width: "100%",
294
+ textAlign: "left",
295
+ overflow: "hidden",
296
+ textOverflow: "ellipsis",
297
+ whiteSpace: "nowrap",
298
+ display: "flex",
299
+ alignItems: "center",
300
+ justifyContent: "space-between",
301
+ gap: "0.5rem",
302
+ cursor: disabled ? "not-allowed" : "pointer",
303
+ opacity: disabled ? 0.6 : 1
304
+ },
305
+ "aria-haspopup": "listbox",
306
+ "aria-expanded": open,
307
+ children: [
308
+ /* @__PURE__ */ jsx(
309
+ "span",
310
+ {
311
+ style: {
312
+ overflow: "hidden",
313
+ textOverflow: "ellipsis",
314
+ whiteSpace: "nowrap",
315
+ color: selectedValues.length === 0 ? "var(--color-text-muted)" : "var(--color-text-primary)"
316
+ },
317
+ children: buttonLabel
318
+ }
319
+ ),
320
+ /* @__PURE__ */ jsx("span", { className: "material-symbols-outlined", style: { fontSize: "1rem", color: "var(--color-text-secondary)", flexShrink: 0 }, children: open ? "expand_less" : "expand_more" })
321
+ ]
322
+ }
323
+ ),
324
+ open && /* @__PURE__ */ jsxs(
325
+ "div",
326
+ {
327
+ className: "form-dropdown-panel",
328
+ style: {
329
+ position: "absolute",
330
+ top: "100%",
331
+ left: 0,
332
+ minWidth: "100%",
333
+ maxHeight: "220px",
334
+ overflowY: "auto",
335
+ border: "1px solid var(--color-border)",
336
+ borderRadius: "var(--radius-md)",
337
+ boxShadow: "0 4px 12px rgba(0,0,0,0.15)",
338
+ marginTop: "2px"
339
+ },
340
+ children: [
341
+ allowAllNone && options.length > 0 && /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: "0.35rem", padding: "0.35rem 0.6rem", borderBottom: "1px solid var(--color-border)", fontSize: "0.75rem" }, children: [
342
+ /* @__PURE__ */ jsxs(
343
+ "button",
344
+ {
345
+ type: "button",
346
+ onClick: () => onChange(options.map((o) => o.value)),
347
+ style: {
348
+ background: "none",
349
+ border: "none",
350
+ color: isAllSelected ? "var(--color-success)" : "var(--color-text-secondary)",
351
+ cursor: "pointer",
352
+ display: "inline-flex",
353
+ alignItems: "center",
354
+ gap: "0.2rem",
355
+ padding: 0,
356
+ fontWeight: isAllSelected ? 600 : 500
357
+ },
358
+ children: [
359
+ /* @__PURE__ */ jsx("span", { className: "material-symbols-outlined", style: { fontSize: "0.9rem" }, children: "check" }),
360
+ /* @__PURE__ */ jsx("span", { children: allLabel })
361
+ ]
362
+ }
363
+ ),
364
+ /* @__PURE__ */ jsx("span", { style: { color: "var(--color-text-muted)" }, children: "|" }),
365
+ /* @__PURE__ */ jsxs(
366
+ "button",
367
+ {
368
+ type: "button",
369
+ onClick: () => onChange([]),
370
+ style: {
371
+ background: "none",
372
+ border: "none",
373
+ color: isNoneSelected ? "var(--color-danger)" : "var(--color-text-secondary)",
374
+ cursor: "pointer",
375
+ display: "inline-flex",
376
+ alignItems: "center",
377
+ gap: "0.2rem",
378
+ padding: 0,
379
+ fontWeight: isNoneSelected ? 600 : 500
380
+ },
381
+ children: [
382
+ /* @__PURE__ */ jsx("span", { className: "material-symbols-outlined", style: { fontSize: "0.9rem" }, children: "close" }),
383
+ /* @__PURE__ */ jsx("span", { children: noneLabel })
384
+ ]
385
+ }
386
+ )
387
+ ] }),
388
+ options.length === 0 ? /* @__PURE__ */ jsx("div", { style: { padding: "0.5rem 0.75rem", fontSize: "0.875rem", color: "var(--color-text-muted)" }, children: "Sin opciones" }) : null,
389
+ options.map((opt) => /* @__PURE__ */ jsxs(
390
+ "label",
391
+ {
392
+ style: {
393
+ display: "flex",
394
+ alignItems: "center",
395
+ gap: "0.5rem",
396
+ padding: "0.4rem 0.75rem",
397
+ cursor: "pointer",
398
+ fontSize: "0.875rem",
399
+ color: selectedValues.includes(opt.value) ? "var(--color-text-primary)" : "var(--color-text-secondary)",
400
+ background: selectedValues.includes(opt.value) ? "var(--color-accent-bg)" : "transparent"
401
+ },
402
+ onMouseEnter: (e) => {
403
+ e.currentTarget.style.background = selectedValues.includes(opt.value) ? "var(--color-accent-bg)" : "var(--color-bg-hover)";
404
+ },
405
+ onMouseLeave: (e) => {
406
+ e.currentTarget.style.background = selectedValues.includes(opt.value) ? "var(--color-accent-bg)" : "transparent";
407
+ },
408
+ children: [
409
+ /* @__PURE__ */ jsx(
410
+ "input",
411
+ {
412
+ type: "checkbox",
413
+ checked: selectedValues.includes(opt.value),
414
+ onChange: () => toggleValue(opt.value),
415
+ style: { width: "auto", margin: 0, accentColor: "var(--color-primary)" }
416
+ }
417
+ ),
418
+ opt.label
419
+ ]
420
+ },
421
+ opt.value
422
+ ))
423
+ ]
424
+ }
425
+ )
426
+ ] });
427
+ }
428
+
429
+ // src/components/forms/SingleSelectDropdown.tsx
430
+ function SingleSelectDropdown({
431
+ options,
432
+ value,
433
+ selected,
434
+ onChange,
435
+ placeholder = "Seleccionar",
436
+ emptyValue = "",
437
+ allowEmptyOption = true,
438
+ disabled,
439
+ label,
440
+ style,
441
+ buttonClassName = "form-select",
442
+ dataTestId,
443
+ title,
444
+ ariaLabel,
445
+ buttonStyle,
446
+ className = "form-group"
447
+ }) {
448
+ const [open, setOpen] = useState(false);
449
+ const rootRef = useRef(null);
450
+ const currentValue = value ?? selected ?? emptyValue;
451
+ const selectedOption = options.find((o) => o.value === currentValue);
452
+ const buttonLabel = selectedOption?.label ?? placeholder;
453
+ const renderedOptions = allowEmptyOption ? [{ value: emptyValue, label: placeholder }, ...options] : options;
454
+ useEffect(() => {
455
+ if (!open) return;
456
+ const onDown = (e) => {
457
+ const el = rootRef.current;
458
+ if (!el) return;
459
+ const target = e.target;
460
+ if (target && el.contains(target)) return;
461
+ setOpen(false);
462
+ };
463
+ document.addEventListener("mousedown", onDown);
464
+ return () => document.removeEventListener("mousedown", onDown);
465
+ }, [open]);
466
+ return /* @__PURE__ */ jsxs("div", { ref: rootRef, className, style: { position: "relative", ...style ?? {} }, children: [
467
+ label ? /* @__PURE__ */ jsx("label", { className: "form-label-dropdown", children: label }) : null,
468
+ /* @__PURE__ */ jsxs(
469
+ "button",
470
+ {
471
+ type: "button",
472
+ className: buttonClassName,
473
+ "data-testid": dataTestId,
474
+ title,
475
+ "aria-label": ariaLabel,
476
+ onClick: () => {
477
+ if (disabled) return;
478
+ setOpen((o) => !o);
479
+ },
480
+ disabled,
481
+ style: {
482
+ width: "100%",
483
+ textAlign: "left",
484
+ overflow: "hidden",
485
+ textOverflow: "ellipsis",
486
+ whiteSpace: "nowrap",
487
+ display: "flex",
488
+ alignItems: "center",
489
+ justifyContent: "space-between",
490
+ gap: "0.5rem",
491
+ cursor: disabled ? "not-allowed" : "pointer",
492
+ opacity: disabled ? 0.6 : 1,
493
+ ...buttonStyle ?? {}
494
+ },
495
+ "aria-haspopup": "listbox",
496
+ "aria-expanded": open,
497
+ children: [
498
+ /* @__PURE__ */ jsx(
499
+ "span",
500
+ {
501
+ style: {
502
+ overflow: "hidden",
503
+ textOverflow: "ellipsis",
504
+ whiteSpace: "nowrap",
505
+ color: currentValue === emptyValue ? "var(--color-text-muted)" : "var(--color-text-primary)"
506
+ },
507
+ children: buttonLabel
508
+ }
509
+ ),
510
+ /* @__PURE__ */ jsx("span", { className: "material-symbols-outlined", style: { fontSize: "1rem", color: "var(--color-text-secondary)", flexShrink: 0 }, children: open ? "expand_less" : "expand_more" })
511
+ ]
512
+ }
513
+ ),
514
+ open ? /* @__PURE__ */ jsxs(
515
+ "div",
516
+ {
517
+ className: "form-dropdown-panel",
518
+ style: {
519
+ position: "absolute",
520
+ top: "100%",
521
+ left: 0,
522
+ minWidth: "100%",
523
+ maxHeight: "220px",
524
+ overflowY: "auto",
525
+ border: "1px solid var(--color-border)",
526
+ borderRadius: "var(--radius-md)",
527
+ boxShadow: "0 4px 12px rgba(0,0,0,0.15)",
528
+ marginTop: "2px"
529
+ },
530
+ role: "listbox",
531
+ children: [
532
+ renderedOptions.length === 0 ? /* @__PURE__ */ jsx("div", { style: { padding: "0.5rem 0.75rem", fontSize: "0.875rem", color: "var(--color-text-muted)" }, children: "Sin opciones" }) : null,
533
+ renderedOptions.map((opt) => {
534
+ const isSelected = opt.value === currentValue;
535
+ return /* @__PURE__ */ jsxs(
536
+ "div",
537
+ {
538
+ role: "option",
539
+ "aria-selected": isSelected,
540
+ onClick: () => {
541
+ onChange(opt.value);
542
+ setOpen(false);
543
+ },
544
+ onMouseEnter: (e) => {
545
+ e.currentTarget.style.background = isSelected ? "var(--color-accent-bg)" : "var(--color-bg-hover)";
546
+ },
547
+ onMouseLeave: (e) => {
548
+ e.currentTarget.style.background = isSelected ? "var(--color-accent-bg)" : "transparent";
549
+ },
550
+ style: {
551
+ display: "flex",
552
+ alignItems: "center",
553
+ gap: "0.5rem",
554
+ padding: "0.4rem 0.75rem",
555
+ cursor: "pointer",
556
+ fontSize: "0.875rem",
557
+ color: isSelected ? "var(--color-text-primary)" : "var(--color-text-secondary)",
558
+ background: isSelected ? "var(--color-accent-bg)" : "transparent",
559
+ userSelect: "none"
560
+ },
561
+ children: [
562
+ isSelected ? /* @__PURE__ */ jsx("span", { className: "material-symbols-outlined", style: { fontSize: "0.95rem" }, children: "check" }) : null,
563
+ opt.label
564
+ ]
565
+ },
566
+ opt.value
567
+ );
568
+ })
569
+ ]
570
+ }
571
+ ) : null
572
+ ] });
573
+ }
574
+
575
+ // src/components/forms/EmailInput.tsx
576
+ function EmailInput({
577
+ value,
578
+ onChange,
579
+ placeholder = "correo@ejemplo.com",
580
+ label = "Correo electr\xF3nico",
581
+ hint,
582
+ error,
583
+ disabled,
584
+ required,
585
+ ariaLabel,
586
+ id: idProp,
587
+ leftIcon = "mail",
588
+ className = "form-group",
589
+ inputClassName = "form-input",
590
+ autoComplete = "email",
591
+ "data-testid": dataTestId
592
+ }) {
593
+ const genId = useId();
594
+ const id = idProp ?? genId;
595
+ return /* @__PURE__ */ jsxs("div", { className, children: [
596
+ label ? /* @__PURE__ */ jsxs("label", { className: "form-label-app", htmlFor: id, children: [
597
+ label,
598
+ required ? /* @__PURE__ */ jsxs("span", { className: "required-mark", "aria-hidden": true, children: [
599
+ " ",
600
+ "*"
601
+ ] }) : null
602
+ ] }) : null,
603
+ /* @__PURE__ */ jsxs("div", { className: "input-with-icon", children: [
604
+ /* @__PURE__ */ jsx("span", { className: "material-symbols-outlined", "aria-hidden": true, children: leftIcon }),
605
+ /* @__PURE__ */ jsx(
606
+ "input",
607
+ {
608
+ id,
609
+ "data-testid": dataTestId,
610
+ type: "email",
611
+ value,
612
+ onChange: (e) => onChange(e.target.value),
613
+ placeholder,
614
+ className: inputClassName,
615
+ required,
616
+ disabled,
617
+ autoComplete,
618
+ "aria-label": ariaLabel ?? label ?? "Email"
619
+ }
620
+ )
621
+ ] }),
622
+ error ? /* @__PURE__ */ jsx("p", { role: "alert", style: { marginTop: "0.35rem", fontSize: "0.8125rem", color: "var(--color-error)" }, children: error }) : hint ? /* @__PURE__ */ jsx("p", { style: { marginTop: "0.35rem", fontSize: "0.8125rem", color: "var(--color-text-muted)" }, children: hint }) : null
623
+ ] });
624
+ }
625
+ return __toCommonJS(forms_entry_exports);
626
+ })();
@@ -0,0 +1,50 @@
1
+ import type { ComponentType, Context, CSSProperties, ReactNode } from 'react';
2
+
3
+ export type IconSize = 'sm' | 'md' | 'lg' | number;
4
+
5
+ export interface IconContextValue {
6
+ fontHref: string;
7
+ injectStylesheet: boolean;
8
+ defaultSize: IconSize;
9
+ className?: string;
10
+ }
11
+
12
+ export interface IconProps {
13
+ name: string;
14
+ size?: IconSize;
15
+ fill?: 0 | 1;
16
+ className?: string;
17
+ style?: CSSProperties;
18
+ 'aria-label'?: string;
19
+ }
20
+
21
+ export interface LucideIconProps {
22
+ as: ComponentType<{
23
+ className?: string;
24
+ size?: number | string;
25
+ strokeWidth?: number;
26
+ 'aria-hidden'?: boolean;
27
+ 'aria-label'?: string;
28
+ }>;
29
+ size?: IconSize;
30
+ className?: string;
31
+ strokeWidth?: number;
32
+ 'aria-label'?: string;
33
+ }
34
+
35
+ export interface IconProviderProps {
36
+ children: ReactNode;
37
+ fontHref?: string;
38
+ injectStylesheet?: boolean;
39
+ defaultSize?: IconContextValue['defaultSize'];
40
+ className?: string;
41
+ }
42
+
43
+ export declare const DEFAULT_FONT_HREF: string;
44
+ export declare const defaultIconContext: IconContextValue;
45
+ export declare const IconContext: Context<IconContextValue>;
46
+
47
+ export declare function IconProvider(props: IconProviderProps): JSX.Element;
48
+ export declare function Icon(props: IconProps): JSX.Element;
49
+ export declare function LucideIcon(props: LucideIconProps): JSX.Element;
50
+ export declare function useIconContext(): IconContextValue;