import { StateEffect, StateField } from '@codemirror/state';
import { Decoration, EditorView, WidgetType, } from '@codemirror/view';
export function createInlinePanelController() {
    const showEffect = StateEffect.define();
    let callbacksRef = null;
    class InlinePanelWidget extends WidgetType {
        options;
        resizeObserver = null;
        constructor(options) {
            super();
            this.options = options;
        }
        toDOM(view) {
            const container = document.createElement('div');
            container.className = 'cm-inline-panel';
            this.resizeObserver = new ResizeObserver(() => view.requestMeasure());
            this.resizeObserver.observe(container);
            callbacksRef?.onMount(container);
            return container;
        }
        destroy() {
            this.resizeObserver?.disconnect();
            this.resizeObserver = null;
            callbacksRef?.onUnmount();
        }
        eq(other) {
            return (other.options.pos === this.options.pos &&
                other.options.placement === this.options.placement);
        }
        ignoreEvent() {
            return true;
        }
    }
    const field = StateField.define({
        create() {
            return Decoration.none;
        },
        update(decorations, transaction) {
            let next = null;
            for (const effect of transaction.effects) {
                if (effect.is(showEffect)) {
                    if (effect.value === null) {
                        next = Decoration.none;
                    }
                    else {
                        const side = effect.value.placement === 'below' ? 1 : -1;
                        next = Decoration.set([
                            Decoration.widget({
                                widget: new InlinePanelWidget(effect.value),
                                block: true,
                                side,
                            }).range(effect.value.pos),
                        ]);
                    }
                }
            }
            if (next !== null) {
                return next;
            }
            return decorations.map(transaction.changes);
        },
        provide: (f) => EditorView.decorations.from(f),
    });
    return {
        extension: field,
        show: (options) => showEffect.of(options),
        hide: () => showEffect.of(null),
        updateCallbacks: (callbacks) => {
            callbacksRef = callbacks;
        },
    };
}
//# sourceMappingURL=inlinePanel.js.map