Skip to content

Commit

Permalink
feat: add util to enforce a color scheme on an html element
Browse files Browse the repository at this point in the history
  • Loading branch information
martimalek committed Jul 5, 2024
1 parent 30eab4a commit 8734552
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 24 deletions.
39 changes: 23 additions & 16 deletions docs/migrating.storybook.mdx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { Meta } from '@storybook/blocks';

import { PlacementMappingsTable } from './components/migration/PlacementMappingsTable';
import { InvertedPropMigrationTable } from './components/migration/InvertedPropMigrationTable';
import { IconMappingsTable } from './components/migration/IconMappingsTable';
import { CssVariablesMigrationTable } from './components/migration/CssVariablesMigrationTable';
import { IconMappingsTable } from './components/migration/IconMappingsTable';
import { InvertedPropMigrationTable } from './components/migration/InvertedPropMigrationTable';
import { PlacementMappingsTable } from './components/migration/PlacementMappingsTable';

<Meta title="Migration to v2" />

Expand Down Expand Up @@ -80,22 +80,29 @@ In case it doesn't work, reach out to the #ask-wave Slack channel for help.
Wave v2 comes with automatic dark scheme enabled by default. That means the color of the UI will reflect the OS color preferences of the user.

Most likely, your app will need adjustments to make the dark scheme readable.
Consider adding a task to your backlog, and disable the dark scheme by wrapping your application root with the `LightScheme` until you are ready:
Consider adding a task to your backlog, and disable the dark scheme by adding the `wave` and `light-scheme` classes to the body of your app.

```tsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App.tsx';
import { ClassicColors, LightScheme } from '@freenow/wave'; // blue primary color
<body class="wave light-scheme">
<!-- APP -->
</body>
```

ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<ClassicColors />
<LightScheme>
<App />
</LightScheme>
</React.StrictMode>
);
In case you cannot access the `body` directly (e.g. NextJS projects) Wave exposes the `enforceSchemeOnElement` utility to programmatically enforce a color scheme for an element.

```tsx
import { enforceSchemeOnElement } from '@freenow/wave';

export const App = () => {
useEffect(() => {
const body = document.querySelector('body');
if (body) enforceSchemeOnElement('light-scheme', body);
}, []);

return {
/* YOUR APP */
};
};
```

## 5️⃣ Polish the code
Expand Down
27 changes: 24 additions & 3 deletions src/components/ColorScheme/docs/DarkScheme.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import React from 'react';
import { Meta, StoryObj } from '@storybook/react';
import { DarkScheme, LightScheme } from '../EnforcedColorScheme';
import { Text } from '../../Text/Text';
import React, { useEffect } from 'react';
import { enforceSchemeOnElement } from '../../../utils';
import { Box } from '../../Box/Box';
import { Button } from '../../Button/Button';
import { Text } from '../../Text/Text';
import { DarkScheme, LightScheme } from '../EnforcedColorScheme';
import { InvertedColorScheme } from '../InvertedColorScheme';

const meta: Meta = {
Expand Down Expand Up @@ -58,3 +60,22 @@ export const InvertedColorSchemeWithButton: Story = {
</InvertedColorScheme>
)
};

export const ProgrammaticDarkSchemeWithButton: Story = {
args: {
children: <Button>The box around me is dark!</Button>,
py: 2
},
render: ({ children, ...props }) => {
useEffect(() => {
const boxElement = document.querySelector('#box-to-enforce-scheme');
if (boxElement) enforceSchemeOnElement('dark-scheme', boxElement);
}, []);

return (
<Box {...props} id="box-to-enforce-scheme" textAlign="center">
{children}
</Box>
);
}
};
25 changes: 23 additions & 2 deletions src/components/ColorScheme/docs/DarkScheme.storybook.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import { Meta, Story } from '@storybook/blocks';

import { Source } from '../../../docs/Source';
import { Box } from '../../Box/Box';
import * as DarkSchemeStories from './DarkScheme.stories';
import { CurrentScheme } from './CurrentScheme';
import * as DarkSchemeStories from './DarkScheme.stories';

<Meta of={DarkSchemeStories} />

Expand All @@ -12,7 +12,7 @@ import { CurrentScheme } from './CurrentScheme';
All components in Wave automatically adapts to the users preferred color scheme.

There are situations where you want to force a specific color scheme to a component, or a group of components.
Wave provides a few components to help you with this.
Wave provides a few options to help you with this.

## Invert Color Scheme

Expand Down Expand Up @@ -51,3 +51,24 @@ Demo:
## Props

All components accept [`Box` props](/docs/components-box--docs).

## Programmatically enforcing a Scheme

In case the above components don't fit your use case Wave offers an `enforceSchemeOnElement` utility as an escape hatch to enforce a color scheme for a passed HTML Element.

> The main use case for it is when you want to enforce a scheme for an element that you cannot access through JSX/HTML and need to do it thorugh JS.
<Story of={DarkSchemeStories.ProgrammaticDarkSchemeWithButton} />

```tsx
useEffect(() => {
const boxElement = document.querySelector('#box-to-enforce-scheme');
if (boxElement) enforceSchemeOnElement('dark-scheme', boxElement);
}, []);

return (
<Box {...props} id="box-to-enforce-scheme" textAlign="center">
{children}
</Box>
);
```
5 changes: 2 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
export * from './components';
export * from './essentials';
export * from './icons';
export * from './hooks';
export { get as themeGet } from './utils/themeGet';
export { getSemanticValue } from './utils/cssVariables';
export * from './icons';
export * from './utils';
2 changes: 2 additions & 0 deletions src/utils/enforceSchemeOnElement.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const enforceSchemeOnElement = (scheme: 'light-scheme' | 'dark-scheme', element: Element): void =>
element.classList.add('wave', scheme);
3 changes: 3 additions & 0 deletions src/utils/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export { getSemanticValue } from './cssVariables';
export { enforceSchemeOnElement } from './enforceSchemeOnElement';
export { get as themeGet } from './themeGet';

0 comments on commit 8734552

Please sign in to comment.