@focus4/styling 11.23.6 → 12.0.0-beta.1
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/lib/config.d.ts +7 -0
- package/lib/focus4.styling.css +66 -66
- package/lib/focus4.styling.d.ts +4 -3
- package/lib/focus4.styling.js +103 -66
- package/lib/focus4.styling.js.map +1 -1
- package/lib/theme/index.d.ts +1 -0
- package/lib/theme/themeable.d.ts +2 -0
- package/package.json +12 -9
- package/lib/utils/color-scheme.d.ts +0 -9
- package/lib/utils/index.d.ts +0 -2
- /package/lib/{utils/animation.d.ts → animation.d.ts} +0 -0
package/lib/config.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** Config Focus de l'application */
|
|
2
|
+
export declare const uiConfig: {
|
|
3
|
+
/** Valeur de "autocomplete" sur les inputs pour lesquels on ne veut pas d'autocomplétion. */
|
|
4
|
+
autocompleteOffValue: string;
|
|
5
|
+
/** Classe CSS par défaut des icônes. */
|
|
6
|
+
defaultIconClassName: string;
|
|
7
|
+
};
|
package/lib/focus4.styling.css
CHANGED
|
@@ -1,3 +1,69 @@
|
|
|
1
|
+
html {
|
|
2
|
+
color: rgb(var(--color-black));
|
|
3
|
+
font-size: var(--font-size-small);
|
|
4
|
+
line-height: 1.4;
|
|
5
|
+
font-family: var(--preferred-font);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
body {
|
|
9
|
+
margin: 0;
|
|
10
|
+
animation-duration: var(--animation-duration);
|
|
11
|
+
animation-delay: var(--animation-delay);
|
|
12
|
+
animation-timing-function: var(--animation-curve-default);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
textarea {
|
|
16
|
+
resize: vertical;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
h1,
|
|
20
|
+
h2,
|
|
21
|
+
h3,
|
|
22
|
+
h4,
|
|
23
|
+
h5,
|
|
24
|
+
h6 {
|
|
25
|
+
margin: 24px 0;
|
|
26
|
+
font-weight: 400;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
h1 {
|
|
30
|
+
font-size: calc(3.5 * var(--font-size));
|
|
31
|
+
line-height: 1.35;
|
|
32
|
+
letter-spacing: -0.02em;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
h2 {
|
|
36
|
+
font-size: calc(2.8 * var(--font-size));
|
|
37
|
+
line-height: 48px;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
h3 {
|
|
41
|
+
font-size: calc(2.2 * var(--font-size));
|
|
42
|
+
line-height: 40px;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
h4 {
|
|
46
|
+
font-size: calc(1.5 * var(--font-size));
|
|
47
|
+
line-height: 32px;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
h5 {
|
|
51
|
+
font-size: calc(1.25 * var(--font-size));
|
|
52
|
+
font-weight: var(--font-weight-semi-bold);
|
|
53
|
+
line-height: 1;
|
|
54
|
+
letter-spacing: 0.02em;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
h6 {
|
|
58
|
+
font-size: var(--font-size);
|
|
59
|
+
line-height: 24px;
|
|
60
|
+
letter-spacing: 0.04em;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
th {
|
|
64
|
+
font-weight: normal;
|
|
65
|
+
}
|
|
66
|
+
|
|
1
67
|
:root {
|
|
2
68
|
--color-black: 0, 0, 0;
|
|
3
69
|
--color-white: 255, 255, 255;
|
|
@@ -330,69 +396,3 @@
|
|
|
330
396
|
--color-primary-light: var(--palette-indigo-900);
|
|
331
397
|
--color-accent: var(--palette-pink-a100);
|
|
332
398
|
}
|
|
333
|
-
|
|
334
|
-
html {
|
|
335
|
-
color: rgb(var(--color-black));
|
|
336
|
-
font-size: var(--font-size-small);
|
|
337
|
-
line-height: 1.4;
|
|
338
|
-
font-family: var(--preferred-font);
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
body {
|
|
342
|
-
margin: 0;
|
|
343
|
-
animation-duration: var(--animation-duration);
|
|
344
|
-
animation-delay: var(--animation-delay);
|
|
345
|
-
animation-timing-function: var(--animation-curve-default);
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
textarea {
|
|
349
|
-
resize: vertical;
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
h1,
|
|
353
|
-
h2,
|
|
354
|
-
h3,
|
|
355
|
-
h4,
|
|
356
|
-
h5,
|
|
357
|
-
h6 {
|
|
358
|
-
margin: 24px 0;
|
|
359
|
-
font-weight: 400;
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
h1 {
|
|
363
|
-
font-size: calc(3.5 * var(--font-size));
|
|
364
|
-
line-height: 1.35;
|
|
365
|
-
letter-spacing: -0.02em;
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
h2 {
|
|
369
|
-
font-size: calc(2.8 * var(--font-size));
|
|
370
|
-
line-height: 48px;
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
h3 {
|
|
374
|
-
font-size: calc(2.2 * var(--font-size));
|
|
375
|
-
line-height: 40px;
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
h4 {
|
|
379
|
-
font-size: calc(1.5 * var(--font-size));
|
|
380
|
-
line-height: 32px;
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
h5 {
|
|
384
|
-
font-size: calc(1.25 * var(--font-size));
|
|
385
|
-
font-weight: var(--font-weight-semi-bold);
|
|
386
|
-
line-height: 1;
|
|
387
|
-
letter-spacing: 0.02em;
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
h6 {
|
|
391
|
-
font-size: var(--font-size);
|
|
392
|
-
line-height: 24px;
|
|
393
|
-
letter-spacing: 0.04em;
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
th {
|
|
397
|
-
font-weight: normal;
|
|
398
|
-
}
|
package/lib/focus4.styling.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import "./variables";
|
|
2
1
|
import "./global.css";
|
|
3
|
-
|
|
4
|
-
export {
|
|
2
|
+
import "./variables";
|
|
3
|
+
export { getDefaultTransition, getSpringTransition } from "./animation";
|
|
4
|
+
export { uiConfig } from "./config";
|
|
5
|
+
export { fromBem, themeable, ThemeContext, ThemeProvider, toBem, useTheme } from "./theme";
|
|
5
6
|
export type { CSSContext, CSSElement, CSSMod, CSSProp, CSSToStrings, FocusCSSContext, ThemeProviderProps, ToBem } from "./theme";
|
package/lib/focus4.styling.js
CHANGED
|
@@ -1,12 +1,109 @@
|
|
|
1
|
+
import classNames from 'classnames';
|
|
2
|
+
import { pick } from 'es-toolkit';
|
|
1
3
|
import { createContext, useContext, useMemo } from 'react';
|
|
2
4
|
import { jsx } from 'react/jsx-runtime';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
|
|
6
|
+
function get() {
|
|
7
|
+
const { animationDelay, animationDuration, animationTimingFunction } = window.getComputedStyle(document.body);
|
|
8
|
+
const delay = toMs(animationDelay);
|
|
9
|
+
const duration = toMs(animationDuration);
|
|
10
|
+
const ease = animationTimingFunction.startsWith("cubic-bezier")
|
|
11
|
+
? animationTimingFunction.substring(13).split(",").map(parseFloat)
|
|
12
|
+
: undefined;
|
|
13
|
+
return { delay, duration, ease };
|
|
14
|
+
}
|
|
15
|
+
/** Récupère les paramètres de transition par défaut, à partir des variables CSS correspondantes. */
|
|
16
|
+
function getDefaultTransition() {
|
|
17
|
+
const { delay, duration, ease } = get();
|
|
18
|
+
return {
|
|
19
|
+
delay: delay / 1000,
|
|
20
|
+
duration: duration / 1000,
|
|
21
|
+
ease
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
/** Récupère les paramètres de transition "spring" par défaut. */
|
|
25
|
+
function getSpringTransition() {
|
|
26
|
+
return {
|
|
27
|
+
type: "spring",
|
|
28
|
+
bounce: 0,
|
|
29
|
+
duration: get().duration / 1000
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
function toMs(d) {
|
|
33
|
+
if (d.endsWith("ms")) {
|
|
34
|
+
return +d.substring(0, d.length - 2);
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
return +d.substring(0, d.length - 1) * 1000;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** Config Focus de l'application */
|
|
42
|
+
const uiConfig = {
|
|
43
|
+
/** Valeur de "autocomplete" sur les inputs pour lesquels on ne veut pas d'autocomplétion. */
|
|
44
|
+
autocompleteOffValue: /Firefox/.exec(navigator.userAgent) ? "off" : "one-time-code",
|
|
45
|
+
/** Classe CSS par défaut des icônes. */
|
|
46
|
+
defaultIconClassName: "material-icons"
|
|
47
|
+
};
|
|
7
48
|
|
|
8
49
|
const ThemeContext = createContext({});
|
|
9
50
|
|
|
51
|
+
/** Merges passed themes by concatenating string keys */
|
|
52
|
+
function themeable(...themes) {
|
|
53
|
+
return themes.reduce(merge, {});
|
|
54
|
+
}
|
|
55
|
+
function merge(original = {}, mixin = {}) {
|
|
56
|
+
/*
|
|
57
|
+
* Make a copy to avoid mutations of nested objects
|
|
58
|
+
* also strip all functions injected by isomorphic-style-loader
|
|
59
|
+
*/
|
|
60
|
+
const result = Object.keys(original).reduce((acc, key) => {
|
|
61
|
+
const value = original[key];
|
|
62
|
+
if (typeof value !== "function") {
|
|
63
|
+
acc[key] = value;
|
|
64
|
+
}
|
|
65
|
+
return acc;
|
|
66
|
+
}, {});
|
|
67
|
+
// Traverse mixin keys and merge them to resulting theme
|
|
68
|
+
Object.keys(mixin).forEach(key => {
|
|
69
|
+
// There's no need to set any defaults here
|
|
70
|
+
const originalValue = result[key];
|
|
71
|
+
const mixinValue = mixin[key];
|
|
72
|
+
switch (typeof mixinValue) {
|
|
73
|
+
case "undefined": // Fallthrough - handles accidentally unset values which may come from props
|
|
74
|
+
case "function": {
|
|
75
|
+
// This handles issue when isomorphic-style-loader addes helper functions to css-module
|
|
76
|
+
break; // Just skip
|
|
77
|
+
}
|
|
78
|
+
default: {
|
|
79
|
+
// Plain values
|
|
80
|
+
switch (typeof originalValue) {
|
|
81
|
+
case "undefined": {
|
|
82
|
+
// Mixin key is new to original theme - take it as is
|
|
83
|
+
result[key] = mixinValue;
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
case "function": {
|
|
87
|
+
// This handles issue when isomorphic-style-loader addes helper functions to css-module
|
|
88
|
+
break; // Just skip
|
|
89
|
+
}
|
|
90
|
+
default: {
|
|
91
|
+
// Finally we can merge
|
|
92
|
+
result[key] = originalValue
|
|
93
|
+
.split(" ")
|
|
94
|
+
.concat(mixinValue.split(" "))
|
|
95
|
+
.filter((item, pos, self) => self.indexOf(item) === pos && item !== "")
|
|
96
|
+
.join(" ");
|
|
97
|
+
break;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
break;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
return result;
|
|
105
|
+
}
|
|
106
|
+
|
|
10
107
|
/**
|
|
11
108
|
* `toBem` permet de transformer un objet de classes CSS, tel que celui importé d'un module CSS, dont les noms respectent la convention BEM
|
|
12
109
|
* en un objet contenant une fonction par "élément" à laquelle on peut appliquer ses "modificateurs".
|
|
@@ -50,7 +147,7 @@ function toBem(css) {
|
|
|
50
147
|
return classNames(css[key], ...data[key].filter(mod => mods[mod]).map(mod => css[`${key}--${mod}`]));
|
|
51
148
|
}
|
|
52
149
|
else {
|
|
53
|
-
return pick(css, key, ...data[key].map(mod => `${key}--${mod}`));
|
|
150
|
+
return pick(css, [key, ...data[key].map(mod => `${key}--${mod}`)]);
|
|
54
151
|
}
|
|
55
152
|
}
|
|
56
153
|
}), {});
|
|
@@ -118,65 +215,5 @@ function useTheme(name, ...themes) {
|
|
|
118
215
|
return toBem(themeable(contextTheme, ...themes.filter(x => x).map(x => fromBem(x))));
|
|
119
216
|
}
|
|
120
217
|
|
|
121
|
-
|
|
122
|
-
const { animationDelay, animationDuration, animationTimingFunction } = window.getComputedStyle(document.body);
|
|
123
|
-
const delay = toMs(animationDelay);
|
|
124
|
-
const duration = toMs(animationDuration);
|
|
125
|
-
const ease = animationTimingFunction.startsWith("cubic-bezier")
|
|
126
|
-
? animationTimingFunction.substring(13).split(",").map(parseFloat)
|
|
127
|
-
: undefined;
|
|
128
|
-
return { delay, duration, ease };
|
|
129
|
-
}
|
|
130
|
-
/** Récupère les paramètres de transition par défaut, à partir des variables CSS correspondantes. */
|
|
131
|
-
function getDefaultTransition() {
|
|
132
|
-
const { delay, duration, ease } = get();
|
|
133
|
-
return {
|
|
134
|
-
delay: delay / 1000,
|
|
135
|
-
duration: duration / 1000,
|
|
136
|
-
ease
|
|
137
|
-
};
|
|
138
|
-
}
|
|
139
|
-
/** Récupère les paramètres de transition "spring" par défaut. */
|
|
140
|
-
function getSpringTransition() {
|
|
141
|
-
return {
|
|
142
|
-
type: "spring",
|
|
143
|
-
bounce: 0,
|
|
144
|
-
duration: get().duration / 1000
|
|
145
|
-
};
|
|
146
|
-
}
|
|
147
|
-
function toMs(d) {
|
|
148
|
-
if (d.endsWith("ms")) {
|
|
149
|
-
return +d.substring(0, d.length - 2);
|
|
150
|
-
}
|
|
151
|
-
else {
|
|
152
|
-
return +d.substring(0, d.length - 1) * 1000;
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
const colorScheme = observable({ dark: false });
|
|
157
|
-
/**
|
|
158
|
-
* Permet d'initialiser l'utilisation du mode sombre dans une application Focus. Par défaut, il est initialisé avec le thème du navigateur de
|
|
159
|
-
* l'utilisateur.
|
|
160
|
-
* @param disableAutoDarkMode Désactive la prise en compte du thème de l'utilisateur et initialise toujours en thème clair.
|
|
161
|
-
*/
|
|
162
|
-
function initColorScheme(disableAutoDarkMode = false) {
|
|
163
|
-
const ls = localStorage.getItem("color-scheme");
|
|
164
|
-
if (ls === "dark" || (!ls && !disableAutoDarkMode && window.matchMedia?.("(prefers-color-scheme: dark)").matches)) {
|
|
165
|
-
colorScheme.dark = true;
|
|
166
|
-
}
|
|
167
|
-
localStorage.setItem("color-scheme", colorScheme.dark ? "dark" : "light");
|
|
168
|
-
autorun(() => {
|
|
169
|
-
const darkModeAttribute = document.documentElement.hasAttribute("dark");
|
|
170
|
-
if (colorScheme.dark && !darkModeAttribute) {
|
|
171
|
-
document.documentElement.setAttribute("dark", "true");
|
|
172
|
-
localStorage.setItem("color-scheme", "dark");
|
|
173
|
-
}
|
|
174
|
-
else if (!colorScheme.dark && darkModeAttribute) {
|
|
175
|
-
document.documentElement.removeAttribute("dark");
|
|
176
|
-
localStorage.setItem("color-scheme", "light");
|
|
177
|
-
}
|
|
178
|
-
});
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
export { ThemeContext, ThemeProvider, colorScheme, fromBem, getDefaultTransition, getSpringTransition, initColorScheme, toBem, useTheme };
|
|
218
|
+
export { ThemeContext, ThemeProvider, fromBem, getDefaultTransition, getSpringTransition, themeable, toBem, uiConfig, useTheme };
|
|
182
219
|
//# sourceMappingURL=focus4.styling.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"focus4.styling.js","sources":["../src/theme/common.ts","../src/theme/to-bem.ts","../src/theme/theme-provider.tsx","../src/theme/use-theme.ts","../src/utils/animation.ts","../src/utils/color-scheme.ts"],"sourcesContent":["import {createContext} from \"react\";\r\n\r\nexport type CSSElement<T> = T & string & {_element: void};\r\nexport type CSSMod<N extends string, T> = N & T & string & {_mod: void};\r\nexport type CSSToStrings<T> = {[P in keyof T]?: string};\r\n\r\nexport type Mods<CSS, E> = {[P in keyof CSS]: CSS[P] extends CSSMod<infer M, E> ? M : never}[keyof CSS];\r\nexport type ModNames<CSS, E> = {[P in keyof CSS]: CSS[P] extends CSSMod<infer _, E> ? P : never}[keyof CSS];\r\nexport type BemFunction<CSS = any, P extends number | string | symbol = any, E = any> = ((object: true) => {\r\n [_ in ModNames<CSS, E> | P]: string;\r\n}) &\r\n (Mods<CSS, E> extends never | undefined ? () => string : (mods?: {[_ in Mods<CSS, E>]?: boolean}) => string);\r\n\r\nexport interface CSSContext {\r\n [key: string]: {};\r\n}\r\n\r\nexport const ThemeContext = createContext<CSSContext>({});\r\n","import classNames from \"classnames\";\r\nimport {pick} from \"lodash\";\r\n\r\nimport {BemFunction, CSSElement, CSSMod, CSSToStrings} from \"./common\";\r\n\r\nexport type AllMods<CSS> = {[P in keyof CSS]: CSS[P] extends CSSMod<infer _, infer __> ? P : never}[keyof CSS];\r\nexport type ToBem<CSS> = Omit<\r\n {\r\n [P in keyof CSS]-?: CSS[P] extends CSSElement<infer E>\r\n ? BemFunction<CSS, P, E>\r\n : CSS[P] extends CSSMod<infer __, infer ___>\r\n ? never\r\n : BemFunction<CSS, P, string>;\r\n },\r\n AllMods<CSS>\r\n>;\r\n\r\nexport type CSSProp<CSS> = CSSToStrings<CSS> | Partial<ToBem<CSS>>;\r\n\r\n/**\r\n * `toBem` permet de transformer un objet de classes CSS, tel que celui importé d'un module CSS, dont les noms respectent la convention BEM\r\n * en un objet contenant une fonction par \"élément\" à laquelle on peut appliquer ses \"modificateurs\".\r\n *\r\n * Par exemple, un objet contenant les classes\r\n * ```ts\r\n * [\"panel\", \"panel--editing\", \"panel--loading\", \"title\", \"title--top\", \"title--bottom\"]\r\n * ```\r\n * sera transformé en un objet avec 2 fonctions `panel` et `title` :\r\n * ```ts\r\n * {\r\n * panel({editing?: boolean; loading?: boolean}) => string;\r\n * title({top?: boolean; bottom?: boolean}) => string;\r\n * }\r\n * ```\r\n * Un appel à une fonction retournera la classe CSS de l'\"élément\", à laquelle seront ajoutées ou non les classes des différents \"modificateurs\",\r\n * selon les valeurs des différents booléens.\r\n *\r\n * Vous pouvez utiliser `toBem` pour éviter d'avoir à concaténer des classes CSS à la main et pour rendre vos composants et votre CSS plus propres.\r\n * Son usage est bien évidemment totalement facultatif et à utiliser si cela vous arrange.\r\n *\r\n * _Remarque 1 : Les modules CSS importés doivent avoir des définitions Typescript générés par la commande `focus4 cssgen` du module `@focus4/tooling`._\r\n *\r\n * _Remarque 2 : Les propriétés `theme` des différents composants Focus acceptent aussi bien un objet CSS classique ou un objet créé par `toBem`._\r\n */\r\nexport function toBem<CSS>(css: CSS): ToBem<CSS> {\r\n const data: {[key: string]: string[]} = {};\r\n for (const key in css) {\r\n const [element, modifier] = key.split(\"--\");\r\n if (data[element] && modifier) {\r\n data[element].push(modifier);\r\n } else if (!data[element]) {\r\n data[element] = modifier ? [modifier] : [];\r\n }\r\n }\r\n\r\n return Object.keys(data).reduce(\r\n (bem, key) => ({\r\n ...bem,\r\n [key]: (mods: true | {[key: string]: boolean} = {}) => {\r\n if (mods !== true) {\r\n return classNames(\r\n (css as any)[key],\r\n ...data[key].filter(mod => mods[mod]).map(mod => (css as any)[`${key}--${mod}`])\r\n );\r\n } else {\r\n return pick(css, key, ...data[key].map(mod => `${key}--${mod}`));\r\n }\r\n }\r\n }),\r\n {}\r\n ) as ToBem<CSS>;\r\n}\r\n\r\n/**\r\n * `fromBem` permet de faire la transformation inverse de `toBem`, à savoir prendre l'objet résultant d'un appel à `toBem` et de ressortir un objet\r\n * qui contient toutes les classes CSS qui le compose.\r\n */\r\nexport function fromBem<T>(css: CSSToStrings<T> | Partial<ToBem<T>> | T): CSSToStrings<T> {\r\n const res: CSSToStrings<T> = {};\r\n\r\n for (const key in css as any) {\r\n const value = (css as any)[key];\r\n if (value) {\r\n if (typeof value === \"string\") {\r\n (res as any)[key] = value;\r\n } else {\r\n Object.assign(res, value(true));\r\n }\r\n }\r\n }\r\n\r\n return res;\r\n}\r\n","import {ReactNode, useContext, useMemo} from \"react\";\r\n\r\nimport {themeable} from \"@focus4/core\";\r\n\r\nimport {CSSContext, ThemeContext} from \"./common\";\r\nimport {fromBem} from \"./to-bem\";\r\n\r\n/** Contient l'ensemble des classes CSS surchargeables (elles le sont toutes), regroupées par composant. */\r\nexport interface FocusCSSContext extends CSSContext {\r\n // Collections\r\n actionBar: {};\r\n advancedSearch: {};\r\n contextualActions: {};\r\n facet: {};\r\n facetBox: {};\r\n group: {};\r\n list: {};\r\n listBase: {};\r\n searchBar: {};\r\n summary: {};\r\n table: {};\r\n timeline: {};\r\n\r\n // Forms\r\n booleanRadio: {};\r\n display: {};\r\n field: {};\r\n form: {};\r\n inputDate: {};\r\n label: {};\r\n select: {};\r\n selectCheckbox: {};\r\n selectChips: {};\r\n selectRadio: {};\r\n\r\n // Layout\r\n dialog: {};\r\n filAriane: {};\r\n header: {};\r\n lateralMenu: {};\r\n layout: {};\r\n mainMenu: {};\r\n overlay: {};\r\n panel: {};\r\n popin: {};\r\n scrollable: {};\r\n scrollspy: {};\r\n\r\n // Toolbox\r\n autocomplete: {};\r\n button: {};\r\n calendar: {};\r\n checkbox: {};\r\n chip: {};\r\n dropdown: {};\r\n floatingActionButton: {};\r\n iconButton: {};\r\n menu: {};\r\n progressIndicator: {};\r\n radio: {};\r\n ripple: {};\r\n slider: {};\r\n snackbar: {};\r\n switch: {};\r\n textField: {};\r\n tabs: {};\r\n tooltip: {};\r\n}\r\n\r\n/** Props du ThemeProvider. */\r\nexport interface ThemeProviderProps {\r\n /** Objet faisant correspondre à un identifiant de composant son objet de classes CSS associé. */\r\n appTheme: Partial<FocusCSSContext>;\r\n /** Enfants. */\r\n children: ReactNode;\r\n}\r\n\r\n/**\r\n * Le `ThemeProvider` permet d'ajouter des classes CSS aux composants Focus (et autres composants utilisant `useTheme`) posés\r\n * à l'intérieur (via un context React).\r\n *\r\n * Les classes CSS ajoutées dans un `ThemeProvider` s'ajouteront aux éventuelles classes posées par un `ThemeProvider` parent,\r\n * y compris sur les mêmes composants.\r\n */\r\nexport function ThemeProvider({appTheme, children}: ThemeProviderProps) {\r\n const context = useContext(ThemeContext);\r\n\r\n const mergedContext = useMemo(() => {\r\n const mc = {} as CSSContext;\r\n\r\n for (const key in context) {\r\n if (key in appTheme && appTheme[key]) {\r\n mc[key] = themeable(fromBem(context[key]), fromBem(appTheme[key]));\r\n } else {\r\n mc[key] = context[key];\r\n }\r\n }\r\n\r\n for (const key in appTheme) {\r\n if (!(key in context) && appTheme[key]) {\r\n mc[key] = appTheme[key]!;\r\n }\r\n }\r\n return mc;\r\n }, [appTheme, context]);\r\n\r\n return <ThemeContext.Provider value={mergedContext}>{children}</ThemeContext.Provider>;\r\n}\r\n","import {useContext} from \"react\";\r\n\r\nimport {themeable} from \"@focus4/core\";\r\n\r\nimport {CSSToStrings, ThemeContext} from \"./common\";\r\nimport {fromBem, toBem, ToBem} from \"./to-bem\";\r\n\r\n/**\r\n * `useTheme` permet de récupérer les classes CSS passées dans un éventuel `ThemeProvider` parent et de les fusionner avec d'autres classes CSS\r\n * passées en paramètre.\r\n *\r\n * `useTheme` accepte aussi bien des objets de classes CSS classiques (importés d'un module CSS), que des objets créés avec `toBem`.\r\n *\r\n * @param name L'identifiant du composant dans le `appTheme` du `ThemeProvider`\r\n * @param themes Les objets de classes CSS à fusionner ensemble et avec celui du contexte.\r\n */\r\nexport function useTheme<T>(\r\n name: string,\r\n ...themes: (CSSToStrings<T> | Partial<ToBem<T>> | T | undefined)[]\r\n): ToBem<T> {\r\n const contextTheme = fromBem(useContext(ThemeContext)[name]) || {};\r\n return toBem(themeable(contextTheme, ...themes.filter(x => x).map(x => fromBem(x!))) as T);\r\n}\r\n","function get() {\r\n const {animationDelay, animationDuration, animationTimingFunction} = window.getComputedStyle(document.body);\r\n\r\n const delay = toMs(animationDelay);\r\n const duration = toMs(animationDuration);\r\n const ease = animationTimingFunction.startsWith(\"cubic-bezier\")\r\n ? animationTimingFunction.substring(13).split(\",\").map(parseFloat)\r\n : undefined;\r\n\r\n return {delay, duration, ease};\r\n}\r\n\r\n/** Récupère les paramètres de transition par défaut, à partir des variables CSS correspondantes. */\r\nexport function getDefaultTransition() {\r\n const {delay, duration, ease} = get();\r\n return {\r\n delay: delay / 1000,\r\n duration: duration / 1000,\r\n ease\r\n } as const;\r\n}\r\n\r\n/** Récupère les paramètres de transition \"spring\" par défaut. */\r\nexport function getSpringTransition() {\r\n return {\r\n type: \"spring\",\r\n bounce: 0,\r\n duration: get().duration / 1000\r\n } as const;\r\n}\r\n\r\nfunction toMs(d: string) {\r\n if (d.endsWith(\"ms\")) {\r\n return +d.substring(0, d.length - 2);\r\n } else {\r\n return +d.substring(0, d.length - 1) * 1000;\r\n }\r\n}\r\n","import {autorun, observable} from \"mobx\";\r\n\r\nexport const colorScheme = observable({dark: false});\r\n\r\n/**\r\n * Permet d'initialiser l'utilisation du mode sombre dans une application Focus. Par défaut, il est initialisé avec le thème du navigateur de\r\n * l'utilisateur.\r\n * @param disableAutoDarkMode Désactive la prise en compte du thème de l'utilisateur et initialise toujours en thème clair.\r\n */\r\nexport function initColorScheme(disableAutoDarkMode = false) {\r\n const ls = localStorage.getItem(\"color-scheme\");\r\n if (ls === \"dark\" || (!ls && !disableAutoDarkMode && window.matchMedia?.(\"(prefers-color-scheme: dark)\").matches)) {\r\n colorScheme.dark = true;\r\n }\r\n localStorage.setItem(\"color-scheme\", colorScheme.dark ? \"dark\" : \"light\");\r\n\r\n autorun(() => {\r\n const darkModeAttribute = document.documentElement.hasAttribute(\"dark\");\r\n if (colorScheme.dark && !darkModeAttribute) {\r\n document.documentElement.setAttribute(\"dark\", \"true\");\r\n localStorage.setItem(\"color-scheme\", \"dark\");\r\n } else if (!colorScheme.dark && darkModeAttribute) {\r\n document.documentElement.removeAttribute(\"dark\");\r\n localStorage.setItem(\"color-scheme\", \"light\");\r\n }\r\n });\r\n}\r\n"],"names":["_jsx"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"focus4.styling.js","sources":["../src/animation.ts","../src/config.ts","../src/theme/common.ts","../src/theme/themeable.ts","../src/theme/to-bem.ts","../src/theme/theme-provider.tsx","../src/theme/use-theme.ts"],"sourcesContent":["function get() {\r\n const {animationDelay, animationDuration, animationTimingFunction} = window.getComputedStyle(document.body);\r\n\r\n const delay = toMs(animationDelay);\r\n const duration = toMs(animationDuration);\r\n const ease = animationTimingFunction.startsWith(\"cubic-bezier\")\r\n ? animationTimingFunction.substring(13).split(\",\").map(parseFloat)\r\n : undefined;\r\n\r\n return {delay, duration, ease};\r\n}\r\n\r\n/** Récupère les paramètres de transition par défaut, à partir des variables CSS correspondantes. */\r\nexport function getDefaultTransition() {\r\n const {delay, duration, ease} = get();\r\n return {\r\n delay: delay / 1000,\r\n duration: duration / 1000,\r\n ease\r\n } as const;\r\n}\r\n\r\n/** Récupère les paramètres de transition \"spring\" par défaut. */\r\nexport function getSpringTransition() {\r\n return {\r\n type: \"spring\",\r\n bounce: 0,\r\n duration: get().duration / 1000\r\n } as const;\r\n}\r\n\r\nfunction toMs(d: string) {\r\n if (d.endsWith(\"ms\")) {\r\n return +d.substring(0, d.length - 2);\r\n } else {\r\n return +d.substring(0, d.length - 1) * 1000;\r\n }\r\n}\r\n","/** Config Focus de l'application */\r\nexport const uiConfig = {\r\n /** Valeur de \"autocomplete\" sur les inputs pour lesquels on ne veut pas d'autocomplétion. */\r\n autocompleteOffValue: /Firefox/.exec(navigator.userAgent) ? \"off\" : \"one-time-code\",\r\n\r\n /** Classe CSS par défaut des icônes. */\r\n defaultIconClassName: \"material-icons\"\r\n};\r\n","import {createContext} from \"react\";\r\n\r\nexport type CSSElement<T> = T & string & {_element: void};\r\nexport type CSSMod<N extends string, T> = N & T & string & {_mod: void};\r\nexport type CSSToStrings<T> = {[P in keyof T]?: string};\r\n\r\nexport type Mods<CSS, E> = {[P in keyof CSS]: CSS[P] extends CSSMod<infer M, E> ? M : never}[keyof CSS];\r\nexport type ModNames<CSS, E> = {[P in keyof CSS]: CSS[P] extends CSSMod<infer _, E> ? P : never}[keyof CSS];\r\nexport type BemFunction<CSS = any, P extends number | string | symbol = any, E = any> = ((object: true) => {\r\n [_ in ModNames<CSS, E> | P]: string;\r\n}) &\r\n (Mods<CSS, E> extends never | undefined ? () => string : (mods?: {[_ in Mods<CSS, E>]?: boolean}) => string);\r\n\r\nexport interface CSSContext {\r\n [key: string]: {};\r\n}\r\n\r\nexport const ThemeContext = createContext<CSSContext>({});\r\n","/** Merges passed themes by concatenating string keys */\r\nexport function themeable<T extends {}>(...themes: T[]) {\r\n return themes.reduce(merge, {}) as T;\r\n}\r\n\r\nfunction merge<T extends {[key: string]: string}>(original = {} as T, mixin = {} as T) {\r\n /*\r\n * Make a copy to avoid mutations of nested objects\r\n * also strip all functions injected by isomorphic-style-loader\r\n */\r\n const result = Object.keys(original).reduce((acc, key) => {\r\n const value = original[key];\r\n if (typeof value !== \"function\") {\r\n acc[key] = value;\r\n }\r\n return acc;\r\n }, {} as {[key: string]: string});\r\n\r\n // Traverse mixin keys and merge them to resulting theme\r\n Object.keys(mixin).forEach(key => {\r\n // There's no need to set any defaults here\r\n const originalValue = result[key];\r\n const mixinValue = mixin[key];\r\n\r\n switch (typeof mixinValue) {\r\n case \"undefined\": // Fallthrough - handles accidentally unset values which may come from props\r\n case \"function\": {\r\n // This handles issue when isomorphic-style-loader addes helper functions to css-module\r\n break; // Just skip\r\n }\r\n\r\n default: {\r\n // Plain values\r\n switch (typeof originalValue) {\r\n case \"undefined\": {\r\n // Mixin key is new to original theme - take it as is\r\n result[key] = mixinValue;\r\n break;\r\n }\r\n case \"function\": {\r\n // This handles issue when isomorphic-style-loader addes helper functions to css-module\r\n break; // Just skip\r\n }\r\n\r\n default: {\r\n // Finally we can merge\r\n result[key] = originalValue\r\n .split(\" \")\r\n .concat(mixinValue.split(\" \"))\r\n .filter((item, pos, self) => self.indexOf(item) === pos && item !== \"\")\r\n .join(\" \");\r\n break;\r\n }\r\n }\r\n break;\r\n }\r\n }\r\n });\r\n\r\n return result;\r\n}\r\n","import classNames from \"classnames\";\r\nimport {pick} from \"es-toolkit\";\r\n\r\nimport {BemFunction, CSSElement, CSSMod, CSSToStrings} from \"./common\";\r\n\r\nexport type AllMods<CSS> = {[P in keyof CSS]: CSS[P] extends CSSMod<infer _, infer __> ? P : never}[keyof CSS];\r\nexport type ToBem<CSS> = Omit<\r\n {\r\n [P in keyof CSS]-?: CSS[P] extends CSSElement<infer E>\r\n ? BemFunction<CSS, P, E>\r\n : CSS[P] extends CSSMod<infer __, infer ___>\r\n ? never\r\n : BemFunction<CSS, P, string>;\r\n },\r\n AllMods<CSS>\r\n>;\r\n\r\nexport type CSSProp<CSS> = CSSToStrings<CSS> | Partial<ToBem<CSS>>;\r\n\r\n/**\r\n * `toBem` permet de transformer un objet de classes CSS, tel que celui importé d'un module CSS, dont les noms respectent la convention BEM\r\n * en un objet contenant une fonction par \"élément\" à laquelle on peut appliquer ses \"modificateurs\".\r\n *\r\n * Par exemple, un objet contenant les classes\r\n * ```ts\r\n * [\"panel\", \"panel--editing\", \"panel--loading\", \"title\", \"title--top\", \"title--bottom\"]\r\n * ```\r\n * sera transformé en un objet avec 2 fonctions `panel` et `title` :\r\n * ```ts\r\n * {\r\n * panel({editing?: boolean; loading?: boolean}) => string;\r\n * title({top?: boolean; bottom?: boolean}) => string;\r\n * }\r\n * ```\r\n * Un appel à une fonction retournera la classe CSS de l'\"élément\", à laquelle seront ajoutées ou non les classes des différents \"modificateurs\",\r\n * selon les valeurs des différents booléens.\r\n *\r\n * Vous pouvez utiliser `toBem` pour éviter d'avoir à concaténer des classes CSS à la main et pour rendre vos composants et votre CSS plus propres.\r\n * Son usage est bien évidemment totalement facultatif et à utiliser si cela vous arrange.\r\n *\r\n * _Remarque 1 : Les modules CSS importés doivent avoir des définitions Typescript générés par la commande `focus4 cssgen` du module `@focus4/tooling`._\r\n *\r\n * _Remarque 2 : Les propriétés `theme` des différents composants Focus acceptent aussi bien un objet CSS classique ou un objet créé par `toBem`._\r\n */\r\nexport function toBem<CSS>(css: CSS): ToBem<CSS> {\r\n const data: {[key: string]: string[]} = {};\r\n for (const key in css) {\r\n const [element, modifier] = key.split(\"--\");\r\n if (data[element] && modifier) {\r\n data[element].push(modifier);\r\n } else if (!data[element]) {\r\n data[element] = modifier ? [modifier] : [];\r\n }\r\n }\r\n\r\n return Object.keys(data).reduce(\r\n (bem, key) => ({\r\n ...bem,\r\n [key]: (mods: true | {[key: string]: boolean} = {}) => {\r\n if (mods !== true) {\r\n return classNames(\r\n (css as any)[key],\r\n ...data[key].filter(mod => mods[mod]).map(mod => (css as any)[`${key}--${mod}`])\r\n );\r\n } else {\r\n return pick(css as any, [key, ...data[key].map(mod => `${key}--${mod}`)]);\r\n }\r\n }\r\n }),\r\n {}\r\n ) as ToBem<CSS>;\r\n}\r\n\r\n/**\r\n * `fromBem` permet de faire la transformation inverse de `toBem`, à savoir prendre l'objet résultant d'un appel à `toBem` et de ressortir un objet\r\n * qui contient toutes les classes CSS qui le compose.\r\n */\r\nexport function fromBem<T>(css: CSSToStrings<T> | Partial<ToBem<T>> | T): CSSToStrings<T> {\r\n const res: CSSToStrings<T> = {};\r\n\r\n for (const key in css as any) {\r\n const value = (css as any)[key];\r\n if (value) {\r\n if (typeof value === \"string\") {\r\n (res as any)[key] = value;\r\n } else {\r\n Object.assign(res, value(true));\r\n }\r\n }\r\n }\r\n\r\n return res;\r\n}\r\n","import {ReactNode, useContext, useMemo} from \"react\";\r\n\r\nimport {CSSContext, ThemeContext} from \"./common\";\r\nimport {themeable} from \"./themeable\";\r\nimport {fromBem} from \"./to-bem\";\r\n\r\n/** Contient l'ensemble des classes CSS surchargeables (elles le sont toutes), regroupées par composant. */\r\nexport interface FocusCSSContext extends CSSContext {\r\n // Collections\r\n actionBar: {};\r\n advancedSearch: {};\r\n contextualActions: {};\r\n facet: {};\r\n facetBox: {};\r\n group: {};\r\n list: {};\r\n listBase: {};\r\n searchBar: {};\r\n summary: {};\r\n table: {};\r\n timeline: {};\r\n\r\n // Forms\r\n booleanRadio: {};\r\n display: {};\r\n field: {};\r\n form: {};\r\n inputDate: {};\r\n label: {};\r\n select: {};\r\n selectCheckbox: {};\r\n selectChips: {};\r\n selectRadio: {};\r\n\r\n // Layout\r\n dialog: {};\r\n filAriane: {};\r\n header: {};\r\n lateralMenu: {};\r\n layout: {};\r\n mainMenu: {};\r\n overlay: {};\r\n panel: {};\r\n popin: {};\r\n scrollable: {};\r\n scrollspy: {};\r\n\r\n // Toolbox\r\n autocomplete: {};\r\n button: {};\r\n calendar: {};\r\n checkbox: {};\r\n chip: {};\r\n dropdown: {};\r\n floatingActionButton: {};\r\n iconButton: {};\r\n menu: {};\r\n progressIndicator: {};\r\n radio: {};\r\n ripple: {};\r\n slider: {};\r\n snackbar: {};\r\n switch: {};\r\n textField: {};\r\n tabs: {};\r\n tooltip: {};\r\n}\r\n\r\n/** Props du ThemeProvider. */\r\nexport interface ThemeProviderProps {\r\n /** Objet faisant correspondre à un identifiant de composant son objet de classes CSS associé. */\r\n appTheme: Partial<FocusCSSContext>;\r\n /** Enfants. */\r\n children: ReactNode;\r\n}\r\n\r\n/**\r\n * Le `ThemeProvider` permet d'ajouter des classes CSS aux composants Focus (et autres composants utilisant `useTheme`) posés\r\n * à l'intérieur (via un context React).\r\n *\r\n * Les classes CSS ajoutées dans un `ThemeProvider` s'ajouteront aux éventuelles classes posées par un `ThemeProvider` parent,\r\n * y compris sur les mêmes composants.\r\n */\r\nexport function ThemeProvider({appTheme, children}: ThemeProviderProps) {\r\n const context = useContext(ThemeContext);\r\n\r\n const mergedContext = useMemo(() => {\r\n const mc = {} as CSSContext;\r\n\r\n for (const key in context) {\r\n if (key in appTheme && appTheme[key]) {\r\n mc[key] = themeable(fromBem(context[key]), fromBem(appTheme[key]));\r\n } else {\r\n mc[key] = context[key];\r\n }\r\n }\r\n\r\n for (const key in appTheme) {\r\n if (!(key in context) && appTheme[key]) {\r\n mc[key] = appTheme[key]!;\r\n }\r\n }\r\n return mc;\r\n }, [appTheme, context]);\r\n\r\n return <ThemeContext.Provider value={mergedContext}>{children}</ThemeContext.Provider>;\r\n}\r\n","import {useContext} from \"react\";\r\n\r\nimport {CSSToStrings, ThemeContext} from \"./common\";\r\nimport {themeable} from \"./themeable\";\r\nimport {fromBem, toBem, ToBem} from \"./to-bem\";\r\n\r\n/**\r\n * `useTheme` permet de récupérer les classes CSS passées dans un éventuel `ThemeProvider` parent et de les fusionner avec d'autres classes CSS\r\n * passées en paramètre.\r\n *\r\n * `useTheme` accepte aussi bien des objets de classes CSS classiques (importés d'un module CSS), que des objets créés avec `toBem`.\r\n *\r\n * @param name L'identifiant du composant dans le `appTheme` du `ThemeProvider`\r\n * @param themes Les objets de classes CSS à fusionner ensemble et avec celui du contexte.\r\n */\r\nexport function useTheme<T>(\r\n name: string,\r\n ...themes: (CSSToStrings<T> | Partial<ToBem<T>> | T | undefined)[]\r\n): ToBem<T> {\r\n const contextTheme = fromBem(useContext(ThemeContext)[name]) || {};\r\n return toBem(themeable(contextTheme, ...themes.filter(x => x).map(x => fromBem(x!))) as T);\r\n}\r\n"],"names":["_jsx"],"mappings":"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"}
|
package/lib/theme/index.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@focus4/styling",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "12.0.0-beta.1",
|
|
4
4
|
"description": "Focus v4, styling module",
|
|
5
5
|
"main": "lib/focus4.styling.js",
|
|
6
6
|
"type": "module",
|
|
@@ -16,13 +16,16 @@
|
|
|
16
16
|
"postinstall": "node postinstall.js"
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@
|
|
20
|
-
"@types/react": "
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"react": "18.3.1",
|
|
25
|
-
"react-dom": "18.3.1"
|
|
19
|
+
"@types/react": "~19.0.8",
|
|
20
|
+
"@types/react-dom": "~19.0.3",
|
|
21
|
+
"classnames": "~2.5.1",
|
|
22
|
+
"es-toolkit": "~1.32.0",
|
|
23
|
+
"tslib": "~2.8.1"
|
|
26
24
|
},
|
|
27
|
-
"
|
|
25
|
+
"peerDependencies": {
|
|
26
|
+
"i18next": ">= 24.2 < 25",
|
|
27
|
+
"react": ">= 19.0 < 20",
|
|
28
|
+
"react-dom": ">= 19.0 < 20"
|
|
29
|
+
},
|
|
30
|
+
"gitHead": "df553f135b41958b14deaab12c0624d1ab7c9be7"
|
|
28
31
|
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
export declare const colorScheme: {
|
|
2
|
-
dark: boolean;
|
|
3
|
-
};
|
|
4
|
-
/**
|
|
5
|
-
* Permet d'initialiser l'utilisation du mode sombre dans une application Focus. Par défaut, il est initialisé avec le thème du navigateur de
|
|
6
|
-
* l'utilisateur.
|
|
7
|
-
* @param disableAutoDarkMode Désactive la prise en compte du thème de l'utilisateur et initialise toujours en thème clair.
|
|
8
|
-
*/
|
|
9
|
-
export declare function initColorScheme(disableAutoDarkMode?: boolean): void;
|
package/lib/utils/index.d.ts
DELETED
|
File without changes
|