1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162 |
- 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;
|