pixelon 0.5.3 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -13195,19 +13195,19 @@ function mapFieldsToFormFields(fields, mode) {
13195
13195
  }));
13196
13196
  }
13197
13197
 
13198
- const CLASS$e = `${COMPONENT_PREFIX}field-value`;
13198
+ const CLASS$g = `${COMPONENT_PREFIX}field-value`;
13199
13199
  const FieldValue = ({
13200
13200
  label,
13201
13201
  children,
13202
13202
  layout = "inline",
13203
13203
  className
13204
- }) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: [CLASS$e, `${CLASS$e}--${layout}`, className].filter(Boolean).join(" "), children: [
13205
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${CLASS$e}__label`, children: label }),
13206
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${CLASS$e}__value`, children })
13204
+ }) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: [CLASS$g, `${CLASS$g}--${layout}`, className].filter(Boolean).join(" "), children: [
13205
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${CLASS$g}__label`, children: label }),
13206
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${CLASS$g}__value`, children })
13207
13207
  ] });
13208
13208
  FieldValue.displayName = "FieldValue";
13209
13209
 
13210
- const CLASS$d = `${COMPONENT_PREFIX}record-card`;
13210
+ const CLASS$f = `${COMPONENT_PREFIX}record-card`;
13211
13211
  const RecordCard = ({
13212
13212
  title,
13213
13213
  summary,
@@ -13219,20 +13219,20 @@ const RecordCard = ({
13219
13219
  className
13220
13220
  }) => {
13221
13221
  const cuerpoId = React.useId();
13222
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: [CLASS$d, open ? `${CLASS$d}--open` : "", className].filter(Boolean).join(" "), children: [
13222
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: [CLASS$f, open ? `${CLASS$f}--open` : "", className].filter(Boolean).join(" "), children: [
13223
13223
  /* @__PURE__ */ jsxRuntime.jsxs(
13224
13224
  "button",
13225
13225
  {
13226
13226
  type: "button",
13227
- className: `${CLASS$d}__header`,
13227
+ className: `${CLASS$f}__header`,
13228
13228
  "aria-expanded": open,
13229
13229
  "aria-controls": cuerpoId,
13230
13230
  "aria-label": ariaLabel,
13231
13231
  onClick: onToggle,
13232
13232
  children: [
13233
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: `${CLASS$d}__heading`, children: [
13234
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${CLASS$d}__title`, children: title }),
13235
- summary && /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${CLASS$d}__summary`, children: summary })
13233
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: `${CLASS$f}__heading`, children: [
13234
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${CLASS$f}__title`, children: title }),
13235
+ summary && /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${CLASS$f}__summary`, children: summary })
13236
13236
  ] }),
13237
13237
  /* @__PURE__ */ jsxRuntime.jsx(
13238
13238
  Icon,
@@ -13240,22 +13240,22 @@ const RecordCard = ({
13240
13240
  type: open ? "chevron-up" : "chevron-down",
13241
13241
  width: 18,
13242
13242
  height: 18,
13243
- className: `${CLASS$d}__chevron`,
13243
+ className: `${CLASS$f}__chevron`,
13244
13244
  "aria-hidden": true
13245
13245
  }
13246
13246
  )
13247
13247
  ]
13248
13248
  }
13249
13249
  ),
13250
- open && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${CLASS$d}__body`, id: cuerpoId, children: [
13250
+ open && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${CLASS$f}__body`, id: cuerpoId, children: [
13251
13251
  children,
13252
- actions && /* @__PURE__ */ jsxRuntime.jsx("div", { className: `${CLASS$d}__actions`, children: actions })
13252
+ actions && /* @__PURE__ */ jsxRuntime.jsx("div", { className: `${CLASS$f}__actions`, children: actions })
13253
13253
  ] })
13254
13254
  ] });
13255
13255
  };
13256
13256
  RecordCard.displayName = "RecordCard";
13257
13257
 
13258
- const CLASS$c = `${COMPONENT_PREFIX}crud-cards`;
13258
+ const CLASS$e = `${COMPONENT_PREFIX}crud-cards`;
13259
13259
  function summaryFields(fields) {
13260
13260
  const visibles = fields.filter((f) => f.showInTable !== false);
13261
13261
  const marcados = visibles.filter((f) => f.summary);
@@ -13274,13 +13274,13 @@ function CardList({
13274
13274
  const claveResumen = new Set(resumen.map((f) => f.key));
13275
13275
  const cuerpo = fields.filter((f) => f.showInTable !== false && !claveResumen.has(f.key));
13276
13276
  if (loading && rows.length === 0) {
13277
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `${CLASS$c}__estado`, children: "Cargando..." });
13277
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `${CLASS$e}__estado`, children: "Cargando..." });
13278
13278
  }
13279
13279
  if (rows.length === 0) {
13280
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `${CLASS$c}__estado`, children: emptyText });
13280
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `${CLASS$e}__estado`, children: emptyText });
13281
13281
  }
13282
13282
  const [principal, ...secundarios] = resumen;
13283
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: CLASS$c, children: rows.map((row) => {
13283
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: CLASS$e, children: rows.map((row) => {
13284
13284
  const key = rowKey(row);
13285
13285
  const opciones = buildOptions?.(row) ?? [];
13286
13286
  const titulo = principal ? renderFieldValue(principal, row) : key;
@@ -13297,14 +13297,14 @@ function CardList({
13297
13297
  {
13298
13298
  type: "button",
13299
13299
  className: [
13300
- `${CLASS$c}__accion`,
13300
+ `${CLASS$e}__accion`,
13301
13301
  o.disabled && o.disabledReason ? "is-con-motivo" : ""
13302
13302
  ].filter(Boolean).join(" "),
13303
13303
  disabled: o.disabled,
13304
13304
  onClick: () => void o.onClick(),
13305
13305
  children: [
13306
13306
  /* @__PURE__ */ jsxRuntime.jsx("span", { children: o.label }),
13307
- o.disabled && o.disabledReason && /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${CLASS$c}__motivo`, children: o.disabledReason })
13307
+ o.disabled && o.disabledReason && /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${CLASS$e}__motivo`, children: o.disabledReason })
13308
13308
  ]
13309
13309
  },
13310
13310
  o.label
@@ -13319,7 +13319,7 @@ function CardList({
13319
13319
  }
13320
13320
  CardList.displayName = "CardList";
13321
13321
 
13322
- const CLASS$b = `${COMPONENT_PREFIX}crud-scroll-end`;
13322
+ const CLASS$d = `${COMPONENT_PREFIX}crud-scroll-end`;
13323
13323
  const MARGEN = 24;
13324
13324
  const SELECTOR_CRUD = `.${COMPONENT_PREFIX}table-container, .${COMPONENT_PREFIX}crud-cards`;
13325
13325
  const ScrollToEnd = ({
@@ -13363,7 +13363,7 @@ const ScrollToEnd = ({
13363
13363
  s.scrollTo({ top: s.scrollHeight, behavior: "smooth" });
13364
13364
  }, []);
13365
13365
  if (!visible) return null;
13366
- return /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: CLASS$b, onClick: alFinal, "aria-label": label, title: label, children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { type: "chevron-down", width: 18, height: 18, "aria-hidden": true }) });
13366
+ return /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: CLASS$d, onClick: alFinal, "aria-label": label, title: label, children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { type: "chevron-down", width: 18, height: 18, "aria-hidden": true }) });
13367
13367
  };
