pixelon 0.9.3 → 0.9.4

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.esm.js CHANGED
@@ -7343,7 +7343,7 @@ const Input$1 = forwardRef(
7343
7343
  );
7344
7344
  Input$1.displayName = "Input";
7345
7345
 
7346
- const sinTildes = (s) => s.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "");
7346
+ const sinTildes$2 = (s) => s.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "");
7347
7347
  const Select$1 = forwardRef(
7348
7348
  ({
7349
7349
  options = [],
@@ -7392,7 +7392,7 @@ const Select$1 = forwardRef(
7392
7392
  const selectorRef = useRef(null);
7393
7393
  const [dropdownPosition, setDropdownPosition] = useState(null);
7394
7394
  const filteredOptions = showSearch && searchValue ? options.filter(
7395
- (option) => filterOption ? filterOption(searchValue, option) : sinTildes(option.label).includes(sinTildes(searchValue))
7395
+ (option) => filterOption ? filterOption(searchValue, option) : sinTildes$2(option.label).includes(sinTildes$2(searchValue))
7396
7396
  ) : options;
7397
7397
  const isOptionSelected = (option) => {
7398
7398
  if (mode === "multiple") {
@@ -12320,6 +12320,442 @@ const CurrencyDisplay = ({
12320
12320
  };
12321
12321
  CurrencyDisplay.displayName = "CurrencyDisplay";
12322
12322
 
12323
+ const CARD_VARIANTS = {
12324
+ /** Con sombra: flota sobre el contenido (hojas, diálogos, paneles). */
12325
+ ELEVATED: "elevated"};
12326
+ const CARD_PADDINGS = {
12327
+ MEDIUM: "medium",
12328
+ LARGE: "large"
12329
+ };
12330
+ const CARD_RADII = {
12331
+ NONE: "none",
12332
+ LARGE: "large"
12333
+ };
12334
+
12335
+ const BASE = `${COMPONENT_PREFIX}card`;
12336
+ const Card = React.forwardRef(
12337
+ ({
12338
+ variant = CARD_VARIANTS.ELEVATED,
12339
+ padding = CARD_PADDINGS.MEDIUM,
12340
+ radius = CARD_RADII.LARGE,
12341
+ fullWidth = false,
12342
+ className = "",
12343
+ children,
12344
+ ...rest
12345
+ }, ref) => {
12346
+ const classes = [
12347
+ BASE,
12348
+ `${BASE}--${variant}`,
12349
+ `${BASE}--padding-${padding}`,
12350
+ `${BASE}--radius-${radius}`,
12351
+ fullWidth ? `${BASE}--full-width` : "",
12352
+ className
12353
+ ].filter(Boolean).join(" ");
12354
+ return /* @__PURE__ */ jsx("div", { ref, className: classes, ...rest, children });
12355
+ }
12356
+ );
12357
+ Card.displayName = "Card";
12358
+
12359
+ const CLASS$j = "px-lumi-bottom-sheet";
12360
+ const BottomSheet = ({
12361
+ open,
12362
+ children,
12363
+ onClose,
12364
+ showGrabber = true,
12365
+ closeOnBackdrop = false,
12366
+ closeOnEscape = true,
12367
+ ariaLabelledBy,
12368
+ className = ""
12369
+ }) => {
12370
+ useEffect(() => {
12371
+ if (!open) return;
12372
+ const onKey = (e) => {
12373
+ if (e.key !== "Escape" || !closeOnEscape) return;
12374
+ e.stopPropagation();
12375
+ onClose?.();
12376
+ };
12377
+ document.addEventListener("keydown", onKey, true);
12378
+ const previous = document.body.style.overflow;
12379
+ document.body.style.overflow = "hidden";
12380
+ return () => {
12381
+ document.removeEventListener("keydown", onKey, true);
12382
+ document.body.style.overflow = previous;
12383
+ };
12384
+ }, [open, closeOnEscape, onClose]);
12385
+ if (!open) return null;
12386
+ return createPortal(
12387
+ /* @__PURE__ */ jsxs(
12388
+ "div",
12389
+ {
12390
+ className: [CLASS$j, className].filter(Boolean).join(" "),
12391
+ role: "dialog",
12392
+ "aria-modal": "true",
12393
+ "aria-labelledby": ariaLabelledBy,
12394
+ children: [
12395
+ /* @__PURE__ */ jsx(
12396
+ "div",
12397
+ {
12398
+ className: `${CLASS$j}__backdrop`,
12399
+ "aria-hidden": "true",
12400
+ onClick: closeOnBackdrop ? onClose : void 0
12401
+ }
12402
+ ),
12403
+ /* @__PURE__ */ jsxs(
12404
+ Card,
12405
+ {
12406
+ className: `${CLASS$j}__sheet`,
12407
+ padding: CARD_PADDINGS.LARGE,
12408
+ radius: CARD_RADII.NONE,
12409
+ fullWidth: true,
12410
+ children: [
12411
+ showGrabber && /* @__PURE__ */ jsx("div", { className: `${CLASS$j}__grabber`, "aria-hidden": "true" }),
12412
+ children
12413
+ ]
12414
+ }
12415
+ )
12416
+ ]
12417
+ }
12418
+ ),
12419
+ document.body
12420
+ );
12421
+ };
12422
+ BottomSheet.displayName = "BottomSheet";
12423
+
12424
+ const PHONE_COUNTRIES = [
12425
+ { code: "CO", name: "Colombia", dialCode: "+57", digits: 10 },
12426
+ { code: "EC", name: "Ecuador", dialCode: "+593", digits: 9 },
12427
+ { code: "PE", name: "Per\xFA", dialCode: "+51", digits: 9 },
12428
+ { code: "VE", name: "Venezuela", dialCode: "+58", digits: 10 },
12429
+ { code: "PA", name: "Panam\xE1", dialCode: "+507", digits: 8 },
12430
+ { code: "MX", name: "M\xE9xico", dialCode: "+52", digits: 10 },
12431
+ { code: "AR", name: "Argentina", dialCode: "+54", digits: 10 },
12432
+ { code: "CL", name: "Chile", dialCode: "+56", digits: 9 },
12433
+ { code: "BR", name: "Brasil", dialCode: "+55", digits: 11 },
12434
+ { code: "CR", name: "Costa Rica", dialCode: "+506", digits: 8 },
12435
+ { code: "US", name: "Estados Unidos", dialCode: "+1", digits: 10 },
12436
+ { code: "ES", name: "Espa\xF1a", dialCode: "+34", digits: 9 }
12437
+ ];
12438
+ const DEFAULT_PHONE_COUNTRY = "CO";
12439
+ function flagOf(code) {
12440
+ const c = (code || "").toUpperCase();
12441
+ if (!/^[A-Z]{2}$/.test(c)) return "";
12442
+ return [...c].map((ch) => String.fromCodePoint(127462 + ch.charCodeAt(0) - 65)).join("");
12443
+ }
12444
+ function splitPhone(value, countries, defaultCountry) {
12445
+ const porDefecto = countries.find((c) => c.code === defaultCountry) ?? countries[0];
12446
+ const v = (value ?? "").replace(/[^0-9+]/g, "");
12447
+ if (v.startsWith("+")) {
12448
+ const d = v.slice(1);
12449
+ const match = countries.filter((c) => d.startsWith(c.dialCode.slice(1))).sort((a, b) => b.dialCode.length - a.dialCode.length)[0];
12450
+ if (match) return { country: match, digits: d.slice(match.dialCode.length - 1) };
12451
+ }
12452
+ return { country: porDefecto, digits: v.replace(/\D/g, "") };
12453
+ }
12454
+
12455
+ const CLASS$i = "px-lumi-phone-input";
12456
+ function sinTildes$1(s) {
12457
+ return s.normalize("NFD").replace(/[̀-ͯ]/g, "").toLowerCase();
12458
+ }
12459
+ const PhoneInput = React.forwardRef(
12460
+ ({
12461
+ value,
12462
+ onChange,
12463
+ onBlur,
12464
+ label,
12465
+ placeholder,
12466
+ disabled,
12467
+ readOnly,
12468
+ error,
12469
+ countries = PHONE_COUNTRIES,
12470
+ defaultCountry = DEFAULT_PHONE_COUNTRY,
12471
+ name,
12472
+ id,
12473
+ className,
12474
+ labels
12475
+ }, ref) => {
12476
+ const [paisElegido, setPaisElegido] = useState(defaultCountry);
12477
+ const [abierto, setAbierto] = useState(false);
12478
+ const [busqueda, setBusqueda] = useState("");
12479
+ const { country, digits } = splitPhone(value, countries, value ? defaultCountry : paisElegido);
12480
+ const pais = value ? country : countries.find((c) => c.code === paisElegido) ?? country;
12481
+ const tope = pais.digits ?? 15;
12482
+ const bloqueado = disabled || readOnly;
12483
+ useEffect(() => {
12484
+ if (!abierto) setBusqueda("");
12485
+ }, [abierto]);
12486
+ const visibles = useMemo(() => {
12487
+ const q = sinTildes$1(busqueda.trim());
12488
+ if (!q) return countries;
12489
+ return countries.filter(
12490
+ (c) => sinTildes$1(c.name).includes(q) || c.dialCode.includes(q) || c.code.toLowerCase() === q
12491
+ );
12492
+ }, [busqueda, countries]);
12493
+ const emitir = (c, d) => {
12494
+ onChange?.(d ? `${c.dialCode}${d}` : "");
12495
+ };
12496
+ const handleDigits = (e) => {
12497
+ const d = e.target.value.replace(/\D/g, "").slice(0, tope);
12498
+ emitir(pais, d);
12499
+ };
12500
+ const elegir = (c) => {
12501
+ setPaisElegido(c.code);
12502
+ emitir(c, digits.slice(0, c.digits ?? 15));
12503
+ setAbierto(false);
12504
+ };
12505
+ const tituloId = `${id ?? name ?? "phone"}-pais-titulo`;
12506
+ return /* @__PURE__ */ jsxs("div", { className: [CLASS$i, error && `${CLASS$i}--error`, bloqueado && `${CLASS$i}--disabled`, className].filter(Boolean).join(" "), children: [
12507
+ /* @__PURE__ */ jsxs(
12508
+ "button",
12509
+ {
12510
+ type: "button",
12511
+ className: `${CLASS$i}__country`,
12512
+ "aria-label": `${labels?.pickCountry ?? "Pa\xEDs del celular"}: ${pais.name} ${pais.dialCode}`,
12513
+ "aria-haspopup": "dialog",
12514
+ "aria-expanded": abierto,
12515
+ disabled: bloqueado,
12516
+ onClick: () => setAbierto(true),
12517
+ children: [
12518
+ /* @__PURE__ */ jsx("span", { className: `${CLASS$i}__flag`, "aria-hidden": "true", children: flagOf(pais.code) }),
12519
+ /* @__PURE__ */ jsx("span", { className: `${CLASS$i}__code`, children: pais.dialCode }),
12520
+ /* @__PURE__ */ jsx("span", { className: `${CLASS$i}__caret`, "aria-hidden": "true", children: "\u25BE" })
12521
+ ]
12522
+ }
12523
+ ),
12524
+ /* @__PURE__ */ jsx("div", { className: `${CLASS$i}__digits`, children: /* @__PURE__ */ jsx(
12525
+ Input$1,
12526
+ {
12527
+ ref,
12528
+ id,
12529
+ name,
12530
+ type: "tel",
12531
+ inputMode: "numeric",
12532
+ autoComplete: "tel-national",
12533
+ label,
12534
+ placeholder,
12535
+ value: digits,
12536
+ onChange: handleDigits,
12537
+ onBlur,
12538
+ disabled,
12539
+ readOnly,
12540
+ error
12541
+ }
12542
+ ) }),
12543
+ /* @__PURE__ */ jsxs(
12544
+ BottomSheet,
12545
+ {
12546
+ open: abierto,
12547
+ onClose: () => setAbierto(false),
12548
+ showGrabber: true,
12549
+ closeOnBackdrop: true,
12550
+ ariaLabelledBy: tituloId,
12551
+ className: `${CLASS$i}__sheet`,
12552
+ children: [
12553
+ /* @__PURE__ */ jsxs("div", { className: `${CLASS$i}__sheet-head`, children: [
12554
+ /* @__PURE__ */ jsx("h2", { id: tituloId, className: `${CLASS$i}__sheet-title`, children: labels?.pickCountry ?? "Pa\xEDs del celular" }),
12555
+ /* @__PURE__ */ jsx(
12556
+ "input",
12557
+ {
12558
+ className: `${CLASS$i}__search`,
12559
+ type: "search",
12560
+ value: busqueda,
12561
+ onChange: (e) => setBusqueda(e.target.value),
12562
+ placeholder: labels?.searchPlaceholder ?? "Buscar pa\xEDs o indicativo",
12563
+ autoComplete: "off",
12564
+ "aria-label": labels?.searchPlaceholder ?? "Buscar pa\xEDs o indicativo"
12565
+ }
12566
+ )
12567
+ ] }),
12568
+ /* @__PURE__ */ jsxs("ul", { className: `${CLASS$i}__list`, role: "listbox", "aria-labelledby": tituloId, children: [
12569
+ visibles.map((c) => {
12570
+ const activo = c.code === pais.code;
12571
+ return /* @__PURE__ */ jsx("li", { role: "option", "aria-selected": activo, children: /* @__PURE__ */ jsxs(
12572
+ "button",
12573
+ {
12574
+ type: "button",
12575
+ className: [`${CLASS$i}__option`, activo && `${CLASS$i}__option--selected`].filter(Boolean).join(" "),
12576
+ onClick: () => elegir(c),
12577
+ children: [
12578
+ /* @__PURE__ */ jsx("span", { className: `${CLASS$i}__flag`, "aria-hidden": "true", children: flagOf(c.code) }),
12579
+ /* @__PURE__ */ jsx("span", { className: `${CLASS$i}__option-name`, children: c.name }),
12580
+ /* @__PURE__ */ jsx("span", { className: `${CLASS$i}__option-code`, children: c.dialCode })
12581
+ ]
12582
+ }
12583
+ ) }, c.code);
12584
+ }),
12585
+ visibles.length === 0 && /* @__PURE__ */ jsx("li", { className: `${CLASS$i}__empty`, children: labels?.noResults ?? "Ning\xFAn pa\xEDs coincide." })
12586
+ ] })
12587
+ ]
12588
+ }
12589
+ )
12590
+ ] });
12591
+ }
12592
+ );
12593
+ PhoneInput.displayName = "PhoneInput";
12594
+
12595
+ const CLASS$h = "px-lumi-sheet-select";
12596
+ function sinTildes(s) {
12597
+ return s.normalize("NFD").replace(/[̀-ͯ]/g, "").toLowerCase();
12598
+ }
12599
+ const SheetSelect = React.forwardRef(
12600
+ ({
12601
+ value,
12602
+ onChange,
12603
+ onBlur,
12604
+ options,
12605
+ label,
12606
+ placeholder,
12607
+ disabled,
12608
+ readOnly,
12609
+ error,
12610
+ searchable,
12611
+ notFoundContent,
12612
+ sheetTitle,
12613
+ searchPlaceholder,
12614
+ name,
12615
+ id,
12616
+ className
12617
+ }, ref) => {
12618
+ const [abierto, setAbierto] = useState(false);
12619
+ const [busqueda, setBusqueda] = useState("");
12620
+ const bloqueado = disabled || readOnly;
12621
+ const elegida = options.find((o) => String(o.value) === String(value ?? ""));
12622
+ const conBuscador = searchable ?? true;
12623
+ useEffect(() => {
12624
+ if (!abierto) setBusqueda("");
12625
+ }, [abierto]);
12626
+ const visibles = useMemo(() => {
12627
+ const q = sinTildes(busqueda.trim());
12628
+ if (!q) return options;
12629
+ return options.filter((o) => sinTildes(o.label).includes(q) || sinTildes(o.hint ?? "").includes(q));
12630
+ }, [busqueda, options]);
12631
+ const abrir = () => {
12632
+ if (!bloqueado) setAbierto(true);
12633
+ };
12634
+ const elegir = (o) => {
12635
+ onChange?.(o.value);
12636
+ setAbierto(false);
12637
+ onBlur?.();
12638
+ };
12639
+ const tituloId = `${id ?? name ?? "sheet-select"}-titulo`;
12640
+ const titulo = sheetTitle ?? label?.replace(/\s\*$/, "") ?? "";
12641
+ return /* @__PURE__ */ jsxs("div", { className: [CLASS$h, bloqueado && `${CLASS$h}--disabled`, className].filter(Boolean).join(" "), children: [
12642
+ /* @__PURE__ */ jsx(
12643
+ Input$1,
12644
+ {
12645
+ ref,
12646
+ id,
12647
+ name,
12648
+ label,
12649
+ placeholder: placeholder ?? "Seleccionar...",
12650
+ value: elegida?.label ?? "",
12651
+ readOnly: true,
12652
+ disabled,
12653
+ error,
12654
+ onClick: abrir,
12655
+ onKeyDown: (e) => {
12656
+ if (e.key === "Enter" || e.key === " " || e.key === "ArrowDown") {
12657
+ e.preventDefault();
12658
+ abrir();
12659
+ }
12660
+ },
12661
+ role: "combobox",
12662
+ "aria-haspopup": "dialog",
12663
+ "aria-expanded": abierto,
12664
+ className: `${CLASS$h}__field`,
12665
+ suffix: /* @__PURE__ */ jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: /* @__PURE__ */ jsx("path", { d: "M6 9l6 6 6-6" }) }),
12666
+ onSuffixClick: abrir,
12667
+ suffixAriaLabel: titulo ? `Elegir ${titulo}` : "Elegir"
12668
+ }
12669
+ ),
12670
+ /* @__PURE__ */ jsxs(
12671
+ BottomSheet,
12672
+ {
12673
+ open: abierto,
12674
+ onClose: () => setAbierto(false),
12675
+ showGrabber: true,
12676
+ closeOnBackdrop: true,
12677
+ ariaLabelledBy: tituloId,
12678
+ className: `${CLASS$h}__sheet`,
12679
+ children: [
12680
+ /* @__PURE__ */ jsxs("div", { className: `${CLASS$h}__sheet-head`, children: [
12681
+ /* @__PURE__ */ jsx("h2", { id: tituloId, className: `${CLASS$h}__sheet-title`, children: titulo }),
12682
+ conBuscador && /* @__PURE__ */ jsx(
12683
+ "input",
12684
+ {
12685
+ className: `${CLASS$h}__search`,
12686
+ type: "search",
12687
+ value: busqueda,
12688
+ onChange: (e) => setBusqueda(e.target.value),
12689
+ placeholder: searchPlaceholder ?? "Buscar",
12690
+ autoComplete: "off",
12691
+ "aria-label": searchPlaceholder ?? "Buscar"
12692
+ }
12693
+ )
12694
+ ] }),
12695
+ /* @__PURE__ */ jsxs("ul", { className: `${CLASS$h}__list`, role: "listbox", "aria-labelledby": tituloId, children: [
12696
+ visibles.map((o) => {
12697
+ const activo = elegida?.value === o.value;
12698
+ return /* @__PURE__ */ jsx("li", { role: "option", "aria-selected": activo, children: /* @__PURE__ */ jsxs(
12699
+ "button",
12700
+ {
12701
+ type: "button",
12702
+ className: [`${CLASS$h}__option`, activo && `${CLASS$h}__option--selected`].filter(Boolean).join(" "),
12703
+ onClick: () => elegir(o),
12704
+ children: [
12705
+ /* @__PURE__ */ jsxs("span", { className: `${CLASS$h}__option-text`, children: [
12706
+ /* @__PURE__ */ jsx("span", { className: `${CLASS$h}__option-label`, children: o.label }),
12707
+ o.hint && /* @__PURE__ */ jsx("span", { className: `${CLASS$h}__option-hint`, children: o.hint })
12708
+ ] }),
12709
+ activo && /* @__PURE__ */ jsx("svg", { className: `${CLASS$h}__check`, width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: /* @__PURE__ */ jsx("path", { d: "M20 6L9 17l-5-5" }) })
12710
+ ]
12711
+ }
12712
+ ) }, o.value);
12713
+ }),
12714
+ visibles.length === 0 && /* @__PURE__ */ jsx("li", { className: `${CLASS$h}__empty`, children: options.length === 0 ? notFoundContent ?? "No hay opciones disponibles." : "Nada coincide." })
12715
+ ] })
12716
+ ]
12717
+ }
12718
+ )
12719
+ ] });
12720
+ }
12721
+ );
12722
+ SheetSelect.displayName = "SheetSelect";
12723
+
12724
+ const SANITIZE_PRESETS = {
12725
+ /** «abc-123 » → «ABC123». */
12726
+ plate: ["noControl", "alnum", "upper", { maxLength: 8 }],
12727
+ /** «+57 (300) 123-4567» → «573001234567». */
12728
+ phone: ["digits", { maxLength: 15 }],
12729
+ /** «1.000.000» → «1000000». */
12730
+ id: ["digits", { maxLength: 15 }],
12731
+ /** Un nombre: sin control, espacios colapsados, recortado al enviar. */
12732
+ name: ["noControl", "collapseSpaces", { maxLength: 150 }, "trim"],
12733
+ /** Una nota corta. */
12734
+ note: ["noControl", "collapseSpaces", { maxLength: 80 }, "trim"]
12735
+ };
12736
+ const CONTROL = /[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]/g;
12737
+ function expandir(spec) {
12738
+ const lista = Array.isArray(spec) ? spec : [spec];
12739
+ return lista.flatMap((r) => typeof r === "object" && "preset" in r ? SANITIZE_PRESETS[r.preset] ?? [] : [r]);
12740
+ }
12741
+ function aplicar(s, r, live) {
12742
+ if (r === "trim") return live ? s : s.trim();
12743
+ if (r === "upper") return s.toUpperCase();
12744
+ if (r === "lower") return s.toLowerCase();
12745
+ if (r === "digits") return s.replace(/[^0-9]/g, "");
12746
+ if (r === "alnum") return s.replace(/[^A-Za-z0-9]/g, "");
12747
+ if (r === "noControl") return s.replace(CONTROL, "");
12748
+ if (r === "collapseSpaces") return s.replace(/\s{2,}/g, " ");
12749
+ if ("maxLength" in r) return s.slice(0, r.maxLength);
12750
+ if ("strip" in r) return s.replace(new RegExp(r.strip, "g"), "");
12751
+ return s;
12752
+ }
12753
+ function sanitize(value, spec, options = {}) {
12754
+ if (!spec || value === null || value === void 0) return value;
12755
+ if (typeof value !== "string") return value;
12756
+ return expandir(spec).reduce((s, r) => aplicar(s, r, !!options.live), value);
12757
+ }
12758
+
12323
12759
  const renderField = ({
12324
12760
  field,
12325
12761
  control,
@@ -12407,10 +12843,14 @@ const renderField = ({
12407
12843
  }, children: formatValue() })
12408
12844
  ] });
12409
12845
  }
12846
+ const onChangeLimpio = field.sanitize ? (e) => {
12847
+ const crudo = e && typeof e === "object" && "target" in e ? e.target.value : e;
12848
+ onChange(sanitize(crudo, field.sanitize, { live: true }));
12849
+ } : onChange;
12410
12850
  const commonProps = {
12411
12851
  ...getCommonProps(),
12412
12852
  value: value ?? "",
12413
- onChange,
12853
+ onChange: onChangeLimpio,
12414
12854
  onBlur,
12415
12855
  ref,
12416
12856
  error: error?.message
@@ -12435,8 +12875,26 @@ const renderField = ({
12435
12875
  return /* @__PURE__ */ jsx(Input$1, { ...commonProps, type: "email" });
12436
12876
  case "INPUT_PASSWORD":
12437
12877
  return /* @__PURE__ */ jsx(Input$1, { ...commonProps, type: "password" });
12438
- case "INPUT_PHONE":
12439
- return /* @__PURE__ */ jsx(Input$1, { ...commonProps, type: "tel" });
12878
+ case "INPUT_PHONE": {
12879
+ const { countries, defaultCountry } = uiProps ?? {};
12880
+ return /* @__PURE__ */ jsx(
12881
+ PhoneInput,
12882
+ {
12883
+ ref,
12884
+ name,
12885
+ label: fieldLabel,
12886
+ placeholder,
12887
+ disabled: isReadOnly,
12888
+ readOnly: isReadOnly,
12889
+ error: error?.message,
12890
+ value: typeof value === "string" ? value : "",
12891
+ onChange: (v) => onChange(v),
12892
+ onBlur,
12893
+ countries,
12894
+ defaultCountry
12895
+ }
12896
+ );
12897
+ }
12440
12898
  case "INPUT_CURRENCY":
12441
12899
  return /* @__PURE__ */ jsx(
12442
12900
  Input$1,
@@ -12462,6 +12920,30 @@ const renderField = ({
12462
12920
  case "TEXTAREA":
12463
12921
  return /* @__PURE__ */ jsx(Input$1, { ...commonProps, type: "textarea" });
12464
12922
  case "SELECT":
12923
+ if (uiProps?.picker === "sheet") {
12924
+ return /* @__PURE__ */ jsx(
12925
+ SheetSelect,
12926
+ {
12927
+ ref,
12928
+ name,
12929
+ label: fieldLabel,
12930
+ placeholder,
12931
+ disabled: isReadOnly,
12932
+ readOnly: isReadOnly,
12933
+ error: error?.message,
12934
+ value: value == null ? "" : String(value),
12935
+ onChange: (v) => onChange(v),
12936
+ onBlur,
12937
+ options: (options || []).map((o) => ({
12938
+ value: String(o.value),
12939
+ label: String(o.label),
12940
+ hint: o.hint
12941
+ })),
12942
+ searchable: uiProps?.showSearch,
12943
+ notFoundContent: uiProps?.notFoundContent
12944
+ }
12945
+ );
12946
+ }
12465
12947
  return /* @__PURE__ */ jsx(
12466
12948
  Select$1,
12467
12949
  {
@@ -12591,8 +13073,11 @@ const transformIncomingValues = (values, fields) => {
12591
13073
  const transformOutgoingValues = (values, fields) => {
12592
13074
  const transformed = { ...values };
12593
13075
  fields.forEach((field) => {
13076
+ if (field.sanitize && values[field.name] !== void 0) {
13077
+ transformed[field.name] = sanitize(values[field.name], field.sanitize);
13078
+ }
12594
13079
  if (field.transformOnSubmit && values[field.name] !== void 0) {
12595
- transformed[field.name] = field.transformOnSubmit(values[field.name]);
13080
+ transformed[field.name] = field.transformOnSubmit(transformed[field.name]);
12596
13081
  }
12597
13082
  });
12598
13083
  return transformed;
@@ -13181,24 +13666,28 @@ function mapFieldsToFormFields(fields, mode) {
13181
13666
  placeholder: field.placeholder,
13182
13667
  uiProps: field.uiProps,
13183
13668
  transformOnSubmit: field.parseValue,
13184
- gridSpan: field.gridSpan
13669
+ gridSpan: field.gridSpan,
13185
13670
  // SPEC-131 T7
13671
+ showIf: field.showIf,
13672
+ // SPEC-181
13673
+ sanitize: field.sanitize
13674
+ // SPEC-183
13186
13675
  }));
13187
13676
  }
13188
13677
 
13189
- const CLASS$h = `${COMPONENT_PREFIX}field-value`;
13678
+ const CLASS$g = `${COMPONENT_PREFIX}field-value`;
13190
13679
  const FieldValue = ({
13191
13680
  label,
13192
13681
  children,
13193
13682
  layout = "inline",
13194
13683
  className
13195
- }) => /* @__PURE__ */ jsxs("div", { className: [CLASS$h, `${CLASS$h}--${layout}`, className].filter(Boolean).join(" "), children: [
13196
- /* @__PURE__ */ jsx("span", { className: `${CLASS$h}__label`, children: label }),
13197
- /* @__PURE__ */ jsx("span", { className: `${CLASS$h}__value`, children })
13684
+ }) => /* @__PURE__ */ jsxs("div", { className: [CLASS$g, `${CLASS$g}--${layout}`, className].filter(Boolean).join(" "), children: [
13685
+ /* @__PURE__ */ jsx("span", { className: `${CLASS$g}__label`, children: label }),
13686
+ /* @__PURE__ */ jsx("span", { className: `${CLASS$g}__value`, children })
13198
13687
  ] });
13199
13688
  FieldValue.displayName = "FieldValue";
13200
13689
 
13201
- const CLASS$g = `${COMPONENT_PREFIX}record-card`;
13690
+ const CLASS$f = `${COMPONENT_PREFIX}record-card`;
13202
13691
  const RecordCard = ({
13203
13692
  title,
13204
13693
  summary,
@@ -13210,20 +13699,20 @@ const RecordCard = ({
13210
13699
  className
13211
13700
  }) => {
13212
13701
  const cuerpoId = useId();
13213
- return /* @__PURE__ */ jsxs("div", { className: [CLASS$g, open ? `${CLASS$g}--open` : "", className].filter(Boolean).join(" "), children: [
13702
+ return /* @__PURE__ */ jsxs("div", { className: [CLASS$f, open ? `${CLASS$f}--open` : "", className].filter(Boolean).join(" "), children: [
13214
13703
  /* @__PURE__ */ jsxs(
13215
13704
  "button",
13216
13705
  {
13217
13706
  type: "button",
13218
- className: `${CLASS$g}__header`,
13707
+ className: `${CLASS$f}__header`,
13219
13708
  "aria-expanded": open,
13220
13709
  "aria-controls": cuerpoId,
13221
13710
  "aria-label": ariaLabel,
13222
13711
  onClick: onToggle,
13223
13712
  children: [
13224
- /* @__PURE__ */ jsxs("span", { className: `${CLASS$g}__heading`, children: [
13225
- /* @__PURE__ */ jsx("span", { className: `${CLASS$g}__title`, children: title }),
13226
- summary && /* @__PURE__ */ jsx("span", { className: `${CLASS$g}__summary`, children: summary })
13713
+ /* @__PURE__ */ jsxs("span", { className: `${CLASS$f}__heading`, children: [
13714
+ /* @__PURE__ */ jsx("span", { className: `${CLASS$f}__title`, children: title }),
13715
+ summary && /* @__PURE__ */ jsx("span", { className: `${CLASS$f}__summary`, children: summary })
13227
13716
  ] }),
13228
13717
  /* @__PURE__ */ jsx(
13229
13718
  Icon,
@@ -13231,22 +13720,22 @@ const RecordCard = ({
13231
13720
  type: open ? "chevron-up" : "chevron-down",
13232
13721
  width: 18,
13233
13722
  height: 18,
13234
- className: `${CLASS$g}__chevron`,
13723
+ className: `${CLASS$f}__chevron`,
13235
13724
  "aria-hidden": true
13236
13725
  }
13237
13726
  )
13238
13727
  ]
13239
13728
  }
13240
13729
  ),
13241
- open && /* @__PURE__ */ jsxs("div", { className: `${CLASS$g}__body`, id: cuerpoId, children: [
13730
+ open && /* @__PURE__ */ jsxs("div", { className: `${CLASS$f}__body`, id: cuerpoId, children: [
13242
13731
  children,
13243
- actions && /* @__PURE__ */ jsx("div", { className: `${CLASS$g}__actions`, children: actions })
13732
+ actions && /* @__PURE__ */ jsx("div", { className: `${CLASS$f}__actions`, children: actions })
13244
13733
  ] })
13245
13734
  ] });
13246
13735
  };
13247
13736
  RecordCard.displayName = "RecordCard";
13248
13737
 
13249
- const CLASS$f = `${COMPONENT_PREFIX}crud-cards`;
13738
+ const CLASS$e = `${COMPONENT_PREFIX}crud-cards`;
13250
13739
  function summaryFields(fields) {
13251
13740
  const visibles = fields.filter((f) => f.showInTable !== false);
13252
13741
  const marcados = visibles.filter((f) => f.summary);
@@ -13265,13 +13754,13 @@ function CardList({
13265
13754
  const claveResumen = new Set(resumen.map((f) => f.key));
13266
13755
  const cuerpo = fields.filter((f) => f.showInTable !== false && !claveResumen.has(f.key));
13267
13756
  if (loading && rows.length === 0) {
13268
- return /* @__PURE__ */ jsx("div", { className: `${CLASS$f}__estado`, children: "Cargando..." });
13757
+ return /* @__PURE__ */ jsx("div", { className: `${CLASS$e}__estado`, children: "Cargando..." });
13269
13758
  }
13270
13759
  if (rows.length === 0) {
13271
- return /* @__PURE__ */ jsx("div", { className: `${CLASS$f}__estado`, children: emptyText });
13760
+ return /* @__PURE__ */ jsx("div", { className: `${CLASS$e}__estado`, children: emptyText });
13272
13761
  }
13273
13762
  const [principal, ...secundarios] = resumen;
13274
- return /* @__PURE__ */ jsx("div", { className: CLASS$f, children: rows.map((row) => {
13763
+ return /* @__PURE__ */ jsx("div", { className: CLASS$e, children: rows.map((row) => {
13275
13764
  const key = rowKey(row);
13276
13765
  const opciones = buildOptions?.(row) ?? [];
13277
13766
  const titulo = principal ? renderFieldValue(principal, row) : key;
@@ -13288,14 +13777,14 @@ function CardList({
13288
13777
  {
13289
13778
  type: "button",
13290
13779
  className: [
13291
- `${CLASS$f}__accion`,
13780
+ `${CLASS$e}__accion`,
13292
13781
  o.disabled && o.disabledReason ? "is-con-motivo" : ""
13293
13782
  ].filter(Boolean).join(" "),
13294
13783
  disabled: o.disabled,
13295
13784
  onClick: () => void o.onClick(),
13296
13785
  children: [
13297
13786
  /* @__PURE__ */ jsx("span", { children: o.label }),
13298
- o.disabled && o.disabledReason && /* @__PURE__ */ jsx("span", { className: `${CLASS$f}__motivo`, children: o.disabledReason })
13787
+ o.disabled && o.disabledReason && /* @__PURE__ */ jsx("span", { className: `${CLASS$e}__motivo`, children: o.disabledReason })
13299
13788
  ]
13300
13789
  },
13301
13790
  o.label
@@ -13310,7 +13799,7 @@ function CardList({
13310
13799
  }
13311
13800
  CardList.displayName = "CardList";
13312
13801
 
13313
- const CLASS$e = `${COMPONENT_PREFIX}crud-scroll-end`;
13802
+ const CLASS$d = `${COMPONENT_PREFIX}crud-scroll-end`;
13314
13803
  const MARGEN = 24;
13315
13804
  const SELECTOR_CRUD = `.${COMPONENT_PREFIX}table-container, .${COMPONENT_PREFIX}crud-cards`;
13316
13805
  const ScrollToEnd = ({
@@ -13354,7 +13843,7 @@ const ScrollToEnd = ({
13354
13843
  s.scrollTo({ top: s.scrollHeight, behavior: "smooth" });
13355
13844
  }, []);
13356
13845
  if (!visible) return null;
13357
- return /* @__PURE__ */ jsx("button", { type: "button", className: CLASS$e, onClick: alFinal, "aria-label": label, title: label, children: /* @__PURE__ */ jsx(Icon, { type: "chevron-down", width: 18, height: 18, "aria-hidden": true }) });
13846
+ return /* @__PURE__ */ jsx("button", { type: "button", className: CLASS$d, onClick: alFinal, "aria-label": label, title: label, children: /* @__PURE__ */ jsx(Icon, { type: "chevron-down", width: 18, height: 18, "aria-hidden": true }) });
13358
13847
  };
13359
13848
  ScrollToEnd.displayName = "ScrollToEnd";
13360
13849
 
@@ -14039,7 +14528,7 @@ function Crud({
14039
14528
  }
14040
14529
  Crud.displayName = "Crud";
14041
14530
 
14042
- const CLASS$d = "px-chat-reactive-crud__chat-link";
14531
+ const CLASS$c = "px-chat-reactive-crud__chat-link";
14043
14532
  function Burbuja() {
14044
14533
  return /* @__PURE__ */ jsx(
14045
14534
  "svg",
@@ -14066,7 +14555,7 @@ const ChatLinkCell = ({
14066
14555
  if (targets.length === 1) {
14067
14556
  const t = targets[0];
14068
14557
  const texto = t.label ? `Abrir chat ${t.label}` : "Abrir chat";
14069
- return /* @__PURE__ */ jsx("button", { type: "button", className: CLASS$d, "aria-label": texto, title: texto, onClick: () => abrir(t.id), children: /* @__PURE__ */ jsx(Burbuja, {}) });
14558
+ return /* @__PURE__ */ jsx("button", { type: "button", className: CLASS$c, "aria-label": texto, title: texto, onClick: () => abrir(t.id), children: /* @__PURE__ */ jsx(Burbuja, {}) });
14070
14559
  }
14071
14560
  return /* @__PURE__ */ jsx(
14072
14561
  DropdownMenu,
@@ -14080,7 +14569,7 @@ const ChatLinkCell = ({
14080
14569
  "button",
14081
14570
  {
14082
14571
  type: "button",
14083
- className: CLASS$d,
14572
+ className: CLASS$c,
14084
14573
  "aria-label": `Abrir chat (${targets.length} conversaciones)`,
14085
14574
  title: "Abrir chat",
14086
14575
  children: /* @__PURE__ */ jsx(Burbuja, {})
@@ -14093,6 +14582,18 @@ const ChatLinkCell = ({
14093
14582
  };
14094
14583
  ChatLinkCell.displayName = "ChatLinkCell";
14095
14584
 
14585
+ function obligatorioSiSeVe(s, f, requiredMsg) {
14586
+ if (!f.visibleWhen) return s.required(requiredMsg);
14587
+ const conds = Array.isArray(f.visibleWhen) ? f.visibleWhen : [f.visibleWhen];
14588
+ return s.when(
14589
+ conds.map((c) => c.field),
14590
+ {
14591
+ is: (...vals) => conds.every((c, i) => c.in.includes(String(vals[i]))),
14592
+ then: (sch) => sch.required(requiredMsg),
14593
+ otherwise: (sch) => sch.notRequired()
14594
+ }
14595
+ );
14596
+ }
14096
14597
  function buildCrudYupSchema(fields) {
14097
14598
  const shape = {};
14098
14599
  for (const f of fields) {
@@ -14122,19 +14623,17 @@ function buildCrudYupSchema(fields) {
14122
14623
  }
14123
14624
  if (f.moleculeType === "INPUT_NUMBER" || f.moleculeType === "INPUT_CURRENCY") {
14124
14625
  let s2 = yup.number().transform((val, orig) => orig === "" || orig === null ? void 0 : val).typeError(`${f.label}: n\xFAmero inv\xE1lido`);
14125
- if (requiredMsg) s2 = s2.required(requiredMsg);
14126
14626
  if (v?.min) s2 = s2.min(Number(v.min.value), v.min.message);
14127
14627
  if (v?.max) s2 = s2.max(Number(v.max.value), v.max.message);
14128
- shape[f.name] = s2;
14628
+ shape[f.name] = requiredMsg ? obligatorioSiSeVe(s2, f, requiredMsg) : s2;
14129
14629
  continue;
14130
14630
  }
14131
14631
  let s = yup.string();
14132
- if (requiredMsg) s = s.required(requiredMsg);
14133
- if (v?.pattern) s = s.matches(new RegExp(v.pattern.value), v.pattern.message);
14632
+ if (v?.pattern) s = s.matches(new RegExp(v.pattern.value), { message: v.pattern.message, excludeEmptyString: true });
14134
14633
  if (v?.email) s = s.email(v.email);
14135
14634
  if (v?.min) s = s.min(Number(v.min.value), v.min.message);
14136
14635
  if (v?.max) s = s.max(Number(v.max.value), v.max.message);
14137
- shape[f.name] = s;
14636
+ shape[f.name] = requiredMsg ? obligatorioSiSeVe(s, f, requiredMsg) : s;
14138
14637
  }
14139
14638
  return yup.object().shape(shape);
14140
14639
  }
@@ -14164,7 +14663,14 @@ const datetime = (value) => {
14164
14663
  minute: "2-digit"
14165
14664
  });
14166
14665
  };
14167
- const CRUD_FORMATTERS = { currency, date, datetime };
14666
+ const phone = (value) => {
14667
+ const s = String(value ?? "").trim();
14668
+ const m = /^\+(\d{1,3})(\d{10})$/.exec(s);
14669
+ if (!m) return s;
14670
+ const [, cc, n] = m;
14671
+ return `+${cc} ${n.slice(0, 3)} ${n.slice(3, 6)} ${n.slice(6)}`;
14672
+ };
14673
+ const CRUD_FORMATTERS = { currency, date, datetime, phone };
14168
14674
  function getFormatter(key) {
14169
14675
  return key ? CRUD_FORMATTERS[key] : void 0;
14170
14676
  }
@@ -14399,7 +14905,7 @@ function uploadViaEventBus(eventBus, file, fileType) {
14399
14905
  });
14400
14906
  }
14401
14907
 
14402
- const CLASS$c = `${COMPONENT_PREFIX$1}file-field`;
14908
+ const CLASS$b = `${COMPONENT_PREFIX$1}file-field`;
14403
14909
  function iconoPorNombre(nombre) {
14404
14910
  const ext = nombre.split(".").pop()?.toLowerCase() ?? "";
14405
14911
  if (["png", "jpg", "jpeg", "gif", "webp", "heic", "heif"].includes(ext)) return ICON_TYPES.IMAGE;
@@ -14430,18 +14936,18 @@ const FileField = ({
14430
14936
  const elegir = () => {
14431
14937
  if (!disabled) inputRef.current?.click();
14432
14938
  };
14433
- return /* @__PURE__ */ jsxs("div", { className: `${CLASS$c}${error ? ` ${CLASS$c}--error` : ""}`, children: [
14434
- /* @__PURE__ */ jsxs("span", { className: `${CLASS$c}__label`, children: [
14939
+ return /* @__PURE__ */ jsxs("div", { className: `${CLASS$b}${error ? ` ${CLASS$b}--error` : ""}`, children: [
14940
+ /* @__PURE__ */ jsxs("span", { className: `${CLASS$b}__label`, children: [
14435
14941
  label,
14436
14942
  required ? " *" : "",
14437
14943
  multiple && hechos > 0 ? ` (${hechos})` : ""
14438
14944
  ] }),
14439
- /* @__PURE__ */ jsxs("div", { className: `${CLASS$c}__box`, children: [
14945
+ /* @__PURE__ */ jsxs("div", { className: `${CLASS$b}__box`, children: [
14440
14946
  /* @__PURE__ */ jsx(
14441
14947
  "input",
14442
14948
  {
14443
14949
  ref: inputRef,
14444
- className: `${CLASS$c}__native`,
14950
+ className: `${CLASS$b}__native`,
14445
14951
  type: "file",
14446
14952
  accept,
14447
14953
  multiple,
@@ -14452,14 +14958,14 @@ const FileField = ({
14452
14958
  }
14453
14959
  }
14454
14960
  ),
14455
- /* @__PURE__ */ jsxs("button", { type: "button", className: `${CLASS$c}__pick`, onClick: elegir, disabled, children: [
14961
+ /* @__PURE__ */ jsxs("button", { type: "button", className: `${CLASS$b}__pick`, onClick: elegir, disabled, children: [
14456
14962
  /* @__PURE__ */ jsx(Icon$1, { type: ICON_TYPES.UPLOAD, size: "small" }),
14457
- /* @__PURE__ */ jsx("span", { className: `${CLASS$c}__pick-text`, children: entries.length === 0 ? multiple ? "Toca para elegir archivos" : "Toca para elegir un archivo" : multiple ? "A\xF1adir m\xE1s" : "Cambiar archivo" })
14963
+ /* @__PURE__ */ jsx("span", { className: `${CLASS$b}__pick-text`, children: entries.length === 0 ? multiple ? "Toca para elegir archivos" : "Toca para elegir un archivo" : multiple ? "A\xF1adir m\xE1s" : "Cambiar archivo" })
14458
14964
  ] }),
14459
- entries.length > 0 && /* @__PURE__ */ jsx("ul", { className: `${CLASS$c}__list`, children: entries.map((e, i) => /* @__PURE__ */ jsxs("li", { className: `${CLASS$c}__item ${CLASS$c}__item--${e.status}`, children: [
14460
- /* @__PURE__ */ jsx("span", { className: `${CLASS$c}__kind`, "aria-hidden": "true", children: /* @__PURE__ */ jsx(Icon$1, { type: iconoPorNombre(e.name), size: "small" }) }),
14461
- /* @__PURE__ */ jsx("span", { className: `${CLASS$c}__name`, children: e.name }),
14462
- /* @__PURE__ */ jsxs("span", { className: `${CLASS$c}__state`, children: [
14965
+ entries.length > 0 && /* @__PURE__ */ jsx("ul", { className: `${CLASS$b}__list`, children: entries.map((e, i) => /* @__PURE__ */ jsxs("li", { className: `${CLASS$b}__item ${CLASS$b}__item--${e.status}`, children: [
14966
+ /* @__PURE__ */ jsx("span", { className: `${CLASS$b}__kind`, "aria-hidden": "true", children: /* @__PURE__ */ jsx(Icon$1, { type: iconoPorNombre(e.name), size: "small" }) }),
14967
+ /* @__PURE__ */ jsx("span", { className: `${CLASS$b}__name`, children: e.name }),
14968
+ /* @__PURE__ */ jsxs("span", { className: `${CLASS$b}__state`, children: [
14463
14969
  e.status === "uploading" && "Subiendo\u2026",
14464
14970
  e.status === "done" && (pesoLegible(e.size) || "Listo"),
14465
14971
  e.status === "error" && "No se pudo subir"
@@ -14468,7 +14974,7 @@ const FileField = ({
14468
14974
  "button",
14469
14975
  {
14470
14976
  type: "button",
14471
- className: `${CLASS$c}__remove`,
14977
+ className: `${CLASS$b}__remove`,
14472
14978
  onClick: () => onRemove(i),
14473
14979
  "aria-label": `Quitar ${e.name}`,
14474
14980
  disabled,
@@ -14477,8 +14983,8 @@ const FileField = ({
14477
14983
  )
14478
14984
  ] }, `${e.name}-${i}`)) })
14479
14985
  ] }),
14480
- error && /* @__PURE__ */ jsx("p", { className: `${CLASS$c}__error`, children: error }),
14481
- !error && subiendo && /* @__PURE__ */ jsx("p", { className: `${CLASS$c}__hint`, children: "Espera a que terminen de subir." })
14986
+ error && /* @__PURE__ */ jsx("p", { className: `${CLASS$b}__error`, children: error }),
14987
+ !error && subiendo && /* @__PURE__ */ jsx("p", { className: `${CLASS$b}__hint`, children: "Espera a que terminen de subir." })
14482
14988
  ] });
14483
14989
  };
14484
14990
 
@@ -15640,7 +16146,7 @@ function buildMarkerIcon(name, color = "#dc2626", heading = 0) {
15640
16146
  return `data:image/svg+xml;charset=UTF-8,${encodeURIComponent(svg)}`;
15641
16147
  }
15642
16148
 
15643
- const CLASS$b = `${COMPONENT_PREFIX$1}map-view`;
16149
+ const CLASS$a = `${COMPONENT_PREFIX$1}map-view`;
15644
16150
  const DEFAULT_CENTER = { lat: 4.711, lng: -74.0721 };
15645
16151
  const DEFAULT_ZOOM = 12;
15646
16152
  const DEFAULT_HEIGHT$1 = 320;
@@ -15710,6 +16216,8 @@ const MapView = ({
15710
16216
  eventBus,
15711
16217
  expandable = true,
15712
16218
  fullBleed = false,
16219
+ interactive = true,
16220
+ expandIcon = "expand",
15713
16221
  animateMs,
15714
16222
  className
15715
16223
  }) => {
@@ -15765,7 +16273,12 @@ const MapView = ({
15765
16273
  mapTypeControl: false,
15766
16274
  streetViewControl: false,
15767
16275
  fullscreenControl: false,
15768
- styles: leerEstiloDelTema()
16276
+ styles: leerEstiloDelTema(),
16277
+ // SPEC-182 — un mapa solo para mirar no se queda con el gesto: `none` es la forma oficial
16278
+ // de Google de que el dedo y la rueda sigan desplazando la página. Se fija al crear el mapa
16279
+ // porque el modo no cambia en caliente: quien quiera el otro monta otra instancia (la de
16280
+ // pantalla completa lo es).
16281
+ ...interactive ? {} : { gestureHandling: "none", zoomControl: false, keyboardShortcuts: false }
15769
16282
  });
15770
16283
  mapRef.current.addListener("dragstart", () => {
15771
16284
  followSuspendedRef.current = true;
@@ -15783,7 +16296,7 @@ const MapView = ({
15783
16296
  useEffect(() => {
15784
16297
  if (!mapReady || !mapRef.current) return;
15785
16298
  const maps = window.google.maps;
15786
- const editable = !!onMoveRef.current;
16299
+ const editable = interactive && !!onMoveRef.current;
15787
16300
  const alive = new Set(list.map((p) => p.id));
15788
16301
  markersRef.current.forEach((entry, id) => {
15789
16302
  if (alive.has(id)) return;
@@ -15855,7 +16368,7 @@ const MapView = ({
15855
16368
  } else {
15856
16369
  mapRef.current.fitBounds(bounds);
15857
16370
  }
15858
- }, [mapReady, list, animateMs]);
16371
+ }, [mapReady, list, animateMs, interactive]);
15859
16372
  useEffect(() => {
15860
16373
  if (!mapReady || !mapRef.current) return;
15861
16374
  const maps = window.google.maps;
@@ -15905,7 +16418,7 @@ const MapView = ({
15905
16418
  if (!mapReady || !mapRef.current) return;
15906
16419
  clickListenerRef.current?.remove?.();
15907
16420
  clickListenerRef.current = null;
15908
- if (!onPointMove || list.length !== 1) return;
16421
+ if (!interactive || !onPointMove || list.length !== 1) return;
15909
16422
  const pointId = list[0].id;
15910
16423
  clickListenerRef.current = mapRef.current.addListener("click", (e) => {
15911
16424
  onMoveRef.current?.(pointId, e.latLng.lat(), e.latLng.lng());
@@ -15914,7 +16427,7 @@ const MapView = ({
15914
16427
  clickListenerRef.current?.remove?.();
15915
16428
  clickListenerRef.current = null;
15916
16429
  };
15917
- }, [mapReady, list, onPointMove]);
16430
+ }, [mapReady, list, onPointMove, interactive]);
15918
16431
  useEffect(
15919
16432
  () => () => {
15920
16433
  markersRef.current.forEach((entry) => {
@@ -15941,31 +16454,34 @@ const MapView = ({
15941
16454
  document.body.style.overflow = prev;
15942
16455
  };
15943
16456
  }, [expanded]);
15944
- const rootClass = [CLASS$b, fullBleed && `${CLASS$b}--full-bleed`, className].filter(Boolean).join(" ");
16457
+ const rootClass = [CLASS$a, fullBleed && `${CLASS$a}--full-bleed`, className].filter(Boolean).join(" ");
15945
16458
  if (overQuota) {
15946
- return /* @__PURE__ */ jsx("div", { className: rootClass, style: { height }, children: /* @__PURE__ */ jsx("p", { className: `${CLASS$b}__state ${CLASS$b}__state--error`, children: labels?.quotaText ?? "Se alcanz\xF3 el l\xEDmite diario de uso del mapa. Intenta ma\xF1ana." }) });
16459
+ return /* @__PURE__ */ jsx("div", { className: rootClass, style: { height }, children: /* @__PURE__ */ jsx("p", { className: `${CLASS$a}__state ${CLASS$a}__state--error`, children: labels?.quotaText ?? "Se alcanz\xF3 el l\xEDmite diario de uso del mapa. Intenta ma\xF1ana." }) });
15947
16460
  }
15948
16461
  if (status === "error") {
15949
- return /* @__PURE__ */ jsx("div", { className: rootClass, style: { height }, children: /* @__PURE__ */ jsx("p", { className: `${CLASS$b}__state ${CLASS$b}__state--error`, children: labels?.errorText ?? "No se pudo cargar el mapa." }) });
16462
+ return /* @__PURE__ */ jsx("div", { className: rootClass, style: { height }, children: /* @__PURE__ */ jsx("p", { className: `${CLASS$a}__state ${CLASS$a}__state--error`, children: labels?.errorText ?? "No se pudo cargar el mapa." }) });
15950
16463
  }
15951
16464
  return /* @__PURE__ */ jsxs("div", { className: rootClass, style: fullBleed ? void 0 : { height }, children: [
15952
- status !== "ready" && /* @__PURE__ */ jsx("p", { className: `${CLASS$b}__state`, children: labels?.loadingText ?? "Cargando mapa\u2026" }),
15953
- /* @__PURE__ */ jsx("div", { ref: nodeRef, className: `${CLASS$b}__canvas`, "aria-label": "Mapa", role: "application" }),
15954
- status === "ready" && list.length === 0 && allRoutes.length === 0 && /* @__PURE__ */ jsx("p", { className: `${CLASS$b}__empty`, children: labels?.emptyText ?? "Sin ubicaciones para mostrar" }),
15955
- status === "ready" && onPointMove && list.length > 0 && /* @__PURE__ */ jsx("p", { className: `${CLASS$b}__empty`, children: labels?.moveHint ?? "Arrastra el pin o toca el mapa para ajustar" }),
16465
+ status !== "ready" && /* @__PURE__ */ jsx("p", { className: `${CLASS$a}__state`, children: labels?.loadingText ?? "Cargando mapa\u2026" }),
16466
+ /* @__PURE__ */ jsx("div", { ref: nodeRef, className: `${CLASS$a}__canvas`, "aria-label": "Mapa", role: "application" }),
16467
+ status === "ready" && list.length === 0 && allRoutes.length === 0 && /* @__PURE__ */ jsx("p", { className: `${CLASS$a}__empty`, children: labels?.emptyText ?? "Sin ubicaciones para mostrar" }),
16468
+ status === "ready" && interactive && onPointMove && list.length > 0 && /* @__PURE__ */ jsx("p", { className: `${CLASS$a}__empty`, children: labels?.moveHint ?? "Arrastra el pin o toca el mapa para ajustar" }),
15956
16469
  status === "ready" && expandable && !fullBleed && /* @__PURE__ */ jsx(
15957
16470
  "button",
15958
16471
  {
15959
16472
  type: "button",
15960
- className: `${CLASS$b}__expand`,
15961
- "aria-label": labels?.expandAria ?? "Ver el mapa en pantalla completa",
15962
- title: labels?.expandAria ?? "Pantalla completa",
16473
+ className: `${CLASS$a}__expand`,
16474
+ "aria-label": labels?.expandAria ?? (expandIcon === "edit" ? "Ajustar el punto en el mapa" : "Ver el mapa en pantalla completa"),
16475
+ title: labels?.expandAria ?? (expandIcon === "edit" ? "Ajustar el punto" : "Pantalla completa"),
15963
16476
  onClick: () => setExpanded(true),
15964
- children: /* @__PURE__ */ jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx("path", { d: "M15 3h6v6M9 21H3v-6M21 3l-7 7M3 21l7-7" }) })
16477
+ children: expandIcon === "edit" ? /* @__PURE__ */ jsxs("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
16478
+ /* @__PURE__ */ jsx("path", { d: "M12 20h9" }),
16479
+ /* @__PURE__ */ jsx("path", { d: "M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z" })
16480
+ ] }) : /* @__PURE__ */ jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx("path", { d: "M15 3h6v6M9 21H3v-6M21 3l-7 7M3 21l7-7" }) })
15965
16481
  }
15966
16482
  ),
15967
16483
  expanded && createPortal(
15968
- /* @__PURE__ */ jsxs("div", { className: `${CLASS$b}-fs`, role: "dialog", "aria-modal": "true", "aria-label": "Mapa", children: [
16484
+ /* @__PURE__ */ jsxs("div", { className: `${CLASS$a}-fs`, role: "dialog", "aria-modal": "true", "aria-label": "Mapa", children: [
15969
16485
  /* @__PURE__ */ jsx(
15970
16486
  MapView,
15971
16487
  {
@@ -15979,7 +16495,7 @@ const MapView = ({
15979
16495
  "button",
15980
16496
  {
15981
16497
  type: "button",
15982
- className: `${CLASS$b}-fs__close`,
16498
+ className: `${CLASS$a}-fs__close`,
15983
16499
  "aria-label": labels?.closeAria ?? "Cerrar el mapa",
15984
16500
  onClick: () => setExpanded(false),
15985
16501
  children: /* @__PURE__ */ jsxs("svg", { width: "22", height: "22", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
@@ -16095,7 +16611,7 @@ function reverseGeocode(lat, lng) {
16095
16611
  });
16096
16612
  }
16097
16613
 
16098
- const CLASS$a = `${COMPONENT_PREFIX$1}location-field`;
16614
+ const CLASS$9 = `${COMPONENT_PREFIX$1}location-field`;
16099
16615
  const GPS_TIMEOUT_MS = 1e4;
16100
16616
  const CONFIRM_MAP_HEIGHT = 180;
16101
16617
  const LocationField = ({
@@ -16168,16 +16684,16 @@ const LocationField = ({
16168
16684
  }
16169
16685
  };
16170
16686
  const hasPoint = value?.lat != null && value?.lng != null;
16171
- return /* @__PURE__ */ jsxs("div", { className: `${CLASS$a}${error ? ` ${CLASS$a}--error` : ""}`, ref: boxRef, children: [
16172
- label && /* @__PURE__ */ jsxs("span", { className: `${CLASS$a}__label`, children: [
16687
+ return /* @__PURE__ */ jsxs("div", { className: `${CLASS$9}${error ? ` ${CLASS$9}--error` : ""}`, ref: boxRef, children: [
16688
+ label && /* @__PURE__ */ jsxs("span", { className: `${CLASS$9}__label`, children: [
16173
16689
  label,
16174
16690
  required ? " *" : ""
16175
16691
  ] }),
16176
- /* @__PURE__ */ jsxs("div", { className: `${CLASS$a}__row`, children: [
16692
+ /* @__PURE__ */ jsxs("div", { className: `${CLASS$9}__row`, children: [
16177
16693
  /* @__PURE__ */ jsx(
16178
16694
  "input",
16179
16695
  {
16180
- className: `${CLASS$a}__input`,
16696
+ className: `${CLASS$9}__input`,
16181
16697
  type: "text",
16182
16698
  value: text,
16183
16699
  disabled,
@@ -16191,7 +16707,7 @@ const LocationField = ({
16191
16707
  "button",
16192
16708
  {
16193
16709
  type: "button",
16194
- className: `${CLASS$a}__gps`,
16710
+ className: `${CLASS$9}__gps`,
16195
16711
  onClick: useMyLocation,
16196
16712
  disabled: disabled || gps === "locating",
16197
16713
  title: labels?.useMyLocation ?? "Enviar mi ubicaci\xF3n",
@@ -16205,21 +16721,24 @@ const LocationField = ({
16205
16721
  }
16206
16722
  )
16207
16723
  ] }),
16208
- open && suggestions.length > 0 && /* @__PURE__ */ jsx("ul", { className: `${CLASS$a}__suggestions`, children: suggestions.map((s) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx("button", { type: "button", onClick: () => void pickSuggestion(s.id, s.description), children: s.description }) }, s.id)) }),
16209
- error && /* @__PURE__ */ jsx("p", { className: `${CLASS$a}__error`, children: error }),
16210
- gps === "denied" && /* @__PURE__ */ jsx("p", { className: `${CLASS$a}__hint ${CLASS$a}__hint--warn`, children: labels?.permissionDenied ?? "No diste permiso de ubicaci\xF3n. Puedes escribir la direcci\xF3n." }),
16211
- gps === "unavailable" && /* @__PURE__ */ jsx("p", { className: `${CLASS$a}__hint ${CLASS$a}__hint--warn`, children: labels?.unavailable ?? "No pudimos obtener tu ubicaci\xF3n. Puedes escribir la direcci\xF3n." }),
16212
- hasPoint && /* @__PURE__ */ jsxs("div", { className: `${CLASS$a}__confirm`, children: [
16724
+ open && suggestions.length > 0 && /* @__PURE__ */ jsx("ul", { className: `${CLASS$9}__suggestions`, children: suggestions.map((s) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx("button", { type: "button", onClick: () => void pickSuggestion(s.id, s.description), children: s.description }) }, s.id)) }),
16725
+ error && /* @__PURE__ */ jsx("p", { className: `${CLASS$9}__error`, children: error }),
16726
+ gps === "denied" && /* @__PURE__ */ jsx("p", { className: `${CLASS$9}__hint ${CLASS$9}__hint--warn`, children: labels?.permissionDenied ?? "No diste permiso de ubicaci\xF3n. Puedes escribir la direcci\xF3n." }),
16727
+ gps === "unavailable" && /* @__PURE__ */ jsx("p", { className: `${CLASS$9}__hint ${CLASS$9}__hint--warn`, children: labels?.unavailable ?? "No pudimos obtener tu ubicaci\xF3n. Puedes escribir la direcci\xF3n." }),
16728
+ hasPoint && /* @__PURE__ */ jsxs("div", { className: `${CLASS$9}__confirm`, children: [
16213
16729
  /* @__PURE__ */ jsx(
16214
16730
  MapView,
16215
16731
  {
16216
16732
  apiKey,
16217
16733
  points: [{ id: "sel", lat: value.lat, lng: value.lng, label: value?.address }],
16218
16734
  height: CONFIRM_MAP_HEIGHT,
16219
- onPointMove: (id, lat, lng) => void movePoint(id, lat, lng)
16735
+ onPointMove: (id, lat, lng) => void movePoint(id, lat, lng),
16736
+ interactive: false,
16737
+ expandIcon: "edit",
16738
+ labels: { expandAria: labels?.editAria ?? "Ajustar el punto en el mapa" }
16220
16739
  }
16221
16740
  ),
16222
- /* @__PURE__ */ jsx("p", { className: `${CLASS$a}__hint`, children: labels?.confirmHint ?? "Verifica que el punto sea correcto." })
16741
+ /* @__PURE__ */ jsx("p", { className: `${CLASS$9}__hint`, children: labels?.confirmHint ?? "El pin marca d\xF3nde est\xE1 el veh\xEDculo. Si no es el punto exacto, toca el l\xE1piz: en el mapa grande puedes arrastrar el pin o tocar el lugar correcto." })
16223
16742
  ] })
16224
16743
  ] });
16225
16744
  };
@@ -16251,6 +16770,8 @@ function toRenderField(f, loaded, eventBus, mapsApiKey, loadError) {
16251
16770
  // y, a media fila, su campo hermano se quedaba con ~400px de blanco al lado. Medido entre
16252
16771
  // «¿En qué situación está?» y «¿A dónde lo llevamos?» del formulario de solicitud.
16253
16772
  gridSpan: 2,
16773
+ showIf: showIfDe(f),
16774
+ // SPEC-181
16254
16775
  uiProps: {
16255
16776
  // SPEC-074 — `error` viene del render de CUSTOM (DynamicForm ya lo pasaba) y aquí se
16256
16777
  // desechaba: el campo obligatorio más importante era el único mudo.
@@ -16283,14 +16804,22 @@ function toRenderField(f, loaded, eventBus, mapsApiKey, loadError) {
16283
16804
  columnWidth: f.columnWidth,
16284
16805
  fixed: f.fixed,
16285
16806
  align: f.align,
16807
+ showIf: showIfDe(f),
16808
+ // SPEC-181
16809
+ sanitize: f.sanitize,
16810
+ // SPEC-183
16286
16811
  // SPEC-106 T8 — con un fallo de carga, el desplegable dice que no se pudo preguntar en vez
16287
16812
  // de «no hay opciones disponibles», que es una respuesta y no la tenemos.
16288
- uiProps: loadError ? { options: options ?? [], notFoundContent: loadError, ...f.searchable ? { showSearch: true } : {} } : options ? { options, ...f.searchable ? { showSearch: true } : {} } : void 0,
16813
+ uiProps: loadError ? { options: options ?? [], notFoundContent: loadError, ...f.searchable ? { showSearch: true } : {}, ...f.picker ? { picker: f.picker } : {} } : options ? { options, ...f.searchable ? { showSearch: true } : {}, ...f.picker ? { picker: f.picker } : {} } : f.picker ? { picker: f.picker } : void 0,
16289
16814
  formatValue
16290
16815
  };
16291
16816
  }
16292
16817
  const cumpleCondicion = (c, row) => c.in.includes(String(row[c.field]));
16293
16818
  const cumplenTodas = (c, row) => (Array.isArray(c) ? c : [c]).every((x) => cumpleCondicion(x, row));
16819
+ function showIfDe(f) {
16820
+ const cond = f.visibleWhen;
16821
+ return cond ? (values) => cumplenTodas(cond, values) : void 0;
16822
+ }
16294
16823
  function matchesVisibleWhen(a, row) {
16295
16824
  if (a.hiddenWhen && cumplenTodas(a.hiddenWhen, row)) return false;
16296
16825
  if (!a.visibleWhen) return true;
@@ -16842,7 +17371,7 @@ function markFitOutliers(points, radiusKm = FIT_RADIUS_KM) {
16842
17371
  return { points: marcados, outside };
16843
17372
  }
16844
17373
 
16845
- const CLASS$9 = `${COMPONENT_PREFIX$1}services-map`;
17374
+ const CLASS$8 = `${COMPONENT_PREFIX$1}services-map`;
16846
17375
  const DEFAULT_HEIGHT = 340;
16847
17376
  function readNumber(row, field) {
16848
17377
  if (!field) return void 0;
@@ -16968,7 +17497,7 @@ const ServicesMap = ({ config, eventBus, apiKey, filter, fill }) => {
16968
17497
  [livePoints]
16969
17498
  );
16970
17499
  const nadaQueDibujar = rows !== null && allPoints.length === 0 && route.length === 0;
16971
- return /* @__PURE__ */ jsx("div", { className: fill ? `${CLASS$9} ${CLASS$9}--fill` : CLASS$9, children: rows === null ? /* @__PURE__ */ jsx("p", { className: `${CLASS$9}__state`, children: labels.loadingText ?? "Cargando ubicaciones\u2026" }) : nadaQueDibujar ? /* @__PURE__ */ jsx("p", { className: `${CLASS$9}__state`, children: lineaSinMapa(labels, missing, failed) }) : /* @__PURE__ */ jsxs(Fragment, { children: [
17500
+ return /* @__PURE__ */ jsx("div", { className: fill ? `${CLASS$8} ${CLASS$8}--fill` : CLASS$8, children: rows === null ? /* @__PURE__ */ jsx("p", { className: `${CLASS$8}__state`, children: labels.loadingText ?? "Cargando ubicaciones\u2026" }) : nadaQueDibujar ? /* @__PURE__ */ jsx("p", { className: `${CLASS$8}__state`, children: lineaSinMapa(labels, missing, failed) }) : /* @__PURE__ */ jsxs(Fragment, { children: [
16972
17501
  /* @__PURE__ */ jsx(
16973
17502
  MapView,
16974
17503
  {
@@ -16982,20 +17511,20 @@ const ServicesMap = ({ config, eventBus, apiKey, filter, fill }) => {
16982
17511
  labels: { emptyText: labels.emptyText }
16983
17512
  }
16984
17513
  ),
16985
- /* @__PURE__ */ jsxs("div", { className: `${CLASS$9}__notes`, children: [
16986
- livePoints.length > 0 && /* @__PURE__ */ jsxs("p", { className: `${CLASS$9}__note ${CLASS$9}__note--live`, children: [
17514
+ /* @__PURE__ */ jsxs("div", { className: `${CLASS$8}__notes`, children: [
17515
+ livePoints.length > 0 && /* @__PURE__ */ jsxs("p", { className: `${CLASS$8}__note ${CLASS$8}__note--live`, children: [
16987
17516
  (config.live?.labels?.liveText ?? "{n} en movimiento").replace(
16988
17517
  "{n}",
16989
17518
  String(livePoints.length)
16990
17519
  ),
16991
17520
  simulated > 0 && ` \xB7 ${config.live?.labels?.simulatedText ?? "incluye posiciones simuladas"}`
16992
17521
  ] }),
16993
- missing > 0 && /* @__PURE__ */ jsx("p", { className: `${CLASS$9}__note`, children: ((missing === 1 ? labels.missingTextOne : void 0) ?? labels.missingText ?? "{n} sin ubicaci\xF3n registrada").replace("{n}", String(missing)) }),
16994
- outside > 0 && /* @__PURE__ */ jsx("p", { className: `${CLASS$9}__note`, children: (labels.outsideText ?? "{n} fuera de la zona (aleja el mapa para verlos)").replace(
17522
+ missing > 0 && /* @__PURE__ */ jsx("p", { className: `${CLASS$8}__note`, children: ((missing === 1 ? labels.missingTextOne : void 0) ?? labels.missingText ?? "{n} sin ubicaci\xF3n registrada").replace("{n}", String(missing)) }),
17523
+ outside > 0 && /* @__PURE__ */ jsx("p", { className: `${CLASS$8}__note`, children: (labels.outsideText ?? "{n} fuera de la zona (aleja el mapa para verlos)").replace(
16995
17524
  "{n}",
16996
17525
  String(outside)
16997
17526
  ) }),
16998
- failed && /* @__PURE__ */ jsx("p", { className: `${CLASS$9}__note`, children: "No se pudieron cargar las ubicaciones." })
17527
+ failed && /* @__PURE__ */ jsx("p", { className: `${CLASS$8}__note`, children: "No se pudieron cargar las ubicaciones." })
16999
17528
  ] })
17000
17529
  ] }) });
17001
17530
  };
@@ -17011,7 +17540,7 @@ function lineaSinMapa(labels, missing, failed) {
17011
17540
  return labels.emptyText ?? "Sin ubicaciones para mostrar";
17012
17541
  }
17013
17542
 
17014
- const CLASS$8 = `${COMPONENT_PREFIX$1}service-shortcuts`;
17543
+ const CLASS$7 = `${COMPONENT_PREFIX$1}service-shortcuts`;
17015
17544
  const ICONS = {
17016
17545
  // SPEC-126 — quien DESPACHA tambien necesita sus puertas, y una de ellas son las conversaciones
17017
17546
  // de sus servicios. Los cinco iconos que habia eran todos de quien PIDE una grua.
@@ -17065,16 +17594,16 @@ const ServiceShortcuts = ({
17065
17594
  }) => {
17066
17595
  if (!options?.length) return null;
17067
17596
  const elegido = !!selectedId;
17068
- return /* @__PURE__ */ jsx("div", { className: [CLASS$8, elegido ? `${CLASS$8}--used` : ""].filter(Boolean).join(" "), children: options.map((o) => {
17597
+ return /* @__PURE__ */ jsx("div", { className: [CLASS$7, elegido ? `${CLASS$7}--used` : ""].filter(Boolean).join(" "), children: options.map((o) => {
17069
17598
  const esElegido = o.id === selectedId;
17070
17599
  return /* @__PURE__ */ jsxs(
17071
17600
  "button",
17072
17601
  {
17073
17602
  type: "button",
17074
17603
  className: [
17075
- `${CLASS$8}__item`,
17076
- elegido ? `${CLASS$8}__item--off` : "",
17077
- esElegido ? `${CLASS$8}__item--chosen` : ""
17604
+ `${CLASS$7}__item`,
17605
+ elegido ? `${CLASS$7}__item--off` : "",
17606
+ esElegido ? `${CLASS$7}__item--chosen` : ""
17078
17607
  ].filter(Boolean).join(" "),
17079
17608
  disabled: elegido,
17080
17609
  "aria-disabled": elegido,
@@ -17086,12 +17615,12 @@ const ServiceShortcuts = ({
17086
17615
  else if (o.route) eventBus?.emit(CHAT_EVENT.NAVIGATE, { route: o.route });
17087
17616
  },
17088
17617
  children: [
17089
- o.icon && /* @__PURE__ */ jsx("span", { className: `${CLASS$8}__icon`, children: ICONS[o.icon] }),
17090
- /* @__PURE__ */ jsxs("span", { className: `${CLASS$8}__text`, children: [
17091
- /* @__PURE__ */ jsx("span", { className: `${CLASS$8}__label`, children: o.label }),
17092
- o.hint && /* @__PURE__ */ jsx("span", { className: `${CLASS$8}__hint`, children: o.hint })
17618
+ o.icon && /* @__PURE__ */ jsx("span", { className: `${CLASS$7}__icon`, children: ICONS[o.icon] }),
17619
+ /* @__PURE__ */ jsxs("span", { className: `${CLASS$7}__text`, children: [
17620
+ /* @__PURE__ */ jsx("span", { className: `${CLASS$7}__label`, children: o.label }),
17621
+ o.hint && /* @__PURE__ */ jsx("span", { className: `${CLASS$7}__hint`, children: o.hint })
17093
17622
  ] }),
17094
- /* @__PURE__ */ jsx("span", { className: `${CLASS$8}__arrow`, children: esElegido ? CHECK : elegido ? null : /* @__PURE__ */ jsx("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx("polyline", { points: "9 18 15 12 9 6" }) }) })
17623
+ /* @__PURE__ */ jsx("span", { className: `${CLASS$7}__arrow`, children: esElegido ? CHECK : elegido ? null : /* @__PURE__ */ jsx("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx("polyline", { points: "9 18 15 12 9 6" }) }) })
17095
17624
  ]
17096
17625
  },
17097
17626
  o.id
@@ -17660,19 +18189,19 @@ function ChatNavigatorChat({ component, eventBus }) {
17660
18189
  ] });
17661
18190
  }
17662
18191
 
17663
- const CLASS$7 = `${COMPONENT_PREFIX$1}user-tools`;
18192
+ const CLASS$6 = `${COMPONENT_PREFIX$1}user-tools`;
17664
18193
  const UserTools = ({ config, onChange, onAction, className }) => {
17665
18194
  const { title, description, items } = config;
17666
- return /* @__PURE__ */ jsxs("section", { className: [CLASS$7, className].filter(Boolean).join(" "), children: [
17667
- title && /* @__PURE__ */ jsx("h2", { className: `${CLASS$7}__title`, children: title }),
17668
- description && /* @__PURE__ */ jsx("p", { className: `${CLASS$7}__description`, children: description }),
17669
- /* @__PURE__ */ jsx("ul", { className: `${CLASS$7}__list`, children: items.map((item) => /* @__PURE__ */ jsx("li", { className: `${CLASS$7}__item`, children: item.kind === "action" ? (
18195
+ return /* @__PURE__ */ jsxs("section", { className: [CLASS$6, className].filter(Boolean).join(" "), children: [
18196
+ title && /* @__PURE__ */ jsx("h2", { className: `${CLASS$6}__title`, children: title }),
18197
+ description && /* @__PURE__ */ jsx("p", { className: `${CLASS$6}__description`, children: description }),
18198
+ /* @__PURE__ */ jsx("ul", { className: `${CLASS$6}__list`, children: items.map((item) => /* @__PURE__ */ jsx("li", { className: `${CLASS$6}__item`, children: item.kind === "action" ? (
17670
18199
  // SPEC-139 T9 — un ajuste que se pulsa: mismo renglón (etiqueta y pista), y en vez
17671
18200
  // de la caja, un botón que dice lo que hace.
17672
- /* @__PURE__ */ jsxs("div", { className: `${CLASS$7}__action`, children: [
17673
- /* @__PURE__ */ jsxs("span", { className: `${CLASS$7}__text`, children: [
17674
- /* @__PURE__ */ jsx("span", { className: `${CLASS$7}__label`, children: item.label }),
17675
- item.hint && /* @__PURE__ */ jsx("span", { className: `${CLASS$7}__hint`, children: item.hint })
18201
+ /* @__PURE__ */ jsxs("div", { className: `${CLASS$6}__action`, children: [
18202
+ /* @__PURE__ */ jsxs("span", { className: `${CLASS$6}__text`, children: [
18203
+ /* @__PURE__ */ jsx("span", { className: `${CLASS$6}__label`, children: item.label }),
18204
+ item.hint && /* @__PURE__ */ jsx("span", { className: `${CLASS$6}__hint`, children: item.hint })
17676
18205
  ] }),
17677
18206
  /* @__PURE__ */ jsx(
17678
18207
  Button,
@@ -17691,13 +18220,13 @@ const UserTools = ({ config, onChange, onAction, className }) => {
17691
18220
  checked: Boolean(item.value),
17692
18221
  disabled: item.disabled,
17693
18222
  onChange: (checked) => onChange?.(item.id, checked),
17694
- label: /* @__PURE__ */ jsxs("span", { className: `${CLASS$7}__text`, children: [
17695
- /* @__PURE__ */ jsx("span", { className: `${CLASS$7}__label`, children: item.label }),
17696
- item.hint && /* @__PURE__ */ jsx("span", { className: `${CLASS$7}__hint`, children: item.hint })
18223
+ label: /* @__PURE__ */ jsxs("span", { className: `${CLASS$6}__text`, children: [
18224
+ /* @__PURE__ */ jsx("span", { className: `${CLASS$6}__label`, children: item.label }),
18225
+ item.hint && /* @__PURE__ */ jsx("span", { className: `${CLASS$6}__hint`, children: item.hint })
17697
18226
  ] })
17698
18227
  }
17699
18228
  ) }, item.id)) }),
17700
- items.length === 0 && /* @__PURE__ */ jsx("p", { className: `${CLASS$7}__empty`, children: "No hay herramientas disponibles por ahora." })
18229
+ items.length === 0 && /* @__PURE__ */ jsx("p", { className: `${CLASS$6}__empty`, children: "No hay herramientas disponibles por ahora." })
17701
18230
  ] });
17702
18231
  };
17703
18232
  UserTools.displayName = "UserTools";
@@ -18307,7 +18836,7 @@ const ChatHeader = ({
18307
18836
  ] });
18308
18837
  };
18309
18838
 
18310
- const CLASS$6 = `${COMPONENT_PREFIX$1}floating-actions`;
18839
+ const CLASS$5 = `${COMPONENT_PREFIX$1}floating-actions`;
18311
18840
  const ICON_VALUES = new Set(Object.values(ICON_TYPES));
18312
18841
  function renderIcon(icon) {
18313
18842
  if (typeof icon === "string" && ICON_VALUES.has(icon)) {
@@ -18316,23 +18845,23 @@ function renderIcon(icon) {
18316
18845
  return icon;
18317
18846
  }
18318
18847
  function Side({ buttons, align, eventBus }) {
18319
- return /* @__PURE__ */ jsx("div", { className: `${CLASS$6}__group ${CLASS$6}__group--${align}`, children: buttons.map((b) => {
18848
+ return /* @__PURE__ */ jsx("div", { className: `${CLASS$5}__group ${CLASS$5}__group--${align}`, children: buttons.map((b) => {
18320
18849
  const emit = () => {
18321
18850
  if (b.disabled) return;
18322
18851
  eventBus.emit(b.event, b.payload);
18323
18852
  };
18324
18853
  if (b.custom) {
18325
- return /* @__PURE__ */ jsxs("div", { className: `${CLASS$6}__slot`, children: [
18854
+ return /* @__PURE__ */ jsxs("div", { className: `${CLASS$5}__slot`, children: [
18326
18855
  b.custom,
18327
- b.panel && b.open && /* @__PURE__ */ jsx("div", { className: `${CLASS$6}__panel ${CLASS$6}__panel--${align}`, children: b.panel })
18856
+ b.panel && b.open && /* @__PURE__ */ jsx("div", { className: `${CLASS$5}__panel ${CLASS$5}__panel--${align}`, children: b.panel })
18328
18857
  ] }, b.id);
18329
18858
  }
18330
- return /* @__PURE__ */ jsxs("div", { className: `${CLASS$6}__slot`, children: [
18859
+ return /* @__PURE__ */ jsxs("div", { className: `${CLASS$5}__slot`, children: [
18331
18860
  /* @__PURE__ */ jsxs(
18332
18861
  "button",
18333
18862
  {
18334
18863
  type: "button",
18335
- className: [`${CLASS$6}__button`, b.active ? `${CLASS$6}__button--active` : ""].filter(Boolean).join(" "),
18864
+ className: [`${CLASS$5}__button`, b.active ? `${CLASS$5}__button--active` : ""].filter(Boolean).join(" "),
18336
18865
  "aria-label": b.ariaLabel,
18337
18866
  title: b.ariaLabel,
18338
18867
  "aria-pressed": b.active,
@@ -18340,16 +18869,16 @@ function Side({ buttons, align, eventBus }) {
18340
18869
  onClick: emit,
18341
18870
  children: [
18342
18871
  renderIcon(b.icon),
18343
- b.badge != null && b.badge !== "" && b.badge !== 0 && /* @__PURE__ */ jsx("span", { className: `${CLASS$6}__badge`, children: b.badge })
18872
+ b.badge != null && b.badge !== "" && b.badge !== 0 && /* @__PURE__ */ jsx("span", { className: `${CLASS$5}__badge`, children: b.badge })
18344
18873
  ]
18345
18874
  }
18346
18875
  ),
18347
- b.panel && b.open && /* @__PURE__ */ jsx("div", { className: `${CLASS$6}__panel ${CLASS$6}__panel--${align}`, children: b.panel })
18876
+ b.panel && b.open && /* @__PURE__ */ jsx("div", { className: `${CLASS$5}__panel ${CLASS$5}__panel--${align}`, children: b.panel })
18348
18877
  ] }, b.id);
18349
18878
  }) });
18350
18879
  }
18351
18880
  const ChatFloatingActions = ({ eventBus, left = [], right = [], offset = 12, glass = false }) => {
18352
- const cls = [CLASS$6, glass ? `${CLASS$6}--glass` : ""].filter(Boolean).join(" ");
18881
+ const cls = [CLASS$5, glass ? `${CLASS$5}--glass` : ""].filter(Boolean).join(" ");
18353
18882
  return /* @__PURE__ */ jsxs("div", { className: cls, style: { paddingLeft: offset, paddingRight: offset }, children: [
18354
18883
  /* @__PURE__ */ jsx(Side, { buttons: left, align: "left", eventBus }),
18355
18884
  /* @__PURE__ */ jsx(Side, { buttons: right, align: "right", eventBus })
@@ -18782,7 +19311,7 @@ const UserMessage = ({
18782
19311
  ] }) });
18783
19312
  };
18784
19313
 
18785
- const CLASS$5 = `${COMPONENT_PREFIX$1}photo-picker`;
19314
+ const CLASS$4 = `${COMPONENT_PREFIX$1}photo-picker`;
18786
19315
  const PhotoPicker = ({
18787
19316
  label,
18788
19317
  hint,
@@ -18807,8 +19336,8 @@ const PhotoPicker = ({
18807
19336
  void onFiles(e.target.files);
18808
19337
  e.target.value = "";
18809
19338
  };
18810
- return /* @__PURE__ */ jsxs("div", { className: `${CLASS$5}${error ? ` ${CLASS$5}--error` : ""}`, children: [
18811
- /* @__PURE__ */ jsxs("span", { className: `${CLASS$5}__label`, children: [
19339
+ return /* @__PURE__ */ jsxs("div", { className: `${CLASS$4}${error ? ` ${CLASS$4}--error` : ""}`, children: [
19340
+ /* @__PURE__ */ jsxs("span", { className: `${CLASS$4}__label`, children: [
18812
19341
  label,
18813
19342
  required ? " *" : "",
18814
19343
  hechas > 0 ? ` (${hechas}${max ? `/${max}` : ""})` : ""
@@ -18817,7 +19346,7 @@ const PhotoPicker = ({
18817
19346
  "input",
18818
19347
  {
18819
19348
  ref: galeriaRef,
18820
- className: `${CLASS$5}__native`,
19349
+ className: `${CLASS$4}__native`,
18821
19350
  type: "file",
18822
19351
  accept: "image/*",
18823
19352
  multiple: max !== 1,
@@ -18830,7 +19359,7 @@ const PhotoPicker = ({
18830
19359
  "input",
18831
19360
  {
18832
19361
  ref: camaraRef,
18833
- className: `${CLASS$5}__native`,
19362
+ className: `${CLASS$4}__native`,
18834
19363
  type: "file",
18835
19364
  accept: "image/*",
18836
19365
  capture: "environment",
@@ -18839,15 +19368,15 @@ const PhotoPicker = ({
18839
19368
  "data-testid": "photo-picker-camera"
18840
19369
  }
18841
19370
  ),
18842
- entries.length > 0 && /* @__PURE__ */ jsx("ul", { className: `${CLASS$5}__grid`, children: entries.map((e, i) => /* @__PURE__ */ jsxs("li", { className: `${CLASS$5}__thumb ${CLASS$5}__thumb--${e.status}`, children: [
18843
- e.previewUrl ? /* @__PURE__ */ jsx("img", { className: `${CLASS$5}__img`, src: e.previewUrl, alt: e.name }) : /* @__PURE__ */ jsx("span", { className: `${CLASS$5}__placeholder`, "aria-hidden": "true", children: /* @__PURE__ */ jsx(Icon$1, { type: ICON_TYPES.IMAGE }) }),
18844
- e.status === "uploading" && /* @__PURE__ */ jsx("span", { className: `${CLASS$5}__state`, children: "Subiendo\u2026" }),
18845
- e.status === "error" && /* @__PURE__ */ jsx("span", { className: `${CLASS$5}__state ${CLASS$5}__state--error`, children: "No se pudo subir" }),
19371
+ entries.length > 0 && /* @__PURE__ */ jsx("ul", { className: `${CLASS$4}__grid`, children: entries.map((e, i) => /* @__PURE__ */ jsxs("li", { className: `${CLASS$4}__thumb ${CLASS$4}__thumb--${e.status}`, children: [
19372
+ e.previewUrl ? /* @__PURE__ */ jsx("img", { className: `${CLASS$4}__img`, src: e.previewUrl, alt: e.name }) : /* @__PURE__ */ jsx("span", { className: `${CLASS$4}__placeholder`, "aria-hidden": "true", children: /* @__PURE__ */ jsx(Icon$1, { type: ICON_TYPES.IMAGE }) }),
19373
+ e.status === "uploading" && /* @__PURE__ */ jsx("span", { className: `${CLASS$4}__state`, children: "Subiendo\u2026" }),
19374
+ e.status === "error" && /* @__PURE__ */ jsx("span", { className: `${CLASS$4}__state ${CLASS$4}__state--error`, children: "No se pudo subir" }),
18846
19375
  onRemove && e.status !== "uploading" && /* @__PURE__ */ jsx(
18847
19376
  "button",
18848
19377
  {
18849
19378
  type: "button",
18850
- className: `${CLASS$5}__remove`,
19379
+ className: `${CLASS$4}__remove`,
18851
19380
  onClick: () => onRemove(i),
18852
19381
  "aria-label": `Quitar ${e.name}`,
18853
19382
  disabled,
@@ -18855,12 +19384,12 @@ const PhotoPicker = ({
18855
19384
  }
18856
19385
  )
18857
19386
  ] }, `${e.name}-${i}`)) }),
18858
- /* @__PURE__ */ jsxs("div", { className: `${CLASS$5}__actions`, children: [
19387
+ /* @__PURE__ */ jsxs("div", { className: `${CLASS$4}__actions`, children: [
18859
19388
  capture && /* @__PURE__ */ jsxs(
18860
19389
  "button",
18861
19390
  {
18862
19391
  type: "button",
18863
- className: `${CLASS$5}__pick`,
19392
+ className: `${CLASS$4}__pick`,
18864
19393
  onClick: () => elegir(camaraRef),
18865
19394
  disabled: disabled || lleno,
18866
19395
  children: [
@@ -18873,7 +19402,7 @@ const PhotoPicker = ({
18873
19402
  "button",
18874
19403
  {
18875
19404
  type: "button",
18876
- className: `${CLASS$5}__pick ${CLASS$5}__pick--secondary`,
19405
+ className: `${CLASS$4}__pick ${CLASS$4}__pick--secondary`,
18877
19406
  onClick: () => elegir(galeriaRef),
18878
19407
  disabled: disabled || lleno,
18879
19408
  children: [
@@ -18883,13 +19412,13 @@ const PhotoPicker = ({
18883
19412
  }
18884
19413
  )
18885
19414
  ] }),
18886
- error && /* @__PURE__ */ jsx("p", { className: `${CLASS$5}__error`, children: error }),
18887
- !error && subiendo && /* @__PURE__ */ jsx("p", { className: `${CLASS$5}__hint`, children: "Espera a que terminen de subir." }),
18888
- !error && !subiendo && hint && /* @__PURE__ */ jsx("p", { className: `${CLASS$5}__hint`, children: hint })
19415
+ error && /* @__PURE__ */ jsx("p", { className: `${CLASS$4}__error`, children: error }),
19416
+ !error && subiendo && /* @__PURE__ */ jsx("p", { className: `${CLASS$4}__hint`, children: "Espera a que terminen de subir." }),
19417
+ !error && !subiendo && hint && /* @__PURE__ */ jsx("p", { className: `${CLASS$4}__hint`, children: hint })
18889
19418
  ] });
18890
19419
  };
18891
19420
 
18892
- const CLASS$4 = `${COMPONENT_PREFIX$1}credentials-card`;
19421
+ const CLASS$3 = `${COMPONENT_PREFIX$1}credentials-card`;
18893
19422
  async function copiar(texto) {
18894
19423
  try {
18895
19424
  await navigator.clipboard.writeText(texto);
@@ -18906,15 +19435,15 @@ const Fila = ({ row }) => {
18906
19435
  const t = setTimeout(() => setCopiado(false), 1800);
18907
19436
  return () => clearTimeout(t);
18908
19437
  }, [copiado]);
18909
- return /* @__PURE__ */ jsxs("li", { className: `${CLASS$4}__row`, children: [
18910
- /* @__PURE__ */ jsx("span", { className: `${CLASS$4}__label`, children: row.label }),
18911
- /* @__PURE__ */ jsx("span", { className: `${CLASS$4}__value`, "data-testid": `credential-${row.label}`, children: visible ? row.value : "\u2022".repeat(Math.min(row.value.length, 12)) }),
18912
- /* @__PURE__ */ jsxs("span", { className: `${CLASS$4}__tools`, children: [
19438
+ return /* @__PURE__ */ jsxs("li", { className: `${CLASS$3}__row`, children: [
19439
+ /* @__PURE__ */ jsx("span", { className: `${CLASS$3}__label`, children: row.label }),
19440
+ /* @__PURE__ */ jsx("span", { className: `${CLASS$3}__value`, "data-testid": `credential-${row.label}`, children: visible ? row.value : "\u2022".repeat(Math.min(row.value.length, 12)) }),
19441
+ /* @__PURE__ */ jsxs("span", { className: `${CLASS$3}__tools`, children: [
18913
19442
  row.masked && /* @__PURE__ */ jsx(
18914
19443
  "button",
18915
19444
  {
18916
19445
  type: "button",
18917
- className: `${CLASS$4}__tool`,
19446
+ className: `${CLASS$3}__tool`,
18918
19447
  onClick: () => setVisible((v) => !v),
18919
19448
  "aria-label": visible ? `Ocultar ${row.label}` : `Ver ${row.label}`,
18920
19449
  children: visible ? "Ocultar" : "Ver"
@@ -18924,7 +19453,7 @@ const Fila = ({ row }) => {
18924
19453
  "button",
18925
19454
  {
18926
19455
  type: "button",
18927
- className: `${CLASS$4}__tool`,
19456
+ className: `${CLASS$3}__tool`,
18928
19457
  onClick: async () => setCopiado(await copiar(row.value)),
18929
19458
  "aria-label": `Copiar ${row.label}`,
18930
19459
  children: copiado ? /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -18943,12 +19472,12 @@ const CredentialsCard = ({
18943
19472
  note,
18944
19473
  action,
18945
19474
  className
18946
- }) => /* @__PURE__ */ jsxs("section", { className: [CLASS$4, className].filter(Boolean).join(" "), "aria-label": title, children: [
18947
- /* @__PURE__ */ jsx("h3", { className: `${CLASS$4}__title`, children: title }),
18948
- intro && /* @__PURE__ */ jsx("p", { className: `${CLASS$4}__intro`, children: intro }),
18949
- /* @__PURE__ */ jsx("ul", { className: `${CLASS$4}__rows`, children: rows.map((r) => /* @__PURE__ */ jsx(Fila, { row: r }, r.label)) }),
18950
- note && /* @__PURE__ */ jsx("p", { className: `${CLASS$4}__note`, children: note }),
18951
- action && /* @__PURE__ */ jsx("div", { className: `${CLASS$4}__action`, children: /* @__PURE__ */ jsx(Button, { fullWidth: true, onClick: action.onClick, disabled: action.disabled, children: action.label }) })
19475
+ }) => /* @__PURE__ */ jsxs("section", { className: [CLASS$3, className].filter(Boolean).join(" "), "aria-label": title, children: [
19476
+ /* @__PURE__ */ jsx("h3", { className: `${CLASS$3}__title`, children: title }),
19477
+ intro && /* @__PURE__ */ jsx("p", { className: `${CLASS$3}__intro`, children: intro }),
19478
+ /* @__PURE__ */ jsx("ul", { className: `${CLASS$3}__rows`, children: rows.map((r) => /* @__PURE__ */ jsx(Fila, { row: r }, r.label)) }),
19479
+ note && /* @__PURE__ */ jsx("p", { className: `${CLASS$3}__note`, children: note }),
19480
+ action && /* @__PURE__ */ jsx("div", { className: `${CLASS$3}__action`, children: /* @__PURE__ */ jsx(Button, { fullWidth: true, onClick: action.onClick, disabled: action.disabled, children: action.label }) })
18952
19481
  ] });
18953
19482
  CredentialsCard.displayName = "CredentialsCard";
18954
19483
 
@@ -19120,7 +19649,7 @@ const TextArea = forwardRef(
19120
19649
  );
19121
19650
  TextArea.displayName = "TextArea";
19122
19651
 
19123
- const CLASS$3 = `${COMPONENT_PREFIX$1}support-request-form`;
19652
+ const CLASS$2 = `${COMPONENT_PREFIX$1}support-request-form`;
19124
19653
  const VACIO = { name: "", email: "", phone: "", subject: "", message: "" };
19125
19654
  function faltantes(v) {
19126
19655
  if (v.name.trim().length < 2) return "Escribe tu nombre.";
@@ -19165,14 +19694,14 @@ const SupportRequestForm = ({
19165
19694
  return /* @__PURE__ */ jsxs(
19166
19695
  "form",
19167
19696
  {
19168
- className: [CLASS$3, sent ? `${CLASS$3}--sent` : "", className].filter(Boolean).join(" "),
19697
+ className: [CLASS$2, sent ? `${CLASS$2}--sent` : "", className].filter(Boolean).join(" "),
19169
19698
  onSubmit: enviar,
19170
19699
  noValidate: true,
19171
19700
  children: [
19172
- /* @__PURE__ */ jsx("h4", { className: `${CLASS$3}__title`, children: title }),
19173
- intro && /* @__PURE__ */ jsx("p", { className: `${CLASS$3}__intro`, children: intro }),
19174
- /* @__PURE__ */ jsxs("div", { className: `${CLASS$3}__fields`, children: [
19175
- /* @__PURE__ */ jsxs("div", { className: `${CLASS$3}__row`, children: [
19701
+ /* @__PURE__ */ jsx("h4", { className: `${CLASS$2}__title`, children: title }),
19702
+ intro && /* @__PURE__ */ jsx("p", { className: `${CLASS$2}__intro`, children: intro }),
19703
+ /* @__PURE__ */ jsxs("div", { className: `${CLASS$2}__fields`, children: [
19704
+ /* @__PURE__ */ jsxs("div", { className: `${CLASS$2}__row`, children: [
19176
19705
  /* @__PURE__ */ jsx(Input$1, { label: "Nombre", value: values.name, onChange: set("name"), fullWidth: true, disabled: sent, autoComplete: "name" }),
19177
19706
  /* @__PURE__ */ jsx(Input$1, { label: "Tel\xE9fono (opcional)", value: values.phone, onChange: set("phone"), fullWidth: true, disabled: sent, inputMode: "tel", autoComplete: "tel" })
19178
19707
  ] }),
@@ -19180,13 +19709,13 @@ const SupportRequestForm = ({
19180
19709
  /* @__PURE__ */ jsx(Input$1, { label: "Asunto", value: values.subject, onChange: set("subject"), fullWidth: true, disabled: sent }),
19181
19710
  /* @__PURE__ */ jsx(TextArea, { label: "Mensaje", value: values.message, onChange: set("message"), fullWidth: true, disabled: sent, minRows: 3, maxLength: 4e3, showCount: true })
19182
19711
  ] }),
19183
- error && /* @__PURE__ */ jsx("p", { className: `${CLASS$3}__error`, role: "alert", children: error }),
19184
- sent ? /* @__PURE__ */ jsxs("p", { className: `${CLASS$3}__done`, role: "status", children: [
19712
+ error && /* @__PURE__ */ jsx("p", { className: `${CLASS$2}__error`, role: "alert", children: error }),
19713
+ sent ? /* @__PURE__ */ jsxs("p", { className: `${CLASS$2}__done`, role: "status", children: [
19185
19714
  /* @__PURE__ */ jsx(Icon$1, { type: ICON_TYPES.CHECK, size: "small" }),
19186
19715
  /* @__PURE__ */ jsx("span", { children: sentLabel })
19187
19716
  ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
19188
- /* @__PURE__ */ jsx("div", { className: `${CLASS$3}__actions`, children: /* @__PURE__ */ jsx(Button, { type: "submit", variant: "primary", isLoading: enviando, disabled: enviando, children: submitLabel }) }),
19189
- note && /* @__PURE__ */ jsx("p", { className: `${CLASS$3}__note`, children: note })
19717
+ /* @__PURE__ */ jsx("div", { className: `${CLASS$2}__actions`, children: /* @__PURE__ */ jsx(Button, { type: "submit", variant: "primary", isLoading: enviando, disabled: enviando, children: submitLabel }) }),
19718
+ note && /* @__PURE__ */ jsx("p", { className: `${CLASS$2}__note`, children: note })
19190
19719
  ] })
19191
19720
  ]
19192
19721
  }
@@ -22119,105 +22648,6 @@ const Notification = ({
22119
22648
  };
22120
22649
  Notification.displayName = "Notification";
22121
22650
 
22122
- const CARD_VARIANTS = {
22123
- /** Con sombra: flota sobre el contenido (hojas, diálogos, paneles). */
22124
- ELEVATED: "elevated"};
22125
- const CARD_PADDINGS = {
22126
- MEDIUM: "medium",
22127
- LARGE: "large"
22128
- };
22129
- const CARD_RADII = {
22130
- NONE: "none",
22131
- LARGE: "large"
22132
- };
22133
-
22134
- const BASE = `${COMPONENT_PREFIX}card`;
22135
- const Card = React.forwardRef(
22136
- ({
22137
- variant = CARD_VARIANTS.ELEVATED,
22138
- padding = CARD_PADDINGS.MEDIUM,
22139
- radius = CARD_RADII.LARGE,
22140
- fullWidth = false,
22141
- className = "",
22142
- children,
22143
- ...rest
22144
- }, ref) => {
22145
- const classes = [
22146
- BASE,
22147
- `${BASE}--${variant}`,
22148
- `${BASE}--padding-${padding}`,
22149
- `${BASE}--radius-${radius}`,
22150
- fullWidth ? `${BASE}--full-width` : "",
22151
- className
22152
- ].filter(Boolean).join(" ");
22153
- return /* @__PURE__ */ jsx("div", { ref, className: classes, ...rest, children });
22154
- }
22155
- );
22156
- Card.displayName = "Card";
22157
-
22158
- const CLASS$2 = "px-lumi-bottom-sheet";
22159
- const BottomSheet = ({
22160
- open,
22161
- children,
22162
- onClose,
22163
- showGrabber = true,
22164
- closeOnBackdrop = false,
22165
- closeOnEscape = true,
22166
- ariaLabelledBy,
22167
- className = ""
22168
- }) => {
22169
- useEffect(() => {
22170
- if (!open) return;
22171
- const onKey = (e) => {
22172
- if (e.key === "Escape" && closeOnEscape) onClose?.();
22173
- };
22174
- document.addEventListener("keydown", onKey);
22175
- const previous = document.body.style.overflow;
22176
- document.body.style.overflow = "hidden";
22177
- return () => {
22178
- document.removeEventListener("keydown", onKey);
22179
- document.body.style.overflow = previous;
22180
- };
22181
- }, [open, closeOnEscape, onClose]);
22182
- if (!open) return null;
22183
- return createPortal(
22184
- /* @__PURE__ */ jsxs(
22185
- "div",
22186
- {
22187
- className: [CLASS$2, className].filter(Boolean).join(" "),
22188
- role: "dialog",
22189
- "aria-modal": "true",
22190
- "aria-labelledby": ariaLabelledBy,
22191
- children: [
22192
- /* @__PURE__ */ jsx(
22193
- "div",
22194
- {
22195
- className: `${CLASS$2}__backdrop`,
22196
- "aria-hidden": "true",
22197
- onClick: closeOnBackdrop ? onClose : void 0
22198
- }
22199
- ),
22200
- /* @__PURE__ */ jsxs(
22201
- Card,
22202
- {
22203
- className: `${CLASS$2}__sheet`,
22204
- padding: CARD_PADDINGS.LARGE,
22205
- radius: CARD_RADII.NONE,
22206
- fullWidth: true,
22207
- children: [
22208
- showGrabber && /* @__PURE__ */ jsx("div", { className: `${CLASS$2}__grabber`, "aria-hidden": "true" }),
22209
- children
22210
- ]
22211
- }
22212
- )
22213
- ]
22214
- }
22215
- ),
22216
- document.body
22217
- );
22218
- };
22219
- BottomSheet.displayName = "BottomSheet";
22220
-
22221
22651
  const CLASS$1 = `${COMPONENT_PREFIX}live-indicator`;
22222
22652
  const LiveIndicator = ({
22223
22653
  label,
@@ -25378,4 +25808,4 @@ function buildBreadcrumbPath(items, targetKey, currentPath = []) {
25378
25808
  return [];
25379
25809
  }
25380
25810
 
25381
- export { ActionFormDrawer, BottomSheet, CHAT_CONFIG_DEFAULTS, CHAT_EVENT, ICON_TYPES as CHAT_ICON_TYPES, CarouselDisplay, Chat, AssistantMessage as ChatAssistantMessage, AssistantThinkingIndicator as ChatAssistantThinkingIndicator, AttachmentPreview as ChatAttachmentPreview, Avatar as ChatAvatar, Button$1 as ChatButton, ChatConfigProvider, DateDivider as ChatDateDivider, FileViewer as ChatFileViewer, ChatFloatingActions, FullscreenViewer as ChatFullscreenViewer, ChatHeader as ChatHeaderComponent, Icon$1 as ChatIcon, Input$2 as ChatInput, ChatInput as ChatInputComponent, Link as ChatLink, Loader$1 as ChatLoader, Logo as ChatLogo, MessageStatus as ChatMessageStatus, Modal as ChatModal, ChatNavigator, Select$2 as ChatSelect, SelectMenu as ChatSelectMenu, StructuredContent as ChatStructuredContent, Text as ChatText, Textarea as ChatTextarea, UserAttachments as ChatUserAttachments, UserMessage as ChatUserMessage, ChatWidget, CredentialsCard, FileField, BADGE_VARIANTS as LUMI_BADGE_VARIANTS, DEFAULT_TITLES as LUMI_DEFAULT_TITLES, LUMI_ICON_TYPES, LiveIndicator, LocationField, ActionBar as LumiActionBar, Badge as LumiBadge, Base as LumiBase, BaseNavbar as LumiBaseNavbar, BaseWorkspace as LumiBaseWorkspace, Breadcrumb as LumiBreadcrumb, BreadcrumbItem as LumiBreadcrumbItem, BreadcrumbSeparator as LumiBreadcrumbSeparator, Button as LumiButton, Calendar as LumiCalendar, Card as LumiCard, Checkbox$1 as LumiCheckbox, Crud as LumiCrud, CurrencyDisplay as LumiCurrencyDisplay, Dashboard as LumiDashboard, DashboardNavbar as LumiDashboardNavbar, DashboardSidebar as LumiDashboardSidebar, DashboardWorkspace as LumiDashboardWorkspace, DateDisplay as LumiDateDisplay, DateInput$1 as LumiDateInput, Drawer as LumiDrawer, DropdownMenu as LumiDropdownMenu, DynamicForm as LumiDynamicForm, FieldValue as LumiFieldValue, Filter as LumiFilter, FilterRow as LumiFilterRow, Checkbox as LumiFormCheckbox, DateInput as LumiFormDateInput, FormDrawer as LumiFormDrawer, Input as LumiFormInput, Select as LumiFormSelect, TimeInput as LumiFormTimeInput, Icon as LumiIcon, Input$1 as LumiInput, Loader as LumiLoader, Menu as LumiMenu, MenuItem as LumiMenuItem, MenuItemGroup as LumiMenuItemGroup, Notification as LumiNotification, Pagination as LumiPagination, Popover as LumiPopover, QRCode as LumiQRCode, RecordCard as LumiRecordCard, Select$1 as LumiSelect, StepIndicator as LumiStepIndicator, Stepper as LumiStepper, SubMenu as LumiSubMenu, Table as LumiTable, Tabs as LumiTabs, TextArea as LumiTextArea, TimeInput$1 as LumiTimeInput, Tooltip as LumiTooltip, MapView, PhotoPicker, ReactiveCrud, ServiceShortcuts, ServicesMap, SessionExpiryPrompt, SupportRequestForm, UserTools, chatEventBus, clearChatComponents, createDeepPropertySubscriber, createEventBus, createStore, createStoreMerger, deepMerge, disabledReasonFor, fetchViaEventBus, getLastFleetSnapshot, matchesDisabledWhen, matchesDoneWhen, matchesVisibleWhen, registerChatComponents, setLastFleetSnapshot, useChatConfig, useReactiveCrud };
25811
+ export { ActionFormDrawer, BottomSheet, CHAT_CONFIG_DEFAULTS, CHAT_EVENT, ICON_TYPES as CHAT_ICON_TYPES, CarouselDisplay, Chat, AssistantMessage as ChatAssistantMessage, AssistantThinkingIndicator as ChatAssistantThinkingIndicator, AttachmentPreview as ChatAttachmentPreview, Avatar as ChatAvatar, Button$1 as ChatButton, ChatConfigProvider, DateDivider as ChatDateDivider, FileViewer as ChatFileViewer, ChatFloatingActions, FullscreenViewer as ChatFullscreenViewer, ChatHeader as ChatHeaderComponent, Icon$1 as ChatIcon, Input$2 as ChatInput, ChatInput as ChatInputComponent, Link as ChatLink, Loader$1 as ChatLoader, Logo as ChatLogo, MessageStatus as ChatMessageStatus, Modal as ChatModal, ChatNavigator, Select$2 as ChatSelect, SelectMenu as ChatSelectMenu, StructuredContent as ChatStructuredContent, Text as ChatText, Textarea as ChatTextarea, UserAttachments as ChatUserAttachments, UserMessage as ChatUserMessage, ChatWidget, CredentialsCard, DEFAULT_PHONE_COUNTRY, FileField, BADGE_VARIANTS as LUMI_BADGE_VARIANTS, DEFAULT_TITLES as LUMI_DEFAULT_TITLES, LUMI_ICON_TYPES, LiveIndicator, LocationField, ActionBar as LumiActionBar, Badge as LumiBadge, Base as LumiBase, BaseNavbar as LumiBaseNavbar, BaseWorkspace as LumiBaseWorkspace, Breadcrumb as LumiBreadcrumb, BreadcrumbItem as LumiBreadcrumbItem, BreadcrumbSeparator as LumiBreadcrumbSeparator, Button as LumiButton, Calendar as LumiCalendar, Card as LumiCard, Checkbox$1 as LumiCheckbox, Crud as LumiCrud, CurrencyDisplay as LumiCurrencyDisplay, Dashboard as LumiDashboard, DashboardNavbar as LumiDashboardNavbar, DashboardSidebar as LumiDashboardSidebar, DashboardWorkspace as LumiDashboardWorkspace, DateDisplay as LumiDateDisplay, DateInput$1 as LumiDateInput, Drawer as LumiDrawer, DropdownMenu as LumiDropdownMenu, DynamicForm as LumiDynamicForm, FieldValue as LumiFieldValue, Filter as LumiFilter, FilterRow as LumiFilterRow, Checkbox as LumiFormCheckbox, DateInput as LumiFormDateInput, FormDrawer as LumiFormDrawer, Input as LumiFormInput, Select as LumiFormSelect, TimeInput as LumiFormTimeInput, Icon as LumiIcon, Input$1 as LumiInput, Loader as LumiLoader, Menu as LumiMenu, MenuItem as LumiMenuItem, MenuItemGroup as LumiMenuItemGroup, Notification as LumiNotification, Pagination as LumiPagination, PhoneInput as LumiPhoneInput, Popover as LumiPopover, QRCode as LumiQRCode, RecordCard as LumiRecordCard, Select$1 as LumiSelect, SheetSelect as LumiSheetSelect, StepIndicator as LumiStepIndicator, Stepper as LumiStepper, SubMenu as LumiSubMenu, Table as LumiTable, Tabs as LumiTabs, TextArea as LumiTextArea, TimeInput$1 as LumiTimeInput, Tooltip as LumiTooltip, MapView, PHONE_COUNTRIES, PhotoPicker, ReactiveCrud, SANITIZE_PRESETS, ServiceShortcuts, ServicesMap, SessionExpiryPrompt, SupportRequestForm, UserTools, chatEventBus, clearChatComponents, createDeepPropertySubscriber, createEventBus, createStore, createStoreMerger, deepMerge, disabledReasonFor, fetchViaEventBus, flagOf, getLastFleetSnapshot, matchesDisabledWhen, matchesDoneWhen, matchesVisibleWhen, registerChatComponents, sanitize, setLastFleetSnapshot, splitPhone, useChatConfig, useReactiveCrud };