-
-
Notifications
You must be signed in to change notification settings - Fork 49
/
Copy pathcreateStyle.tsx
128 lines (113 loc) · 3.63 KB
/
createStyle.tsx
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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
import StyledEngineContext from "./StyledEngineProvider/StyledEngineContext";
import mergeStyleProps from "./mergeStyleProps";
import createStyleObject, {
StyleObject,
StyleCache,
} from "@suid/css/createStyleObject";
import appendStyleElement from "@suid/css/dom/appendStyleElement";
import findStyleElement from "@suid/css/dom/findStyleElement";
import registerStyleElementUsage from "@suid/css/dom/registerStyleElementUsage";
import unregisterStyleElementUsage from "@suid/css/dom/unregisterStyleElementUsage";
import { randomString } from "@suid/utils";
import {
createRenderEffect,
createSignal,
createUniqueId,
onCleanup,
sharedConfig,
useContext,
} from "solid-js";
import { isServer, useAssets } from "solid-js/web";
const styleCache = isServer ? undefined : new StyleCache();
type StyleProps =
| undefined
| Record<string, any>
| (Record<string, any> | undefined)[];
function normalizeStyleProps(props: StyleProps) {
if (!props) return [];
return (
(Array.isArray(props) ? props : [props])
// https://github.com/microsoft/TypeScript/issues/44408
.flat(Infinity as 1)
.filter((v) => !!v) as Record<string, any>[]
);
}
function createStyleId() {
if (!sharedConfig.context) return randomString();
const id = createUniqueId().replaceAll("-", "");
const chunkSize = 9;
const chunks = Math.ceil(id.length / chunkSize);
const ids = [];
for (let chunk = 1; chunk <= chunks; ++chunk) {
const index = (chunk - 1) * chunkSize;
const number = Number(id.slice(index, index + chunkSize));
ids.push(number.toString(32));
}
return ids.join("-");
}
function createStyle(value: () => StyleProps | undefined) {
const context = useContext(StyledEngineContext);
const [name, setName] = createSignal("");
const componentId = createStyleId();
let styleElement: HTMLStyleElement | undefined;
createRenderEffect<
{ className?: string; styleElement?: HTMLStyleElement } | undefined
>((prevResult) => {
const propsValue = value();
let styleObject: StyleObject | undefined;
if (propsValue) {
styleObject = createStyleObject({
name: "css",
props: mergeStyleProps(normalizeStyleProps(propsValue)),
cache: styleCache,
componentId,
});
if (isServer) {
if (process.env.NODE_ENV !== "production") {
if (context.injectFirst)
console.warn(`SUID: 'injectFirst' is not supported in SSR mode.`);
}
useAssets(() => (
<style
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
id={styleObject!.id}
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
innerHTML={styleObject!.rules}
nonce={context.cache?.nonce}
/>
));
} else {
styleElement = findStyleElement(styleObject.id);
if (styleElement) {
registerStyleElementUsage(styleElement);
} else {
styleElement = appendStyleElement(
styleObject.rules,
{
id: styleObject.id,
nonce: context.cache?.nonce,
},
context.injectFirst
);
}
if (prevResult?.styleElement) {
unregisterStyleElementUsage(prevResult.styleElement);
}
}
}
if (typeof styleObject?.className === "string") {
setName(styleObject.className);
} else {
setName("");
}
return {
className: styleObject?.className,
styleElement,
};
}, undefined);
onCleanup(() => {
if (styleElement) unregisterStyleElementUsage(styleElement);
});
return name;
}
export default createStyle;