From b53b2acfe387ca3425191171e00a4fede6403a27 Mon Sep 17 00:00:00 2001 From: L-Sun Date: Thu, 3 Apr 2025 01:51:57 +0000 Subject: [PATCH] fix(ios): mobile modal occlusion issues (#11427) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Close [BS-2925](https://linear.app/affine-design/issue/BS-2925/移动端-dialog-遮挡相关) --- .../src/context-menu/menu-renderer.ts | 1 + .../embed-card-create-modal.ts | 21 +++++++++++++++---- .../components/src/embed-card-modal/styles.ts | 11 ++++++++++ .../component/src/ui/menu/menu.types.ts | 3 ++- .../component/src/ui/menu/mobile/root.tsx | 2 ++ .../mobile/components/sign-in/layout.css.ts | 4 +++- .../dialogs/selectors/date-selector.tsx | 13 ++++++++++++ 7 files changed, 49 insertions(+), 6 deletions(-) diff --git a/blocksuite/affine/components/src/context-menu/menu-renderer.ts b/blocksuite/affine/components/src/context-menu/menu-renderer.ts index a84a069e3e..9976f76f30 100644 --- a/blocksuite/affine/components/src/context-menu/menu-renderer.ts +++ b/blocksuite/affine/components/src/context-menu/menu-renderer.ts @@ -490,6 +490,7 @@ export type MenuHandler = { const popMobileMenu = (options: MenuOptions): MenuHandler => { const model = createModal(document.body); + model.style.position = 'fixed'; const menu = new Menu({ ...options, onClose: () => { diff --git a/blocksuite/affine/components/src/embed-card-modal/embed-card-create-modal.ts b/blocksuite/affine/components/src/embed-card-modal/embed-card-create-modal.ts index 29a09dd47c..63ab1c0d12 100644 --- a/blocksuite/affine/components/src/embed-card-modal/embed-card-create-modal.ts +++ b/blocksuite/affine/components/src/embed-card-modal/embed-card-create-modal.ts @@ -1,6 +1,9 @@ -import { EmbedOptionProvider } from '@blocksuite/affine-shared/services'; +import { + EmbedOptionProvider, + VirtualKeyboardProvider, +} from '@blocksuite/affine-shared/services'; import { isValidUrl, stopPropagation } from '@blocksuite/affine-shared/utils'; -import { WithDisposable } from '@blocksuite/global/lit'; +import { SignalWatcher, WithDisposable } from '@blocksuite/global/lit'; import type { EditorHost } from '@blocksuite/std'; import { ShadowlessElement } from '@blocksuite/std'; import { GfxControllerIdentifier } from '@blocksuite/std/gfx'; @@ -8,11 +11,14 @@ import type { BlockModel } from '@blocksuite/store'; import { html } from 'lit'; import { property, query, state } from 'lit/decorators.js'; import { classMap } from 'lit/directives/class-map.js'; +import { styleMap } from 'lit-html/directives/style-map.js'; import { toast } from '../toast'; import { embedCardModalStyles } from './styles.js'; -export class EmbedCardCreateModal extends WithDisposable(ShadowlessElement) { +export class EmbedCardCreateModal extends SignalWatcher( + WithDisposable(ShadowlessElement) +) { static override styles = embedCardModalStyles; private readonly _onCancel = () => { @@ -98,7 +104,14 @@ export class EmbedCardCreateModal extends WithDisposable(ShadowlessElement) { } override render() { - return html`
+ const keyboard = this.host.std.getOptional(VirtualKeyboardProvider); + const style = styleMap({ + height: keyboard?.visible$.value + ? `calc(100% - ${keyboard.height$.value}px)` + : undefined, + }); + + return html`
diff --git a/blocksuite/affine/components/src/embed-card-modal/styles.ts b/blocksuite/affine/components/src/embed-card-modal/styles.ts index 89b2e7bbc2..b63831b67a 100644 --- a/blocksuite/affine/components/src/embed-card-modal/styles.ts +++ b/blocksuite/affine/components/src/embed-card-modal/styles.ts @@ -2,6 +2,17 @@ import { fontXSStyle, panelBaseStyle } from '@blocksuite/affine-shared/styles'; import { css } from 'lit'; export const embedCardModalStyles = css` + .embed-card-modal { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + z-index: 1000; + height: 100%; + transition: height 0.3s ease-in-out; + } + .embed-card-modal-mask { position: absolute; left: 0; diff --git a/packages/frontend/component/src/ui/menu/menu.types.ts b/packages/frontend/component/src/ui/menu/menu.types.ts index 4db5f868dd..7923e2f992 100644 --- a/packages/frontend/component/src/ui/menu/menu.types.ts +++ b/packages/frontend/component/src/ui/menu/menu.types.ts @@ -6,7 +6,7 @@ import type { DropdownMenuSubContentProps, DropdownMenuSubProps, } from '@radix-ui/react-dropdown-menu'; -import type { ReactNode } from 'react'; +import type { CSSProperties, ReactNode } from 'react'; export interface MenuProps { children: ReactNode; @@ -15,6 +15,7 @@ export interface MenuProps { portalOptions?: Omit; rootOptions?: Omit; contentOptions?: Omit; + contentWrapperStyle?: CSSProperties; noPortal?: boolean; } diff --git a/packages/frontend/component/src/ui/menu/mobile/root.tsx b/packages/frontend/component/src/ui/menu/mobile/root.tsx index ca56d59fa6..1e15bfe230 100644 --- a/packages/frontend/component/src/ui/menu/mobile/root.tsx +++ b/packages/frontend/component/src/ui/menu/mobile/root.tsx @@ -32,6 +32,7 @@ export const MobileMenu = ({ ...otherContentOptions } = {}, + contentWrapperStyle, rootOptions, }: MenuProps) => { const [subMenus, setSubMenus] = useState([]); @@ -131,6 +132,7 @@ export const MobileMenu = ({ className: clsx(className, styles.mobileMenuModal), ...otherContentOptions, }} + contentWrapperStyle={contentWrapperStyle} disableAutoFocus={true} >
) => { const [selectedDate, setSelectedDate] = useState(); + const keyboardService = useService(VirtualKeyboardService); + const keyboardHeight = useLiveData(keyboardService.height$); + const keyboardVisible = useLiveData(keyboardService.visible$); const t = useI18n(); @@ -44,6 +50,13 @@ export const DateSelectorDialog = ({ padding: '15px 20px', }, }} + contentWrapperStyle={ + keyboardVisible + ? { + paddingBottom: `calc(${keyboardHeight}px + 12px)`, + } + : undefined + } items={