Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Preact: Fix hooks when used in stories, preact-kitchen-sink #14473

Merged
merged 16 commits into from
Apr 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 9 additions & 11 deletions addons/storyshots/storyshots-core/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -235,11 +235,11 @@ module.exports = {

### Configure Jest for Preact

StoryShots addon for Preact is dependent on [preact-render-to-json](https://github.com/nathancahill/preact-render-to-json), but
StoryShots addon for Preact is dependent on [preact-render-to-string](https://github.com/preactjs/preact-render-to-string), but
[doesn't](#deps-issue) install it, so you need to install it separately.

```sh
yarn add preact-render-to-json --dev
yarn add preact-render-to-string --dev
```

### Configure Jest for Web Components
Expand Down Expand Up @@ -325,19 +325,18 @@ By design, [`react-test-renderer` doesn't use a browser environment or JSDOM](ht
#### Example with React Testing Library

```js
import initStoryshots from "@storybook/addon-storyshots";
import { render } from "@testing-library/react";
import initStoryshots from '@storybook/addon-storyshots';
import { render } from '@testing-library/react';

const reactTestingLibrarySerializer = {
print: (val, serialize, indent) => serialize(val.container.firstChild),
test: val => val && val.hasOwnProperty("container")
test: (val) => val && val.hasOwnProperty('container'),
};

initStoryshots({
renderer: render,
snapshotSerializers: [reactTestingLibrarySerializer]
snapshotSerializers: [reactTestingLibrarySerializer],
});

```

#### Example with Enzyme
Expand Down Expand Up @@ -584,9 +583,10 @@ initStoryshots({

### `framework`

If you are running tests from outside of your app's directory, storyshots' detection of which framework you are using may fail. Pass `"react"` or `"react-native"` to short-circuit this.
If you are running tests from outside of your app's directory, storyshots' detection of which framework you are using may fail. Pass `"react"` or `"react-native"` to short-circuit this.

For example:

```js
// storybook.test.js

Expand All @@ -604,12 +604,11 @@ initStoryshots({
Use this table as a reference for manually specifying the framework.

| angular | html | preact |
|----------------|------|--------------|
| -------------- | ---- | ------------ |
| react | riot | react-native |
| svelte | vue | vue3 |
| web-components | rax | |


### `test`

Run a custom test function for each story, rather than the default (a vanilla snapshot test).
Expand All @@ -634,7 +633,6 @@ This may be necessary if you want to use React features that are not supported b
such as **ref** or **Portals**.
Note that setting `test` overrides `renderer`.


### `snapshotSerializers`

Pass an array of snapshotSerializers to the jest runtime that serializes your story (such as enzyme-to-json).
Expand Down
5 changes: 5 additions & 0 deletions addons/storyshots/storyshots-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
"glob": "^7.1.6",
"global": "^4.4.0",
"jest-specific-snapshot": "^4.0.0",
"preact-render-to-string": "^5.1.19",
"pretty-format": "^26.6.2",
"react-test-renderer": "^16.8.0 || ^17.0.0",
"read-pkg-up": "^7.0.1",
Expand Down Expand Up @@ -85,6 +86,7 @@
"@storybook/vue3": "*",
"jest-preset-angular": "*",
"jest-vue-preprocessor": "*",
"preact": "^10.5.13",
"react": "^16.8.0 || ^17.0.0",
"react-dom": "^16.8.0 || ^17.0.0",
"rxjs": "*",
Expand Down Expand Up @@ -114,6 +116,9 @@
"jest-vue-preprocessor": {
"optional": true
},
"preact": {
"optional": true
},
"react": {
"optional": true
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
/** @jsx h */
import { h } from 'preact';
import preactRenderer from 'preact-render-to-string/jsx';

// eslint-disable-next-line import/no-extraneous-dependencies
import preactRenderer from 'preact-render-to-json';
const boundRenderer = (_storyElement: any, _rendererOptions: any) =>
preactRenderer(_storyElement, null, { pretty: ' ' });

function getRenderedTree(story: any, context: any, { renderer, ...rendererOptions }: any) {
const storyElement = story.render();
const currentRenderer = renderer || preactRenderer;
const tree = currentRenderer(storyElement, rendererOptions);
const currentRenderer = renderer || boundRenderer;
const tree = currentRenderer(h(story.render, null), rendererOptions);

return tree;
}
Expand Down
2 changes: 1 addition & 1 deletion addons/storyshots/storyshots-core/src/typings.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
declare module 'global';
declare module 'jest-preset-angular/*';
declare module 'preact-render-to-json';
declare module 'preact-render-to-string/jsx';
declare module 'react-test-renderer*';
declare module 'rax-test-renderer*';
declare module 'babel-plugin-require-context-hook/register';
2 changes: 1 addition & 1 deletion app/preact/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
"ts-dedent": "^2.0.0"
},
"devDependencies": {
"preact": "^10.5.9"
"preact": "^10.5.13"
},
"peerDependencies": {
"@babel/core": "*",
Expand Down
43 changes: 24 additions & 19 deletions app/preact/src/client/preview/render.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,44 +7,49 @@ const rootElement = document ? document.getElementById('root') : null;

let renderedStory: Element;

function preactRender(element: StoryFnPreactReturnType | null): void {
if ((preact as any).Fragment) {
function preactRender(story: StoryFnPreactReturnType): void {
if (preact.Fragment) {
// Preact 10 only:
preact.render(element, rootElement);
} else if (element) {
renderedStory = (preact.render(element, rootElement) as unknown) as Element;
preact.render(story, rootElement);
} else {
preact.render(element, rootElement, renderedStory);
renderedStory = (preact.render(story, rootElement, renderedStory) as unknown) as Element;
}
}

export default function renderMain({
storyFn,
kind,
name,
showMain,
showError,
forceRender,
}: RenderContext) {
const element = storyFn();

if (!element) {
const StoryHarness: preact.FunctionalComponent<{
name: string;
kind: string;
showError: RenderContext['showError'];
storyFn: () => any;
}> = ({ showError, name, kind, storyFn }) => {
const content = preact.h(storyFn as any, null);
if (!content) {
showError({
title: `Expecting a Preact element from the story: "${name}" of "${kind}".`,
description: dedent`
Did you forget to return the Preact element from the story?
Use "() => (<MyComp/>)" or "() => { return <MyComp/>; }" when defining the story.
`,
});
return;
return null;
}
return content;
};

export default function renderMain({
storyFn,
kind,
name,
showMain,
showError,
forceRender,
}: RenderContext) {
// But forceRender means that it's the same story, so we want to keep the state in that case.
if (!forceRender) {
preactRender(null);
}

showMain();

preactRender(element);
preactRender(preact.h(StoryHarness, { name, kind, showError, storyFn }));
}
1 change: 1 addition & 0 deletions examples/preact-kitchen-sink/.storybook/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ module.exports = {
addons: [
'@storybook/addon-storysource',
'@storybook/addon-actions',
'@storybook/addon-docs',
'@storybook/addon-links',
'@storybook/addon-knobs',
'@storybook/addon-viewport',
Expand Down
4 changes: 2 additions & 2 deletions examples/preact-kitchen-sink/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
},
"dependencies": {
"global": "^4.4.0",
"preact": "^8.5.3"
"preact": "^10.5.13"
},
"devDependencies": {
"@babel/core": "^7.12.10",
Expand All @@ -29,7 +29,7 @@
"babel-loader": "^8.2.2",
"cross-env": "^7.0.3",
"file-loader": "^6.2.0",
"preact-render-to-json": "^3.6.6",
"preact-render-to-string": "^5.1.19",
"raw-loader": "^4.0.2",
"svg-url-loader": "^7.1.1",
"webpack": "4",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,39 +1,39 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Storyshots Addons/Actions Action and method 1`] = `
<button
class="button"
onclick={[Function]}
"<button
class=\\"button\\"
onclick={[Function onclick]}
>
Click me to log the action
</button>
</button>"
`;

exports[`Storyshots Addons/Actions Action only 1`] = `
<button
class="button"
onclick={[Function]}
"<button
class=\\"button\\"
onclick={[Function onclick]}
>
Click me to log the action
</button>
Click me to log the action
</button>"
`;

exports[`Storyshots Addons/Actions Multiple actions 1`] = `
<button
class="button"
onclick={[Function]}
ondblclick={[Function]}
"<button
class=\\"button\\"
onclick={[Function actionHandler]}
ondblclick={[Function actionHandler]}
>
(Double) click me to log the action
</button>
</button>"
`;

exports[`Storyshots Addons/Actions Multiple actions, object 1`] = `
<button
class="button"
onclick={[Function]}
ondblclick={[Function]}
"<button
class=\\"button\\"
onclick={[Function actionHandler]}
ondblclick={[Function actionHandler]}
>
(Double) click me to log the action
</button>
</button>"
`;
Original file line number Diff line number Diff line change
@@ -1,17 +1,9 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Storyshots Addons/Backgrounds Example 1 1`] = `
<button
class="button"
>
"<button class=\\"button\\">
You should be able to switch backgrounds for this story
</button>
</button>"
`;

exports[`Storyshots Addons/Backgrounds Example 2 1`] = `
<button
class="button"
>
This one too!
</button>
`;
exports[`Storyshots Addons/Backgrounds Example 2 1`] = `"<button class=\\"button\\">This one too!</button>"`;
Original file line number Diff line number Diff line change
@@ -1,40 +1,20 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Storyshots Addons/Knobs All knobs 1`] = `
<div
style="border:2px dotted deeppink; padding: 8px 22px; border-radius: 8px"
>
<h1>
My name is Jane,
</h1>
<h3>
today is January 20, 2017
</h3>
"<div style=\\"border:2px dotted deeppink; padding: 8px 22px; border-radius: 8px\\">
<h1>My name is Jane,</h1>
<h3>today is January 20, 2017</h3>
<p>
I have a stock of 20 apples, costing &dollar;2.25 each.
</p>
<p>
Also, I have:
I have a stock of 20 apples, costing &amp;dollar;2.25 each.
</p>
<p>Also, I have:</p>
<ul>
<li>
Laptop
</li>
<li>
Book
</li>
<li>
Whiskey
</li>
<li>Laptop</li>
<li>Book</li>
<li>Whiskey</li>
</ul>
<p>
Nice to meet you!
</p>
</div>
<p>Nice to meet you!</p>
</div>"
`;

exports[`Storyshots Addons/Knobs Simple 1`] = `
<div>
I am John Doe and I'm 44 years old.
</div>
`;
exports[`Storyshots Addons/Knobs Simple 1`] = `"<div>I am John Doe and I'm 44 years old.</div>"`;
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Storyshots Addons/Links Go to welcome 1`] = `
<button
class="button"
onclick={[Function]}
"<button
class=\\"button\\"
onclick={[Function anonymous]}
>
This button links to Welcome
</button>
</button>"
`;
Loading