From 4e201ede17c5739c200fb1d7a7a53fb1098bded1 Mon Sep 17 00:00:00 2001 From: Saul-Mirone Date: Mon, 28 Apr 2025 14:38:26 +0000 Subject: [PATCH] feat(editor): viewport overlay widget extension (#12035) Closes: BS-3360 ## Summary by CodeRabbit - **New Features** - Introduced a new viewport overlay widget, making it available as part of the workspace and enabling its integration into supported pages. - **Refactor** - Updated internal imports and exports to utilize the new viewport overlay widget package. - Streamlined widget registration and extension mechanisms for improved modularity. - **Chores** - Added configuration and project references to support the new viewport overlay widget package in the build system. --- blocksuite/affine/all/package.json | 3 + blocksuite/affine/all/src/extensions/view.ts | 2 + .../all/src/widgets/viewport-overlay/index.ts | 1 + .../all/src/widgets/viewport-overlay/view.ts | 1 + blocksuite/affine/all/tsconfig.json | 1 + .../blocks/root/src/common-specs/index.ts | 4 -- .../blocks/root/src/common-specs/widgets.ts | 10 --- blocksuite/affine/blocks/root/src/effects.ts | 8 --- .../affine/blocks/root/src/widgets/index.ts | 1 - .../affine/widgets/toolbar/package.json | 9 +-- .../widgets/viewport-overlay/package.json | 40 +++++++++++ .../widgets/viewport-overlay/src/effects.ts | 11 +++ .../viewport-overlay/src/index.ts} | 9 ++- .../widgets/viewport-overlay/src/view.ts | 21 ++++++ .../widgets/viewport-overlay/tsconfig.json | 17 +++++ .../ai/widgets/ai-panel/ai-panel.ts | 8 +-- tools/utils/src/workspace.gen.ts | 14 ++++ tsconfig.json | 1 + yarn.lock | 72 ++++++------------- 19 files changed, 147 insertions(+), 86 deletions(-) create mode 100644 blocksuite/affine/all/src/widgets/viewport-overlay/index.ts create mode 100644 blocksuite/affine/all/src/widgets/viewport-overlay/view.ts delete mode 100644 blocksuite/affine/blocks/root/src/common-specs/widgets.ts create mode 100644 blocksuite/affine/widgets/viewport-overlay/package.json create mode 100644 blocksuite/affine/widgets/viewport-overlay/src/effects.ts rename blocksuite/affine/{blocks/root/src/widgets/viewport-overlay/viewport-overlay.ts => widgets/viewport-overlay/src/index.ts} (86%) create mode 100644 blocksuite/affine/widgets/viewport-overlay/src/view.ts create mode 100644 blocksuite/affine/widgets/viewport-overlay/tsconfig.json diff --git a/blocksuite/affine/all/package.json b/blocksuite/affine/all/package.json index 94a0e9f568..bac7073e1c 100644 --- a/blocksuite/affine/all/package.json +++ b/blocksuite/affine/all/package.json @@ -64,6 +64,7 @@ "@blocksuite/affine-widget-scroll-anchoring": "workspace:*", "@blocksuite/affine-widget-slash-menu": "workspace:*", "@blocksuite/affine-widget-toolbar": "workspace:*", + "@blocksuite/affine-widget-viewport-overlay": "workspace:*", "@blocksuite/data-view": "workspace:*", "@blocksuite/global": "workspace:*", "@blocksuite/std": "workspace:*", @@ -184,6 +185,8 @@ "./widgets/toolbar/view": "./src/widgets/toolbar/view.ts", "./widgets/keyboard-toolbar": "./src/widgets/keyboard-toolbar/index.ts", "./widgets/keyboard-toolbar/view": "./src/widgets/keyboard-toolbar/view.ts", + "./widgets/viewport-overlay": "./src/widgets/viewport-overlay/index.ts", + "./widgets/viewport-overlay/view": "./src/widgets/viewport-overlay/view.ts", "./fragments/doc-title": "./src/fragments/doc-title.ts", "./fragments/frame-panel": "./src/fragments/frame-panel.ts", "./fragments/outline": "./src/fragments/outline.ts", diff --git a/blocksuite/affine/all/src/extensions/view.ts b/blocksuite/affine/all/src/extensions/view.ts index 64662c08d7..10e6529e51 100644 --- a/blocksuite/affine/all/src/extensions/view.ts +++ b/blocksuite/affine/all/src/extensions/view.ts @@ -42,6 +42,7 @@ import { RemoteSelectionViewExtension } from '@blocksuite/affine-widget-remote-s import { ScrollAnchoringViewExtension } from '@blocksuite/affine-widget-scroll-anchoring/view'; import { SlashMenuViewExtension } from '@blocksuite/affine-widget-slash-menu/view'; import { ToolbarViewExtension } from '@blocksuite/affine-widget-toolbar/view'; +import { ViewportOverlayViewExtension } from '@blocksuite/affine-widget-viewport-overlay/view'; import { MigratingViewExtension } from './migrating-view'; @@ -100,5 +101,6 @@ export function getInternalViewExtensions() { ScrollAnchoringViewExtension, SlashMenuViewExtension, ToolbarViewExtension, + ViewportOverlayViewExtension, ]; } diff --git a/blocksuite/affine/all/src/widgets/viewport-overlay/index.ts b/blocksuite/affine/all/src/widgets/viewport-overlay/index.ts new file mode 100644 index 0000000000..0cab03a6b8 --- /dev/null +++ b/blocksuite/affine/all/src/widgets/viewport-overlay/index.ts @@ -0,0 +1 @@ +export * from '@blocksuite/affine-widget-viewport-overlay'; diff --git a/blocksuite/affine/all/src/widgets/viewport-overlay/view.ts b/blocksuite/affine/all/src/widgets/viewport-overlay/view.ts new file mode 100644 index 0000000000..91280b5039 --- /dev/null +++ b/blocksuite/affine/all/src/widgets/viewport-overlay/view.ts @@ -0,0 +1 @@ +export * from '@blocksuite/affine-widget-viewport-overlay/view'; diff --git a/blocksuite/affine/all/tsconfig.json b/blocksuite/affine/all/tsconfig.json index 7f20f73bd7..ea711b96c4 100644 --- a/blocksuite/affine/all/tsconfig.json +++ b/blocksuite/affine/all/tsconfig.json @@ -61,6 +61,7 @@ { "path": "../widgets/scroll-anchoring" }, { "path": "../widgets/slash-menu" }, { "path": "../widgets/toolbar" }, + { "path": "../widgets/viewport-overlay" }, { "path": "../data-view" }, { "path": "../../framework/global" }, { "path": "../../framework/std" }, diff --git a/blocksuite/affine/blocks/root/src/common-specs/index.ts b/blocksuite/affine/blocks/root/src/common-specs/index.ts index 829a39b6c3..0deb0c593d 100644 --- a/blocksuite/affine/blocks/root/src/common-specs/index.ts +++ b/blocksuite/affine/blocks/root/src/common-specs/index.ts @@ -7,13 +7,11 @@ import { RootBlockAdapterExtensions } from '../adapters/extension'; import { clipboardConfigs } from '../clipboard'; import { builtinToolbarConfig } from '../configs/toolbar'; import { fallbackKeymap } from '../keyboard/keymap'; -import { viewportOverlayWidget } from './widgets'; export const CommonSpecs: ExtensionType[] = [ FlavourExtension('affine:page'), ...RootBlockAdapterExtensions, ...clipboardConfigs, - viewportOverlayWidget, fallbackKeymap, ToolbarModuleExtension({ @@ -21,5 +19,3 @@ export const CommonSpecs: ExtensionType[] = [ config: builtinToolbarConfig, }), ]; - -export * from './widgets'; diff --git a/blocksuite/affine/blocks/root/src/common-specs/widgets.ts b/blocksuite/affine/blocks/root/src/common-specs/widgets.ts deleted file mode 100644 index 6cec014d9c..0000000000 --- a/blocksuite/affine/blocks/root/src/common-specs/widgets.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { WidgetViewExtension } from '@blocksuite/std'; -import { literal, unsafeStatic } from 'lit/static-html.js'; - -import { AFFINE_VIEWPORT_OVERLAY_WIDGET } from '../widgets/viewport-overlay/viewport-overlay.js'; - -export const viewportOverlayWidget = WidgetViewExtension( - 'affine:page', - AFFINE_VIEWPORT_OVERLAY_WIDGET, - literal`${unsafeStatic(AFFINE_VIEWPORT_OVERLAY_WIDGET)}` -); diff --git a/blocksuite/affine/blocks/root/src/effects.ts b/blocksuite/affine/blocks/root/src/effects.ts index 52617d60de..b2619f67fe 100644 --- a/blocksuite/affine/blocks/root/src/effects.ts +++ b/blocksuite/affine/blocks/root/src/effects.ts @@ -31,10 +31,6 @@ import { AFFINE_PAGE_DRAGGING_AREA_WIDGET, AffinePageDraggingAreaWidget, } from './widgets/page-dragging-area/page-dragging-area.js'; -import { - AFFINE_VIEWPORT_OVERLAY_WIDGET, - AffineViewportOverlayWidget, -} from './widgets/viewport-overlay/viewport-overlay.js'; export function effects() { // Register components by category @@ -59,10 +55,6 @@ function registerWidgets() { AFFINE_PAGE_DRAGGING_AREA_WIDGET, AffinePageDraggingAreaWidget ); - customElements.define( - AFFINE_VIEWPORT_OVERLAY_WIDGET, - AffineViewportOverlayWidget - ); customElements.define( AFFINE_EDGELESS_ZOOM_TOOLBAR_WIDGET, AffineEdgelessZoomToolbarWidget diff --git a/blocksuite/affine/blocks/root/src/widgets/index.ts b/blocksuite/affine/blocks/root/src/widgets/index.ts index 8d74a22a78..76a088a3c8 100644 --- a/blocksuite/affine/blocks/root/src/widgets/index.ts +++ b/blocksuite/affine/blocks/root/src/widgets/index.ts @@ -1,3 +1,2 @@ export { AffineEdgelessZoomToolbarWidget } from './edgeless-zoom-toolbar/index.js'; export { AffinePageDraggingAreaWidget } from './page-dragging-area/page-dragging-area.js'; -export * from './viewport-overlay/viewport-overlay.js'; diff --git a/blocksuite/affine/widgets/toolbar/package.json b/blocksuite/affine/widgets/toolbar/package.json index ab65581a19..4d5f499950 100644 --- a/blocksuite/affine/widgets/toolbar/package.json +++ b/blocksuite/affine/widgets/toolbar/package.json @@ -39,12 +39,5 @@ "!src/__tests__", "!dist/__tests__" ], - "version": "0.21.0", - "devDependencies": { - "@types/lodash.groupby": "^4", - "@types/lodash.mergewith": "^4", - "@types/lodash.orderby": "^4", - "@types/lodash.partition": "^4", - "@types/lodash.topairs": "^4" - } + "version": "0.21.0" } diff --git a/blocksuite/affine/widgets/viewport-overlay/package.json b/blocksuite/affine/widgets/viewport-overlay/package.json new file mode 100644 index 0000000000..50e000fed8 --- /dev/null +++ b/blocksuite/affine/widgets/viewport-overlay/package.json @@ -0,0 +1,40 @@ +{ + "name": "@blocksuite/affine-widget-viewport-overlay", + "description": "Affine viewport overlay widget.", + "type": "module", + "scripts": { + "build": "tsc" + }, + "sideEffects": false, + "keywords": [], + "author": "toeverything", + "license": "MIT", + "dependencies": { + "@blocksuite/affine-components": "workspace:*", + "@blocksuite/affine-ext-loader": "workspace:*", + "@blocksuite/affine-model": "workspace:*", + "@blocksuite/affine-shared": "workspace:*", + "@blocksuite/global": "workspace:*", + "@blocksuite/icons": "^2.2.12", + "@blocksuite/std": "workspace:*", + "@floating-ui/dom": "^1.6.13", + "@preact/signals-core": "^1.8.0", + "@toeverything/theme": "^1.1.12", + "@types/lodash-es": "^4.17.12", + "lit": "^3.2.0", + "lodash-es": "^4.17.21", + "rxjs": "^7.8.1" + }, + "exports": { + ".": "./src/index.ts", + "./effects": "./src/effects.ts", + "./view": "./src/view.ts" + }, + "files": [ + "src", + "dist", + "!src/__tests__", + "!dist/__tests__" + ], + "version": "0.21.0" +} diff --git a/blocksuite/affine/widgets/viewport-overlay/src/effects.ts b/blocksuite/affine/widgets/viewport-overlay/src/effects.ts new file mode 100644 index 0000000000..e2380751cb --- /dev/null +++ b/blocksuite/affine/widgets/viewport-overlay/src/effects.ts @@ -0,0 +1,11 @@ +import { + AFFINE_VIEWPORT_OVERLAY_WIDGET, + AffineViewportOverlayWidget, +} from './index'; + +export function effects() { + customElements.define( + AFFINE_VIEWPORT_OVERLAY_WIDGET, + AffineViewportOverlayWidget + ); +} diff --git a/blocksuite/affine/blocks/root/src/widgets/viewport-overlay/viewport-overlay.ts b/blocksuite/affine/widgets/viewport-overlay/src/index.ts similarity index 86% rename from blocksuite/affine/blocks/root/src/widgets/viewport-overlay/viewport-overlay.ts rename to blocksuite/affine/widgets/viewport-overlay/src/index.ts index b0410bd347..d0f043dcb1 100644 --- a/blocksuite/affine/blocks/root/src/widgets/viewport-overlay/viewport-overlay.ts +++ b/blocksuite/affine/widgets/viewport-overlay/src/index.ts @@ -1,9 +1,10 @@ import type { RootBlockModel } from '@blocksuite/affine-model'; -import { WidgetComponent } from '@blocksuite/std'; +import { WidgetComponent, WidgetViewExtension } from '@blocksuite/std'; import { css, html } from 'lit'; import { state } from 'lit/decorators.js'; import { classMap } from 'lit/directives/class-map.js'; import { styleMap } from 'lit/directives/style-map.js'; +import { literal, unsafeStatic } from 'lit/static-html.js'; export const AFFINE_VIEWPORT_OVERLAY_WIDGET = 'affine-viewport-overlay-widget'; @@ -76,6 +77,12 @@ export class AffineViewportOverlayWidget extends WidgetComponent private accessor _lockViewport = false; } +export const viewportOverlayWidget = WidgetViewExtension( + 'affine:page', + AFFINE_VIEWPORT_OVERLAY_WIDGET, + literal`${unsafeStatic(AFFINE_VIEWPORT_OVERLAY_WIDGET)}` +); + declare global { interface HTMLElementTagNameMap { [AFFINE_VIEWPORT_OVERLAY_WIDGET]: AffineViewportOverlayWidget; diff --git a/blocksuite/affine/widgets/viewport-overlay/src/view.ts b/blocksuite/affine/widgets/viewport-overlay/src/view.ts new file mode 100644 index 0000000000..f14d6f43ab --- /dev/null +++ b/blocksuite/affine/widgets/viewport-overlay/src/view.ts @@ -0,0 +1,21 @@ +import { + type ViewExtensionContext, + ViewExtensionProvider, +} from '@blocksuite/affine-ext-loader'; + +import { effects } from './effects'; +import { viewportOverlayWidget } from './index'; + +export class ViewportOverlayViewExtension extends ViewExtensionProvider { + override name = 'affine-viewport-overlay-widget'; + + override effect() { + super.effect(); + effects(); + } + + override setup(context: ViewExtensionContext) { + super.setup(context); + context.register(viewportOverlayWidget); + } +} diff --git a/blocksuite/affine/widgets/viewport-overlay/tsconfig.json b/blocksuite/affine/widgets/viewport-overlay/tsconfig.json new file mode 100644 index 0000000000..52ac5011bd --- /dev/null +++ b/blocksuite/affine/widgets/viewport-overlay/tsconfig.json @@ -0,0 +1,17 @@ +{ + "extends": "../../../tsconfig.json", + "compilerOptions": { + "rootDir": "./src", + "outDir": "./dist", + "tsBuildInfoFile": "./dist/tsconfig.tsbuildinfo" + }, + "include": ["./src"], + "references": [ + { "path": "../../components" }, + { "path": "../../ext-loader" }, + { "path": "../../model" }, + { "path": "../../shared" }, + { "path": "../../../framework/global" }, + { "path": "../../../framework/std" } + ] +} diff --git a/packages/frontend/core/src/blocksuite/ai/widgets/ai-panel/ai-panel.ts b/packages/frontend/core/src/blocksuite/ai/widgets/ai-panel/ai-panel.ts index c8960772d5..c19442d1db 100644 --- a/packages/frontend/core/src/blocksuite/ai/widgets/ai-panel/ai-panel.ts +++ b/packages/frontend/core/src/blocksuite/ai/widgets/ai-panel/ai-panel.ts @@ -1,7 +1,3 @@ -import { - AFFINE_VIEWPORT_OVERLAY_WIDGET, - type AffineViewportOverlayWidget, -} from '@blocksuite/affine/blocks/root'; import { ColorScheme } from '@blocksuite/affine/model'; import { DocModeProvider, @@ -19,6 +15,10 @@ import { WidgetComponent, WidgetViewExtension } from '@blocksuite/affine/std'; import { GfxControllerIdentifier } from '@blocksuite/affine/std/gfx'; import { RANGE_SYNC_EXCLUDE_ATTR } from '@blocksuite/affine/std/inline'; import type { BaseSelection } from '@blocksuite/affine/store'; +import { + AFFINE_VIEWPORT_OVERLAY_WIDGET, + type AffineViewportOverlayWidget, +} from '@blocksuite/affine/widgets/viewport-overlay'; import { autoPlacement, autoUpdate, diff --git a/tools/utils/src/workspace.gen.ts b/tools/utils/src/workspace.gen.ts index 2a55628dfb..9b13c6a8af 100644 --- a/tools/utils/src/workspace.gen.ts +++ b/tools/utils/src/workspace.gen.ts @@ -59,6 +59,7 @@ export const PackageList = [ 'blocksuite/affine/widgets/scroll-anchoring', 'blocksuite/affine/widgets/slash-menu', 'blocksuite/affine/widgets/toolbar', + 'blocksuite/affine/widgets/viewport-overlay', 'blocksuite/affine/data-view', 'blocksuite/framework/global', 'blocksuite/framework/std', @@ -936,6 +937,18 @@ export const PackageList = [ 'blocksuite/framework/std', ], }, + { + location: 'blocksuite/affine/widgets/viewport-overlay', + name: '@blocksuite/affine-widget-viewport-overlay', + workspaceDependencies: [ + 'blocksuite/affine/components', + 'blocksuite/affine/ext-loader', + 'blocksuite/affine/model', + 'blocksuite/affine/shared', + 'blocksuite/framework/global', + 'blocksuite/framework/std', + ], + }, { location: 'blocksuite/docs', name: '@blocksuite/bs-docs', @@ -1362,6 +1375,7 @@ export type PackageName = | '@blocksuite/affine-widget-scroll-anchoring' | '@blocksuite/affine-widget-slash-menu' | '@blocksuite/affine-widget-toolbar' + | '@blocksuite/affine-widget-viewport-overlay' | '@blocksuite/bs-docs' | '@blocksuite/global' | '@blocksuite/std' diff --git a/tsconfig.json b/tsconfig.json index 12f50a7957..7603f1b4ff 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -106,6 +106,7 @@ { "path": "./blocksuite/affine/widgets/scroll-anchoring" }, { "path": "./blocksuite/affine/widgets/slash-menu" }, { "path": "./blocksuite/affine/widgets/toolbar" }, + { "path": "./blocksuite/affine/widgets/viewport-overlay" }, { "path": "./blocksuite/docs" }, { "path": "./blocksuite/framework/global" }, { "path": "./blocksuite/framework/std" }, diff --git a/yarn.lock b/yarn.lock index 984d5d7477..b851f6a5af 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3916,11 +3916,27 @@ __metadata: "@preact/signals-core": "npm:^1.8.0" "@toeverything/theme": "npm:^1.1.12" "@types/lodash-es": "npm:^4.17.12" - "@types/lodash.groupby": "npm:^4" - "@types/lodash.mergewith": "npm:^4" - "@types/lodash.orderby": "npm:^4" - "@types/lodash.partition": "npm:^4" - "@types/lodash.topairs": "npm:^4" + lit: "npm:^3.2.0" + lodash-es: "npm:^4.17.21" + rxjs: "npm:^7.8.1" + languageName: unknown + linkType: soft + +"@blocksuite/affine-widget-viewport-overlay@workspace:*, @blocksuite/affine-widget-viewport-overlay@workspace:blocksuite/affine/widgets/viewport-overlay": + version: 0.0.0-use.local + resolution: "@blocksuite/affine-widget-viewport-overlay@workspace:blocksuite/affine/widgets/viewport-overlay" + dependencies: + "@blocksuite/affine-components": "workspace:*" + "@blocksuite/affine-ext-loader": "workspace:*" + "@blocksuite/affine-model": "workspace:*" + "@blocksuite/affine-shared": "workspace:*" + "@blocksuite/global": "workspace:*" + "@blocksuite/icons": "npm:^2.2.12" + "@blocksuite/std": "workspace:*" + "@floating-ui/dom": "npm:^1.6.13" + "@preact/signals-core": "npm:^1.8.0" + "@toeverything/theme": "npm:^1.1.12" + "@types/lodash-es": "npm:^4.17.12" lit: "npm:^3.2.0" lodash-es: "npm:^4.17.21" rxjs: "npm:^7.8.1" @@ -3985,6 +4001,7 @@ __metadata: "@blocksuite/affine-widget-scroll-anchoring": "workspace:*" "@blocksuite/affine-widget-slash-menu": "workspace:*" "@blocksuite/affine-widget-toolbar": "workspace:*" + "@blocksuite/affine-widget-viewport-overlay": "workspace:*" "@blocksuite/data-view": "workspace:*" "@blocksuite/global": "workspace:*" "@blocksuite/std": "workspace:*" @@ -15077,15 +15094,6 @@ __metadata: languageName: node linkType: hard -"@types/lodash.groupby@npm:^4": - version: 4.6.9 - resolution: "@types/lodash.groupby@npm:4.6.9" - dependencies: - "@types/lodash": "npm:*" - checksum: 10/b8310a9f89badc42a504887ca0b9619c2a284b3fec8dc505cf72508eb6beba47b822df939c7d57c0f69bc685f51ff5a232e0480ecad6b18b7ab76fecc1d74691 - languageName: node - linkType: hard - "@types/lodash.ismatch@npm:^4.4.9": version: 4.4.9 resolution: "@types/lodash.ismatch@npm:4.4.9" @@ -15104,42 +15112,6 @@ __metadata: languageName: node linkType: hard -"@types/lodash.mergewith@npm:^4": - version: 4.6.9 - resolution: "@types/lodash.mergewith@npm:4.6.9" - dependencies: - "@types/lodash": "npm:*" - checksum: 10/c5a67e83040103decfd37090127118f5758773d0ce2a1756d442b371721737c7752f48f62544cc970f44abec8471f260cc4c844e1a4fdef8b76cb96bdec8a595 - languageName: node - linkType: hard - -"@types/lodash.orderby@npm:^4": - version: 4.6.9 - resolution: "@types/lodash.orderby@npm:4.6.9" - dependencies: - "@types/lodash": "npm:*" - checksum: 10/f3ca3a6ba09caef431955f3110a6704e25c90934fb70973e2ed1f4dd9aa48c4776c7e8b909b78f9ae1fb169e437497f8fe8e60fafb5c74ede49c36739ac44c3e - languageName: node - linkType: hard - -"@types/lodash.partition@npm:^4": - version: 4.6.9 - resolution: "@types/lodash.partition@npm:4.6.9" - dependencies: - "@types/lodash": "npm:*" - checksum: 10/29d1fead7f9a71af8279ceb6c1b08128c7f05f06a72ed60fea02a7c010f69006a4e3dc24afb9c4a3187a033b918a1b3dcf611004781f927ff573b104bdf34060 - languageName: node - linkType: hard - -"@types/lodash.topairs@npm:^4": - version: 4.3.9 - resolution: "@types/lodash.topairs@npm:4.3.9" - dependencies: - "@types/lodash": "npm:*" - checksum: 10/8d4d9cb7be1c333b70b8d035d0673ef41158bfe24e06616046879149a15438af89673fe21abe1b1e62ddbc00eae5fe4c3795649de8a98742771ba8949100a300 - languageName: node - linkType: hard - "@types/lodash@npm:*": version: 4.17.16 resolution: "@types/lodash@npm:4.17.16"