1 import {$getNearestNodeFromDOMNode, LexicalEditor} from "lexical";
2 import {$isCustomListItemNode} from "../../../nodes/custom-list-item";
4 class TaskListHandler {
5 protected editorContainer: HTMLElement;
6 protected editor: LexicalEditor;
8 constructor(editor: LexicalEditor, editorContainer: HTMLElement) {
10 this.editorContainer = editorContainer;
11 this.setupListeners();
14 protected setupListeners() {
15 this.handleClick = this.handleClick.bind(this);
16 this.editorContainer.addEventListener('click', this.handleClick);
19 handleClick(event: MouseEvent) {
20 const target = event.target;
21 if (target instanceof HTMLElement && target.nodeName === 'LI' && target.classList.contains('task-list-item')) {
22 this.handleTaskListItemClick(target, event);
23 event.preventDefault();
27 handleTaskListItemClick(listItem: HTMLElement, event: MouseEvent) {
28 const bounds = listItem.getBoundingClientRect();
29 const withinBounds = event.clientX <= bounds.right
30 && event.clientX >= bounds.left
31 && event.clientY >= bounds.top
32 && event.clientY <= bounds.bottom;
34 // Outside task list item bounds means we're probably clicking the pseudo-element
39 this.editor.update(() => {
40 const node = $getNearestNodeFromDOMNode(listItem);
41 if ($isCustomListItemNode(node)) {
42 node.setChecked(!node.getChecked());
48 this.editorContainer.removeEventListener('click', this.handleClick);
53 export function registerTaskListHandler(editor: LexicalEditor, editorContainer: HTMLElement): (() => void) {
54 const handler = new TaskListHandler(editor, editorContainer);