import classNames from 'classnames'; import { atom, useAtom } from 'jotai'; import { useRef } from 'react'; import type { Components } from 'react-markdown'; import Markdown from 'react-markdown'; import remarkGfm from 'remark-gfm'; import { useStateWithDeps } from '../hooks/useStateWithDeps'; import { Button } from './core/Button'; import type { EditorProps } from './core/Editor/Editor'; import { Editor } from './core/Editor/Editor'; import { HStack, VStack } from './core/Stacks'; import { Prose } from './Prose'; type ViewMode = 'edit' | 'preview'; interface Props extends Pick { placeholder: string; className?: string; defaultValue: string; onChange: (value: string) => void; name: string; defaultMode?: ViewMode; doneButtonLabel?: string; } const viewModeAtom = atom>({}); export function MarkdownEditor({ className, defaultValue, onChange, name, defaultMode = 'preview', doneButtonLabel = 'Save', forceUpdateKey, ...editorProps }: Props) { const [rawViewMode, setViewMode] = useAtom(viewModeAtom); const [value, setValue] = useStateWithDeps(defaultValue, [forceUpdateKey]); const containerRef = useRef(null); const viewMode = rawViewMode[name] ?? defaultMode; const editor = ( ); const preview = defaultValue.length === 0 ? (

No description

) : ( {value} ); const contents = viewMode === 'preview' ? preview : editor; return (
{contents}
{viewMode === 'preview' && ( )} {viewMode === 'edit' && ( )}
); } const markdownComponents: Partial = { // Ensure links open in external browser by adding target="_blank" a: ({ href, children, ...rest }) => { if (href && !href.match(/https?:\/\//)) { href = `http://${href}`; } return ( {children} ); }, };