@studiolxd/brand 47.1.0 → 48.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/CHANGELOG.md +128 -0
  2. package/dist/_shared/progressbar.js +19 -18
  3. package/dist/_types/atoms/CopyableValue/CopyableValue.d.ts +4 -4
  4. package/dist/_types/atoms/DescriptionList/DescriptionList.d.ts +5 -4
  5. package/dist/_types/atoms/DotsButton/DotsButton.d.ts +15 -0
  6. package/dist/_types/atoms/ProgressBar/ProgressBar.d.ts +12 -2
  7. package/dist/_types/atoms/Slider/Slider.d.ts +19 -2
  8. package/dist/_types/atoms/Spinner/Spinner.d.ts +15 -1
  9. package/dist/_types/constants/copy-to-clipboard.d.ts +22 -0
  10. package/dist/_types/messages/BrandMessages.d.ts +35 -1
  11. package/dist/_types/messages/index.d.ts +1 -1
  12. package/dist/_types/molecules/CalendarPlanner/CalendarPlanner.d.ts +13 -3
  13. package/dist/_types/molecules/CalendarRoster/CalendarRoster.d.ts +38 -5
  14. package/dist/_types/molecules/Carousel/Carousel.d.ts +65 -13
  15. package/dist/_types/molecules/CodeBlock/CodeBlock.d.ts +20 -6
  16. package/dist/_types/molecules/ContextMenu/ContextMenu.d.ts +5 -1
  17. package/dist/_types/molecules/CopyButton/CopyButton.d.ts +5 -6
  18. package/dist/_types/molecules/LanguageSwitcher/LanguageSwitcher.d.ts +13 -1
  19. package/dist/_types/molecules/NotificationList/NotificationList.d.ts +33 -3
  20. package/dist/_types/molecules/ProjectCard/ProjectCard.d.ts +14 -1
  21. package/dist/_types/molecules/Stepper/Stepper.d.ts +32 -7
  22. package/dist/_types/molecules/TreeView/TreeView.d.ts +11 -2
  23. package/dist/_types/molecules/UptimeBars/UptimeBars.d.ts +20 -2
  24. package/dist/_types/organisms/Chart/Chart.d.ts +46 -8
  25. package/dist/_types/sections/LegalFooter/LegalFooter.d.ts +13 -1
  26. package/dist/_types/templates/PublicPageShell/PublicPageShell.d.ts +15 -1
  27. package/dist/calendar-planner.js +47 -47
  28. package/dist/calendar-roster.js +28 -25
  29. package/dist/carousel.js +69 -67
  30. package/dist/chart.js +250 -249
  31. package/dist/code-block.js +34 -34
  32. package/dist/context-menu.js +1 -1
  33. package/dist/copy-button.js +35 -34
  34. package/dist/copyable-value.js +43 -42
  35. package/dist/description-list.js +1 -1
  36. package/dist/dots-button.js +18 -17
  37. package/dist/language-switcher.js +43 -41
  38. package/dist/legal-footer.js +21 -18
  39. package/dist/notification-list.js +40 -38
  40. package/dist/progress-bar.js +1 -0
  41. package/dist/project-card.js +31 -30
  42. package/dist/public-page-shell.js +12 -11
  43. package/dist/slider.js +24 -23
  44. package/dist/spinner.js +19 -14
  45. package/dist/stepper.js +35 -38
  46. package/dist/tree-view.js +86 -85
  47. package/dist/uptime-bars.js +54 -53
  48. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -7,6 +7,134 @@ 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.0.0] — 2026-09-16
