@beweco/aurora-ui 1.0.0-beta.141 → 1.0.0-beta.145

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.
Files changed (71) hide show
  1. package/dist/assets/css/styles.css +34 -3
  2. package/dist/assets/css/theme.css +18 -0
  3. package/dist/index.cjs.js +617 -320
  4. package/dist/index.esm.js +514 -214
  5. package/dist/types/compat/heroui-v2-shims.d.ts.map +1 -1
  6. package/dist/types/components/alert/Alert.d.ts.map +1 -1
  7. package/dist/types/components/analytics-card/AnalyticsCard.d.ts.map +1 -1
  8. package/dist/types/components/autocomplete/AutoComplete.d.ts.map +1 -1
  9. package/dist/types/components/breadcrumbs/Breadcrumbs.d.ts.map +1 -1
  10. package/dist/types/components/button/Button.d.ts.map +1 -1
  11. package/dist/types/components/card/Card.d.ts.map +1 -1
  12. package/dist/types/components/checkbox/Checkbox.d.ts.map +1 -1
  13. package/dist/types/components/chip/Chip.d.ts.map +1 -1
  14. package/dist/types/components/color-picker/ColorPicker.d.ts.map +1 -1
  15. package/dist/types/components/copy-text/CopyText.d.ts.map +1 -1
  16. package/dist/types/components/datepicker/DatePicker.d.ts.map +1 -1
  17. package/dist/types/components/datepicker/calendar-slots.d.ts.map +1 -1
  18. package/dist/types/components/drawer/Drawer.d.ts.map +1 -1
  19. package/dist/types/components/drawer/_internal/DrawerBody.d.ts.map +1 -1
  20. package/dist/types/components/drawer/_internal/DrawerFooter.d.ts +3 -1
  21. package/dist/types/components/drawer/_internal/DrawerFooter.d.ts.map +1 -1
  22. package/dist/types/components/drawer/_internal/DrawerHeader.d.ts.map +1 -1
  23. package/dist/types/components/drawer-filters/DrawerFilters.d.ts.map +1 -1
  24. package/dist/types/components/drawer-filters/_internal/DayMonthPicker.d.ts +6 -0
  25. package/dist/types/components/drawer-filters/_internal/DayMonthPicker.d.ts.map +1 -1
  26. package/dist/types/components/drawer-filters/_internal/FilterSection.d.ts.map +1 -1
  27. package/dist/types/components/dropdown/Dropdown.d.ts.map +1 -1
  28. package/dist/types/components/dropdown/_internal/renderTrigger.d.ts.map +1 -1
  29. package/dist/types/components/h1/H1.d.ts.map +1 -1
  30. package/dist/types/components/h2/H2.d.ts.map +1 -1
  31. package/dist/types/components/h3/H3.d.ts.map +1 -1
  32. package/dist/types/components/h4/H4.d.ts.map +1 -1
  33. package/dist/types/components/input/Input.d.ts.map +1 -1
  34. package/dist/types/components/kanban/_internal/KanbanColumn.d.ts.map +1 -1
  35. package/dist/types/components/menu/_internal/menu-mobile-bottom-bar/MenuMobileBottomBar.d.ts.map +1 -1
  36. package/dist/types/components/menu/_internal/menu-nav-list/MenuNavList.d.ts.map +1 -1
  37. package/dist/types/components/menu-claw/MenuClaw.d.ts.map +1 -1
  38. package/dist/types/components/menu-claw/_internal/menu-claw-history/MenuClawHistoryPanel.d.ts.map +1 -1
  39. package/dist/types/components/menu-claw/_internal/menu-claw-nav/MenuClawNavItem.d.ts.map +1 -1
  40. package/dist/types/components/modal/Modal.d.ts.map +1 -1
  41. package/dist/types/components/modal/_internal/ModalBody.d.ts +1 -1
  42. package/dist/types/components/modal/_internal/ModalBody.d.ts.map +1 -1
  43. package/dist/types/components/modal/_internal/ModalFooter.d.ts +6 -0
  44. package/dist/types/components/modal/_internal/ModalFooter.d.ts.map +1 -1
  45. package/dist/types/components/modal/_internal/ModalHeader.d.ts.map +1 -1
  46. package/dist/types/components/multi-step-wizard/_internal/MultiStepSidebar.d.ts.map +1 -1
  47. package/dist/types/components/multi-step-wizard/_internal/MultistepNavigationButtons.d.ts.map +1 -1
  48. package/dist/types/components/p/P.d.ts.map +1 -1
  49. package/dist/types/components/pagination/Pagination.d.ts.map +1 -1
  50. package/dist/types/components/range-filter/RangeFilter.d.ts.map +1 -1
  51. package/dist/types/components/row-steps/RowSteps.d.ts.map +1 -1
  52. package/dist/types/components/select/Select.d.ts.map +1 -1
  53. package/dist/types/components/step-indicator/StepIndicator.d.ts.map +1 -1
  54. package/dist/types/components/switch/Switch.d.ts.map +1 -1
  55. package/dist/types/components/switch/Switch.types.d.ts +22 -0
  56. package/dist/types/components/switch/Switch.types.d.ts.map +1 -1
  57. package/dist/types/components/switch/index.d.ts +1 -1
  58. package/dist/types/components/switch/index.d.ts.map +1 -1
  59. package/dist/types/components/table/Table.d.ts.map +1 -1
  60. package/dist/types/components/table/TableContent.d.ts.map +1 -1
  61. package/dist/types/components/table/_internal/v2-compat.d.ts.map +1 -1
  62. package/dist/types/components/tabs/Tabs.d.ts.map +1 -1
  63. package/dist/types/components/textarea/Textarea.d.ts.map +1 -1
  64. package/dist/types/components/time-input/TimeInput.d.ts.map +1 -1
  65. package/dist/types/components/tooltip/Tooltip.d.ts.map +1 -1
  66. package/dist/types/components/vertical-steps/VerticalSteps.d.ts.map +1 -1
  67. package/dist/types/index.d.ts +2 -1
  68. package/dist/types/index.d.ts.map +1 -1
  69. package/dist/types/utils/cn.d.ts +46 -0
  70. package/dist/types/utils/cn.d.ts.map +1 -0
  71. package/package.json +3 -2
package/dist/index.cjs.js CHANGED
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var react = require('@heroui/react');
4
+ var tailwindVariants = require('tailwind-variants');
4
5
  var jsxRuntime = require('react/jsx-runtime');
5
6
  var $8WNJc$react = require('react');
6
7
  var react$1 = require('@iconify/react');
@@ -8,6 +9,74 @@ var recharts = require('recharts');
8
9
  var $3wX5A$reactdom = require('react-dom');
9
10
  var framerMotion = require('framer-motion');
10
11
 
12
+ /**
13
+ * `cn` de Aurora: el mismo `cn` de `tailwind-variants` que reexporta HeroUI v3, pero con
14
+ * `tailwind-merge` enseñado a reconocer el vocabulario de HeroUI v2.
15
+ *
16
+ * Por qué existe (TECH-2459): el `cn` de v3 corre sobre `tailwind-merge` 3, que no conoce la
17
+ * escala `tiny/small/medium/large` del plugin `heroui()` de v2. Sin esta configuración:
18
+ *
19
+ * - `cn("text-tiny text-default-500")` → `"text-default-500"`: lee `text-tiny` como un COLOR
20
+ * (`text-<cualquier cosa>` casa con el validador de color), ve otro color detrás y la BORRA
21
+ * del DOM. Medido en `P.tsx`: texto a 16px en vez de 12px.
22
+ * - `cn("border-medium border-default-200")` y `cn("shadow-small shadow-primary")` igual:
23
+ * `border-*` y `shadow-*` también caen en el validador de color.
24
+ * - `cn("rounded-medium rounded-none")` → conserva las dos: no la reconoce como radio, así
25
+ * que el conflicto real no se resuelve y gana la que venga después en la hoja.
26
+ *
27
+ * Las utilidades en sí (`.text-tiny`, `.rounded-medium`…) las genera el Tailwind de la app a
28
+ * partir de los tokens `--text-*`, `--radius-*`, `--border-width-*` y `--shadow-*` que publica
29
+ * `theme-tokens.generated.css` (export `./theme`). Esto solo cubre la otra mitad: que `cn` no
30
+ * las borre ni las deje sin resolver.
31
+ *
32
+ * La escala sale del plugin v2 (`@heroui/theme@2.4.15`, `corePlugin` → `theme.extend`):
33
+ * `fontSize` tiny/small/medium/large, `borderRadius` small/medium/large, `borderWidth`
34
+ * small/medium/large, `boxShadow` small/medium/large. Nada más: la escala `*-unit-*` NO existía
35
+ * en 2.4.15 (ya estaba muerta en v2) y no se repone.
36
+ *
37
+ * Se exporta como `cn` del paquete, así que el de las apps y el de las fachadas es el mismo.
38
+ * Las fachadas deben importarlo de aquí, nunca de `@heroui/react` (lo vigila `cn.test.ts`).
39
+ */
40
+ const V2_TEXT = ["tiny", "small", "medium", "large"];
41
+ const V2_SIZES = ["small", "medium", "large"];
42
+ /**
43
+ * Extensión de `tailwind-merge` (formato `twMergeConfig` de tailwind-variants).
44
+ *
45
+ * `theme.text`/`radius`/`shadow` alimentan los grupos `font-size`, `rounded*` (todas las
46
+ * esquinas y lados) y `shadow`. El ancho de borde no lee del tema en tailwind-merge 3
47
+ * (`scaleBorderWidth` es fijo), así que se extienden sus grupos uno a uno.
48
+ */
49
+ const BORDER_WIDTH_GROUPS = [
50
+ ["border-w", "border"],
51
+ ["border-w-x", "border-x"],
52
+ ["border-w-y", "border-y"],
53
+ ["border-w-s", "border-s"],
54
+ ["border-w-e", "border-e"],
55
+ ["border-w-bs", "border-bs"],
56
+ ["border-w-be", "border-be"],
57
+ ["border-w-t", "border-t"],
58
+ ["border-w-r", "border-r"],
59
+ ["border-w-b", "border-b"],
60
+ ["border-w-l", "border-l"],
61
+ ];
62
+ const AURORA_TW_MERGE_CONFIG = {
63
+ extend: {
64
+ theme: {
65
+ text: V2_TEXT,
66
+ radius: V2_SIZES,
67
+ shadow: V2_SIZES,
68
+ },
69
+ classGroups: Object.fromEntries(BORDER_WIDTH_GROUPS.map(([group, prefix]) => [
70
+ group,
71
+ [{ [prefix]: V2_SIZES }],
72
+ ])),
73
+ },
74
+ };
75
+ // Referencia estable: tailwind-variants cachea el merger por igualdad con la última config.
76
+ const MERGE_OPTIONS = { twMergeConfig: AURORA_TW_MERGE_CONFIG };
77
+ /** Combina clases y resuelve conflictos de Tailwind, conociendo la escala de HeroUI v2. */
78
+ const cn = (...classnames) => tailwindVariants.cnMerge(...classnames)(MERGE_OPTIONS);
79
+
11
80
  // ---------------------------------------------------------------------------
12
81
  // Compound v2 → namespaced v3: símbolos que SÍ desaparecieron como export plano
13
82
  // (verificado: no están en los `export { … }` de sus módulos v3, a diferencia
@@ -94,7 +163,7 @@ function flattenChildren(children) {
94
163
  */
95
164
  function ProgressFacade({ label, showValueLabel = false, size = "md", color = "primary", classNames, className, children, ...props }) {
96
165
  if (typeof children === "function") {
97
- return (jsxRuntime.jsx(react.ProgressBar, { ...props, size: size, color: PROGRESS_V3_COLOR[color], className: react.cn(PROGRESS_FILL_OVERRIDE[color], classNames?.base, className), children: children }));
166
+ return (jsxRuntime.jsx(react.ProgressBar, { ...props, size: size, color: PROGRESS_V3_COLOR[color], className: cn(PROGRESS_FILL_OVERRIDE[color], classNames?.base, className), children: children }));
98
167
  }
99
168
  const own = flattenChildren(children);
100
169
  const hasTrack = own.some((c) => c.type === react.ProgressBar.Track || c.type === react.ProgressBar.Fill);
@@ -103,7 +172,7 @@ function ProgressFacade({ label, showValueLabel = false, size = "md", color = "p
103
172
  return (jsxRuntime.jsxs(react.ProgressBar, { ...props, size: size, color: PROGRESS_V3_COLOR[color],
104
173
  // v2: `cn(classNames?.base, className)` en la raíz (`use-progress.mjs`). La variable del
105
174
  // color va primero para que un `[--progress-bar-fill:…]` del consumidor la sustituya.
106
- className: react.cn(PROGRESS_FILL_OVERRIDE[color], classNames?.base, className), children: [label != null && label !== false && !hasLabel && (jsxRuntime.jsx(react.Label, { className: classNames?.label, children: label })), showValueLabel && !hasOutput && (jsxRuntime.jsx(react.ProgressBar.Output, { className: classNames?.value })), children, !hasTrack && (jsxRuntime.jsx(react.ProgressBar.Track, { className: classNames?.track, children: jsxRuntime.jsx(react.ProgressBar.Fill, { className: classNames?.indicator }) }))] }));
175
+ className: cn(PROGRESS_FILL_OVERRIDE[color], classNames?.base, className), children: [label != null && label !== false && !hasLabel && (jsxRuntime.jsx(react.Label, { className: classNames?.label, children: label })), showValueLabel && !hasOutput && (jsxRuntime.jsx(react.ProgressBar.Output, { className: classNames?.value })), children, !hasTrack && (jsxRuntime.jsx(react.ProgressBar.Track, { className: classNames?.track, children: jsxRuntime.jsx(react.ProgressBar.Fill, { className: classNames?.indicator }) }))] }));
107
176
  }
108
177
  /**
109
178
  * `Progress` de v2 con la anatomía de v3 dentro, y con los estáticos del compound colgados
@@ -171,7 +240,7 @@ const IMAGE_RADIUS_CLASS = {
171
240
  function Image$1({ radius = "lg", classNames, removeWrapper: _removeWrapper, className, ...props }) {
172
241
  return (
173
242
  // biome-ignore lint/a11y/useAltText: passthrough genérico, `alt` lo exige ComponentProps<'img'>
174
- jsxRuntime.jsx("img", { ...props, className: react.cn(IMAGE_RADIUS_CLASS[radius], className, classNames?.img) }));
243
+ jsxRuntime.jsx("img", { ...props, className: cn(IMAGE_RADIUS_CLASS[radius], className, classNames?.img) }));
175
244
  }
176
245
  // ---------------------------------------------------------------------------
177
246
  // Hooks
@@ -697,7 +766,7 @@ const Button = ({ color = "primary", size = "md", variant = "solid", radius = "s
697
766
  };
698
767
  return (jsxRuntime.jsx("a", { ...propsDeEnlace(rest), "data-slot": "button", "data-disabled": deshabilitado || undefined, "aria-disabled": deshabilitado || undefined,
699
768
  // Deshabilitado, sin `href`: un `<a>` no tiene `disabled` y seguiría navegando.
700
- href: deshabilitado ? undefined : href, target: target, rel: rel, download: download, hrefLang: hrefLang, referrerPolicy: referrerPolicy, className: react.cn(react.buttonVariants({
769
+ href: deshabilitado ? undefined : href, target: target, rel: rel, download: download, hrefLang: hrefLang, referrerPolicy: referrerPolicy, className: cn(react.buttonVariants({
701
770
  variant: v3Variant,
702
771
  size,
703
772
  isIconOnly,
@@ -756,7 +825,7 @@ const SHAPE_BY_VARIANT = {
756
825
  light: "transparent",
757
826
  flat: "soft",
758
827
  bordered: "outline",
759
- faded: "outline",
828
+ faded: "faded",
760
829
  // `shadow` de v2 es `solid` + sombra teñida (ver `SHADOW_CLASS`).
761
830
  shadow: "solid",
762
831
  // `dot` de v2: chip neutro con un punto de color (ver `DOT_BASE_CLASS`).
@@ -911,6 +980,7 @@ const V3_VARIANT_BY_SHAPE = {
911
980
  soft: "soft",
912
981
  transparent: "tertiary",
913
982
  outline: "tertiary",
983
+ faded: "tertiary",
914
984
  dot: "tertiary",
915
985
  };
916
986
  /**
@@ -1018,6 +1088,48 @@ const CLOSE_ICON_SIZE_CLASS = {
1018
1088
  md: "size-[18px]",
1019
1089
  lg: "size-5",
1020
1090
  };
1091
+ // ── `bordered` y `faded` (TECH-2459, 24-sep: el usuario ve «muy negro» el `bordered default`) ──
1092
+ //
1093
+ // Antes las dos variantes pintaban borde y texto con `tintFg` (`default-700` = rgb(63,63,70) para
1094
+ // `default`): en el selector de tallas del `addon-card` de beweossmbs el chip sin elegir se leía
1095
+ // como un bloque casi negro al lado del `solid primary` elegido. Y el mismo `tintFg` dejaba el
1096
+ // texto por debajo de AA en otros colores. Medido en `Custom Components/Chip → BorderedColors`
1097
+ // (texto contra el fondo real, blanco / tarjeta `content1` oscura):
1098
+ //
1099
+ // | color | antes claro | antes oscuro | ahora claro | ahora oscuro |
1100
+ // |-----------|-------------|--------------|-------------|--------------|
1101
+ // | default | 10.44 (borde casi negro) | 13.96 (borde casi blanco) | 17.93 | 15.11 |
1102
+ // | primary | 4.66 | 3.80 ✗ | 6.38 | 7.33 |
1103
+ // | secondary | 9.50 | 5.77 | 9.50 | 5.77 |
1104
+ // | success | 2.19 ✗ | 8.08 | 5.50 | 8.08 |
1105
+ // | warning | 2.04 ✗ | 8.68 | 5.20 | 8.68 |
1106
+ // | danger | 4.14 ✗ | 4.27 ✗ | 6.06 | 5.02 |
1107
+ //
1108
+ // Criterio (no es volver a v2 por volver, es que se vea bien dentro de los tokens de Aurora):
1109
+ //
1110
+ // - **Borde**: el color a secas (`border-<color>`). Para `default`, el gris neutro que ya usa el
1111
+ // resto de la familia (`dot` lleva `border-default`, y v2 también en `bordered`/`faded`):
1112
+ // `--color-default`, rgb(212,212,216) en claro y rgb(63,63,70) en oscuro. Se distingue del fondo
1113
+ // (medido: 1.48:1 sobre blanco, 1.70:1 sobre la tarjeta oscura, 2.01:1 sobre el fondo negro) sin
1114
+ // competir con el texto. Input/Select reposan en `default-200`, un paso más claro, porque su borde
1115
+ // enmarca un campo; en un chip el borde ES la forma, y `default-200` (≈1.27:1 sobre blanco,
1116
+ // calculado) la dejaba casi invisible. En oscuro los dos pasos son el mismo rgb(63,63,70).
1117
+ // - **Texto**: el mismo paso legible que ya usa `flat` (`flatFg` + su `dark:`), que es el que la
1118
+ // librería ya validó para texto tintado; `default` usa `foreground`.
1119
+ // - Van como CLASES y no como `borderColor` inline: un estilo inline le ganaba a cualquier
1120
+ // `border-*` de la app, y así `cn` (tailwind-merge) deja ganar la clase del consumidor.
1121
+ // - `faded` conserva lo que lo distinguía en v2 (borde neutro en todos los colores + relleno
1122
+ // `default-100`); hasta ahora era idéntico a `bordered`. Su texto es el `flatFg` SIN el `dark:`
1123
+ // de `flat` (ver `flatDarkFgClass`). Medido: ≥ 4.73:1 en claro y ≥ 4.85:1 en oscuro en los 6
1124
+ // colores. 0 usos en las apps.
1125
+ const OUTLINE_BORDER_CLASS = {
1126
+ default: "border-default",
1127
+ primary: "border-primary",
1128
+ secondary: "border-secondary",
1129
+ success: "border-success",
1130
+ warning: "border-warning",
1131
+ danger: "border-danger",
1132
+ };
1021
1133
  function colorStyle(color, shape) {
1022
1134
  if (shape === "dot") {
1023
1135
  // `dot`: el chip es neutro para cualquier color (el color va solo en el punto).
@@ -1034,7 +1146,14 @@ function colorStyle(color, shape) {
1034
1146
  // `flat` de v2: pastilla translúcida + texto del paso -600/-700 (P-08d).
1035
1147
  return { "--chip-bg": t.flatBg, "--chip-fg": t.flatFg };
1036
1148
  }
1037
- // transparent (light) / outline (bordered, faded): sin relleno, texto tinte del color.
1149
+ if (shape === "outline" || shape === "faded") {
1150
+ // `bordered`/`faded`: texto del paso legible de `flat`; `default` en `foreground`.
1151
+ return {
1152
+ "--chip-bg": shape === "faded" ? "var(--color-default-100)" : "transparent",
1153
+ "--chip-fg": color === "default" ? "var(--color-foreground)" : t.flatFg,
1154
+ };
1155
+ }
1156
+ // transparent (light): sin relleno, texto tinte del color.
1038
1157
  return { "--chip-bg": "transparent", "--chip-fg": t.tintFg };
1039
1158
  }
1040
1159
  /**
@@ -1072,18 +1191,21 @@ const Chip = ({ color = "default", variant = "solid", size = "md", radius = "ful
1072
1191
  : undefined;
1073
1192
  // Con `dot` el color no tiñe el chip, tampoco el de los colores fijos.
1074
1193
  const customClass = isStandard || isDot ? "" : CUSTOM_COLOR_CLASSES[color];
1075
- const outlineClass = shape === "outline" ? "border-2" : "";
1076
- // El `dark:text-*` que v2 declaraba solo para el texto de `flat` en success/warning/danger
1077
- // (P-08d). Va como clase porque `--chip-fg` es inline y no puede depender del tema; la capa
1194
+ const hasBorder = shape === "outline" || shape === "faded";
1195
+ const outlineClass = hasBorder
1196
+ ? cn("border-2", isStandard
1197
+ ? OUTLINE_BORDER_CLASS[shape === "faded" ? "default" : color]
1198
+ : "")
1199
+ : "";
1200
+ // El `dark:text-*` que v2 declaraba para el texto de `flat` en success/warning/danger (P-08d),
1201
+ // reutilizado por `bordered`, que toma el mismo texto. `faded` NO: sobre su relleno
1202
+ // `default-100` oscuro el `danger-500` se quedaba en 4.22:1; con el paso `-600`/`-700` del
1203
+ // tema oscuro (más claro) todos los colores pasan AA. Va como clase porque `--chip-fg` es inline y no puede depender del tema; la capa
1078
1204
  // `utilities` gana al `color: var(--chip-fg)` de `.chip`, que vive en `components`.
1079
- const flatDarkFgClass = isStandard && shape === "soft"
1205
+ const flatDarkFgClass = isStandard && (shape === "soft" || shape === "outline")
1080
1206
  ? (COLOR_TOKENS[color].flatFgDarkClass ?? "")
1081
1207
  : "";
1082
- const baseStyle = vars
1083
- ? shape === "outline"
1084
- ? { ...vars, borderColor: vars["--chip-fg"] }
1085
- : vars
1086
- : undefined;
1208
+ const baseStyle = vars;
1087
1209
  // El `style` del consumidor va DESPUÉS: pisa el relleno/texto calculados (uso real en
1088
1210
  // beweossmbs: `style={{ backgroundColor, color }}` con el color del agente, 5 sitios).
1089
1211
  const style = baseStyle || consumerStyle ? { ...baseStyle, ...consumerStyle } : undefined;
@@ -1105,10 +1227,10 @@ const Chip = ({ color = "default", variant = "solid", size = "md", radius = "ful
1105
1227
  // Con una cadena suelta ambas clases llegan al DOM y gana la que Tailwind emita más
1106
1228
  // tarde, no la del consumidor. Todas las clases de aquí son vocabulario v3 válido, así
1107
1229
  // que tailwind-merge las resuelve bien (la trampa de F1 era con clases v2 muertas).
1108
- className: react.cn(SIZE_CLASS$6[size],
1230
+ className: cn(SIZE_CLASS$6[size],
1109
1231
  // Después de `SIZE_CLASS` a propósito: el cuadrado de un carácter ENCOGE la caja
1110
1232
  // respecto al tamaño normal y tiene que ganar en tailwind-merge.
1111
- isSquare ? ONE_CHAR_CLASS[size] : "", RADIUS_CLASS$9[radius], outlineClass, isDot ? DOT_BASE_CLASS : "", shadowClass, flatDarkFgClass, customClass, isDisabled ? "opacity-50 pointer-events-none" : "", classNames?.base, className), style: style, children: [startContent, isDot && !startContent && (jsxRuntime.jsx("span", { "aria-hidden": "true", "data-slot": "dot", className: react.cn(DOT_SLOT_CLASS, DOT_COLOR_CLASS[color]) })), jsxRuntime.jsx("span", { className: react.cn("flex-1 text-inherit font-normal", startContent
1233
+ isSquare ? ONE_CHAR_CLASS[size] : "", RADIUS_CLASS$9[radius], outlineClass, isDot ? DOT_BASE_CLASS : "", shadowClass, flatDarkFgClass, customClass, isDisabled ? "opacity-50 pointer-events-none" : "", classNames?.base, className), style: style, children: [startContent, isDot && !startContent && (jsxRuntime.jsx("span", { "aria-hidden": "true", "data-slot": "dot", className: cn(DOT_SLOT_CLASS, DOT_COLOR_CLASS[color]) })), jsxRuntime.jsx("span", { className: cn("flex-1 text-inherit font-normal", startContent
1112
1234
  ? CONTENT_PADDING[size].leftWithContent
1113
1235
  : CONTENT_PADDING[size].left, hasEndContent
1114
1236
  ? CONTENT_PADDING[size].rightWithContent
@@ -1121,7 +1243,7 @@ const Chip = ({ color = "default", variant = "solid", size = "md", radius = "ful
1121
1243
  // `.close-button` de v3 impone caja de 24px, `bg-default` y `text-muted`; v2 no
1122
1244
  // pintaba fondo ni caja: el glifo ERA el botón. Se anulan con utilidades (capa
1123
1245
  // `utilities` gana a `components`, incluido el `& svg { size-4 -mx-0.5 my-0.5 }`).
1124
- className: react.cn("h-auto w-auto min-h-0 rounded-full bg-transparent p-0 text-current opacity-70 transition-opacity hover:bg-transparent hover:opacity-100", classNames?.closeButton), onPress: onClose, isDisabled: isDisabled, children: jsxRuntime.jsx("svg", { "aria-hidden": "true", focusable: "false", role: "presentation", viewBox: "0 0 24 24", className: `m-0 shrink-0 ${CLOSE_ICON_SIZE_CLASS[size]}`, children: jsxRuntime.jsx("path", { d: CLOSE_FILLED_PATH, fill: "currentColor" }) }) }))] }));
1246
+ className: cn("h-auto w-auto min-h-0 rounded-full bg-transparent p-0 text-current opacity-70 transition-opacity hover:bg-transparent hover:opacity-100", classNames?.closeButton), onPress: onClose, isDisabled: isDisabled, children: jsxRuntime.jsx("svg", { "aria-hidden": "true", focusable: "false", role: "presentation", viewBox: "0 0 24 24", className: `m-0 shrink-0 ${CLOSE_ICON_SIZE_CLASS[size]}`, children: jsxRuntime.jsx("path", { d: CLOSE_FILLED_PATH, fill: "currentColor" }) }) }))] }));
1125
1247
  };
1126
1248
 
1127
1249
  const sizeMap = {
@@ -1202,6 +1324,20 @@ const STRIP_CLASS = "w-fit gap-0 rounded-[12px] shadow-xs";
1202
1324
  const STRIP_LOOSE_CLASS = "w-fit gap-1";
1203
1325
  /** Controles anterior/siguiente: celda cuadrada, sin el padding lateral de v3. */
1204
1326
  const NAV_CLASS = "w-9 px-0";
