diff --git a/packages/styled-react/src/components/BaseStyles.tsx b/packages/styled-react/src/components/BaseStyles.tsx index d2ed1412d8d..d21f4e8b3d4 100644 --- a/packages/styled-react/src/components/BaseStyles.tsx +++ b/packages/styled-react/src/components/BaseStyles.tsx @@ -3,7 +3,7 @@ import {type CSSProperties, type PropsWithChildren, type JSX} from 'react' import {clsx} from 'clsx' // eslint-disable-next-line import/no-namespace import type * as styledSystem from 'styled-system' -import {useTheme} from './ThemeProvider' +import {useTheme} from './useTheme' import 'focus-visible' import {createGlobalStyle} from 'styled-components' diff --git a/packages/styled-react/src/components/FeatureFlaggedTheming.tsx b/packages/styled-react/src/components/FeatureFlaggedTheming.tsx index 3fa68d7927d..e05f91962c9 100644 --- a/packages/styled-react/src/components/FeatureFlaggedTheming.tsx +++ b/packages/styled-react/src/components/FeatureFlaggedTheming.tsx @@ -1,15 +1,11 @@ import type React from 'react' -import { - ThemeProvider as PrimerThemeProvider, - useTheme as primerUseTheme, - BaseStyles as PrimerBaseStyles, -} from '@primer/react' +import {ThemeProvider as PrimerThemeProvider, BaseStyles as PrimerBaseStyles} from '@primer/react' import type { ThemeProviderProps as PrimerThemeProviderProps, BaseStylesProps as PrimerBaseStylesProps, } from '@primer/react' import {useFeatureFlag} from '@primer/react/experimental' -import {ThemeProvider as StyledThemeProvider, useTheme as styledUseTheme, useColorSchemeVar} from './ThemeProvider' +import {ThemeProvider as StyledThemeProvider} from './ThemeProvider' import type {ThemeProviderProps as StyledThemeProviderProps} from './ThemeProvider' import {BaseStyles as StyledBaseStyles} from './BaseStyles' import type {BaseStylesProps as StyledBaseStylesProps} from './BaseStyles' @@ -26,18 +22,6 @@ export const ThemeProvider: React.FC return {children} } -export function useTheme(): ReturnType { - const enabled = useFeatureFlag('primer_react_styled_react_use_primer_theme_providers') - const styledTheme = styledUseTheme() - const primerTheme = primerUseTheme() - if (enabled) { - return primerTheme as ReturnType - } - return styledTheme -} - -export {useColorSchemeVar} - export function BaseStyles(props: BaseStylesProps) { const enabled = useFeatureFlag('primer_react_styled_react_use_primer_theme_providers') if (enabled) { diff --git a/packages/styled-react/src/components/ThemeContext.ts b/packages/styled-react/src/components/ThemeContext.ts new file mode 100644 index 00000000000..ceaeb522ee6 --- /dev/null +++ b/packages/styled-react/src/components/ThemeContext.ts @@ -0,0 +1,19 @@ +import React from 'react' +import type {ColorMode, ColorModeWithAuto, Theme} from './ThemeProvider' + +export const ThemeContext = React.createContext<{ + theme?: Theme + colorScheme?: string + colorMode?: ColorModeWithAuto + resolvedColorMode?: ColorMode + resolvedColorScheme?: string + dayScheme?: string + nightScheme?: string + setColorMode: React.Dispatch> + setDayScheme: React.Dispatch> + setNightScheme: React.Dispatch> +}>({ + setColorMode: () => null, + setDayScheme: () => null, + setNightScheme: () => null, +}) diff --git a/packages/styled-react/src/components/ThemeProvider.tsx b/packages/styled-react/src/components/ThemeProvider.tsx index aad508730b4..07f51a91b1b 100644 --- a/packages/styled-react/src/components/ThemeProvider.tsx +++ b/packages/styled-react/src/components/ThemeProvider.tsx @@ -2,6 +2,8 @@ import React from 'react' import {ThemeProvider as SCThemeProvider} from 'styled-components' import {theme as defaultTheme, useId, useSyncedState} from '@primer/react' import deepmerge from 'deepmerge' +import {ThemeContext} from './ThemeContext' +import {useTheme} from './useTheme' export const defaultColorMode = 'day' const defaultDayScheme = 'light' @@ -9,7 +11,7 @@ const defaultNightScheme = 'dark' // eslint-disable-next-line @typescript-eslint/no-explicit-any export type Theme = {[key: string]: any} -type ColorMode = 'day' | 'night' | 'light' | 'dark' +export type ColorMode = 'day' | 'night' | 'light' | 'dark' export type ColorModeWithAuto = ColorMode | 'auto' export type ThemeProviderProps = { @@ -25,23 +27,6 @@ export type ThemeProviderProps = { contextOnly?: boolean } -const ThemeContext = React.createContext<{ - theme?: Theme - colorScheme?: string - colorMode?: ColorModeWithAuto - resolvedColorMode?: ColorMode - resolvedColorScheme?: string - dayScheme?: string - nightScheme?: string - setColorMode: React.Dispatch> - setDayScheme: React.Dispatch> - setNightScheme: React.Dispatch> -}>({ - setColorMode: () => null, - setDayScheme: () => null, - setNightScheme: () => null, -}) - // inspired from __NEXT_DATA__, we use application/json to avoid CSRF policy with inline scripts const serverHandoffCache = new Map>() const emptyHandoff: Record = {} @@ -144,15 +129,6 @@ export const ThemeProvider: React.FC ) } -export function useTheme() { - return React.useContext(ThemeContext) -} - -export function useColorSchemeVar(values: Partial>, fallback: string) { - const {colorScheme = ''} = useTheme() - return values[colorScheme] ?? fallback -} - function subscribeToSystemColorMode(callback: () => void) { // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition const media = window?.matchMedia?.('(prefers-color-scheme: dark)') diff --git a/packages/styled-react/src/components/useFeatureFlaggedTheme.ts b/packages/styled-react/src/components/useFeatureFlaggedTheme.ts new file mode 100644 index 00000000000..3b17b2f0f15 --- /dev/null +++ b/packages/styled-react/src/components/useFeatureFlaggedTheme.ts @@ -0,0 +1,20 @@ +import {useColorSchemeVar as primerUseColorSchemeVar, useTheme as primerUseTheme} from '@primer/react' +import {useFeatureFlag} from '@primer/react/experimental' +import {useColorSchemeVar as styledUseColorSchemeVar, useTheme as styledUseTheme} from './useTheme' + +export function useTheme(): ReturnType { + const enabled = useFeatureFlag('primer_react_styled_react_use_primer_theme_providers') + const styledTheme = styledUseTheme() + const primerTheme = primerUseTheme() + if (enabled) { + return primerTheme as ReturnType + } + return styledTheme +} + +export function useColorSchemeVar(values: Partial>, fallback: string) { + const enabled = useFeatureFlag('primer_react_styled_react_use_primer_theme_providers') + const styledValue = styledUseColorSchemeVar(values, fallback) + const primerValue = primerUseColorSchemeVar(values, fallback) + return enabled ? primerValue : styledValue +} diff --git a/packages/styled-react/src/components/useTheme.ts b/packages/styled-react/src/components/useTheme.ts new file mode 100644 index 00000000000..fa6d870875e --- /dev/null +++ b/packages/styled-react/src/components/useTheme.ts @@ -0,0 +1,11 @@ +import React from 'react' +import {ThemeContext} from './ThemeContext' + +export function useTheme() { + return React.useContext(ThemeContext) +} + +export function useColorSchemeVar(values: Partial>, fallback: string) { + const {colorScheme = ''} = useTheme() + return values[colorScheme] ?? fallback +} diff --git a/packages/styled-react/src/index.tsx b/packages/styled-react/src/index.tsx index 837b15b05a4..9937367df26 100644 --- a/packages/styled-react/src/index.tsx +++ b/packages/styled-react/src/index.tsx @@ -12,20 +12,22 @@ export { * @deprecated Theming in JavaScript is no longer supported. Prefer using * `@primer/primitives` and CSS Modules instead. */ - useTheme, + type ThemeProviderProps, +} from './components/FeatureFlaggedTheming' +export { /** * @deprecated Theming in JavaScript is no longer supported. Prefer using * `@primer/primitives` and CSS Modules instead. */ - useColorSchemeVar, + useTheme, /** * @deprecated Theming in JavaScript is no longer supported. Prefer using * `@primer/primitives` and CSS Modules instead. */ - type ThemeProviderProps, -} from './components/FeatureFlaggedTheming' + useColorSchemeVar, +} from './components/useFeatureFlaggedTheme' export { /**