refactor: move frame manager and panel to separate packages (#10324)

### TL;DR
Moved frame management functionality from `blocksuite/blocks` to `@blocksuite/affine-block-frame` package.

### What changed?
- Relocated `frame-manager.ts` from `blocksuite/blocks` to `@blocksuite/affine-block-frame`
- Added new dependencies to block-frame package: `@blocksuite/affine-block-surface` and `yjs`
- Updated imports across multiple components to reference frame manager from its new location
- Moved utility functions `areSetsEqual` and `isFrameBlock` into frame-manager file
- Replaced direct EdgelessRootService references with GfxController in frame panel components

### How to test?
1. Verify frame functionality works in edgeless mode
2. Test frame creation, selection, and manipulation
3. Confirm frame navigation and presentation modes operate correctly
4. Check that frame panel and toolbar interactions remain functional

### Why make this change?
This refactoring improves code organization by consolidating frame-related functionality into a dedicated package, making the codebase more modular and easier to maintain. It also reduces dependencies between packages and provides clearer boundaries for frame-related features.
This commit is contained in:
Saul-Mirone
2025-02-20 13:06:39 +00:00
parent 64cc99354e
commit 007bbabce4
43 changed files with 252 additions and 135 deletions
@@ -13,6 +13,7 @@
"author": "toeverything",
"license": "MIT",
"dependencies": {
"@blocksuite/affine-block-surface": "workspace:*",
"@blocksuite/affine-components": "workspace:*",
"@blocksuite/affine-model": "workspace:*",
"@blocksuite/affine-shared": "workspace:*",
@@ -27,6 +28,7 @@
"@types/mdast": "^4.0.4",
"lit": "^3.2.0",
"minimatch": "^10.0.1",
"yjs": "^13.6.21",
"zod": "^3.23.8"
},
"exports": {
@@ -21,14 +21,13 @@ import {
type IVec,
type SerializedXYWH,
} from '@blocksuite/global/utils';
import { Text } from '@blocksuite/store';
import { type BlockModel, Text } from '@blocksuite/store';
import * as Y from 'yjs';
import { areSetsEqual } from './utils/misc.js';
import { isFrameBlock } from './utils/query.js';
const FRAME_PADDING = 40;
export type NavigatorMode = 'fill' | 'fit';
export class FrameOverlay extends Overlay {
static override overlayName: string = 'frame';
@@ -461,3 +460,13 @@ export class EdgelessFrameManager extends GfxExtension {
this._disposable.dispose();
}
}
function areSetsEqual<T>(setA: Set<T>, setB: Set<T>) {
if (setA.size !== setB.size) return false;
for (const a of setA) if (!setB.has(a)) return false;
return true;
}
export function isFrameBlock(element: unknown): element is FrameBlockModel {
return !!element && (element as BlockModel).flavour === 'affine:frame';
}
@@ -1,2 +1,3 @@
export * from './frame-block.js';
export * from './frame-manager.js';
export * from './frame-spec.js';
@@ -7,6 +7,7 @@
},
"include": ["./src"],
"references": [
{ "path": "../block-surface" },
{ "path": "../components" },
{ "path": "../model" },
{ "path": "../shared" },
@@ -0,0 +1,45 @@
{
"name": "@blocksuite/affine-fragment-frame-panel",
"description": "Frame panel fragment for BlockSuite.",
"type": "module",
"scripts": {
"build": "tsc",
"test:unit": "nx vite:test --run --passWithNoTests",
"test:unit:coverage": "nx vite:test --run --coverage",
"test:e2e": "playwright test"
},
"sideEffects": false,
"keywords": [],
"author": "toeverything",
"license": "MIT",
"dependencies": {
"@blocksuite/affine-block-frame": "workspace:*",
"@blocksuite/affine-block-surface": "workspace:*",
"@blocksuite/affine-components": "workspace:*",
"@blocksuite/affine-model": "workspace:*",
"@blocksuite/affine-shared": "workspace:*",
"@blocksuite/block-std": "workspace:*",
"@blocksuite/global": "workspace:*",
"@blocksuite/icons": "^2.2.1",
"@blocksuite/inline": "workspace:*",
"@blocksuite/store": "workspace:*",
"@floating-ui/dom": "^1.6.10",
"@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.11",
"lit": "^3.2.0",
"minimatch": "^10.0.1",
"zod": "^3.23.8"
},
"exports": {
".": "./src/index.ts",
"./effects": "./src/effects.ts"
},
"files": [
"src",
"dist",
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.19.0"
}
@@ -1,12 +1,14 @@
import { type EditorHost, ShadowlessElement } from '@blocksuite/block-std';
import { generateKeyBetweenV2 } from '@blocksuite/block-std/gfx';
import { EdgelessFrameManager } from '@blocksuite/affine-block-frame';
import type { FrameBlockModel } from '@blocksuite/affine-model';
import {
DocModeProvider,
EdgelessFrameManager,
EdgelessRootService,
EditPropsStore,
type FrameBlockModel,
} from '@blocksuite/blocks';
} from '@blocksuite/affine-shared/services';
import { type EditorHost, ShadowlessElement } from '@blocksuite/block-std';
import {
generateKeyBetweenV2,
GfxControllerIdentifier,
} from '@blocksuite/block-std/gfx';
import {
Bound,
DisposableGroup,
@@ -110,7 +112,7 @@ export class FramePanelBody extends SignalWatcher(
}
this._selected = [];
this._edgelessRootService?.selection.set({
this._gfx.selection.set({
elements: this._selected,
editing: false,
});
@@ -126,6 +128,10 @@ export class FramePanelBody extends SignalWatcher(
private _lastEdgelessRootId = '';
private get _gfx() {
return this.editorHost.std.get(GfxControllerIdentifier);
}
private readonly _selectFrame = (e: SelectEvent) => {
const { selected, id, multiselect } = e.detail;
@@ -138,7 +144,7 @@ export class FramePanelBody extends SignalWatcher(
this._selected = [id];
}
this._edgelessRootService?.selection.set({
this._gfx.selection.set({
elements: this._selected,
editing: false,
});
@@ -152,10 +158,6 @@ export class FramePanelBody extends SignalWatcher(
}));
};
get _edgelessRootService() {
return this.editorHost.std.getOptional(EdgelessRootService);
}
get frames() {
const frames = this.editorHost.doc
.getBlocksByFlavour('affine:frame')
@@ -229,8 +231,9 @@ export class FramePanelBody extends SignalWatcher(
private _fitToElement(e: FitViewEvent) {
const { block } = e.detail;
const bound = Bound.deserialize(block.xywh);
const docModeProvider = this.editorHost.std.get(DocModeProvider);
if (!this._edgelessRootService) {
if (docModeProvider.getEditorMode() !== 'edgeless') {
// When click frame card in page mode
// Should switch to edgeless mode and set viewport to the frame
const viewport = {
@@ -242,11 +245,7 @@ export class FramePanelBody extends SignalWatcher(
this.editorHost.std.get(EditPropsStore).setStorage('viewport', viewport);
this.editorHost.std.get(DocModeProvider).setEditorMode('edgeless');
} else {
this._edgelessRootService.viewport.setViewportByBound(
bound,
this.viewportPadding,
true
);
this._gfx.viewport.setViewportByBound(bound, this.viewportPadding, true);
}
}
@@ -398,7 +397,7 @@ export class FramePanelBody extends SignalWatcher(
this._setDocDisposables(this.editorHost.doc);
// after switch to edgeless mode, should update the selection
if (this.editorHost.doc.id === this._lastEdgelessRootId) {
this._edgelessRootService?.selection.set({
this._gfx.selection.set({
elements: this._selected,
editing: false,
});
@@ -1,5 +1,6 @@
import type { RichText } from '@blocksuite/affine-components/rich-text';
import type { FrameBlockModel } from '@blocksuite/affine-model';
import { ShadowlessElement } from '@blocksuite/block-std';
import type { FrameBlockModel, RichText } from '@blocksuite/blocks';
import { WithDisposable } from '@blocksuite/global/utils';
import { css, html } from 'lit';
import { property, query } from 'lit/decorators.js';
@@ -1,5 +1,5 @@
import type { FrameBlockModel } from '@blocksuite/affine-model';
import { ShadowlessElement } from '@blocksuite/block-std';
import type { FrameBlockModel } from '@blocksuite/blocks';
import { DisposableGroup, WithDisposable } from '@blocksuite/global/utils';
import { css, html, type PropertyValues } from 'lit';
import { property, query } from 'lit/decorators.js';
@@ -1,5 +1,6 @@
import type { FrameBlockModel } from '@blocksuite/affine-model';
import { on, once } from '@blocksuite/affine-shared/utils';
import { ShadowlessElement } from '@blocksuite/block-std';
import { type FrameBlockModel, on, once } from '@blocksuite/blocks';
import { WithDisposable } from '@blocksuite/global/utils';
import { css, html, nothing } from 'lit';
import { property, query } from 'lit/decorators.js';
@@ -0,0 +1,32 @@
import {
AFFINE_FRAME_PANEL_BODY,
FramePanelBody,
} from './body/frame-panel-body';
import { AFFINE_FRAME_CARD, FrameCard } from './card/frame-card';
import {
AFFINE_FRAME_CARD_TITLE,
FrameCardTitle,
} from './card/frame-card-title';
import {
AFFINE_FRAME_TITLE_EDITOR,
FrameCardTitleEditor,
} from './card/frame-card-title-editor';
import { AFFINE_FRAME_PANEL, FramePanel } from './frame-panel';
import {
AFFINE_FRAME_PANEL_HEADER,
FramePanelHeader,
} from './header/frame-panel-header';
import {
AFFINE_FRAMES_SETTING_MENU,
FramesSettingMenu,
} from './header/frames-setting-menu';
export function effects() {
customElements.define(AFFINE_FRAME_PANEL, FramePanel);
customElements.define(AFFINE_FRAME_TITLE_EDITOR, FrameCardTitleEditor);
customElements.define(AFFINE_FRAME_CARD, FrameCard);
customElements.define(AFFINE_FRAME_CARD_TITLE, FrameCardTitle);
customElements.define(AFFINE_FRAME_PANEL_BODY, FramePanelBody);
customElements.define(AFFINE_FRAME_PANEL_HEADER, FramePanelHeader);
customElements.define(AFFINE_FRAMES_SETTING_MENU, FramesSettingMenu);
}
@@ -1,12 +1,12 @@
import type { EditorHost } from '@blocksuite/block-std';
import type { NavigatorMode } from '@blocksuite/affine-block-frame';
import { EdgelessLegacySlotIdentifier } from '@blocksuite/affine-block-surface';
import {
createButtonPopper,
DocModeProvider,
EdgelessLegacySlotIdentifier,
EdgelessRootService,
EditPropsStore,
type NavigatorMode,
} from '@blocksuite/blocks';
} from '@blocksuite/affine-shared/services';
import { createButtonPopper } from '@blocksuite/affine-shared/utils';
import type { EditorHost } from '@blocksuite/block-std';
import { GfxControllerIdentifier } from '@blocksuite/block-std/gfx';
import { DisposableGroup, WithDisposable } from '@blocksuite/global/utils';
import { PresentationIcon, SettingsIcon } from '@blocksuite/icons/lit';
import { css, html, LitElement, type PropertyValues } from 'lit';
@@ -112,13 +112,18 @@ export class FramePanelHeader extends WithDisposable(LitElement) {
private _edgelessDisposables: DisposableGroup | null = null;
private get _gfx() {
return this.editorHost.std.get(GfxControllerIdentifier);
}
private readonly _enterPresentationMode = () => {
if (!this._edgelessRootService) {
const docModeProvider = this.editorHost.std.get(DocModeProvider);
if (docModeProvider.getEditorMode() !== 'edgeless') {
this.editorHost.std.get(DocModeProvider).setEditorMode('edgeless');
}
setTimeout(() => {
this._edgelessRootService?.gfx.tool.setTool({
this._gfx.tool.setTool({
type: 'frameNavigator',
mode: this._navigatorMode,
});
@@ -132,8 +137,6 @@ export class FramePanelHeader extends WithDisposable(LitElement) {
private _navigatorMode: NavigatorMode = 'fit';
private readonly _setEdgelessDisposables = () => {
if (!this._edgelessRootService) return;
const slots = this.editorHost.std.get(EdgelessLegacySlotIdentifier);
this._clearEdgelessDisposables();
@@ -145,10 +148,6 @@ export class FramePanelHeader extends WithDisposable(LitElement) {
);
};
private get _edgelessRootService() {
return this.editorHost.std.getOptional(EdgelessRootService);
}
private _tryLoadNavigatorStateLocalRecord() {
this._navigatorMode = this.editorHost.std
.get(EditPropsStore)
@@ -219,7 +218,8 @@ export class FramePanelHeader extends WithDisposable(LitElement) {
override updated(_changedProperties: PropertyValues) {
if (_changedProperties.has('editorHost')) {
if (this._edgelessRootService) {
const docModeProvider = this.editorHost.std.get(DocModeProvider);
if (docModeProvider.getEditorMode() === 'edgeless') {
this._setEdgelessDisposables();
} else {
this._clearEdgelessDisposables();
@@ -1,9 +1,9 @@
import type { EditorHost } from '@blocksuite/block-std';
import { EdgelessLegacySlotIdentifier } from '@blocksuite/affine-block-surface';
import {
EdgelessLegacySlotIdentifier,
EdgelessRootService,
DocModeProvider,
EditPropsStore,
} from '@blocksuite/blocks';
} from '@blocksuite/affine-shared/services';
import type { EditorHost } from '@blocksuite/block-std';
import { WithDisposable } from '@blocksuite/global/utils';
import { css, html, LitElement, type PropertyValues } from 'lit';
import { property, state } from 'lit/decorators.js';
@@ -103,10 +103,6 @@ export class FramesSettingMenu extends WithDisposable(LitElement) {
this._editPropsStore.setStorage('presentHideToolbar', this.hideToolbar);
};
private get _edgelessRootService() {
return this.editorHost.std.getOptional(EdgelessRootService);
}
private get _editPropsStore() {
return this.editorHost.std.get(EditPropsStore);
}
@@ -176,7 +172,8 @@ export class FramesSettingMenu extends WithDisposable(LitElement) {
override updated(_changedProperties: PropertyValues) {
if (_changedProperties.has('editorHost')) {
if (this._edgelessRootService) {
const docModeProvider = this.editorHost.std.get(DocModeProvider);
if (docModeProvider.getEditorMode() === 'edgeless') {
this.disposables.add(
this.slots.navigatorSettingUpdated.on(
({ blackBackground, hideToolbar }) => {
@@ -0,0 +1,2 @@
export * from './frame-panel';
export * from './tool';
@@ -1,7 +1,6 @@
import type { NavigatorMode } from '@blocksuite/affine-block-frame';
import { BaseTool } from '@blocksuite/block-std/gfx';
import type { NavigatorMode } from '../../../_common/edgeless/frame/consts.js';
type PresentToolOption = {
mode?: NavigatorMode;
};
@@ -1,4 +1,5 @@
import { type FrameBlockModel, on, once } from '@blocksuite/blocks';
import type { FrameBlockModel } from '@blocksuite/affine-model';
import { on, once } from '@blocksuite/affine-shared/utils';
import type { FramePanelBody } from '../body/frame-panel-body.js';
import { FrameCard } from '../card/frame-card.js';
@@ -0,0 +1,20 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"rootDir": "./src",
"outDir": "./dist",
"tsBuildInfoFile": "./dist/tsconfig.tsbuildinfo"
},
"include": ["./src"],
"references": [
{ "path": "../block-frame" },
{ "path": "../block-surface" },
{ "path": "../components" },
{ "path": "../model" },
{ "path": "../shared" },
{ "path": "../../framework/block-std" },
{ "path": "../../framework/global" },
{ "path": "../../framework/inline" },
{ "path": "../../framework/store" }
]
}
+1
View File
@@ -32,6 +32,7 @@
"@blocksuite/affine-block-surface-ref": "workspace:*",
"@blocksuite/affine-block-table": "workspace:*",
"@blocksuite/affine-components": "workspace:*",
"@blocksuite/affine-fragment-frame-panel": "workspace:*",
"@blocksuite/affine-model": "workspace:*",
"@blocksuite/affine-shared": "workspace:*",
"@blocksuite/affine-widget-drag-handle": "workspace:*",
@@ -1 +0,0 @@
export type NavigatorMode = 'fill' | 'fit';
@@ -1,11 +1,12 @@
import { ConnectionOverlay } from '@blocksuite/affine-block-surface';
import type { ExtensionType } from '@blocksuite/store';
import { EdgelessRootBlockSpec } from '../../root-block/edgeless/edgeless-root-spec.js';
import {
EdgelessFrameManager,
FrameOverlay,
} from '../../root-block/edgeless/frame-manager.js';
} from '@blocksuite/affine-block-frame';
import { ConnectionOverlay } from '@blocksuite/affine-block-surface';
import { PresentTool } from '@blocksuite/affine-fragment-frame-panel';
import type { ExtensionType } from '@blocksuite/store';
import { EdgelessRootBlockSpec } from '../../root-block/edgeless/edgeless-root-spec.js';
import { BrushTool } from '../../root-block/edgeless/gfx-tool/brush-tool.js';
import { ConnectorTool } from '../../root-block/edgeless/gfx-tool/connector-tool.js';
import { CopilotTool } from '../../root-block/edgeless/gfx-tool/copilot-tool.js';
@@ -13,7 +14,6 @@ import { DefaultTool } from '../../root-block/edgeless/gfx-tool/default-tool.js'
import { MindMapIndicatorOverlay } from '../../root-block/edgeless/gfx-tool/default-tool-ext/mind-map-ext/indicator-overlay.js';
import { EmptyTool } from '../../root-block/edgeless/gfx-tool/empty-tool.js';
import { EraserTool } from '../../root-block/edgeless/gfx-tool/eraser-tool.js';
import { PresentTool } from '../../root-block/edgeless/gfx-tool/frame-navigator-tool.js';
import { FrameTool } from '../../root-block/edgeless/gfx-tool/frame-tool.js';
import { LassoTool } from '../../root-block/edgeless/gfx-tool/lasso-tool.js';
import { NoteTool } from '../../root-block/edgeless/gfx-tool/note-tool.js';
+5 -1
View File
@@ -33,6 +33,7 @@ import { SmoothCorner } from '@blocksuite/affine-components/smooth-corner';
import { effects as componentToggleButtonEffects } from '@blocksuite/affine-components/toggle-button';
import { ToggleSwitch } from '@blocksuite/affine-components/toggle-switch';
import { effects as componentToolbarEffects } from '@blocksuite/affine-components/toolbar';
import { effects as fragmentFramePanelEffects } from '@blocksuite/affine-fragment-frame-panel/effects';
import { effects as widgetDragHandleEffects } from '@blocksuite/affine-widget-drag-handle/effects';
import { effects as widgetEdgelessAutoConnectEffects } from '@blocksuite/affine-widget-edgeless-auto-connect/effects';
import { effects as widgetFrameTitleEffects } from '@blocksuite/affine-widget-frame-title/effects';
@@ -185,6 +186,8 @@ export function effects() {
stdEffects();
inlineEffects();
dataViewEffects();
blockNoteEffects();
blockAttachmentEffects();
blockBookmarkEffects();
@@ -224,7 +227,8 @@ export function effects() {
widgetRemoteSelectionEffects();
widgetDragHandleEffects();
widgetEdgelessAutoConnectEffects();
dataViewEffects();
fragmentFramePanelEffects();
customElements.define('affine-page-root', PageRootBlockComponent);
customElements.define('affine-preview-root', PreviewRootBlockComponent);
+1 -5
View File
@@ -7,7 +7,6 @@ import { splitElements } from './root-block/edgeless/utils/clipboard-utils.js';
import { isCanvasElement } from './root-block/edgeless/utils/query.js';
export * from './_common/adapters/index.js';
export { type NavigatorMode } from './_common/edgeless/frame/consts.js';
export * from './_common/transformers/index.js';
export * from './_specs/index.js';
export { EdgelessTemplatePanel } from './root-block/edgeless/components/toolbar/template/template-panel.js';
@@ -16,10 +15,6 @@ export type {
TemplateCategory,
TemplateManager,
} from './root-block/edgeless/components/toolbar/template/template-type.js';
export {
EdgelessFrameManager,
FrameOverlay,
} from './root-block/edgeless/frame-manager.js';
export { CopilotTool } from './root-block/edgeless/gfx-tool/copilot-tool.js';
export * from './root-block/edgeless/gfx-tool/index.js';
export { EditPropsMiddlewareBuilder } from './root-block/edgeless/middlewares/base.js';
@@ -95,6 +90,7 @@ export {
ToolbarMoreMenuConfigExtension,
Tooltip,
} from '@blocksuite/affine-components/toolbar';
export * from '@blocksuite/affine-fragment-frame-panel';
export * from '@blocksuite/affine-model';
export {
AttachmentAdapter,
@@ -6,6 +6,11 @@ import {
SYNCED_MIN_HEIGHT,
SYNCED_MIN_WIDTH,
} from '@blocksuite/affine-block-embed';
import {
type EdgelessFrameManager,
type FrameOverlay,
isFrameBlock,
} from '@blocksuite/affine-block-frame';
import {
CanvasElementType,
isNoteBlock,
@@ -65,10 +70,6 @@ import { ifDefined } from 'lit/directives/if-defined.js';
import { styleMap } from 'lit/directives/style-map.js';
import type { EdgelessRootBlockComponent } from '../../edgeless-root-block.js';
import type {
EdgelessFrameManager,
FrameOverlay,
} from '../../frame-manager.js';
import {
AI_CHAT_BLOCK_MAX_HEIGHT,
AI_CHAT_BLOCK_MAX_WIDTH,
@@ -90,7 +91,6 @@ import {
isEmbedLoomBlock,
isEmbedSyncedDocBlock,
isEmbedYoutubeBlock,
isFrameBlock,
isImageBlock,
isMindmapNode,
} from '../../utils/query.js';
@@ -1,3 +1,7 @@
import {
isFrameBlock,
type NavigatorMode,
} from '@blocksuite/affine-block-frame';
import { toast } from '@blocksuite/affine-components/toast';
import type { FrameBlockModel } from '@blocksuite/affine-model';
import { EditPropsStore } from '@blocksuite/affine-shared/services';
@@ -15,9 +19,7 @@ import { cssVar } from '@toeverything/theme';
import { css, html, LitElement, nothing, type PropertyValues } from 'lit';
import { property, state } from 'lit/decorators.js';
import type { NavigatorMode } from '../../../../_common/edgeless/frame/consts.js';
import type { EdgelessRootBlockComponent } from '../../edgeless-root-block.js';
import { isFrameBlock } from '../../utils/query.js';
import { launchIntoFullscreen } from '../utils.js';
import { EdgelessToolbarToolMixin } from './mixins/tool.mixin.js';
@@ -1,3 +1,4 @@
import type { EdgelessFrameManager } from '@blocksuite/affine-block-frame';
import {
EdgelessCRUDIdentifier,
EdgelessLegacySlotIdentifier,
@@ -36,7 +37,6 @@ import { Bound, getCommonBound } from '@blocksuite/global/utils';
import { effect } from '@preact/signals-core';
import { RootService } from '../root-service.js';
import type { EdgelessFrameManager } from './frame-manager.js';
import { TemplateJob } from './services/template.js';
import {
createInsertPlaceMiddleware,
@@ -1,4 +1,9 @@
import { insertEdgelessTextCommand } from '@blocksuite/affine-block-edgeless-text';
import {
type EdgelessFrameManager,
type FrameOverlay,
isFrameBlock,
} from '@blocksuite/affine-block-frame';
import {
ConnectorUtils,
isNoteBlock,
@@ -50,14 +55,9 @@ import { effect } from '@preact/signals-core';
import { isSingleMindMapNode } from '../../../_common/edgeless/mindmap/index.js';
import type { EdgelessRootBlockComponent } from '../edgeless-root-block.js';
import type { EdgelessFrameManager, FrameOverlay } from '../frame-manager.js';
import { prepareCloneData } from '../utils/clone-utils.js';
import { calPanDelta } from '../utils/panning-utils.js';
import {
isCanvasElement,
isEdgelessTextBlock,
isFrameBlock,
} from '../utils/query.js';
import { isCanvasElement, isEdgelessTextBlock } from '../utils/query.js';
import type { EdgelessSnapManager } from '../utils/snap-manager.js';
import {
addText,
@@ -1,3 +1,7 @@
import type {
EdgelessFrameManager,
FrameOverlay,
} from '@blocksuite/affine-block-frame';
import { OverlayIdentifier } from '@blocksuite/affine-block-surface';
import type { FrameBlockModel } from '@blocksuite/affine-model';
import {
@@ -15,8 +19,6 @@ import { Bound, Vec } from '@blocksuite/global/utils';
import { Text } from '@blocksuite/store';
import * as Y from 'yjs';
import type { EdgelessFrameManager, FrameOverlay } from '../frame-manager.js';
export class FrameTool extends BaseTool {
static override toolName = 'frame';
@@ -4,7 +4,6 @@ export { CopilotTool } from './copilot-tool.js';
export { DefaultTool } from './default-tool.js';
export { EmptyTool } from './empty-tool.js';
export { EraserTool } from './eraser-tool.js';
export { PresentTool } from './frame-navigator-tool.js';
export { FrameTool } from './frame-tool.js';
export { LassoTool, type LassoToolOption } from './lasso-tool.js';
export { NoteTool, type NoteToolOption } from './note-tool.js';
@@ -1,3 +1,7 @@
import {
EdgelessFrameManager,
isFrameBlock,
} from '@blocksuite/affine-block-frame';
import { isNoteBlock } from '@blocksuite/affine-block-surface';
import type {
EdgelessTextBlockModel,
@@ -18,12 +22,10 @@ import { getCommonBoundWithRotation, groupBy } from '@blocksuite/global/utils';
import { type BlockSnapshot, BlockSnapshotSchema } from '@blocksuite/store';
import type { EdgelessRootBlockComponent } from '../edgeless-root-block.js';
import { EdgelessFrameManager } from '../frame-manager.js';
import { getSortedCloneElements, prepareCloneData } from './clone-utils.js';
import {
isEdgelessTextBlock,
isEmbedSyncedDocBlock,
isFrameBlock,
isImageBlock,
} from './query.js';
@@ -1,5 +0,0 @@
export function areSetsEqual<T>(setA: Set<T>, setB: Set<T>) {
if (setA.size !== setB.size) return false;
for (const a of setA) if (!setB.has(a)) return false;
return true;
}
@@ -12,7 +12,6 @@ import {
type EmbedLoomModel,
type EmbedSyncedDocModel,
type EmbedYoutubeModel,
type FrameBlockModel,
type ImageBlockModel,
MindmapElementModel,
ShapeElementModel,
@@ -49,10 +48,6 @@ export function isEdgelessTextBlock(
);
}
export function isFrameBlock(element: unknown): element is FrameBlockModel {
return !!element && (element as BlockModel).flavour === 'affine:frame';
}
export function isImageBlock(
element: BlockModel | GfxModel | null
): element is ImageBlockModel {
@@ -1,3 +1,4 @@
import type { EdgelessFrameManager } from '@blocksuite/affine-block-frame';
import { EdgelessCRUDIdentifier } from '@blocksuite/affine-block-surface';
import type {
EdgelessColorPickerButton,
@@ -36,7 +37,6 @@ import { join } from 'lit/directives/join.js';
import { when } from 'lit/directives/when.js';
import type { EdgelessRootBlockComponent } from '../../edgeless/edgeless-root-block.js';
import type { EdgelessFrameManager } from '../../edgeless/frame-manager.js';
import { mountFrameTitleEditor } from '../../edgeless/utils/text.js';
function getMostCommonColor(
@@ -1,3 +1,4 @@
import { isFrameBlock } from '@blocksuite/affine-block-frame';
import { isNoteBlock } from '@blocksuite/affine-block-surface';
import {
cloneGroups,
@@ -47,7 +48,6 @@ import {
isBookmarkBlock,
isEdgelessTextBlock,
isEmbeddedBlock,
isFrameBlock,
isImageBlock,
} from '../../edgeless/utils/query.js';
import { renderAddFrameButton } from './add-frame-button.js';
@@ -1,3 +1,4 @@
import { isFrameBlock } from '@blocksuite/affine-block-frame';
import {
isNoteBlock,
type SurfaceBlockComponent,
@@ -18,7 +19,6 @@ import {
isEmbeddedLinkBlock,
isEmbedLinkedDocBlock,
isEmbedSyncedDocBlock,
isFrameBlock,
isImageBlock,
} from '../../../edgeless/utils/query.js';
@@ -1,3 +1,4 @@
import { isFrameBlock } from '@blocksuite/affine-block-frame';
import { getSurfaceBlock, isNoteBlock } from '@blocksuite/affine-block-surface';
import type { FrameBlockModel, NoteBlockModel } from '@blocksuite/affine-model';
import { NoteDisplayMode } from '@blocksuite/affine-model';
@@ -12,7 +13,6 @@ import {
mapFrameIds,
sortEdgelessElements,
} from '../../../edgeless/utils/clone-utils.js';
import { isFrameBlock } from '../../../edgeless/utils/query.js';
function addBlocksToDoc(targetDoc: Store, model: BlockModel, parentId: string) {
// Add current block to linked doc
+1
View File
@@ -25,6 +25,7 @@
{ "path": "../affine/block-surface-ref" },
{ "path": "../affine/block-table" },
{ "path": "../affine/components" },
{ "path": "../affine/fragment-frame-panel" },
{ "path": "../affine/model" },
{ "path": "../affine/shared" },
{ "path": "../affine/widget-drag-handle" },
-33
View File
@@ -8,36 +8,10 @@ import {
} from './editors/index.js';
import { CommentInput } from './fragments/comment/comment-input.js';
import {
AFFINE_FRAME_PANEL_BODY,
FramePanelBody,
} from './fragments/frame-panel/body/frame-panel-body.js';
import {
AFFINE_FRAME_CARD,
FrameCard,
} from './fragments/frame-panel/card/frame-card.js';
import {
AFFINE_FRAME_CARD_TITLE,
FrameCardTitle,
} from './fragments/frame-panel/card/frame-card-title.js';
import {
AFFINE_FRAME_TITLE_EDITOR,
FrameCardTitleEditor,
} from './fragments/frame-panel/card/frame-card-title-editor.js';
import {
AFFINE_FRAME_PANEL_HEADER,
FramePanelHeader,
} from './fragments/frame-panel/header/frame-panel-header.js';
import {
AFFINE_FRAMES_SETTING_MENU,
FramesSettingMenu,
} from './fragments/frame-panel/header/frames-setting-menu.js';
import {
AFFINE_FRAME_PANEL,
AFFINE_MOBILE_OUTLINE_MENU,
AFFINE_OUTLINE_PANEL,
AFFINE_OUTLINE_VIEWER,
CommentPanel,
FramePanel,
MobileOutlineMenu,
OutlinePanel,
OutlineViewer,
@@ -74,22 +48,15 @@ export function effects() {
AFFINE_OUTLINE_NOTE_PREVIEW_SETTING_MENU,
OutlineNotePreviewSettingMenu
);
customElements.define(AFFINE_FRAME_PANEL, FramePanel);
customElements.define(AFFINE_OUTLINE_NOTICE, OutlineNotice);
customElements.define('comment-panel', CommentPanel);
customElements.define(AFFINE_OUTLINE_PANEL, OutlinePanel);
customElements.define(AFFINE_OUTLINE_PANEL_HEADER, OutlinePanelHeader);
customElements.define('affine-editor-container', AffineEditorContainer);
customElements.define(AFFINE_OUTLINE_NOTE_CARD, OutlineNoteCard);
customElements.define(AFFINE_FRAME_TITLE_EDITOR, FrameCardTitleEditor);
customElements.define('edgeless-editor', EdgelessEditor);
customElements.define(AFFINE_FRAME_CARD, FrameCard);
customElements.define(AFFINE_OUTLINE_VIEWER, OutlineViewer);
customElements.define(AFFINE_MOBILE_OUTLINE_MENU, MobileOutlineMenu);
customElements.define(AFFINE_FRAME_CARD_TITLE, FrameCardTitle);
customElements.define(AFFINE_OUTLINE_BLOCK_PREVIEW, OutlineBlockPreview);
customElements.define(AFFINE_FRAME_PANEL_BODY, FramePanelBody);
customElements.define(AFFINE_FRAME_PANEL_HEADER, FramePanelHeader);
customElements.define(AFFINE_OUTLINE_PANEL_BODY, OutlinePanelBody);
customElements.define(AFFINE_FRAMES_SETTING_MENU, FramesSettingMenu);
}
@@ -1 +0,0 @@
export * from './frame-panel.js';
@@ -1,3 +1,2 @@
export * from './comment/index.js';
export * from './frame-panel/index.js';
export * from './outline/index.js';
@@ -1,5 +1,5 @@
import { FramePanel } from '@blocksuite/affine/blocks';
import type { AffineEditorContainer } from '@blocksuite/affine/presets';
import { FramePanel } from '@blocksuite/affine/presets';
import { useCallback, useEffect, useRef } from 'react';
import * as styles from './frame.css';
+18
View File
@@ -131,6 +131,7 @@ export const PackageList = [
location: 'blocksuite/affine/block-frame',
name: '@blocksuite/affine-block-frame',
workspaceDependencies: [
'blocksuite/affine/block-surface',
'blocksuite/affine/components',
'blocksuite/affine/model',
'blocksuite/affine/shared',
@@ -273,6 +274,21 @@ export const PackageList = [
'blocksuite/framework/store',
],
},
{
location: 'blocksuite/affine/fragment-frame-panel',
name: '@blocksuite/affine-fragment-frame-panel',
workspaceDependencies: [
'blocksuite/affine/block-frame',
'blocksuite/affine/block-surface',
'blocksuite/affine/components',
'blocksuite/affine/model',
'blocksuite/affine/shared',
'blocksuite/framework/block-std',
'blocksuite/framework/global',
'blocksuite/framework/inline',
'blocksuite/framework/store',
],
},
{
location: 'blocksuite/affine/model',
name: '@blocksuite/affine-model',
@@ -379,6 +395,7 @@ export const PackageList = [
'blocksuite/affine/block-surface-ref',
'blocksuite/affine/block-table',
'blocksuite/affine/components',
'blocksuite/affine/fragment-frame-panel',
'blocksuite/affine/model',
'blocksuite/affine/shared',
'blocksuite/affine/widget-drag-handle',
@@ -762,6 +779,7 @@ export type PackageName =
| '@blocksuite/affine-block-table'
| '@blocksuite/affine-components'
| '@blocksuite/data-view'
| '@blocksuite/affine-fragment-frame-panel'
| '@blocksuite/affine-model'
| '@blocksuite/affine-shared'
| '@blocksuite/affine-widget-drag-handle'
+1
View File
@@ -70,6 +70,7 @@
{ "path": "./blocksuite/affine/block-table" },
{ "path": "./blocksuite/affine/components" },
{ "path": "./blocksuite/affine/data-view" },
{ "path": "./blocksuite/affine/fragment-frame-panel" },
{ "path": "./blocksuite/affine/model" },
{ "path": "./blocksuite/affine/shared" },
{ "path": "./blocksuite/affine/widget-drag-handle" },
+27
View File
@@ -3471,6 +3471,7 @@ __metadata:
version: 0.0.0-use.local
resolution: "@blocksuite/affine-block-frame@workspace:blocksuite/affine/block-frame"
dependencies:
"@blocksuite/affine-block-surface": "workspace:*"
"@blocksuite/affine-components": "workspace:*"
"@blocksuite/affine-model": "workspace:*"
"@blocksuite/affine-shared": "workspace:*"
@@ -3485,6 +3486,7 @@ __metadata:
"@types/mdast": "npm:^4.0.4"
lit: "npm:^3.2.0"
minimatch: "npm:^10.0.1"
yjs: "npm:^13.6.21"
zod: "npm:^3.23.8"
languageName: unknown
linkType: soft
@@ -3718,6 +3720,30 @@ __metadata:
languageName: unknown
linkType: soft
"@blocksuite/affine-fragment-frame-panel@workspace:*, @blocksuite/affine-fragment-frame-panel@workspace:blocksuite/affine/fragment-frame-panel":
version: 0.0.0-use.local
resolution: "@blocksuite/affine-fragment-frame-panel@workspace:blocksuite/affine/fragment-frame-panel"
dependencies:
"@blocksuite/affine-block-frame": "workspace:*"
"@blocksuite/affine-block-surface": "workspace:*"
"@blocksuite/affine-components": "workspace:*"
"@blocksuite/affine-model": "workspace:*"
"@blocksuite/affine-shared": "workspace:*"
"@blocksuite/block-std": "workspace:*"
"@blocksuite/global": "workspace:*"
"@blocksuite/icons": "npm:^2.2.1"
"@blocksuite/inline": "workspace:*"
"@blocksuite/store": "workspace:*"
"@floating-ui/dom": "npm:^1.6.10"
"@lit/context": "npm:^1.1.2"
"@preact/signals-core": "npm:^1.8.0"
"@toeverything/theme": "npm:^1.1.11"
lit: "npm:^3.2.0"
minimatch: "npm:^10.0.1"
zod: "npm:^3.23.8"
languageName: unknown
linkType: soft
"@blocksuite/affine-model@workspace:*, @blocksuite/affine-model@workspace:blocksuite/affine/model":
version: 0.0.0-use.local
resolution: "@blocksuite/affine-model@workspace:blocksuite/affine/model"
@@ -3935,6 +3961,7 @@ __metadata:
"@blocksuite/affine-block-surface-ref": "workspace:*"
"@blocksuite/affine-block-table": "workspace:*"
"@blocksuite/affine-components": "workspace:*"
"@blocksuite/affine-fragment-frame-panel": "workspace:*"
"@blocksuite/affine-model": "workspace:*"
"@blocksuite/affine-shared": "workspace:*"
"@blocksuite/affine-widget-drag-handle": "workspace:*"