Skip to content

Commit

Permalink
ThemeProvider + SSR: Fix incorrect theme with multiple ThemeProviders…
Browse files Browse the repository at this point in the history
… on page (#4477)

* ssr theming: add unique id to PRIMER_DATA

* Create two-ravens-prove.md

* update snapshots
  • Loading branch information
siddharthkp committed Apr 10, 2024
1 parent cb5bf80 commit 054de02
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 48 deletions.
5 changes: 5 additions & 0 deletions .changeset/two-ravens-prove.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@primer/react": patch
---

ThemeProvider + SSR: Fix incorrect theme with multiple ThemeProviders on page
78 changes: 39 additions & 39 deletions packages/react/src/NavList/__snapshots__/NavList.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -331,10 +331,10 @@ exports[`NavList renders a simple list 1`] = `
>
<a
aria-current="page"
aria-labelledby=":r1:--label "
aria-labelledby=":r2:--label "
class="c3 c4"
href="/"
id=":r1:"
id=":r2:"
tabindex="0"
>
<div
Expand All @@ -343,7 +343,7 @@ exports[`NavList renders a simple list 1`] = `
>
<span
class="c6"
id=":r1:--label"
id=":r2:--label"
>
Home
</span>
Expand All @@ -354,10 +354,10 @@ exports[`NavList renders a simple list 1`] = `
class="c1 c7"
>
<a
aria-labelledby=":r2:--label "
aria-labelledby=":r3:--label "
class="c3 c4"
href="/about"
id=":r2:"
id=":r3:"
tabindex="0"
>
<div
Expand All @@ -366,7 +366,7 @@ exports[`NavList renders a simple list 1`] = `
>
<span
class="c8"
id=":r2:--label"
id=":r3:--label"
>
About
</span>
Expand All @@ -377,10 +377,10 @@ exports[`NavList renders a simple list 1`] = `
class="c1 c7"
>
<a
aria-labelledby=":r3:--label "
aria-labelledby=":r4:--label "
class="c3 c4"
href="/contact"
id=":r3:"
id=":r4:"
tabindex="0"
>
<div
Expand All @@ -389,7 +389,7 @@ exports[`NavList renders a simple list 1`] = `
>
<span
class="c8"
id=":r3:--label"
id=":r4:--label"
>
Contact
</span>
Expand Down Expand Up @@ -774,23 +774,23 @@ exports[`NavList renders with groups 1`] = `
>
<h3
class="c3"
id=":r5:"
id=":r7:"
>
Overview
</h3>
<ul
aria-labelledby=":r5:"
aria-labelledby=":r7:"
class="c4"
>
<li
class="c5 c6"
>
<a
aria-current="page"
aria-labelledby=":r6:--label "
aria-labelledby=":r8:--label "
class="c7 c8"
href="/getting-started"
id=":r6:"
id=":r8:"
tabindex="0"
>
<div
Expand All @@ -799,7 +799,7 @@ exports[`NavList renders with groups 1`] = `
>
<span
class="c10"
id=":r6:--label"
id=":r8:--label"
>
Getting started
</span>
Expand All @@ -818,22 +818,22 @@ exports[`NavList renders with groups 1`] = `
>
<h3
class="c3"
id=":r7:"
id=":r9:"
>
Components
</h3>
<ul
aria-labelledby=":r7:"
aria-labelledby=":r9:"
class="c4"
>
<li
class="c5 c11"
>
<a
aria-labelledby=":r8:--label "
aria-labelledby=":ra:--label "
class="c7 c8"
href="/Avatar"
id=":r8:"
id=":ra:"
tabindex="0"
>
<div
Expand All @@ -842,7 +842,7 @@ exports[`NavList renders with groups 1`] = `
>
<span
class="c12"
id=":r8:--label"
id=":ra:--label"
>
Avatar
</span>
Expand Down Expand Up @@ -1244,15 +1244,15 @@ exports[`NavList.Item with NavList.SubNav does not have active styles if SubNav
class="c0"
>
<li
aria-labelledby=":r1v:"
aria-labelledby=":r23:"
class="c1 c2"
>
<button
aria-controls=":r20:"
aria-controls=":r24:"
aria-expanded="true"
aria-labelledby=":r1v:--label "
aria-labelledby=":r23:--label "
class="c3 c4"
id=":r1v:"
id=":r23:"
tabindex="0"
>
<div
Expand All @@ -1264,7 +1264,7 @@ exports[`NavList.Item with NavList.SubNav does not have active styles if SubNav
>
<span
class="c1 c7"
id=":r1v:--label"
id=":r23:--label"
>
Item
</span>
Expand All @@ -1291,19 +1291,19 @@ exports[`NavList.Item with NavList.SubNav does not have active styles if SubNav
</button>
<div>
<ul
aria-labelledby=":r1v:"
aria-labelledby=":r23:"
class="c1 c10"
id=":r20:"
id=":r24:"
>
<li
class="c3 c11"
>
<a
aria-current="page"
aria-labelledby=":r22:--label "
aria-labelledby=":r26:--label "
class="c12 c13"
href="#"
id=":r22:"
id=":r26:"
tabindex="0"
>
<div
Expand All @@ -1312,7 +1312,7 @@ exports[`NavList.Item with NavList.SubNav does not have active styles if SubNav
>
<span
class="c1 c14"
id=":r22:--label"
id=":r26:--label"
>
Sub Item
</span>
Expand Down Expand Up @@ -1736,15 +1736,15 @@ exports[`NavList.Item with NavList.SubNav has active styles if SubNav contains t
class="c0"
>
<li
aria-labelledby=":r1q:"
aria-labelledby=":r1t:"
class="c1 c2"
>
<button
aria-controls=":r1r:"
aria-controls=":r1u:"
aria-expanded="false"
aria-labelledby=":r1q:--label "
aria-labelledby=":r1t:--label "
class="c3 c4"
id=":r1q:"
id=":r1t:"
tabindex="0"
>
<div
Expand All @@ -1756,7 +1756,7 @@ exports[`NavList.Item with NavList.SubNav has active styles if SubNav contains t
>
<span
class="c1 c7"
id=":r1q:--label"
id=":r1t:--label"
>
Item
</span>
Expand All @@ -1783,19 +1783,19 @@ exports[`NavList.Item with NavList.SubNav has active styles if SubNav contains t
</button>
<div>
<ul
aria-labelledby=":r1q:"
aria-labelledby=":r1t:"
class="c1 c10"
id=":r1r:"
id=":r1u:"
>
<li
class="c3 c11"
>
<a
aria-current="page"
aria-labelledby=":r1t:--label "
aria-labelledby=":r20:--label "
class="c12 c13"
href="#"
id=":r1t:"
id=":r20:"
tabindex="0"
>
<div
Expand All @@ -1804,7 +1804,7 @@ exports[`NavList.Item with NavList.SubNav has active styles if SubNav contains t
>
<span
class="c1 c7"
id=":r1t:--label"
id=":r20:--label"
>
Sub Item
</span>
Expand Down
10 changes: 6 additions & 4 deletions packages/react/src/ThemeProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import ReactDOM from 'react-dom'
import {ThemeProvider as SCThemeProvider} from 'styled-components'
import defaultTheme from './theme'
import deepmerge from 'deepmerge'
import {useId} from './hooks'

export const defaultColorMode = 'day'
const defaultDayScheme = 'light'
Expand Down Expand Up @@ -39,9 +40,9 @@ const ThemeContext = React.createContext<{
})

// inspired from __NEXT_DATA__, we use application/json to avoid CSRF policy with inline scripts
const getServerHandoff = () => {
const getServerHandoff = (id: string) => {
try {
const serverData = document.getElementById('__PRIMER_DATA__')?.textContent
const serverData = document.getElementById(`__PRIMER_DATA_${id}__`)?.textContent
if (serverData) return JSON.parse(serverData)
} catch (error) {
// if document/element does not exist or JSON is invalid, supress error
Expand All @@ -61,7 +62,8 @@ export const ThemeProvider: React.FC<React.PropsWithChildren<ThemeProviderProps>
// Initialize state
const theme = props.theme ?? fallbackTheme ?? defaultTheme

const {resolvedServerColorMode} = getServerHandoff()
const uniqueDataId = useId()
const {resolvedServerColorMode} = getServerHandoff(uniqueDataId)
const resolvedColorModePassthrough = React.useRef(resolvedServerColorMode)

const [colorMode, setColorMode] = React.useState(props.colorMode ?? fallbackColorMode ?? defaultColorMode)
Expand Down Expand Up @@ -135,7 +137,7 @@ export const ThemeProvider: React.FC<React.PropsWithChildren<ThemeProviderProps>
{props.preventSSRMismatch ? (
<script
type="application/json"
id="__PRIMER_DATA__"
id={`__PRIMER_DATA_${uniqueDataId}__`}
dangerouslySetInnerHTML={{__html: JSON.stringify({resolvedServerColorMode: resolvedColorMode})}}
/>
) : null}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ exports[`AnchoredOverlay should render consistently when open 1`] = `
aria-expanded="true"
aria-haspopup="true"
class="c1 c2"
id=":r6:"
id=":rd:"
tabindex="0"
>
Anchor Button
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2176,7 +2176,7 @@ exports[`TextInput renders trailingAction icon button 1`] = `
className="c3 TextInput-action"
>
<button
aria-labelledby=":r1:"
aria-labelledby=":rl:"
className="c4"
data-block={null}
data-component="IconButton"
Expand Down Expand Up @@ -2215,7 +2215,7 @@ exports[`TextInput renders trailingAction icon button 1`] = `
aria-hidden={true}
className="c5"
data-direction="s"
id=":r1:"
id=":rl:"
onMouseEnter={[Function]}
onMouseLeave={[Function]}
>
Expand Down Expand Up @@ -3170,7 +3170,7 @@ exports[`TextInput renders trailingAction text button with a tooltip 1`] = `
className="c3 TextInput-action"
>
<button
aria-describedby=":r0:"
aria-describedby=":rj:"
className="c4"
data-block={null}
data-no-visuals={true}
Expand All @@ -3196,7 +3196,7 @@ exports[`TextInput renders trailingAction text button with a tooltip 1`] = `
<span
className="c6"
data-direction="s"
id=":r0:"
id=":rj:"
onMouseEnter={[Function]}
onMouseLeave={[Function]}
role="tooltip"
Expand Down

0 comments on commit 054de02

Please sign in to comment.