Selaa lähdekoodia

Update existing stories with latest storybook-django version

Thibaud Colas 3 vuotta sitten
vanhempi
commit
5fd3962d7f

+ 0 - 62
client/storybook/TemplatePattern.tsx

@@ -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 pattern’s 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;

+ 1 - 1
client/storybook/preview.js

@@ -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));

+ 15 - 7
package-lock.json

@@ -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"

+ 1 - 1
package.json

@@ -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",

+ 3 - 0
wagtail/admin/templates/wagtailadmin/shared/breadcrumb.html

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

+ 0 - 1
wagtail/admin/templates/wagtailadmin/shared/breadcrumb.md

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

+ 5 - 11
wagtail/admin/templates/wagtailadmin/shared/breadcrumb.stories.tsx

@@ -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({});
 

+ 3 - 3
wagtail/admin/templates/wagtailadmin/shared/header.html

@@ -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

+ 6 - 12
wagtail/admin/templates/wagtailadmin/shared/header.stories.tsx

@@ -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({});
 

+ 23 - 10
wagtail/admin/templates/wagtailadmin/shared/icons.stories.tsx

@@ -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',
 };