fix(core): improve EdgelessCopilotPanel position (#11814)

Closes: [AF-2101](https://linear.app/affine-design/issue/AF-2101/ai-panel-的输入框menu定位错误,menu-应该出现在输入框下方)

[Screen Recording 2025-04-18 at 20.51.01.mov <span class="graphite__hidden">(uploaded via Graphite)</span> <img class="graphite__hidden" src="https://app.graphite.dev/api/v1/graphite/video/thumbnail/8ypiIKZXudF5a0tIgIzf/67410349-b056-40a7-b1e6-6de5a5137789.mov" />](https://app.graphite.dev/media/video/8ypiIKZXudF5a0tIgIzf/67410349-b056-40a7-b1e6-6de5a5137789.mov)
This commit is contained in:
fundon
2025-04-21 14:08:24 +00:00
parent fd67bdf88b
commit 824e66df58
2 changed files with 31 additions and 27 deletions
@@ -15,14 +15,15 @@ export class EdgelessCopilotPanel extends WithDisposable(LitElement) {
:host {
display: flex;
position: absolute;
max-height: 374px;
}
.edgeless-copilot-panel {
box-sizing: border-box;
padding: 8px 4px 8px 8px;
min-width: 330px;
max-height: 374px;
overflow-y: auto;
overscroll-behavior: contain;
background: ${unsafeCSSVar('--affine-background-overlay-panel-color')};
box-shadow: ${unsafeCSSVar('--affine-overlay-shadow')};
border-radius: 8px;
@@ -11,9 +11,10 @@ import {
import { WidgetComponent, WidgetViewExtension } from '@blocksuite/affine/std';
import { GfxControllerIdentifier } from '@blocksuite/affine/std/gfx';
import {
autoPlacement,
autoUpdate,
computePosition,
flip,
limitShift,
offset,
shift,
size,
@@ -112,41 +113,43 @@ export class EdgelessCopilotWidget extends WidgetComponent<RootBlockModel> {
}
private _updateCopilotPanel(referenceElement: HTMLElement) {
// @TODO: optimize
const viewport = this.gfx.viewport;
const panel = this._copilotPanel;
if (!panel) return;
const originMaxHeight = window.getComputedStyle(panel).maxHeight;
autoUpdate(referenceElement, panel, () => {
computePosition(referenceElement, panel, {
placement: 'bottom-start',
middleware: [
offset({
mainAxis: 4,
}),
flip({
mainAxis: true,
crossAxis: true,
flipAlignment: true,
}),
shift(() => {
const { left, top, width, height } = viewport;
return {
padding: 20,
crossAxis: true,
rootBoundary: {
x: left,
y: top,
width,
height: height - 100,
},
};
offset(4),
autoPlacement({
padding: 10,
allowedPlacements: [
'top-start',
'top-end',
'bottom-start',
'bottom-end',
],
}),
size({
apply: ({ elements }) => {
const { height } = viewport;
elements.floating.style.maxHeight = `${height - 140}px`;
apply: ({ availableHeight }) => {
availableHeight -= 10;
panel.style.maxHeight =
originMaxHeight && originMaxHeight !== 'none'
? `min(${originMaxHeight}, ${availableHeight}px)`
: `${availableHeight}px`;
},
}),
shift({
padding: {
top: 10,
right: 10,
bottom: 150,
left: 10,
},
limiter: limitShift(),
}),
],
})
.then(({ x, y }) => {