components_section_context_menu.js


import { ContextMenu } from "./context_menu.js"

/**
 * A context menu for section break operations (edit name, remove).
 *
 * @example
 * new SectionContextMenu(event.clientX, event.clientY, {
 *   number: 2,
 *   name: 'Introduction',
 *   onEditName: () => focusSectionNameInput(),
 *   onRemove:   () => workspace._removeSectionBreakWithHistory(beforeSegStart),
 *   onDismiss:  () => {},
 * });
 */
export class SectionContextMenu extends ContextMenu {
    /**
     * @param {number} x - Preferred left position in viewport pixels.
     * @param {number} y - Preferred top position in viewport pixels.
     * @param {object} options - Options and callback functions for the menu.
     * @param {number}          [options.number]    - 1-based section number shown in the info block.
     * @param {string}          [options.name]      - Current section name shown in the info block.
     * @param {function(): void} options.onEditName - Called when "Edit name" is clicked.
     * @param {function(): void} options.onRemove   - Called when "Remove section" is clicked.
     * @param {function(): void} [options.onDismiss] - Called when the menu is dismissed via outside click.
     * @param {{message: string, href: (string|undefined)}|null} [options.info] - Info widget config passed to the base ContextMenu.
     */
    constructor(x, y, { number, name, onEditName, onRemove, onDismiss, info = { message: 'Edit the name or remove this section break.', href: '/docs' } } = {}) {
        super('Section', onDismiss, info);

        if (number != null) {
            const info = document.createElement('div');
            info.className = 'ctx-info';
            const pairs = [
                ['SECTION', `${number}`],
                ...(name ? [['NAME', name]] : []),
            ];
            pairs.forEach(([k, v]) => {
                const key = document.createElement('span');
                key.className = 'ctx-info-key';
                key.textContent = k;
                const val = document.createElement('span');
                val.className = 'ctx-info-val';
                val.textContent = v;
                info.appendChild(key);
                info.appendChild(val);
            });
            this.root.appendChild(info);
        }

        const controls = document.createElement('div');
        controls.className = 'ctx-controls';

        if (onEditName) {
            controls.appendChild(this.makeItem(
                '✎', 'Edit name', null,
                () => { this.close(); this._onDismiss(); onEditName(); },
            ));
        }

        if (onRemove) {
            const item = this.makeItem(
                '<span class="icon icon-close" style="width:12px;height:12px;"></span>',
                'Remove section', null,
                () => { this.close(); this._onDismiss(); onRemove(); },
            );
            item.classList.add('ctx-item--danger');
            controls.appendChild(item);
        }

        this.root.appendChild(controls);
        this._mount(x, y);
    }
}