@studiolxd/brand 45.1.0 → 47.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/CHANGELOG.md +168 -0
  2. package/dist/_shared/portal-container.js +9 -0
  3. package/dist/_types/atoms/AsyncMultiSelect/AsyncMultiSelect.d.ts +8 -7
  4. package/dist/_types/atoms/AsyncSelect/AsyncSelect.d.ts +8 -6
  5. package/dist/_types/atoms/InputPhone/InputPhone.d.ts +8 -5
  6. package/dist/_types/atoms/MenuButton/MenuButton.d.ts +22 -2
  7. package/dist/_types/atoms/MultiSelect/MultiSelect.d.ts +8 -6
  8. package/dist/_types/atoms/Popover/Popover.d.ts +8 -1
  9. package/dist/_types/atoms/Select/Select.d.ts +8 -7
  10. package/dist/_types/atoms/Tooltip/Tooltip.d.ts +7 -0
  11. package/dist/_types/constants/portal-container.d.ts +42 -0
  12. package/dist/_types/messages/BrandMessages.d.ts +41 -1
  13. package/dist/_types/messages/index.d.ts +1 -1
  14. package/dist/_types/molecules/AppLauncher/AppLauncher.d.ts +43 -8
  15. package/dist/_types/molecules/Breadcrumb/Breadcrumb.d.ts +10 -2
  16. package/dist/_types/molecules/CommandPalette/CommandPalette.d.ts +43 -8
  17. package/dist/_types/molecules/Consent/Consent.d.ts +93 -20
  18. package/dist/_types/molecules/Menu/Menu.d.ts +8 -1
  19. package/dist/_types/molecules/Modal/Modal.d.ts +8 -6
  20. package/dist/_types/molecules/NotificationButton/NotificationButton.d.ts +17 -4
  21. package/dist/_types/molecules/NotificationPanel/NotificationPanel.d.ts +54 -8
  22. package/dist/_types/molecules/OrgSwitcher/OrgSwitcher.d.ts +15 -1
  23. package/dist/_types/molecules/PrevNextNav/PrevNextNav.d.ts +17 -2
  24. package/dist/_types/molecules/Sheet/Sheet.d.ts +8 -7
  25. package/dist/_types/molecules/SidebarNav/SidebarNav.d.ts +18 -3
  26. package/dist/_types/molecules/SiteNav/SiteNav.d.ts +9 -0
  27. package/dist/_types/molecules/TableOfContents/TableOfContents.d.ts +11 -2
  28. package/dist/_types/molecules/UserMenu/UserMenu.d.ts +16 -1
  29. package/dist/_types/sections/AppHeader/AppHeader.d.ts +8 -2
  30. package/dist/_types/sections/AppRoot/AppRoot.d.ts +12 -1
  31. package/dist/_types/sections/AppShell/AppShell.d.ts +14 -1
  32. package/dist/_types/sections/FloatingDock/FloatingDock.d.ts +33 -3
  33. package/dist/_types/sections/Sidebar/Sidebar.d.ts +27 -3
  34. package/dist/_types/sections/SiteHeader/SiteHeader.d.ts +22 -3
  35. package/dist/_types/sections/SiteShell/SiteShell.d.ts +11 -5
  36. package/dist/_types/templates/OnboardingShell/OnboardingShell.d.ts +19 -2
  37. package/dist/_types/templates/PublicPageShell/PublicPageShell.d.ts +42 -6
  38. package/dist/app-header.js +1 -1
  39. package/dist/app-launcher.js +73 -63
  40. package/dist/app-root.js +10 -8
  41. package/dist/app-shell.js +51 -50
  42. package/dist/async-multi-select.js +65 -64
  43. package/dist/async-select.js +49 -48
  44. package/dist/breadcrumb.js +24 -21
  45. package/dist/command-palette.js +38 -36
  46. package/dist/consent.js +75 -73
  47. package/dist/floating-dock.js +42 -41
  48. package/dist/input-phone.js +38 -37
  49. package/dist/menu-button.js +16 -14
  50. package/dist/menu.js +44 -40
  51. package/dist/modal.js +32 -31
  52. package/dist/multi-select.js +106 -105
  53. package/dist/notification-button.js +18 -17
  54. package/dist/notification-panel.js +81 -80
  55. package/dist/onboarding-shell.js +36 -35
  56. package/dist/org-switcher.js +64 -59
  57. package/dist/popover.js +27 -22
  58. package/dist/prev-next-nav.js +38 -36
  59. package/dist/public-page-shell.js +24 -20
  60. package/dist/select.js +70 -69
  61. package/dist/sheet.js +30 -29
  62. package/dist/sidebar-nav.js +91 -90
  63. package/dist/sidebar.js +72 -71
  64. package/dist/site-header.js +44 -43
  65. package/dist/site-nav.js +27 -25
  66. package/dist/site-shell.js +23 -15
  67. package/dist/table-of-contents.js +30 -27
  68. package/dist/toaster.js +57 -53
  69. package/dist/tooltip.js +45 -41
  70. package/dist/user-menu.js +58 -52
  71. package/package.json +1 -1
