@studiolxd/brand 48.1.0 → 49.0.1

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 (33) hide show
  1. package/CHANGELOG.md +169 -0
  2. package/dist/_shared/untrustedtext.js +27 -26
  3. package/dist/_types/atoms/TypingIndicator/TypingIndicator.d.ts +29 -2
  4. package/dist/_types/messages/BrandMessages.d.ts +25 -1
  5. package/dist/_types/messages/index.d.ts +1 -1
  6. package/dist/_types/molecules/AssistantMessage/AssistantMessage.d.ts +15 -1
  7. package/dist/_types/molecules/ConversationList/ConversationList.d.ts +42 -8
  8. package/dist/_types/molecules/MessageComposer/MessageComposer.d.ts +24 -1
  9. package/dist/_types/organisms/AnnotationThread/AnnotationThread.d.ts +52 -7
  10. package/dist/_types/organisms/ConversationThread/ConversationThread.d.ts +26 -3
  11. package/dist/_types/templates/ChatShell/ChatShell.d.ts +22 -4
  12. package/dist/_types/templates/ConnectorAuth/ConnectorAuthShell.d.ts +6 -1
  13. package/dist/_types/templates/ConnectorAuth/ConnectorConsentPage.d.ts +52 -18
  14. package/dist/_types/templates/ConnectorAuth/ConnectorExternalSignInPage.d.ts +57 -17
  15. package/dist/_types/templates/ConnectorAuth/ConnectorRejectionPage.d.ts +59 -15
  16. package/dist/_types/templates/ConnectorAuth/ConnectorRequestSummary.d.ts +43 -12
  17. package/dist/_types/templates/ConnectorAuth/ConnectorSignInPage.d.ts +46 -12
  18. package/dist/_types/templates/ConnectorAuth/UntrustedText.d.ts +31 -4
  19. package/dist/annotation-thread.js +49 -46
  20. package/dist/assistant-message.js +12 -9
  21. package/dist/brand.css +21 -10
  22. package/dist/chat-shell.js +50 -49
  23. package/dist/connector-consent-page.js +58 -68
  24. package/dist/connector-external-sign-in-page.js +22 -28
  25. package/dist/connector-rejection-page.js +31 -62
  26. package/dist/connector-request-summary.js +22 -20
  27. package/dist/connector-sign-in-page.js +21 -25
  28. package/dist/conversation-list.js +56 -55
  29. package/dist/conversation-thread.js +33 -31
  30. package/dist/link.css +1 -1
  31. package/dist/message-composer.js +38 -37
  32. package/dist/typing-indicator.js +12 -9
  33. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -7,6 +7,175 @@ 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.0.1] — 2026-09-16
