From 824e66df58446dbe8316405436370c947268611f Mon Sep 17 00:00:00 2001 From: fundon Date: Mon, 21 Apr 2025 14:08:24 +0000 Subject: [PATCH] fix(core): improve EdgelessCopilotPanel position (#11814) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 (uploaded via Graphite) ](https://app.graphite.dev/media/video/8ypiIKZXudF5a0tIgIzf/67410349-b056-40a7-b1e6-6de5a5137789.mov) --- .../widgets/edgeless-copilot-panel/index.ts | 3 +- .../ai/widgets/edgeless-copilot/index.ts | 55 ++++++++++--------- 2 files changed, 31 insertions(+), 27 deletions(-) diff --git a/packages/frontend/core/src/blocksuite/ai/widgets/edgeless-copilot-panel/index.ts b/packages/frontend/core/src/blocksuite/ai/widgets/edgeless-copilot-panel/index.ts index 8b1914c748..cd91f40069 100644 --- a/packages/frontend/core/src/blocksuite/ai/widgets/edgeless-copilot-panel/index.ts +++ b/packages/frontend/core/src/blocksuite/ai/widgets/edgeless-copilot-panel/index.ts @@ -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; diff --git a/packages/frontend/core/src/blocksuite/ai/widgets/edgeless-copilot/index.ts b/packages/frontend/core/src/blocksuite/ai/widgets/edgeless-copilot/index.ts index d178b644b7..1e3a463d9b 100644 --- a/packages/frontend/core/src/blocksuite/ai/widgets/edgeless-copilot/index.ts +++ b/packages/frontend/core/src/blocksuite/ai/widgets/edgeless-copilot/index.ts @@ -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 { } 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 }) => {