@studiolxd/brand 49.8.1 → 49.10.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 +126 -0
- package/dist/_shared/calendargrid.js +111 -30
- package/dist/_shared/tokens.js +9 -0
- package/dist/_types/molecules/AppLauncher/AppLauncher.d.ts +19 -0
- package/dist/_types/molecules/CalendarPlanner/CalendarPlanner.d.ts +54 -1
- package/dist/_types/molecules/Card/Card.d.ts +50 -3
- package/dist/_types/molecules/SiteNav/SiteNav.d.ts +12 -0
- package/dist/_types/molecules/_shared/calendarGrid.d.ts +32 -0
- package/dist/_types/molecules/_shared/dropdownItems.d.ts +8 -3
- package/dist/app-launcher.css +1 -1
- package/dist/app-launcher.js +15 -10
- package/dist/brand.css +20 -1
- package/dist/calendar-planner.css +1 -1
- package/dist/calendar-planner.js +185 -89
- package/dist/calendar-roster.js +8 -8
- package/dist/calendar.js +56 -56
- package/dist/card.css +1 -1
- package/dist/card.js +31 -18
- package/dist/site-nav.css +1 -1
- package/dist/site-nav.js +31 -21
- package/dist/tokens.css +20 -1
- package/package.json +341 -171
- package/src/tokens/molecules/app-launcher.css +2 -0
- package/src/tokens/molecules/calendar-planner.css +7 -0
- package/src/tokens/molecules/site-nav.css +3 -0
- package/src/tokens/scss/molecules/_app-launcher.scss +1 -0
- package/src/tokens/scss/molecules/_calendar-planner.scss +6 -0
- package/src/tokens/scss/molecules/_site-nav.scss +2 -0
- package/src/tokens/surface-invert.css +3 -0
- package/src/tokens/surface-light.css +3 -0
- package/src/tokens/surface-public.css +1 -0
- package/src/tokens/tokens.json +9 -0
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,132 @@ 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
|
+
## [49.10.0] — 2026-09-18
|
|
11
|
+
|
|
12
|
+
> **Minor.** La suite marca productos como «próximamente»: se ven en su sitio pero apagados,
|
|
13
|
+
> sin navegación y con un distintivo. Ni la baldosa del `AppLauncher` ni el ítem del `SiteNav`
|
|
14
|
+
> lo admitían.
|
|
15
|
+
|
|
16
|
+
### La entrada apagada con distintivo, en el lanzador y en el índice del sitio
|
|
17
|
+
|
|
18
|
+
`LauncherApp` y `SiteNavItem` ganan las mismas dos claves, `disabled` y `badge`.
|
|
19
|
+
|
|
20
|
+
Con **`disabled`** la entrada se ve en su sitio pero **no navega**: deja de ser un `<a>` —en
|
|
21
|
+
`SiteNav`, ni siquiera pasa por `renderLink`: no hay destino que dar—, se pinta como un enlace
|
|
22
|
+
inactivo (`<span role="link" aria-disabled="true">`, donde el atributo sí es válido y el lector
|
|
23
|
+
lo anuncia como no disponible) y **sin `tabIndex`**, así que el tabulador la salta. La tinta
|
|
24
|
+
apagada es la de un control deshabilitado del sistema (`color.disabled.text-on-light|dark`), que
|
|
25
|
+
no baja de 3:1 sobre la superficie — el mínimo de WCAG 1.4.11 para un componente inactivo, y el
|
|
26
|
+
motivo de no inventar un gris más claro. Tampoco se rellena ni subraya bajo el puntero: el
|
|
27
|
+
`:hover` alcanza también a un `<span>`, de ahí el `:not()` en las reglas de estado.
|
|
28
|
+
|
|
29
|
+
**`badge`** es el distintivo, y su texto llega **ya traducido** desde la aplicación: es
|
|
30
|
+
contenido —como el nombre de la app o el rótulo del ítem—, no cromo. Vale con `disabled`
|
|
31
|
+
(«Próximamente») y sin él («Beta»), y sobre una entrada apagada va en `Tag neutral` en vez de
|
|
32
|
+
`info`: una píldora de novedad sobre algo que no lleva a ningún sitio se leería como disponible.
|
|
33
|
+
En `SiteNav` el distintivo es **hermano del enlace**, no hijo suyo — dentro, la línea de hover
|
|
34
|
+
(que en el DS es una línea bajo el elemento, no `text-decoration`) cruzaría también la píldora,
|
|
35
|
+
y el nombre accesible del enlace arrastraría el estado.
|
|
36
|
+
|
|
37
|
+
`badge` **generaliza `isNew`** del lanzador, que es este mismo distintivo con el texto del
|
|
38
|
+
catálogo (`appLauncher.new`). `isNew` **sigue funcionando y no se retira**; con los dos puestos,
|
|
39
|
+
manda `badge`.
|
|
40
|
+
|
|
41
|
+
### Los `exports` declaran `default`, para que un Node CommonJS pueda `require()`
|
|
42
|
+
|
|
43
|
+
Las 170 subrutas condicionales de `package.json#exports` llevaban solo `types` e `import`.
|
|
44
|
+
`import` casa únicamente con la condición de importación, así que un Node CommonJS —los
|
|
45
|
+
workers de la suite empaquetados con esbuild en formato cjs, o un `tsx` cualquiera— que hiciera
|
|
46
|
+
`require('@studiolxd/brand/email')` moría con `ERR_PACKAGE_PATH_NOT_EXPORTED`. Ahora cada
|
|
47
|
+
subruta añade `default` apuntando **al mismo fichero ESM**, que es lo que Node necesita para
|
|
48
|
+
cargarlo por `require(esm)`: no se publica una segunda copia en CJS ni cambia el formato de
|
|
49
|
+
nada. Las subrutas que ya eran una cadena (CSS, SCSS, JSON, assets) no cambian — una cadena
|
|
50
|
+
vale para toda condición.
|
|
51
|
+
|
|
52
|
+
Lo vigilan dos guardianes, porque quedarse sin `default` no rompe ningún build: un test
|
|
53
|
+
(`scripts/exports-default.test.ts`, en `pnpm test`) y un paso de `release:check`, ambos
|
|
54
|
+
fallando si alguna subruta condicional se queda sin `default` o si `default` no apunta al mismo
|
|
55
|
+
fichero que `import`.
|
|
56
|
+
|
|
57
|
+
Tokens nuevos: `app-launcher.tile-disabled-color`, `site-nav.item-disabled-color`,
|
|
58
|
+
`site-nav.item-badge-gap` y sus pares `surface-dark-*`, todos por referencia a
|
|
59
|
+
`color.disabled.text-on-light|dark` — sin colores nuevos en la paleta.
|
|
60
|
+
|
|
61
|
+
De paso, la doc del `AppLauncher` pierde el apartado «Color de dato», que describía una prop
|
|
62
|
+
`accent` de `LauncherApp` retirada hace versiones.
|
|
63
|
+
|
|
64
|
+
## [49.9.0] — 2026-09-18
|
|
65
|
+
|
|
66
|
+
> **Minor.** Tres huecos del sistema: la segunda línea del ítem de menú admite un nodo, el
|
|
67
|
+
> planificador gana la vista de semana, y la tarjeta-enlace admite selección y acciones sobre
|
|
68
|
+
> su capa.
|
|
69
|
+
|
|
70
|
+
### La segunda línea del ítem de menú admite un nodo
|
|
71
|
+
|
|
72
|
+
`description` —la segunda línea de un ítem `button` o `link`— era `string`: el selector de
|
|
73
|
+
cuentas podía poner el correo debajo del nombre, pero no decir cuál es la **organización
|
|
74
|
+
principal** sin meter esa palabra dentro del texto. Ahora es `ReactNode`, así que la línea lleva
|
|
75
|
+
el correo y, al lado, el `Tag` del papel de esa cuenta.
|
|
76
|
+
|
|
77
|
+
Sigue siendo una sola línea —se recorta con puntos suspensivos igual que antes—: dos renglones
|
|
78
|
+
ahí desbaratan la altura del ítem.
|
|
79
|
+
|
|
80
|
+
### El planificador gana la vista de semana
|
|
81
|
+
|
|
82
|
+
`CalendarPlanner` solo sabía pintar el mes. `view="week"` cambia la parrilla por **siete columnas
|
|
83
|
+
con el día completo**: el nombre y el número del día en la cabecera de cada columna y, debajo, los
|
|
84
|
+
eventos de ese día —con la hora delante de los que la tengan y los de día entero arriba—.
|
|
85
|
+
|
|
86
|
+
- **La lista de eventos es la misma.** `events` no cambia; la hora sale de la propia fecha (un
|
|
87
|
+
evento a las 00:00 es de día entero) y `allDay` lo dice de forma explícita cuando la fecha no
|
|
88
|
+
basta.
|
|
89
|
+
- **La columna no trunca.** No hay «+N más» en la semana: `maxItemsPerDay` es cosa del mes, donde
|
|
90
|
+
la celda mide una fila de siete. Aquí la columna tiene alto de sobra y esconder eventos taparía
|
|
91
|
+
justo lo que se viene a leer.
|
|
92
|
+
- **Las flechas pasan a ser de semana** y `onWeekChange` avisa con el **lunes** de la nueva.
|
|
93
|
+
- **`viewSwitcher`** pinta el conmutador mes/semana en la cabecera (un `ToggleGroup` exclusivo).
|
|
94
|
+
Va **apagado** por defecto: un planificador ya montado no gana botones por actualizar el
|
|
95
|
+
paquete. La vista puede ir controlada (`view` + `onViewChange`) o dejarse al componente
|
|
96
|
+
(`defaultView`).
|
|
97
|
+
- **Cambiar de vista no teletransporta**: se mueve lo justo para que las dos vistas se toquen. Si
|
|
98
|
+
la semana guardada no pisa el mes visible, al ir a la semana se abre la del día 1; al volver al
|
|
99
|
+
mes, si el mes visible no pisa la semana, se abre el mes de su lunes. Una semana a caballo de
|
|
100
|
+
dos meses pisa los dos, así que ir y volver deja al usuario donde estaba.
|
|
101
|
+
|
|
102
|
+
El teclado de la semana vive en `_shared/calendarGrid` junto al del mes: la misma rejilla, con una
|
|
103
|
+
sola fila. Los cinco textos nuevos (`previousWeekLabel`, `nextWeekLabel`, `monthViewLabel`,
|
|
104
|
+
`weekViewLabel`, `viewSwitcherLabel`) van en **props con default castellano** y no en el catálogo:
|
|
105
|
+
una clave obligatoria más en `CalendarPlannerMessages` dejaría sin compilar a toda aplicación que
|
|
106
|
+
ya lo tiene montado, y esto es un minor. Pasarán al catálogo en el próximo major.
|
|
107
|
+
|
|
108
|
+
Tokens nuevos: `calendar-planner.week-cell-min-height` (y sus `sm-`/`lg-`), `weekday-gap`,
|
|
109
|
+
`event-time-font-size`, `event-time-color` y su par oscuro.
|
|
110
|
+
|
|
111
|
+
### La tarjeta-enlace admite selección y acciones sobre su capa
|
|
112
|
+
|
|
113
|
+
`Card linkOverlay` pinta la capa del enlace del título (`::after`) por encima de todo el bloque,
|
|
114
|
+
así que una casilla de selección dentro del `CardHeader` **dejaba de pulsarse** — y de ahí venía
|
|
115
|
+
el apaño del consumidor: envolver la tarjeta en un `<Link>` con un botón dentro, que no es HTML
|
|
116
|
+
válido y deja un enlace cuyo nombre se traga la tarjeta entera.
|
|
117
|
+
|
|
118
|
+
Llega **`CardSelection`**, la ranura de la casilla (la primera de la cabecera, que pasa a ser una
|
|
119
|
+
rejilla de tres columnas: selección, texto y acción), y las zonas interactivas se **declaran**:
|
|
120
|
+
|
|
121
|
+
| Zona | Cómo se declara |
|
|
122
|
+
| --- | --- |
|
|
123
|
+
| `CardAction` | sola: es una ranura interactiva por definición |
|
|
124
|
+
| `CardSelection` | sola: ídem |
|
|
125
|
+
| Cualquier otra subparte | `interactive` en ella (`<CardFooter interactive>`) |
|
|
126
|
+
|
|
127
|
+
Lo declarado sube por encima de la capa (`position: relative` y un apilado interno de 1, que solo
|
|
128
|
+
compite consigo mismo). Lo que es solo texto se queda **debajo a propósito**: ahí la capa es lo
|
|
129
|
+
que hace que pulsar en cualquier punto abra el detalle. El teclado no depende de la capa: las tres
|
|
130
|
+
paradas —casilla, enlace del título y menú— siguen en el orden en que se leen.
|
|
131
|
+
|
|
132
|
+
`CardSelection` corta la propagación como `CardAction` pero **no** la acción por defecto, ni
|
|
133
|
+
colgando de un enlace: esa acción es justo la que marca la casilla. Lo que impide navegar es la
|
|
134
|
+
capa.
|
|
135
|
+
|
|
10
136
|
## [49.8.1] — 2026-09-18
|
|
11
137
|
|
|
12
138
|
> **Patch.** `AppShell` ya no revienta sin `ResizeObserver`.
|
|
@@ -37,11 +37,29 @@ function d(e) {
|
|
|
37
37
|
return a;
|
|
38
38
|
}
|
|
39
39
|
function f(e) {
|
|
40
|
+
let t = (e.getDay() + 6) % 7;
|
|
41
|
+
return new Date(e.getFullYear(), e.getMonth(), e.getDate() - t);
|
|
42
|
+
}
|
|
43
|
+
function p(e, t) {
|
|
44
|
+
let n = f(e);
|
|
45
|
+
return new Date(n.getFullYear(), n.getMonth(), n.getDate() + t * 7);
|
|
46
|
+
}
|
|
47
|
+
function m(e, t) {
|
|
48
|
+
let n = f(e);
|
|
49
|
+
return Array.from({ length: 7 }, (e, r) => {
|
|
50
|
+
let i = new Date(n.getFullYear(), n.getMonth(), n.getDate() + r);
|
|
51
|
+
return {
|
|
52
|
+
date: i,
|
|
53
|
+
outside: t ? !l(i, t) : !1
|
|
54
|
+
};
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
function h(e) {
|
|
40
58
|
let t = [];
|
|
41
59
|
for (let n = 0; n < e.length; n += 7) t.push(e.slice(n, n + 7));
|
|
42
60
|
return t;
|
|
43
61
|
}
|
|
44
|
-
function
|
|
62
|
+
function g(e, t = "narrow") {
|
|
45
63
|
let n = new Intl.DateTimeFormat(e, { weekday: t }), r = new Intl.DateTimeFormat(e, { weekday: "long" });
|
|
46
64
|
return Array.from({ length: 7 }, (e, t) => {
|
|
47
65
|
let i = new Date(2025, 0, 6 + t);
|
|
@@ -51,7 +69,7 @@ function p(e, t = "narrow") {
|
|
|
51
69
|
};
|
|
52
70
|
});
|
|
53
71
|
}
|
|
54
|
-
function
|
|
72
|
+
function _({ block: e, rowModifier: t, weekdays: n }) {
|
|
55
73
|
return /* @__PURE__ */ o("div", {
|
|
56
74
|
role: "row",
|
|
57
75
|
className: [`${e}__row`, t && `${e}__row--${t}`].filter(Boolean).join(" "),
|
|
@@ -66,7 +84,7 @@ function m({ block: e, rowModifier: t, weekdays: n }) {
|
|
|
66
84
|
}, n))
|
|
67
85
|
});
|
|
68
86
|
}
|
|
69
|
-
function
|
|
87
|
+
function v({ 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
88
|
return /* @__PURE__ */ s("div", {
|
|
71
89
|
className: `${t}__header`,
|
|
72
90
|
children: [
|
|
@@ -110,21 +128,21 @@ function h({ block: t, title: n, titleId: r, navigable: i = !0, previousLabel: a
|
|
|
110
128
|
]
|
|
111
129
|
});
|
|
112
130
|
}
|
|
113
|
-
function
|
|
131
|
+
function y(e, t, n) {
|
|
114
132
|
return t && e < t ? t : n && e > n ? n : e;
|
|
115
133
|
}
|
|
116
|
-
function
|
|
134
|
+
function b(e, t) {
|
|
117
135
|
return new Date(e.getFullYear(), e.getMonth(), e.getDate() + t);
|
|
118
136
|
}
|
|
119
|
-
function
|
|
137
|
+
function x(e, t) {
|
|
120
138
|
let n = new Date(e.getFullYear(), e.getMonth() + t, 1), r = new Date(n.getFullYear(), n.getMonth() + 1, 0).getDate();
|
|
121
139
|
return new Date(n.getFullYear(), n.getMonth(), Math.min(e.getDate(), r));
|
|
122
140
|
}
|
|
123
|
-
function
|
|
141
|
+
function S(e) {
|
|
124
142
|
return `${e.getFullYear()}-${e.getMonth()}-${e.getDate()}`;
|
|
125
143
|
}
|
|
126
|
-
function
|
|
127
|
-
let [p, m] = a(() => s ?? /* @__PURE__ */ new Date()), h = i(/* @__PURE__ */ new Map()),
|
|
144
|
+
function C({ month: e, onMonthChange: o, selected: s, onActivate: u, minDate: d, maxDate: f }) {
|
|
145
|
+
let [p, m] = a(() => s ?? /* @__PURE__ */ new Date()), h = i(/* @__PURE__ */ new Map()), g = i(!1), _ = r(() => {
|
|
128
146
|
if (l(p, e)) return p;
|
|
129
147
|
if (s && l(s, e)) return s;
|
|
130
148
|
let t = /* @__PURE__ */ new Date();
|
|
@@ -135,42 +153,42 @@ function b({ month: e, onMonthChange: o, selected: s, onActivate: u, minDate: d,
|
|
|
135
153
|
s
|
|
136
154
|
]);
|
|
137
155
|
n(() => {
|
|
138
|
-
|
|
139
|
-
}, [
|
|
140
|
-
let
|
|
141
|
-
let n =
|
|
142
|
-
|
|
156
|
+
g.current && (g.current = !1, h.current.get(S(_))?.focus());
|
|
157
|
+
}, [_]);
|
|
158
|
+
let v = t((t) => {
|
|
159
|
+
let n = y(t, d, f);
|
|
160
|
+
g.current = !0, m(n), l(n, e) || o(new Date(n.getFullYear(), n.getMonth(), 1));
|
|
143
161
|
}, [
|
|
144
162
|
f,
|
|
145
163
|
d,
|
|
146
164
|
e,
|
|
147
165
|
o
|
|
148
166
|
]), C = t((e) => {
|
|
149
|
-
let t =
|
|
167
|
+
let t = _, n = null;
|
|
150
168
|
switch (e.key) {
|
|
151
169
|
case "ArrowLeft":
|
|
152
|
-
n =
|
|
170
|
+
n = b(t, -1);
|
|
153
171
|
break;
|
|
154
172
|
case "ArrowRight":
|
|
155
|
-
n =
|
|
173
|
+
n = b(t, 1);
|
|
156
174
|
break;
|
|
157
175
|
case "ArrowUp":
|
|
158
|
-
n =
|
|
176
|
+
n = b(t, -7);
|
|
159
177
|
break;
|
|
160
178
|
case "ArrowDown":
|
|
161
|
-
n =
|
|
179
|
+
n = b(t, 7);
|
|
162
180
|
break;
|
|
163
181
|
case "Home":
|
|
164
|
-
n =
|
|
182
|
+
n = b(t, -((t.getDay() + 6) % 7));
|
|
165
183
|
break;
|
|
166
184
|
case "End":
|
|
167
|
-
n =
|
|
185
|
+
n = b(t, 6 - (t.getDay() + 6) % 7);
|
|
168
186
|
break;
|
|
169
187
|
case "PageUp":
|
|
170
|
-
n =
|
|
188
|
+
n = x(t, e.shiftKey ? -12 : -1);
|
|
171
189
|
break;
|
|
172
190
|
case "PageDown":
|
|
173
|
-
n =
|
|
191
|
+
n = x(t, e.shiftKey ? 12 : 1);
|
|
174
192
|
break;
|
|
175
193
|
case "Enter":
|
|
176
194
|
case " ":
|
|
@@ -178,22 +196,85 @@ function b({ month: e, onMonthChange: o, selected: s, onActivate: u, minDate: d,
|
|
|
178
196
|
return;
|
|
179
197
|
default: return;
|
|
180
198
|
}
|
|
181
|
-
e.preventDefault(),
|
|
199
|
+
e.preventDefault(), v(n);
|
|
182
200
|
}, [
|
|
183
|
-
|
|
184
|
-
|
|
201
|
+
_,
|
|
202
|
+
v,
|
|
185
203
|
u
|
|
186
204
|
]), w = t((e) => (t) => {
|
|
187
|
-
let n =
|
|
205
|
+
let n = S(e);
|
|
188
206
|
t ? h.current.set(n, t) : h.current.delete(n);
|
|
189
207
|
}, []);
|
|
190
208
|
return {
|
|
191
|
-
activeDate:
|
|
192
|
-
isTabbable: t((e) => c(e,
|
|
209
|
+
activeDate: _,
|
|
210
|
+
isTabbable: t((e) => c(e, _), [_]),
|
|
193
211
|
cellRef: w,
|
|
194
212
|
onKeyDown: C,
|
|
195
213
|
onCellFocus: t((e) => m(e), [])
|
|
196
214
|
};
|
|
197
215
|
}
|
|
216
|
+
function w({ weekStart: e, onWeekChange: o, onActivate: s, minDate: l, maxDate: u }) {
|
|
217
|
+
let [d, p] = a(() => /* @__PURE__ */ new Date()), m = i(/* @__PURE__ */ new Map()), h = i(!1), g = r(() => f(e), [e]), _ = r(() => {
|
|
218
|
+
if (c(f(d), g)) return d;
|
|
219
|
+
let e = /* @__PURE__ */ new Date();
|
|
220
|
+
return c(f(e), g) ? e : g;
|
|
221
|
+
}, [d, g]);
|
|
222
|
+
n(() => {
|
|
223
|
+
h.current && (h.current = !1, m.current.get(S(_))?.focus());
|
|
224
|
+
}, [_]);
|
|
225
|
+
let v = t((e) => {
|
|
226
|
+
let t = y(e, l, u);
|
|
227
|
+
h.current = !0, p(t), c(f(t), g) || o(f(t));
|
|
228
|
+
}, [
|
|
229
|
+
u,
|
|
230
|
+
l,
|
|
231
|
+
o,
|
|
232
|
+
g
|
|
233
|
+
]), x = t((e) => {
|
|
234
|
+
let t = _, n = null;
|
|
235
|
+
switch (e.key) {
|
|
236
|
+
case "ArrowLeft":
|
|
237
|
+
case "ArrowUp":
|
|
238
|
+
n = b(t, -1);
|
|
239
|
+
break;
|
|
240
|
+
case "ArrowRight":
|
|
241
|
+
case "ArrowDown":
|
|
242
|
+
n = b(t, 1);
|
|
243
|
+
break;
|
|
244
|
+
case "Home":
|
|
245
|
+
n = f(t);
|
|
246
|
+
break;
|
|
247
|
+
case "End":
|
|
248
|
+
n = b(f(t), 6);
|
|
249
|
+
break;
|
|
250
|
+
case "PageUp":
|
|
251
|
+
n = b(t, -7);
|
|
252
|
+
break;
|
|
253
|
+
case "PageDown":
|
|
254
|
+
n = b(t, 7);
|
|
255
|
+
break;
|
|
256
|
+
case "Enter":
|
|
257
|
+
case " ":
|
|
258
|
+
s && (e.preventDefault(), s(t));
|
|
259
|
+
return;
|
|
260
|
+
default: return;
|
|
261
|
+
}
|
|
262
|
+
e.preventDefault(), v(n);
|
|
263
|
+
}, [
|
|
264
|
+
_,
|
|
265
|
+
v,
|
|
266
|
+
s
|
|
267
|
+
]), C = t((e) => (t) => {
|
|
268
|
+
let n = S(e);
|
|
269
|
+
t ? m.current.set(n, t) : m.current.delete(n);
|
|
270
|
+
}, []);
|
|
271
|
+
return {
|
|
272
|
+
activeDate: _,
|
|
273
|
+
isTabbable: t((e) => c(e, _), [_]),
|
|
274
|
+
cellRef: C,
|
|
275
|
+
onKeyDown: x,
|
|
276
|
+
onCellFocus: t((e) => p(e), [])
|
|
277
|
+
};
|
|
278
|
+
}
|
|
198
279
|
//#endregion
|
|
199
|
-
export {
|
|
280
|
+
export { c as a, _ as c, f as d, C as f, g as i, u as l, d as n, l as o, w as p, m as r, v as s, h as t, p as u };
|
package/dist/_shared/tokens.js
CHANGED
|
@@ -214,6 +214,7 @@ var e = {
|
|
|
214
214
|
"--app-launcher-tile-name-line-height": "1.3",
|
|
215
215
|
"--app-launcher-tile-name-color": "#111e30",
|
|
216
216
|
"--app-launcher-tile-name-active-font-weight": "500",
|
|
217
|
+
"--app-launcher-tile-disabled-color": "#4a4a4a",
|
|
217
218
|
"--app-launcher-trigger-hover-bg": "#111e30",
|
|
218
219
|
"--app-launcher-trigger-hover-color": "#ffffff",
|
|
219
220
|
"--app-launcher-tile-highlighted-bg": "#111e30",
|
|
@@ -2191,6 +2192,12 @@ var e = {
|
|
|
2191
2192
|
"--calendar-planner-more-focus-ring-color": "#111e30",
|
|
2192
2193
|
"--calendar-planner-transition-duration": "150ms",
|
|
2193
2194
|
"--calendar-planner-transition-easing": "ease",
|
|
2195
|
+
"--calendar-planner-week-cell-min-height": "12rem",
|
|
2196
|
+
"--calendar-planner-sm-week-cell-min-height": "8rem",
|
|
2197
|
+
"--calendar-planner-lg-week-cell-min-height": "16rem",
|
|
2198
|
+
"--calendar-planner-weekday-gap": "0.25rem",
|
|
2199
|
+
"--calendar-planner-event-time-font-size": "0.875rem",
|
|
2200
|
+
"--calendar-planner-event-time-color": "#4a4a4a",
|
|
2194
2201
|
"--calendar-planner-sm-cell-min-height": "4rem",
|
|
2195
2202
|
"--calendar-planner-lg-cell-min-height": "9rem",
|
|
2196
2203
|
"--calendar-planner-hover-line-width": "1px",
|
|
@@ -2882,6 +2889,8 @@ var e = {
|
|
|
2882
2889
|
"--site-nav-item-hover-color": "#111e30",
|
|
2883
2890
|
"--site-nav-item-underline-offset": "2px",
|
|
2884
2891
|
"--site-nav-item-hover-line-width": "1px",
|
|
2892
|
+
"--site-nav-item-disabled-color": "#4a4a4a",
|
|
2893
|
+
"--site-nav-item-badge-gap": "0.5rem",
|
|
2885
2894
|
"--site-nav-item-current-font-weight": "300",
|
|
2886
2895
|
"--site-nav-focus-ring-width": "2px",
|
|
2887
2896
|
"--site-nav-focus-ring-offset": "2px",
|
|
@@ -23,7 +23,26 @@ export interface LauncherApp {
|
|
|
23
23
|
id: string;
|
|
24
24
|
name: string;
|
|
25
25
|
url: string;
|
|
26
|
+
/**
|
|
27
|
+
* Marca de app nueva. **`badge` lo generaliza**: `isNew` es el mismo
|
|
28
|
+
* distintivo con un único texto, el del catálogo (`appLauncher.new`). Se
|
|
29
|
+
* mantiene por compatibilidad y sigue valiendo; con `badge` puesto, manda
|
|
30
|
+
* `badge`.
|
|
31
|
+
*/
|
|
26
32
|
isNew?: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Producto anunciado y todavía no disponible: la baldosa se ve en su sitio
|
|
35
|
+
* pero **apagada y sin navegación** — no es un `<a>`, no tiene `href` que
|
|
36
|
+
* seguir y el tabulador no se detiene en ella.
|
|
37
|
+
*/
|
|
38
|
+
disabled?: boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Texto del distintivo de la baldosa («Próximamente», «Nuevo», «Beta»…).
|
|
41
|
+
* Llega **ya traducido** desde la aplicación: es contenido de la suite, como
|
|
42
|
+
* el nombre de la app, no cromo del lanzador. Generaliza `isNew`, que es
|
|
43
|
+
* este mismo distintivo con el texto del catálogo.
|
|
44
|
+
*/
|
|
45
|
+
badge?: string;
|
|
27
46
|
}
|
|
28
47
|
export interface AppLauncherLabels {
|
|
29
48
|
/**
|
|
@@ -16,7 +16,20 @@ export interface PlannerEvent {
|
|
|
16
16
|
date: Date;
|
|
17
17
|
label: string;
|
|
18
18
|
variant?: TagVariant;
|
|
19
|
+
/**
|
|
20
|
+
* El evento dura todo el día: la vista de semana lo pinta **sin hora**, el
|
|
21
|
+
* primero de la columna. Sin ella se deriva de la propia fecha —un evento a
|
|
22
|
+
* las 00:00 es de día entero—, que es lo que hace el mes desde siempre y lo
|
|
23
|
+
* que permite que la misma lista de eventos sirva para las dos vistas.
|
|
24
|
+
*/
|
|
25
|
+
allDay?: boolean;
|
|
19
26
|
}
|
|
27
|
+
/**
|
|
28
|
+
* Las dos caras del planificador: el `month` de siempre —la parrilla del mes
|
|
29
|
+
* entera— y `week`, siete columnas con el día completo, donde los eventos con
|
|
30
|
+
* hora se leen en orden.
|
|
31
|
+
*/
|
|
32
|
+
export type CalendarPlannerView = 'month' | 'week';
|
|
20
33
|
export interface CalendarPlannerProps {
|
|
21
34
|
/** Eventos a mostrar en el planificador */
|
|
22
35
|
events?: PlannerEvent[];
|
|
@@ -75,8 +88,48 @@ export interface CalendarPlannerProps {
|
|
|
75
88
|
* `BrandMessagesProvider`. Solo se lee cuando alguna celda desborda.
|
|
76
89
|
*/
|
|
77
90
|
moreLabel?: (count: number) => string;
|
|
91
|
+
/**
|
|
92
|
+
* Vista visible (modo controlado): la parrilla del mes o la semana.
|
|
93
|
+
* Default: `'month'` — el planificador de siempre.
|
|
94
|
+
*/
|
|
95
|
+
view?: CalendarPlannerView;
|
|
96
|
+
/** Vista inicial en modo no controlado. Default: `'month'` */
|
|
97
|
+
defaultView?: CalendarPlannerView;
|
|
98
|
+
/** Callback al cambiar de vista, tanto desde el conmutador como al navegar. */
|
|
99
|
+
onViewChange?: (view: CalendarPlannerView) => void;
|
|
100
|
+
/**
|
|
101
|
+
* Pinta el conmutador mes/semana en la cabecera. Default: `false` — un
|
|
102
|
+
* planificador que ya está montado no gana botones por actualizar el
|
|
103
|
+
* paquete; quien quiera las dos vistas lo pide.
|
|
104
|
+
*/
|
|
105
|
+
viewSwitcher?: boolean;
|
|
106
|
+
/**
|
|
107
|
+
* Semana visible (modo controlado). Vale cualquier día de ella: el
|
|
108
|
+
* componente se queda con su lunes.
|
|
109
|
+
*/
|
|
110
|
+
week?: Date;
|
|
111
|
+
/** Semana inicial en modo no controlado. Default: la del mes visible, o hoy. */
|
|
112
|
+
defaultWeek?: Date;
|
|
113
|
+
/** Callback al cambiar de semana. Recibe el **lunes** de la nueva. */
|
|
114
|
+
onWeekChange?: (weekStart: Date) => void;
|
|
115
|
+
/**
|
|
116
|
+
* aria-label del botón de semana anterior. Default: `'Semana anterior'`
|
|
117
|
+
* (castellano). No sale del catálogo como las flechas de mes: añadirle una
|
|
118
|
+
* clave obligatoria a `CalendarPlannerMessages` rompería a todas las
|
|
119
|
+
* aplicaciones que ya lo tienen montado, así que estos cuatro textos entran
|
|
120
|
+
* como props y pasarán al catálogo en el próximo major.
|
|
121
|
+
*/
|
|
122
|
+
previousWeekLabel?: string;
|
|
123
|
+
/** aria-label del botón de semana siguiente. Default: `'Semana siguiente'`. */
|
|
124
|
+
nextWeekLabel?: string;
|
|
125
|
+
/** Rótulo del botón de vista de mes del conmutador. Default: `'Mes'`. */
|
|
126
|
+
monthViewLabel?: string;
|
|
127
|
+
/** Rótulo del botón de vista de semana del conmutador. Default: `'Semana'`. */
|
|
128
|
+
weekViewLabel?: string;
|
|
129
|
+
/** Nombre accesible del conmutador de vista. Default: `'Vista del calendario'`. */
|
|
130
|
+
viewSwitcherLabel?: string;
|
|
78
131
|
/** Tamaño del componente. Default: 'md' */
|
|
79
132
|
size?: 'sm' | 'md' | 'lg';
|
|
80
133
|
className?: string;
|
|
81
134
|
}
|
|
82
|
-
export declare function CalendarPlanner({ events, renderDay, maxItemsPerDay, onMoreClick, showMoreDialog, onDayClick, month: monthProp, defaultMonth, onMonthChange, navigable, locale, previousMonthLabel, nextMonthLabel, gridLabel, moreLabel, size, className, }: CalendarPlannerProps): import("react/jsx-runtime").JSX.Element;
|
|
135
|
+
export declare function CalendarPlanner({ events, renderDay, maxItemsPerDay, onMoreClick, showMoreDialog, onDayClick, month: monthProp, defaultMonth, onMonthChange, view: viewProp, defaultView, onViewChange, viewSwitcher, week: weekProp, defaultWeek, onWeekChange, navigable, locale, previousMonthLabel, nextMonthLabel, previousWeekLabel, nextWeekLabel, monthViewLabel, weekViewLabel, viewSwitcherLabel, gridLabel, moreLabel, size, className, }: CalendarPlannerProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -115,9 +115,24 @@ export interface CardProps extends Omit<React.ComponentPropsWithoutRef<'div'>, '
|
|
|
115
115
|
* (`data-*`, `aria-*`, `id`…) se reenvía al `<div>`.
|
|
116
116
|
*/
|
|
117
117
|
export declare const Card: import("react").ForwardRefExoticComponent<CardProps & import("react").RefAttributes<HTMLElement>>;
|
|
118
|
-
export
|
|
118
|
+
export interface CardPartProps extends React.ComponentPropsWithoutRef<'div'> {
|
|
119
|
+
/**
|
|
120
|
+
* Declara la subparte como **zona interactiva** de una tarjeta `linkOverlay`:
|
|
121
|
+
* sube por encima de la capa del enlace (`position: relative` + un apilado
|
|
122
|
+
* interno de 1) para que lo que lleve dentro se pueda pulsar. Sin ella, la
|
|
123
|
+
* capa del título cubre el bloque entero y se queda con la pulsación — que
|
|
124
|
+
* es lo que se quiere en todo lo que es solo texto.
|
|
125
|
+
*
|
|
126
|
+
* No hace falta en `CardAction` ni en `CardSelection`, que ya son ranuras
|
|
127
|
+
* interactivas por definición y suben solas. Fuera de `linkOverlay` no hace
|
|
128
|
+
* nada: no hay capa a la que ganar.
|
|
129
|
+
*
|
|
130
|
+
* @default false
|
|
131
|
+
*/
|
|
132
|
+
interactive?: boolean;
|
|
133
|
+
}
|
|
119
134
|
/** Fila superior: el bloque de título a un lado y la acción al otro. */
|
|
120
|
-
export declare const CardHeader: import("react").ForwardRefExoticComponent<
|
|
135
|
+
export declare const CardHeader: import("react").ForwardRefExoticComponent<CardPartProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
121
136
|
export interface CardTitleProps extends Omit<React.ComponentPropsWithoutRef<'h3'>, 'children'> {
|
|
122
137
|
/**
|
|
123
138
|
* Nivel semántico del encabezado en el esquema del documento. Default: `3`
|
|
@@ -185,8 +200,40 @@ export interface CardActionProps extends CardPartProps {
|
|
|
185
200
|
* sus eventos de la tarjeta-enlace que la contiene: ver `isolate`.
|
|
186
201
|
*/
|
|
187
202
|
export declare const CardAction: import("react").ForwardRefExoticComponent<CardActionProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
203
|
+
export interface CardSelectionProps extends React.ComponentPropsWithoutRef<'div'> {
|
|
204
|
+
/**
|
|
205
|
+
* Detiene la propagación del clic: marcar la casilla marca la casilla y no
|
|
206
|
+
* llega al manejador que la tarjeta o la fila tengan puesto más arriba.
|
|
207
|
+
*
|
|
208
|
+
* A diferencia de `CardAction`, **no cancela la acción por defecto** aunque
|
|
209
|
+
* la ranura cuelgue de un enlace: la acción por defecto es justo lo que
|
|
210
|
+
* marca la casilla, así que cancelarla la dejaría sin marcar. Lo que impide
|
|
211
|
+
* que se navegue es la capa —dentro de `linkOverlay` la ranura queda por
|
|
212
|
+
* encima de ella y el enlace ni se entera—; una tarjeta envuelta a mano en un
|
|
213
|
+
* `<Link>` con la casilla dentro no tiene arreglo aquí, porque no lo tiene:
|
|
214
|
+
* es un control dentro de un enlace, y se escribe con `linkOverlay`.
|
|
215
|
+
*
|
|
216
|
+
* @default true
|
|
217
|
+
*/
|
|
218
|
+
isolate?: boolean;
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Ranura de **selección**: la casilla (o el radio) con que se elige la tarjeta
|
|
222
|
+
* dentro de una lista. Va al principio de la cabecera, antes del título, que es
|
|
223
|
+
* donde se busca al repasar una columna de tarjetas.
|
|
224
|
+
*
|
|
225
|
+
* Es la pieza que faltaba para la tarjeta que **navega y se selecciona**: en
|
|
226
|
+
* una `Card linkOverlay`, la capa del enlace del título cubre el bloque entero
|
|
227
|
+
* y se traga la pulsación de cualquier control que no la gane; esta ranura sube
|
|
228
|
+
* por encima de ella (`position: relative` + apilado interno de 1) y conserva su
|
|
229
|
+
* propio foco de teclado, en su sitio del orden de tabulación.
|
|
230
|
+
*
|
|
231
|
+
* No se confunde con `selectable`, que es lo contrario: ahí la tarjeta **entera**
|
|
232
|
+
* es la opción y nada más dentro puede ser interactivo.
|
|
233
|
+
*/
|
|
234
|
+
export declare const CardSelection: import("react").ForwardRefExoticComponent<CardSelectionProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
188
235
|
/** Cuerpo de la tarjeta. */
|
|
189
|
-
export declare const CardContent: import("react").ForwardRefExoticComponent<
|
|
236
|
+
export declare const CardContent: import("react").ForwardRefExoticComponent<CardPartProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
190
237
|
export interface CardFooterProps extends CardPartProps {
|
|
191
238
|
/**
|
|
192
239
|
* `row` (por defecto): las acciones en fila **en escritorio**; por debajo de
|
|
@@ -10,6 +10,18 @@ export interface SiteNavItem {
|
|
|
10
10
|
target?: string;
|
|
11
11
|
/** Relación del enlace. Con `target="_blank"` y sin valor, se aplica `noopener noreferrer`. */
|
|
12
12
|
rel?: string;
|
|
13
|
+
/**
|
|
14
|
+
* Producto anunciado y todavía no disponible: el ítem se ve en su sitio pero
|
|
15
|
+
* **apagado y sin navegación** — no es un enlace, no pasa por `renderLink` y
|
|
16
|
+
* el tabulador no se detiene en él.
|
|
17
|
+
*/
|
|
18
|
+
disabled?: boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Texto del distintivo junto al rótulo («Próximamente», «Nuevo», «Beta»…).
|
|
21
|
+
* Llega **ya traducido**: es contenido de ESTE sitio, como el propio rótulo,
|
|
22
|
+
* no cromo del índice.
|
|
23
|
+
*/
|
|
24
|
+
badge?: string;
|
|
13
25
|
}
|
|
14
26
|
export interface SiteNavGroup {
|
|
15
27
|
id: string;
|
|
@@ -13,6 +13,17 @@ export declare function shiftMonth(month: Date, delta: number): Date;
|
|
|
13
13
|
* semana. Solo se completan las semanas que el mes realmente ocupa.
|
|
14
14
|
*/
|
|
15
15
|
export declare function getCalendarDays(month: Date): CalendarDay[];
|
|
16
|
+
/** Lunes de la semana a la que pertenece `date`. */
|
|
17
|
+
export declare function startOfWeek(date: Date): Date;
|
|
18
|
+
/** Lunes de la semana desplazada `delta` semanas respecto a la de `date`. */
|
|
19
|
+
export declare function shiftWeek(date: Date, delta: number): Date;
|
|
20
|
+
/**
|
|
21
|
+
* Los siete días de la semana de `date`, de lunes a domingo. `outside` sale de
|
|
22
|
+
* comparar con `month` cuando se pasa —la vista de semana atraviesa el cambio
|
|
23
|
+
* de mes—; sin él, ningún día es de fuera: la semana es la unidad y no cuelga
|
|
24
|
+
* de ningún mes.
|
|
25
|
+
*/
|
|
26
|
+
export declare function getWeekDays(date: Date, month?: Date): CalendarDay[];
|
|
16
27
|
/** Agrupa días en semanas de 7. */
|
|
17
28
|
export declare function chunkWeeks(days: CalendarDay[]): CalendarDay[][];
|
|
18
29
|
/**
|
|
@@ -116,3 +127,24 @@ export interface CalendarGridNavigation {
|
|
|
116
127
|
* Mayús de año.
|
|
117
128
|
*/
|
|
118
129
|
export declare function useCalendarGridNavigation({ month, onMonthChange, selected, onActivate, minDate, maxDate, }: UseCalendarGridNavigationOptions): CalendarGridNavigation;
|
|
130
|
+
export interface UseCalendarWeekNavigationOptions {
|
|
131
|
+
/** Lunes de la semana visible */
|
|
132
|
+
weekStart: Date;
|
|
133
|
+
/** Se llama cuando el teclado saca el foco fuera de la semana visible */
|
|
134
|
+
onWeekChange: (weekStart: Date) => void;
|
|
135
|
+
/** Activación de la columna enfocada con Enter/Espacio */
|
|
136
|
+
onActivate?: (date: Date) => void;
|
|
137
|
+
minDate?: Date;
|
|
138
|
+
maxDate?: Date;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* El mismo roving tabindex del mes sobre las siete columnas de la semana: una
|
|
142
|
+
* sola parada de tabulador, flechas para moverse de día —y la semana cambia
|
|
143
|
+
* sola al salir por cualquiera de los dos extremos—, Inicio/Fin para el lunes
|
|
144
|
+
* y el domingo, RePág/AvPág para la semana anterior y la siguiente.
|
|
145
|
+
*
|
|
146
|
+
* Las flechas vertical y horizontal hacen lo mismo aquí: la semana es **una**
|
|
147
|
+
* fila de celdas, así que arriba y abajo no llevan a ninguna otra parte y se
|
|
148
|
+
* quedan recorriendo los días, como ↑/↓ en una lista.
|
|
149
|
+
*/
|
|
150
|
+
export declare function useCalendarWeekNavigation({ weekStart, onWeekChange, onActivate, minDate, maxDate, }: UseCalendarWeekNavigationOptions): CalendarGridNavigation;
|
|
@@ -7,8 +7,13 @@ export type MenuButtonItem = {
|
|
|
7
7
|
* una acción. Con ella el ítem se pinta a dos líneas —`label` arriba,
|
|
8
8
|
* `description` debajo— y el icono se alinea al bloque entero. Sin ella, el
|
|
9
9
|
* ítem se pinta a una línea, exactamente igual que siempre.
|
|
10
|
+
*
|
|
11
|
+
* Admite un **nodo**, no solo texto: la línea de una cuenta lleva a menudo
|
|
12
|
+
* el correo y, al lado, el papel de esa cuenta (`<Tag>Principal</Tag>`).
|
|
13
|
+
* Lo que se pase se recorta igual con puntos suspensivos, así que va en una
|
|
14
|
+
* sola línea: dos renglones ahí desbaratan la altura del ítem.
|
|
10
15
|
*/
|
|
11
|
-
description?:
|
|
16
|
+
description?: ReactNode;
|
|
12
17
|
icon?: ReactNode;
|
|
13
18
|
onClick: () => void;
|
|
14
19
|
disabled?: boolean;
|
|
@@ -23,8 +28,8 @@ export type MenuButtonItem = {
|
|
|
23
28
|
export type MenuLinkItem = {
|
|
24
29
|
type: 'link';
|
|
25
30
|
label: string;
|
|
26
|
-
/** Segunda línea del ítem, más tenue. Igual que en el ítem `button
|
|
27
|
-
description?:
|
|
31
|
+
/** Segunda línea del ítem, más tenue. Igual que en el ítem `button`: admite un nodo. */
|
|
32
|
+
description?: ReactNode;
|
|
28
33
|
icon?: ReactNode;
|
|
29
34
|
href: string;
|
|
30
35
|
disabled?: boolean;
|