[{"data":1,"prerenderedAt":1452},["ShallowReactive",2],{"navigation_docs":3,"-getting-started-quick-start-react":412,"-getting-started-quick-start-react-surround":1447},[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":29,"body":414,"description":1440,"extension":1441,"links":1442,"meta":1443,"navigation":1444,"path":30,"seo":1445,"stem":31,"__hash__":1446},"docs\u002F1.getting-started\u002F5.quick-start-react.md",{"type":415,"value":416,"toc":1433},"minimark",[417,463,509,514,633,639,767,781,896,933,984,1091,1110,1114,1127,1278,1307,1314,1341,1406,1409,1413,1417,1429],[418,419,420,421,425,426,429,430,433,434,437,438,441,442,451,452,455,456,459,460,462],"p",{},"The React layer (",[422,423,424],"code",{},"@skaile\u002Fforge-editor\u002Freact",", shadcn\u002Fui on Radix and Tailwind 4) renders the same framework-free core as the Vue layer: the simple editor, ",[422,427,428],{},"EditorToolbar",", the settings panel and modal, and the ",[422,431,432],{},"@",", ",[422,435,436],{},"#"," and ",[422,439,440],{},"\u002F"," suggestion popups. It uses no Vue, Nuxt UI or Nuxt module. The runnable reference is ",[443,444,448],"a",{"href":445,"rel":446},"https:\u002F\u002Fgithub.com\u002Fskaile-ai\u002Fforge-editor\u002Ftree\u002Fmain\u002Fexamples\u002Freact-simple",[447],"nofollow",[422,449,450],{},"examples\u002Freact-simple","; start it with ",[422,453,454],{},"bun run --cwd examples\u002Freact-simple dev"," (port 3041). It has the same sample picker, read-only toggle, host ",[422,457,458],{},"\u002Fdatum"," command and JSON and Markdown panes as the Vue example, plus ",[422,461,432],{}," mentions.",[418,464,465,469,470,473,474,477,478,477,481,484,485,488,489,491,492,433,495,433,498,501,502,505,506,508],{},[466,467,468],"strong",{},"More than the simple editor:"," every advanced feature has a React binding as well (",[422,471,472],{},".\u002F\u003Cx>\u002Freact",": media, transcript, Typed blocks, authors, comments, AI, collaboration, block UI, themes, the Block outline and the Document tree), and ",[422,475,476],{},"composeEditor(options)"," \u002F ",[422,479,480],{},"advancedEditor()",[422,482,483],{},"AdvancedEditor"," from ",[422,486,487],{},"@skaile\u002Fforge-editor\u002Freact\u002Fadvanced"," compose them all; see ",[443,490,127],{"href":128},". ",[422,493,494],{},"coreContentFeature()",[422,496,497],{},"coreUiFeature()",[422,499,500],{},"mentionsFeature()"," and the three integrations have no components and work in both layers; a React preset is ",[422,503,504],{},"defineEditor({ features })"," over features from ",[422,507,472],{}," and such component-free features.",[510,511,513],"h2",{"id":512},"setup","Setup",[515,516,517,596,608],"ul",{},[518,519,520,523,524,527,528,531,532,433,535,433,538,433,541,433,544,433,547,433,550,433,553,433,556,433,559,433,562,565,566,569,570,433,573,433,576,433,579,433,582,433,585,588,589,595],"li",{},[422,521,522],{},"package.json"," dependencies: ",[422,525,526],{},"@skaile\u002Fforge-editor"," (",[422,529,530],{},"workspace:*"," inside this repository), ",[422,533,534],{},"react",[422,536,537],{},"react-dom",[422,539,540],{},"@tiptap\u002Fcore",[422,542,543],{},"@tiptap\u002Fpm",[422,545,546],{},"@tiptap\u002Freact",[422,548,549],{},"@iconify\u002Freact",[422,551,552],{},"@iconify-json\u002Flucide",[422,554,555],{},"tailwindcss",[422,557,558],{},"tw-animate-css",[422,560,561],{},"yjs",[422,563,564],{},"@hocuspocus\u002Fprovider"," (the last two as in the ",[443,567,568],{"href":17},"README",": source-shipped shared types reference them); dev dependencies ",[422,571,572],{},"vite",[422,574,575],{},"@tailwindcss\u002Fvite",[422,577,578],{},"@vitejs\u002Fplugin-react",[422,580,581],{},"typescript",[422,583,584],{},"@types\u002Freact",[422,586,587],{},"@types\u002Freact-dom",". Use the exact version ranges of the example's ",[443,590,593],{"href":591,"rel":592},"https:\u002F\u002Fgithub.com\u002Fskaile-ai\u002Fforge-editor\u002Fblob\u002Fmain\u002Fexamples\u002Freact-simple\u002Fpackage.json",[447],[422,594,522],{},".",[518,597,598,601,602,437,605,595],{},[422,599,600],{},"index.html"," with ",[422,603,604],{},"\u003Cdiv id=\"app\">\u003C\u002Fdiv>",[422,606,607],{},"\u003Cscript type=\"module\" src=\"\u002Fsrc\u002Fmain.tsx\">\u003C\u002Fscript>",[518,609,610,601,613,433,616,433,619,437,622,625,626,632],{},[422,611,612],{},"tsconfig.json",[422,614,615],{},"jsx: \"react-jsx\"",[422,617,618],{},"moduleResolution: \"Bundler\"",[422,620,621],{},"strict",[422,623,624],{},"include: [\"src\"]"," (see the example's ",[443,627,630],{"href":628,"rel":629},"https:\u002F\u002Fgithub.com\u002Fskaile-ai\u002Fforge-editor\u002Fblob\u002Fmain\u002Fexamples\u002Freact-simple\u002Ftsconfig.json",[447],[422,631,612],{},").",[418,634,635,638],{},[422,636,637],{},"vite.config.ts",":",[640,641,646],"pre",{"className":642,"code":643,"language":644,"meta":645,"style":645},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import tailwindcss from '@tailwindcss\u002Fvite'\nimport react from '@vitejs\u002Fplugin-react'\nimport { defineConfig } from 'vite'\n\nexport default defineConfig({ plugins: [react(), tailwindcss()] })\n","ts","",[422,647,648,674,690,713,720],{"__ignoreMap":645},[649,650,653,657,661,664,668,671],"span",{"class":651,"line":652},"line",1,[649,654,656],{"class":655},"s7zQu","import",[649,658,660],{"class":659},"sTEyZ"," tailwindcss ",[649,662,663],{"class":655},"from",[649,665,667],{"class":666},"sMK4o"," '",[649,669,575],{"class":670},"sfazB",[649,672,673],{"class":666},"'\n",[649,675,677,679,682,684,686,688],{"class":651,"line":676},2,[649,678,656],{"class":655},[649,680,681],{"class":659}," react ",[649,683,663],{"class":655},[649,685,667],{"class":666},[649,687,578],{"class":670},[649,689,673],{"class":666},[649,691,693,695,698,701,704,707,709,711],{"class":651,"line":692},3,[649,694,656],{"class":655},[649,696,697],{"class":666}," {",[649,699,700],{"class":659}," defineConfig",[649,702,703],{"class":666}," }",[649,705,706],{"class":655}," from",[649,708,667],{"class":666},[649,710,572],{"class":670},[649,712,673],{"class":666},[649,714,716],{"class":651,"line":715},4,[649,717,719],{"emptyLinePlaceholder":718},true,"\n",[649,721,723,726,729,732,735,738,742,744,747,749,752,755,758,761,764],{"class":651,"line":722},5,[649,724,725],{"class":655},"export",[649,727,728],{"class":655}," default",[649,730,700],{"class":731},"s2Zo4",[649,733,734],{"class":659},"(",[649,736,737],{"class":666},"{",[649,739,741],{"class":740},"swJcz"," plugins",[649,743,638],{"class":666},[649,745,746],{"class":659}," [",[649,748,534],{"class":731},[649,750,751],{"class":659},"()",[649,753,754],{"class":666},",",[649,756,757],{"class":731}," tailwindcss",[649,759,760],{"class":659},"()] ",[649,762,763],{"class":666},"}",[649,765,766],{"class":659},")\n",[418,768,769,772,773,776,777,780],{},[422,770,771],{},"index.css"," — Tailwind, the animation utilities the shadcn dialog, dropdown and tooltip use, the library sheets, and a ",[422,774,775],{},"@source"," so Tailwind generates the utility classes the library's React code uses (Tailwind skips ",[422,778,779],{},"node_modules"," unless told otherwise):",[640,782,786],{"className":783,"code":784,"language":785,"meta":645,"style":645},"language-css shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","@import \"tailwindcss\";\n@import \"tw-animate-css\";\n\u002F* ui-vars.css maps the shadcn tokens (--primary, --background, …) to the --ui-* variables the feature sheets read. *\u002F\n@import \"@skaile\u002Fforge-editor\u002Freact\u002Fstyles\u002Fui-vars.css\";\n@import \"@skaile\u002Fforge-editor\u002Fstyles\u002Fcore.css\";\n@import \"@skaile\u002Fforge-editor\u002Fstyles\u002Fmentions.css\"; \u002F* the sheet of each feature you use *\u002F\n\n@source \"..\u002Fnode_modules\u002F@skaile\u002Fforge-editor\u002Fdist\"; \u002F* relative path from this CSS file to the installed package's dist *\u002F\n\n\u002F* The shadcn theme block follows: @custom-variant dark, @theme inline, :root and .dark tokens, @layer base.\n   `bunx shadcn@latest init` generates it; examples\u002Freact-simple\u002Fsrc\u002Findex.css has a complete copy. *\u002F\n","css",[422,787,788,804,816,822,835,848,866,871,879,884,890],{"__ignoreMap":645},[649,789,790,793,796,798,801],{"class":651,"line":652},[649,791,792],{"class":655},"@import",[649,794,795],{"class":666}," \"",[649,797,555],{"class":670},[649,799,800],{"class":666},"\"",[649,802,803],{"class":666},";\n",[649,805,806,808,810,812,814],{"class":651,"line":676},[649,807,792],{"class":655},[649,809,795],{"class":666},[649,811,558],{"class":670},[649,813,800],{"class":666},[649,815,803],{"class":666},[649,817,818],{"class":651,"line":692},[649,819,821],{"class":820},"sHwdD","\u002F* ui-vars.css maps the shadcn tokens (--primary, --background, …) to the --ui-* variables the feature sheets read. *\u002F\n",[649,823,824,826,828,831,833],{"class":651,"line":715},[649,825,792],{"class":655},[649,827,795],{"class":666},[649,829,830],{"class":670},"@skaile\u002Fforge-editor\u002Freact\u002Fstyles\u002Fui-vars.css",[649,832,800],{"class":666},[649,834,803],{"class":666},[649,836,837,839,841,844,846],{"class":651,"line":722},[649,838,792],{"class":655},[649,840,795],{"class":666},[649,842,843],{"class":670},"@skaile\u002Fforge-editor\u002Fstyles\u002Fcore.css",[649,845,800],{"class":666},[649,847,803],{"class":666},[649,849,851,853,855,858,860,863],{"class":651,"line":850},6,[649,852,792],{"class":655},[649,854,795],{"class":666},[649,856,857],{"class":670},"@skaile\u002Fforge-editor\u002Fstyles\u002Fmentions.css",[649,859,800],{"class":666},[649,861,862],{"class":666},";",[649,864,865],{"class":820}," \u002F* the sheet of each feature you use *\u002F\n",[649,867,869],{"class":651,"line":868},7,[649,870,719],{"emptyLinePlaceholder":718},[649,872,874,876],{"class":651,"line":873},8,[649,875,775],{"class":655},[649,877,878],{"class":659}," \"..\u002Fnode_modules\u002F@skaile\u002Fforge-editor\u002Fdist\"; \u002F* relative path from this CSS file to the installed package's dist *\u002F\n",[649,880,882],{"class":651,"line":881},9,[649,883,719],{"emptyLinePlaceholder":718},[649,885,887],{"class":651,"line":886},10,[649,888,889],{"class":659},"\u002F* The shadcn theme block follows: @custom-variant dark, @theme inline, :root and .dark tokens, @layer base.\n",[649,891,893],{"class":651,"line":892},11,[649,894,895],{"class":659},"   `bunx shadcn@latest init` generates it; examples\u002Freact-simple\u002Fsrc\u002Findex.css has a complete copy. *\u002F\n",[418,897,898,899,901,902,905,906,909,910,913,914,433,917,433,920,922,923,925,926,527,929,932],{},"The ",[422,900,775],{}," covers the whole ",[422,903,904],{},"dist",", not just ",[422,907,908],{},"dist\u002Freact",": the Features' own React components (",[422,911,912],{},"features\u002F*\u002Freact",", e.g. the image studio dialog), the surfaces (",[422,915,916],{},"document",[422,918,919],{},"markdown",[422,921,422],{},"), the outline and the tree sit beside it, and a host that scans only ",[422,924,908],{}," renders them without their layout classes. In this repository the examples point at the sibling's ",[422,927,928],{},"src",[422,930,931],{},"..\u002F..\u002F..\u002Fpackages\u002Feditor\u002Fsrc",") instead.",[418,934,935,938,939,942,943,945,946,527,949,952,953,956,957,960,961,964,965,968,969,440,972,975,976,979,980,983],{},[422,936,937],{},"main.tsx"," — icons and the editor context. The toolbar and menus render ",[422,940,941],{},"i-lucide-*"," names through ",[422,944,549],{},"; preloading the collection means the page makes no request to the Iconify API. The host owns the context from ",[422,947,948],{},"createEditorContext()",[422,950,951],{},"@skaile\u002Fforge-editor\u002Fcore",") and every React component of the library reads it from ",[422,954,955],{},"EditorContextProvider","; the provider never disposes it, call ",[422,958,959],{},"context.dispose()"," yourself when the context outlives your app. ",[422,962,963],{},"createEditorContext"," takes the same options as the Vue ",[422,966,967],{},"createEditor"," (the default backend syncs the settings with ",[422,970,971],{},"GET",[422,973,974],{},"PUT \u002Fapi\u002Feditor\u002Fsettings","; ",[422,977,978],{},"{ backend: createMemoryBackend() }"," keeps them local, ",[422,981,982],{},"{ backend: createHttpBackend({ fetch }) }"," brings your own HTTP client):",[640,985,989],{"className":986,"code":987,"language":988,"meta":645,"style":645},"language-tsx shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import lucide from '@iconify-json\u002Flucide\u002Ficons.json'\nimport { addCollection } from '@iconify\u002Freact'\nimport { createEditorContext } from '@skaile\u002Fforge-editor\u002Fcore'\nimport { EditorContextProvider } from '@skaile\u002Fforge-editor\u002Freact'\nimport { StrictMode } from 'react'\nimport { createRoot } from 'react-dom\u002Fclient'\nimport { App } from '.\u002FApp'\nimport '.\u002Findex.css'\n\naddCollection(lucide)\nconst context = createEditorContext()\n\ncreateRoot(document.getElementById('app')!).render(\n  \u003CStrictMode>\n    \u003CEditorContextProvider context={context}>\n      \u003CApp \u002F>\n    \u003C\u002FEditorContextProvider>\n  \u003C\u002FStrictMode>,\n)\n","tsx",[422,990,991,996,1001,1006,1011,1016,1021,1026,1031,1035,1040,1045,1050,1056,1062,1068,1074,1080,1086],{"__ignoreMap":645},[649,992,993],{"class":651,"line":652},[649,994,995],{},"import lucide from '@iconify-json\u002Flucide\u002Ficons.json'\n",[649,997,998],{"class":651,"line":676},[649,999,1000],{},"import { addCollection } from '@iconify\u002Freact'\n",[649,1002,1003],{"class":651,"line":692},[649,1004,1005],{},"import { createEditorContext } from '@skaile\u002Fforge-editor\u002Fcore'\n",[649,1007,1008],{"class":651,"line":715},[649,1009,1010],{},"import { EditorContextProvider } from '@skaile\u002Fforge-editor\u002Freact'\n",[649,1012,1013],{"class":651,"line":722},[649,1014,1015],{},"import { StrictMode } from 'react'\n",[649,1017,1018],{"class":651,"line":850},[649,1019,1020],{},"import { createRoot } from 'react-dom\u002Fclient'\n",[649,1022,1023],{"class":651,"line":868},[649,1024,1025],{},"import { App } from '.\u002FApp'\n",[649,1027,1028],{"class":651,"line":873},[649,1029,1030],{},"import '.\u002Findex.css'\n",[649,1032,1033],{"class":651,"line":881},[649,1034,719],{"emptyLinePlaceholder":718},[649,1036,1037],{"class":651,"line":886},[649,1038,1039],{},"addCollection(lucide)\n",[649,1041,1042],{"class":651,"line":892},[649,1043,1044],{},"const context = createEditorContext()\n",[649,1046,1048],{"class":651,"line":1047},12,[649,1049,719],{"emptyLinePlaceholder":718},[649,1051,1053],{"class":651,"line":1052},13,[649,1054,1055],{},"createRoot(document.getElementById('app')!).render(\n",[649,1057,1059],{"class":651,"line":1058},14,[649,1060,1061],{},"  \u003CStrictMode>\n",[649,1063,1065],{"class":651,"line":1064},15,[649,1066,1067],{},"    \u003CEditorContextProvider context={context}>\n",[649,1069,1071],{"class":651,"line":1070},16,[649,1072,1073],{},"      \u003CApp \u002F>\n",[649,1075,1077],{"class":651,"line":1076},17,[649,1078,1079],{},"    \u003C\u002FEditorContextProvider>\n",[649,1081,1083],{"class":651,"line":1082},18,[649,1084,1085],{},"  \u003C\u002FStrictMode>,\n",[649,1087,1089],{"class":651,"line":1088},19,[649,1090,766],{},[418,1092,1093,1094,1096,1097,1100,1101,1104,1105,1107,1108,632],{},"Notices of app-level models (for example the AI model profiles) go through the context's notifier. The simple editor raises none, so ",[422,1095,948],{}," is enough here; hosts of features pass ",[422,1098,1099],{},"createEditorContext({ notify: reactNotifier })"," and mount sonner's ",[422,1102,1103],{},"Toaster"," once (both from ",[422,1106,424],{},", see ",[443,1109,127],{"href":128},[510,1111,1113],{"id":1112},"mount-the-editor","Mount the editor",[418,1115,1116,1119,1120,1122,1123,1126],{},[422,1117,1118],{},"EditorSurface"," takes a preset; ",[422,1121,428],{}," is a sibling that works on the editor you pass it (from ",[422,1124,1125],{},"onReady","), never on a global active editor. The toolbar renders the groups of the preset registered for that editor; without an editor it renders none.",[640,1128,1130],{"className":986,"code":1129,"language":988,"meta":645,"style":645},"import { coreContentFeature, coreUiFeature, defineEditor } from '@skaile\u002Fforge-editor\u002Fcore'\nimport { mentionsFeature } from '@skaile\u002Fforge-editor\u002Fmentions'\nimport { EditorSurface, EditorToolbar } from '@skaile\u002Fforge-editor\u002Freact'\nimport type { Editor, JSONContent } from '@tiptap\u002Fcore'\nimport { useState } from 'react'\n\n\u002F\u002F Module constants: the preset, `metadata`, `abilities`, `extensions` and `commands` are read once at mount.\nconst preset = defineEditor({ features: [coreContentFeature(), coreUiFeature(), mentionsFeature()] })\nconst metadata = { mentions: [{ id: 'u1', label: 'Ada Lovelace' }, { id: 'u2', label: 'Alan Turing' }] }\n\nexport function App() {\n  const [editor, setEditor] = useState\u003CEditor | null>(null)\n  const [content, setContent] = useState\u003CJSONContent>({ type: 'doc', content: [{ type: 'paragraph' }] })\n\n  return (\n    \u003C>\n      \u003CEditorToolbar editor={editor ?? undefined} \u002F>\n      \u003CEditorSurface\n        preset={preset}\n        metadata={metadata}\n        value={content}\n        onChange={setContent}\n        onReady={setEditor}\n        onContentError={error => console.warn(error.message)}\n      \u002F>\n    \u003C\u002F>\n  )\n}\n",[422,1131,1132,1137,1142,1147,1152,1157,1161,1166,1171,1176,1180,1185,1190,1195,1199,1204,1209,1214,1219,1224,1230,1236,1242,1248,1254,1260,1266,1272],{"__ignoreMap":645},[649,1133,1134],{"class":651,"line":652},[649,1135,1136],{},"import { coreContentFeature, coreUiFeature, defineEditor } from '@skaile\u002Fforge-editor\u002Fcore'\n",[649,1138,1139],{"class":651,"line":676},[649,1140,1141],{},"import { mentionsFeature } from '@skaile\u002Fforge-editor\u002Fmentions'\n",[649,1143,1144],{"class":651,"line":692},[649,1145,1146],{},"import { EditorSurface, EditorToolbar } from '@skaile\u002Fforge-editor\u002Freact'\n",[649,1148,1149],{"class":651,"line":715},[649,1150,1151],{},"import type { Editor, JSONContent } from '@tiptap\u002Fcore'\n",[649,1153,1154],{"class":651,"line":722},[649,1155,1156],{},"import { useState } from 'react'\n",[649,1158,1159],{"class":651,"line":850},[649,1160,719],{"emptyLinePlaceholder":718},[649,1162,1163],{"class":651,"line":868},[649,1164,1165],{},"\u002F\u002F Module constants: the preset, `metadata`, `abilities`, `extensions` and `commands` are read once at mount.\n",[649,1167,1168],{"class":651,"line":873},[649,1169,1170],{},"const preset = defineEditor({ features: [coreContentFeature(), coreUiFeature(), mentionsFeature()] })\n",[649,1172,1173],{"class":651,"line":881},[649,1174,1175],{},"const metadata = { mentions: [{ id: 'u1', label: 'Ada Lovelace' }, { id: 'u2', label: 'Alan Turing' }] }\n",[649,1177,1178],{"class":651,"line":886},[649,1179,719],{"emptyLinePlaceholder":718},[649,1181,1182],{"class":651,"line":892},[649,1183,1184],{},"export function App() {\n",[649,1186,1187],{"class":651,"line":1047},[649,1188,1189],{},"  const [editor, setEditor] = useState\u003CEditor | null>(null)\n",[649,1191,1192],{"class":651,"line":1052},[649,1193,1194],{},"  const [content, setContent] = useState\u003CJSONContent>({ type: 'doc', content: [{ type: 'paragraph' }] })\n",[649,1196,1197],{"class":651,"line":1058},[649,1198,719],{"emptyLinePlaceholder":718},[649,1200,1201],{"class":651,"line":1064},[649,1202,1203],{},"  return (\n",[649,1205,1206],{"class":651,"line":1070},[649,1207,1208],{},"    \u003C>\n",[649,1210,1211],{"class":651,"line":1076},[649,1212,1213],{},"      \u003CEditorToolbar editor={editor ?? undefined} \u002F>\n",[649,1215,1216],{"class":651,"line":1082},[649,1217,1218],{},"      \u003CEditorSurface\n",[649,1220,1221],{"class":651,"line":1088},[649,1222,1223],{},"        preset={preset}\n",[649,1225,1227],{"class":651,"line":1226},20,[649,1228,1229],{},"        metadata={metadata}\n",[649,1231,1233],{"class":651,"line":1232},21,[649,1234,1235],{},"        value={content}\n",[649,1237,1239],{"class":651,"line":1238},22,[649,1240,1241],{},"        onChange={setContent}\n",[649,1243,1245],{"class":651,"line":1244},23,[649,1246,1247],{},"        onReady={setEditor}\n",[649,1249,1251],{"class":651,"line":1250},24,[649,1252,1253],{},"        onContentError={error => console.warn(error.message)}\n",[649,1255,1257],{"class":651,"line":1256},25,[649,1258,1259],{},"      \u002F>\n",[649,1261,1263],{"class":651,"line":1262},26,[649,1264,1265],{},"    \u003C\u002F>\n",[649,1267,1269],{"class":651,"line":1268},27,[649,1270,1271],{},"  )\n",[649,1273,1275],{"class":651,"line":1274},28,[649,1276,1277],{},"}\n",[418,1279,1280,1281,1284,1285,1288,1289,1292,1293,1296,1297,1299,1300,1302,1303,1306],{},"Typing ",[422,1282,1283],{},"@Ad"," opens the mention popup with the ",[422,1286,1287],{},"mentions"," list. A list the host does not supply (here ",[422,1290,1291],{},"hashtags",") comes from ",[422,1294,1295],{},"\u002Fapi\u002Feditor\u002Ftags"," through the context's HTTP client, and only once the ",[422,1298,436],{}," popup is used. The simple editor's ",[422,1301,440],{}," menu lists the core blocks; pass ",[422,1304,1305],{},"commands={defaults => [...defaults, ...]}"," (a module function) to add own entries.",[510,1308,1310,1311],{"id":1309},"the-one-liner-simpleeditor","The one-liner: ",[422,1312,1313],{},"SimpleEditor",[418,1315,1316,1317,484,1319,1322,1323,1326,1327,1330,1331,1334,1335,1337,1338,638],{},"Without own features, ",[422,1318,1313],{},[422,1320,1321],{},"@skaile\u002Fforge-editor\u002Freact\u002Fsimple"," builds the preset itself (",[422,1324,1325],{},"core-content"," + ",[422,1328,1329],{},"core-ui",", plus the features in its ",[422,1332,1333],{},"add"," prop) on an ",[422,1336,1118],{},". The toolbar takes its groups from the editor it is given; the ref exposes ",[422,1339,1340],{},"{ editor, openSettings, preset }",[640,1342,1344],{"className":986,"code":1343,"language":988,"meta":645,"style":645},"import { EditorToolbar } from '@skaile\u002Fforge-editor\u002Freact'\nimport { SimpleEditor } from '@skaile\u002Fforge-editor\u002Freact\u002Fsimple'\nimport type { Editor } from '@tiptap\u002Fcore'\nimport { useState } from 'react'\n\nexport function App() {\n  const [editor, setEditor] = useState\u003CEditor | null>(null)\n  return (\n    \u003C>\n      \u003CEditorToolbar editor={editor ?? undefined} \u002F>\n      \u003CSimpleEditor onReady={setEditor} \u002F>\n    \u003C\u002F>\n  )\n}\n",[422,1345,1346,1351,1356,1361,1365,1369,1373,1377,1381,1385,1389,1394,1398,1402],{"__ignoreMap":645},[649,1347,1348],{"class":651,"line":652},[649,1349,1350],{},"import { EditorToolbar } from '@skaile\u002Fforge-editor\u002Freact'\n",[649,1352,1353],{"class":651,"line":676},[649,1354,1355],{},"import { SimpleEditor } from '@skaile\u002Fforge-editor\u002Freact\u002Fsimple'\n",[649,1357,1358],{"class":651,"line":692},[649,1359,1360],{},"import type { Editor } from '@tiptap\u002Fcore'\n",[649,1362,1363],{"class":651,"line":715},[649,1364,1156],{},[649,1366,1367],{"class":651,"line":722},[649,1368,719],{"emptyLinePlaceholder":718},[649,1370,1371],{"class":651,"line":850},[649,1372,1184],{},[649,1374,1375],{"class":651,"line":868},[649,1376,1189],{},[649,1378,1379],{"class":651,"line":873},[649,1380,1203],{},[649,1382,1383],{"class":651,"line":881},[649,1384,1208],{},[649,1386,1387],{"class":651,"line":886},[649,1388,1213],{},[649,1390,1391],{"class":651,"line":892},[649,1392,1393],{},"      \u003CSimpleEditor onReady={setEditor} \u002F>\n",[649,1395,1396],{"class":651,"line":1047},[649,1397,1265],{},[649,1399,1400],{"class":651,"line":1052},[649,1401,1271],{},[649,1403,1404],{"class":651,"line":1058},[649,1405,1277],{},[418,1407,1408],{},"Try the React example here:",[1410,1411],"demo-frame",{"name":1412},"react-simple",[510,1414,1416],{"id":1415},"next-steps","Next steps",[418,1418,898,1419,1422,1423,1425,1426,595],{},[443,1420,1421],{"href":81},"tutorial"," shows the same editor on the React surface. The advanced editor on React is covered in ",[443,1424,127],{"href":128},"; every entry is listed in the ",[443,1427,1428],{"href":333},"exports reference",[1430,1431,1432],"style",{},"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 .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}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 .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}",{"title":645,"searchDepth":676,"depth":676,"links":1434},[1435,1436,1437,1439],{"id":512,"depth":676,"text":513},{"id":1112,"depth":676,"text":1113},{"id":1309,"depth":676,"text":1438},"The one-liner: SimpleEditor",{"id":1415,"depth":676,"text":1416},"Set up the simple editor in a Vite and React app: peers, Tailwind and shadcn tokens, EditorContextProvider, EditorSurface and SimpleEditor.","md",null,{},{"icon":6},{"title":29,"description":1440},"lSl1Y-zdEZ9f61bLI-yLpC5a1G7OpboVVPDNMRLr0mg",[1448,1450],{"title":25,"path":26,"stem":27,"description":1449,"icon":6,"children":-1},"Set up the simple editor in a Vite and Vue app: peers, Nuxt UI plugin, CSS and a mounted SimpleEditor with toolbar and outline.",{"title":33,"path":34,"stem":35,"description":1451,"icon":36,"children":-1},"Terms used across the documentation: editor composition, document, block, source, AI and panel vocabulary.",1793178228729]