13368
13368
  ScrollToEnd.displayName = "ScrollToEnd";
13369
13369
 
@@ -14048,7 +14048,7 @@ function Crud({
14048
14048
  }
14049
14049
  Crud.displayName = "Crud";
14050
14050
 
14051
- const CLASS$a = "px-chat-reactive-crud__chat-link";
14051
+ const CLASS$c = "px-chat-reactive-crud__chat-link";
14052
14052
  function Burbuja() {
14053
14053
  return /* @__PURE__ */ jsxRuntime.jsx(
14054
14054
  "svg",
@@ -14075,7 +14075,7 @@ const ChatLinkCell = ({
14075
14075
  if (targets.length === 1) {
14076
14076
  const t = targets[0];
14077
14077
  const texto = t.label ? `Abrir chat ${t.label}` : "Abrir chat";
14078
- return /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: CLASS$a, "aria-label": texto, title: texto, onClick: () => abrir(t.id), children: /* @__PURE__ */ jsxRuntime.jsx(Burbuja, {}) });
14078
+ return /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: CLASS$c, "aria-label": texto, title: texto, onClick: () => abrir(t.id), children: /* @__PURE__ */ jsxRuntime.jsx(Burbuja, {}) });
14079
14079
  }
14080
14080
  return /* @__PURE__ */ jsxRuntime.jsx(
14081
14081
  DropdownMenu,
@@ -14089,7 +14089,7 @@ const ChatLinkCell = ({
14089
14089
  "button",
14090
14090
  {
14091
14091
  type: "button",
14092
- className: CLASS$a,
14092
+ className: CLASS$c,
14093
14093
  "aria-label": `Abrir chat (${targets.length} conversaciones)`,
14094
14094
  title: "Abrir chat",
14095
14095
  children: /* @__PURE__ */ jsxRuntime.jsx(Burbuja, {})
@@ -14406,7 +14406,7 @@ function uploadViaEventBus(eventBus, file, fileType) {
14406
14406
  });
14407
14407
  }
14408
14408
 
14409
- const CLASS$9 = `${COMPONENT_PREFIX$1}file-field`;
14409
+ const CLASS$b = `${COMPONENT_PREFIX$1}file-field`;
14410
14410
  function iconoPorNombre(nombre) {
14411
14411
  const ext = nombre.split(".").pop()?.toLowerCase() ?? "";
14412
14412
  if (["png", "jpg", "jpeg", "gif", "webp", "heic", "heif"].includes(ext)) return ICON_TYPES.IMAGE;
@@ -14437,18 +14437,18 @@ const FileField = ({
14437
14437
  const elegir = () => {
14438
14438
  if (!disabled) inputRef.current?.click();
14439
14439
  };
14440
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${CLASS$9}${error ? ` ${CLASS$9}--error` : ""}`, children: [
14441
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: `${CLASS$9}__label`, children: [
14440
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${CLASS$b}${error ? ` ${CLASS$b}--error` : ""}`, children: [
14441
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: `${CLASS$b}__label`, children: [
14442
14442
  label,
14443
14443
  required ? " *" : "",
14444
14444
  multiple && hechos > 0 ? ` (${hechos})` : ""
14445
14445
  ] }),
14446
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${CLASS$9}__box`, children: [
14446
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${CLASS$b}__box`, children: [
14447
14447
  /* @__PURE__ */ jsxRuntime.jsx(
14448
14448
  "input",
14449
14449
  {
14450
14450
  ref: inputRef,
14451
- className: `${CLASS$9}__native`,
14451
+ className: `${CLASS$b}__native`,
14452
14452
  type: "file",
14453
14453
  accept,
14454
14454
  multiple,
@@ -14459,14 +14459,14 @@ const FileField = ({
14459
14459
  }
14460
14460
  }
14461
14461
  ),
14462
- /* @__PURE__ */ jsxRuntime.jsxs("button", { type: "button", className: `${CLASS$9}__pick`, onClick: elegir, disabled, children: [
14462
+ /* @__PURE__ */ jsxRuntime.jsxs("button", { type: "button", className: `${CLASS$b}__pick`, onClick: elegir, disabled, children: [
14463
14463
  /* @__PURE__ */ jsxRuntime.jsx(Icon$1, { type: ICON_TYPES.UPLOAD, size: "small" }),
14464
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${CLASS$9}__pick-text`, children: entries.length === 0 ? multiple ? "Toca para elegir archivos" : "Toca para elegir un archivo" : multiple ? "A\xF1adir m\xE1s" : "Cambiar archivo" })
14464
+ /* @__PURE__ */ jsxRuntime.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" })
14465
14465
  ] }),
14466
- entries.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("ul", { className: `${CLASS$9}__list`, children: entries.map((e, i) => /* @__PURE__ */ jsxRuntime.jsxs("li", { className: `${CLASS$9}__item ${CLASS$9}__item--${e.status}`, children: [
14467
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${CLASS$9}__kind`, "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx(Icon$1, { type: iconoPorNombre(e.name), size: "small" }) }),
14468
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${CLASS$9}__name`, children: e.name }),
14469
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: `${CLASS$9}__state`, children: [
14466
+ entries.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("ul", { className: `${CLASS$b}__list`, children: entries.map((e, i) => /* @__PURE__ */ jsxRuntime.jsxs("li", { className: `${CLASS$b}__item ${CLASS$b}__item--${e.status}`, children: [
14467
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${CLASS$b}__kind`, "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx(Icon$1, { type: iconoPorNombre(e.name), size: "small" }) }),
14468
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${CLASS$b}__name`, children: e.name }),
14469
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: `${CLASS$b}__state`, children: [
14470
14470
  e.status === "uploading" && "Subiendo\u2026",
14471
14471
  e.status === "done" && (pesoLegible(e.size) || "Listo"),
14472
14472
  e.status === "error" && "No se pudo subir"
@@ -14475,7 +14475,7 @@ const FileField = ({
14475
14475
  "button",
14476
14476
  {
14477
14477
  type: "button",
14478
- className: `${CLASS$9}__remove`,
14478
+ className: `${CLASS$b}__remove`,
14479
14479
  onClick: () => onRemove(i),
14480
14480
  "aria-label": `Quitar ${e.name}`,
14481
14481
  disabled,
@@ -14484,8 +14484,8 @@ const FileField = ({
14484
14484
  )
14485
14485
  ] }, `${e.name}-${i}`)) })
14486
14486
  ] }),
14487
- error && /* @__PURE__ */ jsxRuntime.jsx("p", { className: `${CLASS$9}__error`, children: error }),
14488
- !error && subiendo && /* @__PURE__ */ jsxRuntime.jsx("p", { className: `${CLASS$9}__hint`, children: "Espera a que terminen de subir." })
14487
+ error && /* @__PURE__ */ jsxRuntime.jsx("p", { className: `${CLASS$b}__error`, children: error }),
14488
+ !error && subiendo && /* @__PURE__ */ jsxRuntime.jsx("p", { className: `${CLASS$b}__hint`, children: "Espera a que terminen de subir." })
14489
14489
  ] });
14490
14490
  };
14491
14491
 
@@ -15641,7 +15641,7 @@ function buildMarkerIcon(name, color = "#dc2626", heading = 0) {
15641
15641
  return `data:image/svg+xml;charset=UTF-8,${encodeURIComponent(svg)}`;
15642
15642
  }
15643
15643
 
15644
- const CLASS$8 = `${COMPONENT_PREFIX$1}map-view`;
15644
+ const CLASS$a = `${COMPONENT_PREFIX$1}map-view`;
15645
15645
  const DEFAULT_CENTER = { lat: 4.711, lng: -74.0721 };
15646
15646
  const DEFAULT_ZOOM = 12;
15647
15647
  const DEFAULT_HEIGHT$1 = 320;
@@ -15906,23 +15906,23 @@ const MapView = ({
15906
15906
  document.body.style.overflow = prev;
15907
15907
  };
15908
15908
  }, [expanded]);
15909
- const rootClass = [CLASS$8, fullBleed && `${CLASS$8}--full-bleed`, className].filter(Boolean).join(" ");
15909
+ const rootClass = [CLASS$a, fullBleed && `${CLASS$a}--full-bleed`, className].filter(Boolean).join(" ");
15910
15910
  if (overQuota) {
15911
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: rootClass, style: { height }, children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: `${CLASS$8}__state ${CLASS$8}__state--error`, children: labels?.quotaText ?? "Se alcanz\xF3 el l\xEDmite diario de uso del mapa. Intenta ma\xF1ana." }) });
15911
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: rootClass, style: { height }, children: /* @__PURE__ */ jsxRuntime.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." }) });
15912
15912
  }
15913
15913
  if (status === "error") {
15914
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: rootClass, style: { height }, children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: `${CLASS$8}__state ${CLASS$8}__state--error`, children: labels?.errorText ?? "No se pudo cargar el mapa." }) });
15914
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: rootClass, style: { height }, children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: `${CLASS$a}__state ${CLASS$a}__state--error`, children: labels?.errorText ?? "No se pudo cargar el mapa." }) });
15915
15915
  }
15916
15916
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: rootClass, style: fullBleed ? void 0 : { height }, children: [
15917
- status !== "ready" && /* @__PURE__ */ jsxRuntime.jsx("p", { className: `${CLASS$8}__state`, children: labels?.loadingText ?? "Cargando mapa\u2026" }),
15918
- /* @__PURE__ */ jsxRuntime.jsx("div", { ref: nodeRef, className: `${CLASS$8}__canvas`, "aria-label": "Mapa", role: "application" }),
15919
- status === "ready" && list.length === 0 && allRoutes.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("p", { className: `${CLASS$8}__empty`, children: labels?.emptyText ?? "Sin ubicaciones para mostrar" }),
15920
- status === "ready" && onPointMove && list.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("p", { className: `${CLASS$8}__empty`, children: labels?.moveHint ?? "Arrastra el pin o toca el mapa para ajustar" }),
15917
+ status !== "ready" && /* @__PURE__ */ jsxRuntime.jsx("p", { className: `${CLASS$a}__state`, children: labels?.loadingText ?? "Cargando mapa\u2026" }),
15918
+ /* @__PURE__ */ jsxRuntime.jsx("div", { ref: nodeRef, className: `${CLASS$a}__canvas`, "aria-label": "Mapa", role: "application" }),
15919
+ status === "ready" && list.length === 0 && allRoutes.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("p", { className: `${CLASS$a}__empty`, children: labels?.emptyText ?? "Sin ubicaciones para mostrar" }),
15920
+ status === "ready" && onPointMove && list.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("p", { className: `${CLASS$a}__empty`, children: labels?.moveHint ?? "Arrastra el pin o toca el mapa para ajustar" }),
15921
15921
  status === "ready" && expandable && !fullBleed && /* @__PURE__ */ jsxRuntime.jsx(
15922
15922
  "button",
15923
15923
  {
15924
15924
  type: "button",
15925
- className: `${CLASS$8}__expand`,
15925
+ className: `${CLASS$a}__expand`,
15926
15926
  "aria-label": labels?.expandAria ?? "Ver el mapa en pantalla completa",
15927
15927
  title: labels?.expandAria ?? "Pantalla completa",
15928
15928
  onClick: () => setExpanded(true),
@@ -15930,7 +15930,7 @@ const MapView = ({
15930
15930
  }
15931
15931
  ),
15932
15932
  expanded && ReactDOM.createPortal(
15933
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${CLASS$8}-fs`, role: "dialog", "aria-modal": "true", "aria-label": "Mapa", children: [
15933
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${CLASS$a}-fs`, role: "dialog", "aria-modal": "true", "aria-label": "Mapa", children: [
15934
15934
  /* @__PURE__ */ jsxRuntime.jsx(
15935
15935
  MapView,
15936
15936
  {
@@ -15944,7 +15944,7 @@ const MapView = ({
15944
15944
  "button",
15945
15945
  {
15946
15946
  type: "button",
15947
- className: `${CLASS$8}-fs__close`,
15947
+ className: `${CLASS$a}-fs__close`,
15948
15948
  "aria-label": labels?.closeAria ?? "Cerrar el mapa",
15949
15949
  onClick: () => setExpanded(false),
15950
15950
  children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "22", height: "22", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
@@ -16060,7 +16060,7 @@ function reverseGeocode(lat, lng) {
16060
16060
  });
16061
16061
  }
16062
16062
 
16063
- const CLASS$7 = `${COMPONENT_PREFIX$1}location-field`;
16063
+ const CLASS$9 = `${COMPONENT_PREFIX$1}location-field`;
16064
16064
  const GPS_TIMEOUT_MS = 1e4;
16065
16065
  const CONFIRM_MAP_HEIGHT = 180;
16066
16066
  const LocationField = ({
@@ -16133,16 +16133,16 @@ const LocationField = ({
16133
16133
  }
16134
16134
  };
16135
16135
  const hasPoint = value?.lat != null && value?.lng != null;
16136
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${CLASS$7}${error ? ` ${CLASS$7}--error` : ""}`, ref: boxRef, children: [
16137
- label && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: `${CLASS$7}__label`, children: [
16136
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${CLASS$9}${error ? ` ${CLASS$9}--error` : ""}`, ref: boxRef, children: [
16137
+ label && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: `${CLASS$9}__label`, children: [
16138
16138
  label,
16139
16139
  required ? " *" : ""
16140
16140
  ] }),
16141
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${CLASS$7}__row`, children: [
16141
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${CLASS$9}__row`, children: [
16142
16142
  /* @__PURE__ */ jsxRuntime.jsx(
16143
16143
  "input",
16144
16144
  {
16145
- className: `${CLASS$7}__input`,
16145
+ className: `${CLASS$9}__input`,
16146
16146
  type: "text",
16147
16147
  value: text,
16148
16148
  disabled,
@@ -16156,7 +16156,7 @@ const LocationField = ({
16156
16156
  "button",
16157
16157
  {
16158
16158
  type: "button",
16159
- className: `${CLASS$7}__gps`,
16159
+ className: `${CLASS$9}__gps`,
16160
16160
  onClick: useMyLocation,
16161
16161
  disabled: disabled || gps === "locating",
16162
16162
  title: labels?.useMyLocation ?? "Enviar mi ubicaci\xF3n",
@@ -16170,11 +16170,11 @@ const LocationField = ({
16170
16170
  }
16171
16171
  )
16172
16172
  ] }),
16173
- open && suggestions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("ul", { className: `${CLASS$7}__suggestions`, children: suggestions.map((s) => /* @__PURE__ */ jsxRuntime.jsx("li", { children: /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: () => void pickSuggestion(s.id, s.description), children: s.description }) }, s.id)) }),
16174
- error && /* @__PURE__ */ jsxRuntime.jsx("p", { className: `${CLASS$7}__error`, children: error }),
16175
- gps === "denied" && /* @__PURE__ */ jsxRuntime.jsx("p", { className: `${CLASS$7}__hint ${CLASS$7}__hint--warn`, children: labels?.permissionDenied ?? "No diste permiso de ubicaci\xF3n. Puedes escribir la direcci\xF3n." }),
16176
- gps === "unavailable" && /* @__PURE__ */ jsxRuntime.jsx("p", { className: `${CLASS$7}__hint ${CLASS$7}__hint--warn`, children: labels?.unavailable ?? "No pudimos obtener tu ubicaci\xF3n. Puedes escribir la direcci\xF3n." }),
16177
- hasPoint && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${CLASS$7}__confirm`, children: [
16173
+ open && suggestions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("ul", { className: `${CLASS$9}__suggestions`, children: suggestions.map((s) => /* @__PURE__ */ jsxRuntime.jsx("li", { children: /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: () => void pickSuggestion(s.id, s.description), children: s.description }) }, s.id)) }),
16174
+ error && /* @__PURE__ */ jsxRuntime.jsx("p", { className: `${CLASS$9}__error`, children: error }),
16175
+ gps === "denied" && /* @__PURE__ */ jsxRuntime.jsx("p", { className: `${CLASS$9}__hint ${CLASS$9}__hint--warn`, children: labels?.permissionDenied ?? "No diste permiso de ubicaci\xF3n. Puedes escribir la direcci\xF3n." }),
16176
+ gps === "unavailable" && /* @__PURE__ */ jsxRuntime.jsx("p", { className: `${CLASS$9}__hint ${CLASS$9}__hint--warn`, children: labels?.unavailable ?? "No pudimos obtener tu ubicaci\xF3n. Puedes escribir la direcci\xF3n." }),
16177
+ hasPoint && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${CLASS$9}__confirm`, children: [
16178
16178
  /* @__PURE__ */ jsxRuntime.jsx(
16179
16179
  MapView,
16180
16180
  {
@@ -16184,7 +16184,7 @@ const LocationField = ({
16184
16184
  onPointMove: (id, lat, lng) => void movePoint(id, lat, lng)
16185
16185
  }
16186
16186
  ),
16187
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: `${CLASS$7}__hint`, children: labels?.confirmHint ?? "Verifica que el punto sea correcto." })
16187
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: `${CLASS$9}__hint`, children: labels?.confirmHint ?? "Verifica que el punto sea correcto." })
16188
16188
  ] })
16189
16189
  ] });
16190
16190
  };
@@ -16807,7 +16807,7 @@ function markFitOutliers(points, radiusKm = FIT_RADIUS_KM) {
16807
16807
  return { points: marcados, outside };
16808
16808
  }
16809
16809
 
16810
- const CLASS$6 = `${COMPONENT_PREFIX$1}services-map`;
16810
+ const CLASS$8 = `${COMPONENT_PREFIX$1}services-map`;
16811
16811
  const DEFAULT_HEIGHT = 340;
16812
16812
  function readNumber(row, field) {
16813
16813
  if (!field) return void 0;
@@ -16932,7 +16932,8 @@ const ServicesMap = ({ config, eventBus, apiKey, filter, fill }) => {
16932
16932
  () => livePoints.length === 1 ? livePoints[0].id : void 0,
16933
16933
  [livePoints]
16934
16934
  );
16935
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: fill ? `${CLASS$6} ${CLASS$6}--fill` : CLASS$6, children: rows === null ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: `${CLASS$6}__state`, children: labels.loadingText ?? "Cargando ubicaciones\u2026" }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
16935
+ const nadaQueDibujar = rows !== null && allPoints.length === 0 && route.length === 0;
16936
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: fill ? `${CLASS$8} ${CLASS$8}--fill` : CLASS$8, children: rows === null ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: `${CLASS$8}__state`, children: labels.loadingText ?? "Cargando ubicaciones\u2026" }) : nadaQueDibujar ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: `${CLASS$8}__state`, children: lineaSinMapa(labels, missing, failed) }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
16936
16937
  /* @__PURE__ */ jsxRuntime.jsx(
16937
16938
  MapView,
16938
16939
  {
@@ -16946,26 +16947,36 @@ const ServicesMap = ({ config, eventBus, apiKey, filter, fill }) => {
16946
16947
  labels: { emptyText: labels.emptyText }
16947
16948
  }
16948
16949
  ),
16949
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${CLASS$6}__notes`, children: [
16950
- livePoints.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: `${CLASS$6}__note ${CLASS$6}__note--live`, children: [
16950
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${CLASS$8}__notes`, children: [
16951
+ livePoints.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: `${CLASS$8}__note ${CLASS$8}__note--live`, children: [
16951
16952
  (config.live?.labels?.liveText ?? "{n} en movimiento").replace(
16952
16953
  "{n}",
16953
16954
  String(livePoints.length)
16954
16955
  ),
16955
16956
  simulated > 0 && ` \xB7 ${config.live?.labels?.simulatedText ?? "incluye posiciones simuladas"}`
16956
16957
  ] }),
16957
- missing > 0 && /* @__PURE__ */ jsxRuntime.jsx("p", { className: `${CLASS$6}__note`, children: ((missing === 1 ? labels.missingTextOne : void 0) ?? labels.missingText ?? "{n} sin ubicaci\xF3n registrada").replace("{n}", String(missing)) }),
16958
- outside > 0 && /* @__PURE__ */ jsxRuntime.jsx("p", { className: `${CLASS$6}__note`, children: (labels.outsideText ?? "{n} fuera de la zona (aleja el mapa para verlos)").replace(
16958
+ missing > 0 && /* @__PURE__ */ jsxRuntime.jsx("p", { className: `${CLASS$8}__note`, children: ((missing === 1 ? labels.missingTextOne : void 0) ?? labels.missingText ?? "{n} sin ubicaci\xF3n registrada").replace("{n}", String(missing)) }),
16959
+ outside > 0 && /* @__PURE__ */ jsxRuntime.jsx("p", { className: `${CLASS$8}__note`, children: (labels.outsideText ?? "{n} fuera de la zona (aleja el mapa para verlos)").replace(
16959
16960
  "{n}",
16960
16961
  String(outside)
16961
16962
  ) }),
16962
- failed && /* @__PURE__ */ jsxRuntime.jsx("p", { className: `${CLASS$6}__note`, children: "No se pudieron cargar las ubicaciones." })
16963
+ failed && /* @__PURE__ */ jsxRuntime.jsx("p", { className: `${CLASS$8}__note`, children: "No se pudieron cargar las ubicaciones." })
16963
16964
  ] })
16964
16965
  ] }) });
16965
16966
  };
16966
16967
  ServicesMap.displayName = "ServicesMap";
16968
+ function lineaSinMapa(labels, missing, failed) {
16969
+ if (failed) return "No se pudieron cargar las ubicaciones.";
16970
+ if (missing === 1) {
16971
+ return (labels.missingTextOne ?? labels.missingText ?? "{n} sin ubicaci\xF3n registrada").replace("{n}", "1");
16972
+ }
16973
+ if (missing > 1) {
16974
+ return (labels.missingText ?? "{n} sin ubicaci\xF3n registrada").replace("{n}", String(missing));
16975
+ }
16976
+ return labels.emptyText ?? "Sin ubicaciones para mostrar";
16977
+ }
16967
16978
 
16968
- const CLASS$5 = `${COMPONENT_PREFIX$1}service-shortcuts`;
16979
+ const CLASS$7 = `${COMPONENT_PREFIX$1}service-shortcuts`;
16969
16980
  const ICONS = {
16970
16981
  // SPEC-126 — quien DESPACHA tambien necesita sus puertas, y una de ellas son las conversaciones
16971
16982
  // de sus servicios. Los cinco iconos que habia eran todos de quien PIDE una grua.
@@ -16995,6 +17006,15 @@ const ICONS = {
16995
17006
  /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "11", cy: "11", r: "7" }),
16996
17007
  /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "16.5", y1: "16.5", x2: "21", y2: "21" })
16997
17008
  ] }),
17009
+ // SPEC-139 — una grúa con un «más»: inscribir la mía.
17010
+ enroll: /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
17011
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M3 17V8h8l3 4h4v5" }),
17012
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "7", cy: "17", r: "2" }),
17013
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "16", cy: "17", r: "2" }),
17014
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "9", y1: "17", x2: "14", y2: "17" }),
17015
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "19", y1: "3", x2: "19", y2: "9" }),
17016
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "16", y1: "6", x2: "22", y2: "6" })
17017
+ ] }),
16998
17018
  // SPEC-008 — quien tiene cuenta: operadora, empresa aliada o conductor.
16999
17019
  user: /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
17000
17020
  /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "12", cy: "8", r: "4" }),
@@ -17010,16 +17030,16 @@ const ServiceShortcuts = ({
17010
17030
  }) => {
17011
17031
  if (!options?.length) return null;
17012
17032
  const elegido = !!selectedId;
17013
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: [CLASS$5, elegido ? `${CLASS$5}--used` : ""].filter(Boolean).join(" "), children: options.map((o) => {
17033
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: [CLASS$7, elegido ? `${CLASS$7}--used` : ""].filter(Boolean).join(" "), children: options.map((o) => {
17014
17034
  const esElegido = o.id === selectedId;
17015
17035
  return /* @__PURE__ */ jsxRuntime.jsxs(
17016
17036
  "button",
17017
17037
  {
17018
17038
  type: "button",
17019
17039
  className: [
17020
- `${CLASS$5}__item`,
17021
- elegido ? `${CLASS$5}__item--off` : "",
17022
- esElegido ? `${CLASS$5}__item--chosen` : ""
17040
+ `${CLASS$7}__item`,
17041
+ elegido ? `${CLASS$7}__item--off` : "",
17042
+ esElegido ? `${CLASS$7}__item--chosen` : ""
17023
17043
  ].filter(Boolean).join(" "),
17024
17044
  disabled: elegido,
17025
17045
  "aria-disabled": elegido,
@@ -17030,12 +17050,12 @@ const ServiceShortcuts = ({
17030
17050
  else if (o.route) eventBus?.emit(CHAT_EVENT.NAVIGATE, { route: o.route });
17031
17051
  },
17032
17052
  children: [
17033
- o.icon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${CLASS$5}__icon`, children: ICONS[o.icon] }),
17034
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: `${CLASS$5}__text`, children: [
17035
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${CLASS$5}__label`, children: o.label }),
17036
- o.hint && /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${CLASS$5}__hint`, children: o.hint })
17053
+ o.icon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${CLASS$7}__icon`, children: ICONS[o.icon] }),
17054
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: `${CLASS$7}__text`, children: [
17055
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${CLASS$7}__label`, children: o.label }),
17056
+ o.hint && /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${CLASS$7}__hint`, children: o.hint })
17037
17057
  ] }),
17038
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${CLASS$5}__arrow`, children: esElegido ? CHECK : elegido ? null : /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "9 18 15 12 9 6" }) }) })
17058
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${CLASS$7}__arrow`, children: esElegido ? CHECK : elegido ? null : /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "9 18 15 12 9 6" }) }) })
17039
17059
  ]
17040
17060
  },
17041
17061
  o.id
@@ -17604,25 +17624,44 @@ function ChatNavigatorChat({ component, eventBus }) {
17604
17624
  ] });
17605
17625
  }
17606
17626
 
17607
- const CLASS$4 = `${COMPONENT_PREFIX$1}user-tools`;
17608
- const UserTools = ({ config, onChange, className }) => {
17627
+ const CLASS$6 = `${COMPONENT_PREFIX$1}user-tools`;
17628
+ const UserTools = ({ config, onChange, onAction, className }) => {
17609
17629
  const { title, description, items } = config;
17610
- return /* @__PURE__ */ jsxRuntime.jsxs("section", { className: [CLASS$4, className].filter(Boolean).join(" "), children: [
17611
- title && /* @__PURE__ */ jsxRuntime.jsx("h2", { className: `${CLASS$4}__title`, children: title }),
17612
- description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: `${CLASS$4}__description`, children: description }),
17613
- /* @__PURE__ */ jsxRuntime.jsx("ul", { className: `${CLASS$4}__list`, children: items.map((item) => /* @__PURE__ */ jsxRuntime.jsx("li", { className: `${CLASS$4}__item`, children: /* @__PURE__ */ jsxRuntime.jsx(
17630
+ return /* @__PURE__ */ jsxRuntime.jsxs("section", { className: [CLASS$6, className].filter(Boolean).join(" "), children: [
17631
+ title && /* @__PURE__ */ jsxRuntime.jsx("h2", { className: `${CLASS$6}__title`, children: title }),
17632
+ description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: `${CLASS$6}__description`, children: description }),
17633
+ /* @__PURE__ */ jsxRuntime.jsx("ul", { className: `${CLASS$6}__list`, children: items.map((item) => /* @__PURE__ */ jsxRuntime.jsx("li", { className: `${CLASS$6}__item`, children: item.kind === "action" ? (
17634
+ // SPEC-139 T9 — un ajuste que se pulsa: mismo renglón (etiqueta y pista), y en vez
17635
+ // de la caja, un botón que dice lo que hace.
17636
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${CLASS$6}__action`, children: [
17637
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: `${CLASS$6}__text`, children: [
17638
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${CLASS$6}__label`, children: item.label }),
17639
+ item.hint && /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${CLASS$6}__hint`, children: item.hint })
17640
+ ] }),
17641
+ /* @__PURE__ */ jsxRuntime.jsx(
17642
+ Button,
17643
+ {
17644
+ variant: "secondary",
17645
+ size: "small",
17646
+ disabled: item.disabled,
17647
+ onClick: () => onAction?.(item.id),
17648
+ children: item.label
17649
+ }
17650
+ )
17651
+ ] })
17652
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
17614
17653
  Checkbox$1,
17615
17654
  {
17616
- checked: item.value,
17655
+ checked: Boolean(item.value),
17617
17656
  disabled: item.disabled,
17618
17657
  onChange: (checked) => onChange?.(item.id, checked),
17619
- label: /* @__PURE__ */ jsxRuntime.jsxs("span", { className: `${CLASS$4}__text`, children: [
17620
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${CLASS$4}__label`, children: item.label }),
17621
- item.hint && /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${CLASS$4}__hint`, children: item.hint })
17658
+ label: /* @__PURE__ */ jsxRuntime.jsxs("span", { className: `${CLASS$6}__text`, children: [
17659
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${CLASS$6}__label`, children: item.label }),
17660
+ item.hint && /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${CLASS$6}__hint`, children: item.hint })
17622
17661
  ] })
17623
17662
  }
