1 import {EditorContainerUiElement} from "../core";
2 import {el} from "../../../utils/dom";
3 import {EditorFormField} from "../forms";
4 import {$getAllNodesOfType} from "../../../utils/nodes";
5 import {uniqueIdSmall} from "../../../../services/util";
6 import {$isHeadingNode, HeadingNode} from "@lexical/rich-text/LexicalHeadingNode";
8 export class LinkField extends EditorContainerUiElement {
9 protected input: EditorFormField;
10 protected headerMap = new Map<string, HeadingNode>();
12 constructor(input: EditorFormField) {
18 buildDOM(): HTMLElement {
19 const listId = 'editor-form-datalist-' + this.input.getName() + '-' + Date.now();
20 const inputOuterDOM = this.input.getDOMElement();
21 const inputFieldDOM = inputOuterDOM.querySelector('input');
22 inputFieldDOM?.setAttribute('list', listId);
23 inputFieldDOM?.setAttribute('autocomplete', 'off');
24 const datalist = el('datalist', {id: listId});
26 const container = el('div', {
27 class: 'editor-link-field-container',
28 }, [inputOuterDOM, datalist]);
30 inputFieldDOM?.addEventListener('focusin', () => {
31 this.updateDataList(datalist);
34 inputFieldDOM?.addEventListener('input', () => {
35 const value = inputFieldDOM.value;
36 const header = this.headerMap.get(value);
38 this.updateFormFromHeader(header);
45 updateFormFromHeader(header: HeadingNode) {
46 this.getHeaderIdAndText(header).then(({id, text}) => {
47 const modal = this.getContext().manager.getActiveModal('link');
49 modal.getForm().setValues({
58 getHeaderIdAndText(header: HeadingNode): Promise<{id: string, text: string}> {
59 return new Promise((res) => {
60 this.getContext().editor.update(() => {
61 let id = header.getId();
63 id = 'header-' + uniqueIdSmall();
67 const text = header.getTextContent();
73 updateDataList(listEl: HTMLElement) {
74 this.getContext().editor.getEditorState().read(() => {
75 const headers = $getAllNodesOfType($isHeadingNode) as HeadingNode[];
77 this.headerMap.clear();
78 const listEls: HTMLElement[] = [];
80 for (const header of headers) {
81 const key = 'header-' + header.getKey();
82 this.headerMap.set(key, header);
83 listEls.push(el('option', {
85 label: header.getTextContent().substring(0, 54),
89 listEl.innerHTML = '';
90 listEl.append(...listEls);