Let Storybook stories fetch theme
This commit is contained in:
parent
33090b5cbd
commit
ce35c870d4
4 changed files with 59 additions and 33 deletions
7
.storybook/StorybookThemeContext.d.ts
vendored
Normal file
7
.storybook/StorybookThemeContext.d.ts
vendored
Normal 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>;
|
7
.storybook/StorybookThemeContext.js
Normal file
7
.storybook/StorybookThemeContext.js
Normal 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);
|
|
@ -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>
|
||||||
|
|
|
@ -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', () => {
|
||||||
|
|
Loading…
Reference in a new issue