17624
17663
  ) }, item.id)) }),
17625
- items.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("p", { className: `${CLASS$4}__empty`, children: "No hay herramientas disponibles por ahora." })
17664
+ items.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("p", { className: `${CLASS$6}__empty`, children: "No hay herramientas disponibles por ahora." })
17626
17665
  ] });
17627
17666
  };
17628
17667
  UserTools.displayName = "UserTools";
@@ -17662,6 +17701,14 @@ function UserToolsChat({ component, eventBus }) {
17662
17701
  value
17663
17702
  });
17664
17703
  };
17704
+ const handleAction = (id) => {
17705
+ eventBus?.emit(CHAT_EVENT.COMPONENT_INTERACTION, {
17706
+ type: "user_tools",
17707
+ id,
17708
+ kind: "action",
17709
+ value: true
17710
+ });
17711
+ };
17665
17712
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
17666
17713
  /* @__PURE__ */ jsxRuntime.jsxs("button", { type: "button", className: "px-chat-reactive-crud-trigger", onClick: () => setOpen(true), children: [
17667
17714
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "px-chat-reactive-crud-trigger__icon", children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
@@ -17686,7 +17733,7 @@ function UserToolsChat({ component, eventBus }) {
17686
17733
  }
17687
17734
  )
17688
17735
  ] }),
