From 468a45432367650ce0bbbe0f87513e449ad886dd Mon Sep 17 00:00:00 2001 From: miggymofongo Date: Wed, 8 Jan 2025 01:05:20 -0400 Subject: [PATCH] started to implement a horizontal rule command updated customKeymap with a keyboard shortcut to insert hr element updated editor appearance implemented a custom schema filler doc that prefilled a couple of nodes into the editor moved css to component because it wasn't reading from a separate component --- src/pages/app-write/app-write.ts | 261 +++++++++++++++------------- src/pages/app-write/write-styles.ts | 14 +- src/styles/shared-styles.ts | 3 +- 3 files changed, 148 insertions(+), 130 deletions(-) diff --git a/src/pages/app-write/app-write.ts b/src/pages/app-write/app-write.ts index 88934a2..2a8786f 100644 --- a/src/pages/app-write/app-write.ts +++ b/src/pages/app-write/app-write.ts @@ -13,14 +13,19 @@ import { Transaction } from 'prosemirror-state'; import { EditorView } from 'prosemirror-view'; import { Schema } from 'prosemirror-model'; -import { MenuBar } from './write-menu'; import { keymap } from 'prosemirror-keymap'; import { toggleMark } from 'prosemirror-commands'; import {undo, redo, history} from 'prosemirror-history' import { baseKeymap } from 'prosemirror-commands'; +/* i begin by creating a custom schema. following the guide +on prosemirror.net, i created a basic schema with a few +types of nodes. +texts are + +*/ export const customSchema = new Schema({ nodes: { text: { @@ -49,7 +54,15 @@ export const customSchema = new Schema({ toDOM() { return ['p', { class: 'boring' }, 0]; }, - parseDOM: [{ tag: 'p.boring', priority: 60 }], + parseDOM: [{ tag: 'p', priority: 60 }], + }, + hr: { + group: 'block', + selectable: true, + parseDOM: [{ tag: 'horizontal_rule' }], + toDOM() { + return ['hr', { class: 'horizontal-rule'}] + } }, doc: { content: 'block+', @@ -77,9 +90,20 @@ export const customSchema = new Schema({ ], inclusive: false, }, + bold: { + + }, + emphasis: { + + } }, }); + + + + + // function for error reports function errorReport(message: string): void { @@ -87,25 +111,53 @@ export const customSchema = new Schema({ } - // Commands + + + /* COMMANDS + commands are functions that take an editor state + and a dispatch function and returns a boolean + to implement editing actions.*/ + + + /**this command inserts a star by your cursor. it sets + * type to the star node, and creates one when + * dispatch is provided */ function insertStar(state: EditorState, dispatch?: (tr: Transaction) => void): boolean { - const type = customSchema.nodes.star; + const star = customSchema.nodes.star; const { $from } = state.selection; // If the parent cannot replace with the 'star' node, return false - if (!$from.parent.canReplaceWith($from.index(), $from.index(), type)) { + if (!$from.parent.canReplaceWith($from.index(), $from.index(), star)) { return false; } // If dispatch is provided, apply the transaction if (dispatch) { - dispatch(state.tr.replaceSelectionWith(type.create())); + dispatch(state.tr.replaceSelectionWith(star.create())); } // Always return true if insertion conditions are met return true; } + /* function that inserts an
line break +*/ +function insertHR(state: EditorState, dispatch?: (tr: Transaction) => void): boolean { + const hr = customSchema.nodes.hr; // Access the HR node from the schema + if (!hr) { + console.error('HR node is not defined in the schema.'); + return false; + } + + if (dispatch) { + dispatch(state.tr.replaceSelectionWith(hr.create())); + } + return true; +} + + + + /* this command will prompt you for a url, which will apply link mark to your selection and make your selection a hyperlink */ @@ -122,47 +174,29 @@ function toggleLink(state: EditorState, dispatch?: (tr: Transaction) => void): b } - /* starting to build a function that inserts an
line break - function insertHR(state: EditorState, dispatch?: (tr: Transaction) => void): boolean { - const type = customSchema.nodes.boring_paragraph - return false - } */ // custom keymap to apply to state const customKeymap = keymap({ - 'Ctrl-Space': insertStar, + 'Ctrl-Shift-Space': insertStar, 'Ctrl-b': (state, dispatch) => { console.log("Ctrl-b pressed, toggling shouting mark..."); return toggleMark(customSchema.marks.shouting)(state, dispatch); }, - 'Ctrl-q': (state, dispatch) => { - console.log("you should have just gotten an alert"); + 'Ctrl-k': (state, dispatch) => { + console.log("you should have just gotten an alert to place a url into a hyperlink"); return toggleLink(state, dispatch); }, + 'Ctrl-Shift-h': insertHR, + }); - const menuItems = [ - { - label: 'Bold', - command: (state, dispatch, view) => { - // Example command logic for bold - console.log('Bold clicked'); - return true; // Return true if active, false otherwise - }, - }, - { - label: 'Italic', - command: (state, dispatch, view) => { - console.log('Italic clicked'); - return true; - }, - }, -]; + + @@ -177,87 +211,61 @@ export class AppWrite extends LitElement { static styles = [ styles, - css` - .ProseMirror { - position: relative; - white-space: pre-wrap; - word-wrap: break-word; - outline: none; - background-color: white; - color: black; - border-radius: 4px; - padding: 10px; - min-height: 200px; /* Ensure there's enough height to type */ - } - .ProseMirror:empty::before { - content: "Start typing here..."; - color: black; - pointer-events: none; /* Ensures the placeholder doesn't block typing */ + css` +.ProseMirror { + background: black; + color: white; + background-clip: padding-box; + padding: 5px 0; + position: relative; + word-wrap: break-word; + white-space: pre-wrap; + -webkit-font-variant-ligatures: none; + font-variant-ligatures: none; + padding: 1rem; + line-height: 1.2; + outline: none; + font-family: var( + --markdown-editor-typography-font-family, + var(--mdc-typography-font-family, Montserrat, sans-serif) + ); + font-size: var( + --markdown-editor-typography-font-size, + var(--mdc-typography-subtitle1-font-size, 1rem) + ); + font-weight: var( + --markdown-editor-typography-font-weight, + var(--mdc-typography-subtitle1-font-weight, 400) + ); + letter-spacing: var( + --markdown-editor-typography-letter-spacing, + var(--mdc-typography-subtitle1-letter-spacing, 0.009375em) + ); + } - } + .ProseMirror pre { + white-space: pre-wrap; + } + .ProseMirror a { + color: var(--markdown-editor-typography-anchor-color, -webkit-link); + text-decoration: var(--markdown-editor-typography-anchor-text-decoration); + } + .ProseMirror-focused .ProseMirror-gapcursor { + display: block; + } + shouting { + all: unset; /* Remove inherited or conflicting styles */ + font-weight: bold; + text-transform: uppercase; + color: red; } - .ProseMirror { - word-wrap: break-word; - white-space: pre-wrap; - white-space: break-spaces; - -webkit-font-variant-ligatures: none; - font-variant-ligatures: none; - font-feature-settings: "liga" 0; /* the above doesn't seem to work in Edge */ - } - - .ProseMirror pre { - white-space: pre-wrap; - } - - .ProseMirror li { - position: relative; - } - - .ProseMirror-hideselection *::selection { background: transparent; } - .ProseMirror-hideselection *::-moz-selection { background: transparent; } - .ProseMirror-hideselection { caret-color: transparent; } - - /* See https://github.com/ProseMirror/prosemirror/issues/1421#issuecomment-1759320191 */ - .ProseMirror [draggable][contenteditable=false] { user-select: text } - - .ProseMirror-selectednode { - outline: 2px solid #8cf; - } - - /* Make sure li selections wrap around markers */ - - li.ProseMirror-selectednode { - outline: none; - } - - li.ProseMirror-selectednode:after { - content: ""; - position: absolute; - left: -32px; - right: -2px; top: -2px; bottom: -2px; - border: 2px solid #8cf; - pointer-events: none; - } - - /* Protect against generic img rules */ - - img.ProseMirror-separator { - display: inline !important; - border: none !important; - margin: 0 !important; - } - - shouting { - all: unset; /* Remove inherited or conflicting styles */ - font-weight: bold; - text-transform: uppercase; - color: red; - } - - ` + .boring { + background: grey; + } +` ]; @@ -271,31 +279,39 @@ export class AppWrite extends LitElement { errorReport('Editor container not here'); return; } + } - private initializeEditor() { + private initializeEditor() { if (!this.editorContainer) { errorReport('Editor container not here'); return; } - /* this is a schema of initial content to pre-populate the */ - - const initialContent = customSchema.nodes.doc.createAndFill([ - customSchema.nodes.paragraph.create( - null, - customSchema.text("Welcome to the editor! Start typing here.") - )]); + /* this is a schema of initial content to pre-populate the editor + with guidance */ - if (!initialContent) { + let doc = customSchema.node("doc", null, [ + customSchema.node("paragraph", null, [customSchema.text("write anything")]), + customSchema.node("boring_paragraph", null, [customSchema.text("you can't apply any marks to text in this boring paragraph")]) + + + ]) + + if (!doc) { console.error("failed to create initial document") return; } + + + /* here i create a state with doc as the schema, + which includes a couple */ + const state = EditorState.create({ - doc: initialContent, + doc: doc, plugins: [ history(), keymap({ @@ -304,11 +320,13 @@ export class AppWrite extends LitElement { }), customKeymap, keymap(baseKeymap), + ], }); + let view = new EditorView(this.editorContainer, { state, dispatchTransaction(transaction) { @@ -322,9 +340,10 @@ export class AppWrite extends LitElement { + console.log(state) - } + } connectedCallback(): void { super.connectedCallback(); @@ -344,13 +363,13 @@ export class AppWrite extends LitElement { protected render() { return html` - +
+ -
+
-
`; } } \ No newline at end of file diff --git a/src/pages/app-write/write-styles.ts b/src/pages/app-write/write-styles.ts index 7afcdce..83dcf10 100644 --- a/src/pages/app-write/write-styles.ts +++ b/src/pages/app-write/write-styles.ts @@ -4,6 +4,7 @@ export const editorStyles = css` { + .ProseMirror { background: white; color: black; @@ -48,14 +49,13 @@ export const editorStyles = css` { display: block; } -shouting { - all: unset; /* Remove inherited or conflicting styles */ - font-weight: bold; - text-transform: uppercase; - color: red; -} + shouting { + all: unset; /* Remove inherited or conflicting styles */ + font-weight: bold; + text-transform: uppercase; + color: red; } -.boring { + .boring { background: grey; } diff --git a/src/styles/shared-styles.ts b/src/styles/shared-styles.ts index c10c555..a390769 100644 --- a/src/styles/shared-styles.ts +++ b/src/styles/shared-styles.ts @@ -45,6 +45,5 @@ export const styles = css` flex-direction: row; align-items: flex-start; justify-content: space-between; - } - +}} ` \ No newline at end of file