@satellatickets/ui 0.1.0 → 0.2.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/web/index.js CHANGED
@@ -1,64 +1,32 @@
1
- import { UIContext, buttonIconSize, createUIContextValue, iconSizePx, textVariantStyles, useBrand, useButton, useColorScheme, useTheme } from "@satellatickets/core";
2
- import { jsx, jsxs } from "react/jsx-runtime";
1
+ 'use client';
2
+ import { FormFieldContext, ToastContext, UIContext, buttonIconSize, createFormFieldValue, createToastStore, createUIContextValue, firstEnabledTab, getTabInDirection, iconButtonIconSize, iconSizePx, inputIconSize, isFeedbackTone, textVariantStyles, useBrand, useButton, useColorScheme, useControllableState, useFormFieldControl, useLink, useTheme, useToast } from "@satellatickets/core";
3
3
  import { cssVariables } from "@satellatickets/tokens";
4
- import { useMemo, useSyncExternalStore } from "react";
4
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
5
+ import { useContext, useEffect, useId, useMemo, useRef, useState, useSyncExternalStore } from "react";
5
6
  //#region src/_internal/cx.ts
6
7
  /** Une clases CSS ignorando valores falsos. */
7
8
  function cx(...parts) {
8
9
  return parts.filter(Boolean).join(" ");
9
10
  }
10
11
  //#endregion
11
- //#region src/badge/Badge.module.css
12
- var Badge_module_default = {
13
- "danger": "sui-danger-iCOp0a",
14
- "info": "sui-info-iCOp0a",
15
- "root": "sui-root-iCOp0a",
16
- "success": "sui-success-iCOp0a",
17
- "warning": "sui-warning-iCOp0a"
12
+ //#region src/_internal/feedback.ts
13
+ /** El icono refuerza el color: el tono no depende solo de él. */
14
+ const feedbackIcon = {
15
+ success: "circle-check",
16
+ warning: "triangle-alert",
17
+ danger: "circle-x",
18
+ info: "info"
18
19
  };
19
- //#endregion
20
- //#region src/badge/Badge.web.tsx
21
- const variantClass$1 = {
22
- success: Badge_module_default.success,
23
- warning: Badge_module_default.warning,
24
- danger: Badge_module_default.danger,
25
- info: Badge_module_default.info
20
+ /**
21
+ * Si el tono interrumpe al lector de pantalla (`alert`, `assertive`) o espera a que
22
+ * termine de leer (`status`, `polite`).
23
+ */
24
+ const feedbackUrgent = {
25
+ success: false,
26
+ warning: true,
27
+ danger: true,
28
+ info: false
26
29
  };
27
- function Badge({ variant = "info", className, testID, children }) {
28
- return /* @__PURE__ */ jsx("span", {
29
- className: cx(Badge_module_default.root, variantClass$1[variant], className),
30
- "data-testid": testID,
31
- children
32
- });
33
- }
34
- //#endregion
35
- //#region src/box/Box.module.css
36
- var Box_module_default = { "root": "sui-root-fYQz2a" };
37
- //#endregion
38
- //#region src/box/Box.web.tsx
39
- function Box({ as: Tag = "div", padding, paddingX, paddingY, background, radius, borderColor, shadow, flex, className, style, testID, children }) {
40
- const vars = {};
41
- if (padding !== void 0) vars["--box-padding"] = `var(${cssVariables[`space.${padding}`]})`;
42
- if (paddingX !== void 0) vars["--box-padding-x"] = `var(${cssVariables[`space.${paddingX}`]})`;
43
- if (paddingY !== void 0) vars["--box-padding-y"] = `var(${cssVariables[`space.${paddingY}`]})`;
44
- if (background !== void 0) vars["--box-background"] = `var(${cssVariables[`color.bg.${background}`]})`;
45
- if (radius !== void 0) vars["--box-radius"] = `var(${cssVariables[`radius.${radius}`]})`;
46
- if (borderColor !== void 0) {
47
- vars["--box-border-color"] = `var(${cssVariables[`color.border.${borderColor}`]})`;
48
- vars["--box-border-width"] = `var(${cssVariables["borderWidth.thin"]})`;
49
- }
50
- if (shadow !== void 0) vars["--box-shadow"] = `var(${cssVariables[`shadow.${shadow}`]})`;
51
- if (flex !== void 0) vars["--box-flex"] = String(flex);
52
- return /* @__PURE__ */ jsx(Tag, {
53
- className: cx(Box_module_default.root, className),
54
- style: {
55
- ...vars,
56
- ...style
57
- },
58
- "data-testid": testID,
59
- children
60
- });
61
- }
62
30
  //#endregion
63
31
  //#region ../icons/src/icons.ts
64
32
  const icons = {
@@ -357,6 +325,10 @@ function renderElement(element, index) {
357
325
  }, index);
358
326
  }
359
327
  }
328
+ /** Variable CSS del color: un color de texto o el icono de un estado de feedback. */
329
+ function colorVariable(color) {
330
+ return isFeedbackTone(color) ? cssVariables[`color.feedback.${color}.icon`] : cssVariables[`color.text.${color}`];
331
+ }
360
332
  function Icon({ name, size = "md", color = "primary", label, className, testID }) {
361
333
  const px = iconSizePx[size];
362
334
  const decorative = label === void 0;
@@ -366,7 +338,7 @@ function Icon({ name, size = "md", color = "primary", label, className, testID }
366
338
  height: px,
367
339
  viewBox: `0 0 24 24`,
368
340
  fill: "none",
369
- stroke: `var(${cssVariables[`color.text.${color}`]})`,
341
+ stroke: `var(${colorVariable(color)})`,
370
342
  strokeWidth: 2,
371
343
  strokeLinecap: "round",
372
344
  strokeLinejoin: "round",
@@ -379,6 +351,23 @@ function Icon({ name, size = "md", color = "primary", label, className, testID }
379
351
  });
380
352
  }
381
353
  //#endregion
354
+ //#region src/button/Button.module.css
355
+ var Button_module_default = {
356
+ "content": "sui-content-FZ-IiW",
357
+ "danger": "sui-danger-FZ-IiW",
358
+ "fullWidth": "sui-fullWidth-FZ-IiW",
359
+ "ghost": "sui-ghost-FZ-IiW",
360
+ "label": "sui-label-FZ-IiW",
361
+ "lg": "sui-lg-FZ-IiW",
362
+ "loading": "sui-loading-FZ-IiW",
363
+ "md": "sui-md-FZ-IiW",
364
+ "primary": "sui-primary-FZ-IiW",
365
+ "root": "sui-root-FZ-IiW",
366
+ "secondary": "sui-secondary-FZ-IiW",
367
+ "sm": "sui-sm-FZ-IiW",
368
+ "spinner": "sui-spinner-FZ-IiW"
369
+ };
370
+ //#endregion
382
371
  //#region src/spinner/Spinner.module.css