17689
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-chat-reactive-crud-fs__body", children: /* @__PURE__ */ jsxRuntime.jsx(UserTools, { config, onChange: handleChange }) })
17736
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-chat-reactive-crud-fs__body", children: /* @__PURE__ */ jsxRuntime.jsx(UserTools, { config, onChange: handleChange, onAction: handleAction }) })
17690
17737
  ] }),
17691
17738
  document.body
17692
17739
  )
@@ -18224,7 +18271,7 @@ const ChatHeader = ({
18224
18271
  ] });
18225
18272
  };
18226
18273
 
18227
- const CLASS$3 = `${COMPONENT_PREFIX$1}floating-actions`;
18274
+ const CLASS$5 = `${COMPONENT_PREFIX$1}floating-actions`;
18228
18275
  const ICON_VALUES = new Set(Object.values(ICON_TYPES));
18229
18276
  function renderIcon(icon) {
18230
18277
  if (typeof icon === "string" && ICON_VALUES.has(icon)) {
@@ -18233,23 +18280,23 @@ function renderIcon(icon) {
18233
18280
  return icon;
18234
18281
  }
18235
18282
  function Side({ buttons, align, eventBus }) {
18236
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `${CLASS$3}__group ${CLASS$3}__group--${align}`, children: buttons.map((b) => {
18283
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `${CLASS$5}__group ${CLASS$5}__group--${align}`, children: buttons.map((b) => {
18237
18284
  const emit = () => {
18238
18285
  if (b.disabled) return;
18239
18286
  eventBus.emit(b.event, b.payload);
18240
18287
  };
18241
18288
  if (b.custom) {
18242
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${CLASS$3}__slot`, children: [
18289
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${CLASS$5}__slot`, children: [
18243
18290
  b.custom,
18244
- b.panel && b.open && /* @__PURE__ */ jsxRuntime.jsx("div", { className: `${CLASS$3}__panel ${CLASS$3}__panel--${align}`, children: b.panel })
18291
+ b.panel && b.open && /* @__PURE__ */ jsxRuntime.jsx("div", { className: `${CLASS$5}__panel ${CLASS$5}__panel--${align}`, children: b.panel })
18245
18292
  ] }, b.id);
18246
18293
  }
18247
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${CLASS$3}__slot`, children: [
18294
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${CLASS$5}__slot`, children: [
18248
18295
  /* @__PURE__ */ jsxRuntime.jsxs(
18249
18296
  "button",
18250
18297
  {
18251
18298
  type: "button",
18252
- className: [`${CLASS$3}__button`, b.active ? `${CLASS$3}__button--active` : ""].filter(Boolean).join(" "),
18299
+ className: [`${CLASS$5}__button`, b.active ? `${CLASS$5}__button--active` : ""].filter(Boolean).join(" "),
18253
18300
  "aria-label": b.ariaLabel,
18254
18301
  title: b.ariaLabel,
18255
18302
  "aria-pressed": b.active,
@@ -18257,16 +18304,16 @@ function Side({ buttons, align, eventBus }) {
18257
18304
  onClick: emit,
18258
18305
  children: [
18259
18306
  renderIcon(b.icon),
18260
- b.badge != null && b.badge !== "" && b.badge !== 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${CLASS$3}__badge`, children: b.badge })
18307
+ b.badge != null && b.badge !== "" && b.badge !== 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${CLASS$5}__badge`, children: b.badge })
18261
18308
  ]
18262
18309
  }
18263
18310
  ),
18264
- b.panel && b.open && /* @__PURE__ */ jsxRuntime.jsx("div", { className: `${CLASS$3}__panel ${CLASS$3}__panel--${align}`, children: b.panel })
18311
+ b.panel && b.open && /* @__PURE__ */ jsxRuntime.jsx("div", { className: `${CLASS$5}__panel ${CLASS$5}__panel--${align}`, children: b.panel })
18265
18312
  ] }, b.id);
18266
18313
  }) });
