A simple example for using Milkdown with Svelte.
Clone the repo: git clone https://github.com/semanticdata/svelte-milkdown.git
.
Install dependencies: pnpm install
.
Run the example: pnpm start
.
Open http://localhost:5173/
in your browser.
By default, milkdown will create editor on the document.body. Alternatively, you can also point out which dom node you want it to load into:
import {rootCtx} from '@milkdown/core'
Editor.make().config((ctx) => {
ctx.set(rootCtx, document.querySelector('#editor'))
})
It's also possible to just pass a selector to rootCtx:
The selector will be passed to document.querySelector to get the dom.
import {rootCtx} from '@milkdown/core'
Editor.make().config((ctx) => {
ctx.set(rootCtx, '#editor')
})
We support three types of default values:
You can set a markdown string as the default value of the editor.
import {defaultValueCtx} from '@milkdown/core'
const defaultValue = '# Hello milkdown'
Editor.make().config((ctx) => {
ctx.set(defaultValueCtx, defaultValue)
})
And then the editor will be rendered with default value.
You can also use HTML as default value.
Let's assume that we have the following html snippets:
<div id="pre">
<h1>Hello milkdown!</h1>
</div>
Then we can use it as a defaultValue with a type specification:
import {defaultValueCtx} from '@milkdown/core'
const defaultValue = {
type: 'html',
dom: document.querySelector('#pre')
}
Editor.make().config((ctx) => {
ctx.set(defaultValueCtx, defaultValue)
})
We can also use a JSON object as a default value.
This JSON object can be obtained by a listener through the listener-plugin, for example:
import {listener, listenerCtx} from '@milkdown/plugin-listener'
let jsonOutput
Editor.make()
.config((ctx) => {
ctx.get(listenerCtx).updated((ctx, doc, prevDoc) => {
jsonOutput = doc.toJSON()
})
})
.use(listener)
Then we can use this jsonOutput as default Value:
import {defaultValueCtx} from '@milkdown/core'
const defaultValue = {
type: 'json',
value: jsonOutput
}
Editor.make().config((ctx) => {
ctx.set(defaultValueCtx, defaultValue)
})
You can inspect the editor's status through the status property.
import {Editor, EditorStatus} from '@milkdown/core'
const editor = Editor.make().use(/*some plugins*/)
assert(editor.status === EditorStatus.Idle)
editor.create().then(() => {
assert(editor.status === EditorStatus.Created)
})
assert(editor.status === EditorStatus.OnCreate)
editor.destroy().then(() => {
assert(editor.status === EditorStatus.Destroyed)
})
assert(editor.status === EditorStatus.OnDestroyed)
You can also listen to the status changes:
import { Editor, EditorStatus } from '@milkdown/core';
const editor = Editor.make().use(/*some plugins*/);
editor.onStatusChange((status: EditorStatus) => {
console.log(status);
});
As mentioned above, you can add a listener to the editor, in order to get it's value when needed.
Markdown Listener
You can add markdown listener to get the editor's contents as a markdown string.
You can add as many listeners as you want, all the listeners will be triggered at once.
import {listener, listenerCtx} from '@milkdown/plugin-listener'
let output = ''
Editor.make()
.config((ctx) => {
ctx.get(listenerCtx).markdownUpdated((ctx, markdown, prevMarkdown) => {
output = markdown
})
})
.use(listener)
You can also listen to the raw prosemirror document node, and do things you want from there.
import {listener, listenerCtx} from '@milkdown/plugin-listener'
let jsonOutput
Editor.make()
.config((ctx) => {
ctx.get(listenerCtx).updated((ctx, doc, prevDoc) => {
jsonOutput = doc.toJSON()
})
})
.use(listener)
For more details about listeners, please check Using Listeners.
You can set the editor to readonly mode by setting the editable property.
import {editorViewOptionsCtx} from '@milkdown/core'
let readonly = false
const editable = () => !readonly
Editor.make().config((ctx) => {
ctx.update(editorViewOptionsCtx, (prev) => ({
...prev,
editable
}))
})
// set to readonly after 5 secs.
setTimeout(() => {
readonly = true
}, 5000)
You can use an action to get the context value in a running editor on demand.
For example, to get the markdown string by running an action:
import {Editor, editorViewCtx, serializerCtx} from '@milkdown/core'
async function playWithEditor() {
const editor = await Editor.make().use(commonmark).create()
const getMarkdown = () =>
editor.action((ctx) => {
const editorView = ctx.get(editorViewCtx)
const serializer = ctx.get(serializerCtx)
return serializer(editorView.state.doc)
})
// get markdown string:
getMarkdown()
}
We provide some macros out of the box, you can use them as actions:
import {insert} from '@milkdown/utils'
editor.action(insert('# Hello milkdown'))
For more details about macros, please check macros.
You can call editor.destroy to destroy an existing editor. You can create a new editor again with editor.create.
await editor.destroy()
// Then create again
await editor.create()
If you just want to recreate the editor, you can use editor.create, it will destroy the old editor and create a new one.
await editor.create()
// This equals to call `editor.destroy` and `editor.create` again.
await editor.create()
If you want to clear the plugins and configs for the editor when calling editor.destroy, you can pass true to editor.destroy.
await editor.destroy(true)
Milkdown provides the following official plugins: | name | description | | :--------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------- | | @milkdown/preset-commonmark | Add commonmark syntax support | | @milkdown/preset-gfm | Add gfm syntax support | | @milkdown/plugin-history | Add undo & redo support | | @milkdown/plugin-clipboard | Add markdown copy & paste support | | @milkdown/plugin-cursor | Add drop & gap cursor | | @milkdown/plugin-listener | Add listener support | | @milkdown/plugin-collaborative | Add collaborative editing support | | @milkdown/plugin-prism | Add prism support for code block highlight | | @milkdown/plugin-math | Add LaTeX support for math | | @milkdown/plugin-tooltip | Add selected tooltip for text | | @milkdown/plugin-slash | Add slash commands support | | @milkdown/plugin-emoji | Add emoji support | | @milkdown/plugin-diagram | Add mermaid diagram support | | @milkdown/plugin-indent | Add tab indent support | | @milkdown/plugin-upload | Add drop and upload support |
The site uses various technologies cobbled together. Here's some of them:
Source code in this repository is available under the MIT License.