components_link_context_menu.js
import { ContextMenu } from "./context_menu.js"
/**
* A context menu for hyperlink operations (edit, copy, remove).
*
* @example
* new LinkContextMenu(event.clientX, event.clientY, {
* onEdit: () => openEditDialog(linkId),
* onCopy: () => navigator.clipboard.writeText(url),
* onRemove: () => removeLink(linkId),
* onDismiss: () => {},
* });
*/
export class LinkContextMenu extends ContextMenu {
/**
* @param {number} x - Preferred left position in viewport pixels.
* @param {number} y - Preferred top position in viewport pixels.
* @param {object} callbacks - Callback functions for menu actions.
* @param {function(): void} [callbacks.onEdit] - Called when "Edit link" is clicked.
* @param {function(): void} [callbacks.onCopy] - Called when "Copy link" is clicked.
* @param {function(): void} [callbacks.onRemove] - Called when "Remove link" is clicked.
* @param {function(): void} [callbacks.onDismiss] - Called when the menu is dismissed.
* @param {{message: string, href: (string|undefined)}|null} [callbacks.info] - Info widget config passed to the base ContextMenu.
*/
constructor(x, y, { onEdit, onCopy, onRemove, onDismiss, info = { message: 'Edit, copy, or remove this hyperlink.', href: '/docs' } } = {}) {
super('Link', onDismiss, info);
const controls = document.createElement('div');
controls.className = 'ctx-controls';
if (onEdit) {
controls.appendChild(this.makeItem(
'✎', 'Edit link', null,
() => { this.close(); this._onDismiss(); onEdit(); },
));
}
if (onCopy) {
controls.appendChild(this.makeItem(
'⧉', 'Copy link', null,
() => { this.close(); this._onDismiss(); onCopy(); },
));
}
if (onRemove) {
const item = this.makeItem(
'<span class="icon icon-close" style="width:12px;height:12px;"></span>',
'Remove link', null,
() => { this.close(); this._onDismiss(); onRemove(); },
);
item.classList.add('ctx-item--danger');
controls.appendChild(item);
}
this.root.appendChild(controls);
this._mount(x, y);
}
}