mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-18 14:56:59 +08:00
fix(editor): centerize iframe modal in mobile (#13073)
Close [BS-3160](https://linear.app/affine-design/issue/BS-3160/新的-embed-输入的-sheet-没有弹起来) #### PR Dependency Tree * **PR #13073** 👈 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 * **Bug Fixes** * Improved popup positioning and responsiveness when using virtual keyboards, ensuring popups remain visible and correctly placed above the keyboard. * Standardized how popups and overlays are created and referenced throughout the app, reducing inconsistencies and potential display issues. * Enhanced stability of date picker, AI panels, and slash menu popovers by refining how their elements are managed and updated. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -11,6 +11,7 @@ import {
|
|||||||
type IframeOptions,
|
type IframeOptions,
|
||||||
LinkPreviewServiceIdentifier,
|
LinkPreviewServiceIdentifier,
|
||||||
NotificationProvider,
|
NotificationProvider,
|
||||||
|
VirtualKeyboardProvider,
|
||||||
} from '@blocksuite/affine-shared/services';
|
} from '@blocksuite/affine-shared/services';
|
||||||
import { matchModels } from '@blocksuite/affine-shared/utils';
|
import { matchModels } from '@blocksuite/affine-shared/utils';
|
||||||
import { BlockSuiteError, ErrorCode } from '@blocksuite/global/exceptions';
|
import { BlockSuiteError, ErrorCode } from '@blocksuite/global/exceptions';
|
||||||
@@ -213,9 +214,33 @@ export class EmbedIframeBlockComponent extends CaptionedBlockComponent<EmbedIfra
|
|||||||
this._linkInputAbortController.abort();
|
this._linkInputAbortController.abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const keyboard = this.host.std.getOptional(VirtualKeyboardProvider);
|
||||||
|
const computePosition = keyboard
|
||||||
|
? {
|
||||||
|
referenceElement: document.body,
|
||||||
|
placement: 'top' as const,
|
||||||
|
middleware: [
|
||||||
|
offset(({ rects }) => ({
|
||||||
|
mainAxis:
|
||||||
|
-rects.floating.height -
|
||||||
|
(window.innerHeight -
|
||||||
|
rects.floating.height -
|
||||||
|
keyboard.height$.value) /
|
||||||
|
2,
|
||||||
|
})),
|
||||||
|
],
|
||||||
|
autoUpdate: { animationFrame: true },
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
referenceElement: this._blockContainer,
|
||||||
|
placement: 'bottom' as const,
|
||||||
|
middleware: [flip(), offset(LINK_CREATE_POPUP_OFFSET), shift()],
|
||||||
|
autoUpdate: { animationFrame: true },
|
||||||
|
};
|
||||||
|
|
||||||
this._linkInputAbortController = new AbortController();
|
this._linkInputAbortController = new AbortController();
|
||||||
|
|
||||||
createLitPortal({
|
const { update } = createLitPortal({
|
||||||
template: html`<embed-iframe-link-input-popup
|
template: html`<embed-iframe-link-input-popup
|
||||||
.model=${this.model}
|
.model=${this.model}
|
||||||
.abortController=${this._linkInputAbortController}
|
.abortController=${this._linkInputAbortController}
|
||||||
@@ -224,15 +249,19 @@ export class EmbedIframeBlockComponent extends CaptionedBlockComponent<EmbedIfra
|
|||||||
.options=${options}
|
.options=${options}
|
||||||
></embed-iframe-link-input-popup>`,
|
></embed-iframe-link-input-popup>`,
|
||||||
container: document.body,
|
container: document.body,
|
||||||
computePosition: {
|
computePosition,
|
||||||
referenceElement: this._blockContainer,
|
|
||||||
placement: 'bottom',
|
|
||||||
middleware: [flip(), offset(LINK_CREATE_POPUP_OFFSET), shift()],
|
|
||||||
autoUpdate: { animationFrame: true },
|
|
||||||
},
|
|
||||||
abortController: this._linkInputAbortController,
|
abortController: this._linkInputAbortController,
|
||||||
closeOnClickAway: true,
|
closeOnClickAway: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (keyboard) {
|
||||||
|
this._linkInputAbortController.signal.addEventListener(
|
||||||
|
'abort',
|
||||||
|
keyboard.height$.subscribe(() => {
|
||||||
|
update();
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ export class LatexBlockComponent extends CaptionedBlockComponent<LatexBlockModel
|
|||||||
|
|
||||||
this.selection.setGroup('note', []);
|
this.selection.setGroup('note', []);
|
||||||
|
|
||||||
const portal = createLitPortal({
|
const { portal } = createLitPortal({
|
||||||
template: html`<latex-editor-menu
|
template: html`<latex-editor-menu
|
||||||
.std=${this.std}
|
.std=${this.std}
|
||||||
.latexSignal=${this.model.props.latex$}
|
.latexSignal=${this.model.props.latex$}
|
||||||
|
|||||||
@@ -179,7 +179,7 @@ export class HoverController implements ReactiveController {
|
|||||||
this._portal = createLitPortal({
|
this._portal = createLitPortal({
|
||||||
...portalOptions,
|
...portalOptions,
|
||||||
abortController: this._abortController,
|
abortController: this._abortController,
|
||||||
});
|
}).portal;
|
||||||
|
|
||||||
const transition = this._hoverOptions.transition;
|
const transition = this._hoverOptions.transition;
|
||||||
if (transition) {
|
if (transition) {
|
||||||
|
|||||||
@@ -161,7 +161,7 @@ export function createLitPortal({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!positionConfigOrFn) {
|
if (!positionConfigOrFn) {
|
||||||
return portalRoot;
|
return { portal: portalRoot, update: () => {} };
|
||||||
}
|
}
|
||||||
|
|
||||||
const visibility = portalRoot.style.visibility;
|
const visibility = portalRoot.style.visibility;
|
||||||
@@ -221,5 +221,5 @@ export function createLitPortal({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return portalRoot;
|
return { portal: portalRoot, update };
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ export class DateCell extends BaseCellRenderer<number, number> {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
const root = createLitPortal({
|
const { portal } = createLitPortal({
|
||||||
abortController,
|
abortController,
|
||||||
closeOnClickAway: true,
|
closeOnClickAway: true,
|
||||||
computePosition: {
|
computePosition: {
|
||||||
@@ -107,7 +107,7 @@ export class DateCell extends BaseCellRenderer<number, number> {
|
|||||||
// for now the slide-layout-modal's z-index is `1001`
|
// for now the slide-layout-modal's z-index is `1001`
|
||||||
// the z-index of popover should be higher than it
|
// the z-index of popover should be higher than it
|
||||||
// root.style.zIndex = 'var(--affine-z-index-popover)';
|
// root.style.zIndex = 'var(--affine-z-index-popover)';
|
||||||
root.style.zIndex = '1002';
|
portal.style.zIndex = '1002';
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -190,7 +190,7 @@ export class AffineLatexNode extends SignalWatcher(
|
|||||||
|
|
||||||
blockComponent.selection.setGroup('note', []);
|
blockComponent.selection.setGroup('note', []);
|
||||||
|
|
||||||
const portal = createLitPortal({
|
const { portal } = createLitPortal({
|
||||||
template: html`<latex-editor-menu
|
template: html`<latex-editor-menu
|
||||||
.std=${this.std}
|
.std=${this.std}
|
||||||
.latexSignal=${this.latexEditorSignal}
|
.latexSignal=${this.latexEditorSignal}
|
||||||
|
|||||||
@@ -378,7 +378,7 @@ export class InnerSlashMenu extends WithDisposable(LitElement) {
|
|||||||
this._closeSubMenu();
|
this._closeSubMenu();
|
||||||
});
|
});
|
||||||
|
|
||||||
const subMenuElement = createLitPortal({
|
const { portal: subMenuElement } = createLitPortal({
|
||||||
shadowDom: false,
|
shadowDom: false,
|
||||||
template: html`<inner-slash-menu
|
template: html`<inner-slash-menu
|
||||||
.context=${this.context}
|
.context=${this.context}
|
||||||
|
|||||||
@@ -305,6 +305,6 @@ export function handleInlineAskAIAction(
|
|||||||
},
|
},
|
||||||
abortController: abortController,
|
abortController: abortController,
|
||||||
closeOnClickAway: true,
|
closeOnClickAway: true,
|
||||||
});
|
}).portal;
|
||||||
}, 0);
|
}, 0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ export class AskAIToolbarButton extends WithDisposable(LitElement) {
|
|||||||
},
|
},
|
||||||
abortController: this._abortController,
|
abortController: this._abortController,
|
||||||
closeOnClickAway: true,
|
closeOnClickAway: true,
|
||||||
});
|
}).portal;
|
||||||
};
|
};
|
||||||
|
|
||||||
private readonly _generateAnswer: AffineAIPanelWidgetConfig['generateAnswer'] =
|
private readonly _generateAnswer: AffineAIPanelWidgetConfig['generateAnswer'] =
|
||||||
|
|||||||
Reference in New Issue
Block a user