MilkdownEditor.vue 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. <template>
  2. <Milkdown ref="content" />
  3. </template>
  4. <script setup lang="ts">
  5. import { Editor, rootCtx, defaultValueCtx } from '@milkdown/kit/core'
  6. import { nord } from '@milkdown/theme-nord'
  7. import { Milkdown, useEditor } from '@milkdown/vue'
  8. import {
  9. commonmark, toggleStrongCommand,
  10. toggleEmphasisCommand, toggleLinkCommand,
  11. wrapInOrderedListCommand,
  12. wrapInBlockquoteCommand,
  13. } from '@milkdown/kit/preset/commonmark'
  14. import { getMarkdown, replaceAll, callCommand } from '@milkdown/kit/utils'
  15. import { history } from '@milkdown/kit/plugin/history'
  16. const content = ref<HTMLElement>()
  17. let editor: Editor
  18. useEditor((root) => {
  19. editor = Editor.make()
  20. .config((ctx) => {
  21. ctx.set(rootCtx, root)
  22. ctx.set(defaultValueCtx, `# Write anything
  23. # Hello
  24. ## Hello
  25. ### Hello
  26. #### Hello
  27. ##### Hello
  28. ###### Hello
  29. > Hello, world!
  30. > multiline
  31. >
  32. > quote
  33. > > hm
  34. >
  35. > yeap
  36. Hello world
  37. - hello
  38. - world
  39. - x
  40. - y
  41. 1. hello
  42. 2. write
  43. `)
  44. })
  45. .config(nord)
  46. .use(commonmark)
  47. .use(history)
  48. return editor
  49. },
  50. )
  51. function appendMarkdown(str: string) {
  52. const text = editor.action(getMarkdown())
  53. editor.action(replaceAll(text + str))
  54. }
  55. const toggleBold = () => editor.action(callCommand(toggleStrongCommand.key))
  56. const toggleItalic = () => editor.action(callCommand(toggleEmphasisCommand.key))
  57. const toggleLink = () => editor.action(callCommand(toggleLinkCommand.key))
  58. const toggleList = () => editor.action(callCommand(wrapInOrderedListCommand.key))
  59. const toggleQuote = () => editor.action(callCommand(wrapInBlockquoteCommand.key))
  60. const getMdText = () => editor.action(getMarkdown())
  61. defineExpose({
  62. content,
  63. appendMarkdown,
  64. toggleBold,
  65. toggleItalic,
  66. toggleList,
  67. toggleLink,
  68. toggleQuote,
  69. getMdText,
  70. })
  71. </script>
  72. <style>
  73. @tailwind base;
  74. @tailwind utilities;
  75. h1 { @apply text-4xl font-bold; }
  76. h2 { @apply text-3xl font-bold; }
  77. h3 { @apply text-2xl font-bold; }
  78. h4 { @apply text-xl font-semibold; }
  79. h5 { @apply text-lg font-semibold; }
  80. h6 { @apply text-base font-semibold; }
  81. blockquote {
  82. @apply pl-2 border-l-2 border-primary bg-primary/10 rounded-r-md pr-1;
  83. @apply bg-[url('@/assets/icons/blockquote.svg')] bg-origin-content bg-right-top bg-no-repeat
  84. }
  85. div[contenteditable] {
  86. @apply flex flex-col gap-2;
  87. }
  88. a {
  89. @apply underline decoration-primary/50 text-primary cursor-pointer;
  90. }
  91. ul {
  92. @apply list-outside list-disc ml-4;
  93. }
  94. ol {
  95. @apply list-outside list-decimal ml-4;
  96. }
  97. </style>