-
-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Obsidian Editor inside AddOrEditTaskModal #50
Comments
This comment has been minimized.
This comment has been minimized.
So, Basically what i want is a function by Obsidian, similar to MarkdownRenderer, where i wont be passing a complete file to edit. I will only pass the previous task content, or the content which the user has entered, and now the user can edit that content, add anything he wants and then, i will receive this content entered/edited by user in a variable. From this received data, i will fetch all the fields and update them in json and file when the user will press save button. This editor, will also help me for the adding Comments feature i want to have in future just like this Github. But, notice one this in, github also, right now i am adding this comment using simple text editor. And there is a button to Preview this into Markdow, if you have entered any image or any other document. But in Obsidian it will be live, just like Obisidian's Live Editor. |
I am going to use the code from the following link and create a new file in my project : https://github.com/mgmeyers/obsidian-kanban/blob/main/src/components/Editor/MarkdownEditor.tsx Then I will update the below code in my AddOrEditTaskModal to use this MarkdownEditor : To embed the `MarkdownEditor` inside the `EditTaskContent` component and replace the existing `textarea`, here’s how you can modify the code.
### Steps:
1. **Create the `EmbeddedMarkdownEditor.tsx` file**:
Place the provided `MarkdownEditor` code in the `EmbeddedMarkdownEditor.tsx` file as planned.
2. **Modify `EditTaskContent` to Use `MarkdownEditor`**:
Replace the existing `textarea` with the `MarkdownEditor` from your `EmbeddedMarkdownEditor.tsx` file, while handling the necessary props, such as `value`, `onChange`, `onSubmit`, etc.
Here is how you can update the `EditTaskContent` component to use the new `MarkdownEditor`:
### Code Changes in `EditTaskContent`:
Replace the `textarea` block with the following:
```tsx
// Import the MarkdownEditor from the EmbeddedMarkdownEditor file
import { MarkdownEditor } from './Editor/EmbeddedMarkdownEditor';
// ...
const EditTaskContent: React.FC<{ app: App, plugin: TaskBoard, root: HTMLElement, task?: taskItem, taskExists?: boolean, filePath: string; onSave: (updatedTask: taskItem) => void; onClose: () => void }> = ({ app, plugin, root, task = taskItemEmpty, taskExists, filePath, onSave, onClose }) => {
// Replace the textarea state handler with the MarkdownEditor state handler
const [taskContent, setTaskContent] = useState(task.body ? task.body.join('\n') : '');
// Function to handle the submission of the task from MarkdownEditor
const handleMarkdownSubmit = (editor: EditorView) => {
const updatedContent = editor.state.doc.toString();
const updatedTask = parseTaskContent(updatedContent);
setTaskContent(updatedContent);
setUpdatedTask(updatedTask);
onSave(updatedTask);
onClose();
};
return (
<div className="EditTaskModalHome">
{/* Your other code */}
{/* Conditional rendering based on active tab */}
<div className={`EditTaskModalTabContent ${activeTab === 'preview' ? 'show' : 'hide'}`}>
{/* Preview Section */}
<div className="EditTaskModalHomePreview" style={{ display: activeTab === 'preview' ? 'block' : 'none' }}>
{/* Your Preview logic */}
</div>
</div>
<div className={`EditTaskModalTabContent ${activeTab === 'editor' ? 'show' : 'hide'}`}>
<div className="EditTaskModalHomePreviewHeader">
Directly Edit any value or add more sub tasks and description for this task.
</div>
{/* Embed the MarkdownEditor */}
<MarkdownEditor
value={taskContent}
onChange={(update) => setTaskContent(update.state.doc.toString())}
onSubmit={handleMarkdownSubmit}
className="EditTaskModalBodyDescription"
placeholder="Body content"
/>
</div>
{/* Rest of your component code */}
<button className="EditTaskModalHomeSaveBtn" onClick={handleSave}>Save</button>
</div>
);
};
// Rest of your modal logic Key Changes:
By following these steps, you'll be able to replace the standard
|
Following is the simplest code GPT gave using the codeMirror library, just sharing here to refer, because I am deleting the below file /src/components/MarkdownEditor.tsx : // /src/components/MarkdownEditor.tsx
import { EditorView, basicSetup } from 'codemirror';
import React, { useEffect, useRef, useState } from 'react';
import { markdown, markdownLanguage } from '@codemirror/lang-markdown';
import { indentWithTab } from '@codemirror/commands';
import { keymap } from '@codemirror/view';
import { oneDark } from '@codemirror/theme-one-dark';
class MarkdownEditor {
private editorView: EditorView | null = null;
private onChangeCallback: (value: string) => void;
constructor(onChangeCallback: (value: string) => void) {
this.onChangeCallback = onChangeCallback;
}
initializeEditor(editorContainer: HTMLDivElement, initialValue: string) {
if (this.editorView) {
this.editorView.destroy();
}
this.editorView = new EditorView({
doc: initialValue,
extensions: [
basicSetup,
markdown({ base: markdownLanguage }),
oneDark,
keymap.of([indentWithTab]), // Correctly wrap keybindings with `keymap.of()`
EditorView.updateListener.of((update) => {
if (update.docChanged) {
const currentValue = this.editorView?.state.doc.toString() || '';
this.onChangeCallback(currentValue);
}
}),
],
parent: editorContainer,
});
}
destroyEditor() {
if (this.editorView) {
this.editorView.destroy();
this.editorView = null;
}
}
getEditorValue(): string {
return this.editorView?.state.doc.toString() || '';
}
static extractIndentedLines(content: string): string[] {
return content
.split('\n')
.filter((line) => /^\s+[^- \[]/.test(line)); // lines with indentation not starting with `- [ ]`
}
}
export default function CodeMirrorEditor({ initialContent, onChange }: { initialContent: string, onChange: (bodyContent: string[]) => void }) {
const editorRef = useRef<HTMLDivElement>(null);
const [editorInstance, setEditorInstance] = useState<MarkdownEditor | null>(null);
useEffect(() => {
if (editorRef.current) {
const editor = new MarkdownEditor((value: string) => {
const indentedLines = MarkdownEditor.extractIndentedLines(value);
onChange(indentedLines);
});
editor.initializeEditor(editorRef.current, initialContent);
setEditorInstance(editor);
return () => {
editor.destroyEditor();
};
}
}, [initialContent, onChange]);
return <div ref={editorRef} className="markdown-editor"></div>;
} |
Creating a new branch for this Markdown Editor Implementation called |
A suggestion from Hover Editor developerAs for integrating with a modal, HE isn't just integrating an editor - we're integrating a workspace root with a leaf and a view and all the rest, which is why we can show anything in the popover, not just markdown. (See the rootSplit property of hover editors.) You can probably do something similar in a modal, but we have a LOT of monkeypatches to make it work right, and you'll have even more to deal with in a modal. Notably, modals override the default keyboard event handling which means commands won't work in the modal. You may also run into z-ordering problems because modals are layered above where this stuff normally renders. If I were trying to do what you're doing, I'd probably just do my own modal class copying the HTML rather than extending Obsidian's modal. That would let me bypass both the keyboard and z-order issues, though there might also be some challenges still with what happens if somebody switches away from the view. Well, that's what I'd do if I wanted to be able to display notes in a modal; if all you want to do is to be able to edit some markdown in one, you might be better off looking at the Kanban plugin, which pops up little mini-markdown editors when you edit Kanban cards, and it still supports all the editor hotkeys and such. I'm fairly sure they're managing that with a lot less monkeypatching, though again you may run into some issues with z-order and hotkeys if you're integrating with Obsidian's Modal class. |
Right now, in the AddOrEdiTaskModal i only have a MarkdownRenderer, which renders the passed content in the format of Obsidians Reading View mode. But i want to now convert it into Obsidian's Edit View. Where the user can see the live Preview of the content the user has entered, as well as, the user will able to edit right from the modal itself, the things he want to edit. Also more powerful features like making font bold, italic, adding code, pasting images and documents, literally everything just like the Obsidian Editor.
So I just have to find a way to add this Editor inside this modal. Then i can simply remove the TextArea input element to take task Description and mention as a message that, add the Description in the below Editor.
The text was updated successfully, but these errors were encountered: