generated from morewings/react-library-template
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
docs(storybook): add theme playground
fix #35
- Loading branch information
Showing
17 changed files
with
695 additions
and
226 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,25 @@ | ||
import {addons} from '@storybook/manager-api'; | ||
import {addons, types} from '@storybook/manager-api'; | ||
|
||
import {TOOL_ID, PANEL_ID} from '../src/env/theme-playground/constants'; | ||
import {ThemeSwitcherTool} from '../src/env/theme-playground/ThemeSwitcherTool'; | ||
import {Panel} from '../src/env/theme-playground/PlaygroundPanel'; | ||
import kovalTheme from './kovalTheme'; | ||
|
||
addons.setConfig({ | ||
theme: kovalTheme, | ||
}); | ||
|
||
addons.add(TOOL_ID, { | ||
type: types.TOOL, | ||
title: 'Theme provider', | ||
match: ({viewMode}) => !!(viewMode && viewMode.match(/^(story|docs)$/)), | ||
render: ThemeSwitcherTool, | ||
}); | ||
|
||
// Register the panel | ||
addons.add(PANEL_ID, { | ||
type: types.PANEL, | ||
title: 'Theme playground', | ||
match: ({viewMode}) => viewMode === 'story', | ||
render: Panel, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import type {FC} from 'react'; | ||
// @ts-expect-error TODO: maybe fix later | ||
// eslint-disable-next-line @typescript-eslint/no-unused-vars | ||
import React, {useState, useEffect, useCallback} from 'react'; | ||
import {styled} from '@storybook/theming'; | ||
import {ColorControl} from '@storybook/blocks'; | ||
|
||
export type Props = { | ||
onChange: (name: string, value?: string) => void; | ||
value?: string; | ||
name: string; | ||
}; | ||
|
||
const Wrapper = styled.div` | ||
display: flex; | ||
flex-direction: row; | ||
text-align: left; | ||
flex-shrink: 1; | ||
align-items: center; | ||
gap: 12px; | ||
& input { | ||
width: 210px; | ||
} | ||
`; | ||
|
||
const Label = styled.label` | ||
font-weight: bold; | ||
font-size: 14px; | ||
`; | ||
|
||
export const Control: FC<Props> = ({onChange, value: valueProp, name}) => { | ||
const [value, setValue] = useState<string | undefined>(valueProp); | ||
useEffect(() => { | ||
setValue(valueProp); | ||
}, [valueProp]); | ||
const handleChange = useCallback( | ||
(value?: string) => { | ||
setValue(value); | ||
onChange(name, value); | ||
}, | ||
[name, onChange] | ||
); | ||
return ( | ||
<Wrapper> | ||
<Label htmlFor="foo" style={{color: value}}> | ||
{name.replace('color', '')}: | ||
</Label> | ||
<ColorControl value={value} name={name} onChange={handleChange} /> | ||
</Wrapper> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import type {FC} from 'react'; | ||
// @ts-expect-error TODO: maybe fix later | ||
// eslint-disable-next-line @typescript-eslint/no-unused-vars | ||
import React, {useCallback, useEffect} from 'react'; | ||
import {useChannel} from '@storybook/manager-api'; | ||
import {AddonPanel, ActionBar} from '@storybook/components'; | ||
import {useAddonState} from '@storybook/manager-api'; | ||
|
||
import {useGlobalThemesManager} from './../useGlobalThemes.ts'; | ||
import {EVENTS} from '../constants'; | ||
import {Playground} from './Playground'; | ||
import {ADDON_ID} from '../constants'; | ||
|
||
type PanelProps = { | ||
active: boolean; | ||
}; | ||
|
||
export const Panel: FC<PanelProps> = props => { | ||
const [theme, setTheme] = useAddonState(ADDON_ID, {}); | ||
|
||
const {themes, selectedTheme} = useGlobalThemesManager(); | ||
|
||
const vanillaTheme = themes?.find( | ||
({name}) => Boolean(selectedTheme) && name === selectedTheme | ||
)?.themeObject; | ||
|
||
const handleThemeReset = useCallback(() => { | ||
setTheme({}); | ||
}, [setTheme]); | ||
|
||
const emit = useChannel({[EVENTS.RESET_THEME]: handleThemeReset}); | ||
|
||
useEffect(() => { | ||
emit(EVENTS.SET_THEME, theme); | ||
}, [emit, theme]); | ||
|
||
const handleColorChange = useCallback( | ||
(change: Record<string, string>) => { | ||
change && setTheme({...theme, ...change}); | ||
}, | ||
[setTheme, theme] | ||
); | ||
|
||
const handleBackgroundInvert = useCallback((nextBgColors: object) => { | ||
console.log('invert', nextBgColors); | ||
}, []); | ||
|
||
const handleReset = useCallback(() => { | ||
emit(EVENTS.RESET_THEME); | ||
}, [emit]); | ||
|
||
return ( | ||
<AddonPanel {...props}> | ||
<Playground | ||
vanillaTheme={vanillaTheme} | ||
theme={theme} | ||
onColorChange={handleColorChange} | ||
onBackgroundInvert={handleBackgroundInvert} | ||
/> | ||
<ActionBar | ||
actionItems={[ | ||
// {title: 'Save theme', onClick: () => {}}, | ||
{title: 'Reset theme', onClick: handleReset}, | ||
]}></ActionBar> | ||
</AddonPanel> | ||
); | ||
}; |
140 changes: 140 additions & 0 deletions
140
src/env/theme-playground/PlaygroundPanel/Playground.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
import type {FC} from 'react'; | ||
// @ts-expect-error TODO: maybe fix later | ||
// eslint-disable-next-line @typescript-eslint/no-unused-vars | ||
import React, {useCallback} from 'react'; | ||
import {styled} from '@storybook/theming'; | ||
// import {BooleanControl} from '@storybook/blocks'; | ||
|
||
import type {PublicThemeType} from './../../../lib/Theme'; | ||
import {ColorsList} from '../types'; | ||
import {Control} from './Control'; | ||
|
||
type PanelContentProps = { | ||
onColorChange: (arg0: Record<string, string>) => void; | ||
onBackgroundInvert: (bgColors: object) => void; | ||
vanillaTheme?: PublicThemeType; | ||
theme: Partial<PublicThemeType>; | ||
}; | ||
|
||
const Wrapper = styled.div` | ||
padding: 12px; | ||
`; | ||
|
||
const FieldSet = styled.fieldset` | ||
display: flex; | ||
flex-direction: row; | ||
gap: 36px; | ||
max-width: 100%; | ||
align-items: center; | ||
flex-wrap: wrap; | ||
margin-bottom: 24px; | ||
border-color: hsla(203, 50%, 30%, 0.15); | ||
`; | ||
|
||
const Legend = styled.legend` | ||
font-size: 16px; | ||
color: #73828c; | ||
font-weight: bolder; | ||
`; | ||
|
||
// const BooleanWrapper = styled.div` | ||
// display: flex; | ||
// flex-direction: row; | ||
// gap: 12px; | ||
// align-items: center; | ||
// & > span { | ||
// font-weight: bold; | ||
// } | ||
// & > label { | ||
// margin-bottom: 0; | ||
// } | ||
// `; | ||
|
||
// type BackgroundColors = { | ||
// background000?: string; | ||
// background100?: string; | ||
// background200?: string; | ||
// background300?: string; | ||
// background400?: string; | ||
// background500?: string; | ||
// background600?: string; | ||
// }; | ||
// | ||
// const getBackground = (theme: BackgroundColors & unknown): BackgroundColors => { | ||
// return { | ||
// background000: theme['background000'], | ||
// background100: theme['background100'], | ||
// background200: theme['background200'], | ||
// background300: theme['background300'], | ||
// background400: theme['background400'], | ||
// background500: theme['background500'], | ||
// background600: theme['background600'], | ||
// }; | ||
// }; | ||
// | ||
// const getInvertedBackground = (theme: BackgroundColors & unknown): BackgroundColors => { | ||
// return { | ||
// background000: theme['background600'], | ||
// background100: theme['background500'], | ||
// background200: theme['background400'], | ||
// background300: theme['background300'], | ||
// background400: theme['background200'], | ||
// background500: theme['background100'], | ||
// background600: theme['background000'], | ||
// }; | ||
// }; | ||
|
||
export const Playground: FC<PanelContentProps> = ({onColorChange, vanillaTheme, theme}) => { | ||
// const [inverted, setInverted] = useState<undefined | boolean>(false); | ||
|
||
const handleChange = useCallback( | ||
(name?: string, value?: string) => { | ||
name && value && onColorChange({[name]: value}); | ||
}, | ||
[onColorChange] | ||
); | ||
|
||
// TODO: mode logic to Panel. Fix state problem | ||
// const handleInvert = useCallback( | ||
// (value?: boolean) => { | ||
// setInverted(value); | ||
// if (vanillaTheme) { | ||
// const nextTheme = value | ||
// ? getInvertedBackground(vanillaTheme) | ||
// : getBackground(vanillaTheme); | ||
// onColorChange(nextTheme); | ||
// } | ||
// }, | ||
// [onColorChange, setInverted, vanillaTheme] | ||
// ); | ||
|
||
return ( | ||
<Wrapper> | ||
<FieldSet> | ||
<Legend>Brand colors</Legend> | ||
{Object.values(ColorsList).map(colorToken => { | ||
return ( | ||
<Control | ||
key={colorToken} | ||
value={{...vanillaTheme, ...theme}[colorToken]} | ||
name={colorToken} | ||
onChange={handleChange} | ||
/> | ||
); | ||
})} | ||
</FieldSet> | ||
<FieldSet> | ||
<Legend>Other colors</Legend> | ||
{/*<BooleanWrapper>*/} | ||
{/* <span>Invert background colors:</span>*/} | ||
{/* <BooleanControl value={inverted} onChange={handleInvert} name="Hello" />*/} | ||
{/*</BooleanWrapper>*/} | ||
<Control | ||
value={{...vanillaTheme, ...theme}.textColor} | ||
name="Text" | ||
onChange={handleChange} | ||
/> | ||
</FieldSet> | ||
</Wrapper> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export {Panel} from './Panel'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import type {FC} from 'react'; | ||
import {styled} from '@storybook/theming'; | ||
|
||
const gradient = | ||
'linear-gradient(-45deg, transparent, transparent 45%, pink 45%, pink 55%, transparent 55%, transparent 100%)'; | ||
|
||
export const Color: FC<{colorName?: string}> = ({colorName = gradient}) => { | ||
return <ColorDiv style={{background: colorName}} />; | ||
}; | ||
|
||
export const ColorDiv = styled.div({ | ||
width: '16px', | ||
height: '16px', | ||
borderRadius: '8px', | ||
border: '1px solid lightgray', | ||
}); |
Oops, something went wrong.