mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-30 00:29:46 +08:00
refactor(editor): always show keyboard toolbar in mobile (#13384)
Close [AF-2756](https://linear.app/affine-design/issue/AF-2756/激活输入区的时候,展示toolbar,适配不弹虚拟键盘的场景,比如实体键盘) #### PR Dependency Tree * **PR #13384** 👈 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 by introducing static keyboard height and app tab safe area tracking for more consistent toolbar behavior. * **Bug Fixes** * Enhanced keyboard visibility detection on Android and iOS, especially when a physical keyboard is connected. * **Refactor** * Simplified and streamlined keyboard toolbar logic, including delayed panel closing and refined height calculations. * Removed unused or redundant toolbar closing methods and position management logic. * **Style** * Updated toolbar and panel styles for better positioning and layout consistency. * Adjusted and removed certain mobile-specific padding styles. <!-- end of auto-generated comment: release notes by coderabbit.ai --> #### PR Dependency Tree * **PR #13384** 👈 This tree was auto-generated by [Charcoal](https://github.com/danerwilliams/charcoal)
This commit is contained in:
@@ -4,6 +4,14 @@ import type { ReadonlySignal } from '@preact/signals-core';
|
|||||||
export interface VirtualKeyboardProvider {
|
export interface VirtualKeyboardProvider {
|
||||||
readonly visible$: ReadonlySignal<boolean>;
|
readonly visible$: ReadonlySignal<boolean>;
|
||||||
readonly height$: ReadonlySignal<number>;
|
readonly height$: ReadonlySignal<number>;
|
||||||
|
/**
|
||||||
|
* The static height of the keyboard, it should record the last non-zero height of virtual keyboard
|
||||||
|
*/
|
||||||
|
readonly staticHeight$: ReadonlySignal<number>;
|
||||||
|
/**
|
||||||
|
* The safe area of the app tab, it will be used when the keyboard is open or closed
|
||||||
|
*/
|
||||||
|
readonly appTabSafeArea$: ReadonlySignal<string>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface VirtualKeyboardProviderWithAction
|
export interface VirtualKeyboardProviderWithAction
|
||||||
|
|||||||
@@ -168,10 +168,6 @@ export type KeyboardSubToolbarConfig = {
|
|||||||
export type KeyboardToolbarContext = {
|
export type KeyboardToolbarContext = {
|
||||||
std: BlockStdScope;
|
std: BlockStdScope;
|
||||||
rootComponent: BlockComponent;
|
rootComponent: BlockComponent;
|
||||||
/**
|
|
||||||
* Close tool bar, and blur the focus if blur is true, default is false
|
|
||||||
*/
|
|
||||||
closeToolbar: (blur?: boolean) => void;
|
|
||||||
/**
|
/**
|
||||||
* Close current tool panel and show virtual keyboard
|
* Close current tool panel and show virtual keyboard
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -71,21 +71,18 @@ export class AffineKeyboardToolPanel extends SignalWatcher(
|
|||||||
.map(group => (typeof group === 'function' ? group(this.context) : group))
|
.map(group => (typeof group === 'function' ? group(this.context) : group))
|
||||||
.filter((group): group is KeyboardToolPanelGroup => group !== null);
|
.filter((group): group is KeyboardToolPanelGroup => group !== null);
|
||||||
|
|
||||||
return repeat(
|
return html`<div class="affine-keyboard-tool-panel-container">
|
||||||
groups,
|
${repeat(
|
||||||
group => group.name,
|
groups,
|
||||||
group => this._renderGroup(group)
|
group => group.name,
|
||||||
);
|
group => this._renderGroup(group)
|
||||||
|
)}
|
||||||
|
</div>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override willUpdate(changedProperties: PropertyValues<this>) {
|
protected override willUpdate(changedProperties: PropertyValues<this>) {
|
||||||
if (changedProperties.has('height')) {
|
if (changedProperties.has('height')) {
|
||||||
this.style.height = `${this.height}px`;
|
this.style.height = this.height;
|
||||||
if (this.height === 0) {
|
|
||||||
this.style.padding = '0';
|
|
||||||
} else {
|
|
||||||
this.style.padding = '';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,5 +93,5 @@ export class AffineKeyboardToolPanel extends SignalWatcher(
|
|||||||
accessor context!: KeyboardToolbarContext;
|
accessor context!: KeyboardToolbarContext;
|
||||||
|
|
||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
accessor height = 0;
|
accessor height = '';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import {
|
|||||||
requiredProperties,
|
requiredProperties,
|
||||||
ShadowlessElement,
|
ShadowlessElement,
|
||||||
} from '@blocksuite/std';
|
} from '@blocksuite/std';
|
||||||
import { effect, type Signal, signal, untracked } from '@preact/signals-core';
|
import { effect, type Signal, signal } from '@preact/signals-core';
|
||||||
import { html } from 'lit';
|
import { html } from 'lit';
|
||||||
import { property } from 'lit/decorators.js';
|
import { property } from 'lit/decorators.js';
|
||||||
import { repeat } from 'lit/directives/repeat.js';
|
import { repeat } from 'lit/directives/repeat.js';
|
||||||
@@ -22,7 +22,6 @@ import type {
|
|||||||
KeyboardToolbarItem,
|
KeyboardToolbarItem,
|
||||||
KeyboardToolPanelConfig,
|
KeyboardToolPanelConfig,
|
||||||
} from './config';
|
} from './config';
|
||||||
import { PositionController } from './position-controller';
|
|
||||||
import { keyboardToolbarStyles } from './styles';
|
import { keyboardToolbarStyles } from './styles';
|
||||||
import {
|
import {
|
||||||
isKeyboardSubToolBarConfig,
|
isKeyboardSubToolBarConfig,
|
||||||
@@ -41,10 +40,7 @@ export class AffineKeyboardToolbar extends SignalWatcher(
|
|||||||
) {
|
) {
|
||||||
static override styles = keyboardToolbarStyles;
|
static override styles = keyboardToolbarStyles;
|
||||||
|
|
||||||
/** This field records the panel static height same as the virtual keyboard height */
|
private readonly _expanded$ = signal(false);
|
||||||
panelHeight$ = signal(0);
|
|
||||||
|
|
||||||
positionController = new PositionController(this);
|
|
||||||
|
|
||||||
get std() {
|
get std() {
|
||||||
return this.rootComponent.std;
|
return this.rootComponent.std;
|
||||||
@@ -54,9 +50,31 @@ export class AffineKeyboardToolbar extends SignalWatcher(
|
|||||||
return this._currentPanelIndex$.value !== -1;
|
return this._currentPanelIndex$.value !== -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private get panelHeight() {
|
||||||
|
return this._expanded$.value
|
||||||
|
? `${
|
||||||
|
this.keyboard.staticHeight$.value !== 0
|
||||||
|
? this.keyboard.staticHeight$.value
|
||||||
|
: 330
|
||||||
|
}px`
|
||||||
|
: this.keyboard.appTabSafeArea$.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prevent flickering during keyboard opening
|
||||||
|
*/
|
||||||
|
private _resetPanelIndexTimeoutId: ReturnType<typeof setTimeout> | null =
|
||||||
|
null;
|
||||||
private readonly _closeToolPanel = () => {
|
private readonly _closeToolPanel = () => {
|
||||||
this._currentPanelIndex$.value = -1;
|
|
||||||
if (!this.keyboard.visible$.peek()) this.keyboard.show();
|
if (!this.keyboard.visible$.peek()) this.keyboard.show();
|
||||||
|
|
||||||
|
if (this._resetPanelIndexTimeoutId) {
|
||||||
|
clearTimeout(this._resetPanelIndexTimeoutId);
|
||||||
|
this._resetPanelIndexTimeoutId = null;
|
||||||
|
}
|
||||||
|
this._resetPanelIndexTimeoutId = setTimeout(() => {
|
||||||
|
this._currentPanelIndex$.value = -1;
|
||||||
|
}, 100);
|
||||||
};
|
};
|
||||||
|
|
||||||
private readonly _currentPanelIndex$ = signal(-1);
|
private readonly _currentPanelIndex$ = signal(-1);
|
||||||
@@ -83,6 +101,10 @@ export class AffineKeyboardToolbar extends SignalWatcher(
|
|||||||
if (this._currentPanelIndex$.value === index) {
|
if (this._currentPanelIndex$.value === index) {
|
||||||
this._closeToolPanel();
|
this._closeToolPanel();
|
||||||
} else {
|
} else {
|
||||||
|
if (this._resetPanelIndexTimeoutId) {
|
||||||
|
clearTimeout(this._resetPanelIndexTimeoutId);
|
||||||
|
this._resetPanelIndexTimeoutId = null;
|
||||||
|
}
|
||||||
this._currentPanelIndex$.value = index;
|
this._currentPanelIndex$.value = index;
|
||||||
this.keyboard.hide();
|
this.keyboard.hide();
|
||||||
this._scrollCurrentBlockIntoView();
|
this._scrollCurrentBlockIntoView();
|
||||||
@@ -123,9 +145,6 @@ export class AffineKeyboardToolbar extends SignalWatcher(
|
|||||||
return {
|
return {
|
||||||
std: this.std,
|
std: this.std,
|
||||||
rootComponent: this.rootComponent,
|
rootComponent: this.rootComponent,
|
||||||
closeToolbar: (blur = false) => {
|
|
||||||
this.close(blur);
|
|
||||||
},
|
|
||||||
closeToolPanel: () => {
|
closeToolPanel: () => {
|
||||||
this._closeToolPanel();
|
this._closeToolPanel();
|
||||||
},
|
},
|
||||||
@@ -226,7 +245,15 @@ export class AffineKeyboardToolbar extends SignalWatcher(
|
|||||||
<icon-button
|
<icon-button
|
||||||
size="36px"
|
size="36px"
|
||||||
@click=${() => {
|
@click=${() => {
|
||||||
this.close(true);
|
if (this.keyboard.staticHeight$.value === 0) {
|
||||||
|
this._closeToolPanel();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this.keyboard.visible$.peek()) {
|
||||||
|
this.keyboard.hide();
|
||||||
|
} else {
|
||||||
|
this.keyboard.show();
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
${KeyboardIcon()}
|
${KeyboardIcon()}
|
||||||
@@ -237,6 +264,23 @@ export class AffineKeyboardToolbar extends SignalWatcher(
|
|||||||
override connectedCallback() {
|
override connectedCallback() {
|
||||||
super.connectedCallback();
|
super.connectedCallback();
|
||||||
|
|
||||||
|
// There are two cases that `_expanded$` will be true:
|
||||||
|
// 1. when virtual keyboard is opened, the panel need to be expanded and overlapped by the keyboard,
|
||||||
|
// so that the toolbar will be on the top of the keyboard.
|
||||||
|
// 2. the panel is opened, whether the keyboard is closed or not exists (e.g. a physical keyboard connected)
|
||||||
|
//
|
||||||
|
// There is one case that `_expanded$` will be false:
|
||||||
|
// 1. the panel is closed, and the keyboard is closed, the toolbar will be rendered at the bottom of the viewport
|
||||||
|
this._disposables.add(
|
||||||
|
effect(() => {
|
||||||
|
if (this.keyboard.visible$.value || this.panelOpened) {
|
||||||
|
this._expanded$.value = true;
|
||||||
|
} else {
|
||||||
|
this._expanded$.value = false;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
// prevent editor blur when click item in toolbar
|
// prevent editor blur when click item in toolbar
|
||||||
this.disposables.addFromEvent(this, 'pointerdown', e => {
|
this.disposables.addFromEvent(this, 'pointerdown', e => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@@ -260,15 +304,17 @@ export class AffineKeyboardToolbar extends SignalWatcher(
|
|||||||
if (this.keyboard.visible$.value) {
|
if (this.keyboard.visible$.value) {
|
||||||
this._closeToolPanel();
|
this._closeToolPanel();
|
||||||
}
|
}
|
||||||
// when keyboard is closed and the panel is not opened, we need to close the toolbar,
|
|
||||||
// this usually happens when user close keyboard from system side
|
|
||||||
else if (this.hasUpdated && untracked(() => !this.panelOpened)) {
|
|
||||||
this.close(true);
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
this._watchAutoShow();
|
this._watchAutoShow();
|
||||||
|
|
||||||
|
this.disposables.add(() => {
|
||||||
|
if (this._resetPanelIndexTimeoutId) {
|
||||||
|
clearTimeout(this._resetPanelIndexTimeoutId);
|
||||||
|
this._resetPanelIndexTimeoutId = null;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private _watchAutoShow() {
|
private _watchAutoShow() {
|
||||||
@@ -331,7 +377,7 @@ export class AffineKeyboardToolbar extends SignalWatcher(
|
|||||||
<affine-keyboard-tool-panel
|
<affine-keyboard-tool-panel
|
||||||
.config=${this._currentPanelConfig}
|
.config=${this._currentPanelConfig}
|
||||||
.context=${this._context}
|
.context=${this._context}
|
||||||
.height=${this.panelHeight$.value}
|
.height=${this.panelHeight}
|
||||||
></affine-keyboard-tool-panel>
|
></affine-keyboard-tool-panel>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
@@ -339,9 +385,6 @@ export class AffineKeyboardToolbar extends SignalWatcher(
|
|||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
accessor keyboard!: VirtualKeyboardProviderWithAction;
|
accessor keyboard!: VirtualKeyboardProviderWithAction;
|
||||||
|
|
||||||
@property({ attribute: false })
|
|
||||||
accessor close: (blur: boolean) => void = () => {};
|
|
||||||
|
|
||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
accessor config!: KeyboardToolbarConfig;
|
accessor config!: KeyboardToolbarConfig;
|
||||||
|
|
||||||
|
|||||||
@@ -1,42 +0,0 @@
|
|||||||
import { type VirtualKeyboardProvider } from '@blocksuite/affine-shared/services';
|
|
||||||
import { DisposableGroup } from '@blocksuite/global/disposable';
|
|
||||||
import type { BlockStdScope, ShadowlessElement } from '@blocksuite/std';
|
|
||||||
import { effect, type Signal } from '@preact/signals-core';
|
|
||||||
import type { ReactiveController, ReactiveControllerHost } from 'lit';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This controller is used to control the keyboard toolbar position
|
|
||||||
*/
|
|
||||||
export class PositionController implements ReactiveController {
|
|
||||||
private readonly _disposables = new DisposableGroup();
|
|
||||||
|
|
||||||
host: ReactiveControllerHost &
|
|
||||||
ShadowlessElement & {
|
|
||||||
std: BlockStdScope;
|
|
||||||
panelHeight$: Signal<number>;
|
|
||||||
keyboard: VirtualKeyboardProvider;
|
|
||||||
panelOpened: boolean;
|
|
||||||
};
|
|
||||||
|
|
||||||
constructor(host: PositionController['host']) {
|
|
||||||
(this.host = host).addController(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
hostConnected() {
|
|
||||||
const { keyboard } = this.host;
|
|
||||||
|
|
||||||
this._disposables.add(
|
|
||||||
effect(() => {
|
|
||||||
if (keyboard.visible$.value) {
|
|
||||||
this.host.panelHeight$.value = keyboard.height$.value;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
this.host.style.bottom = '0px';
|
|
||||||
}
|
|
||||||
|
|
||||||
hostDisconnected() {
|
|
||||||
this._disposables.dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -7,6 +7,7 @@ export const keyboardToolbarStyles = css`
|
|||||||
position: fixed;
|
position: fixed;
|
||||||
display: block;
|
display: block;
|
||||||
width: 100vw;
|
width: 100vw;
|
||||||
|
bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.keyboard-toolbar {
|
.keyboard-toolbar {
|
||||||
@@ -60,14 +61,18 @@ export const keyboardToolbarStyles = css`
|
|||||||
|
|
||||||
export const keyboardToolPanelStyles = css`
|
export const keyboardToolPanelStyles = css`
|
||||||
affine-keyboard-tool-panel {
|
affine-keyboard-tool-panel {
|
||||||
|
display: block;
|
||||||
|
overflow-y: auto;
|
||||||
|
box-sizing: border-box;
|
||||||
|
background-color: ${unsafeCSSVarV2('layer/background/primary')};
|
||||||
|
}
|
||||||
|
|
||||||
|
.affine-keyboard-tool-panel-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 24px;
|
gap: 24px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 16px 4px 8px 8px;
|
padding: 16px 4px 8px 8px;
|
||||||
overflow-y: auto;
|
|
||||||
box-sizing: border-box;
|
|
||||||
background-color: ${unsafeCSSVarV2('layer/background/primary')};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
${scrollbarStyle('affine-keyboard-tool-panel')}
|
${scrollbarStyle('affine-keyboard-tool-panel')}
|
||||||
|
|||||||
@@ -20,18 +20,6 @@ import {
|
|||||||
export const AFFINE_KEYBOARD_TOOLBAR_WIDGET = 'affine-keyboard-toolbar-widget';
|
export const AFFINE_KEYBOARD_TOOLBAR_WIDGET = 'affine-keyboard-toolbar-widget';
|
||||||
|
|
||||||
export class AffineKeyboardToolbarWidget extends WidgetComponent<RootBlockModel> {
|
export class AffineKeyboardToolbarWidget extends WidgetComponent<RootBlockModel> {
|
||||||
private readonly _close = (blur: boolean) => {
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this._show$.value = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
private readonly _show$ = signal(false);
|
private readonly _show$ = signal(false);
|
||||||
|
|
||||||
private _initialInputMode: string = '';
|
private _initialInputMode: string = '';
|
||||||
@@ -129,7 +117,6 @@ export class AffineKeyboardToolbarWidget extends WidgetComponent<RootBlockModel>
|
|||||||
.keyboard=${this.keyboard}
|
.keyboard=${this.keyboard}
|
||||||
.config=${this.config}
|
.config=${this.config}
|
||||||
.rootComponent=${this.block.rootComponent}
|
.rootComponent=${this.block.rootComponent}
|
||||||
.close=${this._close}
|
|
||||||
></affine-keyboard-toolbar>`}
|
></affine-keyboard-toolbar>`}
|
||||||
></blocksuite-portal>`;
|
></blocksuite-portal>`;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -120,7 +120,9 @@ framework.impl(VirtualKeyboardProvider, {
|
|||||||
const navBarHeight = (await AffineTheme.getSystemNavBarHeight())
|
const navBarHeight = (await AffineTheme.getSystemNavBarHeight())
|
||||||
.height;
|
.height;
|
||||||
callback({
|
callback({
|
||||||
visible: true,
|
// When an physical keyboard is connected, the virtual keyboard height is 0,
|
||||||
|
// even though the `keyboardWillShow` event is still triggered.
|
||||||
|
visible: info.keyboardHeight !== 0,
|
||||||
height: info.keyboardHeight - navBarHeight,
|
height: info.keyboardHeight - navBarHeight,
|
||||||
});
|
});
|
||||||
})().catch(console.error);
|
})().catch(console.error);
|
||||||
|
|||||||
@@ -121,9 +121,9 @@ framework.impl(VirtualKeyboardProvider, {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Promise.all([
|
Promise.all([
|
||||||
Keyboard.addListener('keyboardDidShow', info => {
|
Keyboard.addListener('keyboardWillShow', info => {
|
||||||
callback({
|
callback({
|
||||||
visible: true,
|
visible: info.keyboardHeight !== 0,
|
||||||
height: info.keyboardHeight,
|
height: info.keyboardHeight,
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
|
|||||||
+10
@@ -1,4 +1,5 @@
|
|||||||
import { VirtualKeyboardProvider } from '@affine/core/mobile/modules/virtual-keyboard';
|
import { VirtualKeyboardProvider } from '@affine/core/mobile/modules/virtual-keyboard';
|
||||||
|
import { globalVars } from '@affine/core/mobile/styles/variables.css';
|
||||||
import type { Container } from '@blocksuite/affine/global/di';
|
import type { Container } from '@blocksuite/affine/global/di';
|
||||||
import { DisposableGroup } from '@blocksuite/affine/global/disposable';
|
import { DisposableGroup } from '@blocksuite/affine/global/disposable';
|
||||||
import {
|
import {
|
||||||
@@ -29,6 +30,12 @@ export function KeyboardToolbarExtension(
|
|||||||
// eslint-disable-next-line rxjs/finnish
|
// eslint-disable-next-line rxjs/finnish
|
||||||
readonly height$ = signal(0);
|
readonly height$ = signal(0);
|
||||||
|
|
||||||
|
// eslint-disable-next-line rxjs/finnish
|
||||||
|
readonly staticHeight$ = signal(0);
|
||||||
|
|
||||||
|
// eslint-disable-next-line rxjs/finnish
|
||||||
|
readonly appTabSafeArea$ = signal(`calc(${globalVars.appTabSafeArea})`);
|
||||||
|
|
||||||
static override setup(di: Container) {
|
static override setup(di: Container) {
|
||||||
super.setup(di);
|
super.setup(di);
|
||||||
di.addImpl(BSVirtualKeyboardProvider, provider => {
|
di.addImpl(BSVirtualKeyboardProvider, provider => {
|
||||||
@@ -40,6 +47,9 @@ export function KeyboardToolbarExtension(
|
|||||||
this._disposables.add(
|
this._disposables.add(
|
||||||
affineVirtualKeyboardProvider.onChange(({ visible, height }) => {
|
affineVirtualKeyboardProvider.onChange(({ visible, height }) => {
|
||||||
batch(() => {
|
batch(() => {
|
||||||
|
if (visible && this.staticHeight$.peek() !== height) {
|
||||||
|
this.staticHeight$.value = height;
|
||||||
|
}
|
||||||
this.visible$.value = visible;
|
this.visible$.value = visible;
|
||||||
this.height$.value = height;
|
this.height$.value = height;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -23,9 +23,6 @@ globalStyle('body:has(>#app-tabs):not(:has(affine-keyboard-toolbar))', {
|
|||||||
globalStyle('body:has(affine-keyboard-toolbar)', {
|
globalStyle('body:has(affine-keyboard-toolbar)', {
|
||||||
paddingBottom: `calc(${globalVars.appKeyboardStaticHeight} + 46px)`,
|
paddingBottom: `calc(${globalVars.appKeyboardStaticHeight} + 46px)`,
|
||||||
});
|
});
|
||||||
globalStyle('body:has(>#app-tabs) affine-keyboard-tool-panel', {
|
|
||||||
paddingBottom: `calc(${globalVars.appTabSafeArea} + 8px)`,
|
|
||||||
});
|
|
||||||
globalStyle('body:has(>#app-tabs) edgeless-toolbar-widget', {
|
globalStyle('body:has(>#app-tabs) edgeless-toolbar-widget', {
|
||||||
bottom: globalVars.appTabSafeArea,
|
bottom: globalVars.appTabSafeArea,
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user