1327
+ /**
1328
+ * TECH-2459 (beweossmbs, 24-sep) — anterior/siguiente deshabilitados por estar en un EXTREMO
1329
+ * (página 1 / última). v3 los apaga con `status-disabled` (`opacity: var(--disabled-opacity)`,
1330
+ * `@heroui/styles/dist/components/pagination.css:57`), que aquí deja el galón en el
1331
+ * `text-default-foreground` de `CELL_CLASS` al 50 %: medido `rgb(0,0,0)` a opacidad 0.5 sobre
1332
+ * `default-100`, que se lee como un control activo. Se pinta el galón en `default-300` y a
1333
+ * opacidad plena, el gris de «apagado» de la paleta (el mismo que usaba v2,
1334
+ * `data-[disabled=true]:text-default-300` de `@heroui/theme@2.4.15` `pagination.js:489`); el
1335
+ * cursor y el `pointer-events` de v3 se conservan.
1336
+ *
1337
+ * Solo en los extremos: con `isDisabled` en toda la paginación manda el apagado uniforme de v3
1338
+ * (todas las celdas al 50 %), y las flechas no deben verse distintas del resto.
1339
+ */
1340
+ const NAV_AT_EDGE_CLASS = "disabled:text-default-300 disabled:opacity-100";
1205
1341
  /**
1206
1342
  * Radio de cada pieza según su posición en la tira.
1207
1343
  *
@@ -1276,6 +1412,33 @@ const DEFAULT_TRANSLATIONS$g = {
1276
1412
  jumpBackwardAriaLabel: "Retroceder {count} páginas",
1277
1413
  jumpForwardAriaLabel: "Avanzar {count} páginas",
1278
1414
  };
1415
+ /**
1416
+ * TECH-2459 (beweossmbs, 24-sep) — los mismos textos en inglés, para cuando el idioma de la app es
1417
+ * inglés. El defecto medido: con la interfaz en inglés, «anterior» se anunciaba «Página anterior».
1418
+ * La app SÍ comunica su idioma (`<HeroUIProvider locale="en-US">` → `I18nProvider` de react-aria,
1419
+ * `src/compat/heroui-v2-shims.tsx`), y es el mismo que ya siguen los textos propios de react-aria
1420
+ * (la casilla «Select all» de la tabla, los calendarios…); la fachada lo ignoraba porque solo
1421
+ * miraba `translations`. Ahora el idioma elige la base y `translations` sigue ganando encima.
1422
+ */
1423
+ const EN_TRANSLATIONS = {
1424
+ previousPageAriaLabel: "Previous page",
1425
+ nextPageAriaLabel: "Next page",
1426
+ jumpBackwardAriaLabel: "Jump back {count} pages",
1427
+ jumpForwardAriaLabel: "Jump forward {count} pages",
1428
+ };
1429
+ /**
1430
+ * Base de textos según el idioma de react-aria (`useLocale`): inglés si el locale es `en*`,
1431
+ * español en cualquier otro caso (el default de la librería, regla `auraui-i18n`).
1432
+ *
1433
+ * Sin provider, react-aria resuelve el idioma del NAVEGADOR (`navigator.language`), igual que
1434
+ * para sus propios textos: una app que no declare `locale` sigue al navegador. Para fijarlo, la
1435
+ * app pasa `locale` a `HeroUIProvider` o los textos por `translations`.
1436
+ */
1437
+ function baseTranslations(locale) {
1438
+ return locale.toLowerCase().startsWith("en")
1439
+ ? EN_TRANSLATIONS
1440
+ : DEFAULT_TRANSLATIONS$g;
1441
+ }
1279
1442
  /**
1280
1443
  * TECH-2459 · elipsis navegable — páginas que salta la elipsis. Literal de v2:
1281
1444
  * `dotsJump = 5`, default desestructurado en `@heroui/pagination@2.2.20`
@@ -1395,7 +1558,8 @@ function getPaginationRange(total, current) {
1395
1558
  const Pagination = ({ total, page, initialPage = 1, onChange, size: _size = "sm", className, isDisabled, showControls = true, isCompact = true, showShadow = false, color = "primary", translations = {}, }) => {
1396
1559
  const [internalPage, setInternalPage] = $8WNJc$react.useState(initialPage);
1397
1560
  const currentPage = page ?? internalPage;
1398
- const t = { ...DEFAULT_TRANSLATIONS$g, ...translations };
1561
+ const { locale } = react.useLocale();
1562
+ const t = { ...baseTranslations(locale), ...translations };
1399
1563
  const goTo = (next) => {
1400
1564
  const clamped = Math.min(Math.max(next, 1), total);
1401
1565
  if (page === undefined) {
@@ -1416,19 +1580,19 @@ const Pagination = ({ total, page, initialPage = 1, onChange, size: _size = "sm"
1416
1580
  isFirst: !showControls && index === 0,
1417
1581
  isLast: !showControls && index === lastItemIndex,
1418
1582
  });
1419
- const activeClass = react.cn(ACTIVE_COLOR_CLASS[color], showShadow ? ACTIVE_SHADOW_CLASS[color] : "", ACTIVE_LINK_CLASS);
1583
+ const activeClass = cn(ACTIVE_COLOR_CLASS[color], showShadow ? ACTIVE_SHADOW_CLASS[color] : "", ACTIVE_LINK_CLASS);
1420
1584
  return (
1421
1585
  // `w-fit` reproduce el `max-w-fit` del wrapper de v2: `.pagination` de v3 es `w-full` +
1422
1586
  // `justify-between`, así que dentro de un `flex justify-center` (como el de AccordionList) la
1423
1587
  // tira se quedaba pegada a la izquierda en vez de centrarse.
1424
- jsxRuntime.jsx(react.Pagination, { className: react.cn("w-fit", className), children: jsxRuntime.jsxs(react.Pagination.Content, { className: isCompact ? STRIP_CLASS : STRIP_LOOSE_CLASS, children: [showControls && (jsxRuntime.jsx(react.Pagination.Item, { children: jsxRuntime.jsx(react.Pagination.Previous
1588
+ jsxRuntime.jsx(react.Pagination, { className: cn("w-fit", className), children: jsxRuntime.jsxs(react.Pagination.Content, { className: isCompact ? STRIP_CLASS : STRIP_LOOSE_CLASS, children: [showControls && (jsxRuntime.jsx(react.Pagination.Item, { children: jsxRuntime.jsx(react.Pagination.Previous
1425
1589
  // v3 mete el galón en un `<span aria-hidden="true">`
1426
1590
  // (`pagination.js:165`), así que sin esto el botón se queda SIN nombre
1427
1591
  // accesible: un lector de pantalla lo anuncia como "botón" a secas. v2 sí
1428
1592
  // lo nombraba ("previous page button", `use-pagination.js:213`), pero en
1429
1593
  // inglés y hardcodeado; aquí va por `translations` (regla obligatoria de
1430
1594
  // i18n del repo, skill `auraui-i18n`).
1431
- , { "aria-label": t.previousPageAriaLabel, className: react.cn(CELL_CLASS, NAV_CLASS, cellRadius(isCompact, { isFirst: true, isLast: false })), isDisabled: isDisabled || currentPage <= 1, onPress: () => goTo(currentPage - 1), children: jsxRuntime.jsx(react.Pagination.PreviousIcon, {}) }) })), items.map((item, index) => {
1595
+ , { "aria-label": t.previousPageAriaLabel, className: cn(CELL_CLASS, NAV_CLASS, isDisabled ? "" : NAV_AT_EDGE_CLASS, cellRadius(isCompact, { isFirst: true, isLast: false })), isDisabled: isDisabled || currentPage <= 1, onPress: () => goTo(currentPage - 1), children: jsxRuntime.jsx(react.Pagination.PreviousIcon, {}) }) })), items.map((item, index) => {
1432
1596
  if (item === "ellipsis") {
1433
1597
  const isBefore = index < activeIndex;
1434
1598
  const label = isBefore
@@ -1436,14 +1600,14 @@ const Pagination = ({ total, page, initialPage = 1, onChange, size: _size = "sm"
1436
1600
  : t.jumpForwardAriaLabel;
1437
1601
  return (
1438
1602
  // biome-ignore lint/suspicious/noArrayIndexKey: solo hay como máximo 2 elipsis, posición estable
1439
- jsxRuntime.jsx(react.Pagination.Item, { children: jsxRuntime.jsxs(react.Pagination.Link, { "aria-label": label.replace("{count}", String(DOTS_JUMP)), className: react.cn("group", CELL_CLASS, cellRadius(isCompact, itemPosition(index))), isDisabled: isDisabled, onPress: () => goTo(isBefore
1603
+ jsxRuntime.jsx(react.Pagination.Item, { children: jsxRuntime.jsxs(react.Pagination.Link, { "aria-label": label.replace("{count}", String(DOTS_JUMP)), className: cn("group", CELL_CLASS, cellRadius(isCompact, itemPosition(index))), isDisabled: isDisabled, onPress: () => goTo(isBefore
1440
1604
  ? currentPage - DOTS_JUMP
1441
1605
  : currentPage + DOTS_JUMP), children: [jsxRuntime.jsx(EllipsisDotsIcon, {}), jsxRuntime.jsx(JumpIcon, { isBefore: isBefore })] }) }, `ellipsis-${index}`));
1442
1606
  }
1443
- return (jsxRuntime.jsx(react.Pagination.Item, { children: jsxRuntime.jsx(react.Pagination.Link, { className: react.cn(CELL_CLASS, cellRadius(isCompact, itemPosition(index)), item === currentPage ? activeClass : ""), isActive: item === currentPage, isDisabled: isDisabled, onPress: () => goTo(item), children: item }) }, item));
1607
+ return (jsxRuntime.jsx(react.Pagination.Item, { children: jsxRuntime.jsx(react.Pagination.Link, { className: cn(CELL_CLASS, cellRadius(isCompact, itemPosition(index)), item === currentPage ? activeClass : ""), isActive: item === currentPage, isDisabled: isDisabled, onPress: () => goTo(item), children: item }) }, item));
1444
1608
  }), showControls && (jsxRuntime.jsx(react.Pagination.Item, { children: jsxRuntime.jsx(react.Pagination.Next
1445
1609
  /* Mismo motivo que en `Previous`: el galón es `aria-hidden`. */
1446
- , { "aria-label": t.nextPageAriaLabel, className: react.cn(CELL_CLASS, NAV_CLASS, cellRadius(isCompact, { isFirst: false, isLast: true })), isDisabled: isDisabled || currentPage >= total, onPress: () => goTo(currentPage + 1), children: jsxRuntime.jsx(react.Pagination.NextIcon, {}) }) }))] }) }));
1610
+ , { "aria-label": t.nextPageAriaLabel, className: cn(CELL_CLASS, NAV_CLASS, isDisabled ? "" : NAV_AT_EDGE_CLASS, cellRadius(isCompact, { isFirst: false, isLast: true })), isDisabled: isDisabled || currentPage >= total, onPress: () => goTo(currentPage + 1), children: jsxRuntime.jsx(react.Pagination.NextIcon, {}) }) }))] }) }));
1447
1611
  };
1448
1612
 
1449
1613
  // TECH-2459 · F5 · P-01 — Valores tomados del tema v2 REAL (`@heroui/theme@2.4.15`,
@@ -1624,7 +1788,7 @@ exports.HolidayType = void 0;
1624
1788
  */
1625
1789
  function withConsumerClass(own, consumer) {
1626
1790
  const base = own.filter(Boolean).join(" ");
1627
- return consumer ? react.cn(base, consumer) : base;
1791
+ return consumer ? cn(base, consumer) : base;
1628
1792
  }
1629
1793
  /**
1630
1794
  * `calendarWidth` de v2 → estilo en línea del `Calendar`. v3 fija `.calendar { w-63 max-w-63 }`
@@ -1719,7 +1883,12 @@ const ROOT_HELPER_SPACE_CLASS = {
1719
1883
  };
1720
1884
  const GROUP_PLACEMENT_CLASS = {
1721
1885
  outside: undefined,
1722
- "outside-left": "relative flex-1",
1886
+ // `min-w-min` (TECH-2459, beweossmbs QA 24-sep, barra de la agenda por debajo de 1440px):
1887
+ // `.date-input-group` de v3 lleva `overflow-hidden`, y un ítem flex con overflow distinto de
1888
+ // `visible` tiene `min-width: auto` = 0. Con `flex-1` el grupo se quedaba con el hueco sobrante
1889
+ // y recortaba su propio botón de calendario (104px con 140 de contenido a 1280px). En v2 el
1890
+ // overflow era visible: el grupo conservaba su contenido y era la etiqueta la que se partía.
1891
+ "outside-left": "relative flex-1 min-w-min",
1723
1892
  };
1724
1893
  const HELPER_PLACEMENT_CLASS = {
1725
1894
  outside: undefined,
@@ -2221,7 +2390,9 @@ labelPlacement: _labelPlacement, isInvalid = false, isRequired = false, isDisabl
2221
2390
  // `undefined` y el campo dejaba de llenar su contenedor: en una fila flex se encogía al ancho
2222
2391
  // de su contenido (medido por S2: 208px dentro de una fila de 592, 336px de hueco). En una
2223
2392
  // columna no se notaba porque el `stretch` del flex lo tapaba — pero afecta a cualquier app.
2224
- fullWidth = true, value, defaultValue, onChange, onValueChange, className, classNames, required, name, type = "text", onKeyDown, ...rest }, ref) => {
2393
+ fullWidth = true, value, defaultValue, onChange, onValueChange, className, classNames, required, name, type = "text", onKeyDown,
2394
+ // Nombre y descripción accesibles: van al `TextField`, no al `<input>` (ver abajo).
2395
+ "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, "aria-describedby": ariaDescribedBy, ...rest }, ref) => {
2225
2396
  // El `<input>` real, también para la fachada: v2 devolvía el foco al campo al limpiar
2226
2397
  // (`domRef.current?.focus()` en `handleClear`). Se combina con el `ref` del consumidor.
2227
2398
  const inputRef = $8WNJc$react.useRef(null);
@@ -2264,6 +2435,19 @@ fullWidth = true, value, defaultValue, onChange, onValueChange, className, class
2264
2435
  // Solo flota cuando hay label y NO hay placeholder: con placeholder, v2 ya mostraba el label
2265
2436
  // arriba desde el primer render (ver el bloque de arriba).
2266
2437
  const labelFlotante = Boolean(label) && !placeholder;
2438
+ // ── Nombre accesible sin `label` visible ─────────────────────────────────────────────────
2439
+ //
2440
+ // Quien llama a `useLabel` (y avisa «If you do not provide a visible label, you must specify
2441
+ // an aria-label…») es el `TextField` de react-aria, que se los pasa al `<input>` por contexto.
2442
+ // Dejarlos en el spread del `<input>` hacía que avisara AUNQUE la app diera nombre (medido en
2443
+ // beweossmbs: 14/16 avisos al cargar `/clients/table`, del buscador con solo placeholder).
2444
+ // Y `aria-describedby` en el `<input>` pisaba el id de la `Description` propia. v2 no avisaba
2445
+ // nunca: `"aria-label": label ? aria-label : safeAriaLabel(aria-label, placeholder)`
2446
+ // (`@heroui/input@2.4.33`, `dist/use-input.js:119`). Con `aria-labelledby` no se añade el
2447
+ // placeholder: react-aria lo concatenaría al nombre del elemento referido.
2448
+ const accessibleLabel = label || ariaLabelledBy
2449
+ ? ariaLabel
2450
+ : ariaLabel?.trim() || placeholder?.trim() || undefined;
2267
2451
  const handleChange = (event) => {
2268
2452
  onChange?.(event);
2269
2453
  onValueChange?.(event.target.value);
@@ -2296,10 +2480,10 @@ fullWidth = true, value, defaultValue, onChange, onValueChange, className, class
2296
2480
  clearValue();
2297
2481
  }
2298
2482
  };
2299
- return (jsxRuntime.jsxs(react.TextField, { id: inputId, value: currentValue,
2483
+ return (jsxRuntime.jsxs(react.TextField, { id: inputId, "aria-label": accessibleLabel, "aria-labelledby": ariaLabelledBy, "aria-describedby": ariaDescribedBy, value: currentValue,
2300
2484
  // Solo el modo no controlado escribe aquí; en controlado manda el `value` del padre
2301
2485
  // (que se entera por `onChange`/`onValueChange` del `<input>`).
2302
- onChange: isControlled ? undefined : setUncontrolledValue, name: name, isInvalid: isInvalid, isRequired: isRequired, isDisabled: isDisabled, isReadOnly: isReadOnly, className: react.cn(FIELD_STACK_CLASS$3[size], fullWidth ? "w-full" : "",
2486
+ onChange: isControlled ? undefined : setUncontrolledValue, name: name, isInvalid: isInvalid, isRequired: isRequired, isDisabled: isDisabled, isReadOnly: isReadOnly, className: cn(FIELD_STACK_CLASS$3[size], fullWidth ? "w-full" : "",
2303
2487
  // `mainWrapper` de v2 no tiene nodo propio aquí (ver tabla en `Input.types.ts`):
2304
2488
  // se fusiona en la raíz antes que `base`, que es el slot más externo.
2305
2489
  classNames?.mainWrapper,
@@ -2307,13 +2491,21 @@ fullWidth = true, value, defaultValue, onChange, onValueChange, className, class
2307
2491
  classNames?.base,
2308
2492
  // El `className` del consumidor, en la raíz y en último lugar: el slot `base` de
2309
2493
  // v2 y la posición que le deja ganar en tailwind-merge (ver bloque de arriba).
2310
- className), children: [label && (jsxRuntime.jsx(react.Label, { className: react.cn(LABEL_CLASS$4, LABEL_LEFT_CLASS[variant], variant === "underlined" ? "top-0" : LABEL_OFFSET_CLASS$1[size], isInvalid ? INVALID_LABEL_CLASS$2 : "", labelFlotante ? LABEL_INSIDE_CLASS[size] : "", labelFlotante ? LABEL_FLOAT_CLASS : "", classNames?.label), children: label })), jsxRuntime.jsxs(react.InputGroup, { isInvalid: isInvalid, isDisabled: isDisabled, isReadOnly: isReadOnly, className: react.cn(SIZE_CLASS$3[size], radius === "full" ? PADDING_FULL_CLASS$1[size] : PADDING_CLASS$2[size], variant === "underlined" ? UNDERLINED_INNER_CLASS$1[size] : "", RADIUS_CLASS$6[radius], VARIANT_CLASS$3[variant], FIELD_FOCUS_CLASS$3, FIELD_SHADOW_CLASS$2,
2494
+ className), children: [label && (jsxRuntime.jsx(react.Label, { className: cn(LABEL_CLASS$4, LABEL_LEFT_CLASS[variant], variant === "underlined" ? "top-0" : LABEL_OFFSET_CLASS$1[size], isInvalid ? INVALID_LABEL_CLASS$2 : "", labelFlotante ? LABEL_INSIDE_CLASS[size] : "", labelFlotante ? LABEL_FLOAT_CLASS : "", classNames?.label), children: label })), jsxRuntime.jsxs(react.InputGroup, { isInvalid: isInvalid, isDisabled: isDisabled, isReadOnly: isReadOnly, className: cn(SIZE_CLASS$3[size], radius === "full" ? PADDING_FULL_CLASS$1[size] : PADDING_CLASS$2[size], variant === "underlined" ? UNDERLINED_INNER_CLASS$1[size] : "", RADIUS_CLASS$6[radius], VARIANT_CLASS$3[variant], FIELD_FOCUS_CLASS$3, FIELD_SHADOW_CLASS$2,
2311
2495
  // Incondicional, como el `inputWrapper` de v2: la caja del campo llena
2312
2496
  // siempre su raíz, y es la raíz la que responde a `fullWidth` y al ancho que
2313
2497
  // pase el consumidor.
2314
2498
  "w-full",
2315
2499
  // v3 fusiona `innerWrapper` e `inputWrapper` de v2 en este único elemento.
2316
- classNames?.innerWrapper, classNames?.inputWrapper), children: [startContent && (jsxRuntime.jsx(react.InputGroup.Prefix, { className: "border-none bg-transparent px-0", children: startContent })), jsxRuntime.jsx(react.InputGroup.Input, { ...rest, ref: setInputRef, onKeyDown: handleKeyDown, required: required, type: type, placeholder: labelFlotante ? " " : placeholder, onChange: handleChange, className: react.cn("bg-transparent p-0", SIZE_TEXT_CLASS$2[size], isInvalid ? INVALID_TEXT_CLASS$2 : "", startContent ? "ps-1.5" : "", endContent || showClear ? "pe-1.5" : "", classNames?.input) }), showClear && (jsxRuntime.jsx(react.CloseButton, { "aria-label": "Limpiar", className: react.cn("h-4 w-4 min-h-0 p-0.5 mr-1", classNames?.clearButton), onPress: handleClear })), endContent && (jsxRuntime.jsx(react.InputGroup.Suffix, { className: "border-none bg-transparent px-0", children: endContent }))] }), description && !isInvalid && (jsxRuntime.jsx(react.Description, { className: react.cn(HELPER_CLASS$2, "text-left", classNames?.helperWrapper, classNames?.description), children: description })), isInvalid && errorMessage && (jsxRuntime.jsx(react.FieldError, { className: react.cn(HELPER_CLASS$2, "text-left", classNames?.helperWrapper, classNames?.errorMessage), children: errorMessage }))] }));
2500
+ classNames?.innerWrapper, classNames?.inputWrapper), children: [startContent && (jsxRuntime.jsx(react.InputGroup.Prefix, { className: "border-none bg-transparent px-0", children: startContent })), jsxRuntime.jsx(react.InputGroup.Input, { ...rest, ref: setInputRef, onKeyDown: handleKeyDown, required: required, type: type, placeholder: labelFlotante ? " " : placeholder, onChange: handleChange, className: cn(
2501
+ // `w-full min-w-0` (TECH-2459, beweossmbs QA 24-sep): `.input-group__input`
2502
+ // de v3 es `flex-1` sin ancho, así que el `<input>` aportaba su ancho
2503
+ // intrínseco (~151px) como min-content y el campo no encogía en una fila
2504
+ // flex estrecha (hex del color picker de Agenda → Colors: 180px y 35px
2505
+ // fuera de su fila; en v2, 132px). v2 ponía `w-full` en este slot
2506
+ // (`@heroui/theme@2.4.15`, `dist/components/input.js:111`), y un ancho
2507
+ // en porcentaje no cuenta para el min-content de un `<input>`.
2508
+ "w-full min-w-0 bg-transparent p-0", SIZE_TEXT_CLASS$2[size], isInvalid ? INVALID_TEXT_CLASS$2 : "", startContent ? "ps-1.5" : "", endContent || showClear ? "pe-1.5" : "", classNames?.input) }), showClear && (jsxRuntime.jsx(react.CloseButton, { "aria-label": "Limpiar", className: cn("h-4 w-4 min-h-0 p-0.5 mr-1", classNames?.clearButton), onPress: handleClear })), endContent && (jsxRuntime.jsx(react.InputGroup.Suffix, { className: "border-none bg-transparent px-0", children: endContent }))] }), description && !isInvalid && (jsxRuntime.jsx(react.Description, { className: cn(HELPER_CLASS$2, "text-left", classNames?.helperWrapper, classNames?.description), children: description })), isInvalid && errorMessage && (jsxRuntime.jsx(react.FieldError, { className: cn(HELPER_CLASS$2, "text-left", classNames?.helperWrapper, classNames?.errorMessage), children: errorMessage }))] }));
2317
2509
  });
2318
2510
  Input.displayName = "Input";
2319
2511
 
@@ -2435,18 +2627,36 @@ const SHADOW_CLASS = {
2435
2627
  md: "shadow-[shadow:var(--aurora-shadow-medium)]",
2436
2628
  lg: "shadow-[shadow:var(--aurora-shadow-large)]",
2437
2629
  };
2630
+ // Geometría v2 de la raíz (slot `base` de `@heroui/theme@2.4.15`, `dist/components/card.js`):
2631
+ // `flex flex-col relative overflow-hidden`, SIN `gap`. v3 (`@heroui/styles/…/card.css:5`) pone
2632
+ // `gap-3 overflow-visible`, y eso ROMPE layouts de v2 (medido por beweossmbs con la .141): con
2633
+ // tres hijos la card crece 24px (Notificaciones automáticas: 220px frente a 192, y la última card
2634
+ // queda cortada por su contenedor), y el texto que no cabe se sale de la card en vez de
2635
+ // recortarse (cabecera de recurso de la agenda, vista Semana: 80px frente a 56 y los nombres
2636
+ // fuera). Va primero en el `cn`: un `gap-*`/`overflow-*` de la app lo retira por fusión.
2637
+ // `overflow-hidden` no quita nada que se viera: la onda ya se recorta en su propia capa
2638
+ // (`Card.css`), el anillo de foco es un `ring` (`box-shadow`, no lo recorta el `overflow` de su
2639
+ // propio nodo) y la sombra de la card se pinta fuera de su caja. Medido en la story `V2Geometry`: tres
2640
+ // hijos de 20px dan 108px (132 con el gap de v3) y el texto que desborda ya no asoma.
2641
+ const ROOT_V2_CLASS = "gap-0 overflow-hidden";
2438
2642
  // Literales del `tv` de v2 (`@heroui/theme@2.4.15`, `dist/components/card.js`), con sus tokens
2439
2643
  // traducidos a los que existen en Tailwind 4 + Aurora:
2440
2644
  // isPressable → `cursor-pointer` + compound `data-[pressed=true]:scale-[0.97]
2441
2645
  // tap-highlight-transparent` (el hundido lo hace aquí `:active`, que es lo que
2442
2646
  // marcaba `data-pressed` en un botón nativo)
2443
2647
  // disableAnimation=false → `transition-transform-background motion-reduce:transition-none`
2444
- // foco → `dataFocusVisibleClasses` (`outline-2 outline-focus outline-offset-2`)
2648
+ // foco → `dataFocusVisibleClasses` (`outline-2 outline-focus outline-offset-2`). Aquí va con el
2649
+ // MISMO anillo que los botones de v3/Aurora (`status-focused` → `focus-ring`:
2650
+ // `ring-2 ring-focus ring-offset-background` + offset 2px), no con `outline`: en
2651
+ // Tailwind 4 `outline-none` fija `--tw-outline-style: none` y `focus-visible:outline-2`
2652
+ // hereda ese estilo, así que el anillo NO se pintaba (regresión de la .141, al pasar de
2653
+ // `<button>` a `<div role="button">`). El `ring` es `box-shadow` fuera de la caja: no lo
2654
+ // recorta el `overflow-hidden` de la raíz y se compone con la sombra de la card.
2445
2655
  // isHoverable → `data-[hover=true]:bg-content2` (aquí `hover:`, react-aria ya no escribe
2446
2656
  // `data-hover` — trampa 3 de la skill `auraui-components`)
2447
2657
  // isDisabled → `opacity-disabled cursor-not-allowed` (`opacity-disabled` era 0.5 en v2)
2448
2658
  // fullWidth → `w-full`
2449
- const PRESSABLE_CLASS = "isolate cursor-pointer text-foreground outline-none focus-visible:z-10 focus-visible:outline-2 focus-visible:outline-focus focus-visible:outline-offset-2 [-webkit-tap-highlight-color:transparent]";
2659
+ const PRESSABLE_CLASS = "isolate cursor-pointer text-foreground outline-none focus-visible:z-10 focus-visible:ring-2 focus-visible:ring-focus focus-visible:ring-offset-2 focus-visible:ring-offset-background [-webkit-tap-highlight-color:transparent]";
2450
2660
  const PRESS_ANIMATION_CLASS = "transition-[transform,background-color] motion-reduce:transition-none active:scale-[0.97]";
2451
2661
  const HOVERABLE_CLASS = "hover:bg-content2";
2452
2662
  const DISABLED_CLASS = "opacity-50 cursor-not-allowed";
@@ -2562,7 +2772,7 @@ const Card = $8WNJc$react.forwardRef(({ children, className, shadow = "sm", radi
2562
2772
  event.preventDefault();
2563
2773
  press(pressEventFromKey(event));
2564
2774
  }, [onKeyUp, pulsable, press]);
2565
- const combinedClassName = react.cn(paddingClasses[padding], RADIUS_CLASS$5[radius], SHADOW_CLASS[shadow], fullWidth ? "w-full" : "", isPressable ? PRESSABLE_CLASS : "", isPressable && !disableAnimation ? PRESS_ANIMATION_CLASS : "", isHoverable ? HOVERABLE_CLASS : "", isDisabled ? DISABLED_CLASS : "",
2775
+ const combinedClassName = cn(ROOT_V2_CLASS, paddingClasses[padding], RADIUS_CLASS$5[radius], SHADOW_CLASS[shadow], fullWidth ? "w-full" : "", isPressable ? PRESSABLE_CLASS : "", isPressable && !disableAnimation ? PRESS_ANIMATION_CLASS : "", isHoverable ? HOVERABLE_CLASS : "", isDisabled ? DISABLED_CLASS : "",
2566
2776
  // El `className` de la app, último: gana por fusión (ver JSDoc).
2567
2777
  className);
2568
2778
  // v2 cambiaba el ELEMENTO a `<button>` con `isPressable`, y hasta la .140 esta fachada lo
@@ -2587,11 +2797,11 @@ const Card = $8WNJc$react.forwardRef(({ children, className, shadow = "sm", radi
2587
2797
  Card.displayName = "Card";
2588
2798
 
2589
2799
  const H2 = ({ children, className, ...props }) => {
2590
- return (jsxRuntime.jsx("h2", { className: react.cn("text-lg font-semibold", className), ...props, children: children }));
2800
+ return (jsxRuntime.jsx("h2", { className: cn("text-lg font-semibold", className), ...props, children: children }));
2591
2801
  };
2592
2802
 
2593
2803
  const P = ({ children, className, ...props }) => {
2594
- return (jsxRuntime.jsx("p", { className: react.cn("text-xs text-default-500 font-normal", className), ...props, children: children }));
2804
+ return (jsxRuntime.jsx("p", { className: cn("text-xs text-default-500 font-normal", className), ...props, children: children }));
2595
2805
  };
2596
2806
 
2597
2807
  const defaultTranslations$f = {
@@ -2675,9 +2885,9 @@ const AnalyticsCard = ({ data, showTimePeriods = true, showDropdownMenu = true,
2675
2885
  // Card.types.ts) — se pierde el `as="dl"` semántico de v2. No había `<dt>`/`<dd>` reales dentro
2676
2886
  // (siempre fue un `<dl>` "vacío" de esa semántica), así que el cambio a `<div>` no pierde
2677
2887
  // estructura real.
2678
- return (jsxRuntime.jsx(Card, { className: "dark:border-default-100 border border-transparent", ...props, children: jsxRuntime.jsxs("section", { className: "flex flex-col flex-nowrap", children: [jsxRuntime.jsx("div", { className: "flex flex-col justify-between gap-y-2", children: jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-2", children: [jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-0", children: [jsxRuntime.jsx(H2, { children: t.title }), jsxRuntime.jsx(P, { children: t.description })] }), jsxRuntime.jsx("div", { className: "h-2", "aria-hidden": "true" }), showTimePeriods && (jsxRuntime.jsx(react.Tabs, { className: "self-end", onSelectionChange: (key) => handleTimePeriodChange(String(key)), children: jsxRuntime.jsx(react.Tabs.ListContainer, { className: "bg-default-100", children: jsxRuntime.jsxs(react.Tabs.List, { "aria-label": t.title, children: [jsxRuntime.jsxs(react.Tabs.Tab, { id: "6-months", className: "whitespace-nowrap", children: [t.months6, jsxRuntime.jsx(react.Tabs.Indicator, {})] }), jsxRuntime.jsxs(react.Tabs.Tab, { id: "3-months", className: "whitespace-nowrap", children: [t.months3, jsxRuntime.jsx(react.Tabs.Indicator, {})] }), jsxRuntime.jsxs(react.Tabs.Tab, { id: "30-days", className: "whitespace-nowrap", children: [t.days30, jsxRuntime.jsx(react.Tabs.Indicator, {})] }), jsxRuntime.jsxs(react.Tabs.Tab, { id: "7-days", className: "whitespace-nowrap", children: [t.days7, jsxRuntime.jsx(react.Tabs.Indicator, {})] }), jsxRuntime.jsxs(react.Tabs.Tab, { id: "24-hours", className: "whitespace-nowrap", children: [t.hours24, jsxRuntime.jsx(react.Tabs.Indicator, {})] })] }) }) })), showMetricCards && (jsxRuntime.jsx("div", { className: "mt-2 flex w-full items-center", children: jsxRuntime.jsx("div", { className: "-my-3 flex w-full max-w-[800px] items-center gap-x-3 overflow-x-auto py-3", children: data.map(({ key, change, changeType, type, value, title }) => (jsxRuntime.jsxs("button", { type: "button", className: react.cn("rounded-[12px] flex w-full flex-col gap-2 p-3 transition-colors", {
2888
+ return (jsxRuntime.jsx(Card, { className: "dark:border-default-100 border border-transparent", ...props, children: jsxRuntime.jsxs("section", { className: "flex flex-col flex-nowrap", children: [jsxRuntime.jsx("div", { className: "flex flex-col justify-between gap-y-2", children: jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-2", children: [jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-0", children: [jsxRuntime.jsx(H2, { children: t.title }), jsxRuntime.jsx(P, { children: t.description })] }), jsxRuntime.jsx("div", { className: "h-2", "aria-hidden": "true" }), showTimePeriods && (jsxRuntime.jsx(react.Tabs, { className: "self-end", onSelectionChange: (key) => handleTimePeriodChange(String(key)), children: jsxRuntime.jsx(react.Tabs.ListContainer, { className: "bg-default-100", children: jsxRuntime.jsxs(react.Tabs.List, { "aria-label": t.title, children: [jsxRuntime.jsxs(react.Tabs.Tab, { id: "6-months", className: "whitespace-nowrap", children: [t.months6, jsxRuntime.jsx(react.Tabs.Indicator, {})] }), jsxRuntime.jsxs(react.Tabs.Tab, { id: "3-months", className: "whitespace-nowrap", children: [t.months3, jsxRuntime.jsx(react.Tabs.Indicator, {})] }), jsxRuntime.jsxs(react.Tabs.Tab, { id: "30-days", className: "whitespace-nowrap", children: [t.days30, jsxRuntime.jsx(react.Tabs.Indicator, {})] }), jsxRuntime.jsxs(react.Tabs.Tab, { id: "7-days", className: "whitespace-nowrap", children: [t.days7, jsxRuntime.jsx(react.Tabs.Indicator, {})] }), jsxRuntime.jsxs(react.Tabs.Tab, { id: "24-hours", className: "whitespace-nowrap", children: [t.hours24, jsxRuntime.jsx(react.Tabs.Indicator, {})] })] }) }) })), showMetricCards && (jsxRuntime.jsx("div", { className: "mt-2 flex w-full items-center", children: jsxRuntime.jsx("div", { className: "-my-3 flex w-full max-w-[800px] items-center gap-x-3 overflow-x-auto py-3", children: data.map(({ key, change, changeType, type, value, title }) => (jsxRuntime.jsxs("button", { type: "button", className: cn("rounded-[12px] flex w-full flex-col gap-2 p-3 transition-colors", {
2679
2889
  "bg-default-100": activeChart === key,
2680
- }), onClick: () => handleChartChange(key), children: [jsxRuntime.jsx("span", { className: react.cn("text-sm text-default-500 font-medium transition-colors", {
2890
+ }), onClick: () => handleChartChange(key), children: [jsxRuntime.jsx("span", { className: cn("text-sm text-default-500 font-medium transition-colors", {
2681
2891
  "text-primary": activeChart === key,
2682
2892
  }), children: title }), jsxRuntime.jsxs("div", { className: "flex items-center gap-x-3", children: [jsxRuntime.jsx("span", { className: "text-foreground text-2xl font-bold", children: formatValue(value, type) }), jsxRuntime.jsx(Chip, { color: changeType === "positive"
2683
2893
  ? "success"
@@ -2718,7 +2928,7 @@ const AnalyticsCard = ({ data, showTimePeriods = true, showDropdownMenu = true,
2718
2928
  };
2719
2929
 
2720
2930
  const H3 = ({ children, className, ...props }) => {
2721
- return (jsxRuntime.jsx("h3", { className: react.cn("text-base font-medium", className), ...props, children: children }));
2931
+ return (jsxRuntime.jsx("h3", { className: cn("text-base font-medium", className), ...props, children: children }));
2722
2932
  };
2723
2933
 
2724
2934
  function ChartTooltip({ active, payload, label, series, formatValue, }) {
@@ -2913,18 +3123,18 @@ function translateItem(element) {
2913
3123
  classNames?.description);
2914
3124
  if (onlyBase || typeof children === "function") {
2915
3125
  return $8WNJc$react.cloneElement(element, {
2916
- className: react.cn(classNames?.base, className) || undefined,
3126
+ className: cn(classNames?.base, className) || undefined,
2917
3127
  description: undefined,
2918
3128
  startContent: undefined,
2919
3129
  endContent: undefined,
2920
3130
  classNames: undefined,
2921
3131
  });
2922
3132
  }
2923
- const title = (jsxRuntime.jsx("span", { className: react.cn(ITEM_TITLE_CLASS$1, classNames?.title), children: children }));
2924
- const next = (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [hasStart && (jsxRuntime.jsx("span", { "data-slot": "start-content", [ITEM_EXTRA_ATTR]: "", className: ITEM_SIDE_CLASS, children: startContent })), hasDescription ? (jsxRuntime.jsxs("div", { className: react.cn(ITEM_WRAPPER_CLASS, classNames?.wrapper), children: [title, jsxRuntime.jsx(react.Description, { className: react.cn(ITEM_DESCRIPTION_CLASS, classNames?.description), children: description })] })) : (title), hasEnd && (jsxRuntime.jsx("span", { "data-slot": "end-content", [ITEM_EXTRA_ATTR]: "", className: ITEM_SIDE_CLASS, children: endContent }))] }));
3133
+ const title = (jsxRuntime.jsx("span", { className: cn(ITEM_TITLE_CLASS$1, classNames?.title), children: children }));
3134
+ const next = (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [hasStart && (jsxRuntime.jsx("span", { "data-slot": "start-content", [ITEM_EXTRA_ATTR]: "", className: ITEM_SIDE_CLASS, children: startContent })), hasDescription ? (jsxRuntime.jsxs("div", { className: cn(ITEM_WRAPPER_CLASS, classNames?.wrapper), children: [title, jsxRuntime.jsx(react.Description, { className: cn(ITEM_DESCRIPTION_CLASS, classNames?.description), children: description })] })) : (title), hasEnd && (jsxRuntime.jsx("span", { "data-slot": "end-content", [ITEM_EXTRA_ATTR]: "", className: ITEM_SIDE_CLASS, children: endContent }))] }));
2925
3135
  return $8WNJc$react.cloneElement(element, {
2926
3136
  // v2: `cn(classNames?.base, className)` (`use-listbox-item.mjs`), así que `className` gana.
2927
- className: react.cn(classNames?.base, className) || undefined,
3137
+ className: cn(classNames?.base, className) || undefined,
2928
3138
  description: undefined,
2929
3139
  startContent: undefined,
2930
3140
  endContent: undefined,
@@ -2945,14 +3155,14 @@ function translateSection(element) {
2945
3155
  // items de la sección se quedarían sin checkmark.
2946
3156
  const parts = [];
2947
3157
  if (hasTitle) {
2948
- parts.push(jsxRuntime.jsx(react.Header, { className: react.cn(SECTION_HEADING_CLASS$1, classNames?.heading), children: title }, "aura-section-header"));
3158
+ parts.push(jsxRuntime.jsx(react.Header, { className: cn(SECTION_HEADING_CLASS$1, classNames?.heading), children: title }, "aura-section-header"));
2949
3159
  }
2950
3160
  parts.push(...(Array.isArray(inner) ? inner : [inner]));
2951
3161
  if (showDivider) {
2952
- parts.push(jsxRuntime.jsx(react.Separator, { className: react.cn(SECTION_DIVIDER_CLASS, classNames?.divider) }, "aura-section-divider"));
3162
+ parts.push(jsxRuntime.jsx(react.Separator, { className: cn(SECTION_DIVIDER_CLASS, classNames?.divider) }, "aura-section-divider"));
2953
3163
  }
2954
3164
  return $8WNJc$react.cloneElement(element, {
2955
- className: react.cn(classNames?.base, className) || undefined,
3165
+ className: cn(classNames?.base, className) || undefined,
2956
3166
  // `title` en v3 es el atributo global de HTML: sin retirarlo sale como *tooltip*
2957
3167
  // nativo sobre toda la sección (el mismo motivo por el que v2 lo quitaba del spread,
2958
3168
  // `chunk-Q2EVG7SO.mjs`: «removed title from props to avoid browsers showing a tooltip»).
@@ -3476,7 +3686,7 @@ labelPlacement: _labelPlacement, scrollShadowProps, ...props }) => {
3476
3686
  // de la app va al final y gana por `cn`, y `overflow-y-auto` para que un
3477
3687
  // `max-h-*` recorte desplazando y no desbordando.
3478
3688
  className: scrollShadowProps?.className
3479
- ? react.cn(OPCIONES_CLASS, "overflow-y-auto", scrollShadowProps.className)
3689
+ ? cn(OPCIONES_CLASS, "overflow-y-auto", scrollShadowProps.className)
3480
3690
  : OPCIONES_CLASS, style: scrollShadowProps?.style, renderEmptyState: hideEmptyContent
3481
3691
  ? undefined
3482
3692
  : () => jsxRuntime.jsx("div", { className: EMPTY_CONTENT_CLASS$1, children: emptyContent }), children: withV2ItemContent(
@@ -3728,7 +3938,12 @@ const ColorPicker = $8WNJc$react.forwardRef(({ value, onChange, label, required
3728
3938
  ${error
3729
3939
  ? "border-danger dark:border-danger-400"
3730
3940
  : "border-default-300 dark:border-default-700"}
3731
- `, "aria-label": t.customColorLabel, title: t.customColorLabel }), jsxRuntime.jsx(Input, { type: "text", value: textValue, onValueChange: handleTextChange, onBlur: handleTextBlur, placeholder: t.placeholder, disabled: disabled, isDisabled: disabled, isInvalid: error || isInvalidFormat, size: "sm", variant: "bordered", classNames: {
3941
+ `, "aria-label": t.customColorLabel, title: t.customColorLabel }), jsxRuntime.jsx(Input, { type: "text", value: textValue, onValueChange: handleTextChange, onBlur: handleTextBlur, placeholder: t.placeholder, disabled: disabled, isDisabled: disabled, isInvalid: error || isInvalidFormat, size: "sm", variant: "bordered",
3942
+ // `min-w-0` (TECH-2459, beweossmbs QA 24-sep): el campo es un ítem de la fila
3943
+ // flex de la muestra de color y tiene que poder encoger en huecos estrechos
3944
+ // (Agenda → Colors: 180px). El `w-full min-w-0` del `<input>` en la fachada
3945
+ // ya lo arregla; esto es el suelo explícito en la raíz del campo.
3946
+ className: "min-w-0", classNames: {
3732
3947
  input: "uppercase font-mono text-sm",
3733
3948
  inputWrapper: "min-h-8 h-8 focus-within:!border-primary-500",
3734
3949
  }, startContent: textValue.startsWith("#") ? null : (jsxRuntime.jsx("span", { className: "text-default-400 text-sm", children: "#" })) })] }), (error || isInvalidFormat) && (jsxRuntime.jsx("p", { className: "text-xs text-danger", children: isInvalidFormat ? t.invalidColorFormat : errorText }))] }), showPredefinedColors && predefinedColors.length > 0 && (jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("p", { className: "text-xs font-medium text-default-600 mb-2", children: t.predefinedColorsLabel }), jsxRuntime.jsx("div", { className: "flex flex-wrap gap-2", children: predefinedColors.map((color) => renderColorCircle(color.value, color.name, normalizeHexColor(value) === normalizeHexColor(color.value))) })] })), enableRecentColors && recentColors.length > 0 && (jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("p", { className: "text-xs font-medium text-default-600 mb-2", children: t.recentColorsLabel }), jsxRuntime.jsx("div", { className: "flex flex-wrap gap-2", children: recentColors.map((color) => renderColorCircle(color, color, normalizeHexColor(value) === color)) })] }))] }));
@@ -6013,11 +6228,11 @@ const DonutChart = ({ data, height = 220, innerRadiusRatio = 0.65, showLegend =
6013
6228
  };
6014
6229
 
6015
6230
  const H1 = ({ children, className, ...props }) => {
6016
- return (jsxRuntime.jsx("h1", { className: react.cn("text-xl font-bold", className), ...props, children: children }));
6231
+ return (jsxRuntime.jsx("h1", { className: cn("text-xl font-bold", className), ...props, children: children }));
6017
6232
  };
6018
6233
 
6019
6234
  const H4 = ({ children, className, ...props }) => {
6020
- return (jsxRuntime.jsx("h4", { className: react.cn("text-sm font-medium ", className), ...props, children: children }));
6235
+ return (jsxRuntime.jsx("h4", { className: cn("text-sm font-medium ", className), ...props, children: children }));
6021
6236
  };
6022
6237
 
6023
6238
  /**
@@ -6043,7 +6258,7 @@ const H4 = ({ children, className, ...props }) => {
6043
6258
  * igual para la vía `items` que para la vía `children`. Ganan por CAPA
6044
6259
  * (`@layer utilities` va después de `@layer components`), no por especificidad.
6045
6260
  */
