1 import {EditorContainerUiElement} from "../core";
2 import {el} from "../../../utils/dom";
3 import {EditorFormField} from "../forms";
4 import {CustomHeadingNode} from "../../../nodes/custom-heading";
5 import {$getAllNodesOfType} from "../../../utils/nodes";
6 import {$isHeadingNode} from "@lexical/rich-text";
7 import {uniqueIdSmall} from "../../../../services/util";
9 export class LinkField extends EditorContainerUiElement {
10 protected input: EditorFormField;
11 protected headerMap = new Map<string, CustomHeadingNode>();
13 constructor(input: EditorFormField) {
19 buildDOM(): HTMLElement {
20 const listId = 'editor-form-datalist-' + this.input.getName() + '-' + Date.now();
21 const inputOuterDOM = this.input.getDOMElement();
22 const inputFieldDOM = inputOuterDOM.querySelector('input');
23 inputFieldDOM?.setAttribute('list', listId);
24 inputFieldDOM?.setAttribute('autocomplete', 'off');
25 const datalist = el('datalist', {id: listId});
27 const container = el('div', {
28 class: 'editor-link-field-container',
29 }, [inputOuterDOM, datalist]);
31 inputFieldDOM?.addEventListener('focusin', () => {
32 this.updateDataList(datalist);
35 inputFieldDOM?.addEventListener('input', () => {
36 const value = inputFieldDOM.value;
37 const header = this.headerMap.get(value);
39 this.updateFormFromHeader(header);
46 updateFormFromHeader(header: CustomHeadingNode) {
47 this.getHeaderIdAndText(header).then(({id, text}) => {
48 console.log('updating form', id, text);
49 const modal = this.getContext().manager.getActiveModal('link');
51 modal.getForm().setValues({
60 getHeaderIdAndText(header: CustomHeadingNode): Promise<{id: string, text: string}> {
61 return new Promise((res) => {
62 this.getContext().editor.update(() => {
63 let id = header.getId();
64 console.log('header', id, header.__id);
66 id = 'header-' + uniqueIdSmall();
70 const text = header.getTextContent();
76 updateDataList(listEl: HTMLElement) {
77 this.getContext().editor.getEditorState().read(() => {
78 const headers = $getAllNodesOfType($isHeadingNode) as CustomHeadingNode[];
80 this.headerMap.clear();
81 const listEls: HTMLElement[] = [];
83 for (const header of headers) {
84 const key = 'header-' + header.getKey();
85 this.headerMap.set(key, header);
86 listEls.push(el('option', {
88 label: header.getTextContent().substring(0, 54),
92 listEl.innerHTML = '';
93 listEl.append(...listEls);