11
+
12
+ > **Patch.** Arregla una regresión de la v47.1.0: `Link.css` colgaba `inline-size:
13
+ > fit-content` de TODO `<a>` del documento (`a:where(:not(.button))`), no solo del enlace
14
+ > del sistema (`.link`). Cualquier `<a>` que fuera pieza de OTRO componente con su propia
15
+ > clase BEM y que no fijara su propio ancho se encogía a su texto: el ítem `link` de `Menu`
16
+ > (`<a class="menu__item">`, en `ContextMenu`/`UserMenu`) quedaba como una cajita junto a un
17
+ > ítem `button` que sí ocupaba la fila, y una `Card` con `href` (o `render={<a/>}`) dentro de
18
+ > una rejilla (`Columns align="stretch"`) se encogía a su título en vez de ocupar la celda —
19
+ > más visible cuanto más corto el título, porque el texto largo ya llenaba el hueco y
20
+ > disimulaba el bug.
21
+
22
+ ### El arreglo
23
+
24
+ `inline-size: fit-content` sale del selector combinado y pasa a una regla aparte con
25
+ `:where(.link)` en solitario: solo el enlace del sistema (el átomo `Link`, o cualquier cosa
26
+ que lleve `class="link"`) se resiste a estirarse en un `Stack`/`Inline`. El `<a>` pelado
27
+ sigue vistiéndose (color, subrayado, foco) desde el selector de siempre, sin el
28
+ `inline-size`: lo que necesita su ancho de layout —`menu__item`, `card`, y cualquier otro
29
+ `<a>` con clase propia que no lo pise ya con su propio `width`/`inline-size`/`flex`— deja de
30
+ perderlo por una regla que no era la suya. Barrido el árbol de `src/`: ningún otro `<a>` de
31
+ componente (`sidebar-nav__link`, `breadcrumb__link`, `pagination__link`, `tabs__tab`,
32
+ `site-nav__link`, `project-card__link`…) dependía del `inline-size` que se retira — todos o
33
+ fijan su propio ancho o son enlaces de una sola palabra donde `fit-content` nunca actuaba.
34
+
35
+ Dos stories de contrato nuevas (`tags: ['!dev']`, corren en `test:stories`):
36
+ `Molecules/Menu` → «el ítem enlace ocupa el mismo ancho que el ítem botón», y
37
+ `Molecules/Card` → «cards enlazadas en rejilla ocupan su celda» (título corto y largo, mismo
38
+ ancho de celda). La story de `Atoms/Link` → «no se estira dentro de un Stack
39
+ `align="stretch"`» sigue en verde: sigue siendo `.link`, así que conserva su ancho de
40
+ contenido.
41
+
42
+ ## [49.0.0] — 2026-09-16
43
+
44
+ > **Major.** La **última ola** del proveedor de textos, y la más distinta: el chat y las
45
+ > pantallas del conector. Doce espacios nuevos, y con ellos la línea que faltaba por
46
+ > trazar — **lo que afirma algo no se pone en un catálogo de cromo**. Los textos de
47
+ > consentimiento, los cinco motivos de rechazo, qué se concede y el nombre del asistente
48
+ > pasan a ser **props obligatorias y sin default**, como `confirmDialog.confirmLabel` en la
49
+ > v45. Con esto, ningún componente del paquete trae ya castellano puesto.
50
+
51
+ ### El chat y el conector leen del proveedor
52
+
53
+ Doce espacios nuevos en `BrandMessages`: `messageComposer`, `conversationList`,
54
+ `conversationThread`, `typingIndicator`, `annotationThread`, `chatShell`, `untrustedText`,
55
+ `connectorRequestSummary`, `connectorConsent`, `connectorSignIn`,
56
+ `connectorExternalSignIn` y `connectorRejection`. Mismo orden —**prop → proveedor →
57
+ error**— y cada texto se lee **donde se pinta**: una lista de conversaciones que carga bien
58
+ no exige el título de su aviso de error, un hilo de anotaciones abierto no exige los
59
+ rótulos de «atendida» ni de «resuelta», y un armazón de chat montado sin columna no exige
60
+ ninguno de sus dos textos.
61
+
62
+ ### La línea de esta ola: el cromo nombra un control, el contenido afirma algo
63
+
64
+ Es la distinción que las ocho olas anteriores rozaron y esta tiene que resolver, porque
65
+ aquí casi todo el texto es una frase larga de producto o de consentimiento. La regla, en
66
+ una línea: **si el texto nombra un control, un estado o un dato, es cromo y va al catálogo;
67
+ si afirma algo —qué se concede, a dónde sale un acceso, qué comprobación ha fallado, cómo
68
+ se llama el asistente—, es contenido y es prop obligatoria sin default.**
69
+
70
+ Tres parejas la enseñan mejor que cualquier definición:
71
+
72
+ - **`connectorConsent.deny` frente a `ConnectorConsentPage.approveLabel`.** «Denegar»
73
+ describe lo único que hace ese botón —no seguir— y no hay consecuencia que nombrar:
74
+ cromo. El otro es **donde se concede el acceso**, y tiene que nombrar la consecuencia:
75
+ obligatorio y fuera del catálogo. Es literalmente el caso de `confirmDialog.cancel`
76
+ frente a `ConfirmDialog.confirmLabel`, y se resuelve igual.
77
+ - **`connectorRequestSummary.scope` frente a `scopeReadLabel`.** El rótulo «Permiso» nombra
78
+ qué dato va en esa fila de la ficha: cromo. Lo que ese permiso **es** —«leer los datos de
79
+ este producto»— afirma qué va a poder hacer una herramienta con los datos de quien lee la
80
+ pantalla, y eso lo sabe el servidor de autorización, no un catálogo común.
81
+ - **`typingIndicator.typing(name)` frente a `TypingIndicator.name`.** Que alguien esté
82
+ escribiendo es cromo: lo dice igual cualquier chat, y el orden de las piezas es del
83
+ idioma. **Quién** escribe es contenido: un catálogo común dejaría diciendo «El asistente»
84
+ en un chat cuyo asistente tiene nombre propio.
85
+
86
+ ### `ConnectorRejectionPage` deja de traer los cinco rechazos dentro
87
+
88
+ Era el caso más claro de todos y el que más cambia: un `Record` con **veinte cadenas
89
+ castellanas** —título, explicación, qué hacer y rótulo de la salida, por cada uno de los
90
+ cinco motivos— vivía dentro del componente, y la prop `reason` elegía cuatro. Cada una de
91
+ esas veinte afirma algo sobre una comprobación de seguridad («no se ha enviado nada a
92
+ ninguna parte», «si no la reconoces, no vuelvas a intentarlo»), y eso no lo decide el
93
+ sistema de diseño.
94
+
95
+ Así que el `Record` se retira entero, `reason` **desaparece** y `title`, `description`,
96
+ `hint` y `retryLabel` pasan a ser obligatorias. El tipo `ConnectorRejectionReason` se
97
+ queda —es el **vocabulario** de los cinco motivos, escrito en el sistema— para que la
98
+ aplicación teclee contra él al sacar los cuatro textos de su catálogo. La maqueta, el
99
+ orden y la postura no cambian: ninguno de los cinco ofrece reintentar en el sitio.
100
+
101
+ ### `untrustedText.quotes`: las comillas son puntuación del idioma
102
+
103
+ Las comillas que enmarcan un dato de fuera no son una decisión del producto ni un adorno:
104
+ son `« »` en castellano, `“ ”` en inglés y `„ “` en alemán. Al catálogo, como el resto del
105
+ cromo. El **valor** que enmarcan sigue entrando por `value` y no pasa por ningún catálogo
106
+ —es dato de un tercero—: por eso se pinta entrecomillado, aislado en un `<bdi>` y con los
107
+ caracteres invisibles a la vista.
108
+
109
+ ### `chatShell.list` no es `conversationList.nav`, aunque hoy digan lo mismo
110
+
111
+ Dos espacios para la misma palabra, a propósito: son dos piezas distintas —el armazón de la
112
+ pantalla y la lista que cuelga de él—, y el armazón se monta también **sin lista**, dentro
113
+ de un `AppShell` donde la columna vive en el `Sidebar`. El precedente ya estaba puesto con
114
+ `appRoot.skipToContent` frente a `appShell.skipToContent`.
115
+
116
+ ### Los tres estados de `AnnotationThread` van clave a clave
117
+
118
+ Contra la regla general de que una **lista** se traduce pasándola entera. Es la misma
119
+ excepción que los seis tipos de la leyenda de `CalendarRoster`, y por la misma razón: es un
120
+ vocabulario **cerrado** del componente —abierta, atendida, resuelta— y obligar a la
121
+ aplicación a montar nada para traducir tres palabras era peor que darle tres claves. Las
122
+ props siguen ganando, así que una revisión puede llamar «Verificada» a `acknowledged`.
123
+
124
+ ### Para quien actualice
125
+
126
+ **1. El catálogo del `BrandMessagesProvider` tiene que crecer con los doce espacios**, o la
127
+ primera pantalla de chat o de conector **lanza en render**:
128
+
129
+ | Espacio | Claves | Qué es |
130
+ | --- | --- | --- |
131
+ | `messageComposer` | `placeholder`, `send` | el marcador del campo y el botón que manda |
132
+ | `conversationList` | `new`, `nav`, `delete(label)`, `empty`, `error` | el cromo de la lista y sus dos estados propios |
133
+ | `conversationThread` | `label` | el nombre de la región que anuncia los mensajes |
134
+ | `typingIndicator` | `typing(name)` | la plantilla del estado de escritura |
135
+ | `annotationThread` | `label`, `open`, `acknowledged`, `resolved`, `edited`, `replies(count)` | el hilo, sus tres estados, la marca de editada y el recuento |
136
+ | `chatShell` | `list`, `listTrigger` | la columna de conversaciones y el botón que la despliega |
137
+ | `untrustedText` | `expand`, `collapse`, `quotes` | el desplegador de un valor recortado y las comillas del idioma |
138
+ | `connectorRequestSummary` | `client`, `product`, `account`, `scope`, `redirect` | los cinco rótulos de la ficha de la petición |
139
+ | `connectorConsent` | `title`, `deny` | el título de la pantalla y la salida que no concede nada |
140
+ | `connectorSignIn` | `title`, `signIn`, `fallbackProduct` | identificarse dentro del flujo del conector |
141
+ | `connectorExternalSignIn` | `title`, `organization`, `submit(platform)` | el conector ajeno (hoy, el de Moodle) |
142
+ | `connectorRejection` | `code` | el rótulo del código técnico |
143
+
144
+ Cuatro de ellas interpolan un dato (`conversationList.delete`,
145
+ `typingIndicator.typing`, `annotationThread.replies`, `connectorExternalSignIn.submit`),
146
+ así que son funciones. Y `untrustedText.quotes` **no es una cadena**: es la pareja
147
+ `[apertura, cierre]`.
148
+
149
+ **2. Estas props pasan a ser obligatorias y sin default. Rompen a quien no las pase, y esa
150
+ es la parte breaking de la release:**
151
+
152
+ | Componente | Props que pasan a obligatorias |
153
+ | --- | --- |
154
+ | `TypingIndicator` | `name` |
155
+ | `AssistantMessage` | `streamingName` |
156
+ | `ConversationThread` | `streamingName` |
157
+ | `ConnectorRequestSummary` | `scopeReadLabel`, `scopeWriteLabel` |
158
+ | `ConnectorConsentPage` | `intro`, `redirectNotice`, `approveLabel`, `scopeReadLabel`, `scopeWriteLabel` |
159
+ | `ConnectorSignInPage` | `intro`, `scopeReadLabel`, `scopeWriteLabel` |
160
+ | `ConnectorExternalSignInPage` | `platformName`, `intro`, `signingInTo` |
161
+ | `ConnectorRejectionPage` | `title`, `description`, `hint`, `retryLabel` |
162
+
163
+ **3. Y estos dos cambios de forma:**
164
+
165
+ - **`ConnectorRejectionPage.reason` desaparece.** Los cuatro textos que elegía ahora se
166
+ pasan. `ConnectorRejectionReason` sigue exportado, como vocabulario.
167
+ - **`ConnectorExternalSignInPage.platformName` pasa de `ReactNode` a `string`**, porque el
168
+ catálogo la interpola dentro del rótulo del botón
169
+ (`connectorExternalSignIn.submit(platform)`). Y `submitLabel` pasa de
170
+ `(parts: { platform }) => ReactNode` a `(platform: string) => string`, la misma firma que
171
+ la clave a la que anula.
172
+
173
+ **Ojo con dos valores.** `messageComposer.placeholder` y `typingIndicator.typing` llevan
174
+ **puntos suspensivos** dentro («Escribe un mensaje…», «… está escribiendo…»): son parte del
175
+ texto, no adorno — ver `Foundations/Redacción` § «Los estados de carga llevan puntos
176
+ suspensivos». Y `conversationList.delete` recibe el título de la conversación **entero**, sin
177
+ recortar: es el `aria-label` del aspa, y ahí el recorte visual de la fila no pinta nada.
178
+
10
179
  ## [48.1.0] — 2026-09-16
