@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.
- package/CHANGELOG.md +141 -0
- package/dist/_shared/brandmessagescontext.js +15 -0
- package/dist/_shared/calendargrid.js +42 -42
- package/dist/_shared/datepicker.js +41 -41
- package/dist/_shared/imagecropdialog.js +54 -54
- package/dist/_shared/tokens.js +4 -0
- package/dist/_types/atoms/StarRating/StarRating.d.ts +87 -30
- package/dist/_types/messages/BrandMessages.d.ts +26 -0
- package/dist/_types/messages/BrandMessagesContext.d.ts +21 -0
- package/dist/_types/messages/BrandMessagesProvider.d.ts +46 -0
- package/dist/_types/messages/index.d.ts +5 -0
- package/dist/_types/molecules/Card/Card.d.ts +12 -1
- package/dist/_types/molecules/ConfirmDialog/ConfirmDialog.d.ts +42 -2
- package/dist/_types/molecules/Pagination/Pagination.d.ts +40 -23
- package/dist/_types/organisms/DataTable/DataTable.d.ts +3 -2
- package/dist/accordion.js +26 -26
- package/dist/alert.js +26 -26
- package/dist/annotation-thread.js +1 -1
- package/dist/app-header.js +8 -8
- package/dist/app-launcher.js +34 -34
- package/dist/app-shell.js +14 -14
- package/dist/assistant-message.js +8 -8
- package/dist/async-multi-select-field.js +9 -9
- package/dist/async-multi-select.js +40 -40
- package/dist/async-select-field.js +9 -9
- package/dist/async-select.js +64 -64
- package/dist/avatar-upload.js +40 -40
- package/dist/avatar.js +5 -5
- package/dist/banner.js +9 -9
- package/dist/brand.css +11 -2
- package/dist/button.js +7 -7
- package/dist/calendar-planner.js +16 -16
- package/dist/calendar.js +38 -38
- package/dist/card.js +28 -29
- package/dist/carousel.js +19 -19
- package/dist/chart.js +137 -137
- package/dist/chat-shell.js +23 -23
- package/dist/checkbox-field.js +11 -11
- package/dist/checkbox.js +7 -7
- package/dist/close-button.js +6 -6
- package/dist/code-block.js +15 -15
- package/dist/code.js +5 -5
- package/dist/collapsible.js +1 -1
- package/dist/columns.js +7 -7
- package/dist/command-palette.js +14 -14
- package/dist/confirm-dialog.css +1 -1
- package/dist/confirm-dialog.js +65 -42
- package/dist/connector-auth-shell.js +9 -9
- package/dist/consent.js +23 -23
- package/dist/container.js +6 -6
- package/dist/conversation-list.js +19 -19
- package/dist/conversation-thread.js +15 -15
- package/dist/copy-button.js +9 -9
- package/dist/copyable-value.js +17 -17
- package/dist/data-table.js +29 -29
- package/dist/date-picker-field.js +9 -9
- package/dist/date-time-field.js +12 -12
- package/dist/description-list.js +12 -12
- package/dist/docs-search.js +1 -1
- package/dist/dots-button.js +7 -7
- package/dist/dropdown-field.js +13 -13
- package/dist/email.js +44 -44
- package/dist/error-text.js +4 -4
- package/dist/field-row.js +20 -20
- package/dist/figure.js +8 -8
- package/dist/file-upload-field.js +9 -9
- package/dist/file-upload.js +29 -29
- package/dist/filter-bar.js +10 -10
- package/dist/floating-dock.js +17 -17
- package/dist/form-field.js +43 -43
- package/dist/form.js +14 -14
- package/dist/heading.js +5 -5
- package/dist/input-field.js +20 -20
- package/dist/input-phone-field.js +9 -9
- package/dist/input-phone.js +19 -19
- package/dist/input.js +5 -5
- package/dist/kbd.js +5 -5
- package/dist/label.js +5 -5
- package/dist/link.js +7 -7
- package/dist/list.js +7 -7
- package/dist/menu-button.js +7 -7
- package/dist/message-bubble.js +5 -5
- package/dist/message-composer.js +13 -13
- package/dist/messages.js +12 -0
- package/dist/multi-select-field.js +9 -9
- package/dist/multi-select.js +52 -52
- package/dist/notification-button.js +8 -8
- package/dist/notification-panel.js +25 -25
- package/dist/number-input-field.js +9 -9
- package/dist/number-input.js +11 -11
- package/dist/otp-field.js +9 -9
- package/dist/otp-input.js +48 -48
- package/dist/pagination.js +92 -89
- package/dist/paragraph.js +5 -5
- package/dist/password-field.js +15 -15
- package/dist/prose.js +4 -4
- package/dist/public-page-shell.js +11 -11
- package/dist/radio-field.js +11 -11
- package/dist/radio-group.js +5 -5
- package/dist/radio.js +5 -5
- package/dist/scroll-area.js +11 -11
- package/dist/search-form.js +8 -8
- package/dist/select-field.js +9 -9
- package/dist/select.js +85 -85
- package/dist/separator.js +6 -6
- package/dist/sidebar.js +16 -16
- package/dist/site-header.js +14 -14
- package/dist/site-shell.js +6 -6
- package/dist/sparkline.js +9 -9
- package/dist/star-rating.css +1 -1
- package/dist/star-rating.js +55 -41
- package/dist/stat-tile.js +12 -12
- package/dist/steps.js +32 -32
- package/dist/switcher-field.js +13 -13
- package/dist/switcher.js +8 -8
- package/dist/table-of-contents.js +14 -14
- package/dist/tag.js +5 -5
- package/dist/text.js +7 -7
- package/dist/textarea-field.js +11 -11
- package/dist/textarea.js +5 -5
- package/dist/time-field.js +9 -9
- package/dist/time-select.js +17 -17
- package/dist/toaster.js +16 -16
- package/dist/toggle-group.js +7 -7
- package/dist/toggle.js +5 -5
- package/dist/tokens.css +11 -2
- package/dist/tooltip.js +16 -16
- package/dist/tree-view.js +41 -41
- package/dist/uptime-bars.js +34 -34
- package/dist/user-message.js +8 -8
- package/dist/visually-hidden.js +5 -5
- package/package.json +5 -1
- package/src/tokens/components/description-list.css +1 -1
- package/src/tokens/components/star-rating.css +5 -0
- package/src/tokens/molecules/confirm-dialog.css +1 -0
- package/src/tokens/scss/components/_description-list.scss +1 -1
- package/src/tokens/scss/components/_star-rating.scss +3 -0
- package/src/tokens/scss/molecules/_confirm-dialog.scss +1 -0
- package/src/tokens/surface-invert.css +2 -0
- package/src/tokens/surface-public.css +1 -0
- 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 {
|
|
3
|
-
import {
|
|
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:
|
|
55
|
-
return /* @__PURE__ */
|
|
54
|
+
function m({ block: e, rowModifier: t, weekdays: n }) {
|
|
55
|
+
return /* @__PURE__ */ o("div", {
|
|
56
56
|
role: "row",
|
|
57
|
-
className: [`${e}__row`,
|
|
58
|
-
children:
|
|
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":
|
|
62
|
-
children: /* @__PURE__ */
|
|
63
|
-
title:
|
|
64
|
-
children:
|
|
61
|
+
"aria-label": n,
|
|
62
|
+
children: /* @__PURE__ */ o("abbr", {
|
|
63
|
+
title: n,
|
|
64
|
+
children: t
|
|
65
65
|
})
|
|
66
|
-
},
|
|
66
|
+
}, n))
|
|
67
67
|
});
|
|
68
68
|
}
|
|
69
|
-
function h({ block:
|
|
70
|
-
return /* @__PURE__ */
|
|
71
|
-
className: `${
|
|
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
|
-
|
|
73
|
+
i && /* @__PURE__ */ o("button", {
|
|
74
74
|
type: "button",
|
|
75
|
-
className: `${
|
|
76
|
-
"aria-label":
|
|
75
|
+
className: `${t}__nav`,
|
|
76
|
+
"aria-label": a,
|
|
77
77
|
disabled: l,
|
|
78
78
|
onClick: d,
|
|
79
|
-
children: /* @__PURE__ */
|
|
79
|
+
children: /* @__PURE__ */ o(e, {
|
|
80
80
|
name: "chevron",
|
|
81
81
|
size: p,
|
|
82
|
-
className: `${
|
|
82
|
+
className: `${t}__chevron--prev`
|
|
83
83
|
})
|
|
84
84
|
}),
|
|
85
|
-
/* @__PURE__ */
|
|
86
|
-
id:
|
|
87
|
-
className: `${
|
|
85
|
+
/* @__PURE__ */ o("h2", {
|
|
86
|
+
id: r,
|
|
87
|
+
className: `${t}__title`,
|
|
88
88
|
"aria-live": "polite",
|
|
89
|
-
children: m ? /* @__PURE__ */
|
|
89
|
+
children: m ? /* @__PURE__ */ o("button", {
|
|
90
90
|
type: "button",
|
|
91
91
|
ref: g,
|
|
92
|
-
className: `${
|
|
92
|
+
className: `${t}__title-button`,
|
|
93
93
|
"aria-expanded": h,
|
|
94
94
|
onClick: m,
|
|
95
|
-
children:
|
|
96
|
-
}) :
|
|
95
|
+
children: n
|
|
96
|
+
}) : n
|
|
97
97
|
}),
|
|
98
|
-
|
|
98
|
+
i && /* @__PURE__ */ o("button", {
|
|
99
99
|
type: "button",
|
|
100
|
-
className: `${
|
|
100
|
+
className: `${t}__nav`,
|
|
101
101
|
"aria-label": c,
|
|
102
102
|
disabled: u,
|
|
103
103
|
onClick: f,
|
|
104
|
-
children: /* @__PURE__ */
|
|
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:
|
|
127
|
-
let [p, m] =
|
|
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 (
|
|
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
|
-
|
|
135
|
+
s
|
|
136
136
|
]);
|
|
137
|
-
|
|
137
|
+
n(() => {
|
|
138
138
|
b.current && (b.current = !1, h.current.get(y(x))?.focus());
|
|
139
139
|
}, [x]);
|
|
140
|
-
let S =
|
|
141
|
-
let
|
|
142
|
-
b.current = !0, m(
|
|
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
|
-
|
|
148
|
-
]), C =
|
|
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 =
|
|
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:
|
|
192
|
+
isTabbable: t((e) => c(e, x), [x]),
|
|
193
193
|
cellRef: w,
|
|
194
194
|
onKeyDown: C,
|
|
195
|
-
onCellFocus:
|
|
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 {
|
|
7
|
-
import {
|
|
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
|
|
9
|
+
var f = {
|
|
10
10
|
day: "dd",
|
|
11
11
|
month: "mm",
|
|
12
12
|
year: "aaaa"
|
|
13
|
-
},
|
|
14
|
-
function
|
|
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
|
|
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(
|
|
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) =>
|
|
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(
|
|
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
|
|
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
|
|
64
|
-
let [z, B] =
|
|
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 =
|
|
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 = `${
|
|
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]), $ =
|
|
70
|
+
}, [C, w]), $ = a((e) => {
|
|
71
71
|
let t = e.target.value;
|
|
72
72
|
if (W(t), t.trim() === "") {
|
|
73
|
-
|
|
73
|
+
p?.(null);
|
|
74
74
|
return;
|
|
75
75
|
}
|
|
76
76
|
let n = V.parse(t);
|
|
77
|
-
n &&
|
|
78
|
-
}, [V,
|
|
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 =
|
|
89
|
-
W(V.format(e)),
|
|
90
|
-
}, [V,
|
|
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":
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
111
|
+
O && /* @__PURE__ */ u("input", {
|
|
112
112
|
type: "hidden",
|
|
113
113
|
name: O,
|
|
114
|
-
value:
|
|
114
|
+
value: i instanceof Date ? _(i) : ""
|
|
115
115
|
}),
|
|
116
|
-
/* @__PURE__ */
|
|
116
|
+
/* @__PURE__ */ d("div", {
|
|
117
117
|
className: "date-picker__control",
|
|
118
|
-
children: [/* @__PURE__ */
|
|
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:
|
|
128
|
+
placeholder: m ?? V.mask(h),
|
|
129
129
|
disabled: C,
|
|
130
130
|
readOnly: w,
|
|
131
|
-
"aria-label":
|
|
131
|
+
"aria-label": ne,
|
|
132
132
|
"aria-describedby": ae,
|
|
133
133
|
onChange: $,
|
|
134
134
|
onKeyDown: se,
|
|
135
135
|
onBlur: I
|
|
136
|
-
}), /* @__PURE__ */
|
|
136
|
+
}), /* @__PURE__ */ u(n, {
|
|
137
137
|
trigger: le,
|
|
138
|
-
label:
|
|
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__ */
|
|
146
|
-
value: X ??
|
|
145
|
+
children: /* @__PURE__ */ u(r, {
|
|
146
|
+
value: X ?? i ?? null,
|
|
147
147
|
onChange: ce,
|
|
148
|
-
gridLabel: F ??
|
|
149
|
-
previousMonthLabel:
|
|
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:
|
|
155
|
-
maxDate:
|
|
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__ */
|
|
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 {
|
|
172
|
+
export { v as t };
|