feat(editor): mark a checkbox item as done when clicking on its text
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
kolaente 2023-11-18 18:01:09 +01:00
parent d3497c96d7
commit 2967019cd9
Signed by: konrad
GPG Key ID: F40E70337AB24C9B
2 changed files with 48 additions and 4 deletions

View File

@ -1,5 +1,5 @@
<template> <template>
<div class="tiptap"> <div class="tiptap" ref="tiptapInstanceRef">
<EditorToolbar <EditorToolbar
v-if="editor && isEditing" v-if="editor && isEditing"
:editor="editor" :editor="editor"
@ -174,6 +174,8 @@ import {eventToHotkeyString} from '@github/hotkey'
import {mergeAttributes} from '@tiptap/core' import {mergeAttributes} from '@tiptap/core'
import {createRandomID} from '@/helpers/randomId' import {createRandomID} from '@/helpers/randomId'
const tiptapInstanceRef = ref<HTMLInputElement | null>(null)
const {t} = useI18n() const {t} = useI18n()
const CustomTableCell = TableCell.extend({ const CustomTableCell = TableCell.extend({
@ -531,20 +533,61 @@ function setFocusToEditor(event) {
editor.value?.commands.focus() editor.value?.commands.focus()
} }
function clickTasklistCheckbox(event) {
// Needs to be a separate function to be able to remove the event listener
event.target.parentNode.parentNode.firstChild.click()
}
watch(
() => isEditing.value,
editing => {
nextTick(() => {
const checkboxes = tiptapInstanceRef.value.querySelectorAll('[data-checked]')
if (editing) {
checkboxes.forEach(check => {
if (check.children.length < 2) {
return
}
// We assume the first child contains the label element with the checkbox and the second child the actual label
// When the actual label is clicked, we forward that click to the checkbox.
check.children[1].removeEventListener('click', clickTasklistCheckbox)
})
return
}
checkboxes.forEach(check => {
if (check.children.length < 2) {
return
}
// We assume the first child contains the label element with the checkbox and the second child the actual label
// When the actual label is clicked, we forward that click to the checkbox.
check.children[1].addEventListener('click', clickTasklistCheckbox)
})
})
},
{immediate: true},
)
</script> </script>
<style lang="scss"> <style lang="scss">
.tiptap__editor { .tiptap__editor {
&.tiptap__editor-is-edit-enabled { &.tiptap__editor-is-edit-enabled {
min-height: 10rem; min-height: 10rem;
.ProseMirror { .ProseMirror {
padding: .5rem; padding: .5rem;
} }
&:focus-within, &:focus { &:focus-within, &:focus {
box-shadow: 0 0 0 2px hsla(var(--primary-hsl), 0.5); box-shadow: 0 0 0 2px hsla(var(--primary-hsl), 0.5);
} }
ul[data-type='taskList'] li > div {
cursor: text;
}
} }
transition: box-shadow $transition; transition: box-shadow $transition;
@ -794,6 +837,7 @@ ul[data-type='taskList'] {
> div { > div {
flex: 1 1 auto; flex: 1 1 auto;
cursor: pointer;
} }
} }

View File

@ -177,7 +177,7 @@ export const ALPHABETICAL_SORT = 'title'
</script> </script>
<script setup lang="ts"> <script setup lang="ts">
import {computed, nextTick, onMounted, reactive, ref, shallowReactive, toRefs, watch} from 'vue' import {computed, nextTick, onMounted, reactive, ref, shallowReactive, toRefs} from 'vue'
import {camelCase} from 'camel-case' import {camelCase} from 'camel-case'
import {watchDebounced} from '@vueuse/core' import {watchDebounced} from '@vueuse/core'