@zuii/core 1.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.
- package/LICENSE +21 -0
- package/package.json +16 -0
- package/src/styles/_base.scss +8 -0
- package/src/styles/_tokens.scss +141 -0
- package/src/styles/main.scss +2 -0
- package/src/styles/tokens.css +270 -0
- package/src/styles/tokens.ts +2027 -0
- package/src/utils/contrast.ts +35 -0
- package/src/utils/getName.ts +99 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { colord, extend } from 'colord';
|
|
2
|
+
import mixPlugin from 'colord/plugins/mix';
|
|
3
|
+
import { calcAPCA } from 'apca-w3';
|
|
4
|
+
|
|
5
|
+
extend([mixPlugin]);
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Détermine la couleur de contraste idéale (noir ou blanc) pour une couleur donnée en utilisant l'algorithme APCA.
|
|
9
|
+
* APCA (Accessible Perceptual Contrast Algorithm) est plus précis que le WCAG 2.1 car il prend en compte
|
|
10
|
+
* la perception humaine de la luminosité.
|
|
11
|
+
*
|
|
12
|
+
* @param {string} color - La couleur au format hexadécimal, RGB, RGBA ou HSL.
|
|
13
|
+
* @returns {string} La couleur de contraste recommandée (teintée de blanc ou de noir).
|
|
14
|
+
*/
|
|
15
|
+
export const getContrastColor = (color: string): string => {
|
|
16
|
+
const whiteContrast = Math.abs(Number(calcAPCA('#ffffff', color)));
|
|
17
|
+
const blackContrast = Math.abs(Number(calcAPCA('#000000', color)));
|
|
18
|
+
|
|
19
|
+
return whiteContrast > blackContrast
|
|
20
|
+
? colord(color).mix('#ffffff', 0.95).toHex()
|
|
21
|
+
: colord(color).mix('#000000', 0.85).toHex();
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Génère une couleur teintée en mélangeant une couleur de base avec une couleur de mix.
|
|
26
|
+
* Utilise color-mix en interne si supporté par le contexte, sinon simule le mélange.
|
|
27
|
+
*
|
|
28
|
+
* @param {string} baseColor - La couleur de base.
|
|
29
|
+
* @param {string} mixColor - La couleur à mélanger.
|
|
30
|
+
* @param {number} amount - Le pourcentage de la couleur de mix (0 à 100).
|
|
31
|
+
* @returns {string} La couleur résultante au format hexadécimal.
|
|
32
|
+
*/
|
|
33
|
+
export const getTintedColor = (baseColor: string, mixColor: string, amount: number): string => {
|
|
34
|
+
return colord(baseColor).mix(mixColor, amount / 100).toHex();
|
|
35
|
+
};
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Options pour l'injection dynamique de classes BEM.
|
|
3
|
+
*/
|
|
4
|
+
interface InjectOptions {
|
|
5
|
+
/**
|
|
6
|
+
* Nom de base servant de préfixe BEM (ex: 'cavaliers').
|
|
7
|
+
*/
|
|
8
|
+
name: string;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Liste de sélecteurs CSS à cibler, séparés par des virgules (ex: '.container, .form').
|
|
12
|
+
* Chaque élément trouvé recevra une classe composée : {base}__{selecteur}.
|
|
13
|
+
*/
|
|
14
|
+
selector: string;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Préfixe global optionnel à ajouter avant le nom de base.
|
|
18
|
+
* @default ''
|
|
19
|
+
*/
|
|
20
|
+
classPrefix?: string;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Si vrai, applique aussi le nom de base comme classe simple sur l'élément <body>.
|
|
24
|
+
* @default false
|
|
25
|
+
*/
|
|
26
|
+
targetBody?: boolean;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Injecte automatiquement des classes CSS BEM dans le DOM pour faciliter le styling spécifique par page.
|
|
31
|
+
*
|
|
32
|
+
* ### Démonstration :
|
|
33
|
+
* ```typescript
|
|
34
|
+
* // Si vous appelez la fonction ainsi :
|
|
35
|
+
* injectDynamicPageClass({
|
|
36
|
+
* name: 'cavaliers',
|
|
37
|
+
* selector: '.container, .group, .datagrid'
|
|
38
|
+
* });
|
|
39
|
+
*
|
|
40
|
+
* // Résultat dans le DOM :
|
|
41
|
+
* // <div class="container cavaliers__container">...</div>
|
|
42
|
+
* // <div class="group cavaliers__group">...</div>
|
|
43
|
+
* // <div class="datagrid cavaliers__datagrid">...</div>
|
|
44
|
+
* ```
|
|
45
|
+
*
|
|
46
|
+
* ### Fonctionnement :
|
|
47
|
+
* 1. Détermine le **nom de base** (via l'option `name`).
|
|
48
|
+
* 2. Pour chaque **sélecteur** fourni (séparé par des virgules) :
|
|
49
|
+
* - Trouve tous les éléments correspondants.
|
|
50
|
+
* - Génère un suffixe propre en retirant les symboles CSS (`.` ou `#`).
|
|
51
|
+
* - Applique la classe générée : `{base}__{suffixe}`.
|
|
52
|
+
*
|
|
53
|
+
* @param {InjectOptions} options - Configuration de l'injection.
|
|
54
|
+
*/
|
|
55
|
+
export const injectDynamicPageClass = ({
|
|
56
|
+
name,
|
|
57
|
+
selector,
|
|
58
|
+
classPrefix = '',
|
|
59
|
+
targetBody = false
|
|
60
|
+
}: InjectOptions): void => {
|
|
61
|
+
// 1. Détermination du nom de base (Prefixe BEM)
|
|
62
|
+
if (!name) {
|
|
63
|
+
throw new Error('Name is required');
|
|
64
|
+
}
|
|
65
|
+
if (!selector) {
|
|
66
|
+
throw new Error('Selector is required');
|
|
67
|
+
}
|
|
68
|
+
const fullPrefix = classPrefix ? `${classPrefix}-${name}` : name;
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Helper interne pour appliquer une classe proprement.
|
|
72
|
+
*/
|
|
73
|
+
const apply = (el: Element, rawSelector: string) => {
|
|
74
|
+
// Nettoyage du sélecteur pour en faire un suffixe BEM propre (retrait du . ou #)
|
|
75
|
+
const suffix = rawSelector.replace(/^[.#]/, '').trim();
|
|
76
|
+
const className = suffix ? `${fullPrefix}__${suffix}` : fullPrefix;
|
|
77
|
+
|
|
78
|
+
if (!el.classList.contains(className)) {
|
|
79
|
+
el.classList.add(className);
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
// 2. Application sur le Body (Global)
|
|
84
|
+
if (targetBody) {
|
|
85
|
+
if (!document.body.classList.contains(fullPrefix)) {
|
|
86
|
+
document.body.classList.add(fullPrefix);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// 3. Application sur les sélecteurs cibles
|
|
91
|
+
// On split par virgule pour gérer les listes de sélecteurs nativement.
|
|
92
|
+
selector.split(',').forEach(s => {
|
|
93
|
+
const targetSelector = s.trim();
|
|
94
|
+
if (!targetSelector) return;
|
|
95
|
+
|
|
96
|
+
const elements = document.querySelectorAll(targetSelector);
|
|
97
|
+
elements.forEach(el => apply(el, targetSelector));
|
|
98
|
+
});
|
|
99
|
+
};
|