0
0
mirror of https://github.com/wagtail/wagtail.git synced 2024-11-24 10:58:52 +01:00

Update existing stories with latest storybook-django version

This commit is contained in:
Thibaud Colas 2022-04-06 09:56:10 +01:00
parent 64dd361cf7
commit 5fd3962d7f
10 changed files with 57 additions and 108 deletions

View File

@ -1,62 +0,0 @@
import React, { useRef, useEffect } from 'react';
import { renderPattern, simulateLoading } from 'storybook-django';
const getTemplateName = (template?: string, filename?: string): string =>
template ||
filename?.replace(/.+\/templates\//, '').replace(/\.stories\..+$/, '.html') ||
'template-not-found';
type ContextMapping = { [key: string]: any };
type TagsMapping = { [key: string]: any };
interface TemplatePatternProps {
element?: 'div' | 'span';
// Path to the template file.
template?: string;
// Path to a Storybook `stories` file, which should be placed next to and named the same as the HTML template.
filename?: string;
context?: ContextMapping;
tags?: TagsMapping;
}
const PATTERN_LIBRARY_RENDER_URL = '/pattern-library/api/v1/render-pattern';
/**
* Retrieves a template patterns HTML (or error response) from the server.
*/
export const getTemplatePattern = (
templateName: string,
context: ContextMapping,
tags: TagsMapping,
callback: (html: string) => void,
) =>
renderPattern(PATTERN_LIBRARY_RENDER_URL, templateName, context, tags)
.catch(callback)
.then((res) => res.text())
.then(callback);
/**
* Renders one of our Django templates as if it was a React component.
* All props are marked as optional, but either template or filename should be provided.
*/
const TemplatePattern = ({
element = 'div',
template,
filename,
context = {},
tags = {},
}: TemplatePatternProps) => {
const ref = useRef(null);
useEffect(() => {
const templateName = getTemplateName(template, filename);
getTemplatePattern(templateName, context, tags, (html) =>
simulateLoading(ref.current, html),
);
});
return React.createElement(element, { ref });
};
export default TemplatePattern;

View File

@ -29,7 +29,7 @@ const loadIconSprite = () => {
const sprite = document.createElement('div');
sprite.innerHTML = html;
const symbols = Array.from(sprite.querySelectorAll('symbol'));
const icons = symbols.map((elt) => elt.id.replace('icon-', ''));
const icons = symbols.map((elt) => elt.id.replace('icon-', '')).sort();
window.WAGTAIL_ICONS = icons;
sessionStorage.setItem('WAGTAIL_ICONS', JSON.stringify(icons));

22
package-lock.json generated
View File

@ -63,7 +63,7 @@
"redux-mock-store": "^1.3.0",
"sass": "^1.45.1",
"sass-loader": "^12.4.0",
"storybook-django": "^0.3.0",
"storybook-django": "^0.5.1",
"stylelint": "^14.2.0",
"tailwindcss": "^3.0.23",
"tailwindcss-vanilla-rtl": "^0.1.0",
@ -26381,12 +26381,20 @@
"dev": true
},
"node_modules/storybook-django": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/storybook-django/-/storybook-django-0.3.0.tgz",
"integrity": "sha512-sgepkbrPtbfoCOP9C1yysqyd/ZfrHBdpyBoXgd1oT3qjEtbqDPcXueRATMXY82wJq89tTJgMuGl24dv4JC9l9w==",
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/storybook-django/-/storybook-django-0.5.1.tgz",
"integrity": "sha512-aanBh2hU/ucP+0zjfAsAvFZtwY/e07FWgTzTjb1fKUpCeliutrrzkaH/9veVccZtr2zSqD3M1xgRLhN/YsQ0iA==",
"dev": true,
"dependencies": {
"http-proxy-middleware": "^2.0.0"
},
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
},
"peerDependenciesMeta": {
"react": {
"optional": true
}
}
},
"node_modules/stream-browserify": {
@ -50028,9 +50036,9 @@
"dev": true
},
"storybook-django": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/storybook-django/-/storybook-django-0.3.0.tgz",
"integrity": "sha512-sgepkbrPtbfoCOP9C1yysqyd/ZfrHBdpyBoXgd1oT3qjEtbqDPcXueRATMXY82wJq89tTJgMuGl24dv4JC9l9w==",
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/storybook-django/-/storybook-django-0.5.1.tgz",
"integrity": "sha512-aanBh2hU/ucP+0zjfAsAvFZtwY/e07FWgTzTjb1fKUpCeliutrrzkaH/9veVccZtr2zSqD3M1xgRLhN/YsQ0iA==",
"dev": true,
"requires": {
"http-proxy-middleware": "^2.0.0"

View File

@ -85,7 +85,7 @@
"redux-mock-store": "^1.3.0",
"sass": "^1.45.1",
"sass-loader": "^12.4.0",
"storybook-django": "^0.3.0",
"storybook-django": "^0.5.1",
"stylelint": "^14.2.0",
"tailwindcss": "^3.0.23",
"tailwindcss-vanilla-rtl": "^0.1.0",

View File

@ -1,4 +1,7 @@
{% load i18n wagtailadmin_tags %}
{% comment "text/markdown" %}
The breadcrumb component is reused across a lot of Wagtails headers.
{% endcomment %}
{% if use_next_template %}
{% include 'wagtailadmin/shared/breadcrumb-next.html' with trailing_breadcrumb_title=trailing_breadcrumb_title %}

View File

@ -1 +0,0 @@
The breadcrumb component is reused across a lot of Wagtails headers.

View File

@ -1,21 +1,15 @@
import React from 'react';
import TemplatePattern from '../../../../../client/storybook/TemplatePattern';
import { Pattern, generateDocs } from 'storybook-django/src/react';
import template from './breadcrumb.html';
import docs from './breadcrumb.md';
const { docs } = generateDocs(template);
export default {
parameters: {
docs: {
source: { code: template },
extractComponentDescription: () => docs,
},
},
parameters: { docs },
};
const Template = (args) => (
<TemplatePattern filename={__filename} context={args} />
);
const Template = (args) => <Pattern filename={__filename} context={args} />;
export const Base = Template.bind({});

View File

@ -1,10 +1,10 @@
{% load i18n wagtailadmin_tags %}
{% comment %}
{% comment "text/markdown" %}
Variables accepted by this template:
- `title`
- `subtitle`
- `title` - Displayed as `h1`
- `subtitle` - Within the `h1` tag but smaller
- `search_url` - if present, display a search box. This is a URL route name (taking no parameters) to be used as the action for that search box
- `query_parameters` - a query string (without the '?') to be placed after the search URL
- `icon` - name of an icon to place against the title

View File

@ -1,20 +1,16 @@
import React from 'react';
import TemplatePattern from '../../../../../client/storybook/TemplatePattern';
import { Pattern, generateDocs } from 'storybook-django/src/react';
import template from './header.html';
const { docs, argTypes } = generateDocs(template);
export default {
parameters: {
docs: {
source: { code: template },
// Trial generating documentation from comment within the template. To be replaced by a better pattern.
extractComponentDescription: () =>
template
.match(/{% comment %}\n((.|\n)+){% endcomment %}/m)[1]
.replace(/ {4}/g, ''),
},
docs,
},
argTypes: {
...argTypes,
icon: {
options: window.WAGTAIL_ICONS,
control: { type: 'select' },
@ -23,9 +19,7 @@ export default {
},
};
const Template = (args) => (
<TemplatePattern filename={__filename} context={args} />
);
const Template = (args) => <Pattern filename={__filename} context={args} />;
export const Base = Template.bind({});

View File

@ -1,10 +1,10 @@
import React, { useState, useEffect } from 'react';
import { getTemplatePattern } from '../../../../../client/storybook/TemplatePattern';
import { getTemplatePattern } from 'storybook-django/src/react';
/**
* Displays all icons within our sprite.
*/
const Icons = ({ color }: { color: string }) => {
const IconsTable = ({ color }: { color: string }) => {
const [template, setTemplate] = useState<string>('');
useEffect(() => {
@ -17,20 +17,33 @@ const Icons = ({ color }: { color: string }) => {
}, []);
return (
<>
<table>
<caption>All registered icons</caption>
<thead>
<tr>
<th scope="col">Visual</th>
<th scope="col">Name</th>
<th scope="col">Usage</th>
</tr>
</thead>
{window.WAGTAIL_ICONS.map((icon) => (
<div key={icon}>
<span
<tr key={icon}>
<td
dangerouslySetInnerHTML={{
__html: template
.replace(/__icon__/g, icon)
.replace(/<svg/, `<svg style="fill: ${color};"`),
}}
/>
<code>{`{% icon name="${icon}" %}`}</code>
</div>
<td>
<code>{icon}</code>
</td>
<td>
<code>{`{% icon name="${icon}" %}`}</code>
</td>
</tr>
))}
</>
</table>
);
};
@ -42,8 +55,8 @@ export default {
},
};
export const icons = (args) => <Icons {...args} />;
export const Icons = (args) => <IconsTable {...args} />;
icons.args = {
Icons.args = {
color: 'currentColor',
};