Let Storybook stories fetch theme

This commit is contained in:
Evan Hahn 2021-10-27 14:49:58 -05:00 committed by GitHub
parent 33090b5cbd
commit ce35c870d4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 59 additions and 33 deletions

7
.storybook/StorybookThemeContext.d.ts vendored Normal file
View file

@ -0,0 +1,7 @@
// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import type { Context } from 'react';
import type { ThemeType } from '../ts/types/Util';
export const StorybookThemeContext: Context<ThemeType>;

View file

@ -0,0 +1,7 @@
// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import { createContext } from 'react';
import { ThemeType } from '../ts/types/Util';
export const StorybookThemeContext = createContext(ThemeType.light);

View file

@ -8,7 +8,9 @@ import classnames from 'classnames';
import * as styles from './styles.scss'; import * as styles from './styles.scss';
import messages from '../_locales/en/messages.json'; import messages from '../_locales/en/messages.json';
import { I18n } from '../sticker-creator/util/i18n'; import { I18n } from '../sticker-creator/util/i18n';
import { ThemeType } from '../ts/types/Util';
import { ClassyProvider } from '../ts/components/PopperRootContext'; import { ClassyProvider } from '../ts/components/PopperRootContext';
import { StorybookThemeContext } from './StorybookThemeContext';
const optionsConfig = { const optionsConfig = {
display: 'inline-radio', display: 'inline-radio',
@ -31,6 +33,8 @@ const makeThemeKnob = pane =>
) )
); );
const parseThemeString = str => (str === '' ? ThemeType.light : ThemeType.dark);
const makeModeKnob = pane => const makeModeKnob = pane =>
persistKnob(`${pane}-pane-mode`)(localValue => persistKnob(`${pane}-pane-mode`)(localValue =>
optionsKnob( optionsKnob(
@ -46,19 +50,21 @@ addDecorator(withKnobs({ escapeHTML: false }));
addDecorator((storyFn /* , context */) => { addDecorator((storyFn /* , context */) => {
const contents = storyFn(); const contents = storyFn();
const firstPaneTheme = makeThemeKnob('First'); const firstPaneThemeString = makeThemeKnob('First');
const firstPaneTheme = parseThemeString(firstPaneThemeString);
const firstPaneMode = makeModeKnob('First'); const firstPaneMode = makeModeKnob('First');
const secondPane = persistKnob('second-pane-active')(localValue => const secondPane = persistKnob('second-pane-active')(localValue =>
boolean('Second Pane Active', localValue !== 'false', 'Second Pane') boolean('Second Pane Active', localValue !== 'false', 'Second Pane')
); );
const secondPaneTheme = makeThemeKnob('Second'); const secondPaneThemeString = makeThemeKnob('Second');
const secondPaneTheme = parseThemeString(secondPaneThemeString);
const secondPaneMode = makeModeKnob('Second'); const secondPaneMode = makeModeKnob('Second');
// Adding it to the body as well so that we can cover modals and other // Adding it to the body as well so that we can cover modals and other
// components that are rendered outside of this decorator container // components that are rendered outside of this decorator container
if (firstPaneTheme === '') { if (firstPaneThemeString === '') {
document.body.classList.remove('dark-theme'); document.body.classList.remove('dark-theme');
} else { } else {
document.body.classList.add('dark-theme'); document.body.classList.add('dark-theme');
@ -76,18 +82,30 @@ addDecorator((storyFn /* , context */) => {
return ( return (
<div className={styles.container}> <div className={styles.container}>
<ClassyProvider themes={['dark']}> <StorybookThemeContext.Provider value={firstPaneTheme}>
<div <ClassyProvider themes={['dark']}>
className={classnames(styles.panel, firstPaneTheme, firstPaneMode)} <div
> className={classnames(
{contents} styles.panel,
</div> firstPaneThemeString,
</ClassyProvider> firstPaneMode
)}
>
{contents}
</div>
</ClassyProvider>
</StorybookThemeContext.Provider>
{secondPane ? ( {secondPane ? (
<div <div
className={classnames(styles.panel, secondPaneTheme, secondPaneMode)} className={classnames(
styles.panel,
secondPaneThemeString,
secondPaneMode
)}
> >
{contents} <StorybookThemeContext.Provider value={secondPaneTheme}>
{contents}
</StorybookThemeContext.Provider>
</div> </div>
) : null} ) : null}
</div> </div>

View file

@ -1,4 +1,4 @@
// Copyright 2020 Signal Messenger, LLC // Copyright 2020-2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only // SPDX-License-Identifier: AGPL-3.0-only
import * as React from 'react'; import * as React from 'react';
@ -11,9 +11,10 @@ import { pngUrl } from '../../storybook/Fixtures';
import type { Props } from './Image'; import type { Props } from './Image';
import { Image } from './Image'; import { Image } from './Image';
import { IMAGE_PNG } from '../../types/MIME'; import { IMAGE_PNG } from '../../types/MIME';
import { ThemeType } from '../../types/Util'; import type { ThemeType } from '../../types/Util';
import { setupI18n } from '../../util/setupI18n'; import { setupI18n } from '../../util/setupI18n';
import enMessages from '../../../_locales/en/messages.json'; import enMessages from '../../../_locales/en/messages.json';
import { StorybookThemeContext } from '../../../.storybook/StorybookThemeContext';
import { fakeAttachment } from '../../test-both/helpers/fakeAttachment'; import { fakeAttachment } from '../../test-both/helpers/fakeAttachment';
@ -63,7 +64,7 @@ const createProps = (overrideProps: Partial<Props> = {}): Props => ({
softCorners: boolean('softCorners', overrideProps.softCorners || false), softCorners: boolean('softCorners', overrideProps.softCorners || false),
tabIndex: number('tabIndex', overrideProps.tabIndex || 0), tabIndex: number('tabIndex', overrideProps.tabIndex || 0),
theme: text('theme', overrideProps.theme || 'light') as ThemeType, theme: text('theme', overrideProps.theme || 'light') as ThemeType,
url: text('url', overrideProps.url || pngUrl), url: text('url', 'url' in overrideProps ? overrideProps.url || null : pngUrl),
width: number('width', overrideProps.width || 100), width: number('width', overrideProps.width || 100),
}); });
@ -196,26 +197,19 @@ story.add('Blurhash', () => {
return <Image {...props} />; return <Image {...props} />;
}); });
story.add('undefined blurHash (light)', () => { story.add('undefined blurHash', () => {
const defaultProps = createProps(); const Wrapper = () => {
const props = { const theme = React.useContext(StorybookThemeContext);
...defaultProps, const props = createProps({
blurHash: undefined, blurHash: undefined,
theme: ThemeType.light, theme,
url: undefined,
});
return <Image {...props} />;
}; };
return <Image {...props} />; return <Wrapper />;
});
story.add('undefined blurHash (dark)', () => {
const defaultProps = createProps();
const props = {
...defaultProps,
blurHash: undefined,
theme: ThemeType.dark,
};
return <Image {...props} />;
}); });
story.add('Missing Image', () => { story.add('Missing Image', () => {