@studiolxd/brand 49.3.1 → 49.5.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,107 @@ 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.5.0] — 2026-09-18
11
+
12
+ > **Minor.** La cuenta se lee en dos líneas: el ítem de menú acepta una segunda línea bajo la
13
+ > etiqueta, y la cabecera del menú de cuenta enseña la foto de la cuenta activa.
14
+
15
+ ### `MenuItem description` — el ítem de dos líneas
16
+
17
+ Un ítem de menú solo sabía decir una cosa: icono y una línea. El selector de varias cuentas del
18
+ shell tenía que apretar ahí nombre y correo —«Ana García · ana@…»— con el avatar haciendo de
19
+ icono, que es justo la información que se lee peor cuando hay tres cuentas parecidas.
20
+
21
+ `description` (opcional, en los ítems `button` y `link`) pinta esa segunda línea debajo de la
22
+ etiqueta, más tenue, y centra el icono —el avatar— contra el bloque de las dos. Cada línea se
23
+ recorta con puntos suspensivos, así que un correo largo no ensancha el panel. Es **aditivo**: sin
24
+ `description` el ítem sale con el marcado de siempre —ni envoltorio de texto ni segunda línea—, y
25
+ los menús de una línea que ya existen no cambian ni un píxel.
26
+
27
+ No hay tokens nuevos. La segunda línea toma la letra y la tinta del rótulo de sección
28
+ (`menu.label-font-size`, `menu.label-color`), que es el papel que ya cumplen en este menú, y bajo
29
+ el puntero o el teclado va con la tinta del ítem resaltado en vez de con la suya, para no quedarse
30
+ gris sobre el relleno de marca. Las clases son `menu__item-icon`, `-text`, `-label` y
31
+ `-description`; el `UserMenu` las tiene con su prefijo y su propia tinta (la del correo de la
32
+ cabecera), para que una lista de cuentas dentro de ese panel se lea igual.
33
+
34
+ ### `UserMenu` — la cabecera enseña a quién pertenece la cuenta
35
+
36
+ La cabecera del panel decía el nombre y el correo, pero no enseñaba la foto: el avatar solo
37
+ estaba en el disparador, y al abrir el menú desaparecía justo cuando hace falta confirmar en qué
38
+ cuenta estás. Ahora la cabecera es una fila: el `Avatar` de siempre a la izquierda (foto o, sin
39
+ `avatarUrl`, las iniciales) y, al lado, nombre y correo en columna. Decorativo (`alt=""`), porque
40
+ el nombre va escrito al lado. El aire entre foto y texto es el mismo que en el disparador
41
+ (`user-menu.trigger-gap`): es la misma pareja. Sin tokens nuevos.
42
+
43
+ ## [49.4.0] — 2026-09-17
44
+
45
+ > **Minor.** Cuatro huecos que dejó al descubierto la campaña de crudos de bricks: un bocadillo
46
+ > sobre un control apagado, la ranura de acciones de una tarjeta-enlace, dónde aterriza lo que
47
+ > calcula un motor de arrastre, y el HTML que no viene de React.
48
+
49
+ ### `Tooltip disabledTrigger` — el motivo de un control deshabilitado
50
+
51
+ Un control apagado es el que más necesita explicarse, y es justo el que no puede: un
52
+ `button[disabled]` no recibe eventos de puntero ni foco, así que no dispara nada. Con
53
+ `disabledTrigger`, el bocadillo se dispara desde un envoltorio focusable
54
+ (`span.tooltip__trigger`, `tabIndex={0}`) que pone el propio componente, y el CSS apaga los
55
+ eventos de puntero del hijo deshabilitado para que el hover **sobre el botón** llegue al
56
+ envoltorio. Eso segundo es lo que falta siempre que esto se monta a mano —el `<span tabIndex={0}>`
57
+ casero abre con el teclado pero no con el ratón—, y era el caso de `design-matrix-studio` en
58
+ bricks. El control sigue deshabilitado de verdad; lo único que cambia es quién dispara.
59
+
60
+ Se descartó la otra forma, un `Button disabledReason`: ataría el átomo más usado del sistema a
61
+ `Tooltip` y a su proveedor, lo obligaría a ser componente de cliente en apps que hoy lo pintan
62
+ desde el servidor, y no serviría para un `Select` o un `Switcher` apagados.
63
+
64
+ ### `Card linkOverlay` y `CardAction isolate` — la tarjeta que navega y lleva acciones
65
+
66
+ Envolver una tarjeta con menú en el `<a>` del router mete un `<button>` dentro de un `<a>`: no es
67
+ HTML válido, y el lector de pantalla lee un enlace cuyo nombre se traga el título, el estado, el
68
+ pie y la etiqueta del menú. La forma del sistema es `Card linkOverlay`: la tarjeta es contenedora,
69
+ el enlace es el del **título** y estira su área de pulsación a todo el bloque con una capa vacía;
70
+ la ranura de acciones sube por encima y se pulsa sola.
71
+
72
+ Y para lo que ya existe —una tarjeta envuelta en un enlace, una fila pulsable—, `CardAction`
73
+ **aísla su ranura por defecto** (`isolate`): detiene la propagación y, **solo cuando cuelga de un
74
+ enlace y solo para lo que se pulsa dentro de ella**, cancela la acción por defecto. Las dos cosas
75
+ hacen falta: detener la propagación no cancela la navegación, y acotar el `preventDefault` es lo
76
+ que evita romper un `type="submit"` de una tarjeta contenedora o el ítem de un `Menu`, que se
77
+ pinta en un portal fuera del enlace.
78
+
79
+ ### `Sortable` — dónde aterriza lo que calcula un motor de arrastre
80
+
81
+ El sistema no trae motor de arrastre y no va a traerlo. Lo que faltaba era dónde deja el motor lo
82
+ que calcula en cada fotograma, porque la respuesta de manual —`style={{ transform: CSS.Transform
83
+ .toString(transform) }}`— es justo lo que el sistema no puede emitir: una app con `style-src
84
+ 'self'` descarta el atributo `style` sin dejar ni una violación en consola.
85
+
86
+ `Sortable` recibe el desplazamiento como **dato** (`transform`, con la forma que devuelven dnd-kit
87
+ y compañía, para pasársela tal cual), lo escribe por el **CSSOM** en `--sortable-x`/`-y` y las dos
88
+ escalas, y publica el estado como atributo (`data-dragging`). El `transform` y la atenuación del
89
+ original (`--opacity-disabled`, sin token nuevo: el original queda fuera de juego) viven en la
90
+ hoja del sistema. Reenvía `ref`, que es lo que el motor necesita para registrar el nodo, y anula
91
+ la transición con `prefers-reduced-motion` —la dicta el motor en una cadena suya, así que no pasa
92
+ por los tokens de duración—.
93
+
94
+ ### `Prose html` — el HTML que no viene de React
95
+
96
+ `Prose` existía para vestir la semántica cruda de un documento, pero solo aceptaba `children`, así
97
+ que el HTML de un parser de `.docx`/`.pdf` acababa en un `dangerouslySetInnerHTML` sobre un
98
+ `<div>` desnudo —nueve sitios en una sola pantalla de bricks—, fuera de la escala, del ritmo y de
99
+ la medida de lectura. Ahora entra por `html`, **excluyente con `children` por tipo**. El DS **no
100
+ sanea**: la cadena llega ya limpia del consumidor, y por eso la prop es `string` y no un
101
+ `ReactNode`. Se descartó una pieza aparte (`RawHtml`) dentro de `Prose`: obligaría a escribir dos
102
+ componentes para una sola cosa y dejaría el HTML suelto sin vestir cuando se olvidara el de fuera.
103
+
104
+ ### Además
105
+
106
+ - Norma en Foundations › Opacidad: el original de un arrastre usa `--opacity-disabled`, que es el
107
+ mismo estado de «fuera de juego» del rol — no es un valor nuevo.
108
+ - `src/index.ts`, `scripts/entry-points.mjs` y `package.json#exports` registran `Sortable`
109
+ (componente de cliente).
110
+
10
111
  ## [49.3.1] — 2026-09-17
11
112
 
12
113
  > **Patch.** La v49.0.1 estrechó a `:where(.link)` el `inline-size: fit-content` que evita
@@ -7,11 +7,22 @@ function i({ children: e, ...n }) {
7
7
  children: e
8
8
  });
9
9
  }
10
- function a(r, i) {
10
+ function a(r, i, a, o) {
11
+ let s = a && o ? /* @__PURE__ */ n("span", {
12
+ className: `${o}__item-text`,
13
+ children: [/* @__PURE__ */ t("span", {
14
+ className: `${o}__item-label`,
15
+ children: r
16
+ }), /* @__PURE__ */ t("span", {
17
+ className: `${o}__item-description`,
18
+ children: a
19
+ })]
20
+ }) : r;
11
21
  return i ? /* @__PURE__ */ n(e, { children: [/* @__PURE__ */ t("span", {
12
22
  "aria-hidden": "true",
23
+ className: o ? `${o}__item-icon` : void 0,
13
24
  children: i
14
- }), r] }) : /* @__PURE__ */ t(e, { children: r });
25
+ }), s] }) : /* @__PURE__ */ t(e, { children: s });
15
26
  }
16
27
  function o(e) {
17
28
  return e.reduce((e, t) => {
@@ -22,8 +33,8 @@ function o(e) {
22
33
  }), e;
23
34
  }, []);
24
35
  }