383
372
  var Spinner_module_default = {
384
373
  "icon": "sui-icon-iFfE_q",
@@ -388,9 +377,10 @@ var Spinner_module_default = {
388
377
  //#endregion
389
378
  //#region src/spinner/Spinner.web.tsx
390
379
  /**
391
- * Indicador de carga indeterminada. Versión mínima (ROADMAP Fase 3): el icono
392
- * `loader-circle` girando. Con `label` es una barra de progreso indeterminada
393
- * para los lectores de pantalla; sin él, es decorativo.
380
+ * Indicador de carga indeterminada: el icono `loader-circle` girando. Con `label` es
381
+ * una barra de progreso indeterminada para los lectores de pantalla; sin él, es
382
+ * decorativo. Con movimiento reducido gira más despacio, pero no se detiene: parado
383
+ * no diría que algo está en curso.
394
384
  */
395
385
  function Spinner({ size = "md", color = "primary", label, className, testID }) {
396
386
  const decorative = label === void 0;
@@ -409,31 +399,179 @@ function Spinner({ size = "md", color = "primary", label, className, testID }) {
409
399
  });
410
400
  }
411
401
  //#endregion
412
- //#region src/button/Button.module.css
413
- var Button_module_default = {
414
- "content": "sui-content-FZ-IiW",
415
- "danger": "sui-danger-FZ-IiW",
416
- "fullWidth": "sui-fullWidth-FZ-IiW",
417
- "ghost": "sui-ghost-FZ-IiW",
418
- "label": "sui-label-FZ-IiW",
419
- "lg": "sui-lg-FZ-IiW",
420
- "loading": "sui-loading-FZ-IiW",
421
- "md": "sui-md-FZ-IiW",
422
- "primary": "sui-primary-FZ-IiW",
423
- "root": "sui-root-FZ-IiW",
424
- "secondary": "sui-secondary-FZ-IiW",
425
- "sm": "sui-sm-FZ-IiW",
426
- "spinner": "sui-spinner-FZ-IiW"
402
+ //#region src/icon-button/IconButton.module.css
403
+ var IconButton_module_default = {
404
+ "lg": "sui-lg-f0wlja",
405
+ "md": "sui-md-f0wlja",
406
+ "sm": "sui-sm-f0wlja"
427
407
  };
428
408
  //#endregion
409
+ //#region src/icon-button/IconButton.web.tsx
410
+ const variantClass$3 = {
411
+ primary: Button_module_default.primary,
412
+ secondary: Button_module_default.secondary,
413
+ ghost: Button_module_default.ghost,
414
+ danger: Button_module_default.danger
415
+ };
416
+ const sizeClass$3 = {
417
+ sm: IconButton_module_default.sm,
418
+ md: IconButton_module_default.md,
419
+ lg: IconButton_module_default.lg
420
+ };
421
+ function IconButton({ icon, label, variant = "ghost", size = "md", disabled = false, loading = false, onPress, type = "button", className, style, testID, ref }) {
422
+ const { interactive, press } = useButton({
423
+ disabled,
424
+ loading,
425
+ onPress
426
+ });
427
+ const iconSize = iconButtonIconSize[size];
428
+ function handleClick(event) {
429
+ if (!interactive) event.preventDefault();
430
+ press();
431
+ }
432
+ return /* @__PURE__ */ jsxs("button", {
433
+ ref,
434
+ type,
435
+ className: cx(Button_module_default.root, variantClass$3[variant], sizeClass$3[size], loading && Button_module_default.loading, className),
436
+ style,
437
+ disabled,
438
+ "aria-disabled": loading ? true : void 0,
439
+ "aria-busy": loading ? true : void 0,
440
+ "aria-label": label,
441
+ "data-testid": testID,
442
+ onClick: handleClick,
443
+ children: [/* @__PURE__ */ jsx("span", {
444
+ className: Button_module_default.content,
445
+ children: /* @__PURE__ */ jsx(Icon, {
446
+ name: icon,
447
+ size: iconSize
448
+ })
449
+ }), loading ? /* @__PURE__ */ jsx("span", {
450
+ className: Button_module_default.spinner,
451
+ children: /* @__PURE__ */ jsx(Spinner, { size: iconSize })
452
+ }) : null]
453
+ });
454
+ }
455
+ //#endregion
456
+ //#region src/alert/Alert.module.css
457
+ var Alert_module_default = {
458
+ "close": "sui-close-hPKSzG",
459
+ "content": "sui-content-hPKSzG",
460
+ "danger": "sui-danger-hPKSzG",
461
+ "description": "sui-description-hPKSzG",
462
+ "icon": "sui-icon-hPKSzG",
463
+ "info": "sui-info-hPKSzG",
464
+ "root": "sui-root-hPKSzG",
465
+ "success": "sui-success-hPKSzG",
466
+ "title": "sui-title-hPKSzG",
467
+ "warning": "sui-warning-hPKSzG"
468
+ };
469
+ //#endregion
470
+ //#region src/alert/Alert.web.tsx
471
+ const toneClass = {
472
+ success: Alert_module_default.success,
473
+ warning: Alert_module_default.warning,
474
+ danger: Alert_module_default.danger,
475
+ info: Alert_module_default.info
476
+ };
477
+ function Alert({ tone = "info", title, onClose, closeLabel, className, style, testID, children }) {
478
+ const hasDescription = children !== void 0 && children !== null;
479
+ return /* @__PURE__ */ jsxs("div", {
480
+ className: cx(Alert_module_default.root, toneClass[tone], className),
481
+ style,
482
+ role: feedbackUrgent[tone] ? "alert" : "status",
483
+ "data-testid": testID,
484
+ children: [
485
+ /* @__PURE__ */ jsx("span", {
486
+ className: Alert_module_default.icon,
487
+ children: /* @__PURE__ */ jsx(Icon, {
488
+ name: feedbackIcon[tone],
489
+ size: "md",
490
+ color: tone
491
+ })
492
+ }),
493
+ /* @__PURE__ */ jsxs("div", {
494
+ className: Alert_module_default.content,
495
+ children: [title === void 0 ? null : /* @__PURE__ */ jsx("p", {
496
+ className: Alert_module_default.title,
497
+ children: title
498
+ }), hasDescription ? /* @__PURE__ */ jsx("div", {
499
+ className: Alert_module_default.description,
500
+ children
501
+ }) : null]
502
+ }),
503
+ onClose === void 0 ? null : /* @__PURE__ */ jsx(IconButton, {
504
+ icon: "x",
505
+ label: closeLabel,
506
+ size: "sm",
507
+ variant: "ghost",
508
+ onPress: onClose,
509
+ className: Alert_module_default.close
510
+ })
511
+ ]
512
+ });
513
+ }
514
+ //#endregion
515
+ //#region src/badge/Badge.module.css
516
+ var Badge_module_default = {
517
+ "danger": "sui-danger-iCOp0a",
518
+ "info": "sui-info-iCOp0a",
519
+ "root": "sui-root-iCOp0a",
520
+ "success": "sui-success-iCOp0a",
521
+ "warning": "sui-warning-iCOp0a"
522
+ };
523
+ //#endregion
524
+ //#region src/badge/Badge.web.tsx
525
+ const variantClass$2 = {
526
+ success: Badge_module_default.success,
527
+ warning: Badge_module_default.warning,
528
+ danger: Badge_module_default.danger,
529
+ info: Badge_module_default.info
530
+ };
531
+ function Badge({ variant = "info", className, testID, children }) {
532
+ return /* @__PURE__ */ jsx("span", {
533
+ className: cx(Badge_module_default.root, variantClass$2[variant], className),
534
+ "data-testid": testID,
535
+ children
536
+ });
537
+ }
538
+ //#endregion
539
+ //#region src/box/Box.module.css
540
+ var Box_module_default = { "root": "sui-root-fYQz2a" };
541
+ //#endregion
542
+ //#region src/box/Box.web.tsx
543
+ function Box({ as: Tag = "div", padding, paddingX, paddingY, background, radius, borderColor, shadow, flex, className, style, testID, children }) {
544
+ const vars = {};
545
+ if (padding !== void 0) vars["--box-padding"] = `var(${cssVariables[`space.${padding}`]})`;
546
+ if (paddingX !== void 0) vars["--box-padding-x"] = `var(${cssVariables[`space.${paddingX}`]})`;
547
+ if (paddingY !== void 0) vars["--box-padding-y"] = `var(${cssVariables[`space.${paddingY}`]})`;
548
+ if (background !== void 0) vars["--box-background"] = `var(${cssVariables[`color.bg.${background}`]})`;
549
+ if (radius !== void 0) vars["--box-radius"] = `var(${cssVariables[`radius.${radius}`]})`;
550
+ if (borderColor !== void 0) {
551
+ vars["--box-border-color"] = `var(${cssVariables[`color.border.${borderColor}`]})`;
552
+ vars["--box-border-width"] = `var(${cssVariables["borderWidth.thin"]})`;
553
+ }
554
+ if (shadow !== void 0) vars["--box-shadow"] = `var(${cssVariables[`shadow.${shadow}`]})`;
555
+ if (flex !== void 0) vars["--box-flex"] = String(flex);
556
+ return /* @__PURE__ */ jsx(Tag, {
557
+ className: cx(Box_module_default.root, className),
558
+ style: {
559
+ ...vars,
560
+ ...style
561
+ },
562
+ "data-testid": testID,
563
+ children
564
+ });
565
+ }
566
+ //#endregion
429
567
  //#region src/button/Button.web.tsx
430
- const variantClass = {
568
+ const variantClass$1 = {
431
569
  primary: Button_module_default.primary,
432
570
  secondary: Button_module_default.secondary,
433
571
  ghost: Button_module_default.ghost,
434
572
  danger: Button_module_default.danger
435
573
  };
436
- const sizeClass = {
574
+ const sizeClass$2 = {
437
575
  sm: Button_module_default.sm,
438
576
  md: Button_module_default.md,
439
577
  lg: Button_module_default.lg
@@ -452,7 +590,7 @@ function Button({ variant = "primary", size = "md", disabled = false, loading =
452
590
  return /* @__PURE__ */ jsxs("button", {
453
591
  ref,
454
592
  type,
455
- className: cx(Button_module_default.root, variantClass[variant], sizeClass[size], fullWidth && Button_module_default.fullWidth, loading && Button_module_default.loading, className),
593
+ className: cx(Button_module_default.root, variantClass$1[variant], sizeClass$2[size], fullWidth && Button_module_default.fullWidth, loading && Button_module_default.loading, className),
456
594
  style,
457
595
  disabled,
458
596
  "aria-disabled": loading ? true : void 0,
@@ -483,6 +621,598 @@ function Button({ variant = "primary", size = "md", disabled = false, loading =
483
621
  });
484
622
  }
485
623
  //#endregion
624
+ //#region src/card/Card.module.css
625
+ var Card_module_default = {
626
+ "elevated": "sui-elevated-So50QW",
627
+ "interactive": "sui-interactive-So50QW",
628
+ "outlined": "sui-outlined-So50QW",
629
+ "root": "sui-root-So50QW"
630
+ };
631
+ //#endregion
632
+ //#region src/card/Card.web.tsx
633
+ const variantClass = {
634
+ outlined: Card_module_default.outlined,
635
+ elevated: Card_module_default.elevated
636
+ };
637
+ function Card({ variant = "outlined", padding = 4, onPress, accessibilityLabel, className, style, testID, ref, children }) {
638
+ const vars = { "--card-padding": `var(${cssVariables[`space.${padding}`]})` };
639
+ const classes = cx(Card_module_default.root, variantClass[variant], onPress !== void 0 && Card_module_default.interactive, className);
640
+ if (onPress === void 0) return /* @__PURE__ */ jsx("div", {
641
+ ref,
642
+ className: classes,
643
+ style: {
644
+ ...vars,
645
+ ...style
646
+ },
647
+ "data-testid": testID,
648
+ children
649
+ });
650
+ function handleKeyDown(event) {
651
+ if (event.target !== event.currentTarget) return;
652
+ if (event.key !== "Enter" && event.key !== " ") return;
653
+ event.preventDefault();
654
+ onPress?.();
655
+ }
656
+ return /* @__PURE__ */ jsx("div", {
657
+ ref,
658
+ role: "button",
659
+ tabIndex: 0,
660
+ className: classes,
661
+ style: {
662
+ ...vars,
663
+ ...style
664
+ },
665
+ "aria-label": accessibilityLabel,
666
+ "data-testid": testID,
667
+ onClick: onPress,
668
+ onKeyDown: handleKeyDown,
669
+ children
670
+ });
671
+ }
672
+ //#endregion
673
+ //#region src/_internal/mergeRefs.ts
674
+ /** Un solo `ref` que actualiza varios: el interno del componente y el que recibe por props. */
675
+ function mergeRefs(...refs) {
676
+ return (node) => {
677
+ for (const ref of refs) if (typeof ref === "function") ref(node);
678
+ else if (ref !== null && ref !== void 0) ref.current = node;
679
+ };
680
+ }
681
+ //#endregion
682
+ //#region src/checkbox/Checkbox.module.css
683
+ var Checkbox_module_default = {
684
+ "box": "sui-box-iE7-OG",
685
+ "check": "sui-check-iE7-OG",
686
+ "dash": "sui-dash-iE7-OG",
687
+ "disabled": "sui-disabled-iE7-OG",
688
+ "input": "sui-input-iE7-OG",
689
+ "invalid": "sui-invalid-iE7-OG",
690
+ "label": "sui-label-iE7-OG",
691
+ "mark": "sui-mark-iE7-OG",
692
+ "root": "sui-root-iE7-OG"
693
+ };
694
+ //#endregion
695
+ //#region src/checkbox/Checkbox.web.tsx
696
+ function Checkbox({ checked, defaultChecked, indeterminate = false, onCheckedChange, disabled = false, invalid = false, required = false, accessibilityLabel, id, name, value, className, style, testID, ref, children }) {
697
+ const input = useRef(null);
698
+ const setRef = useMemo(() => mergeRefs(input, ref), [ref]);
699
+ useEffect(() => {
700
+ if (input.current !== null) input.current.indeterminate = indeterminate;
701
+ }, [indeterminate]);
702
+ return /* @__PURE__ */ jsxs("label", {
703
+ className: cx(Checkbox_module_default.root, disabled && Checkbox_module_default.disabled, className),
704
+ style,
705
+ children: [
706
+ /* @__PURE__ */ jsx("input", {
707
+ ref: setRef,
708
+ type: "checkbox",
709
+ className: Checkbox_module_default.input,
710
+ id,
711
+ name,
712
+ value,
713
+ ...checked === void 0 ? { defaultChecked } : { checked },
714
+ onChange: (event) => onCheckedChange?.(event.target.checked),
715
+ disabled,
716
+ "aria-label": accessibilityLabel,
717
+ "aria-invalid": invalid ? true : void 0,
718
+ "aria-required": required ? true : void 0,
719
+ "data-testid": testID
720
+ }),
721
+ /* @__PURE__ */ jsxs("span", {
722
+ className: cx(Checkbox_module_default.box, invalid && Checkbox_module_default.invalid),
723
+ "aria-hidden": "true",
724
+ children: [/* @__PURE__ */ jsx(Icon, {
725
+ name: "check",
726
+ size: "sm",
727
+ color: "onPrimary",
728
+ className: cx(Checkbox_module_default.mark, Checkbox_module_default.check)
729
+ }), /* @__PURE__ */ jsx(Icon, {
730
+ name: "minus",
731
+ size: "sm",
732
+ color: "onPrimary",
733
+ className: cx(Checkbox_module_default.mark, Checkbox_module_default.dash)
734
+ })]
735
+ }),
736
+ children === void 0 || children === null ? null : /* @__PURE__ */ jsx("span", {
737
+ className: Checkbox_module_default.label,
738
+ children
739
+ })
740
+ ]
741
+ });
742
+ }
743
+ //#endregion
744
+ //#region src/divider/Divider.module.css
745
+ var Divider_module_default = {
746
+ "horizontal": "sui-horizontal-Ea_Ija",
747
+ "root": "sui-root-Ea_Ija",
748
+ "vertical": "sui-vertical-Ea_Ija"
749
+ };
750
+ //#endregion
751
+ //#region src/divider/Divider.web.tsx
752
+ const orientationClass = {
753
+ horizontal: Divider_module_default.horizontal,
754
+ vertical: Divider_module_default.vertical
755
+ };
756
+ function Divider({ orientation = "horizontal", className, testID }) {
757
+ const classes = cx(Divider_module_default.root, orientationClass[orientation], className);
758
+ return orientation === "horizontal" ? /* @__PURE__ */ jsx("hr", {
759
+ className: classes,
760
+ "data-testid": testID
761
+ }) : /* @__PURE__ */ jsx("div", {
762
+ role: "separator",
763
+ "aria-orientation": "vertical",
764
+ className: classes,
765
+ "data-testid": testID
766
+ });
767
+ }
768
+ //#endregion
769
+ //#region src/form-field/FormField.module.css
770
+ var FormField_module_default = {
771
+ "disabled": "sui-disabled-E2FhZq",
772
+ "error": "sui-error-E2FhZq",
773
+ "errorIcon": "sui-errorIcon-E2FhZq",
774
+ "help": "sui-help-E2FhZq",
775
+ "label": "sui-label-E2FhZq",
776
+ "required": "sui-required-E2FhZq",
777
+ "root": "sui-root-E2FhZq"
778
+ };
779
+ //#endregion
780
+ //#region src/form-field/FormField.web.tsx
781
+ /**
782
+ * Etiqueta, ayuda y error de un control (ADR-037). El `<label>` apunta al `id` que
783
+ * toma el control, y la ayuda y el error se enlazan con `aria-describedby`.
784
+ */
785
+ function FormField({ label, help, error, required = false, disabled = false, className, testID, children }) {
786
+ const baseId = useId();
787
+ const field = useMemo(() => createFormFieldValue(baseId, {
788
+ label,
789
+ help,
790
+ error,
791
+ disabled,
792
+ required
793
+ }), [
794
+ baseId,
795
+ label,
796
+ help,
797
+ error,
798
+ disabled,
799
+ required
800
+ ]);
801
+ return /* @__PURE__ */ jsx(FormFieldContext.Provider, {
802
+ value: field,
803
+ children: /* @__PURE__ */ jsxs("div", {
804
+ className: cx(FormField_module_default.root, disabled && FormField_module_default.disabled, className),
805
+ "data-testid": testID,
806
+ children: [
807
+ /* @__PURE__ */ jsxs("label", {
808
+ className: FormField_module_default.label,
809
+ htmlFor: field.controlId,
810
+ children: [label, required ? /* @__PURE__ */ jsx("span", {
811
+ className: FormField_module_default.required,
812
+ "aria-hidden": "true",
813
+ children: " *"
814
+ }) : null]
815
+ }),
816
+ children,
817
+ field.help === void 0 ? null : /* @__PURE__ */ jsx("p", {
818
+ id: field.helpId,
819
+ className: FormField_module_default.help,
820
+ children: field.help
821
+ }),
822
+ /* @__PURE__ */ jsx("div", {
823
+ "aria-live": "polite",
824
+ children: field.error === void 0 ? null : /* @__PURE__ */ jsxs("p", {
825
+ id: field.errorId,
826
+ className: FormField_module_default.error,
827
+ children: [/* @__PURE__ */ jsx("span", {
828
+ className: FormField_module_default.errorIcon,
829
+ children: /* @__PURE__ */ jsx(Icon, {
830
+ name: "circle-alert",
831
+ size: "sm",
832
+ color: "danger"
833
+ })
834
+ }), field.error]
835
+ })
836
+ })
837
+ ]
838
+ })
839
+ });
840
+ }
841
+ //#endregion
842
+ //#region src/_internal/field.module.css
843
+ var field_module_default = {
844
+ "control": "sui-control-jPIPoq",
845
+ "disabled": "sui-disabled-jPIPoq",
846
+ "field": "sui-field-jPIPoq",
847
+ "invalid": "sui-invalid-jPIPoq",
848
+ "readOnly": "sui-readOnly-jPIPoq"
849
+ };
850
+ //#endregion
851
+ //#region src/input/Input.module.css
852
+ var Input_module_default = {
853
+ "input": "sui-input-DAA5va",
854
+ "lg": "sui-lg-DAA5va",
855
+ "md": "sui-md-DAA5va",
856
+ "root": "sui-root-DAA5va",
857
+ "sm": "sui-sm-DAA5va"
858
+ };
859
+ //#endregion
860
+ //#region src/input/Input.web.tsx
861
+ const typeAttributes = {
862
+ text: { type: "text" },
863
+ email: { type: "email" },
864
+ password: { type: "password" },
865
+ search: { type: "search" },
866
+ tel: { type: "tel" },
867
+ url: { type: "url" },
868
+ number: {
869
+ type: "text",
870
+ inputMode: "decimal"
871
+ }
872
+ };
873
+ const sizeClass$1 = {
874
+ sm: Input_module_default.sm,
875
+ md: Input_module_default.md,
876
+ lg: Input_module_default.lg
877
+ };
878
+ function Input({ value, defaultValue, onChangeText, placeholder, type = "text", size = "md", disabled, readOnly = false, invalid, required, iconStart, iconEnd, maxLength, onFocus, onBlur, onSubmit, accessibilityLabel, id, name, autoComplete, className, style, testID, ref }) {
879
+ const control = useFormFieldControl({
880
+ id,
881
+ invalid,
882
+ disabled,
883
+ required
884
+ });
885
+ const attributes = typeAttributes[type];
886
+ const iconSize = inputIconSize[size];
887
+ const iconColor = control.disabled ? "disabled" : "muted";
888
+ function handleMouseDown(event) {
889
+ const input = event.currentTarget.querySelector("input");
890
+ if (input === null || event.target === input || control.disabled) return;
891
+ event.preventDefault();
892
+ input.focus();
893
+ }
894
+ function handleKeyDown(event) {
895
+ if (event.key === "Enter" && !event.nativeEvent.isComposing) onSubmit?.();
896
+ }
897
+ return /* @__PURE__ */ jsxs("div", {
898
+ className: cx(field_module_default.field, Input_module_default.root, sizeClass$1[size], control.invalid && field_module_default.invalid, readOnly && field_module_default.readOnly, control.disabled && field_module_default.disabled, className),
899
+ style,
900
+ onMouseDown: handleMouseDown,
901
+ children: [
902
+ iconStart === void 0 ? null : /* @__PURE__ */ jsx(Icon, {
903
+ name: iconStart,
904
+ size: iconSize,
905
+ color: iconColor
906
+ }),
907
+ /* @__PURE__ */ jsx("input", {
908
+ ref,
909
+ id: control.id,
910
+ className: cx(field_module_default.control, Input_module_default.input),
911
+ type: attributes.type,
912
+ inputMode: attributes.inputMode,
913
+ name,
914
+ autoComplete,
915
+ ...value === void 0 ? { defaultValue } : { value },
916
+ onChange: (event) => onChangeText?.(event.target.value),
917
+ placeholder,
918
+ disabled: control.disabled,
919
+ readOnly,
920
+ maxLength,
921
+ "aria-label": accessibilityLabel,
922
+ "aria-describedby": control.describedBy,
923
+ "aria-invalid": control.invalid ? true : void 0,
924
+ "aria-required": control.required ? true : void 0,
925
+ "data-testid": testID,
926
+ onFocus,
927
+ onBlur,
928
+ onKeyDown: handleKeyDown
929
+ }),
930
+ iconEnd === void 0 ? null : /* @__PURE__ */ jsx(Icon, {
931
+ name: iconEnd,
932
+ size: iconSize,
933
+ color: iconColor
934
+ })
935
+ ]
936
+ });
937
+ }
938
+ //#endregion
939
+ //#region src/link/Link.module.css
940
+ var Link_module_default = {
941
+ "always": "sui-always-5twIfq",
942
+ "hover": "sui-hover-5twIfq",
943
+ "root": "sui-root-5twIfq",
944
+ "typed": "sui-typed-5twIfq",
945
+ "uppercase": "sui-uppercase-5twIfq"
946
+ };
947
+ //#endregion
948
+ //#region src/link/Link.web.tsx
949
+ const underlineClass = {
950
+ always: Link_module_default.always,
951
+ hover: Link_module_default.hover
952
+ };
953
+ function Link({ href, variant, color = "link", underline = "always", onPress, accessibilityLabel, target, rel, className, style, testID, ref, children }) {
954
+ const { press } = useLink({ onPress });
955
+ const spec = variant === void 0 ? void 0 : textVariantStyles[variant];
956
+ const vars = { "--link-color": `var(${cssVariables[`color.text.${color}`]})` };
957
+ if (spec !== void 0) {
958
+ vars["--link-family"] = `var(${cssVariables[`font.family.${spec.family}`]})`;
959
+ vars["--link-size"] = `var(${cssVariables[`font.size.${spec.size}`]})`;
960
+ vars["--link-line-height"] = `var(${cssVariables[`font.lineHeight.${spec.size}`]})`;
961
+ vars["--link-weight"] = `var(${cssVariables[`font.weight.${spec.weight}`]})`;
962
+ if (spec.letterSpacing !== void 0) vars["--link-letter-spacing"] = `${spec.letterSpacing}px`;
963
+ }
964
+ function handleClick(event) {
965
+ if (event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return;
966
+ if (!press()) event.preventDefault();
967
+ }
968
+ return /* @__PURE__ */ jsx("a", {
969
+ ref,
970
+ href,
971
+ target,
972
+ rel: rel ?? (target === "_blank" ? "noopener noreferrer" : void 0),
973
+ className: cx(Link_module_default.root, underlineClass[underline], spec !== void 0 && Link_module_default.typed, spec?.uppercase && Link_module_default.uppercase, className),
974
+ style: {
975
+ ...vars,
976
+ ...style
977
+ },
978
+ "aria-label": accessibilityLabel,
979
+ "data-testid": testID,
980
+ onClick: handleClick,
981
+ children
982
+ });
983
+ }
984
+ //#endregion
985
+ //#region src/modal/Modal.module.css
986
+ var Modal_module_default = {
987
+ "body": "sui-body-M_CPgW",
988
+ "close": "sui-close-M_CPgW",
989
+ "description": "sui-description-M_CPgW",
990
+ "dialog": "sui-dialog-M_CPgW",
991
+ "footer": "sui-footer-M_CPgW",
992
+ "header": "sui-header-M_CPgW",
993
+ "root": "sui-root-M_CPgW",
994
+ "sheet": "sui-sheet-M_CPgW",
995
+ "title": "sui-title-M_CPgW",
996
+ "titles": "sui-titles-M_CPgW"
997
+ };
998
+ //#endregion
999
+ //#region src/modal/ModalDialog.web.tsx
1000
+ const presentationClass = {
1001
+ dialog: Modal_module_default.dialog,
1002
+ sheet: Modal_module_default.sheet
1003
+ };
1004
+ /**
1005
+ * La implementación que comparten `Modal` y `Sheet` (ADR-040): un `<dialog>` real
1006
+ * abierto con `showModal()`. El foco, la inercia del fondo y el apilamiento los
1007
+ * resuelve el navegador.
1008
+ */
1009
+ function ModalDialog({ presentation, open, onClose, title, description, closeLabel, dismissible = true, footer, className, style, testID, ref, children }) {
1010
+ const dialog = useRef(null);
1011
+ const setRef = useMemo(() => mergeRefs(dialog, ref), [ref]);
1012
+ const titleId = useId();
1013
+ const descriptionId = useId();
1014
+ useEffect(() => {
1015
+ const element = dialog.current;
1016
+ if (element === null) return;
1017
+ if (open && !element.open) element.showModal();
1018
+ else if (!open && element.open) element.close();
1019
+ }, [open]);
1020
+ function handleCancel(event) {
1021
+ event.preventDefault();
1022
+ if (dismissible) onClose();
1023
+ }
1024
+ function handleNativeClose() {
1025
+ if (open) onClose();
1026
+ }
1027
+ function handleClick(event) {
1028
+ if (event.target === event.currentTarget && dismissible) onClose();
1029
+ }
1030
+ const hasBody = children !== void 0 && children !== null;
1031
+ const hasFooter = footer !== void 0 && footer !== null;
1032
+ return /* @__PURE__ */ jsx("dialog", {
1033
+ ref: setRef,
1034
+ className: cx(Modal_module_default.root, presentationClass[presentation], className),
1035
+ style,
1036
+ "aria-labelledby": titleId,
1037
+ "aria-describedby": description === void 0 ? void 0 : descriptionId,
1038
+ "data-testid": testID,
1039
+ onCancel: handleCancel,
1040
+ onClose: handleNativeClose,
1041
+ onClick: handleClick,
1042
+ children: open ? /* @__PURE__ */ jsxs(Fragment, { children: [
1043
+ /* @__PURE__ */ jsxs("div", {
1044
+ className: Modal_module_default.header,
1045
+ children: [/* @__PURE__ */ jsxs("div", {
1046
+ className: Modal_module_default.titles,
1047
+ children: [/* @__PURE__ */ jsx("h2", {
1048
+ id: titleId,
1049
+ className: Modal_module_default.title,
1050
+ children: title
1051
+ }), description === void 0 ? null : /* @__PURE__ */ jsx("p", {
1052
+ id: descriptionId,
1053
+ className: Modal_module_default.description,
1054
+ children: description
1055
+ })]
1056
+ }), closeLabel === void 0 ? null : /* @__PURE__ */ jsx(IconButton, {
1057
+ icon: "x",
1058
+ label: closeLabel,
1059
+ size: "sm",
1060
+ variant: "ghost",
1061
+ onPress: onClose,
1062
+ className: Modal_module_default.close
1063
+ })]
1064
+ }),
1065
+ hasBody ? /* @__PURE__ */ jsx("div", {
1066
+ className: Modal_module_default.body,
1067
+ children
1068
+ }) : null,
1069
+ hasFooter ? /* @__PURE__ */ jsx("div", {
1070
+ className: Modal_module_default.footer,
1071
+ children: footer
1072
+ }) : null
1073
+ ] }) : null
1074
+ });
1075
+ }
1076
+ //#endregion
1077
+ //#region src/modal/Modal.web.tsx
1078
+ /** Un diálogo centrado (ADR-040). */
1079
+ function Modal(props) {
1080
+ return /* @__PURE__ */ jsx(ModalDialog, {
1081
+ ...props,
1082
+ presentation: "dialog"
1083
+ });
1084
+ }
1085
+ //#endregion
1086
+ //#region src/select/Select.module.css
1087
+ var Select_module_default = {
1088
+ "chevron": "sui-chevron-Rxx4wG",
1089
+ "lg": "sui-lg-Rxx4wG",
1090
+ "md": "sui-md-Rxx4wG",
1091
+ "placeholder": "sui-placeholder-Rxx4wG",
1092
+ "root": "sui-root-Rxx4wG",
1093
+ "select": "sui-select-Rxx4wG",
1094
+ "sm": "sui-sm-Rxx4wG"
1095
+ };
1096
+ //#endregion
1097
+ //#region src/select/Select.web.tsx
1098
+ const sizeClass = {
1099
+ sm: Select_module_default.sm,
1100
+ md: Select_module_default.md,
1101
+ lg: Select_module_default.lg
1102
+ };
1103
+ /**
1104
+ * Un `<select>` real (ADR-038): el teclado, los lectores de pantalla y el selector del
1105
+ * sistema en móvil son los del navegador.
1106
+ */
1107
+ function Select({ options, value, defaultValue, onValueChange, placeholder, size = "md", disabled, invalid, required, accessibilityLabel, id, name, className, style, testID, ref }) {
1108
+ const control = useFormFieldControl({
1109
+ id,
1110
+ invalid,
1111
+ disabled,
1112
+ required
1113
+ });
1114
+ const [current, setCurrent] = useControllableState({
1115
+ value,
1116
+ defaultValue: defaultValue ?? "",
1117
+ onChange: onValueChange
1118
+ });
1119
+ return /* @__PURE__ */ jsxs("div", {
1120
+ className: cx(field_module_default.field, Select_module_default.root, sizeClass[size], control.invalid && field_module_default.invalid, control.disabled && field_module_default.disabled, className),
1121
+ style,
1122
+ children: [/* @__PURE__ */ jsxs("select", {
1123
+ ref,
1124
+ id: control.id,
1125
+ className: cx(field_module_default.control, Select_module_default.select, current === "" && Select_module_default.placeholder),
1126
+ name,
1127
+ value: current,
1128
+ onChange: (event) => setCurrent(event.target.value),
1129
+ disabled: control.disabled,
1130
+ "aria-label": accessibilityLabel,
1131
+ "aria-describedby": control.describedBy,
1132
+ "aria-invalid": control.invalid ? true : void 0,
1133
+ "aria-required": control.required ? true : void 0,
1134
+ "data-testid": testID,
1135
+ children: [/* @__PURE__ */ jsx("option", {
1136
+ value: "",
1137
+ disabled: true,
1138
+ hidden: true,
1139
+ children: placeholder ?? ""
1140
+ }), options.map((option) => /* @__PURE__ */ jsx("option", {
1141
+ value: option.value,
1142
+ disabled: option.disabled,
1143
+ children: option.label
1144
+ }, option.value))]
1145
+ }), /* @__PURE__ */ jsx("span", {
1146
+ className: Select_module_default.chevron,
1147
+ "aria-hidden": "true",
1148
+ children: /* @__PURE__ */ jsx(Icon, {
1149
+ name: "chevron-down",
1150
+ size: inputIconSize[size],
1151
+ color: control.disabled ? "disabled" : "muted"
1152
+ })
1153
+ })]
1154
+ });
1155
+ }
1156
+ //#endregion
1157
+ //#region src/sheet/Sheet.web.tsx
1158
+ /** Un diálogo anclado al borde inferior (ADR-040). Comparte todo con `Modal` salvo dónde se coloca. */
1159
+ function Sheet(props) {
1160
+ return /* @__PURE__ */ jsx(ModalDialog, {
1161
+ ...props,
1162
+ presentation: "sheet"
1163
+ });
1164
+ }
1165
+ //#endregion
1166
+ //#region src/skeleton/Skeleton.module.css
1167
+ var Skeleton_module_default = {
1168
+ "bar": "sui-bar-KsqoQq",
1169
+ "circle": "sui-circle-KsqoQq",
1170
+ "line": "sui-line-KsqoQq",
1171
+ "pulse": "sui-pulse-KsqoQq",
1172
+ "rectangle": "sui-rectangle-KsqoQq",
1173
+ "root": "sui-root-KsqoQq"
1174
+ };
1175
+ //#endregion
1176
+ //#region src/skeleton/Skeleton.web.tsx
1177
+ const shapeClass = {
1178
+ text: Skeleton_module_default.line,
1179
+ rectangle: Skeleton_module_default.rectangle,
1180
+ circle: Skeleton_module_default.circle
1181
+ };
1182
+ function dimension(value) {
1183
+ return typeof value === "number" ? `${value}px` : value;
1184
+ }
1185
+ /** Decorativo: los lectores de pantalla lo ignoran. */
1186
+ function Skeleton({ shape = "text", width, height, variant = "body", lines = 1, className, style, testID }) {
1187
+ const vars = {};
1188
+ if (width !== void 0) vars["--skeleton-width"] = dimension(width);
1189
+ if (shape === "text") {
1190
+ const spec = textVariantStyles[variant];
1191
+ vars["--skeleton-font-size"] = `var(${cssVariables[`font.size.${spec.size}`]})`;
1192
+ vars["--skeleton-line-height"] = `var(${cssVariables[`font.lineHeight.${spec.size}`]})`;
1193
+ return /* @__PURE__ */ jsx("span", {
1194
+ className: cx(Skeleton_module_default.root, className),
1195
+ style: {
1196
+ ...vars,
1197
+ ...style
1198
+ },
1199
+ "aria-hidden": "true",
1200
+ "data-testid": testID,
1201
+ children: Array.from({ length: Math.max(1, lines) }, (_, index) => /* @__PURE__ */ jsx("span", { className: cx(Skeleton_module_default.bar, shapeClass.text) }, index))
1202
+ });
1203
+ }
1204
+ if (height !== void 0) vars["--skeleton-height"] = dimension(height);
1205
+ return /* @__PURE__ */ jsx("span", {
1206
+ className: cx(Skeleton_module_default.root, Skeleton_module_default.bar, shapeClass[shape], className),
1207
+ style: {
1208
+ ...vars,
1209
+ ...style
1210
+ },
1211
+ "aria-hidden": "true",
1212
+ "data-testid": testID
1213
+ });
1214
+ }
1215
+ //#endregion
486
1216
  //#region src/stack/Stack.module.css
487
1217
  var Stack_module_default = {
488
1218
  "alignCenter": "sui-alignCenter-oAyu1G",
@@ -530,6 +1260,126 @@ function Stack({ direction = "column", gap, align = "stretch", justify = "start"
530
1260
  });
531
1261
  }
532
1262
  //#endregion
1263
+ //#region src/switch/Switch.module.css
1264
+ var Switch_module_default = {
1265
+ "disabled": "sui-disabled-WH6kOa",
1266
+ "input": "sui-input-WH6kOa",
1267
+ "label": "sui-label-WH6kOa",
1268
+ "root": "sui-root-WH6kOa",
1269
+ "thumb": "sui-thumb-WH6kOa",
1270
+ "track": "sui-track-WH6kOa"
1271
+ };
1272
+ //#endregion
1273
+ //#region src/switch/Switch.web.tsx
1274
+ function Switch({ checked, defaultChecked, onCheckedChange, disabled = false, accessibilityLabel, id, name, value, className, style, testID, ref, children }) {
1275
+ return /* @__PURE__ */ jsxs("label", {
1276
+ className: cx(Switch_module_default.root, disabled && Switch_module_default.disabled, className),
1277
+ style,
1278
+ children: [
1279
+ /* @__PURE__ */ jsx("input", {
1280
+ ref,
1281
+ type: "checkbox",
1282
+ role: "switch",
1283
+ className: Switch_module_default.input,
1284
+ id,
1285
+ name,
1286
+ value,
1287
+ ...checked === void 0 ? { defaultChecked } : { checked },
1288
+ onChange: (event) => onCheckedChange?.(event.target.checked),
1289
+ disabled,
1290
+ "aria-label": accessibilityLabel,
1291
+ "data-testid": testID
1292
+ }),
1293
+ /* @__PURE__ */ jsx("span", {
1294
+ className: Switch_module_default.track,
1295
+ "aria-hidden": "true",
1296
+ children: /* @__PURE__ */ jsx("span", { className: Switch_module_default.thumb })
1297
+ }),
1298
+ children === void 0 || children === null ? null : /* @__PURE__ */ jsx("span", {
1299
+ className: Switch_module_default.label,
1300
+ children
1301
+ })
1302
+ ]
1303
+ });
1304
+ }
1305
+ //#endregion
1306
+ //#region src/tabs/Tabs.module.css
1307
+ var Tabs_module_default = {
1308
+ "list": "sui-list-5aOC0W",
1309
+ "panel": "sui-panel-5aOC0W",
1310
+ "root": "sui-root-5aOC0W",
1311
+ "selected": "sui-selected-5aOC0W",
1312
+ "tab": "sui-tab-5aOC0W"
1313
+ };
1314
+ //#endregion
1315
+ //#region src/tabs/Tabs.web.tsx
1316
+ const keyDirection = {
1317
+ ArrowRight: "next",
1318
+ ArrowLeft: "previous",
1319
+ Home: "first",
1320
+ End: "last"
1321
+ };
1322
+ function Tabs({ items, value, defaultValue, onValueChange, accessibilityLabel, className, style, testID }) {
1323
+ const baseId = useId();
1324
+ const [selected, setSelected] = useControllableState({
1325
+ value,
1326
+ defaultValue: defaultValue ?? firstEnabledTab(items) ?? "",
1327
+ onChange: onValueChange
1328
+ });
1329
+ const tabs = useRef(/* @__PURE__ */ new Map());
1330
+ const selectedIndex = items.findIndex((item) => item.value === selected);
1331
+ const active = items[selectedIndex];
1332
+ const panelId = `${baseId}-panel`;
1333
+ function handleKeyDown(event) {
1334
+ const direction = keyDirection[event.key];
1335
+ if (direction === void 0) return;
1336
+ event.preventDefault();
1337
+ const next = getTabInDirection(items, selected, direction);
1338
+ setSelected(next);
1339
+ tabs.current.get(next)?.focus();
1340
+ }
1341
+ return /* @__PURE__ */ jsxs("div", {
1342
+ className: cx(Tabs_module_default.root, className),
1343
+ style,
1344
+ "data-testid": testID,
1345
+ children: [/* @__PURE__ */ jsx("div", {
1346
+ role: "tablist",
1347
+ "aria-label": accessibilityLabel,
1348
+ className: Tabs_module_default.list,
1349
+ children: items.map((item, index) => {
1350
+ const isSelected = item.value === selected;
1351
+ return /* @__PURE__ */ jsxs("button", {
1352
+ ref: (node) => {
1353
+ if (node === null) tabs.current.delete(item.value);
1354
+ else tabs.current.set(item.value, node);
1355
+ },
1356
+ type: "button",
1357
+ role: "tab",
1358
+ id: `${baseId}-tab-${index}`,
1359
+ "aria-selected": isSelected,
1360
+ "aria-controls": isSelected && item.content !== void 0 ? panelId : void 0,
1361
+ tabIndex: isSelected ? 0 : -1,
1362
+ disabled: item.disabled,
1363
+ className: cx(Tabs_module_default.tab, isSelected && Tabs_module_default.selected),
1364
+ onClick: () => setSelected(item.value),
1365
+ onKeyDown: handleKeyDown,
1366
+ children: [item.icon === void 0 ? null : /* @__PURE__ */ jsx(Icon, {
1367
+ name: item.icon,
1368
+ size: "sm"
1369
+ }), item.label]
1370
+ }, item.value);
1371
+ })
1372
+ }), active?.content === void 0 || active.content === null ? null : /* @__PURE__ */ jsx("div", {
1373
+ role: "tabpanel",
1374
+ id: panelId,
1375
+ "aria-labelledby": `${baseId}-tab-${selectedIndex}`,
1376
+ tabIndex: 0,
1377
+ className: Tabs_module_default.panel,
1378
+ children: active.content
1379
+ })]
1380
+ });
1381
+ }
1382
+ //#endregion
533
1383
  //#region src/text/Text.module.css
534
1384
  var Text_module_default = {
535
1385
  "center": "sui-center-ca3VdW",
@@ -580,6 +1430,139 @@ function Text({ variant = "body", color = "primary", align, truncate = false, as
580
1430
  });
581
1431
  }
582
1432
  //#endregion
1433
+ //#region src/text-area/TextArea.module.css
1434
+ var TextArea_module_default = { "root": "sui-root-c4Gv8W" };
1435
+ //#endregion
1436
+ //#region src/text-area/TextArea.web.tsx
1437
+ function TextArea({ value, defaultValue, onChangeText, placeholder, rows = 3, disabled, readOnly = false, invalid, required, maxLength, onFocus, onBlur, accessibilityLabel, id, name, className, style, testID, ref }) {
1438
+ const control = useFormFieldControl({
1439
+ id,
1440
+ invalid,
1441
+ disabled,
1442
+ required
1443
+ });
1444
+ return /* @__PURE__ */ jsx("textarea", {
1445
+ ref,
1446
+ id: control.id,
1447
+ className: cx(field_module_default.field, TextArea_module_default.root, control.invalid && field_module_default.invalid, readOnly && field_module_default.readOnly, control.disabled && field_module_default.disabled, className),
1448
+ style,
1449
+ rows,
1450
+ name,
1451
+ ...value === void 0 ? { defaultValue } : { value },
1452
+ onChange: (event) => onChangeText?.(event.target.value),
1453
+ placeholder,
1454
+ disabled: control.disabled,
1455
+ readOnly,
1456
+ maxLength,
1457
+ "aria-label": accessibilityLabel,
1458
+ "aria-describedby": control.describedBy,
1459
+ "aria-invalid": control.invalid ? true : void 0,
1460
+ "aria-required": control.required ? true : void 0,
1461
+ "data-testid": testID,
1462
+ onFocus,
1463
+ onBlur
1464
+ });
1465
+ }
1466
+ //#endregion
1467
+ //#region src/toast/Toast.module.css
1468
+ var Toast_module_default = {
1469
+ "actions": "sui-actions-8N5mCG",
1470
+ "content": "sui-content-8N5mCG",
1471
+ "description": "sui-description-8N5mCG",
1472
+ "enter": "sui-enter-8N5mCG",
1473
+ "icon": "sui-icon-8N5mCG",
1474
+ "root": "sui-root-8N5mCG",
1475
+ "title": "sui-title-8N5mCG",
1476
+ "viewport": "sui-viewport-8N5mCG"
1477
+ };
1478
+ //#endregion
1479
+ //#region src/toast/Toast.web.tsx
1480
+ /**
1481
+ * La tarjeta de un toast. Es interna: los toasts se muestran con `useToast` y los
1482
+ * pinta `UIProvider` (ADR-039).
1483
+ */
1484
+ function Toast({ toast, onDismiss }) {
1485
+ const { tone, title, description, action, closeLabel } = toast;
1486
+ return /* @__PURE__ */ jsxs("div", {
1487
+ className: Toast_module_default.root,
1488
+ role: feedbackUrgent[tone] ? "alert" : "status",
1489
+ children: [
1490
+ /* @__PURE__ */ jsx("span", {
1491
+ className: Toast_module_default.icon,
1492
+ children: /* @__PURE__ */ jsx(Icon, {
1493
+ name: feedbackIcon[tone],
1494
+ size: "md",
1495
+ color: tone
1496
+ })
1497
+ }),
1498
+ /* @__PURE__ */ jsxs("div", {
1499
+ className: Toast_module_default.content,
1500
+ children: [/* @__PURE__ */ jsx("p", {
1501
+ className: Toast_module_default.title,
1502
+ children: title
1503
+ }), description === void 0 ? null : /* @__PURE__ */ jsx("p", {
1504
+ className: Toast_module_default.description,
1505
+ children: description
1506
+ })]
1507
+ }),
1508
+ action === void 0 && closeLabel === void 0 ? null : /* @__PURE__ */ jsxs("div", {
1509
+ className: Toast_module_default.actions,
1510
+ children: [action === void 0 ? null : /* @__PURE__ */ jsx(Button, {
1511
+ variant: "ghost",
1512
+ size: "sm",
1513
+ onPress: () => {
1514
+ action.onPress();
1515
+ onDismiss();
1516
+ },
1517
+ children: action.label
1518
+ }), closeLabel === void 0 ? null : /* @__PURE__ */ jsx(IconButton, {
1519
+ icon: "x",
1520
+ label: closeLabel,
1521
+ size: "sm",
1522
+ variant: "ghost",
1523
+ onPress: onDismiss
1524
+ })]
1525
+ })
1526
+ ]
1527
+ });
1528
+ }
1529
+ //#endregion
1530
+ //#region src/toast/ToastViewport.web.tsx
1531
+ /**
1532
+ * La zona donde aparecen los toasts de un `UIProvider` (ADR-039). Existe siempre,
1533
+ * aunque esté vacía: así los lectores de pantalla anuncian cada toast al llegar.
1534
+ */
1535
+ function ToastViewport({ store }) {
1536
+ const toasts = useSyncExternalStore(store.subscribe, store.getSnapshot, store.getSnapshot);
1537
+ return /* @__PURE__ */ jsx("div", {
1538
+ className: Toast_module_default.viewport,
1539
+ "aria-live": "polite",
1540
+ onMouseEnter: store.pause,
1541
+ onMouseLeave: store.resume,
1542
+ onFocus: store.pause,
1543
+ onBlur: store.resume,
1544
+ children: toasts.map((toast) => /* @__PURE__ */ jsx(Toast, {
1545
+ toast,
1546
+ onDismiss: () => store.dismiss(toast.id)
1547
+ }, toast.id))
1548
+ });
1549
+ }
1550
+ //#endregion
1551
+ //#region src/toast/useToastHost.ts
1552
+ /**
1553
+ * La cola de toasts de un `UIProvider` (ADR-039). Uno anidado, por ejemplo para cambiar
1554
+ * de marca en una sección, reutiliza la del de fuera: solo hay una zona de avisos por app.
1555
+ */
1556
+ function useToastHost() {
1557
+ const outer = useContext(ToastContext);
1558
+ const [own] = useState(() => outer === null ? createToastStore() : null);
1559
+ useEffect(() => () => own?.dismiss(), [own]);
1560
+ return {
1561
+ store: outer ?? own ?? createToastStore(),
1562
+ own: outer === null ? own : null
1563
+ };
1564
+ }
1565
+ //#endregion
583
1566
  //#region src/ui-provider/UIProvider.module.css
584
1567
  var UIProvider_module_default = { "root": "sui-root-QoB9YG" };
585
1568
  //#endregion
@@ -603,7 +1586,8 @@ function useSystemColorScheme() {
603
1586
  }
604
1587
  /**
605
1588
  * Activa tema y marca para todo lo que envuelve (ADR-010). Pone `data-theme` y
606
- * `data-brand` en un contenedor sin caja propia; `tokens.css` hace el resto.
1589
+ * `data-brand` en un contenedor sin caja propia; `tokens.css` hace el resto. También
1590
+ * guarda la cola de toasts y los pinta (ADR-039).
607
1591
  */
608
1592
  function UIProvider({ theme = "system", brand, children }) {
609
1593
  const system = useSystemColorScheme();
@@ -612,15 +1596,19 @@ function UIProvider({ theme = "system", brand, children }) {
612
1596
  system,
613
1597
  brand
614
1598
  ]);
1599
+ const toasts = useToastHost();
615
1600
  return /* @__PURE__ */ jsx(UIContext.Provider, {
616
1601
  value,
617
- children: /* @__PURE__ */ jsx("div", {
618
- className: UIProvider_module_default.root,
619
- "data-theme": value.colorScheme,
620
- "data-brand": brand,
621
- children
1602
+ children: /* @__PURE__ */ jsx(ToastContext.Provider, {
1603
+ value: toasts.store,
1604
+ children: /* @__PURE__ */ jsxs("div", {
1605
+ className: UIProvider_module_default.root,
1606
+ "data-theme": value.colorScheme,
1607
+ "data-brand": brand,
1608
+ children: [children, toasts.own === null ? null : /* @__PURE__ */ jsx(ToastViewport, { store: toasts.own })]
1609
+ })
622
1610
  })
623
1611
  });
624
1612
  }
625
1613
  //#endregion
626
- export { Badge, Box, Button, Icon, Spinner, Stack, Text, UIProvider, useBrand, useColorScheme, useTheme };
1614
+ export { Alert, Badge, Box, Button, Card, Checkbox, Divider, FormField, Icon, IconButton, Input, Link, Modal, Select, Sheet, Skeleton, Spinner, Stack, Switch, Tabs, Text, TextArea, UIProvider, useBrand, useColorScheme, useTheme, useToast };