From 5470e25bb075a738092cd3adcb486e10a6697f1c Mon Sep 17 00:00:00 2001 From: Jared Vititoe Date: Fri, 19 Jun 2026 20:41:46 -0400 Subject: [PATCH] fix(ui): report category dropdown uses folds menu, not native select (N56) Extract a shared ReportCategorySelect: folds Button trigger + PopOut + FocusTrap + Menu + MenuItem (escape + arrow-key nav, like OrderButton), replacing the OS-styled native ` Instead of folds `Chip`+`PopOut`+`Menu`** - **File:** `src/app/features/room/ReportRoomModal.tsx` lines 138–163; `src/app/features/room/ReportUserModal.tsx` lines 144–169 -- **Status:** **OPEN** +- **Status:** **FIXED** — extracted a shared `ReportCategorySelect` component (`src/app/features/room/ReportCategorySelect.tsx`) using the folds `Button` trigger + `PopOut` + `FocusTrap` + `Menu` + `MenuItem` pattern (with `escapeDeactivates`/arrow-key nav, matching `OrderButton`); both modals now use it instead of the native `` — the established pattern for all dropdowns in both message modals and search filters is `Chip onClick → setMenuAnchor → PopOut → FocusTrap → Menu → MenuItem` (reference: `OrderButton` in `SearchFilters.tsx` lines 63–114). -- **Fix:** Replace native `` that looked foreign inside the modal. + */ +export function ReportCategorySelect({ id, value, labels, onChange }: ReportCategorySelectProps) { + const [anchor, setAnchor] = useState(); + + const handleOpen: MouseEventHandler = (evt) => { + setAnchor(evt.currentTarget.getBoundingClientRect()); + }; + + const handleSelect = (key: string) => { + onChange(key); + setAnchor(undefined); + }; + + return ( + setAnchor(undefined), + clickOutsideDeactivates: true, + escapeDeactivates: stopPropagation, + isKeyForward: (evt: KeyboardEvent) => + evt.key === 'ArrowDown' || evt.key === 'ArrowRight', + isKeyBackward: (evt: KeyboardEvent) => evt.key === 'ArrowUp' || evt.key === 'ArrowLeft', + }} + > + + + {Object.keys(labels).map((key) => ( + handleSelect(key)} + > + {labels[key]} + + ))} + + + + } + > + + + ); +} diff --git a/src/app/features/room/ReportRoomModal.tsx b/src/app/features/room/ReportRoomModal.tsx index f55477f16..6c4b22712 100644 --- a/src/app/features/room/ReportRoomModal.tsx +++ b/src/app/features/room/ReportRoomModal.tsx @@ -18,6 +18,7 @@ import { Spinner, } from 'folds'; import { AsyncStatus, useAsyncCallback } from '../../hooks/useAsyncCallback'; +import { ReportCategorySelect } from './ReportCategorySelect'; import { useMatrixClient } from '../../hooks/useMatrixClient'; import { stopPropagation } from '../../utils/keyboard'; import { useModalStyle } from '../../hooks/useModalStyle'; @@ -131,31 +132,12 @@ export function ReportRoomModal({ roomId, onClose }: ReportRoomModalProps) { Category - ) => - setCategory(e.target.value as ReportCategory) - } - style={{ - padding: `${config.space.S200} ${config.space.S300}`, - borderRadius: config.radii.R300, - border: `1px solid ${color.Surface.ContainerLine}`, - background: color.Surface.Container, - color: color.Surface.OnContainer, - fontSize: 'inherit', - fontFamily: 'inherit', - width: '100%', - }} - > - {(Object.keys(CATEGORY_LABELS) as ReportCategory[]).map((key) => ( - - ))} - + labels={CATEGORY_LABELS} + onChange={(v) => setCategory(v as ReportCategory)} + /> diff --git a/src/app/features/room/ReportUserModal.tsx b/src/app/features/room/ReportUserModal.tsx index fc89703f5..d7cccbe10 100644 --- a/src/app/features/room/ReportUserModal.tsx +++ b/src/app/features/room/ReportUserModal.tsx @@ -19,6 +19,7 @@ import { } from 'folds'; import { Method } from 'matrix-js-sdk'; import { AsyncStatus, useAsyncCallback } from '../../hooks/useAsyncCallback'; +import { ReportCategorySelect } from './ReportCategorySelect'; import { useMatrixClient } from '../../hooks/useMatrixClient'; import { stopPropagation } from '../../utils/keyboard'; import { useModalStyle } from '../../hooks/useModalStyle'; @@ -137,31 +138,12 @@ export function ReportUserModal({ userId, onClose }: ReportUserModalProps) { Category - ) => - setCategory(e.target.value as ReportCategory) - } - style={{ - padding: `${config.space.S200} ${config.space.S300}`, - borderRadius: config.radii.R300, - border: `1px solid ${color.Surface.ContainerLine}`, - background: color.Surface.Container, - color: color.Surface.OnContainer, - fontSize: 'inherit', - fontFamily: 'inherit', - width: '100%', - }} - > - {(Object.keys(CATEGORY_LABELS) as ReportCategory[]).map((key) => ( - - ))} - + labels={CATEGORY_LABELS} + onChange={(v) => setCategory(v as ReportCategory)} + />