@studiolxd/brand 38.17.0 → 40.0.0

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 (141) hide show
  1. package/CHANGELOG.md +141 -0
  2. package/dist/_shared/brandmessagescontext.js +15 -0
  3. package/dist/_shared/calendargrid.js +42 -42
  4. package/dist/_shared/datepicker.js +41 -41
  5. package/dist/_shared/imagecropdialog.js +54 -54
  6. package/dist/_shared/tokens.js +4 -0
  7. package/dist/_types/atoms/StarRating/StarRating.d.ts +87 -30
  8. package/dist/_types/messages/BrandMessages.d.ts +26 -0
  9. package/dist/_types/messages/BrandMessagesContext.d.ts +21 -0
  10. package/dist/_types/messages/BrandMessagesProvider.d.ts +46 -0
  11. package/dist/_types/messages/index.d.ts +5 -0
  12. package/dist/_types/molecules/Card/Card.d.ts +12 -1
  13. package/dist/_types/molecules/ConfirmDialog/ConfirmDialog.d.ts +42 -2
  14. package/dist/_types/molecules/Pagination/Pagination.d.ts +40 -23
  15. package/dist/_types/organisms/DataTable/DataTable.d.ts +3 -2
  16. package/dist/accordion.js +26 -26
  17. package/dist/alert.js +26 -26
  18. package/dist/annotation-thread.js +1 -1
  19. package/dist/app-header.js +8 -8
  20. package/dist/app-launcher.js +34 -34
  21. package/dist/app-shell.js +14 -14
  22. package/dist/assistant-message.js +8 -8
  23. package/dist/async-multi-select-field.js +9 -9
  24. package/dist/async-multi-select.js +40 -40
  25. package/dist/async-select-field.js +9 -9
  26. package/dist/async-select.js +64 -64
  27. package/dist/avatar-upload.js +40 -40
  28. package/dist/avatar.js +5 -5
  29. package/dist/banner.js +9 -9
  30. package/dist/brand.css +11 -2
  31. package/dist/button.js +7 -7
  32. package/dist/calendar-planner.js +16 -16
  33. package/dist/calendar.js +38 -38
  34. package/dist/card.js +28 -29
  35. package/dist/carousel.js +19 -19
  36. package/dist/chart.js +137 -137
  37. package/dist/chat-shell.js +23 -23
  38. package/dist/checkbox-field.js +11 -11
  39. package/dist/checkbox.js +7 -7
  40. package/dist/close-button.js +6 -6
  41. package/dist/code-block.js +15 -15
  42. package/dist/code.js +5 -5
  43. package/dist/collapsible.js +1 -1
  44. package/dist/columns.js +7 -7
  45. package/dist/command-palette.js +14 -14
  46. package/dist/confirm-dialog.css +1 -1
  47. package/dist/confirm-dialog.js +65 -42
  48. package/dist/connector-auth-shell.js +9 -9
  49. package/dist/consent.js +23 -23
  50. package/dist/container.js +6 -6
  51. package/dist/conversation-list.js +19 -19
  52. package/dist/conversation-thread.js +15 -15
  53. package/dist/copy-button.js +9 -9
  54. package/dist/copyable-value.js +17 -17
  55. package/dist/data-table.js +29 -29
  56. package/dist/date-picker-field.js +9 -9
  57. package/dist/date-time-field.js +12 -12
  58. package/dist/description-list.js +12 -12
  59. package/dist/docs-search.js +1 -1
  60. package/dist/dots-button.js +7 -7
  61. package/dist/dropdown-field.js +13 -13
  62. package/dist/email.js +44 -44
  63. package/dist/error-text.js +4 -4
  64. package/dist/field-row.js +20 -20
  65. package/dist/figure.js +8 -8
  66. package/dist/file-upload-field.js +9 -9
  67. package/dist/file-upload.js +29 -29
  68. package/dist/filter-bar.js +10 -10
  69. package/dist/floating-dock.js +17 -17
  70. package/dist/form-field.js +43 -43
  71. package/dist/form.js +14 -14
  72. package/dist/heading.js +5 -5
  73. package/dist/input-field.js +20 -20
  74. package/dist/input-phone-field.js +9 -9
  75. package/dist/input-phone.js +19 -19
  76. package/dist/input.js +5 -5
  77. package/dist/kbd.js +5 -5
  78. package/dist/label.js +5 -5
  79. package/dist/link.js +7 -7
  80. package/dist/list.js +7 -7
  81. package/dist/menu-button.js +7 -7
  82. package/dist/message-bubble.js +5 -5
  83. package/dist/message-composer.js +13 -13
  84. package/dist/messages.js +12 -0
  85. package/dist/multi-select-field.js +9 -9
  86. package/dist/multi-select.js +52 -52
  87. package/dist/notification-button.js +8 -8
  88. package/dist/notification-panel.js +25 -25
  89. package/dist/number-input-field.js +9 -9
  90. package/dist/number-input.js +11 -11
  91. package/dist/otp-field.js +9 -9
  92. package/dist/otp-input.js +48 -48
  93. package/dist/pagination.js +92 -89
  94. package/dist/paragraph.js +5 -5
  95. package/dist/password-field.js +15 -15
  96. package/dist/prose.js +4 -4
  97. package/dist/public-page-shell.js +11 -11
  98. package/dist/radio-field.js +11 -11
  99. package/dist/radio-group.js +5 -5
  100. package/dist/radio.js +5 -5
  101. package/dist/scroll-area.js +11 -11
  102. package/dist/search-form.js +8 -8
  103. package/dist/select-field.js +9 -9
  104. package/dist/select.js +85 -85
  105. package/dist/separator.js +6 -6
  106. package/dist/sidebar.js +16 -16
  107. package/dist/site-header.js +14 -14
  108. package/dist/site-shell.js +6 -6
  109. package/dist/sparkline.js +9 -9
  110. package/dist/star-rating.css +1 -1
  111. package/dist/star-rating.js +55 -41
  112. package/dist/stat-tile.js +12 -12
  113. package/dist/steps.js +32 -32
  114. package/dist/switcher-field.js +13 -13
  115. package/dist/switcher.js +8 -8
  116. package/dist/table-of-contents.js +14 -14
  117. package/dist/tag.js +5 -5
  118. package/dist/text.js +7 -7
  119. package/dist/textarea-field.js +11 -11
  120. package/dist/textarea.js +5 -5
  121. package/dist/time-field.js +9 -9
  122. package/dist/time-select.js +17 -17
  123. package/dist/toaster.js +16 -16
  124. package/dist/toggle-group.js +7 -7
  125. package/dist/toggle.js +5 -5
  126. package/dist/tokens.css +11 -2
  127. package/dist/tooltip.js +16 -16
  128. package/dist/tree-view.js +41 -41
  129. package/dist/uptime-bars.js +34 -34
  130. package/dist/user-message.js +8 -8
  131. package/dist/visually-hidden.js +5 -5
  132. package/package.json +5 -1
  133. package/src/tokens/components/description-list.css +1 -1
  134. package/src/tokens/components/star-rating.css +5 -0
  135. package/src/tokens/molecules/confirm-dialog.css +1 -0
  136. package/src/tokens/scss/components/_description-list.scss +1 -1
  137. package/src/tokens/scss/components/_star-rating.scss +3 -0
  138. package/src/tokens/scss/molecules/_confirm-dialog.scss +1 -0
  139. package/src/tokens/surface-invert.css +2 -0
  140. package/src/tokens/surface-public.css +1 -0
  141. package/src/tokens/tokens.json +4 -0
