editor.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. <script setup lang="ts">
  2. import { Editor, EditorToolbar } from "@enesis/editor"
  3. import { ref } from "vue"
  4. const content = ref(`# Getting Started with the Editor
  5. This document demonstrates all the features the editor supports.
  6. ## Text Formatting
  7. You can use **bold**, *italic*, \`code\`, ~~strikethrough~~, and ^^highlight^^.
  8. ## Links & References
  9. Visit [Nuxt UI](https://ui.nuxt.com) for documentation. Reference [[other pages]] and use #tags for categorization.
  10. ## Tasks & Tables
  11. * TODO Task tracking with six states
  12. * DOING Work in progress
  13. * DONE Completed tasks
  14. | Feature | Status |
  15. |---|---|
  16. | Tables | Done |
  17. | Undo/Redo | Done |
  18. \`\`\`typescript
  19. function greet(name: string): string {
  20. return \`Hello, \${name}!\`
  21. }
  22. \`\`\`
  23. > [!NOTE] Use callouts for important information
  24. ## Properties
  25. author:: Editor Demo
  26. status:: published`)
  27. </script>
  28. <template>
  29. <UPage>
  30. <UPageHeader
  31. title="Editor"
  32. description="Multi-block editor shell with insertion zones, toolbar, drag-to-reorder, and unified undo/redo."
  33. />
  34. <UPageBody>
  35. <div class="space-y-8">
  36. <section class="space-y-4">
  37. <p class="text-sm text-muted leading-relaxed">
  38. The <code class="text-xs font-mono px-1 py-0.5 rounded bg-elevated border border-default">Editor</code> component manages a list of blocks with insertion zones between them.
  39. Each block is a <code class="text-xs font-mono px-1 py-0.5 rounded bg-elevated border border-default">*</code> list item in the unified markdown string.
  40. Drag the <span class="i-lucide-grip-vertical size-4 inline-block align-middle text-muted" /> handle to reorder blocks.
  41. </p>
  42. <div class="rounded-lg border border-default dark:bg-neutral-950/50 p-4 sm:p-8 rounded-t-md overflow-hidden">
  43. <Editor v-model:content="content" :focused="true" marker-mode="always-visible">
  44. <template #toolbar="{ handlers, selectionVersion, canUndo, canRedo, undo, redo }">
  45. <EditorToolbar
  46. :handlers="handlers"
  47. :selection-version="selectionVersion"
  48. :can-undo="canUndo"
  49. :can-redo="canRedo"
  50. :undo="undo"
  51. :redo="redo"
  52. />
  53. </template>
  54. </Editor>
  55. </div>
  56. </section>
  57. <section class="space-y-4">
  58. <h2 class="text-lg font-semibold text-highlighted">Props</h2>
  59. <div class="rounded-lg border border-default overflow-hidden">
  60. <table class="w-full border-separate border-spacing-0 rounded-md text-sm">
  61. <thead class="bg-muted">
  62. <tr>
  63. <th class="py-3 px-4 font-semibold text-sm border-e border-b first:border-s border-t border-muted text-left">Prop</th>
  64. <th class="py-3 px-4 font-semibold text-sm border-e border-b first:border-s border-t border-muted text-left">Type</th>
  65. <th class="py-3 px-4 font-semibold text-sm border-e border-b first:border-s border-t border-muted text-left">Default</th>
  66. <th class="py-3 px-4 font-semibold text-sm border-e border-b first:border-s border-t border-muted text-left">Description</th>
  67. </tr>
  68. </thead>
  69. <tbody>
  70. <tr><td class="py-3 px-4 text-sm align-top border-e border-b first:border-s border-muted text-left"><code class="md-code">content</code></td><td class="py-3 px-4 text-sm align-top border-e border-b first:border-s border-muted text-left"><code class="md-code">string</code></td><td class="py-3 px-4 text-sm align-top border-e border-b first:border-s border-muted text-left">—</td><td class="py-3 px-4 text-sm align-top border-e border-b first:border-s border-muted text-left text-muted">Full document markdown (v-model)</td></tr>
  71. <tr><td class="py-3 px-4 text-sm align-top border-e border-b first:border-s border-muted text-left"><code class="md-code">focused</code></td><td class="py-3 px-4 text-sm align-top border-e border-b first:border-s border-muted text-left"><code class="md-code">boolean</code></td><td class="py-3 px-4 text-sm align-top border-e border-b first:border-s border-muted text-left"><code class="md-code">false</code></td><td class="py-3 px-4 text-sm align-top border-e border-b first:border-s border-muted text-left text-muted">Focus first block on mount</td></tr>
  72. <tr><td class="py-3 px-4 text-sm align-top border-e border-b first:border-s border-muted text-left"><code class="md-code">markerMode</code></td><td class="py-3 px-4 text-sm align-top border-e border-b first:border-s border-muted text-left"><code class="md-code">'live-preview' \| 'always-visible'</code></td><td class="py-3 px-4 text-sm align-top border-e border-b first:border-s border-muted text-left"><code class="md-code">'live-preview'</code></td><td class="py-3 px-4 text-sm align-top border-e border-b first:border-s border-muted text-left text-muted">Decorator visibility mode</td></tr>
  73. <tr><td class="py-3 px-4 text-sm align-top border-e border-b first:border-s border-muted text-left"><code class="md-code">theme</code></td><td class="py-3 px-4 text-sm align-top border-e border-b first:border-s border-muted text-left"><code class="md-code">ThemeInput</code></td><td class="py-3 px-4 text-sm align-top border-e border-b first:border-s border-muted text-left">—</td><td class="py-3 px-4 text-sm align-top border-e border-b first:border-s border-muted text-left text-muted">CSS-variable theme preset</td></tr>
  74. <tr><td class="py-3 px-4 text-sm align-top border-e border-b first:border-s border-muted text-left"><code class="md-code">keyBinding</code></td><td class="py-3 px-4 text-sm align-top border-e border-b first:border-s border-muted text-left"><code class="md-code">KeyBinding</code></td><td class="py-3 px-4 text-sm align-top border-e border-b first:border-s border-muted text-left"><code class="md-code">default</code></td><td class="py-3 px-4 text-sm align-top border-e border-b first:border-s border-muted text-left text-muted">Swappable keyboard handler</td></tr>
  75. <tr><td class="py-3 px-4 text-sm align-top border-e border-b first:border-s border-muted text-left"><code class="md-code">extraPatterns</code></td><td class="py-3 px-4 text-sm align-top border-e border-b first:border-s border-muted text-left"><code class="md-code">PatternSpec[]</code></td><td class="py-3 px-4 text-sm align-top border-e border-b first:border-s border-muted text-left">—</td><td class="py-3 px-4 text-sm align-top border-e border-b first:border-s border-muted text-left text-muted">Custom suggestion triggers</td></tr>
  76. </tbody>
  77. </table>
  78. </div>
  79. </section>
  80. <section class="space-y-4">
  81. <h2 class="text-lg font-semibold text-highlighted">Slot: #toolbar</h2>
  82. <div class="rounded-lg border border-default overflow-hidden">
  83. <table class="w-full border-separate border-spacing-0 rounded-md text-sm">
  84. <thead class="bg-muted">
  85. <tr>
  86. <th class="py-3 px-4 font-semibold text-sm border-e border-b first:border-s border-t border-muted text-left">Binding</th>
  87. <th class="py-3 px-4 font-semibold text-sm border-e border-b first:border-s border-t border-muted text-left">Type</th>
  88. <th class="py-3 px-4 font-semibold text-sm border-e border-b first:border-s border-t border-muted text-left">Description</th>
  89. </tr>
  90. </thead>
  91. <tbody>
  92. <tr><td class="py-3 px-4 text-sm align-top border-e border-b first:border-s border-muted text-left"><code class="md-code">handlers</code></td><td class="py-3 px-4 text-sm align-top border-e border-b first:border-s border-muted text-left"><code class="md-code">FormattingHandlers</code></td><td class="py-3 px-4 text-sm align-top border-e border-b first:border-s border-muted text-left text-muted">Toggle/wrap/insert helpers</td></tr>
  93. <tr><td class="py-3 px-4 text-sm align-top border-e border-b first:border-s border-muted text-left"><code class="md-code">selectionVersion</code></td><td class="py-3 px-4 text-sm align-top border-e border-b first:border-s border-muted text-left"><code class="md-code">number</code></td><td class="py-3 px-4 text-sm align-top border-e border-b first:border-s border-muted text-left text-muted">Bumped on cursor move</td></tr>
  94. <tr><td class="py-3 px-4 text-sm align-top border-e border-b first:border-s border-muted text-left"><code class="md-code">canUndo / canRedo</code></td><td class="py-3 px-4 text-sm align-top border-e border-b first:border-s border-muted text-left"><code class="md-code">boolean</code></td><td class="py-3 px-4 text-sm align-top border-e border-b first:border-s border-muted text-left text-muted">Undo/redo availability</td></tr>
  95. <tr><td class="py-3 px-4 text-sm align-top border-e border-b first:border-s border-muted text-left"><code class="md-code">undo / redo</code></td><td class="py-3 px-4 text-sm align-top border-e border-b first:border-s border-muted text-left"><code class="md-code">() => void</code></td><td class="py-3 px-4 text-sm align-top border-e border-b first:border-s border-muted text-left text-muted">Undo/redo functions</td></tr>
  96. </tbody>
  97. </table>
  98. </div>
  99. </section>
  100. <section class="space-y-4">
  101. <h2 class="text-lg font-semibold text-highlighted">Events</h2>
  102. <div class="rounded-lg border border-default overflow-hidden">
  103. <table class="w-full border-separate border-spacing-0 rounded-md text-sm">
  104. <thead class="bg-muted">
  105. <tr>
  106. <th class="py-3 px-4 font-semibold text-sm border-e border-b first:border-s border-t border-muted text-left">Event</th>
  107. <th class="py-3 px-4 font-semibold text-sm border-e border-b first:border-s border-t border-muted text-left">Payload</th>
  108. <th class="py-3 px-4 font-semibold text-sm border-e border-b first:border-s border-t border-muted text-left">Description</th>
  109. </tr>
  110. </thead>
  111. <tbody>
  112. <tr><td class="py-3 px-4 text-sm align-top border-e border-b first:border-s border-muted text-left"><code class="md-code">focus</code></td><td class="py-3 px-4 text-sm align-top border-e border-b first:border-s border-muted text-left"><code class="md-code">{ view, handlers }</code></td><td class="py-3 px-4 text-sm align-top border-e border-b first:border-s border-muted text-left text-muted">Block gained focus</td></tr>
  113. <tr><td class="py-3 px-4 text-sm align-top border-e border-b first:border-s border-muted text-left"><code class="md-code">blur</code></td><td class="py-3 px-4 text-sm align-top border-e border-b first:border-s border-muted text-left">—</td><td class="py-3 px-4 text-sm align-top border-e border-b first:border-s border-muted text-left text-muted">All blocks lost focus</td></tr>
  114. <tr><td class="py-3 px-4 text-sm align-top border-e border-b first:border-s border-muted text-left"><code class="md-code">selection-change</code></td><td class="py-3 px-4 text-sm align-top border-e border-b first:border-s border-muted text-left"><code class="md-code">{ from, to, empty }</code></td><td class="py-3 px-4 text-sm align-top border-e border-b first:border-s border-muted text-left text-muted">Selection changed</td></tr>
  115. <tr><td class="py-3 px-4 text-sm align-top border-e border-b first:border-s border-muted text-left"><code class="md-code">error</code></td><td class="py-3 px-4 text-sm align-top border-e border-b first:border-s border-muted text-left"><code class="md-code">{ code, message?, blockId? }</code></td><td class="py-3 px-4 text-sm align-top border-e border-b first:border-s border-muted text-left text-muted">Mount failure or KaTeX error</td></tr>
  116. </tbody>
  117. </table>
  118. </div>
  119. </section>
  120. <section class="space-y-4">
  121. <h2 class="text-lg font-semibold text-highlighted">Exposed Methods</h2>
  122. <div class="rounded-lg border border-default overflow-hidden">
  123. <table class="w-full border-separate border-spacing-0 rounded-md text-sm">
  124. <thead class="bg-muted">
  125. <tr>
  126. <th class="py-3 px-4 font-semibold text-sm border-e border-b first:border-s border-t border-muted text-left">Method</th>
  127. <th class="py-3 px-4 font-semibold text-sm border-e border-b first:border-s border-t border-muted text-left">Signature</th>
  128. <th class="py-3 px-4 font-semibold text-sm border-e border-b first:border-s border-t border-muted text-left">Description</th>
  129. </tr>
  130. </thead>
  131. <tbody>
  132. <tr><td class="py-3 px-4 text-sm align-top border-e border-b first:border-s border-muted text-left"><code class="md-code">undo</code></td><td class="py-3 px-4 text-sm align-top border-e border-b first:border-s border-muted text-left"><code class="md-code">() => void</code></td><td class="py-3 px-4 text-sm align-top border-e border-b first:border-s border-muted text-left text-muted">Undo last operation</td></tr>
  133. <tr><td class="py-3 px-4 text-sm align-top border-e border-b first:border-s border-muted text-left"><code class="md-code">redo</code></td><td class="py-3 px-4 text-sm align-top border-e border-b first:border-s border-muted text-left"><code class="md-code">() => void</code></td><td class="py-3 px-4 text-sm align-top border-e border-b first:border-s border-muted text-left text-muted">Redo last undone operation</td></tr>
  134. <tr><td class="py-3 px-4 text-sm align-top border-e border-b first:border-s border-muted text-left"><code class="md-code">canUndo / canRedo</code></td><td class="py-3 px-4 text-sm align-top border-e border-b first:border-s border-muted text-left"><code class="md-code">Ref&lt;boolean&gt;</code></td><td class="py-3 px-4 text-sm align-top border-e border-b first:border-s border-muted text-left text-muted">Undo/redo availability</td></tr>
  135. <tr><td class="py-3 px-4 text-sm align-top border-e border-b first:border-s border-muted text-left"><code class="md-code">getHistoryState</code></td><td class="py-3 px-4 text-sm align-top border-e border-b first:border-s border-muted text-left"><code class="md-code">() => { canUndo, canRedo }</code></td><td class="py-3 px-4 text-sm align-top border-e border-b first:border-s border-muted text-left text-muted">Inspect undo/redo state</td></tr>
  136. <tr><td class="py-3 px-4 text-sm align-top border-e border-b first:border-s border-muted text-left"><code class="md-code">applyHistory</code></td><td class="py-3 px-4 text-sm align-top border-e border-b first:border-s border-muted text-left"><code class="md-code">(op) => void</code></td><td class="py-3 px-4 text-sm align-top border-e border-b first:border-s border-muted text-left text-muted">Push operation to history stack</td></tr>
  137. </tbody>
  138. </table>
  139. </div>
  140. </section>
  141. </div>
  142. </UPageBody>
  143. </UPage>
  144. </template>