25
- function s({ items: e, itemClass: n, separatorClass: i, renderLink: s, labelClass: c, radioValue: l, onRadioValueChange: u }) {
26
- let d = (e, o) => {
36
+ function s({ items: e, itemClass: n, separatorClass: i, renderLink: s, labelClass: c, blockClass: l, radioValue: u, onRadioValueChange: d }) {
37
+ let f = (e, o) => {
27
38
  if (e.type === "separator") return /* @__PURE__ */ t(r.Separator, { className: i }, o);
28
39
  if (e.type === "label") return c ? /* @__PURE__ */ t(r.Group, { children: /* @__PURE__ */ t(r.GroupLabel, {
29
40
  className: c,
@@ -34,20 +45,20 @@ function s({ items: e, itemClass: n, separatorClass: i, renderLink: s, labelClas
34
45
  value: e.value,
35
46
  disabled: e.disabled,
36
47
  closeOnClick: e.closeOnSelect !== !1,
37
- children: a(e.label, e.icon)
48
+ children: a(e.label, e.icon, void 0, l)
38
49
  }, o);
39
- let l = a(e.label, e.icon);
50
+ let u = a(e.label, e.icon, e.description, l);
40
51
  return e.type === "link" ? e.disabled ? /* @__PURE__ */ t(r.Item, {
41
52
  className: n(e.destructive),
42
53
  disabled: !0,
43
- children: l
54
+ children: u
44
55
  }, o) : /* @__PURE__ */ t(r.Item, {
45
56
  className: n(e.destructive),
46
57
  render: (t) => s({
47
58
  ...t,
48
59
  href: e.href,
49
60
  className: t.className ?? n(e.destructive),
50
- children: l
61
+ children: u
51
62
  })
52
63
  }, o) : /* @__PURE__ */ t(r.Item, {
53
64
  className: n(e.destructive),
@@ -60,18 +71,18 @@ function s({ items: e, itemClass: n, separatorClass: i, renderLink: s, labelClas
60
71
  }
61
72
  setTimeout(() => e.onClick(), 0);
62
73
  },
63
- children: l
74
+ children: u
64
75
  }, o);
65
- }, f = e;
66
- if (!f.some((e) => e.type === "radio")) return f.map(d);
67
- let p = 0;
68
- return o(f).map((e, n) => {
69
- let i = p;
70
- p += e.items.length;
71
- let a = e.items.map((e, t) => d(e, i + t));
76
+ }, p = e;
77
+ if (!p.some((e) => e.type === "radio")) return p.map(f);
78
+ let m = 0;
79
+ return o(p).map((e, n) => {
80
+ let i = m;
81
+ m += e.items.length;
82
+ let a = e.items.map((e, t) => f(e, i + t));
72
83
  return e.radio ? /* @__PURE__ */ t(r.RadioGroup, {
73
- value: l,
74
- onValueChange: (e) => u?.(String(e)),
84
+ value: u,
85
+ onValueChange: (e) => d?.(String(e)),
75
86
  children: a
76
87
  }, `radio-${n}`) : a;
77
88
  });
@@ -0,0 +1,66 @@
1
+ import './Sortable.css';
2
+ /** Elementos con los que puede montarse el envoltorio ordenable. */
3
+ export type SortableElement = 'div' | 'li';
4
+ /**
5
+ * Desplazamiento que la biblioteca de arrastre calcula en cada fotograma, en
6
+ * píxeles. Es la forma que devuelven los motores de arrastre al uso (dnd-kit
7
+ * entre ellos), así que se les pasa tal cual: el DS no depende de ninguno.
8
+ */
9
+ export interface SortableTransform {
10
+ x: number;
11
+ y: number;
12
+ scaleX?: number;
13
+ scaleY?: number;
14
+ }
15
+ export interface SortableProps extends Omit<React.ComponentPropsWithoutRef<'div'>, 'style'> {
16
+ /** Elemento del envoltorio. `div` por defecto; `li` dentro de una lista. */
17
+ as?: SortableElement;
18
+ /**
19
+ * Desplazamiento del elemento mientras se reordena la lista, tal y como lo
20
+ * devuelve el motor de arrastre. `null` (o ausente) es la posición de
21
+ * reposo. Se escribe por el CSSOM en `--sortable-x`/`--sortable-y` (y las
22
+ * dos escalas), que es lo que consume el `transform` de la hoja.
23
+ */
24
+ transform?: SortableTransform | null;
25
+ /**
26
+ * Transición que acompaña al desplazamiento, la que dicte el motor (`transform
27
+ * 200ms ease`). `null` o ausente: sin transición. Con
28
+ * `prefers-reduced-motion` la hoja la anula.
29
+ */
30
+ transition?: string | null;
31
+ /**
32
+ * El elemento es el que se está arrastrando ahora mismo. Pone
33
+ * `data-dragging` —de donde cuelga el CSS— y atenúa el original, que se
34
+ * queda como hueco mientras la copia viaja con el puntero.
35
+ */
36
+ dragging?: boolean;
37
+ }
38
+ /**
39
+ * Envoltorio de un elemento **ordenable por arrastre**.
40
+ *
41
+ * El sistema no trae motor de arrastre y no va a traerlo: quien lo pone es la
42
+ * aplicación (dnd-kit, en la suite). Lo que faltaba era dónde aterriza lo que
43
+ * ese motor calcula en tiempo de ejecución, porque la respuesta evidente —un
44
+ * `style` inline con el `transform`— es justo lo que el sistema no puede
45
+ * emitir: una app servida con `style-src 'self'` descarta el atributo `style`
46
+ * sin dejar ni una violación en consola, y el arrastre se queda quieto sin
47
+ * que nadie sepa por qué.
48
+ *
49
+ * `Sortable` es ese aterrizaje: recibe el desplazamiento como **dato**, lo
50
+ * escribe por el CSSOM (que la CSP sí permite) en las variables que consume su
51
+ * hoja, y publica el estado como atributo (`data-dragging`). El aspecto —qué
52
+ * `transform` se aplica, cuánto se atenúa el original— vive en el CSS del
53
+ * sistema, no en la app.
54
+ *
55
+ * Reenvía `ref`: es lo que necesita el motor para medir y registrar el nodo
56
+ * (`setNodeRef` de dnd-kit).
57
+ *
58
+ * ```tsx
59
+ * const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({ id });
60
+ *
61
+ * <Sortable ref={setNodeRef} transform={transform} transition={transition} dragging={isDragging}>
62
+ * <Card>…</Card>
63
+ * </Sortable>
64
+ * ```
65
+ */
66
+ export declare const Sortable: import("react").ForwardRefExoticComponent<SortableProps & import("react").RefAttributes<HTMLElement>>;
@@ -41,6 +41,23 @@ export interface TooltipProps extends Omit<React.HTMLAttributes<HTMLElement>, 'c
41
41
  * @default true
42
42
  */
43
43
  describe?: boolean;
44
+ /**
45
+ * El disparador está **deshabilitado** y el bocadillo es justo lo que
46
+ * explica por qué. Un `button[disabled]` no sirve de disparador: el
47
+ * navegador no le manda eventos de puntero ni lo deja recibir foco, así que
48
+ * el bocadillo no se abre ni con el ratón ni con el teclado — y quien no
49
+ * puede pulsar es precisamente quien necesita leer el motivo.
50
+ *
51
+ * Con `disabledTrigger` el bocadillo se dispara desde un envoltorio
52
+ * focusable (`span.tooltip__trigger`, `tabIndex={0}`) que pone el propio
53
+ * componente: es él quien recibe hover, foco y el `aria-describedby`,
54
+ * mientras el control de dentro sigue deshabilitado de verdad. El CSS
55
+ * apaga los eventos de puntero del hijo deshabilitado para que el hover
56
+ * sobre el botón llegue al envoltorio en vez de perderse.
57
+ *
58
+ * @default false
59
+ */
60
+ disabledTrigger?: boolean;
44
61
  /**
45
62
  * Nodo DOM donde montar el portal. Por defecto, el nodo de la superficie que
46
63
  * llegue por contexto —`SiteShell` publica el suyo, para que la capa herede
@@ -67,6 +67,23 @@ export interface CardProps extends Omit<React.ComponentPropsWithoutRef<'div'>, '
67
67
  color?: CardColor;
68
68
  /** Maqueta de la tarjeta. Default: `'default'`. */
69
69
  variant?: CardVariant;
70
+ /**
71
+ * Modo contenedor: el enlace del **título** cubre toda la tarjeta. La
72
+ * tarjeta sigue siendo un `<div>` con contenido interactivo dentro —un menú
73
+ * en `CardAction`, un botón en el pie—, y quien navega es el `<a>` del
74
+ * título, que estira su área de pulsación a todo el bloque con una capa
75
+ * vacía (`::after`).
76
+ *
77
+ * Es la forma correcta de una «tarjeta que es enlace **y** lleva acciones»:
78
+ * meter un `<button>` dentro de un `<a>` —envolviendo la tarjeta en el
79
+ * `Link` del router— no es HTML válido, y un lector de pantalla anuncia un
80
+ * enlace cuyo nombre se come el título, el estado, el pie y la etiqueta del
81
+ * menú de una sentada. Con `linkOverlay` cada control conserva su papel: un
82
+ * enlace con el nombre del título, y un botón de menú aparte.
83
+ *
84
+ * La ranura de acciones queda por encima de la capa, así que se pulsa sola.
85
+ */
86
+ linkOverlay?: boolean;
70
87
  /**
71
88
  * Modo contenedor: la tarjeta entera es la opción de un grupo. Dentro va
72
89
  * un `RadioField` (o `CheckboxField`) del DS, que la tarjeta extiende a todo
@@ -136,8 +153,38 @@ export interface CardDescriptionProps extends Omit<ParagraphProps, 'children'> {
136
153
  * hereda el cuerpo de la superficie en la que viva la tarjeta.
137
154
  */
138
155
  export declare const CardDescription: import("react").ForwardRefExoticComponent<CardDescriptionProps & import("react").RefAttributes<HTMLParagraphElement>>;
139
- /** Acción alineada al extremo de la cabecera (menú, botón…). */
140
- export declare const CardAction: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
156
+ export interface CardActionProps extends CardPartProps {
157
+ /**
158
+ * La ranura **aísla sus eventos** de la tarjeta que la contiene, que es lo
159
+ * que se quiere siempre que la tarjeta sea a la vez un enlace (`Card href`,
160
+ * `Card render`, o un `<Link>` del router envolviéndola): pulsar el menú de
161
+ * la cabecera abre el menú, no navega.
162
+ *
163
+ * Hace dos cosas, y las dos hacen falta:
164
+ *
165
+ * - `stopPropagation`, para que el clic no llegue a un manejador que la
166
+ * tarjeta o la fila tengan puesto más arriba;
167
+ * - `preventDefault` **solo cuando la ranura cuelga de un enlace** —se
168
+ * comprueba en el DOM, buscando un `a[href]` por encima del propio nodo—
169
+ * y **solo para lo que se pulsa dentro de ella**. Sin esto no basta:
170
+ * detener la propagación no cancela la acción por defecto del navegador,
171
+ * que sigue el enlace igual. Y acotarlo evita romper lo que sí depende de
172
+ * su acción por defecto: un `type="submit"` dentro de una tarjeta
173
+ * contenedora, o el ítem de un `Menu` que se pinta en un portal fuera del
174
+ * enlace.
175
+ *
176
+ * `false` para la tarjeta que quiere lo contrario: que pulsar la acción
177
+ * cuente también como pulsar la tarjeta.
178
+ *
179
+ * @default true
180
+ */
181
+ isolate?: boolean;
182
+ }
183
+ /**
184
+ * Acción alineada al extremo de la cabecera (menú, botón…). Por defecto aísla
185
+ * sus eventos de la tarjeta-enlace que la contiene: ver `isolate`.
186
+ */
187
+ export declare const CardAction: import("react").ForwardRefExoticComponent<CardActionProps & import("react").RefAttributes<HTMLDivElement>>;
141
188
  /** Cuerpo de la tarjeta. */
142
189
  export declare const CardContent: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
143
190
  export interface CardFooterProps extends CardPartProps {
@@ -2,7 +2,7 @@ import { type ComponentPropsWithoutRef, type ReactNode } from 'react';
2
2
  import './Prose.css';
3
3
  /** Elementos con los que puede montarse el contenedor de texto largo. */
4
4
  export type ProseElement = 'div' | 'article' | 'section' | 'main' | 'aside';
5
- export interface ProseProps extends ComponentPropsWithoutRef<'div'> {
5
+ interface ProseBaseProps extends Omit<ComponentPropsWithoutRef<'div'>, 'children' | 'dangerouslySetInnerHTML'> {
6
6
  /**
7
7
  * Elemento del contenedor. `div` por defecto; `article` cuando el bloque es
8
8
  * el documento en sí (una página de documentación, un texto legal).
@@ -16,8 +16,32 @@ export interface ProseProps extends ComponentPropsWithoutRef<'div'> {
16
16
  * anchas o figuras a sangre.
17
17
  */
18
18
  measure?: boolean;
19
- children: ReactNode;
20
19
  }
20
+ export type ProseProps = (ProseBaseProps & {
21
+ /** Contenido en nodos de React. Excluyente con `html`. */
22
+ children: ReactNode;
23
+ html?: never;
24
+ }) | (ProseBaseProps & {
25
+ /**
26
+ * Cadena de **HTML ya saneado**, para el contenido que no viene de React: lo
27
+ * que devuelve un parser de `.docx`/`.pdf`, un campo de un CMS, un markdown ya
28
+ * compilado. Excluyente con `children`.
29
+ *
30
+ * Es la misma excepción que ya justifica a `Prose` —el contenido no trae
31
+ * clases porque no lo escribió nadie del sistema— llevada a su forma real: sin
32
+ * esta prop, cada aplicación acababa poniendo su propio
33
+ * `dangerouslySetInnerHTML` en un `<div>` desnudo, fuera de la hoja del
34
+ * sistema, y ese texto salía sin escala, sin ritmo y sin medida de lectura.
35
+ *
36
+ * **El sistema no sanea.** No lleva sanitizador ni va a llevarlo: la política
37
+ * de lo que se permite depende de la aplicación y de dónde venga el HTML. Lo
38
+ * que llega aquí tiene que venir ya limpio del consumidor (`sanitize-html`,
39
+ * DOMPurify, lo que use), y por eso la prop se declara `string` y no un
40
+ * `ReactNode`: es una frontera, y se cruza a conciencia.
41
+ */
42
+ html: string;
43
+ children?: never;
44
+ });
21
45
  /**
22
46
  * Contenedor de contenido largo: viste la semántica cruda que sale de un
23
47
  * markdown o de un CMS (`h2`–`h6`, `p`, `ul`/`ol`, `blockquote`, `pre`/`code`,
@@ -30,7 +54,11 @@ export interface ProseProps extends ComponentPropsWithoutRef<'div'> {
30
54
  * siendo de componentes (el único otro caso, mucho menor, es el `<mark>` del
31
55
  * extracto de `DocsSearch`).
32
56
  *
57
+ * El contenido entra de una de dos formas, **nunca de las dos**: `children`
58
+ * (nodos de React) o `html` (una cadena ya saneada). Ver la prop `html`.
59
+ *
33
60
  * Reenvía el resto de props del elemento (`data-*`, `aria-*`, `id`…) y
34
61
  * concatena `className` tras las clases propias.
35
62
  */
36
63
  export declare const Prose: import("react").ForwardRefExoticComponent<ProseProps & import("react").RefAttributes<HTMLDivElement>>;
64
+ export {};
@@ -2,6 +2,13 @@ import type { ReactNode } from 'react';
2
2
  export type MenuButtonItem = {
3
3
  type: 'button';
4
4
  label: string;
5
+ /**
6
+ * Segunda línea del ítem, más tenue: el correo de una cuenta, el detalle de
7
+ * una acción. Con ella el ítem se pinta a dos líneas —`label` arriba,
8
+ * `description` debajo— y el icono se alinea al bloque entero. Sin ella, el
9
+ * ítem se pinta a una línea, exactamente igual que siempre.
10
+ */
11
+ description?: string;
5
12
  icon?: ReactNode;
6
13
  onClick: () => void;
7
14
  disabled?: boolean;
@@ -16,6 +23,8 @@ export type MenuButtonItem = {
16
23
  export type MenuLinkItem = {
17
24
  type: 'link';
18
25
  label: string;
26
+ /** Segunda línea del ítem, más tenue. Igual que en el ítem `button`. */
27
+ description?: string;
19
28
  icon?: ReactNode;
20
29
  href: string;
21
30
  disabled?: boolean;
@@ -63,9 +72,17 @@ interface RenderDropdownItemsOptions {
63
72
  renderLink: (props: MenuRenderLinkProps) => ReactNode;
64
73
  /** Clase del rótulo de sección (ítems `label`). Sin ella, no se renderizan. */
65
74
  labelClass?: string;
75
+ /**
76
+ * Bloque BEM del menú que renderiza (`menu`, `user-menu`…): de él salen las
77
+ * clases del icono y de las dos líneas del ítem (`<bloque>__item-icon`,
78
+ * `-text`, `-label`, `-description`). Sin él, el ítem se pinta como siempre
79
+ * —una línea y el icono sin clase— y `description` se ignora: un menú que no
80
+ * viste la segunda línea no la dibuja a medias.
81
+ */
82
+ blockClass?: string;
66
83
  /** Valor activo del grupo de radio. */
67
84
  radioValue?: string;
68
85
  onRadioValueChange?: (value: string) => void;
69
86
  }
70
- export declare function renderDropdownItems({ items, itemClass, separatorClass, renderLink, labelClass, radioValue, onRadioValueChange, }: RenderDropdownItemsOptions): ReactNode;
87
+ export declare function renderDropdownItems({ items, itemClass, separatorClass, renderLink, labelClass, blockClass, radioValue, onRadioValueChange, }: RenderDropdownItemsOptions): ReactNode;
71
88
  export {};
package/dist/app-shell.js CHANGED
@@ -2,8 +2,8 @@
2
2
  import './app-shell.css';
3
3
  import { n as e } from "./_shared/brandmessagescontext.js";
4
4
  import { SkipLink as t } from "./skip-link.js";
5
- import { TooltipProvider as n } from "./tooltip.js";
6
- import { t as r } from "./_shared/css-properties.js";
5
+ import { t as n } from "./_shared/css-properties.js";
6
+ import { TooltipProvider as r } from "./tooltip.js";
7
7
  import { n as i, t as a } from "./_shared/appshellcontext.js";
8
8
  import { useCallback as o, useEffect as s, useMemo as c, useState as l } from "react";
9
9
  import { jsx as u, jsxs as d } from "react/jsx-runtime";
@@ -49,10 +49,10 @@ function m({ header: i, sidebar: f, children: m, defaultSidebar: h = "open", sid
49
49
  j,
50
50
  M,
51
51
  S
52
- ]), F = r({ "--app-shell-sidebar-width": D ? `${D}px` : void 0 }), I = !S && T;
52
+ ]), F = n({ "--app-shell-sidebar-width": D ? `${D}px` : void 0 }), I = !S && T;
53
53
  return /* @__PURE__ */ u(a.Provider, {
54
54
  value: P,
55
- children: /* @__PURE__ */ d(n, { children: [/* @__PURE__ */ u(t, {
55
+ children: /* @__PURE__ */ d(r, { children: [/* @__PURE__ */ u(t, {
56
56
  href: "#main-content",
57
57
  children: x("skipToContent", b)
58
58
  }), /* @__PURE__ */ d("div", {
package/dist/card.css CHANGED
@@ -1 +1 @@
1
- .card{box-shadow:none;color:inherit;padding-inline:var(--card-padding-inline);align-items:flex-start;gap:var(--card-gap);border-radius:var(--card-border-radius);flex-direction:column;padding-block-start:var(--card-padding-block-start);padding-block-end:var(--card-padding-block-end);text-decoration:none;display:flex}.card p:not(.paragraph){font-size:var(--card-description-font-size);margin-block-end:var(--card-description-margin-block-end)}.card .arrow{margin-block-start:auto}:where(button.card){appearance:none;font:inherit;text-align:start;cursor:pointer;background:0 0;border:0;inline-size:100%;margin:0}.card__footer.card__footer--column{flex-direction:column;align-items:stretch}.card.card--primary{background-color:var(--card-primary-bg);color:var(--card-primary-color);--text-list-color:var(--card-primary-color);--text-h1-color:var(--card-primary-color);--text-h2-color:var(--card-primary-color);--text-h3-color:var(--card-primary-color);--text-h4-color:var(--card-primary-color);--text-h5-color:var(--card-primary-color);--text-h6-color:var(--card-primary-color)}.card.card--outline{background-color:var(--card-outline-bg);color:var(--card-outline-color);border:var(--card-outline-border-width) solid var(--card-outline-border-color)}.card.card--accent-1{background-color:var(--card-accent-1-bg);color:var(--card-accent-1-color);--text-list-color:var(--card-accent-1-color)}.card.card--accent-2{background-color:var(--card-accent-2-bg);color:var(--card-accent-2-color);--text-list-color:var(--card-accent-2-color)}.card.card--support-1{background-color:var(--card-support-1-bg);color:var(--card-support-1-color);--text-list-color:var(--card-support-1-color)}.card.card--support-2{background-color:var(--card-support-2-bg);color:var(--card-support-2-color);--text-list-color:var(--card-support-2-color)}.card.card--square,.card.card--split{gap:0;padding-block:0;padding-inline:0}.card__body{align-items:flex-start;gap:var(--card-gap);inline-size:100%;padding-inline:var(--card-padding-inline);flex-direction:column;flex:1;padding-block-start:var(--card-padding-block-start);padding-block-end:var(--card-padding-block-end);display:flex}.card__media img{object-fit:cover;block-size:100%;inline-size:100%;display:block}.card--square .card__media,.card--split .card__media{aspect-ratio:1;inline-size:100%}@media (width>=768px){.card.card--split{flex-direction:row;align-items:stretch}.card--split .card__media,.card--split .card__body{flex:50%;inline-size:50%}.card--split .card__media{aspect-ratio:auto}}.card__header,.card__content,.card__footer{inline-size:100%}.card__header{align-items:start;column-gap:var(--card-header-gap);row-gap:var(--card-header-row-gap);grid-template-columns:minmax(0,1fr) auto;display:grid}.card__header>*{grid-column:1}.card__header>.card__action{grid-area:1/2;justify-self:end}.card__title{font-weight:var(--card-title-font-weight);color:inherit;margin-block:0}.card__description{color:inherit;margin-block:0}.card__description--lines-1{min-block-size:1lh}.card__description--lines-2{min-block-size:2lh}.card__description--lines-3{min-block-size:3lh}.card__footer{align-items:stretch;gap:var(--card-footer-gap);flex-direction:column;margin-block-start:auto;display:flex}.card__footer>*{inline-size:100%}@media (width>=768px){.card__footer:not(.card__footer--column){flex-direction:row}.card__footer:not(.card__footer--column)>*{inline-size:auto}}.card.card--selectable{cursor:pointer;position:relative}.card--selectable .radio-field,.card--selectable .checkbox-field{margin:0;position:absolute;inset:0}.card--selectable .radio-field__control,.card--selectable .checkbox-field__control{opacity:0;cursor:pointer;position:absolute;inset:0}.card.card--selectable:has(input:focus-visible){outline:var(--card-selectable-focus-ring-width) solid var(--card-selectable-focus-ring-color);outline-offset:var(--card-selectable-focus-ring-offset)}.card.card--selectable.card--selected{background-color:var(--card-accent-1-bg);color:var(--card-accent-1-color);border-color:var(--card-accent-1-bg);--text-list-color:var(--card-accent-1-color)}.card.card--selectable:has(input:checked){background-color:var(--card-accent-1-bg);color:var(--card-accent-1-color);border-color:var(--card-accent-1-bg);--text-list-color:var(--card-accent-1-color)}
1
+ .card{box-shadow:none;color:inherit;padding-inline:var(--card-padding-inline);align-items:flex-start;gap:var(--card-gap);border-radius:var(--card-border-radius);flex-direction:column;padding-block-start:var(--card-padding-block-start);padding-block-end:var(--card-padding-block-end);text-decoration:none;display:flex}.card p:not(.paragraph){font-size:var(--card-description-font-size);margin-block-end:var(--card-description-margin-block-end)}.card .arrow{margin-block-start:auto}:where(button.card){appearance:none;font:inherit;text-align:start;cursor:pointer;background:0 0;border:0;inline-size:100%;margin:0}.card__footer.card__footer--column{flex-direction:column;align-items:stretch}.card.card--primary{background-color:var(--card-primary-bg);color:var(--card-primary-color);--text-list-color:var(--card-primary-color);--text-h1-color:var(--card-primary-color);--text-h2-color:var(--card-primary-color);--text-h3-color:var(--card-primary-color);--text-h4-color:var(--card-primary-color);--text-h5-color:var(--card-primary-color);--text-h6-color:var(--card-primary-color)}.card.card--outline{background-color:var(--card-outline-bg);color:var(--card-outline-color);border:var(--card-outline-border-width) solid var(--card-outline-border-color)}.card.card--accent-1{background-color:var(--card-accent-1-bg);color:var(--card-accent-1-color);--text-list-color:var(--card-accent-1-color)}.card.card--accent-2{background-color:var(--card-accent-2-bg);color:var(--card-accent-2-color);--text-list-color:var(--card-accent-2-color)}.card.card--support-1{background-color:var(--card-support-1-bg);color:var(--card-support-1-color);--text-list-color:var(--card-support-1-color)}.card.card--support-2{background-color:var(--card-support-2-bg);color:var(--card-support-2-color);--text-list-color:var(--card-support-2-color)}.card.card--square,.card.card--split{gap:0;padding-block:0;padding-inline:0}.card__body{align-items:flex-start;gap:var(--card-gap);inline-size:100%;padding-inline:var(--card-padding-inline);flex-direction:column;flex:1;padding-block-start:var(--card-padding-block-start);padding-block-end:var(--card-padding-block-end);display:flex}.card__media img{object-fit:cover;block-size:100%;inline-size:100%;display:block}.card--square .card__media,.card--split .card__media{aspect-ratio:1;inline-size:100%}@media (width>=768px){.card.card--split{flex-direction:row;align-items:stretch}.card--split .card__media,.card--split .card__body{flex:50%;inline-size:50%}.card--split .card__media{aspect-ratio:auto}}.card__header,.card__content,.card__footer{inline-size:100%}.card__header{align-items:start;column-gap:var(--card-header-gap);row-gap:var(--card-header-row-gap);grid-template-columns:minmax(0,1fr) auto;display:grid}.card__header>*{grid-column:1}.card__header>.card__action{grid-area:1/2;justify-self:end}.card__title{font-weight:var(--card-title-font-weight);color:inherit;margin-block:0}.card__description{color:inherit;margin-block:0}.card__description--lines-1{min-block-size:1lh}.card__description--lines-2{min-block-size:2lh}.card__description--lines-3{min-block-size:3lh}.card__footer{align-items:stretch;gap:var(--card-footer-gap);flex-direction:column;margin-block-start:auto;display:flex}.card__footer>*{inline-size:100%}@media (width>=768px){.card__footer:not(.card__footer--column){flex-direction:row}.card__footer:not(.card__footer--column)>*{inline-size:auto}}.card.card--selectable{cursor:pointer;position:relative}.card--selectable .radio-field,.card--selectable .checkbox-field{margin:0;position:absolute;inset:0}.card--selectable .radio-field__control,.card--selectable .checkbox-field__control{opacity:0;cursor:pointer;position:absolute;inset:0}.card.card--selectable:has(input:focus-visible){outline:var(--card-selectable-focus-ring-width) solid var(--card-selectable-focus-ring-color);outline-offset:var(--card-selectable-focus-ring-offset)}.card.card--selectable.card--selected{background-color:var(--card-accent-1-bg);color:var(--card-accent-1-color);border-color:var(--card-accent-1-bg);--text-list-color:var(--card-accent-1-color)}.card.card--selectable:has(input:checked){background-color:var(--card-accent-1-bg);color:var(--card-accent-1-color);border-color:var(--card-accent-1-bg);--text-list-color:var(--card-accent-1-color)}.card.card--link-overlay{position:relative}.card.card--link-overlay .card__title a:after{content:"";position:absolute;inset:0}.card.card--link-overlay .card__action{z-index:1;position:relative}
package/dist/card.js CHANGED
@@ -4,80 +4,81 @@ import { VisuallyHidden as e } from "./visually-hidden.js";
4
4
  import { Arrow as t } from "./arrow.js";
5
5
  import { Heading as n } from "./heading.js";
6
6
  import { Paragraph as r } from "./paragraph.js";
7
- import { forwardRef as i } from "react";
8
- import { Fragment as a, jsx as o, jsxs as s } from "react/jsx-runtime";
9
- import { useRender as c } from "@base-ui/react/use-render";
7
+ import { forwardRef as i, useCallback as a, useRef as o } from "react";
8
+ import { Fragment as s, jsx as c, jsxs as l } from "react/jsx-runtime";
9
+ import { useRender as u } from "@base-ui/react/use-render";
10
10
  //#region src/stories/molecules/Card/Card.tsx
11
- var l = i(function({ href: r, render: i, external: l = !1, title: u, description: d, ctaLabel: f, color: p = "outline", variant: m = "default", media: h, selectable: g = !1, selected: _ = !1, className: v, children: y, ...b }, x) {
12
- let S = [
11
+ var d = i(function({ href: r, render: i, external: a = !1, title: o, description: d, ctaLabel: f, color: p = "outline", variant: m = "default", media: h, linkOverlay: g = !1, selectable: _ = !1, selected: v = !1, className: y, children: b, ...x }, S) {
12
+ let C = [
13
13
  "card",
14
14
  `card--${p}`,
15
15
  m === "default" ? "" : `card--${m}`,
16
- g ? "card--selectable" : "",
17
- g && _ ? "card--selected" : "",
18
- v ?? ""
19
- ].filter(Boolean).join(" "), C = /* @__PURE__ */ s(a, { children: [
20
- u !== void 0 && /* @__PURE__ */ o(n, {
16
+ g ? "card--link-overlay" : "",
17
+ _ ? "card--selectable" : "",
18
+ _ && v ? "card--selected" : "",
19
+ y ?? ""
20
+ ].filter(Boolean).join(" "), w = /* @__PURE__ */ l(s, { children: [
21
+ o !== void 0 && /* @__PURE__ */ c(n, {
21
22
  level: 2,
22
23
  size: 8,
23
- children: u
24
+ children: o
24
25
  }),
25
- d && (typeof d == "string" ? /* @__PURE__ */ o("p", { children: d }) : d),
26
- y,
27
- f !== void 0 && /* @__PURE__ */ s(a, { children: [/* @__PURE__ */ o(e, { children: f }), /* @__PURE__ */ o(t, { size: "lg" })] })
28
- ] }), w = h && /* @__PURE__ */ o("div", {
26
+ d && (typeof d == "string" ? /* @__PURE__ */ c("p", { children: d }) : d),
27
+ b,
28
+ f !== void 0 && /* @__PURE__ */ l(s, { children: [/* @__PURE__ */ c(e, { children: f }), /* @__PURE__ */ c(t, { size: "lg" })] })
29
+ ] }), T = h && /* @__PURE__ */ c("div", {
29
30
  className: "card__media",
30
- children: /* @__PURE__ */ o("img", {
31
+ children: /* @__PURE__ */ c("img", {
31
32
  src: h.src,
32
33
  alt: h.alt
33
34
  })
34
- }), T = m === "default" && !h ? C : /* @__PURE__ */ s(a, { children: [w, /* @__PURE__ */ o("div", {
35
+ }), E = m === "default" && !h ? w : /* @__PURE__ */ l(s, { children: [T, /* @__PURE__ */ c("div", {
35
36
  className: "card__body",
36
- children: C
37
+ children: w
37
38
  })] });
38
- return c({
39
+ return u({
39
40
  render: i,
40
- ref: x,
41
+ ref: S,
41
42
  enabled: i !== void 0,
42
43
  props: {
43
- className: S,
44
- ...b,
45
- children: T
44
+ className: C,
45
+ ...x,
46
+ children: E
46
47
  }
47
- }) || (r === void 0 ? /* @__PURE__ */ o("div", {
48
- ref: x,
49
- className: S,
50
- ...b,
51
- children: y
52
- }) : /* @__PURE__ */ o("a", {
53
- ref: x,
48
+ }) || (r === void 0 ? /* @__PURE__ */ c("div", {
49
+ ref: S,
50
+ className: C,
51
+ ...x,
52
+ children: b
53
+ }) : /* @__PURE__ */ c("a", {
54
+ ref: S,
54
55
  href: r,
55
- className: S,
56
- ...l ? {
56
+ className: C,
57
+ ...a ? {
57
58
  target: "_blank",
58
59
  rel: "noopener noreferrer"
59
60
  } : {},
60
- ...b,
61
- children: T
61
+ ...x,
62
+ children: E
62
63
  }));
63
- }), u = i(function({ className: e, ...t }, n) {
64
- return /* @__PURE__ */ o("div", {
64
+ }), f = i(function({ className: e, ...t }, n) {
65
+ return /* @__PURE__ */ c("div", {
65
66
  ref: n,
66
67
  className: ["card__header", e].filter(Boolean).join(" "),
67
68
  ...t
68
69
  });
69
- }), d = i(function({ level: e = 3, size: t = 4, className: r, children: i, ...a }, s) {
70
- return /* @__PURE__ */ o(n, {
71
- ref: s,
70
+ }), p = i(function({ level: e = 3, size: t = 4, className: r, children: i, ...a }, o) {
71
+ return /* @__PURE__ */ c(n, {
72
+ ref: o,
72
73
  level: e,
73
74
  size: t,
74
75
  className: ["card__title", r].filter(Boolean).join(" "),
75
76
  ...a,
76
77
  children: i
77
78
  });
78
- }), f = i(function({ size: e = "small", lines: t, className: n, children: i, ...a }, s) {
79
- return /* @__PURE__ */ o(r, {
80
- ref: s,
79
+ }), m = i(function({ size: e = "small", lines: t, className: n, children: i, ...a }, o) {
80
+ return /* @__PURE__ */ c(r, {
81
+ ref: o,
81
82
  size: e,
82
83
  className: [
83
84
  "card__description",
@@ -87,20 +88,31 @@ var l = i(function({ href: r, render: i, external: l = !1, title: u, description
87
88
  ...a,
88
89
  children: i
89
90
  });
90
- }), p = i(function({ className: e, ...t }, n) {
91
- return /* @__PURE__ */ o("div", {
92
- ref: n,
93
- className: ["card__action", e].filter(Boolean).join(" "),
94
- ...t
91
+ }), h = i(function({ isolate: e = !0, className: t, onClick: n, ...r }, i) {
92
+ let s = o(null);
93
+ return /* @__PURE__ */ c("div", {
94
+ ref: a((e) => {
95
+ s.current = e, typeof i == "function" ? i(e) : i && (i.current = e);
96
+ }, [i]),
97
+ className: ["card__action", t].filter(Boolean).join(" "),
98
+ onClick: (t) => {
99
+ if (e) {
100
+ t.stopPropagation();
101
+ let e = s.current;
102
+ (e?.contains(t.target) ?? !1) && e?.parentElement?.closest("a[href], [role=\"link\"]") && t.preventDefault();
103
+ }
104
+ n?.(t);
105
+ },
106
+ ...r
95
107
  });
96
- }), m = i(function({ className: e, ...t }, n) {
97
- return /* @__PURE__ */ o("div", {
108
+ }), g = i(function({ className: e, ...t }, n) {
109
+ return /* @__PURE__ */ c("div", {
98
110
  ref: n,
99
111
  className: ["card__content", e].filter(Boolean).join(" "),
100
112
  ...t
101
113
  });
102
- }), h = i(function({ direction: e = "row", className: t, ...n }, r) {
103
- return /* @__PURE__ */ o("div", {
114
+ }), _ = i(function({ direction: e = "row", className: t, ...n }, r) {
115
+ return /* @__PURE__ */ c("div", {
104
116
  ref: r,
105
117
  className: [
106
118
  "card__footer",
@@ -111,4 +123,4 @@ var l = i(function({ href: r, render: i, external: l = !1, title: u, description
111
123
  });
112
124
  });
113
125
  //#endregion
114
- export { l as Card, p as CardAction, m as CardContent, f as CardDescription, h as CardFooter, u as CardHeader, d as CardTitle };
126
+ export { d as Card, h as CardAction, g as CardContent, m as CardDescription, _ as CardFooter, f as CardHeader, p as CardTitle };
package/dist/menu.css CHANGED
@@ -1 +1 @@
1
- @keyframes menu-open{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}@keyframes menu-close{0%{opacity:1;transform:scale(1)}to{opacity:0;transform:scale(.95)}}.menu__content{box-sizing:border-box;background-color:var(--menu-bg);border-width:var(--menu-border-width);border-style:solid;border-color:var(--menu-border-color);border-radius:var(--menu-border-radius);box-shadow:var(--menu-shadow);padding-block:var(--menu-padding-block);transform-origin:var(--transform-origin);max-height:var(--menu-content-max-height,var(--available-height));overscroll-behavior:contain;outline:none;padding-inline:0;overflow-y:auto}.menu__content[data-open]{animation:menu-open var(--menu-transition-duration) var(--menu-transition-easing)}.menu__content[data-closed]{animation:menu-close var(--menu-transition-duration) var(--menu-transition-easing)}.menu__item{align-items:center;gap:var(--menu-item-icon-gap);padding-block:var(--menu-item-padding-block);padding-inline:var(--menu-item-padding-inline);margin-inline:var(--menu-padding-inline);border-radius:var(--menu-item-border-radius);font-family:var(--menu-item-font-family);font-size:var(--menu-item-font-size);font-weight:var(--menu-item-font-weight);line-height:var(--menu-item-line-height);color:var(--menu-item-color);cursor:var(--menu-item-cursor);box-shadow:none;transition:background-color var(--menu-transition-duration) var(--menu-transition-easing), color var(--menu-transition-duration) var(--menu-transition-easing);outline:none;text-decoration:none;display:flex}.menu__item:focus-visible{outline:none}.menu__item[data-highlighted]{background-color:var(--menu-item-highlighted-bg);color:var(--menu-item-highlighted-color)}.menu__item:is(a):hover:not([data-highlighted]),.menu__item:is(a):focus-visible:not([data-highlighted]){color:var(--menu-item-color);box-shadow:none}.menu__item.menu__item--destructive:is(a):hover:not([data-highlighted]),.menu__item.menu__item--destructive:is(a):focus-visible:not([data-highlighted]){color:var(--menu-item-destructive-color)}.menu__item[data-disabled]{opacity:var(--menu-disabled-opacity);cursor:not-allowed;pointer-events:none}.menu__item.menu__item--destructive{color:var(--menu-item-destructive-color)}.menu__item.menu__item--destructive[data-highlighted]{background-color:var(--menu-item-destructive-highlighted-bg);color:var(--menu-item-destructive-highlighted-color)}.menu__item svg{width:var(--menu-item-icon-size);height:var(--menu-item-icon-size);flex-shrink:0}.menu__label{padding-block:var(--menu-label-padding-block);padding-inline:var(--menu-label-padding-inline);font-family:var(--menu-item-font-family);font-size:var(--menu-label-font-size);font-weight:var(--menu-label-font-weight);color:var(--menu-label-color)}.menu__item[data-checked]{font-weight:var(--menu-item-selected-font-weight)}.menu__separator{height:var(--menu-separator-height);background-color:var(--menu-separator-color);margin-block:var(--menu-separator-margin-block);border:none;margin-inline:0}.menu__positioner{z-index:var(--menu-z-index)}.menu__content--sm .menu__item{font-size:var(--menu-sm-item-font-size);padding-block:var(--menu-sm-item-padding-block)}.menu__content--sm .menu__item svg{width:var(--menu-sm-item-icon-size);height:var(--menu-sm-item-icon-size)}.menu__content--lg .menu__item{font-size:var(--menu-lg-item-font-size);padding-block:var(--menu-lg-item-padding-block)}.menu__content--lg .menu__item svg{width:var(--menu-lg-item-icon-size);height:var(--menu-lg-item-icon-size)}
1
+ @keyframes menu-open{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}@keyframes menu-close{0%{opacity:1;transform:scale(1)}to{opacity:0;transform:scale(.95)}}.menu__content{box-sizing:border-box;background-color:var(--menu-bg);border-width:var(--menu-border-width);border-style:solid;border-color:var(--menu-border-color);border-radius:var(--menu-border-radius);box-shadow:var(--menu-shadow);padding-block:var(--menu-padding-block);transform-origin:var(--transform-origin);max-height:var(--menu-content-max-height,var(--available-height));overscroll-behavior:contain;outline:none;padding-inline:0;overflow-y:auto}.menu__content[data-open]{animation:menu-open var(--menu-transition-duration) var(--menu-transition-easing)}.menu__content[data-closed]{animation:menu-close var(--menu-transition-duration) var(--menu-transition-easing)}.menu__item{align-items:center;gap:var(--menu-item-icon-gap);padding-block:var(--menu-item-padding-block);padding-inline:var(--menu-item-padding-inline);margin-inline:var(--menu-padding-inline);border-radius:var(--menu-item-border-radius);font-family:var(--menu-item-font-family);font-size:var(--menu-item-font-size);font-weight:var(--menu-item-font-weight);line-height:var(--menu-item-line-height);color:var(--menu-item-color);cursor:var(--menu-item-cursor);box-shadow:none;transition:background-color var(--menu-transition-duration) var(--menu-transition-easing), color var(--menu-transition-duration) var(--menu-transition-easing);outline:none;text-decoration:none;display:flex}.menu__item:focus-visible{outline:none}.menu__item[data-highlighted]{background-color:var(--menu-item-highlighted-bg);color:var(--menu-item-highlighted-color)}.menu__item:is(a):hover:not([data-highlighted]),.menu__item:is(a):focus-visible:not([data-highlighted]){color:var(--menu-item-color);box-shadow:none}.menu__item.menu__item--destructive:is(a):hover:not([data-highlighted]),.menu__item.menu__item--destructive:is(a):focus-visible:not([data-highlighted]){color:var(--menu-item-destructive-color)}.menu__item[data-disabled]{opacity:var(--menu-disabled-opacity);cursor:not-allowed;pointer-events:none}.menu__item.menu__item--destructive{color:var(--menu-item-destructive-color)}.menu__item.menu__item--destructive[data-highlighted]{background-color:var(--menu-item-destructive-highlighted-bg);color:var(--menu-item-destructive-highlighted-color)}.menu__item svg{width:var(--menu-item-icon-size);height:var(--menu-item-icon-size);flex-shrink:0}.menu__label{padding-block:var(--menu-label-padding-block);padding-inline:var(--menu-label-padding-inline);font-family:var(--menu-item-font-family);font-size:var(--menu-label-font-size);font-weight:var(--menu-label-font-weight);color:var(--menu-label-color)}.menu__item[data-checked]{font-weight:var(--menu-item-selected-font-weight)}.menu__separator{height:var(--menu-separator-height);background-color:var(--menu-separator-color);margin-block:var(--menu-separator-margin-block);border:none;margin-inline:0}.menu__positioner{z-index:var(--menu-z-index)}.menu__content--sm .menu__item{font-size:var(--menu-sm-item-font-size);padding-block:var(--menu-sm-item-padding-block)}.menu__content--sm .menu__item svg{width:var(--menu-sm-item-icon-size);height:var(--menu-sm-item-icon-size)}.menu__content--lg .menu__item{font-size:var(--menu-lg-item-font-size);padding-block:var(--menu-lg-item-padding-block)}.menu__content--lg .menu__item svg{width:var(--menu-lg-item-icon-size);height:var(--menu-lg-item-icon-size)}.menu__item-icon{flex-shrink:0}.menu__item-text{flex-direction:column;flex:1;min-width:0;display:flex}.menu__item-label,.menu__item-description{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.menu__item-description{font-size:var(--menu-label-font-size);color:var(--menu-label-color)}.menu__item[data-highlighted] .menu__item-description,.menu__item.menu__item--destructive .menu__item-description{color:inherit}
package/dist/menu.js CHANGED
@@ -42,6 +42,7 @@ function c({ trigger: c, items: l, value: u, onValueChange: d, renderLink: f = r
42
42
  itemClass: s,
43
43
  separatorClass: "menu__separator",
44
44
  labelClass: "menu__label",
45
+ blockClass: "menu",
45
46
  radioValue: u,
46
47
  onRadioValueChange: d,
47
48
  renderLink: f
package/dist/prose.js CHANGED
@@ -2,17 +2,23 @@ import './prose.css';
2
2
  import { forwardRef as e } from "react";
3
3
  import { jsx as t } from "react/jsx-runtime";
4
4
  //#region src/stories/molecules/Prose/Prose.tsx
5
- var n = e(function({ as: e = "div", size: n = "md", measure: r = !0, className: i, children: a, ...o }, s) {
6
- return /* @__PURE__ */ t(e, {
7
- ref: s,
8
- className: [
9
- "prose",
10
- n === "md" ? "" : `prose--${n}`,
11
- r ? "" : "prose--full",
12
- i ?? ""
13
- ].filter(Boolean).join(" "),
14
- ...o,
5
+ var n = e(function({ as: e = "div", size: n = "md", measure: r = !0, className: i, children: a, html: o, ...s }, c) {
6
+ let l = [
7
+ "prose",
8
+ n === "md" ? "" : `prose--${n}`,
9
+ r ? "" : "prose--full",
10
+ i ?? ""
11
+ ].filter(Boolean).join(" ");
12
+ return o === void 0 ? /* @__PURE__ */ t(e, {
13
+ ref: c,
14
+ className: l,
15
+ ...s,
15
16
  children: a
17
+ }) : /* @__PURE__ */ t(e, {
18
+ ref: c,
19
+ className: l,
20
+ ...s,
21
+ dangerouslySetInnerHTML: { __html: o }
16
22
  });
17
23
  });
18
24
  //#endregion
@@ -0,0 +1 @@
1
+ .sortable{transform:translate3d(var(--sortable-x,0px), var(--sortable-y,0px), 0) scale(var(--sortable-scale-x,1), var(--sortable-scale-y,1));transition:var(--sortable-transition,none)}.sortable[data-dragging]{opacity:var(--opacity-disabled)}@media (prefers-reduced-motion:reduce){.sortable{transition:none}}
@@ -0,0 +1,26 @@
1
+ 'use client';
2
+ import './sortable.css';
3
+ import { t as e } from "./_shared/css-properties.js";
4
+ import { forwardRef as t, useCallback as n } from "react";
5
+ import { jsx as r } from "react/jsx-runtime";
6
+ //#region src/stories/atoms/Sortable/Sortable.tsx
7
+ var i = t(function({ as: t = "div", transform: i, transition: a, dragging: o = !1, className: s, children: c, ...l }, u) {
8
+ let d = e({
9
+ "--sortable-x": i ? `${i.x}px` : void 0,
10
+ "--sortable-y": i ? `${i.y}px` : void 0,
11
+ "--sortable-scale-x": i?.scaleX === void 0 ? void 0 : String(i.scaleX),
12
+ "--sortable-scale-y": i?.scaleY === void 0 ? void 0 : String(i.scaleY),
13
+ "--sortable-transition": a ?? void 0
14
+ });
15
+ return /* @__PURE__ */ r(t, {
16
+ ref: n((e) => {
17
+ d(e), typeof u == "function" ? u(e) : u && (u.current = e);
18
+ }, [d, u]),
19
+ className: ["sortable", s].filter(Boolean).join(" "),
20
+ "data-dragging": o ? "" : void 0,
21
+ ...l,
22
+ children: c
23
+ });
24
+ });
25
+ //#endregion
26
+ export { i as Sortable };
package/dist/tooltip.css CHANGED
@@ -1 +1 @@
1
- .tooltip{box-sizing:border-box;max-width:var(--tooltip-max-width);padding-block:var(--tooltip-padding-block);padding-inline:var(--tooltip-padding-inline);border-radius:var(--tooltip-border-radius);background-color:var(--tooltip-bg);color:var(--tooltip-color);font-family:var(--tooltip-font-family);font-size:var(--tooltip-font-size);line-height:var(--tooltip-line-height);transform-origin:var(--transform-origin);animation-duration:var(--tooltip-transition-duration);animation-timing-function:var(--tooltip-transition-easing)}.tooltip[data-open]{animation-name:tooltip-in}.tooltip[data-closed]{animation-name:tooltip-out}.tooltip__arrow{fill:var(--tooltip-bg);line-height:0}.tooltip__arrow[data-side=top]{top:100%}.tooltip__arrow[data-side=bottom]{bottom:100%;rotate:180deg}.tooltip__arrow[data-side=left]{left:100%;translate:-25%;rotate:-90deg}.tooltip__arrow[data-side=right]{right:100%;translate:25%;rotate:90deg}@keyframes tooltip-in{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}@keyframes tooltip-out{0%{opacity:1;transform:scale(1)}to{opacity:0;transform:scale(.95)}}.tooltip__positioner{z-index:var(--tooltip-z-index)}
1
+ .tooltip{box-sizing:border-box;max-width:var(--tooltip-max-width);padding-block:var(--tooltip-padding-block);padding-inline:var(--tooltip-padding-inline);border-radius:var(--tooltip-border-radius);background-color:var(--tooltip-bg);color:var(--tooltip-color);font-family:var(--tooltip-font-family);font-size:var(--tooltip-font-size);line-height:var(--tooltip-line-height);transform-origin:var(--transform-origin);animation-duration:var(--tooltip-transition-duration);animation-timing-function:var(--tooltip-transition-easing)}.tooltip[data-open]{animation-name:tooltip-in}.tooltip[data-closed]{animation-name:tooltip-out}.tooltip__arrow{fill:var(--tooltip-bg);line-height:0}.tooltip__arrow[data-side=top]{top:100%}.tooltip__arrow[data-side=bottom]{bottom:100%;rotate:180deg}.tooltip__arrow[data-side=left]{left:100%;translate:-25%;rotate:-90deg}.tooltip__arrow[data-side=right]{right:100%;translate:25%;rotate:90deg}@keyframes tooltip-in{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}@keyframes tooltip-out{0%{opacity:1;transform:scale(1)}to{opacity:0;transform:scale(.95)}}.tooltip__positioner{z-index:var(--tooltip-z-index)}.tooltip__trigger{display:inline-flex}.tooltip__trigger:focus-visible{outline:var(--border-width-focus) solid currentColor;outline-offset:var(--spacing-1)}.tooltip__trigger>:disabled,.tooltip__trigger>[aria-disabled=true]{pointer-events:none}
package/dist/tooltip.js CHANGED
@@ -20,31 +20,35 @@ function l() {
20
20
  let e = document.documentElement;
21
21
  return c(getComputedStyle(e).getPropertyValue("--tooltip-offset").trim(), e);
22
22
  }
23
- var u = t(function({ label: t, children: s, side: c = "top", align: u = "center", sideOffset: d, open: f, defaultOpen: p, onOpenChange: m, delayDuration: h, describe: g = !0, container: _, className: v, ...y }, b) {
24
- let x = e(_), S = n(), [C, w] = r(p ?? !1), T = f ?? C;
23
+ var u = t(function({ label: t, children: s, side: c = "top", align: u = "center", sideOffset: d, open: f, defaultOpen: p, onOpenChange: m, delayDuration: h, describe: g = !0, disabledTrigger: _ = !1, container: v, className: y, ...b }, x) {
24
+ let S = e(v), C = n(), [w, T] = r(p ?? !1), E = f ?? w;
25
25
  return /* @__PURE__ */ a(o.Root, {
26
26
  open: f,
27
27
  defaultOpen: p,
28
28
  onOpenChange: (e) => {
29
- f === void 0 && w(e), m?.(e);
29
+ f === void 0 && T(e), m?.(e);
30
30
  },
31
31
  children: [/* @__PURE__ */ i(o.Trigger, {
32
- ref: b,
33
- render: s,
34
- "aria-describedby": T && g ? S : void 0,
32
+ ref: x,
33
+ render: _ ? /* @__PURE__ */ i("span", {
34
+ className: "tooltip__trigger",
35
+ tabIndex: 0,
36
+ children: s
37
+ }) : s,
38
+ "aria-describedby": E && g ? C : void 0,
35
39
  ...h === void 0 ? {} : { delay: h },
36
- ...y
40
+ ...b
37
41
  }), /* @__PURE__ */ i(o.Portal, {
38
- container: x,
42
+ container: S,
39
43
  children: /* @__PURE__ */ i(o.Positioner, {
40
44
  className: "tooltip__positioner",
41
45
  side: c,
42
46
  align: u,
43
47
  sideOffset: d ?? l,
44
48
  children: /* @__PURE__ */ a(o.Popup, {
45
- id: S,
49
+ id: C,
46
50
  role: "tooltip",
47
- className: ["tooltip", v].filter(Boolean).join(" "),
51
+ className: ["tooltip", y].filter(Boolean).join(" "),
48
52
  children: [t, /* @__PURE__ */ i(o.Arrow, {
49
53
  className: "tooltip__arrow",
50
54
  children: /* @__PURE__ */ i("svg", {
@@ -1 +1 @@
1
- .user-menu__trigger{all:unset;box-sizing:border-box;align-items:center;gap:var(--user-menu-trigger-gap);width:100%;padding-block:var(--user-menu-trigger-padding-block);padding-inline:var(--user-menu-trigger-padding-inline);border-radius:var(--user-menu-trigger-border-radius);cursor:pointer;display:flex}.user-menu__trigger.user-menu__trigger--compact{width:auto;padding-inline:var(--user-menu-trigger-compact-padding-inline)}.user-menu__trigger:focus-visible{outline:var(--user-menu-focus-ring-width) solid var(--user-menu-focus-ring-color);outline-offset:var(--user-menu-focus-ring-offset)}.user-menu__avatar-wrap{flex-shrink:0;position:relative}.user-menu__notification-badge{position:absolute;inset-block-start:calc(-1 * var(--user-menu-badge-offset));inset-inline-end:calc(-1 * var(--user-menu-badge-offset))}.user-menu__name{text-overflow:ellipsis;white-space:nowrap;min-width:0;font-size:var(--user-menu-name-font-size);font-weight:var(--user-menu-name-font-weight);color:var(--user-menu-name-color);flex:1;overflow:hidden}.user-menu__chevron{transition:transform var(--user-menu-transition-duration) var(--user-menu-transition-easing);flex-shrink:0;transform:rotate(90deg)}.user-menu__trigger[data-popup-open] .user-menu__chevron{transform:rotate(-90deg)}@keyframes user-menu-open{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}@keyframes user-menu-close{0%{opacity:1;transform:scale(1)}to{opacity:0;transform:scale(.95)}}.user-menu__content{box-sizing:border-box;background-color:var(--user-menu-content-bg);border-width:var(--user-menu-content-border-width);border-style:solid;border-color:var(--user-menu-content-border-color);border-radius:var(--user-menu-content-border-radius);box-shadow:var(--user-menu-content-shadow);padding-block:var(--user-menu-content-padding-block);padding-inline:var(--user-menu-content-padding-inline);min-width:var(--user-menu-content-min-width);transform-origin:var(--transform-origin);max-height:var(--user-menu-content-max-height,var(--available-height));overscroll-behavior:contain;outline:none;overflow-y:auto}.user-menu__content[data-open]{animation:user-menu-open var(--user-menu-transition-duration) var(--user-menu-transition-easing)}.user-menu__content[data-closed]{animation:user-menu-close var(--user-menu-transition-duration) var(--user-menu-transition-easing)}.user-menu__header{gap:var(--user-menu-header-gap);padding-block:var(--user-menu-header-padding-block);padding-inline:var(--user-menu-header-padding-inline);flex-direction:column;display:flex}.user-menu__header-name{font-size:var(--user-menu-header-name-font-size);font-weight:var(--user-menu-header-name-font-weight);color:var(--user-menu-header-name-color);text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.user-menu__header-email{font-size:var(--user-menu-header-email-font-size);color:var(--user-menu-header-email-color);text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.user-menu__item{align-items:center;gap:var(--user-menu-item-icon-gap);padding-block:var(--user-menu-item-padding-block);padding-inline:var(--user-menu-item-padding-inline);border-radius:var(--user-menu-item-border-radius);font-family:var(--user-menu-item-font-family);font-size:var(--user-menu-item-font-size);font-weight:var(--user-menu-item-font-weight);color:var(--user-menu-item-color);cursor:pointer;box-shadow:none;transition:background-color var(--user-menu-transition-duration) var(--user-menu-transition-easing), color var(--user-menu-transition-duration) var(--user-menu-transition-easing);outline:none;text-decoration:none;display:flex}.user-menu__item[data-highlighted]{background-color:var(--user-menu-item-highlighted-bg);color:var(--user-menu-item-highlighted-color)}.user-menu__item[data-disabled]{opacity:var(--user-menu-disabled-opacity);cursor:not-allowed;pointer-events:none}.user-menu__item.user-menu__item--destructive{color:var(--user-menu-item-destructive-color)}.user-menu__item.user-menu__item--destructive[data-highlighted]{background-color:var(--user-menu-item-destructive-highlighted-bg);color:var(--user-menu-item-destructive-highlighted-color)}.user-menu__separator{height:var(--user-menu-separator-height);background-color:var(--user-menu-separator-color);margin-block:var(--user-menu-separator-margin-block);border:none}.user-menu__positioner{z-index:var(--user-menu-content-z-index)}
1
+ .user-menu__trigger{all:unset;box-sizing:border-box;align-items:center;gap:var(--user-menu-trigger-gap);width:100%;padding-block:var(--user-menu-trigger-padding-block);padding-inline:var(--user-menu-trigger-padding-inline);border-radius:var(--user-menu-trigger-border-radius);cursor:pointer;display:flex}.user-menu__trigger.user-menu__trigger--compact{width:auto;padding-inline:var(--user-menu-trigger-compact-padding-inline)}.user-menu__trigger:focus-visible{outline:var(--user-menu-focus-ring-width) solid var(--user-menu-focus-ring-color);outline-offset:var(--user-menu-focus-ring-offset)}.user-menu__avatar-wrap{flex-shrink:0;position:relative}.user-menu__notification-badge{position:absolute;inset-block-start:calc(-1 * var(--user-menu-badge-offset));inset-inline-end:calc(-1 * var(--user-menu-badge-offset))}.user-menu__name{text-overflow:ellipsis;white-space:nowrap;min-width:0;font-size:var(--user-menu-name-font-size);font-weight:var(--user-menu-name-font-weight);color:var(--user-menu-name-color);flex:1;overflow:hidden}.user-menu__chevron{transition:transform var(--user-menu-transition-duration) var(--user-menu-transition-easing);flex-shrink:0;transform:rotate(90deg)}.user-menu__trigger[data-popup-open] .user-menu__chevron{transform:rotate(-90deg)}@keyframes user-menu-open{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}@keyframes user-menu-close{0%{opacity:1;transform:scale(1)}to{opacity:0;transform:scale(.95)}}.user-menu__content{box-sizing:border-box;background-color:var(--user-menu-content-bg);border-width:var(--user-menu-content-border-width);border-style:solid;border-color:var(--user-menu-content-border-color);border-radius:var(--user-menu-content-border-radius);box-shadow:var(--user-menu-content-shadow);padding-block:var(--user-menu-content-padding-block);padding-inline:var(--user-menu-content-padding-inline);min-width:var(--user-menu-content-min-width);transform-origin:var(--transform-origin);max-height:var(--user-menu-content-max-height,var(--available-height));overscroll-behavior:contain;outline:none;overflow-y:auto}.user-menu__content[data-open]{animation:user-menu-open var(--user-menu-transition-duration) var(--user-menu-transition-easing)}.user-menu__content[data-closed]{animation:user-menu-close var(--user-menu-transition-duration) var(--user-menu-transition-easing)}.user-menu__header{align-items:center;gap:var(--user-menu-trigger-gap);padding-block:var(--user-menu-header-padding-block);padding-inline:var(--user-menu-header-padding-inline);display:flex}.user-menu__header-text{gap:var(--user-menu-header-gap);flex-direction:column;min-width:0;display:flex}.user-menu__header-name{font-size:var(--user-menu-header-name-font-size);font-weight:var(--user-menu-header-name-font-weight);color:var(--user-menu-header-name-color);text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.user-menu__header-email{font-size:var(--user-menu-header-email-font-size);color:var(--user-menu-header-email-color);text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.user-menu__item{align-items:center;gap:var(--user-menu-item-icon-gap);padding-block:var(--user-menu-item-padding-block);padding-inline:var(--user-menu-item-padding-inline);border-radius:var(--user-menu-item-border-radius);font-family:var(--user-menu-item-font-family);font-size:var(--user-menu-item-font-size);font-weight:var(--user-menu-item-font-weight);color:var(--user-menu-item-color);cursor:pointer;box-shadow:none;transition:background-color var(--user-menu-transition-duration) var(--user-menu-transition-easing), color var(--user-menu-transition-duration) var(--user-menu-transition-easing);outline:none;text-decoration:none;display:flex}.user-menu__item[data-highlighted]{background-color:var(--user-menu-item-highlighted-bg);color:var(--user-menu-item-highlighted-color)}.user-menu__item[data-disabled]{opacity:var(--user-menu-disabled-opacity);cursor:not-allowed;pointer-events:none}.user-menu__item.user-menu__item--destructive{color:var(--user-menu-item-destructive-color)}.user-menu__item.user-menu__item--destructive[data-highlighted]{background-color:var(--user-menu-item-destructive-highlighted-bg);color:var(--user-menu-item-destructive-highlighted-color)}.user-menu__separator{height:var(--user-menu-separator-height);background-color:var(--user-menu-separator-color);margin-block:var(--user-menu-separator-margin-block);border:none}.user-menu__positioner{z-index:var(--user-menu-content-z-index)}.user-menu__item-icon{flex-shrink:0}.user-menu__item-text{flex-direction:column;flex:1;min-width:0;display:flex}.user-menu__item-label,.user-menu__item-description{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.user-menu__item-description{font-size:var(--user-menu-header-email-font-size);color:var(--user-menu-header-email-color)}.user-menu__item[data-highlighted] .user-menu__item-description,.user-menu__item.user-menu__item--destructive .user-menu__item-description{color:inherit}
package/dist/user-menu.js CHANGED
@@ -69,17 +69,27 @@ function m({ name: u, email: m, avatarUrl: h, notificationCount: g, items: _ = [
69
69
  className: "user-menu__content",
70
70
  children: [/* @__PURE__ */ c("div", {
71
71
  className: "user-menu__header",
72
- children: [/* @__PURE__ */ s("span", {
73
- className: "user-menu__header-name",
74
- children: u
75
- }), /* @__PURE__ */ s("span", {
76
- className: "user-menu__header-email",
77
- children: m
72
+ children: [/* @__PURE__ */ s(r, {
73
+ src: h,
74
+ name: u,
75
+ alt: "",
76
+ size: "md",
77
+ className: "user-menu__header-avatar"
78
+ }), /* @__PURE__ */ c("div", {
79
+ className: "user-menu__header-text",
80
+ children: [/* @__PURE__ */ s("span", {
81
+ className: "user-menu__header-name",
82
+ children: u
83
+ }), /* @__PURE__ */ s("span", {
84
+ className: "user-menu__header-email",
85
+ children: m
86
+ })]
78
87
  })]
79
88
  }), _.length > 0 && /* @__PURE__ */ c(o, { children: [/* @__PURE__ */ s(l.Separator, { className: "user-menu__separator" }), a({
80
89
  items: _,
81
90
  itemClass: p,
82
91
  separatorClass: "user-menu__separator",
92
+ blockClass: "user-menu",
83
93
  renderLink: b
84
94
  })] })]
85
95
  })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@studiolxd/brand",
3
- "version": "49.3.1",
3
+ "version": "49.5.0",
4
4
  "description": "El sistema de diseño de Studio LXD: componentes React, tokens y documentación de la suite SLXD.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -574,6 +574,10 @@
574
574
  "types": "./dist/_types/atoms/Sparkline/Sparkline.d.ts",
575
575
  "import": "./dist/sparkline.js"
576
576
  },
577
+ "./sortable": {
578
+ "types": "./dist/_types/atoms/Sortable/Sortable.d.ts",
579
+ "import": "./dist/sortable.js"
580
+ },
577
581
  "./spinner": {
578
582
  "types": "./dist/_types/atoms/Spinner/Spinner.d.ts",
579
583
  "import": "./dist/spinner.js"