From 1413c8a08cd357fb95701a215f760d9f854da96a Mon Sep 17 00:00:00 2001 From: Duncan McClean Date: Tue, 10 Mar 2026 10:54:03 +0000 Subject: [PATCH 1/2] Only remove Bard set when backspace key is hit --- .../js/components/fieldtypes/bard/Set.js | 31 ++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/resources/js/components/fieldtypes/bard/Set.js b/resources/js/components/fieldtypes/bard/Set.js index bd5225b064d..9b9b988aa96 100644 --- a/resources/js/components/fieldtypes/bard/Set.js +++ b/resources/js/components/fieldtypes/bard/Set.js @@ -1,5 +1,5 @@ import { Node } from '@tiptap/core'; -import { Plugin, PluginKey } from '@tiptap/pm/state'; +import { Plugin, PluginKey, NodeSelection } from '@tiptap/pm/state'; import { Slice, Fragment } from '@tiptap/pm/model'; import { Decoration, DecorationSet } from '@tiptap/pm/view'; import { VueNodeViewRenderer } from '@tiptap/vue-3'; @@ -75,6 +75,35 @@ export const Set = Node.create({ }; }, + addKeyboardShortcuts() { + const shortcuts = {}; + const type = this.type; + + const isSetSelected = (state) => { + const { selection } = state; + return selection instanceof NodeSelection && selection.node.type === type; + }; + + const blockCharacterKey = () => isSetSelected(this.editor.state); + + // Letters a-z + for (let i = 97; i <= 122; i++) { + shortcuts[String.fromCharCode(i)] = blockCharacterKey; + } + + // Numbers 0-9 + for (let i = 0; i <= 9; i++) { + shortcuts[String(i)] = blockCharacterKey; + } + + // Common punctuation/symbols + [' ', '-', '=', '[', ']', '\\', ';', "'", ',', '.', '/', '`'].forEach( + (key) => (shortcuts[key] = blockCharacterKey), + ); + + return shortcuts; + }, + addProseMirrorPlugins() { const bard = this.options.bard; const type = this.type; From 19566f8b9b1fae779cb694c5886cfcffaba09bc4 Mon Sep 17 00:00:00 2001 From: Duncan McClean Date: Thu, 12 Mar 2026 16:57:16 +0000 Subject: [PATCH 2/2] refactor into a tiptap plugin --- .../js/components/fieldtypes/bard/Set.js | 44 +++++++------------ 1 file changed, 15 insertions(+), 29 deletions(-) diff --git a/resources/js/components/fieldtypes/bard/Set.js b/resources/js/components/fieldtypes/bard/Set.js index 9b9b988aa96..907d5e58cd9 100644 --- a/resources/js/components/fieldtypes/bard/Set.js +++ b/resources/js/components/fieldtypes/bard/Set.js @@ -75,35 +75,6 @@ export const Set = Node.create({ }; }, - addKeyboardShortcuts() { - const shortcuts = {}; - const type = this.type; - - const isSetSelected = (state) => { - const { selection } = state; - return selection instanceof NodeSelection && selection.node.type === type; - }; - - const blockCharacterKey = () => isSetSelected(this.editor.state); - - // Letters a-z - for (let i = 97; i <= 122; i++) { - shortcuts[String.fromCharCode(i)] = blockCharacterKey; - } - - // Numbers 0-9 - for (let i = 0; i <= 9; i++) { - shortcuts[String(i)] = blockCharacterKey; - } - - // Common punctuation/symbols - [' ', '-', '=', '[', ']', '\\', ';', "'", ',', '.', '/', '`'].forEach( - (key) => (shortcuts[key] = blockCharacterKey), - ); - - return shortcuts; - }, - addProseMirrorPlugins() { const bard = this.options.bard; const type = this.type; @@ -115,6 +86,21 @@ export const Set = Node.create({ return found; }; return [ + new Plugin({ + key: new PluginKey('setBlockCharacterInput'), + props: { + handleKeyDown(view, event) { + const { selection } = view.state; + if (!(selection instanceof NodeSelection) || selection.node.type !== type) return false; + + const key = event.key; + if (['Backspace', 'Delete', 'Enter', 'Escape', 'Tab'].includes(key)) return false; + if (key.length === 1) return true; + + return false; + }, + }, + }), new Plugin({ key: new PluginKey('setSelectionDecorator'), props: {