From 185b35258cf1bc88050988f94e6f2c7a7a459d66 Mon Sep 17 00:00:00 2001 From: Jacob Pierce Date: Tue, 3 Mar 2026 14:31:09 -0800 Subject: [PATCH 1/2] focus the editor when closing tool modals --- .../TipTapEditor/TipTapEditor/composables/useImageHandling.js | 1 + .../TipTapEditor/TipTapEditor/composables/useLinkHandling.js | 1 + .../TipTapEditor/TipTapEditor/composables/useMathHandling.js | 1 + 3 files changed, 3 insertions(+) diff --git a/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/composables/useImageHandling.js b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/composables/useImageHandling.js index d80b3f6e03..86362245e7 100644 --- a/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/composables/useImageHandling.js +++ b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/composables/useImageHandling.js @@ -21,6 +21,7 @@ export function useImageHandling(editor) { modalInitialData.value = {}; editingNodePos.value = null; closeModalBase(); + editor.value?.commands.focus(); }; setupClickOutside('.image-upload-modal', closeModal); diff --git a/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/composables/useLinkHandling.js b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/composables/useLinkHandling.js index 148d8c6e8d..9cd5670b4d 100644 --- a/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/composables/useLinkHandling.js +++ b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/composables/useLinkHandling.js @@ -89,6 +89,7 @@ export function useLinkHandling(editor) { isEditorOpen.value = false; savedSelection.value = null; editorMode.value = 'create'; + editor.value?.commands.focus(); }; const openBubbleMenu = () => { diff --git a/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/composables/useMathHandling.js b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/composables/useMathHandling.js index 27a8f11df5..9c4aa1f63d 100644 --- a/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/composables/useMathHandling.js +++ b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/composables/useMathHandling.js @@ -18,6 +18,7 @@ export function useMathHandling(editor, editorMode) { const closeMathModal = () => { closeModalBase(); + editor.value?.commands.focus(); }; setupClickOutside('.formulas-menu', closeMathModal); From 40672ee4f269f3f4199f2487978e6c8158c55ba4 Mon Sep 17 00:00:00 2001 From: Jacob Pierce Date: Tue, 3 Mar 2026 14:33:30 -0800 Subject: [PATCH 2/2] Autofocus TipTap editor when creating new assessment questions Add autofocus prop to TipTapEditor, threaded through to the TipTap Editor constructor. AssessmentItemEditor sets shouldAutofocusQuestion when it mounts with an empty question (i.e. a newly created one), which passes autofocus=true to the TipTapEditor so the ProseMirror view receives focus as soon as it initializes. Co-Authored-By: Claude Opus 4.6 --- .../AssessmentItemEditor/AssessmentItemEditor.vue | 3 +++ .../views/TipTapEditor/TipTapEditor/TipTapEditor.vue | 8 +++++++- .../TipTapEditor/TipTapEditor/composables/useEditor.js | 3 ++- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/contentcuration/contentcuration/frontend/channelEdit/components/AssessmentItemEditor/AssessmentItemEditor.vue b/contentcuration/contentcuration/frontend/channelEdit/components/AssessmentItemEditor/AssessmentItemEditor.vue index 788b69e483..6fda15ddb4 100644 --- a/contentcuration/contentcuration/frontend/channelEdit/components/AssessmentItemEditor/AssessmentItemEditor.vue +++ b/contentcuration/contentcuration/frontend/channelEdit/components/AssessmentItemEditor/AssessmentItemEditor.vue @@ -41,6 +41,7 @@ v-if="isQuestionOpen" v-model="question" mode="edit" + :autofocus="shouldAutofocusQuestion" :imageProcessor="EditorImageProcessor" @update="onQuestionUpdate" @minimize="closeQuestion" @@ -201,6 +202,7 @@ data() { return { isQuestionOpen: false, + shouldAutofocusQuestion: false, openHintIdx: null, openAnswerIdx: null, kindSelectKey: 0, @@ -322,6 +324,7 @@ }, mounted() { if (!this.question) { + this.shouldAutofocusQuestion = true; this.openQuestion(); } }, diff --git a/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/TipTapEditor.vue b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/TipTapEditor.vue index d8afaa6469..ecf8577021 100644 --- a/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/TipTapEditor.vue +++ b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/TipTapEditor.vue @@ -215,7 +215,9 @@ const processedContent = preprocessMarkdown(newValue); if (!editor.value) { - initializeEditor(processedContent, props.mode); + initializeEditor(processedContent, props.mode, { + autofocus: props.autofocus, + }); return; } @@ -289,6 +291,10 @@ type: String, default: 'edit', // 'edit' or 'view' }, + autofocus: { + type: Boolean, + default: false, + }, tabindex: { type: [String, Number], default: 0, diff --git a/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/composables/useEditor.js b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/composables/useEditor.js index 259a71a9ee..06ff8dd2fa 100644 --- a/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/composables/useEditor.js +++ b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/composables/useEditor.js @@ -15,8 +15,9 @@ export function useEditor() { const isReady = ref(false); const isFocused = ref(false); - const initializeEditor = (content, mode = 'edit') => { + const initializeEditor = (content, mode = 'edit', { autofocus = false } = {}) => { editor.value = new Editor({ + autofocus, editable: mode === 'edit', extensions: [ StarterKitExtension.configure({