Open quantizor opened 2 years ago
This would be great, I could really use this too. +1 Did you happen to find a work around to achieve something similar ?
@sctgraham this is what I came up with:
const XSTYLED_CLASS_PREFIX = 'xstyled-color-mode-';
const ColorModeContext = React.createContext<DSIColorModes>('light');
/**
* Composes the typical `<ThemeProvider>` with some goodies. This wrapper should be placed at the root of your application.
*/
export function DSStyleProvider({
children,
colorMode = 'light',
theme,
}: React.PropsWithChildren<{
/**
* Forces a particular color mode.
*/
colorMode?: 'light' | 'dark';
theme: DSITheme;
}>) {
const Wrapper = (() => {
switch (colorMode) {
case 'dark':
return DSDarkModeProvider;
default:
return DSLightModeProvider;
}
})();
return (
<ThemeProvider
// @ts-expect-error need to make ThemeProvider less restrictive
theme={theme}
>
<ColorModeProvider targetSelector={`[class*="${XSTYLED_CLASS_PREFIX}"]`}>
<Wrapper>
{children}
</Wrapper>
</ColorModeProvider>
</ThemeProvider>
);
}
/**
* This wrapper forces on dark mode for a particular component subtree. Note that color mode shifting is not enabled by default
* in DSP (controlled by the `useColorSchemeMediaQuery` theme variable) for UX reasons; dark mode is currently reserved for specific
* interfaces like CAD view.
*/
export function DSDarkModeProvider({ children }: React.PropsWithChildren<{}>) {
return (
<ColorModeContext.Provider value="dark">
<x.div className={`${XSTYLED_CLASS_PREFIX}dark`} display="contents">
{children}
</x.div>
</ColorModeContext.Provider>
);
}
/**
* This wrapper forces on light mode for a particular component subtree. Note that color mode shifting is not enabled by default
* in DSP (controlled by the `useColorSchemeMediaQuery` theme variable) for UX reasons.
*
* You should pretty much never need to use this component, but it is included with the library for completeness.
*/
export function DSLightModeProvider({ children }: React.PropsWithChildren<{}>) {
return (
<ColorModeContext.Provider value="light">
<x.div className={`${XSTYLED_CLASS_PREFIX}light`} display="contents">
{children}
</x.div>
</ColorModeContext.Provider>
);
}
/**
* Replacement for xstyled's `useColorMode` that pays attention to component
* subtrees.
*/
export function useColorMode() {
return React.useContext(ColorModeContext);
}
@gregberge you might want to steal this impl, it's been working great in our design system
Sweet ! Thanks for taking the time. I'll dig into this and see how it goes. Great use of display:contents
btw.
@sctgraham just a heads up I updated my example with a revised targetSelector
The
ColorModeProvider
component currently enables color shifting in general, but as far as I can tell there is no way to explicitly force a particular color mode for a given subtree. The use case I'm working on is there are particular screens where the insides are meant to use a dark style, but the outer UI is normal 🤷🏼