From 71c82e1b1e2c45788c739bb8241414f18273108c Mon Sep 17 00:00:00 2001 From: trevor-signal <131492920+trevor-signal@users.noreply.github.com> Date: Tue, 6 Jan 2026 13:04:09 -0500 Subject: [PATCH] Ensure composition input is focused when clicking to edit or reply to message --- ts/axo/AxoContextMenu.dom.tsx | 1 + ts/axo/AxoDropdownMenu.dom.tsx | 4 +++ ts/axo/_internal/AxoBaseMenu.dom.tsx | 1 + .../conversation/MessageContextMenu.dom.tsx | 32 ++++++++++++++++--- ts/util/lint/exceptions.json | 7 ++++ 5 files changed, 40 insertions(+), 5 deletions(-) diff --git a/ts/axo/AxoContextMenu.dom.tsx b/ts/axo/AxoContextMenu.dom.tsx index acbec52106..70f6fe0464 100644 --- a/ts/axo/AxoContextMenu.dom.tsx +++ b/ts/axo/AxoContextMenu.dom.tsx @@ -238,6 +238,7 @@ export namespace AxoContextMenu { className={AxoBaseMenu.menuContentStyles} alignOffset={-6} collisionPadding={6} + onCloseAutoFocus={props.onCloseAutoFocus} > {props.children} diff --git a/ts/axo/AxoDropdownMenu.dom.tsx b/ts/axo/AxoDropdownMenu.dom.tsx index 30e0123b4c..584013e99e 100644 --- a/ts/axo/AxoDropdownMenu.dom.tsx +++ b/ts/axo/AxoDropdownMenu.dom.tsx @@ -190,6 +190,7 @@ export namespace AxoDropdownMenu { */ export const Content: FC = memo(props => { const { context, labelId, descriptionId } = useCreateAriaLabellingContext(); + const { open } = useStrictContext(RootContext); return ( @@ -200,6 +201,9 @@ export namespace AxoDropdownMenu { className={AxoBaseMenu.menuContentStyles} aria-labelledby={labelId} aria-describedby={descriptionId} + onCloseAutoFocus={props.onCloseAutoFocus} + // @ts-expect-error -- React/TS doesn't know about inert + inert={open ? undefined : 'true'} > {props.children} diff --git a/ts/axo/_internal/AxoBaseMenu.dom.tsx b/ts/axo/_internal/AxoBaseMenu.dom.tsx index c783c1d723..1c7d73c3bb 100644 --- a/ts/axo/_internal/AxoBaseMenu.dom.tsx +++ b/ts/axo/_internal/AxoBaseMenu.dom.tsx @@ -205,6 +205,7 @@ export namespace AxoBaseMenu { */ export type MenuContentProps = Readonly<{ + onCloseAutoFocus?: (e: Event) => void; children: ReactNode; }>; diff --git a/ts/components/conversation/MessageContextMenu.dom.tsx b/ts/components/conversation/MessageContextMenu.dom.tsx index 5d08287c1d..26c9142257 100644 --- a/ts/components/conversation/MessageContextMenu.dom.tsx +++ b/ts/components/conversation/MessageContextMenu.dom.tsx @@ -1,7 +1,7 @@ // Copyright 2023 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only -import React, { type ReactNode } from 'react'; +import React, { useRef, type ReactNode } from 'react'; import type { LocalizerType } from '../../types/I18N.std.js'; import { AxoMenuBuilder } from '../../axo/AxoMenuBuilder.dom.js'; @@ -49,13 +49,21 @@ export function MessageContextMenu({ onPinMessage, onUnpinMessage, children, -}: MessageContextMenuProps): React.JSX.Element { +}: MessageContextMenuProps): JSX.Element { + const shouldReturnFocusToTrigger = useRef(true); + return ( {children} - + { + if (!shouldReturnFocusToTrigger.current) { + e.preventDefault(); + } + }} + > {shouldShowAdditional && ( <> {onDownload && ( @@ -64,7 +72,14 @@ export function MessageContextMenu({ )} {onReplyToMessage && ( - + { + // onReplyToMessage will focus the quill input + shouldReturnFocusToTrigger.current = false; + onReplyToMessage(); + }} + > {i18n('icu:MessageContextMenu__reply')} )} @@ -86,7 +101,14 @@ export function MessageContextMenu({ )} {onEdit && ( - + { + // onEdit will focus the quill input + shouldReturnFocusToTrigger.current = false; + onEdit(); + }} + > {i18n('icu:edit')} )} diff --git a/ts/util/lint/exceptions.json b/ts/util/lint/exceptions.json index 984e0073b3..907b39be68 100644 --- a/ts/util/lint/exceptions.json +++ b/ts/util/lint/exceptions.json @@ -2370,5 +2370,12 @@ "line": " message.innerHTML = window.SignalContext.i18n('icu:optimizingApplication');", "reasonCategory": "usageTrusted", "updated": "2021-09-17T21:02:59.414Z" + }, + { + "rule": "React-useRef", + "path": "ts/components/conversation/MessageContextMenu.dom.tsx", + "line": " const shouldReturnFocusToTrigger = useRef(true);", + "reasonCategory": "usageTrusted", + "updated": "2025-12-19T16:03:53.849Z" } ]