6046
- const V2_INK_CLASS = react.cn(
6261
+ const V2_INK_CLASS = cn(
6047
6262
  // `[data-slot=link]` y no `a`: el breadcrumb ACTUAL de v3 no es un `<a>` (sin `href`,
6048
6263
  // react-aria lo renderiza como `<span role="link" aria-current="page">`), así que un
6049
6264
  // selector por etiqueta se lo dejaba fuera. Verificado en el DOM.
@@ -6092,7 +6307,7 @@ const V2_INK_CLASS = react.cn(
6092
6307
  * Va desde la RAÍZ y por el mismo motivo que `V2_INK_CLASS`: `Breadcrumbs.Item` de v3 pisa las
6093
6308
  * clases de sus partes internas, así que un `className` en el item no sobrevive.
6094
6309
  */
6095
- const V2_SPACING_CLASS = react.cn(
6310
+ const V2_SPACING_CLASS = cn(
6096
6311
  // v2: `item: "flex gap-1 items-center"` → 4px entre la etiqueta y el separador.
6097
6312
  "[&_[data-slot=breadcrumbs-item]]:gap-1",
6098
6313
  // v2: ni el item ni el enlace tenían padding → el primer glifo caía en el canto del rastro…
@@ -6141,7 +6356,7 @@ const BreadcrumbsComponent = ({ items, children, onItemClick,
6141
6356
  // lleguen como atributo DOM desconocido al `<nav>` subyacente, aceptadas solo por
6142
6357
  // compatibilidad de tipos con quien ya las pasaba en v2.
6143
6358
  size: _size, radius: _radius, variant: _variant, className, ...heroUIProps }) => {
6144
- return (jsxRuntime.jsx(react.Breadcrumbs, { ...heroUIProps, className: react.cn(V2_INK_CLASS, V2_SPACING_CLASS, className), children: items
6359
+ return (jsxRuntime.jsx(react.Breadcrumbs, { ...heroUIProps, className: cn(V2_INK_CLASS, V2_SPACING_CLASS, className), children: items
6145
6360
  ? items.map((item, index) => (jsxRuntime.jsx(react.Breadcrumbs.Item, { ...(onItemClick && item.href && !item.isCurrent
6146
6361
  ? { onPress: () => onItemClick(item.href) }
6147
6362
  : { href: item.href }), children: item.label }, `${item.href || item.label}-${index}`)))
@@ -6236,7 +6451,7 @@ const KanbanCardComponent = ({ item, columnId, index, renderContent, onCardClick
6236
6451
  onDragEnd?.();
6237
6452
  }, [onDragEnd]);
6238
6453
  const isInteractive = isClickable && onCardClick;
6239
- return (jsxRuntime.jsx("div", { className: react.cn("bg-content1 border border-default-200 rounded-lg p-4 transition-all", isInteractive && "cursor-pointer hover:border-default-400", isDraggable && "cursor-grab active:cursor-grabbing", isDragging && "opacity-50 scale-95 shadow-lg", className), onClick: isInteractive ? handleClick : undefined, onKeyDown: isInteractive ? handleKeyDown : undefined, role: isInteractive ? "button" : undefined, tabIndex: isInteractive ? 0 : undefined, draggable: isDraggable, onDragStart: handleDragStart, onDragEnd: handleDragEnd, children: renderContent(item) }));
6454
+ return (jsxRuntime.jsx("div", { className: cn("bg-content1 border border-default-200 rounded-lg p-4 transition-all", isInteractive && "cursor-pointer hover:border-default-400", isDraggable && "cursor-grab active:cursor-grabbing", isDragging && "opacity-50 scale-95 shadow-lg", className), onClick: isInteractive ? handleClick : undefined, onKeyDown: isInteractive ? handleKeyDown : undefined, role: isInteractive ? "button" : undefined, tabIndex: isInteractive ? 0 : undefined, draggable: isDraggable, onDragStart: handleDragStart, onDragEnd: handleDragEnd, children: renderContent(item) }));
6240
6455
  };
6241
6456
  const KanbanCard = $8WNJc$react.memo(KanbanCardComponent);
6242
6457
  KanbanCard.displayName = "KanbanCard";
@@ -6431,7 +6646,7 @@ const KanbanColumnComponent = ({ column, renderItem, onCardClick, cardClassName,
6431
6646
  const newDropIndex = e.clientY < midpoint ? itemIndex : itemIndex + 1;
6432
6647
  setDropIndex(newDropIndex);
6433
6648
  }, []);
6434
- return (jsxRuntime.jsxs("div", { className: react.cn("flex flex-col bg-default-50 rounded-lg border border-default-200 transition-colors", isDragOver && isDragging && "border-primary-400 bg-primary-50/30", className), onDragOver: handleDragOver, onDragLeave: handleDragLeave, onDrop: handleDrop, children: [renderColumnHeader ? (renderColumnHeader(column)) : (jsxRuntime.jsxs("div", { className: "flex items-center justify-between px-4 py-3 border-b border-default-200", children: [jsxRuntime.jsx("h3", { className: "font-semibold text-foreground", children: column.title }), showItemCount && (jsxRuntime.jsx(Badge, { color: V3_BADGE_COLOR[column.countBadgeColor ?? "default"], variant: "soft", size: "lg",
6649
+ return (jsxRuntime.jsxs("div", { className: cn("flex flex-col bg-default-50 rounded-lg border border-default-200 transition-colors", isDragOver && isDragging && "border-primary-400 bg-primary-50/30", className), onDragOver: handleDragOver, onDragLeave: handleDragLeave, onDrop: handleDrop, children: [renderColumnHeader ? (renderColumnHeader(column)) : (jsxRuntime.jsxs("div", { className: "flex items-center justify-between px-4 py-3 border-b border-default-200", children: [jsxRuntime.jsx("h3", { className: "font-semibold text-foreground", children: column.title }), showItemCount && (jsxRuntime.jsx(Badge, { color: V3_BADGE_COLOR[column.countBadgeColor ?? "default"], variant: "soft", size: "lg",
6435
6650
  // `static transform-none`: el Badge de v3 se posiciona ABSOLUTO por
6436
6651
  // `placement` (`.badge--top-right { absolute top-0 right-0 }` +
6437
6652
  // `translate(25%,-25%)`), pensado para vivir dentro de un `Badge.Anchor`.
@@ -6441,7 +6656,7 @@ const KanbanColumnComponent = ({ column, renderItem, onCardClick, cardClassName,
6441
6656
  // siempre visible pero la story lo tapaba, y ahora queda apagado por defecto.
6442
6657
  className: "static text-xs font-medium transform-none", style: column.countBadgeColor === "secondary"
6443
6658
  ? SECONDARY_BADGE_STYLE
6444
- : undefined, "aria-label": `${itemCount} ${t.itemsLabel}`, children: itemCount }))] })), jsxRuntime.jsx("div", { ref: scrollContainerRef, className: react.cn("flex-1 overflow-y-auto p-3 space-y-3", isDragOver && isEmpty && "min-h-24"), style: { maxHeight }, children: isEmpty ? (isDragOver && isDragging ? (jsxRuntime.jsx("div", { className: "h-24 border-2 border-dashed border-primary-300 rounded-lg bg-primary-50/50 flex items-center justify-center", children: jsxRuntime.jsx("span", { className: "text-primary-500 text-sm", children: t.dropHere }) })) : renderEmptyState ? (renderEmptyState(column)) : (jsxRuntime.jsx("div", { className: "flex items-center justify-center h-24 text-default-400 text-sm", children: column.emptyMessage || t.emptyMessage }))) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [column.items.map((item, index) => (jsxRuntime.jsxs("div", { onDragOver: (e) => handleDragOverItem(e, index), children: [isDragOver && dropIndex === index && (jsxRuntime.jsx("div", { className: "h-1 bg-primary-400 rounded-full mb-3 animate-pulse" })), jsxRuntime.jsx(KanbanCard, { item: item, columnId: column.id, index: index, renderContent: renderItem, onCardClick: onCardClick, className: cardClassName, isClickable: isCardClickable, isDraggable: isDraggable, onDragStart: onDragStart, onDragEnd: onDragEnd })] }, item.id))), isDragOver && dropIndex === column.items.length && (jsxRuntime.jsx("div", { className: "h-1 bg-primary-400 rounded-full mt-3 animate-pulse" })), column.isLoading && (jsxRuntime.jsx("div", { className: "flex items-center justify-center py-4", children: jsxRuntime.jsx(react.Spinner, { size: "sm", color: "accent" }) }))] })) })] }));
6659
+ : undefined, "aria-label": `${itemCount} ${t.itemsLabel}`, children: itemCount }))] })), jsxRuntime.jsx("div", { ref: scrollContainerRef, className: cn("flex-1 overflow-y-auto p-3 space-y-3", isDragOver && isEmpty && "min-h-24"), style: { maxHeight }, children: isEmpty ? (isDragOver && isDragging ? (jsxRuntime.jsx("div", { className: "h-24 border-2 border-dashed border-primary-300 rounded-lg bg-primary-50/50 flex items-center justify-center", children: jsxRuntime.jsx("span", { className: "text-primary-500 text-sm", children: t.dropHere }) })) : renderEmptyState ? (renderEmptyState(column)) : (jsxRuntime.jsx("div", { className: "flex items-center justify-center h-24 text-default-400 text-sm", children: column.emptyMessage || t.emptyMessage }))) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [column.items.map((item, index) => (jsxRuntime.jsxs("div", { onDragOver: (e) => handleDragOverItem(e, index), children: [isDragOver && dropIndex === index && (jsxRuntime.jsx("div", { className: "h-1 bg-primary-400 rounded-full mb-3 animate-pulse" })), jsxRuntime.jsx(KanbanCard, { item: item, columnId: column.id, index: index, renderContent: renderItem, onCardClick: onCardClick, className: cardClassName, isClickable: isCardClickable, isDraggable: isDraggable, onDragStart: onDragStart, onDragEnd: onDragEnd })] }, item.id))), isDragOver && dropIndex === column.items.length && (jsxRuntime.jsx("div", { className: "h-1 bg-primary-400 rounded-full mt-3 animate-pulse" })), column.isLoading && (jsxRuntime.jsx("div", { className: "flex items-center justify-center py-4", children: jsxRuntime.jsx(react.Spinner, { size: "sm", color: "accent" }) }))] })) })] }));
6445
6660
  };
6446
6661
  const KanbanColumn = $8WNJc$react.memo(KanbanColumnComponent);
6447
6662
  KanbanColumn.displayName = "KanbanColumn";
@@ -6526,7 +6741,7 @@ const KanbanComponent = ({ columns, renderItem, onCardClick, onItemMove, isDragg
6526
6741
  });
6527
6742
  handleDragEnd();
6528
6743
  }, [onItemMove, handleDragEnd]);
6529
- return (jsxRuntime.jsx("div", { className: react.cn("flex", columnGapClasses[columnGap], horizontalScroll && "overflow-x-auto pb-4", className), children: columns.map((column) => (jsxRuntime.jsx("div", { className: "flex-shrink-0", style: { width: columnWidth }, children: jsxRuntime.jsx(KanbanColumn, { column: column, renderItem: renderItem, onCardClick: onCardClick, cardClassName: cardClassName, isCardClickable: isCardClickable, maxHeight: columnMaxHeight, renderColumnHeader: renderColumnHeader, renderEmptyState: renderEmptyState, isDraggable: dragEnabled, onDragStart: handleDragStart, onDragEnd: handleDragEnd, onDrop: handleDrop, isDragging: isDragging, translations: t, onLoadMore: onLoadMore ? () => onLoadMore(column.id) : undefined, showItemCount: showItemCount }) }, column.id))) }));
6744
+ return (jsxRuntime.jsx("div", { className: cn("flex", columnGapClasses[columnGap], horizontalScroll && "overflow-x-auto pb-4", className), children: columns.map((column) => (jsxRuntime.jsx("div", { className: "flex-shrink-0", style: { width: columnWidth }, children: jsxRuntime.jsx(KanbanColumn, { column: column, renderItem: renderItem, onCardClick: onCardClick, cardClassName: cardClassName, isCardClickable: isCardClickable, maxHeight: columnMaxHeight, renderColumnHeader: renderColumnHeader, renderEmptyState: renderEmptyState, isDraggable: dragEnabled, onDragStart: handleDragStart, onDragEnd: handleDragEnd, onDrop: handleDrop, isDragging: isDragging, translations: t, onLoadMore: onLoadMore ? () => onLoadMore(column.id) : undefined, showItemCount: showItemCount }) }, column.id))) }));
6530
6745
  };
6531
6746
  const Kanban = $8WNJc$react.memo(KanbanComponent);
6532
6747
  Kanban.displayName = "Kanban";
@@ -6702,9 +6917,9 @@ const MenuMobileBottomBar = $8WNJc$react.memo(function MenuMobileBottomBar({ ite
6702
6917
  const handleItemPress = $8WNJc$react.useCallback((key, href) => {
6703
6918
  onSelect?.(key, href);
6704
6919
  }, [onSelect]);
6705
- return (jsxRuntime.jsx("nav", { className: react.cn("menu-mobile-bottom-bar", forceVisible && "menu-mobile-bottom-bar--force-visible"), "aria-label": navAriaLabel, children: jsxRuntime.jsxs("div", { className: "menu-mobile-bottom-bar__container", children: [visibleItems.map((item) => {
6920
+ return (jsxRuntime.jsx("nav", { className: cn("menu-mobile-bottom-bar", forceVisible && "menu-mobile-bottom-bar--force-visible"), "aria-label": navAriaLabel, children: jsxRuntime.jsxs("div", { className: "menu-mobile-bottom-bar__container", children: [visibleItems.map((item) => {
6706
6921
  const isSelected = selectedKey === item.key;
6707
- return (jsxRuntime.jsxs("button", { type: "button", className: react.cn("menu-mobile-bottom-bar__item", isSelected && "menu-mobile-bottom-bar__item--active"), onClick: () => handleItemPress(item.key, item.href), "aria-current": isSelected ? "page" : undefined, "aria-label": item.title, children: [item.icon && (jsxRuntime.jsx(IconComponent, { icon: item.icon, size: "md", className: "menu-mobile-bottom-bar__icon" })), jsxRuntime.jsx("span", { className: "menu-mobile-bottom-bar__label", children: item.title })] }, item.key));
6922
+ return (jsxRuntime.jsxs("button", { type: "button", className: cn("menu-mobile-bottom-bar__item", isSelected && "menu-mobile-bottom-bar__item--active"), onClick: () => handleItemPress(item.key, item.href), "aria-current": isSelected ? "page" : undefined, "aria-label": item.title, children: [item.icon && (jsxRuntime.jsx(IconComponent, { icon: item.icon, size: "md", className: "menu-mobile-bottom-bar__icon" })), jsxRuntime.jsx("span", { className: "menu-mobile-bottom-bar__label", children: item.title })] }, item.key));
6708
6923
  }), jsxRuntime.jsxs("button", { type: "button", className: "menu-mobile-bottom-bar__item", onClick: onMenuPress, "aria-label": menuLabel, children: [jsxRuntime.jsx(IconComponent, { icon: "solar:hamburger-menu-linear", size: "md", className: "menu-mobile-bottom-bar__icon" }), jsxRuntime.jsx("span", { className: "menu-mobile-bottom-bar__label", children: menuLabel })] })] }) }));
6709
6924
  });
6710
6925
 
@@ -6744,7 +6959,16 @@ const ITEM_COLLAPSED_CLASS = "w-11 h-11 gap-0 p-0 justify-center";
6744
6959
  // `w-full flex-1`: el slot `title` de v2 era `flex-1 text-small font-normal w-full`, y su slot
6745
6960
  // `wrapper` `w-full` — el título se comía el espacio libre y empujaba el `endContent` al borde.
6746
6961
  // El `[data-slot="label"]` de v3 es `w-fit`, que es la otra mitad de P-14.
6747
- const ITEM_TITLE_CLASS = "w-full flex-1 text-sm font-medium text-default-500 group-data-[selected=true]:text-default-600";
6962
+ //
6963
+ // `min-w-0 truncate`: v2 le ponía `truncate` al slot `title` siempre que el título fuera texto
6964
+ // (`@heroui/theme@2.4.15`, `dist/components/listbox.js`, variante `hasTitleTextChild: { true:
6965
+ // { title: "truncate" } }`; en el menú el título es siempre un string). La migración copió el slot
6966
+ // base y se dejó la variante. Sin ella, una etiqueta que no cabe no se corta:
6967
+ // medido en beweossmbs y en la story `Menu › LongLabelTruncation`, «menu_automations» ocupaba sus
6968
+ // 126,8px enteros y empujaba la chip «AI» de x=204,7 a x=222,8, 6px FUERA del ítem. `truncate` solo
6969
+ // no basta: un flex item parte de `min-width: auto` (su ancho de contenido) y no encoge por debajo;
6970
+ // `min-w-0` es lo que le deja ceder el hueco a la chip, y entonces sí corta con elipsis.
6971
+ const ITEM_TITLE_CLASS = "w-full min-w-0 flex-1 truncate text-sm font-medium text-default-500 group-data-[selected=true]:text-default-600";
6748
6972
  // TECH-2459 · G2 · fix de navegación — resolución de un ítem por su clave.
6749
6973
  //
6750
6974
  // `onSelectionChange` del `ListBox` entrega la CLAVE, no el ítem. v2 no necesitaba esto:
@@ -6871,7 +7095,7 @@ const MenuNavList = $8WNJc$react.forwardRef(({ items, isCollapsed, defaultSelect
6871
7095
  // `MenuClawNavItem` (HTML semántico + `onClick`, sin `ListBox`).
6872
7096
  const renderSubItem = $8WNJc$react.useCallback((item) => {
6873
7097
  const isSelected = item.key === selectedKey;
6874
- return (jsxRuntime.jsx("li", { children: jsxRuntime.jsxs("button", { type: "button", "data-menu-subitem-selected": isSelected ? "true" : "false", "aria-current": isSelected ? "page" : undefined, className: react.cn("flex w-full items-center justify-between gap-2 min-h-9 rounded-[14px] px-3 py-2 menu-nav-list__sub-item text-left", "text-default-500 hover:text-default-700 transition-colors outline-none", "focus-visible:z-10 focus-visible:outline-2 focus-visible:outline-focus focus-visible:outline-offset-2", isSelected && "selected"), onClick: () => handleItemPress(item), children: [jsxRuntime.jsx(react.Label, { className: "text-sm font-normal text-inherit", children: item.title }), item.endContent ?? null] }) }, item.key));
7098
+ return (jsxRuntime.jsx("li", { children: jsxRuntime.jsxs("button", { type: "button", "data-menu-subitem-selected": isSelected ? "true" : "false", "aria-current": isSelected ? "page" : undefined, className: cn("flex w-full items-center justify-between gap-2 min-h-9 rounded-[14px] px-3 py-2 menu-nav-list__sub-item text-left", "text-default-500 hover:text-default-700 transition-colors outline-none", "focus-visible:z-10 focus-visible:outline-2 focus-visible:outline-focus focus-visible:outline-offset-2", isSelected && "selected"), onClick: () => handleItemPress(item), children: [jsxRuntime.jsx(react.Label, { className: "text-sm font-normal text-inherit", children: item.title }), item.endContent ?? null] }) }, item.key));
6875
7099
  }, [handleItemPress, selectedKey]);
6876
7100
  // Renders a nested item, i.e., an item that has sub-items.
6877
7101
  // biome-ignore lint/correctness/useExhaustiveDependencies: <explanation>
@@ -6883,16 +7107,16 @@ const MenuNavList = $8WNJc$react.forwardRef(({ items, isCollapsed, defaultSelect
6883
7107
  const isSelectedKeyInThisNest = Boolean(selectedKey && item.items?.length) &&
6884
7108
  (item.items?.some((child) => child.key === selectedKey) ?? false);
6885
7109
  const isItemSelected = selectedKey === item.key;
6886
- return (jsxRuntime.jsxs(react.ListBoxItem, { id: item.key, textValue: item.title, "aria-selected": isItemSelected, className: react.cn(ITEM_BASE_CLASS, isCollapsed && ITEM_COLLAPSED_CLASS, {
7110
+ return (jsxRuntime.jsxs(react.ListBoxItem, { id: item.key, textValue: item.title, "aria-selected": isItemSelected, className: cn(ITEM_BASE_CLASS, isCollapsed && ITEM_COLLAPSED_CLASS, {
6887
7111
  "h-auto p-0": !isCollapsed && isNestType,
6888
7112
  }, {
6889
7113
  "inline-block w-11": isCollapsed && isNestType,
6890
7114
  }, {
6891
7115
  "data-[selected=true]:bg-primary-100 h-11 justify-center items-center flex": isCollapsed && isNestType,
6892
- }), children: [isCollapsed || isNestType ? null : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [item.icon ? (jsxRuntime.jsx(IconComponent, { className: react.cn("text-default-500 group-data-[selected=true]:text-foreground", iconClassName), icon: item.icon, size: "lg" })) : ((item.startContent ?? null)), jsxRuntime.jsx(react.Label, { className: ITEM_TITLE_CLASS, children: item.title }), hideEndContent ? null : (item.endContent ?? null)] })), isCollapsed && isNestType ? (
7116
+ }), children: [isCollapsed || isNestType ? null : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [item.icon ? (jsxRuntime.jsx(IconComponent, { className: cn("text-default-500 group-data-[selected=true]:text-foreground", iconClassName), icon: item.icon, size: "lg" })) : ((item.startContent ?? null)), jsxRuntime.jsx(react.Label, { className: ITEM_TITLE_CLASS, children: item.title }), hideEndContent ? null : (item.endContent ?? null)] })), isCollapsed && isNestType ? (
6893
7117
  // `placement`/`offset` viven en `PopoverContent` en v3, no en la raíz
6894
7118
  // `Popover` (a diferencia de v2) — mismo patrón que Tooltip.Content.
6895
- jsxRuntime.jsxs(react.Popover, { children: [jsxRuntime.jsx(react.PopoverTrigger, { children: jsxRuntime.jsxs("div", { className: "flex w-full items-center justify-center gap-1", children: [jsxRuntime.jsxs(react.Tooltip, { delay: 0, children: [jsxRuntime.jsx(react.Tooltip.Trigger, { children: jsxRuntime.jsx("div", { className: "flex items-center justify-center", children: item.icon ? (jsxRuntime.jsx(IconComponent, { className: react.cn("text-default-500 group-data-[selected=true]:text-default-600", iconClassName), icon: item.icon, size: "lg" })) : ((item.startContent ?? null)) }) }), jsxRuntime.jsx(react.Tooltip.Content, { placement: "right", className: "text-default-500", children: item.title })] }), jsxRuntime.jsx(IconComponent, { className: "text-default-400 shrink-0", icon: "solar:alt-arrow-right-outline", size: "sm", "aria-hidden": true })] }) }), jsxRuntime.jsx(react.PopoverContent, { placement: "right", offset: 10, className: "border border-default-200 bg-white p-0 shadow-md", children: jsxRuntime.jsxs("div", { className: "min-w-[200px] rounded-[14px] p-2", children: [jsxRuntime.jsx("div", { className: "px-3 py-2 text-sm font-semibold text-default-500", children: item.title }), jsxRuntime.jsx("ul", { className: "mt-0.5 flex flex-col gap-0.5 border-l border-default-200 pl-4 ml-2", children: (item.items?.length ? item.items : [item]).map((child) => renderSubItem(child)) })] }) })] })) : null, !isCollapsed && isNestType ? (jsxRuntime.jsxs("details", { className: "group/details w-full p-0", "aria-label": item.title, open: isSelectedKeyInThisNest, children: [jsxRuntime.jsx("summary", { className: react.cn("flex h-11 list-none cursor-pointer items-center gap-2 rounded-[14px] px-3 py-1.5 pr-3", "text-default-500 hover:bg-default-100 [&::-webkit-details-marker]:hidden [&::marker]:hidden"), children: item.icon ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(IconComponent, { className: react.cn("text-default-500 group-open/details:text-default-600", iconClassName), icon: item.icon, size: "lg" }), jsxRuntime.jsx("span", { className: "text-sm font-medium text-default-500 group-open/details:text-default-600 flex-1", children: item.title }), jsxRuntime.jsxs("span", { className: "flex shrink-0 items-center text-default-400", children: [jsxRuntime.jsx(IconComponent, { className: "hidden group-open/details:inline-block", icon: "solar:alt-arrow-down-outline", size: "sm", "aria-hidden": true }), jsxRuntime.jsx(IconComponent, { className: "inline-block group-open/details:hidden", icon: "solar:alt-arrow-right-outline", size: "sm", "aria-hidden": true })] })] })) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [item.startContent ?? null, jsxRuntime.jsxs("span", { className: "ml-auto flex shrink-0 items-center text-default-400", children: [jsxRuntime.jsx(IconComponent, { className: "hidden group-open/details:inline-block", icon: "solar:alt-arrow-down-outline", size: "sm", "aria-hidden": true }), jsxRuntime.jsx(IconComponent, { className: "inline-block group-open/details:hidden", icon: "solar:alt-arrow-right-outline", size: "sm", "aria-hidden": true })] })] })) }), jsxRuntime.jsx("div", { className: "py-0 pl-4", children: item.items && item.items?.length > 0 ? (jsxRuntime.jsx("ul", { className: "mt-0.5 flex flex-col gap-0.5 border-l border-default-200 pl-4 ml-2", children: item.items.map((child) => renderSubItem(child)) })) : (renderItem(item)) })] })) : null] }, item.key));
7119
+ jsxRuntime.jsxs(react.Popover, { children: [jsxRuntime.jsx(react.PopoverTrigger, { children: jsxRuntime.jsxs("div", { className: "flex w-full items-center justify-center gap-1", children: [jsxRuntime.jsxs(react.Tooltip, { delay: 0, children: [jsxRuntime.jsx(react.Tooltip.Trigger, { children: jsxRuntime.jsx("div", { className: "flex items-center justify-center", children: item.icon ? (jsxRuntime.jsx(IconComponent, { className: cn("text-default-500 group-data-[selected=true]:text-default-600", iconClassName), icon: item.icon, size: "lg" })) : ((item.startContent ?? null)) }) }), jsxRuntime.jsx(react.Tooltip.Content, { placement: "right", className: "text-default-500", children: item.title })] }), jsxRuntime.jsx(IconComponent, { className: "text-default-400 shrink-0", icon: "solar:alt-arrow-right-outline", size: "sm", "aria-hidden": true })] }) }), jsxRuntime.jsx(react.PopoverContent, { placement: "right", offset: 10, className: "border border-default-200 bg-white p-0 shadow-md", children: jsxRuntime.jsxs("div", { className: "min-w-[200px] rounded-[14px] p-2", children: [jsxRuntime.jsx("div", { className: "px-3 py-2 text-sm font-semibold text-default-500", children: item.title }), jsxRuntime.jsx("ul", { className: "mt-0.5 flex flex-col gap-0.5 border-l border-default-200 pl-4 ml-2", children: (item.items?.length ? item.items : [item]).map((child) => renderSubItem(child)) })] }) })] })) : null, !isCollapsed && isNestType ? (jsxRuntime.jsxs("details", { className: "group/details w-full p-0", "aria-label": item.title, open: isSelectedKeyInThisNest, children: [jsxRuntime.jsx("summary", { className: cn("flex h-11 list-none cursor-pointer items-center gap-2 rounded-[14px] px-3 py-1.5 pr-3", "text-default-500 hover:bg-default-100 [&::-webkit-details-marker]:hidden [&::marker]:hidden"), children: item.icon ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(IconComponent, { className: cn("text-default-500 group-open/details:text-default-600", iconClassName), icon: item.icon, size: "lg" }), jsxRuntime.jsx("span", { className: "text-sm font-medium text-default-500 group-open/details:text-default-600 flex-1", children: item.title }), jsxRuntime.jsxs("span", { className: "flex shrink-0 items-center text-default-400", children: [jsxRuntime.jsx(IconComponent, { className: "hidden group-open/details:inline-block", icon: "solar:alt-arrow-down-outline", size: "sm", "aria-hidden": true }), jsxRuntime.jsx(IconComponent, { className: "inline-block group-open/details:hidden", icon: "solar:alt-arrow-right-outline", size: "sm", "aria-hidden": true })] })] })) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [item.startContent ?? null, jsxRuntime.jsxs("span", { className: "ml-auto flex shrink-0 items-center text-default-400", children: [jsxRuntime.jsx(IconComponent, { className: "hidden group-open/details:inline-block", icon: "solar:alt-arrow-down-outline", size: "sm", "aria-hidden": true }), jsxRuntime.jsx(IconComponent, { className: "inline-block group-open/details:hidden", icon: "solar:alt-arrow-right-outline", size: "sm", "aria-hidden": true })] })] })) }), jsxRuntime.jsx("div", { className: "py-0 pl-4", children: item.items && item.items?.length > 0 ? (jsxRuntime.jsx("ul", { className: "mt-0.5 flex flex-col gap-0.5 border-l border-default-200 pl-4 ml-2", children: item.items.map((child) => renderSubItem(child)) })) : (renderItem(item)) })] })) : null] }, item.key));
6896
7120
  }, [isCollapsed, hideEndContent, iconClassName, selectedKey, renderSubItem]);
