@zevra/ui 0.4.0 → 0.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/README.md +64 -1
- package/dist/actions.d.ts +41 -0
- package/dist/actions.d.ts.map +1 -0
- package/dist/actions.js +24 -0
- package/dist/actions.js.map +1 -0
- package/dist/catalogue.d.ts +30 -0
- package/dist/catalogue.d.ts.map +1 -0
- package/dist/catalogue.js +830 -0
- package/dist/catalogue.js.map +1 -0
- package/dist/content.d.ts +135 -0
- package/dist/content.d.ts.map +1 -0
- package/dist/content.js +85 -0
- package/dist/content.js.map +1 -0
- package/dist/css-inline.d.ts +11 -0
- package/dist/css-inline.d.ts.map +1 -0
- package/dist/css-inline.js +13 -0
- package/dist/css-inline.js.map +1 -0
- package/dist/cx.d.ts +16 -0
- package/dist/cx.d.ts.map +1 -0
- package/dist/cx.js +20 -0
- package/dist/cx.js.map +1 -0
- package/dist/data.d.ts +136 -0
- package/dist/data.d.ts.map +1 -0
- package/dist/data.js +98 -0
- package/dist/data.js.map +1 -0
- package/dist/feedback.d.ts +88 -0
- package/dist/feedback.d.ts.map +1 -0
- package/dist/feedback.js +38 -0
- package/dist/feedback.js.map +1 -0
- package/dist/forms.d.ts +120 -0
- package/dist/forms.d.ts.map +1 -0
- package/dist/forms.js +60 -0
- package/dist/forms.js.map +1 -0
- package/dist/icon-data.d.ts +6 -0
- package/dist/icon-data.d.ts.map +1 -0
- package/dist/icon-data.js +77 -0
- package/dist/icon-data.js.map +1 -0
- package/dist/icon.d.ts +33 -0
- package/dist/icon.d.ts.map +1 -0
- package/dist/icon.js +13 -0
- package/dist/icon.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +41 -0
- package/dist/index.js.map +1 -0
- package/dist/layout.d.ts +166 -0
- package/dist/layout.d.ts.map +1 -0
- package/dist/layout.js +120 -0
- package/dist/layout.js.map +1 -0
- package/dist/navigation.d.ts +150 -0
- package/dist/navigation.d.ts.map +1 -0
- package/dist/navigation.js +104 -0
- package/dist/navigation.js.map +1 -0
- package/dist/overlays.d.ts +68 -0
- package/dist/overlays.d.ts.map +1 -0
- package/dist/overlays.js +114 -0
- package/dist/overlays.js.map +1 -0
- package/dist/surfaces.d.ts +61 -0
- package/dist/surfaces.d.ts.map +1 -0
- package/dist/surfaces.js +54 -0
- package/dist/surfaces.js.map +1 -0
- package/dist/typography.d.ts +89 -0
- package/dist/typography.d.ts.map +1 -0
- package/dist/typography.js +76 -0
- package/dist/typography.js.map +1 -0
- package/package.json +36 -4
- package/react/actions.tsx +138 -0
- package/react/catalogue.tsx +1644 -0
- package/react/content.tsx +313 -0
- package/react/css-inline.ts +14 -0
- package/react/cx.ts +20 -0
- package/react/data.tsx +300 -0
- package/react/feedback.tsx +229 -0
- package/react/forms.tsx +383 -0
- package/react/icon-data.ts +114 -0
- package/react/icon.tsx +84 -0
- package/react/index.ts +42 -0
- package/react/layout.tsx +347 -0
- package/react/navigation.tsx +329 -0
- package/react/overlays.tsx +237 -0
- package/react/surfaces.tsx +161 -0
- package/react/typography.tsx +220 -0
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import type { AnchorHTMLAttributes, ButtonHTMLAttributes, HTMLAttributes, ReactNode } from 'react';
|
|
2
|
+
type Div = Omit<HTMLAttributes<HTMLDivElement>, 'className'>;
|
|
3
|
+
type Span = Omit<HTMLAttributes<HTMLSpanElement>, 'className'>;
|
|
4
|
+
type A = Omit<AnchorHTMLAttributes<HTMLAnchorElement>, 'className'>;
|
|
5
|
+
type Btn = Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'className'>;
|
|
6
|
+
/** Une colonne, un filet, rien d'autre : ni ombre, ni rayon. Une ombre ferait
|
|
7
|
+
* flotter une pièce qui ne bouge jamais. Elle défile pour son propre compte —
|
|
8
|
+
* une nav longue n'entraîne jamais le contenu. */
|
|
9
|
+
export declare function Sidebar({ className, ...reste }: Div & {
|
|
10
|
+
className?: string;
|
|
11
|
+
}): import("react").JSX.Element;
|
|
12
|
+
export declare function SidebarHead({ className, ...reste }: Div & {
|
|
13
|
+
className?: string;
|
|
14
|
+
}): import("react").JSX.Element;
|
|
15
|
+
/** Collé en bas quand la nav est courte, il suit le contenu quand elle est
|
|
16
|
+
* longue. */
|
|
17
|
+
export declare function SidebarFoot({ className, ...reste }: Div & {
|
|
18
|
+
className?: string;
|
|
19
|
+
}): import("react").JSX.Element;
|
|
20
|
+
export interface SideGroupProps extends Div {
|
|
21
|
+
titre?: ReactNode;
|
|
22
|
+
className?: string;
|
|
23
|
+
children?: ReactNode;
|
|
24
|
+
}
|
|
25
|
+
export declare function SideGroup({ titre, className, children, ...reste }: SideGroupProps): import("react").JSX.Element;
|
|
26
|
+
export interface SideLinkProps extends A {
|
|
27
|
+
/** Pose `aria-current="page"` en plus de la classe : sans lui, l'entrée
|
|
28
|
+
* courante est marquée pour l'œil et muette au lecteur d'écran. */
|
|
29
|
+
courant?: boolean;
|
|
30
|
+
/** Rang mono ou glyphe, sur une colonne de largeur fixe — sinon les
|
|
31
|
+
* libellés se décalent d'un groupe à l'autre. */
|
|
32
|
+
num?: ReactNode;
|
|
33
|
+
className?: string;
|
|
34
|
+
children?: ReactNode;
|
|
35
|
+
}
|
|
36
|
+
export declare function SideLink({ courant, num, className, children, ...reste }: SideLinkProps): import("react").JSX.Element;
|
|
37
|
+
/** Elle REMPLACE la colonne sous le point de rupture : masquée au-dessus,
|
|
38
|
+
* elle n'apparaît que dans le bloc mobile du CSS. Ne pas la conditionner en
|
|
39
|
+
* JavaScript — le rendu serveur ne connaît pas la largeur de l'écran. */
|
|
40
|
+
export declare function Topbar({ className, ...reste }: Div & {
|
|
41
|
+
className?: string;
|
|
42
|
+
}): import("react").JSX.Element;
|
|
43
|
+
/** Le logo cède AVANT le nom : un logo client très large ne doit jamais
|
|
44
|
+
* pousser la barre hors de l'écran. */
|
|
45
|
+
export declare function TopbarLogo({ className, ...reste }: Div & {
|
|
46
|
+
className?: string;
|
|
47
|
+
}): import("react").JSX.Element;
|
|
48
|
+
export declare function TopbarTitle({ className, ...reste }: Span & {
|
|
49
|
+
className?: string;
|
|
50
|
+
}): import("react").JSX.Element;
|
|
51
|
+
export declare function TopbarBurger({ className, type, ...reste }: Btn & {
|
|
52
|
+
className?: string;
|
|
53
|
+
}): import("react").JSX.Element;
|
|
54
|
+
/** Croix bordée du chrome — fermeture d'un tiroir, d'une feuille de source.
|
|
55
|
+
* Angles vifs : le rayon signale l'action, le chrome n'en est pas une. */
|
|
56
|
+
export declare function ChromeButton({ className, type, ...reste }: Btn & {
|
|
57
|
+
className?: string;
|
|
58
|
+
'aria-label': string;
|
|
59
|
+
}): import("react").JSX.Element;
|
|
60
|
+
export interface CrumbsProps extends Omit<A, 'children'> {
|
|
61
|
+
/** Les segments, du plus général au plus précis. Le DERNIER est plus sombre :
|
|
62
|
+
* c'est celui qu'on lit, le reste n'est qu'un chemin. */
|
|
63
|
+
segments: ReactNode[];
|
|
64
|
+
/** Séparateur. Le `/` par défaut est celui du relevé. */
|
|
65
|
+
separateur?: ReactNode;
|
|
66
|
+
className?: string;
|
|
67
|
+
}
|
|
68
|
+
/** ⚠️ Le fil ENTIER est cliquable — c'est un seul nœud, pas une liste de
|
|
69
|
+
* liens. Sans `href`, il se rend en `<span>` : un `<a>` sans cible reste
|
|
70
|
+
* annoncé comme un lien et déçoit. */
|
|
71
|
+
export declare function Crumbs({ segments, separateur, href, className, ...reste }: CrumbsProps): import("react").JSX.Element;
|
|
72
|
+
/** À poser dans un `SelectAnchor` (forms) : c'est l'enveloppe qui ancre le
|
|
73
|
+
* menu, pas le déclencheur — l'ancrer sur le déclencheur casse sa largeur
|
|
74
|
+
* maximale calculée sur la fenêtre. */
|
|
75
|
+
export declare function Menu({ className, ...reste }: Div & {
|
|
76
|
+
className?: string;
|
|
77
|
+
role?: string;
|
|
78
|
+
}): import("react").JSX.Element;
|
|
79
|
+
export interface MenuItemProps extends Btn {
|
|
80
|
+
/** Pose `aria-selected` en plus de la classe. */
|
|
81
|
+
actif?: boolean;
|
|
82
|
+
className?: string;
|
|
83
|
+
}
|
|
84
|
+
export declare function MenuItem({ actif, className, type, ...reste }: MenuItemProps): import("react").JSX.Element;
|
|
85
|
+
export interface TabsProps<T extends string> {
|
|
86
|
+
onglets: readonly {
|
|
87
|
+
id: T;
|
|
88
|
+
label: ReactNode;
|
|
89
|
+
compte?: ReactNode;
|
|
90
|
+
}[];
|
|
91
|
+
actif: T;
|
|
92
|
+
onChange: (id: T) => void;
|
|
93
|
+
/** Rangée qui défile au lieu de passer à la ligne. */
|
|
94
|
+
rail?: boolean;
|
|
95
|
+
/** Identifiant du panneau piloté, pour `aria-controls`. */
|
|
96
|
+
panneau?: string;
|
|
97
|
+
className?: string;
|
|
98
|
+
}
|
|
99
|
+
/** ⚠️ Il n'existe AUCUNE classe d'onglet dans le CSS, et c'est délibéré : une
|
|
100
|
+
* rangée d'onglets est une rangée de puces, avec la grammaire d'état de
|
|
101
|
+
* `Seg`. Un onglet SOULIGNÉ reste à faire — il suppose d'arbitrer couleur et
|
|
102
|
+
* épaisseur du trait actif, ce qu'aucune source ne donne. Ce composant
|
|
103
|
+
* n'ajoute donc que l'ARIA, pas un style de plus. */
|
|
104
|
+
export declare function Tabs<T extends string>({ onglets, actif, onChange, rail, panneau, className, }: TabsProps<T>): import("react").JSX.Element;
|
|
105
|
+
export interface PagerProps extends Div {
|
|
106
|
+
/** Pied de tableau : compte à gauche, sens à droite. C'est un MODIFICATEUR,
|
|
107
|
+
* il se pose avec `Pager`, jamais seul. */
|
|
108
|
+
pied?: boolean;
|
|
109
|
+
className?: string;
|
|
110
|
+
}
|
|
111
|
+
export declare function Pager({ pied, className, ...reste }: PagerProps): import("react").JSX.Element;
|
|
112
|
+
/** ⚠️ Une flèche désactivée reste ATTEIGNABLE au clavier (`aria-disabled` et
|
|
113
|
+
* non `disabled`) : sinon elle disparaît du parcours sans être annoncée. */
|
|
114
|
+
export declare function PagerArrow({ desactive, className, type, ...reste }: Btn & {
|
|
115
|
+
desactive?: boolean;
|
|
116
|
+
className?: string;
|
|
117
|
+
'aria-label': string;
|
|
118
|
+
}): import("react").JSX.Element;
|
|
119
|
+
/** Le rang courant (« p. 12 / 31 »). Cliquable dans le relevé : il ouvre la
|
|
120
|
+
* saisie directe d'un numéro. */
|
|
121
|
+
export declare function PagerRank({ className, type, ...reste }: Btn & {
|
|
122
|
+
className?: string;
|
|
123
|
+
}): import("react").JSX.Element;
|
|
124
|
+
/** « ‹ Précédent · Suivant › » du pied de tableau. */
|
|
125
|
+
export declare function PagerStep({ className, type, ...reste }: Btn & {
|
|
126
|
+
className?: string;
|
|
127
|
+
}): import("react").JSX.Element;
|
|
128
|
+
export interface CitePanelProps extends Div {
|
|
129
|
+
titre?: ReactNode;
|
|
130
|
+
/** Croix de fermeture et actions de tête. */
|
|
131
|
+
actions?: ReactNode;
|
|
132
|
+
pied?: ReactNode;
|
|
133
|
+
className?: string;
|
|
134
|
+
children?: ReactNode;
|
|
135
|
+
}
|
|
136
|
+
export declare function CitePanel({ titre, actions, pied, className, children, ...reste }: CitePanelProps): import("react").JSX.Element;
|
|
137
|
+
export interface ScrollProps extends Div {
|
|
138
|
+
/** Barre fine, aux couleurs du système. OPT-IN : par défaut la barre native
|
|
139
|
+
* est conservée — sur macOS et iOS, l'habiller la rend permanente et elle
|
|
140
|
+
* mange une colonne. */
|
|
141
|
+
habillee?: boolean;
|
|
142
|
+
className?: string;
|
|
143
|
+
}
|
|
144
|
+
/** ⚠️ Porte `min-height: 0` ET `min-width: 0`. Sans les deux, un enfant flex
|
|
145
|
+
* refuse de rétrécir sous son contenu : la zone déborde et c'est la PAGE qui
|
|
146
|
+
* part en défilement horizontal. C'est la faute la plus fréquente de ce
|
|
147
|
+
* gabarit. */
|
|
148
|
+
export declare function Scroll({ habillee, className, ...reste }: ScrollProps): import("react").JSX.Element;
|
|
149
|
+
export {};
|
|
150
|
+
//# sourceMappingURL=navigation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"navigation.d.ts","sourceRoot":"","sources":["../react/navigation.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { cx } from './cx.js';
|
|
3
|
+
import { Seg, SegGroup } from './forms.js';
|
|
4
|
+
/* ─── Colonne latérale ─────────────────────────────────────────────── */
|
|
5
|
+
/** Une colonne, un filet, rien d'autre : ni ombre, ni rayon. Une ombre ferait
|
|
6
|
+
* flotter une pièce qui ne bouge jamais. Elle défile pour son propre compte —
|
|
7
|
+
* une nav longue n'entraîne jamais le contenu. */
|
|
8
|
+
export function Sidebar({ className, ...reste }) {
|
|
9
|
+
return _jsx("aside", { className: cx('zv-sidebar', className), ...reste });
|
|
10
|
+
}
|
|
11
|
+
export function SidebarHead({ className, ...reste }) {
|
|
12
|
+
return _jsx("div", { className: cx('zv-sidebar__head', className), ...reste });
|
|
13
|
+
}
|
|
14
|
+
/** Collé en bas quand la nav est courte, il suit le contenu quand elle est
|
|
15
|
+
* longue. */
|
|
16
|
+
export function SidebarFoot({ className, ...reste }) {
|
|
17
|
+
return _jsx("div", { className: cx('zv-sidebar__foot', className), ...reste });
|
|
18
|
+
}
|
|
19
|
+
export function SideGroup({ titre, className, children, ...reste }) {
|
|
20
|
+
return (_jsxs("div", { className: cx('zv-sidegroup', className), ...reste, children: [titre && _jsx("div", { className: "zv-sidegroup__title", children: titre }), children] }));
|
|
21
|
+
}
|
|
22
|
+
export function SideLink({ courant, num, className, children, ...reste }) {
|
|
23
|
+
return (_jsxs("a", { "aria-current": courant ? 'page' : undefined, className: cx('zv-sidelink', courant && 'zv-sidelink--on', className), ...reste, children: [num != null && _jsx("span", { className: "zv-sidelink__num", children: num }), children] }));
|
|
24
|
+
}
|
|
25
|
+
/* ─── Barre supérieure ─────────────────────────────────────────────── */
|
|
26
|
+
/** Elle REMPLACE la colonne sous le point de rupture : masquée au-dessus,
|
|
27
|
+
* elle n'apparaît que dans le bloc mobile du CSS. Ne pas la conditionner en
|
|
28
|
+
* JavaScript — le rendu serveur ne connaît pas la largeur de l'écran. */
|
|
29
|
+
export function Topbar({ className, ...reste }) {
|
|
30
|
+
return _jsx("header", { className: cx('zv-topbar', className), ...reste });
|
|
31
|
+
}
|
|
32
|
+
/** Le logo cède AVANT le nom : un logo client très large ne doit jamais
|
|
33
|
+
* pousser la barre hors de l'écran. */
|
|
34
|
+
export function TopbarLogo({ className, ...reste }) {
|
|
35
|
+
return _jsx("div", { className: cx('zv-topbar__logo', className), ...reste });
|
|
36
|
+
}
|
|
37
|
+
export function TopbarTitle({ className, ...reste }) {
|
|
38
|
+
return _jsx("span", { className: cx('zv-topbar__title', className), ...reste });
|
|
39
|
+
}
|
|
40
|
+
export function TopbarBurger({ className, type = 'button', ...reste }) {
|
|
41
|
+
return _jsx("button", { type: type, className: cx('zv-topbar__burger', className), ...reste });
|
|
42
|
+
}
|
|
43
|
+
/** Croix bordée du chrome — fermeture d'un tiroir, d'une feuille de source.
|
|
44
|
+
* Angles vifs : le rayon signale l'action, le chrome n'en est pas une. */
|
|
45
|
+
export function ChromeButton({ className, type = 'button', ...reste }) {
|
|
46
|
+
return _jsx("button", { type: type, className: cx('zv-chrome-btn', className), ...reste });
|
|
47
|
+
}
|
|
48
|
+
/** ⚠️ Le fil ENTIER est cliquable — c'est un seul nœud, pas une liste de
|
|
49
|
+
* liens. Sans `href`, il se rend en `<span>` : un `<a>` sans cible reste
|
|
50
|
+
* annoncé comme un lien et déçoit. */
|
|
51
|
+
export function Crumbs({ segments, separateur = '/', href, className, ...reste }) {
|
|
52
|
+
const contenu = segments.map((seg, i) => (_jsxs("span", { children: [i > 0 && (_jsx("span", { className: "zv-crumbs__sep", "aria-hidden": "true", children: separateur })), _jsx("span", { className: i === segments.length - 1 ? 'zv-crumbs__seg' : undefined, children: seg })] }, i)));
|
|
53
|
+
const classe = cx('zv-crumbs', className);
|
|
54
|
+
if (!href) {
|
|
55
|
+
return _jsx("span", { className: classe, children: contenu });
|
|
56
|
+
}
|
|
57
|
+
return (_jsx("a", { href: href, className: classe, ...reste, children: contenu }));
|
|
58
|
+
}
|
|
59
|
+
/* ─── Menu déroulant ───────────────────────────────────────────────── */
|
|
60
|
+
/** À poser dans un `SelectAnchor` (forms) : c'est l'enveloppe qui ancre le
|
|
61
|
+
* menu, pas le déclencheur — l'ancrer sur le déclencheur casse sa largeur
|
|
62
|
+
* maximale calculée sur la fenêtre. */
|
|
63
|
+
export function Menu({ className, ...reste }) {
|
|
64
|
+
return _jsx("div", { role: "listbox", className: cx('zv-menu', className), ...reste });
|
|
65
|
+
}
|
|
66
|
+
export function MenuItem({ actif, className, type = 'button', ...reste }) {
|
|
67
|
+
return (_jsx("button", { type: type, role: "option", "aria-selected": actif ?? false, className: cx('zv-menu__item', actif && 'zv-menu__item--on', className), ...reste }));
|
|
68
|
+
}
|
|
69
|
+
/** ⚠️ Il n'existe AUCUNE classe d'onglet dans le CSS, et c'est délibéré : une
|
|
70
|
+
* rangée d'onglets est une rangée de puces, avec la grammaire d'état de
|
|
71
|
+
* `Seg`. Un onglet SOULIGNÉ reste à faire — il suppose d'arbitrer couleur et
|
|
72
|
+
* épaisseur du trait actif, ce qu'aucune source ne donne. Ce composant
|
|
73
|
+
* n'ajoute donc que l'ARIA, pas un style de plus. */
|
|
74
|
+
export function Tabs({ onglets, actif, onChange, rail, panneau, className, }) {
|
|
75
|
+
return (_jsx(SegGroup, { role: "tablist", rail: rail, className: className, children: onglets.map((o) => (_jsx(Seg, { role: "tab", "aria-selected": o.id === actif, "aria-controls": panneau, on: o.id === actif, compte: o.compte, onClick: () => onChange(o.id), children: o.label }, o.id))) }));
|
|
76
|
+
}
|
|
77
|
+
export function Pager({ pied, className, ...reste }) {
|
|
78
|
+
return (_jsx("nav", { className: cx('zv-pager', pied && 'zv-pager--foot', className), ...reste }));
|
|
79
|
+
}
|
|
80
|
+
/** ⚠️ Une flèche désactivée reste ATTEIGNABLE au clavier (`aria-disabled` et
|
|
81
|
+
* non `disabled`) : sinon elle disparaît du parcours sans être annoncée. */
|
|
82
|
+
export function PagerArrow({ desactive, className, type = 'button', ...reste }) {
|
|
83
|
+
return (_jsx("button", { type: type, "aria-disabled": desactive || undefined, className: cx('zv-pager__arrow', className), ...reste }));
|
|
84
|
+
}
|
|
85
|
+
/** Le rang courant (« p. 12 / 31 »). Cliquable dans le relevé : il ouvre la
|
|
86
|
+
* saisie directe d'un numéro. */
|
|
87
|
+
export function PagerRank({ className, type = 'button', ...reste }) {
|
|
88
|
+
return _jsx("button", { type: type, className: cx('zv-pager__rank', className), ...reste });
|
|
89
|
+
}
|
|
90
|
+
/** « ‹ Précédent · Suivant › » du pied de tableau. */
|
|
91
|
+
export function PagerStep({ className, type = 'button', ...reste }) {
|
|
92
|
+
return _jsx("button", { type: type, className: cx('zv-pager__step', className), ...reste });
|
|
93
|
+
}
|
|
94
|
+
export function CitePanel({ titre, actions, pied, className, children, ...reste }) {
|
|
95
|
+
return (_jsxs("div", { className: cx('zv-cite-panel', className), ...reste, children: [_jsxs("div", { className: "zv-cite-panel__head", children: [titre && _jsx("span", { className: "zv-cite-panel__title", children: titre }), actions] }), _jsx("div", { className: "zv-cite-panel__body", children: children }), pied && _jsx("div", { className: "zv-cite-panel__foot", children: pied })] }));
|
|
96
|
+
}
|
|
97
|
+
/** ⚠️ Porte `min-height: 0` ET `min-width: 0`. Sans les deux, un enfant flex
|
|
98
|
+
* refuse de rétrécir sous son contenu : la zone déborde et c'est la PAGE qui
|
|
99
|
+
* part en défilement horizontal. C'est la faute la plus fréquente de ce
|
|
100
|
+
* gabarit. */
|
|
101
|
+
export function Scroll({ habillee, className, ...reste }) {
|
|
102
|
+
return (_jsx("div", { className: cx('zv-scroll-y', habillee && 'zv-scrollbar', className), ...reste }));
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=navigation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"navigation.js","sourceRoot":"","sources":["../react/navigation.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { HTMLAttributes, ReactNode, RefObject } from 'react';
|
|
2
|
+
type Div = Omit<HTMLAttributes<HTMLDivElement>, 'className'>;
|
|
3
|
+
export interface UseOverlayOptions {
|
|
4
|
+
ouvert: boolean;
|
|
5
|
+
onClose: () => void;
|
|
6
|
+
/** Le nœud à piéger. Sans lui, pas de piège — mais Échap fonctionne quand
|
|
7
|
+
* même. */
|
|
8
|
+
panneau?: RefObject<HTMLElement | null>;
|
|
9
|
+
/** Verrouille le défilement du document. Vrai pour une modale, vrai pour un
|
|
10
|
+
* tiroir mobile ; faux pour ce qui ne recouvre pas la page. */
|
|
11
|
+
verrouille?: boolean;
|
|
12
|
+
}
|
|
13
|
+
/** Échap, piège de focus, restitution du focus, verrou de défilement.
|
|
14
|
+
* Exporté : une app qui dessine son propre enrobage doit pouvoir reprendre
|
|
15
|
+
* ce comportement sans recopier trente lignes qui se trompent une fois sur
|
|
16
|
+
* deux. */
|
|
17
|
+
export declare function useOverlay({ ouvert, onClose, panneau, verrouille }: UseOverlayOptions): void;
|
|
18
|
+
/** Toujours l'encre de charte diluée, jamais un noir pur : la page est
|
|
19
|
+
* bleutée, un gris neutre y ferait un trou sale. */
|
|
20
|
+
export declare function Scrim({ className, ...reste }: Div & {
|
|
21
|
+
className?: string;
|
|
22
|
+
}): import("react").JSX.Element;
|
|
23
|
+
export interface DrawerProps extends Omit<Div, 'title'> {
|
|
24
|
+
ouvert: boolean;
|
|
25
|
+
onClose: () => void;
|
|
26
|
+
/** Nom du dialogue — ce que le lecteur d'écran annonce à l'ouverture. */
|
|
27
|
+
label?: string;
|
|
28
|
+
/** Croix de fermeture posée en absolu par-dessus la tête du panneau. */
|
|
29
|
+
fermeture?: ReactNode;
|
|
30
|
+
className?: string;
|
|
31
|
+
children?: ReactNode;
|
|
32
|
+
}
|
|
33
|
+
/** ⚠️ Le tiroir n'existe QUE sous le point de rupture : au-dessus, la
|
|
34
|
+
* navigation est une colonne et il n'y a rien à ouvrir. Le CSS s'en charge —
|
|
35
|
+
* ne pas conditionner le rendu sur la largeur en JavaScript, le serveur ne
|
|
36
|
+
* la connaît pas. */
|
|
37
|
+
export declare function Drawer({ ouvert, onClose, label, fermeture, className, children, ...reste }: DrawerProps): import("react").JSX.Element;
|
|
38
|
+
export interface ModalProps extends Omit<Div, 'title'> {
|
|
39
|
+
ouvert: boolean;
|
|
40
|
+
onClose: () => void;
|
|
41
|
+
titre?: ReactNode;
|
|
42
|
+
/** Actions de tête, à droite du titre (la croix, en général). */
|
|
43
|
+
actions?: ReactNode;
|
|
44
|
+
/** Pied d'actions. Il reste visible quand le corps défile — c'est tout
|
|
45
|
+
* l'intérêt du plafond de hauteur. */
|
|
46
|
+
pied?: ReactNode;
|
|
47
|
+
/** Modale destructive : le filet HAUT porte l'avertissement, pas un fond
|
|
48
|
+
* rouge — une surface d'alerte pleine rendrait le texte pénible à lire. */
|
|
49
|
+
danger?: boolean;
|
|
50
|
+
className?: string;
|
|
51
|
+
children?: ReactNode;
|
|
52
|
+
}
|
|
53
|
+
export declare function Modal({ ouvert, onClose, titre, actions, pied, danger, className, children, ...reste }: ModalProps): import("react").JSX.Element | null;
|
|
54
|
+
/** Le conteneur ne capte RIEN : seules les notifications le font, sans quoi
|
|
55
|
+
* une colonne invisible bloquerait les clics dans tout le coin de l'écran. */
|
|
56
|
+
export declare function Toasts({ className, ...reste }: Div & {
|
|
57
|
+
className?: string;
|
|
58
|
+
}): import("react").JSX.Element;
|
|
59
|
+
export interface ToastProps extends Div {
|
|
60
|
+
ton?: 'ok' | 'err';
|
|
61
|
+
className?: string;
|
|
62
|
+
}
|
|
63
|
+
/** ⚠️ Ne remplace PAS `Alert` : une erreur de formulaire se dit à côté du
|
|
64
|
+
* champ, jamais dans un coin qui disparaît. Réserver ce composant à ce qui
|
|
65
|
+
* est vrai APRÈS COUP — « copié », « enregistré », « envoyé ». */
|
|
66
|
+
export declare function Toast({ ton, className, ...reste }: ToastProps): import("react").JSX.Element;
|
|
67
|
+
export {};
|
|
68
|
+
//# sourceMappingURL=overlays.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"overlays.d.ts","sourceRoot":"","sources":["../react/overlays.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAGjE,KAAK,GAAG,GAAG,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,WAAW,CAAC,CAAA;AAK5D,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,OAAO,CAAA;IACf,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB;gBACY;IACZ,OAAO,CAAC,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAA;IACvC;oEACgE;IAChE,UAAU,CAAC,EAAE,OAAO,CAAA;CACrB;AAED;;;YAGY;AACZ,wBAAgB,UAAU,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,UAAiB,EAAE,EAAE,iBAAiB,QAwD5F;AAID;qDACqD;AACrD,wBAAgB,KAAK,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG,GAAG;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,+BAE1E;AAID,MAAM,WAAW,WAAY,SAAQ,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC;IACrD,MAAM,EAAE,OAAO,CAAA;IACf,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,yEAAyE;IACzE,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,wEAAwE;IACxE,SAAS,CAAC,EAAE,SAAS,CAAA;IACrB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,SAAS,CAAA;CACrB;AAED;;;sBAGsB;AACtB,wBAAgB,MAAM,CAAC,EACrB,MAAM,EACN,OAAO,EACP,KAAoB,EACpB,SAAS,EACT,SAAS,EACT,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,WAAW,+BAqBb;AAID,MAAM,WAAW,UAAW,SAAQ,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC;IACpD,MAAM,EAAE,OAAO,CAAA;IACf,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB,iEAAiE;IACjE,OAAO,CAAC,EAAE,SAAS,CAAA;IACnB;2CACuC;IACvC,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB;gFAC4E;IAC5E,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,SAAS,CAAA;CACrB;AAED,wBAAgB,KAAK,CAAC,EACpB,MAAM,EACN,OAAO,EACP,KAAK,EACL,OAAO,EACP,IAAI,EACJ,MAAM,EACN,SAAS,EACT,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,UAAU,sCA+BZ;AAID;+EAC+E;AAC/E,wBAAgB,MAAM,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG,GAAG;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,+BAS3E;AAED,MAAM,WAAW,UAAW,SAAQ,GAAG;IACrC,GAAG,CAAC,EAAE,IAAI,GAAG,KAAK,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED;;mEAEmE;AACnE,wBAAgB,KAAK,CAAC,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,UAAU,+BAE7D"}
|
package/dist/overlays.js
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
// Enrobages — voile, tiroir, modale, notification flottante.
|
|
4
|
+
//
|
|
5
|
+
// SEUL fichier du paquet marqué « use client », avec un hook. Tout ce qui vit
|
|
6
|
+
// ici vole le regard à la page : il faut une touche Échap, un piège de focus
|
|
7
|
+
// et un verrou de défilement, et rien de cela ne s'écrit en CSS.
|
|
8
|
+
//
|
|
9
|
+
// ⚠️ Ne PAS écrire `data-open={ouvert}` en React : cela rend `data-open="false"`,
|
|
10
|
+
// que le sélecteur d'attribut du CSS considère comme PRÉSENT — le panneau
|
|
11
|
+
// resterait ouvert. Ces composants emploient la classe `--open`, prévue pour ça.
|
|
12
|
+
import { useCallback, useEffect, useRef } from 'react';
|
|
13
|
+
import { cx } from './cx.js';
|
|
14
|
+
const FOCUSABLES = 'a[href],button:not([disabled]),input:not([disabled]),select:not([disabled]),textarea:not([disabled]),[tabindex]:not([tabindex="-1"])';
|
|
15
|
+
/** Échap, piège de focus, restitution du focus, verrou de défilement.
|
|
16
|
+
* Exporté : une app qui dessine son propre enrobage doit pouvoir reprendre
|
|
17
|
+
* ce comportement sans recopier trente lignes qui se trompent une fois sur
|
|
18
|
+
* deux. */
|
|
19
|
+
export function useOverlay({ ouvert, onClose, panneau, verrouille = true }) {
|
|
20
|
+
// Le nœud qui avait le focus AVANT l'ouverture : c'est à lui qu'il revient
|
|
21
|
+
// à la fermeture. Sans cela, le focus repart au début du document et un
|
|
22
|
+
// utilisateur au clavier perd sa place dans la page.
|
|
23
|
+
const origine = useRef(null);
|
|
24
|
+
useEffect(() => {
|
|
25
|
+
if (!ouvert)
|
|
26
|
+
return;
|
|
27
|
+
const cible = panneau?.current;
|
|
28
|
+
// ⚠️ Le document du PANNEAU, pas `document` : un enrobage peut vivre dans
|
|
29
|
+
// un autre document que celui du script (planche de composants rendue dans
|
|
30
|
+
// un iframe, fenêtre détachée). Écouter `document` y poserait la touche
|
|
31
|
+
// Échap sur la page hôte — elle fermerait la modale d'à côté et pas
|
|
32
|
+
// celle-ci. Sans panneau, on retombe sur le document courant.
|
|
33
|
+
const docu = cible?.ownerDocument ?? document;
|
|
34
|
+
origine.current = docu.activeElement;
|
|
35
|
+
// ⚠️ La valeur PRÉCÉDENTE est restaurée, pas remise à '' : une page qui
|
|
36
|
+
// gérait déjà son propre défilement serait cassée par un reset aveugle.
|
|
37
|
+
const overflowPrecedent = verrouille ? docu.body.style.overflow : null;
|
|
38
|
+
if (verrouille)
|
|
39
|
+
docu.body.style.overflow = 'hidden';
|
|
40
|
+
const premier = cible?.querySelector(FOCUSABLES);
|
|
41
|
+
premier?.focus();
|
|
42
|
+
function onKey(e) {
|
|
43
|
+
if (e.key === 'Escape') {
|
|
44
|
+
e.stopPropagation();
|
|
45
|
+
onClose();
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
if (e.key !== 'Tab' || !cible)
|
|
49
|
+
return;
|
|
50
|
+
const noeuds = Array.from(cible.querySelectorAll(FOCUSABLES)).filter((n) => n.offsetParent !== null || n === docu.activeElement);
|
|
51
|
+
if (noeuds.length === 0)
|
|
52
|
+
return;
|
|
53
|
+
const debut = noeuds[0];
|
|
54
|
+
const fin = noeuds[noeuds.length - 1];
|
|
55
|
+
// Le cycle est refermé à la main : sans cela, Tab sort du panneau et
|
|
56
|
+
// l'utilisateur se retrouve à parcourir la page cachée derrière le voile.
|
|
57
|
+
if (e.shiftKey && docu.activeElement === debut) {
|
|
58
|
+
e.preventDefault();
|
|
59
|
+
fin.focus();
|
|
60
|
+
}
|
|
61
|
+
else if (!e.shiftKey && docu.activeElement === fin) {
|
|
62
|
+
e.preventDefault();
|
|
63
|
+
debut.focus();
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
docu.addEventListener('keydown', onKey);
|
|
67
|
+
return () => {
|
|
68
|
+
docu.removeEventListener('keydown', onKey);
|
|
69
|
+
if (overflowPrecedent !== null)
|
|
70
|
+
docu.body.style.overflow = overflowPrecedent;
|
|
71
|
+
origine.current?.focus?.();
|
|
72
|
+
};
|
|
73
|
+
}, [ouvert, onClose, panneau, verrouille]);
|
|
74
|
+
}
|
|
75
|
+
/* ─── Voile ────────────────────────────────────────────────────────── */
|
|
76
|
+
/** Toujours l'encre de charte diluée, jamais un noir pur : la page est
|
|
77
|
+
* bleutée, un gris neutre y ferait un trou sale. */
|
|
78
|
+
export function Scrim({ className, ...reste }) {
|
|
79
|
+
return _jsx("div", { className: cx('zv-scrim', className), "aria-hidden": "true", ...reste });
|
|
80
|
+
}
|
|
81
|
+
/** ⚠️ Le tiroir n'existe QUE sous le point de rupture : au-dessus, la
|
|
82
|
+
* navigation est une colonne et il n'y a rien à ouvrir. Le CSS s'en charge —
|
|
83
|
+
* ne pas conditionner le rendu sur la largeur en JavaScript, le serveur ne
|
|
84
|
+
* la connaît pas. */
|
|
85
|
+
export function Drawer({ ouvert, onClose, label = 'Navigation', fermeture, className, children, ...reste }) {
|
|
86
|
+
const panneau = useRef(null);
|
|
87
|
+
useOverlay({ ouvert, onClose, panneau });
|
|
88
|
+
const fermer = useCallback(() => onClose(), [onClose]);
|
|
89
|
+
return (_jsxs("div", { role: "dialog", "aria-modal": "true", "aria-label": label, "aria-hidden": !ouvert, className: cx('zv-drawer', ouvert && 'zv-drawer--open', className), ...reste, children: [_jsx("div", { className: "zv-scrim", onClick: fermer, "aria-hidden": "true" }), _jsxs("div", { className: "zv-drawer__panel", ref: panneau, children: [fermeture && _jsx("div", { className: "zv-drawer__close", children: fermeture }), children] })] }));
|
|
90
|
+
}
|
|
91
|
+
export function Modal({ ouvert, onClose, titre, actions, pied, danger, className, children, ...reste }) {
|
|
92
|
+
const panneau = useRef(null);
|
|
93
|
+
useOverlay({ ouvert, onClose, panneau });
|
|
94
|
+
const fermer = useCallback(() => onClose(), [onClose]);
|
|
95
|
+
// Une modale fermée n'est pas rendue du tout : contrairement au tiroir, elle
|
|
96
|
+
// n'a pas d'animation d'entrée à préserver, et son contenu (un formulaire,
|
|
97
|
+
// le plus souvent) ne doit pas rester dans le DOM à l'état fantôme.
|
|
98
|
+
if (!ouvert)
|
|
99
|
+
return null;
|
|
100
|
+
return (_jsxs("div", { role: "dialog", "aria-modal": "true", "aria-label": typeof titre === 'string' ? titre : undefined, className: cx('zv-modal', 'zv-modal--open', danger && 'zv-modal--danger', className), ...reste, children: [_jsx("div", { className: "zv-scrim", onClick: fermer, "aria-hidden": "true" }), _jsxs("div", { className: "zv-modal__panel", ref: panneau, children: [(titre || actions) && (_jsxs("div", { className: "zv-modal__head", children: [titre && _jsx("h2", { className: "zv-modal__title", children: titre }), actions] })), _jsx("div", { className: "zv-modal__body", children: children }), pied && _jsx("div", { className: "zv-modal__foot", children: pied })] })] }));
|
|
101
|
+
}
|
|
102
|
+
/* ─── Notification flottante ───────────────────────────────────────── */
|
|
103
|
+
/** Le conteneur ne capte RIEN : seules les notifications le font, sans quoi
|
|
104
|
+
* une colonne invisible bloquerait les clics dans tout le coin de l'écran. */
|
|
105
|
+
export function Toasts({ className, ...reste }) {
|
|
106
|
+
return (_jsx("div", { className: cx('zv-toasts', className), role: "region", "aria-live": "polite", ...reste }));
|
|
107
|
+
}
|
|
108
|
+
/** ⚠️ Ne remplace PAS `Alert` : une erreur de formulaire se dit à côté du
|
|
109
|
+
* champ, jamais dans un coin qui disparaît. Réserver ce composant à ce qui
|
|
110
|
+
* est vrai APRÈS COUP — « copié », « enregistré », « envoyé ». */
|
|
111
|
+
export function Toast({ ton, className, ...reste }) {
|
|
112
|
+
return _jsx("div", { className: cx('zv-toast', ton && `zv-toast--${ton}`, className), ...reste });
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=overlays.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"overlays.js","sourceRoot":"","sources":["../react/overlays.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { HTMLAttributes, ReactNode } from 'react';
|
|
2
|
+
type Div = Omit<HTMLAttributes<HTMLDivElement>, 'className'>;
|
|
3
|
+
/** Le violet et le cyan du spectre, très dilués. Ce n'est PAS un emploi du
|
|
4
|
+
* spectre en aplat : c'est une lumière — elle ne compte pas dans les trois
|
|
5
|
+
* emplois autorisés. */
|
|
6
|
+
export declare function Halo({ place, className, ...reste }: Div & {
|
|
7
|
+
place: 'hero' | 'cta' | 'core';
|
|
8
|
+
className?: string;
|
|
9
|
+
}): import("react").JSX.Element;
|
|
10
|
+
export declare function GridFloor({ carte, className, ...reste }: Div & {
|
|
11
|
+
carte?: boolean;
|
|
12
|
+
className?: string;
|
|
13
|
+
}): import("react").JSX.Element;
|
|
14
|
+
/** Éteint le bas d'une scène pour que le texte qui la suit reste lisible.
|
|
15
|
+
* `blanc` quand la page est blanche sous la scène. */
|
|
16
|
+
export declare function Fade({ blanc, className, ...reste }: Div & {
|
|
17
|
+
blanc?: boolean;
|
|
18
|
+
className?: string;
|
|
19
|
+
}): import("react").JSX.Element;
|
|
20
|
+
export interface BandProps extends Div {
|
|
21
|
+
/** Glyphe en filigrane, très dilué, dans un coin. */
|
|
22
|
+
filigrane?: ReactNode;
|
|
23
|
+
/** Lueur d'accent derrière le contenu. */
|
|
24
|
+
lueur?: boolean;
|
|
25
|
+
className?: string;
|
|
26
|
+
children?: ReactNode;
|
|
27
|
+
}
|
|
28
|
+
/** LA surface sombre du système. ⚠️ Les surfaces sombres se font avec elle et
|
|
29
|
+
* `--accent-on-dark`, JAMAIS en inversant les neutres : les contrastes ont
|
|
30
|
+
* été réglés dans ce sens-là et pas dans l'autre. */
|
|
31
|
+
export declare function Band({ filigrane, lueur, className, children, ...reste }: BandProps): import("react").JSX.Element;
|
|
32
|
+
/** Panneau sombre plus petit qu'une bande : une carte, un encart. */
|
|
33
|
+
export declare function PanelNavy({ className, ...reste }: Div & {
|
|
34
|
+
className?: string;
|
|
35
|
+
}): import("react").JSX.Element;
|
|
36
|
+
/** Repeint un texte pour une surface sombre. `Band` le fait déjà pour son
|
|
37
|
+
* contenu courant — cette classe sert aux cas isolés. */
|
|
38
|
+
export declare function TextOnDark({ className, ...reste }: Div & {
|
|
39
|
+
className?: string;
|
|
40
|
+
}): import("react").JSX.Element;
|
|
41
|
+
export interface GlyphProps extends Div {
|
|
42
|
+
/** `deep` accentue l'ombre portée, `watermark` dilue le glyphe jusqu'au
|
|
43
|
+
* filigrane. */
|
|
44
|
+
variante?: 'deep' | 'watermark';
|
|
45
|
+
className?: string;
|
|
46
|
+
children?: ReactNode;
|
|
47
|
+
}
|
|
48
|
+
/** Enveloppe d'un logo de produit posé comme motif. Le glyphe lui-même est
|
|
49
|
+
* une image du paquet (`@zevra/ui/logos/…`), pas un tracé du CSS. */
|
|
50
|
+
export declare function Glyph({ variante, className, children, ...reste }: GlyphProps): import("react").JSX.Element;
|
|
51
|
+
export type Animation = 'rise' | 'pop' | 'filet' | 'glyph-in' | 'converge' | 'breathe' | 'drift' | 'dot-active' | 'progress';
|
|
52
|
+
/** Les neuf animations du paquet, nommées. ⚠️ Elles sont pilotées AU
|
|
53
|
+
* DÉFILEMENT et réservées à la vitrine : le chrome applicatif n'anime rien.
|
|
54
|
+
* `prefers-reduced-motion` les coupe toutes, globalement, depuis base.css.
|
|
55
|
+
*
|
|
56
|
+
* `option` échelonne les entrées d'une même rangée (`pop`, rangs 2 à 6) ou
|
|
57
|
+
* donne le coin d'arrivée (`converge` : tr, bl, br — le défaut vient du
|
|
58
|
+
* haut-gauche). Passée à une autre animation, elle est ignorée. */
|
|
59
|
+
export declare function anim(nom: Animation, option?: 2 | 3 | 4 | 5 | 6 | 'tr' | 'bl' | 'br'): string;
|
|
60
|
+
export {};
|
|
61
|
+
//# sourceMappingURL=surfaces.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"surfaces.d.ts","sourceRoot":"","sources":["../react/surfaces.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAGtD,KAAK,GAAG,GAAG,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,WAAW,CAAC,CAAA;AAI5D;;yBAEyB;AACzB,wBAAgB,IAAI,CAAC,EACnB,KAAK,EACL,SAAS,EACT,GAAG,KAAK,EACT,EAAE,GAAG,GAAG;IAAE,KAAK,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,+BAQ9D;AAID,wBAAgB,SAAS,CAAC,EACxB,KAAK,EACL,SAAS,EACT,GAAG,KAAK,EACT,EAAE,GAAG,GAAG;IAAE,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,+BAQ/C;AAID;uDACuD;AACvD,wBAAgB,IAAI,CAAC,EACnB,KAAK,EACL,SAAS,EACT,GAAG,KAAK,EACT,EAAE,GAAG,GAAG;IAAE,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,+BAQ/C;AAID,MAAM,WAAW,SAAU,SAAQ,GAAG;IACpC,qDAAqD;IACrD,SAAS,CAAC,EAAE,SAAS,CAAA;IACrB,0CAA0C;IAC1C,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,SAAS,CAAA;CACrB;AAED;;sDAEsD;AACtD,wBAAgB,IAAI,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,SAAS,+BAYlF;AAED,qEAAqE;AACrE,wBAAgB,SAAS,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG,GAAG;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,+BAE9E;AAED;0DAC0D;AAC1D,wBAAgB,UAAU,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG,GAAG;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,+BAE/E;AAID,MAAM,WAAW,UAAW,SAAQ,GAAG;IACrC;qBACiB;IACjB,QAAQ,CAAC,EAAE,MAAM,GAAG,WAAW,CAAA;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,SAAS,CAAA;CACrB;AAED;sEACsE;AACtE,wBAAgB,KAAK,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,UAAU,+BAU5E;AAID,MAAM,MAAM,SAAS,GACjB,MAAM,GACN,KAAK,GACL,OAAO,GACP,UAAU,GACV,UAAU,GACV,SAAS,GACT,OAAO,GACP,YAAY,GACZ,UAAU,CAAA;AAEd;;;;;;oEAMoE;AACpE,wBAAgB,IAAI,CAClB,GAAG,EAAE,SAAS,EACd,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAC9C,MAAM,CAKR"}
|
package/dist/surfaces.js
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { cx } from './cx.js';
|
|
3
|
+
/* ─── Halo ambiant ─────────────────────────────────────────────────── */
|
|
4
|
+
/** Le violet et le cyan du spectre, très dilués. Ce n'est PAS un emploi du
|
|
5
|
+
* spectre en aplat : c'est une lumière — elle ne compte pas dans les trois
|
|
6
|
+
* emplois autorisés. */
|
|
7
|
+
export function Halo({ place, className, ...reste }) {
|
|
8
|
+
return (_jsx("div", { "aria-hidden": "true", className: cx('zv-halo', `zv-halo--${place}`, className), ...reste }));
|
|
9
|
+
}
|
|
10
|
+
/* ─── Sol quadrillé ────────────────────────────────────────────────── */
|
|
11
|
+
export function GridFloor({ carte, className, ...reste }) {
|
|
12
|
+
return (_jsx("div", { "aria-hidden": "true", className: cx('zv-grid-floor', carte && 'zv-grid-floor--card', className), ...reste }));
|
|
13
|
+
}
|
|
14
|
+
/* ─── Voile de fondu ───────────────────────────────────────────────── */
|
|
15
|
+
/** Éteint le bas d'une scène pour que le texte qui la suit reste lisible.
|
|
16
|
+
* `blanc` quand la page est blanche sous la scène. */
|
|
17
|
+
export function Fade({ blanc, className, ...reste }) {
|
|
18
|
+
return (_jsx("div", { "aria-hidden": "true", className: cx('zv-fade', blanc && 'zv-fade--white', className), ...reste }));
|
|
19
|
+
}
|
|
20
|
+
/** LA surface sombre du système. ⚠️ Les surfaces sombres se font avec elle et
|
|
21
|
+
* `--accent-on-dark`, JAMAIS en inversant les neutres : les contrastes ont
|
|
22
|
+
* été réglés dans ce sens-là et pas dans l'autre. */
|
|
23
|
+
export function Band({ filigrane, lueur, className, children, ...reste }) {
|
|
24
|
+
return (_jsxs("section", { className: cx('zv-band', className), ...reste, children: [lueur && _jsx("div", { className: "zv-band__glow", "aria-hidden": "true" }), filigrane && (_jsx("div", { className: "zv-band__watermark", "aria-hidden": "true", children: filigrane })), _jsx("div", { className: "zv-band__content", children: children })] }));
|
|
25
|
+
}
|
|
26
|
+
/** Panneau sombre plus petit qu'une bande : une carte, un encart. */
|
|
27
|
+
export function PanelNavy({ className, ...reste }) {
|
|
28
|
+
return _jsx("div", { className: cx('zv-panel-navy', className), ...reste });
|
|
29
|
+
}
|
|
30
|
+
/** Repeint un texte pour une surface sombre. `Band` le fait déjà pour son
|
|
31
|
+
* contenu courant — cette classe sert aux cas isolés. */
|
|
32
|
+
export function TextOnDark({ className, ...reste }) {
|
|
33
|
+
return _jsx("div", { className: cx('zv-text-on-dark', className), ...reste });
|
|
34
|
+
}
|
|
35
|
+
/** Enveloppe d'un logo de produit posé comme motif. Le glyphe lui-même est
|
|
36
|
+
* une image du paquet (`@zevra/ui/logos/…`), pas un tracé du CSS. */
|
|
37
|
+
export function Glyph({ variante, className, children, ...reste }) {
|
|
38
|
+
return (_jsx("div", { "aria-hidden": "true", className: cx('zv-glyph', variante && `zv-glyph--${variante}`, className), ...reste, children: children }));
|
|
39
|
+
}
|
|
40
|
+
/** Les neuf animations du paquet, nommées. ⚠️ Elles sont pilotées AU
|
|
41
|
+
* DÉFILEMENT et réservées à la vitrine : le chrome applicatif n'anime rien.
|
|
42
|
+
* `prefers-reduced-motion` les coupe toutes, globalement, depuis base.css.
|
|
43
|
+
*
|
|
44
|
+
* `option` échelonne les entrées d'une même rangée (`pop`, rangs 2 à 6) ou
|
|
45
|
+
* donne le coin d'arrivée (`converge` : tr, bl, br — le défaut vient du
|
|
46
|
+
* haut-gauche). Passée à une autre animation, elle est ignorée. */
|
|
47
|
+
export function anim(nom, option) {
|
|
48
|
+
if (nom === 'pop' && typeof option === 'number')
|
|
49
|
+
return `zv-anim-pop zv-anim-pop--${option}`;
|
|
50
|
+
if (nom === 'converge' && typeof option === 'string')
|
|
51
|
+
return `zv-anim-converge zv-anim-converge--${option}`;
|
|
52
|
+
return `zv-anim-${nom}`;
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=surfaces.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"surfaces.js","sourceRoot":"","sources":["../react/surfaces.tsx"],"names":[],"mappings":";AAYA,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAA;AAI5B,0EAA0E;AAE1E;;yBAEyB;AACzB,MAAM,UAAU,IAAI,CAAC,EACnB,KAAK,EACL,SAAS,EACT,GAAG,KAAK,EACqD;IAC7D,OAAO,CACL,6BACc,MAAM,EAClB,SAAS,EAAE,EAAE,CAAC,SAAS,EAAE,YAAY,KAAK,EAAE,EAAE,SAAS,CAAC,KACpD,KAAK,GACT,CACH,CAAA;AACH,CAAC;AAED,0EAA0E;AAE1E,MAAM,UAAU,SAAS,CAAC,EACxB,KAAK,EACL,SAAS,EACT,GAAG,KAAK,EACsC;IAC9C,OAAO,CACL,6BACc,MAAM,EAClB,SAAS,EAAE,EAAE,CAAC,eAAe,EAAE,KAAK,IAAI,qBAAqB,EAAE,SAAS,CAAC,KACrE,KAAK,GACT,CACH,CAAA;AACH,CAAC;AAED,0EAA0E;AAE1E;uDACuD;AACvD,MAAM,UAAU,IAAI,CAAC,EACnB,KAAK,EACL,SAAS,EACT,GAAG,KAAK,EACsC;IAC9C,OAAO,CACL,6BACc,MAAM,EAClB,SAAS,EAAE,EAAE,CAAC,SAAS,EAAE,KAAK,IAAI,gBAAgB,EAAE,SAAS,CAAC,KAC1D,KAAK,GACT,CACH,CAAA;AACH,CAAC;AAaD;;sDAEsD;AACtD,MAAM,UAAU,IAAI,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAa;IACjF,OAAO,CACL,mBAAS,SAAS,EAAE,EAAE,CAAC,SAAS,EAAE,SAAS,CAAC,KAAM,KAAK,aACpD,KAAK,IAAI,cAAK,SAAS,EAAC,eAAe,iBAAa,MAAM,GAAG,EAC7D,SAAS,IAAI,CACZ,cAAK,SAAS,EAAC,oBAAoB,iBAAa,MAAM,YACnD,SAAS,GACN,CACP,EACD,cAAK,SAAS,EAAC,kBAAkB,YAAE,QAAQ,GAAO,IAC1C,CACX,CAAA;AACH,CAAC;AAED,qEAAqE;AACrE,MAAM,UAAU,SAAS,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAgC;IAC7E,OAAO,cAAK,SAAS,EAAE,EAAE,CAAC,eAAe,EAAE,SAAS,CAAC,KAAM,KAAK,GAAI,CAAA;AACtE,CAAC;AAED;0DAC0D;AAC1D,MAAM,UAAU,UAAU,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAgC;IAC9E,OAAO,cAAK,SAAS,EAAE,EAAE,CAAC,iBAAiB,EAAE,SAAS,CAAC,KAAM,KAAK,GAAI,CAAA;AACxE,CAAC;AAYD;sEACsE;AACtE,MAAM,UAAU,KAAK,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAc;IAC3E,OAAO,CACL,6BACc,MAAM,EAClB,SAAS,EAAE,EAAE,CAAC,UAAU,EAAE,QAAQ,IAAI,aAAa,QAAQ,EAAE,EAAE,SAAS,CAAC,KACrE,KAAK,YAER,QAAQ,GACL,CACP,CAAA;AACH,CAAC;AAeD;;;;;;oEAMoE;AACpE,MAAM,UAAU,IAAI,CAClB,GAAc,EACd,MAA+C;IAE/C,IAAI,GAAG,KAAK,KAAK,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,OAAO,4BAA4B,MAAM,EAAE,CAAA;IAC5F,IAAI,GAAG,KAAK,UAAU,IAAI,OAAO,MAAM,KAAK,QAAQ;QAClD,OAAO,sCAAsC,MAAM,EAAE,CAAA;IACvD,OAAO,WAAW,GAAG,EAAE,CAAA;AACzB,CAAC"}
|