会
Next.jsで
Tailwind CSSを
選んだ
<div className={css`
margin: 0;
padding: 0;
`}>
以前は
やる
以前はdangerouslySetInnerHTML
で
自前で
const classes: {[key:string]: string} = {
h1: '',
h2: 'my-6 text-xl md:text-2xl pb-1 border-b',
h3: 'my-3 text-lg md:text-xl',
h4: '',
h5: '',
h6: '',
p: 'my-3 text-sm md:text-base',
a: 'text-red-600',
ul: 'my-3 ml-6 text-sm list-disc',
img: 'my-3',
video: 'my-3',
pre: 'hljs my-3 text-sm md:text-base'
}
export default Object.keys(classes).map(key => ({
type: 'output',
regex: new RegExp(`<${key}(?: (.*)>|>)`, 'g'),
replace: `<${key} class="${classes[key]}" $1>`
})).concat({
type: 'output',
regex: /(?<!(?:<pre(?: (.*)>|>)))(?:\n?\s*<code(?: (.*)>|>))/g,
replace: '<code class="bg-gray-100 px-2 py-px mx-px" $1>'
})
これを
export const AppMarkdownParagraph = ({ node }: Props) => {
return (
<p className={css`
font-size: 16px;
margin: 16px 0;
color: ${color['grey-5']};
`}>
{node.children.map((node, i) => (
<AppMarkdown
key={i}
node={node}/>
))}
</p>
)
}
同じ
コンポーネント未作成の
export const AppMarkdown = ({ node }: Props) => {
if (node.type === 'root')
return <AppMarkdownRoot node={node} />
if (node.type === 'paragraph')
return <AppMarkdownParagraph node={node} />
if (node.type === 'text')
return <AppMarkdownText node={node} />
if (node.type === 'list')
return <AppMarkdownList node={node} />
if (node.type === 'listItem')
return <AppMarkdownListItem node={node} />
if (node.type === 'image')
return <AppMarkdownImage node={node} />
if (node.type === 'heading')
return <AppMarkdownHeading node={node} />
if (node.type === 'code')
return <AppMarkdownCode node={node} />
if (node.type === 'link')
return <AppMarkdownLink node={node} />
if (node.type === 'inlineCode')
return <AppMarkdownInlineCode node={node} />
if (node.type === 'video')
return <AppMarkdownVideo node={node} />
throw new Error(
`Not something we can render: ${node.type}`
)
}
これで
実は