mirror of
https://github.com/wagtail/wagtail.git
synced 2024-11-28 00:17:06 +01:00
63 lines
1.7 KiB
TypeScript
63 lines
1.7 KiB
TypeScript
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;
|