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);
    }
}