18267
18314
  }
18268
18315
  const ChatFloatingActions = ({ eventBus, left = [], right = [], offset = 12, glass = false }) => {
18269
- const cls = [CLASS$3, glass ? `${CLASS$3}--glass` : ""].filter(Boolean).join(" ");
18316
+ const cls = [CLASS$5, glass ? `${CLASS$5}--glass` : ""].filter(Boolean).join(" ");
18270
18317
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cls, style: { paddingLeft: offset, paddingRight: offset }, children: [
18271
18318
  /* @__PURE__ */ jsxRuntime.jsx(Side, { buttons: left, align: "left", eventBus }),
18272
18319
  /* @__PURE__ */ jsxRuntime.jsx(Side, { buttons: right, align: "right", eventBus })
@@ -18699,6 +18746,176 @@ const UserMessage = ({
18699
18746
  ] }) });
18700
18747
  };
18701
18748
 
18749
+ const CLASS$4 = `${COMPONENT_PREFIX$1}photo-picker`;
18750
+ const PhotoPicker = ({
18751
+ label,
18752
+ hint,
18753
+ required,
18754
+ max,
18755
+ capture,
18756
+ entries,
18757
+ disabled,
18758
+ error,
18759
+ onFiles,
18760
+ onRemove
18761
+ }) => {
18762
+ const galeriaRef = React.useRef(null);
18763
+ const camaraRef = React.useRef(null);
18764
+ const hechas = entries.filter((e) => e.status === "done").length;
18765
+ const subiendo = entries.some((e) => e.status === "uploading");
18766
+ const lleno = max !== void 0 && entries.length >= max;
18767
+ const elegir = (ref) => {
18768
+ if (!disabled && !lleno) ref.current?.click();
18769
+ };
18770
+ const alCambiar = (e) => {
18771
+ void onFiles(e.target.files);
18772
+ e.target.value = "";
18773
+ };
18774
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${CLASS$4}${error ? ` ${CLASS$4}--error` : ""}`, children: [
18775
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: `${CLASS$4}__label`, children: [
18776
+ label,
18777
+ required ? " *" : "",
18778
+ hechas > 0 ? ` (${hechas}${max ? `/${max}` : ""})` : ""
18779
+ ] }),
18780
+ /* @__PURE__ */ jsxRuntime.jsx(
18781
+ "input",
18782
+ {
18783
+ ref: galeriaRef,
18784
+ className: `${CLASS$4}__native`,
18785
+ type: "file",
18786
+ accept: "image/*",
18787
+ multiple: max !== 1,
18788
+ disabled,
18789
+ onChange: alCambiar,
18790
+ "data-testid": "photo-picker-gallery"
18791
+ }
18792
+ ),
18793
+ capture && /* @__PURE__ */ jsxRuntime.jsx(
18794
+ "input",
18795
+ {
18796
+ ref: camaraRef,
18797
+ className: `${CLASS$4}__native`,
18798
+ type: "file",
18799
+ accept: "image/*",
18800
+ capture: "environment",
18801
+ disabled,
18802
+ onChange: alCambiar,
18803
+ "data-testid": "photo-picker-camera"
18804
+ }
18805
+ ),
18806
+ entries.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("ul", { className: `${CLASS$4}__grid`, children: entries.map((e, i) => /* @__PURE__ */ jsxRuntime.jsxs("li", { className: `${CLASS$4}__thumb ${CLASS$4}__thumb--${e.status}`, children: [
18807
+ e.previewUrl ? /* @__PURE__ */ jsxRuntime.jsx("img", { className: `${CLASS$4}__img`, src: e.previewUrl, alt: e.name }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${CLASS$4}__placeholder`, "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx(Icon$1, { type: ICON_TYPES.IMAGE }) }),
18808
+ e.status === "uploading" && /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${CLASS$4}__state`, children: "Subiendo\u2026" }),
18809
+ e.status === "error" && /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${CLASS$4}__state ${CLASS$4}__state--error`, children: "No se pudo subir" }),
18810
+ onRemove && e.status !== "uploading" && /* @__PURE__ */ jsxRuntime.jsx(
18811
+ "button",
18812
+ {
18813
+ type: "button",
18814
+ className: `${CLASS$4}__remove`,
18815
+ onClick: () => onRemove(i),
18816
+ "aria-label": `Quitar ${e.name}`,
18817
+ disabled,
18818
+ children: /* @__PURE__ */ jsxRuntime.jsx(Icon$1, { type: ICON_TYPES.CLOSE, size: "small" })
18819
+ }
18820
+ )
18821
+ ] }, `${e.name}-${i}`)) }),
18822
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${CLASS$4}__actions`, children: [
18823
+ capture && /* @__PURE__ */ jsxRuntime.jsxs(
18824
+ "button",
18825
+ {
18826
+ type: "button",
18827
+ className: `${CLASS$4}__pick`,
18828
+ onClick: () => elegir(camaraRef),
18829
+ disabled: disabled || lleno,
18830
+ children: [
18831
+ /* @__PURE__ */ jsxRuntime.jsx(Icon$1, { type: ICON_TYPES.IMAGE, size: "small" }),
18832
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Tomar foto" })
18833
+ ]
18834
+ }
18835
+ ),
18836
+ /* @__PURE__ */ jsxRuntime.jsxs(
18837
+ "button",
18838
+ {
18839
+ type: "button",
18840
+ className: `${CLASS$4}__pick ${CLASS$4}__pick--secondary`,
18841
+ onClick: () => elegir(galeriaRef),
18842
+ disabled: disabled || lleno,
18843
+ children: [
18844
+ /* @__PURE__ */ jsxRuntime.jsx(Icon$1, { type: ICON_TYPES.UPLOAD, size: "small" }),
18845
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: entries.length === 0 ? "Elegir fotos" : "A\xF1adir m\xE1s" })
18846
+ ]
18847
+ }
18848
+ )
18849
+ ] }),
18850
+ error && /* @__PURE__ */ jsxRuntime.jsx("p", { className: `${CLASS$4}__error`, children: error }),
18851
+ !error && subiendo && /* @__PURE__ */ jsxRuntime.jsx("p", { className: `${CLASS$4}__hint`, children: "Espera a que terminen de subir." }),
18852
+ !error && !subiendo && hint && /* @__PURE__ */ jsxRuntime.jsx("p", { className: `${CLASS$4}__hint`, children: hint })
18853
+ ] });
18854
+ };
18855
+
18856
+ const CLASS$3 = `${COMPONENT_PREFIX$1}credentials-card`;
18857
+ async function copiar(texto) {
18858
+ try {
18859
+ await navigator.clipboard.writeText(texto);
18860
+ return true;
18861
+ } catch {
18862
+ return false;
18863
+ }
18864
+ }
18865
+ const Fila = ({ row }) => {
18866
+ const [copiado, setCopiado] = React.useState(false);
18867
+ const [visible, setVisible] = React.useState(!row.masked);
18868
+ React.useEffect(() => {
18869
+ if (!copiado) return;
18870
+ const t = setTimeout(() => setCopiado(false), 1800);
18871
+ return () => clearTimeout(t);
18872
+ }, [copiado]);
18873
+ return /* @__PURE__ */ jsxRuntime.jsxs("li", { className: `${CLASS$3}__row`, children: [
18874
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${CLASS$3}__label`, children: row.label }),
18875
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${CLASS$3}__value`, "data-testid": `credential-${row.label}`, children: visible ? row.value : "\u2022".repeat(Math.min(row.value.length, 12)) }),
18876
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: `${CLASS$3}__tools`, children: [
18877
+ row.masked && /* @__PURE__ */ jsxRuntime.jsx(
18878
+ "button",
18879
+ {
18880
+ type: "button",
18881
+ className: `${CLASS$3}__tool`,
18882
+ onClick: () => setVisible((v) => !v),
18883
+ "aria-label": visible ? `Ocultar ${row.label}` : `Ver ${row.label}`,
18884
+ children: visible ? "Ocultar" : "Ver"
18885
+ }
18886
+ ),
18887
+ row.copyable !== false && /* @__PURE__ */ jsxRuntime.jsx(
18888
+ "button",
18889
+ {
18890
+ type: "button",
18891
+ className: `${CLASS$3}__tool`,
18892
+ onClick: async () => setCopiado(await copiar(row.value)),
18893
+ "aria-label": `Copiar ${row.label}`,
18894
+ children: copiado ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
18895
+ /* @__PURE__ */ jsxRuntime.jsx(Icon$1, { type: ICON_TYPES.CHECK, size: "small" }),
18896
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Copiado" })
18897
+ ] }) : "Copiar"
18898
+ }
18899
+ )
18900
+ ] })
18901
+ ] });
18902
+ };
18903
+ const CredentialsCard = ({
18904
+ title,
18905
+ intro,
18906
+ rows,
18907
+ note,
18908
+ action,
18909
+ className
18910
+ }) => /* @__PURE__ */ jsxRuntime.jsxs("section", { className: [CLASS$3, className].filter(Boolean).join(" "), "aria-label": title, children: [
18911
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: `${CLASS$3}__title`, children: title }),
18912
+ intro && /* @__PURE__ */ jsxRuntime.jsx("p", { className: `${CLASS$3}__intro`, children: intro }),
18913
+ /* @__PURE__ */ jsxRuntime.jsx("ul", { className: `${CLASS$3}__rows`, children: rows.map((r) => /* @__PURE__ */ jsxRuntime.jsx(Fila, { row: r }, r.label)) }),
18914
+ note && /* @__PURE__ */ jsxRuntime.jsx("p", { className: `${CLASS$3}__note`, children: note }),
18915
+ action && /* @__PURE__ */ jsxRuntime.jsx("div", { className: `${CLASS$3}__action`, children: /* @__PURE__ */ jsxRuntime.jsx(Button, { fullWidth: true, onClick: action.onClick, disabled: action.disabled, children: action.label }) })
18916
+ ] });
18917
+ CredentialsCard.displayName = "CredentialsCard";
18918
+
18702
18919
  const FADE_AFTER_MS = 4e3;
18703
18920
  const NewMessageDivider = ({
18704
18921
  label = "Nuevo mensaje",
@@ -24961,6 +25178,7 @@ exports.ChatTextarea = Textarea;
24961
25178
  exports.ChatUserAttachments = UserAttachments;
24962
25179
  exports.ChatUserMessage = UserMessage;
24963
25180
  exports.ChatWidget = ChatWidget;
25181
+ exports.CredentialsCard = CredentialsCard;
24964
25182
  exports.FileField = FileField;
24965
25183
  exports.LUMI_BADGE_VARIANTS = BADGE_VARIANTS;
24966
25184
  exports.LUMI_DEFAULT_TITLES = DEFAULT_TITLES;
@@ -25020,6 +25238,7 @@ exports.LumiTextArea = TextArea;
25020
25238
  exports.LumiTimeInput = TimeInput$1;
25021
25239
  exports.LumiTooltip = Tooltip;
25022
25240
  exports.MapView = MapView;
25241
+ exports.PhotoPicker = PhotoPicker;
25023
25242
  exports.ReactiveCrud = ReactiveCrud;
25024
25243
  exports.ServiceShortcuts = ServiceShortcuts;
25025
25244
  exports.ServicesMap = ServicesMap;