feat(editor): extract keyboard toolbar widget (#11707)

This commit is contained in:
Saul-Mirone
2025-04-15 12:06:49 +00:00
parent ecdaea9176
commit b5c9741f18
25 changed files with 201 additions and 33 deletions

View File

@@ -55,6 +55,7 @@
"@blocksuite/affine-widget-edgeless-auto-connect": "workspace:*",
"@blocksuite/affine-widget-edgeless-toolbar": "workspace:*",
"@blocksuite/affine-widget-frame-title": "workspace:*",
"@blocksuite/affine-widget-keyboard-toolbar": "workspace:*",
"@blocksuite/affine-widget-linked-doc": "workspace:*",
"@blocksuite/affine-widget-remote-selection": "workspace:*",
"@blocksuite/affine-widget-scroll-anchoring": "workspace:*",
@@ -121,6 +122,7 @@
"./widgets/scroll-anchoring": "./src/widgets/scroll-anchoring.ts",
"./widgets/slash-menu": "./src/widgets/slash-menu.ts",
"./widgets/toolbar": "./src/widgets/toolbar.ts",
"./widgets/keyboard-toolbar": "./src/widgets/keyboard-toolbar.ts",
"./fragments/doc-title": "./src/fragments/doc-title.ts",
"./fragments/frame-panel": "./src/fragments/frame-panel.ts",
"./fragments/outline": "./src/fragments/outline.ts",

View File

@@ -0,0 +1 @@
export * from '@blocksuite/affine-widget-keyboard-toolbar';

View File

@@ -52,6 +52,7 @@
{ "path": "../widgets/edgeless-auto-connect" },
{ "path": "../widgets/edgeless-toolbar" },
{ "path": "../widgets/frame-title" },
{ "path": "../widgets/keyboard-toolbar" },
{ "path": "../widgets/linked-doc" },
{ "path": "../widgets/remote-selection" },
{ "path": "../widgets/scroll-anchoring" },

View File

@@ -46,6 +46,7 @@
"@blocksuite/affine-widget-edgeless-auto-connect": "workspace:*",
"@blocksuite/affine-widget-edgeless-toolbar": "workspace:*",
"@blocksuite/affine-widget-frame-title": "workspace:*",
"@blocksuite/affine-widget-keyboard-toolbar": "workspace:*",
"@blocksuite/affine-widget-linked-doc": "workspace:*",
"@blocksuite/affine-widget-remote-selection": "workspace:*",
"@blocksuite/affine-widget-scroll-anchoring": "workspace:*",

View File

@@ -7,6 +7,7 @@ import { effects as gfxShapeEffects } from '@blocksuite/affine-gfx-shape/effects
import { effects as gfxTemplateEffects } from '@blocksuite/affine-gfx-template/effects';
import { effects as gfxCanvasTextEffects } from '@blocksuite/affine-gfx-text/effects';
import { effects as widgetEdgelessToolbarEffects } from '@blocksuite/affine-widget-edgeless-toolbar/effects';
import { effects as widgetMobileToolbarEffects } from '@blocksuite/affine-widget-keyboard-toolbar/effects';
import { effects as widgetLinkedDocEffects } from '@blocksuite/affine-widget-linked-doc/effects';
import { EdgelessAutoCompletePanel } from './edgeless/components/auto-complete/auto-complete-panel.js';
@@ -44,7 +45,6 @@ import {
} from './widgets/edgeless-zoom-toolbar/index.js';
import { ZoomBarToggleButton } from './widgets/edgeless-zoom-toolbar/zoom-bar-toggle-button.js';
import { EdgelessZoomToolbar } from './widgets/edgeless-zoom-toolbar/zoom-toolbar.js';
import { effects as widgetMobileToolbarEffects } from './widgets/keyboard-toolbar/effects.js';
import { AffineCustomModal } from './widgets/modal/custom-modal.js';
import { AFFINE_MODAL_WIDGET } from './widgets/modal/modal.js';
import {

View File

@@ -8,7 +8,6 @@ export * from './page/page-root-block.js';
export { PageRootService } from './page/page-root-service.js';
export * from './page/page-root-spec.js';
export * from './preview/preview-root-block.js';
export * from './root-config.js';
export { RootService } from './root-service.js';
export * from './types.js';
export * from './utils/index.js';

View File

@@ -1,4 +1,5 @@
import { ViewportElementExtension } from '@blocksuite/affine-shared/services';
import { keyboardToolbarWidget } from '@blocksuite/affine-widget-keyboard-toolbar';
import { IS_MOBILE } from '@blocksuite/global/env';
import { BlockViewExtension, WidgetViewExtension } from '@blocksuite/std';
import type { ExtensionType } from '@blocksuite/store';
@@ -6,16 +7,9 @@ import { literal, unsafeStatic } from 'lit/static-html.js';
import { PageClipboard } from '../clipboard/page-clipboard.js';
import { CommonSpecs } from '../common-specs/index.js';
import { AFFINE_KEYBOARD_TOOLBAR_WIDGET } from '../widgets/keyboard-toolbar/index.js';
import { AFFINE_PAGE_DRAGGING_AREA_WIDGET } from '../widgets/page-dragging-area/page-dragging-area.js';
import { PageRootService } from './page-root-service.js';
export const keyboardToolbarWidget = WidgetViewExtension(
'affine:page',
AFFINE_KEYBOARD_TOOLBAR_WIDGET,
literal`${unsafeStatic(AFFINE_KEYBOARD_TOOLBAR_WIDGET)}`
);
export const pageDraggingAreaWidget = WidgetViewExtension(
'affine:page',
AFFINE_PAGE_DRAGGING_AREA_WIDGET,

View File

@@ -1,10 +0,0 @@
import { ConfigExtensionFactory } from '@blocksuite/std';
import type { KeyboardToolbarConfig } from './widgets/keyboard-toolbar/config.js';
export interface RootBlockConfig {
keyboardToolbar?: Partial<KeyboardToolbarConfig>;
}
export const RootBlockConfigExtension =
ConfigExtensionFactory<RootBlockConfig>('affine:root-block');

View File

@@ -1,5 +1,4 @@
export { AffineEdgelessZoomToolbarWidget } from './edgeless-zoom-toolbar/index.js';
export * from './keyboard-toolbar/index.js';
export { AffineModalWidget } from './modal/modal.js';
export { AffinePageDraggingAreaWidget } from './page-dragging-area/page-dragging-area.js';
export * from './viewport-overlay/viewport-overlay.js';

View File

@@ -43,6 +43,7 @@
{ "path": "../../widgets/edgeless-auto-connect" },
{ "path": "../../widgets/edgeless-toolbar" },
{ "path": "../../widgets/frame-title" },
{ "path": "../../widgets/keyboard-toolbar" },
{ "path": "../../widgets/linked-doc" },
{ "path": "../../widgets/remote-selection" },
{ "path": "../../widgets/scroll-anchoring" },

View File

@@ -0,0 +1,57 @@
{
"name": "@blocksuite/affine-widget-keyboard-toolbar",
"description": "Affine keyboard toolbar widget.",
"type": "module",
"scripts": {
"build": "tsc"
},
"sideEffects": false,
"keywords": [],
"author": "toeverything",
"license": "MIT",
"dependencies": {
"@blocksuite/affine-block-attachment": "workspace:*",
"@blocksuite/affine-block-database": "workspace:*",
"@blocksuite/affine-block-embed": "workspace:*",
"@blocksuite/affine-block-image": "workspace:*",
"@blocksuite/affine-block-latex": "workspace:*",
"@blocksuite/affine-block-list": "workspace:*",
"@blocksuite/affine-block-note": "workspace:*",
"@blocksuite/affine-block-paragraph": "workspace:*",
"@blocksuite/affine-block-surface": "workspace:*",
"@blocksuite/affine-block-surface-ref": "workspace:*",
"@blocksuite/affine-components": "workspace:*",
"@blocksuite/affine-fragment-doc-title": "workspace:*",
"@blocksuite/affine-inline-latex": "workspace:*",
"@blocksuite/affine-inline-link": "workspace:*",
"@blocksuite/affine-inline-preset": "workspace:*",
"@blocksuite/affine-inline-reference": "workspace:*",
"@blocksuite/affine-model": "workspace:*",
"@blocksuite/affine-rich-text": "workspace:*",
"@blocksuite/affine-shared": "workspace:*",
"@blocksuite/data-view": "workspace:*",
"@blocksuite/global": "workspace:*",
"@blocksuite/icons": "^2.2.10",
"@blocksuite/std": "workspace:*",
"@blocksuite/store": "workspace:*",
"@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.12",
"@types/lodash-es": "^4.17.12",
"fflate": "^0.8.2",
"lit": "^3.2.0",
"lodash-es": "^4.17.21",
"rxjs": "^7.8.1"
},
"exports": {
".": "./src/index.ts",
"./effects": "./src/effects.ts"
},
"files": [
"src",
"dist",
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.21.0"
}

View File

@@ -97,12 +97,15 @@ import {
YesterdayIcon,
YoutubeDuotoneIcon,
} from '@blocksuite/icons/lit';
import type { BlockStdScope } from '@blocksuite/std';
import {
type BlockComponent,
type BlockStdScope,
ConfigExtensionFactory,
} from '@blocksuite/std';
import { computed } from '@preact/signals-core';
import { cssVarV2 } from '@toeverything/theme/v2';
import type { TemplateResult } from 'lit';
import type { PageRootBlockComponent } from '../../page/page-root-block.js';
import {
FigmaDuotoneIcon,
HeadingIcon,
@@ -156,7 +159,7 @@ export type KeyboardSubToolbarConfig = {
export type KeyboardToolbarContext = {
std: BlockStdScope;
rootComponent: PageRootBlockComponent;
rootComponent: BlockComponent;
/**
* Close tool bar, and blur the focus if blur is true, default is false
*/
@@ -1126,3 +1129,7 @@ export const defaultKeyboardToolbarConfig: KeyboardToolbarConfig = {
},
],
};
export const KeyboardToolbarConfigExtension = ConfigExtensionFactory<
Partial<KeyboardToolbarConfig>
>('affine:keyboard-toolbar');

View File

@@ -0,0 +1,2 @@
export * from './config.js';
export * from './widget.js';

View File

@@ -3,6 +3,7 @@ import { type VirtualKeyboardProviderWithAction } from '@blocksuite/affine-share
import { SignalWatcher, WithDisposable } from '@blocksuite/global/lit';
import { ArrowLeftBigIcon, KeyboardIcon } from '@blocksuite/icons/lit';
import {
BlockComponent,
PropTypes,
requiredProperties,
ShadowlessElement,
@@ -14,7 +15,6 @@ import { repeat } from 'lit/directives/repeat.js';
import { styleMap } from 'lit/directives/style-map.js';
import { when } from 'lit/directives/when.js';
import { PageRootBlockComponent } from '../../page/page-root-block';
import type {
KeyboardIconType,
KeyboardToolbarConfig,
@@ -34,7 +34,7 @@ export const AFFINE_KEYBOARD_TOOLBAR = 'affine-keyboard-toolbar';
@requiredProperties({
config: PropTypes.object,
rootComponent: PropTypes.instanceOf(PageRootBlockComponent),
rootComponent: PropTypes.instanceOf(BlockComponent),
})
export class AffineKeyboardToolbar extends SignalWatcher(
WithDisposable(ShadowlessElement)
@@ -338,5 +338,5 @@ export class AffineKeyboardToolbar extends SignalWatcher(
accessor config!: KeyboardToolbarConfig;
@property({ attribute: false })
accessor rootComponent!: PageRootBlockComponent;
accessor rootComponent!: BlockComponent;
}

View File

@@ -7,14 +7,15 @@ import {
type VirtualKeyboardProviderWithAction,
} from '@blocksuite/affine-shared/services';
import { IS_MOBILE } from '@blocksuite/global/env';
import { WidgetComponent } from '@blocksuite/std';
import { WidgetComponent, WidgetViewExtension } from '@blocksuite/std';
import { effect, signal } from '@preact/signals-core';
import { html, nothing } from 'lit';
import { literal, unsafeStatic } from 'lit/static-html.js';
import { RootBlockConfigExtension } from '../../root-config.js';
import { defaultKeyboardToolbarConfig } from './config.js';
export * from './config.js';
import {
defaultKeyboardToolbarConfig,
KeyboardToolbarConfigExtension,
} from './config.js';
export const AFFINE_KEYBOARD_TOOLBAR_WIDGET = 'affine-keyboard-toolbar-widget';
@@ -64,8 +65,7 @@ export class AffineKeyboardToolbarWidget extends WidgetComponent<RootBlockModel>
get config() {
return {
...defaultKeyboardToolbarConfig,
...this.std.getOptional(RootBlockConfigExtension.identifier)
?.keyboardToolbar,
...this.std.getOptional(KeyboardToolbarConfigExtension.identifier),
};
}
@@ -134,6 +134,12 @@ export class AffineKeyboardToolbarWidget extends WidgetComponent<RootBlockModel>
}
}
export const keyboardToolbarWidget = WidgetViewExtension(
'affine:page',
AFFINE_KEYBOARD_TOOLBAR_WIDGET,
literal`${unsafeStatic(AFFINE_KEYBOARD_TOOLBAR_WIDGET)}`
);
declare global {
interface HTMLElementTagNameMap {
[AFFINE_KEYBOARD_TOOLBAR_WIDGET]: AffineKeyboardToolbarWidget;

View File

@@ -0,0 +1,34 @@
{
"extends": "../../../tsconfig.json",
"compilerOptions": {
"rootDir": "./src",
"outDir": "./dist",
"tsBuildInfoFile": "./dist/tsconfig.tsbuildinfo"
},
"include": ["./src"],
"references": [
{ "path": "../../blocks/attachment" },
{ "path": "../../blocks/database" },
{ "path": "../../blocks/embed" },
{ "path": "../../blocks/image" },
{ "path": "../../blocks/latex" },
{ "path": "../../blocks/list" },
{ "path": "../../blocks/note" },
{ "path": "../../blocks/paragraph" },
{ "path": "../../blocks/surface" },
{ "path": "../../blocks/surface-ref" },
{ "path": "../../components" },
{ "path": "../../fragments/doc-title" },
{ "path": "../../inlines/latex" },
{ "path": "../../inlines/link" },
{ "path": "../../inlines/preset" },
{ "path": "../../inlines/reference" },
{ "path": "../../model" },
{ "path": "../../rich-text" },
{ "path": "../../shared" },
{ "path": "../../data-view" },
{ "path": "../../../framework/global" },
{ "path": "../../../framework/std" },
{ "path": "../../../framework/store" }
]
}

View File

@@ -50,6 +50,7 @@ export const PackageList = [
'blocksuite/affine/widgets/edgeless-auto-connect',
'blocksuite/affine/widgets/edgeless-toolbar',
'blocksuite/affine/widgets/frame-title',
'blocksuite/affine/widgets/keyboard-toolbar',
'blocksuite/affine/widgets/linked-doc',
'blocksuite/affine/widgets/remote-selection',
'blocksuite/affine/widgets/scroll-anchoring',
@@ -339,6 +340,7 @@ export const PackageList = [
'blocksuite/affine/widgets/edgeless-auto-connect',
'blocksuite/affine/widgets/edgeless-toolbar',
'blocksuite/affine/widgets/frame-title',
'blocksuite/affine/widgets/keyboard-toolbar',
'blocksuite/affine/widgets/linked-doc',
'blocksuite/affine/widgets/remote-selection',
'blocksuite/affine/widgets/scroll-anchoring',
@@ -773,6 +775,35 @@ export const PackageList = [
'blocksuite/framework/std',
],
},
{
location: 'blocksuite/affine/widgets/keyboard-toolbar',
name: '@blocksuite/affine-widget-keyboard-toolbar',
workspaceDependencies: [
'blocksuite/affine/blocks/attachment',
'blocksuite/affine/blocks/database',
'blocksuite/affine/blocks/embed',
'blocksuite/affine/blocks/image',
'blocksuite/affine/blocks/latex',
'blocksuite/affine/blocks/list',
'blocksuite/affine/blocks/note',
'blocksuite/affine/blocks/paragraph',
'blocksuite/affine/blocks/surface',
'blocksuite/affine/blocks/surface-ref',
'blocksuite/affine/components',
'blocksuite/affine/fragments/doc-title',
'blocksuite/affine/inlines/latex',
'blocksuite/affine/inlines/link',
'blocksuite/affine/inlines/preset',
'blocksuite/affine/inlines/reference',
'blocksuite/affine/model',
'blocksuite/affine/rich-text',
'blocksuite/affine/shared',
'blocksuite/affine/data-view',
'blocksuite/framework/global',
'blocksuite/framework/std',
'blocksuite/framework/store',
],
},
{
location: 'blocksuite/affine/widgets/linked-doc',
name: '@blocksuite/affine-widget-linked-doc',
@@ -1238,6 +1269,7 @@ export type PackageName =
| '@blocksuite/affine-widget-edgeless-auto-connect'
| '@blocksuite/affine-widget-edgeless-toolbar'
| '@blocksuite/affine-widget-frame-title'
| '@blocksuite/affine-widget-keyboard-toolbar'
| '@blocksuite/affine-widget-linked-doc'
| '@blocksuite/affine-widget-remote-selection'
| '@blocksuite/affine-widget-scroll-anchoring'

View File

@@ -97,6 +97,7 @@
{ "path": "./blocksuite/affine/widgets/edgeless-auto-connect" },
{ "path": "./blocksuite/affine/widgets/edgeless-toolbar" },
{ "path": "./blocksuite/affine/widgets/frame-title" },
{ "path": "./blocksuite/affine/widgets/keyboard-toolbar" },
{ "path": "./blocksuite/affine/widgets/linked-doc" },
{ "path": "./blocksuite/affine/widgets/remote-selection" },
{ "path": "./blocksuite/affine/widgets/scroll-anchoring" },

View File

@@ -2822,6 +2822,7 @@ __metadata:
"@blocksuite/affine-widget-edgeless-auto-connect": "workspace:*"
"@blocksuite/affine-widget-edgeless-toolbar": "workspace:*"
"@blocksuite/affine-widget-frame-title": "workspace:*"
"@blocksuite/affine-widget-keyboard-toolbar": "workspace:*"
"@blocksuite/affine-widget-linked-doc": "workspace:*"
"@blocksuite/affine-widget-remote-selection": "workspace:*"
"@blocksuite/affine-widget-scroll-anchoring": "workspace:*"
@@ -3650,6 +3651,45 @@ __metadata:
languageName: unknown
linkType: soft
"@blocksuite/affine-widget-keyboard-toolbar@workspace:*, @blocksuite/affine-widget-keyboard-toolbar@workspace:blocksuite/affine/widgets/keyboard-toolbar":
version: 0.0.0-use.local
resolution: "@blocksuite/affine-widget-keyboard-toolbar@workspace:blocksuite/affine/widgets/keyboard-toolbar"
dependencies:
"@blocksuite/affine-block-attachment": "workspace:*"
"@blocksuite/affine-block-database": "workspace:*"
"@blocksuite/affine-block-embed": "workspace:*"
"@blocksuite/affine-block-image": "workspace:*"
"@blocksuite/affine-block-latex": "workspace:*"
"@blocksuite/affine-block-list": "workspace:*"
"@blocksuite/affine-block-note": "workspace:*"
"@blocksuite/affine-block-paragraph": "workspace:*"
"@blocksuite/affine-block-surface": "workspace:*"
"@blocksuite/affine-block-surface-ref": "workspace:*"
"@blocksuite/affine-components": "workspace:*"
"@blocksuite/affine-fragment-doc-title": "workspace:*"
"@blocksuite/affine-inline-latex": "workspace:*"
"@blocksuite/affine-inline-link": "workspace:*"
"@blocksuite/affine-inline-preset": "workspace:*"
"@blocksuite/affine-inline-reference": "workspace:*"
"@blocksuite/affine-model": "workspace:*"
"@blocksuite/affine-rich-text": "workspace:*"
"@blocksuite/affine-shared": "workspace:*"
"@blocksuite/data-view": "workspace:*"
"@blocksuite/global": "workspace:*"
"@blocksuite/icons": "npm:^2.2.10"
"@blocksuite/std": "workspace:*"
"@blocksuite/store": "workspace:*"
"@lit/context": "npm:^1.1.2"
"@preact/signals-core": "npm:^1.8.0"
"@toeverything/theme": "npm:^1.1.12"
"@types/lodash-es": "npm:^4.17.12"
fflate: "npm:^0.8.2"
lit: "npm:^3.2.0"
lodash-es: "npm:^4.17.21"
rxjs: "npm:^7.8.1"
languageName: unknown
linkType: soft
"@blocksuite/affine-widget-linked-doc@workspace:*, @blocksuite/affine-widget-linked-doc@workspace:blocksuite/affine/widgets/linked-doc":
version: 0.0.0-use.local
resolution: "@blocksuite/affine-widget-linked-doc@workspace:blocksuite/affine/widgets/linked-doc"
@@ -3808,6 +3848,7 @@ __metadata:
"@blocksuite/affine-widget-edgeless-auto-connect": "workspace:*"
"@blocksuite/affine-widget-edgeless-toolbar": "workspace:*"
"@blocksuite/affine-widget-frame-title": "workspace:*"
"@blocksuite/affine-widget-keyboard-toolbar": "workspace:*"
"@blocksuite/affine-widget-linked-doc": "workspace:*"
"@blocksuite/affine-widget-remote-selection": "workspace:*"
"@blocksuite/affine-widget-scroll-anchoring": "workspace:*"