Files
AFFiNE-Mirror/blocksuite/affine/blocks/block-root/src/widgets/inner-modal/inner-modal.ts
T
2025-03-08 12:00:34 +08:00

65 lines
1.5 KiB
TypeScript

import { WidgetComponent } from '@blocksuite/block-std';
import {
autoUpdate,
computePosition,
type FloatingElement,
type ReferenceElement,
size,
} from '@floating-ui/dom';
import { nothing } from 'lit';
export const AFFINE_INNER_MODAL_WIDGET = 'affine-inner-modal-widget';
export class AffineInnerModalWidget extends WidgetComponent {
private _getTarget?: () => ReferenceElement;
get target(): ReferenceElement {
if (this._getTarget) {
return this._getTarget();
}
return document.body;
}
open(
modal: FloatingElement,
ops: { onClose?: () => void }
): { close(): void } {
const cancel = autoUpdate(this.target, modal, () => {
computePosition(this.target, modal, {
middleware: [
size({
apply: ({ rects }) => {
Object.assign(modal.style, {
left: `${rects.reference.x}px`,
top: `${rects.reference.y}px`,
width: `${rects.reference.width}px`,
height: `${rects.reference.height}px`,
});
},
}),
],
}).catch(console.error);
});
const close = () => {
modal.remove();
ops.onClose?.();
cancel();
};
return { close };
}
override render() {
return nothing;
}
setTarget(fn: () => ReferenceElement) {
this._getTarget = fn;
}
}
declare global {
interface HTMLElementTagNameMap {
[AFFINE_INNER_MODAL_WIDGET]: AffineInnerModalWidget;
}
}