UNPKG

@limetech/lime-elements

Version:
241 lines (240 loc) • 7.25 kB
import { h } from '@stencil/core'; import translate from '../../../global/translations'; import { ENTER, ESCAPE } from '../../../util/keycodes'; /** * This component is a menu for editing a link in the text editor. * It allows the user to input the text and url for the link. * @beta * @private */ export class TextEditorLinkMenu { constructor() { this.getTranslation = (key) => { return translate.get(key, this.language); }; this.isValid = (href) => { try { new URL(href); } catch (_a) { return false; } return true; }; this.handleKeyDown = (event) => { var _a; if (event.key !== ENTER) { return; } if (this.saveButton) { this.saveButton.focus(); } event.preventDefault(); if (this.isValid((_a = this.link) === null || _a === void 0 ? void 0 : _a.href)) { this.handleSave(event); } }; this.handleCancel = (event) => { if (event instanceof KeyboardEvent && event.key !== ESCAPE) { return; } event.stopPropagation(); event.preventDefault(); this.cancel.emit(); }; this.handleSave = (event) => { event.stopPropagation(); this.save.emit(); }; this.handleLinkInputAction = (event) => { window.open(this.link.href, '_blank'); event.stopPropagation(); }; this.handleLinkTitleChange = (event) => { var _a; this.emitLinkChange(event.detail, (_a = this.link) === null || _a === void 0 ? void 0 : _a.href); }; this.handleLinkValueChange = (event) => { var _a; const href = event.detail; this.emitLinkChange((_a = this.link) === null || _a === void 0 ? void 0 : _a.text, href); }; this.emitLinkChange = (text, href) => { const newLink = { text: text, href: href, }; this.linkChange.emit(newLink); }; this.link = undefined; this.language = 'en'; this.isOpen = false; } connectedCallback() { this.setupGlobalHandlers(); } disconnectedCallback() { this.teardownGlobalHandlers(); } setupGlobalHandlers() { if (this.isOpen) { document.addEventListener('keyup', this.handleCancel); } } teardownGlobalHandlers() { document.removeEventListener('keyup', this.handleCancel); } componentDidLoad() { this.focusOnTextInput(); } focusOnTextInput() { if (this.textInput) { const inputField = this.textInput.shadowRoot.querySelector('input'); if (inputField) { requestAnimationFrame(() => { inputField.focus(); }); } } } render() { var _a, _b; const isValid = this.isValid(this.link.href); return [ h("limel-input-field", { label: this.getTranslation('editor-link-menu.text'), value: ((_a = this.link) === null || _a === void 0 ? void 0 : _a.text) || '', leadingIcon: "text_cursor", onChange: this.handleLinkTitleChange, onKeyDown: this.handleKeyDown, ref: (el) => (this.textInput = el) }), h("limel-input-field", { label: this.getTranslation('editor-link-menu.link'), value: ((_b = this.link) === null || _b === void 0 ? void 0 : _b.href) || '', type: "text", leadingIcon: "-lime-text-link", trailingIcon: "external_link", invalid: !isValid, onChange: this.handleLinkValueChange, onAction: this.handleLinkInputAction, onKeyDown: this.handleKeyDown }), h("div", { class: "actions" }, h("limel-button", { label: this.getTranslation('cancel'), onClick: this.handleCancel }), h("limel-button", { primary: true, label: this.getTranslation('save'), disabled: !isValid, onClick: this.handleSave, ref: (el) => (this.saveButton = el), slot: "button" })), ]; } static get is() { return "limel-text-editor-link-menu"; } static get encapsulation() { return "shadow"; } static get originalStyleUrls() { return { "$": ["editor-link-menu.scss"] }; } static get styleUrls() { return { "$": ["editor-link-menu.css"] }; } static get properties() { return { "link": { "type": "unknown", "mutable": false, "complexType": { "original": "EditorTextLink", "resolved": "{ text?: string; href: string; }", "references": { "EditorTextLink": { "location": "import", "path": "../prosemirror-adapter/menu/types" } } }, "required": false, "optional": false, "docs": { "tags": [], "text": "The link" } }, "language": { "type": "string", "mutable": false, "complexType": { "original": "Languages", "resolved": "\"da\" | \"de\" | \"en\" | \"fi\" | \"fr\" | \"nb\" | \"nl\" | \"no\" | \"sv\"", "references": { "Languages": { "location": "import", "path": "../../date-picker/date.types" } } }, "required": false, "optional": false, "docs": { "tags": [], "text": "Defines the language for translations." }, "attribute": "language", "reflect": true, "defaultValue": "'en'" }, "isOpen": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "Open state of the link-menu dialog" }, "attribute": "is-open", "reflect": true, "defaultValue": "false" } }; } static get events() { return [{ "method": "cancel", "name": "cancel", "bubbles": true, "cancelable": true, "composed": true, "docs": { "tags": [], "text": "Emitted when the menu is closed from inside the component.\n(*Not* emitted when the consumer sets the `open`-property to `false`.)" }, "complexType": { "original": "void", "resolved": "void", "references": {} } }, { "method": "save", "name": "save", "bubbles": true, "cancelable": true, "composed": true, "docs": { "tags": [], "text": "Emitted when the menu is saved from inside the component." }, "complexType": { "original": "void", "resolved": "void", "references": {} } }, { "method": "linkChange", "name": "linkChange", "bubbles": true, "cancelable": true, "composed": true, "docs": { "tags": [], "text": "Emitted when the user inputs new values for the link" }, "complexType": { "original": "EditorTextLink", "resolved": "{ text?: string; href: string; }", "references": { "EditorTextLink": { "location": "import", "path": "../prosemirror-adapter/menu/types" } } } }]; } } //# sourceMappingURL=editor-link-menu.js.map