@acusti/styling 0.6.0-alpha3 → 0.6.0-beta

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/Style.js CHANGED
@@ -1,13 +1,13 @@
1
1
  import * as React from 'react';
2
- import { unregisterStyles, updateStyles } from './style-registry.js';
2
+ import { getRegisteredStyles, registerStyles, unregisterStyles, updateStyles, } from './style-registry.js';
3
3
  const { useCallback, useEffect, useRef, useState } = React;
4
4
  const Style = ({ children: styles }) => {
5
5
  const [ownerDocument, setOwnerDocument] = useState(null);
6
- const handleRef = useCallback((element) => {
7
- if (!element)
8
- return;
9
- setOwnerDocument(element.ownerDocument);
10
- }, []);
6
+ const isMountedRef = useRef(false);
7
+ useEffect(() => {
8
+ isMountedRef.current = true;
9
+ unregisterStyles({ ownerDocument: 'global', styles });
10
+ }, []); // eslint-disable-line react-hooks/exhaustive-deps
11
11
  useEffect(() => () => {
12
12
  if (!ownerDocument)
13
13
  return;
@@ -24,21 +24,20 @@ const Style = ({ children: styles }) => {
24
24
  });
25
25
  previousStylesRef.current = styles;
26
26
  }, [ownerDocument, styles]);
27
+ const handleRef = useCallback((element) => {
28
+ if (!element)
29
+ return;
30
+ setOwnerDocument(element.ownerDocument);
31
+ }, []);
27
32
  if (ownerDocument)
28
33
  return null;
