diff --git a/contentcuration/contentcuration/frontend/channelEdit/components/AnswersEditor/AnswersEditor.spec.js b/contentcuration/contentcuration/frontend/channelEdit/components/AnswersEditor/AnswersEditor.spec.js index 7544e79acf..fe0ec93a82 100644 --- a/contentcuration/contentcuration/frontend/channelEdit/components/AnswersEditor/AnswersEditor.spec.js +++ b/contentcuration/contentcuration/frontend/channelEdit/components/AnswersEditor/AnswersEditor.spec.js @@ -3,6 +3,7 @@ import { shallowMount, mount } from '@vue/test-utils'; import { AssessmentItemToolbarActions } from '../../constants'; import AnswersEditor from './AnswersEditor'; import { AssessmentItemTypes } from 'shared/constants'; +import TipTapEditor from 'shared/views/TipTapEditor/TipTapEditor/TipTapEditor.vue'; jest.mock('shared/views/TipTapEditor/TipTapEditor/TipTapEditor.vue'); @@ -245,6 +246,31 @@ describe('AnswersEditor', () => { }); }); + describe('autofocus on the open answer editor', () => { + beforeEach(() => { + wrapper = mount(AnswersEditor, { + propsData: { + questionKind: AssessmentItemTypes.SINGLE_SELECTION, + answers: [ + { answer: 'Mayonnaise (I mean you can, but...)', correct: true, order: 1 }, + { answer: 'Peanut butter', correct: false, order: 2 }, + ], + openAnswerIdx: 1, + }, + }); + }); + + it('passes autofocus=true to the open answer editor', () => { + const editors = wrapper.findAllComponents(TipTapEditor); + expect(editors.at(1).props('autofocus')).toBe(true); + }); + + it('passes autofocus=false to closed answer editors', () => { + const editors = wrapper.findAllComponents(TipTapEditor); + expect(editors.at(0).props('autofocus')).toBe(false); + }); + }); + describe('on an answer click', () => { beforeEach(async () => { wrapper = mount(AnswersEditor, { @@ -314,7 +340,7 @@ describe('AnswersEditor', () => { }, }); - const editors = wrapper.findAllComponents({ name: 'RichTextEditor' }); + const editors = wrapper.findAllComponents(TipTapEditor); editors.at(1).vm.$emit('update', 'European butter'); await wrapper.vm.$nextTick(); diff --git a/contentcuration/contentcuration/frontend/channelEdit/components/AnswersEditor/AnswersEditor.vue b/contentcuration/contentcuration/frontend/channelEdit/components/AnswersEditor/AnswersEditor.vue index 83fc9e2bcf..fb2c83b9e2 100644 --- a/contentcuration/contentcuration/frontend/channelEdit/components/AnswersEditor/AnswersEditor.vue +++ b/contentcuration/contentcuration/frontend/channelEdit/components/AnswersEditor/AnswersEditor.vue @@ -94,6 +94,7 @@ v-model="answer.answer" class="editor" :mode="isAnswerOpen(answerIdx) ? 'edit' : 'view'" + :autofocus="isAnswerOpen(answerIdx)" :imageProcessor="EditorImageProcessor" @update="updateAnswerText($event, answerIdx)" @minimize="emitClose" @@ -164,6 +165,7 @@ v-model="answer.answer" class="editor" :mode="isAnswerOpen(answerIdx) ? 'edit' : 'view'" + :autofocus="isAnswerOpen(answerIdx)" :imageProcessor="EditorImageProcessor" @update="updateAnswerText($event, answerIdx)" @minimize="emitClose" diff --git a/contentcuration/contentcuration/frontend/channelEdit/components/HintsEditor/HintsEditor.spec.js b/contentcuration/contentcuration/frontend/channelEdit/components/HintsEditor/HintsEditor.spec.js index 65b228a26f..a44043a60a 100644 --- a/contentcuration/contentcuration/frontend/channelEdit/components/HintsEditor/HintsEditor.spec.js +++ b/contentcuration/contentcuration/frontend/channelEdit/components/HintsEditor/HintsEditor.spec.js @@ -3,6 +3,7 @@ import { shallowMount, mount } from '@vue/test-utils'; import { AssessmentItemToolbarActions } from '../../constants'; import HintsEditor from './HintsEditor'; +import TipTapEditor from 'shared/views/TipTapEditor/TipTapEditor/TipTapEditor.vue'; jest.mock('shared/views/TipTapEditor/TipTapEditor/TipTapEditor.vue'); @@ -65,7 +66,7 @@ describe('HintsEditor', () => { }); // Find all instances of your new RichTextEditor component - const editors = wrapper.findAllComponents({ name: 'RichTextEditor' }); + const editors = wrapper.findAllComponents(TipTapEditor); expect(editors.length).toBe(2); // Instead of checking the raw HTML, we check the `value` prop passed to each editor. @@ -85,7 +86,7 @@ describe('HintsEditor', () => { }, }); - const editors = wrapper.findAllComponents({ name: 'RichTextEditor' }); + const editors = wrapper.findAllComponents(TipTapEditor); editors.at(1).vm.$emit('update', 'Updated hint'); }); @@ -131,6 +132,30 @@ describe('HintsEditor', () => { }); }); + describe('autofocus on the open hint editor', () => { + beforeEach(() => { + wrapper = mount(HintsEditor, { + propsData: { + hints: [ + { hint: 'First hint', order: 1 }, + { hint: 'Second hint', order: 2 }, + ], + openHintIdx: 0, + }, + }); + }); + + it('passes autofocus=true to the open hint editor', () => { + const editors = wrapper.findAllComponents(TipTapEditor); + expect(editors.at(0).props('autofocus')).toBe(true); + }); + + it('passes autofocus=false to closed hint editors', () => { + const editors = wrapper.findAllComponents(TipTapEditor); + expect(editors.at(1).props('autofocus')).toBe(false); + }); + }); + describe('on hint click', () => { beforeEach(async () => { wrapper = mount(HintsEditor, { diff --git a/contentcuration/contentcuration/frontend/channelEdit/components/HintsEditor/HintsEditor.vue b/contentcuration/contentcuration/frontend/channelEdit/components/HintsEditor/HintsEditor.vue index 05ad7ebf85..ad204c50cd 100644 --- a/contentcuration/contentcuration/frontend/channelEdit/components/HintsEditor/HintsEditor.vue +++ b/contentcuration/contentcuration/frontend/channelEdit/components/HintsEditor/HintsEditor.vue @@ -51,6 +51,7 @@ diff --git a/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/TipTapEditor.vue b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/TipTapEditor.vue index 70a2b6b77c..f59e183e86 100644 --- a/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/TipTapEditor.vue +++ b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/TipTapEditor.vue @@ -205,6 +205,11 @@ if (editor.value && editor.value.isEditable !== (newMode === 'edit')) { editor.value.setEditable(newMode === 'edit'); } + if (newMode === 'edit' && editor.value && props.autofocus) { + nextTick(() => { + editor.value?.commands.focus('end'); + }); + } }, );