/
css.ts
114 lines (107 loc) · 2.99 KB
/
css.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
const constructionToken = Symbol()
/**
* @ignore
*/
export class CSSResult {
readonly cssText?: string
constructor(cssText: string, safeToken: symbol) {
if (safeToken !== constructionToken) { throw new Error('Erreur : Utilez `unsafeCSS` ou `css`.') }
this.cssText = cssText
}
toString = (): string => this.cssText
}
/**
* Permet d'insérer un champ de string qui n'est pas un CSSResult et n'a donc pas été traité par un tag CSS dans la string litteral inclus dans le tag CSS
*
* A utiliser si nécessaire, mais passer de préférence par le tag css qui est plus sur
*
* Exemple via le tag css :
* ```typescript
* const mainColor = css`red`;
* ...
* static get styles() {
* return css`
* div { color: ${mainColor} }
* `;
* }
* ```
* Exemple via le tag unsafeCSS :
* ```typescript
* static get styles() {
* const mainColor = 'red';
* return css`
* div { color: ${unsafeCSS(mainColor)} }
* `;
* }
* ```
* @param {unknown} value
* @returns
*/
export const unsafeCSS = (value: unknown): CSSResult => new CSSResult(String(value), constructionToken)
const textFromCSSResult = (value: CSSResult | number): string | number => {
if (value instanceof CSSResult) {
return value.cssText
} else if (typeof value === 'number') {
return value
} else {
throw new Error('Erreur : Utilez `unsafeCSS` pour passer des valeurs sans `css`. Mais attention à la sécurité de vos pages')
}
}
/**
* @ignore
*/
export function arrayFlat(
styles: CSSResultArray, result: CSSResult[] = []): CSSResult[] {
for (let i = 0, length = styles.length; i < length; i++) {
const value = styles[i]
if (Array.isArray(value)) {
arrayFlat(value, result)
} else {
result.push(value)
}
}
return result
}
/**
* Tag permettant d'insérer du CSS dans la propriété styles du composant. Exemple :
* ```typescript
* static get styles() {
* return css`
* :host {
* font-family: Arial, Helvetica, sans-serif;
* margin: auto;
* width: 25rem;
* display: flex;
* flex-direction: column;
* align-items: center;
* }
* `
* }
* ```
* ou avec un array pour par exemple hériter des styles du parent :
* ```typescript
* static get styles() {
* const mainColor = css`red`
* return [
* super.styles,
* css`
* :host {
* display: block;
* text-align: center;
* }
* `
* ]
* }
* ```
* @param {TemplateStringsArray} strings
* @param {(...Array<CSSResult | number>)} values
* @returns
*/
export const css = (strings: TemplateStringsArray, ...values: Array<CSSResult | number>): CSSResult => {
const cssText = values.reduce((acc, v, idx) => `${acc} ${textFromCSSResult(v)}` + strings[idx + 1], strings[0])
return new CSSResult(cssText, constructionToken)
}
/**
* @ignore
*/
export type CSSResultArray = Array<CSSResult | CSSResultArray>