begin work on upgrading Markdown component to work with new react-markdown version API

pull/67/head
dperolio 3 years ago
parent 68c086d3b0
commit e43678be5c
No known key found for this signature in database
GPG Key ID: 3E9BBAA710D3DDCE

@ -6,11 +6,13 @@ import { getMediaDimensions } from '@vizality/util/file';
import { toKebabCase } from '@vizality/util/string';
import { open as openModal } from '@vizality/modal';
import { joinClassNames } from '@vizality/util/dom';
import { getModule } from '@vizality/webpack';
import { getModule, contextMenu } from '@vizality/webpack';
import { Regexes } from '@vizality/constants';
import { CodeBlock, Icon, DeferredRender, Spinner, LazyImageZoomable, ImageModal, Anchor } from '.';
import { CodeBlock, Icon, DeferredRender, Spinner, LazyImageZoomable, ImageModal, Anchor, ContextMenu } from '.';
const { readFile } = promises;
const { openContextMenu, closeContextMenu } = contextMenu;
export default memo(({ source }) => {
const [ markdown, setMarkdown ] = useState();
@ -33,7 +35,7 @@ export default memo(({ source }) => {
setMarkdown(source.trim());
}
}
}, [ markdown ]);
}, [ source, markdown ]);
const flatten = (text, child) => {
return typeof child === 'string'
@ -49,18 +51,49 @@ export default memo(({ source }) => {
};
})();
const renderers = {
root: ({ children }) => {
return children;
},
const getHeader = (level, children) => {
const sizes = [ null, size32, size24, size20, size16, size14, size12 ];
const text = toKebabCase(children.reduce(flatten, ''));
const slug = `vz-markdown-header--${generateId(text)}`;
const Header = `h${level}`;
return (
<Header
id={slug}
className={joinClassNames('vz-markdown-header', `vz-markdown-header-h${level}`, sizes[level], base)}
>
<Anchor className='vz-markdown-anchor' href={`#${slug}`}>
<Icon
name='Link'
className='vz-markdown-anchor-icon'
iconClassName='vz-markdown-anchor-icon'
size='16px'
onContextMenu={evt => openContextMenu(evt, () => (
<ContextMenu.Menu navId='vz-markdown-link-reference-context-menu' onClose={closeContextMenu}>
<ContextMenu.Item
id='copy-link'
label='Copy Link'
action={() => {
try {
const href = vizality.api.routes.getLocation()?.href;
const protocolUrl = href?.replace(href?.match(new RegExp(`${Regexes.DISCORD}/`))[0], '');
DiscordNative?.clipboard?.copy(`<${protocolUrl.replace('vizality', 'vizality:/')}#${slug}>`);
} catch (err) {
/*
* text: ({ children }) => {
* return <span className='vz-markdown__span'>{children}</span>;
* },
*/
}
}}
/>
</ContextMenu.Menu>
))}
/>
</Anchor>
{children}
</Header>
);
};
paragraph: ({ children }) => {
const renderers = {
p: ({ children }) => {
return <p className='vz-markdown-p'>
{children}
</p>;
@ -83,13 +116,13 @@ export default memo(({ source }) => {
);
},
listItem: ({ children }) => {
li: ({ children }) => {
return <li className='vz-markdown-list-item'>
{children}
</li>;
},
link: ({ href, children }) => {
a: ({ href, children }) => {
return <>
<Anchor
href={href}
@ -111,7 +144,7 @@ export default memo(({ source }) => {
</>;
},
emphasis: ({ children }) => {
em: ({ children }) => {
return <em className='vz-markdown-em'>{children}</em>;
},
@ -123,20 +156,31 @@ export default memo(({ source }) => {
return <blockquote className='vz-markdown-blockquote'>{children}</blockquote>;
},
thematicBreak: () => {
hr: () => {
return <hr className='vz-markdown-hr' />;
},
code: ({ language, value }) => {
return <CodeBlock language={language} content={value} className='vz-markdown-code' />;
},
inlineCode: ({ children }) => {
return <code className='vz-markdown-code-inline'>{children}</code>;
code: ({ inline, className, children }) => {
const language = className?.match(/(language-)/)?.input?.replace('language-', '');
return (
inline
? (
<code className='vz-markdown-code-inline'>
{children}
</code>
)
: (
<CodeBlock
language={language}
content={children?.join()}
className='vz-markdown-code'
/>
)
);
},
// @todo Fix this to work with variable dimensions.
image: ({ alt, src }) => {
img: ({ alt, src }) => {
return <LazyImageZoomable
className={joinClassNames('vz-markdown-image', imageWrapper)}
src={src}
@ -156,64 +200,44 @@ export default memo(({ source }) => {
/>;
},
// @todo Fix this to work with variable dimensions.
imageReference: ({ alt, src }) => {
return <LazyImageZoomable
className={joinClassNames('vz-markdown-image', imageWrapper)}
src={src}
alt={alt}
width='500'
height='500'
onClick={e => {
e.preventDefault();
openModal(() =>
<ImageModal
src={src}
width='500'
height='500'
/>);
}}
/>;
},
table: ({ children }) => {
return <table className='vz-markdown-table'>{children}</table>;
},
tableHead: ({ children }) => {
thead: ({ children }) => {
return <thead className='vz-markdown-thead'>{children}</thead>;
},
tableBody: ({ children }) => {
tbody: ({ children }) => {
return <tbody className='vz-markdown-tbody'>{children}</tbody>;
},
tableRow: ({ children }) => {
tr: ({ children }) => {
return <tr className='vz-markdown-tr'>{children}</tr>;
},
tableCell: ({ isHeader, align, children }) => {
td: ({ isHeader, style, children }) => {
return isHeader
? <th className={joinClassNames('vz-markdown-th', { 'vz-markdown-th vz-align-right': align })}>{children}</th>
: <td className={joinClassNames('vz-markdown-td', { 'vz-markdown-td vz-align-right': align })}>{children}</td>;
? (
<th className='vz-markdown-th' style={style}>
{children}
</th>
)
: (
<td className='vz-markdown-td' style={style}>
{children}
</td>
);
},
heading: ({ level, children }) => {
const sizes = [ null, size32, size24, size20, size16, size14, size12 ];
const text = toKebabCase(children.reduce(flatten, ''));
const slug = `vz-markdown-header--${generateId(text)}`;
const Header = `h${level}`;
return (
<Header id={slug} className={joinClassNames('vz-markdown-header', `vz-markdown-header-h${level}`, sizes[level], base)}>
<Anchor className='vz-markdown-anchor' href={`#${slug}`}>
<Icon name='Link' className='vz-markdown-anchor-icon' iconClassName='vz-markdown-anchor-icon' size='16px' />
</Anchor>
{children}
</Header>
);
}
h1: ({ level, children }) => getHeader(level, children),
h2: ({ level, children }) => getHeader(level, children),
h3: ({ level, children }) => getHeader(level, children),
h4: ({ level, children }) => getHeader(level, children),
h5: ({ level, children }) => getHeader(level, children),
h6: ({ level, children }) => getHeader(level, children)
};
return (
<>
{existsSync(source)
@ -223,10 +247,10 @@ export default memo(({ source }) => {
<Spinner />
</div>
}>
<Markdown source={markdown} renderers={renderers} />
<Markdown children={markdown} components={renderers} />
</DeferredRender>
)
: <Markdown source={markdown} renderers={renderers} />
: <Markdown children={markdown} components={renderers} />
}
</>
);

Loading…
Cancel
Save