uraniyum 1.1.9 → 1.2.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/dist/helpers.d.ts +0 -1
- package/dist/index.esm.js +59 -117
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +59 -117
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/package.json +1 -1
- package/src/helpers.ts +2 -5
- package/src/styles.ts +95 -127
package/src/styles.ts
CHANGED
|
@@ -11,25 +11,9 @@ export interface StyleRule {
|
|
|
11
11
|
export type StylesMap = Record<string, StyleRule>;
|
|
12
12
|
export type ClassNames<T extends StylesMap> = { [K in keyof T]: string };
|
|
13
13
|
|
|
14
|
-
const styleCache = new Map<string, true>();
|
|
15
|
-
const keyframeCache = new Map<string, string>();
|
|
16
14
|
let styleElement: HTMLStyleElement | null = null;
|
|
17
15
|
let styleSheet: CSSStyleSheet | null = null;
|
|
18
16
|
|
|
19
|
-
const ALLOWED_PREFIXES = [
|
|
20
|
-
"root",
|
|
21
|
-
"button",
|
|
22
|
-
"icon",
|
|
23
|
-
"text",
|
|
24
|
-
"container",
|
|
25
|
-
"wrapper",
|
|
26
|
-
"card",
|
|
27
|
-
"header",
|
|
28
|
-
"section",
|
|
29
|
-
];
|
|
30
|
-
|
|
31
|
-
const KEYFRAMES_PREFIX = "@keyframes ";
|
|
32
|
-
|
|
33
17
|
function ensureStyleSheet(): CSSStyleSheet {
|
|
34
18
|
if (!styleSheet) {
|
|
35
19
|
if (!styleElement) {
|
|
@@ -42,43 +26,73 @@ function ensureStyleSheet(): CSSStyleSheet {
|
|
|
42
26
|
return styleSheet;
|
|
43
27
|
}
|
|
44
28
|
|
|
45
|
-
function hashString(str: string): string {
|
|
46
|
-
let hash = 5381;
|
|
47
|
-
for (let i = 0; i < str.length; i++) {
|
|
48
|
-
hash = (hash * 33) ^ str.charCodeAt(i);
|
|
49
|
-
}
|
|
50
|
-
return (hash >>> 0).toString(36);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
29
|
const camelToKebabCache = new Map<string, string>();
|
|
54
30
|
|
|
55
31
|
function camelToKebab(str: string): string {
|
|
56
32
|
const cached = camelToKebabCache.get(str);
|
|
57
33
|
if (cached) return cached;
|
|
58
34
|
|
|
59
|
-
const result = str.replace(/[A-Z]/g,
|
|
35
|
+
const result = str.replace(/[A-Z]/g, m => "-" + m.toLowerCase());
|
|
60
36
|
camelToKebabCache.set(str, result);
|
|
61
37
|
return result;
|
|
62
38
|
}
|
|
63
39
|
|
|
64
|
-
|
|
65
|
-
const parts: string[] = [];
|
|
40
|
+
type AtomicKey = string;
|
|
66
41
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
const val = rule[key];
|
|
42
|
+
const atomicClassCache = new Map<AtomicKey, string>();
|
|
43
|
+
let atomicCounter = 0;
|
|
70
44
|
|
|
71
|
-
|
|
45
|
+
function nextAtomicClass(): string {
|
|
46
|
+
return `a-${atomicCounter++}`;
|
|
47
|
+
}
|
|
72
48
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
49
|
+
function registerAtomicRule(
|
|
50
|
+
selector: string,
|
|
51
|
+
decl: string,
|
|
52
|
+
): string {
|
|
53
|
+
const key = `${selector}|${decl}`;
|
|
54
|
+
|
|
55
|
+
const cached = atomicClassCache.get(key);
|
|
56
|
+
if (cached) return cached;
|
|
57
|
+
|
|
58
|
+
const className = nextAtomicClass();
|
|
59
|
+
atomicClassCache.set(key, className);
|
|
60
|
+
|
|
61
|
+
ensureStyleSheet().insertRule(
|
|
62
|
+
`${selector.replace(/&/g, `.${className}`)}{${decl}}`,
|
|
63
|
+
styleSheet!.cssRules.length,
|
|
64
|
+
);
|
|
76
65
|
|
|
77
|
-
|
|
66
|
+
return className;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const KEYFRAMES_PREFIX = "@keyframes ";
|
|
70
|
+
const keyframeCache = new Map<string, string>();
|
|
71
|
+
let keyframeCounter = 0;
|
|
72
|
+
|
|
73
|
+
function registerKeyframes(
|
|
74
|
+
name: string,
|
|
75
|
+
frames: Record<string, any>,
|
|
76
|
+
): string {
|
|
77
|
+
const signature = name + JSON.stringify(frames);
|
|
78
|
+
const cached = keyframeCache.get(signature);
|
|
79
|
+
if (cached) return cached;
|
|
80
|
+
|
|
81
|
+
const unique = `${name}-${keyframeCounter++}`;
|
|
82
|
+
|
|
83
|
+
const steps: string[] = [];
|
|
84
|
+
for (const step in frames) {
|
|
85
|
+
const decls = stringifyDecls(frames[step] ?? {}, new Map());
|
|
86
|
+
steps.push(`${step}{${decls}}`);
|
|
78
87
|
}
|
|
79
88
|
|
|
80
|
-
|
|
81
|
-
|
|
89
|
+
ensureStyleSheet().insertRule(
|
|
90
|
+
`@keyframes ${unique}{${steps.join("")}}`,
|
|
91
|
+
styleSheet!.cssRules.length,
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
keyframeCache.set(signature, unique);
|
|
95
|
+
return unique;
|
|
82
96
|
}
|
|
83
97
|
|
|
84
98
|
function stringifyDecls(
|
|
@@ -88,19 +102,15 @@ function stringifyDecls(
|
|
|
88
102
|
const out: string[] = [];
|
|
89
103
|
|
|
90
104
|
for (const key in props) {
|
|
91
|
-
if (!Object.prototype.hasOwnProperty.call(props, key)) continue;
|
|
92
105
|
const raw = props[key];
|
|
93
|
-
|
|
94
106
|
if (raw == null || typeof raw === "object") continue;
|
|
95
107
|
|
|
96
|
-
let val
|
|
97
|
-
typeof raw === "function" ? raw() :
|
|
108
|
+
let val =
|
|
109
|
+
typeof raw === "function" ? raw() : raw;
|
|
98
110
|
|
|
99
|
-
if (typeof val === "string"
|
|
111
|
+
if (typeof val === "string") {
|
|
100
112
|
for (const [orig, uniq] of keyframes) {
|
|
101
|
-
|
|
102
|
-
val = val.replaceAll(`$${orig}`, uniq);
|
|
103
|
-
}
|
|
113
|
+
val = val.replaceAll(`$${orig}`, uniq);
|
|
104
114
|
}
|
|
105
115
|
}
|
|
106
116
|
|
|
@@ -110,123 +120,83 @@ function stringifyDecls(
|
|
|
110
120
|
return out.join(";");
|
|
111
121
|
}
|
|
112
122
|
|
|
113
|
-
function
|
|
114
|
-
|
|
115
|
-
frames: Record<string, any>,
|
|
116
|
-
): string {
|
|
117
|
-
const hash = hashString(name + JSON.stringify(frames));
|
|
118
|
-
const unique = `${name}-${hash}`;
|
|
119
|
-
|
|
120
|
-
const cached = keyframeCache.get(unique);
|
|
121
|
-
if (cached) return cached;
|
|
122
|
-
|
|
123
|
-
const sheet = ensureStyleSheet();
|
|
124
|
-
|
|
125
|
-
const steps: string[] = [];
|
|
126
|
-
for (const step in frames) {
|
|
127
|
-
if (!Object.prototype.hasOwnProperty.call(frames, step)) continue;
|
|
128
|
-
const decls = stringifyDecls(frames[step] ?? {}, new Map());
|
|
129
|
-
steps.push(`${step}{${decls}}`);
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
const ruleText = `@keyframes ${unique}{${steps.join("")}}`;
|
|
133
|
-
sheet.insertRule(ruleText, sheet.cssRules.length);
|
|
134
|
-
keyframeCache.set(unique, unique);
|
|
135
|
-
|
|
136
|
-
return unique;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
function buildRules(
|
|
140
|
-
className: string,
|
|
141
|
-
rule: Record<string, any>,
|
|
123
|
+
function buildAtomicClasses(
|
|
124
|
+
rule: StyleRule,
|
|
142
125
|
keyframes: Map<string, string>,
|
|
143
126
|
): string[] {
|
|
144
|
-
const
|
|
145
|
-
const baseDecls: string[] = [];
|
|
127
|
+
const classes: string[] = [];
|
|
146
128
|
|
|
147
129
|
for (const key in rule) {
|
|
148
|
-
if (!Object.prototype.hasOwnProperty.call(rule, key)) continue;
|
|
149
130
|
const val = rule[key];
|
|
150
|
-
|
|
151
|
-
if (key.startsWith("@keyframes")) {
|
|
152
|
-
continue;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
131
|
if (!val) continue;
|
|
156
132
|
|
|
157
133
|
if (key[0] === ":" && typeof val === "object") {
|
|
158
|
-
const decls = stringifyDecls(val
|
|
159
|
-
if (decls)
|
|
160
|
-
|
|
161
|
-
|
|
134
|
+
const decls = stringifyDecls(val, keyframes);
|
|
135
|
+
if (!decls) continue;
|
|
136
|
+
|
|
137
|
+
classes.push(
|
|
138
|
+
registerAtomicRule(`&${key}`, decls),
|
|
139
|
+
);
|
|
162
140
|
continue;
|
|
163
141
|
}
|
|
164
142
|
|
|
165
143
|
if (key.startsWith("@media") && typeof val === "object") {
|
|
166
|
-
const decls = stringifyDecls(val
|
|
167
|
-
if (decls)
|
|
168
|
-
|
|
169
|
-
|
|
144
|
+
const decls = stringifyDecls(val, keyframes);
|
|
145
|
+
if (!decls) continue;
|
|
146
|
+
|
|
147
|
+
const className = nextAtomicClass();
|
|
148
|
+
atomicClassCache.set(`${key}|${decls}`, className);
|
|
149
|
+
|
|
150
|
+
ensureStyleSheet().insertRule(
|
|
151
|
+
`${key}{.${className}{${decls}}}`,
|
|
152
|
+
styleSheet!.cssRules.length,
|
|
153
|
+
);
|
|
154
|
+
|
|
155
|
+
classes.push(className);
|
|
170
156
|
continue;
|
|
171
157
|
}
|
|
172
158
|
|
|
173
|
-
if (
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
159
|
+
if (typeof val !== "object") {
|
|
160
|
+
let resolved =
|
|
161
|
+
typeof val === "function" ? val() : val;
|
|
162
|
+
|
|
163
|
+
if (typeof resolved === "string") {
|
|
164
|
+
for (const [orig, uniq] of keyframes) {
|
|
165
|
+
resolved = resolved.replaceAll(`$${orig}`, uniq);
|
|
166
|
+
}
|
|
178
167
|
}
|
|
179
|
-
continue;
|
|
180
|
-
}
|
|
181
168
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
169
|
+
const decl = `${camelToKebab(key)}:${resolved}`;
|
|
170
|
+
classes.push(
|
|
171
|
+
registerAtomicRule("&", decl),
|
|
172
|
+
);
|
|
185
173
|
}
|
|
186
174
|
}
|
|
187
175
|
|
|
188
|
-
|
|
189
|
-
rules.push(`.${className}{${baseDecls.join(";")}}`);
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
return rules;
|
|
176
|
+
return classes;
|
|
193
177
|
}
|
|
194
178
|
|
|
195
179
|
export function makeStyles<T extends StylesMap>(styles: T) {
|
|
196
180
|
return (): ClassNames<T> => {
|
|
197
181
|
const classNames = {} as ClassNames<T>;
|
|
198
182
|
const keyframesMap = new Map<string, string>();
|
|
199
|
-
const sheet = ensureStyleSheet();
|
|
200
183
|
|
|
201
184
|
for (const key in styles) {
|
|
202
|
-
if (!Object.prototype.hasOwnProperty.call(styles, key)) continue;
|
|
203
185
|
if (!key.startsWith(KEYFRAMES_PREFIX)) continue;
|
|
204
186
|
|
|
205
187
|
const name = key.slice(KEYFRAMES_PREFIX.length);
|
|
206
|
-
const frames = styles[key] as
|
|
188
|
+
const frames = styles[key] as any;
|
|
207
189
|
const unique = registerKeyframes(name, frames);
|
|
208
190
|
keyframesMap.set(name, unique);
|
|
209
191
|
}
|
|
210
192
|
|
|
211
193
|
for (const slot in styles) {
|
|
212
|
-
if (!Object.prototype.hasOwnProperty.call(styles, slot)) continue;
|
|
213
194
|
if (slot.startsWith(KEYFRAMES_PREFIX)) continue;
|
|
214
195
|
|
|
215
|
-
const rule = styles[slot] as StyleRule;
|
|
216
|
-
const
|
|
217
|
-
const className = ALLOWED_PREFIXES.includes(slot)
|
|
218
|
-
? `${slot}-${hash}`
|
|
219
|
-
: `css-${hash}`;
|
|
196
|
+
const rule = (styles[slot] ?? {}) as StyleRule;
|
|
197
|
+
const classes = buildAtomicClasses(rule, keyframesMap);
|
|
220
198
|
|
|
221
|
-
|
|
222
|
-
const rules = buildRules(className, rule, keyframesMap);
|
|
223
|
-
for (const r of rules) {
|
|
224
|
-
sheet.insertRule(r, sheet.cssRules.length);
|
|
225
|
-
}
|
|
226
|
-
styleCache.set(className, true);
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
(classNames as any)[slot] = className;
|
|
199
|
+
(classNames as any)[slot] = classes.join(" ");
|
|
230
200
|
}
|
|
231
201
|
|
|
232
202
|
return classNames;
|
|
@@ -245,13 +215,11 @@ export function mergeStyleSets<T extends StylesMap>(
|
|
|
245
215
|
for (const set of sets) {
|
|
246
216
|
if (!set) continue;
|
|
247
217
|
for (const key in set) {
|
|
248
|
-
if (!Object.prototype.hasOwnProperty.call(set, key)) continue;
|
|
249
|
-
|
|
250
218
|
const prev = (merged[key] as StyleRule) ?? {};
|
|
251
219
|
const cur = (set[key] as StyleRule) ?? {};
|
|
252
|
-
merged[key] = { ...prev, ...cur }
|
|
220
|
+
merged[key] = { ...prev, ...cur };
|
|
253
221
|
}
|
|
254
222
|
}
|
|
255
223
|
|
|
256
224
|
return makeStyles(merged as T)();
|
|
257
|
-
}
|
|
225
|
+
}
|