diff --git a/blocksuite/affine/blocks/block-root/src/widgets/keyboard-toolbar/index.ts b/blocksuite/affine/blocks/block-root/src/widgets/keyboard-toolbar/index.ts
index 5d9792cf24..bab0abbfc2 100644
--- a/blocksuite/affine/blocks/block-root/src/widgets/keyboard-toolbar/index.ts
+++ b/blocksuite/affine/blocks/block-root/src/widgets/keyboard-toolbar/index.ts
@@ -1,9 +1,13 @@
import { getDocTitleByEditorHost } from '@blocksuite/affine-fragment-doc-title';
import type { RootBlockModel } from '@blocksuite/affine-model';
-import { FeatureFlagService } from '@blocksuite/affine-shared/services';
+import {
+ FeatureFlagService,
+ VirtualKeyboardProvider,
+ type VirtualKeyboardProviderWithAction,
+} from '@blocksuite/affine-shared/services';
import { IS_MOBILE } from '@blocksuite/global/env';
import { WidgetComponent } from '@blocksuite/std';
-import { signal } from '@preact/signals-core';
+import { effect, signal } from '@preact/signals-core';
import { html, nothing } from 'lit';
import type { PageRootBlockComponent } from '../../page/page-root-block.js';
@@ -22,6 +26,7 @@ export class AffineKeyboardToolbarWidget extends WidgetComponent<
if (blur) {
if (document.activeElement === this._docTitle?.inlineEditorContainer) {
this._docTitle?.inlineEditor?.setInlineRange(null);
+ this._docTitle?.inlineEditor?.eventSource?.blur();
} else if (document.activeElement === this.block?.rootComponent) {
this.std.selection.clear();
}
@@ -31,6 +36,27 @@ export class AffineKeyboardToolbarWidget extends WidgetComponent<
private readonly _show$ = signal(false);
+ private _initialInputMode: string = '';
+
+ get keyboard(): VirtualKeyboardProviderWithAction {
+ return {
+ // fallback keyboard actions
+ show: () => {
+ const rootComponent = this.block?.rootComponent;
+ if (rootComponent && rootComponent === document.activeElement) {
+ rootComponent.inputMode = this._initialInputMode;
+ }
+ },
+ hide: () => {
+ const rootComponent = this.block?.rootComponent;
+ if (rootComponent && rootComponent === document.activeElement) {
+ rootComponent.inputMode = 'none';
+ }
+ },
+ ...this.std.get(VirtualKeyboardProvider),
+ };
+ }
+
private get _docTitle() {
return getDocTitleByEditorHost(this.std.host);
}
@@ -48,12 +74,25 @@ export class AffineKeyboardToolbarWidget extends WidgetComponent<
const rootComponent = this.block?.rootComponent;
if (rootComponent) {
+ this._initialInputMode = rootComponent.inputMode;
+ this.disposables.add(() => {
+ rootComponent.inputMode = this._initialInputMode;
+ });
this.disposables.addFromEvent(rootComponent, 'focus', () => {
this._show$.value = true;
});
this.disposables.addFromEvent(rootComponent, 'blur', () => {
this._show$.value = false;
});
+
+ this.disposables.add(
+ effect(() => {
+ // recover input mode when keyboard toolbar is hidden
+ if (!this._show$.value) {
+ rootComponent.inputMode = this._initialInputMode;
+ }
+ })
+ );
}
if (this._docTitle) {
@@ -84,10 +123,11 @@ export class AffineKeyboardToolbarWidget extends WidgetComponent<
return html` `}
+ >`}
>`;
}
}
diff --git a/blocksuite/affine/blocks/block-root/src/widgets/keyboard-toolbar/keyboard-toolbar.ts b/blocksuite/affine/blocks/block-root/src/widgets/keyboard-toolbar/keyboard-toolbar.ts
index 7c6a876dc0..6f67b0e055 100644
--- a/blocksuite/affine/blocks/block-root/src/widgets/keyboard-toolbar/keyboard-toolbar.ts
+++ b/blocksuite/affine/blocks/block-root/src/widgets/keyboard-toolbar/keyboard-toolbar.ts
@@ -1,5 +1,5 @@
import { getSelectedModelsCommand } from '@blocksuite/affine-shared/commands';
-import { VirtualKeyboardProvider } from '@blocksuite/affine-shared/services';
+import { type VirtualKeyboardProviderWithAction } from '@blocksuite/affine-shared/services';
import { SignalWatcher, WithDisposable } from '@blocksuite/global/lit';
import { ArrowLeftBigIcon, KeyboardIcon } from '@blocksuite/icons/lit';
import {
@@ -50,10 +50,6 @@ export class AffineKeyboardToolbar extends SignalWatcher(
return this.rootComponent.std;
}
- get keyboard() {
- return this._context.std.get(VirtualKeyboardProvider);
- }
-
get panelOpened() {
return this._currentPanelIndex$.value !== -1;
}
@@ -324,6 +320,9 @@ export class AffineKeyboardToolbar extends SignalWatcher(
`;
}
+ @property({ attribute: false })
+ accessor keyboard!: VirtualKeyboardProviderWithAction;
+
@property({ attribute: false })
accessor close: (blur: boolean) => void = () => {};
diff --git a/blocksuite/affine/blocks/block-root/src/widgets/linked-doc/mobile-linked-doc-menu.ts b/blocksuite/affine/blocks/block-root/src/widgets/linked-doc/mobile-linked-doc-menu.ts
index 9ef5fe348c..2ffd5df74a 100644
--- a/blocksuite/affine/blocks/block-root/src/widgets/linked-doc/mobile-linked-doc-menu.ts
+++ b/blocksuite/affine/blocks/block-root/src/widgets/linked-doc/mobile-linked-doc-menu.ts
@@ -230,9 +230,6 @@ export class AffineMobileLinkedDocMenu extends SignalWatcher(
}
override firstUpdated() {
- if (!this.keyboard.visible$.value) {
- this.keyboard.show();
- }
this._scrollInputToTop();
}
diff --git a/blocksuite/affine/shared/src/services/virtual-keyboard-service.ts b/blocksuite/affine/shared/src/services/virtual-keyboard-service.ts
index 57cbe0af0a..c086cad05d 100644
--- a/blocksuite/affine/shared/src/services/virtual-keyboard-service.ts
+++ b/blocksuite/affine/shared/src/services/virtual-keyboard-service.ts
@@ -2,11 +2,16 @@ import { createIdentifier } from '@blocksuite/global/di';
import type { ReadonlySignal } from '@preact/signals-core';
export interface VirtualKeyboardProvider {
- show: () => void;
- hide: () => void;
readonly visible$: ReadonlySignal;
readonly height$: ReadonlySignal;
}
-export const VirtualKeyboardProvider =
- createIdentifier('VirtualKeyboardProvider');
+export interface VirtualKeyboardProviderWithAction
+ extends VirtualKeyboardProvider {
+ show: () => void;
+ hide: () => void;
+}
+
+export const VirtualKeyboardProvider = createIdentifier<
+ VirtualKeyboardProvider | VirtualKeyboardProviderWithAction
+>('VirtualKeyboardProvider');
diff --git a/packages/frontend/apps/ios/src/index.tsx b/packages/frontend/apps/ios/src/index.tsx
index 3ee551fada..9b39259655 100644
--- a/packages/frontend/apps/ios/src/index.tsx
+++ b/packages/frontend/apps/ios/src/index.tsx
@@ -12,9 +12,6 @@ import { NbStoreNativeDBApis } from './plugins/nbstore';
bindNativeDBApis(NbStoreNativeDBApis);
-// TODO(@L-Sun) Uncomment this when the `show` method implement by `@capacitor/keyboard` in ios
-// import './virtual-keyboard';
-
function mountApp() {
// oxlint-disable-next-line @typescript-eslint/no-non-null-assertion
const root = document.getElementById('app')!;
diff --git a/packages/frontend/core/src/blocksuite/extensions/entry/enable-mobile.ts b/packages/frontend/core/src/blocksuite/extensions/entry/enable-mobile.ts
index 6b30103ece..7aaacc37dc 100644
--- a/packages/frontend/core/src/blocksuite/extensions/entry/enable-mobile.ts
+++ b/packages/frontend/core/src/blocksuite/extensions/entry/enable-mobile.ts
@@ -10,9 +10,9 @@ import type {
} from '@blocksuite/affine/global/di';
import { DisposableGroup } from '@blocksuite/affine/global/disposable';
import {
- DocModeProvider,
FeatureFlagService,
VirtualKeyboardProvider as BSVirtualKeyboardProvider,
+ type VirtualKeyboardProviderWithAction,
} from '@blocksuite/affine/shared/services';
import type { SpecBuilder } from '@blocksuite/affine/shared/utils';
import {
@@ -69,35 +69,12 @@ function KeyboardToolbarExtension(framework: FrameworkProvider): ExtensionType {
private readonly _disposables = new DisposableGroup();
- private get _rootContentEditable() {
- const editorMode = this.std.get(DocModeProvider).getEditorMode();
- if (editorMode !== 'page') return null;
-
- if (!this.std.host.doc.root) return;
- return this.std.view.getBlock(this.std.host.doc.root.id);
- }
-
// eslint-disable-next-line rxjs/finnish
readonly visible$ = signal(false);
// eslint-disable-next-line rxjs/finnish
readonly height$ = signal(0);
- show() {
- if ('show' in affineVirtualKeyboardProvider) {
- affineVirtualKeyboardProvider.show();
- } else if (this._rootContentEditable) {
- this._rootContentEditable.inputMode = '';
- }
- }
- hide() {
- if ('hide' in affineVirtualKeyboardProvider) {
- affineVirtualKeyboardProvider.hide();
- } else if (this._rootContentEditable) {
- this._rootContentEditable.inputMode = 'none';
- }
- }
-
static override setup(di: Container) {
super.setup(di);
di.addImpl(BSVirtualKeyboardProvider, provider => {
@@ -125,6 +102,20 @@ function KeyboardToolbarExtension(framework: FrameworkProvider): ExtensionType {
}
}
+ if ('show' in affineVirtualKeyboardProvider) {
+ return class
+ extends BSVirtualKeyboardService
+ implements VirtualKeyboardProviderWithAction
+ {
+ show() {
+ affineVirtualKeyboardProvider.show();
+ }
+ hide() {
+ affineVirtualKeyboardProvider.hide();
+ }
+ };
+ }
+
return BSVirtualKeyboardService;
}