A first version that has some working standard features.
This commit is contained in:
97
tp-rtb-link.js
Normal file
97
tp-rtb-link.js
Normal file
@@ -0,0 +1,97 @@
|
||||
import '@tp/tp-dialog/tp-dialog.js';
|
||||
import '@tp/tp-form/tp-form.js';
|
||||
import '@tp/tp-input/tp-input.js';
|
||||
import '@tp/tp-button/tp-button.js';
|
||||
import { html } from 'lit';
|
||||
import { TpRtbBaseExtension } from './tp-rtb-base-extension.js';
|
||||
import Link from '@tiptap/extension-link';
|
||||
|
||||
class TpRtbLink extends TpRtbBaseExtension {
|
||||
constructor() {
|
||||
super();
|
||||
this.label = 'Link';
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`
|
||||
${super.render()}
|
||||
|
||||
<tp-dialog>
|
||||
<h3>Add Link</h3>
|
||||
<tp-form @submit=${this._saveLink}>
|
||||
<tp-input name="url" .value=${this.url} required errorMessage="Required">
|
||||
<input type="text">
|
||||
</tp-input>
|
||||
<tp-input name="text" .value=${this.text}>
|
||||
<input type="text">
|
||||
</tp-input>
|
||||
<div class="buttons">
|
||||
<tp-button dialog-dismiss>Cancel</tp-button>
|
||||
<tp-button submit primary>Save</tp-button>
|
||||
</div>
|
||||
</tp-form>
|
||||
</tp-dialog>
|
||||
`;
|
||||
}
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
url: { type: String },
|
||||
text: { type: String },
|
||||
};
|
||||
}
|
||||
|
||||
getExtension() {
|
||||
return Link.configure({
|
||||
autolink: true,
|
||||
linkOnPaste: true,
|
||||
openOnClick: false, // We will handle opening links manually
|
||||
});
|
||||
}
|
||||
|
||||
_handleClick() {
|
||||
if (this.parentEditor && this.parentEditor.editor) {
|
||||
const { editor } = this.parentEditor;
|
||||
const { selection } = editor.state;
|
||||
const { from, to } = selection;
|
||||
this.text = editor.state.doc.textBetween(from, to, ' ');
|
||||
this.url = editor.getAttributes('link').href || '';
|
||||
|
||||
const dialog = this.shadowRoot.querySelector('tp-dialog');
|
||||
dialog.show();
|
||||
}
|
||||
}
|
||||
|
||||
_saveLink(e) {
|
||||
const { url, text } = e.detail;
|
||||
const { editor } = this.parentEditor;
|
||||
|
||||
console.log(e.detail);
|
||||
if (url) {
|
||||
console.log(url, editor);
|
||||
editor.chain().focus().setLink({ href: url }).run();
|
||||
// If text is provided and different from current selection, update it
|
||||
if (text && editor.state.selection.empty) {
|
||||
editor.chain().focus().insertContent(text).run();
|
||||
}
|
||||
} else {
|
||||
editor.chain().focus().unsetLink().run();
|
||||
}
|
||||
|
||||
this.shadowRoot.querySelector('tp-dialog').close();
|
||||
}
|
||||
|
||||
_setupEditorListeners() {
|
||||
const { editor } = this.parentEditor;
|
||||
|
||||
editor.on('selectionUpdate', () => {
|
||||
this.active = editor.isActive('link');
|
||||
});
|
||||
|
||||
editor.on('focus', () => {
|
||||
this.active = editor.isActive('link');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define('tp-rtb-link', TpRtbLink);
|
Reference in New Issue
Block a user