6897
7121
  // Renders a simple item (without children) in the navigation list.
6898
7122
  // biome-ignore lint/correctness/useExhaustiveDependencies: <explanation>
@@ -6904,11 +7128,11 @@ const MenuNavList = $8WNJc$react.forwardRef(({ items, isCollapsed, defaultSelect
6904
7128
  return renderNestItem(item);
6905
7129
  }
6906
7130
  const isItemSelected = selectedKey === item.key;
6907
- return (jsxRuntime.jsx(react.ListBoxItem, { id: item.key, textValue: item.title, "aria-selected": isItemSelected, "aria-label": item.title || `Menu item ${item.key}`, className: react.cn(ITEM_BASE_CLASS, isCollapsed && ITEM_COLLAPSED_CLASS), children: isCollapsed ? (jsxRuntime.jsxs(react.Tooltip, { delay: 0, closeDelay: 200, children: [jsxRuntime.jsx(react.Tooltip.Trigger, { children: jsxRuntime.jsx("div", { className: "flex w-full items-center justify-center", "aria-hidden": "true", children: item.icon ? (jsxRuntime.jsx(IconComponent, { className: react.cn("text-default-500", "group-data-[selected=true]:text-default-600", iconClassName), icon: item.icon, size: "lg" })) : ((item.startContent ?? null)) }) }), jsxRuntime.jsx(react.Tooltip.Content, { placement: "right", className: "text-default-500", children: item.title })] })) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [item.icon ? (jsxRuntime.jsx(IconComponent, { className: react.cn("text-default-500", "group-data-[selected=true]:text-default-600", iconClassName), icon: item.icon, size: "lg" })) : ((item.startContent ?? null)), jsxRuntime.jsx(react.Label, { className: ITEM_TITLE_CLASS, children: item.title }), hideEndContent ? null : (item.endContent ?? null)] })) }, item.key));
7131
+ return (jsxRuntime.jsx(react.ListBoxItem, { id: item.key, textValue: item.title, "aria-selected": isItemSelected, "aria-label": item.title || `Menu item ${item.key}`, className: cn(ITEM_BASE_CLASS, isCollapsed && ITEM_COLLAPSED_CLASS), children: isCollapsed ? (jsxRuntime.jsxs(react.Tooltip, { delay: 0, closeDelay: 200, children: [jsxRuntime.jsx(react.Tooltip.Trigger, { children: jsxRuntime.jsx("div", { className: "flex w-full items-center justify-center", "aria-hidden": "true", children: item.icon ? (jsxRuntime.jsx(IconComponent, { className: cn("text-default-500", "group-data-[selected=true]:text-default-600", iconClassName), icon: item.icon, size: "lg" })) : ((item.startContent ?? null)) }) }), jsxRuntime.jsx(react.Tooltip.Content, { placement: "right", className: "text-default-500", children: item.title })] })) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [item.icon ? (jsxRuntime.jsx(IconComponent, { className: cn("text-default-500", "group-data-[selected=true]:text-default-600", iconClassName), icon: item.icon, size: "lg" })) : ((item.startContent ?? null)), jsxRuntime.jsx(react.Label, { className: ITEM_TITLE_CLASS, children: item.title }), hideEndContent ? null : (item.endContent ?? null)] })) }, item.key));
6908
7132
  }, [isCollapsed, hideEndContent, iconClassName, selectedKey, renderNestItem]);
6909
7133
  // `ListBox` de v3 ya no es polimórfico via `as` (a diferencia de Breadcrumbs/Pagination) —
6910
7134
  // renderiza siempre su propio contenedor; el landmark de navegación se envuelve por fuera.
