next-style 1.1.2 → 1.1.4
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 +60 -42
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -0
- package/package.json +6 -5
- package/dist/index.jsx +0 -148
package/README.md
CHANGED
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
**next-style** is a lightweight runtime CSS-in-JS engine designed for React, Next.js, and Bun.
|
|
4
4
|
|
|
5
5
|
It is intentionally designed to be **page-scoped and component-scoped**, ensuring predictable
|
|
6
|
-
style isolation with zero global leakage between pages.
|
|
6
|
+
style isolation with zero global leakage between pages or routes.
|
|
7
|
+
|
|
8
|
+
The library is framework-agnostic at its core and does not depend on React internally.
|
|
7
9
|
|
|
8
10
|
---
|
|
9
11
|
|
|
@@ -13,11 +15,12 @@ style isolation with zero global leakage between pages.
|
|
|
13
15
|
- No global singleton style registry
|
|
14
16
|
- No cross-page or cross-route CSS leakage
|
|
15
17
|
- Each page owns its own styles
|
|
16
|
-
- Explicit style injection via
|
|
18
|
+
- Explicit style injection via a `<style>` tag
|
|
19
|
+
- No implicit DOM side effects
|
|
17
20
|
|
|
18
21
|
Because of this design:
|
|
19
22
|
- `new NextStyle()` must be created inside the page or component scope
|
|
20
|
-
-
|
|
23
|
+
- Styles must be injected manually using `ns.StyleText`
|
|
21
24
|
|
|
22
25
|
---
|
|
23
26
|
|
|
@@ -27,12 +30,12 @@ Because of this design:
|
|
|
27
30
|
- Deterministic hashing (same styles always produce the same class name)
|
|
28
31
|
- Nested pseudo selectors (`_hover`, `_focus`, `_active`)
|
|
29
32
|
- Built-in responsive media queries
|
|
30
|
-
-
|
|
33
|
+
- Page-scoped global styles
|
|
31
34
|
- `@keyframes` support
|
|
32
35
|
- `@font-face` support
|
|
33
36
|
- PostCSS + Autoprefixer integration
|
|
34
|
-
- Automatic rule deduplication (
|
|
35
|
-
- Single `<style>` injection per page
|
|
37
|
+
- Automatic rule deduplication (per instance)
|
|
38
|
+
- Single `<style>` injection per page or component
|
|
36
39
|
- No side effects (`sideEffects: false`)
|
|
37
40
|
|
|
38
41
|
---
|
|
@@ -82,17 +85,17 @@ You may optionally provide a **custom prefix** to control generated class names.
|
|
|
82
85
|
import { NextStyle } from "next-style"
|
|
83
86
|
|
|
84
87
|
export default function Page() {
|
|
85
|
-
const
|
|
86
|
-
const
|
|
88
|
+
const ns = new NextStyle("home")
|
|
89
|
+
const btn = ns.css({
|
|
87
90
|
padding: "8px 16px",
|
|
88
91
|
backgroundColor: "black",
|
|
89
92
|
color: "white",
|
|
90
|
-
borderRadius:
|
|
93
|
+
borderRadius: "6px"
|
|
91
94
|
})
|
|
92
95
|
return (
|
|
93
96
|
<>
|
|
94
|
-
<style.
|
|
95
|
-
<button className={
|
|
97
|
+
<style>{ ns.StyleText }</style>
|
|
98
|
+
<button className={ btn }>Click me</button>
|
|
96
99
|
</>
|
|
97
100
|
)
|
|
98
101
|
}
|
|
@@ -106,25 +109,10 @@ home_ab12cd3
|
|
|
106
109
|
|
|
107
110
|
Notes:
|
|
108
111
|
- The prefix is optional
|
|
109
|
-
- If omitted,
|
|
112
|
+
- If omitted, a default prefix is used
|
|
110
113
|
- Prefixes help identify styles per page or component
|
|
111
114
|
- Each page or component should create its own `NextStyle` instance
|
|
112
115
|
|
|
113
|
-
|
|
114
|
-
## Why StyleProvider Is Required Per Page
|
|
115
|
-
|
|
116
|
-
`next-style` does not use a global style registry.
|
|
117
|
-
|
|
118
|
-
Each `NextStyle` instance:
|
|
119
|
-
- Collects styles locally
|
|
120
|
-
- Injects a single `<style>` tag
|
|
121
|
-
- Is destroyed when the page/component unmounts
|
|
122
|
-
|
|
123
|
-
This ensures:
|
|
124
|
-
- No stale CSS after route changes
|
|
125
|
-
- No style conflicts between pages
|
|
126
|
-
- Predictable SSR and CSR behavior
|
|
127
|
-
|
|
128
116
|
---
|
|
129
117
|
|
|
130
118
|
## Pseudo Selectors
|
|
@@ -132,7 +120,7 @@ This ensures:
|
|
|
132
120
|
Pseudo selectors are defined using keys prefixed with `_`.
|
|
133
121
|
|
|
134
122
|
```ts
|
|
135
|
-
const card =
|
|
123
|
+
const card = ns.css({
|
|
136
124
|
backgroundColor: "#fff",
|
|
137
125
|
transition: "0.2s ease",
|
|
138
126
|
_hover: {
|
|
@@ -162,7 +150,7 @@ Built-in breakpoints:
|
|
|
162
150
|
- `_xxl` → min-width: 1536px
|
|
163
151
|
|
|
164
152
|
```ts
|
|
165
|
-
const box =
|
|
153
|
+
const box = ns.css({
|
|
166
154
|
width: 100,
|
|
167
155
|
_md: {
|
|
168
156
|
width: 200
|
|
@@ -179,16 +167,16 @@ Media queries can be nested and are automatically merged.
|
|
|
179
167
|
|
|
180
168
|
## Global Styles (Page Scoped)
|
|
181
169
|
|
|
182
|
-
Global styles are
|
|
170
|
+
Global styles are scoped to the current page or component instance.
|
|
183
171
|
|
|
184
172
|
```ts
|
|
185
|
-
|
|
173
|
+
ns.global("body", {
|
|
186
174
|
margin: 0,
|
|
187
175
|
fontFamily: "Inter, sans-serif"
|
|
188
176
|
})
|
|
189
177
|
```
|
|
190
178
|
|
|
191
|
-
These styles
|
|
179
|
+
These styles exist only for the lifetime of the page or component.
|
|
192
180
|
|
|
193
181
|
---
|
|
194
182
|
|
|
@@ -197,14 +185,16 @@ These styles are removed automatically when the page unmounts.
|
|
|
197
185
|
Create animations using `keyframes()`:
|
|
198
186
|
|
|
199
187
|
```ts
|
|
200
|
-
const fadeIn =
|
|
188
|
+
const fadeIn = ns.keyframes({
|
|
201
189
|
from: { opacity: 0 },
|
|
202
190
|
to: { opacity: 1 }
|
|
203
191
|
})
|
|
204
192
|
```
|
|
205
193
|
|
|
194
|
+
Use the animation in styles:
|
|
195
|
+
|
|
206
196
|
```ts
|
|
207
|
-
const modal =
|
|
197
|
+
const modal = ns.css({
|
|
208
198
|
animation: `${ fadeIn } 0.3s ease-out`
|
|
209
199
|
})
|
|
210
200
|
```
|
|
@@ -218,7 +208,7 @@ Keyframes are scoped to the current `NextStyle` instance.
|
|
|
218
208
|
Declare fonts using `fontFace()`:
|
|
219
209
|
|
|
220
210
|
```ts
|
|
221
|
-
|
|
211
|
+
ns.fontFace({
|
|
222
212
|
fontFamily: "Inter",
|
|
223
213
|
src: "url(/fonts/inter.woff2) format('woff2')",
|
|
224
214
|
fontWeight: 400,
|
|
@@ -227,7 +217,7 @@ style.fontFace({
|
|
|
227
217
|
})
|
|
228
218
|
```
|
|
229
219
|
|
|
230
|
-
Font-face rules are injected only for the current page.
|
|
220
|
+
Font-face rules are injected only for the current page or component.
|
|
231
221
|
|
|
232
222
|
---
|
|
233
223
|
|
|
@@ -240,12 +230,31 @@ Font-face rules are injected only for the current page.
|
|
|
240
230
|
|
|
241
231
|
---
|
|
242
232
|
|
|
243
|
-
##
|
|
233
|
+
## Server-Side Rendering (SSR)
|
|
234
|
+
|
|
235
|
+
`next-style` is SSR-safe.
|
|
236
|
+
|
|
237
|
+
Because the core API only generates strings:
|
|
238
|
+
- No JSX is exported from the library
|
|
239
|
+
- No React runtime is required
|
|
240
|
+
- No side effects occur during render
|
|
241
|
+
|
|
242
|
+
You can safely inject styles during SSR:
|
|
243
|
+
|
|
244
|
+
```tsx
|
|
245
|
+
<style>{ ns.StyleText }</style>
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
The same output will be produced on both the server and the client.
|
|
249
|
+
|
|
250
|
+
---
|
|
251
|
+
|
|
252
|
+
## Performance Characteristics
|
|
244
253
|
|
|
245
|
-
- CSS rules are generated and
|
|
254
|
+
- CSS rules are generated and deduplicated per instance
|
|
246
255
|
- PostCSS and Autoprefixer results are cached
|
|
247
|
-
-
|
|
248
|
-
- No global runtime
|
|
256
|
+
- Only one `<style>` tag is required per page or component
|
|
257
|
+
- No global runtime mutations
|
|
249
258
|
|
|
250
259
|
Ideal for:
|
|
251
260
|
- Next.js App Router
|
|
@@ -254,6 +263,15 @@ Ideal for:
|
|
|
254
263
|
|
|
255
264
|
---
|
|
256
265
|
|
|
266
|
+
## Common Gotchas
|
|
267
|
+
|
|
268
|
+
- Do not create a shared `NextStyle` instance across pages
|
|
269
|
+
- Do not treat `next-style` as a global style manager
|
|
270
|
+
- Always inject `ns.StyleText` before elements that use generated class names
|
|
271
|
+
- Avoid calling `ns.css()` conditionally with different order between renders
|
|
272
|
+
|
|
273
|
+
---
|
|
274
|
+
|
|
257
275
|
## Package Information
|
|
258
276
|
|
|
259
277
|
- Name: `next-style`
|
|
@@ -275,8 +293,8 @@ https://github.com/kingslimes/next-style/issues
|
|
|
275
293
|
- `&` selector nesting
|
|
276
294
|
- `_dark` / `_light` helpers
|
|
277
295
|
- `@layer` support
|
|
278
|
-
-
|
|
279
|
-
-
|
|
296
|
+
- Optional React helpers
|
|
297
|
+
- Dev-time warnings for incorrect usage
|
|
280
298
|
|
|
281
299
|
---
|
|
282
300
|
|
package/dist/index.d.ts
CHANGED
|
@@ -31,6 +31,6 @@ export declare class NextStyle {
|
|
|
31
31
|
global: (selector: string, style: NextStyleProperties) => void;
|
|
32
32
|
keyframes: (frames: KeyframesObject) => string;
|
|
33
33
|
fontFace: (font: FontFaceObject) => void;
|
|
34
|
-
|
|
34
|
+
get StyleText(): string | null;
|
|
35
35
|
}
|
|
36
36
|
export {};
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import postcss from"postcss";import autoprefixer from"autoprefixer";var processor=postcss([autoprefixer({overrideBrowserslist:[">0.2%","not dead","not op_mini all"]})]),postcssCache=new Map;function postcssTransform(cssText){let cached=postcssCache.get(cssText);if(cached)return cached;let result=processor.process(cssText,{from:void 0}).css;return postcssCache.set(cssText,result),result}function stableStringify(value){if(value==null||typeof value!=="object")return JSON.stringify(value);if(Array.isArray(value))return`[${value.map(stableStringify).join(",")}]`;return`{${Object.keys(value).sort().map((k)=>`"${k}":${stableStringify(value[k])}`).join(",")}}`}function createHashName(seed){let hash=BigInt("0xcbf29ce484222325"),prime=BigInt("0x100000001b3");for(let i=0;i<seed.length;i++)hash^=BigInt(seed.charCodeAt(i)),hash*=prime,hash&=BigInt("0xffffffffffffffff");return hash.toString(36).slice(0,9)}function toKebabCase(prop){return prop.replace(/[A-Z]/g,(m)=>`-${m.toLowerCase()}`)}var MEDIA_MAP={_sm:"(min-width:640px)",_md:"(min-width:768px)",_lg:"(min-width:1024px)",_xl:"(min-width:1280px)",_xxl:"(min-width:1536px)"};function mergeMedia(parent,current){if(!parent)return current;if(!current)return parent;return`${parent} and ${current}`}function serializeNested(style,ctx){let css="",base="";for(let key in style){let value=style[key];if(value==null||typeof value==="object"||key.startsWith("_"))continue;base+=`${toKebabCase(key)}:${value};`}if(base){let rule=`${ctx.selector}{${base}}`;css+=ctx.media?`@media ${ctx.media}{${rule}}`:rule}for(let pseudo of["_hover","_focus","_active"]){let value=style[pseudo];if(!value)continue;css+=serializeNested(value,{selector:`${ctx.selector}:${pseudo.slice(1)}`,media:ctx.media})}for(let key in MEDIA_MAP){let mediaKey=key,value=style[mediaKey];if(!value)continue;css+=serializeNested(value,{selector:ctx.selector,media:mergeMedia(ctx.media,MEDIA_MAP[mediaKey])})}return css}class NextStyle{prefix;rules=new Map;constructor(prefix="next"){this.prefix=prefix}css=(style)=>{let seed=stableStringify(style),hash=createHashName(seed),className=`${this.prefix}_${hash}`,key=`class:${className}`;if(!this.rules.has(key)){let raw=serializeNested(style,{selector:`.${className}`}),cssText=postcssTransform(raw);this.rules.set(key,cssText)}return className};global=(selector,style)=>{let key=`global:${selector}`;if(!this.rules.has(key)){let raw=serializeNested(style,{selector}),cssText=postcssTransform(raw);this.rules.set(key,cssText)}};keyframes=(frames)=>{let seed=stableStringify(frames),hash=createHashName(seed),name=`${this.prefix}_${hash}`,key=`@keyframes:${name}`;if(!this.rules.has(key)){let body="";for(let step in frames){let props="",frame=frames[step];for(let prop in frame)props+=`${toKebabCase(prop)}:${frame[prop]};`;body+=`${step}{${props}}`}let cssText=postcssTransform(`@keyframes ${name}{${body}}`);this.rules.set(key,cssText)}return name};fontFace=(font)=>{let seed=stableStringify(font),key=`@font-face:${createHashName(seed)}`;if(!this.rules.has(key)){let body="";for(let prop in font)body+=`${toKebabCase(prop)}:${font[prop]};`;let cssText=postcssTransform(`@font-face{${body}}`);this.rules.set(key,cssText)}};get StyleText(){if(this.rules.size===0)return null;let cssText="";for(let rule of this.rules.values())cssText+=rule+`
|
|
2
|
+
`;return cssText}}export{NextStyle};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "next-style",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.4",
|
|
4
4
|
"description": "Lightweight runtime CSS-in-JS engine with nested pseudo selectors, media queries, global styles, keyframes, and font-face support.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "kingslimes",
|
|
@@ -16,11 +16,11 @@
|
|
|
16
16
|
"LICENSE",
|
|
17
17
|
"README.md"
|
|
18
18
|
],
|
|
19
|
-
"main": "./dist/index.
|
|
19
|
+
"main": "./dist/index.js",
|
|
20
20
|
"types": "./dist/index.d.ts",
|
|
21
21
|
"exports": {
|
|
22
22
|
".": {
|
|
23
|
-
"import": "./dist/index.
|
|
23
|
+
"import": "./dist/index.js",
|
|
24
24
|
"types": "./dist/index.d.ts"
|
|
25
25
|
}
|
|
26
26
|
},
|
|
@@ -52,7 +52,6 @@
|
|
|
52
52
|
"font-face"
|
|
53
53
|
],
|
|
54
54
|
"peerDependencies": {
|
|
55
|
-
"react": ">=18",
|
|
56
55
|
"postcss": "^8",
|
|
57
56
|
"autoprefixer": "^10"
|
|
58
57
|
},
|
|
@@ -60,7 +59,9 @@
|
|
|
60
59
|
"csstype": "latest"
|
|
61
60
|
},
|
|
62
61
|
"engines": {
|
|
63
|
-
"bun": ">=1.0.0",
|
|
64
62
|
"node": ">=18"
|
|
63
|
+
},
|
|
64
|
+
"publishConfig": {
|
|
65
|
+
"access": "public"
|
|
65
66
|
}
|
|
66
67
|
}
|
package/dist/index.jsx
DELETED
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
import postcss from "postcss";
|
|
2
|
-
import autoprefixer from "autoprefixer";
|
|
3
|
-
const processor = postcss([autoprefixer({
|
|
4
|
-
overrideBrowserslist: [">0.2%", "not dead", "not op_mini all"]
|
|
5
|
-
})]);
|
|
6
|
-
const postcssCache = new Map();
|
|
7
|
-
function postcssTransform(cssText) {
|
|
8
|
-
const cached = postcssCache.get(cssText);
|
|
9
|
-
if (cached) return cached;
|
|
10
|
-
const result = processor.process(cssText, {
|
|
11
|
-
from: undefined
|
|
12
|
-
}).css;
|
|
13
|
-
postcssCache.set(cssText, result);
|
|
14
|
-
return result;
|
|
15
|
-
}
|
|
16
|
-
function stableStringify(value) {
|
|
17
|
-
if (value == null || typeof value !== "object") return JSON.stringify(value);
|
|
18
|
-
if (Array.isArray(value)) return `[${value.map(stableStringify).join(",")}]`;
|
|
19
|
-
const keys = Object.keys(value).sort();
|
|
20
|
-
return `{${keys.map(k => `"${k}":${stableStringify(value[k])}`).join(",")}}`;
|
|
21
|
-
}
|
|
22
|
-
function createHashName(seed) {
|
|
23
|
-
let hash = BigInt("0xcbf29ce484222325");
|
|
24
|
-
const prime = BigInt("0x100000001b3");
|
|
25
|
-
for (let i = 0; i < seed.length; i++) {
|
|
26
|
-
hash ^= BigInt(seed.charCodeAt(i));
|
|
27
|
-
hash *= prime;
|
|
28
|
-
hash &= BigInt("0xffffffffffffffff");
|
|
29
|
-
}
|
|
30
|
-
return hash.toString(36).slice(0, 9);
|
|
31
|
-
}
|
|
32
|
-
function toKebabCase(prop) {
|
|
33
|
-
return prop.replace(/[A-Z]/g, m => `-${m.toLowerCase()}`);
|
|
34
|
-
}
|
|
35
|
-
const MEDIA_MAP = {
|
|
36
|
-
_sm: "( min-width: 640px )",
|
|
37
|
-
_md: "( min-width: 768px )",
|
|
38
|
-
_lg: "( min-width: 1024px )",
|
|
39
|
-
_xl: "( min-width: 1280px )",
|
|
40
|
-
_xxl: "( min-width: 1536px )"
|
|
41
|
-
};
|
|
42
|
-
function mergeMedia(parent, current) {
|
|
43
|
-
if (!parent) return current;
|
|
44
|
-
if (!current) return parent;
|
|
45
|
-
return `${parent} and ${current}`;
|
|
46
|
-
}
|
|
47
|
-
function serializeNested(style, ctx) {
|
|
48
|
-
let css = "";
|
|
49
|
-
let base = "";
|
|
50
|
-
for (const key in style) {
|
|
51
|
-
const value = style[key];
|
|
52
|
-
if (value == null || typeof value === "object" || key.startsWith("_")) continue;
|
|
53
|
-
base += `${toKebabCase(key)}:${value};`;
|
|
54
|
-
}
|
|
55
|
-
if (base) {
|
|
56
|
-
const rule = `${ctx.selector}{${base}}`;
|
|
57
|
-
css += ctx.media ? `@media ${ctx.media}{${rule}}` : rule;
|
|
58
|
-
}
|
|
59
|
-
for (const pseudo of ["_hover", "_focus", "_active"]) {
|
|
60
|
-
const value = style[pseudo];
|
|
61
|
-
if (!value) continue;
|
|
62
|
-
css += serializeNested(value, {
|
|
63
|
-
selector: `${ctx.selector}:${pseudo.slice(1)}`,
|
|
64
|
-
media: ctx.media
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
for (const key in MEDIA_MAP) {
|
|
68
|
-
const mediaKey = key;
|
|
69
|
-
const value = style[mediaKey];
|
|
70
|
-
if (!value) continue;
|
|
71
|
-
css += serializeNested(value, {
|
|
72
|
-
selector: ctx.selector,
|
|
73
|
-
media: mergeMedia(ctx.media, MEDIA_MAP[mediaKey])
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
return css;
|
|
77
|
-
}
|
|
78
|
-
export class NextStyle {
|
|
79
|
-
rules = new Map();
|
|
80
|
-
constructor(prefix = "next") {
|
|
81
|
-
this.prefix = prefix;
|
|
82
|
-
}
|
|
83
|
-
css = style => {
|
|
84
|
-
const seed = stableStringify(style);
|
|
85
|
-
const hash = createHashName(seed);
|
|
86
|
-
const className = `${this.prefix}_${hash}`;
|
|
87
|
-
const key = `class:${className}`;
|
|
88
|
-
if (!this.rules.has(key)) {
|
|
89
|
-
const raw = serializeNested(style, {
|
|
90
|
-
selector: `.${className}`
|
|
91
|
-
});
|
|
92
|
-
const cssText = postcssTransform(raw);
|
|
93
|
-
this.rules.set(key, cssText);
|
|
94
|
-
}
|
|
95
|
-
return className;
|
|
96
|
-
};
|
|
97
|
-
global = (selector, style) => {
|
|
98
|
-
const key = `global:${selector}`;
|
|
99
|
-
if (!this.rules.has(key)) {
|
|
100
|
-
const raw = serializeNested(style, {
|
|
101
|
-
selector
|
|
102
|
-
});
|
|
103
|
-
const cssText = postcssTransform(raw);
|
|
104
|
-
this.rules.set(key, cssText);
|
|
105
|
-
}
|
|
106
|
-
};
|
|
107
|
-
keyframes = frames => {
|
|
108
|
-
const seed = stableStringify(frames);
|
|
109
|
-
const hash = createHashName(seed);
|
|
110
|
-
const name = `${this.prefix}_${hash}`;
|
|
111
|
-
const key = `@keyframes:${name}`;
|
|
112
|
-
if (!this.rules.has(key)) {
|
|
113
|
-
let body = "";
|
|
114
|
-
for (const step in frames) {
|
|
115
|
-
let props = "";
|
|
116
|
-
const frame = frames[step];
|
|
117
|
-
for (const prop in frame) {
|
|
118
|
-
props += `${toKebabCase(prop)}:${frame[prop]};`;
|
|
119
|
-
}
|
|
120
|
-
body += `${step}{${props}}`;
|
|
121
|
-
}
|
|
122
|
-
const cssText = postcssTransform(`@keyframes ${name}{${body}}`);
|
|
123
|
-
this.rules.set(key, cssText);
|
|
124
|
-
}
|
|
125
|
-
return name;
|
|
126
|
-
};
|
|
127
|
-
fontFace = font => {
|
|
128
|
-
const seed = stableStringify(font);
|
|
129
|
-
const hash = createHashName(seed);
|
|
130
|
-
const key = `@font-face:${hash}`;
|
|
131
|
-
if (!this.rules.has(key)) {
|
|
132
|
-
let body = "";
|
|
133
|
-
for (const prop in font) {
|
|
134
|
-
body += `${toKebabCase(prop)}:${font[prop]};`;
|
|
135
|
-
}
|
|
136
|
-
const cssText = postcssTransform(`@font-face{${body}}`);
|
|
137
|
-
this.rules.set(key, cssText);
|
|
138
|
-
}
|
|
139
|
-
};
|
|
140
|
-
StyleProvider = () => {
|
|
141
|
-
if (this.rules.size === 0) return null;
|
|
142
|
-
let cssText = "";
|
|
143
|
-
for (const rule of this.rules.values()) {
|
|
144
|
-
cssText += rule + "\n";
|
|
145
|
-
}
|
|
146
|
-
return <style>{cssText}</style>;
|
|
147
|
-
};
|
|
148
|
-
}
|