Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding prefersColorScheme option to theme provider to select the system default #93

Merged
merged 1 commit into from
Nov 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 26 additions & 2 deletions src/components/ThemeProvider/ThemeProvider.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export const Nested = () => {
<div id="app2">
<ThemeProvider root="#app2" scope="application2" theme="dark">
<Card background="backgroundPrimary" marginTop="4">
<Collapsible label="Nested Application 2">
<Collapsible label="Nested Application 2 (Dark)">
<Text variant="normal" color="text100">
Lorem ipsum dolor sit amet, consectetur adipiscing elit,
sed do eiusmod tempor incididunt ut labore et dolore
Expand Down Expand Up @@ -85,7 +85,31 @@ export const Nested = () => {
}}
>
<Card background="backgroundPrimary" marginTop="4">
<Collapsible label="Nested Application 3">
<Collapsible label="Nested Application 3 (Custom Theme)">
<Text variant="normal" color="text100">
Lorem ipsum dolor sit amet, consectetur adipiscing elit,
sed do eiusmod tempor incididunt ut labore et dolore
magna aliqua. Ut enim ad minim veniam, quis nostrud
exercitation ullamco laboris nisi ut aliquip ex ea
commodo consequat. Duis aute irure dolor in
reprehenderit in voluptate velit esse cillum dolore eu
fugiat nulla pariatur. Excepteur sint occaecat cupidatat
non proident, sunt in culpa qui officia deserunt mollit
anim id est laborum.
</Text>
</Collapsible>
</Card>
</ThemeProvider>
</div>

<div id="app4">
<ThemeProvider
root="#app4"
scope="application4"
prefersColorScheme
>
<Card background="backgroundPrimary" marginTop="4">
<Collapsible label="Nested Application 4 (Prefers Color Scheme)">
<Text variant="normal" color="text100">
Lorem ipsum dolor sit amet, consectetur adipiscing elit,
sed do eiusmod tempor incididunt ut labore et dolore
Expand Down
43 changes: 24 additions & 19 deletions src/components/ThemeProvider/ThemeProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,10 @@ interface ThemeProviderProps {
theme?: Theme | ThemeOverrides
root?: string
scope?: string
prefersColorScheme?: boolean
}

const getTheme = (scope?: string): Theme => {
const getPersistedTheme = (scope?: string) => {
const persistedTheme = localStorage.getItem(
getStorageKey(scope)
) as Theme | null
Expand All @@ -50,13 +51,17 @@ const getTheme = (scope?: string): Theme => {
return persistedTheme
}

// else if (matchMedia(`(prefers-color-scheme: light)`).matches) {
// return 'light'
// } else if (matchMedia(`(prefers-color-scheme: dark)`).matches) {
// return 'dark'
// }
return null
}

const getPreferredColorScheme = () => {
if (matchMedia(`(prefers-color-scheme: light)`).matches) {
return 'light'
} else if (matchMedia(`(prefers-color-scheme: dark)`).matches) {
return 'dark'
}

return DEFAULT_THEME
return null
}

const ThemeContext = createContext<ThemeContextValue | null>(null)
Expand All @@ -72,19 +77,19 @@ export const ThemeProvider = (props: PropsWithChildren<ThemeProviderProps>) => {
window.document.documentElement.classList.add('is-apple')
}, [])

// Load theme from local storage
useEffect(() => {
if (!props.theme) {
setTheme(getTheme(props.scope))
}
}, [props.theme, props.scope])

// Allow prop theme override
useEffect(() => {
if (props.theme) {
setTheme(props.theme)
}
}, [props.theme])
const theme =
// Use the theme prop if it exists
props.theme ||
// or use the persisted theme from local store if it exists
getPersistedTheme(props.scope) ||
// or use the browser's preferred color scheme if enabled
(props.prefersColorScheme && getPreferredColorScheme()) ||
// or use the default theme
DEFAULT_THEME

setTheme(theme)
}, [props.theme, props.scope, props.prefersColorScheme])

// Set the data-theme attribtute on the document root element
useEffect(() => {
Expand Down