diff --git a/examples/basic/src/components/Alert.mdx b/examples/basic/src/components/Alert.mdx index 9d2c1ea90..bc93b7b0b 100644 --- a/examples/basic/src/components/Alert.mdx +++ b/examples/basic/src/components/Alert.mdx @@ -9,7 +9,7 @@ export const meta = doc('Alert') ## Basic usage - Other message + Some message ## Using different kinds @@ -20,3 +20,15 @@ export const meta = doc('Alert') Some message Some message + +## Use with children as a function + + + {() => { + const message = 'Hello world' + + return ( + {message} + ) + }} + diff --git a/packages/docz-core/src/utils/plugin-mdast.ts b/packages/docz-core/src/utils/plugin-mdast.ts new file mode 100644 index 000000000..038c90c47 --- /dev/null +++ b/packages/docz-core/src/utils/plugin-mdast.ts @@ -0,0 +1,61 @@ +import visit from 'unist-util-visit' +import remove from 'unist-util-remove' + +const componentName = (value: string) => { + const match = value.match(/^\<\\?(\w+)/) + return match && match[1] +} + +const valuesFromTreeNodes = (tree: any) => (first: number, last: number) => { + const values: string[] = [] + + if (first !== last) { + for (let i = last; i >= first; i--) { + const found = tree.children[i] + + if (found.children && found.children.length > 0) { + values.push(...found.children.map((child: any) => child.value)) + } + + if (found.value && found.value.length > 0) { + values.push(found.value) + } + + if (i !== first) remove(tree, found) + } + } + + return values +} + +export const plugin = () => (tree: any, file: any) => { + visit(tree, 'html', visitor) + + function visitor(node: any, idx: any, parent: any): void { + try { + if (!node.value || typeof node.value !== 'string') return + + const component = componentName(node.value) + const tagOpen = new RegExp(`^\\<${component}`) + const tagClose = new RegExp(`\\<\\/${component}\\>$`) + + const hasOpenTag = (value: string) => tagOpen.test(value) + const hasCloseTag = (value: string) => tagClose.test(value) + + if (!component || (hasOpenTag(node.value) && hasCloseTag(node.value))) + return + + const tagCloseIdx = tree.children.findIndex( + ({ value }: any) => value && !hasOpenTag(value) && hasCloseTag(value) + ) + + const mergeUntilCloseTag = valuesFromTreeNodes(tree) + const values = mergeUntilCloseTag(idx, tagCloseIdx) + + node.value = values.reverse().join('\n') + } catch (err) { + console.log(err) + return + } + } +}