diff --git a/packages/@react-spectrum/s2/src/Provider.tsx b/packages/@react-spectrum/s2/src/Provider.tsx index 4e2e31e7999..971a42007a8 100644 --- a/packages/@react-spectrum/s2/src/Provider.tsx +++ b/packages/@react-spectrum/s2/src/Provider.tsx @@ -13,6 +13,7 @@ import type {ColorScheme, Router} from '@react-types/provider'; import {colorScheme, UnsafeStyles} from './style-utils' with {type: 'macro'}; import {createContext, JSX, ReactNode, useContext} from 'react'; +import {generateDefaultColorSchemeStyles} from './page.macro' with {type: 'macro'}; import {I18nProvider, RouterProvider, useLocale} from 'react-aria-components'; import {mergeStyles} from '../style/runtime'; import {style} from '../style/spectrum-theme' with {type: 'macro'}; @@ -52,7 +53,7 @@ export const ColorSchemeContext = createContext; let parentColorScheme = useContext(ColorSchemeContext); - let colorScheme = props.colorScheme || parentColorScheme || 'light dark'; + let colorScheme = props.colorScheme || parentColorScheme; if (colorScheme !== parentColorScheme) { result = {result}; } @@ -68,6 +69,8 @@ export function Provider(props: ProviderProps) { return result; } +generateDefaultColorSchemeStyles(); + let providerStyles = style({ ...colorScheme(), '--s2-container-bg': { @@ -80,7 +83,14 @@ let providerStyles = style({ } } }, - backgroundColor: '--s2-container-bg' + backgroundColor: { + // Don't set a background unless one is requested. + background: { + base: '--s2-container-bg', + 'layer-1': '--s2-container-bg', + 'layer-2': '--s2-container-bg' + } + } }); function ProviderInner(props: ProviderProps) { diff --git a/packages/@react-spectrum/s2/src/page.macro.ts b/packages/@react-spectrum/s2/src/page.macro.ts index 7f26dbb4685..bc560db504e 100644 --- a/packages/@react-spectrum/s2/src/page.macro.ts +++ b/packages/@react-spectrum/s2/src/page.macro.ts @@ -49,3 +49,27 @@ export function generatePageStyles(this: MacroContext | void) { }); } } + +// This generates a low specificity rule to define default values for +// --lightningcss-light and --lightningcss-dark. This is used when rendering +// a without setting a colorScheme prop, and when page.css is not present. +// It is equivalent to setting `color-scheme: light dark`, but without overriding +// the browser default for content outside the provider. +export function generateDefaultColorSchemeStyles(this: MacroContext | void) { + if (this && typeof this.addAsset === 'function') { + this.addAsset({ + type: 'css', + content: `@layer _.a { + :where(html) { + --lightningcss-light: initial; + --lightningcss-dark: ; + + @media (prefers-color-scheme: dark) { + --lightningcss-light: ; + --lightningcss-dark: initial; + } + } + }` + }); + } +} diff --git a/packages/@react-spectrum/s2/src/style-utils.ts b/packages/@react-spectrum/s2/src/style-utils.ts index 26ee2e8cf4c..8ba1995c2df 100644 --- a/packages/@react-spectrum/s2/src/style-utils.ts +++ b/packages/@react-spectrum/s2/src/style-utils.ts @@ -131,6 +131,8 @@ export const fieldInput = () => ({ export const colorScheme = () => ({ colorScheme: { + // Default to page color scheme if none is defined. + default: '[var(--lightningcss-light, light) var(--lightningcss-dark, dark)]', colorScheme: { 'light dark': 'light dark', light: 'light',