Skip to content

Commit

Permalink
Merge pull request #205 from storybookjs/charles/sb-1508-recipes-brok…
Browse files Browse the repository at this point in the history
…en-images

Fix static build + broken images on recipes
  • Loading branch information
cdedreuille authored Jul 17, 2024
2 parents e93bd2a + ab24089 commit 3778ea5
Show file tree
Hide file tree
Showing 9 changed files with 53 additions and 22 deletions.
6 changes: 4 additions & 2 deletions apps/frontpage/app/recipes/[...name]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,11 @@ interface RecipeDetailsProps {

export async function generateStaticParams() {
const recipes = (await fetchRecipesData()) || [];
return recipes.map((name) => ({
params: { name },
const listOfNames = recipes.map((recipe) => ({
name: [...recipe.split('/')],
}));

return listOfNames;
}

export default async function RecipeDetails({ params }: RecipeDetailsProps) {
Expand Down
65 changes: 45 additions & 20 deletions apps/frontpage/content/recipes/@mui/material.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,21 @@ npx storybook@latest add @storybook/addon-themes

<details>
<summary>Did the configuration script fail?</summary>
<p>Under the hood, this runs <code>npx @storybook/auto-config themes</code>, which should read your project and try to configure your Storybook with the correct decorator. If running that command directly does not solve your problem, please file a bug on the <a href="https://github.com/storybookjs/auto-config/issues/new?assignees=&labels=bug&projects=&template=bug_report.md&title=%5BBug%5D" target="_blank">@storybook/auto-config</a> repository so that we can further improve it. To manually add this addon, install it, and then add it to the addons array in your <code>.storybook/main.ts</code>.</p>
<p>
Under the hood, this runs <code>npx @storybook/auto-config themes</code>,
which should read your project and try to configure your Storybook with the
correct decorator. If running that command directly does not solve your
problem, please file a bug on the{' '}
<a
href="https://github.com/storybookjs/auto-config/issues/new?assignees=&labels=bug&projects=&template=bug_report.md&title=%5BBug%5D"
target="_blank"
>
@storybook/auto-config
</a>{' '}
repository so that we can further improve it. To manually add this addon,
install it, and then add it to the addons array in your{' '}
<code>.storybook/main.ts</code>.
</p>
</details>

### 2. Bundle fonts and icons for better perf
Expand Down Expand Up @@ -54,7 +68,6 @@ import '@fontsource/material-icons';

Inside of `.storybook/preview.js`, import `<CssBaseline />`, `<ThemeProvider />`, and your theme(s), then apply them to your stories with the [`withThemeFromJSXProvider`](https://github.com/storybookjs/storybook/blob/next/code/addons/themes/docs/api.md#withthemefromjsxprovider) decorator by adding it to the `decorators` array.


```js
// .storybook/preview.js
import { CssBaseline, ThemeProvider } from '@mui/material';
Expand All @@ -65,14 +78,15 @@ import { lightTheme, darkTheme } from '../src/themes.js';

export const decorators = [
withThemeFromJSXProvider({
themes: {
light: lightTheme,
dark: darkTheme,
},
defaultTheme: 'light',
Provider: ThemeProvider,
GlobalStyles: CssBaseline,
})];
themes: {
light: lightTheme,
dark: darkTheme,
},
defaultTheme: 'light',
Provider: ThemeProvider,
GlobalStyles: CssBaseline,
}),
];
```

<Callout variant="neutral" icon="ℹ️">
Expand All @@ -81,14 +95,13 @@ When you provide more than one theme, a toolbar menu will appear in the Storyboo

</Callout>


## 4. Use Material UI prop types for better controls and docs

Storybook controls give you graphical controls to manipulate a component’s props. They’re handy for finding edge cases of a component and prototyping in the browser.

Usually, you have to manually configure controls. But if you’re using Typescript, you can reuse Material UI’s component prop types to auto-generate story controls. As a bonus, this will also automatically populate the prop table in your documentation tab.

![Changing the button components props using Storybook controls](https://storybookblog.ghost.io/content/images/2022/10/2022-10-04-15.48.29.gif)
![Changing the button components props using Storybook controls](/recipes-assets/mui-1.gif)

Let’s take the following Button component for example.

Expand All @@ -107,7 +120,7 @@ export const Button = ({ label, ...rest }: ButtonProps) => <MuiButton {...rest}>

Here I’m using the label prop as the `MuiButton`’s child and passing all other props through. However, when we render this into Storybook, our controls panel only lets us change the label prop that we declared ourselves.

![The button story with only a label prop control](https://lh5.googleusercontent.com/ytI83Pvj6fPPl_OipK-4sF3rz_XMS4x6m6uSwkAI4nJ76Pqph8FOk9mb3hRNDCoV0xXLHX4pnXXvpq5EH1ysTnmXj61tdN94fVm1yjgMP58ow0QLWWL4_ouZIJcZ4LhKxyAZ8kKDybhOiZZfyAFeA9JqJpE51GzKgnoE8J0ByTYQ5p6ViKgw3J01Aw)
![The button story with only a label prop control](/recipes-assets/mui-2.gif)

This is because Storybook only adds props to the controls table that are explicitly declared in the component’s prop types or in the Story Args. Let’s update Storybook’s Docgen configuration to bring Material UI‘s Button props into the controls table as well.

Expand All @@ -132,7 +145,9 @@ module.exports = {
shouldRemoveUndefinedFromOptional: true,
// Filter out third-party props from node_modules except @mui packages
propFilter: (prop) =>
prop.parent ? !/node_modules\/(?!@mui)/.test(prop.parent.fileName) : true,
prop.parent
? !/node_modules\/(?!@mui)/.test(prop.parent.fileName)
: true,
},
},
};
Expand Down Expand Up @@ -161,18 +176,23 @@ Lastly, update the `ButtonProps` type to extend from Material UI’s Button prop
// button.component.tsx

import React from 'react';
import { Button as MuiButton, ButtonProps as MuiButtonProps } from '@mui/material';
import {
Button as MuiButton,
ButtonProps as MuiButtonProps,
} from '@mui/material';

export interface ButtonProps extends MuiButtonProps {
label: string;
}

export const Button = ({ label, ...rest }: ButtonProps) => <MuiButton {...rest}>{label}</MuiButton>;
export const Button = ({ label, ...rest }: ButtonProps) => (
<MuiButton {...rest}>{label}</MuiButton>
);
```

Restart your Storybook server so that these config changes take effect. You should now see that Button has controls for all of `MuiButton`'s props as well.

![The button story with all 27 prop controls from the MUI button props](https://lh3.googleusercontent.com/Km5jyCjJw_qhnmgQvlrIELxixgqwNN4FqCGbY1sjDBDI49owJg1xgwwoPBp9yRuumGzP9tlBXtOVOxqwnyLVNano2TzgV8zjXzbc7LtpE1PuaaY5GXVzRmAUP5W7t24KmNfH8HU8lB7VHpV14UTvUP9H6n1faDoJ9xfpAL4lx8-Yqgkgb9f-FKhkoQ)
![The button story with all 27 prop controls from the MUI button props](/recipes-assets/mui-2.gif)

### Choose which controls are visible

Expand All @@ -182,7 +202,10 @@ Our button now has **27 props**, which is perhaps a little much for your use cas
// button.component.tsx

import React from 'react';
import { Button as MuiButton, ButtonProps as MuiButtonProps } from '@mui/material';
import {
Button as MuiButton,
ButtonProps as MuiButtonProps,
} from '@mui/material';

// Only include variant, size, and color
type ButtonBaseProps = Pick<MuiButtonProps, 'variant' | 'size' | 'color'>;
Expand All @@ -194,11 +217,13 @@ export interface ButtonProps extends ButtonBaseProps {
label: string;
}

export const Button = ({ label, ...rest }: ButtonProps) => <MuiButton {...rest}>{label}</MuiButton>;
export const Button = ({ label, ...rest }: ButtonProps) => (
<MuiButton {...rest}>{label}</MuiButton>
);
```

And now our Button will only take the variant, size, and color props from `MuiButton`.

![The button story with only the controls specified](https://lh3.googleusercontent.com/lqYwmkGTpx1aiKkPILYcsPs5WChsgI8PLO45Dba6LXk1GeKsTJhy_5F7BWIydAOinZ9nyxOeFB9OjUE3T_lEc1jFFAPpymN4SdMa2TIe0Cu9aASmPEtO6JbGrdpzfHisTgeaeVHNVdqYzjmKZl_VxsBEBqKTsg0bMn9p-oRKqbcdu_5jOhyuBSNuYA)
![The button story with only the controls specified](/recipes-assets/mui-4.png)

📣 Shout out to [Eric Mudrak’s](https://twitter.com/ejmudrak) awesome [Storybook with React & TypeScript](https://www.erikmudrak.com/post/storybook-with-react-typescript) article that inspired this tip.
4 changes: 4 additions & 0 deletions apps/frontpage/next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ module.exports = withPlausibleProxy()({
protocol: 'https',
hostname: '*.gravatar.com',
},
{
protocol: 'https',
hostname: 'raw.githubusercontent.com',
},
],
},
async headers() {
Expand Down
Binary file added apps/frontpage/public/recipes-assets/mui-1.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/frontpage/public/recipes-assets/mui-2.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/frontpage/public/recipes-assets/mui-3.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/frontpage/public/recipes-assets/mui-4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/frontpage/public/recipes-assets/mui-5.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/frontpage/public/recipes-assets/mui-6.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 3778ea5

Please sign in to comment.