Files
gitbook/packages/react-contentkit/src/ElementMarkdownClient.tsx
T
Samy Pessé 70c6c9df42 First pass at implementing ContentKit (#69)
* Start

* Try webframe

* Lint and format

* Move to package

* Continue

* Implement card and cleanup contexts

* Start code blocks

* Start rendering image

* Continue with card

* Start stack

* Start text

* Start modal

* Format

* Continue

* Fix TS errors

* Cleanup

* Make markdown work with server components

* Format

* Add visual test

* Lint and format

* Fix lifecycle

* Implement textinput

* Divider

* Remove console logs

* Remove listSpaceIntegrationsBlocks
2024-02-28 14:46:47 +01:00

53 lines
1.5 KiB
TypeScript

'use client';
import { ContentKitMarkdown } from '@gitbook/api';
import { ContentKitClientElementProps } from './types';
import { resolveDynamicBinding } from './dynamic';
import React from 'react';
import { useContentKitClientContext } from './context';
/**
* Client component to render the default markdown output and then update it on state update.
*/
export function ElementMarkdownClient(
props: ContentKitClientElementProps<ContentKitMarkdown> & {
initialMarkdown: string | undefined;
renderMarkdown: (markdown: string) => React.ReactNode | Promise<React.ReactNode>;
children: React.ReactNode;
},
) {
const {
element,
initialMarkdown = element.content,
renderMarkdown,
children: initialChildren,
} = props;
const [children, setChildren] = React.useState<React.ReactNode>(null);
const context = useContentKitClientContext();
const markdown = resolveDynamicBinding(context.state, element.content);
React.useEffect(() => {
if (initialMarkdown === markdown) {
setChildren(null);
return;
}
let cancelled = false;
(async () => {
const parsed = await renderMarkdown(markdown);
if (!cancelled) {
setChildren(parsed);
}
})();
return () => {
cancelled = true;
};
}, [initialMarkdown, markdown]);
return <>{children || initialChildren}</>;
}