From 723d6af54ed75c3349a44aa5f3e5e3117868c2bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A8=8B=E5=BA=8F=E5=91=98=E9=98=BF=E6=B1=9F=28Relakkes?= =?UTF-8?q?=29?= Date: Fri, 9 Oct 2026 13:08:19 +0800 Subject: [PATCH] fix(desktop): keep the settings permission menu inside the window The default-permission menu in Settings > General grew rightwards from the trigger's left edge. The trigger sits at the end of the row, so the 340px menu ran past the content column and was clipped. Add a menuAlign option and right-align the menu there; composer callers keep the left alignment. Fixes #1474 --- .../controls/PermissionModeSelector.test.tsx | 20 ++++++++++ .../controls/PermissionModeSelector.tsx | 10 ++++- .../src/pages/settings/GeneralSettings.tsx | 1 + .../GeneralSettingsPermissionMenu.test.tsx | 38 +++++++++++++++++++ 4 files changed, 67 insertions(+), 2 deletions(-) create mode 100644 desktop/src/pages/settings/GeneralSettingsPermissionMenu.test.tsx diff --git a/desktop/src/components/controls/PermissionModeSelector.test.tsx b/desktop/src/components/controls/PermissionModeSelector.test.tsx index 67659eef..ed241388 100644 --- a/desktop/src/components/controls/PermissionModeSelector.test.tsx +++ b/desktop/src/components/controls/PermissionModeSelector.test.tsx @@ -479,6 +479,26 @@ describe('PermissionModeSelector', () => { expect(onChange).toHaveBeenCalledWith('acceptEdits') }) + it('opens the desktop menu from the trigger start edge by default', () => { + render() + + fireEvent.click(screen.getByRole('button', { name: 'Ask permissions' })) + + const menu = screen.getByRole('menu') + expect(menu).toHaveClass('left-0') + expect(menu).not.toHaveClass('right-0') + }) + + it('anchors the desktop menu to the trigger end edge when asked to align right', () => { + render() + + fireEvent.click(screen.getByRole('button', { name: 'Ask permissions' })) + + const menu = screen.getByRole('menu') + expect(menu).toHaveClass('right-0') + expect(menu).not.toHaveClass('left-0') + }) + it('shows Auto beside the existing permission modes', () => { render() diff --git a/desktop/src/components/controls/PermissionModeSelector.tsx b/desktop/src/components/controls/PermissionModeSelector.tsx index 9fcac395..91b929fa 100644 --- a/desktop/src/components/controls/PermissionModeSelector.tsx +++ b/desktop/src/components/controls/PermissionModeSelector.tsx @@ -73,6 +73,11 @@ type Props = { */ trigger?: 'chip' | 'elevatedOnly' menuPlacement?: 'top' | 'bottom' + /** + * Which trigger edge the desktop menu lines up with. `right` keeps it inside + * the container when the trigger sits at the end of a row, as in Settings. + */ + menuAlign?: 'left' | 'right' /** Controlled mode: override current value */ value?: PermissionMode /** Controlled mode: called on change instead of updating global store */ @@ -80,7 +85,7 @@ type Props = { } export const PermissionModeSelector = forwardRef(function PermissionModeSelector( - { sessionId, workDir: workDirProp, compact = false, trigger = 'chip', menuPlacement = 'top', value, onChange }: Props = {}, + { sessionId, workDir: workDirProp, compact = false, trigger = 'chip', menuPlacement = 'top', menuAlign = 'left', value, onChange }: Props = {}, handleRef, ) { const t = useTranslation() @@ -175,6 +180,7 @@ export const PermissionModeSelector = forwardRef ) : ( -