@@ -1,5 +1,29 @@
1
1
  import { type ReactNode } from 'react';
2
2
  import './FloatingDock.css';
3
+ /**
4
+ * El cromo del dock, y **solo el cromo**: el aspa y cómo se lee el contador.
5
+ *
6
+ * **Tiene espacio propio y no hereda `modal.close`, a propósito.** El panel del
7
+ * dock no es un `Modal` y no puede serlo: es un diálogo **no modal**
8
+ * (`modal={false}`) sin velo, que no atrapa el foco y deja la página viva
9
+ * detrás, montado por portal **dentro del propio ancla** para heredar por
10
+ * cascada la superficie donde el consumidor lo haya puesto, anclado a una
11
+ * esquina de la ventana y con el aspa fuera de la cabecera. El `Modal` del
12
+ * sistema es lo contrario en las cuatro cosas —velo, foco atrapado, portal en
13
+ * `document.body`, diálogo centrado—, así que hacerlo pasar por él no era
14
+ * quitar una clave: era cambiar el componente. La razón es real y de hoy, no
15
+ * histórica, y por eso el aspa se llama aquí.
16
+ *
17
+ * El `label` del lanzador **no está aquí**: nombra lo que abre el dock —«Abrir
18
+ * el asistente», «Abrir el chat de soporte»— y eso lo sabe el producto. Sigue
19
+ * siendo prop obligatoria.
20
+ */
21
+ export interface FloatingDockMessages {
22
+ /** Nombre accesible del aspa que cierra el panel. */
23
+ close: string;
24
+ /** Cómo se lee el contador de novedades. Interpola el número. */
25
+ badge: (count: number) => string;
26
+ }
3
27
  /** Esquina de la ventana a la que se ancla el dock. */
4
28
  export type FloatingDockPosition = 'bottom-end' | 'bottom-start' | 'top-end' | 'top-start';
