Skip to content

Commit

Permalink
feat: custom theme provider implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
Sergio committed Mar 13, 2020
1 parent 108336c commit 95c7085
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 8 deletions.
37 changes: 34 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,38 @@ addDecorator(withThemesProvider(themes));
configure(() => require('./stories'), module);
```

### Usage with Emotion
### How to use your own implementation of ThemeProvider

Thanks to @gillerg8 you can use this package 100% compatible with Emotion
> https://github.com/gillerg8/themeprovider-storybook
Thanks to @ckknight suggestion, you can easily use your own context for themeprovider.

> This is just an example of a custom theme provider, probably this is not a working, just for suggesting purposes.
```jsx
const ThemeContext: Context<Theme | void> = React.createContext();
const ThemeConsumer = ThemeContext.Consumer;

export default function SomeCustomImplementationOfThemeProvider(props: Props) {
const outerTheme = useContext(ThemeContext);
const themeContext = useMemo(() => mergeTheme(props.theme, outerTheme), [
props.theme,
outerTheme,
]);

if (!props.children) {
return null;
}

return <ThemeContext.Provider value={themeContext}>{props.children}</ThemeContext.Provider>;
}
```

On config.js file of Storybook, just pass a `CustomThemeProvider`
```jsx
import { SomeCustomImplementationOfThemeProvider } from "src/app/CustomThemeProvider.jsx"

addDecorator(
withThemesProvider(themes),
SomeCustomImplementationOfThemeProvider
);
```

`SomeCustomImplementationOfThemeProvider` must admit a `theme` as prop.
12 changes: 9 additions & 3 deletions src/ThemesProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { Theme } from "./types/Theme";

export interface ThemesProviderProps {
themes: List<Theme>;
CustomThemeProvider?: React.ComponentType<{ theme: Theme }>;
story?: any;
children: React.ReactChild;
}
Expand All @@ -15,7 +16,7 @@ interface ThemesProvider {
theme: Theme;
}

export const ThemesProvider: React.FunctionComponent<ThemesProviderProps> = ({ story, children, themes }) => {
export const ThemesProvider: React.FunctionComponent<ThemesProviderProps> = ({ story, children, themes, CustomThemeProvider }) => {
const [theme, setTheme] = React.useState(null);

React.useEffect(() => {
Expand All @@ -28,6 +29,11 @@ export const ThemesProvider: React.FunctionComponent<ThemesProviderProps> = ({ s
};
}, [themes, children]);

if (!theme && story) return <ThemeProvider theme={themes.first()}>{story()}</ThemeProvider>
return <ThemeProvider theme={theme}>{children}</ThemeProvider>
if (CustomThemeProvider) {
if (!theme && story) return (<CustomThemeProvider theme={themes.first()}>{story()}</CustomThemeProvider>);
return (<CustomThemeProvider theme={theme}>{children}</CustomThemeProvider>);
}

if (!theme && story) return (<ThemeProvider theme={themes.first()}>{story()}</ThemeProvider>);
return (<ThemeProvider theme={theme}>{children}</ThemeProvider>);
};
4 changes: 2 additions & 2 deletions src/withThemesProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import { ModalProvider } from "./components/Modal";
import { ThemesProvider } from "./ThemesProvider";
import { Theme } from "./types/Theme";

export const withThemesProvider = (themes: Theme[]) => (story: any): JSX.Element => {
export const withThemesProvider = (themes: Theme[], CustomThemeProvider?: React.ComponentType<{ theme: Theme }>) => (story: any): JSX.Element => {
return (
<ThemesProvider story={story} themes={List(themes)}>
<ThemesProvider CustomThemeProvider={CustomThemeProvider} story={story} themes={List(themes)}>
<ModalProvider>
<BackgroundHelper themes={List(themes)}>{story()}</BackgroundHelper>
</ModalProvider>
Expand Down

0 comments on commit 95c7085

Please sign in to comment.