@slimr/css 2.1.11 → 2.1.12
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 +28 -8
- package/cjs/createClass.d.ts +43 -0
- package/cjs/{src/createClass.js → createClass.js} +88 -132
- package/cjs/createClass.js.map +1 -0
- package/cjs/createClass.ts +92 -211
- package/{esm/src → cjs}/index.d.ts +1 -0
- package/cjs/{src/index.js → index.js} +1 -0
- package/cjs/index.js.map +1 -0
- package/cjs/index.ts +1 -0
- package/cjs/{src/createClass.d.ts → shorthandProps.d.ts} +7 -47
- package/cjs/shorthandProps.js +51 -0
- package/cjs/shorthandProps.js.map +1 -0
- package/cjs/shorthandProps.ts +118 -0
- package/esm/createClass.d.ts +43 -0
- package/esm/{src/createClass.js → createClass.js} +85 -128
- package/esm/createClass.js.map +1 -0
- package/esm/createClass.ts +92 -211
- package/{cjs/src → esm}/index.d.ts +1 -0
- package/esm/{src/index.js → index.js} +1 -0
- package/esm/index.js.map +1 -0
- package/esm/index.ts +1 -0
- package/esm/{src/createClass.d.ts → shorthandProps.d.ts} +7 -47
- package/esm/shorthandProps.js +47 -0
- package/esm/shorthandProps.js.map +1 -0
- package/esm/shorthandProps.ts +118 -0
- package/package.json +4 -1
- package/src/createClass.ts +92 -211
- package/src/index.ts +1 -0
- package/src/shorthandProps.ts +118 -0
- package/tsconfig.json +1 -1
- package/cjs/src/createClass.js.map +0 -1
- package/cjs/src/index.js.map +0 -1
- package/esm/src/createClass.js.map +0 -1
- package/esm/src/index.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @slimr/css
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
tiny css-in-js features, inspired by the popular emotion library
|
|
4
4
|
|
|
5
5
|
`@slimr` is a set of slim React (hence '@slimr') libs:
|
|
6
6
|
|
|
@@ -16,9 +16,9 @@ A tiny alternative to the popular emotion library
|
|
|
16
16
|
|
|
17
17
|
Pros:
|
|
18
18
|
|
|
19
|
-
- Much less bundle size
|
|
19
|
+
- Much smaller (less bundle size)
|
|
20
20
|
- Less is more: faster, less bugs, no breaking changes
|
|
21
|
-
- Is progressive -- lazy loads styles
|
|
21
|
+
- Is progressive -- lazy loads styles
|
|
22
22
|
- Css shorthand props like [chakra-ui](https://chakra-ui.com/docs/styled-system/style-props):
|
|
23
23
|
- `m` --> `margin`
|
|
24
24
|
- `mx` --> `margin-left` and bottom
|
|
@@ -35,11 +35,7 @@ Pros:
|
|
|
35
35
|
}
|
|
36
36
|
```
|
|
37
37
|
|
|
38
|
-
- Breakpoints are `[30em, 48em, 62em, 80em, 96em]`
|
|
39
|
-
|
|
40
|
-
Cons:
|
|
41
|
-
|
|
42
|
-
- No SSR support
|
|
38
|
+
- Breakpoints are `[30em, 48em, 62em, 80em, 96em]` and can be overridden by setting `css.breakpoints`
|
|
43
39
|
|
|
44
40
|
## Setup/Install
|
|
45
41
|
|
|
@@ -47,6 +43,30 @@ Cons:
|
|
|
47
43
|
npm i @slimr/css
|
|
48
44
|
```
|
|
49
45
|
|
|
46
|
+
## addCss
|
|
47
|
+
|
|
48
|
+
Injects css to the page head
|
|
49
|
+
|
|
50
|
+
- Lazy: Will not be added until the component mounts, if called from within a component
|
|
51
|
+
- Batches dom changes for better performance
|
|
52
|
+
- Has local cache to recall prior adds, to reduce duplicates and dom changes
|
|
53
|
+
|
|
54
|
+
@param css - css to be injected
|
|
55
|
+
@returns void
|
|
56
|
+
|
|
57
|
+
## `css` (alias for `createClass`)
|
|
58
|
+
|
|
59
|
+
## `classJoin`
|
|
60
|
+
|
|
61
|
+
Joins class names and omits falsey props
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
classJoin('a', 'b', 'c') // 'a b c'
|
|
65
|
+
classJoin('a', 0, 'b', null, 'c') // 'a b c'
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Shorthang Props (`shorthandPropsMap` and `ShorthandProps`)
|
|
69
|
+
|
|
50
70
|
## Usage
|
|
51
71
|
|
|
52
72
|
```tsx
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { T2SProps } from '@slimr/util';
|
|
2
|
+
/**
|
|
3
|
+
* Injects css to the page head
|
|
4
|
+
*
|
|
5
|
+
* - Lazy: Will not be added until the component mounts, if called from within a component
|
|
6
|
+
* - Batches dom changes for better performance
|
|
7
|
+
* - Has local cache to recall prior adds, to reduce duplicates and dom changes
|
|
8
|
+
*
|
|
9
|
+
* @param css - css to be injected
|
|
10
|
+
* @returns void
|
|
11
|
+
*/
|
|
12
|
+
export declare function addCss(css: string): void;
|
|
13
|
+
export declare namespace addCss {
|
|
14
|
+
var que: Set<string>;
|
|
15
|
+
var count: number;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Joins class names and omits falsey props
|
|
19
|
+
*
|
|
20
|
+
* @param classes - class names to be joined
|
|
21
|
+
* @returns a string of joined class names
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```typescript
|
|
25
|
+
* classJoin('a', 'b', 'c') // 'a b c'
|
|
26
|
+
* classJoin('a', 0, 'b', null, 'c') // 'a b c'
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export declare function classJoin(...classes: (string | 0 | null | undefined)[]): string;
|
|
30
|
+
/**
|
|
31
|
+
* Injects css and creates unique class names
|
|
32
|
+
*
|
|
33
|
+
* - Skips if already added
|
|
34
|
+
*
|
|
35
|
+
* @param cssString - string or template string, to be injected
|
|
36
|
+
* @returns a unique class name
|
|
37
|
+
*/
|
|
38
|
+
export declare function createClass(...p: T2SProps): string;
|
|
39
|
+
export declare namespace createClass {
|
|
40
|
+
var breakPoints: string[];
|
|
41
|
+
var count: number;
|
|
42
|
+
var history: Map<string, string>;
|
|
43
|
+
}
|
|
@@ -1,13 +1,95 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.createClass = exports.
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
/**
|
|
3
|
+
exports.createClass = exports.classJoin = exports.addCss = void 0;
|
|
4
|
+
const util_1 = require("@slimr/util");
|
|
5
|
+
const shorthandProps_js_1 = require("./shorthandProps.js");
|
|
6
|
+
/**
|
|
7
|
+
* Injects css to the page head
|
|
8
|
+
*
|
|
9
|
+
* - Lazy: Will not be added until the component mounts, if called from within a component
|
|
10
|
+
* - Batches dom changes for better performance
|
|
11
|
+
* - Has local cache to recall prior adds, to reduce duplicates and dom changes
|
|
12
|
+
*
|
|
13
|
+
* @param css - css to be injected
|
|
14
|
+
* @returns void
|
|
15
|
+
*/
|
|
16
|
+
function addCss(css) {
|
|
17
|
+
addCss.que.add(css);
|
|
18
|
+
setTimeout(() => {
|
|
19
|
+
const css = [...addCss.que].join('\n');
|
|
20
|
+
if (css) {
|
|
21
|
+
addCss.que.clear();
|
|
22
|
+
const s = document.createElement('style');
|
|
23
|
+
s.id = `u${addCss.count++}`;
|
|
24
|
+
s.innerHTML = css;
|
|
25
|
+
document.head.appendChild(s);
|
|
26
|
+
}
|
|
27
|
+
}, 0);
|
|
28
|
+
}
|
|
29
|
+
exports.addCss = addCss;
|
|
30
|
+
addCss.que = new Set();
|
|
31
|
+
addCss.count = 0;
|
|
32
|
+
/**
|
|
33
|
+
* Joins class names and omits falsey props
|
|
34
|
+
*
|
|
35
|
+
* @param classes - class names to be joined
|
|
36
|
+
* @returns a string of joined class names
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```typescript
|
|
40
|
+
* classJoin('a', 'b', 'c') // 'a b c'
|
|
41
|
+
* classJoin('a', 0, 'b', null, 'c') // 'a b c'
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
7
44
|
function classJoin(...classes) {
|
|
8
45
|
return classes.filter(c => c && typeof c === 'string').join(' ');
|
|
9
46
|
}
|
|
10
47
|
exports.classJoin = classJoin;
|
|
48
|
+
/**
|
|
49
|
+
* Injects css and creates unique class names
|
|
50
|
+
*
|
|
51
|
+
* - Skips if already added
|
|
52
|
+
*
|
|
53
|
+
* @param cssString - string or template string, to be injected
|
|
54
|
+
* @returns a unique class name
|
|
55
|
+
*/
|
|
56
|
+
function createClass(...p) {
|
|
57
|
+
let css = (0, util_1.t2s)(...p);
|
|
58
|
+
if (!css)
|
|
59
|
+
return '';
|
|
60
|
+
let className = createClass.history.get(css);
|
|
61
|
+
if (!className) {
|
|
62
|
+
className = 's' + createClass.count++;
|
|
63
|
+
createClass.history.set(css, className);
|
|
64
|
+
css = deleteComments(css);
|
|
65
|
+
css = (0, shorthandProps_js_1.expandShorthands)(css);
|
|
66
|
+
css = expandArrayValues(css);
|
|
67
|
+
const qs = findQueries(css);
|
|
68
|
+
for (const q of qs.reverse()) {
|
|
69
|
+
css = css.slice(0, q.start) + css.slice(q.end);
|
|
70
|
+
}
|
|
71
|
+
css = `.${className}{\n${css}\n}\n`;
|
|
72
|
+
css += qs
|
|
73
|
+
.map(q => {
|
|
74
|
+
if (q.query.startsWith('&')) {
|
|
75
|
+
return `.${className}${q.query.slice(1)}{\n${q.innerBody}\n}`;
|
|
76
|
+
}
|
|
77
|
+
if (q.query.startsWith('@keyframes')) {
|
|
78
|
+
return q.outerBody;
|
|
79
|
+
}
|
|
80
|
+
return `${q.query}{\n.${className}{${q.innerBody}\n}\n}`;
|
|
81
|
+
})
|
|
82
|
+
.join('\n');
|
|
83
|
+
css = trimByLine(css) + '\n\n';
|
|
84
|
+
addCss(css);
|
|
85
|
+
}
|
|
86
|
+
return className;
|
|
87
|
+
}
|
|
88
|
+
exports.createClass = createClass;
|
|
89
|
+
/** Breakpoints like chakra */
|
|
90
|
+
createClass.breakPoints = ['30em', '48em', '62em', '80em', '96em'];
|
|
91
|
+
createClass.count = 0;
|
|
92
|
+
createClass.history = new Map();
|
|
11
93
|
/** delete css comments **/
|
|
12
94
|
function deleteComments(css) {
|
|
13
95
|
return css.replace(/{\/\*[\s\S]*?(?=\*\/})\*\/}/gm, '');
|
|
@@ -35,7 +117,7 @@ function expandArrayValues(css) {
|
|
|
35
117
|
if (i === 0) {
|
|
36
118
|
return `${prop}: ${val};`;
|
|
37
119
|
}
|
|
38
|
-
return `@media (min-width: ${
|
|
120
|
+
return `@media (min-width: ${createClass.breakPoints[i - 1]}) { ${prop}: ${val}; }`;
|
|
39
121
|
})
|
|
40
122
|
.join('\n');
|
|
41
123
|
}
|
|
@@ -43,48 +125,6 @@ function expandArrayValues(css) {
|
|
|
43
125
|
})
|
|
44
126
|
.join('\n');
|
|
45
127
|
}
|
|
46
|
-
exports.shorthandPropsMap = {
|
|
47
|
-
ai: 'align-items',
|
|
48
|
-
b: 'border',
|
|
49
|
-
br: 'border-radius',
|
|
50
|
-
bg: 'background',
|
|
51
|
-
c: 'color',
|
|
52
|
-
d: 'display',
|
|
53
|
-
f: 'flex',
|
|
54
|
-
fd: 'flex-direction',
|
|
55
|
-
i: 'inset',
|
|
56
|
-
h: 'height',
|
|
57
|
-
jc: 'justify-content',
|
|
58
|
-
m: 'margin',
|
|
59
|
-
ml: 'margin-left',
|
|
60
|
-
mr: 'margin-right',
|
|
61
|
-
mt: 'margin-top',
|
|
62
|
-
mb: 'margin-bottom',
|
|
63
|
-
maxW: 'max-width',
|
|
64
|
-
minW: 'min-width',
|
|
65
|
-
p: 'padding',
|
|
66
|
-
pl: 'padding-left',
|
|
67
|
-
pr: 'padding-right',
|
|
68
|
-
pt: 'padding-top',
|
|
69
|
-
pb: 'padding-bottom',
|
|
70
|
-
pos: 'position',
|
|
71
|
-
ta: 'text-align',
|
|
72
|
-
w: 'width',
|
|
73
|
-
z: 'z-index',
|
|
74
|
-
};
|
|
75
|
-
exports.shorthandProps = [...Object.keys(exports.shorthandPropsMap), 'mx', 'my', 'px', 'py'];
|
|
76
|
-
/** Expand short-hand css props to full */
|
|
77
|
-
function expandProps(css) {
|
|
78
|
-
css = '\n' + css; // inject a newline to make the regex easier
|
|
79
|
-
// Handle 'mx', 'my', 'px', 'py'
|
|
80
|
-
css = css
|
|
81
|
-
.replace(/([mp])x:([^;]*)/g, '$1l:$2;\n$1r:$2')
|
|
82
|
-
.replace(/([mp])y:([^;]*);/g, '$1t:$2;\n$1b:$2');
|
|
83
|
-
Object.entries(exports.shorthandPropsMap).forEach(([k, v]) => {
|
|
84
|
-
css = css.replace(new RegExp(`([ \n\t;])${k}:`, 'g'), `$1${v}:`);
|
|
85
|
-
});
|
|
86
|
-
return css.trim();
|
|
87
|
-
}
|
|
88
128
|
/** Find @keyframes, @media, @container queries in css **/
|
|
89
129
|
function findQueries(css) {
|
|
90
130
|
const queries = [];
|
|
@@ -120,95 +160,11 @@ function findQueries(css) {
|
|
|
120
160
|
return queries;
|
|
121
161
|
}
|
|
122
162
|
/** Trims whitespace for every line */
|
|
123
|
-
function
|
|
163
|
+
function trimByLine(css) {
|
|
124
164
|
return css
|
|
125
165
|
.split('\n')
|
|
126
166
|
.map(l => l.trim())
|
|
127
167
|
.filter(l => l)
|
|
128
168
|
.join('\n');
|
|
129
169
|
}
|
|
130
|
-
/**
|
|
131
|
-
* Assemble a string from a template string array and a list of placeholders.
|
|
132
|
-
*
|
|
133
|
-
* - If the first argument is a string, it is returned as is.
|
|
134
|
-
*
|
|
135
|
-
* i.e.
|
|
136
|
-
* myFoo(...props: TemplateStringProps) => {
|
|
137
|
-
* const inputStr = t2s(...props);
|
|
138
|
-
* }
|
|
139
|
-
* myFoo`hello ${name}` => 'hello world'
|
|
140
|
-
* myFoo(`hello ${name}`) => 'hello world'
|
|
141
|
-
*/
|
|
142
|
-
function t2s(...tsp) {
|
|
143
|
-
const [s, ...p] = tsp;
|
|
144
|
-
return typeof s === 'string' ? s : s.map((s, i) => s + (p?.[i] ?? '')).join('');
|
|
145
|
-
}
|
|
146
|
-
exports.t2s = t2s;
|
|
147
|
-
/**
|
|
148
|
-
* Injects css to the page
|
|
149
|
-
*
|
|
150
|
-
* - Batches adds for performance
|
|
151
|
-
*
|
|
152
|
-
* @param css - css to be injected
|
|
153
|
-
* @returns void
|
|
154
|
-
*/
|
|
155
|
-
function addCss(css) {
|
|
156
|
-
addCss.que.add(css);
|
|
157
|
-
setTimeout(() => {
|
|
158
|
-
const css = [...addCss.que].join('\n');
|
|
159
|
-
if (css) {
|
|
160
|
-
addCss.que.clear();
|
|
161
|
-
const s = document.createElement('style');
|
|
162
|
-
s.id = `u${addCss.count++}`;
|
|
163
|
-
s.innerHTML = css;
|
|
164
|
-
document.head.appendChild(s);
|
|
165
|
-
}
|
|
166
|
-
}, 0);
|
|
167
|
-
}
|
|
168
|
-
exports.addCss = addCss;
|
|
169
|
-
addCss.que = new Set();
|
|
170
|
-
addCss.count = 0;
|
|
171
|
-
/**
|
|
172
|
-
* Injects css and creates unique class names
|
|
173
|
-
*
|
|
174
|
-
* - Skips if already added
|
|
175
|
-
*
|
|
176
|
-
* @param css - string or template string, to be injected
|
|
177
|
-
* @returns a unique class name
|
|
178
|
-
*/
|
|
179
|
-
function createClass(...p) {
|
|
180
|
-
let css = t2s(...p);
|
|
181
|
-
if (!css)
|
|
182
|
-
return '';
|
|
183
|
-
let className = createClass.history.get(css);
|
|
184
|
-
if (!className) {
|
|
185
|
-
className = 's' + createClass.count++;
|
|
186
|
-
createClass.history.set(css, className);
|
|
187
|
-
css = deleteComments(css);
|
|
188
|
-
css = expandProps(css);
|
|
189
|
-
css = expandArrayValues(css);
|
|
190
|
-
const qs = findQueries(css);
|
|
191
|
-
for (const q of qs.reverse()) {
|
|
192
|
-
css = css.slice(0, q.start) + css.slice(q.end);
|
|
193
|
-
}
|
|
194
|
-
css = `.${className}{\n${css}\n}\n`;
|
|
195
|
-
css += qs
|
|
196
|
-
.map(q => {
|
|
197
|
-
if (q.query.startsWith('&')) {
|
|
198
|
-
return `.${className}${q.query.slice(1)}{\n${q.innerBody}\n}`;
|
|
199
|
-
}
|
|
200
|
-
if (q.query.startsWith('@keyframes')) {
|
|
201
|
-
return q.outerBody;
|
|
202
|
-
}
|
|
203
|
-
return `${q.query}{\n.${className}{${q.innerBody}\n}\n}`;
|
|
204
|
-
})
|
|
205
|
-
.join('\n');
|
|
206
|
-
css = trim(css) + '\n\n';
|
|
207
|
-
addCss(css);
|
|
208
|
-
}
|
|
209
|
-
return className;
|
|
210
|
-
}
|
|
211
|
-
exports.createClass = createClass;
|
|
212
|
-
createClass.count = 0;
|
|
213
|
-
createClass.history = new Map();
|
|
214
170
|
//# sourceMappingURL=createClass.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createClass.js","sourceRoot":"","sources":["../src/createClass.ts"],"names":[],"mappings":"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"}
|
package/cjs/createClass.ts
CHANGED
|
@@ -1,14 +1,98 @@
|
|
|
1
|
-
|
|
2
|
-
export const breakPoints = ['30em', '48em', '62em', '80em', '96em']
|
|
1
|
+
import {T2SProps, t2s} from '@slimr/util'
|
|
3
2
|
|
|
4
|
-
|
|
5
|
-
type allowableAny = any
|
|
3
|
+
import {expandShorthands} from './shorthandProps.js'
|
|
6
4
|
|
|
7
|
-
/**
|
|
8
|
-
|
|
5
|
+
/**
|
|
6
|
+
* Injects css to the page head
|
|
7
|
+
*
|
|
8
|
+
* - Lazy: Will not be added until the component mounts, if called from within a component
|
|
9
|
+
* - Batches dom changes for better performance
|
|
10
|
+
* - Has local cache to recall prior adds, to reduce duplicates and dom changes
|
|
11
|
+
*
|
|
12
|
+
* @param css - css to be injected
|
|
13
|
+
* @returns void
|
|
14
|
+
*/
|
|
15
|
+
export function addCss(css: string) {
|
|
16
|
+
addCss.que.add(css)
|
|
17
|
+
setTimeout(() => {
|
|
18
|
+
const css = [...addCss.que].join('\n')
|
|
19
|
+
if (css) {
|
|
20
|
+
addCss.que.clear()
|
|
21
|
+
const s = document.createElement('style')
|
|
22
|
+
s.id = `u${addCss.count++}`
|
|
23
|
+
s.innerHTML = css
|
|
24
|
+
document.head.appendChild(s)
|
|
25
|
+
}
|
|
26
|
+
}, 0)
|
|
27
|
+
}
|
|
28
|
+
addCss.que = new Set<string>()
|
|
29
|
+
addCss.count = 0
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Joins class names and omits falsey props
|
|
33
|
+
*
|
|
34
|
+
* @param classes - class names to be joined
|
|
35
|
+
* @returns a string of joined class names
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```typescript
|
|
39
|
+
* classJoin('a', 'b', 'c') // 'a b c'
|
|
40
|
+
* classJoin('a', 0, 'b', null, 'c') // 'a b c'
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
export function classJoin(...classes: (string | 0 | null | undefined)[]) {
|
|
9
44
|
return classes.filter(c => c && typeof c === 'string').join(' ')
|
|
10
45
|
}
|
|
11
46
|
|
|
47
|
+
/**
|
|
48
|
+
* Injects css and creates unique class names
|
|
49
|
+
*
|
|
50
|
+
* - Skips if already added
|
|
51
|
+
*
|
|
52
|
+
* @param cssString - string or template string, to be injected
|
|
53
|
+
* @returns a unique class name
|
|
54
|
+
*/
|
|
55
|
+
export function createClass(...p: T2SProps) {
|
|
56
|
+
let css = t2s(...p)
|
|
57
|
+
if (!css) return ''
|
|
58
|
+
let className = createClass.history.get(css)
|
|
59
|
+
if (!className) {
|
|
60
|
+
className = 's' + createClass.count++
|
|
61
|
+
createClass.history.set(css, className)
|
|
62
|
+
|
|
63
|
+
css = deleteComments(css)
|
|
64
|
+
css = expandShorthands(css)
|
|
65
|
+
css = expandArrayValues(css)
|
|
66
|
+
const qs = findQueries(css)
|
|
67
|
+
|
|
68
|
+
for (const q of qs.reverse()) {
|
|
69
|
+
css = css.slice(0, q.start) + css.slice(q.end)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
css = `.${className}{\n${css}\n}\n`
|
|
73
|
+
css += qs
|
|
74
|
+
.map(q => {
|
|
75
|
+
if (q.query.startsWith('&')) {
|
|
76
|
+
return `.${className}${q.query.slice(1)}{\n${q.innerBody}\n}`
|
|
77
|
+
}
|
|
78
|
+
if (q.query.startsWith('@keyframes')) {
|
|
79
|
+
return q.outerBody
|
|
80
|
+
}
|
|
81
|
+
return `${q.query}{\n.${className}{${q.innerBody}\n}\n}`
|
|
82
|
+
})
|
|
83
|
+
.join('\n')
|
|
84
|
+
|
|
85
|
+
css = trimByLine(css) + '\n\n'
|
|
86
|
+
|
|
87
|
+
addCss(css)
|
|
88
|
+
}
|
|
89
|
+
return className
|
|
90
|
+
}
|
|
91
|
+
/** Breakpoints like chakra */
|
|
92
|
+
createClass.breakPoints = ['30em', '48em', '62em', '80em', '96em']
|
|
93
|
+
createClass.count = 0
|
|
94
|
+
createClass.history = new Map<string, string>()
|
|
95
|
+
|
|
12
96
|
/** delete css comments **/
|
|
13
97
|
function deleteComments(css: string) {
|
|
14
98
|
return css.replace(/{\/\*[\s\S]*?(?=\*\/})\*\/}/gm, '')
|
|
@@ -35,7 +119,7 @@ function expandArrayValues(css: string) {
|
|
|
35
119
|
if (i === 0) {
|
|
36
120
|
return `${prop}: ${val};`
|
|
37
121
|
}
|
|
38
|
-
return `@media (min-width: ${breakPoints[i - 1]}) { ${prop}: ${val}; }`
|
|
122
|
+
return `@media (min-width: ${createClass.breakPoints[i - 1]}) { ${prop}: ${val}; }`
|
|
39
123
|
})
|
|
40
124
|
.join('\n')
|
|
41
125
|
}
|
|
@@ -44,117 +128,6 @@ function expandArrayValues(css: string) {
|
|
|
44
128
|
.join('\n')
|
|
45
129
|
}
|
|
46
130
|
|
|
47
|
-
export interface ShorthandProps {
|
|
48
|
-
/** shorthand for css:align-items */
|
|
49
|
-
ai?: string
|
|
50
|
-
/** shorthand for css:border */
|
|
51
|
-
b?: string | number
|
|
52
|
-
/** shorthand for css:border-radius */
|
|
53
|
-
br?: string | number
|
|
54
|
-
/** shorthand for css:background */
|
|
55
|
-
bg?: string
|
|
56
|
-
/** shorthand for css:color */
|
|
57
|
-
c?: string
|
|
58
|
-
/** shorthand for css:display */
|
|
59
|
-
d?: string
|
|
60
|
-
/** shorthand for css:flex */
|
|
61
|
-
f?: string
|
|
62
|
-
/** shorthand for css:flex-direction */
|
|
63
|
-
fd?: string
|
|
64
|
-
/** shorthand for css:height */
|
|
65
|
-
h?: number | string
|
|
66
|
-
/** shorthand for css:inset */
|
|
67
|
-
i?: number | string
|
|
68
|
-
/** shorthand for css:justify-content */
|
|
69
|
-
jc?: string
|
|
70
|
-
/** shorthand for css:margin */
|
|
71
|
-
m?: number | string
|
|
72
|
-
/** shorthand for css:margin-left */
|
|
73
|
-
ml?: number | string
|
|
74
|
-
/** shorthand for css:margin-right */
|
|
75
|
-
mr?: number | string
|
|
76
|
-
/** shorthand for css:margin-top */
|
|
77
|
-
mt?: number | string
|
|
78
|
-
/** shorthand for css:margin-bottom */
|
|
79
|
-
mb?: number | string
|
|
80
|
-
/** shorthand for css:margin-top & margin-bottom */
|
|
81
|
-
my?: number | string
|
|
82
|
-
/** shorthand for css:margin-left & margin-right */
|
|
83
|
-
mx?: number | string
|
|
84
|
-
/** shorthand for css:max-width */
|
|
85
|
-
maxW?: number | string
|
|
86
|
-
/** shorthand for css:min-width */
|
|
87
|
-
minW?: number | string
|
|
88
|
-
/** shorthand for css:padding */
|
|
89
|
-
p?: number | string
|
|
90
|
-
/** shorthand for css:padding-left */
|
|
91
|
-
pl?: number | string
|
|
92
|
-
/** shorthand for css:padding-right */
|
|
93
|
-
pr?: number | string
|
|
94
|
-
/** shorthand for css:padding-top */
|
|
95
|
-
pt?: number | string
|
|
96
|
-
/** shorthand for css:padding-bottom */
|
|
97
|
-
pb?: number | string
|
|
98
|
-
/** shorthand for css:padding-top & padding-bottom */
|
|
99
|
-
py?: number | string
|
|
100
|
-
/** shorthand for css:padding-left & padding-right */
|
|
101
|
-
px?: number | string
|
|
102
|
-
/** shorthand for css:position */
|
|
103
|
-
pos?: number | string
|
|
104
|
-
/** shorthand for css:text-align */
|
|
105
|
-
ta?: string
|
|
106
|
-
/** shorthand for css:width */
|
|
107
|
-
w?: number | string
|
|
108
|
-
/** shorthand for css:z-index */
|
|
109
|
-
z?: number | string
|
|
110
|
-
}
|
|
111
|
-
export const shorthandPropsMap: Record<
|
|
112
|
-
keyof Omit<ShorthandProps, 'mx' | 'my' | 'px' | 'py'>,
|
|
113
|
-
string
|
|
114
|
-
> = {
|
|
115
|
-
ai: 'align-items',
|
|
116
|
-
b: 'border',
|
|
117
|
-
br: 'border-radius',
|
|
118
|
-
bg: 'background',
|
|
119
|
-
c: 'color',
|
|
120
|
-
d: 'display',
|
|
121
|
-
f: 'flex',
|
|
122
|
-
fd: 'flex-direction',
|
|
123
|
-
i: 'inset',
|
|
124
|
-
h: 'height',
|
|
125
|
-
jc: 'justify-content',
|
|
126
|
-
m: 'margin',
|
|
127
|
-
ml: 'margin-left',
|
|
128
|
-
mr: 'margin-right',
|
|
129
|
-
mt: 'margin-top',
|
|
130
|
-
mb: 'margin-bottom',
|
|
131
|
-
maxW: 'max-width',
|
|
132
|
-
minW: 'min-width',
|
|
133
|
-
p: 'padding',
|
|
134
|
-
pl: 'padding-left',
|
|
135
|
-
pr: 'padding-right',
|
|
136
|
-
pt: 'padding-top',
|
|
137
|
-
pb: 'padding-bottom',
|
|
138
|
-
pos: 'position',
|
|
139
|
-
ta: 'text-align',
|
|
140
|
-
w: 'width',
|
|
141
|
-
z: 'z-index',
|
|
142
|
-
}
|
|
143
|
-
export const shorthandProps = [...Object.keys(shorthandPropsMap), 'mx', 'my', 'px', 'py']
|
|
144
|
-
|
|
145
|
-
/** Expand short-hand css props to full */
|
|
146
|
-
function expandProps(css: string) {
|
|
147
|
-
css = '\n' + css // inject a newline to make the regex easier
|
|
148
|
-
// Handle 'mx', 'my', 'px', 'py'
|
|
149
|
-
css = css
|
|
150
|
-
.replace(/([mp])x:([^;]*)/g, '$1l:$2;\n$1r:$2')
|
|
151
|
-
.replace(/([mp])y:([^;]*);/g, '$1t:$2;\n$1b:$2')
|
|
152
|
-
Object.entries(shorthandPropsMap).forEach(([k, v]) => {
|
|
153
|
-
css = css.replace(new RegExp(`([ \n\t;])${k}:`, 'g'), `$1${v}:`)
|
|
154
|
-
})
|
|
155
|
-
return css.trim()
|
|
156
|
-
}
|
|
157
|
-
|
|
158
131
|
/** Find @keyframes, @media, @container queries in css **/
|
|
159
132
|
function findQueries(css: string) {
|
|
160
133
|
const queries = []
|
|
@@ -189,102 +162,10 @@ function findQueries(css: string) {
|
|
|
189
162
|
}
|
|
190
163
|
|
|
191
164
|
/** Trims whitespace for every line */
|
|
192
|
-
function
|
|
165
|
+
function trimByLine(css: string) {
|
|
193
166
|
return css
|
|
194
167
|
.split('\n')
|
|
195
168
|
.map(l => l.trim())
|
|
196
169
|
.filter(l => l)
|
|
197
170
|
.join('\n')
|
|
198
171
|
}
|
|
199
|
-
|
|
200
|
-
/**
|
|
201
|
-
* Assemble a string from a template string array and a list of placeholders.
|
|
202
|
-
*
|
|
203
|
-
* - If the first argument is a string, it is returned as is.
|
|
204
|
-
*
|
|
205
|
-
* i.e.
|
|
206
|
-
* myFoo(...props: TemplateStringProps) => {
|
|
207
|
-
* const inputStr = t2s(...props);
|
|
208
|
-
* }
|
|
209
|
-
* myFoo`hello ${name}` => 'hello world'
|
|
210
|
-
* myFoo(`hello ${name}`) => 'hello world'
|
|
211
|
-
*/
|
|
212
|
-
export function t2s(...tsp: TemplateStringProps) {
|
|
213
|
-
const [s, ...p] = tsp
|
|
214
|
-
return typeof s === 'string' ? s : s.map((s, i) => s + (p?.[i] ?? '')).join('')
|
|
215
|
-
}
|
|
216
|
-
export type TemplateStringProps = [
|
|
217
|
-
strings: TemplateStringsArray | string,
|
|
218
|
-
...placeHolders: string[]
|
|
219
|
-
]
|
|
220
|
-
|
|
221
|
-
/**
|
|
222
|
-
* Injects css to the page
|
|
223
|
-
*
|
|
224
|
-
* - Batches adds for performance
|
|
225
|
-
*
|
|
226
|
-
* @param css - css to be injected
|
|
227
|
-
* @returns void
|
|
228
|
-
*/
|
|
229
|
-
export function addCss(css: string) {
|
|
230
|
-
addCss.que.add(css)
|
|
231
|
-
setTimeout(() => {
|
|
232
|
-
const css = [...addCss.que].join('\n')
|
|
233
|
-
if (css) {
|
|
234
|
-
addCss.que.clear()
|
|
235
|
-
const s = document.createElement('style')
|
|
236
|
-
s.id = `u${addCss.count++}`
|
|
237
|
-
s.innerHTML = css
|
|
238
|
-
document.head.appendChild(s)
|
|
239
|
-
}
|
|
240
|
-
}, 0)
|
|
241
|
-
}
|
|
242
|
-
addCss.que = new Set<string>()
|
|
243
|
-
addCss.count = 0
|
|
244
|
-
|
|
245
|
-
/**
|
|
246
|
-
* Injects css and creates unique class names
|
|
247
|
-
*
|
|
248
|
-
* - Skips if already added
|
|
249
|
-
*
|
|
250
|
-
* @param css - string or template string, to be injected
|
|
251
|
-
* @returns a unique class name
|
|
252
|
-
*/
|
|
253
|
-
export function createClass(...p: TemplateStringProps) {
|
|
254
|
-
let css = t2s(...p)
|
|
255
|
-
if (!css) return ''
|
|
256
|
-
let className = createClass.history.get(css)
|
|
257
|
-
if (!className) {
|
|
258
|
-
className = 's' + createClass.count++
|
|
259
|
-
createClass.history.set(css, className)
|
|
260
|
-
|
|
261
|
-
css = deleteComments(css)
|
|
262
|
-
css = expandProps(css)
|
|
263
|
-
css = expandArrayValues(css)
|
|
264
|
-
const qs = findQueries(css)
|
|
265
|
-
|
|
266
|
-
for (const q of qs.reverse()) {
|
|
267
|
-
css = css.slice(0, q.start) + css.slice(q.end)
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
css = `.${className}{\n${css}\n}\n`
|
|
271
|
-
css += qs
|
|
272
|
-
.map(q => {
|
|
273
|
-
if (q.query.startsWith('&')) {
|
|
274
|
-
return `.${className}${q.query.slice(1)}{\n${q.innerBody}\n}`
|
|
275
|
-
}
|
|
276
|
-
if (q.query.startsWith('@keyframes')) {
|
|
277
|
-
return q.outerBody
|
|
278
|
-
}
|
|
279
|
-
return `${q.query}{\n.${className}{${q.innerBody}\n}\n}`
|
|
280
|
-
})
|
|
281
|
-
.join('\n')
|
|
282
|
-
|
|
283
|
-
css = trim(css) + '\n\n'
|
|
284
|
-
|
|
285
|
-
addCss(css)
|
|
286
|
-
}
|
|
287
|
-
return className
|
|
288
|
-
}
|
|
289
|
-
createClass.count = 0
|
|
290
|
-
createClass.history = new Map<string, string>()
|