package/CHANGELOG.md CHANGED
@@ -7,6 +7,147 @@ El paquete sigue [semver](https://semver.org/lang/es/): **patch** para bug fixes
7
7
  regeneración de `dist`, **minor** para componentes/props/variantes/tokens nuevos, **major**
8
8
  para breaking changes.
9
9
 
10
+ ## [40.0.0] — 2026-09-15
11
+
12
+ > **Major.** El sistema estrena **proveedor de textos**: un catálogo que se monta una vez
13
+ > en la raíz de la aplicación y del que los componentes leen lo que pintan. `Pagination`
14
+ > es el primero en usarlo, y con él pierde sus textos castellano por defecto.
15
+
16
+ ### El proveedor de textos, y por qué
17
+
18
+ Hasta hoy, todo texto que un componente emite por su cuenta venía en una prop opcional con
19
+ el castellano puesto. En una suite de doce aplicaciones que hablan seis idiomas eso es un
20
+ fallo silencioso: el componente pinta «Cancelar» dentro de una página en francés, no falla
21
+ nada, ningún test lo ve, y se ve bien estando mal. Un inventario de hoy midió el tamaño del
22
+ asunto: **111 componentes, 310 props de texto**.
23
+
24
+ El mecanismo son cuatro piezas en `src/messages/`, y se importa desde
25
+ `@studiolxd/brand/messages`:
26
+
27
+ - **`BrandMessages`** — el contrato, anidado por componente. **El tipo nace aquí**, en el
28
+ sistema, y el catálogo de la aplicación lo satisface; no al revés, porque un sistema que
29
+ necesitara un paquete ajeno para declarar lo que necesita dejaría de sostenerse solo.
30
+ - **`BrandMessagesProvider`** — se monta una vez, con el catálogo entero. Todas las claves
31
+ de cada espacio son **obligatorias**: si una aplicación se deja una, no compila.
32
+ - **`useBrandMessages`** — el lector, para los componentes.
33
+
34
+ El orden es **prop → proveedor → error**, y no hay cuarto escalón: ahí es donde estaba el
35
+ castellano, y de ahí se ha ido. El error se lanza **donde el texto se pinta**, así que un
36
+ paginador sin selector de registros no exige el texto del selector, y quien ya pasa todas
37
+ las props sigue funcionando sin montar nada.
38
+
39
+ Lo que se gana, dicho sin adornos: una clave que falta es un error de compilación; un
40
+ proveedor sin montar es un fallo ruidoso e inmediato. Ninguno de los dos es un texto mudo
41
+ en el idioma equivocado que nadie descubre.
42
+
43
+ ### Breaking — `Pagination` ya no trae sus textos
44
+
45
+ Sus ocho textos —`label`, `pagesGroup`, `previous`, `next`, `goToPage`, `perPage`,
46
+ `total` y el `allOption` del selector, que estaba cableado dentro— salen del proveedor o de
47
+ las props. **Un `Pagination` sin proveedor y sin props de texto lanza en render.** Siete de
48
+ las ocho claves ya existían tal cual en el espacio `pagination` de los catálogos de la
49
+ suite; la octava se ha escrito en los seis idiomas.
50
+
51
+ Alcanza a quien lo compone: `DataTable` monta un `Pagination`, así que una pantalla con
52
+ tabla necesita el proveedor aunque no pagine a mano.
53
+
54
+ ### Storybook: un fixture, no un default por la puerta de atrás
55
+
56
+ Las historias se envuelven en un decorador que monta el proveedor con un fixture
57
+ castellano. No es el default de antes con otro nombre, y la diferencia es la que da sentido
58
+ a todo lo anterior: el fixture vive fuera de `src/`, no es punto de entrada, ningún
59
+ componente lo importa y `package.json#files` solo publica `dist/`, `src/tokens/` y el
60
+ registro de cambios — así que **ningún código de un consumidor puede caer en él**. Un
61
+ default viaja dentro del paquete y se alcanza en ejecución; un fixture no. Las cuatro
62
+ condiciones las vigila un test, no un comentario.
63
+
64
+ ### Sobre lo que viene
65
+
66
+ Esta versión es **una rebanada vertical**: una sola familia llevada hasta el final, con sus
67
+ defaults retirados, para probar el patrón antes de comprometer los otros 110 componentes.
68
+ El patrón aguanta. Lo que no es gratis, y conviene saberlo: retirar el default es
69
+ incompatible por componente y se propaga a quien lo compone, así que lo que sigue se
70
+ ordenará **por familias y con versión mayor**, no componente a componente.
71
+
72
+ ## [39.0.0] — 2026-09-15
73
+
74
+ > **Major.** `StarRating` deja de traer sus textos puestos: ahora se le pasan, y el
75
+ > compilador lo exige. Además, la flecha de la tarjeta enlazada es opcional, el
76
+ > `ConfirmDialog` sabe pedir una frase de confirmación y el término de una lista de
77
+ > descripción deja de verse diminuto en superficie pública.
78
+
79
+ ### Breaking — `StarRating`: el componente recibe su texto
80
+
81
+ Los cinco textos pasan a ser props **obligatorias y sin valor por defecto**, exigidas por
82
+ el tipo en cuanto el componente puede emitirlas: `valueLabel` siempre en lectura;
83
+ `countLabel` en cuanto se pasa `reviewCount`; `emptyLabel` en cuanto `value` puede ser
84
+ `null`; `optionLabel` y `groupLabel` en modo entrada. El corte lo hace el tipo, no la
85
+ documentación: si el valor de tu API es `number` no se te pide `emptyLabel`, y el día que
86
+ pase a `number | null` el compilador te lo reclama en vez de dejarte pintar cinco estrellas
87
+ vacías —que es el dibujo de «valorado con 0», una nota real y la peor de todas.
88
+
89
+ Van con ello otros tres cambios incompatibles: **`value` pasa a obligatorio** en lectura
90
+ (antes omitirlo pintaba cero estrellas, o sea un olvido disfrazado de valoración);
91
+ **`locale` desaparece**, porque el componente ya no escribe ninguna cifra y quien compone
92
+ la frase es quien la escribe; y el modo se elige con `readOnly` **literal**.
93
+
94
+ Qué hacer al actualizar: `StarRating.mdx` § «Qué se rompe al actualizar» trae el código
95
+ exacto de los textos que había, para copiarlos tal cual si tu app está en castellano.
96
+
97
+ > La regla del repo sobre textos de componente —prop opcional con el castellano por
98
+ > defecto— queda en revisión: hay ya cuatro piezas que no la cumplen, y lo que decida esa
99
+ > revisión se escribirá en su sitio, no aquí.
100
+
101
+ ### `Card`: la flecha la manda `ctaLabel`
102
+
103
+ En modo enlace, la flecha y el nombre accesible del CTA aparecen **con `ctaLabel` y solo
104
+ con él**. Sin la prop no hay ninguno de los dos: una rejilla de catálogo donde cada tarjeta
105
+ repite la misma flecha es ruido, no señal. No hay `showArrow`/`hideArrow` — una sola cosa
106
+ que decidir, no dos que se puedan contradecir. Ningún consumidor del repo se ve afectado:
107
+ los veinte usos del modo enlace ya pasaban `ctaLabel`.
108
+
109
+ ### `ConfirmDialog`: frase de confirmación
110
+
111
+ Nueva prop `confirmPhrase` —la frase exacta que hay que teclear para que la acción se
112
+ habilite— con `confirmPhraseLabel` y `confirmPhraseMismatch`, obligatorias en cuanto se usa
113
+ la primera, porque el rótulo es donde el producto dice QUÉ hay que escribir y eso el diálogo
114
+ no lo sabe. El botón de confirmar nace apagado; el error sale **tras un intento** —salir del
115
+ campo con algo escrito, o pulsar Intro—, nunca mientras se teclea, y seguir escribiendo lo
116
+ retira. Con la frase puesta, Intro confirma desde el propio campo. La comparación perdona
117
+ los espacios de los extremos y nada más: ni caja ni acentos, que es de lo que vive la
118
+ barrera. Con la frase, el foco entra en el campo y no en «Cancelar»: lo que la regla del
119
+ foco evita es que un Intro de más caiga sobre la acción que destruye, y aquí el botón nace
120
+ apagado.
121
+
122
+ Existía porque faltaba: tres sitios de la suite resolvían este patrón de tres maneras
123
+ distintas, dos dejando el botón vivo y lanzando desde `onConfirm` para que el diálogo no se
124
+ cerrara, y otro saltándose el `ConfirmDialog` entero para montar un `Modal` a mano.
125
+
126
+ ### `DescriptionList`: el término, proporcionado en superficie pública
127
+
128
+ El bloque `.site-shell` subía el valor a `--text-font-size` (20px) y **no tocaba el
129
+ término**, que se quedaba en `--label-font-size` (14px): dentro de `AppShell` el par es
130
+ 14/16 y no canta, en superficie pública era 14/20 y el término se veía diminuto al lado de
131
+ su valor. El término pasa a `{text.paragraph.small.font-size}`, que ES el peldaño
132
+ inmediatamente por debajo del valor por definición: **la superficie de aplicación queda
133
+ idéntica** (14/16) y la pública pasa a 16/20. Cambia el aspecto de toda ficha pública de la
134
+ suite que monte una `DescriptionList` dentro de un `SiteShell`, incluidas las pantallas de
135
+ conexión de conector.
136
+
137
+ No había ninguna historia que montara una `DescriptionList` dentro de un `SiteShell` — por
138
+ eso nadie lo había visto. Ahora la hay. Y `Typography.mdx` gana el escalón que le faltaba a
139
+ la doctrina: **«hereda un peldaño por debajo»**, entre «hereda el cuerpo» y «talla propia»,
140
+ donde encajan el término de la ficha, el Breadcrumb, el pie de `Figure`, la ayuda de
141
+ formulario y el índice del `Accordion`.
142
+
143
+ ### Publicación
144
+
145
+ `scripts/publish-npm.mjs` sube el paquete con `npm stage publish` en vez de publicarlo
146
+ directo, y termina imprimiendo el identificador del stage: el segundo factor se difiere a
147
+ una persona, que aprueba con su sesión. El camino del token «Automation» queda documentado
148
+ como lo que es —npm está restringiendo los tokens que se saltan el 2FA— y el ritual de
149
+ `release:check` + tag no cambia.
150
+
10
151
  ## [38.17.0] — 2026-09-15
11
152
 
12
153
  > **Minor.** En `ChatShell`, el botón que despliega el cajón de conversaciones
@@ -0,0 +1,15 @@
1
+ import { createContext as e, useContext as t } from "react";
2
+ //#region src/stories/messages/BrandMessagesContext.ts
3
+ var n = e(null);
4
+ function r(e) {
5
+ let r = t(n);
6
+ return function(t, n) {
7
+ if (n !== void 0) return n;
8
+ if (!r) throw Error(`@studiolxd/brand: falta el texto «${String(e)}.${String(t)}» y no hay catálogo montado. Monta <BrandMessagesProvider> en la raíz de la aplicación con los textos del idioma vigente, o pasa la prop suelta en este uso concreto.`);
9
+ let i = r[e]?.[t];
10
+ if (i === void 0) throw Error(`@studiolxd/brand: el catálogo montado no trae «${String(e)}.${String(t)}».`);
11
+ return i;
12
+ };
13
+ }
14
+ //#endregion
15
+ export { r as n, n as t };
@@ -1,6 +1,6 @@
1
1
  import { Icon as e } from "../icon.js";
2
- import { jsx as t, jsxs as n } from "react/jsx-runtime";
3
- import { useCallback as r, useEffect as i, useMemo as a, useRef as o, useState as s } from "react";
2
+ import { useCallback as t, useEffect as n, useMemo as r, useRef as i, useState as a } from "react";
3
+ import { jsx as o, jsxs as s } from "react/jsx-runtime";
4
4
  //#region src/stories/molecules/_shared/calendarGrid.tsx
5
5
  function c(e, t) {
6
6
  return e.getFullYear() === t.getFullYear() && e.getMonth() === t.getMonth() && e.getDate() === t.getDate();
@@ -51,57 +51,57 @@ function p(e, t = "narrow") {
51
51
  };
52
52
  });
