@limetech/lime-elements
Version:
241 lines (240 loc) • 7.25 kB
JavaScript
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