feat(islands): add customizable wysiwyg editor @mdxeditor

This commit is contained in:
Julien Oculi 2025-05-13 16:11:24 +02:00
parent 49e26cb816
commit fba0c18aa8
3 changed files with 104 additions and 0 deletions

View file

@ -0,0 +1,84 @@
/** @jsxImportSource react */
// deno-lint-ignore no-unused-vars
import React from 'react'
import {
BoldItalicUnderlineToggles,
ChangeCodeMirrorLanguage,
CodeToggle,
ConditionalContents,
CreateLink,
DiffSourceToggleWrapper,
headingsPlugin,
InsertCodeBlock,
InsertFrontmatter,
InsertImage,
InsertTable,
InsertThematicBreak,
ListsToggle,
markdownShortcutPlugin,
MDXEditor,
Separator,
StrikeThroughSupSubToggles,
toolbarPlugin,
UndoRedo,
} from '@mdxeditor/editor'
export default function MdxEditor(props: { markdown?: string }) {
return (
<MDXEditor
markdown={props.markdown ?? ''}
plugins={[
headingsPlugin(),
markdownShortcutPlugin(),
toolbarPlugin({
toolbarContents: () => <KitchenSinkToolbar />,
}),
]}
/>
)
}
function KitchenSinkToolbar() {
return (
<DiffSourceToggleWrapper>
<ConditionalContents
options={[
{
when: (editor: Record<string, unknown>) =>
editor?.editorType === 'codeblock',
contents: () => <ChangeCodeMirrorLanguage />,
},
{
fallback: () => (
<>
<UndoRedo />
<Separator />
<BoldItalicUnderlineToggles />
<CodeToggle />
<Separator />
<StrikeThroughSupSubToggles />
<Separator />
<ListsToggle />
<Separator />
<CreateLink />
<InsertImage />
<Separator />
<InsertTable />
<InsertThematicBreak />
<Separator />
<InsertCodeBlock />
<Separator />
<InsertFrontmatter />
</>
),
},
]}
/>
</DiffSourceToggleWrapper>
)
}

View file

@ -28,6 +28,7 @@
"imports": {
"@deno/emit": "jsr:@deno/emit@^0.46.0",
"@deno/gfm": "jsr:@deno/gfm@^0.10.0",
"@mdxeditor/editor": "npm:@mdxeditor/editor@^3.32.3",
"@std/fs": "jsr:@std/fs@^1.0.6",
"@std/path": "jsr:@std/path@^1.0.8",
"fresh": "jsr:@fresh/core@^2.0.0-alpha.25",
@ -49,6 +50,8 @@
"@std/json": "jsr:@std/json@^1.0.1",
"@std/streams": "jsr:@std/streams@^0.224.5",
"preact": "npm:preact@^10.24.2",
"react": "npm:react@^19.1.0",
"react-dom": "npm:react-dom@^19.1.0",
"web-push": "npm:web-push@^3.6.7"
},
"compilerOptions": {

17
islands/MdxEditor.tsx Normal file
View file

@ -0,0 +1,17 @@
import { useEffect, useRef } from 'preact/hooks'
import ReactMdxEditor from ':components/react/MdxEditor.tsx'
import React from 'react'
import ReactDOM from 'react-dom/client'
export default function MdxEditor(props: Parameters<typeof ReactMdxEditor>[0]) {
const ref = useRef<HTMLDivElement>(null)
useEffect(() => {
if (ref.current) {
const root = ReactDOM.createRoot(ref.current!)
root.render(React.createElement(ReactMdxEditor, props))
}
}, [])
return <div ref={ref}></div>
}