@studiolxd/brand 40.0.0 → 40.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.
package/CHANGELOG.md CHANGED
@@ -7,6 +7,51 @@ El paquete sigue [semver](https://semver.org/lang/es/): **patch** para bug fixes
7
7
  regeneración de `dist`, **minor** para componentes/props/variantes/tokens nuevos, **major**
8
8
  para breaking changes.
9
9
 
10
+ ## [40.1.0] — 2026-09-15
11
+
12
+ > **Minor.** `AnnotationThread` gana un tercer estado y una ranura para la coordenada de
13
+ > cada anotación.
14
+
15
+ ### El tercer estado: `acknowledged`
16
+
17
+ El organismo tenía dos estados, `open` y `resolved`, y le faltaba el peldaño de en medio.
18
+ No es un matiz visual: donde se usa, el pie ofrece **las transiciones disponibles desde
19
+ donde estás**, así que colapsar «planteada» y «atendida» en un mismo `open` hace que el
20
+ rótulo diga lo mismo en dos estados entre los que se puede mover, y la interfaz deja de
21
+ decir si alguien se ha hecho cargo.
22
+
23
+ Se llama `acknowledged` —«Atendida» por defecto, con su `acknowledgedLabel`— y no
24
+ `verified`, que es el vocabulario de UN producto: donde nació, «verificada» significa que
25
+ alguien comprobó el arreglo, pero en una nota de traducción el mismo peldaño es «alguien ya
26
+ se ha hecho cargo». El nombre del sistema dice **dónde está el hilo** —planteado, atendido,
27
+ cerrado—, no qué significa en tu dominio; el rótulo es prop, así que cada producto sigue
28
+ diciendo su palabra. Se descartó `reviewed` por colisión: el componente vive en paneles de
29
+ revisión, donde «revisada» ya se lee como otra cosa.
30
+
31
+ El tratamiento es una **escala de presencia** —plena, segundo plano, retirada— con un solo
32
+ token nuevo, `annotation-thread.acknowledged-opacity`, hermano del `resolved-opacity` que ya
33
+ existía. Ningún color nuevo: el `Tag` usa su variante `info`. Y por ser opacidad se lee
34
+ igual en superficie clara y oscura, así que no hizo falta ningún par `surface-dark-*`.
35
+
36
+ ### `AnnotationEntry.meta`: la coordenada de una anotación
37
+
38
+ Ranura nueva **por anotación**, no del hilo: cada una tiene su fecha y su sitio, y una
39
+ respuesta puede apuntar a otro lugar que la anotación que abre el hilo. Se pinta dentro de
40
+ la cabecera de esa anotación, después del avatar, el autor, la fecha y la marca de editada
41
+ — añade, no sustituye.
42
+
43
+ No es `actions`, y la diferencia no es de colocación: `actions` son las cosas que se le
44
+ hacen a la anotación —editar, borrar, citar—; la coordenada es parte de **lo que la
45
+ anotación es**. Puesta entre los botones del pie se convertía en un botón más.
46
+
47
+ Cuando no cabe, la que baja de línea es la coordenada y nunca la fecha: lo garantiza el
48
+ orden del marcado, no una media query. Una coordenada larga —el título de una lección— se
49
+ parte dentro en vez de desbordar el hilo. Las dos cosas las mide un test en un navegador de
50
+ verdad, dentro de una caja estrecha.
51
+
52
+ La ranura lee los tokens `meta-*` que el organismo ya tenía para la fecha, así que no
53
+ estrena ninguno.
54
+
10
55
  ## [40.0.0] — 2026-09-15
11
56
 
12
57
  > **Major.** El sistema estrena **proveedor de textos**: un catálogo que se monta una vez
@@ -3104,6 +3104,7 @@ var e = {
3104
3104
  "--annotation-thread-body-color": "#111e30",
3105
3105
  "--annotation-thread-replies-label-font-size": "0.875rem",
3106
3106
  "--annotation-thread-replies-label-color": "#4a4a4a",
3107
+ "--annotation-thread-acknowledged-opacity": "0.7",
3107
3108
  "--annotation-thread-resolved-opacity": "0.4",
3108
3109
  "--chart-series-1": "#1e7ff6",
3109
3110
  "--chart-series-2": "#f16123",
@@ -13,16 +13,36 @@ export interface AnnotationEntry {
13
13
  avatar?: ReactNode;
14
14
  /** Se marca como editada junto a la fecha. */
15
15
  edited?: boolean;
16
+ /**
17
+ * Lo que el producto añade **a la fila de metadatos**, al lado de la fecha:
18
+ * la coordenada de la anotación —el enlace a la lección, al segmento, a la
19
+ * versión—, no una acción sobre ella (para eso está `actions`).
20
+ *
21
+ * Se añade DESPUÉS de la fecha y de la marca de editada: no las sustituye, y
22
+ * al estrecharse cae a su propia línea sin empujarlas fuera de la vista.
23
+ */
24
+ meta?: ReactNode;
16
25
  /** Acciones de **esta** anotación: editar, borrar, citar. */
17
26
  actions?: ReactNode;
18
27
  }
28
+ /**
29
+ * Los tres estados del hilo, en orden de flujo. El nombre dice **dónde está el
30
+ * hilo**, no cómo lo llama cada producto: el rótulo es una prop, así que una
31
+ * revisión puede escribir «Verificada» sobre `acknowledged` sin que el sistema
32
+ * herede el vocabulario de un producto.
33
+ */
34
+ export type AnnotationThreadStatus = 'open' | 'acknowledged' | 'resolved';
19
35
  export interface AnnotationThreadProps extends React.ComponentPropsWithoutRef<'article'> {
20
36
  /** La anotación que abre el hilo. */
21
37
  annotation: AnnotationEntry;
22
38
  /** Las respuestas, en orden. */
23
39
  replies?: AnnotationEntry[];
24
- /** Estado del hilo. Un hilo resuelto se retira visualmente sin desaparecer. */
25
- status?: 'open' | 'resolved';
40
+ /**
41
+ * Estado del hilo, en orden de flujo. `open` pide atención; `acknowledged`
42
+ * es el hilo que alguien ya ha mirado y da un paso atrás sin cerrarse;
43
+ * `resolved` se retira visualmente sin desaparecer.
44
+ */
45
+ status?: AnnotationThreadStatus;
26
46
  /** Acciones del hilo entero: resolver, reabrir, seguir. Van al pie. */
27
47
  actions?: ReactNode;
28
48
  /** Con qué se responde: un `MessageComposer`, un `TextareaField`, un `Button`. */
@@ -33,6 +53,8 @@ export interface AnnotationThreadProps extends React.ComponentPropsWithoutRef<'a
33
53
  dateFormat?: Intl.DateTimeFormatOptions;
34
54
  /** Rótulo del estado abierto. Por defecto, en castellano: «Abierta». */
35
55
  openLabel?: string;
56
+ /** Rótulo del estado atendido. Por defecto, en castellano: «Atendida». */
57
+ acknowledgedLabel?: string;
36
58
  /** Rótulo del estado resuelto. Por defecto, en castellano: «Resuelta». */
37
59
  resolvedLabel?: string;
38
60
  /** Marca de anotación editada. Por defecto, en castellano: «editada». */
@@ -50,12 +72,12 @@ export interface AnnotationThreadProps extends React.ComponentPropsWithoutRef<'a
50
72
  /**
51
73
  * Un hilo de anotaciones sobre algo: el comentario de revisión de una lección,
52
74
  * la nota sobre un segmento de traducción. Cada anotación lleva **autor, fecha
53
- * y sus propias acciones**, el hilo tiene **estado** (abierta o resuelta) y se
54
- * responde al pie.
75
+ * y sus propias acciones**, el hilo tiene **estado** (abierta, atendida o
76
+ * resuelta) y se responde al pie.
55
77
  *
56
78
  * No es `ConversationThread`: aquello es una conversación de usuario y
57
79
  * asistente, con burbujas, orden de emisor y desplazamiento automático. Aquí
58
80
  * todas las anotaciones son iguales, lo que importa es quién dijo qué y cuándo,
59
81
  * y si el asunto sigue abierto.
60
82
  */
61
- export declare function AnnotationThread({ annotation, replies, status, actions, reply, locale, dateFormat, openLabel, resolvedLabel, editedLabel, repliesLabel, label, className, ...rest }: AnnotationThreadProps): import("react/jsx-runtime").JSX.Element;
83
+ export declare function AnnotationThread({ annotation, replies, status, actions, reply, locale, dateFormat, openLabel, acknowledgedLabel, resolvedLabel, editedLabel, repliesLabel, label, className, ...rest }: AnnotationThreadProps): import("react/jsx-runtime").JSX.Element;
@@ -1 +1 @@
1
- .annotation-thread{gap:var(--annotation-thread-gap);padding-block:var(--annotation-thread-padding-block);padding-inline:var(--annotation-thread-padding-inline);border:var(--annotation-thread-border-width) var(--annotation-thread-border-style) var(--annotation-thread-border-color);flex-direction:column;display:flex}.annotation-thread.annotation-thread--resolved{opacity:var(--annotation-thread-resolved-opacity)}.annotation-thread__status{display:flex}.annotation-thread__item{gap:var(--annotation-thread-item-gap);flex-direction:column;display:flex}.annotation-thread__header{align-items:center;gap:var(--annotation-thread-header-gap);flex-wrap:wrap;display:flex}.annotation-thread__avatar{flex-shrink:0;display:inline-flex}.annotation-thread__author{font-family:var(--annotation-thread-author-font-family);font-size:var(--annotation-thread-author-font-size);font-weight:var(--annotation-thread-author-font-weight);color:var(--annotation-thread-author-color)}.annotation-thread__date,.annotation-thread__edited{font-size:var(--annotation-thread-meta-font-size);color:var(--annotation-thread-meta-color)}.annotation-thread__body{font-size:var(--annotation-thread-body-font-size);line-height:var(--annotation-thread-body-line-height);color:var(--annotation-thread-body-color)}.annotation-thread__item-actions{gap:var(--annotation-thread-header-gap);flex-wrap:wrap;display:flex}.annotation-thread__replies{gap:var(--annotation-thread-items-gap);border-inline-start:var(--annotation-thread-reply-guide-width) var(--annotation-thread-reply-guide-style) var(--annotation-thread-reply-guide-color);flex-direction:column;padding-inline-start:var(--annotation-thread-reply-indent);display:flex}.annotation-thread__replies-label{font-size:var(--annotation-thread-replies-label-font-size);color:var(--annotation-thread-replies-label-color);margin-block:0}.annotation-thread__actions{gap:var(--annotation-thread-header-gap);flex-wrap:wrap;display:flex}
1
+ .annotation-thread{gap:var(--annotation-thread-gap);padding-block:var(--annotation-thread-padding-block);padding-inline:var(--annotation-thread-padding-inline);border:var(--annotation-thread-border-width) var(--annotation-thread-border-style) var(--annotation-thread-border-color);flex-direction:column;display:flex}.annotation-thread.annotation-thread--acknowledged{opacity:var(--annotation-thread-acknowledged-opacity)}.annotation-thread.annotation-thread--resolved{opacity:var(--annotation-thread-resolved-opacity)}.annotation-thread__status{display:flex}.annotation-thread__item{gap:var(--annotation-thread-item-gap);flex-direction:column;display:flex}.annotation-thread__header{align-items:center;gap:var(--annotation-thread-header-gap);flex-wrap:wrap;display:flex}.annotation-thread__avatar{flex-shrink:0;display:inline-flex}.annotation-thread__author{font-family:var(--annotation-thread-author-font-family);font-size:var(--annotation-thread-author-font-size);font-weight:var(--annotation-thread-author-font-weight);color:var(--annotation-thread-author-color)}.annotation-thread__date,.annotation-thread__edited{font-size:var(--annotation-thread-meta-font-size);color:var(--annotation-thread-meta-color)}.annotation-thread__meta{align-items:center;gap:var(--annotation-thread-header-gap);overflow-wrap:anywhere;min-inline-size:0;font-size:var(--annotation-thread-meta-font-size);color:var(--annotation-thread-meta-color);flex-wrap:wrap;display:inline-flex}.annotation-thread__body{font-size:var(--annotation-thread-body-font-size);line-height:var(--annotation-thread-body-line-height);color:var(--annotation-thread-body-color)}.annotation-thread__item-actions{gap:var(--annotation-thread-header-gap);flex-wrap:wrap;display:flex}.annotation-thread__replies{gap:var(--annotation-thread-items-gap);border-inline-start:var(--annotation-thread-reply-guide-width) var(--annotation-thread-reply-guide-style) var(--annotation-thread-reply-guide-color);flex-direction:column;padding-inline-start:var(--annotation-thread-reply-indent);display:flex}.annotation-thread__replies-label{font-size:var(--annotation-thread-replies-label-font-size);color:var(--annotation-thread-replies-label-color);margin-block:0}.annotation-thread__actions{gap:var(--annotation-thread-header-gap);flex-wrap:wrap;display:flex}
@@ -4,12 +4,16 @@ import "react";
4
4
  import { jsx as t, jsxs as n } from "react/jsx-runtime";
5
5
  //#region src/stories/organisms/AnnotationThread/AnnotationThread.tsx
6
6
  var r = {
7
+ open: "warning",
8
+ acknowledged: "info",
9
+ resolved: "success"
10
+ }, i = {
7
11
  day: "numeric",
8
12
  month: "short",
9
13
  hour: "2-digit",
10
14
  minute: "2-digit"
11
15
  };
12
- function i({ entry: e, locale: r, dateFormat: i, editedLabel: a }) {
16
+ function a({ entry: e, locale: r, dateFormat: i, editedLabel: a }) {
13
17
  let o = e.date instanceof Date ? e.date : new Date(e.date), s = new Intl.DateTimeFormat(r, i).format(o);
14
18
  return /* @__PURE__ */ n("article", {
15
19
  className: "annotation-thread__item",
@@ -33,6 +37,10 @@ function i({ entry: e, locale: r, dateFormat: i, editedLabel: a }) {
33
37
  e.edited && /* @__PURE__ */ t("span", {
34
38
  className: "annotation-thread__edited",
35
39
  children: a
40
+ }),
41
+ e.meta && /* @__PURE__ */ t("span", {
42
+ className: "annotation-thread__meta",
43
+ children: e.meta
36
44
  })
37
45
  ]
38
46
  }),
@@ -47,52 +55,55 @@ function i({ entry: e, locale: r, dateFormat: i, editedLabel: a }) {
47
55
  ]
48
56
  });
49
57
  }
50
- function a({ annotation: a, replies: o = [], status: s = "open", actions: c, reply: l, locale: u = "es-ES", dateFormat: d = r, openLabel: f = "Abierta", resolvedLabel: p = "Resuelta", editedLabel: m = "editada", repliesLabel: h = (e) => e === 1 ? "1 respuesta" : `${e} respuestas`, label: g = "Hilo de anotaciones", className: _, ...v }) {
51
- let y = s === "resolved";
58
+ function o({ annotation: o, replies: s = [], status: c = "open", actions: l, reply: u, locale: d = "es-ES", dateFormat: f = i, openLabel: p = "Abierta", acknowledgedLabel: m = "Atendida", resolvedLabel: h = "Resuelta", editedLabel: g = "editada", repliesLabel: _ = (e) => e === 1 ? "1 respuesta" : `${e} respuestas`, label: v = "Hilo de anotaciones", className: y, ...b }) {
52
59
  return /* @__PURE__ */ n("article", {
53
60
  className: [
54
61
  "annotation-thread",
55
- y ? "annotation-thread--resolved" : "",
56
- _ ?? ""
62
+ c === "open" ? "" : `annotation-thread--${c}`,
63
+ y ?? ""
57
64
  ].filter(Boolean).join(" "),
58
- "aria-label": g,
59
- ...v,
65
+ "aria-label": v,
66
+ ...b,
60
67
  children: [
61
68
  /* @__PURE__ */ t("div", {
62
69
  className: "annotation-thread__status",
63
70
  children: /* @__PURE__ */ t(e, {
64
- variant: y ? "success" : "warning",
65
- children: y ? p : f
71
+ variant: r[c],
72
+ children: {
73
+ open: p,
74
+ acknowledged: m,
75
+ resolved: h
76
+ }[c]
66
77
  })
67
78
  }),
68
- /* @__PURE__ */ t(i, {
69
- entry: a,
70
- locale: u,
71
- dateFormat: d,
72
- editedLabel: m
79
+ /* @__PURE__ */ t(a, {
80
+ entry: o,
81
+ locale: d,
82
+ dateFormat: f,
83
+ editedLabel: g
73
84
  }),
74
- o.length > 0 && /* @__PURE__ */ n("div", {
85
+ s.length > 0 && /* @__PURE__ */ n("div", {
75
86
  className: "annotation-thread__replies",
76
87
  children: [/* @__PURE__ */ t("p", {
77
88
  className: "annotation-thread__replies-label",
78
- children: h(o.length)
79
- }), o.map((e) => /* @__PURE__ */ t(i, {
89
+ children: _(s.length)
90
+ }), s.map((e) => /* @__PURE__ */ t(a, {
80
91
  entry: e,
81
- locale: u,
82
- dateFormat: d,
83
- editedLabel: m
92
+ locale: d,
93
+ dateFormat: f,
94
+ editedLabel: g
84
95
  }, e.id))]
85
96
  }),
86
- l && /* @__PURE__ */ t("div", {
97
+ u && /* @__PURE__ */ t("div", {
87
98
  className: "annotation-thread__reply",
88
- children: l
99
+ children: u
89
100
  }),
90
- c && /* @__PURE__ */ t("footer", {
101
+ l && /* @__PURE__ */ t("footer", {
91
102
  className: "annotation-thread__actions",
92
- children: c
103
+ children: l
93
104
  })
94
105
  ]
95
106
  });
96
107
  }
97
108
  //#endregion
98
- export { a as AnnotationThread };
109
+ export { o as AnnotationThread };