6911
- return (jsxRuntime.jsx("nav", { "aria-label": "Menu navigation", ref: ref, children: jsxRuntime.jsx(react.ListBox, { "aria-label": "Menu navigation", className: react.cn("list-none items-center", className), items: items, selectedKeys: selectedKeys, selectionMode: "single", onSelectionChange: handleSelectionChange,
7135
+ return (jsxRuntime.jsx("nav", { "aria-label": "Menu navigation", ref: ref, children: jsxRuntime.jsx(react.ListBox, { "aria-label": "Menu navigation", className: cn("list-none items-center", className), items: items, selectedKeys: selectedKeys, selectionMode: "single", onSelectionChange: handleSelectionChange,
6912
7136
  // Neutraliza el Escape del `ListBox`: con el valor por defecto
6913
7137
  // (`clearSelection`) vaciaría la selección y `handleSelectionChange` leería ese
6914
7138
  // conjunto vacío como un reclic, navegando a la ruta actual sin que nadie haya
@@ -6955,10 +7179,10 @@ const MenuNavList = $8WNJc$react.forwardRef(({ items, isCollapsed, defaultSelect
6955
7179
  // porque es lo correcto en 6 de las 8 stories y las dos que quedan
6956
7180
  // pasan de sobra; anotado por si alguien mide `malformed-menu` a solas
6957
7181
  // y cree haber encontrado una mejora.
6958
- className: react.cn("w-full", {
7182
+ className: cn("w-full", {
6959
7183
  "p-0 max-w-[44px] gap-1": isCollapsed,
6960
7184
  "mb-[9px]": !isCollapsed,
6961
- }), children: [jsxRuntime.jsx(react.Header, { className: react.cn("pl-1 text-xs font-normal text-foreground-500",
7185
+ }), children: [jsxRuntime.jsx(react.Header, { className: cn("pl-1 text-xs font-normal text-foreground-500",
6962
7186
  // El relleno vertical SOLO cuando la sección tiene título, que
6963
7187
  // es la semántica del `data-[has-title=true]:pt-1` de v2. Con
6964
7188
  // título el bloque mide 29px; sin título, v2 dejaba solo la
@@ -7209,7 +7433,7 @@ const MenuClawHistoryPanel = $8WNJc$react.memo(function MenuClawHistoryPanel({ i
7209
7433
  if (isCollapsed && !onNewConversation) {
7210
7434
  return null;
7211
7435
  }
7212
- return (jsxRuntime.jsxs("div", { className: "flex max-h-[40%] min-h-0 flex-col gap-2 pb-3", children: [onNewConversation ? (jsxRuntime.jsxs("button", { type: "button", title: newLabel, onClick: onNewConversation, className: react.cn("flex h-9 shrink-0 items-center gap-3 rounded-xl bg-foreground px-2 text-sm font-medium text-background transition-opacity hover:opacity-90", "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-focus", isCollapsed && "justify-center"), children: [jsxRuntime.jsx("span", { className: "flex h-5 w-5 shrink-0 items-center justify-center", children: jsxRuntime.jsx(IconComponent, { icon: "solar:pen-new-square-linear", size: "md", "aria-hidden": true }) }), !isCollapsed ? (jsxRuntime.jsx("span", { className: "menu-claw-collapsible truncate", children: newLabel })) : null] })) : null, !isCollapsed && items.length > 0 ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("p", { className: "shrink-0 px-2 pb-1 pt-2 text-xs font-medium uppercase tracking-wide text-default-400", children: title }), jsxRuntime.jsx("ul", { "aria-label": title, className: "flex min-h-0 flex-1 flex-col gap-0.5 overflow-y-auto [&::-webkit-scrollbar]:hidden [-ms-overflow-style:none] [scrollbar-width:none]", children: visibleItems.map((item) => (jsxRuntime.jsx("li", { children: jsxRuntime.jsxs("button", { type: "button", disabled: item.disabled, "aria-disabled": item.disabled, title: item.title, onClick: () => handleItemPress(item), className: react.cn("flex min-h-9 w-full items-center gap-3 rounded-lg px-2 py-1.5 text-left text-sm text-default-600 transition-colors", "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-focus", item.disabled
7436
+ return (jsxRuntime.jsxs("div", { className: "flex max-h-[40%] min-h-0 flex-col gap-2 pb-3", children: [onNewConversation ? (jsxRuntime.jsxs("button", { type: "button", title: newLabel, onClick: onNewConversation, className: cn("flex h-9 shrink-0 items-center gap-3 rounded-xl bg-foreground px-2 text-sm font-medium text-background transition-opacity hover:opacity-90", "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-focus", isCollapsed && "justify-center"), children: [jsxRuntime.jsx("span", { className: "flex h-5 w-5 shrink-0 items-center justify-center", children: jsxRuntime.jsx(IconComponent, { icon: "solar:pen-new-square-linear", size: "md", "aria-hidden": true }) }), !isCollapsed ? (jsxRuntime.jsx("span", { className: "menu-claw-collapsible truncate", children: newLabel })) : null] })) : null, !isCollapsed && items.length > 0 ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("p", { className: "shrink-0 px-2 pb-1 pt-2 text-xs font-medium uppercase tracking-wide text-default-400", children: title }), jsxRuntime.jsx("ul", { "aria-label": title, className: "flex min-h-0 flex-1 flex-col gap-0.5 overflow-y-auto [&::-webkit-scrollbar]:hidden [-ms-overflow-style:none] [scrollbar-width:none]", children: visibleItems.map((item) => (jsxRuntime.jsx("li", { children: jsxRuntime.jsxs("button", { type: "button", disabled: item.disabled, "aria-disabled": item.disabled, title: item.title, onClick: () => handleItemPress(item), className: cn("flex min-h-9 w-full items-center gap-3 rounded-lg px-2 py-1.5 text-left text-sm text-default-600 transition-colors", "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-focus", item.disabled
7213
7437
  ? "cursor-not-allowed opacity-50"
7214
7438
  : "hover:bg-default-100"), children: [jsxRuntime.jsx("span", { className: "flex h-5 w-5 shrink-0 items-center justify-center text-default-400", children: jsxRuntime.jsx(IconComponent, { icon: "solar:chat-round-dots-linear", size: "md", "aria-hidden": true }) }), jsxRuntime.jsxs("span", { className: "flex min-w-0 flex-col", children: [jsxRuntime.jsx("span", { className: "truncate", children: item.title }), item.meta ? (jsxRuntime.jsx("span", { className: "truncate text-xs text-default-400", children: item.meta })) : null] })] }) }, item.id))) }), hasHiddenItems ? (jsxRuntime.jsxs("button", { type: "button", onClick: handleToggleExpand, "aria-expanded": isExpanded, className: "flex w-full shrink-0 items-center gap-1.5 rounded-lg px-2 py-2 text-xs font-medium text-default-500 transition-colors hover:bg-default-100 hover:text-default-700 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-focus", children: [jsxRuntime.jsx(IconComponent, { icon: isExpanded
7215
7439
  ? "solar:alt-arrow-up-linear"
@@ -7256,14 +7480,14 @@ const MenuClawNavItem = ({ item, selectedKey, isCollapsed, onSelect, depth = 0,
7256
7480
  onSelect(item.key, item.href);
7257
7481
  }, [isGroup, onSelect, item.key, item.href]);
7258
7482
  const icon = item.icon || item.startContent ? (jsxRuntime.jsx("span", { className: "flex h-5 w-5 shrink-0 items-center justify-center text-default-500 [&_svg]:h-5 [&_svg]:w-5", children: item.icon ? (jsxRuntime.jsx(IconComponent, { icon: item.icon, size: "md", "aria-hidden": true })) : (item.startContent) })) : null;
7259
- return (jsxRuntime.jsxs("li", { children: [jsxRuntime.jsxs("button", { type: "button", title: isCollapsed ? item.title : undefined, onClick: handleClick, "aria-expanded": isGroup ? isOpen : undefined, "aria-controls": isGroup ? submenuId : undefined, className: react.cn(
7483
+ return (jsxRuntime.jsxs("li", { children: [jsxRuntime.jsxs("button", { type: "button", title: isCollapsed ? item.title : undefined, onClick: handleClick, "aria-expanded": isGroup ? isOpen : undefined, "aria-controls": isGroup ? submenuId : undefined, className: cn(
7260
7484
  // `text-small` es clase muerta de v2 (TECH-2459 · G2) → `text-sm` (mismo tamaño).
7261
7485
  "flex w-full items-center rounded-lg px-2 py-1.5 text-left text-sm transition-colors", "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-focus", depth === 0 ? "min-h-9" : "min-h-8", isCollapsed ? "justify-center" : "gap-3",
7262
7486
  // Sangría del hijo: alinea su texto con el del padre (px-2 + icono
7263
7487
  // de 20px + gap de 12px).
7264
7488
  !isCollapsed && depth > 0 && !icon ? "pl-10" : undefined, isActive
7265
7489
  ? "bg-default-100 font-medium text-foreground"
7266
- : "text-default-600 hover:bg-default-100", item.className), children: [icon, !isCollapsed ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("span", { className: "menu-claw-collapsible flex-1 truncate", children: item.title }), item.endContent ?? null, isGroup ? (jsxRuntime.jsx(IconComponent, { icon: "solar:alt-arrow-down-linear", size: "sm", "aria-hidden": true, className: react.cn("shrink-0 text-default-400 transition-transform", isOpen && "rotate-180") })) : null] })) : null] }), isGroup && isOpen ? (jsxRuntime.jsx("ul", { id: submenuId, className: "mt-0.5 flex flex-col gap-0.5", children: children.map((child) => (jsxRuntime.jsx(MenuClawNavItem, { item: child, selectedKey: selectedKey, isCollapsed: isCollapsed, onSelect: onSelect, depth: depth + 1 }, child.key))) })) : null] }));
7490
+ : "text-default-600 hover:bg-default-100", item.className), children: [icon, !isCollapsed ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("span", { className: "menu-claw-collapsible flex-1 truncate", children: item.title }), item.endContent ?? null, isGroup ? (jsxRuntime.jsx(IconComponent, { icon: "solar:alt-arrow-down-linear", size: "sm", "aria-hidden": true, className: cn("shrink-0 text-default-400 transition-transform", isOpen && "rotate-180") })) : null] })) : null] }), isGroup && isOpen ? (jsxRuntime.jsx("ul", { id: submenuId, className: "mt-0.5 flex flex-col gap-0.5", children: children.map((child) => (jsxRuntime.jsx(MenuClawNavItem, { item: child, selectedKey: selectedKey, isCollapsed: isCollapsed, onSelect: onSelect, depth: depth + 1 }, child.key))) })) : null] }));
7267
7491
  };
7268
7492
  MenuClawNavItem.displayName = "MenuClawNavItem";
7269
7493
 
@@ -7376,9 +7600,9 @@ const MenuClaw = $8WNJc$react.memo(function MenuClaw({ userInfo, helpButton, men
7376
7600
  menuItems.onSelect?.(key, href, "bottomBar");
7377
7601
  }, [onOpenSidebarChange, menuItems.onSelect]);
7378
7602
  const showBottomBar = (mobileBottomBarGroupKey && bottomBarItems.length > 0) || showNativeMenu;
7379
- return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [showBottomBar ? (jsxRuntime.jsx(MenuMobileBottomBar, { items: bottomBarItems, selectedKey: selectedKey, onSelect: handleBottomBarSelect, onMenuPress: handleSidebarOpen, menuLabel: t.menuLabel, navAriaLabel: t.mobileNavAriaLabel, forceVisible: showNativeMenu && bottomBarItems.length === 0 })) : null, jsxRuntime.jsx("button", { type: "button", "aria-label": t.closeSidebarAriaLabel, className: `menu-claw-overlay ${isOpenSidebar ? "menu-claw-overlay--open" : ""}`, onClick: handleSidebarClose, tabIndex: isOpenSidebar ? 0 : -1 }), jsxRuntime.jsx("div", { className: react.cn("menu-claw", collapsed ? "menu-claw--collapsed" : "menu-claw--expanded", isOpenSidebar && "menu-claw--mobile-open"), "aria-hidden": !isOpenSidebar, children: jsxRuntime.jsxs("div", { className: "menu-claw__content", children: [jsxRuntime.jsxs("div", { className: react.cn("flex items-center", collapsed ? "justify-center" : "justify-end"), children: [jsxRuntime.jsx("button", { type: "button", "aria-label": t.closeSidebarAriaLabel, className: "menu-claw-header-button menu-claw-header-button--close-mobile", onClick: handleSidebarClose, children: jsxRuntime.jsx(IconComponent, { icon: "material-symbols-light:close", size: "lg", "aria-hidden": true }) }), jsxRuntime.jsx("button", { type: "button", "aria-label": t.toggleSidebarAriaLabel, "aria-expanded": !collapsed, onClick: handleCollapseToggle, className: "menu-claw-header-button menu-claw-header-button--collapse-toggle h-7 w-7 shrink-0 rounded-lg text-default-500 transition-colors hover:bg-default-100", children: jsxRuntime.jsx(IconComponent, { icon: collapsed
7603
+ return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [showBottomBar ? (jsxRuntime.jsx(MenuMobileBottomBar, { items: bottomBarItems, selectedKey: selectedKey, onSelect: handleBottomBarSelect, onMenuPress: handleSidebarOpen, menuLabel: t.menuLabel, navAriaLabel: t.mobileNavAriaLabel, forceVisible: showNativeMenu && bottomBarItems.length === 0 })) : null, jsxRuntime.jsx("button", { type: "button", "aria-label": t.closeSidebarAriaLabel, className: `menu-claw-overlay ${isOpenSidebar ? "menu-claw-overlay--open" : ""}`, onClick: handleSidebarClose, tabIndex: isOpenSidebar ? 0 : -1 }), jsxRuntime.jsx("div", { className: cn("menu-claw", collapsed ? "menu-claw--collapsed" : "menu-claw--expanded", isOpenSidebar && "menu-claw--mobile-open"), "aria-hidden": !isOpenSidebar, children: jsxRuntime.jsxs("div", { className: "menu-claw__content", children: [jsxRuntime.jsxs("div", { className: cn("flex items-center", collapsed ? "justify-center" : "justify-end"), children: [jsxRuntime.jsx("button", { type: "button", "aria-label": t.closeSidebarAriaLabel, className: "menu-claw-header-button menu-claw-header-button--close-mobile", onClick: handleSidebarClose, children: jsxRuntime.jsx(IconComponent, { icon: "material-symbols-light:close", size: "lg", "aria-hidden": true }) }), jsxRuntime.jsx("button", { type: "button", "aria-label": t.toggleSidebarAriaLabel, "aria-expanded": !collapsed, onClick: handleCollapseToggle, className: "menu-claw-header-button menu-claw-header-button--collapse-toggle h-7 w-7 shrink-0 rounded-lg text-default-500 transition-colors hover:bg-default-100", children: jsxRuntime.jsx(IconComponent, { icon: collapsed
7380
7604
  ? "solar:alt-arrow-right-linear"
7381
- : "solar:alt-arrow-left-linear", size: "md", "aria-hidden": true }) })] }), jsxRuntime.jsxs("div", { className: react.cn("flex items-center py-3", collapsed ? "justify-center gap-0" : "gap-3"), children: [jsxRuntime.jsxs(react.Avatar, { size: "sm", className: "shrink-0", children: [userInfo?.avatar?.trim() ? (jsxRuntime.jsx(react.Avatar.Image, { src: userInfo.avatar, alt: userName })) : null, jsxRuntime.jsx(react.Avatar.Fallback, { className: userInfo?.avatar?.trim()
7605
+ : "solar:alt-arrow-left-linear", size: "md", "aria-hidden": true }) })] }), jsxRuntime.jsxs("div", { className: cn("flex items-center py-3", collapsed ? "justify-center gap-0" : "gap-3"), children: [jsxRuntime.jsxs(react.Avatar, { size: "sm", className: "shrink-0", children: [userInfo?.avatar?.trim() ? (jsxRuntime.jsx(react.Avatar.Image, { src: userInfo.avatar, alt: userName })) : null, jsxRuntime.jsx(react.Avatar.Fallback, { className: userInfo?.avatar?.trim()
7382
7606
  ? undefined
7383
7607
  : "bg-warning text-warning-foreground", children: getUserInitials(userName) })] }), !collapsed ? (jsxRuntime.jsxs("div", { className: "menu-claw-collapsible flex min-w-0 flex-col overflow-hidden", children: [jsxRuntime.jsx("p", { className: "truncate text-sm font-semibold text-foreground", children: userName }), jsxRuntime.jsx("p", { className: "truncate text-xs text-default-400", children: userRole })] })) : null] }), jsxRuntime.jsx(MenuClawHistoryPanel, { items: historyConfig.items, initialVisibleCount: historyConfig.initialVisibleCount, onNewConversation: history?.onNewConversation, isCollapsed: collapsed, title: t.historyTitle, newLabel: t.historyNewLabel, showMoreLabel: t.historyShowMoreLabel, showLessLabel: t.historyShowLessLabel, onBeforeSelect: handleSidebarClose }), jsxRuntime.jsx("nav", { className: "flex min-h-0 flex-1 flex-col overflow-y-auto [&::-webkit-scrollbar]:hidden [-ms-overflow-style:none] [scrollbar-width:none]", children: menuItems.items.map((group) => (jsxRuntime.jsxs("div", { className: "mb-2", children: [group.title && !collapsed ? (jsxRuntime.jsx("p", { className: "px-2 pb-1 pt-2 text-xs font-medium uppercase tracking-wide text-default-400", children: group.title })) : null, jsxRuntime.jsx("ul", { className: "flex flex-col gap-0.5", children: (group.items ?? []).map((item) => (jsxRuntime.jsx(MenuClawNavItem, { item: item, selectedKey: selectedKey, isCollapsed: collapsed, onSelect: handleMenuSelect }, item.key))) })] }, group.key))) }), helpSection ? (jsxRuntime.jsx("div", { className: "mt-auto flex flex-col items-center justify-center", children: jsxRuntime.jsx(Button, { fullWidth: true,
7384
7608
  // TECH-2459 · G2 — la fachada propia de `Button` (D-G4-1) pinta
@@ -7542,7 +7766,7 @@ const StepIndicator = ({ currentStep, totalSteps, color = "primary", showStepTex
7542
7766
  const stepText = stepTextFormatter
7543
7767
  ? stepTextFormatter(currentStep, totalSteps)
7544
7768
  : defaultStepText(currentStep, totalSteps);
7545
- return (jsxRuntime.jsxs("div", { className: react.cn("w-full", className), ...props, children: [showStepText && (jsxRuntime.jsx("div", { className: "text-center text-sm font-medium text-default-400 mb-3", children: stepText })), jsxRuntime.jsx("div", { className: "w-full bg-content2 rounded-full h-2 overflow-hidden", children: jsxRuntime.jsx("div", { className: react.cn("h-full transition-all duration-300 ease-out rounded-full", colorClasses[color]), style: { width: `${progressPercentage}%` } }) })] }));
7769
+ return (jsxRuntime.jsxs("div", { className: cn("w-full", className), ...props, children: [showStepText && (jsxRuntime.jsx("div", { className: "text-center text-sm font-medium text-default-400 mb-3", children: stepText })), jsxRuntime.jsx("div", { className: "w-full bg-content2 rounded-full h-2 overflow-hidden", children: jsxRuntime.jsx("div", { className: cn("h-full transition-all duration-300 ease-out rounded-full", colorClasses[color]), style: { width: `${progressPercentage}%` } }) })] }));
7546
7770
  };
7547
7771
 
7548
7772
  /*
@@ -7665,7 +7889,7 @@ const VerticalSteps = $8WNJc$react.forwardRef(({ color = "primary", steps: steps
7665
7889
  ? color
7666
7890
  : "primary";
7667
7891
  const containerVars = $8WNJc$react.useMemo(() => getContainerCSSVars$1(stepColor), [stepColor]);
7668
- return (jsxRuntime.jsx("nav", { "aria-label": "Progress", className: "max-w-fit", children: jsxRuntime.jsx("ol", { "data-step-color": stepColor, className: react.cn("flex flex-col gap-y-3", className), style: containerVars, children: steps?.map((step, stepIdx) => {
7892
+ return (jsxRuntime.jsx("nav", { "aria-label": "Progress", className: "max-w-fit", children: jsxRuntime.jsx("ol", { "data-step-color": stepColor, className: cn("flex flex-col gap-y-3", className), style: containerVars, children: steps?.map((step, stepIdx) => {
7669
7893
  const status = currentStep === stepIdx
7670
7894
  ? "active"
7671
7895
  : stepIdx < currentStep || step.isCompleted
@@ -7674,13 +7898,13 @@ const VerticalSteps = $8WNJc$react.forwardRef(({ color = "primary", steps: steps
7674
7898
  const isDisabled = status === "inactive";
7675
7899
  return (
7676
7900
  // biome-ignore lint/suspicious/noArrayIndexKey: <explanation>
7677
- jsxRuntime.jsxs("li", { className: "relative", children: [jsxRuntime.jsx("div", { className: "flex w-full max-w-full items-center", children: jsxRuntime.jsxs("button", { type: "button", ref: ref, "aria-current": status === "active" ? "step" : undefined, className: react.cn(
7901
+ jsxRuntime.jsxs("li", { className: "relative", children: [jsxRuntime.jsx("div", { className: "flex w-full max-w-full items-center", children: jsxRuntime.jsxs("button", { type: "button", ref: ref, "aria-current": status === "active" ? "step" : undefined, className: cn(
7678
7902
  // TECH-2459 · G2 — `rounded-large` es clase muerta de v2;
7679
7903
  // mismo valor exacto (14px) que usa RADIUS_CLASS en
7680
7904
  // Button/Card de F3.0.
7681
7905
  "group rounded-[14px] flex w-full cursor-pointer items-center justify-center gap-4 px-3 py-2.5", stepClassName, {
7682
7906
  "cursor-not-allowed": isDisabled,
7683
- }), onClick: () => setCurrentStep(stepIdx), disabled: isDisabled, ...props, children: [jsxRuntime.jsx("div", { className: "flex h-full items-center", children: jsxRuntime.jsx("div", { className: "relative", children: jsxRuntime.jsx("div", { className: react.cn(
7907
+ }), onClick: () => setCurrentStep(stepIdx), disabled: isDisabled, ...props, children: [jsxRuntime.jsx("div", { className: "flex h-full items-center", children: jsxRuntime.jsx("div", { className: "relative", children: jsxRuntime.jsx("div", { className: cn(
7684
7908
  // TECH-2459 · G2 — clases muertas de v2:
7685
7909
  // border-medium=2px→border-2; text-large
7686
7910
  // (18/28px) coincide exacto con `text-lg`.
@@ -7688,24 +7912,24 @@ const VerticalSteps = $8WNJc$react.forwardRef(({ color = "primary", steps: steps
7688
7912
  "shadow-lg": status === "complete",
7689
7913
  }), "data-status": status, style: getCircleStyle$1(status), children: jsxRuntime.jsx("div", { className: "flex items-center justify-center", children: status === "complete" ? (jsxRuntime.jsx(IconComponent, { className: "font-bold", style: {
7690
7914
  color: "var(--active-fg-color)",
7691
- }, icon: "material-symbols:check-rounded", title: t.checkIconTitle })) : (jsxRuntime.jsx("span", { children: stepIdx + 1 })) }) }) }) }), jsxRuntime.jsx("div", { className: "flex-1 text-left", children: jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("div", { className: react.cn(
7915
+ }, icon: "material-symbols:check-rounded", title: t.checkIconTitle })) : (jsxRuntime.jsx("span", { children: stepIdx + 1 })) }) }) }) }), jsxRuntime.jsx("div", { className: "flex-1 text-left", children: jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("div", { className: cn(
7692
7916
  // `text-medium` es clase muerta de v2 → `text-base` (16px, mismo valor).
7693
7917
  "text-base text-default-600 font-medium transition-[color,opacity] duration-300 group-active:opacity-70", {
7694
7918
  "text-default-300": status ===
7695
7919
  "inactive",
7696
7920
  }), children: step.title }), (!hideInactiveDescriptions ||
7697
- status === "active") && (jsxRuntime.jsx("div", { className: react.cn(
7921
+ status === "active") && (jsxRuntime.jsx("div", { className: cn(
7698
7922
  // `text-tiny`/`text-small` son clases muertas de v2 →
7699
7923
  // `text-xs`/`text-sm` (mismo tamaño exacto, 12px/14px).
7700
7924
  "text-xs text-default-600 lg:text-sm transition-[color,opacity] duration-300 group-active:opacity-70", {
7701
7925
  "text-default-300": status ===
7702
7926
  "inactive",
7703
7927
  }), children: step.description }))] }) })] }, stepIdx) }), stepIdx < steps.length - 1 &&
7704
- !hideProgressBars && (jsxRuntime.jsx("div", { "aria-hidden": "true", className: react.cn("pointer-events-none absolute top-[calc(64px*var(--idx)+1)] left-3 flex h-1/2 -translate-y-1/3 items-center px-4", {
7928
+ !hideProgressBars && (jsxRuntime.jsx("div", { "aria-hidden": "true", className: cn("pointer-events-none absolute top-[calc(64px*var(--idx)+1)] left-3 flex h-1/2 -translate-y-1/3 items-center px-4", {
7705
7929
  "h-1/4": stepIdx === currentStep,
7706
7930
  }), style: {
7707
7931
  "--idx": stepIdx,
7708
- }, children: jsxRuntime.jsx("div", { className: react.cn("relative h-full w-0.5 bg-[var(--inactive-bar-color)] transition-colors duration-300", "after:absolute after:block after:h-0 after:w-full after:bg-[var(--active-border-color)] after:transition-[height] after:duration-300 after:content-['']", {
7932
+ }, children: jsxRuntime.jsx("div", { className: cn("relative h-full w-0.5 bg-[var(--inactive-bar-color)] transition-colors duration-300", "after:absolute after:block after:h-0 after:w-full after:bg-[var(--active-border-color)] after:transition-[height] after:duration-300 after:content-['']", {
7709
7933
  "after:h-full": stepIdx <
7710
7934
  currentStep,
7711
7935
  }) }) }))] }, stepIdx));
@@ -7722,7 +7946,7 @@ const MultiStepSidebar = $8WNJc$react.forwardRef(({ children, className, current
7722
7946
  onClose?.();
7723
7947
  }
7724
7948
  };
7725
- return (jsxRuntime.jsx("div", { ...containerProps, className: "fixed inset-0 z-50 flex items-center justify-center bg-content3/50 backdrop-blur-sm", onClick: handleOverlayClick, children: jsxRuntime.jsxs("div", { ref: ref, className: react.cn("relative flex h-full w-full max-w-4xl overflow-hidden rounded-lg bg-background shadow-lg lg:h-auto lg:max-h-[85vh] lg:min-h-[512px]", className), ...props, children: [jsxRuntime.jsx("div", { className: react.cn("multi-step-wizard__steps-panel absolute inset-y-0 left-0 w-1/3 flex-col justify-start gap-y-8 overflow-y-auto p-8 [&::-webkit-scrollbar]:hidden [-ms-overflow-style:none] [scrollbar-width:none]"), children: jsxRuntime.jsx(VerticalSteps, { className: "aura-stepper-theme", color: "primary", currentStep: currentPage, steps: steps, onStepChange: onChangePage, hideInactiveDescriptions: hideInactiveDescriptions }) }), jsxRuntime.jsxs("div", { className: "relative flex w-full flex-col items-center justify-between gap-4 md:ml-[33.333333%] md:w-2/3 md:p-4 min-h-0", children: [jsxRuntime.jsx(Button, { isIconOnly: true, ...dismissControlProps, "aria-label": closeTranslation, className: "absolute right-4 top-4", size: "sm", variant: "light", color: "default", onPress: onClose, startContent: jsxRuntime.jsx(IconComponent, { className: "text-foreground", icon: "material-symbols:close-rounded", size: "lg" }) }), jsxRuntime.jsx("div", { className: "pt-9 w-10/12 md:hidden", children: jsxRuntime.jsx("div", { className: "flex w-full justify-center", children: jsxRuntime.jsx(StepIndicator, { className: "aura-stepper-theme", currentStep: currentPage + 1, totalSteps: steps.length }) }) }), jsxRuntime.jsx("div", { className: "flex flex-col flex-1 w-full justify-between p-4 sm:max-w-md md:max-w-lg overflow-y-auto min-h-0 [&::-webkit-scrollbar]:hidden [-ms-overflow-style:none] [scrollbar-width:none]", children: children })] })] }) }));
7949
+ return (jsxRuntime.jsx("div", { ...containerProps, className: "fixed inset-0 z-50 flex items-center justify-center bg-content3/50 backdrop-blur-sm", onClick: handleOverlayClick, children: jsxRuntime.jsxs("div", { ref: ref, className: cn("relative flex h-full w-full max-w-4xl overflow-hidden rounded-lg bg-background shadow-lg lg:h-auto lg:max-h-[85vh] lg:min-h-[512px]", className), ...props, children: [jsxRuntime.jsx("div", { className: cn("multi-step-wizard__steps-panel absolute inset-y-0 left-0 w-1/3 flex-col justify-start gap-y-8 overflow-y-auto p-8 [&::-webkit-scrollbar]:hidden [-ms-overflow-style:none] [scrollbar-width:none]"), children: jsxRuntime.jsx(VerticalSteps, { className: "aura-stepper-theme", color: "primary", currentStep: currentPage, steps: steps, onStepChange: onChangePage, hideInactiveDescriptions: hideInactiveDescriptions }) }), jsxRuntime.jsxs("div", { className: "relative flex w-full flex-col items-center justify-between gap-4 md:ml-[33.333333%] md:w-2/3 md:p-4 min-h-0", children: [jsxRuntime.jsx(Button, { isIconOnly: true, ...dismissControlProps, "aria-label": closeTranslation, className: "absolute right-4 top-4", size: "sm", variant: "light", color: "default", onPress: onClose, startContent: jsxRuntime.jsx(IconComponent, { className: "text-foreground", icon: "material-symbols:close-rounded", size: "lg" }) }), jsxRuntime.jsx("div", { className: "pt-9 w-10/12 md:hidden", children: jsxRuntime.jsx("div", { className: "flex w-full justify-center", children: jsxRuntime.jsx(StepIndicator, { className: "aura-stepper-theme", currentStep: currentPage + 1, totalSteps: steps.length }) }) }), jsxRuntime.jsx("div", { className: "flex flex-col flex-1 w-full justify-between p-4 sm:max-w-md md:max-w-lg overflow-y-auto min-h-0 [&::-webkit-scrollbar]:hidden [-ms-overflow-style:none] [scrollbar-width:none]", children: children })] })] }) }));
7726
7950
  });
7727
7951
  MultiStepSidebar.displayName = "MultiStepSidebar";
7728
7952
 
@@ -7731,7 +7955,7 @@ const MultistepNavigationButtons = ({ nextButtonProps, cancelButtonProps, classN
7731
7955
  // backButtonProps || {};
7732
7956
  const { children: nextButtonChildren, ...restNextButtonProps } = nextButtonProps || {};
7733
7957
  const { children: cancelButtonChildren, ...restCancelButtonProps } = cancelButtonProps || {};
7734
- return (jsxRuntime.jsx("div", { className: react.cn("flex w-full flex-col-reverse gap-2 pt-4 sm:flex-row sm:justify-between md:justify-end", className), children: jsxRuntime.jsxs("div", { className: "flex w-full flex-col-reverse gap-2 md:w-auto md:flex-row", children: [jsxRuntime.jsx(Button, { className: "w-full md:w-auto", color: "default", variant: "flat", ...restCancelButtonProps, children: cancelButtonChildren || "Cancel" }), jsxRuntime.jsx(Button, { className: "w-full md:w-auto", color: "primary", ...restNextButtonProps, children: nextButtonChildren || "Next" })] }) }));
7958
+ return (jsxRuntime.jsx("div", { className: cn("flex w-full flex-col-reverse gap-2 pt-4 sm:flex-row sm:justify-between md:justify-end", className), children: jsxRuntime.jsxs("div", { className: "flex w-full flex-col-reverse gap-2 md:w-auto md:flex-row", children: [jsxRuntime.jsx(Button, { className: "w-full md:w-auto", color: "default", variant: "flat", ...restCancelButtonProps, children: cancelButtonChildren || "Cancel" }), jsxRuntime.jsx(Button, { className: "w-full md:w-auto", color: "primary", ...restNextButtonProps, children: nextButtonChildren || "Next" })] }) }));
7735
7959
  };
7736
7960
 
7737
7961
  const MultiStepWizard = ({ isOpen, steps, translations, onClose, onComplete, completeButtonText, hideInactiveDescriptions, isDismissable = true, }) => {
@@ -8253,17 +8477,17 @@ const RowSteps = $8WNJc$react.forwardRef(({ color = "primary", steps: stepsProp
8253
8477
  ? color
8254
8478
  : "primary";
8255
8479
  const containerVars = $8WNJc$react.useMemo(() => getContainerCSSVars(stepColor), [stepColor]);
8256
- return (jsxRuntime.jsx("nav", { "aria-label": "Progress", className: "-my-4 max-w-fit overflow-x-auto py-4", children: jsxRuntime.jsx("ol", { "data-step-color": stepColor, className: react.cn("flex flex-row flex-nowrap gap-x-3", className), style: containerVars, children: steps?.map((step, stepIdx) => {
8480
+ return (jsxRuntime.jsx("nav", { "aria-label": "Progress", className: "-my-4 max-w-fit overflow-x-auto py-4", children: jsxRuntime.jsx("ol", { "data-step-color": stepColor, className: cn("flex flex-row flex-nowrap gap-x-3", className), style: containerVars, children: steps?.map((step, stepIdx) => {
8257
8481
  const status = currentStep === stepIdx
8258
8482
  ? "active"
8259
8483
  : currentStep < stepIdx
8260
8484
  ? "inactive"
8261
8485
  : "complete";
8262
- return (jsxRuntime.jsx("li", { className: "relative flex w-full items-center pr-12 last:pr-0", children: jsxRuntime.jsxs("button", { type: "button", ref: ref, "aria-current": status === "active" ? "step" : undefined, className: react.cn(
8486
+ return (jsxRuntime.jsx("li", { className: "relative flex w-full items-center pr-12 last:pr-0", children: jsxRuntime.jsxs("button", { type: "button", ref: ref, "aria-current": status === "active" ? "step" : undefined, className: cn(
8263
8487
  // TECH-2459 · G2 — `rounded-large` es clase muerta (plugin
8264
8488
  // Tailwind propio de v2, v3 no lo trae). Mismo valor exacto
8265
8489
  // (14px) que usa RADIUS_CLASS en Button/Card de F3.0.
8266
- "group rounded-[14px] flex w-full cursor-pointer flex-row items-center justify-center gap-x-3 py-2.5", stepClassName), onClick: () => setCurrentStep(stepIdx), ...props, children: [jsxRuntime.jsx("div", { className: "h-ful relative flex items-center", children: jsxRuntime.jsx("div", { className: "relative", children: jsxRuntime.jsx("div", { className: react.cn(
8490
+ "group rounded-[14px] flex w-full cursor-pointer flex-row items-center justify-center gap-x-3 py-2.5", stepClassName), onClick: () => setCurrentStep(stepIdx), ...props, children: [jsxRuntime.jsx("div", { className: "h-ful relative flex items-center", children: jsxRuntime.jsx("div", { className: "relative", children: jsxRuntime.jsx("div", { className: cn(
8267
8491
  // TECH-2459 · G2 — `border-medium`/`text-large` son
8268
8492
  // clases muertas de v2 (tabla-mapeo-tokens.md §4):
8269
8493
  // border-medium=2px→border-2; text-large (18/28px)
@@ -8274,7 +8498,7 @@ const RowSteps = $8WNJc$react.forwardRef(({ color = "primary", steps: stepsProp
8274
8498
  "complete",
8275
8499
  }), "data-status": status, style: getCircleStyle(status), children: jsxRuntime.jsx("div", { className: "flex items-center justify-center", children: status === "complete" ? (jsxRuntime.jsx(IconComponent, { className: "font-bold", style: {
8276
8500
  color: "var(--active-fg-color)",
8277
- }, icon: "material-symbols:check-rounded" })) : (jsxRuntime.jsx("span", { children: stepIdx + 1 })) }) }) }) }), step.title && (jsxRuntime.jsx("div", { className: "max-w-full flex-1 text-start", children: jsxRuntime.jsx("div", { className: react.cn(
8501
+ }, icon: "material-symbols:check-rounded" })) : (jsxRuntime.jsx("span", { children: stepIdx + 1 })) }) }) }) }), step.title && (jsxRuntime.jsx("div", { className: "max-w-full flex-1 text-start", children: jsxRuntime.jsx("div", { className: cn(
8278
8502
  // `text-small`/`text-medium` son clases muertas de v2 →
8279
8503
  // `text-sm`/`text-base` (mismo tamaño exacto, 14px/16px).
8280
8504
  "text-sm text-default-600 lg:text-base font-medium transition-[color,opacity] duration-300 group-active:opacity-80", {
@@ -8283,7 +8507,7 @@ const RowSteps = $8WNJc$react.forwardRef(({ color = "primary", steps: stepsProp
8283
8507
  }), children: step.title }) })), stepIdx < steps.length - 1 &&
8284
8508
  !hideProgressBars && (jsxRuntime.jsx("div", { "aria-hidden": "true", className: "pointer-events-none absolute right-0 w-10 flex-none items-center", style: {
8285
8509
  "--idx": stepIdx,
8286
- }, children: jsxRuntime.jsx("div", { className: react.cn("relative h-0.5 w-full bg-[var(--inactive-bar-color)] transition-colors duration-300", "after:absolute after:block after:h-full after:w-0 after:bg-[var(--active-border-color)] after:transition-[width] after:duration-300 after:content-['']", {
8510
+ }, children: jsxRuntime.jsx("div", { className: cn("relative h-0.5 w-full bg-[var(--inactive-bar-color)] transition-colors duration-300", "after:absolute after:block after:h-full after:w-0 after:bg-[var(--active-border-color)] after:transition-[width] after:duration-300 after:content-['']", {
8287
8511
  "after:w-full": stepIdx <
8288
8512
  currentStep,
8289
8513
  }) }) }))] }, stepIdx) }, stepIdx));
@@ -9086,52 +9310,23 @@ const COLOR_VAR = {
9086
9310
  warning: "var(--warning)",
9087
9311
  danger: "var(--danger)",
9088
9312
  };
9089
- /*
9090
- * TECH-2459 · F5 (P6) — El Switch se queda con el ASPECTO DE v3, por decisión del usuario.
9091
- *
9092
- * Historia corta, porque este componente ha cambiado de criterio dos veces y conviene que no
9093
- * vuelva a moverse sin dato:
9094
- *
9095
- * · F3/G1 aceptó las medidas de v3 como cambio legítimo (P-23).
9096
- * · F5/R2 las revirtió a las de v2 con un argumento cuantitativo: el tamaño era el 74-77% de
9097
- * lo que quedaba de diferencia en `schedulerow--alineacion-semana` y el 100% de los 367 px
9098
- * de `edge-cases-testing` en oscuro.
9099
- * · Esta ronda las vuelve a v3 porque el usuario, mirando los dos Storybook uno al lado del
9100
- * otro, pidió expresamente el aspecto de v3 para este componente («al switch hay que
9101
- * dejarlo como se ve en la v3»). El contrato de la ronda es explícito en que v3 puede verse
9102
- * distinto y que eso está bien; aquí manda el criterio del usuario, no la cifra.
9103
- *
9104
- * Lo que eso significa, con los literales de los dos lados a la vista:
9105
- *
9106
- * pista v2 (`@heroui/theme@2.4.15`, `dist/components/toggle.js`, slot `wrapper`)
9107
- * sm 40×24 · md 48×28 · lg 56×32, `rounded-full`, `bg-default-200`
9108
- * v3 (`@heroui/styles/dist/components/switch.css`)
9109
- * sm 32×16 · md 40×20 · lg 48×24, `rounded-lg`/`rounded-xl`, `--default`
9110
- * thumb v2 círculo `bg-white` con `shadow-small`; sm 16 · md 20 · lg 24
9111
- * v3 rectángulo redondeado; sm 16,5×12 · md 22×16 · lg 27,5×20
9112
- *
9113
- * Ya no se pisa NADA de eso: la pista, el thumb, su radio, su color y su desplazamiento salen de
9114
- * v3. Por eso desaparecieron `TRACK_CLASS`, `THUMB_CLASS`, el `bg-white`/`shadow-small` del thumb
9115
- * y el `--switch-control-bg` que forzaba el gris apagado de v2 — y con ellos la clase `group`,
9116
- * que solo existía para que el thumb pudiera leer el `data-selected` de esta raíz.
9117
- *
9118
- * Lo que SÍ se conserva, y no es aspecto:
9119
- *
9120
- * · `--switch-control-bg-checked` (ver `COLOR_VAR`): sostiene la prop `color` de la API v2, que
9121
- * v3 eliminó. Sin ella `color="success"` y compañía dejarían de pintar. El valor de
9122
- * `primary` coincide con el de v3 (`--accent` = `--color-primary`), así que el aspecto por
9123
- * defecto es el de v3 igualmente.
9124
- * · `inline-flex flex-row items-center` en la raíz: es COLOCACIÓN, no aspecto del control. v3
9125
- * usa `flex flex-col items-start` para poder apilar `description`/`field-error`, slots que
9126
- * esta fachada no renderiza; al ser **inline**, la caja participa de la línea de texto, y eso
9127
- * es lo que la sitúa donde la esperan los consumidores (medido: 1px de diferencia en un
9128
- * contenedor de bloque, y `schedule-row` se apoya en ello). Dentro de un contenedor flex da
9129
- * igual: un ítem flex se blockifica.
9130
- *
9131
- * Consecuencia asumida: la referencia v2 de las stories con Switch deja de coincidir. Declarado
9132
- * como CAMBIO-V3 en `vrt/classification-overrides.json`, con las cifras en
9133
- * `.bewe/epics/TECH-2459/findings/p6-switch-aspecto-v3.md`.
9134
- */
9313
+ // Literales COMPLETOS (sin interpolar): Tailwind de las apps los descubre escaneando `dist`.
9314
+ const SIZE_CLASSES = {
9315
+ sm: {
9316
+ control: "h-6 w-10 rounded-full",
9317
+ thumb: "h-4 w-5 ms-1 rounded-full group-data-[selected=true]/switch:ms-[calc(100%-1.5rem)]",
9318
+ },
9319
+ md: {
9320
+ control: "h-7 w-12 rounded-full",
9321
+ thumb: "h-5 w-6 ms-1 rounded-full group-data-[selected=true]/switch:ms-[calc(100%-1.75rem)]",
9322
+ },
9323
+ lg: {
9324
+ control: "h-8 w-14 rounded-full",
9325
+ thumb: "h-6 w-7 ms-1 rounded-full group-data-[selected=true]/switch:ms-[calc(100%-2rem)]",
9326
+ },
9327
+ };
9328
+ // Thumb ENCENDIDO blanco en cualquier pack y con cualquier `color` (defecto 1 del bloque de arriba).
9329
+ const THUMB_ON_CLASS = "group-data-[selected=true]/switch:bg-white";
9135
9330
  // Los subcomponentes compound de v3, adjuntos como estáticos para que la API v3 siga funcionando a
9136
9331
  // través de la fachada (`<Switch><Switch.Content><Switch.Control><Switch.Thumb/>…`). `Root` se deja
9137
9332
  // FUERA a propósito (mismo criterio que `Alert` y `Checkbox`): la raíz de v3 es justo la pieza que
@@ -9158,12 +9353,32 @@ function hasCompoundChildren$2(children) {
9158
9353
  *
9159
9354
  * Dos modos, decididos por los `children`:
9160
9355
  * - **API v2** (`children` como label, `isSelected`/`defaultSelected`, `onValueChange`, `color`,
9161
- * `size`): la fachada compone `Switch.Content`/`Switch.Control`/`Switch.Thumb` por dentro y
9162
- * repone `color` pisando `--switch-control-bg-checked`.
9356
+ * `size`, `classNames`): la fachada compone `Switch.Content`/`Switch.Control`/`Switch.Thumb` por
9357
+ * dentro, repone `color` pisando `--switch-control-bg-checked`, aplica su escala de tamaños y el
9358
+ * thumb encendido blanco (ver el bloque de la cabecera).
9163
9359
  * - **API compound v3** (`<Switch><Switch.Content>…`): pasa los children tal cual a la raíz de
9164
- * HeroUI, sin geometría ni colocación propias.
9165
- */
9166
- const SwitchFacade = ({ id, size = "md", color, children, onChange, onValueChange, className, style, ...props }) => {
9360
+ * HeroUI, sin geometría ni colocación propias: ahí manda el JSX del consumidor.
9361
+ *
9362
+ * `classNames` (slots de v2 → nodo de v3; las clases de la app van al FINAL y ganan por `cn`):
9363
+ *
9364
+ * base → `Switch.Content`, la `<label>` que contiene la pista y la etiqueta: es el MISMO papel
9365
+ * que tenía `base` en v2 (una `<label>` con esos dos hijos directos, que la app
9366
+ * coloca con `flex-row-reverse justify-between`, y toda ella clicable). Pero la raíz
9367
+ * de v3 (`SwitchField`) la envuelve con una caja `inline-flex`, y un `w-full` de la
9368
+ * app se resolvería contra esa caja encogida. Así que con `base` la raíz pasa a
9369
+ * `display: contents` (se aparta de la maqueta) y `className` viaja con `base` a la
9370
+ * `<label>`, como en v2 (`cn(classNames.base, className)`). Lo único de la raíz que
9371
+ * `contents` pierde es la opacidad de `status-disabled` (el cursor y el
9372
+ * `pointer-events` se heredan; los tokens de color, también): se repone en la
9373
+ * `<label>` con su `data-disabled`. Medido en el navegador con el JSX de smbs: la
9374
+ * fila entera (390×52) conmuta, no solo el texto y la pista. Sin `base` no cambia
9375
+ * nada.
9376
+ * wrapper → la pista (`Switch.Control`).
9377
+ * thumb → el thumb (`Switch.Thumb`).
9378
+ * label → un `<span data-slot="label">` que envuelve los `children`; solo existe si se pasa
9379
+ * `classNames.label` (sin él los children siguen PELADOS, como hasta ahora).
9380
+ */
9381
+ const SwitchFacade = ({ id, size = "md", color, children, onChange, onValueChange, className, classNames, style, ...props }) => {
9167
9382
  const generatedId = $8WNJc$react.useId();
9168
9383
  const autoId = id || generatedId;
9169
9384
  const handleChange = (isSelected) => {
@@ -9183,6 +9398,10 @@ const SwitchFacade = ({ id, size = "md", color, children, onChange, onValueChang
9183
9398
  // a `status` también en compound). Sin `color`, el encendido es el `--accent` de v3.
9184
9399
  style: color === undefined ? style : colorStyle, onChange: handleChange, children: children }));
9185
9400
  }
9401
+ const sizeClasses = SIZE_CLASSES[size] ?? SIZE_CLASSES.md;
9402
+ // Con `classNames.base`, la `<label>` (`Switch.Content`) hace de `base` de v2 y la raíz se
9403
+ // aparta de la maqueta (ver `classNames` en el JSDoc de arriba).
9404
+ const hasBase = Boolean(classNames?.base);
9186
9405
  return (jsxRuntime.jsx(react.Switch, { ...props, id: autoId, size: size,
9187
9406
  // COLOCACIÓN, no aspecto (ver el bloque de arriba): v3 usa `flex flex-col items-start`
9188
9407
  // para poder apilar `description`/`field-error`, slots que esta fachada no renderiza.
@@ -9190,10 +9409,12 @@ const SwitchFacade = ({ id, size = "md", color, children, onChange, onValueChang
9190
9409
  // (Storybook centra con `#storybook-root` en `display: block`): con `flex` el widget cae
9191
9410
  // en y=346 y con `inline-flex` en y=345, donde lo esperan los consumidores. Dentro de un
9192
9411
  // contenedor flex (el uso real, p. ej. `schedule-row`) da igual: un ítem flex se
9193
- // blockifica.
9194
- className: ["inline-flex flex-row items-center", className]
9195
- .filter(Boolean)
9196
- .join(" "), style: colorStyle, onChange: handleChange, children: jsxRuntime.jsxs(react.Switch.Content, { children: [jsxRuntime.jsx(react.Switch.Control, { children: jsxRuntime.jsx(react.Switch.Thumb, {}) }), children] }) }));
9412
+ // blockifica. `group/switch`: de aquí lee el thumb el `data-selected`.
9413
+ className: hasBase
9414
+ ? "group/switch contents"
9415
+ : cn("group/switch inline-flex flex-row items-center", className), style: colorStyle, onChange: handleChange, children: jsxRuntime.jsxs(react.Switch.Content, { className: hasBase
9416
+ ? cn("data-[disabled=true]:opacity-(--disabled-opacity)", classNames?.base, className)
9417
+ : undefined, children: [jsxRuntime.jsx(react.Switch.Control, { className: cn(sizeClasses.control, classNames?.wrapper), children: jsxRuntime.jsx(react.Switch.Thumb, { className: cn(sizeClasses.thumb, THUMB_ON_CLASS, classNames?.thumb) }) }), classNames?.label && children != null ? (jsxRuntime.jsx("span", { "data-slot": "label", className: classNames.label, children: children })) : (children)] }) }));
9197
9418
  };
9198
9419
  SwitchFacade.displayName = "Aurora.Switch";
9199
9420
  /**
@@ -9363,7 +9584,7 @@ shouldForceLeadingZeros = true, startContent, endContent, ...props }) {
9363
9584
  // `cn` (tailwind-merge) y no una concatenación: el consumidor tiene que poder pisar la
9364
9585
  // colocación y el ancho (`ScheduleRow` pasa `w-full`). Todas las clases de aquí son
9365
9586
  // vocabulario v3 válido, así que tailwind-merge las resuelve bien.
9366
- className: react.cn(ROOT_CLASS[labelPlacement], className), shouldForceLeadingZeros: shouldForceLeadingZeros, ...props, children: [label && (jsxRuntime.jsx(react.Label, { className: LABEL_CLASS_BY_PLACEMENT[labelPlacement], children: label })), jsxRuntime.jsxs(react.TimeField.Group, { className: react.cn(FIELD_BORDER_CLASS, GROUP_SIZE_CLASS, FIELD_FOCUS_CLASS$2), children: [startContent !== undefined && startContent !== null && (jsxRuntime.jsx(react.TimeField.Prefix, { className: CONTENT_SLOT_CLASS, children: startContent })), jsxRuntime.jsx(react.TimeField.Input, { className: INPUT_CLASS, children: (segment) => (jsxRuntime.jsx(react.TimeField.Segment, { segment: segment, className: segment.type === "dayPeriod"
9587
+ className: cn(ROOT_CLASS[labelPlacement], className), shouldForceLeadingZeros: shouldForceLeadingZeros, ...props, children: [label && (jsxRuntime.jsx(react.Label, { className: LABEL_CLASS_BY_PLACEMENT[labelPlacement], children: label })), jsxRuntime.jsxs(react.TimeField.Group, { className: cn(FIELD_BORDER_CLASS, GROUP_SIZE_CLASS, FIELD_FOCUS_CLASS$2), children: [startContent !== undefined && startContent !== null && (jsxRuntime.jsx(react.TimeField.Prefix, { className: CONTENT_SLOT_CLASS, children: startContent })), jsxRuntime.jsx(react.TimeField.Input, { className: INPUT_CLASS, children: (segment) => (jsxRuntime.jsx(react.TimeField.Segment, { segment: segment, className: segment.type === "dayPeriod"
9367
9588
  ? DAY_PERIOD_SEGMENT_CLASS
9368
9589
  : undefined })) }), endContent !== undefined && endContent !== null && (jsxRuntime.jsx(react.TimeField.Suffix, { className: CONTENT_SLOT_CLASS, children: endContent }))] })] }));
9369
9590
  }
@@ -10229,7 +10450,7 @@ labelPlacement: _labelPlacement, scrollShadowProps, items, isSearchable = false,
10229
10450
  // Mismo criterio que el `group-data-[has-helper=true]` de v2: cuenta como "con ayuda" el campo
10230
10451
  // que efectivamente PINTA una descripción o un mensaje de error, no el que solo recibe la prop.
10231
10452
  const hasHelper = Boolean((description && !isInvalid) || (isInvalid && errorMessage));
10232
- const triggerClassName = react.cn(SIZE_CLASS[size], radius === "full" ? PADDING_FULL_CLASS[size] : PADDING_CLASS[size], TRIGGER_ALIGN_CLASS, isMultiline ? MULTILINE_TRIGGER_CLASS : "", RADIUS_CLASS$4[radius], VARIANT_CLASS$1[variant],
10453
+ const triggerClassName = cn(SIZE_CLASS[size], radius === "full" ? PADDING_FULL_CLASS[size] : PADDING_CLASS[size], TRIGGER_ALIGN_CLASS, isMultiline ? MULTILINE_TRIGGER_CLASS : "", RADIUS_CLASS$4[radius], VARIANT_CLASS$1[variant],
10233
10454
  // En v2 el estado inválido MANDABA también con el campo enfocado
10234
10455
  // (`group-data-[focus=true]:!border-danger`), así que el borde de foco no se aplica cuando
10235
10456
  // el campo está en error: se queda el `danger`.
@@ -10270,7 +10491,7 @@ labelPlacement: _labelPlacement, scrollShadowProps, items, isSearchable = false,
10270
10491
  // (`cn(classNames.listboxWrapper, scrollShadowProps.className)`, `chunk-YFRCT47S.mjs:
10271
10492
  // 321-331`), en ese orden.
10272
10493
  className: classNames?.listboxWrapper || scrollShadowProps?.className
10273
- ? react.cn(LISTBOX_SCROLL_CLASS, classNames?.listboxWrapper, scrollShadowProps?.className)
10494
+ ? cn(LISTBOX_SCROLL_CLASS, classNames?.listboxWrapper, scrollShadowProps?.className)
10274
10495
  : undefined, style: scrollShadowProps?.style,
10275
10496
  // El hueco que v2 llenaba con su `emptyContent` (ver el bloque de
10276
10497
  // `DEFAULT_TRANSLATIONS`). `renderEmptyState` es la vía de v3: el `ListBox` de
@@ -10285,7 +10506,7 @@ labelPlacement: _labelPlacement, scrollShadowProps, items, isSearchable = false,
10285
10506
  const ValuePart = usesAutocompleteShell
10286
10507
  ? react.Autocomplete.Value
10287
10508
  : react.Select.Value;
10288
- const triggerContent = (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [startContent != null && startContent !== false && (jsxRuntime.jsx("span", { "data-slot": "start-content", className: START_CONTENT_CLASS, children: startContent })), jsxRuntime.jsx(ValuePart, { className: react.cn(SIZE_TEXT_CLASS$1[size], isMultiline
10509
+ const triggerContent = (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [startContent != null && startContent !== false && (jsxRuntime.jsx("span", { "data-slot": "start-content", className: START_CONTENT_CLASS, children: startContent })), jsxRuntime.jsx(ValuePart, { className: cn(SIZE_TEXT_CLASS$1[size], isMultiline
10289
10510
  ? MULTILINE_VALUE_ROOM_CLASS
10290
10511
  : isClearable
10291
10512
  ? VALUE_ROOM_CLEARABLE_CLASS
@@ -10321,7 +10542,7 @@ labelPlacement: _labelPlacement, scrollShadowProps, items, isSearchable = false,
10321
10542
  acaba a 17px del borde derecho en la referencia y a 13px con el valor de v3 — 4px
10322
10543
  de más. */
10323
10544
  jsxRuntime.jsx(react.Select.Indicator, { className: "end-3" }))] }));
10324
- const inner = (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [label && (jsxRuntime.jsx(react.Label, { className: react.cn(LABEL_CLASS$1, hasHelper
10545
+ const inner = (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [label && (jsxRuntime.jsx(react.Label, { className: cn(LABEL_CLASS$1, hasHelper
10325
10546
  ? LABEL_OFFSET_HELPER_CLASS[size]
10326
10547
  : LABEL_OFFSET_CLASS[size], isInvalid ? INVALID_LABEL_CLASS$1 : "", classNames?.label), children: label })), usesAutocompleteShell ? (jsxRuntime.jsx(react.Autocomplete.Trigger, { className: triggerClassName, children: triggerContent })) : (jsxRuntime.jsx(react.Select.Trigger, { className: triggerClassName, children: triggerContent })), description && !isInvalid && (jsxRuntime.jsx(react.Description, { className: `${HELPER_CLASS$1} text-left`, children: description })), usesAutocompleteShell ? (jsxRuntime.jsx(react.Autocomplete.Popover, { className: classNames?.popoverContent, children: isSearchable ? (jsxRuntime.jsxs(react.Autocomplete.Filter, { filter: contains, inputValue: searchText, onInputChange: setSearchText, children: [jsxRuntime.jsx(react.SearchField, { autoFocus: true, "aria-label": resolvedSearchPlaceholder, fullWidth: true, children: jsxRuntime.jsxs(react.SearchField.Group, { className: SEARCH_GROUP_CLASS, children: [jsxRuntime.jsx(react.SearchField.SearchIcon, {}), jsxRuntime.jsx(react.SearchField.Input, { placeholder: resolvedSearchPlaceholder })] }) }), listBox] })) : (listBox) })) : (jsxRuntime.jsx(react.Select.Popover, { className: classNames?.popoverContent, children: listBox })), isInvalid && errorMessage && (jsxRuntime.jsx(react.FieldError, { className: `${HELPER_CLASS$1} text-left`, children: errorMessage }))] }));
10327
10548
  const commonProps = {
@@ -10366,7 +10587,7 @@ labelPlacement: _labelPlacement, scrollShadowProps, items, isSearchable = false,
10366
10587
  // v2 fusionaba: `useSelect` metía el `className` en `slots.base({ class: baseStyles })`
10367
10588
  // (`@heroui/select@2.4.22`, `dist/chunk-ONGPOZUT.mjs:171,202`) y el `tv` de v2 lleva
10368
10589
  // `twMerge: true` por defecto (`@heroui/theme@2.4.15`, `dist/utils/tv.js:56`).
10369
- className: react.cn(FIELD_STACK_CLASS$1[size],
10590
+ className: cn(FIELD_STACK_CLASS$1[size],
10370
10591
  // `w-full` y `min-w-40` son las dos ramas EXCLUYENTES de `fullWidth` en el `tv` de v2
10371
10592
  // (ver `ROOT_MIN_WIDTH_CLASS`).
10372
10593
  fullWidth ? "w-full" : ROOT_MIN_WIDTH_CLASS,
@@ -10684,7 +10905,7 @@ const CheckboxFacade = ({ children, onChange, onValueChange, color = "primary",
10684
10905
  onValueChange?.(isSelected);
10685
10906
  };
10686
10907
  if (hasCompoundChildren$1(children)) {
10687
- return (jsxRuntime.jsx(react.Checkbox, { ...rest, isInvalid: isInvalid, onChange: handleChange, className: react.cn(classNames?.base, className), children: children }));
10908
+ return (jsxRuntime.jsx(react.Checkbox, { ...rest, isInvalid: isInvalid, onChange: handleChange, className: cn(classNames?.base, className), children: children }));
10688
10909
  }
10689
10910
  const indicatorContent = typeof icon === "function"
10690
10911
  ? (state) => icon({
@@ -10700,13 +10921,13 @@ const CheckboxFacade = ({ children, onChange, onValueChange, color = "primary",
10700
10921
  // (`.checkbox`) usa `flex flex-col items-start` para apilar `Description`/`FieldError`,
10701
10922
  // slots que esta fachada no renderiza; en **inline** la caja participa de la línea de
10702
10923
  // texto, donde la esperan los consumidores (mismo criterio que la fachada `Switch`).
10703
- className: react.cn("group/checkbox relative -m-2 inline-flex max-w-fit flex-row items-center p-2", classNames?.base, className), children: jsxRuntime.jsxs(react.Checkbox.Content, { className: "group/content gap-2 font-normal", children: [jsxRuntime.jsx(react.Checkbox.Control, { className: react.cn(CONTROL_BASE, CONTROL_SIZE[size], RADIUS_CLASS$3[radius ?? RADIUS_BY_SIZE[size]], CONTROL_COLOR[color],
10924
+ className: cn("group/checkbox relative -m-2 inline-flex max-w-fit flex-row items-center p-2", classNames?.base, className), children: jsxRuntime.jsxs(react.Checkbox.Content, { className: "group/content gap-2 font-normal", children: [jsxRuntime.jsx(react.Checkbox.Control, { className: cn(CONTROL_BASE, CONTROL_SIZE[size], RADIUS_CLASS$3[radius ?? RADIUS_BY_SIZE[size]], CONTROL_COLOR[color],
10704
10925
  // v2 `isInvalid`: `before:border-danger` (el borde vivía en el pseudo).
10705
- isInvalid && "border-danger", disableAnimation && "transition-none before:transition-none", classNames?.wrapper), children: jsxRuntime.jsx(react.Checkbox.Indicator, { className: react.cn(INDICATOR_SIZE[size], INDICATOR_COLOR[color], disableAnimation && "[&_svg]:transition-none", classNames?.icon), children: indicatorContent }) }), hasLabel && (
10926
+ isInvalid && "border-danger", disableAnimation && "transition-none before:transition-none", classNames?.wrapper), children: jsxRuntime.jsx(react.Checkbox.Indicator, { className: cn(INDICATOR_SIZE[size], INDICATOR_COLOR[color], disableAnimation && "[&_svg]:transition-none", classNames?.icon), children: indicatorContent }) }), hasLabel && (
10706
10927
  // Slot `label` de v2: `relative text-foreground select-none` + tamaño de texto.
10707
10928
  // `data-slot="label"` para que las reglas de cursor/selección de `.checkbox` de v3
10708
10929
  // le alcancen igual que a un `<Label>`.
10709
- jsxRuntime.jsx("span", { "data-slot": "label", className: react.cn("relative select-none text-foreground", LABEL_SIZE[size], lineThrough && LINE_THROUGH, isInvalid && "text-danger", classNames?.label), children: children }))] }) }));
10930
+ jsxRuntime.jsx("span", { "data-slot": "label", className: cn("relative select-none text-foreground", LABEL_SIZE[size], lineThrough && LINE_THROUGH, isInvalid && "text-danger", classNames?.label), children: children }))] }) }));
10710
10931
  };
10711
10932
  CheckboxFacade.displayName = "Aurora.Checkbox";
10712
10933
  /**
@@ -10853,9 +11074,9 @@ function withSortIndicator(node) {
10853
11074
  /** Compone una clase sobre un `className` de react-aria, que puede ser string o render prop. */
10854
11075
  function withClass(className, extra) {
10855
11076
  if (typeof className === "function") {
10856
- return (renderProps) => react.cn(className(renderProps), extra);
11077
+ return (renderProps) => cn(className(renderProps), extra);
10857
11078
  }
10858
- return react.cn(className, extra);
11079
+ return cn(className, extra);
10859
11080
  }
10860
11081
  /**
10861
11082
  * `Table.Header`: indicador de orden en cada columna ordenable, clase sticky si se pidió y la
@@ -10919,6 +11140,46 @@ function transformBody(body) {
10919
11140
  return $8WNJc$react.cloneElement(body, undefined, ...spread(mapNodes(children, withSelectionCell)));
10920
11141
  }
10921
11142
 
11143
+ /**
11144
+ * TECH-2459 (beweossmbs, 24-sep: «Sessions history» de finanzas) — la celda del ESTADO VACÍO.
11145
+ *
11146
+ * En v3 `renderEmptyState` es un render prop de react-aria que pinta lo que devuelva dentro de
11147
+ * `<tbody data-empty="true"><tr role="row"><td role="rowheader" colspan>`
11148
+ * (`react-aria-components/dist/private/Table.mjs:886-915`), y ese `<td>` NO lleva `.table__cell`:
11149
+ * se queda sin el `bg-surface`, el padding ni el color de las celdas. Medido en la story
11150
+ * `EmptyState` con la cadena pelada que devuelven 12 de las 13 tablas de beweossmbs: 20 px de
11151
+ * alto, `padding: 0`, `text-align: start` (el texto pegado arriba a la izquierda) y fondo
11152
+ * transparente, o sea el gris de la raíz `table-root--primary` asomando.
11153
+ *
11154
+ * No es una regresión de la librería: ni la fachada ni `Table.Content` pintaron nunca ese estado
11155
+ * (`git log -S renderEmptyState|data-empty|emptyContent -- src/components/table` → 0 commits); lo
11156
+ * que se había arreglado era backoffice, en su propia app (TECH-2298, `49f2b35`: cada
11157
+ * `renderEmptyState` devuelve `<div className="flex h-40 items-center justify-center
11158
+ * text-default-500">`). Aquí se resuelve para todas las apps, en la única pieza por la que pasan
11159
+ * todas las tablas.
11160
+ *
11161
+ * Qué se le da a la celda, con tokens de v3 (no se busca la métrica de v2):
11162
+ * - `h-40`: aire. En una celda de tabla `height` actúa de alto MÍNIMO, así que un nodo propio más
11163
+ * alto sigue mandando, y uno de `h-40` como el de backoffice mide lo mismo (no se suma: por
11164
+ * eso es alto y no padding vertical).
11165
+ * - `px-4 text-center align-middle`: centrado en los dos ejes; `px-4` es el lateral de `.table__cell`.
11166
+ * - `text-sm text-default-500`: el cuerpo de las celdas de v3 (`text-sm`) en el gris atenuado que
11167
+ * ya usan las apps para este texto (backoffice), legible sobre el blanco (contraste AA).
11168
+ * - `bg-surface`: el fondo del cuerpo (`.table__cell` de `table.css`), no el gris de la raíz. Las
11169
+ * esquinas redondeadas ya las pone `table.css` (primera/última celda de la primera/última fila).
11170
+ *
11171
+ * Selector por `data-empty`, que react-aria solo escribe con el cuerpo vacío. Cadenas literales
11172
+ * completas: Tailwind solo emite lo que encuentra escrito entero.
11173
+ */
11174
+ const EMPTY_STATE_CLASS = [
11175
+ "[&>tbody[data-empty]>tr>td]:h-40",
11176
+ "[&>tbody[data-empty]>tr>td]:px-4",
11177
+ "[&>tbody[data-empty]>tr>td]:text-center",
11178
+ "[&>tbody[data-empty]>tr>td]:align-middle",
11179
+ "[&>tbody[data-empty]>tr>td]:text-sm",
11180
+ "[&>tbody[data-empty]>tr>td]:text-default-500",
11181
+ "[&>tbody[data-empty]>tr>td]:bg-surface",
11182
+ ].join(" ");
10922
11183
  /** Default de v2 (`use-table`, `@heroui/table@2.2.32`), sin reinterpretar. */
10923
11184
  function defaultShowCheckboxes(props) {
10924
11185
  const behavior = props.selectionBehavior ?? "toggle";
@@ -10961,7 +11222,8 @@ function TableContent({ children, isHeaderSticky, showSelectionCheckboxes, ...pr
10961
11222
  return child;
10962
11223
  });
10963
11224
  // Esparcido y no `{content}`: ver `spread` (un array como hijo único exigiría claves).
10964
- return $8WNJc$react.createElement(react.Table.Content, props, ...spread(content));
11225
+ // La clase del estado vacío va delante: la de la app, detrás, gana si pisa el mismo grupo.
11226
+ return $8WNJc$react.createElement(react.Table.Content, { ...props, className: cn(EMPTY_STATE_CLASS, props.className) }, ...spread(content));
10965
11227
  }
10966
11228
  TableContent.displayName = "Aurora.Table.Content";
10967
11229
 
@@ -10992,6 +11254,24 @@ function isPart$2(node, parts) {
10992
11254
  function withSticky(isHeaderSticky, root) {
10993
11255
  return isHeaderSticky === undefined ? (root) : (jsxRuntime.jsx(TableStickyContext.Provider, { value: isHeaderSticky, children: root }));
10994
11256
  }
11257
+ /**
11258
+ * TECH-2459 (beweossmbs, 24-sep) — barra de scroll NATIVA en el contenedor que inserta la fachada.
11259
+ *
11260
+ * `table.css:20` le aplica a `.table__scroll-container` la utilidad `scrollbar` de v3, que con los
11261
+ * tokens de `@heroui/styles` resuelve a `scrollbar-width: thin` y un pulgar al 15 % de opacidad
11262
+ * sobre carril transparente (medido en la story `Overflow`:
11263
+ * `oklch(0.2103 0.0059 285.89 / 0.15) rgba(0,0,0,0)`). Con barras clásicas (Windows, o macOS con
11264
+ * «mostrar barras: siempre») casi no se ve, y el usuario concluye que la tabla no tiene scroll
11265
+ * horizontal aunque lo tenga: es affordance, no estética. `scrollbar-default` (utilidad de la
11266
+ * propia v3, `utilities/index.css:71`) devuelve la barra del sistema; al ser capa `utilities`
11267
+ * gana a la regla de `components` sin `!important`.
11268
+ *
11269
+ * Solo en el contenedor que monta la fachada. Si la app monta su propio `Table.ScrollContainer`
11270
+ * (o un `ResizableContainer`), la fachada no toca nada y manda lo que la app escriba; y una clase
11271
+ * de la app sobre el root dirigida al contenedor (`[&_.table__scroll-container]:scrollbar-thin`)
11272
+ * gana por especificidad.
11273
+ */
11274
+ const SCROLL_CONTAINER_CLASS = "scrollbar-default";
10995
11275
  const TableFacade = ({ children, isHeaderSticky, ...props }) => {
10996
11276
  const nodes = $8WNJc$react.Children.toArray(children);
10997
11277
  // Sin hijos, o con un contenedor de scroll ya montado a mano: el root tal cual.
@@ -11000,7 +11280,7 @@ const TableFacade = ({ children, isHeaderSticky, ...props }) => {
11000
11280
  }
11001
11281
  const scrollable = nodes.filter((node) => !isPart$2(node, OUTSIDE_SCROLL));
11002
11282
  const outsideScroll = nodes.filter((node) => isPart$2(node, OUTSIDE_SCROLL));
11003
- return withSticky(isHeaderSticky, jsxRuntime.jsxs(react.Table, { ...props, children: [jsxRuntime.jsx(react.Table.ScrollContainer, { children: scrollable }), outsideScroll] }));
11283
+ return withSticky(isHeaderSticky, jsxRuntime.jsxs(react.Table, { ...props, children: [jsxRuntime.jsx(react.Table.ScrollContainer, { className: SCROLL_CONTAINER_CLASS, children: scrollable }), outsideScroll] }));
11004
11284
  };
11005
11285
  TableFacade.displayName = "Aurora.Table";
11006
11286
  /**
@@ -11625,7 +11905,7 @@ fullWidth = true, value, defaultValue, onChange, onValueChange, className, class
11625
11905
  onChange?.(event);
11626
11906
  onValueChange?.(event.target.value);
11627
11907
  };
11628
- const field = (jsxRuntime.jsx(react.TextArea, { ...rest, ref: setRefs, rows: fieldRows, style: fieldStyle, placeholder: placeholder, onChange: handleChange, onKeyDown: handleKeyDown, className: react.cn(SIZE_TEXT_CLASS[size], RESIZE_CLASS, RADIUS_CLASS$2[radius], VARIANT_CLASS[variant], isInvalid ? INVALID_TEXT_CLASS : "", FIELD_FOCUS_CLASS, FIELD_SHADOW_CLASS,
11908
+ const field = (jsxRuntime.jsx(react.TextArea, { ...rest, ref: setRefs, rows: fieldRows, style: fieldStyle, placeholder: placeholder, onChange: handleChange, onKeyDown: handleKeyDown, className: cn(SIZE_TEXT_CLASS[size], RESIZE_CLASS, RADIUS_CLASS$2[radius], VARIANT_CLASS[variant], isInvalid ? INVALID_TEXT_CLASS : "", FIELD_FOCUS_CLASS, FIELD_SHADOW_CLASS,
11629
11909
  // Incondicional, como el slot `input` de v2: el campo llena siempre su raíz,
11630
11910
  // y es la raíz la que responde a `fullWidth` y al ancho del consumidor.
11631
11911
  "w-full", isClearable ? CLEARABLE_FIELD_CLASS : "", classNames?.input ?? classNames?.inputWrapper) }));
@@ -11645,10 +11925,10 @@ fullWidth = true, value, defaultValue, onChange, onValueChange, className, class
11645
11925
  // es suyo (`useFormReset` devuelve el estado al `defaultValue`; el autosize lo escucha).
11646
11926
  jsxRuntime.jsxs(react.TextField, { id: textareaId, value: ownsValue ? ownValue : value, defaultValue: ownsValue ? undefined : defaultValue,
11647
11927
  // Solo cuando la fachada es dueña del valor (limpiable y no controlado).
11648
- onChange: ownsValue ? setOwnValue : undefined, name: name, isInvalid: isInvalid, isRequired: isRequired, isDisabled: isDisabled, isReadOnly: isReadOnly, className: react.cn(FIELD_STACK_CLASS, fullWidth ? "w-full" : "",
11928
+ onChange: ownsValue ? setOwnValue : undefined, name: name, isInvalid: isInvalid, isRequired: isRequired, isDisabled: isDisabled, isReadOnly: isReadOnly, className: cn(FIELD_STACK_CLASS, fullWidth ? "w-full" : "",
11649
11929
  // El `className` del consumidor, en la raíz y en último lugar: el slot `base` de
11650
11930
  // v2 y la posición que le deja ganar en tailwind-merge (ver bloque de arriba).
11651
- className), children: [label && (jsxRuntime.jsx(react.Label, { className: react.cn(LABEL_CLASS, isInvalid ? INVALID_LABEL_CLASS : "", classNames?.label), children: label })), isClearable ? (jsxRuntime.jsxs("div", { className: CLEAR_WRAPPER_CLASS, children: [field, showClear && (jsxRuntime.jsx(react.CloseButton, { "aria-label": "Limpiar", className: react.cn(CLEAR_BUTTON_CLASS, classNames?.clearButton), onPress: handleClear }))] })) : (field), description && !isInvalid && (jsxRuntime.jsx(react.Description, { className: react.cn(HELPER_CLASS, "text-left", classNames?.description), children: description })), isInvalid && errorMessage && (jsxRuntime.jsx(react.FieldError, { className: react.cn(HELPER_CLASS, "text-left", classNames?.errorMessage), children: errorMessage }))] }));
11931
+ className), children: [label && (jsxRuntime.jsx(react.Label, { className: cn(LABEL_CLASS, isInvalid ? INVALID_LABEL_CLASS : "", classNames?.label), children: label })), isClearable ? (jsxRuntime.jsxs("div", { className: CLEAR_WRAPPER_CLASS, children: [field, showClear && (jsxRuntime.jsx(react.CloseButton, { "aria-label": "Limpiar", className: cn(CLEAR_BUTTON_CLASS, classNames?.clearButton), onPress: handleClear }))] })) : (field), description && !isInvalid && (jsxRuntime.jsx(react.Description, { className: cn(HELPER_CLASS, "text-left", classNames?.description), children: description })), isInvalid && errorMessage && (jsxRuntime.jsx(react.FieldError, { className: cn(HELPER_CLASS, "text-left", classNames?.errorMessage), children: errorMessage }))] }));
11652
11932
  });
11653
11933
  Textarea.displayName = "Textarea";
11654
11934
 
@@ -11798,7 +12078,7 @@ function GlobalToast({ translations = {} } = {}) {
11798
12078
  const slots = react.toastVariants({ placement: "top end", variant });
11799
12079
  const isSecondary = color === "secondary";
11800
12080
  const StatusIcon = ICON_BY_VARIANT[variant];
11801
- return (jsxRuntime.jsx("div", { className: "fixed top-4 right-4 z-[2000] w-full max-w-sm", children: jsxRuntime.jsxs("div", { className: react.cn(slots.toast(), "gap-x-0 rounded-[12px]", SURFACE_BY_COLOR[color]), "data-frontmost": "true", style: { position: "relative" }, children: [jsxRuntime.jsx("div", { className: react.cn(slots.indicator(), INDICATOR_BASE, ICON_BY_COLOR[color]), children: jsxRuntime.jsx(StatusIcon, {}) }), jsxRuntime.jsxs("div", { className: react.cn(slots.content(), "ms-2 box-border min-h-10 justify-center"), children: [jsxRuntime.jsx("div", { className: slots.title(), style: isSecondary ? { color: "var(--color-secondary-600)" } : undefined, children: toast.title }), toast.description && (jsxRuntime.jsx("div", { className: slots.description(), children: toast.description }))] }), jsxRuntime.jsx(react.CloseButton, { "aria-label": t.closeButtonAriaLabel, className: react.cn("shrink-0 self-center bg-transparent", CLOSE_BY_COLOR[color]), onPress: hideToast })] }) }));
12081
+ return (jsxRuntime.jsx("div", { className: "fixed top-4 right-4 z-[2000] w-full max-w-sm", children: jsxRuntime.jsxs("div", { className: cn(slots.toast(), "gap-x-0 rounded-[12px]", SURFACE_BY_COLOR[color]), "data-frontmost": "true", style: { position: "relative" }, children: [jsxRuntime.jsx("div", { className: cn(slots.indicator(), INDICATOR_BASE, ICON_BY_COLOR[color]), children: jsxRuntime.jsx(StatusIcon, {}) }), jsxRuntime.jsxs("div", { className: cn(slots.content(), "ms-2 box-border min-h-10 justify-center"), children: [jsxRuntime.jsx("div", { className: slots.title(), style: isSecondary ? { color: "var(--color-secondary-600)" } : undefined, children: toast.title }), toast.description && (jsxRuntime.jsx("div", { className: slots.description(), children: toast.description }))] }), jsxRuntime.jsx(react.CloseButton, { "aria-label": t.closeButtonAriaLabel, className: cn("shrink-0 self-center bg-transparent", CLOSE_BY_COLOR[color]), onPress: hideToast })] }) }));
11802
12082
  }
11803
12083
 
11804
12084
  /**
@@ -13405,111 +13685,6 @@ const DrawerFiltersHeader = ({ titleId, title, description, }) => {
13405
13685
  return (jsxRuntime.jsxs("div", { className: "px-6 pt-10", children: [jsxRuntime.jsx(H2, { id: titleId, className: "text-xl font-semibold text-foreground mb-2", children: title }), jsxRuntime.jsx(P, { className: "text-default-500", children: description })] }));
13406
13686
  };
13407
13687
 
13408
- const NO_YEAR_CLASS = "[&_[data-type='year']]:hidden [&_[data-type='literal']:has(+[data-type='year'])]:hidden";
13409
- // Year used to construct CalendarDate values. React Aria's onChange only fires when
13410
- // ALL segments (including hidden year) are user-confirmed. Since users can't type year
13411
- // (it's CSS-hidden), we read month+day directly from the DOM via data-placeholder
13412
- // attributes when the picker loses focus, bypassing the year-confirmation requirement.
13413
- const FILLER_YEAR = new Date().getFullYear();
13414
- /**
13415
- * Reads month and day from segment DOM elements.
13416
- * Returns null if any segment is still in placeholder state (user hasn't typed it yet).
13417
- * React Aria marks unconfirmed segments with data-placeholder="true".
13418
- */
13419
- function readConfirmedMonthDay(container, monthSelector = '[data-type="month"]', daySelector = '[data-type="day"]') {
13420
- const monthEl = container.querySelector(monthSelector);
13421
- const dayEl = container.querySelector(daySelector);
13422
- if (!monthEl || !dayEl)
13423
- return null;
13424
- if (monthEl.getAttribute("data-placeholder") === "true")
13425
- return null;
13426
- if (dayEl.getAttribute("data-placeholder") === "true")
13427
- return null;
13428
- const month = Number(monthEl.getAttribute("aria-valuenow"));
13429
- const day = Number(dayEl.getAttribute("aria-valuenow"));
13430
- if (month >= 1 && month <= 12 && day >= 1 && day <= 31)
13431
- return { month, day };
13432
- return null;
13433
- }
13434
- const DayMonthPicker = ({ value, onChange, translations, }) => {
13435
- const t = {
13436
- dayMonthAriaLabel: "Seleccionar mes y día",
13437
- dayMonthRangeAriaLabel: "Seleccionar rango de mes y día",
13438
- dayMonthSingleOption: "Día específico",
13439
- dayMonthRangeOption: "Rango de fechas",
13440
- ...translations,
13441
- };
13442
- const [mode, setMode] = $8WNJc$react.useState(value?.type === "dayMonthRange" ? "range" : "single");
13443
- $8WNJc$react.useEffect(() => {
13444
- setMode(value?.type === "dayMonthRange" ? "range" : "single");
13445
- }, [value?.type]);
13446
- const pickerValue = value?.type === "dayMonth" ? value.dayMonth : null;
13447
- const rangeValue = value?.type === "dayMonthRange" ? value.dayMonthRange : null;
13448
- // Refs to DOM wrappers — used by the DOM-reading fallback for manual input.
13449
- const singleRef = $8WNJc$react.useRef(null);
13450
- const rangeRef = $8WNJc$react.useRef(null);
13451
- // Stable refs so focus-change callbacks always read current values without
13452
- // needing to be recreated on every render.
13453
- const pickerValueRef = $8WNJc$react.useRef(pickerValue);
13454
- pickerValueRef.current = pickerValue;
13455
- const rangeValueRef = $8WNJc$react.useRef(rangeValue);
13456
- rangeValueRef.current = rangeValue;
13457
- const handleModeChange = (newMode) => {
13458
- const nextMode = newMode === "range" ? "range" : "single";
13459
- setMode(nextMode);
13460
- if (nextMode === "single") {
13461
- onChange({ type: "dayMonth", dayMonth: null, dayMonthRange: null });
13462
- return;
13463
- }
13464
- onChange({ type: "dayMonthRange", dayMonth: null, dayMonthRange: null });
13465
- };
13466
- const handleSingleChange = (date) => {
13467
- onChange({ type: "dayMonth", dayMonth: date, dayMonthRange: null });
13468
- };
13469
- const handleRangeChange = (range) => {
13470
- onChange({ type: "dayMonthRange", dayMonth: null, dayMonthRange: range });
13471
- };
13472
- // Called by React Aria when the DatePicker gains/loses focus.
13473
- // When value=null (placeholder mode) React Aria never fires onChange because the
13474
- // hidden year segment is never user-confirmed. On blur we read the confirmed
13475
- // month/day directly from the DOM as a workaround.
13476
- const handleSingleFocusChange = (isFocused) => {
13477
- if (isFocused || pickerValueRef.current)
13478
- return;
13479
- if (!singleRef.current)
13480
- return;
13481
- const result = readConfirmedMonthDay(singleRef.current);
13482
- if (result) {
13483
- handleSingleChange(new $2aaf608024c21ca1$export$99faa760c7908e4f(FILLER_YEAR, result.month, result.day));
13484
- }
13485
- };
13486
- const handleRangeFocusChange = (isFocused) => {
13487
- if (isFocused || rangeValueRef.current)
13488
- return;
13489
- if (!rangeRef.current)
13490
- return;
13491
- const monthEls = rangeRef.current.querySelectorAll('[data-type="month"]');
13492
- const dayEls = rangeRef.current.querySelectorAll('[data-type="day"]');
13493
- if (monthEls.length < 2 || dayEls.length < 2)
13494
- return;
13495
- const allConfirmed = [...monthEls, ...dayEls].every((el) => el.getAttribute("data-placeholder") !== "true");
13496
- if (!allConfirmed)
13497
- return;
13498
- const startMonth = Number(monthEls[0].getAttribute("aria-valuenow"));
13499
- const startDay = Number(dayEls[0].getAttribute("aria-valuenow"));
13500
- const endMonth = Number(monthEls[1].getAttribute("aria-valuenow"));
13501
- const endDay = Number(dayEls[1].getAttribute("aria-valuenow"));
13502
- const valid = (m, d) => m >= 1 && m <= 12 && d >= 1 && d <= 31;
13503
- if (valid(startMonth, startDay) && valid(endMonth, endDay)) {
13504
- handleRangeChange({
13505
- start: new $2aaf608024c21ca1$export$99faa760c7908e4f(FILLER_YEAR, startMonth, startDay),
13506
- end: new $2aaf608024c21ca1$export$99faa760c7908e4f(FILLER_YEAR, endMonth, endDay),
13507
- });
13508
- }
13509
- };
13510
- return (jsxRuntime.jsxs("div", { className: "w-full flex flex-wrap xs:gap-5 justify-between items-center", children: [jsxRuntime.jsxs(react.RadioGroup, { orientation: "horizontal", value: mode, onChange: handleModeChange, children: [jsxRuntime.jsx(react.Radio, { value: "single", children: jsxRuntime.jsxs(react.Radio.Content, { children: [jsxRuntime.jsx(react.Radio.Control, { children: jsxRuntime.jsx(react.Radio.Indicator, {}) }), t.dayMonthSingleOption] }) }), jsxRuntime.jsx(react.Radio, { value: "range", children: jsxRuntime.jsxs(react.Radio.Content, { children: [jsxRuntime.jsx(react.Radio.Control, { children: jsxRuntime.jsx(react.Radio.Indicator, {}) }), t.dayMonthRangeOption] }) })] }), mode === "single" ? (jsxRuntime.jsx("div", { ref: singleRef, children: jsxRuntime.jsx(DatePicker, { value: pickerValue, onChange: handleSingleChange, onFocusChange: handleSingleFocusChange, "aria-label": t.dayMonthAriaLabel, endContent: jsxRuntime.jsx(IconComponent, { icon: "solar:calendar-outline" }), className: `w-full md:w-auto md:max-w-40 ${NO_YEAR_CLASS}` }, "dmp") })) : (jsxRuntime.jsx("div", { ref: rangeRef, children: jsxRuntime.jsx(DateRangePicker, { value: rangeValue, onChange: handleRangeChange, onFocusChange: handleRangeFocusChange, "aria-label": t.dayMonthRangeAriaLabel, endContent: jsxRuntime.jsx(IconComponent, { icon: "solar:calendar-outline" }), className: `w-full md:w-auto md:max-w-xs ${NO_YEAR_CLASS}` }, "dmpr") }))] }));
13511
- };
13512
-
13513
13688
  /**
13514
13689
  * Las cuatro props de slider que v2 tenía y v3 eliminó, traducidas a clases. Los valores son los
13515
13690
  * LITERALES del `tv` de v2 (`npm pack @heroui/theme@2.4.15` → `dist/components/slider.js`), no
@@ -13643,7 +13818,113 @@ const RangeFilter = ({ title, description, value, onChange, minValue, maxValue,
13643
13818
  const [min, max] = newValue;
13644
13819
  setCurrentValue([min, max]);
13645
13820
  onChange([min, max]);
13646
- }, className: "w-full", isDisabled: false, ...restSliderProps, children: jsxRuntime.jsxs(react.Slider.Track, { children: [jsxRuntime.jsx(react.Slider.Fill, { className: fillClassName }), stepMarks.length > 0 ? (jsxRuntime.jsx(react.Slider.Marks, { children: stepMarks.map((left) => (jsxRuntime.jsx("span", { className: SLIDER_STEP_CLASS, style: { left: `${left}%` } }, left))) })) : null, jsxRuntime.jsx(react.Slider.Thumb, { index: 0, "aria-label": t.minLabel, className: thumbClassName }), jsxRuntime.jsx(react.Slider.Thumb, { index: 1, "aria-label": t.maxLabel, className: thumbClassName })] }) }) }), jsxRuntime.jsxs("div", { className: "flex justify-between items-center text-sm", children: [jsxRuntime.jsxs("div", { className: "flex flex-col items-start", children: [jsxRuntime.jsx("span", { className: "text-xs text-default-500", children: t.minLabel }), jsxRuntime.jsx("span", { className: "font-medium text-default-700", children: formatValue(currentValue[0]) })] }), jsxRuntime.jsxs("div", { className: "flex flex-col items-end", children: [jsxRuntime.jsx("span", { className: "text-xs text-default-500", children: t.maxLabel }), jsxRuntime.jsx("span", { className: "font-medium text-default-700", children: formatValue(currentValue[1]) })] })] })] }));
13821
+ }, className: "w-full", isDisabled: false, "aria-label": restSliderProps["aria-label"] ??
13822
+ (restSliderProps["aria-labelledby"] ? undefined : t.title), ...restSliderProps, children: jsxRuntime.jsxs(react.Slider.Track, { children: [jsxRuntime.jsx(react.Slider.Fill, { className: fillClassName }), stepMarks.length > 0 ? (jsxRuntime.jsx(react.Slider.Marks, { children: stepMarks.map((left) => (jsxRuntime.jsx("span", { className: SLIDER_STEP_CLASS, style: { left: `${left}%` } }, left))) })) : null, jsxRuntime.jsx(react.Slider.Thumb, { index: 0, "aria-label": t.minLabel, className: thumbClassName }), jsxRuntime.jsx(react.Slider.Thumb, { index: 1, "aria-label": t.maxLabel, className: thumbClassName })] }) }) }), jsxRuntime.jsxs("div", { className: "flex justify-between items-center text-sm", children: [jsxRuntime.jsxs("div", { className: "flex flex-col items-start", children: [jsxRuntime.jsx("span", { className: "text-xs text-default-500", children: t.minLabel }), jsxRuntime.jsx("span", { className: "font-medium text-default-700", children: formatValue(currentValue[0]) })] }), jsxRuntime.jsxs("div", { className: "flex flex-col items-end", children: [jsxRuntime.jsx("span", { className: "text-xs text-default-500", children: t.maxLabel }), jsxRuntime.jsx("span", { className: "font-medium text-default-700", children: formatValue(currentValue[1]) })] })] })] }));
13823
+ };
13824
+
13825
+ const NO_YEAR_CLASS = "[&_[data-type='year']]:hidden [&_[data-type='literal']:has(+[data-type='year'])]:hidden";
13826
+ // Year used to construct CalendarDate values. React Aria's onChange only fires when
13827
+ // ALL segments (including hidden year) are user-confirmed. Since users can't type year
13828
+ // (it's CSS-hidden), we read month+day directly from the DOM via data-placeholder
13829
+ // attributes when the picker loses focus, bypassing the year-confirmation requirement.
13830
+ const FILLER_YEAR = new Date().getFullYear();
13831
+ /**
13832
+ * Reads month and day from segment DOM elements.
13833
+ * Returns null if any segment is still in placeholder state (user hasn't typed it yet).
13834
+ * React Aria marks unconfirmed segments with data-placeholder="true".
13835
+ */
13836
+ function readConfirmedMonthDay(container, monthSelector = '[data-type="month"]', daySelector = '[data-type="day"]') {
13837
+ const monthEl = container.querySelector(monthSelector);
13838
+ const dayEl = container.querySelector(daySelector);
13839
+ if (!monthEl || !dayEl)
13840
+ return null;
13841
+ if (monthEl.getAttribute("data-placeholder") === "true")
13842
+ return null;
13843
+ if (dayEl.getAttribute("data-placeholder") === "true")
13844
+ return null;
13845
+ const month = Number(monthEl.getAttribute("aria-valuenow"));
13846
+ const day = Number(dayEl.getAttribute("aria-valuenow"));
13847
+ if (month >= 1 && month <= 12 && day >= 1 && day <= 31)
13848
+ return { month, day };
13849
+ return null;
13850
+ }
13851
+ const DayMonthPicker = ({ value, onChange, translations, ariaLabelledBy, }) => {
13852
+ const t = {
13853
+ dayMonthAriaLabel: "Seleccionar mes y día",
13854
+ dayMonthRangeAriaLabel: "Seleccionar rango de mes y día",
13855
+ dayMonthSingleOption: "Día específico",
13856
+ dayMonthRangeOption: "Rango de fechas",
13857
+ ...translations,
13858
+ };
13859
+ const [mode, setMode] = $8WNJc$react.useState(value?.type === "dayMonthRange" ? "range" : "single");
13860
+ $8WNJc$react.useEffect(() => {
13861
+ setMode(value?.type === "dayMonthRange" ? "range" : "single");
13862
+ }, [value?.type]);
13863
+ const pickerValue = value?.type === "dayMonth" ? value.dayMonth : null;
13864
+ const rangeValue = value?.type === "dayMonthRange" ? value.dayMonthRange : null;
13865
+ // Refs to DOM wrappers — used by the DOM-reading fallback for manual input.
13866
+ const singleRef = $8WNJc$react.useRef(null);
13867
+ const rangeRef = $8WNJc$react.useRef(null);
13868
+ // Stable refs so focus-change callbacks always read current values without
13869
+ // needing to be recreated on every render.
13870
+ const pickerValueRef = $8WNJc$react.useRef(pickerValue);
13871
+ pickerValueRef.current = pickerValue;
13872
+ const rangeValueRef = $8WNJc$react.useRef(rangeValue);
13873
+ rangeValueRef.current = rangeValue;
13874
+ const handleModeChange = (newMode) => {
13875
+ const nextMode = newMode === "range" ? "range" : "single";
13876
+ setMode(nextMode);
13877
+ if (nextMode === "single") {
13878
+ onChange({ type: "dayMonth", dayMonth: null, dayMonthRange: null });
13879
+ return;
13880
+ }
13881
+ onChange({ type: "dayMonthRange", dayMonth: null, dayMonthRange: null });
13882
+ };
13883
+ const handleSingleChange = (date) => {
13884
+ onChange({ type: "dayMonth", dayMonth: date, dayMonthRange: null });
13885
+ };
13886
+ const handleRangeChange = (range) => {
13887
+ onChange({ type: "dayMonthRange", dayMonth: null, dayMonthRange: range });
13888
+ };
13889
+ // Called by React Aria when the DatePicker gains/loses focus.
13890
+ // When value=null (placeholder mode) React Aria never fires onChange because the
13891
+ // hidden year segment is never user-confirmed. On blur we read the confirmed
13892
+ // month/day directly from the DOM as a workaround.
13893
+ const handleSingleFocusChange = (isFocused) => {
13894
+ if (isFocused || pickerValueRef.current)
13895
+ return;
13896
+ if (!singleRef.current)
13897
+ return;
13898
+ const result = readConfirmedMonthDay(singleRef.current);
13899
+ if (result) {
13900
+ handleSingleChange(new $2aaf608024c21ca1$export$99faa760c7908e4f(FILLER_YEAR, result.month, result.day));
13901
+ }
13902
+ };
13903
+ const handleRangeFocusChange = (isFocused) => {
13904
+ if (isFocused || rangeValueRef.current)
13905
+ return;
13906
+ if (!rangeRef.current)
13907
+ return;
13908
+ const monthEls = rangeRef.current.querySelectorAll('[data-type="month"]');
13909
+ const dayEls = rangeRef.current.querySelectorAll('[data-type="day"]');
13910
+ if (monthEls.length < 2 || dayEls.length < 2)
13911
+ return;
13912
+ const allConfirmed = [...monthEls, ...dayEls].every((el) => el.getAttribute("data-placeholder") !== "true");
13913
+ if (!allConfirmed)
13914
+ return;
13915
+ const startMonth = Number(monthEls[0].getAttribute("aria-valuenow"));
13916
+ const startDay = Number(dayEls[0].getAttribute("aria-valuenow"));
13917
+ const endMonth = Number(monthEls[1].getAttribute("aria-valuenow"));
13918
+ const endDay = Number(dayEls[1].getAttribute("aria-valuenow"));
13919
+ const valid = (m, d) => m >= 1 && m <= 12 && d >= 1 && d <= 31;
13920
+ if (valid(startMonth, startDay) && valid(endMonth, endDay)) {
13921
+ handleRangeChange({
13922
+ start: new $2aaf608024c21ca1$export$99faa760c7908e4f(FILLER_YEAR, startMonth, startDay),
13923
+ end: new $2aaf608024c21ca1$export$99faa760c7908e4f(FILLER_YEAR, endMonth, endDay),
13924
+ });
13925
+ }
13926
+ };
13927
+ return (jsxRuntime.jsxs("div", { className: "w-full flex flex-wrap xs:gap-5 justify-between items-center", children: [jsxRuntime.jsxs(react.RadioGroup, { orientation: "horizontal", value: mode, onChange: handleModeChange, "aria-labelledby": ariaLabelledBy, children: [jsxRuntime.jsx(react.Radio, { value: "single", children: jsxRuntime.jsxs(react.Radio.Content, { children: [jsxRuntime.jsx(react.Radio.Control, { children: jsxRuntime.jsx(react.Radio.Indicator, {}) }), t.dayMonthSingleOption] }) }), jsxRuntime.jsx(react.Radio, { value: "range", children: jsxRuntime.jsxs(react.Radio.Content, { children: [jsxRuntime.jsx(react.Radio.Control, { children: jsxRuntime.jsx(react.Radio.Indicator, {}) }), t.dayMonthRangeOption] }) })] }), mode === "single" ? (jsxRuntime.jsx("div", { ref: singleRef, children: jsxRuntime.jsx(DatePicker, { value: pickerValue, onChange: handleSingleChange, onFocusChange: handleSingleFocusChange, "aria-label": t.dayMonthAriaLabel, endContent: jsxRuntime.jsx(IconComponent, { icon: "solar:calendar-outline" }), className: `w-full md:w-auto md:max-w-40 ${NO_YEAR_CLASS}` }, "dmp") })) : (jsxRuntime.jsx("div", { ref: rangeRef, children: jsxRuntime.jsx(DateRangePicker, { value: rangeValue, onChange: handleRangeChange, onFocusChange: handleRangeFocusChange, "aria-label": t.dayMonthRangeAriaLabel, endContent: jsxRuntime.jsx(IconComponent, { icon: "solar:calendar-outline" }), className: `w-full md:w-auto md:max-w-xs ${NO_YEAR_CLASS}` }, "dmpr") }))] }));
13647
13928
  };
13648
13929
 
13649
13930
  /**
@@ -13682,6 +13963,13 @@ const resolveSelectPlaceholder = (translations, title) => (translations?.selectP
13682
13963
  // =========================================================================
13683
13964
  const FilterSection = ({ filter, translations, value, onChange, isExpanded = false, onToggleExpanded, }) => {
13684
13965
  const isDisabled = filter.disabled === true;
13966
+ // TECH-2459 · El título visible de la sección es el NOMBRE ACCESIBLE de su control. Sin él,
13967
+ // react-aria (`useLabel`, vía `useSelect`/`useSlider`/`useListBox`) avisaba en dev «If you do
13968
+ // not provide a visible label, you must specify an aria-label or aria-labelledby» cada vez que
13969
+ // se desplegaba una sección (medido por beweossmbs en el drawer del catálogo con la .141), y el
13970
+ // lector de pantalla anunciaba solo el placeholder («Seleccionar categoría»). El control se
13971
+ // asocia por `aria-labelledby` a este id: sin cambio visual.
13972
+ const titleId = $8WNJc$react.useId();
13685
13973
  const [internalExpanded, setInternalExpanded] = $8WNJc$react.useState(isDisabled ? false : isExpanded);
13686
13974
  const handleToggleExpanded = () => {
13687
13975
  if (isDisabled)
@@ -13778,27 +14066,27 @@ const FilterSection = ({ filter, translations, value, onChange, isExpanded = fal
13778
14066
  const renderFilterContent = () => {
13779
14067
  switch (filter.type) {
13780
14068
  case "select":
13781
- return (jsxRuntime.jsx(SelectFilter, { filter: filter, value: value, onChange: onChange, translations: translations }));
14069
+ return (jsxRuntime.jsx(SelectFilter, { filter: filter, value: value, onChange: onChange, translations: translations, titleId: titleId }));
13782
14070
  case "multiselect":
13783
- return (jsxRuntime.jsx(MultiSelectFilter, { filter: filter, value: value, onChange: onChange, translations: translations }));
14071
+ return (jsxRuntime.jsx(MultiSelectFilter, { filter: filter, value: value, onChange: onChange, translations: translations, titleId: titleId }));
13784
14072
  case "range":
13785
- return (jsxRuntime.jsx(RangeFilterComponent, { filter: filter, value: value, onChange: onChange }));
14073
+ return (jsxRuntime.jsx(RangeFilterComponent, { filter: filter, value: value, onChange: onChange, titleId: titleId }));
13786
14074
  case "date":
13787
- return (jsxRuntime.jsx(DateFilter, { filter: filter, value: value, onChange: onChange, translations: translations }));
14075
+ return (jsxRuntime.jsx(DateFilter, { filter: filter, value: value, onChange: onChange, translations: translations, titleId: titleId }));
13788
14076
  case "text":
13789
- return (jsxRuntime.jsx(TextFilter, { filter: filter, value: value, onChange: onChange }));
14077
+ return (jsxRuntime.jsx(TextFilter, { filter: filter, value: value, onChange: onChange, titleId: titleId }));
13790
14078
  case "number":
13791
- return (jsxRuntime.jsx(NumberFilter, { filter: filter, value: value, onChange: onChange }));
14079
+ return (jsxRuntime.jsx(NumberFilter, { filter: filter, value: value, onChange: onChange, titleId: titleId }));
13792
14080
  default:
13793
14081
  return null;
13794
14082
  }
13795
14083
  };
13796
- return (jsxRuntime.jsxs("div", { className: react.cn("bg-white rounded-xl max-w-sm", isDisabled && "opacity-50"), style: {
14084
+ return (jsxRuntime.jsxs("div", { className: cn("bg-white rounded-xl max-w-sm", isDisabled && "opacity-50"), style: {
13797
14085
  border: "0 solid #e5e7eb",
13798
14086
  boxShadow: "var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow)",
13799
14087
  "--tw-shadow": "var(--aurora-shadow-medium)",
13800
14088
  "--tw-shadow-colored": "var(--aurora-shadow-medium)",
13801
- }, children: [jsxRuntime.jsxs("button", { type: "button", className: react.cn("flex items-center justify-between w-full text-left p-4", isDisabled && "cursor-not-allowed"), onClick: handleToggleExpanded, children: [jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [jsxRuntime.jsx(H2, { className: "text-base font-normal text-foreground", children: filter.title }), !isDisabled && hasActiveFilter() && (jsxRuntime.jsx("span", { className: "text-xs px-2 py-1 rounded-full text-black dark:text-white", style: {
14089
+ }, children: [jsxRuntime.jsxs("button", { type: "button", className: cn("flex items-center justify-between w-full text-left p-4", isDisabled && "cursor-not-allowed"), onClick: handleToggleExpanded, children: [jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [jsxRuntime.jsx(H2, { id: titleId, className: "text-base font-normal text-foreground", children: filter.title }), !isDisabled && hasActiveFilter() && (jsxRuntime.jsx("span", { className: "text-xs px-2 py-1 rounded-full text-black dark:text-white", style: {
13802
14090
  backgroundColor: "var(--color-default)",
13803
14091
  }, children: getActiveFilterCount() }))] }), jsxRuntime.jsx(IconComponent, { icon: internalExpanded
13804
14092
  ? "solar:alt-arrow-down-outline"
@@ -13807,10 +14095,10 @@ const FilterSection = ({ filter, translations, value, onChange, isExpanded = fal
13807
14095
  // =========================================================================
13808
14096
  // SELECT FILTER
13809
14097
  // =========================================================================
13810
- const SelectFilter = ({ filter, value, onChange, translations }) => {
14098
+ const SelectFilter = ({ filter, value, onChange, translations, titleId }) => {
13811
14099
  const currentValue = value?.value || "";
13812
14100
  const triggerPlaceholder = resolveSelectPlaceholder(translations, filter.title);
13813
- return (jsxRuntime.jsx(Select, { placeholder: triggerPlaceholder, selectedKeys: new Set(currentValue ? [currentValue] : []), onSelectionChange: (keys) => {
14101
+ return (jsxRuntime.jsx(Select, { "aria-labelledby": titleId, placeholder: triggerPlaceholder, selectedKeys: new Set(currentValue ? [currentValue] : []), onSelectionChange: (keys) => {
13814
14102
  const selectedKey = Array.from(keys)[0];
13815
14103
  onChange({ value: selectedKey || "" });
13816
14104
  }, className: "w-full", children: filter.data.map((item) => (
@@ -13824,7 +14112,8 @@ const SelectFilter = ({ filter, value, onChange, translations }) => {
13824
14112
  // =========================================================================
13825
14113
  // MULTISELECT FILTER
13826
14114
  // =========================================================================
13827
- const MultiSelectFilter = ({ filter, value, onChange, translations }) => {
14115
+ const MultiSelectFilter = ({ filter, value, onChange, translations, titleId }) => {
14116
+ const valueId = $8WNJc$react.useId();
13828
14117
  const triggerRef = $8WNJc$react.useRef(null);
13829
14118
  const [triggerWidthPx, setTriggerWidthPx] = $8WNJc$react.useState(null);
13830
14119
  const [isOpen, setIsOpen] = $8WNJc$react.useState(false);
@@ -13918,11 +14207,11 @@ const MultiSelectFilter = ({ filter, value, onChange, translations }) => {
13918
14207
  maxWidth: Math.max(triggerWidthPx, 220),
13919
14208
  }
13920
14209
  : undefined;
13921
- return (jsxRuntime.jsxs(react.Popover, { isOpen: isOpen, onOpenChange: handleOpenChange, children: [jsxRuntime.jsx(react.PopoverTrigger, { children: jsxRuntime.jsxs("button", { ref: triggerRef, type: "button", className: react.cn(
14210
+ return (jsxRuntime.jsxs(react.Popover, { isOpen: isOpen, onOpenChange: handleOpenChange, children: [jsxRuntime.jsx(react.PopoverTrigger, { "aria-labelledby": titleId, "aria-describedby": valueId, children: jsxRuntime.jsxs("button", { ref: triggerRef, type: "button", "aria-labelledby": titleId, "aria-describedby": valueId, className: cn(
13922
14211
  // TECH-2459 · `bg-transparent` y no `bg-background`: este disparador tiene pinta de campo y vive
13923
14212
  // DENTRO de un drawer, o sea el escenario del relleno negro sobre tarjeta gris. En oscuro
13924
14213
  // `--color-background` es negro puro, y el `bordered` de v2 no llevaba ninguna clase `bg-*`.
13925
- "flex w-full min-h-12 items-center justify-between gap-2 rounded-[12px] border border-default-200 bg-transparent px-3 py-2.5 text-left text-sm transition-colors", "hover:border-default-300 focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2 focus-visible:ring-offset-background", isOpen && "border-primary"), "aria-expanded": isOpen, "aria-haspopup": "dialog", children: [jsxRuntime.jsx("span", { className: "line-clamp-2 min-w-0 flex-1 text-sm font-medium leading-snug text-foreground", title: triggerSelectionTitle, children: triggerSelection.visible.length > 0 ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [triggerSelection.visible.map((item, index) => (jsxRuntime.jsxs($8WNJc$react.Fragment, { children: [index > 0 ? (jsxRuntime.jsx("span", { className: "font-normal text-default-400", children: ", " })) : null, jsxRuntime.jsx("span", { children: item.label })] }, item.value))), triggerSelection.overflow > 0 ? (jsxRuntime.jsxs("span", { className: "font-normal text-default-500", children: [" ", moreLabelTemplate.replace("{more}", String(triggerSelection.overflow))] })) : null] })) : (jsxRuntime.jsx("span", { className: "font-normal text-default-400", children: triggerPlaceholder })) }), jsxRuntime.jsx(IconComponent, { icon: isOpen
14214
+ "flex w-full min-h-12 items-center justify-between gap-2 rounded-[12px] border border-default-200 bg-transparent px-3 py-2.5 text-left text-sm transition-colors", "hover:border-default-300 focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2 focus-visible:ring-offset-background", isOpen && "border-primary"), "aria-expanded": isOpen, "aria-haspopup": "dialog", children: [jsxRuntime.jsx("span", { id: valueId, className: "line-clamp-2 min-w-0 flex-1 text-sm font-medium leading-snug text-foreground", title: triggerSelectionTitle, children: triggerSelection.visible.length > 0 ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [triggerSelection.visible.map((item, index) => (jsxRuntime.jsxs($8WNJc$react.Fragment, { children: [index > 0 ? (jsxRuntime.jsx("span", { className: "font-normal text-default-400", children: ", " })) : null, jsxRuntime.jsx("span", { children: item.label })] }, item.value))), triggerSelection.overflow > 0 ? (jsxRuntime.jsxs("span", { className: "font-normal text-default-500", children: [" ", moreLabelTemplate.replace("{more}", String(triggerSelection.overflow))] })) : null] })) : (jsxRuntime.jsx("span", { className: "font-normal text-default-400", children: triggerPlaceholder })) }), jsxRuntime.jsx(IconComponent, { icon: isOpen
13926
14215
  ? "solar:alt-arrow-up-outline"
13927
14216
  : "solar:alt-arrow-down-outline", className: "shrink-0 text-default-400", size: "sm", "aria-hidden": true })] }) }), jsxRuntime.jsx(react.PopoverContent, { placement: "bottom start", offset: 6, className: "w-full min-w-0 max-w-none box-border border border-default-200 bg-content1 p-0 shadow-medium", style: popoverWidthStyle, children: jsxRuntime.jsxs("div", { className: "flex w-full flex-col gap-0 p-2", children: [searchable && (jsxRuntime.jsx("div", { className: "border-b border-default-100 px-1 pb-2", children: jsxRuntime.jsx(Input, { type: "search", placeholder: searchPlaceholder, value: searchQuery, onValueChange: setSearchQuery, className: "w-full", size: "sm", variant: "flat", radius: "full",
13928
14217
  // `InputClassNames` de G1-forms ya no tiene slot `base` (v3 no
@@ -13936,7 +14225,7 @@ const MultiSelectFilter = ({ filter, value, onChange, translations }) => {
13936
14225
  // =========================================================================
13937
14226
  // RANGE FILTER
13938
14227
  // =========================================================================
13939
- const RangeFilterComponent = ({ filter, value, onChange }) => {
14228
+ const RangeFilterComponent = ({ filter, value, onChange, titleId }) => {
13940
14229
  const currentValue = value || { min: filter.data.min, max: filter.data.max };
13941
14230
  const rangeValue = [currentValue.min, currentValue.max];
13942
14231
  const handleChange = (newValue) => {
@@ -13951,12 +14240,12 @@ const RangeFilterComponent = ({ filter, value, onChange }) => {
13951
14240
  const data = Array.from({
13952
14241
  length: Math.ceil((filter.data.max - filter.data.min) / (filter.data.step || 1)) + 1,
13953
14242
  }, (_, i) => filter.data.min + i * (filter.data.step || 1));
13954
- return (jsxRuntime.jsx(RangeFilter, { title: `Rango de ${filter.title.toLowerCase()}`, minValue: filter.data.min, maxValue: filter.data.max, step: filter.data.step || 1, data: data, value: rangeValue, onChange: handleChange, formatValue: formatter, className: "w-full", showHistogramCount: filter.data.showHistogramCount }));
14243
+ return (jsxRuntime.jsx(RangeFilter, { title: `Rango de ${filter.title.toLowerCase()}`, minValue: filter.data.min, maxValue: filter.data.max, step: filter.data.step || 1, data: data, value: rangeValue, onChange: handleChange, formatValue: formatter, className: "w-full", showHistogramCount: filter.data.showHistogramCount, sliderProps: { "aria-labelledby": titleId } }));
13955
14244
  };
13956
14245
  // =========================================================================
13957
14246
  // DATE FILTER
13958
14247
  // =========================================================================
13959
- const DateFilter = ({ filter, value, onChange, translations }) => {
14248
+ const DateFilter = ({ filter, value, onChange, translations, titleId }) => {
13960
14249
  if (filter.granularity === "dayMonth") {
13961
14250
  const rawDayMonth = value?.type === "dayMonth" && value.dayMonth && typeof value.dayMonth !== "string"
13962
14251
  ? value.dayMonth
@@ -13975,7 +14264,7 @@ const DateFilter = ({ filter, value, onChange, translations }) => {
13975
14264
  dayMonthRange: value.type === "dayMonthRange" ? rawDayMonthRange : null,
13976
14265
  }
13977
14266
  : null;
13978
- return (jsxRuntime.jsx(DayMonthPicker, { value: dayMonthValue, onChange: (v) => onChange({ date: null, dateRange: null, ...v }), translations: translations }));
14267
+ return (jsxRuntime.jsx(DayMonthPicker, { value: dayMonthValue, onChange: (v) => onChange({ date: null, dateRange: null, ...v }), translations: translations, ariaLabelledBy: titleId }));
13979
14268
  }
13980
14269
  const handleDateSelectorChange = (dateSelectorValue) => {
13981
14270
  onChange({
@@ -14047,23 +14336,25 @@ const DateFilter = ({ filter, value, onChange, translations }) => {
14047
14336
  dateSelectorTranslations.selectDateRangeAriaLabel =
14048
14337
  translations.selectDateRangeAriaLabel;
14049
14338
  }
14050
- return (jsxRuntime.jsx(DateSelector, { initialType: getInitialType(), initialDate: getInitialDate(), initialDateRange: getInitialDateRange(), onChange: handleDateSelectorChange, translations: dateSelectorTranslations, className: "w-full" }));
14339
+ return (jsxRuntime.jsx(DateSelector, { initialType: getInitialType(), initialDate: getInitialDate(), initialDateRange: getInitialDateRange(), onChange: handleDateSelectorChange, translations: dateSelectorTranslations,
14340
+ // El grupo «Día / Rango» se nombra con el título de la sección (ver `titleId`).
14341
+ radioGroupProps: { "aria-labelledby": titleId }, className: "w-full" }));
14051
14342
  };
14052
14343
  // =========================================================================
14053
14344
  // TEXT FILTER
14054
14345
  // =========================================================================
14055
- const TextFilter = ({ filter, value, onChange }) => {
14346
+ const TextFilter = ({ filter, value, onChange, titleId }) => {
14056
14347
  const currentValue = value?.value || "";
14057
- return (jsxRuntime.jsx(Input, { type: "text", placeholder: filter.data.placeholder || `Ingrese ${filter.title.toLowerCase()}`, value: currentValue, onValueChange: (newValue) => {
14348
+ return (jsxRuntime.jsx(Input, { "aria-labelledby": titleId, type: "text", placeholder: filter.data.placeholder || `Ingrese ${filter.title.toLowerCase()}`, value: currentValue, onValueChange: (newValue) => {
14058
14349
  onChange({ value: newValue });
14059
14350
  }, className: "w-full" }));
14060
14351
  };
14061
14352
  // =========================================================================
14062
14353
  // NUMBER FILTER
14063
14354
  // =========================================================================
14064
- const NumberFilter = ({ filter, value, onChange }) => {
14355
+ const NumberFilter = ({ filter, value, onChange, titleId }) => {
14065
14356
  const currentValue = value?.value?.toString() || "";
14066
- return (jsxRuntime.jsx(Input, { type: "number", placeholder: filter.data.placeholder || `Ingrese ${filter.title.toLowerCase()}`, value: currentValue, onValueChange: (newValue) => {
14357
+ return (jsxRuntime.jsx(Input, { "aria-labelledby": titleId, type: "number", placeholder: filter.data.placeholder || `Ingrese ${filter.title.toLowerCase()}`, value: currentValue, onValueChange: (newValue) => {
14067
14358
  const numValue = newValue === "" ? null : Number(newValue);
14068
14359
  onChange({ value: numValue });
14069
14360
  }, min: filter.data.min, max: filter.data.max, step: filter.data.step, className: "w-full" }));
@@ -14205,7 +14496,7 @@ const DrawerFilters = ({ isOpen, onOpenChange, config, onApplyFilters, onClearFi
14205
14496
  // beweossmbs con la .140). `Drawer.Backdrop` (`ModalOverlay`) ya crea su propio estado de
14206
14497
  // overlay con `isOpen`/`onOpenChange` y calcula todos los slots de `drawerVariants()`, así que
14207
14498
  // el root no aportaba nada.
14208
- return (jsxRuntime.jsx(react.Drawer.Backdrop, { isOpen: isOpen, onOpenChange: handleOpenChange, isDismissable: false, children: jsxRuntime.jsx(react.Drawer.Content, { placement: "right", className: react.cn("drawer-filters", className), children: jsxRuntime.jsxs(react.Drawer.Dialog, { "aria-labelledby": titleId, className: "w-full p-0 sm:max-w-md", children: [jsxRuntime.jsx(react.Drawer.CloseTrigger, {}), jsxRuntime.jsx(DrawerFiltersHeader, { titleId: titleId, title: config.title, description: config.description }), jsxRuntime.jsx(react.Drawer.Body, { className: "px-6 py-10", children: jsxRuntime.jsx("div", { className: "space-y-3", children: config.data.map((filter) => {
14499
+ return (jsxRuntime.jsx(react.Drawer.Backdrop, { isOpen: isOpen, onOpenChange: handleOpenChange, isDismissable: false, children: jsxRuntime.jsx(react.Drawer.Content, { placement: "right", className: cn("drawer-filters", className), children: jsxRuntime.jsxs(react.Drawer.Dialog, { "aria-labelledby": titleId, className: "w-full p-0 sm:max-w-md", children: [jsxRuntime.jsx(react.Drawer.CloseTrigger, {}), jsxRuntime.jsx(DrawerFiltersHeader, { titleId: titleId, title: config.title, description: config.description }), jsxRuntime.jsx(react.Drawer.Body, { className: "px-6 py-10", children: jsxRuntime.jsx("div", { className: "space-y-3", children: config.data.map((filter) => {
14209
14500
  return (jsxRuntime.jsx(FilterSection, { filter: filter, translations: translations, value: filterValues[filter.key], onChange: (value) => handleFilterChange(filter.key, value) }, filter.key));
14210
14501
  }) }) }), jsxRuntime.jsx(DrawerFiltersFooter, { onClearFilters: handleClearFilters, onCancel: handleCancel, onApplyFilters: handleApplyFilters, translations: translations })] }) }) }));
14211
14502
  };
@@ -16106,7 +16397,7 @@ const Modal = ({ isOpen, defaultOpen, onOpenChange, onClose, size = "md", radius
16106
16397
  // de react-aria no se pueden pisar por esta vía.
16107
16398
  render: hasExtraAria
16108
16399
  ? (sectionProps) => jsxRuntime.jsx("section", { ...extraAria, ...sectionProps })
16109
- : undefined, className: react.cn(RADIUS_CLASS$1[radius], size !== "full" && MAX_WIDTH_CLASS[size], "px-6 py-9", classNames?.base, className, contentClassName), children: ({ close }) => (jsxRuntime.jsx(ModalDialogBody, { close: close, headerId: headerId, classNames: classNames, registerContentProps: registerContentProps, hideCloseButton: hideCloseButton, children: children })) }) }) }));
16400
+ : undefined, className: cn(RADIUS_CLASS$1[radius], size !== "full" && MAX_WIDTH_CLASS[size], "px-6 py-9", classNames?.base, className, contentClassName), children: ({ close }) => (jsxRuntime.jsx(ModalDialogBody, { close: close, headerId: headerId, classNames: classNames, registerContentProps: registerContentProps, hideCloseButton: hideCloseButton, children: children })) }) }) }));
16110
16401
  };
16111
16402
  /** Aísla el `useMemo` del valor de contexto (el render-prop de `Dialog` no puede usar hooks). */
16112
16403
  const ModalDialogBody = ({ close, headerId, classNames, registerContentProps, hideCloseButton, children, }) => {
@@ -16169,7 +16460,7 @@ const ModalHeader = ({ className, ...props }) => {
16169
16460
  , {
16170
16461
  // Nombra el diálogo (`aria-labelledby`, ver `Modal.tsx`). Va antes del spread: un `id`
16171
16462
  // propio del consumidor gana, igual que en v2 (`id: headerId, ...otherProps`).
16172
- id: headerId, ...props, className: react.cn("flex-row gap-0 px-6 py-4 text-lg font-semibold",
16463
+ id: headerId, ...props, className: cn("flex-row gap-0 px-6 py-4 text-lg font-semibold",
16173
16464
  // v2 `classNames.header` del `<Modal>`; el `className` propio gana
16174
16465
  // (`clsx(classNames.header, className)` en `@heroui/modal@2.2.19`).
16175
16466
  classNames?.header, className) }));
@@ -16340,7 +16631,7 @@ const ModalBody = $8WNJc$react.forwardRef(({ className, ...props }, forwardedRef
16340
16631
  return (jsxRuntime.jsx(react.ModalBody, { ref: callbackRef, ...props,
16341
16632
  // v2 `classNames.body` del `<Modal>` entre la geometría y el `className` propio,
16342
16633
  // que gana (`clsx(classNames.body, className)` en `@heroui/modal@2.2.19`).
16343
- className: react.cn(BODY_V2_GEOMETRY$1, classNames?.body, className) }));
16634
+ className: cn(BODY_V2_GEOMETRY$1, classNames?.body, className) }));
16344
16635
  });
16345
16636
  ModalBody.displayName = "ModalBody";
16346
16637
 
@@ -16350,13 +16641,19 @@ ModalBody.displayName = "ModalBody";
16350
16641
  * v3 conserva `flex-row justify-end gap-2` pero pierde el padding, y añade un
16351
16642
  * `.modal__body + .modal__footer { mt-5 }` que v2 no tenía (v2 separaba los slots solo
16352
16643
  * con su propio padding) — de ahí el `mt-0`.
16644
+ *
16645
+ * `items-stretch`: v2 no declaraba `items-*` (`align-items: normal`, que en flex estira), y v3
16646
+ * pone `items-center`. En un footer en columna (`className="flex flex-col"`, «Register payment»
16647
+ * de beweossmbs) eso encogía cada fila a su contenido: medido con la .141, Total 83px frente a
16648
+ * 464 y botones `flex-1` 108px frente a 226. En la fila por defecto no cambia nada visible
16649
+ * (los `Button` tienen alto propio). Un `items-*` de la app lo retira por fusión.
16353
16650
  */
16354
16651
  const ModalFooter = ({ className, ...props }) => {
16355
16652
  const { classNames } = $8WNJc$react.useContext(ModalFacadeContext);
16356
16653
  return (jsxRuntime.jsx(react.ModalFooter, { ...props,
16357
16654
  // v2 `classNames.footer` del `<Modal>` entre la fachada y el `className` propio, que
16358
16655
  // gana (`clsx(classNames.footer, className)` en `@heroui/modal@2.2.19`).
16359
- className: react.cn("mt-0 px-6 py-4", classNames?.footer, className) }));
16656
+ className: cn("mt-0 items-stretch px-6 py-4", classNames?.footer, className) }));
16360
16657
  };
16361
16658
  ModalFooter.displayName = "ModalFooter";
16362
16659
 
@@ -16453,10 +16750,11 @@ const DrawerFacade = ({ isOpen, defaultOpen, onOpenChange, onClose, placement =
16453
16750
  // Sin `Drawer.Root` (el `DialogTrigger` de react-aria) a propósito: la fachada no tiene
16454
16751
  // disparador propio —lo abre el `isOpen` de la app— y un `DialogTrigger` sin hijo pulsable
16455
16752
  // avisa en consola en CADA montaje («A PressResponder was rendered without a pressable
16456
- // child», medido en jsdom; `Modal` lo sigue emitiendo). `Drawer.Backdrop` (`ModalOverlay`)
16753
+ // child», medido en jsdom). `Modal` hace lo mismo desde 27958d2 (ya no monta `Modal.Root`) y
16754
+ // `Modal.v2.test.tsx` vigila 0 avisos con modales cerrados. `Drawer.Backdrop` (`ModalOverlay`)
16457
16755
  // ya crea y publica su propio estado de overlay con `isOpen`/`onOpenChange`, y trae todos los
16458
16756
  // slots de `drawerVariants()`, así que el root no aportaba nada.
16459
- return (jsxRuntime.jsx(react.Drawer.Backdrop, { isOpen: isOpen, defaultOpen: defaultOpen, onOpenChange: handleOpenChange, variant: backdrop, isDismissable: isDismissable, isKeyboardDismissDisabled: isKeyboardDismissDisabled, children: jsxRuntime.jsx(react.Drawer.Content, { placement: placement, children: jsxRuntime.jsx(react.Drawer.Dialog, { "aria-labelledby": headerId, className: react.cn(sizeClass(size, placement), "p-0", scrollBehavior === "outside" && "overflow-y-auto", className), children: ({ close }) => (jsxRuntime.jsx(DrawerDialogBody, { close: close, headerId: headerId, scrollBehavior: scrollBehavior, hideCloseButton: hideCloseButton, children: children })) }) }) }));
16757
+ return (jsxRuntime.jsx(react.Drawer.Backdrop, { isOpen: isOpen, defaultOpen: defaultOpen, onOpenChange: handleOpenChange, variant: backdrop, isDismissable: isDismissable, isKeyboardDismissDisabled: isKeyboardDismissDisabled, children: jsxRuntime.jsx(react.Drawer.Content, { placement: placement, children: jsxRuntime.jsx(react.Drawer.Dialog, { "aria-labelledby": headerId, className: cn(sizeClass(size, placement), "p-0", scrollBehavior === "outside" && "overflow-y-auto", className), children: ({ close }) => (jsxRuntime.jsx(DrawerDialogBody, { close: close, headerId: headerId, scrollBehavior: scrollBehavior, hideCloseButton: hideCloseButton, children: children })) }) }) }));
16460
16758
  };
16461
16759
  /** Aísla el `useMemo` del valor de contexto (el render-prop de `Dialog` no puede usar hooks). */
16462
16760
  const DrawerDialogBody = ({ close, headerId, scrollBehavior, hideCloseButton, children }) => {
@@ -16518,7 +16816,7 @@ DrawerContent.displayName = "Aurora.DrawerContent";
16518
16816
  */
16519
16817
  const DrawerHeader = ({ className, children }) => {
16520
16818
  const { headerId } = $8WNJc$react.useContext(DrawerFacadeContext);
16521
- return (jsxRuntime.jsx(react.DrawerHeader, { id: headerId, className: react.cn("flex-initial flex-row gap-0 px-6 py-4 text-lg font-semibold", className), children: children }));
16819
+ return (jsxRuntime.jsx(react.DrawerHeader, { id: headerId, className: cn("flex-initial flex-row gap-0 px-6 py-4 text-lg font-semibold", className), children: children }));
16522
16820
  };
16523
16821
  DrawerHeader.displayName = "Aurora.DrawerHeader";
16524
16822
 
@@ -16536,7 +16834,7 @@ DrawerHeader.displayName = "Aurora.DrawerHeader";
16536
16834
  const BODY_V2_GEOMETRY = "mx-0 mt-0 flex flex-1 flex-col gap-3 px-6 py-2";
16537
16835
  const DrawerBody = ({ className, children }) => {
16538
16836
  const { scrollBehavior } = $8WNJc$react.useContext(DrawerFacadeContext);
16539
- return (jsxRuntime.jsx(react.DrawerBody, { className: react.cn(BODY_V2_GEOMETRY, scrollBehavior === "outside" && "flex-none overflow-visible", className), children: children }));
16837
+ return (jsxRuntime.jsx(react.DrawerBody, { className: cn(BODY_V2_GEOMETRY, scrollBehavior === "outside" && "flex-none overflow-visible", className), children: children }));
16540
16838
  };
16541
16839
  DrawerBody.displayName = "Aurora.DrawerBody";
16542
16840
 
@@ -16544,9 +16842,11 @@ DrawerBody.displayName = "Aurora.DrawerBody";
16544
16842
  * Geometría v2 del slot `footer`: `flex flex-row gap-2 px-6 py-4 justify-end`
16545
16843
  * (`@heroui/theme@2.4.15`, slot `footer`). v3 conserva `flex-row justify-end gap-2` pero pierde
16546
16844
  * el padding y añade `.drawer__body + .drawer__footer { mt-5 }`, que v2 no tenía — de ahí el
16547
- * `mt-0` (mismo arreglo que `ModalFooter`).
16845
+ * `mt-0` (mismo arreglo que `ModalFooter`). Y `items-stretch` en lugar del `items-center` de
16846
+ * v3: v2 no declaraba `items-*`, así que un footer en columna estiraba sus filas (en «Register
16847
+ * payment» de beweossmbs, Total 83px frente a 464 con la .141; detalle en `ModalFooter`).
16548
16848
  */
16549
- const DrawerFooter = ({ className, children }) => (jsxRuntime.jsx(react.DrawerFooter, { className: react.cn("mt-0 px-6 py-4", className), children: children }));
16849
+ const DrawerFooter = ({ className, children }) => (jsxRuntime.jsx(react.DrawerFooter, { className: cn("mt-0 items-stretch px-6 py-4", className), children: children }));
16550
16850
  DrawerFooter.displayName = "Aurora.DrawerFooter";
16551
16851
 
16552
16852
  // TECH-2459 — Fachada `Alert` (hallazgo loginos 07-sep: `index.tsx` reexportaba el `Alert` CRUDO de
@@ -16790,7 +17090,7 @@ const AlertFacade = ({ color, status, variant = "flat", radius = "md", title, de
16790
17090
  return null;
16791
17091
  }
16792
17092
  if (hasCompoundChildren(children)) {
16793
- return (jsxRuntime.jsx(react.Alert, { ...rest, status: effectiveStatus, className: react.cn(classNames?.base, className), children: children }));
17093
+ return (jsxRuntime.jsx(react.Alert, { ...rest, status: effectiveStatus, className: cn(classNames?.base, className), children: children }));
16794
17094
  }
16795
17095
  const handleClose = () => {
16796
17096
  if (!isControlled) {
@@ -16809,20 +17109,20 @@ const AlertFacade = ({ color, status, variant = "flat", radius = "md", title, de
16809
17109
  // Base v2: `flex flex-grow flex-row w-full items-start py-3 px-4 gap-x-1`. v3 ya trae
16810
17110
  // flex/w-full/items-start/px-4/py-3; se repone el `gap-x-1` (v3: `gap-4`), se quita el
16811
17111
  // `shadow-surface` (v2 no tenía sombra en el base) y se aplica variant/radius.
16812
- className: react.cn("grow gap-x-1 shadow-none", slots.base, RADIUS_CLASS[radius], hideIconWrapper && "gap-x-0", classNames?.base, className), children: [startContent, !hideIcon && (jsxRuntime.jsx(react.Alert.Indicator, { className: react.cn(ICON_WRAPPER_BASE,
17112
+ className: cn("grow gap-x-1 shadow-none", slots.base, RADIUS_CLASS[radius], hideIconWrapper && "gap-x-0", classNames?.base, className), children: [startContent, !hideIcon && (jsxRuntime.jsx(react.Alert.Indicator, { className: cn(ICON_WRAPPER_BASE,
16813
17113
  // v2 `hideIconWrapper`: `!bg-transparent !shadow-none !border-none` — se omiten
16814
17114
  // las clases teñidas en vez de pisarlas, porque `bg-transparent` no borraría el
16815
17115
  // `dark:bg-*` (grupo distinto para tailwind-merge).
16816
17116
  hideIconWrapper ? "bg-transparent" : slots.iconWrapper, classNames?.iconWrapper), children: icon !== undefined && icon !== null ? (classNames?.alertIcon ? (
16817
17117
  // `alertIcon` de v2 se aplicaba al propio SVG; aquí solo alcanza al icono
16818
17118
  // personalizado (el de v3 por defecto se renderiza dentro del indicador).
16819
- jsxRuntime.jsx("span", { className: classNames.alertIcon, children: icon })) : (icon)) : undefined })), jsxRuntime.jsxs(react.Alert.Content, { className: react.cn("ms-2 box-border min-h-10 justify-center text-inherit", !hasContent && "items-center", classNames?.mainWrapper), children: [hasTitle && (
17119
+ jsxRuntime.jsx("span", { className: classNames.alertIcon, children: icon })) : (icon)) : undefined })), jsxRuntime.jsxs(react.Alert.Content, { className: cn("ms-2 box-border min-h-10 justify-center text-inherit", !hasContent && "items-center", classNames?.mainWrapper), children: [hasTitle && (
16820
17120
  // v2: `text-small w-full font-medium block text-inherit leading-5`; v3 (`.alert__title`)
16821
17121
  // pone `leading-6` y el color del estado — `text-inherit` devuelve el de v2.
16822
- jsxRuntime.jsx(react.Alert.Title, { className: react.cn("w-full leading-5 text-inherit", classNames?.title), children: title })), hasDescription && (
17122
+ jsxRuntime.jsx(react.Alert.Title, { className: cn("w-full leading-5 text-inherit", classNames?.title), children: title })), hasDescription && (
16823
17123
  // v2: `pl-[1px] text-small font-normal text-inherit`; v3 (`.alert__description`) pone
16824
17124
  // `text-muted`.
16825
- jsxRuntime.jsx(react.Alert.Description, { className: react.cn("pl-px font-normal text-inherit", slots.description, classNames?.description), children: description })), children] }), endContent, showClose && (jsxRuntime.jsx(react.CloseButton, { "aria-label": t.closeButtonAriaLabel, className: react.cn(CLOSE_BASE, slots.closeButton, classNames?.closeButton), onPress: handleClose }))] }));
17125
+ jsxRuntime.jsx(react.Alert.Description, { className: cn("pl-px font-normal text-inherit", slots.description, classNames?.description), children: description })), children] }), endContent, showClose && (jsxRuntime.jsx(react.CloseButton, { "aria-label": t.closeButtonAriaLabel, className: cn(CLOSE_BASE, slots.closeButton, classNames?.closeButton), onPress: handleClose }))] }));
16826
17126
  };
16827
17127
  AlertFacade.displayName = "Aurora.Alert";
16828
17128
  /**
@@ -16903,7 +17203,7 @@ function renderDropdownTrigger(child, triggerClassName) {
16903
17203
  : child.props.ref);
16904
17204
  const childClass = child.props.className;
16905
17205
  const className = triggerClassName && typeof childClass !== "function"
16906
- ? react.cn(triggerClassName, childClass)
17206
+ ? cn(triggerClassName, childClass)
16907
17207
  : childClass;
16908
17208
  return $8WNJc$react.cloneElement(child, {
16909
17209
  ...mergeTriggerProps$1(triggerProps, child.props),
@@ -16991,7 +17291,7 @@ function hasValue(node) {
16991
17291
  * (`react-aria-components/dist/private/Menu.mjs:318-355`).
16992
17292
  */
16993
17293
  const DropdownSectionFacade = ({ title, classNames, className, children, ...props }) => {
16994
- return (jsxRuntime.jsxs(react.Dropdown.Section, { ...props, className: react.cn(className, classNames?.base), children: [hasValue(title) ? (jsxRuntime.jsx(react.Header, { className: react.cn(SECTION_HEADING_CLASS, classNames?.heading), children: title })) : null, children] }));
17294
+ return (jsxRuntime.jsxs(react.Dropdown.Section, { ...props, className: cn(className, classNames?.base), children: [hasValue(title) ? (jsxRuntime.jsx(react.Header, { className: cn(SECTION_HEADING_CLASS, classNames?.heading), children: title })) : null, children] }));
16995
17295
  };
16996
17296
  DropdownSectionFacade.displayName = "Aurora.DropdownSection";
16997
17297
  /**
@@ -17170,7 +17470,7 @@ const DropdownFacade = ({ children, placement, offset, crossOffset, shouldFlip,
17170
17470
  // v2: `base` (caja exterior), luego `content` + `className` (caja interior); en v3 es una sola
17171
17471
  // caja, así que van juntas y en ese orden. `cn` funde conflictos entre ellas; frente a la clase
17172
17472
  // de v3 (`.dropdown__popover`, capa `components`) cualquier utilidad ya gana por capa.
17173
- const popoverClass = react.cn(classNames?.base, classNames?.content, className) || undefined;
17473
+ const popoverClass = cn(classNames?.base, classNames?.content, className) || undefined;
17174
17474
  const menuWithClose = (node) => withCloseOnSelect(node, closeOnSelect);
17175
17475
  const nodes = flatten(children);
17176
17476
  // El popover es del consumidor: se respeta su árbol entero y se le COMPLETA lo que no dijo
@@ -17186,7 +17486,7 @@ const DropdownFacade = ({ children, placement, offset, crossOffset, shouldFlip,
17186
17486
  return $8WNJc$react.cloneElement(own, {
17187
17487
  ...missing,
17188
17488
  ...(popoverClass && typeof ownClass !== "function"
17189
- ? { className: react.cn(popoverClass, ownClass) }
17489
+ ? { className: cn(popoverClass, ownClass) }
17190
17490
  : {}),
17191
17491
  }, ...mapTree(own.props.children, menuWithClose));
17192
17492
  };
@@ -17401,7 +17701,7 @@ titleValue: _titleValue, ...props }) => {
17401
17701
  const children = ownChildren ?? title;
17402
17702
  const sizeClass = $8WNJc$react.useContext(TabSizeContext);
17403
17703
  const tabProps = sizeClass
17404
- ? { ...props, className: react.cn(sizeClass, props.className) }
17704
+ ? { ...props, className: cn(sizeClass, props.className) }
17405
17705
  : props;
17406
17706
  // `children` como función es la forma de render props de react-aria (`TabRenderProps`). No se
17407
17707
  // puede inspeccionar, y menos aún combinar con un hermano —React rechaza una función como
@@ -17596,11 +17896,11 @@ const TabsFacade = (allProps) => {
17596
17896
  // `.tabs[data-orientation="horizontal"] > .tabs__list-container { align-self: start }` de
17597
17897
  // neutralize, que no hace falta: dentro de una fila el carril ya mide su contenido.
17598
17898
  const orientationAttr = v3Orientation ?? "horizontal";
17599
- return (jsxRuntime.jsxs(react.Tabs, { ...rootProps, orientation: v3Orientation, variant: v3Variant, children: [jsxRuntime.jsx("div", { className: react.cn("flex", v3Variant === "secondary" && "tabs--secondary", fullWidth && "w-full", classNames?.base, className), "data-orientation": orientationAttr, "data-slot": "tabs-base", children: jsxRuntime.jsx(react.Tabs.ListContainer, { className: react.cn(fullWidth && "w-full"), children: jsxRuntime.jsx(react.Tabs.List, { "aria-describedby": ariaDescribedby, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledby, className: react.cn(classNames?.tabList), children: tabs.map(({ id, title, tabClassName, tabProps }) => ($8WNJc$react.createElement(react.Tabs.Tab, { ...tabProps, className: react.cn(size && TAB_SIZE_CLASS[size], classNames?.tab, tabClassName), id: id, key: id },
17600
- jsxRuntime.jsx(react.Tabs.Indicator, { className: react.cn(classNames?.cursor) }),
17899
+ return (jsxRuntime.jsxs(react.Tabs, { ...rootProps, orientation: v3Orientation, variant: v3Variant, children: [jsxRuntime.jsx("div", { className: cn("flex", v3Variant === "secondary" && "tabs--secondary", fullWidth && "w-full", classNames?.base, className), "data-orientation": orientationAttr, "data-slot": "tabs-base", children: jsxRuntime.jsx(react.Tabs.ListContainer, { className: cn(fullWidth && "w-full"), children: jsxRuntime.jsx(react.Tabs.List, { "aria-describedby": ariaDescribedby, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledby, className: cn(classNames?.tabList), children: tabs.map(({ id, title, tabClassName, tabProps }) => ($8WNJc$react.createElement(react.Tabs.Tab, { ...tabProps, className: cn(size && TAB_SIZE_CLASS[size], classNames?.tab, tabClassName), id: id, key: id },
17900
+ jsxRuntime.jsx(react.Tabs.Indicator, { className: cn(classNames?.cursor) }),
17601
17901
  classNames?.tabContent ? (jsxRuntime.jsx("span", { className: classNames.tabContent, children: title })) : (title)))) }) }) }), tabs
17602
17902
  .filter(({ panel }) => hasPanelContent(panel))
17603
- .map(({ id, panel, tabClassName }) => (jsxRuntime.jsx(react.Tabs.Panel, { className: react.cn(classNames?.panel, tabClassName), id: id, shouldForceMount: !destroyInactiveTabPanel || undefined, children: typeof panel === "function" ? null : panel }, id)))] }));
17903
+ .map(({ id, panel, tabClassName }) => (jsxRuntime.jsx(react.Tabs.Panel, { className: cn(classNames?.panel, tabClassName), id: id, shouldForceMount: !destroyInactiveTabPanel || undefined, children: typeof panel === "function" ? null : panel }, id)))] }));
17604
17904
  }
17605
17905
  // Forma v3 (o nada que traducir): el camino de siempre. Solo se traducen las props de v2 que
17606
17906
  // tienen equivalente, para que una app a medio migrar no las pierda.
@@ -17610,7 +17910,7 @@ const TabsFacade = (allProps) => {
17610
17910
  const v3Props = {
17611
17911
  ...rest,
17612
17912
  className: fullWidth || classNames?.base
17613
- ? react.cn(fullWidth && "w-full", classNames?.base, className)
17913
+ ? cn(fullWidth && "w-full", classNames?.base, className)
17614
17914
  : className,
17615
17915
  orientation: v3Orientation,
17616
17916
  variant: v3Variant,
@@ -17781,7 +18081,7 @@ const Tooltip = ({ enableTapOnTouch = true, touchPlacement = "top", placement, o
17781
18081
  delay = 0, closeDelay, trigger, className, classNames, color = "default", children, }) => {
17782
18082
  // v3 tiene un solo nodo donde v2 tenía `base` + `content` (ver `TooltipClassNames`). Orden de
17783
18083
  // v2: color → `classNames` → `className`; `cn` fusiona para que la clase de la app gane.
17784
- const contentClassName = react.cn(COLOR_CLASSES[color] ?? "", classNames?.base, classNames?.content, className);
18084
+ const contentClassName = cn(COLOR_CLASSES[color] ?? "", classNames?.base, classNames?.content, className);
17785
18085
  const arrow = showArrow && (jsxRuntime.jsx(react.Tooltip.Arrow, { className: classNames?.arrow }));
17786
18086
  // Detección táctil: NO basta con `(hover: none)`. Muchos móviles (p.ej.
17787
18087
  // Android) reportan `(hover: hover)` y `(hover: none)` da false, dejando el
@@ -18667,10 +18967,6 @@ Object.defineProperty(exports, "TableRow", {
18667
18967
  enumerable: true,
18668
18968
  get: function () { return react.TableRow; }
18669
18969
  });
18670
- Object.defineProperty(exports, "cn", {
18671
- enumerable: true,
18672
- get: function () { return react.cn; }
18673
- });
18674
18970
  Object.defineProperty(exports, "loadIcons", {
18675
18971
  enumerable: true,
18676
18972
  get: function () { return react$1.loadIcons; }
@@ -18795,6 +19091,7 @@ exports.WizardNavigation = WizardNavigation;
18795
19091
  exports.WizardSidebar = WizardSidebar;
18796
19092
  exports.applyCustomPrimaryColor = applyCustomPrimaryColor;
18797
19093
  exports.applyLindaTones = applyLindaTones;
19094
+ exports.cn = cn;
18798
19095
  exports.computeBars = computeBars;
18799
19096
  exports.computeMax = computeMax;
18800
19097
  exports.computeSlices = computeSlices;