29
- console.log('styles', styles);
30
- console.log('replaced styles', styles.replace(/"/g, '"'));
31
- // TODO why does styles get HTML entities for double quote marks?
32
- return (React.createElement("style", { dangerouslySetInnerHTML: {
33
- __html: styles.replace(/"/g, '"') +
34
- '/*\n' +
35
- 'styles:' +
36
- styles +
37
- '\n\n' +
38
- 'replaced styles: ' +
39
- styles.replace(/"/g, '"') +
40
- '\n*/',
41
- }, ref: handleRef }));
34
+ // Avoid duplicate style rendering during SSR via style registry
35
+ if (!isMountedRef.current) {
36
+ if (getRegisteredStyles({ ownerDocument: 'global', styles }))
37
+ return null;
38
+ registerStyles({ ownerDocument: 'global', styles });
39
+ }
40
+ return React.createElement("style", { dangerouslySetInnerHTML: { __html: styles }, ref: handleRef });
42
41
  };
43
42
  export default Style;
44
43
  //# sourceMappingURL=Style.js.map
package/dist/Style.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"Style.js","sourceRoot":"","sources":["../src/Style.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAErE,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAC;AAM3D,MAAM,KAAK,GAAG,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAS,EAAE,EAAE;IAC1C,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,QAAQ,CAAkB,IAAI,CAAC,CAAC;IAE1E,MAAM,SAAS,GAAG,WAAW,CAAC,CAAC,OAA2B,EAAE,EAAE;QAC1D,IAAI,CAAC,OAAO;YAAE,OAAO;QACrB,gBAAgB,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;IAC5C,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,SAAS,CACL,GAAG,EAAE,CAAC,GAAG,EAAE;QACP,IAAI,CAAC,aAAa;YAAE,OAAO;QAC3B,gBAAgB,CAAC,EAAE,aAAa,EAAE,MAAM,EAAE,CAAC,CAAC;IAChD,CAAC,EACD,CAAC,aAAa,CAAC,CAClB,CAAC;IAEF,MAAM,iBAAiB,GAAG,MAAM,CAAS,EAAE,CAAC,CAAC;IAE7C,SAAS,CAAC,GAAG,EAAE;QACX,IAAI,CAAC,aAAa;YAAE,OAAO;QAE3B,YAAY,CAAC;YACT,aAAa;YACb,cAAc,EAAE,iBAAiB,CAAC,OAAO;YACzC,MAAM;SACT,CAAC,CAAC;QAEH,iBAAiB,CAAC,OAAO,GAAG,MAAM,CAAC;IACvC,CAAC,EAAE,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,CAAC;IAE5B,IAAI,aAAa;QAAE,OAAO,IAAI,CAAC;IAC/B,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC9B,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE,MAAM,CAAC,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,CAAC;IAC/D,iEAAiE;IACjE,OAAO,CACH,+BACI,uBAAuB,EAAE;YACrB,MAAM,EACF,MAAM,CAAC,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC;gBAC9B,MAAM;gBACN,SAAS;gBACT,MAAM;gBACN,MAAM;gBACN,mBAAmB;gBACnB,MAAM,CAAC,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC;gBAC9B,MAAM;SACb,EACD,GAAG,EAAE,SAAS,GAChB,CACL,CAAC;AACN,CAAC,CAAC;AAEF,eAAe,KAAK,CAAC"}
1
+ {"version":3,"file":"Style.js","sourceRoot":"","sources":["../src/Style.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EACH,mBAAmB,EACnB,cAAc,EACd,gBAAgB,EAChB,YAAY,GACf,MAAM,qBAAqB,CAAC;AAE7B,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAC;AAM3D,MAAM,KAAK,GAAG,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAS,EAAE,EAAE;IAC1C,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,QAAQ,CAAkB,IAAI,CAAC,CAAC;IAC1E,MAAM,YAAY,GAAG,MAAM,CAAU,KAAK,CAAC,CAAC;IAE5C,SAAS,CAAC,GAAG,EAAE;QACX,YAAY,CAAC,OAAO,GAAG,IAAI,CAAC;QAC5B,gBAAgB,CAAC,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;IAC1D,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,kDAAkD;IAE1D,SAAS,CACL,GAAG,EAAE,CAAC,GAAG,EAAE;QACP,IAAI,CAAC,aAAa;YAAE,OAAO;QAC3B,gBAAgB,CAAC,EAAE,aAAa,EAAE,MAAM,EAAE,CAAC,CAAC;IAChD,CAAC,EACD,CAAC,aAAa,CAAC,CAClB,CAAC;IAEF,MAAM,iBAAiB,GAAG,MAAM,CAAS,EAAE,CAAC,CAAC;IAE7C,SAAS,CAAC,GAAG,EAAE;QACX,IAAI,CAAC,aAAa;YAAE,OAAO;QAE3B,YAAY,CAAC;YACT,aAAa;YACb,cAAc,EAAE,iBAAiB,CAAC,OAAO;YACzC,MAAM;SACT,CAAC,CAAC;QAEH,iBAAiB,CAAC,OAAO,GAAG,MAAM,CAAC;IACvC,CAAC,EAAE,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,CAAC;IAE5B,MAAM,SAAS,GAAG,WAAW,CAAC,CAAC,OAA2B,EAAE,EAAE;QAC1D,IAAI,CAAC,OAAO;YAAE,OAAO;QACrB,gBAAgB,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;IAC5C,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,IAAI,aAAa;QAAE,OAAO,IAAI,CAAC;IAE/B,gEAAgE;IAChE,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE;QACvB,IAAI,mBAAmB,CAAC,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;YAAE,OAAO,IAAI,CAAC;QAC1E,cAAc,CAAC,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;KACvD;IAED,OAAO,+BAAO,uBAAuB,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,SAAS,GAAI,CAAC;AAClF,CAAC,CAAC;AAEF,eAAe,KAAK,CAAC"}
@@ -1,7 +1,11 @@
1
1
  declare type Payload = {
2
- ownerDocument: Document;
2
+ ownerDocument: Document | 'global';
3
3
  styles: string;
4
4
  };
5
+ export declare const getRegisteredStyles: ({ ownerDocument, styles }: Payload) => {
6
+ element: HTMLStyleElement | null;
7
+ referenceCount: number;
8
+ } | null;
5
9
  export declare const registerStyles: ({ ownerDocument, styles }: Payload) => void;
6
10
  export declare const unregisterStyles: ({ ownerDocument, styles }: Payload) => void;
7
11
  declare type UpdatePayload = {
@@ -1,18 +1,30 @@
1
1
  const styleRegistry = new Map();
2
+ export const getRegisteredStyles = ({ ownerDocument, styles }) => {
3
+ if (!styles)
4
+ return null;
5
+ const stylesMap = styleRegistry.get(styles);
6
+ if (!stylesMap)
7
+ return null;
8
+ return stylesMap.get(ownerDocument) || null;
9
+ };
2
10
  export const registerStyles = ({ ownerDocument, styles }) => {
3
11
  if (!styles)
4
12
  return;
5
- const stylesMap = styleRegistry.get(styles);
6
- const existingStylesItem = stylesMap === null || stylesMap === void 0 ? void 0 : stylesMap.get(ownerDocument);
13
+ const existingStylesItem = getRegisteredStyles({ ownerDocument, styles });
7
14
  if (existingStylesItem) {
8
15
  existingStylesItem.referenceCount++;
9
16
  return;
10
17
  }
18
+ if (ownerDocument === 'global') {
19
+ styleRegistry.set(styles, new Map([[ownerDocument, { element: null, referenceCount: 1 }]]));
20
+ return;
21
+ }
11
22
  const element = ownerDocument.createElement('style');
12
23
  element.setAttribute('data-ukt-styling', '');
13
24
  element.innerHTML = styles;
14
25
  ownerDocument.head.appendChild(element);
15
26
  const stylesItem = { element, referenceCount: 1 };
27
+ const stylesMap = styleRegistry.get(styles);
16
28
  if (stylesMap) {
17
29
  stylesMap.set(ownerDocument, stylesItem);
18
30
  return;
@@ -22,19 +34,21 @@ export const registerStyles = ({ ownerDocument, styles }) => {
22
34
  export const unregisterStyles = ({ ownerDocument, styles }) => {
23
35
  if (!styles)
24
36
  return;
25
- const stylesMap = styleRegistry.get(styles);
26
- const stylesItem = stylesMap === null || stylesMap === void 0 ? void 0 : stylesMap.get(ownerDocument);
27
- if (!stylesMap || !stylesItem)
37
+ const stylesItem = getRegisteredStyles({ ownerDocument, styles });
38
+ if (!stylesItem)
28
39
  return;
29
40
  stylesItem.referenceCount--;
30
41
  if (stylesItem.referenceCount)
31
42
  return;
32
43
  // If no more references to these styles in this document, remove <style> element from the DOM
33
- const { parentElement } = stylesItem.element;
34
- if (parentElement) {
35
- parentElement.removeChild(stylesItem.element);
44
+ if (stylesItem.element) {
45
+ const { parentElement } = stylesItem.element;
46
+ if (parentElement) {
47
+ parentElement.removeChild(stylesItem.element);
48
+ }
36
49
  }
37
50
  // Then remove the document Map
51
+ const stylesMap = styleRegistry.get(styles);
38
52
  stylesMap.delete(ownerDocument);
39
53
  if (stylesMap.size)
40
54
  return;
@@ -6,9 +6,13 @@
6
6
  */
7
7
 
8
8
  declare type Payload = {|
9
- ownerDocument: Document,
9
+ ownerDocument: Document | "global",
10
10
  styles: string,
11
11
  |};
12
+ declare export var getRegisteredStyles: (x: Payload) => {|
13
+ element: HTMLStyleElement | null,
14
+ referenceCount: number,
15
+ |} | null;
12
16
  declare export var registerStyles: (x: Payload) => void;
13
17
  declare export var unregisterStyles: (x: Payload) => void;
14
18
  declare type UpdatePayload = {|
@@ -1 +1 @@
1
- {"version":3,"file":"style-registry.js","sourceRoot":"","sources":["../src/style-registry.ts"],"names":[],"mappings":"AAKA,MAAM,aAAa,GAAkB,IAAI,GAAG,EAAE,CAAC;AAI/C,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,EAAE,aAAa,EAAE,MAAM,EAAW,EAAE,EAAE;IACjE,IAAI,CAAC,MAAM;QAAE,OAAO;IAEpB,MAAM,SAAS,GAAG,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAC5C,MAAM,kBAAkB,GAAG,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,GAAG,CAAC,aAAa,CAAC,CAAC;IAEzD,IAAI,kBAAkB,EAAE;QACpB,kBAAkB,CAAC,cAAc,EAAE,CAAC;QACpC,OAAO;KACV;IAED,MAAM,OAAO,GAAG,aAAa,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IACrD,OAAO,CAAC,YAAY,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAC;IAC7C,OAAO,CAAC,SAAS,GAAG,MAAM,CAAC;IAC3B,aAAa,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IACxC,MAAM,UAAU,GAAG,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC,EAAE,CAAC;IAElD,IAAI,SAAS,EAAE;QACX,SAAS,CAAC,GAAG,CAAC,aAAa,EAAE,UAAU,CAAC,CAAC;QACzC,OAAO;KACV;IAED,aAAa,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC,aAAa,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;AACtE,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,EAAE,aAAa,EAAE,MAAM,EAAW,EAAE,EAAE;IACnE,IAAI,CAAC,MAAM;QAAE,OAAO;IAEpB,MAAM,SAAS,GAAG,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAC5C,MAAM,UAAU,GAAG,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,GAAG,CAAC,aAAa,CAAC,CAAC;IACjD,IAAI,CAAC,SAAS,IAAI,CAAC,UAAU;QAAE,OAAO;IAEtC,UAAU,CAAC,cAAc,EAAE,CAAC;IAC5B,IAAI,UAAU,CAAC,cAAc;QAAE,OAAO;IAEtC,8FAA8F;IAC9F,MAAM,EAAE,aAAa,EAAE,GAAG,UAAU,CAAC,OAAO,CAAC;IAC7C,IAAI,aAAa,EAAE;QACf,aAAa,CAAC,WAAW,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;KACjD;IACD,+BAA+B;IAC/B,SAAS,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;IAEhC,IAAI,SAAS,CAAC,IAAI;QAAE,OAAO;IAC3B,4EAA4E;IAC5E,aAAa,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;AACjC,CAAC,CAAC;AAIF,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,EACzB,aAAa,EACb,cAAc,EACd,MAAM,GACM,EAAE,EAAE;IAChB,IAAI,cAAc,KAAK,MAAM;QAAE,OAAO;IAEtC,IAAI,cAAc,EAAE;QAChB,gBAAgB,CAAC,EAAE,aAAa,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC,CAAC;KAC/D;IAED,cAAc,CAAC,EAAE,aAAa,EAAE,MAAM,EAAE,CAAC,CAAC;AAC9C,CAAC,CAAC"}
1
+ {"version":3,"file":"style-registry.js","sourceRoot":"","sources":["../src/style-registry.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@acusti/styling",
3
- "version": "0.6.0-alpha3",
3
+ "version": "0.6.0-beta",
4
4
  "type": "module",
5
5
  "sideEffects": false,
6
6
  "exports": "./dist/index.js",
package/src/Style.tsx CHANGED
@@ -1,6 +1,11 @@
1
1
  import * as React from 'react';
2
2
 
3
- import { unregisterStyles, updateStyles } from './style-registry.js';
3
+ import {
4
+ getRegisteredStyles,
5
+ registerStyles,
6
+ unregisterStyles,
7
+ updateStyles,
8
+ } from './style-registry.js';
4
9
 
5
10
  const { useCallback, useEffect, useRef, useState } = React;
6
11
 
@@ -10,11 +15,12 @@ type Props = {
10
15
 
11
16
  const Style = ({ children: styles }: Props) => {
12
17
  const [ownerDocument, setOwnerDocument] = useState<Document | null>(null);
18
+ const isMountedRef = useRef<boolean>(false);
13
19
 
14
- const handleRef = useCallback((element: HTMLElement | null) => {
15
- if (!element) return;
16
- setOwnerDocument(element.ownerDocument);
17
- }, []);
20
+ useEffect(() => {
21
+ isMountedRef.current = true;
22
+ unregisterStyles({ ownerDocument: 'global', styles });
23
+ }, []); // eslint-disable-line react-hooks/exhaustive-deps
18
24
 
19
25
  useEffect(
20
26
  () => () => {
@@ -38,26 +44,20 @@ const Style = ({ children: styles }: Props) => {
38
44
  previousStylesRef.current = styles;
39
45
  }, [ownerDocument, styles]);
40
46
 
47
+ const handleRef = useCallback((element: HTMLElement | null) => {
48
+ if (!element) return;
49
+ setOwnerDocument(element.ownerDocument);
50
+ }, []);
51
+
41
52
  if (ownerDocument) return null;
42
- console.log('styles', styles);
43
- console.log('replaced styles', styles.replace(/&quot;/g, '"'));
44
- // TODO why does styles get HTML entities for double quote marks?
45
- return (
46
- <style
47
- dangerouslySetInnerHTML={{
48
- __html:
49
- styles.replace(/&quot;/g, '"') +
50
- '/*\n' +
51
- 'styles:' +
52
- styles +
53
- '\n\n' +
54
- 'replaced styles: ' +
55
- styles.replace(/&quot;/g, '"') +
56
- '\n*/',
57
- }}
58
- ref={handleRef}
59
- />
60
- );
53
+
54
+ // Avoid duplicate style rendering during SSR via style registry
55
+ if (!isMountedRef.current) {
56
+ if (getRegisteredStyles({ ownerDocument: 'global', styles })) return null;
57
+ registerStyles({ ownerDocument: 'global', styles });
58
+ }
59
+
60
+ return <style dangerouslySetInnerHTML={{ __html: styles }} ref={handleRef} />;
61
61
  };
62
62
 
63
63
  export default Style;
@@ -1,29 +1,43 @@
1
1
  type StyleRegistry = Map<
2
2
  string,
3
- Map<Document, { element: HTMLStyleElement; referenceCount: number }>
3
+ Map<Document | 'global', { element: HTMLStyleElement | null; referenceCount: number }>
4
4
  >;
5
5
 
6
6
  const styleRegistry: StyleRegistry = new Map();
7
7
 
8
- type Payload = { ownerDocument: Document; styles: string };
8
+ type Payload = { ownerDocument: Document | 'global'; styles: string };
9
+
10
+ export const getRegisteredStyles = ({ ownerDocument, styles }: Payload) => {
11
+ if (!styles) return null;
12
+ const stylesMap = styleRegistry.get(styles);
13
+ if (!stylesMap) return null;
14
+ return stylesMap.get(ownerDocument) || null;
15
+ };
9
16
 
10
17
  export const registerStyles = ({ ownerDocument, styles }: Payload) => {
11
18
  if (!styles) return;
12
19
 
13
- const stylesMap = styleRegistry.get(styles);
14
- const existingStylesItem = stylesMap?.get(ownerDocument);
15
-
20
+ const existingStylesItem = getRegisteredStyles({ ownerDocument, styles });
16
21
  if (existingStylesItem) {
17
22
  existingStylesItem.referenceCount++;
18
23
  return;
19
24
  }
20
25
 
26
+ if (ownerDocument === 'global') {
27
+ styleRegistry.set(
28
+ styles,
29
+ new Map([[ownerDocument, { element: null, referenceCount: 1 }]]),
30
+ );
31
+ return;
32
+ }
33
+
21
34
  const element = ownerDocument.createElement('style');
22
35
  element.setAttribute('data-ukt-styling', '');
23
36
  element.innerHTML = styles;
24
37
  ownerDocument.head.appendChild(element);
25
38
  const stylesItem = { element, referenceCount: 1 };
26
39
 
40
+ const stylesMap = styleRegistry.get(styles);
27
41
  if (stylesMap) {
28
42
  stylesMap.set(ownerDocument, stylesItem);
29
43
  return;
@@ -35,19 +49,22 @@ export const registerStyles = ({ ownerDocument, styles }: Payload) => {
35
49
  export const unregisterStyles = ({ ownerDocument, styles }: Payload) => {
36
50
  if (!styles) return;
37
51
 
38
- const stylesMap = styleRegistry.get(styles);
39
- const stylesItem = stylesMap?.get(ownerDocument);
40
- if (!stylesMap || !stylesItem) return;
52
+ const stylesItem = getRegisteredStyles({ ownerDocument, styles });
53
+ if (!stylesItem) return;
41
54
 
42
55
  stylesItem.referenceCount--;
43
56
  if (stylesItem.referenceCount) return;
44
57
 
45
58
  // If no more references to these styles in this document, remove <style> element from the DOM
46
- const { parentElement } = stylesItem.element;
47
- if (parentElement) {
48
- parentElement.removeChild(stylesItem.element);
59
+ if (stylesItem.element) {
60
+ const { parentElement } = stylesItem.element;
61
+ if (parentElement) {
62
+ parentElement.removeChild(stylesItem.element);
63
+ }
49
64
  }
65
+
50
66
  // Then remove the document Map
67
+ const stylesMap = styleRegistry.get(styles)!;
51
68
  stylesMap.delete(ownerDocument);
52
69
 
53
70
  if (stylesMap.size) return;