mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-13 04:48:53 +00:00
fix(core): fix menu not close when click outside (#9535)
This commit is contained in:
@@ -8,5 +8,4 @@ export * from './scope/index.js';
|
||||
export * from './selection/index.js';
|
||||
export * from './service/index.js';
|
||||
export * from './spec/index.js';
|
||||
export * from './utils/index.js';
|
||||
export * from './view/index.js';
|
||||
|
||||
14
blocksuite/framework/block-std/src/range/active.ts
Normal file
14
blocksuite/framework/block-std/src/range/active.ts
Normal file
@@ -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;
|
||||
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
export * from './path-finder.js';
|
||||
@@ -1,30 +0,0 @@
|
||||
export class PathFinder {
|
||||
static equals = (path1: readonly string[], path2: readonly string[]) => {
|
||||
return PathFinder.pathToKey(path1) === PathFinder.pathToKey(path2);
|
||||
};
|
||||
|
||||
static id = (path: readonly string[]) => {
|
||||
return path[path.length - 1];
|
||||
};
|
||||
|
||||
// check if path1 includes path2
|
||||
static includes = (path1: string[], path2: string[]) => {
|
||||
return PathFinder.pathToKey(path1).startsWith(PathFinder.pathToKey(path2));
|
||||
};
|
||||
|
||||
static keyToPath = (key: string) => {
|
||||
return key.split('|');
|
||||
};
|
||||
|
||||
static parent = (path: readonly string[]) => {
|
||||
return path.slice(0, path.length - 1);
|
||||
};
|
||||
|
||||
static pathToKey = (path: readonly string[]) => {
|
||||
return path.join('|');
|
||||
};
|
||||
|
||||
private constructor() {
|
||||
// this is a static class
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user