@studiolxd/brand 47.1.0 → 48.1.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 (59) hide show
  1. package/CHANGELOG.md +161 -0
  2. package/dist/_shared/progressbar.js +19 -18
  3. package/dist/_shared/tokens.js +0 -1
  4. package/dist/_types/atoms/CopyableValue/CopyableValue.d.ts +4 -4
  5. package/dist/_types/atoms/DescriptionList/DescriptionList.d.ts +5 -4
  6. package/dist/_types/atoms/DotsButton/DotsButton.d.ts +15 -0
  7. package/dist/_types/atoms/ProgressBar/ProgressBar.d.ts +12 -2
  8. package/dist/_types/atoms/Slider/Slider.d.ts +19 -2
  9. package/dist/_types/atoms/Spinner/Spinner.d.ts +15 -1
  10. package/dist/_types/constants/copy-to-clipboard.d.ts +22 -0
  11. package/dist/_types/messages/BrandMessages.d.ts +35 -1
  12. package/dist/_types/messages/index.d.ts +1 -1
  13. package/dist/_types/molecules/CalendarPlanner/CalendarPlanner.d.ts +13 -3
  14. package/dist/_types/molecules/CalendarRoster/CalendarRoster.d.ts +38 -5
  15. package/dist/_types/molecules/Carousel/Carousel.d.ts +65 -13
  16. package/dist/_types/molecules/CodeBlock/CodeBlock.d.ts +20 -6
  17. package/dist/_types/molecules/ContextMenu/ContextMenu.d.ts +5 -1
  18. package/dist/_types/molecules/CopyButton/CopyButton.d.ts +5 -6
  19. package/dist/_types/molecules/FilterBar/FilterBar.d.ts +4 -3
  20. package/dist/_types/molecules/LanguageSwitcher/LanguageSwitcher.d.ts +13 -1
  21. package/dist/_types/molecules/NotificationList/NotificationList.d.ts +33 -3
  22. package/dist/_types/molecules/Pagination/Pagination.d.ts +16 -2
  23. package/dist/_types/molecules/ProjectCard/ProjectCard.d.ts +14 -1
  24. package/dist/_types/molecules/Stepper/Stepper.d.ts +32 -7
  25. package/dist/_types/molecules/TreeView/TreeView.d.ts +11 -2
  26. package/dist/_types/molecules/UptimeBars/UptimeBars.d.ts +20 -2
  27. package/dist/_types/organisms/Chart/Chart.d.ts +46 -8
  28. package/dist/_types/sections/LegalFooter/LegalFooter.d.ts +13 -1
  29. package/dist/_types/templates/PublicPageShell/PublicPageShell.d.ts +15 -1
  30. package/dist/brand.css +2 -4
  31. package/dist/calendar-planner.js +47 -47
  32. package/dist/calendar-roster.js +28 -25
  33. package/dist/carousel.js +69 -67
  34. package/dist/chart.js +250 -249
  35. package/dist/code-block.js +34 -34
  36. package/dist/context-menu.js +1 -1
  37. package/dist/copy-button.js +35 -34
  38. package/dist/copyable-value.js +43 -42
  39. package/dist/description-list.js +1 -1
  40. package/dist/dots-button.js +18 -17
  41. package/dist/filter-bar.css +1 -1
  42. package/dist/language-switcher.js +43 -41
  43. package/dist/legal-footer.js +21 -18
  44. package/dist/notification-list.js +40 -38
  45. package/dist/pagination.js +12 -12
  46. package/dist/progress-bar.js +1 -0
  47. package/dist/project-card.js +31 -30
  48. package/dist/public-page-shell.js +12 -11
  49. package/dist/slider.js +24 -23
  50. package/dist/spinner.js +19 -14
  51. package/dist/stepper.js +35 -38
  52. package/dist/tokens.css +2 -4
  53. package/dist/tree-view.js +86 -85
  54. package/dist/uptime-bars.js +54 -53
  55. package/package.json +1 -1
  56. package/src/tokens/molecules/filter-bar.css +1 -2
  57. package/src/tokens/scss/molecules/_filter-bar.scss +1 -2
  58. package/src/tokens/surface-public.css +0 -1
  59. package/src/tokens/tokens.json +0 -1
