Add documentLevel mode to DTWebThemeProvider
When documentLevel is true, sets data-brand and data-theme on document.documentElement instead of rendering a wrapper div. This is needed for apps where CSS ancestor selectors must match from the document root (e.g. [data-brand="dt"] .card). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,11 +1,12 @@
|
|||||||
/**
|
/**
|
||||||
* DTWebThemeProvider
|
* DTWebThemeProvider
|
||||||
*
|
*
|
||||||
* Sets data-brand and data-theme attributes on a wrapper div.
|
* Sets data-brand and data-theme attributes on a wrapper div (default)
|
||||||
|
* or on document.documentElement (documentLevel mode).
|
||||||
* Provides React context for child components to read the active brand/theme.
|
* Provides React context for child components to read the active brand/theme.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { createContext, type ReactNode } from 'react';
|
import { createContext, useEffect, type ReactNode } from 'react';
|
||||||
import type { ThemeBrand, ThemeMode } from '@dangerousthings/tokens';
|
import type { ThemeBrand, ThemeMode } from '@dangerousthings/tokens';
|
||||||
import { cx } from '../utils/cx';
|
import { cx } from '../utils/cx';
|
||||||
|
|
||||||
@@ -21,7 +22,9 @@ interface DTWebThemeProviderProps {
|
|||||||
brand?: ThemeBrand;
|
brand?: ThemeBrand;
|
||||||
/** Theme mode @default 'dark' */
|
/** Theme mode @default 'dark' */
|
||||||
theme?: ThemeMode;
|
theme?: ThemeMode;
|
||||||
/** Additional className for the wrapper div */
|
/** When true, sets data-brand/data-theme on document.documentElement instead of a wrapper div */
|
||||||
|
documentLevel?: boolean;
|
||||||
|
/** Additional className for the wrapper div (ignored when documentLevel is true) */
|
||||||
className?: string;
|
className?: string;
|
||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
}
|
}
|
||||||
@@ -29,14 +32,26 @@ interface DTWebThemeProviderProps {
|
|||||||
export function DTWebThemeProvider({
|
export function DTWebThemeProvider({
|
||||||
brand = 'dt',
|
brand = 'dt',
|
||||||
theme = 'dark',
|
theme = 'dark',
|
||||||
|
documentLevel,
|
||||||
className,
|
className,
|
||||||
children,
|
children,
|
||||||
}: DTWebThemeProviderProps) {
|
}: DTWebThemeProviderProps) {
|
||||||
|
useEffect(() => {
|
||||||
|
if (documentLevel) {
|
||||||
|
document.documentElement.dataset.brand = brand;
|
||||||
|
document.documentElement.dataset.theme = theme;
|
||||||
|
}
|
||||||
|
}, [documentLevel, brand, theme]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DTWebThemeContext.Provider value={{ brand, theme }}>
|
<DTWebThemeContext.Provider value={{ brand, theme }}>
|
||||||
<div data-brand={brand} data-theme={theme} className={cx('dt-theme-root', className)}>
|
{documentLevel ? (
|
||||||
{children}
|
children
|
||||||
</div>
|
) : (
|
||||||
|
<div data-brand={brand} data-theme={theme} className={cx('dt-theme-root', className)}>
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</DTWebThemeContext.Provider>
|
</DTWebThemeContext.Provider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user