Repository navigation
Implement Obsidian-like Canvas Feature in Notes System - #12
Merged
Merged
Conversation
Add the canvas note type, initialize empty documents, preserve canvas filenames, and validate JSON Canvas content before writes. Cover format validation and all notes scopes with backend tests.
Add React Flow, Markdown rendering, HTML sanitization, and image export packages. Declare the peer packages needed by the existing chart and testing dependencies.
Validate and preserve JSON Canvas data, resolve stable file references, and support geometry, duplication, arrangement, and portable Markdown exports. Include unit coverage for interchange and invalid input.
Add cards, connections, groups, nested previews, linked-note editing, navigation, selection, history, and layout controls. Support media import and canvas, PNG, and file-bundle exports.
Serialize writes per document, flush pending changes on tab close, and recover browser-backed drafts. Test save failures, retries, concurrent edits, and exhausted browser storage.
Enable canvas creation and editing across library, project, experiment, and item notes. Add rich-text canvas embeds, wiki-link suggestions, graph references, and backlinks; fix library folder creation and test shared-panel creation.
Exercise directory and project creation, tab switches and reloads, nested references, linked-note editing, connections, grouping, history, media, import validation, read-only behavior, and downloads.
Document canvas note APIs, editing controls, persistence, exports, and interoperability limits. Link the canvas guide from the documentation index.
Keep editors, links, and media controls interactive while enabling dragging from both headers and preview content. Add browser regressions for pointer tracking on selected and unselected cards and for text selection, and update the usage guide.
ThePyProgrammer
marked this pull request as ready for review
October 30, 2026 05:31
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Canvas documents
Use New canvas in a notes explorer, or right-click a folder and choose New canvas. Canvases appear alongside notes and folders in library, paper, website, repository, project, and experiment notes. Names end in
.canvas; storage uses the existing notes API and database, with no migration or new service required.The editor stores JSON Canvas 1.0, the open format used by Obsidian Canvas. It preserves node ordering, standard optional fields, and extension fields on import and export.
Cards and connections
#Headingor#^block-id..canvasattachments become canvas documents in the current notes folder. Remote media can be referenced by an imported file node's HTTP(S) URL.Editing and navigation
Drag card headers to move them and selected card borders to resize. Drag blank space for a selection box, Shift-click for multiple selection, or use Ctrl/Command+A. Alt-drag leaves a duplicate at the original position. The inspector offers duplication, deletion, layer ordering, grouping, six alignments, row/column/grid layouts, spacing distribution, and horizontal/vertical justification.
Use Space-drag or the middle mouse button to pan, wheel to scroll, Ctrl/Command-wheel or pinch to zoom, and the minimap to navigate. The controls include fit-all, fit-selection, 100% zoom, group navigation, and card text search. Settings expose grid snapping, object snapping, resize aspect ratio, minimap visibility, and read-only mode.
Undo history holds the last 100 canvas operations and resets when the editor closes. Read-only mode prevents document changes while retaining navigation and export.
Saving and references
Changes autosave after a short debounce. Writes are serialized per document, and switching tabs flushes pending changes. The directory receives each draft immediately. Unsaved content is also backed up in browser storage when available; a failed save shows Retry save, and reopening a canvas recovers its draft. Browser storage limits can prevent large media drafts from being backed up; API saving still works. The application warns before leaving with a pending save.
Internal references use the note ID as an optional
researchos.noteIdextension. Renaming or moving a referenced note keeps the reference intact. File paths refresh on export. Imported paths resolve within the current source first, then across loaded sources if unique. A deleted ID does not silently resolve to a different file with the same name. References resolve only within notes loaded by the current library/project/panel.Canvases participate in directory search, pinning, recent notes, graph links, and backlinks. In a rich-text note, use Embed canvas or type
![[Name.canvas]]to insert a preview. Ordinary wiki links can also target canvases.Import and export
Attachments are stored in optional ResearchOS extensions inside the canvas, rather than separate backend uploads. Use ZIP export when moving media to Obsidian; a standalone
.canvasfile cannot supply separate attachment files to applications that ignore those extensions. Importing an Obsidian canvas does not grant this web application access to its local vault: matching notes must already exist in ResearchOS, or be added/relinked. ZIP export is supported; ZIP/vault import is not.Compatibility boundaries
This is an implementation of the JSON Canvas format and the core visual Canvas workflow, not the Obsidian application runtime. Obsidian Bases (
.basedatabases), community plugin behaviors, vault filesystem services, Obsidian-specific commands/branding, and exact mobile long-press menus are not implemented. Generic file nodes referencing those files are preserved. Browser/touch interaction uses the graph editor's gestures; desktop and touch menus are not identical to Obsidian's.Local SVG and HTML media are not executed. Web embeds run in sandboxed frames, HTML note previews are sanitized, and Markdown cards do not execute embedded HTML. Cyclic previews stop rather than recursively rendering forever.
Development checks
From
frontend, runnpm run test:run,npm run test:e2e -- canvas.spec.js, andnpm run build. The repository currently has a pre-existing KaTeX/Tiptap peer-version mismatch; dependency installation may requirenpm install --legacy-peer-deps. Frombackend, run.venv/Scripts/python.exe -m pytest tests/test_canvas.py tests/test_note_batch.py tests/test_chat_and_notes_routes.py -qon Windows.