Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore: improve React 18 support (#72)
* chore: improve React 18 support * review suggestion
- Loading branch information
1 parent
c33da85
commit 1d0df06
Showing
15 changed files
with
145 additions
and
16 deletions.
There are no files selected for viewing
7 changes: 7 additions & 0 deletions
7
change/@griffel-react-13bf5fac-a88b-41ad-98fc-a8df3be96e6d.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
{ | ||
"type": "patch", | ||
"comment": "chore: improve React 18 support by using useInsertionEffect", | ||
"packageName": "@griffel/react", | ||
"email": "olfedias@microsoft.com", | ||
"dependentChangeType": "patch" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
/* | ||
* @jest-environment node | ||
*/ | ||
|
||
// 👆 this is intentionally to test in SSR like environment | ||
|
||
import type { GriffelRenderer } from '@griffel/core'; | ||
import * as React from 'react'; | ||
|
||
import { insertionFactory } from './insertionFactory'; | ||
|
||
describe('insertionFactory (node)', () => { | ||
it('does not use insertionEffect', () => { | ||
const useInsertionEffect = jest.spyOn(React, 'useInsertionEffect'); | ||
|
||
const renderer: Partial<GriffelRenderer> = { id: 'a', insertCSSRules: jest.fn() }; | ||
const insertStyles = insertionFactory(); | ||
|
||
insertStyles(renderer as GriffelRenderer, { d: ['a'] }); | ||
|
||
expect(useInsertionEffect).not.toHaveBeenCalled(); | ||
expect(renderer.insertCSSRules).toHaveBeenCalledTimes(1); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import type { GriffelRenderer } from '@griffel/core'; | ||
|
||
import { insertionFactory } from './insertionFactory'; | ||
import { useInsertionEffect as _useInsertionEffect } from './useInsertionEffect'; | ||
import * as React from 'react'; | ||
|
||
jest.mock('./useInsertionEffect', () => ({ | ||
useInsertionEffect: jest.fn().mockImplementation(fn => fn()), | ||
})); | ||
|
||
const useInsertionEffect = _useInsertionEffect as jest.MockedFunction<typeof React.useInsertionEffect>; | ||
|
||
describe('canUseDOM', () => { | ||
beforeEach(() => { | ||
jest.clearAllMocks(); | ||
}); | ||
|
||
it('uses "useInsertionEffect" when available', () => { | ||
const renderer: Partial<GriffelRenderer> = { insertCSSRules: jest.fn() }; | ||
const insertStyles = insertionFactory(); | ||
|
||
insertStyles(renderer as GriffelRenderer, { d: ['a'] }); | ||
|
||
expect(useInsertionEffect).toHaveBeenCalledTimes(1); | ||
expect(renderer.insertCSSRules).toHaveBeenCalledTimes(1); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import type { CSSRulesByBucket, GriffelInsertionFactory, GriffelRenderer } from '@griffel/core'; | ||
|
||
import { canUseDOM } from './utils/canUseDOM'; | ||
import { useInsertionEffect } from './useInsertionEffect'; | ||
|
||
export const insertionFactory: GriffelInsertionFactory = () => { | ||
const insertionCache: Record<string, boolean> = {}; | ||
|
||
return function insert(renderer: GriffelRenderer, cssRules: CSSRulesByBucket) { | ||
// Even if `useInsertionEffect` is available, we can use it on a client only as it will not be executed in SSR | ||
if (useInsertionEffect && canUseDOM()) { | ||
// eslint-disable-next-line react-hooks/rules-of-hooks | ||
useInsertionEffect(() => { | ||
renderer.insertCSSRules(cssRules!); | ||
}, [renderer, cssRules]); | ||
|
||
return; | ||
} | ||
|
||
if (insertionCache[renderer.id] === undefined) { | ||
renderer.insertCSSRules(cssRules!); | ||
insertionCache[renderer.id] = true; | ||
} | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import * as React from 'react'; | ||
|
||
export const useInsertionEffect: typeof React.useInsertionEffect | undefined = | ||
// @ts-expect-error Hack to make sure that `useInsertionEffect` will not cause bundling issues in older React versions | ||
// eslint-disable-next-line no-useless-concat | ||
React['useInsertion' + 'Effect'] ? React['useInsertion' + 'Effect'] : undefined; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
/* | ||
* @jest-environment node | ||
*/ | ||
|
||
// 👆 this is intentionally to test in SSR like environment | ||
|
||
import { canUseDOM } from './canUseDOM'; | ||
|
||
describe('canUseDOM (node)', () => { | ||
it('returns "false"', () => { | ||
expect(canUseDOM()).toBe(false); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import { canUseDOM } from './canUseDOM'; | ||
|
||
describe('canUseDOM', () => { | ||
it('returns "true"', () => { | ||
expect(canUseDOM()).toBe(true); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
/** | ||
* Verifies if an application can use DOM. | ||
*/ | ||
export function canUseDOM(): boolean { | ||
return typeof window !== 'undefined' && !!(window.document && window.document.createElement); | ||
} |