fix(editor): virtual keyboard closes unexpectedly when backspace is pressed after a block (#13386)

Close
[AF-2764](https://linear.app/affine-design/issue/AF-2764/移动端没法删除图片和其他非文本block)

#### PR Dependency Tree


* **PR #13386** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Improved virtual keyboard handling on mobile devices to prevent
unexpected keyboard closure during certain editing actions.
* Added new signals for keyboard height and safe area, enhancing UI
responsiveness and adaptability to keyboard state.

* **Refactor**
* Streamlined keyboard toolbar logic for more reliable panel height
calculation and smoother panel open/close transitions.
* Simplified and modernized the approach to toolbar visibility and input
mode restoration.

* **Style**
* Updated keyboard toolbar and panel styling for better positioning and
layout consistency across devices.

* **Bug Fixes**
* Fixed an issue where the virtual keyboard could be incorrectly
reported as visible when a physical keyboard is connected.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
L-Sun
2025-08-01 12:27:45 +08:00
committed by GitHub
parent 3c9fe48c6c
commit 916887e9dc
3 changed files with 32 additions and 27 deletions

View File

@@ -221,7 +221,7 @@ export class AffineKeyboardToolbar extends SignalWatcher(
}
private _renderItems() {
if (document.activeElement !== this.rootComponent)
if (!this.std.event.active$.value)
return html`<div class="item-container"></div>`;
const goPrevToolbarAction = when(

View File

@@ -61,29 +61,26 @@ export class AffineKeyboardToolbarWidget extends WidgetComponent<RootBlockModel>
override connectedCallback(): void {
super.connectedCallback();
const rootComponent = this.block?.rootComponent;
if (rootComponent) {
this.disposables.addFromEvent(rootComponent, 'focus', () => {
this._show$.value = true;
});
this.disposables.addFromEvent(rootComponent, 'blur', () => {
this._show$.value = false;
});
this.disposables.add(
effect(() => {
this._show$.value = this.std.event.active$.value;
})
);
if (this.keyboard.fallback) {
this._initialInputMode = rootComponent.inputMode;
this.disposables.add(() => {
rootComponent.inputMode = this._initialInputMode;
});
this.disposables.add(
effect(() => {
// recover input mode when keyboard toolbar is hidden
if (!this._show$.value) {
rootComponent.inputMode = this._initialInputMode;
}
})
);
}
const rootComponent = this.block?.rootComponent;
if (rootComponent && this.keyboard.fallback) {
this._initialInputMode = rootComponent.inputMode;
this.disposables.add(() => {
rootComponent.inputMode = this._initialInputMode;
});
this.disposables.add(
effect(() => {
// recover input mode when keyboard toolbar is hidden
if (!this._show$.value) {
rootComponent.inputMode = this._initialInputMode;
}
})
);
}
if (this._docTitle) {