5
29
  export interface FloatingDockProps extends Omit<React.ComponentPropsWithoutRef<'div'>, 'title' | 'children'> {
@@ -26,15 +50,21 @@ export interface FloatingDockProps extends Omit<React.ComponentPropsWithoutRef<'
26
50
  defaultOpen?: boolean;
27
51
  /** Se llama al abrirse y al cerrarse, en controlado y en no controlado. */
28
52
  onOpenChange?: (open: boolean) => void;
29
- /** `aria-label` del aspa. Default: «Cerrar» (castellano). */
53
+ /**
54
+ * `aria-label` del aspa. **Sin default**: sin él, sale de
55
+ * `floatingDock.close` del `BrandMessagesProvider` — espacio propio, no
56
+ * `modal.close`: el panel del dock no es un `Modal` (ver
57
+ * `FloatingDockMessages`).
58
+ */
30
59
  closeLabel?: string;
31
60
  /** Novedades sin ver. Con 0 (o sin él) no hay contador. */
32
61
  badge?: number;
33
62
  /** Tope del contador («99+»). */
34
63
  badgeMax?: number;
35
64
  /**
36
- * Cómo se lee el contador. Default: «N mensajes nuevos» (castellano).
37
- * Interpola el número, así que es una función.
65
+ * Cómo se lee el contador. **Sin default**: sin ella, sale de
66
+ * `floatingDock.badge` del proveedor. Interpola el número, así que es una
67
+ * función. Solo se lee cuando hay contador y `badgeLive`.
38
68
  */
39
69
  badgeLabel?: (count: number) => string;
40
70
  /**
@@ -1,6 +1,20 @@
1
1
  import { type ReactNode } from 'react';
2
2
  import './Sidebar.css';
3
3
  export { useSidebar } from './SidebarContext';
4
+ /**
5
+ * Lo que la barra dice por su cuenta, y todo es **cromo**: su nombre de región,
6
+ * el nombre del asa que la ensancha y cómo se lee su ancho. Ninguno depende de
7
+ * qué haya dentro —eso lo escribe el producto en `children`—, así que los tres
8
+ * van al catálogo.
9
+ */
10
+ export interface SidebarMessages {
11
+ /** Nombre accesible del `aside`. */
12
+ label: string;
13
+ /** Nombre accesible del asa de redimensión. */
14
+ resizer: string;
15
+ /** Valor hablado del asa: el ancho con su unidad. */
16
+ resizerValue: (width: number) => string;
17
+ }
4
18
  export interface SidebarProps {
5
19
  /** Arriba del todo (un `Logo`). */
6
20
  logo?: ReactNode;
@@ -9,11 +23,21 @@ export interface SidebarProps {
9
23
  /** Pie fijo, fuera del scroll del panel. */
10
24
  footer?: ReactNode;
11
25
  id?: string;
12
- /** Nombre accesible del `aside`. Default: «Barra lateral» (castellano). Una app multiidioma debe pasarlo traducido. */
26
+ /**
27
+ * Nombre accesible del `aside`. **Sin default**: sin él, sale de
28
+ * `sidebar.label` del `BrandMessagesProvider`.
29
+ */
13
30
  label?: string;
14
- /** Texto accesible del asa de redimensión. Default: «Ancho de la barra lateral» (castellano). Una app multiidioma debe pasarlo traducido. */
31
+ /**
32
+ * Nombre accesible del asa de redimensión. **Sin default**: sale de
33
+ * `sidebar.resizer`. Solo se lee cuando el asa existe (escritorio, dentro de
34
+ * un `AppShell`, con la barra no cerrada).
35
+ */
15
36
  resizerLabel?: string;
16
- /** Valor hablado del asa: el ancho con su unidad. Default: «N píxeles» (castellano). Una app multiidioma debe pasarlo traducido. */
37
+ /**
38
+ * Valor hablado del asa: el ancho con su unidad. **Sin default**: sale de
39
+ * `sidebar.resizerValue`. Interpola el ancho, así que es una función.
40
+ */
17
41
  resizerValueText?: (width: number) => string;
18
42
  /** Fuerza el modo sin `AppShell` (Storybook, pruebas). Con shell, lo decide el shell. */
19
43
  mode?: 'open' | 'rail';
@@ -11,11 +11,20 @@ export type SiteHeaderLogoLinkProps = {
11
11
  export interface SiteHeaderProps {
12
12
  /** Destino del logotipo. */
13
13
  logoHref?: string;
14
- /** Texto accesible del enlace del logotipo. */
14
+ /**
15
+ * Texto accesible del enlace del logotipo. **Sin default**: sin él, sale de
16
+ * `siteHeader.logo` del `BrandMessagesProvider`.
17
+ */
15
18
  logoLabel?: string;
16
- /** aria-label del botón de menú. */
19
+ /**
20
+ * aria-label del botón de menú. **Reenvío puro** al `MenuButton`: sin él, el
21
+ * botón lee `menuButton.open`.
22
+ */
17
23
  menuLabel?: string;
18
- /** aria-label del botón de menú cuando está abierto («Cerrar menú»). */
24
+ /**
25
+ * aria-label del botón de menú abierto. **Reenvío puro** al `MenuButton`:
26
+ * sin él, lee `menuButton.close`.
27
+ */
19
28
  menuCloseLabel?: string;
20
29
  /** La marca. Por defecto el `Logo` de Studio LXD a `logoSize`; un producto de la suite pone la suya. */
21
30
  logo?: ReactNode;
@@ -55,4 +64,14 @@ export interface SiteHeaderProps {
55
64
  * El enlace de salto al contenido no va aquí: lo pone `AppRoot`, una vez por
56
65
  * documento.
57
66
  */
67
+ /**
68
+ * El único texto propio de la cabecera, y es **cromo**: qué hace el logotipo
69
+ * («ir al inicio»), no qué marca es. Lo que dice el botón de menú no se repite
70
+ * aquí —es un reenvío puro al `MenuButton`—, y los enlaces de `actions` y del
71
+ * panel son **contenido** del producto.
72
+ */
73
+ export interface SiteHeaderMessages {
74
+ /** Texto accesible del enlace del logotipo. */
75
+ logo: string;
76
+ }
58
77
  export declare function SiteHeader({ logoHref, logoLabel, menuLabel, menuCloseLabel, logoSize, logo, menuButtonSize, renderLogoLink, width, open, onOpenChange, children, settings, panelId, actions, language, }: SiteHeaderProps): import("react/jsx-runtime").JSX.Element;
@@ -17,10 +17,16 @@ export interface SiteShellProps {
17
17
  * Para las aplicaciones con barra y sidebar está `AppShell`.
18
18
  */
19
19
  /**
20
- * Reenvía el `ref` al nodo raíz (`.site-shell`): un `Modal`/`Sheet` abierto
21
- * desde dentro necesita apuntar su `container` aquí para heredar los tokens
22
- * de la superficie pública — el portal por defecto monta en `document.body`,
23
- * que no es descendiente de `.site-shell` (a diferencia del tema oscuro, que
24
- * se activa en `<html>` y sí llega a cualquier portal sin configuración).
20
+ * **Los portales que se abran dentro heredan la superficie.** El shell publica
21
+ * su nodo raíz por `PortalContainerContext`, y todo componente con portal
22
+ * —`Select`, `MultiSelect`, `DatePicker`, `Popover`, `Tooltip`, `Menu`,
23
+ * `Modal`, `Sheet`, `Toaster`…— lo toma como destino cuando no recibe
24
+ * `container`. Sin eso, la lista de un `Select` montaba en `document.body`,
25
+ * fuera de `.site-shell`, y se abría a la talla de aplicación mientras su
26
+ * campo iba a la pública. No hay nada que pasar en cada uso; la prop
27
+ * `container` sigue ahí para quien quiera otro destino y gana siempre.
28
+ *
29
+ * Reenvía además el `ref` al nodo raíz (`.site-shell`), para quien necesite
30
+ * apuntar ahí a mano.
25
31
  */
26
32
  export declare const SiteShell: import("react").ForwardRefExoticComponent<SiteShellProps & import("react").RefAttributes<HTMLDivElement>>;
@@ -29,7 +29,10 @@ export interface OnboardingShellProps {
29
29
  * @deprecated Usa `preferences`.
30
30
  */
31
31
  switchers?: ReactNode;
32
- /** Nombre accesible de la banda de preferencias. Default: «Preferencias» (castellano). */
32
+ /**
33
+ * Nombre accesible de la banda de preferencias. **Reenvío puro** al
34
+ * `PublicPageShell`: sin él, la banda lee `publicPageShell.preferences`.
35
+ */
33
36
  preferencesLabel?: string;
34
37
  /**
35
38
  * El progreso: un `Stepper`. La ranura se monta siempre; es el `Stepper`
@@ -47,7 +50,11 @@ export interface OnboardingShellProps {
47
50
  * escritorio, y debajo y centrada en móvil.
48
51
  */
49
52
  exitAction?: ReactNode;
50
- /** Nombre accesible del grupo de acciones del pie. Default: «Acciones del paso» (castellano). */
53
+ /**
54
+ * Nombre accesible del grupo de acciones del pie. **Sin default**: sin él,
55
+ * sale de `onboardingShell.actions` del `BrandMessagesProvider`. Solo se lee
56
+ * cuando el paso trae alguna acción.
57
+ */
51
58
  actionsLabel?: string;
52
59
  /** `id` del `main` (`main-content` por defecto, destino del `SkipLink`). */
53
60
  id?: string;
@@ -101,4 +108,14 @@ export interface OnboardingShellProps {
101
108
  * dentro —un `Form`, un campo suelto, un `AvatarUpload`— sale a la talla que
102
109
  * le toca sin que la aplicación tenga que acordarse de pedirla.
103
110
  */
111
+ /**
112
+ * El único texto propio de la plantilla, y es **cromo**: el nombre del grupo de
113
+ * acciones del pie. Lo que digan los botones —«Continuar», «Atrás», «Omitir por
114
+ * ahora»— es **contenido** y viene en las ranuras. El nombre de la banda de
115
+ * preferencias tampoco está aquí: es un reenvío puro al `PublicPageShell`.
116
+ */
117
+ export interface OnboardingShellMessages {
118
+ /** Nombre accesible del grupo de acciones del pie. */
119
+ actions: string;
120
+ }
104
121
  export declare function OnboardingShell({ children, brand, preferences, switchers, preferencesLabel, stepper, primaryAction, backAction, exitAction, actionsLabel, id, shell, width, className, }: OnboardingShellProps): import("react/jsx-runtime").JSX.Element;
@@ -1,4 +1,5 @@
1
1
  import { type ReactNode } from 'react';
2
+ import { type ContainerSpace, type ContainerWidth } from '../../atoms/Container/Container';
2
3
  import './PublicPageShell.css';
3
4
  export interface PublicPageShellProps {
4
5
  /** El contenido de la página: lo que va dentro del `main`. */
@@ -19,8 +20,31 @@ export interface PublicPageShellProps {
19
20
  * pie, igual que `header` y `footer`.
20
21
  */
21
22
  preferences?: ReactNode;
22
- /** Nombre accesible de la banda de preferencias. Default: «Preferencias» (castellano). */
23
+ /**
24
+ * Nombre accesible de la banda de preferencias. **Sin default**: sin él,
25
+ * sale de `publicPageShell.preferences` del `BrandMessagesProvider`. Solo se
26
+ * lee cuando hay banda.
27
+ */
23
28
  preferencesLabel?: string;
29
+ /**
30
+ * Medida del contenido del `main`, tal cual la de `Container`. Por defecto
31
+ * `'xl'` (1280px), el ancho de las páginas públicas; `'full'` para que el
32
+ * contenido llegue tan lejos como la banda, que es lo que necesita una
33
+ * portada que abre con un `Hero` de lado a lado.
34
+ */
35
+ mainWidth?: ContainerWidth;
36
+ /**
37
+ * Aire vertical del `main`. Por defecto `'xl'`, el de una página pública
38
+ * corriente; `'none'` cuando lo que va dentro son secciones que ya traen su
39
+ * propio aire (ver `Container` § «Las secciones traen su aire»).
40
+ */
41
+ mainSpace?: ContainerSpace;
42
+ /**
43
+ * Quita el aire lateral del `main`, para contenido que debe tocar el borde
44
+ * de la pantalla. Por defecto `false`. Va con `mainWidth="full"`: sin él, el
45
+ * contenido seguiría acotado y solo se perdería el margen.
46
+ */
47
+ mainFlush?: boolean;
24
48
  /** `id` del `main` (`main-content` por defecto, destino del `SkipLink`). */
25
49
  id?: string;
26
50
  /**
@@ -50,10 +74,22 @@ export interface PublicPageShellProps {
50
74
  * flotante abierto desde la página —`ConsentPreferences`, un `Modal`, un
51
75
  * `Sheet`—: su portal monta por defecto en `document.body`, que no es
52
76
  * descendiente de `.site-shell` y por tanto no hereda el remapeo de superficie
53
- * pública. Apuntarlo al `main` no serviría: el `main` es un `Container`
54
- * acotado y con su aire, así que el panel quedaría metido dentro de la columna
55
- * de contenido en vez de flotar sobre la página. Con `shell={false}` no hay
56
- * marco y el `ref` se queda sin asignar: ahí el contenedor es el `AppShell` de
57
- * la app.
77
+ * pública. Apuntarlo al `main` no serviría: el `main` es un `Container` —por
78
+ * defecto acotado y con su aire—, así que el panel quedaría metido dentro de
79
+ * la columna de contenido en vez de flotar sobre la página. Con `shell={false}`
80
+ * no hay marco y el `ref` se queda sin asignar: ahí el contenedor es el
81
+ * `AppShell` de la app.
82
+ *
83
+ * **El `main` lleva los mismos mandos que un `Container`** (`mainWidth`,
84
+ * `mainSpace`, `mainFlush`), con los defaults de siempre. Es lo que permite que
85
+ * una portada abra con un `Hero` de lado a lado sin salirse del marco.
58
86
  */
87
+ /**
88
+ * El único texto del marco, y es **cromo**: el nombre de la banda donde viven
89
+ * el idioma y el tema. Lo que se ponga dentro es **contenido**.
90
+ */
91
+ export interface PublicPageShellMessages {
92
+ /** Nombre accesible de la banda de preferencias. */
93
+ preferences: string;
94
+ }
59
95
  export declare const PublicPageShell: import("react").ForwardRefExoticComponent<PublicPageShellProps & import("react").RefAttributes<HTMLDivElement>>;
@@ -5,7 +5,7 @@ import { t } from "./_shared/appshellcontext.js";
5
5
  import { useContext as n, useState as r } from "react";
6
6
  import { jsx as i, jsxs as a } from "react/jsx-runtime";
7
7
  //#region src/stories/sections/AppHeader/AppHeader.tsx
8
- function o({ start: o, notifications: s, end: c, menuLabel: l = "Menú de navegación", menuCloseLabel: u, sidebarId: d }) {
8
+ function o({ start: o, notifications: s, end: c, menuLabel: l, menuCloseLabel: u, sidebarId: d }) {
9
9
  let f = n(t), [p, m] = r(!1), h = f ? f.sidebar === "open" : p;
10
10
  return /* @__PURE__ */ a("header", {
11
11
  className: "app-header",
@@ -1,119 +1,129 @@
1
1
  'use client';
2
2
  import './app-launcher.css';
3
- import { Icon as e } from "./icon.js";
4
- import { Tag as t } from "./tag.js";
5
- import { Modal as n } from "./modal.js";
6
- import { useState as r } from "react";
7
- import { Fragment as i, jsx as a, jsxs as o } from "react/jsx-runtime";
8
- import { Popover as s } from "@base-ui/react/popover";
3
+ import { n as e } from "./_shared/brandmessagescontext.js";
4
+ import { Icon as t } from "./icon.js";
5
+ import { n } from "./_shared/portal-container.js";
6
+ import { Tag as r } from "./tag.js";
7
+ import { Modal as i } from "./modal.js";
8
+ import { useState as a } from "react";
9
+ import { Fragment as o, jsx as s, jsxs as c } from "react/jsx-runtime";
10
+ import { Popover as l } from "@base-ui/react/popover";
9
11
  //#region src/stories/molecules/AppLauncher/AppLauncher.tsx
10
- function c({ app: e, isCurrent: n, newLabel: r }) {
11
- return /* @__PURE__ */ o("a", {
12
- href: e.url,
12
+ function u({ app: t, isCurrent: n, newLabel: i }) {
13
+ let a = e("appLauncher");
14
+ return /* @__PURE__ */ c("a", {
15
+ href: t.url,
13
16
  className: `app-launcher__tile${n ? " app-launcher__tile--active" : ""}`,
14
17
  "aria-current": n ? "page" : void 0,
15
- children: [/* @__PURE__ */ a("span", {
18
+ children: [/* @__PURE__ */ s("span", {
16
19
  className: "app-launcher__tile-name",
17
- children: e.name
18
- }), e.isNew && /* @__PURE__ */ a(t, {
20
+ children: t.name
21
+ }), t.isNew && /* @__PURE__ */ s(r, {
19
22
  variant: "info",
20
23
  className: "app-launcher__tile-badge",
21
- children: r
24
+ children: a("new", i)
22
25
  })]
23
26
  });
24
27
  }
25
- function l({ apps: e, currentAppId: t, newLabel: n }) {
26
- return /* @__PURE__ */ a("ul", {
28
+ function d({ apps: e, currentAppId: t, newLabel: n }) {
29
+ return /* @__PURE__ */ s("ul", {
27
30
  className: "app-launcher__grid",
28
31
  role: "list",
29
- children: e.map((e) => /* @__PURE__ */ a("li", { children: /* @__PURE__ */ a(c, {
32
+ children: e.map((e) => /* @__PURE__ */ s("li", { children: /* @__PURE__ */ s(u, {
30
33
  app: e,
31
34
  isCurrent: e.id === t,
32
35
  newLabel: n
33
36
  }) }, e.id))
34
37
  });
35
38
  }
36
- function u({ apps: t, labels: n, currentAppId: r, open: i, defaultOpen: c, onOpenChange: u }) {
37
- return /* @__PURE__ */ o(s.Root, {
38
- open: i,
39
- defaultOpen: c,
40
- onOpenChange: (e) => u?.(e),
41
- children: [/* @__PURE__ */ a(s.Trigger, { render: n.trigger ? /* @__PURE__ */ o("button", {
39
+ function f({ apps: r, labels: i, currentAppId: a, open: o, defaultOpen: u, onOpenChange: f }) {
40
+ let p = e("appLauncher"), m = n(void 0);
41
+ return /* @__PURE__ */ c(l.Root, {
42
+ open: o,
43
+ defaultOpen: u,
44
+ onOpenChange: (e) => f?.(e),
45
+ children: [/* @__PURE__ */ s(l.Trigger, { render: i.trigger ? /* @__PURE__ */ c("button", {
42
46
  type: "button",
43
47
  className: "app-launcher__trigger app-launcher__trigger--label",
44
- children: [/* @__PURE__ */ a(e, {
48
+ children: [/* @__PURE__ */ s(t, {
45
49
  name: "grid",
46
50
  size: "md"
47
- }), /* @__PURE__ */ a("span", {
51
+ }), /* @__PURE__ */ s("span", {
48
52
  className: "app-launcher__trigger-label",
49
- children: n.trigger
53
+ children: i.trigger
50
54
  })]
51
- }) : /* @__PURE__ */ a("button", {
55
+ }) : /* @__PURE__ */ s("button", {
52
56
  type: "button",
53
57
  className: "app-launcher__trigger",
54
- "aria-label": n.open,
55
- children: /* @__PURE__ */ a(e, {
58
+ "aria-label": p("open", i.open),
59
+ children: /* @__PURE__ */ s(t, {
56
60
  name: "grid",
57
61
  size: "md"
58
62
  })
59
- }) }), /* @__PURE__ */ a(s.Portal, { children: /* @__PURE__ */ a(s.Positioner, {
60
- className: "app-launcher__positioner",
61
- sideOffset: 4,
62
- align: "end",
63
- children: /* @__PURE__ */ a(s.Popup, {
64
- className: "app-launcher__content",
65
- children: /* @__PURE__ */ a(l, {
66
- apps: t,
67
- currentAppId: r,
68
- newLabel: n.new
63
+ }) }), /* @__PURE__ */ s(l.Portal, {
64
+ container: m,
65
+ children: /* @__PURE__ */ s(l.Positioner, {
66
+ className: "app-launcher__positioner",
67
+ sideOffset: 4,
68
+ align: "end",
69
+ children: /* @__PURE__ */ s(l.Popup, {
70
+ className: "app-launcher__content",
71
+ children: /* @__PURE__ */ s(d, {
72
+ apps: r,
73
+ currentAppId: a,
74
+ newLabel: i.new
75
+ })
69
76
  })
70
77
  })
71
- }) })]
78
+ })]
72
79
  });
73
80
  }
74
- function d(e, t, n) {
75
- let [i, a] = r(t ?? !1);
76
- return [e ?? i, (t) => {
77
- e === void 0 && a(t), n?.(t);
81
+ function p(e, t, n) {
82
+ let [r, i] = a(t ?? !1);
83
+ return [e ?? r, (t) => {
84
+ e === void 0 && i(t), n?.(t);
78
85
  }];
79
86
  }
80
- function f({ apps: t, labels: r, currentAppId: s, open: c, defaultOpen: u, onOpenChange: f }) {
81
- let [p, m] = d(c, u, f);
82
- return /* @__PURE__ */ o(i, { children: [r.trigger ? /* @__PURE__ */ o("button", {
87
+ function m({ apps: n, labels: r, currentAppId: a, open: l, defaultOpen: u, onOpenChange: f }) {
88
+ let m = e("appLauncher"), [h, g] = p(l, u, f);
89
+ return /* @__PURE__ */ c(o, { children: [r.trigger ? /* @__PURE__ */ c("button", {
83
90
  type: "button",
84
91
  className: "app-launcher__trigger app-launcher__trigger--label",
85
92
  "aria-haspopup": "dialog",
86
- onClick: () => m(!0),
87
- children: [/* @__PURE__ */ a(e, {
93
+ onClick: () => g(!0),
94
+ children: [/* @__PURE__ */ s(t, {
88
95
  name: "grid",
89
96
  size: "md"
90
- }), /* @__PURE__ */ a("span", {
97
+ }), /* @__PURE__ */ s("span", {
91
98
  className: "app-launcher__trigger-label",
92
99
  children: r.trigger
93
100
  })]
94
- }) : /* @__PURE__ */ a("button", {
101
+ }) : /* @__PURE__ */ s("button", {
95
102
  type: "button",
96
103
  className: "app-launcher__trigger",
97
- "aria-label": r.open,
104
+ "aria-label": m("open", r.open),
98
105
  "aria-haspopup": "dialog",
99
- onClick: () => m(!0),
100
- children: /* @__PURE__ */ a(e, {
106
+ onClick: () => g(!0),
107
+ children: /* @__PURE__ */ s(t, {
101
108
  name: "grid",
102
109
  size: "md"
103
110
  })
104
- }), /* @__PURE__ */ a(n, {
105
- open: p,
106
- onClose: () => m(!1),
107
- title: r.title ?? "Aplicaciones",
108
- children: /* @__PURE__ */ a(l, {
109
- apps: t,
110
- currentAppId: s,
111
+ }), /* @__PURE__ */ s(i, {
112
+ open: h,
113
+ onClose: () => g(!1),
114
+ title: m("title", r.title),
115
+ children: /* @__PURE__ */ s(d, {
116
+ apps: n,
117
+ currentAppId: a,
111
118
  newLabel: r.new
112
119
  })
113
120
  })] });
114
121
  }
115
- function p({ presentation: e = "modal", ...t }) {
116
- return a(e === "popover" ? u : f, { ...t });
122
+ function h({ presentation: e = "modal", labels: t = {}, ...n }) {
123
+ return s(e === "popover" ? f : m, {
124
+ labels: t,
125
+ ...n
126
+ });
117
127
  }
118
128
  //#endregion
119
- export { p as AppLauncher };
129
+ export { h as AppLauncher };
package/dist/app-root.js CHANGED
@@ -1,11 +1,13 @@
1
- import { SkipLink as e } from "./skip-link.js";
2
- import { Fragment as t, jsx as n, jsxs as r } from "react/jsx-runtime";
1
+ 'use client';
2
+ import { n as e } from "./_shared/brandmessagescontext.js";
3
+ import { SkipLink as t } from "./skip-link.js";
4
+ import { Fragment as n, jsx as r, jsxs as i } from "react/jsx-runtime";
3
5
  //#region src/stories/sections/AppRoot/AppRoot.tsx
4
- function i({ skipLabel: i = "Saltar al contenido principal", skipHref: a = "#main-content", children: o }) {
5
- return /* @__PURE__ */ r(t, { children: [/* @__PURE__ */ n(e, {
6
- href: a,
7
- children: i
8
- }), o] });
6
+ function a({ skipLabel: a, skipHref: o = "#main-content", children: s }) {
7
+ return /* @__PURE__ */ i(n, { children: [/* @__PURE__ */ r(t, {
8
+ href: o,
9
+ children: e("appRoot")("skipToContent", a)
10
+ }), s] });
9
11
  }
10
12
  //#endregion
11
- export { i as AppRoot };
13
+ export { a as AppRoot };
package/dist/app-shell.js CHANGED
@@ -1,78 +1,79 @@
1
1
  'use client';
2
2
  import './app-shell.css';
3
- import { SkipLink as e } from "./skip-link.js";
4
- import { TooltipProvider as t } from "./tooltip.js";
5
- import { t as n } from "./_shared/css-properties.js";
6
- import { n as r, t as i } from "./_shared/appshellcontext.js";
7
- import { useCallback as a, useEffect as o, useMemo as s, useState as c } from "react";
8
- import { jsx as l, jsxs as u } from "react/jsx-runtime";
3
+ import { n as e } from "./_shared/brandmessagescontext.js";
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";
7
+ import { n as i, t as a } from "./_shared/appshellcontext.js";
8
+ import { useCallback as o, useEffect as s, useMemo as c, useState as l } from "react";
9
+ import { jsx as u, jsxs as d } from "react/jsx-runtime";
9
10
  //#region src/stories/sections/AppShell/AppShell.tsx
10
- var d = "(min-width: 1024px)";
11
- function f() {
12
- let [e, t] = c(() => typeof window > "u" ? !0 : window.matchMedia(d).matches);
13
- return o(() => {
14
- let e = window.matchMedia(d), n = () => t(e.matches);
11
+ var f = "(min-width: 1024px)";
12
+ function p() {
13
+ let [e, t] = l(() => typeof window > "u" ? !0 : window.matchMedia(f).matches);
14
+ return s(() => {
15
+ let e = window.matchMedia(f), n = () => t(e.matches);
15
16
  return n(), e.addEventListener("change", n), () => e.removeEventListener("change", n);
16
17
  }, []), e;
17
18
  }
18
- function p({ header: r, sidebar: d, children: p, defaultSidebar: m = "open", sidebarState: h, onSidebarChange: g, defaultSidebarWidth: _, onSidebarWidthChange: v, skipLabel: y = "Saltar al contenido principal" }) {
19
- let b = f(), [x, S] = c(m), [C, w] = c(!1), [T, E] = c(_), D = b ? h ?? x : C ? "open" : "closed", O = a((e) => {
20
- b ? (S(e), g?.(e)) : w(e === "open");
21
- }, [b, g]), k = a(() => O(D === "open" ? "closed" : "open"), [O, D]), A = a(() => O("closed"), [O]), j = a((e) => {
22
- E(e), v?.(e);
23
- }, [v]);
24
- o(() => {
25
- if (b || !C) return;
19
+ function m({ header: i, sidebar: f, children: m, defaultSidebar: h = "open", sidebarState: g, onSidebarChange: _, defaultSidebarWidth: v, onSidebarWidthChange: y, skipLabel: b }) {
20
+ let x = e("appShell"), S = p(), [C, w] = l(h), [T, E] = l(!1), [D, O] = l(v), k = S ? g ?? C : T ? "open" : "closed", A = o((e) => {
21
+ S ? (w(e), _?.(e)) : E(e === "open");
22
+ }, [S, _]), j = o(() => A(k === "open" ? "closed" : "open"), [A, k]), M = o(() => A("closed"), [A]), N = o((e) => {
23
+ O(e), y?.(e);
24
+ }, [y]);
25
+ s(() => {
26
+ if (S || !T) return;
26
27
  let e = (e) => {
27
- e.key === "Escape" && w(!1);
28
+ e.key === "Escape" && E(!1);
28
29
  };
29
30
  document.addEventListener("keydown", e);
30
31
  let t = document.body.style.overflow;
31
32
  return document.body.style.overflow = "hidden", () => {
32
33
  document.removeEventListener("keydown", e), document.body.style.overflow = t;
33
34
  };
34
- }, [b, C]);
35
- let M = s(() => ({
36
- sidebar: D,
37
- setSidebar: O,
38
- sidebarWidth: T ?? 0,
39
- setSidebarWidth: j,
40
- toggleSidebar: k,
41
- closeSidebar: A,
42
- isDesktop: b
35
+ }, [S, T]);
36
+ let P = c(() => ({
37
+ sidebar: k,
38
+ setSidebar: A,
39
+ sidebarWidth: D ?? 0,
40
+ setSidebarWidth: N,
41
+ toggleSidebar: j,
42
+ closeSidebar: M,
43
+ isDesktop: S
43
44
  }), [
44
- D,
45
- O,
46
- T,
47
- j,
48
45
  k,
49
46
  A,
50
- b
51
- ]), N = n({ "--app-shell-sidebar-width": T ? `${T}px` : void 0 }), P = !b && C;
52
- return /* @__PURE__ */ l(i.Provider, {
53
- value: M,
54
- children: /* @__PURE__ */ u(t, { children: [/* @__PURE__ */ l(e, {
47
+ D,
48
+ N,
49
+ j,
50
+ M,
51
+ S
52
+ ]), F = r({ "--app-shell-sidebar-width": D ? `${D}px` : void 0 }), I = !S && T;
53
+ return /* @__PURE__ */ u(a.Provider, {
54
+ value: P,
55
+ children: /* @__PURE__ */ d(n, { children: [/* @__PURE__ */ u(t, {
55
56
  href: "#main-content",
56
- children: y
57
- }), /* @__PURE__ */ u("div", {
58
- ref: N,
57
+ children: x("skipToContent", b)
58
+ }), /* @__PURE__ */ d("div", {
59
+ ref: F,
59
60
  className: "app-shell",
60
- "data-sidebar": D,
61
- children: [r, /* @__PURE__ */ u("div", {
61
+ "data-sidebar": k,
62
+ children: [i, /* @__PURE__ */ d("div", {
62
63
  className: "app-shell__body",
63
64
  children: [
64
- d,
65
- P && /* @__PURE__ */ l("div", {
65
+ f,
66
+ I && /* @__PURE__ */ u("div", {
66
67
  className: "app-shell__backdrop",
67
- onClick: A,
68
+ onClick: M,
68
69
  "aria-hidden": "true"
69
70
  }),
70
- /* @__PURE__ */ l("main", {
71
+ /* @__PURE__ */ u("main", {
71
72
  id: "main-content",
72
73
  tabIndex: -1,
73
74
  className: "app-shell__content",
74
- inert: P || void 0,
75
- children: p
75
+ inert: I || void 0,
76
+ children: m
76
77
  })
77
78
  ]
78
79
  })]
@@ -80,4 +81,4 @@ function p({ header: r, sidebar: d, children: p, defaultSidebar: m = "open", sid
80
81
  });
81
82
  }
82
83
  //#endregion
83
- export { p as AppShell, r as useAppShell };
84
+ export { m as AppShell, i as useAppShell };