@studiolxd/brand 49.21.0 → 49.23.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 +70 -0
- package/dist/_shared/colorpicker.js +410 -0
- package/dist/_shared/tokens.js +62 -0
- package/dist/_types/atoms/ColorSwatch/ColorSwatch.d.ts +35 -0
- package/dist/_types/messages/BrandMessages.d.ts +5 -1
- package/dist/_types/messages/index.d.ts +1 -1
- package/dist/_types/molecules/ColorPicker/ColorArea.d.ts +51 -0
- package/dist/_types/molecules/ColorPicker/ColorPicker.d.ts +130 -0
- package/dist/_types/molecules/ColorPicker/colorModel.d.ts +54 -0
- package/dist/_types/molecules/ColorPickerField/ColorPickerField.d.ts +26 -0
- package/dist/_types/sections/AppHeader/AppHeader.d.ts +37 -2
- package/dist/app-header.css +1 -1
- package/dist/app-header.js +34 -21
- package/dist/app-shell.css +1 -1
- package/dist/brand.css +137 -1
- package/dist/color-picker-field.css +1 -0
- package/dist/color-picker-field.js +46 -0
- package/dist/color-picker.js +3 -0
- package/dist/color-swatch.css +1 -0
- package/dist/color-swatch.js +29 -0
- package/dist/colorpicker.css +1 -0
- package/dist/tokens.css +146 -1
- package/package.json +16 -1
- package/src/tokens/components/color-swatch.css +22 -0
- package/src/tokens/components/color-swatch.ts +7 -0
- package/src/tokens/index.css +3 -0
- package/src/tokens/molecules/color-picker-field.css +19 -0
- package/src/tokens/molecules/color-picker-field.ts +4 -0
- package/src/tokens/molecules/color-picker.css +63 -0
- package/src/tokens/molecules/color-picker.ts +8 -0
- package/src/tokens/scss/_index.legacy.scss +3 -0
- package/src/tokens/scss/_index.scss +3 -0
- package/src/tokens/scss/components/_color-swatch.scss +12 -0
- package/src/tokens/scss/molecules/_color-picker-field.scss +9 -0
- package/src/tokens/scss/molecules/_color-picker.scss +50 -0
- package/src/tokens/surface-dark-derived.css +8 -0
- package/src/tokens/surface-invert.css +14 -0
- package/src/tokens/surface-light.css +14 -0
- package/src/tokens/surface-public.css +2 -0
- package/src/tokens/tokens.json +62 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/** Saturación y brillo, de 0 a 100. */
|
|
2
|
+
export interface AreaValue {
|
|
3
|
+
s: number;
|
|
4
|
+
v: number;
|
|
5
|
+
}
|
|
6
|
+
interface ColorAreaProps {
|
|
7
|
+
/** Tono del fondo del área, ya en hex opaco. */
|
|
8
|
+
hueColor: string;
|
|
9
|
+
saturation: number;
|
|
10
|
+
brightness: number;
|
|
11
|
+
/** Mientras se arrastra o con cada tecla. */
|
|
12
|
+
onChange: (value: AreaValue) => void;
|
|
13
|
+
/** Al soltar el puntero, o con cada tecla. */
|
|
14
|
+
onCommit: (value: AreaValue) => void;
|
|
15
|
+
label: string;
|
|
16
|
+
roleDescription: string;
|
|
17
|
+
valueText: string;
|
|
18
|
+
disabled?: boolean;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* El área de saturación × brillo: la única pieza del selector que no sale de
|
|
22
|
+
* Base UI, porque Base UI no tiene un deslizador de dos dimensiones.
|
|
23
|
+
*
|
|
24
|
+
* Accesibilidad: la APG de WAI-ARIA no define un patrón de deslizador 2D, así
|
|
25
|
+
* que se sigue su **patrón Slider** extendido a dos ejes, que es lo que hacen
|
|
26
|
+
* los selectores de color accesibles: el pulgar es **un** `role="slider"`
|
|
27
|
+
* enfocable, con `aria-roledescription` que dice que es bidimensional,
|
|
28
|
+
* `aria-valuenow` en el eje horizontal (saturación) y `aria-valuetext` con los
|
|
29
|
+
* dos valores, que es lo que lee el lector de pantalla en cada cambio.
|
|
30
|
+
*
|
|
31
|
+
* Teclado —el del patrón Slider, en dos ejes—:
|
|
32
|
+
* - `←`/`→`: saturación ±1 (en RTL, `→` resta: la flecha va hacia donde se
|
|
33
|
+
* mueve el pulgar). `↑`/`↓`: brillo ±1.
|
|
34
|
+
* - `Mayús`+flecha: el mismo eje ±10.
|
|
35
|
+
* - `RePág`/`AvPág`: brillo ±10. Con `Mayús`, saturación ±10.
|
|
36
|
+
* - `Inicio`/`Fin`: saturación al mínimo y al máximo. Con `Ctrl`, el brillo.
|
|
37
|
+
*
|
|
38
|
+
* Puntero (ratón, lápiz y táctil): el área captura el puntero al pulsar
|
|
39
|
+
* (`setPointerCapture`), así que el arrastre sigue aunque se salga del área
|
|
40
|
+
* —y no cuenta como clic fuera del panel, porque empezó dentro—. El foco pasa
|
|
41
|
+
* al pulgar al pulsar, para que el teclado siga donde se dejó el ratón.
|
|
42
|
+
*
|
|
43
|
+
* La dirección es la de Base UI (`DirectionProvider`), la misma que invierte
|
|
44
|
+
* las bandas: en RTL la saturación crece hacia la izquierda.
|
|
45
|
+
*
|
|
46
|
+
* La posición del pulgar y el tono del fondo se escriben por el CSSOM
|
|
47
|
+
* (`useCssProperties`): el área solo existe dentro del panel, que se pinta en
|
|
48
|
+
* cliente, así que no hay HTML de servidor que la CSP pudiera descartar.
|
|
49
|
+
*/
|
|
50
|
+
export declare const ColorArea: import("react").ForwardRefExoticComponent<ColorAreaProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
51
|
+
export {};
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import type { PopoverChangeDetails } from '../../atoms/Popover/Popover';
|
|
2
|
+
import './ColorPicker.css';
|
|
3
|
+
/**
|
|
4
|
+
* El cromo del selector de color. Ninguno trae el castellano puesto: salen
|
|
5
|
+
* del `BrandMessagesProvider` (espacio `colorPicker`), y cada uno se lee
|
|
6
|
+
* **donde se pinta** —un selector sin transparencia no exige `alpha`, uno sin
|
|
7
|
+
* predefinidos no exige `presets`—.
|
|
8
|
+
*
|
|
9
|
+
* Las cifras no son texto: saturación y brillo llegan como números a
|
|
10
|
+
* `areaValue`, y el tono y la opacidad los formatea `Intl` con `locale`.
|
|
11
|
+
*/
|
|
12
|
+
export interface ColorPickerMessages {
|
|
13
|
+
/** Nombre del disparador cuando va suelto, sin etiqueta ni `aria-label`. */
|
|
14
|
+
trigger: string;
|
|
15
|
+
/** El valor actual, que describe el disparador. Recibe el hex. */
|
|
16
|
+
value: (hex: string) => string;
|
|
17
|
+
/** Descripción del disparador cuando no hay color. */
|
|
18
|
+
empty: string;
|
|
19
|
+
/** Nombre del panel (`role="dialog"`) cuando el selector va suelto. */
|
|
20
|
+
dialog: string;
|
|
21
|
+
/** Nombre del área de saturación y brillo. */
|
|
22
|
+
area: string;
|
|
23
|
+
/** `aria-roledescription` del área: dice que el deslizador tiene dos ejes. */
|
|
24
|
+
areaDescription: string;
|
|
25
|
+
/** Lo que anuncia el área: saturación y brillo, de 0 a 100, ya redondeados. */
|
|
26
|
+
areaValue: (saturation: number, brightness: number) => string;
|
|
27
|
+
/** Nombre de la banda de tono. */
|
|
28
|
+
hue: string;
|
|
29
|
+
/** Nombre de la banda de opacidad (solo con `alpha`). */
|
|
30
|
+
alpha: string;
|
|
31
|
+
/** Nombre del campo hexadecimal. */
|
|
32
|
+
hex: string;
|
|
33
|
+
/** Nombre del grupo de predefinidos (solo con `presets`). */
|
|
34
|
+
presets: string;
|
|
35
|
+
/** Botón de quitar el color (solo con `clearable`). */
|
|
36
|
+
clear: string;
|
|
37
|
+
}
|
|
38
|
+
/** Un color predefinido: el valor y el nombre con que se anuncia. */
|
|
39
|
+
export interface ColorPickerPreset {
|
|
40
|
+
/** Hex de 3, 4, 6 u 8 dígitos. Lo que no sea hex no se ofrece. */
|
|
41
|
+
color: string;
|
|
42
|
+
/** Nombre accesible y rótulo emergente: «Lavanda», «Texto». */
|
|
43
|
+
title: string;
|
|
44
|
+
}
|
|
45
|
+
export interface ColorPickerProps {
|
|
46
|
+
/**
|
|
47
|
+
* Valor (controlado): un hex. `null` es «sin color». Si llega algo que no es
|
|
48
|
+
* hex (`transparent`, un nombre), la muestra lo pinta tal cual y el panel
|
|
49
|
+
* arranca en negro.
|
|
50
|
+
*/
|
|
51
|
+
value?: string | null;
|
|
52
|
+
/** Valor al montar (no controlado). */
|
|
53
|
+
defaultValue?: string | null;
|
|
54
|
+
/**
|
|
55
|
+
* Se llama mientras se elige —en cada paso del arrastre, con cada tecla—,
|
|
56
|
+
* con el hex en minúsculas: `#rrggbb`, o `#rrggbbaa` con `alpha`. Es el sitio
|
|
57
|
+
* de la vista previa.
|
|
58
|
+
*/
|
|
59
|
+
onValueChange?: (hex: string) => void;
|
|
60
|
+
/**
|
|
61
|
+
* Se llama al terminar un gesto: al soltar el área o una banda, con cada
|
|
62
|
+
* tecla, al elegir un predefinido o al escribir un hex válido. Es el sitio
|
|
63
|
+
* del guardado.
|
|
64
|
+
*/
|
|
65
|
+
onValueCommitted?: (hex: string) => void;
|
|
66
|
+
/**
|
|
67
|
+
* Con transparencia: pinta la banda de opacidad y emite `#rrggbbaa`. Por
|
|
68
|
+
* defecto `false`: emite `#rrggbb` y descarta el alfa de lo que entre.
|
|
69
|
+
*/
|
|
70
|
+
alpha?: boolean;
|
|
71
|
+
/** Colores predefinidos, con su nombre: la paleta de un tema. */
|
|
72
|
+
presets?: ColorPickerPreset[];
|
|
73
|
+
/** Añade «Quitar color» al pie del panel. */
|
|
74
|
+
clearable?: boolean;
|
|
75
|
+
/**
|
|
76
|
+
* Se llama al quitar el color, y el panel se cierra (con `open` controlado,
|
|
77
|
+
* lo cierra quien lo controla, aquí mismo). Sin controlar, el valor pasa a
|
|
78
|
+
* `null`.
|
|
79
|
+
*/
|
|
80
|
+
onClear?: () => void;
|
|
81
|
+
/**
|
|
82
|
+
* Panel abierto (controlado). Sin él, el panel se abre con el disparador y
|
|
83
|
+
* se cierra con Escape, con un clic fuera o al quitar el color; elegir un
|
|
84
|
+
* color **no** lo cierra. Controlado, quien lo usa puede cerrarlo en
|
|
85
|
+
* `onValueCommitted`.
|
|
86
|
+
*/
|
|
87
|
+
open?: boolean;
|
|
88
|
+
/** Panel abierto al montar (no controlado). */
|
|
89
|
+
defaultOpen?: boolean;
|
|
90
|
+
/**
|
|
91
|
+
* Se llama al abrirse y al cerrarse por el disparador, Escape o un clic
|
|
92
|
+
* fuera. El segundo argumento es el detalle de Base UI, como en `Popover`.
|
|
93
|
+
*/
|
|
94
|
+
onOpenChange?: (open: boolean, details: PopoverChangeDetails) => void;
|
|
95
|
+
size?: 'sm' | 'md' | 'lg';
|
|
96
|
+
disabled?: boolean;
|
|
97
|
+
/** Pone el disparador en error (lo hace el campo cuando trae `errorMessage`). */
|
|
98
|
+
error?: boolean;
|
|
99
|
+
/** Locale con que `Intl` formatea el tono y la opacidad. */
|
|
100
|
+
locale?: string;
|
|
101
|
+
/** `id` del disparador: lo apunta el `htmlFor` de la etiqueta. */
|
|
102
|
+
id?: string;
|
|
103
|
+
/** Nombre en el formulario: se monta un input oculto con el hex. */
|
|
104
|
+
name?: string;
|
|
105
|
+
/** Nombre accesible del disparador cuando va suelto. */
|
|
106
|
+
'aria-label'?: string;
|
|
107
|
+
/** Lo pone el campo: la etiqueta nombra el disparador. */
|
|
108
|
+
'aria-labelledby'?: string;
|
|
109
|
+
/** Ids de ayuda/error que describen el disparador (lo pone el campo). */
|
|
110
|
+
'aria-describedby'?: string;
|
|
111
|
+
/**
|
|
112
|
+
* Nombre del panel. **Sin default**: sin él, sale de `colorPicker.dialog`.
|
|
113
|
+
* En un campo lo pone la etiqueta.
|
|
114
|
+
*/
|
|
115
|
+
dialogLabel?: string;
|
|
116
|
+
/** Texto de «Quitar color». **Sin default**: sin él, `colorPicker.clear`. */
|
|
117
|
+
clearLabel?: string;
|
|
118
|
+
/** Se añade DESPUÉS de las clases propias. */
|
|
119
|
+
className?: string;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Selector de color: una muestra que abre un panel con el área de saturación
|
|
123
|
+
* y brillo, la banda de tono, la de opacidad (con `alpha`), el campo hex y los
|
|
124
|
+
* predefinidos. Emite siempre hex en minúsculas.
|
|
125
|
+
*
|
|
126
|
+
* Todo es Base UI salvo el área 2D: el `Popover` (foco, portal, cierre), las
|
|
127
|
+
* bandas (`Slider`) y el campo (`Input`) son los de brand. El `ref` va al
|
|
128
|
+
* disparador.
|
|
129
|
+
*/
|
|
130
|
+
export declare const ColorPicker: import("react").ForwardRefExoticComponent<ColorPickerProps & import("react").RefAttributes<HTMLButtonElement>>;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* El modelo del selector de color: conversiones puras entre hexadecimal, RGB y
|
|
3
|
+
* HSV, sin dependencias.
|
|
4
|
+
*
|
|
5
|
+
* El selector trabaja en **HSV** (tono, saturación, brillo) porque es el
|
|
6
|
+
* espacio de sus controles: el área es saturación × brillo y la banda es el
|
|
7
|
+
* tono. Pero lo que entra y sale es **hexadecimal en minúsculas**: `#rrggbb`,
|
|
8
|
+
* o `#rrggbbaa` cuando hay transparencia. Por eso el estado vivo es un `Hsva`
|
|
9
|
+
* y el hex se deriva: ida y vuelta por hex se pierde el tono de un gris (todo
|
|
10
|
+
* gris es `s = 0` con cualquier tono), y el pulgar de la banda saltaría a cero
|
|
11
|
+
* al arrastrar por la columna del gris.
|
|
12
|
+
*/
|
|
13
|
+
/** Canales de 0 a 255 y alfa de 0 a 1. */
|
|
14
|
+
export interface Rgba {
|
|
15
|
+
r: number;
|
|
16
|
+
g: number;
|
|
17
|
+
b: number;
|
|
18
|
+
a: number;
|
|
19
|
+
}
|
|
20
|
+
/** Tono de 0 a 360, saturación y brillo de 0 a 100, alfa de 0 a 1. */
|
|
21
|
+
export interface Hsva {
|
|
22
|
+
h: number;
|
|
23
|
+
s: number;
|
|
24
|
+
v: number;
|
|
25
|
+
a: number;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Lee un hexadecimal de 3, 4, 6 u 8 dígitos, con o sin `#`, en mayúsculas o
|
|
29
|
+
* minúsculas. Cualquier otra cosa —un nombre CSS, `rgb()`, `transparent`—
|
|
30
|
+
* devuelve `null`: el selector solo edita hex; la muestra sí pinta cualquier
|
|
31
|
+
* color CSS.
|
|
32
|
+
*/
|
|
33
|
+
export declare function parseHex(input: string): Rgba | null;
|
|
34
|
+
/**
|
|
35
|
+
* `#rrggbb` en minúsculas, o `#rrggbbaa` con `alpha`. Con `alpha` el par del
|
|
36
|
+
* alfa va siempre, también cuando es opaco (`ff`): el formato no cambia de
|
|
37
|
+
* longitud según el valor.
|
|
38
|
+
*/
|
|
39
|
+
export declare function formatHex({ r, g, b, a }: Rgba, alpha: boolean): string;
|
|
40
|
+
export declare function rgbToHsv({ r, g, b, a }: Rgba): Hsva;
|
|
41
|
+
export declare function hsvToRgb({ h, s, v, a }: Hsva): Rgba;
|
|
42
|
+
export declare function hexToHsva(hex: string): Hsva | null;
|
|
43
|
+
export declare function hsvaToHex(hsva: Hsva, alpha: boolean): string;
|
|
44
|
+
/**
|
|
45
|
+
* Normaliza un hex a la forma que emite el selector (`#rrggbb` o
|
|
46
|
+
* `#rrggbbaa`, minúsculas), o `null` si no lo es. Sin `alpha`, la
|
|
47
|
+
* transparencia de un `#rrggbbaa` se descarta.
|
|
48
|
+
*/
|
|
49
|
+
export declare function normalizeHex(input: string, alpha: boolean): string | null;
|
|
50
|
+
/**
|
|
51
|
+
* Las paradas del degradado de tono, cada 60°: los seis colores puros y la
|
|
52
|
+
* vuelta al rojo. Salen del propio modelo, no de una lista escrita a mano.
|
|
53
|
+
*/
|
|
54
|
+
export declare function hueStops(): string[];
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { ColorPickerProps } from '../ColorPicker/ColorPicker';
|
|
2
|
+
import './ColorPickerField.css';
|
|
3
|
+
export interface ColorPickerFieldProps extends Omit<ColorPickerProps, 'id' | 'aria-describedby' | 'aria-label' | 'aria-labelledby'> {
|
|
4
|
+
/** `id` del disparador. Si no se pasa, se genera con `useId`. */
|
|
5
|
+
id?: string;
|
|
6
|
+
label: string;
|
|
7
|
+
/**
|
|
8
|
+
* Oculta la etiqueta a la vista (sigue leyéndola el lector de pantalla).
|
|
9
|
+
* Por defecto `false`. Sin valor, lo decide quien lo envuelva: dentro de un
|
|
10
|
+
* `FieldRow` que no es la primera de la lista, la etiqueta se oculta sola.
|
|
11
|
+
*/
|
|
12
|
+
labelHidden?: boolean;
|
|
13
|
+
/** Mensaje de error: se anuncia (`role="alert"`) y pone el disparador en error. */
|
|
14
|
+
errorMessage?: string;
|
|
15
|
+
/** Texto de ayuda, enlazado por `aria-describedby`. */
|
|
16
|
+
helperText?: string;
|
|
17
|
+
/** Se añade DESPUÉS de las clases propias (el consumidor añade, no sustituye). */
|
|
18
|
+
className?: string;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* El `ColorPicker` como campo de formulario: etiqueta, disparador, ayuda y
|
|
22
|
+
* error. La etiqueta nombra el disparador y el panel; el `ref` va al
|
|
23
|
+
* **disparador**, para que react-hook-form pueda enfocarlo al fallar la
|
|
24
|
+
* validación; el `className`, al contenedor.
|
|
25
|
+
*/
|
|
26
|
+
export declare const ColorPickerField: import("react").ForwardRefExoticComponent<ColorPickerFieldProps & import("react").RefAttributes<HTMLButtonElement>>;
|
|
@@ -1,6 +1,41 @@
|
|
|
1
1
|
import { type ReactNode } from 'react';
|
|
2
2
|
import './AppHeader.css';
|
|
3
|
+
export type AppHeaderLogoLinkProps = {
|
|
4
|
+
href: string;
|
|
5
|
+
className: string;
|
|
6
|
+
'aria-label': string;
|
|
7
|
+
children: ReactNode;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* El único texto propio de la barra, y solo cuando lleva `logo`: es **cromo**,
|
|
11
|
+
* qué hace el logotipo («ir al inicio»), no qué marca es — el mismo criterio
|
|
12
|
+
* que `siteHeader.logo`.
|
|
13
|
+
*/
|
|
14
|
+
export interface AppHeaderMessages {
|
|
15
|
+
/** Texto accesible del enlace del logotipo. */
|
|
16
|
+
logo: string;
|
|
17
|
+
}
|
|
3
18
|
export interface AppHeaderProps {
|
|
19
|
+
/**
|
|
20
|
+
* La marca del producto, entre el botón de menú y `start`: un `Logo`, un SVG
|
|
21
|
+
* o una imagen de cualquier proporción. Toma el alto de contenido de la barra
|
|
22
|
+
* (`--app-header-content-height`) y el ancho que le dé su proporción; no hay
|
|
23
|
+
* que darle medidas. Sin `logo`, la barra no cambia.
|
|
24
|
+
*/
|
|
25
|
+
logo?: ReactNode;
|
|
26
|
+
/** Destino del logotipo. Solo se usa con `logo`. */
|
|
27
|
+
logoHref?: string;
|
|
28
|
+
/**
|
|
29
|
+
* Texto accesible del enlace del logotipo. **Sin default**: sin él, sale de
|
|
30
|
+
* `appHeader.logo` del `BrandMessagesProvider`. Solo se lee con `logo`.
|
|
31
|
+
*/
|
|
32
|
+
logoLabel?: string;
|
|
33
|
+
/**
|
|
34
|
+
* Enlace del logotipo para el router del producto. Recibe `href`, `className`,
|
|
35
|
+
* `aria-label` y `children`, y debe reenviarlos todos. Mismo contrato que en
|
|
36
|
+
* `SiteHeader`.
|
|
37
|
+
*/
|
|
38
|
+
renderLogoLink?: (props: AppHeaderLogoLinkProps) => ReactNode;
|
|
4
39
|
/** Tras el botón de menú: breadcrumb, buscador, título de página… */
|
|
5
40
|
start?: ReactNode;
|
|
6
41
|
/** Antes del avatar: la campana con su contador. Sitio fijo. */
|
|
@@ -24,6 +59,6 @@ export interface AppHeaderProps {
|
|
|
24
59
|
* La barra superior de la aplicación, en todos los anchos. A la izquierda el
|
|
25
60
|
* botón de menú, que abre el cajón en móvil y pliega/despliega la sidebar en
|
|
26
61
|
* escritorio; a la derecha, notificaciones y cuenta. Entre medias, lo que la
|
|
27
|
-
* página necesite.
|
|
62
|
+
* página necesite. Con `logo`, la marca del producto va justo tras el botón.
|
|
28
63
|
*/
|
|
29
|
-
export declare function AppHeader({ start, notifications, end, menuLabel, menuCloseLabel, sidebarId, }: AppHeaderProps): import("react/jsx-runtime").JSX.Element;
|
|
64
|
+
export declare function AppHeader({ logo, logoHref, logoLabel, renderLogoLink, start, notifications, end, menuLabel, menuCloseLabel, sidebarId, }: AppHeaderProps): import("react/jsx-runtime").JSX.Element;
|
package/dist/app-header.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
.app-header{align-items:center;gap:var(--app-header-gap);block-size:var(--app-header-height);padding-inline:var(--app-header-padding-inline);box-sizing:content-box;background-color:var(--app-header-bg);box-shadow:0 var(--app-header-border-width) 0 var(--app-header-border-color);z-index:var(--app-header-z-index);flex-shrink:0;padding-block-start:env(safe-area-inset-top);display:flex;position:sticky;inset-block-start:0}.app-header__start{flex:1;align-items:center;min-inline-size:0;display:flex}.app-header__notifications,.app-header__end{flex-shrink:0;align-items:center;display:flex}
|
|
1
|
+
.app-header{align-items:center;gap:var(--app-header-gap);block-size:var(--app-header-height);padding-inline:var(--app-header-padding-inline);box-sizing:content-box;background-color:var(--app-header-bg);box-shadow:0 var(--app-header-border-width) 0 var(--app-header-border-color);z-index:var(--app-header-z-index);flex-shrink:0;padding-block-start:env(safe-area-inset-top);display:flex;position:sticky;inset-block-start:0}.app-header__start{flex:1;align-items:center;min-inline-size:0;display:flex}.app-header__notifications,.app-header__end{flex-shrink:0;align-items:center;display:flex}.app-header__logo{box-shadow:none;color:inherit;--logo-height-sm:var(--app-header-content-height);--logo-height-md:var(--app-header-content-height);--logo-height-lg:var(--app-header-content-height);--logo-height-xl:var(--app-header-content-height);--logo-height-xxl:var(--app-header-content-height);flex-shrink:0;align-items:center;padding-block-end:0;display:flex}.app-header__logo:hover{box-shadow:none;color:inherit}.app-header__logo>*{block-size:var(--app-header-content-height);inline-size:auto}
|
package/dist/app-header.js
CHANGED
|
@@ -1,37 +1,50 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import './app-header.css';
|
|
3
|
-
import {
|
|
4
|
-
import { t } from "./
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
3
|
+
import { n as e } from "./_shared/brandmessagescontext.js";
|
|
4
|
+
import { MenuButton as t } from "./menu-button.js";
|
|
5
|
+
import { t as n } from "./_shared/appshellcontext.js";
|
|
6
|
+
import { useContext as r, useState as i } from "react";
|
|
7
|
+
import { jsx as a, jsxs as o } from "react/jsx-runtime";
|
|
7
8
|
//#region src/stories/sections/AppHeader/AppHeader.tsx
|
|
8
|
-
function
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
function s({ children: e, ...t }) {
|
|
10
|
+
return /* @__PURE__ */ a("a", {
|
|
11
|
+
...t,
|
|
12
|
+
children: e
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
function c({ logo: c, logoHref: l = "/", logoLabel: u, renderLogoLink: d = s, start: f, notifications: p, end: m, menuLabel: h, menuCloseLabel: g, sidebarId: _ }) {
|
|
16
|
+
let v = r(n), [y, b] = i(!1), x = v ? v.sidebar === "open" : y, S = v ? v.toggleSidebar : () => b((e) => !e), C = e("appHeader");
|
|
17
|
+
return /* @__PURE__ */ o("header", {
|
|
11
18
|
className: "app-header",
|
|
12
19
|
children: [
|
|
13
|
-
/* @__PURE__ */
|
|
14
|
-
isOpen:
|
|
15
|
-
onClick:
|
|
16
|
-
label:
|
|
17
|
-
closeLabel:
|
|
18
|
-
"aria-controls":
|
|
19
|
-
"aria-expanded":
|
|
20
|
+
/* @__PURE__ */ a(t, {
|
|
21
|
+
isOpen: x,
|
|
22
|
+
onClick: S,
|
|
23
|
+
label: h,
|
|
24
|
+
closeLabel: g,
|
|
25
|
+
"aria-controls": _,
|
|
26
|
+
"aria-expanded": x
|
|
20
27
|
}),
|
|
21
|
-
|
|
28
|
+
c && d({
|
|
29
|
+
href: l,
|
|
30
|
+
className: "app-header__logo",
|
|
31
|
+
"aria-label": C("logo", u),
|
|
32
|
+
children: c
|
|
33
|
+
}),
|
|
34
|
+
/* @__PURE__ */ a("div", {
|
|
22
35
|
className: "app-header__start",
|
|
23
|
-
children:
|
|
36
|
+
children: f
|
|
24
37
|
}),
|
|
25
|
-
|
|
38
|
+
p && /* @__PURE__ */ a("div", {
|
|
26
39
|
className: "app-header__notifications",
|
|
27
|
-
children:
|
|
40
|
+
children: p
|
|
28
41
|
}),
|
|
29
|
-
|
|
42
|
+
m && /* @__PURE__ */ a("div", {
|
|
30
43
|
className: "app-header__end",
|
|
31
|
-
children:
|
|
44
|
+
children: m
|
|
32
45
|
})
|
|
33
46
|
]
|
|
34
47
|
});
|
|
35
48
|
}
|
|
36
49
|
//#endregion
|
|
37
|
-
export {
|
|
50
|
+
export { c as AppHeader };
|
package/dist/app-shell.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
.app-shell{--app-shell-sidebar-width:var(--sidebar-width);--app-shell-banner-height:0px;--app-shell-chrome-block-start:calc(var(--app-shell-banner-height) + var(--app-header-height) + env(safe-area-inset-top));flex-direction:column;block-size:100dvh;display:flex;overflow:clip}.app-shell__banner{flex-shrink:0}.app-shell__body{flex:1;min-block-size:0;display:flex;position:relative}.app-shell__content{min-inline-size:0;padding-inline:var(--section-padding-inline);padding-block:var(--section-padding-block-lg);flex:1;padding-block-end:max(var(--section-padding-block-lg), env(safe-area-inset-bottom));padding-inline-end:max(var(--section-padding-inline), env(safe-area-inset-right));overflow:auto}.app-shell__content.app-shell__content--flush{padding-block:0;padding-inline:0;padding-block-end:env(safe-area-inset-bottom);padding-inline-end:env(safe-area-inset-right)}.app-shell__backdrop{inset:0;background-color:var(--sidebar-backdrop-bg);opacity:var(--sidebar-backdrop-opacity);z-index:var(--sidebar-backdrop-z-index);position:fixed;inset-block-start:var(--app-shell-chrome-block-start)}
|
|
1
|
+
.app-shell{--app-shell-sidebar-width:var(--sidebar-width);--app-shell-banner-height:0px;--app-shell-chrome-block-start:calc(var(--app-shell-banner-height) + var(--app-header-height) + env(safe-area-inset-top));flex-direction:column;block-size:100dvh;display:flex;overflow:clip}.app-shell__banner{flex-shrink:0}.app-shell__body{flex:1;min-block-size:0;display:flex;position:relative}.app-shell__content{min-inline-size:0;padding-inline:var(--section-padding-inline);padding-block:var(--section-padding-block-lg);flex:1;padding-block-end:max(var(--section-padding-block-lg), env(safe-area-inset-bottom));padding-inline-end:max(var(--section-padding-inline), env(safe-area-inset-right));overflow:auto}.app-shell__content.app-shell__content--flush{padding-block:0;padding-inline:0;padding-block-end:env(safe-area-inset-bottom);padding-inline-end:env(safe-area-inset-right)}.app-shell__backdrop{inset:0;background-color:var(--sidebar-backdrop-bg);opacity:var(--sidebar-backdrop-opacity);z-index:var(--sidebar-backdrop-z-index);position:fixed;inset-block-start:var(--app-shell-chrome-block-start)}.app-shell:has(.app-header__logo) .sidebar__header{display:none}
|