Skip to content

Commit

Permalink
feat(Storybook): add toolbar menu for switching theme
Browse files Browse the repository at this point in the history
  • Loading branch information
pylafleur committed Jan 13, 2025
1 parent bfbfd3f commit c145568
Show file tree
Hide file tree
Showing 7 changed files with 150 additions and 137 deletions.
2 changes: 2 additions & 0 deletions packages/storybook/.storybook/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ const config: StorybookConfig = {
getAbsolutePath('@storybook/addon-actions'),
getAbsolutePath('@storybook/addon-controls'),
getAbsolutePath('@storybook/addon-links'),
getAbsolutePath('@storybook/addon-toolbars'),
getAbsolutePath('@storybook/addon-viewport'),
getAbsolutePath('@storybook/addon-webpack5-compiler-babel'),
],
webpackFinal: async (config) => ({
Expand Down
23 changes: 21 additions & 2 deletions packages/storybook/.storybook/preview.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,38 @@
import { DesignSystem, injectMainCss } from '@equisoft/design-elements-react';
import { Decorator, Preview } from '@storybook/react';
import { DocsContainer } from "@storybook/blocks";
import { themes } from './themes';

injectMainCss();

const decorators: Decorator[] = [
Story => (
<DesignSystem>
(Story, { globals }) => (
<DesignSystem themeCustomization={themes[globals.theme].customization}>
<Story />
</DesignSystem>
),
];

const preview: Preview = {
decorators,
globalTypes: {
theme: {
name: 'Theme',
description: 'Global theme for components',
toolbar: {
title: 'Theme',
icon: 'paintbrush',
items: Object.keys(themes).map((value: string) => ({
value,
title: themes[value].name,
})),
dynamicTitle: true,
},
},
},
initialGlobals: {
theme: 'equisoft',
},
parameters: {
controls: {
exclude: ['key', 'ref'],
Expand Down
31 changes: 31 additions & 0 deletions packages/storybook/.storybook/themes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { equisoftThemeCustomization, ThemeCustomization } from '@equisoft/design-elements-react';

export const themes: Record<string, { name: string, customization: ThemeCustomization }> = {
'equisoft': {
name: 'Equisoft Theme',
customization: equisoftThemeCustomization,
},
'festive': {
name: 'Festive Theme',
customization: {
ref: {
'color-brand-05': '#e9e0f9',
'color-brand-20': '#ad84ea',
'color-brand-50': '#710096',
'color-brand-70': '#36005a',
'color-brand-80': '#230139',
'color-accent-20': '#e9f9b2',
'color-accent-50': '#c3ef3e',
'color-accent-70': '#a7d414',
'color-alert-02': '#fdfcf6',
'color-alert-05': '#ffdaec',
'color-alert-20': '#ffb6da',
'color-alert-50': '#ff69b4',
'color-alert-70': '#cf0068',
},
alias: {
'text-heading-md-font-size:mobile': 'font-size-600',
},
},
},
};
2 changes: 2 additions & 0 deletions packages/storybook/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
"@storybook/addon-controls": "^8.1.2",
"@storybook/addon-docs": "^8.1.2",
"@storybook/addon-links": "^8.1.2",
"@storybook/addon-toolbars": "^8.4.7",
"@storybook/addon-viewport": "^8.4.7",
"@storybook/addon-webpack5-compiler-babel": "^3.0.3",
"@storybook/blocks": "^8.1.2",
"@storybook/manager-api": "^8.1.2",
Expand Down
8 changes: 6 additions & 2 deletions packages/storybook/stories/1-getting-started.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,12 @@ export const App: VoidFunctionComponent = () => (

## Theming

For most cases, you won't need to provide a theme, as the DesignSystem uses Equisoft's theme by default. However, it's
possible to override the theme, or parts of the theme. For more details, take a look at the [Theme definition](https://github.com/kronostechnologies/design-elements/blob/master/packages/react/src/themes/theme.ts).
For most cases, you won't need to provide a theme, as the DesignSystem uses Equisoft's color scheme by default. However,
it's possible to override parts of the theme by providing a `themeCustomization` object to the `DesignSystem` component.
For more details, take a look at the [type definitions](https://github.com/kronostechnologies/design-elements/blob/master/packages/react/src/themes/theme.ts)
and the list of available design tokens.

You can switch the theme throughout the storybook using the Theme menu in the toolbar at the top.

<Canvas of={GettingStartedStories.Theming} />

Expand Down
183 changes: 50 additions & 133 deletions packages/storybook/stories/1-getting-started.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,10 @@ import {
Button,
DesignSystem,
SectionalBanner,
DropdownList,
DropdownListOption,
ThemeCustomization,
equisoftThemeCustomization,
useTheme,
} from '@equisoft/design-elements-react';
import { Meta, StoryObj } from '@storybook/react';
import { useState } from 'react';
import { themes } from '../.storybook/themes';

const meta: Meta = {
title: 'Getting Started',
Expand All @@ -20,142 +16,63 @@ export default meta;

type Story = StoryObj<typeof DesignSystem>;

const flowerThemeCustomization: ThemeCustomization = {
ref: {
'color-brand-05': '#e9e0f9',
'color-brand-20': '#ad84ea',
'color-brand-50': '#710096',
'color-brand-70': '#36005a',
'color-brand-80': '#230139',
'color-accent-20': '#f9f5b2',
'color-accent-50': '#efbd3e',
'color-accent-70': '#d4a714',
'color-white': '#FFFFFF',
'color-black': '#000000',
'color-neutral-02': '#FAFAFA',
'color-neutral-05': '#F1F2F2',
'color-neutral-15': '#DBDEE1',
'color-neutral-30': '#B7BBC2',
'color-neutral-50': '#878F9A',
'color-neutral-65': '#60666E',
'color-neutral-90': '#1B1C1E',
'color-alert-02': '#fdfcf6',
'color-alert-05': '#faf6e9',
'color-alert-20': '#f9e399',
'color-alert-50': '#cd9d23',
'color-alert-70': '#7b6315',
'color-informative-02': '#F9F7FB',
'color-informative-05': '#E0F0F9',
'color-informative-20': '#84C6EA',
'color-informative-50': '#006296',
'color-informative-70': '#003A5A',
'color-success-02': '#F6FCF8',
'color-success-05': '#E1F7EA',
'color-success-20': '#8ADDA9',
'color-success-50': '#008533',
'color-success-70': '#004F1E',
'color-warning-02': '#FFFBF5',
'color-warning-05': '#FFF7E5',
'color-warning-20': '#FFDD99',
'color-warning-50': '#F5A200',
'color-warning-70': '#9E6900',
'color-warning-80': '#664400',
'color-discovery-02': '#F9F7FB',
'color-discovery-05': '#EFEAF6',
'color-discovery-20': '#CFC1E3',
'color-discovery-50': '#602FA0',
'color-discovery-70': '#3A1C60',
},
};

export const Theming: Story = {
render() {
const [themeCustomization, setThemeCustomization] = useState(equisoftThemeCustomization);
const [label, setLabel] = useState('Equisoft Theme');

function setCustomTheme(newSelectedTheme: DropdownListOption): void {
setLabel(newSelectedTheme.label);
switch (newSelectedTheme.value) {
case 'flower':
setThemeCustomization(flowerThemeCustomization);
break;
case 'equisoft':
default:
setThemeCustomization(equisoftThemeCustomization);
break;
}
}

render(_args, { globals }) {
return (
<DesignSystem themeCustomization={themeCustomization}>
<div>
<div style={{ display: 'box', alignItems: 'center', gap: '2rem' }}>
<h3>{label}</h3>
<div style={{ width: '200px' }}>
<DropdownList
onChange={(option: DropdownListOption) => setCustomTheme(option)}
defaultValue="equisoft"
options={[
{
label: 'Equisoft Theme',
value: 'equisoft',
},
{
label: 'Flower Theme',
value: 'flower',
},
]}
/>
</div>
<>
<div style={{ display: 'box', alignItems: 'center', gap: '2rem' }}>
<h3 style={{
fontSize: useTheme().alias['text-heading-md-font-size'],
marginTop: '0',
}}
>
{themes[globals.theme].name}
</h3>
</div>
<div style={{ display: 'table-row', alignItems: 'center' }}>
<div style={{ padding: '1rem' }}>
<Button label="Primary" buttonType="primary" />
<Button label="Secondary" buttonType="secondary" />
<Button label="Tertiary" buttonType="tertiary" />
<Button label="Destructive Primary" buttonType="destructive-primary" />
<Button label="Destructive Secondary" buttonType="destructive-secondary" />
</div>
<div style={{ padding: '1rem' }}>
<Button label="Primary" buttonType="primary" disabled />
<Button label="Secondary" buttonType="secondary" disabled />
<Button label="Tertiary" buttonType="tertiary" disabled />
<Button label="Destructive Primary" buttonType="destructive-primary" disabled />
<Button label="Destructive Secondary" buttonType="destructive-secondary" disabled />
</div>
<div style={{
display: 'table-row', alignItems: 'center',
backgroundColor: useTheme().component['global-header-background-color'],
padding: '1rem',
}}
>
<div style={{ padding: '1rem' }}>
<Button label="Primary" buttonType="primary" />
<Button label="Secondary" buttonType="secondary" />
<Button label="Tertiary" buttonType="tertiary" />
<Button label="Destructive Primary" buttonType="destructive-primary" />
<Button label="Destructive Secondary" buttonType="destructive-secondary" />
</div>
<div style={{ padding: '1rem' }}>
<Button label="Primary" buttonType="primary" disabled />
<Button label="Secondary" buttonType="secondary" disabled />
<Button label="Tertiary" buttonType="tertiary" disabled />
<Button label="Destructive Primary" buttonType="destructive-primary" disabled />
<Button label="Destructive Secondary" buttonType="destructive-secondary" disabled />
</div>
<div style={{
backgroundColor: useTheme().component['global-header-background-color'],
padding: '1rem',
}}
>
<Button label="Primary" buttonType="primary" inverted />
<Button label="Secondary" buttonType="secondary" inverted />
<Button label="Tertiary" buttonType="tertiary" inverted />
<Button label="Destructive Primary" buttonType="destructive-primary" inverted />
<Button label="Destructive Secondary" buttonType="destructive-secondary" inverted />
</div>
<div style={{
backgroundColor: useTheme().component['global-header-background-color'],
padding: '1rem',
}}
>
<Button label="Primary" buttonType="primary" inverted disabled />
<Button label="Secondary" buttonType="secondary" inverted disabled />
<Button label="Tertiary" buttonType="tertiary" inverted disabled />
<Button label="Destructive Primary" buttonType="destructive-primary" inverted disabled />
<Button
label="Destructive Secondary"
buttonType="destructive-secondary"
inverted
disabled
/>
</div>
<Button label="Primary" buttonType="primary" inverted />
<Button label="Secondary" buttonType="secondary" inverted />
<Button label="Tertiary" buttonType="tertiary" inverted />
<Button label="Destructive Primary" buttonType="destructive-primary" inverted />
<Button label="Destructive Secondary" buttonType="destructive-secondary" inverted />
</div>
<div style={{
backgroundColor: useTheme().component['global-header-background-color'],
padding: '1rem',
}}
>
<Button label="Primary" buttonType="primary" inverted disabled />
<Button label="Secondary" buttonType="secondary" inverted disabled />
<Button label="Tertiary" buttonType="tertiary" inverted disabled />
<Button label="Destructive Primary" buttonType="destructive-primary" inverted disabled />
<Button
label="Destructive Secondary"
buttonType="destructive-secondary"
inverted
disabled
/>
</div>
</div>
</DesignSystem>
</>
);
},
};
Expand Down
38 changes: 38 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1774,6 +1774,8 @@ __metadata:
"@storybook/addon-controls": "npm:^8.1.2"
"@storybook/addon-docs": "npm:^8.1.2"
"@storybook/addon-links": "npm:^8.1.2"
"@storybook/addon-toolbars": "npm:^8.4.7"
"@storybook/addon-viewport": "npm:^8.4.7"
"@storybook/addon-webpack5-compiler-babel": "npm:^3.0.3"
"@storybook/blocks": "npm:^8.1.2"
"@storybook/manager-api": "npm:^8.1.2"
Expand Down Expand Up @@ -3074,6 +3076,26 @@ __metadata:
languageName: node
linkType: hard

"@storybook/addon-toolbars@npm:^8.4.7":
version: 8.4.7
resolution: "@storybook/addon-toolbars@npm:8.4.7"
peerDependencies:
storybook: ^8.4.7
checksum: 10c0/1c315d5ad07291f35ad780ef69fbd6570a582c008ab911cf14bff84061546b9ea1373d1127213844652d73a47c3011d28c1ad08d465fc120969c133dabfe7638
languageName: node
linkType: hard

"@storybook/addon-viewport@npm:^8.4.7":
version: 8.4.7
resolution: "@storybook/addon-viewport@npm:8.4.7"
dependencies:
memoizerific: "npm:^1.11.3"
peerDependencies:
storybook: ^8.4.7
checksum: 10c0/4dec3b59be1f3b99d3c9eaab695a7e346d975b772f6691f8286005d78a13a204c5680c6c8733ae83060c7639b56efed9f3580cee7413834ac6595b56345183ef
languageName: node
linkType: hard

"@storybook/addon-webpack5-compiler-babel@npm:^3.0.3":
version: 3.0.5
resolution: "@storybook/addon-webpack5-compiler-babel@npm:3.0.5"
Expand Down Expand Up @@ -10554,6 +10576,13 @@ __metadata:
languageName: node
linkType: hard

"map-or-similar@npm:^1.5.0":
version: 1.5.0
resolution: "map-or-similar@npm:1.5.0"
checksum: 10c0/33c6ccfdc272992e33e4e99a69541a3e7faed9de3ac5bc732feb2500a9ee71d3f9d098980a70b7746e7eeb7f859ff7dfb8aa9b5ecc4e34170a32ab78cfb18def
languageName: node
linkType: hard

"math-intrinsics@npm:^1.1.0":
version: 1.1.0
resolution: "math-intrinsics@npm:1.1.0"
Expand Down Expand Up @@ -10624,6 +10653,15 @@ __metadata:
languageName: node
linkType: hard

"memoizerific@npm:^1.11.3":
version: 1.11.3
resolution: "memoizerific@npm:1.11.3"
dependencies:
map-or-similar: "npm:^1.5.0"
checksum: 10c0/661bf69b7afbfad57f0208f0c63324f4c96087b480708115b78ee3f0237d86c7f91347f6db31528740b2776c2e34c709bcb034e1e910edee2270c9603a0a469e
languageName: node
linkType: hard

"meow@npm:^13.0.0, meow@npm:^13.2.0":
version: 13.2.0
resolution: "meow@npm:13.2.0"
Expand Down

0 comments on commit c145568

Please sign in to comment.