[{"data":1,"prerenderedAt":2324},["ShallowReactive",2],{"navigation_docs":3,"-tutorial-compose-features":412,"-tutorial-compose-features-surround":2319},[4,38,84,326,386],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":37},"Getting started","i-lucide-rocket","\u002Fgetting-started","1.getting-started",[10,15,20,24,28,32],{"title":11,"path":12,"stem":13,"icon":14},"Introduction","\u002Fgetting-started\u002Fintroduction","1.getting-started\u002F1.introduction","i-lucide-book-open",{"title":16,"path":17,"stem":18,"icon":19},"Installation","\u002Fgetting-started\u002Finstallation","1.getting-started\u002F2.installation","i-lucide-download",{"title":21,"path":22,"stem":23,"icon":6},"Quick start: Nuxt","\u002Fgetting-started\u002Fquick-start-nuxt","1.getting-started\u002F3.quick-start-nuxt",{"title":25,"path":26,"stem":27,"icon":6},"Quick start: plain Vue","\u002Fgetting-started\u002Fquick-start-vue","1.getting-started\u002F4.quick-start-vue",{"title":29,"path":30,"stem":31,"icon":6},"Quick start: React","\u002Fgetting-started\u002Fquick-start-react","1.getting-started\u002F5.quick-start-react",{"title":33,"path":34,"stem":35,"icon":36},"Glossary","\u002Fgetting-started\u002Fglossary","1.getting-started\u002F6.glossary","i-lucide-book-a",false,{"title":39,"icon":40,"path":41,"stem":42,"children":43,"page":37},"Tutorial","i-lucide-graduation-cap","\u002Ftutorial","2.tutorial",[44,49,54,59,64,69,74,79],{"title":45,"path":46,"stem":47,"icon":48},"Tutorial: overview","\u002Ftutorial\u002Foverview","2.tutorial\u002F1.overview","i-lucide-map",{"title":50,"path":51,"stem":52,"icon":53},"Chapter 2: A simple editor","\u002Ftutorial\u002Fsimple-editor","2.tutorial\u002F2.simple-editor","i-lucide-pencil",{"title":55,"path":56,"stem":57,"icon":58},"Chapter 3: Compose features","\u002Ftutorial\u002Fcompose-features","2.tutorial\u002F3.compose-features","i-lucide-blocks",{"title":60,"path":61,"stem":62,"icon":63},"Chapter 4: Your own block, path A","\u002Ftutorial\u002Fown-block-path-a","2.tutorial\u002F4.own-block-path-a","i-lucide-square-plus",{"title":65,"path":66,"stem":67,"icon":68},"Chapter 5: Your own feature, path B","\u002Ftutorial\u002Fown-feature-path-b","2.tutorial\u002F5.own-feature-path-b","i-lucide-puzzle",{"title":70,"path":71,"stem":72,"icon":73},"Chapter 6: Backend and collaboration","\u002Ftutorial\u002Fbackend-and-collaboration","2.tutorial\u002F6.backend-and-collaboration","i-lucide-users",{"title":75,"path":76,"stem":77,"icon":78},"Chapter 7: AI","\u002Ftutorial\u002Fai","2.tutorial\u002F7.ai","i-lucide-sparkles",{"title":80,"path":81,"stem":82,"icon":83},"Chapter 8: The React surface","\u002Ftutorial\u002Freact-surface","2.tutorial\u002F8.react-surface","i-lucide-atom",{"title":85,"icon":14,"path":86,"stem":87,"children":88,"page":37},"Guides","\u002Fguides","3.guides",[89,93,98,103,108,112,116,121,126,130,134,139,144,149,154,159,164,169,174,179,184,189,194,199,204,209,213,218,223,228,233,237,242,247,251,256,261,266,271,276,281,286,291,295,302,307,311,316,321],{"title":90,"path":91,"stem":92,"icon":58},"Feature composition and entries","\u002Fguides\u002Fcomposition","3.guides\u002F1.composition",{"title":94,"path":95,"stem":96,"icon":97},"Media, mentions and transcript features","\u002Fguides\u002Fmedia-mentions-transcript","3.guides\u002F10.media-mentions-transcript","i-lucide-image",{"title":99,"path":100,"stem":101,"icon":102},"Authors and comments","\u002Fguides\u002Fauthors-and-comments","3.guides\u002F11.authors-and-comments","i-lucide-message-square-text",{"title":104,"path":105,"stem":106,"icon":107},"Themes (Obsidian)","\u002Fguides\u002Fthemes","3.guides\u002F12.themes","i-lucide-palette",{"title":109,"path":110,"stem":111,"icon":58},"Composites and the settings UI","\u002Fguides\u002Fcomposites","3.guides\u002F13.composites",{"title":113,"path":114,"stem":115,"icon":78},"AI","\u002Fguides\u002Fai","3.guides\u002F14.ai",{"title":117,"path":118,"stem":119,"icon":120},"Document tree","\u002Fguides\u002Fdocument-tree","3.guides\u002F15.document-tree","i-lucide-folder-tree",{"title":122,"path":123,"stem":124,"icon":125},"Markdown and code","\u002Fguides\u002Fmarkdown-and-code","3.guides\u002F16.markdown-and-code","i-lucide-file-code",{"title":127,"path":128,"stem":129,"icon":83},"Advanced editor in React","\u002Fguides\u002Fadvanced-react","3.guides\u002F17.advanced-react",{"title":131,"path":132,"stem":133,"icon":6},"Kitchen sink: learning path","\u002Fguides\u002Fadvanced-nuxt-example","3.guides\u002F18.advanced-nuxt-example",{"title":135,"path":136,"stem":137,"icon":138},"Production","\u002Fguides\u002Fproduction","3.guides\u002F19.production","i-lucide-server",{"title":140,"path":141,"stem":142,"icon":143},"Register the Nuxt module","\u002Fguides\u002Fnuxt-module","3.guides\u002F2.nuxt-module","i-lucide-package",{"title":145,"path":146,"stem":147,"icon":148},"Storage adapters, comment stores, Nitro host","\u002Fguides\u002Fstorage-adapters","3.guides\u002F20.storage-adapters","i-lucide-database",{"title":150,"path":151,"stem":152,"icon":153},"Migrating from #tiptap-editor","\u002Fguides\u002Fmigration","3.guides\u002F21.migration","i-lucide-arrow-right-left",{"title":155,"path":156,"stem":157,"icon":158},"Content tree mechanics","\u002Fguides\u002Fcontent-tree","3.guides\u002F22.content-tree","i-lucide-git-fork",{"title":160,"path":161,"stem":162,"icon":163},"Block capabilities, abilities and actions","\u002Fguides\u002Fblock-capabilities","3.guides\u002F23.block-capabilities","i-lucide-shield-check",{"title":165,"path":166,"stem":167,"icon":168},"Block types in code and JSON","\u002Fguides\u002Fblock-types","3.guides\u002F24.block-types","i-lucide-shapes",{"title":170,"path":171,"stem":172,"icon":173},"Derive methods and the Derivation index","\u002Fguides\u002Fderive-methods","3.guides\u002F25.derive-methods","i-lucide-git-branch-plus",{"title":175,"path":176,"stem":177,"icon":178},"Block properties and Property definitions","\u002Fguides\u002Fblock-properties","3.guides\u002F26.block-properties","i-lucide-sliders-horizontal",{"title":180,"path":181,"stem":182,"icon":183},"Image studio","\u002Fguides\u002Fimage-studio","3.guides\u002F27.image-studio","i-lucide-image-plus",{"title":185,"path":186,"stem":187,"icon":188},"Prüfung and Freigabestatus","\u002Fguides\u002Fpruefung","3.guides\u002F28.pruefung","i-lucide-stamp",{"title":190,"path":191,"stem":192,"icon":193},"Workspace: find, read, reference and embed Blocks across Documents","\u002Fguides\u002Fworkspace","3.guides\u002F29.workspace","i-lucide-network",{"title":195,"path":196,"stem":197,"icon":198},"EditorPorts: auth and storage","\u002Fguides\u002Feditor-ports","3.guides\u002F3.editor-ports","i-lucide-plug",{"title":200,"path":201,"stem":202,"icon":203},"Collections: an ordered list of Blocks","\u002Fguides\u002Fcollections","3.guides\u002F30.collections","i-lucide-list-checks",{"title":205,"path":206,"stem":207,"icon":208},"Data views: a query shown as table, list or board","\u002Fguides\u002Fdata-views","3.guides\u002F31.data-views","i-lucide-table-properties",{"title":210,"path":211,"stem":212,"icon":193},"Explore: backlinks, related Blocks and the trail","\u002Fguides\u002Fexplore","3.guides\u002F32.explore",{"title":214,"path":215,"stem":216,"icon":217},"Render: export a Block or a Document to a file","\u002Fguides\u002Frender","3.guides\u002F33.render","i-lucide-file-output",{"title":219,"path":220,"stem":221,"icon":222},"Importers: what a dropped file becomes","\u002Fguides\u002Fimporters","3.guides\u002F34.importers","i-lucide-file-input",{"title":224,"path":225,"stem":226,"icon":227},"Templates: start a Document from a Dokumentvorlage","\u002Fguides\u002Ftemplates","3.guides\u002F35.templates","i-lucide-file-stack",{"title":229,"path":230,"stem":231,"icon":232},"Citations","\u002Fguides\u002Fcitations","3.guides\u002F36.citations","i-lucide-quote",{"title":234,"path":235,"stem":236,"icon":163},"AI proposals and the export check","\u002Fguides\u002Fexport-check","3.guides\u002F37.export-check",{"title":238,"path":239,"stem":240,"icon":241},"Query: filter, sort, group and total Blocks","\u002Fguides\u002Fquery","3.guides\u002F38.query","i-lucide-list-filter",{"title":243,"path":244,"stem":245,"icon":246},"Edges: backlinks and authored connections","\u002Fguides\u002Fedges","3.guides\u002F39.edges","i-lucide-link-2",{"title":248,"path":249,"stem":250,"icon":163},"Server routes and authentication","\u002Fguides\u002Froutes-and-auth","3.guides\u002F4.routes-and-auth",{"title":252,"path":253,"stem":254,"icon":255},"Speech: text to audio, and subtitle files","\u002Fguides\u002Fspeech","3.guides\u002F41.speech","i-lucide-audio-lines",{"title":257,"path":258,"stem":259,"icon":260},"Graph: the Edges around a Block","\u002Fguides\u002Fgraph","3.guides\u002F42.graph","i-lucide-waypoints",{"title":262,"path":263,"stem":264,"icon":265},"PDF viewer: passages, anchors and quotes","\u002Fguides\u002Fpdf-viewer","3.guides\u002F43.pdf-viewer","i-lucide-file-search",{"title":267,"path":268,"stem":269,"icon":270},"Obsidian: import and export a vault","\u002Fguides\u002Fobsidian","3.guides\u002F44.obsidian","i-lucide-folder-input",{"title":272,"path":273,"stem":274,"icon":275},"Typst: render a Document as a PDF with citations","\u002Fguides\u002Ftypst","3.guides\u002F45.typst","i-lucide-file-text",{"title":277,"path":278,"stem":279,"icon":280},"Audio: read aloud, mixdown and ElevenLabs","\u002Fguides\u002Faudio","3.guides\u002F46.audio","i-lucide-audio-waveform",{"title":282,"path":283,"stem":284,"icon":285},"Slides: decks, slide layouts and exports","\u002Fguides\u002Fslides","3.guides\u002F47.slides","i-lucide-presentation",{"title":287,"path":288,"stem":289,"icon":290},"Knowledge graph: sources and concepts beside the Documents","\u002Fguides\u002Fknowledge-graph","3.guides\u002F49.knowledge-graph","i-lucide-share-2",{"title":292,"path":293,"stem":294,"icon":78},"AI configuration and secrets","\u002Fguides\u002Fai-configuration","3.guides\u002F5.ai-configuration",{"title":296,"path":297,"stem":298,"children":299,"icon":301},"Index on Postgres: typos, meaning and SQL pushdown","\u002Fguides\u002Findex-pg","3.guides\u002F50.index-pg",[300],{"title":296,"path":297,"stem":298,"icon":301},"i-lucide-database-zap",{"title":303,"path":304,"stem":305,"icon":306},"Charts: bar, line, pie and scatter over a query","\u002Fguides\u002Fcharts","3.guides\u002F51.charts","i-lucide-chart-column",{"title":308,"path":309,"stem":310,"icon":73},"Collaboration on the client","\u002Fguides\u002Fcollaboration","3.guides\u002F6.collaboration",{"title":312,"path":313,"stem":314,"icon":315},"Block UI (drag handle, hover actions)","\u002Fguides\u002Fblock-ui","3.guides\u002F7.block-ui","i-lucide-grip-vertical",{"title":317,"path":318,"stem":319,"icon":320},"Settings and app lifetime","\u002Fguides\u002Fsettings","3.guides\u002F8.settings","i-lucide-settings",{"title":322,"path":323,"stem":324,"icon":325},"Language","\u002Fguides\u002Flanguage","3.guides\u002F9.language","i-lucide-languages",{"title":327,"icon":14,"path":328,"stem":329,"children":330,"page":37},"Reference","\u002Freference","4.reference",[331,335,339,344,348,352,356,360,364,368,373,378,382],{"title":332,"path":333,"stem":334,"icon":143},"Public exports","\u002Freference\u002Fexports","4.reference\u002F1.exports",{"title":336,"path":337,"stem":338,"icon":173},"Derive method contract","\u002Freference\u002Fderive-methods","4.reference\u002F10.derive-methods",{"title":340,"path":341,"stem":342,"icon":343},"Changelog","\u002Freference\u002Fchangelog","4.reference\u002F11.changelog","i-lucide-history",{"title":345,"path":346,"stem":347,"icon":217},"Renderer port","\u002Freference\u002Frenderer-port","4.reference\u002F12.renderer-port",{"title":349,"path":350,"stem":351,"icon":255},"Speech port","\u002Freference\u002Fspeech-port","4.reference\u002F13.speech-port",{"title":353,"path":354,"stem":355,"icon":58},"Presets and features","\u002Freference\u002Fpresets-and-features","4.reference\u002F2.presets-and-features",{"title":357,"path":358,"stem":359,"icon":68},"Feature contract","\u002Freference\u002Ffeature-contract","4.reference\u002F3.feature-contract",{"title":361,"path":362,"stem":363,"icon":107},"CSS and UI-provider requirements","\u002Freference\u002Fcss-and-ui","4.reference\u002F4.css-and-ui",{"title":365,"path":366,"stem":367,"icon":148},"Vue-free advanced schema","\u002Freference\u002Fadvanced-schema","4.reference\u002F5.advanced-schema",{"title":369,"path":370,"stem":371,"icon":372},"Dependency rules","\u002Freference\u002Fdependency-rules","4.reference\u002F6.dependency-rules","i-lucide-git-branch",{"title":374,"path":375,"stem":376,"icon":377},"Commands","\u002Freference\u002Fcommands","4.reference\u002F7.commands","i-lucide-terminal",{"title":379,"path":380,"stem":381,"icon":163},"Block capability contract","\u002Freference\u002Fblock-capabilities","4.reference\u002F8.block-capabilities",{"title":383,"path":384,"stem":385,"icon":168},"Block type contract","\u002Freference\u002Fblock-types","4.reference\u002F9.block-types",{"title":387,"path":388,"stem":389,"children":390,"icon":393},"AI agents","\u002Fai-agents","5.ai-agents\u002F1.index",[391,394,398,402,407],{"title":392,"path":388,"stem":389,"icon":393},"Overview","i-lucide-bot",{"title":395,"path":396,"stem":397,"icon":198},"Integrate the editor","\u002Fai-agents\u002Fintegrate","5.ai-agents\u002F2.integrate",{"title":399,"path":400,"stem":401,"icon":68},"Add a block or feature","\u002Fai-agents\u002Fextend","5.ai-agents\u002F3.extend",{"title":403,"path":404,"stem":405,"icon":406},"Pitfalls and invariants","\u002Fai-agents\u002Finvariants","5.ai-agents\u002F4.invariants","i-lucide-shield-alert",{"title":408,"path":409,"stem":410,"icon":411},"Verify","\u002Fai-agents\u002Fverify","5.ai-agents\u002F5.verify","i-lucide-check-check",{"id":413,"title":55,"body":414,"description":2312,"extension":2313,"links":2314,"meta":2315,"navigation":2316,"path":56,"seo":2317,"stem":57,"__hash__":2318},"docs\u002F2.tutorial\u002F3.compose-features.md",{"type":415,"value":416,"toc":2302},"minimark",[417,438,453,456,461,468,1265,1279,1365,1391,1394,1455,1459,1486,1763,1766,1939,1973,1977,2014,2018,2024,2086,2091,2098,2125,2237,2276,2280,2289,2293,2298],[418,419,420,424,425,429,430,433,434,437],"p",{},[421,422,423],"code",{},"SimpleEditor"," is a fixed composition. An editor is really a list of ",[426,427,428],"strong",{},"features",", and ",[421,431,432],{},"EditorSurface"," mounts any list you build with ",[421,435,436],{},"defineEditor",". In this chapter the meeting-notes editor gets people and tag mentions, image drop, tables and a drag handle by adding four entries to that list.",[418,439,440,441,444,445,448,449,452],{},"Try it. Type ",[421,442,443],{},"@a"," for people, ",[421,446,447],{},"#i"," for tags, ",[421,450,451],{},"\u002F"," for the block menu, drop an image on the page, or insert a table from the toolbar:",[454,455],"demo-composed-editor",{},[457,458,460],"h2",{"id":459},"the-preset","The preset",[418,462,463,464,467],{},"Each feature is one factory you import from its own entry, so a feature you do not import is not in your bundle. ",[421,465,466],{},"defineEditor({ features })"," keeps the given order: toolbar groups, menu entries and the schema follow it. The component of the demo above is the whole code:",[469,470,476],"pre",{"className":471,"code":472,"filename":473,"language":474,"meta":475,"style":475},"language-vue shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u003Cscript setup lang=\"ts\">\nimport { coreContentFeature, coreUiFeature, defineEditor } from '@skaile\u002Fforge-editor\u002Fcore'\nimport { blockUiFeature } from '@skaile\u002Fforge-editor\u002Fblock-ui\u002Fvue'\nimport { mediaFeature } from '@skaile\u002Fforge-editor\u002Fmedia\u002Fvue'\nimport { mentionsFeature } from '@skaile\u002Fforge-editor\u002Fmentions'\nimport { tablesFeature } from '@skaile\u002Fforge-editor\u002Ftables'\nimport { EditorSurface, EditorToolbar } from '@skaile\u002Fforge-editor\u002Fvue'\nimport type { Editor, JSONContent } from '@tiptap\u002Fvue-3'\nimport { ref, shallowRef } from 'vue'\n\n\u002F\u002F An editor is the sum of its features. Mentions and tags come from the `backend` the app context carries.\nconst preset = defineEditor({\n  features: [coreContentFeature(), coreUiFeature(), mentionsFeature(), mediaFeature(), tablesFeature(), blockUiFeature()],\n})\n\nconst content = ref\u003CJSONContent>({\n  type: 'doc',\n  content: [\n    { type: 'heading', attrs: { level: 1 }, content: [{ type: 'text', text: 'Meeting notes' }] },\n    {\n      type: 'paragraph',\n      content: [{ type: 'text', text: 'Type @ to mention a person, # to add a tag, \u002F for the block menu, or drop an image.' }],\n    },\n  ],\n})\nconst editor = shallowRef\u003CEditor>()\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003C!-- Global MDC components skip Nuxt's `.client` handling, so the page's server render would reach the editor: no UI kit there. -->\n  \u003CClientOnly>\n    \u003Cdiv class=\"not-prose my-6 flex flex-col gap-3\">\n      \u003CEditorToolbar :editor=\"editor\" \u002F>\n      \u003Cdiv class=\"min-h-64 rounded-lg border border-default p-4\">\n        \u003CEditorSurface v-model=\"content\" :preset=\"preset\" @ready=\"editor = $event\" \u002F>\n      \u003C\u002Fdiv>\n    \u003C\u002Fdiv>\n  \u003C\u002FClientOnly>\n\u003C\u002Ftemplate>\n","docs\u002Fapp\u002Fcomponents\u002Fcontent\u002FDemoComposedEditor.client.vue","vue","",[421,477,478,513,553,574,595,616,637,663,692,717,724,731,751,803,812,817,842,860,871,952,958,975,1017,1023,1031,1038,1060,1070,1075,1085,1091,1102,1125,1151,1171,1226,1236,1246,1256],{"__ignoreMap":475},[479,480,483,487,491,495,498,501,504,508,510],"span",{"class":481,"line":482},"line",1,[479,484,486],{"class":485},"sMK4o","\u003C",[479,488,490],{"class":489},"swJcz","script",[479,492,494],{"class":493},"spNyl"," setup",[479,496,497],{"class":493}," lang",[479,499,500],{"class":485},"=",[479,502,503],{"class":485},"\"",[479,505,507],{"class":506},"sfazB","ts",[479,509,503],{"class":485},[479,511,512],{"class":485},">\n",[479,514,516,520,523,527,530,533,535,538,541,544,547,550],{"class":481,"line":515},2,[479,517,519],{"class":518},"s7zQu","import",[479,521,522],{"class":485}," {",[479,524,526],{"class":525},"sTEyZ"," coreContentFeature",[479,528,529],{"class":485},",",[479,531,532],{"class":525}," coreUiFeature",[479,534,529],{"class":485},[479,536,537],{"class":525}," defineEditor",[479,539,540],{"class":485}," }",[479,542,543],{"class":518}," from",[479,545,546],{"class":485}," '",[479,548,549],{"class":506},"@skaile\u002Fforge-editor\u002Fcore",[479,551,552],{"class":485},"'\n",[479,554,556,558,560,563,565,567,569,572],{"class":481,"line":555},3,[479,557,519],{"class":518},[479,559,522],{"class":485},[479,561,562],{"class":525}," blockUiFeature",[479,564,540],{"class":485},[479,566,543],{"class":518},[479,568,546],{"class":485},[479,570,571],{"class":506},"@skaile\u002Fforge-editor\u002Fblock-ui\u002Fvue",[479,573,552],{"class":485},[479,575,577,579,581,584,586,588,590,593],{"class":481,"line":576},4,[479,578,519],{"class":518},[479,580,522],{"class":485},[479,582,583],{"class":525}," mediaFeature",[479,585,540],{"class":485},[479,587,543],{"class":518},[479,589,546],{"class":485},[479,591,592],{"class":506},"@skaile\u002Fforge-editor\u002Fmedia\u002Fvue",[479,594,552],{"class":485},[479,596,598,600,602,605,607,609,611,614],{"class":481,"line":597},5,[479,599,519],{"class":518},[479,601,522],{"class":485},[479,603,604],{"class":525}," mentionsFeature",[479,606,540],{"class":485},[479,608,543],{"class":518},[479,610,546],{"class":485},[479,612,613],{"class":506},"@skaile\u002Fforge-editor\u002Fmentions",[479,615,552],{"class":485},[479,617,619,621,623,626,628,630,632,635],{"class":481,"line":618},6,[479,620,519],{"class":518},[479,622,522],{"class":485},[479,624,625],{"class":525}," tablesFeature",[479,627,540],{"class":485},[479,629,543],{"class":518},[479,631,546],{"class":485},[479,633,634],{"class":506},"@skaile\u002Fforge-editor\u002Ftables",[479,636,552],{"class":485},[479,638,640,642,644,647,649,652,654,656,658,661],{"class":481,"line":639},7,[479,641,519],{"class":518},[479,643,522],{"class":485},[479,645,646],{"class":525}," EditorSurface",[479,648,529],{"class":485},[479,650,651],{"class":525}," EditorToolbar",[479,653,540],{"class":485},[479,655,543],{"class":518},[479,657,546],{"class":485},[479,659,660],{"class":506},"@skaile\u002Fforge-editor\u002Fvue",[479,662,552],{"class":485},[479,664,666,668,671,673,676,678,681,683,685,687,690],{"class":481,"line":665},8,[479,667,519],{"class":518},[479,669,670],{"class":518}," type",[479,672,522],{"class":485},[479,674,675],{"class":525}," Editor",[479,677,529],{"class":485},[479,679,680],{"class":525}," JSONContent",[479,682,540],{"class":485},[479,684,543],{"class":518},[479,686,546],{"class":485},[479,688,689],{"class":506},"@tiptap\u002Fvue-3",[479,691,552],{"class":485},[479,693,695,697,699,702,704,707,709,711,713,715],{"class":481,"line":694},9,[479,696,519],{"class":518},[479,698,522],{"class":485},[479,700,701],{"class":525}," ref",[479,703,529],{"class":485},[479,705,706],{"class":525}," shallowRef",[479,708,540],{"class":485},[479,710,543],{"class":518},[479,712,546],{"class":485},[479,714,474],{"class":506},[479,716,552],{"class":485},[479,718,720],{"class":481,"line":719},10,[479,721,723],{"emptyLinePlaceholder":722},true,"\n",[479,725,727],{"class":481,"line":726},11,[479,728,730],{"class":729},"sHwdD","\u002F\u002F An editor is the sum of its features. Mentions and tags come from the `backend` the app context carries.\n",[479,732,734,737,740,742,745,748],{"class":481,"line":733},12,[479,735,736],{"class":493},"const",[479,738,739],{"class":525}," preset ",[479,741,500],{"class":485},[479,743,537],{"class":744},"s2Zo4",[479,746,747],{"class":525},"(",[479,749,750],{"class":485},"{\n",[479,752,754,757,760,763,766,769,771,773,775,777,779,781,783,785,787,789,791,793,795,797,800],{"class":481,"line":753},13,[479,755,756],{"class":489},"  features",[479,758,759],{"class":485},":",[479,761,762],{"class":525}," [",[479,764,765],{"class":744},"coreContentFeature",[479,767,768],{"class":525},"()",[479,770,529],{"class":485},[479,772,532],{"class":744},[479,774,768],{"class":525},[479,776,529],{"class":485},[479,778,604],{"class":744},[479,780,768],{"class":525},[479,782,529],{"class":485},[479,784,583],{"class":744},[479,786,768],{"class":525},[479,788,529],{"class":485},[479,790,625],{"class":744},[479,792,768],{"class":525},[479,794,529],{"class":485},[479,796,562],{"class":744},[479,798,799],{"class":525},"()]",[479,801,802],{"class":485},",\n",[479,804,806,809],{"class":481,"line":805},14,[479,807,808],{"class":485},"}",[479,810,811],{"class":525},")\n",[479,813,815],{"class":481,"line":814},15,[479,816,723],{"emptyLinePlaceholder":722},[479,818,820,822,825,827,829,831,835,838,840],{"class":481,"line":819},16,[479,821,736],{"class":493},[479,823,824],{"class":525}," content ",[479,826,500],{"class":485},[479,828,701],{"class":744},[479,830,486],{"class":485},[479,832,834],{"class":833},"sBMFI","JSONContent",[479,836,837],{"class":485},">",[479,839,747],{"class":525},[479,841,750],{"class":485},[479,843,845,848,850,852,855,858],{"class":481,"line":844},17,[479,846,847],{"class":489},"  type",[479,849,759],{"class":485},[479,851,546],{"class":485},[479,853,854],{"class":506},"doc",[479,856,857],{"class":485},"'",[479,859,802],{"class":485},[479,861,863,866,868],{"class":481,"line":862},18,[479,864,865],{"class":489},"  content",[479,867,759],{"class":485},[479,869,870],{"class":525}," [\n",[479,872,874,877,879,881,883,886,888,890,893,895,897,900,902,906,909,912,914,916,919,921,923,925,928,930,932,935,937,939,942,944,946,949],{"class":481,"line":873},19,[479,875,876],{"class":485},"    {",[479,878,670],{"class":489},[479,880,759],{"class":485},[479,882,546],{"class":485},[479,884,885],{"class":506},"heading",[479,887,857],{"class":485},[479,889,529],{"class":485},[479,891,892],{"class":489}," attrs",[479,894,759],{"class":485},[479,896,522],{"class":485},[479,898,899],{"class":489}," level",[479,901,759],{"class":485},[479,903,905],{"class":904},"sbssI"," 1",[479,907,908],{"class":485}," },",[479,910,911],{"class":489}," content",[479,913,759],{"class":485},[479,915,762],{"class":525},[479,917,918],{"class":485},"{",[479,920,670],{"class":489},[479,922,759],{"class":485},[479,924,546],{"class":485},[479,926,927],{"class":506},"text",[479,929,857],{"class":485},[479,931,529],{"class":485},[479,933,934],{"class":489}," text",[479,936,759],{"class":485},[479,938,546],{"class":485},[479,940,941],{"class":506},"Meeting notes",[479,943,857],{"class":485},[479,945,540],{"class":485},[479,947,948],{"class":525},"] ",[479,950,951],{"class":485},"},\n",[479,953,955],{"class":481,"line":954},20,[479,956,957],{"class":485},"    {\n",[479,959,961,964,966,968,971,973],{"class":481,"line":960},21,[479,962,963],{"class":489},"      type",[479,965,759],{"class":485},[479,967,546],{"class":485},[479,969,970],{"class":506},"paragraph",[479,972,857],{"class":485},[479,974,802],{"class":485},[479,976,978,981,983,985,987,989,991,993,995,997,999,1001,1003,1005,1008,1010,1012,1015],{"class":481,"line":977},22,[479,979,980],{"class":489},"      content",[479,982,759],{"class":485},[479,984,762],{"class":525},[479,986,918],{"class":485},[479,988,670],{"class":489},[479,990,759],{"class":485},[479,992,546],{"class":485},[479,994,927],{"class":506},[479,996,857],{"class":485},[479,998,529],{"class":485},[479,1000,934],{"class":489},[479,1002,759],{"class":485},[479,1004,546],{"class":485},[479,1006,1007],{"class":506},"Type @ to mention a person, # to add a tag, \u002F for the block menu, or drop an image.",[479,1009,857],{"class":485},[479,1011,540],{"class":485},[479,1013,1014],{"class":525},"]",[479,1016,802],{"class":485},[479,1018,1020],{"class":481,"line":1019},23,[479,1021,1022],{"class":485},"    },\n",[479,1024,1026,1029],{"class":481,"line":1025},24,[479,1027,1028],{"class":525},"  ]",[479,1030,802],{"class":485},[479,1032,1034,1036],{"class":481,"line":1033},25,[479,1035,808],{"class":485},[479,1037,811],{"class":525},[479,1039,1041,1043,1046,1048,1050,1052,1055,1057],{"class":481,"line":1040},26,[479,1042,736],{"class":493},[479,1044,1045],{"class":525}," editor ",[479,1047,500],{"class":485},[479,1049,706],{"class":744},[479,1051,486],{"class":485},[479,1053,1054],{"class":833},"Editor",[479,1056,837],{"class":485},[479,1058,1059],{"class":525},"()\n",[479,1061,1063,1066,1068],{"class":481,"line":1062},27,[479,1064,1065],{"class":485},"\u003C\u002F",[479,1067,490],{"class":489},[479,1069,512],{"class":485},[479,1071,1073],{"class":481,"line":1072},28,[479,1074,723],{"emptyLinePlaceholder":722},[479,1076,1078,1080,1083],{"class":481,"line":1077},29,[479,1079,486],{"class":485},[479,1081,1082],{"class":489},"template",[479,1084,512],{"class":485},[479,1086,1088],{"class":481,"line":1087},30,[479,1089,1090],{"class":729},"  \u003C!-- Global MDC components skip Nuxt's `.client` handling, so the page's server render would reach the editor: no UI kit there. -->\n",[479,1092,1094,1097,1100],{"class":481,"line":1093},31,[479,1095,1096],{"class":485},"  \u003C",[479,1098,1099],{"class":489},"ClientOnly",[479,1101,512],{"class":485},[479,1103,1105,1108,1111,1114,1116,1118,1121,1123],{"class":481,"line":1104},32,[479,1106,1107],{"class":485},"    \u003C",[479,1109,1110],{"class":489},"div",[479,1112,1113],{"class":493}," class",[479,1115,500],{"class":485},[479,1117,503],{"class":485},[479,1119,1120],{"class":506},"not-prose my-6 flex flex-col gap-3",[479,1122,503],{"class":485},[479,1124,512],{"class":485},[479,1126,1128,1131,1134,1137,1140,1142,1144,1146,1148],{"class":481,"line":1127},33,[479,1129,1130],{"class":485},"      \u003C",[479,1132,1133],{"class":489},"EditorToolbar",[479,1135,1136],{"class":485}," :",[479,1138,1139],{"class":493},"editor",[479,1141,500],{"class":485},[479,1143,503],{"class":485},[479,1145,1139],{"class":525},[479,1147,503],{"class":485},[479,1149,1150],{"class":485}," \u002F>\n",[479,1152,1154,1156,1158,1160,1162,1164,1167,1169],{"class":481,"line":1153},34,[479,1155,1130],{"class":485},[479,1157,1110],{"class":489},[479,1159,1113],{"class":493},[479,1161,500],{"class":485},[479,1163,503],{"class":485},[479,1165,1166],{"class":506},"min-h-64 rounded-lg border border-default p-4",[479,1168,503],{"class":485},[479,1170,512],{"class":485},[479,1172,1174,1177,1179,1182,1184,1186,1189,1191,1193,1196,1198,1200,1202,1204,1207,1210,1212,1214,1216,1219,1222,1224],{"class":481,"line":1173},35,[479,1175,1176],{"class":485},"        \u003C",[479,1178,432],{"class":489},[479,1180,1181],{"class":493}," v-model",[479,1183,500],{"class":485},[479,1185,503],{"class":485},[479,1187,1188],{"class":525},"content",[479,1190,503],{"class":485},[479,1192,1136],{"class":485},[479,1194,1195],{"class":493},"preset",[479,1197,500],{"class":485},[479,1199,503],{"class":485},[479,1201,1195],{"class":525},[479,1203,503],{"class":485},[479,1205,1206],{"class":485}," @",[479,1208,1209],{"class":493},"ready",[479,1211,500],{"class":485},[479,1213,503],{"class":485},[479,1215,1139],{"class":525},[479,1217,1218],{"class":485}," = ",[479,1220,1221],{"class":525},"$event",[479,1223,503],{"class":485},[479,1225,1150],{"class":485},[479,1227,1229,1232,1234],{"class":481,"line":1228},36,[479,1230,1231],{"class":485},"      \u003C\u002F",[479,1233,1110],{"class":489},[479,1235,512],{"class":485},[479,1237,1239,1242,1244],{"class":481,"line":1238},37,[479,1240,1241],{"class":485},"    \u003C\u002F",[479,1243,1110],{"class":489},[479,1245,512],{"class":485},[479,1247,1249,1252,1254],{"class":481,"line":1248},38,[479,1250,1251],{"class":485},"  \u003C\u002F",[479,1253,1099],{"class":489},[479,1255,512],{"class":485},[479,1257,1259,1261,1263],{"class":481,"line":1258},39,[479,1260,1065],{"class":485},[479,1262,1082],{"class":489},[479,1264,512],{"class":485},[418,1266,1267,1268,1271,1272,1275,1276,1278],{},"What each feature adds on top of ",[421,1269,1270],{},"coreContentFeature()"," (headings, lists, marks and so on) and ",[421,1273,1274],{},"coreUiFeature()"," (toolbar, ",[421,1277,451],{}," menu, command palette):",[1280,1281,1282,1298],"table",{},[1283,1284,1285],"thead",{},[1286,1287,1288,1292,1295],"tr",{},[1289,1290,1291],"th",{},"Feature",[1289,1293,1294],{},"Entry",[1289,1296,1297],{},"What it adds",[1299,1300,1301,1323,1337,1351],"tbody",{},[1286,1302,1303,1309,1313],{},[1304,1305,1306],"td",{},[421,1307,1308],{},"mentionsFeature()",[1304,1310,1311],{},[421,1312,613],{},[1304,1314,1315,1318,1319,1322],{},[421,1316,1317],{},"@username"," and ",[421,1320,1321],{},"#tag"," chips with suggestion popups",[1286,1324,1325,1330,1334],{},[1304,1326,1327],{},[421,1328,1329],{},"mediaFeature()",[1304,1331,1332],{},[421,1333,592],{},[1304,1335,1336],{},"Image, audio, video and file blocks, drop and paste of files, toolbar buttons, the audio recorder",[1286,1338,1339,1344,1348],{},[1304,1340,1341],{},[421,1342,1343],{},"tablesFeature()",[1304,1345,1346],{},[421,1347,634],{},[1304,1349,1350],{},"Tables with a toolbar group",[1286,1352,1353,1358,1362],{},[1304,1354,1355],{},[421,1356,1357],{},"blockUiFeature()",[1304,1359,1360],{},[421,1361,571],{},[1304,1363,1364],{},"Drag handle, hover actions per block, block-range selection",[418,1366,1367,1368,1371,1372,1375,1376,1375,1379,1382,1383,1386,1387,1390],{},"None of the four needs Typed blocks, AI or Yjs, and none imports the others: ",[421,1369,1370],{},"bun run check:editor-entries"," proves that per feature. The framework-free entries (",[421,1373,1374],{},"\u002Fmentions",", ",[421,1377,1378],{},"\u002Ftables",[421,1380,1381],{},"\u002Fcore",") work on both surfaces; the entries with a ",[421,1384,1385],{},"\u002Fvue"," suffix carry Vue components, and their React twins end in ",[421,1388,1389],{},"\u002Freact"," (chapter 8).",[418,1392,1393],{},"Two rules to remember:",[1395,1396,1397,1415],"ul",{},[1398,1399,1400,1403,1404,1407,1408,1410,1411,1414],"li",{},[426,1401,1402],{},"The preset is read once."," Build it in ",[421,1405,1406],{},"\u003Cscript setup>"," or at module level. To change the list, remount ",[421,1409,432],{}," with a new ",[421,1412,1413],{},"key",".",[1398,1416,1417,1443,1444,1447,1448,1318,1451,1454],{},[426,1418,1419,1421,1422,1375,1425,1375,1428,1375,1431,1375,1434,1375,1437,1318,1440,1414],{},[421,1420,432],{}," takes ",[421,1423,1424],{},"v-model",[421,1426,1427],{},":preset",[421,1429,1430],{},":editable",[421,1432,1433],{},":metadata",[421,1435,1436],{},":abilities",[421,1438,1439],{},":extensions",[421,1441,1442],{},":commands"," The last three are the props chapter 4 uses; ",[421,1445,1446],{},"metadata"," supplies the lists behind ",[421,1449,1450],{},"@",[421,1452,1453],{},"#"," when you do not want the context's backend to.",[457,1456,1458],{"id":1457},"where-the-suggestions-come-from","Where the suggestions come from",[418,1460,1461,1462,1318,1464,1466,1467,1318,1470,1473,1474,1477,1478,1481,1482,1485],{},"The ",[421,1463,1450],{},[421,1465,1453],{}," popups search two named lists, ",[421,1468,1469],{},"mentions",[421,1471,1472],{},"hashtags",". A list your app does not supply falls back to the feature's built-in source, which asks the context's backend: ",[421,1475,1476],{},"users"," for mentions, ",[421,1479,1480],{},"tags"," for hashtags. The memory backend of the example's ",[421,1483,1484],{},"main.ts"," (chapter 2) answers both from the data you gave it:",[469,1487,1491],{"className":1488,"code":1489,"filename":1490,"language":507,"meta":475,"style":475},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u002F\u002F No data layer: documents, dropped files (as blob: URLs), mention users and tags, and settings live in the page.\nconst backend = createMemoryBackend({\n  users: [\n    { id: 'u1', username: 'Ada Lovelace', color: '#7c3aed' },\n    { id: 'u2', username: 'Alan Turing', color: '#0ea5e9' },\n    { id: 'u3', username: 'Grace Hopper', color: '#16a34a' },\n  ],\n  tags: ['idee', 'entwurf', 'wichtig'],\n})\n\ncreateApp(App)\n  .use(ui)\n  .use(createEditor({ kit: nuxtUiKit(), backend }))\n","examples\u002Fvue-simple\u002Fsrc\u002Fmain.ts",[421,1492,1493,1498,1514,1523,1570,1613,1656,1662,1700,1706,1710,1718,1729],{"__ignoreMap":475},[479,1494,1495],{"class":481,"line":482},[479,1496,1497],{"class":729},"\u002F\u002F No data layer: documents, dropped files (as blob: URLs), mention users and tags, and settings live in the page.\n",[479,1499,1500,1502,1505,1507,1510,1512],{"class":481,"line":515},[479,1501,736],{"class":493},[479,1503,1504],{"class":525}," backend ",[479,1506,500],{"class":485},[479,1508,1509],{"class":744}," createMemoryBackend",[479,1511,747],{"class":525},[479,1513,750],{"class":485},[479,1515,1516,1519,1521],{"class":481,"line":555},[479,1517,1518],{"class":489},"  users",[479,1520,759],{"class":485},[479,1522,870],{"class":525},[479,1524,1525,1527,1530,1532,1534,1537,1539,1541,1544,1546,1548,1551,1553,1555,1558,1560,1562,1565,1567],{"class":481,"line":576},[479,1526,876],{"class":485},[479,1528,1529],{"class":489}," id",[479,1531,759],{"class":485},[479,1533,546],{"class":485},[479,1535,1536],{"class":506},"u1",[479,1538,857],{"class":485},[479,1540,529],{"class":485},[479,1542,1543],{"class":489}," username",[479,1545,759],{"class":485},[479,1547,546],{"class":485},[479,1549,1550],{"class":506},"Ada Lovelace",[479,1552,857],{"class":485},[479,1554,529],{"class":485},[479,1556,1557],{"class":489}," color",[479,1559,759],{"class":485},[479,1561,546],{"class":485},[479,1563,1564],{"class":506},"#7c3aed",[479,1566,857],{"class":485},[479,1568,1569],{"class":485}," },\n",[479,1571,1572,1574,1576,1578,1580,1583,1585,1587,1589,1591,1593,1596,1598,1600,1602,1604,1606,1609,1611],{"class":481,"line":597},[479,1573,876],{"class":485},[479,1575,1529],{"class":489},[479,1577,759],{"class":485},[479,1579,546],{"class":485},[479,1581,1582],{"class":506},"u2",[479,1584,857],{"class":485},[479,1586,529],{"class":485},[479,1588,1543],{"class":489},[479,1590,759],{"class":485},[479,1592,546],{"class":485},[479,1594,1595],{"class":506},"Alan Turing",[479,1597,857],{"class":485},[479,1599,529],{"class":485},[479,1601,1557],{"class":489},[479,1603,759],{"class":485},[479,1605,546],{"class":485},[479,1607,1608],{"class":506},"#0ea5e9",[479,1610,857],{"class":485},[479,1612,1569],{"class":485},[479,1614,1615,1617,1619,1621,1623,1626,1628,1630,1632,1634,1636,1639,1641,1643,1645,1647,1649,1652,1654],{"class":481,"line":618},[479,1616,876],{"class":485},[479,1618,1529],{"class":489},[479,1620,759],{"class":485},[479,1622,546],{"class":485},[479,1624,1625],{"class":506},"u3",[479,1627,857],{"class":485},[479,1629,529],{"class":485},[479,1631,1543],{"class":489},[479,1633,759],{"class":485},[479,1635,546],{"class":485},[479,1637,1638],{"class":506},"Grace Hopper",[479,1640,857],{"class":485},[479,1642,529],{"class":485},[479,1644,1557],{"class":489},[479,1646,759],{"class":485},[479,1648,546],{"class":485},[479,1650,1651],{"class":506},"#16a34a",[479,1653,857],{"class":485},[479,1655,1569],{"class":485},[479,1657,1658,1660],{"class":481,"line":639},[479,1659,1028],{"class":525},[479,1661,802],{"class":485},[479,1663,1664,1667,1669,1671,1673,1676,1678,1680,1682,1685,1687,1689,1691,1694,1696,1698],{"class":481,"line":665},[479,1665,1666],{"class":489},"  tags",[479,1668,759],{"class":485},[479,1670,762],{"class":525},[479,1672,857],{"class":485},[479,1674,1675],{"class":506},"idee",[479,1677,857],{"class":485},[479,1679,529],{"class":485},[479,1681,546],{"class":485},[479,1683,1684],{"class":506},"entwurf",[479,1686,857],{"class":485},[479,1688,529],{"class":485},[479,1690,546],{"class":485},[479,1692,1693],{"class":506},"wichtig",[479,1695,857],{"class":485},[479,1697,1014],{"class":525},[479,1699,802],{"class":485},[479,1701,1702,1704],{"class":481,"line":694},[479,1703,808],{"class":485},[479,1705,811],{"class":525},[479,1707,1708],{"class":481,"line":719},[479,1709,723],{"emptyLinePlaceholder":722},[479,1711,1712,1715],{"class":481,"line":726},[479,1713,1714],{"class":744},"createApp",[479,1716,1717],{"class":525},"(App)\n",[479,1719,1720,1723,1726],{"class":481,"line":733},[479,1721,1722],{"class":485},"  .",[479,1724,1725],{"class":744},"use",[479,1727,1728],{"class":525},"(ui)\n",[479,1730,1731,1733,1735,1737,1740,1742,1744,1747,1749,1752,1754,1756,1758,1760],{"class":481,"line":753},[479,1732,1722],{"class":485},[479,1734,1725],{"class":744},[479,1736,747],{"class":525},[479,1738,1739],{"class":744},"createEditor",[479,1741,747],{"class":525},[479,1743,918],{"class":485},[479,1745,1746],{"class":489}," kit",[479,1748,759],{"class":485},[479,1750,1751],{"class":744}," nuxtUiKit",[479,1753,768],{"class":525},[479,1755,529],{"class":485},[479,1757,1504],{"class":525},[479,1759,808],{"class":485},[479,1761,1762],{"class":525},"))\n",[418,1764,1765],{},"An app without a backend can pass its own lists on the surface instead, and never calls those endpoints:",[469,1767,1769],{"className":471,"code":1768,"language":474,"meta":475,"style":475},"\u003CEditorSurface\n  :preset=\"preset\"\n  :metadata=\"{\n    mentions: [{ id: 'u1', label: 'anna', color: '#e11d48' }],\n    hashtags: q => searchTags(q.query),\n  }\"\n  @metadata-create=\"(list, item) => persist(list, item)\"\n\u002F>\n",[421,1770,1771,1778,1794,1806,1860,1887,1894,1934],{"__ignoreMap":475},[479,1772,1773,1775],{"class":481,"line":482},[479,1774,486],{"class":485},[479,1776,1777],{"class":489},"EditorSurface\n",[479,1779,1780,1783,1785,1787,1789,1791],{"class":481,"line":515},[479,1781,1782],{"class":485},"  :",[479,1784,1195],{"class":493},[479,1786,500],{"class":485},[479,1788,503],{"class":485},[479,1790,1195],{"class":525},[479,1792,1793],{"class":485},"\"\n",[479,1795,1796,1798,1800,1802,1804],{"class":481,"line":555},[479,1797,1782],{"class":485},[479,1799,1446],{"class":493},[479,1801,500],{"class":485},[479,1803,503],{"class":485},[479,1805,750],{"class":485},[479,1807,1808,1811,1813,1815,1817,1819,1821,1823,1825,1827,1829,1832,1834,1836,1839,1841,1843,1845,1847,1849,1852,1854,1856,1858],{"class":481,"line":576},[479,1809,1810],{"class":489},"    mentions",[479,1812,759],{"class":485},[479,1814,762],{"class":525},[479,1816,918],{"class":485},[479,1818,1529],{"class":489},[479,1820,759],{"class":485},[479,1822,546],{"class":485},[479,1824,1536],{"class":506},[479,1826,857],{"class":485},[479,1828,529],{"class":485},[479,1830,1831],{"class":489}," label",[479,1833,759],{"class":485},[479,1835,546],{"class":485},[479,1837,1838],{"class":506},"anna",[479,1840,857],{"class":485},[479,1842,529],{"class":485},[479,1844,1557],{"class":489},[479,1846,759],{"class":485},[479,1848,546],{"class":485},[479,1850,1851],{"class":506},"#e11d48",[479,1853,857],{"class":485},[479,1855,540],{"class":485},[479,1857,1014],{"class":525},[479,1859,802],{"class":485},[479,1861,1862,1865,1867,1871,1874,1877,1880,1882,1885],{"class":481,"line":597},[479,1863,1864],{"class":744},"    hashtags",[479,1866,759],{"class":485},[479,1868,1870],{"class":1869},"sHdIc"," q",[479,1872,1873],{"class":493}," =>",[479,1875,1876],{"class":744}," searchTags",[479,1878,1879],{"class":525},"(q",[479,1881,1414],{"class":485},[479,1883,1884],{"class":525},"query)",[479,1886,802],{"class":485},[479,1888,1889,1892],{"class":481,"line":618},[479,1890,1891],{"class":485},"  }",[479,1893,1793],{"class":485},[479,1895,1896,1899,1902,1904,1906,1908,1911,1913,1916,1919,1921,1924,1927,1929,1932],{"class":481,"line":639},[479,1897,1898],{"class":485},"  @",[479,1900,1901],{"class":493},"metadata-create",[479,1903,500],{"class":485},[479,1905,503],{"class":485},[479,1907,747],{"class":485},[479,1909,1910],{"class":1869},"list",[479,1912,529],{"class":485},[479,1914,1915],{"class":1869}," item",[479,1917,1918],{"class":485},")",[479,1920,1873],{"class":493},[479,1922,1923],{"class":744}," persist",[479,1925,1926],{"class":525},"(list",[479,1928,529],{"class":485},[479,1930,1931],{"class":525}," item)",[479,1933,1793],{"class":485},[479,1935,1936],{"class":481,"line":665},[479,1937,1938],{"class":525},"\u002F>\n",[418,1940,1941,1942,1944,1945,1948,1949,1952,1953,1956,1957,1959,1960,1963,1964,1318,1966,1969,1970,1414],{},"Mentions are ",[421,1943,1317],{}," chips tinted with the item's ",[421,1946,1947],{},"color"," (a ",[421,1950,1951],{},"#rgb"," or ",[421,1954,1955],{},"#rrggbb"," value; anything else is dropped). Tags are ",[421,1958,1321],{}," chips; the typed name is normalised (lower case, spaces become ",[421,1961,1962],{},"-",", letters, digits, ",[421,1965,1962],{},[421,1967,1968],{},"_"," only, at most 64 characters), and the popup offers „#name erstellen“ when it is not in the list. Picking that entry emits ",[421,1971,1972],{},"metadataCreate('hashtags', { id, label })",[457,1974,1976],{"id":1975},"images-and-files","Images and files",[418,1978,1979,1981,1982,1984,1985,1988,1989,1992,1993,1996,1997,2000,2001,2004,2005,2008,2009,2013],{},[421,1980,1329],{}," adds image, audio, video and file blocks, drop and paste of files, the toolbar buttons (Bild, Audio-Datei, Video, Aufnahme), the matching ",[421,1983,451],{}," commands and the audio recorder. Every path ends in one function, ",[421,1986,1987],{},"editor.storage.media.upload(file)",", which calls the backend's ",[421,1990,1991],{},"assets"," capability. The memory backend answers with a ",[421,1994,1995],{},"blob:"," URL, so a dropped image shows up at once and disappears when the page reloads. To store files elsewhere, implement ",[421,1998,1999],{},"assets.upload"," in your own backend; the returned ",[421,2002,2003],{},"url"," becomes the block's ",[421,2006,2007],{},"src",". Accepted types and sizes are in ",[2010,2011,2012],"a",{"href":95},"Media, mentions and transcript",". The transcript feature (speaker blocks) is described there as well; the meeting notes do not need it.",[457,2015,2017],{"id":2016},"the-feature-stylesheets","The feature stylesheets",[418,2019,2020,2021,759],{},"Features that draw their own UI ship a stylesheet. Import each one after Tailwind, Nuxt UI and ",[421,2022,2023],{},"core.css",[469,2025,2029],{"className":2026,"code":2027,"language":2028,"meta":475,"style":475},"language-css shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","@import \"@skaile\u002Fforge-editor\u002Fstyles\u002Fmentions.css\";\n@import \"@skaile\u002Fforge-editor\u002Fstyles\u002Fmedia.css\";\n@import \"@skaile\u002Fforge-editor\u002Fstyles\u002Ftables.css\";\n@import \"@skaile\u002Fforge-editor\u002Fstyles\u002Fblock-ui.css\";\n","css",[421,2030,2031,2047,2060,2073],{"__ignoreMap":475},[479,2032,2033,2036,2039,2042,2044],{"class":481,"line":482},[479,2034,2035],{"class":518},"@import",[479,2037,2038],{"class":485}," \"",[479,2040,2041],{"class":506},"@skaile\u002Fforge-editor\u002Fstyles\u002Fmentions.css",[479,2043,503],{"class":485},[479,2045,2046],{"class":485},";\n",[479,2048,2049,2051,2053,2056,2058],{"class":481,"line":515},[479,2050,2035],{"class":518},[479,2052,2038],{"class":485},[479,2054,2055],{"class":506},"@skaile\u002Fforge-editor\u002Fstyles\u002Fmedia.css",[479,2057,503],{"class":485},[479,2059,2046],{"class":485},[479,2061,2062,2064,2066,2069,2071],{"class":481,"line":555},[479,2063,2035],{"class":518},[479,2065,2038],{"class":485},[479,2067,2068],{"class":506},"@skaile\u002Fforge-editor\u002Fstyles\u002Ftables.css",[479,2070,503],{"class":485},[479,2072,2046],{"class":485},[479,2074,2075,2077,2079,2082,2084],{"class":481,"line":576},[479,2076,2035],{"class":518},[479,2078,2038],{"class":485},[479,2080,2081],{"class":506},"@skaile\u002Fforge-editor\u002Fstyles\u002Fblock-ui.css",[479,2083,503],{"class":485},[479,2085,2046],{"class":485},[418,2087,2088,2090],{},[2010,2089,361],{"href":362}," has the full list and the reason for the order.",[457,2092,2094,2095],{"id":2093},"the-shortcut-composeeditor","The shortcut: ",[421,2096,2097],{},"composeEditor",[418,2099,2100,2102,2103,2105,2106,2109,2110,2113,2114,2116,2117,2120,2121,2124],{},[421,2101,436],{}," is the explicit form. ",[421,2104,2097],{}," from ",[421,2107,2108],{},"@skaile\u002Fforge-editor\u002Fvue\u002Fadvanced"," builds the same kind of preset from three ",[426,2111,2112],{},"dimensions",", the document model (",[421,2115,1188],{},"), the editing UX (",[421,2118,2119],{},"interaction",") and ",[421,2122,2123],{},"ai",", each a named level or a list of feature ids:",[469,2126,2128],{"className":1488,"code":2127,"language":507,"meta":475,"style":475},"import { composeEditor } from '@skaile\u002Fforge-editor\u002Fvue\u002Fadvanced'\n\n\u002F\u002F core-content and core-ui plus mentions, media, tables and block UI, without AI.\nconst preset = composeEditor({ content: ['mentions', 'media', 'tables'], interaction: ['block-ui'], ai: false })\n",[421,2129,2130,2149,2153,2158],{"__ignoreMap":475},[479,2131,2132,2134,2136,2139,2141,2143,2145,2147],{"class":481,"line":482},[479,2133,519],{"class":518},[479,2135,522],{"class":485},[479,2137,2138],{"class":525}," composeEditor",[479,2140,540],{"class":485},[479,2142,543],{"class":518},[479,2144,546],{"class":485},[479,2146,2108],{"class":506},[479,2148,552],{"class":485},[479,2150,2151],{"class":481,"line":515},[479,2152,723],{"emptyLinePlaceholder":722},[479,2154,2155],{"class":481,"line":555},[479,2156,2157],{"class":729},"\u002F\u002F core-content and core-ui plus mentions, media, tables and block UI, without AI.\n",[479,2159,2160,2162,2164,2166,2168,2170,2172,2174,2176,2178,2180,2182,2184,2186,2188,2191,2193,2195,2197,2200,2202,2204,2206,2209,2211,2213,2215,2218,2220,2222,2224,2227,2229,2233,2235],{"class":481,"line":576},[479,2161,736],{"class":493},[479,2163,739],{"class":525},[479,2165,500],{"class":485},[479,2167,2138],{"class":744},[479,2169,747],{"class":525},[479,2171,918],{"class":485},[479,2173,911],{"class":489},[479,2175,759],{"class":485},[479,2177,762],{"class":525},[479,2179,857],{"class":485},[479,2181,1469],{"class":506},[479,2183,857],{"class":485},[479,2185,529],{"class":485},[479,2187,546],{"class":485},[479,2189,2190],{"class":506},"media",[479,2192,857],{"class":485},[479,2194,529],{"class":485},[479,2196,546],{"class":485},[479,2198,2199],{"class":506},"tables",[479,2201,857],{"class":485},[479,2203,1014],{"class":525},[479,2205,529],{"class":485},[479,2207,2208],{"class":489}," interaction",[479,2210,759],{"class":485},[479,2212,762],{"class":525},[479,2214,857],{"class":485},[479,2216,2217],{"class":506},"block-ui",[479,2219,857],{"class":485},[479,2221,1014],{"class":525},[479,2223,529],{"class":485},[479,2225,2226],{"class":489}," ai",[479,2228,759],{"class":485},[479,2230,2232],{"class":2231},"sfNiH"," false",[479,2234,540],{"class":485},[479,2236,811],{"class":525},[418,2238,2239,2240,2242,2243,2246,2247,2250,2251,2254,2255,2258,2259,2261,2262,2264,2265,1375,2268,2271,2272,2275],{},"The result is a preset like the one from ",[421,2241,436],{},", plus ",[421,2244,2245],{},"omitted",", the features that were selected but dropped because a feature they ",[421,2248,2249],{},"require"," is missing or because the ",[421,2252,2253],{},"backend"," lacks a capability. ",[421,2256,2257],{},"advancedEditor()"," is the one-line wrapper for the full catalog. Prefer ",[421,2260,436],{}," while you learn what each feature does, and ",[421,2263,2097],{}," when you want a level (",[421,2266,2267],{},"'rich'",[421,2269,2270],{},"'full'",") instead of a list. See ",[2010,2273,2274],{"href":91},"Feature composition"," for the levels.",[457,2277,2279],{"id":2278},"what-you-have-now","What you have now",[418,2281,2282,2283,2285,2286,2288],{},"An editor assembled from features: mentions and tags backed by a memory backend, image drop with ",[421,2284,1995],{}," URLs, tables and a drag handle, mounted with ",[421,2287,432],{},". You also know the rule that makes this safe: a feature that is not in the list contributes nothing, neither code nor schema.",[457,2290,2292],{"id":2291},"next","Next",[418,2294,2295,2297],{},[2010,2296,60],{"href":61}," adds a block the library does not have.",[2299,2300,2301],"style",{},"html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}",{"title":475,"searchDepth":515,"depth":515,"links":2303},[2304,2305,2306,2307,2308,2310,2311],{"id":459,"depth":515,"text":460},{"id":1457,"depth":515,"text":1458},{"id":1975,"depth":515,"text":1976},{"id":2016,"depth":515,"text":2017},{"id":2093,"depth":515,"text":2309},"The shortcut: composeEditor",{"id":2278,"depth":515,"text":2279},{"id":2291,"depth":515,"text":2292},"Replace SimpleEditor with EditorSurface over defineEditor and add mentions, media, tables and block UI as features.","md",null,{},{"icon":58},{"title":55,"description":2312},"LCXptrijvITj-1wwEo2aV8lOTV95rsklZiRSKMhDxUo",[2320,2322],{"title":50,"path":51,"stem":52,"description":2321,"icon":53,"children":-1},"Mount SimpleEditor with a JSON v-model, add the toolbar and the outline beside it, switch it read-only and handle rejected content.",{"title":60,"path":61,"stem":62,"description":2323,"icon":63,"children":-1},"Write the „Hinweis“ callout as a TipTap node and plug it into SimpleEditor through the extensions and commands props.",1793178229082]