UNPKG

aquameta-widget

Version:

Widget rendering framework built on top of Aquameta

75 lines (70 loc) 1.98 kB
import html from '/db/widget/core/html.js'; import React from '/db/widget/dep/react.js'; import styled from '/db/widget/dep/styled-components.js'; import Markdown from '/db/widget/component/markdown.js'; import Centered from '/db/widget/component/centered.js'; const SlideWrapper = styled.div` background-color: ${({theme}) => theme.colors.opaque.light}; border: 2px solid ${({theme}) => theme.colors.dark}; border-radius: 2px; color: ${({theme}) => theme.colors.dark}; display: inline-block; height: auto; height: ${({theme}) => theme.height}; overflow: auto; padding: 0 30px; width: 100%; `; function LazyLoader({importPath}) { const LazyComp = React.useMemo(() => { return React.lazy(async () => { let component; try { component = await import(importPath); } catch (e) { component = { default: () => html`<${Centered}>Component not found<//>` }; } return component; }); }, [importPath]); return html` <${React.Suspense} fallback=${html`<${Loading} />`}> <${LazyComp}/> <//> `; } function Loading() { return html`<${Centered}>Loading...<//>` } const shortcodeRegex = /SHORTCODE'(.*?)'END/g; export default function Slide(props) { let content = props.slide.markdown; const children = []; while (true) { const match = shortcodeRegex.exec(content); if (!match) { break; } const markdown = content.slice(0, match.index); const [shortcode, importPath] = match; content = content.slice(match.index + shortcode.length); const l = children.length; children.push( html`<${Markdown} key=${l+'md'} markdown=${markdown} />`, html`<${LazyLoader} key=${l+'comp'} importPath=${importPath} />`, ); } if (content) { const l = children.length; children.push( html`<${Markdown} key=${l+'md'} markdown=${content} />` ); } return html` <${SlideWrapper}> ${children} <//> `; }