Skip to content

Commit 7c75c61

Browse files
arturbienchaance
authored andcommitted
address document-context comments
1 parent 1796aa9 commit 7c75c61

File tree

3 files changed

+23
-27
lines changed

3 files changed

+23
-27
lines changed

packages/react/document-context/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,13 @@
2828
"version": "yarn version"
2929
},
3030
"dependencies": {
31-
"@radix-ui/react-primitive": "workspace:*"
31+
"@radix-ui/react-primitive": "workspace:*",
32+
"use-sync-external-store": "^1.4.0"
3233
},
3334
"devDependencies": {
3435
"@repo/typescript-config": "workspace:*",
3536
"@types/react": "^19.0.7",
37+
"@types/use-sync-external-store": "^0.0.6",
3638
"react": "^19.0.0",
3739
"typescript": "^5.7.3"
3840
},

packages/react/document-context/src/document-context.test.tsx

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,6 @@ function TestComponent() {
88
}
99

1010
describe('DocumentContext', () => {
11-
it('provides default document when no custom document is provided', () => {
12-
render(
13-
<DocumentProvider>
14-
<TestComponent />
15-
</DocumentProvider>
16-
);
17-
18-
expect(screen.getByText('Has document: true')).toBeInTheDocument();
19-
});
20-
2111
it('provides custom document when specified', () => {
2212
const mockDocument = {} as Document;
2313

@@ -59,18 +49,20 @@ describe('DocumentContext', () => {
5949
expect(screen.getByText('Document ID: 2')).toBeInTheDocument();
6050
});
6151

62-
it('provides global document when no value is passed to provider', () => {
52+
it('useDocument returns global document when no value is passed to provider', () => {
6353
function TestDocumentConsumer() {
6454
const doc = useDocument();
6555
return <div>{doc === globalThis.document ? 'global document' : 'other document'}</div>;
6656
}
6757

68-
render(
69-
<DocumentProvider>
70-
<TestDocumentConsumer />
71-
</DocumentProvider>
72-
);
58+
render(<TestDocumentConsumer />);
7359

7460
expect(screen.getByText('global document')).toBeInTheDocument();
7561
});
62+
63+
it('useDocument returns default document when custom document is not provided', () => {
64+
render(<TestComponent />);
65+
66+
expect(screen.getByText('Has document: true')).toBeInTheDocument();
67+
});
7668
});
Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,25 @@
11
import * as React from 'react';
2-
2+
import { useSyncExternalStore } from 'use-sync-external-store/shim';
33
// Use null as initial value to handle SSR safely
44
const DocumentContext = React.createContext<Document | null>(null);
55

66
interface DocumentProviderProps {
7-
document?: Document;
7+
document: Document;
88
children: React.ReactNode;
99
}
1010

11-
export function DocumentProvider({ document: doc, children }: DocumentProviderProps) {
12-
const value = React.useMemo(
13-
() => doc ?? (typeof document !== 'undefined' ? globalThis?.document : null),
14-
[doc]
15-
);
16-
return <DocumentContext.Provider value={value}>{children}</DocumentContext.Provider>;
11+
export function DocumentProvider({ document, children }: DocumentProviderProps) {
12+
return <DocumentContext.Provider value={document}>{children}</DocumentContext.Provider>;
1713
}
1814

15+
const subscribe = () => () => {};
16+
1917
export function useDocument() {
2018
const doc = React.useContext(DocumentContext);
21-
// Return default document if available and no context value
22-
return doc ?? (typeof document !== 'undefined' ? globalThis?.document : null);
19+
const isHydrated = useSyncExternalStore(
20+
subscribe,
21+
() => true,
22+
() => false
23+
);
24+
return doc ?? (isHydrated ? document : null);
2325
}

0 commit comments

Comments
 (0)