Skip to content

Commit

Permalink
Merge pull request #19451 from storybookjs/tom/sb-557-typescript-2
Browse files Browse the repository at this point in the history
Add Preact/Webpack templates and update renderer/preset (2)
  • Loading branch information
tmeasday authored Oct 13, 2022
2 parents 149471e + 62471a5 commit c83449f
Show file tree
Hide file tree
Showing 18 changed files with 174 additions and 55 deletions.
11 changes: 10 additions & 1 deletion code/addons/docs/src/preset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,20 @@ type BabelParams = {
};
function createBabelOptions({ babelOptions, mdxBabelOptions, configureJSX }: BabelParams) {
const babelPlugins = mdxBabelOptions?.plugins || babelOptions?.plugins || [];

const filteredBabelPlugins = babelPlugins.filter((p: any) => {
const name = Array.isArray(p) ? p[0] : p;
if (typeof name === 'string') {
return !name.includes('plugin-transform-react-jsx');
}
return true;
});

const jsxPlugin = [
require.resolve('@babel/plugin-transform-react-jsx'),
{ pragma: 'React.createElement', pragmaFrag: 'React.Fragment' },
];
const plugins = configureJSX ? [...babelPlugins, jsxPlugin] : babelPlugins;
const plugins = configureJSX ? [...filteredBabelPlugins, jsxPlugin] : babelPlugins;
return {
// don't use the root babelrc by default (users can override this in mdxBabelOptions)
babelrc: false,
Expand Down
2 changes: 0 additions & 2 deletions code/lib/cli/rendererAssets/preact/Button.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
/** @jsx h */
import { h } from 'preact';
import PropTypes from 'prop-types';
import './button.css';

Expand Down
2 changes: 0 additions & 2 deletions code/lib/cli/rendererAssets/preact/Button.stories.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
/** @jsx h */
import { h } from 'preact';
import { Button } from './Button';

// More on default export: https://storybook.js.org/docs/preact/writing-stories/introduction#default-export
Expand Down
10 changes: 4 additions & 6 deletions code/lib/cli/rendererAssets/preact/Header.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
/** @jsx h */
import { h, Fragment } from 'preact';
import PropTypes from 'prop-types';

import { Button } from './Button';
Expand Down Expand Up @@ -29,17 +27,17 @@ export const Header = ({ user, onLogin, onLogout, onCreateAccount }) => (
</div>
<div>
{user ? (
<Fragment>
<>
<span className="welcome">
Welcome, <b>{user.name}</b>!
</span>
<Button size="small" onClick={onLogout} label="Log out" />
</Fragment>
</>
) : (
<Fragment>
<>
<Button size="small" onClick={onLogin} label="Log in" />
<Button primary size="small" onClick={onCreateAccount} label="Sign up" />
</Fragment>
</>
)}
</div>
</div>
Expand Down
2 changes: 0 additions & 2 deletions code/lib/cli/rendererAssets/preact/Header.stories.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
/** @jsx h */
import { h } from 'preact';
import { Header } from './Header';

export default {
Expand Down
2 changes: 0 additions & 2 deletions code/lib/cli/rendererAssets/preact/Page.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
/** @jsx h */
import { h } from 'preact';
import { useState } from 'preact/hooks';

import { Header } from './Header';
Expand Down
2 changes: 0 additions & 2 deletions code/lib/cli/rendererAssets/preact/Page.stories.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
/** @jsx h */
import { h } from 'preact';
import { within, userEvent } from '@storybook/testing-library';

import { Page } from './Page';
Expand Down
60 changes: 44 additions & 16 deletions code/lib/cli/src/repro-templates.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const craTemplates = {
'cra/default-js': {
name: 'Create React App (Javascript)',
script: 'npx create-react-app .',
script: 'npx create-react-app {{beforeDir}}',
cadence: ['ci', 'daily', 'weekly'],
expected: {
framework: '@storybook/cra',
Expand All @@ -11,7 +11,7 @@ const craTemplates = {
},
'cra/default-ts': {
name: 'Create React App (Typescript)',
script: 'npx create-react-app . --template typescript',
script: 'npx create-react-app {{beforeDir}} --template typescript',
cadence: ['ci', 'daily', 'weekly'],
// Re-enable once https://github.com/storybookjs/storybook/issues/19351 is fixed.
skipTasks: ['smoke-test'],
Expand All @@ -26,7 +26,7 @@ const craTemplates = {
const reactViteTemplates = {
'react-vite/default-js': {
name: 'React Vite (JS)',
script: 'yarn create vite . --template react',
script: 'yarn create vite {{beforeDir}} --template react',
cadence: ['ci', 'daily', 'weekly'],
expected: {
framework: '@storybook/react-vite',
Expand All @@ -36,7 +36,7 @@ const reactViteTemplates = {
},
'react-vite/default-ts': {
name: 'React Vite (TS)',
script: 'yarn create vite . --template react-ts',
script: 'yarn create vite {{beforeDir}} --template react-ts',
cadence: ['ci', 'daily', 'weekly'],
expected: {
framework: '@storybook/react-vite',
Expand All @@ -49,7 +49,7 @@ const reactViteTemplates = {
const reactWebpackTemplates = {
'react-webpack/18-ts': {
name: 'React Webpack5 (TS)',
script: 'yarn create webpack5-react .',
script: 'yarn create webpack5-react {{beforeDir}}',
cadence: ['ci', 'daily', 'weekly'],
expected: {
framework: '@storybook/react-webpack5',
Expand All @@ -59,7 +59,8 @@ const reactWebpackTemplates = {
},
'react-webpack/17-ts': {
name: 'React Webpack5 (TS)',
script: 'yarn create webpack5-react . --version-react="17" --version-react-dom="17"',
script:
'yarn create webpack5-react {{beforeDir}} --version-react="17" --version-react-dom="17"',
cadence: ['ci', 'daily', 'weekly'],
expected: {
framework: '@storybook/react-webpack5',
Expand All @@ -72,7 +73,7 @@ const reactWebpackTemplates = {
const vue3ViteTemplates = {
'vue3-vite/default-js': {
name: 'Vue3 Vite (JS)',
script: 'yarn create vite . --template vue',
script: 'yarn create vite {{beforeDir}} --template vue',
cadence: ['ci', 'daily', 'weekly'],
expected: {
framework: '@storybook/vue3-vite',
Expand All @@ -82,7 +83,7 @@ const vue3ViteTemplates = {
},
'vue3-vite/default-ts': {
name: 'Vue3 Vite (TS)',
script: 'yarn create vite . --template vue-ts',
script: 'yarn create vite {{beforeDir}} --template vue-ts',
cadence: ['ci', 'daily', 'weekly'],
expected: {
framework: '@storybook/vue3-vite',
Expand All @@ -99,7 +100,7 @@ const vue2ViteTemplates = {
// We don't really want to maintain weird custom scripts like this,
// preferring community bootstrap scripts / generators instead.
script:
'yarn create vite . --template vanilla && yarn add --dev @vitejs/plugin-vue2 vue-template-compiler vue@2 && echo "import vue2 from \'@vitejs/plugin-vue2\';\n\nexport default {\n\tplugins: [vue2()]\n};" > vite.config.js',
'yarn create vite {{beforeDir}} --template vanilla && yarn add --dev @vitejs/plugin-vue2 vue-template-compiler vue@2 && echo "import vue2 from \'@vitejs/plugin-vue2\';\n\nexport default {\n\tplugins: [vue2()]\n};" > vite.config.js',
cadence: ['ci', 'daily', 'weekly'],
expected: {
framework: '@storybook/vue2-vite',
Expand All @@ -112,7 +113,7 @@ const vue2ViteTemplates = {
const htmlWebpackTemplates = {
'html-webpack/default': {
name: 'HTML Webpack5',
script: 'yarn create webpack5-html .',
script: 'yarn create webpack5-html {{beforeDir}}',
cadence: ['ci', 'daily', 'weekly'],
expected: {
framework: '@storybook/html-webpack5',
Expand All @@ -125,7 +126,7 @@ const htmlWebpackTemplates = {
const svelteViteTemplates = {
'svelte-vite/default-js': {
name: 'Svelte Vite (JS)',
script: 'yarn create vite . --template svelte',
script: 'yarn create vite {{beforeDir}} --template svelte',
cadence: ['ci', 'daily', 'weekly'],
expected: {
framework: '@storybook/svelte-vite',
Expand All @@ -135,7 +136,7 @@ const svelteViteTemplates = {
},
'svelte-vite/default-ts': {
name: 'Svelte Vite (TS)',
script: 'yarn create vite . --template svelte-ts',
script: 'yarn create vite {{beforeDir}} --template svelte-ts',
cadence: ['ci', 'daily', 'weekly'],
expected: {
framework: '@storybook/svelte-vite',
Expand All @@ -148,7 +149,7 @@ const svelteViteTemplates = {
const litViteTemplates = {
'lit-vite/default-js': {
name: 'Lit Vite (JS)',
script: 'yarn create vite . --template lit',
script: 'yarn create vite {{beforeDir}} --template lit',
cadence: ['ci', 'daily', 'weekly'] as any,
// Re-enable once https://github.com/storybookjs/storybook/issues/19351 is fixed.
skipTasks: ['smoke-test'],
Expand All @@ -160,7 +161,7 @@ const litViteTemplates = {
},
'lit-vite/default-ts': {
name: 'Lit Vite (TS)',
script: 'yarn create vite . --template lit-ts',
script: 'yarn create vite {{beforeDir}} --template lit-ts',
cadence: ['ci', 'daily', 'weekly'] as any,
// Re-enable once https://github.com/storybookjs/storybook/issues/19351 is fixed.
skipTasks: ['smoke-test'],
Expand All @@ -175,7 +176,8 @@ const litViteTemplates = {
const vueCliTemplates = {
'vue-cli/default-js': {
name: 'Vue-CLI (Default JS)',
script: 'npx -p @vue/cli vue create . --default --packageManager=yarn --force --merge',
script:
'npx -p @vue/cli vue create {{beforeDir}} --default --packageManager=yarn --force --merge',
cadence: ['ci', 'daily', 'weekly'],
// Re-enable once https://github.com/storybookjs/storybook/issues/19351 is fixed.
skipTasks: ['smoke-test'],
Expand All @@ -188,7 +190,7 @@ const vueCliTemplates = {
'vue-cli/vue2-default-js': {
name: 'Vue-CLI (Vue2 JS)',
script:
'npx -p @vue/cli vue create . --default --packageManager=yarn --force --merge --preset=Default\\ (Vue\\ 2)',
'npx -p @vue/cli vue create {{beforeDir}} --default --packageManager=yarn --force --merge --preset=Default\\ (Vue\\ 2)',
cadence: ['ci', 'daily', 'weekly'],
// Re-enable once https://github.com/storybookjs/storybook/issues/19351 is fixed.
skipTasks: ['smoke-test'],
Expand All @@ -200,6 +202,31 @@ const vueCliTemplates = {
},
};

const preactWebpackTemplates = {
'preact-webpack5/default-js': {
name: 'Preact CLI (Default JS)',
script: 'npx preact-cli create default {{beforeDir}} --name preact-app --yarn --no-install',
// cadence: ['ci', 'daily', 'weekly'],
cadence: [] as string[],
expected: {
framework: '@storybook/preact-webpack5',
renderer: '@storybook/preact',
builder: '@storybook/builder-webpack5',
},
},
'preact-webpack5/default-ts': {
name: 'Preact CLI (Default TS)',
script: 'npx preact-cli create typescript {{beforeDir}} --name preact-app --yarn --no-install',
// cadence: ['ci', 'daily', 'weekly'],
cadence: [] as string[],
expected: {
framework: '@storybook/preact-webpack5',
renderer: '@storybook/preact',
builder: '@storybook/builder-webpack5',
},
},
};

export default {
...craTemplates,
...reactWebpackTemplates,
Expand All @@ -210,6 +237,7 @@ export default {
...litViteTemplates,
...vueCliTemplates,
...htmlWebpackTemplates,
...preactWebpackTemplates,
// FIXME: missing documentation.json
// 'angular/latest': {
// name: 'Angular (latest)',
Expand Down
16 changes: 1 addition & 15 deletions code/presets/preact-webpack/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export const babel: StorybookConfig['babelDefault'] = (config) => {
...(config.plugins || []).filter((p) => {
const name = Array.isArray(p) ? p[0] : p;
if (typeof name === 'string') {
return !name.includes('babel-plugin-transform-react-jsx');
return !name.includes('plugin-transform-react-jsx');
}
return true;
}),
Expand All @@ -23,20 +23,6 @@ export const babel: StorybookConfig['babelDefault'] = (config) => {
};

export const webpackFinal: StorybookConfig['webpackFinal'] = (config) => {
const rules = config.module?.rules || [];
const tsxRule = rules.find((rule) => (rule.test as RegExp).test?.('main.tsx'));
tsxRule.use = (tsxRule.use as any).map((entry: any) => {
let newPlugins = entry.options.plugins;
if (entry.loader?.includes('babel-loader')) {
newPlugins = (entry.options as any).plugins.map((plugin: any) => {
if (plugin[0]?.includes?.('@babel/plugin-transform-react-jsx')) {
return [plugin[0], { importSource: 'preact', runtime: 'automatic' }];
}
return plugin;
});
}
return { ...entry, options: { ...entry.options, plugins: newPlugins } };
});
return {
...config,
resolve: {
Expand Down
2 changes: 1 addition & 1 deletion code/renderers/preact/src/config.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export { renderToDOM } from './render';
export { renderToDOM, render } from './render';

export const parameters = { framework: 'preact' as const };
18 changes: 18 additions & 0 deletions code/renderers/preact/src/render.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,26 @@
/** @jsx h */
import * as preact from 'preact';
import { dedent } from 'ts-dedent';
import type { RenderContext } from '@storybook/store';
import { ArgsStoryFn } from '@storybook/csf';

import type { StoryFnPreactReturnType, PreactFramework } from './types';

const { h } = preact;

export const render: ArgsStoryFn<PreactFramework> = (args, context) => {
const { id, component: Component } = context;
if (!Component) {
throw new Error(
`Unable to render story ${id} as the component annotation is missing from the default export`
);
}

// @ts-expect-error I think the type of Component should be Preact.ComponentType, but even that
// doens't make TS happy, I suspect because TS wants "react" components.
return <Component {...args} />;
};

let renderedStory: Element;

function preactRender(story: StoryFnPreactReturnType | null, domElement: Element): void {
Expand Down
14 changes: 14 additions & 0 deletions code/renderers/preact/template/components/Button.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/* eslint-disable react/react-in-jsx-scope */
// eslint-disable-next-line import/no-extraneous-dependencies
import PropTypes from 'prop-types';

export const Button = ({ onClick, children }) => (
<button type="button" onClick={onClick}>
{children}
</button>
);

Button.propTypes = {
onClick: PropTypes.func.isRequired,
children: PropTypes.node.isRequired,
};
38 changes: 38 additions & 0 deletions code/renderers/preact/template/components/Form.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/* eslint-disable react/react-in-jsx-scope */
// eslint-disable-next-line import/no-extraneous-dependencies
import PropTypes from 'prop-types';
import { useState } from 'preact/hooks';

export const Form = ({ onSuccess }) => {
const [value, setValue] = useState('');
const [complete, setComplete] = useState(false);

function onSubmit(event) {
event.preventDefault();
onSuccess(value);

setTimeout(() => setComplete(true), 500);
setTimeout(() => setComplete(false), 1500);
}

return (
<form id="interaction-test-form" onSubmit={onSubmit}>
<label>
Enter Value
<input
type="text"
data-testid="value"
value={value}
required
onChange={(event) => setValue(event.target.value)}
/>
</label>
<button type="submit">Submit</button>
{complete && <p>Completed!!</p>}
</form>
);
};

Form.propTypes = {
onSuccess: PropTypes.func.isRequired,
};
10 changes: 10 additions & 0 deletions code/renderers/preact/template/components/Html.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/* eslint-disable react/react-in-jsx-scope */
// eslint-disable-next-line import/no-extraneous-dependencies
import PropTypes from 'prop-types';

// eslint-disable-next-line react/no-danger
export const Html = ({ content }) => <div dangerouslySetInnerHTML={{ __html: content }} />;

Html.propTypes = {
content: PropTypes.string.isRequired,
};
Loading

0 comments on commit c83449f

Please sign in to comment.