11
+
12
+ > **Major.** Novena familia al proveedor de textos: copiar, datos y estado. Diecisiete
13
+ > espacios nuevos, y con ellos el primero que **no es de un componente sino de una
14
+ > conducta**: `copy`, las tres palabras que dicen por igual el botón suelto, el valor en
15
+ > línea y el bloque de código. Además, la banda de preferencias de `PublicPageShell` se
16
+ > puede pedir a otra medida, y `Foundations/Redacción` fija por escrito que los estados de
17
+ > carga conservan sus puntos suspensivos.
18
+
19
+ ### Copiar, datos y estado leen del proveedor
20
+
21
+ Diecisiete espacios nuevos en `BrandMessages`: `copy`, `codeBlock`, `dotsButton`,
22
+ `progressBar`, `spinner`, `slider`, `treeView`, `uptimeBars`, `chart`, `stepper`,
23
+ `carousel`, `languageSwitcher`, `projectCard`, `legalFooter`, `calendarRoster`,
24
+ `calendarPlanner` y `notificationList`. Mismo orden —**prop → proveedor → error**— y cada
25
+ texto se lee **donde se pinta**: un botón que nunca falla no exige el aviso de
26
+ portapapeles roto, un spinner decorativo no exige su texto, un progreso que empieza en el
27
+ primer paso no exige la marca de «completado», un deslizador de un pulgar no exige los dos
28
+ nombres del rango y un cuadrante sin leyenda no exige ninguno de sus seis tipos.
29
+
30
+ ### `copy` es un espacio de conducta, y es la primera excepción a «un espacio por componente»
31
+
32
+ `CopyButton`, `CopyableValue`, `DescriptionDetails copyable` y el acuse de `CodeBlock`
33
+ dicen **las mismas tres palabras**: «Copiar», «Copiado», «No se pudo copiar». Un espacio
34
+ por componente habría obligado a la aplicación a escribirlas tres veces, con el riesgo de
35
+ que un día dijeran cosas distintas; el catálogo de la suite ya las tiene una sola vez
36
+ (`common.copy`, `common.copied`). Así que la interfaz `CopyMessages` vive donde ya vivía
37
+ la conducta compartida —`src/stories/constants/copy-to-clipboard.ts`— y no junto a un
38
+ componente: lo que comparten es el comportamiento, y el texto va con él.
39
+
40
+ `CodeBlock` es el caso que lo enseña: lee de **dos** espacios, porque su rótulo dice
41
+ «Copiar código» (suyo, `codeBlock.copy`) y su acuse dice «Copiado» (de todos,
42
+ `copy.copied`). Y `codeBlock.region` —el nombre del área desplazable— interpola el
43
+ lenguaje, así que es función.
44
+
45
+ ### Un nombre genérico es cromo; el de ESTA pantalla sigue siendo prop
46
+
47
+ `ProgressBar` y `TreeView` son la pareja que mejor lo enseña. El catálogo pone «Progreso»
48
+ y «Árbol», que valen en cualquier pantalla; lo que avanza de verdad —«Subiendo el
49
+ vídeo»— y de qué árbol se trata —«Matriz de contenidos»— lo sabe solo la pantalla, y para
50
+ eso siguen estando las props, que ganan. Lo mismo en `Chart`: el cromo de la tabla
51
+ equivalente es catálogo, pero **`ariaLabel` sigue obligatorio y fuera** —un texto común lo
52
+ dejaría diciendo «Gráfico» en todas partes sin que nada fallara—.
53
+
54
+ ### Cuatro piezas entran al alcance por arrastre
55
+
56
+ `Spinner` no estaba en la lista y entra: es el estado por excelencia, y su «Cargando…» es
57
+ exactamente el texto que la norma de redacción de esta misma release declara excepción.
58
+ `Slider` tenía tres palabras cableadas dentro del default de `thumbLabel` («Valor»,
59
+ «Mínimo», «Máximo») que ninguna prop de texto dejaba ver. `CalendarPlanner` comparte
60
+ familia con `CalendarRoster` y se habría quedado con su «+N más» en castellano.
61
+ `DescriptionDetails` y `ContextMenu` pasan a ser **reenvíos puros**: sus props siguen
62
+ existiendo como anulación puntual, pero ya no hacen falta para traducir.
63
+
64
+ `MessageComposer`, `ConversationList`, `ConversationThread`, `AssistantMessage`,
65
+ `AnnotationThread`, `ChatShell`, `TypingIndicator` y las pantallas de `ConnectorAuth`
66
+ **no entran**: son texto de producto y legal, y tienen ola propia.
67
+
68
+ ### La leyenda del cuadrante va clave a clave, contra la regla general
69
+
70
+ La norma del sistema es que una **lista** se traduce pasándola entera, no con una prop de
71
+ texto por elemento. Los seis tipos de la leyenda de `CalendarRoster` son la excepción: es
72
+ un vocabulario **cerrado** del componente —festivo, vacaciones, ausencia, recuperación,
73
+ cumpleaños, no laborable—, y obligar a la aplicación a montar el array con sus `type`
74
+ correctos solo para traducir seis palabras era peor que darles seis claves.
75
+ `legendItems` sigue existiendo para sustituir la leyenda **entera** —otro orden, otros
76
+ tipos— y gana. `birthdayPrefix` se queda fuera: es un emoji, y un emoji no se traduce.
77
+
78
+ ### Redacción: los estados de carga conservan los puntos suspensivos
79
+
80
+ Sección propia en `Foundations/Redacción`, con sus ejemplos ✓/✗. «Buscando…»,
81
+ «Cargando…», «Guardando…» no son una frase que se corta: son **progreso**, y los tres
82
+ puntos dicen que algo está pasando ahora mismo y que va a terminar. Quitárselos convierte
83
+ el estado en un rótulo. Vale igual para el texto visible y para el que solo oye un lector
84
+ de pantalla. Lo que **no** es un estado en curso sigue sin llevarlos, aunque hable de algo
85
+ que tarda.
86
+
87
+ ### La banda de preferencias de `PublicPageShell` se puede pedir a otra medida
88
+
89
+ Prop nueva, `preferencesWidth?: ContainerWidth`, con el prefijo de la ranura —como
90
+ `mainWidth`— porque el marco tiene cuatro y un `width` pelado no diría cuál gobierna. El
91
+ default es `'xl'`, lo de hoy, **así que esta parte no es breaking**. Una página que lee a
92
+ `lg` pide `preferencesWidth="lg"` y la banda estrecha con ella.
93
+
94
+ Lo que resolvía el hueco hasta hoy —anidar un `Container width="lg"` dentro de
95
+ `preferences`— metía un `container__inner` dentro de otro: el relleno lateral se contaba
96
+ dos veces y la banda dejaba de alinear con el `main`. Sin CSS nuevo.
97
+
98
+ ### Para quien actualice
99
+
100
+ El catálogo del `BrandMessagesProvider` tiene que crecer con los diecisiete espacios, o la
101
+ primera pantalla con un `CopyButton`, un `Spinner` o una `ProgressBar` **lanza en render**.
102
+ Estas son las claves que hay que aportar:
103
+
104
+ | Espacio | Claves | Qué es |
105
+ | --- | --- | --- |
106
+ | `copy` | `label`, `copied`, `error` | copiar al portapapeles, para toda la familia |
107
+ | `codeBlock` | `copy`, `region(language?)` | el rótulo propio del bloque y el nombre de su área |
108
+ | `dotsButton` | `label` | el botón de tres puntos — lo reenvía `ContextMenu` |
109
+ | `progressBar` | `label` | el nombre genérico de lo que avanza |
110
+ | `spinner` | `label` | la espera, con sus puntos suspensivos |
111
+ | `slider` | `value`, `min`, `max`, `valueAt(index)` | los nombres de los pulgares |
112
+ | `treeView` | `label` | el nombre genérico del árbol |
113
+ | `uptimeBars` | `label`, `noData` | la tira y cómo se dice que un punto no tiene dato |
114
+ | `chart` | `tableCaption`, `tableHint`, `category`, `value`, `share`, `empty` | el cromo de la tabla equivalente |
115
+ | `stepper` | `label`, `compact(current, total)`, `completed`, `current`, `pending` | el progreso y sus tres marcas de estado |
116
+ | `carousel` | `label`, `roleDescription`, `track`, `previous`, `next`, `indicator(index)`, `pause`, `play`, `slideStatus(index, total)`, `slideRoleDescription` | todo el cromo del carrusel |
117
+ | `languageSwitcher` | `label` | la etiqueta del selector — **no** los idiomas |
118
+ | `projectCard` | `tags` | la lista de etiquetas de categoría |
119
+ | `legalFooter` | `label` | la navegación del pie legal |
120
+ | `calendarRoster` | `name`, `legend`, `holiday`, `vacation`, `absence`, `recovery`, `birthday`, `nonWorking` | la columna de nombres y los seis tipos de la leyenda |
121
+ | `calendarPlanner` | `more(count)` | el botón de desbordamiento de una celda |
122
+ | `notificationList` | `label`, `unread`, `markRead` | la bandeja — **no** el panel de la cabecera |
123
+
124
+ Seis de ellas interpolan un dato (`codeBlock.region`, `slider.valueAt`, `stepper.compact`,
125
+ `carousel.indicator`, `carousel.slideStatus`, `calendarPlanner.more`), así que son
126
+ funciones.
127
+
128
+ A cambio, dejan de hacer falta para traducir `DescriptionDetails.copyLabel` y
129
+ `copiedLabel`, y `ContextMenu.label`: son reenvíos puros y siguen existiendo solo como
130
+ anulación puntual. `RecoveryCodes` mantiene sus tres `labels` obligatorias —«Copiar todos»
131
+ no es «Copiar»—, pero su botón lee `copy.error` si el portapapeles falla.
132
+
133
+ **Ojo con dos valores.** `spinner.label` lleva **puntos suspensivos** dentro («Cargando…»):
134
+ son parte del texto, no adorno. Y `notificationList.*` no es `notificationPanel.*`: en el
135
+ catálogo de la suite son `notifications.inbox.*` y `notifications.panel.*`, y mezclarlos
136
+ deja la bandeja diciendo lo del flotante.
137
+
10
138
  ## [47.1.0] — 2026-09-15
11
139
 
12
140
  > **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 };
@@ -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
  /**