fix(core): fix menu not close when click outside (#9535)

This commit is contained in:
EYHN
2025-01-10 08:04:48 +00:00
parent 9882af5d01
commit 18ff7500c8
8 changed files with 75 additions and 36 deletions
@@ -0,0 +1,14 @@
/**
* Check if the active element is in the editor host.
* TODO(@mirone): this is a trade-off, we need to use separate awareness store for every store to make sure the selection is isolated.
*
* @param editorHost - The editor host element.
* @returns Whether the active element is in the editor host.
*/
export function isActiveInEditor(editorHost: HTMLElement) {
const currentActiveElement = document.activeElement;
if (!currentActiveElement) return false;
const currentEditorHost = currentActiveElement?.closest('editor-host');
if (!currentEditorHost) return false;
return currentEditorHost === editorHost;
}
@@ -3,6 +3,7 @@ import { signal } from '@preact/signals-core';
import { TextSelection } from '../selection/index.js';
import type { BlockComponent } from '../view/element/block-component.js';
import { isActiveInEditor } from './active.js';
export const getInlineRangeProvider: (
element: BlockComponent
@@ -87,6 +88,8 @@ export const getInlineRangeProvider: (
editorHost.disposables.add(
selectionManager.slots.changed.on(selections => {
if (!isActiveInEditor(editorHost)) return;
const textSelection = selections.find(s => s.type === 'text') as
| TextSelection
| undefined;
@@ -4,6 +4,7 @@ import type { BaseSelection, BlockModel } from '@blocksuite/store';
import { TextSelection } from '../selection/index.js';
import type { BlockComponent } from '../view/element/block-component.js';
import { BLOCK_ID_ATTR } from '../view/index.js';
import { isActiveInEditor } from './active.js';
import { RANGE_SYNC_EXCLUDE_ATTR } from './consts.js';
import type { RangeManager } from './range-manager.js';
@@ -169,6 +170,7 @@ export class RangeBinding {
private readonly _onNativeSelectionChanged = async () => {
if (this.isComposing) return;
if (!this.host) return; // Unstable when switching views, card <-> embed
if (!isActiveInEditor(this.host)) return;
await this.host.updateComplete;
@@ -247,6 +249,7 @@ export class RangeBinding {
};
private readonly _onStdSelectionChanged = (selections: BaseSelection[]) => {
// TODO(@mirone): this is a trade-off, we need to use separate awareness store for every store to make sure the selection is isolated.
const closestHost = document.activeElement?.closest('editor-host');
if (closestHost && closestHost !== this.host) return;