package/CHANGELOG.md CHANGED
@@ -7,6 +7,167 @@ 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
+ ## [48.1.0] — 2026-09-16
11
+
12
+ > **Minor.** `FilterBar` pasa a columnas fijas por punto de corte —4 en escritorio, 2 en
13
+ > tableta, 1 antes de `md`— que llenan la fila entera en vez de dejar hueco a la derecha.
14
+ > Y `Pagination` deja de pintarse con 0 registros, sea cual sea el resto de sus props.
15
+
16
+ ### `FilterBar`: columnas por punto de corte, no por aritmética del ancho disponible
17
+
18
+ `.filter-bar__row` era `repeat(auto-fill, minmax(<mínimo>, 1fr))`: el número de columnas
19
+ lo decidía solo el ancho disponible, así que cuatro filtros en escritorio podían dejar una
20
+ columna vacía a la derecha en vez de llenar la fila. Ahora el máximo de columnas es fijo
21
+ por punto de corte —4 en `lg`, 2 en `md`, 1 antes— y la rejilla es `auto-fit` con un
22
+ mínimo que es una fracción del contenedor: con menos filtros que el máximo, las columnas
23
+ que sobran colapsan y las que tienen contenido se reparten el ancho sobrante, así que la
24
+ fila siempre queda llena — tres filtros en escritorio son tres columnas iguales, no tres
25
+ de cuatro con hueco. Con más filtros que el máximo, saltan de fila como antes. El botón de
26
+ `actions` sigue siendo una celda más de la misma rejilla, así que participa del reparto.
27
+
28
+ Se retira el token `filter-bar.column-min-inline-size` (ya no decide nada: el máximo de
29
+ columnas es fijo en el CSS, no una medida). El resto de los tokens de la barra no cambia.
30
+
31
+ ### `Pagination`: con 0 registros, nunca se pinta
32
+
33
+ `total === 0` dejaba de pintar el `<nav>` solo si además `pageCount` no estaba informado y
34
+ `afterPageSize` estaba vacío — con `showTotal`, con el selector de página o con la ranura
35
+ llena, un listado sin resultados seguía sacando un paginador sin nada que paginar. Ahora
36
+ `total === 0` (o `pageCount === 0`) no pinta el `<nav>` **nunca**, con independencia de las
37
+ demás props. La ranura sigue salvando al paginador solo cuando el total **no se conoce
38
+ todavía** (la prop no se ha informado) y hay como mucho una página — una tabla que aún no
39
+ ha resuelto su total pero ya trae algo que exportar—; con una página y registros de verdad
40
+ (`total` informado y mayor que 0) se sigue pintando si hay selector, ranura o total, como
41
+ antes.
42
+
43
+ ## [48.0.0] — 2026-09-16
44
+
45
+ > **Major.** Novena familia al proveedor de textos: copiar, datos y estado. Diecisiete
46
+ > espacios nuevos, y con ellos el primero que **no es de un componente sino de una
47
+ > conducta**: `copy`, las tres palabras que dicen por igual el botón suelto, el valor en
48
+ > línea y el bloque de código. Además, la banda de preferencias de `PublicPageShell` se
49
+ > puede pedir a otra medida, y `Foundations/Redacción` fija por escrito que los estados de
50
+ > carga conservan sus puntos suspensivos.
51
+
52
+ ### Copiar, datos y estado leen del proveedor
53
+
54
+ Diecisiete espacios nuevos en `BrandMessages`: `copy`, `codeBlock`, `dotsButton`,
55
+ `progressBar`, `spinner`, `slider`, `treeView`, `uptimeBars`, `chart`, `stepper`,
56
+ `carousel`, `languageSwitcher`, `projectCard`, `legalFooter`, `calendarRoster`,
57
+ `calendarPlanner` y `notificationList`. Mismo orden —**prop → proveedor → error**— y cada
58
+ texto se lee **donde se pinta**: un botón que nunca falla no exige el aviso de
59
+ portapapeles roto, un spinner decorativo no exige su texto, un progreso que empieza en el
60
+ primer paso no exige la marca de «completado», un deslizador de un pulgar no exige los dos
61
+ nombres del rango y un cuadrante sin leyenda no exige ninguno de sus seis tipos.
62
+
63
+ ### `copy` es un espacio de conducta, y es la primera excepción a «un espacio por componente»
64
+
65
+ `CopyButton`, `CopyableValue`, `DescriptionDetails copyable` y el acuse de `CodeBlock`
66
+ dicen **las mismas tres palabras**: «Copiar», «Copiado», «No se pudo copiar». Un espacio
67
+ por componente habría obligado a la aplicación a escribirlas tres veces, con el riesgo de
68
+ que un día dijeran cosas distintas; el catálogo de la suite ya las tiene una sola vez
69
+ (`common.copy`, `common.copied`). Así que la interfaz `CopyMessages` vive donde ya vivía
70
+ la conducta compartida —`src/stories/constants/copy-to-clipboard.ts`— y no junto a un
71
+ componente: lo que comparten es el comportamiento, y el texto va con él.
72
+
73
+ `CodeBlock` es el caso que lo enseña: lee de **dos** espacios, porque su rótulo dice
74
+ «Copiar código» (suyo, `codeBlock.copy`) y su acuse dice «Copiado» (de todos,
75
+ `copy.copied`). Y `codeBlock.region` —el nombre del área desplazable— interpola el
76
+ lenguaje, así que es función.
77
+
78
+ ### Un nombre genérico es cromo; el de ESTA pantalla sigue siendo prop
79
+
80
+ `ProgressBar` y `TreeView` son la pareja que mejor lo enseña. El catálogo pone «Progreso»
81
+ y «Árbol», que valen en cualquier pantalla; lo que avanza de verdad —«Subiendo el
82
+ vídeo»— y de qué árbol se trata —«Matriz de contenidos»— lo sabe solo la pantalla, y para
83
+ eso siguen estando las props, que ganan. Lo mismo en `Chart`: el cromo de la tabla
84
+ equivalente es catálogo, pero **`ariaLabel` sigue obligatorio y fuera** —un texto común lo
85
+ dejaría diciendo «Gráfico» en todas partes sin que nada fallara—.
86
+
87
+ ### Cuatro piezas entran al alcance por arrastre
88
+
89
+ `Spinner` no estaba en la lista y entra: es el estado por excelencia, y su «Cargando…» es
90
+ exactamente el texto que la norma de redacción de esta misma release declara excepción.
91
+ `Slider` tenía tres palabras cableadas dentro del default de `thumbLabel` («Valor»,
92
+ «Mínimo», «Máximo») que ninguna prop de texto dejaba ver. `CalendarPlanner` comparte
93
+ familia con `CalendarRoster` y se habría quedado con su «+N más» en castellano.
94
+ `DescriptionDetails` y `ContextMenu` pasan a ser **reenvíos puros**: sus props siguen
95
+ existiendo como anulación puntual, pero ya no hacen falta para traducir.
96
+
97
+ `MessageComposer`, `ConversationList`, `ConversationThread`, `AssistantMessage`,
98
+ `AnnotationThread`, `ChatShell`, `TypingIndicator` y las pantallas de `ConnectorAuth`
99
+ **no entran**: son texto de producto y legal, y tienen ola propia.
100
+
101
+ ### La leyenda del cuadrante va clave a clave, contra la regla general
102
+
103
+ La norma del sistema es que una **lista** se traduce pasándola entera, no con una prop de
104
+ texto por elemento. Los seis tipos de la leyenda de `CalendarRoster` son la excepción: es
105
+ un vocabulario **cerrado** del componente —festivo, vacaciones, ausencia, recuperación,
106
+ cumpleaños, no laborable—, y obligar a la aplicación a montar el array con sus `type`
107
+ correctos solo para traducir seis palabras era peor que darles seis claves.
108
+ `legendItems` sigue existiendo para sustituir la leyenda **entera** —otro orden, otros
109
+ tipos— y gana. `birthdayPrefix` se queda fuera: es un emoji, y un emoji no se traduce.
110
+
111
+ ### Redacción: los estados de carga conservan los puntos suspensivos
112
+
113
+ Sección propia en `Foundations/Redacción`, con sus ejemplos ✓/✗. «Buscando…»,
114
+ «Cargando…», «Guardando…» no son una frase que se corta: son **progreso**, y los tres
115
+ puntos dicen que algo está pasando ahora mismo y que va a terminar. Quitárselos convierte
116
+ el estado en un rótulo. Vale igual para el texto visible y para el que solo oye un lector
117
+ de pantalla. Lo que **no** es un estado en curso sigue sin llevarlos, aunque hable de algo
118
+ que tarda.
119
+
120
+ ### La banda de preferencias de `PublicPageShell` se puede pedir a otra medida
121
+
122
+ Prop nueva, `preferencesWidth?: ContainerWidth`, con el prefijo de la ranura —como
123
+ `mainWidth`— porque el marco tiene cuatro y un `width` pelado no diría cuál gobierna. El
124
+ default es `'xl'`, lo de hoy, **así que esta parte no es breaking**. Una página que lee a
125
+ `lg` pide `preferencesWidth="lg"` y la banda estrecha con ella.
126
+
127
+ Lo que resolvía el hueco hasta hoy —anidar un `Container width="lg"` dentro de
128
+ `preferences`— metía un `container__inner` dentro de otro: el relleno lateral se contaba
129
+ dos veces y la banda dejaba de alinear con el `main`. Sin CSS nuevo.
130
+
131
+ ### Para quien actualice
132
+
133
+ El catálogo del `BrandMessagesProvider` tiene que crecer con los diecisiete espacios, o la
134
+ primera pantalla con un `CopyButton`, un `Spinner` o una `ProgressBar` **lanza en render**.
135
+ Estas son las claves que hay que aportar:
136
+
137
+ | Espacio | Claves | Qué es |
138
+ | --- | --- | --- |
139
+ | `copy` | `label`, `copied`, `error` | copiar al portapapeles, para toda la familia |
140
+ | `codeBlock` | `copy`, `region(language?)` | el rótulo propio del bloque y el nombre de su área |
141
+ | `dotsButton` | `label` | el botón de tres puntos — lo reenvía `ContextMenu` |
142
+ | `progressBar` | `label` | el nombre genérico de lo que avanza |
143
+ | `spinner` | `label` | la espera, con sus puntos suspensivos |
144
+ | `slider` | `value`, `min`, `max`, `valueAt(index)` | los nombres de los pulgares |
145
+ | `treeView` | `label` | el nombre genérico del árbol |
146
+ | `uptimeBars` | `label`, `noData` | la tira y cómo se dice que un punto no tiene dato |
147
+ | `chart` | `tableCaption`, `tableHint`, `category`, `value`, `share`, `empty` | el cromo de la tabla equivalente |
148
+ | `stepper` | `label`, `compact(current, total)`, `completed`, `current`, `pending` | el progreso y sus tres marcas de estado |
149
+ | `carousel` | `label`, `roleDescription`, `track`, `previous`, `next`, `indicator(index)`, `pause`, `play`, `slideStatus(index, total)`, `slideRoleDescription` | todo el cromo del carrusel |
150
+ | `languageSwitcher` | `label` | la etiqueta del selector — **no** los idiomas |
151
+ | `projectCard` | `tags` | la lista de etiquetas de categoría |
152
+ | `legalFooter` | `label` | la navegación del pie legal |
153
+ | `calendarRoster` | `name`, `legend`, `holiday`, `vacation`, `absence`, `recovery`, `birthday`, `nonWorking` | la columna de nombres y los seis tipos de la leyenda |
154
+ | `calendarPlanner` | `more(count)` | el botón de desbordamiento de una celda |
155
+ | `notificationList` | `label`, `unread`, `markRead` | la bandeja — **no** el panel de la cabecera |
156
+
157
+ Seis de ellas interpolan un dato (`codeBlock.region`, `slider.valueAt`, `stepper.compact`,
158
+ `carousel.indicator`, `carousel.slideStatus`, `calendarPlanner.more`), así que son
159
+ funciones.
160
+
161
+ A cambio, dejan de hacer falta para traducir `DescriptionDetails.copyLabel` y
162
+ `copiedLabel`, y `ContextMenu.label`: son reenvíos puros y siguen existiendo solo como
163
+ anulación puntual. `RecoveryCodes` mantiene sus tres `labels` obligatorias —«Copiar todos»
164
+ no es «Copiar»—, pero su botón lee `copy.error` si el portapapeles falla.
165
+
166
+ **Ojo con dos valores.** `spinner.label` lleva **puntos suspensivos** dentro («Cargando…»):
167
+ son parte del texto, no adorno. Y `notificationList.*` no es `notificationPanel.*`: en el
168
+ catálogo de la suite son `notifications.inbox.*` y `notifications.panel.*`, y mezclarlos
169
+ deja la bandeja diciendo lo del flotante.
170
+
10
171
  ## [47.1.0] — 2026-09-15