53
53
  }
54
- function m({ block: e, rowModifier: n, weekdays: r }) {
55
- return /* @__PURE__ */ t("div", {
54
+ function m({ block: e, rowModifier: t, weekdays: n }) {
55
+ return /* @__PURE__ */ o("div", {
56
56
  role: "row",
57
- className: [`${e}__row`, n && `${e}__row--${n}`].filter(Boolean).join(" "),
58
- children: r.map(({ short: n, long: r }) => /* @__PURE__ */ t("div", {
57
+ className: [`${e}__row`, t && `${e}__row--${t}`].filter(Boolean).join(" "),
58
+ children: n.map(({ short: t, long: n }) => /* @__PURE__ */ o("div", {
59
59
  role: "columnheader",
60
60
  className: `${e}__weekday`,
61
- "aria-label": r,
62
- children: /* @__PURE__ */ t("abbr", {
63
- title: r,
64
- children: n
61
+ "aria-label": n,
62
+ children: /* @__PURE__ */ o("abbr", {
63
+ title: n,
64
+ children: t
65
65
  })
66
- }, r))
66
+ }, n))
67
67
  });
68
68
  }
69
- function h({ block: r, title: i, titleId: a, navigable: o = !0, previousLabel: s, nextLabel: c, prevDisabled: l = !1, nextDisabled: u = !1, onPrev: d, onNext: f, chevronSize: p, onTitleClick: m, titleExpanded: h, titleRef: g, children: _ }) {
70
- return /* @__PURE__ */ n("div", {
71
- className: `${r}__header`,
69
+ function h({ block: t, title: n, titleId: r, navigable: i = !0, previousLabel: a, nextLabel: c, prevDisabled: l = !1, nextDisabled: u = !1, onPrev: d, onNext: f, chevronSize: p, onTitleClick: m, titleExpanded: h, titleRef: g, children: _ }) {
70
+ return /* @__PURE__ */ s("div", {
71
+ className: `${t}__header`,
72
72
  children: [
73
- o && /* @__PURE__ */ t("button", {
73
+ i && /* @__PURE__ */ o("button", {
74
74
  type: "button",
75
- className: `${r}__nav`,
76
- "aria-label": s,
75
+ className: `${t}__nav`,
76
+ "aria-label": a,
77
77
  disabled: l,
78
78
  onClick: d,
79
- children: /* @__PURE__ */ t(e, {
79
+ children: /* @__PURE__ */ o(e, {
80
80
  name: "chevron",
81
81
  size: p,
82
- className: `${r}__chevron--prev`
82
+ className: `${t}__chevron--prev`
83
83
  })
84
84
  }),
85
- /* @__PURE__ */ t("h2", {
86
- id: a,
87
- className: `${r}__title`,
85
+ /* @__PURE__ */ o("h2", {
86
+ id: r,
87
+ className: `${t}__title`,
88
88
  "aria-live": "polite",
89
- children: m ? /* @__PURE__ */ t("button", {
89
+ children: m ? /* @__PURE__ */ o("button", {
90
90
  type: "button",
91
91
  ref: g,
92
- className: `${r}__title-button`,
92
+ className: `${t}__title-button`,
93
93
  "aria-expanded": h,
94
94
  onClick: m,
95
- children: i
96
- }) : i
95
+ children: n
96
+ }) : n
97
97
  }),
98
- o && /* @__PURE__ */ t("button", {
98
+ i && /* @__PURE__ */ o("button", {
99
99
  type: "button",
100
- className: `${r}__nav`,
100
+ className: `${t}__nav`,
101
101
  "aria-label": c,
102
102
  disabled: u,
103
103
  onClick: f,
104
- children: /* @__PURE__ */ t(e, {
104
+ children: /* @__PURE__ */ o(e, {
105
105
  name: "chevron",
106
106
  size: p
107
107
  })
@@ -123,29 +123,29 @@ function v(e, t) {
123
123
  function y(e) {
124
124
  return `${e.getFullYear()}-${e.getMonth()}-${e.getDate()}`;
125
125
  }
126
- function b({ month: e, onMonthChange: t, selected: n, onActivate: u, minDate: d, maxDate: f }) {
127
- let [p, m] = s(() => n ?? /* @__PURE__ */ new Date()), h = o(/* @__PURE__ */ new Map()), b = o(!1), x = a(() => {
126
+ function b({ month: e, onMonthChange: o, selected: s, onActivate: u, minDate: d, maxDate: f }) {
127
+ let [p, m] = a(() => s ?? /* @__PURE__ */ new Date()), h = i(/* @__PURE__ */ new Map()), b = i(!1), x = r(() => {
128
128
  if (l(p, e)) return p;
129
- if (n && l(n, e)) return n;
129
+ if (s && l(s, e)) return s;
130
130
  let t = /* @__PURE__ */ new Date();
131
131
  return l(t, e) ? t : new Date(e.getFullYear(), e.getMonth(), 1);
132
132
  }, [
133
133
  p,
134
134
  e,
135
- n
135
+ s
136
136
  ]);
137
- i(() => {
137
+ n(() => {
138
138
  b.current && (b.current = !1, h.current.get(y(x))?.focus());
139
139
  }, [x]);
140
- let S = r((n) => {
141
- let r = g(n, d, f);
142
- b.current = !0, m(r), l(r, e) || t(new Date(r.getFullYear(), r.getMonth(), 1));
140
+ let S = t((t) => {
141
+ let n = g(t, d, f);
142
+ b.current = !0, m(n), l(n, e) || o(new Date(n.getFullYear(), n.getMonth(), 1));
143
143
  }, [
144
144
  f,
145
145
  d,
146
146
  e,
147
- t
148
- ]), C = r((e) => {
147
+ o
148
+ ]), C = t((e) => {
149
149
  let t = x, n = null;
150
150
  switch (e.key) {
151
151
  case "ArrowLeft":
@@ -183,16 +183,16 @@ function b({ month: e, onMonthChange: t, selected: n, onActivate: u, minDate: d,
183
183
  x,
184
184
  S,
185
185
  u
186
- ]), w = r((e) => (t) => {
186
+ ]), w = t((e) => (t) => {
187
187
  let n = y(e);
188
188
  t ? h.current.set(n, t) : h.current.delete(n);
189
189
  }, []);
190
190
  return {
191
191
  activeDate: x,
192
- isTabbable: r((e) => c(e, x), [x]),
192
+ isTabbable: t((e) => c(e, x), [x]),
193
193
  cellRef: w,
194
194
  onKeyDown: C,
195
- onCellFocus: r((e) => m(e), [])
195
+ onCellFocus: t((e) => m(e), [])
196
196
  };
197
197
  }
198
198
  //#endregion
@@ -3,23 +3,23 @@ import { Icon as e } from "../icon.js";
3
3
  import { Input as t } from "../input.js";
4
4
  import { Popover as n } from "../popover.js";
5
5
  import { Calendar as r } from "../calendar.js";
6
- import { jsx as i, jsxs as a } from "react/jsx-runtime";
7
- import { forwardRef as o, useCallback as s, useId as c, useMemo as l, useRef as ee, useState as u } from "react";
6
+ import { forwardRef as i, useCallback as a, useId as o, useMemo as s, useRef as c, useState as l } from "react";
7
+ import { jsx as u, jsxs as d } from "react/jsx-runtime";
8
8
  //#region src/stories/molecules/DatePicker/dateMask.ts
9
- var d = {
9
+ var f = {
10
10
  day: "dd",
11
11
  month: "mm",
12
12
  year: "aaaa"
13
- }, f = /[‎‏؜]/g, p = new Date(2026, 8, 25);
14
- function m(e, t) {
13
+ }, p = /[‎‏؜]/g, m = new Date(2026, 8, 25);
14
+ function h(e, t) {
15
15
  return String(e).padStart(t, "0");
16
16
  }
17
- function h(e) {
17
+ function g(e) {
18
18
  let t = new Intl.DateTimeFormat(e, {
19
19
  day: "2-digit",
20
20
  month: "2-digit",
21
21
  year: "numeric"
22
- }).formatToParts(p), n = t.filter((e) => e.type === "day" || e.type === "month" || e.type === "year").map((e) => e.type), r = t.find((e) => e.type === "literal" && e.value.replace(f, "").trim() !== "")?.value.replace(f, "").trim() || "/", i = {
22
+ }).formatToParts(m), n = t.filter((e) => e.type === "day" || e.type === "month" || e.type === "year").map((e) => e.type), r = t.find((e) => e.type === "literal" && e.value.replace(p, "").trim() !== "")?.value.replace(p, "").trim() || "/", i = {
23
23
  day: 2,
24
24
  month: 2,
25
25
  year: 4
@@ -30,13 +30,13 @@ function h(e) {
30
30
  month: e.getMonth() + 1,
31
31
  year: e.getFullYear()
32
32
  };
33
- return n.map((e) => m(t[e], i[e])).join(r);
33
+ return n.map((e) => h(t[e], i[e])).join(r);
34
34
  }
35
35
  function o(e) {
36
36
  return n.map((t) => e[t]).join(r);
37
37
  }
38
38
  function s(e) {
39
- let t = e.replace(f, "").trim();
39
+ let t = e.replace(p, "").trim();
40
40
  if (/\p{L}/u.test(t)) return null;
41
41
  let r = t.split(/\D+/).filter(Boolean);
42
42
  if (r.length !== 3) return null;
@@ -57,25 +57,25 @@ function h(e) {
57
57
  }
58
58
  //#endregion
59
59
  //#region src/stories/molecules/DatePicker/DatePicker.tsx
60
- function g(e) {
60
+ function _(e) {
61
61
  return `${String(e.getFullYear()).padStart(4, "0")}-${String(e.getMonth() + 1).padStart(2, "0")}-${String(e.getDate()).padStart(2, "0")}`;
62
62
  }
63
- var _ = o(function({ value: o, onChange: f, placeholder: p, maskLetters: m = d, invalidMessage: _ = "Escribe una fecha completa, con el día, el mes y el año.", openCalendarLabel: v = "Abrir calendario", minDate: y, maxDate: b, disabledDates: x, size: S = "md", disabled: C, readOnly: w, error: T = !1, locale: E = "es-ES", id: D, name: O, describedBy: te, "aria-describedby": ne, "aria-label": re, calendarLabel: k = "Calendario", previousMonthLabel: A, nextMonthLabel: j, previousYearsLabel: M, nextYearsLabel: N, yearGridLabel: P, gridLabel: F, onBlur: I, className: L }, R) {
64
- let [z, B] = u(!1), V = l(() => h(E), [E]), H = o instanceof Date ? V.format(o) : "", [U, W] = u(H), [G, K] = u(H);
63
+ var v = i(function({ value: i, onChange: p, placeholder: m, maskLetters: h = f, invalidMessage: v = "Escribe una fecha completa, con el día, el mes y el año.", openCalendarLabel: y = "Abrir calendario", minDate: b, maxDate: ee, disabledDates: x, size: S = "md", disabled: C, readOnly: w, error: T = !1, locale: E = "es-ES", id: D, name: O, describedBy: k, "aria-describedby": te, "aria-label": ne, calendarLabel: A = "Calendario", previousMonthLabel: re, nextMonthLabel: j, previousYearsLabel: M, nextYearsLabel: N, yearGridLabel: P, gridLabel: F, onBlur: I, className: L }, R) {
64
+ let [z, B] = l(!1), V = s(() => g(E), [E]), H = i instanceof Date ? V.format(i) : "", [U, W] = l(H), [G, K] = l(H);
65
65
  H !== G && (K(H), W(H));
66
- let q = ee(null), J = s((e) => {
66
+ let q = c(null), J = a((e) => {
67
67
  q.current = e, typeof R == "function" ? R(e) : R && (R.current = e);
68
- }, [R]), Y = U.trim(), X = Y ? V.parse(U) : null, Z = Y !== "" && !X, ie = T || Z, Q = `${c()}-date-picker-invalid`, ae = [te ?? ne, Z ? Q : void 0].filter(Boolean).join(" ") || void 0, oe = s((e) => {
68
+ }, [R]), Y = U.trim(), X = Y ? V.parse(U) : null, Z = Y !== "" && !X, ie = T || Z, Q = `${o()}-date-picker-invalid`, ae = [k ?? te, Z ? Q : void 0].filter(Boolean).join(" ") || void 0, oe = a((e) => {
69
69
  (w || C) && e || B(e);
70
- }, [C, w]), $ = s((e) => {
70
+ }, [C, w]), $ = a((e) => {
71
71
  let t = e.target.value;
72
72
  if (W(t), t.trim() === "") {
73
- f?.(null);
73
+ p?.(null);
74
74
  return;
75
75
  }
76
76
  let n = V.parse(t);
77
- n && f?.(n);
78
- }, [V, f]), se = s((e) => {
77
+ n && p?.(n);
78
+ }, [V, p]), se = a((e) => {
79
79
  if (e.key === "ArrowDown" && !w && !C) {
80
80
  e.preventDefault(), B(!0);
81
81
  return;
@@ -85,37 +85,37 @@ var _ = o(function({ value: o, onChange: f, placeholder: p, maskLetters: m = d,
85
85
  C,
86
86
  z,
87
87
  w
88
- ]), ce = s((e) => {
89
- W(V.format(e)), f?.(e), B(!1), requestAnimationFrame(() => q.current?.focus());
90
- }, [V, f]), le = /* @__PURE__ */ i("button", {
88
+ ]), ce = a((e) => {
89
+ W(V.format(e)), p?.(e), B(!1), requestAnimationFrame(() => q.current?.focus());
90
+ }, [V, p]), le = /* @__PURE__ */ u("button", {
91
91
  type: "button",
92
92
  className: "date-picker__button",
93
- "aria-label": v,
93
+ "aria-label": y,
94
94
  "aria-haspopup": "dialog",
95
95
  "aria-expanded": z,
96
96
  disabled: C,
97
97
  tabIndex: w ? -1 : void 0,
98
- children: /* @__PURE__ */ i(e, {
98
+ children: /* @__PURE__ */ u(e, {
99
99
  name: "calendar",
100
100
  size: "sm",
101
101
  className: "date-picker__glyph"
102
102
  })
103
103
  });
104
- return /* @__PURE__ */ a("div", {
104
+ return /* @__PURE__ */ d("div", {
105
105
  className: [
106
106
  "date-picker",
107
107
  S === "md" ? "" : `date-picker--${S}`,
108
108
  L ?? ""
109
109
  ].filter(Boolean).join(" "),
110
110
  children: [
111
- O && /* @__PURE__ */ i("input", {
111
+ O && /* @__PURE__ */ u("input", {
112
112
  type: "hidden",
113
113
  name: O,
114
- value: o instanceof Date ? g(o) : ""
114
+ value: i instanceof Date ? _(i) : ""
115
115
  }),
116
- /* @__PURE__ */ a("div", {
116
+ /* @__PURE__ */ d("div", {
117
117
  className: "date-picker__control",
118
- children: [/* @__PURE__ */ i(t, {
118
+ children: [/* @__PURE__ */ u(t, {
119
119
  ref: J,
120
120
  id: D,
121
121
  className: "date-picker__input",
@@ -125,48 +125,48 @@ var _ = o(function({ value: o, onChange: f, placeholder: p, maskLetters: m = d,
125
125
  size: S,
126
126
  error: ie,
127
127
  value: U,
128
- placeholder: p ?? V.mask(m),
128
+ placeholder: m ?? V.mask(h),
129
129
  disabled: C,
130
130
  readOnly: w,
131
- "aria-label": re,
131
+ "aria-label": ne,
132
132
  "aria-describedby": ae,
133
133
  onChange: $,
134
134
  onKeyDown: se,
135
135
  onBlur: I
136
- }), /* @__PURE__ */ i(n, {
136
+ }), /* @__PURE__ */ u(n, {
137
137
  trigger: le,
138
- label: k,
138
+ label: A,
139
139
  open: z,
140
140
  onOpenChange: oe,
141
141
  side: "bottom",
142
142
  align: "end",
143
143
  sideOffset: -1,
144
144
  className: "date-picker__popover",
145
- children: /* @__PURE__ */ i(r, {
146
- value: X ?? o ?? null,
145
+ children: /* @__PURE__ */ u(r, {
146
+ value: X ?? i ?? null,
147
147
  onChange: ce,
148
- gridLabel: F ?? k,
149
- previousMonthLabel: A,
148
+ gridLabel: F ?? A,
149
+ previousMonthLabel: re,
150
150
  nextMonthLabel: j,
151
151
  previousYearsLabel: M,
152
152
  nextYearsLabel: N,
153
153
  yearGridLabel: P,
154
- minDate: y,
155
- maxDate: b,
154
+ minDate: b,
155
+ maxDate: ee,
156
156
  disabledDates: x,
157
157
  locale: E,
158
158
  size: S
159
159
  })
160
160
  })]
161
161
  }),
162
- Z && /* @__PURE__ */ i("span", {
162
+ Z && /* @__PURE__ */ u("span", {
163
163
  id: Q,
164
164
  className: "date-picker__message",
165
165
  role: "alert",
166
- children: _
166
+ children: v
167
167
  })
168
168
  ]
169
169
  });
170
170
  });
171
171
  //#endregion
172
- export { _ as t };
172
+ export { v as t };