Skip to content

Commit

Permalink
docs(theme): add theme for light & dark theme usage
Browse files Browse the repository at this point in the history
  • Loading branch information
gcornut committed Jan 28, 2025
1 parent c028aaf commit 79dfd67
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 25 deletions.
1 change: 1 addition & 0 deletions packages/site-demo/content/menu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
- Typography
- Size
- Spacing
- Light & Dark Theme
- Components: '*'
- Patterns:
- Drag and drop
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { ThemeProvider, Button, Chip, Flag, useTheme } from '@lumx/react';

# Light & Dark Theme

By default, all component use a `light` theme that can be used on a light background.
Some components provide an alternative `dark` theme that can be used to adapt to dark backgrounds.

This theme is not synced to the user's preferred color scheme, it **must be activated manually**.

## Activate via prop

On the supported components, use the `theme` prop to activate the desired theme.

<DemoBlock orientation="horizontal" backgroundColor={{ color: 'dark', variant: 'N' }} alwaysShowCode>
<Button theme="dark">Dark Button</Button>
<Chip theme="dark">Dark Chip</Chip>
</DemoBlock>

## Activate via context

Use the `ThemeProvider` component to apply the desired theme to all of its children.

<DemoBlock orientation="horizontal" backgroundColor={{ color: 'dark', variant: 'N' }} alwaysShowCode>
<ThemeProvider value="dark">
<Button>Dark Button</Button>
<Chip>Dark Chip</Chip>
</ThemeProvider>
</DemoBlock>

Please note **some exceptions** to the theme context propagation:
- The `Popover` ignores the theme context for now because most children that we put inside do not support the `dark` theme (List & ListItem)
- The components `Popover`, `Lightbox` and `Dialog` all stop the propagation of the theme context and reset the theme because their children won't appear on the same background from where they are called

Use the `useTheme()` hook to get the theme from the current theme context when you need to adapt within your custom component.

<DemoBlock orientation="horizontal" backgroundColor={{ color: 'dark', variant: 'N' }}>
{() => {
function MyComponent() {
const theme = useTheme();
return <Flag theme={theme} label={`Current theme: ${theme}`} />;
}
return <ThemeProvider value="dark"><MyComponent /></ThemeProvider>;
}}
</DemoBlock>
56 changes: 31 additions & 25 deletions packages/site-demo/src/components/content/DemoBlock/DemoBlock.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ interface DemoBlockProps extends FlexBoxProps {
withThemeSwitcher?: boolean;
hasPlayButton?: boolean;
backgroundColor?: { color: ColorPalette; variant: ColorVariant };
alwaysShowCode?: boolean;
}

const DEFAULT_PROPS: Partial<DemoBlockProps> = {
Expand All @@ -40,14 +41,15 @@ export const DemoBlock: React.FC<DemoBlockProps> = ({
withThemeSwitcher = false,
hasPlayButton = false,
backgroundColor: propBackgroundColor,
alwaysShowCode,
...flexBoxProps
}) => {
const [theme, setTheme] = useState<Theme>(Theme.light);
const toggleTheme = (isChecked: boolean) => {
setTheme(isChecked ? Theme.dark : Theme.light);
};

const [showCode, setShowCode] = useState(false);
const [showCode, setShowCode] = useState(!!alwaysShowCode);
const toggleShowCode = () => setShowCode(!showCode);

if (flexBoxProps.orientation === Orientation.horizontal) {
Expand All @@ -74,31 +76,35 @@ export const DemoBlock: React.FC<DemoBlockProps> = ({
)}
{isFunction(children) ? children({ theme }) : children}
</FlexBox>
<div className="demo-block__toolbar">
<div className="demo-block__code-toggle">
<Button
disabled={!codeString}
emphasis={Emphasis.low}
leftIcon={mdiCodeTags}
onClick={toggleShowCode}
>
{showCode ? 'Hide code' : 'Show code'}
</Button>
</div>
{(!alwaysShowCode || withThemeSwitcher) && (
<div className="demo-block__toolbar">
{!alwaysShowCode && (
<div className="demo-block__code-toggle">
<Button
disabled={!codeString}
emphasis={Emphasis.low}
leftIcon={mdiCodeTags}
onClick={toggleShowCode}
>
{showCode ? 'Hide code' : 'Show code'}
</Button>
</div>
)}

{withThemeSwitcher && (
<div className="demo-block__theme-toggle">
<Switch
disabled={!children}
position={Alignment.right}
isChecked={theme === Theme.dark}
onChange={toggleTheme}
>
Dark theme
</Switch>
</div>
)}
</div>
{withThemeSwitcher && (
<div className="demo-block__theme-toggle">
<Switch
disabled={!children}
position={Alignment.right}
isChecked={theme === Theme.dark}
onChange={toggleTheme}
>
Dark theme
</Switch>
</div>
)}
</div>
)}

<CodeBlock
className={classNames('demo-block__code', showCode && codeString && 'demo-block__code--shown')}
Expand Down

0 comments on commit 79dfd67

Please sign in to comment.