11
172
 
12
173
  > **Minor.** La norma de puntuación de subtítulos y estados vacíos, fijada por escrito en
@@ -1,8 +1,9 @@
1
1
  import '../progressbar.css';
2
- import { jsx as e, jsxs as t } from "react/jsx-runtime";
2
+ import { n as e } from "./brandmessagescontext.js";
3
+ import { jsx as t, jsxs as n } from "react/jsx-runtime";
3
4
  //#endregion
4
5
  //#region src/stories/atoms/ProgressBar/ProgressBar.tsx
5
- var n = Number({ "progress-bar": {
6
+ var r = Number({ "progress-bar": {
6
7
  "height-sm": {
7
8
  $value: "{spacing.2}",
8
9
  $type: "dimension",
@@ -179,38 +180,38 @@ var n = Number({ "progress-bar": {
179
180
  $description: "Cifra sobre el relleno primary — surface-dark. El relleno se invierte a blanco, así que la cifra pasa a la tinta clara: si no, quedaría blanco sobre blanco"
180
181
  }
181
182
  } }["progress-bar"]["inside-label-threshold"].$value);
182
- function r({ value: r, variant: i = "primary", size: a = "md", label: o = "Progreso", className: s }) {
183
- let c = Math.min(100, Math.max(0, Math.round(r))), l = a !== "sm", u = l && c >= n, d = l && !u;
184
- return /* @__PURE__ */ e("div", {
183
+ function i({ value: i, variant: a = "primary", size: o = "md", label: s, className: c }) {
184
+ let l = e("progressBar"), u = Math.min(100, Math.max(0, Math.round(i))), d = o !== "sm", f = d && u >= r, p = d && !f;
185
+ return /* @__PURE__ */ t("div", {
185
186
  className: [
186
187
  "progress-bar",
187
- `progress-bar--${i}`,
188
188
  `progress-bar--${a}`,
189
- s
189
+ `progress-bar--${o}`,
190
+ c
190
191
  ].filter(Boolean).join(" "),
191
- children: /* @__PURE__ */ t("div", {
192
+ children: /* @__PURE__ */ n("div", {
192
193
  className: "progress-bar__track",
193
194
  role: "progressbar",
194
- "aria-valuenow": c,
195
+ "aria-valuenow": u,
195
196
  "aria-valuemin": 0,
196
197
  "aria-valuemax": 100,
197
- "aria-valuetext": `${c}%`,
198
- "aria-label": o,
199
- "data-value": c,
200
- children: [/* @__PURE__ */ e("div", {
198
+ "aria-valuetext": `${u}%`,
199
+ "aria-label": l("label", s),
200
+ "data-value": u,
201
+ children: [/* @__PURE__ */ t("div", {
201
202
  className: "progress-bar__fill",
202
- children: u && /* @__PURE__ */ t("span", {
203
+ children: f && /* @__PURE__ */ n("span", {
203
204
  className: "progress-bar__label progress-bar__label--inside",
204
205
  "aria-hidden": "true",
205
- children: [c, "%"]
206
+ children: [u, "%"]
206
207
  })
207
- }), d && /* @__PURE__ */ t("span", {
208
+ }), p && /* @__PURE__ */ n("span", {
208
209
  className: "progress-bar__label progress-bar__label--outside",
209
210
  "aria-hidden": "true",
210
- children: [c, "%"]
211
+ children: [u, "%"]
211
212
  })]
212
213
  })
213
214
  });
214
215
  }
215
216
  //#endregion
216
- export { r as t };
217
+ export { i as t };
@@ -2546,7 +2546,6 @@ var e = {
2546
2546
  "--filter-bar-gap": "1.5rem",
2547
2547
  "--filter-bar-column-gap": "1rem",
2548
2548
  "--filter-bar-row-gap": "0.75rem",
2549
- "--filter-bar-column-min-inline-size": "12rem",
2550
2549
  "--filter-bar-actions-gap": "0.75rem",
2551
2550
  "--filter-bar-label-offset": "calc(0.875rem * 1.5 + 0.5rem)",
2552
2551
  "--filter-bar-control-block-size": "2.5rem",
@@ -10,13 +10,13 @@ export interface CopyableValueProps {
10
10
  */
11
11
  copyText?: string;
12
12
  /**
13
- * Nombre accesible del botón de copiar. Default castellano.
14
- * @default 'Copiar'
13
+ * Nombre accesible del botón de copiar. **Sin default**: sin él, sale de
14
+ * `copy.label` del `BrandMessagesProvider`.
15
15
  */
16
16
  copyLabel?: string;
17
17
  /**
18
- * Acuse tras copiar, anunciado en una región viva. Default castellano.
19
- * @default 'Copiado'
18
+ * Acuse tras copiar, anunciado en una región viva. **Sin default**: sin él,
19
+ * sale de `copy.copied`. Solo se lee tras copiar.
20
20
  */
21
21
  copiedLabel?: string;
22
22
  /** Se añade DESPUÉS de las clases propias. */
@@ -31,13 +31,14 @@ export interface DescriptionDetailsProps extends React.ComponentPropsWithoutRef<
31
31
  */
32
32
  copyText?: string;
33
33
  /**
34
- * Nombre accesible del botón de copiar. Default castellano.
35
- * @default 'Copiar'
34
+ * Nombre accesible del botón de copiar. **Reenvío puro** al `CopyableValue`
35
+ * de dentro, que lee `copy.label` del `BrandMessagesProvider`: no hace falta
36
+ * pasarla para traducir.
36
37
  */
37
38
  copyLabel?: string;
38
39
  /**
39
- * Acuse tras copiar, anunciado en una región viva. Default castellano.
40
- * @default 'Copiado'
40
+ * Acuse tras copiar. **Reenvío puro** al `CopyableValue`, que lee
41
+ * `copy.copied`.
41
42
  */
42
43
  copiedLabel?: string;
43
44
  }
@@ -1,10 +1,25 @@
1
1
  import { type ButtonBaseProps } from '../Button/Button';
2
2
  import './DotsButton.css';
3
+ /**
4
+ * El único texto del botón de tres puntos, y es **cromo**: dice que hay más
5
+ * acciones, no de qué son. Es el mismo en una fila de tabla, en una tarjeta y
6
+ * dentro de un `ContextMenu`, así que va al catálogo una sola vez y el
7
+ * `ContextMenu` lo reenvía sin repetir la clave.
8
+ */
9
+ export interface DotsButtonMessages {
10
+ /** Nombre accesible del botón. */
11
+ label: string;
12
+ }
3
13
  export interface DotsButtonProps extends Omit<ButtonBaseProps, 'variant' | 'iconOnly' | 'children' | 'href'> {
4
14
  /** Talla del sistema (32/40/48). */
5
15
  size?: 'sm' | 'md' | 'lg';
6
16
  /** Puntos en fila (por defecto) o en columna. */
7
17
  orientation?: 'horizontal' | 'vertical';
18
+ /**
19
+ * Nombre accesible del botón. **Sin default**: sin él, sale de
20
+ * `dotsButton.label` del `BrandMessagesProvider`.
21
+ */
22
+ 'aria-label'?: string;
8
23
  }
9
24
  /**
10
25
  * El botón de «más opciones»: un `Button` ghost de solo icono con el icono
@@ -1,4 +1,13 @@
1
1
  import './ProgressBar.css';
2
+ /**
3
+ * El único texto de la barra, y es **cromo**: el nombre genérico de lo que
4
+ * avanza. Lo que avanza **de verdad** en una pantalla concreta —«Subiendo el
5
+ * vídeo»— se dice con la prop `label`, que gana.
6
+ */
7
+ export interface ProgressBarMessages {
8
+ /** Nombre accesible de la barra cuando la pantalla no dice qué avanza. */
9
+ label: string;
10
+ }
2
11
  export type ProgressBarVariant = 'primary' | 'accent-1' | 'accent-2' | 'support-1' | 'support-2';
3
12
  export type ProgressBarSize = 'sm' | 'md' | 'lg';
4
13
  export interface ProgressBarProps {
@@ -9,8 +18,9 @@ export interface ProgressBarProps {
9
18
  /** Talla de la barra. En `sm` no se muestra la cifra. */
10
19
  size?: ProgressBarSize;
11
20
  /**
12
- * Nombre accesible de la barra: qué está avanzando. Default: «Progreso»
13
- * (castellano). Una app multiidioma debe pasarlo traducido.
21
+ * Nombre accesible de la barra: qué está avanzando. **Sin default**: sin él,
22
+ * sale de `progressBar.label` del `BrandMessagesProvider`, que es el nombre
23
+ * genérico; esta prop es la que dice qué avanza en ESTA pantalla.
14
24
  */
15
25
  label?: string;
16
26
  /** Clases adicionales para el contenedor. */
@@ -1,5 +1,20 @@
1
1
  import { Slider as BaseSlider } from '@base-ui/react/slider';
2
2
  import './Slider.css';
3
+ /**
4
+ * Los nombres genéricos de los pulgares, y son **cromo**: dicen qué pulgar es,
5
+ * no qué mide el deslizador. Lo que mide se dice con `label`, que es de la
6
+ * pantalla, y la cifra es formato.
7
+ */
8
+ export interface SliderMessages {
9
+ /** Nombre del pulgar único cuando el deslizador no trae `label`. */
10
+ value: string;
11
+ /** Nombre del primer pulgar de un rango de dos. */
12
+ min: string;
13
+ /** Nombre del segundo pulgar de un rango de dos. */
14
+ max: string;
15
+ /** Nombre del pulgar n (base 1) con tres o más. Interpola, así que es función. */
16
+ valueAt: (index: number) => string;
17
+ }
3
18
  type BaseSliderRootProps = Omit<React.ComponentPropsWithoutRef<typeof BaseSlider.Root>, 'className' | 'value' | 'defaultValue' | 'onValueChange' | 'onValueCommitted'>;
4
19
  export interface SliderProps extends BaseSliderRootProps {
5
20
  /** Valor actual (controlado). Un número, o una lista para un rango. */
@@ -16,8 +31,10 @@ export interface SliderProps extends BaseSliderRootProps {
16
31
  */
17
32
  label?: string;
18
33
  /**
19
- * Nombre accesible de cada pulgar. Por defecto, en castellano: con dos
20
- * pulgares «Mínimo» y «Máximo»; con más, «Valor 1», «Valor 2»…
34
+ * Nombre accesible de cada pulgar. **Sin default**: sin él, con un pulgar es
35
+ * `label` —y en su defecto `slider.value`—, con dos son `slider.min` y
36
+ * `slider.max`, y con más, `slider.valueAt`. Cada clave se lee **donde se
37
+ * pinta**: un deslizador de un solo pulgar no exige las del rango.
21
38
  */
22
39
  thumbLabel?: (index: number, total: number) => string;
23
40
  /** Muestra el valor formateado junto a la banda. */
@@ -1,8 +1,22 @@
1
1
  import './Spinner.css';
2
+ /**
3
+ * El único texto de la espera, y es **cromo**: lo que se dice mientras no se
4
+ * sabe cuánto falta. Conserva los puntos suspensivos —es progreso, no una
5
+ * frase: ver Foundations → Redacción § «Los estados de carga llevan puntos
6
+ * suspensivos».
7
+ */
8
+ export interface SpinnerMessages {
9
+ /** Texto anunciado por lectores de pantalla mientras se espera. */
10
+ label: string;
11
+ }
2
12
  export type SpinnerSize = 'sm' | 'md' | 'lg';
3
13
  export interface SpinnerProps {
4
14
  size?: SpinnerSize;
5
- /** Texto anunciado por lectores de pantalla. Default castellano: «Cargando…». Ignorado cuando aria-hidden es true. */
15
+ /**
16
+ * Texto anunciado por lectores de pantalla. **Sin default**: sin él, sale de
17
+ * `spinner.label` del `BrandMessagesProvider`. **No se lee** cuando
18
+ * `aria-hidden` es `true`: un spinner decorativo no exige la clave.
19
+ */
6
20
  label?: string;
7
21
  /** Cuando true, el spinner es puramente decorativo (sin rol ni anuncio). */
8
22
  'aria-hidden'?: boolean;
@@ -32,3 +32,25 @@ export declare function useCopyToClipboard(feedbackDuration?: number): {
32
32
  error: unknown;
33
33
  }>;
34
34
  };
35
+ /**
36
+ * Los tres textos de copiar al portapapeles, en **un solo espacio** para toda
37
+ * la familia: el botón suelto (`CopyButton`), el valor en línea
38
+ * (`CopyableValue`, y con él `DescriptionDetails copyable`) y el bloque de
39
+ * código (`CodeBlock`, que solo lee el acuse: su rótulo dice «Copiar código» y
40
+ * vive en `codeBlock.copy`).
41
+ *
42
+ * No es un espacio por componente como el resto, y es deliberado: son
43
+ * literalmente las mismas tres palabras en los tres sitios, el catálogo de la
44
+ * suite ya las tiene una sola vez (`common.copy`, `common.copied`) y repetir
45
+ * la clave por componente obligaría a la aplicación a escribir «Copiar» tres
46
+ * veces con el riesgo de que un día dijeran cosas distintas. Lo que comparten
47
+ * es la conducta —por eso este fichero existe—, y el texto va con ella.
48
+ */
49
+ export interface CopyMessages {
50
+ /** Nombre accesible del botón de copiar. */
51
+ label: string;
52
+ /** Acuse tras copiar, anunciado en una región viva. */
53
+ copied: string;
54
+ /** Aviso cuando el portapapeles no está disponible (contexto no seguro, permiso denegado). */
55
+ error: string;
56
+ }
@@ -45,6 +45,23 @@ import type { TableOfContentsMessages } from '../molecules/TableOfContents/Table
45
45
  import type { PrevNextNavMessages } from '../molecules/PrevNextNav/PrevNextNav';
46
46
  import type { PublicPageShellMessages } from '../templates/PublicPageShell/PublicPageShell';
47
47
  import type { OnboardingShellMessages } from '../templates/OnboardingShell/OnboardingShell';
48
+ import type { CopyMessages } from '../constants/copy-to-clipboard';
49
+ import type { CodeBlockMessages } from '../molecules/CodeBlock/CodeBlock';
50
+ import type { DotsButtonMessages } from '../atoms/DotsButton/DotsButton';
51
+ import type { ProgressBarMessages } from '../atoms/ProgressBar/ProgressBar';
52
+ import type { SpinnerMessages } from '../atoms/Spinner/Spinner';
53
+ import type { SliderMessages } from '../atoms/Slider/Slider';
54
+ import type { TreeViewMessages } from '../molecules/TreeView/TreeView';
55
+ import type { UptimeBarsMessages } from '../molecules/UptimeBars/UptimeBars';
56
+ import type { ChartMessages } from '../organisms/Chart/Chart';
57
+ import type { StepperMessages } from '../molecules/Stepper/Stepper';
58
+ import type { CarouselMessages } from '../molecules/Carousel/Carousel';
59
+ import type { LanguageSwitcherMessages } from '../molecules/LanguageSwitcher/LanguageSwitcher';
60
+ import type { ProjectCardMessages } from '../molecules/ProjectCard/ProjectCard';
61
+ import type { LegalFooterMessages } from '../sections/LegalFooter/LegalFooter';
62
+ import type { CalendarRosterMessages } from '../molecules/CalendarRoster/CalendarRoster';
63
+ import type { CalendarPlannerMessages } from '../molecules/CalendarPlanner/CalendarPlanner';
64
+ import type { NotificationListMessages } from '../molecules/NotificationList/NotificationList';
48
65
  /**
49
66
  * El contrato de textos de la librería: un espacio por componente, y dentro
50
67
  * de cada espacio **todas las claves obligatorias**.
@@ -114,5 +131,22 @@ export interface BrandMessages {
114
131
  prevNextNav: PrevNextNavMessages;
115
132
  publicPageShell: PublicPageShellMessages;
116
133
  onboardingShell: OnboardingShellMessages;
134
+ copy: CopyMessages;
135
+ codeBlock: CodeBlockMessages;
136
+ dotsButton: DotsButtonMessages;
137
+ progressBar: ProgressBarMessages;
138
+ spinner: SpinnerMessages;
139
+ slider: SliderMessages;
140
+ treeView: TreeViewMessages;
141
+ uptimeBars: UptimeBarsMessages;
142
+ chart: ChartMessages;
143
+ stepper: StepperMessages;
144
+ carousel: CarouselMessages;
145
+ languageSwitcher: LanguageSwitcherMessages;
146
+ projectCard: ProjectCardMessages;
147
+ legalFooter: LegalFooterMessages;
148
+ calendarRoster: CalendarRosterMessages;
149
+ calendarPlanner: CalendarPlannerMessages;
150
+ notificationList: NotificationListMessages;
117
151
  }
118
- export type { PaginationMessages, TableMessages, DataTableMessages, InputFieldMessages, PasswordFieldMessages, SelectMessages, MultiSelectMessages, NumberInputMessages, OtpInputMessages, InputPhoneMessages, AsyncSelectMessages, AsyncMultiSelectMessages, DocsSearchMessages, SearchFormMessages, FilterBarMessages, CalendarMessages, DatePickerMessages, TimeSelectMessages, FileUploadMessages, ImageCropDialogMessages, AvatarUploadMessages, ModalMessages, SheetMessages, ConfirmDialogMessages, AlertMessages, BannerMessages, ToasterMessages, ConsentMessages, CommandPaletteMessages, AppLauncherMessages, FloatingDockMessages, NotificationButtonMessages, NotificationPanelMessages, MenuButtonMessages, AppRootMessages, AppShellMessages, SidebarMessages, SidebarNavMessages, SiteNavMessages, SiteHeaderMessages, UserMenuMessages, OrgSwitcherMessages, BreadcrumbMessages, TableOfContentsMessages, PrevNextNavMessages, PublicPageShellMessages, OnboardingShellMessages, };
152
+ export type { PaginationMessages, TableMessages, DataTableMessages, InputFieldMessages, PasswordFieldMessages, SelectMessages, MultiSelectMessages, NumberInputMessages, OtpInputMessages, InputPhoneMessages, AsyncSelectMessages, AsyncMultiSelectMessages, DocsSearchMessages, SearchFormMessages, FilterBarMessages, CalendarMessages, DatePickerMessages, TimeSelectMessages, FileUploadMessages, ImageCropDialogMessages, AvatarUploadMessages, ModalMessages, SheetMessages, ConfirmDialogMessages, AlertMessages, BannerMessages, ToasterMessages, ConsentMessages, CommandPaletteMessages, AppLauncherMessages, FloatingDockMessages, NotificationButtonMessages, NotificationPanelMessages, MenuButtonMessages, AppRootMessages, AppShellMessages, SidebarMessages, SidebarNavMessages, SiteNavMessages, SiteHeaderMessages, UserMenuMessages, OrgSwitcherMessages, BreadcrumbMessages, TableOfContentsMessages, PrevNextNavMessages, PublicPageShellMessages, OnboardingShellMessages, CopyMessages, CodeBlockMessages, DotsButtonMessages, ProgressBarMessages, SpinnerMessages, SliderMessages, TreeViewMessages, UptimeBarsMessages, ChartMessages, StepperMessages, CarouselMessages, LanguageSwitcherMessages, ProjectCardMessages, LegalFooterMessages, CalendarRosterMessages, CalendarPlannerMessages, NotificationListMessages, };
@@ -2,4 +2,4 @@ export { BrandMessagesProvider } from './BrandMessagesProvider';
2
2
  export type { BrandMessagesProviderProps } from './BrandMessagesProvider';
3
3
  export { useBrandMessages } from './BrandMessagesContext';
4
4
  export type { BrandMessagesReader } from './BrandMessagesContext';
5
- export type { BrandMessages, PaginationMessages, TableMessages, DataTableMessages, InputFieldMessages, PasswordFieldMessages, SelectMessages, MultiSelectMessages, NumberInputMessages, OtpInputMessages, InputPhoneMessages, AsyncSelectMessages, AsyncMultiSelectMessages, DocsSearchMessages, SearchFormMessages, FilterBarMessages, CalendarMessages, DatePickerMessages, TimeSelectMessages, FileUploadMessages, ImageCropDialogMessages, AvatarUploadMessages, ModalMessages, SheetMessages, ConfirmDialogMessages, AlertMessages, BannerMessages, ToasterMessages, ConsentMessages, CommandPaletteMessages, AppLauncherMessages, FloatingDockMessages, NotificationButtonMessages, NotificationPanelMessages, MenuButtonMessages, AppRootMessages, AppShellMessages, SidebarMessages, SidebarNavMessages, SiteNavMessages, SiteHeaderMessages, UserMenuMessages, OrgSwitcherMessages, BreadcrumbMessages, TableOfContentsMessages, PrevNextNavMessages, PublicPageShellMessages, OnboardingShellMessages, } from './BrandMessages';
5
+ export type { BrandMessages, PaginationMessages, TableMessages, DataTableMessages, InputFieldMessages, PasswordFieldMessages, SelectMessages, MultiSelectMessages, NumberInputMessages, OtpInputMessages, InputPhoneMessages, AsyncSelectMessages, AsyncMultiSelectMessages, DocsSearchMessages, SearchFormMessages, FilterBarMessages, CalendarMessages, DatePickerMessages, TimeSelectMessages, FileUploadMessages, ImageCropDialogMessages, AvatarUploadMessages, ModalMessages, SheetMessages, ConfirmDialogMessages, AlertMessages, BannerMessages, ToasterMessages, ConsentMessages, CommandPaletteMessages, AppLauncherMessages, FloatingDockMessages, NotificationButtonMessages, NotificationPanelMessages, MenuButtonMessages, AppRootMessages, AppShellMessages, SidebarMessages, SidebarNavMessages, SiteNavMessages, SiteHeaderMessages, UserMenuMessages, OrgSwitcherMessages, BreadcrumbMessages, TableOfContentsMessages, PrevNextNavMessages, PublicPageShellMessages, OnboardingShellMessages, CopyMessages, CodeBlockMessages, DotsButtonMessages, ProgressBarMessages, SpinnerMessages, SliderMessages, TreeViewMessages, UptimeBarsMessages, ChartMessages, StepperMessages, CarouselMessages, LanguageSwitcherMessages, ProjectCardMessages, LegalFooterMessages, CalendarRosterMessages, CalendarPlannerMessages, NotificationListMessages, } from './BrandMessages';
@@ -1,6 +1,16 @@
1
1
  import { type ReactNode } from 'react';
2
2
  import type { TagVariant } from '../../atoms/Tag/Tag';
3
3
  import './CalendarPlanner.css';
4
+ /**
5
+ * El único texto propio del planificador: el botón que abre los eventos que no
6
+ * caben en una celda. Las **flechas de mes no están aquí** —son el mismo texto
7
+ * que el del `Calendar` y salen de `calendar.previousMonth` / `.nextMonth`—, y
8
+ * `gridLabel` tampoco: nombra a ESE planificador.
9
+ */
10
+ export interface CalendarPlannerMessages {
11
+ /** Rótulo del botón de desbordamiento: «+3 más». Interpola, así que es función. */
12
+ more: (count: number) => string;
13
+ }
4
14
  export interface PlannerEvent {
5
15
  id: string;
6
16
  date: Date;
@@ -60,9 +70,9 @@ export interface CalendarPlannerProps {
60
70
  */
61
71
  gridLabel?: string;
62
72
  /**
63
- * Rótulo visible del botón que abre los eventos ocultos de una celda.
64
- * Default: `+N más` (castellano). Interpola el número, así que es una
65
- * función: una app multiidioma debe pasarla traducida.
73
+ * Rótulo visible del botón que abre los eventos ocultos de una celda. **Sin
74
+ * default**: sin él, sale de `calendarPlanner.more` del
75
+ * `BrandMessagesProvider`. Solo se lee cuando alguna celda desborda.
66
76
  */
67
77
  moreLabel?: (count: number) => string;
68
78
  /** Tamaño del componente. Default: 'md' */
@@ -1,5 +1,33 @@
1
1
  import type { ComponentType, ReactNode } from 'react';
2
2
  import './CalendarRoster.css';
3
+ /**
4
+ * El cromo del cuadrante: el encabezado de la columna de nombres y la leyenda
5
+ * con sus seis tipos. Las **flechas de mes no están aquí**: son el mismo texto
6
+ * que el del `Calendar` y salen de `calendar.previousMonth` / `.nextMonth`.
7
+ *
8
+ * Los seis tipos van clave a clave, no como lista: una lista en el catálogo
9
+ * obligaría a la aplicación a montar el array entero con sus `type` correctos
10
+ * solo para traducir seis palabras. `legendItems` sigue existiendo para
11
+ * sustituir la leyenda **entera** —otro orden, otros tipos—, y gana.
12
+ */
13
+ export interface CalendarRosterMessages {
14
+ /** Encabezado de la columna de nombres (empleado, recurso, aula…). */
15
+ name: string;
16
+ /** Nombre accesible de la leyenda. */
17
+ legend: string;
18
+ /** Un día festivo. */
19
+ holiday: string;
20
+ /** Vacaciones. */
21
+ vacation: string;
22
+ /** Una ausencia. */
23
+ absence: string;
24
+ /** Una recuperación de horas. */
25
+ recovery: string;
26
+ /** Un cumpleaños. */
27
+ birthday: string;
28
+ /** Un día no laborable. */
29
+ nonWorking: string;
30
+ }
3
31
  export type RosterCellType = 'schedule' | 'holiday' | 'vacation' | 'absence' | 'recovery' | 'birthday' | 'non-working';
4
32
  export interface RosterCell {
5
33
  type: RosterCellType;
@@ -41,7 +69,10 @@ export interface CalendarRosterProps {
41
69
  * Cuando se pasa, sustituye al renderizado por defecto de chips/schedule.
42
70
  */
43
71
  renderCell?: (day: number, date: Date, cell: RosterCell | null) => ReactNode;
44
- /** Etiqueta de la columna de nombre. Default: 'Empleado' */
72
+ /**
73
+ * Etiqueta de la columna de nombre. **Sin default**: sin ella, sale de
74
+ * `calendarRoster.name` del `BrandMessagesProvider`.
75
+ */
45
76
  nameLabel?: string;
46
77
  /**
47
78
  * Lo que precede a la etiqueta de un cumpleaños. Default: `'🎂 '`
@@ -52,13 +83,15 @@ export interface CalendarRosterProps {
52
83
  /** Muestra la leyenda al final. Default: true */
53
84
  showLegend?: boolean;
54
85
  /**
55
- * Entradas de la leyenda, en orden. Default: las seis del sistema con sus etiquetas
56
- * en castellano. Es texto **visible**: una app multiidioma debe pasarlas traducidas.
86
+ * Entradas de la leyenda, en orden. **Sin default**: sin ella, la leyenda se
87
+ * arma con los seis tipos del sistema y sus textos de
88
+ * `calendarRoster.*`. Se pasa entera para cambiar el orden o quitar tipos,
89
+ * no para traducir.
57
90
  */
58
91
  legendItems?: LegendItem[];
59
92
  /**
60
- * aria-label de la leyenda. Default: "Leyenda" (castellano).
61
- * Una app multiidioma debe pasarla traducida.
93
+ * aria-label de la leyenda. **Sin default**: sin ella, sale de
94
+ * `calendarRoster.legend`. Solo se lee con `showLegend`.
62
95
  */
63
96
  legendLabel?: string;
64
97
  /**