11
180
 
12
181
  > **Minor.** `FilterBar` pasa a columnas fijas por punto de corte —4 en escritorio, 2 en
@@ -1,43 +1,44 @@
1
1
  import '../untrustedtext.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
  //#region src/stories/templates/ConnectorAuth/UntrustedText.tsx
4
- var n = /[\u061C\u200B\u200E\u200F\u202A-\u202E\u2060-\u2064\u2066-\u2069\uFEFF]/g, r = 80;
5
- function i(e) {
6
- return e.replace(n, (e) => `[U+${e.codePointAt(0).toString(16).toUpperCase().padStart(4, "0")}]`);
5
+ var r = /[\u061C\u200B\u200E\u200F\u202A-\u202E\u2060-\u2064\u2066-\u2069\uFEFF]/g, i = 80;
6
+ function a(e) {
7
+ return e.replace(r, (e) => `[U+${e.codePointAt(0).toString(16).toUpperCase().padStart(4, "0")}]`);
7
8
  }
8
- function a({ value: n, expandable: a = !1, expandLabel: o = "Ver el valor completo", collapseLabel: s = "Ver menos", quotes: c = ["«", "»"], className: l }) {
9
- let u = (...e) => [...e, l].filter(Boolean).join(" ");
10
- if (typeof n != "string") return /* @__PURE__ */ e("span", {
11
- className: u("connector-untrusted"),
12
- children: n
9
+ function o({ value: r, expandable: o = !1, expandLabel: s, collapseLabel: c, quotes: l, className: u }) {
10
+ let d = e("untrustedText"), f = (...e) => [...e, u].filter(Boolean).join(" ");
11
+ if (typeof r != "string") return /* @__PURE__ */ t("span", {
12
+ className: f("connector-untrusted"),
13
+ children: r
13
14
  });
14
- let d = i(n), f = Array.from(d).length > r, [p, m] = c, h = /* @__PURE__ */ t("span", {
15
- className: f ? "connector-untrusted__value connector-untrusted__value--clamped" : "connector-untrusted__value",
15
+ let p = a(r), m = Array.from(p).length > i, [h, g] = d("quotes", l), _ = /* @__PURE__ */ n("span", {
16
+ className: m ? "connector-untrusted__value connector-untrusted__value--clamped" : "connector-untrusted__value",
16
17
  children: [
17
- p,
18
- /* @__PURE__ */ e("bdi", { children: d }),
19
- m
18
+ h,
19
+ /* @__PURE__ */ t("bdi", { children: p }),
20
+ g
20
21
  ]
21
22
  });
22
- return !f || !a ? /* @__PURE__ */ e("span", {
23
- className: u("connector-untrusted"),
24
- children: h
25
- }) : /* @__PURE__ */ e("details", {
26
- className: u("connector-untrusted", "connector-untrusted--expandable"),
27
- children: /* @__PURE__ */ t("summary", {
23
+ return !m || !o ? /* @__PURE__ */ t("span", {
24
+ className: f("connector-untrusted"),
25
+ children: _
26
+ }) : /* @__PURE__ */ t("details", {
27
+ className: f("connector-untrusted", "connector-untrusted--expandable"),
28
+ children: /* @__PURE__ */ n("summary", {
28
29
  className: "connector-untrusted__summary",
29
- children: [h, /* @__PURE__ */ t("span", {
30
+ children: [_, /* @__PURE__ */ n("span", {
30
31
  className: "link connector-untrusted__toggle",
31
- children: [/* @__PURE__ */ e("span", {
32
+ children: [/* @__PURE__ */ t("span", {
32
33
  className: "connector-untrusted__more",
33
- children: o
34
- }), /* @__PURE__ */ e("span", {
34
+ children: d("expand", s)
35
+ }), /* @__PURE__ */ t("span", {
35
36
  className: "connector-untrusted__less",
36
- children: s
37
+ children: d("collapse", c)
37
38
  })]
38
39
  })]
39
40
  })
40
41
  });
41
42
  }
42
43
  //#endregion
43
- export { a as t };
44
+ export { o as t };
@@ -1,7 +1,34 @@
1
1
  import './TypingIndicator.css';
2
+ /**
3
+ * El verbo, y solo el verbo: «… está escribiendo…».
4
+ *
5
+ * La frase entera —«El asistente está escribiendo…»— tiene **dos mitades que
6
+ * no se deciden en el mismo sitio**. Que alguien esté escribiendo es cromo: lo
7
+ * dice igual cualquier chat de la suite, y el orden de las piezas es del
8
+ * idioma. **Quién** escribe es contenido: el asistente se llama como lo llame
9
+ * el producto, y un catálogo común lo dejaría diciendo «El asistente» en un
10
+ * chat cuyo asistente tiene nombre propio.
11
+ *
12
+ * De ahí que la clave sea una **función**: el catálogo pone la plantilla y el
13
+ * nombre entra por la prop `name`, que es obligatoria.
14
+ */
15
+ export interface TypingIndicatorMessages {
16
+ /** Plantilla del anuncio. Recibe el nombre de quien escribe. */
17
+ typing: (name: string) => string;
18
+ }
2
19
  export interface TypingIndicatorProps {
3
- /** Texto anunciado por lectores de pantalla. Default castellano: «El asistente está escribiendo…». */
20
+ /**
21
+ * Quién está escribiendo. **Obligatoria y sin default**: el nombre del
22
+ * asistente es contenido del producto, no cromo del sistema — ver
23
+ * `TypingIndicatorMessages`.
24
+ */
25
+ name: string;
26
+ /**
27
+ * La frase entera, cuando la plantilla del catálogo no vale. **Sin
28
+ * default**: sin ella, sale de `typingIndicator.typing(name)` del
29
+ * `BrandMessagesProvider`.
30
+ */
4
31
  label?: string;
5
32
  }
6
33
  /** Tres puntos cuadrados que laten en secuencia: «alguien está escribiendo». */
7
- export declare function TypingIndicator({ label }: TypingIndicatorProps): import("react/jsx-runtime").JSX.Element;
34
+ export declare function TypingIndicator({ name, label }: TypingIndicatorProps): import("react/jsx-runtime").JSX.Element;
@@ -62,6 +62,18 @@ import type { LegalFooterMessages } from '../sections/LegalFooter/LegalFooter';
62
62
  import type { CalendarRosterMessages } from '../molecules/CalendarRoster/CalendarRoster';
63
63
  import type { CalendarPlannerMessages } from '../molecules/CalendarPlanner/CalendarPlanner';
64
64
  import type { NotificationListMessages } from '../molecules/NotificationList/NotificationList';
65
+ import type { MessageComposerMessages } from '../molecules/MessageComposer/MessageComposer';
66
+ import type { ConversationListMessages } from '../molecules/ConversationList/ConversationList';
67
+ import type { ConversationThreadMessages } from '../organisms/ConversationThread/ConversationThread';
68
+ import type { TypingIndicatorMessages } from '../atoms/TypingIndicator/TypingIndicator';
69
+ import type { AnnotationThreadMessages } from '../organisms/AnnotationThread/AnnotationThread';
70
+ import type { ChatShellMessages } from '../templates/ChatShell/ChatShell';
71
+ import type { UntrustedTextMessages } from '../templates/ConnectorAuth/UntrustedText';
72
+ import type { ConnectorRequestSummaryMessages } from '../templates/ConnectorAuth/ConnectorRequestSummary';
73
+ import type { ConnectorConsentMessages } from '../templates/ConnectorAuth/ConnectorConsentPage';
74
+ import type { ConnectorSignInMessages } from '../templates/ConnectorAuth/ConnectorSignInPage';
75
+ import type { ConnectorExternalSignInMessages } from '../templates/ConnectorAuth/ConnectorExternalSignInPage';
76
+ import type { ConnectorRejectionMessages } from '../templates/ConnectorAuth/ConnectorRejectionPage';
65
77
  /**
66
78
  * El contrato de textos de la librería: un espacio por componente, y dentro
67
79
  * de cada espacio **todas las claves obligatorias**.
@@ -148,5 +160,17 @@ export interface BrandMessages {
148
160
  calendarRoster: CalendarRosterMessages;
149
161
  calendarPlanner: CalendarPlannerMessages;
150
162
  notificationList: NotificationListMessages;
163
+ messageComposer: MessageComposerMessages;
164
+ conversationList: ConversationListMessages;
165
+ conversationThread: ConversationThreadMessages;
166
+ typingIndicator: TypingIndicatorMessages;
167
+ annotationThread: AnnotationThreadMessages;
168
+ chatShell: ChatShellMessages;
169
+ untrustedText: UntrustedTextMessages;
170
+ connectorRequestSummary: ConnectorRequestSummaryMessages;
171
+ connectorConsent: ConnectorConsentMessages;
172
+ connectorSignIn: ConnectorSignInMessages;
173
+ connectorExternalSignIn: ConnectorExternalSignInMessages;
174
+ connectorRejection: ConnectorRejectionMessages;
151
175
  }
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, };
176
+ 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, MessageComposerMessages, ConversationListMessages, ConversationThreadMessages, TypingIndicatorMessages, AnnotationThreadMessages, ChatShellMessages, UntrustedTextMessages, ConnectorRequestSummaryMessages, ConnectorConsentMessages, ConnectorSignInMessages, ConnectorExternalSignInMessages, ConnectorRejectionMessages, };
@@ -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, CopyMessages, CodeBlockMessages, DotsButtonMessages, ProgressBarMessages, SpinnerMessages, SliderMessages, TreeViewMessages, UptimeBarsMessages, ChartMessages, StepperMessages, CarouselMessages, LanguageSwitcherMessages, ProjectCardMessages, LegalFooterMessages, CalendarRosterMessages, CalendarPlannerMessages, NotificationListMessages, } 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, MessageComposerMessages, ConversationListMessages, ConversationThreadMessages, TypingIndicatorMessages, AnnotationThreadMessages, ChatShellMessages, UntrustedTextMessages, ConnectorRequestSummaryMessages, ConnectorConsentMessages, ConnectorSignInMessages, ConnectorExternalSignInMessages, ConnectorRejectionMessages, } from './BrandMessages';
@@ -19,7 +19,21 @@ export interface AssistantMessageProps extends React.ComponentPropsWithoutRef<'d
19
19
  timestampFormat?: Intl.DateTimeFormatOptions;
20
20
  /** Cuando true, muestra el indicador de escritura en lugar del contenido. */
21
21
  isStreaming?: boolean;
22
- /** Texto anunciado por lectores de pantalla para el estado de escritura. */
22
+ /**
23
+ * Quién escribe mientras se genera la respuesta, para el `TypingIndicator`.
24
+ * **Obligatoria y sin default**: el nombre del asistente es contenido del
25
+ * producto, y el verbo lo pone el catálogo
26
+ * (`typingIndicator.typing(name)`). Se pide siempre, aunque este mensaje no
27
+ * esté generándose: el mensaje del asistente puede estarlo en cualquier
28
+ * momento, y un nombre que aparece solo a veces es un texto sin traducir
29
+ * esperando su turno.
30
+ */
31
+ streamingName: string;
32
+ /**
33
+ * La frase entera del estado de escritura, cuando la plantilla del catálogo
34
+ * no vale. **Sin default**: sin ella, sale de
35
+ * `typingIndicator.typing(streamingName)`.
36
+ */
23
37
  streamingLabel?: string;
24
38
  /** Se añade DESPUÉS de las clases propias del componente (el consumidor añade, no sustituye). */
25
39
  className?: string;
@@ -1,5 +1,27 @@
1
1
  import { type ReactNode } from 'react';
2
2
  import './ConversationList.css';
3
+ /**
4
+ * El cromo de la lista de conversaciones: el botón de abrir una nueva, el
5
+ * nombre de la navegación, el aspa de cada fila y los dos estados que la lista
6
+ * pinta ella misma —vacía y rota—.
7
+ *
8
+ * Los cinco son **genéricos**: dicen lo mismo en cualquier chat de la suite y
9
+ * ninguno afirma nada del producto. Los títulos de las conversaciones son
10
+ * datos y viajan en `conversations`; el detalle del fallo lo pone `error`, que
11
+ * nunca tuvo default.
12
+ */
13
+ export interface ConversationListMessages {
14
+ /** Rótulo del botón que abre una conversación nueva. */
15
+ new: string;
16
+ /** Nombre accesible del `<nav>` que envuelve la lista. */
17
+ nav: string;
18
+ /** Nombre accesible del aspa de una fila. Recibe el título de la conversación. */
19
+ delete: (label: string) => string;
20
+ /** Título del estado vacío que la lista pinta ella misma. */
21
+ empty: string;
22
+ /** Título del aviso de que la lista no se pudo cargar. */
23
+ error: string;
24
+ }
3
25
  export interface ConversationItem {
4
26
  id: string;
5
27
  label: string;
@@ -10,11 +32,20 @@ export interface ConversationListProps extends Omit<React.ComponentPropsWithoutR
10
32
  onNew: () => void;
11
33
  onSelect: (id: string) => void;
12
34
  onDelete: (id: string) => void;
13
- /** Texto del botón que abre una conversación nueva. Default castellano. */
35
+ /**
36
+ * Texto del botón que abre una conversación nueva. **Sin default**: sin él,
37
+ * sale de `conversationList.new` del `BrandMessagesProvider`.
38
+ */
14
39
  newLabel?: string;
15
- /** `aria-label` del `<nav>` que envuelve la lista. Default castellano. */
40
+ /**
41
+ * `aria-label` del `<nav>` que envuelve la lista. **Sin default**: sin él,
42
+ * sale de `conversationList.nav`.
43
+ */
16
44
  navLabel?: string;
17
- /** Nombre accesible del aspa de cada fila. Recibe el título de la conversación. */
45
+ /**
46
+ * Nombre accesible del aspa de cada fila. Recibe el título de la
47
+ * conversación. **Sin default**: sin él, sale de `conversationList.delete`.
48
+ */
18
49
  deleteLabel?: (label: string) => string;
19
50
  /**
20
51
  * La lista aún está cargando: en su sitio se pintan marcadores (`Skeleton`)
@@ -31,13 +62,16 @@ export interface ConversationListProps extends Omit<React.ComponentPropsWithoutR
31
62
  error?: ReactNode;
32
63
  /**
33
64
  * Título del `EmptyState` que la lista pinta **ella misma** cuando no hay
34
- * conversaciones. Default: "Todavía no hay conversaciones" (castellano). Sin
35
- * pasarla, el consumidor se lleva ese texto: el hueco vacío nunca se queda en
36
- * blanco, así que la pantalla no tiene que añadir un aviso propio encima —si
37
- * lo añade, se ven dos.
65
+ * conversaciones. **Sin default**: sin él, sale de
66
+ * `conversationList.empty`, así que el hueco vacío nunca se queda en blanco
67
+ * y la pantalla no tiene que añadir un aviso propio encima —si lo añade, se
68
+ * ven dos—. Solo se lee con la lista vacía.
38
69
  */
39
70
  emptyMessage?: string;
40
- /** `title` del `Alert` de error. Default castellano. */
71
+ /**
72
+ * `title` del `Alert` de error. **Sin default**: sin él, sale de
73
+ * `conversationList.error`, y solo se lee cuando hay `error`.
74
+ */
41
75
  errorTitle?: string;
42
76
  /** Se añade DESPUÉS de las clases propias del componente (el consumidor añade, no sustituye). */
43
77
  className?: string;
@@ -1,12 +1,35 @@
1
1
  import { type ComponentProps, type ReactNode } from 'react';
2
2
  import './MessageComposer.css';
3
+ /**
4
+ * El cromo de la caja de escribir: el marcador del campo vacío y el rótulo del
5
+ * botón que manda. Son las dos palabras que dicen lo mismo en cualquier chat
6
+ * de la suite, así que van en el catálogo.
7
+ *
8
+ * Lo que NO va aquí es la línea de ayuda (`helperText`): la escribe el
9
+ * producto —el atajo de teclado, un aviso de privacidad— y nunca tuvo default
10
+ * en ningún idioma.
11
+ */
12
+ export interface MessageComposerMessages {
13
+ /** Marcador del campo vacío. */
14
+ placeholder: string;
15
+ /** Rótulo del botón de enviar. Es también su nombre accesible. */
16
+ send: string;
17
+ }
3
18
  export interface MessageComposerProps extends Omit<ComponentProps<'div'>, 'onChange'> {
4
19
  value: string;
5
20
  onChange: (value: string) => void;
6
21
  onSend: () => void;
22
+ /**
23
+ * Marcador del campo vacío. **Sin default**: sin él, sale de
24
+ * `messageComposer.placeholder` del `BrandMessagesProvider`.
25
+ */
7
26
  placeholder?: string;
8
27
  disabled?: boolean;
9
- /** Texto del botón de enviar. Es también su nombre accesible: no hay `aria-label` que lo contradiga. */
28
+ /**
29
+ * Texto del botón de enviar. Es también su nombre accesible: no hay
30
+ * `aria-label` que lo contradiga. **Sin default**: sin él, sale de
31
+ * `messageComposer.send`.
32
+ */
10
33
  sendLabel?: string;
11
34
  /**
12
35
  * Línea de ayuda bajo el marco, enlazada al campo con `aria-describedby`
@@ -1,5 +1,34 @@
1
1
  import { type ReactNode } from 'react';
2
2
  import './AnnotationThread.css';
3
+ /**
4
+ * El cromo del hilo de anotaciones: cómo se llama el hilo, cómo se dicen sus
5
+ * tres estados, cómo se marca una anotación editada y cómo se cuentan las
6
+ * respuestas.
7
+ *
8
+ * Los tres estados van **clave a clave** —como los seis tipos de la leyenda de
9
+ * `CalendarRoster`— porque son un vocabulario **cerrado** del componente: el
10
+ * hilo solo puede estar abierto, atendido o resuelto, y obligar a la
11
+ * aplicación a montar nada para traducir tres palabras era peor que darles
12
+ * tres claves. Las props siguen ganando: una revisión que llame «Verificada» a
13
+ * `acknowledged` sigue pudiendo.
14
+ *
15
+ * Quién escribió cada anotación, cuándo y qué dice son datos y viajan en
16
+ * `annotation` y `replies`.
17
+ */
18
+ export interface AnnotationThreadMessages {
19
+ /** Nombre accesible del hilo. */
20
+ label: string;
21
+ /** Rótulo del estado abierto. */
22
+ open: string;
23
+ /** Rótulo del estado atendido. */
24
+ acknowledged: string;
25
+ /** Rótulo del estado resuelto. */
26
+ resolved: string;
27
+ /** Marca de anotación editada, junto a la fecha. */
28
+ edited: string;
29
+ /** Rótulo que cuenta las respuestas. Recibe cuántas son, con su plural. */
30
+ replies: (count: number) => string;
31
+ }
3
32
  export interface AnnotationEntry {
4
33
  /** Identificador único dentro del hilo. */
5
34
  id: string;
@@ -60,20 +89,36 @@ export interface AnnotationThreadProps extends React.ComponentPropsWithoutRef<'a
60
89
  locale?: string;
61
90
  /** Formato de la fecha. Por defecto, día y hora cortos. */
62
91
  dateFormat?: Intl.DateTimeFormatOptions;
63
- /** Rótulo del estado abierto. Por defecto, en castellano: «Abierta». */
92
+ /**
93
+ * Rótulo del estado abierto. **Sin default**: sin él, sale de
94
+ * `annotationThread.open` del `BrandMessagesProvider`. Solo se lee con el
95
+ * hilo en ese estado.
96
+ */
64
97
  openLabel?: string;
65
- /** Rótulo del estado atendido. Por defecto, en castellano: «Atendida». */
98
+ /**
99
+ * Rótulo del estado atendido. **Sin default**: sin él, sale de
100
+ * `annotationThread.acknowledged`. Solo se lee con el hilo en ese estado.
101
+ */
66
102
  acknowledgedLabel?: string;
67
- /** Rótulo del estado resuelto. Por defecto, en castellano: «Resuelta». */
103
+ /**
104
+ * Rótulo del estado resuelto. **Sin default**: sin él, sale de
105
+ * `annotationThread.resolved`. Solo se lee con el hilo en ese estado.
106
+ */
68
107
  resolvedLabel?: string;
69
- /** Marca de anotación editada. Por defecto, en castellano: «editada». */
108
+ /**
109
+ * Marca de anotación editada. **Sin default**: sin ella, sale de
110
+ * `annotationThread.edited`, y solo se lee cuando alguna anotación lo está.
111
+ */
70
112
  editedLabel?: string;
71
113
  /**
72
- * Rótulo que cuenta las respuestas. Por defecto, en castellano:
73
- * «1 respuesta» / «N respuestas».
114
+ * Rótulo que cuenta las respuestas, con su plural. **Sin default**: sin él,
115
+ * sale de `annotationThread.replies`, y solo se lee cuando hay respuestas.
74
116
  */
75
117
  repliesLabel?: (count: number) => string;
76
- /** Nombre accesible del hilo. Por defecto, en castellano: «Hilo de anotaciones». */
118
+ /**
119
+ * Nombre accesible del hilo. **Sin default**: sin él, sale de
120
+ * `annotationThread.label`.
121
+ */
77
122
  label?: string;
78
123
  /** Se añade DESPUÉS de las clases propias. */
79
124
  className?: string;
@@ -1,6 +1,17 @@
1
1
  import { type ReactNode } from 'react';
2
2
  import type { MessageTimestamp } from '../../molecules/_shared/messageTimestamp';
3
3
  import './ConversationThread.css';
4
+ /**
5
+ * El cromo del hilo: cómo se llama la región que anuncia los mensajes nuevos.
6
+ *
7
+ * Es una sola clave, y **no incluye el estado de escritura**: ese vive en
8
+ * `typingIndicator.typing(name)`, que es de quien lo pinta. El hilo solo lo
9
+ * reenvía.
10
+ */
11
+ export interface ConversationThreadMessages {
12
+ /** Nombre accesible del `role="log"` que envuelve el hilo. */
13
+ label: string;
14
+ }
4
15
  export interface ConversationMessage {
5
16
  id: string;
6
17
  role: 'user' | 'assistant';
@@ -21,11 +32,23 @@ export interface ConversationThreadProps extends React.ComponentPropsWithoutRef<
21
32
  messages?: ConversationMessage[];
22
33
  /** Burbujas ya montadas por el producto (mensajes con herramientas, adjuntos…): el hilo pone el contenedor, el `role="log"` y el autoscroll. */
23
34
  children?: ReactNode;
24
- /** Texto accesible para el indicador de escritura. */
35
+ /**
36
+ * Quién escribe mientras se genera una respuesta. **Obligatoria y sin
37
+ * default**: el nombre del asistente es contenido del producto; el verbo lo
38
+ * pone el catálogo (`typingIndicator.typing(name)`). Se reenvía a cada
39
+ * `AssistantMessage`.
40
+ */
41
+ streamingName: string;
42
+ /**
43
+ * La frase entera del estado de escritura, cuando la plantilla del catálogo
44
+ * no vale. **Sin default**: sin ella, sale de
45
+ * `typingIndicator.typing(streamingName)`. Se reenvía a cada
46
+ * `AssistantMessage`.
47
+ */
25
48
  streamingLabel?: string;
26
49
  /**
27
- * aria-label del `role="log"` que envuelve el hilo. Default: "Conversación"
28
- * (castellano). Una app multiidioma debe pasarla traducida.
50
+ * `aria-label` del `role="log"` que envuelve el hilo. **Sin default**: sin
51
+ * él, sale de `conversationThread.label` del `BrandMessagesProvider`.
29
52
  */
30
53
  ariaLabel?: string;
31
54
  /** Locale con el que se formatean las marcas de tiempo. Default `'es-ES'`. */
@@ -1,5 +1,22 @@
1
1
  import { type ReactNode } from 'react';
2
2
  import './ChatShell.css';
3
+ /**
4
+ * El cromo del armazón: cómo se llama la columna de conversaciones y cómo se
5
+ * llama el botón que la despliega en pantallas estrechas.
6
+ *
7
+ * **Espacio propio y no el de `ConversationList`**, aunque hoy digan la misma
8
+ * palabra. Son dos piezas distintas —el armazón de la pantalla y la lista que
9
+ * cuelga de él— y el precedente está puesto: `appRoot.skipToContent` y
10
+ * `appShell.skipToContent` son la misma frase en dos espacios. El armazón se
11
+ * monta también sin `list` —dentro de un `AppShell`, donde la columna vive en
12
+ * el `Sidebar`—, y entonces ninguna de las dos claves se lee.
13
+ */
14
+ export interface ChatShellMessages {
15
+ /** Nombre accesible de la columna de conversaciones, y título del cajón en pantallas estrechas. */
16
+ list: string;
17
+ /** Nombre accesible del botón que abre el cajón de conversaciones. */
18
+ listTrigger: string;
19
+ }
3
20
  export interface ChatShellProps extends React.ComponentPropsWithoutRef<'div'> {
4
21
  /**
5
22
  * La columna de conversaciones, normalmente un `ConversationList`. Sin ella,
@@ -18,13 +35,14 @@ export interface ChatShellProps extends React.ComponentPropsWithoutRef<'div'> {
18
35
  composer?: ReactNode;
19
36
  /**
20
37
  * `aria-label` de la columna de conversaciones y título del cajón en
21
- * pantallas estrechas. Default: "Conversaciones" (castellano). Solo se usa
22
- * si hay `list`.
38
+ * pantallas estrechas. **Sin default**: sin él, sale de `chatShell.list` del
39
+ * `BrandMessagesProvider`. Solo se lee si hay `list`.
23
40
  */
24
41
  listLabel?: string;
25
42
  /**
26
- * Nombre accesible del botón que abre el cajón de conversaciones. Default:
27
- * "Abrir conversaciones" (castellano).
43
+ * Nombre accesible del botón que abre el cajón de conversaciones. **Sin
44
+ * default**: sin él, sale de `chatShell.listTrigger`. Solo se lee por debajo
45
+ * del punto de ruptura, que es donde el botón existe.
28
46
  */
29
47
  listTriggerLabel?: string;
30
48
  /**