|
1 | | -import {useState, useLayoutEffect} from 'react'; |
2 | | -const {create} = require('nano-css'); |
3 | | -const {addon: addonCssom} = require('nano-css/addon/cssom'); |
4 | | -const {addon: addonPipe} = require('nano-css/addon/pipe'); |
5 | | - |
6 | | -export interface CssPipe { |
7 | | - className: string; |
8 | | - css: (css: object) => void; |
9 | | - remove: () => void; |
10 | | -} |
11 | | - |
12 | | -const flattenSelectors = (css) => { |
13 | | - const flatenned = {}; |
14 | | - const amp = {}; |
15 | | - let hasAmp = false; |
16 | | - |
17 | | - for (const key in css) { |
18 | | - const value = css[key]; |
19 | | - if (typeof value === 'object') { |
20 | | - flatenned[key] = value; |
21 | | - } else { |
22 | | - hasAmp = true; |
23 | | - amp[key] = value; |
24 | | - } |
25 | | - } |
26 | | - if (hasAmp) { |
27 | | - flatenned['&'] = amp; |
28 | | - } |
29 | | - |
30 | | - return flatenned; |
31 | | -}; |
32 | | - |
33 | | -const nano = create(); |
34 | | -addonCssom(nano); |
35 | | -addonPipe(nano); |
| 1 | +import {useLayoutEffect, useMemo} from 'react'; |
| 2 | +import {create, NanoRenderer} from 'nano-css'; |
| 3 | +import {addon as addonCSSOM, CSSOMAddon} from 'nano-css/addon/cssom'; |
| 4 | +import {addon as addonVCSSOM, VCSSOMAddon} from 'nano-css/addon/vcssom'; |
| 5 | +import {cssToTree} from 'nano-css/addon/vcssom/cssToTree'; |
| 6 | + |
| 7 | +type Nano = |
| 8 | + & NanoRenderer |
| 9 | + & CSSOMAddon |
| 10 | + & VCSSOMAddon |
| 11 | + ; |
| 12 | +const nano = create() as Nano; |
| 13 | +addonCSSOM(nano); |
| 14 | +addonVCSSOM(nano); |
| 15 | + |
| 16 | +let counter = 0; |
36 | 17 |
|
37 | 18 | const useCss = (css: object): string => { |
38 | | - const [pipe] = useState<CssPipe>(nano.pipe()); |
| 19 | + const className = useMemo(() => 'react-use-css-' + (counter++).toString(36), []); |
| 20 | + const sheet = useMemo(() => new nano.VSheet(), []); |
39 | 21 |
|
40 | 22 | useLayoutEffect(() => { |
41 | | - pipe.css(flattenSelectors(css)); |
42 | | - return () => pipe.remove(); |
| 23 | + const tree = {}; |
| 24 | + cssToTree(tree, css, '.' + className, ''); |
| 25 | + sheet.diff(tree); |
| 26 | + |
| 27 | + return () => { |
| 28 | + sheet.diff({}); |
| 29 | + }; |
43 | 30 | }); |
44 | 31 |
|
45 | | - return pipe.className; |
| 32 | + return className; |
46 | 33 | }; |
47 | 34 |
|
48 | 35 | export default useCss; |
0 commit comments