Compare commits

...

4 Commits

Author SHA1 Message Date
jared 5470e25bb0 fix(ui): report category dropdown uses folds menu, not native select (N56)
CI / Build & Quality Checks (push) Successful in 10m52s
CI / Trigger Desktop Build (push) Successful in 7s
Extract a shared ReportCategorySelect: folds Button trigger + PopOut +
FocusTrap + Menu + MenuItem (escape + arrow-key nav, like OrderButton),
replacing the OS-styled native <select> in both ReportRoomModal and
ReportUserModal.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 20:41:46 -04:00
jared 374d6dc396 fix(ui): note join/leave sound preview affordance (N82)
Selecting a join/leave sound auto-plays a preview, but nothing communicated
that. Add it to the SettingTile description.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 20:37:55 -04:00
jared d0715774a8 fix(ui): ScheduleMessageModal + PollCreator use folds Dialog shell (N15, N29)
Both rendered as <Box as="form" role="dialog"> with manually assembled
background/borderRadius(R400)/boxShadow. Switch to <Dialog as="form"
variant="Surface"> so the surface comes from the design system (R300 radius),
matching the other message-action dialogs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 20:32:16 -04:00
jared 6f544e2b1f fix(ui): report modals use folds Dialog shell (N63)
ReportRoomModal/ReportUserModal rendered as <Box as="form" role="dialog">
with inline background/borderRadius(R400)/boxShadow. Switch both to
<Dialog as="form" variant="Surface"> so the surface (background, R300 radius,
shadow) comes from the design system, matching MessageReportItem and every
other message-action modal.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 20:26:17 -04:00
7 changed files with 120 additions and 88 deletions
+4 -5
View File
@@ -319,7 +319,7 @@ This document tracks identified bugs, edge cases, and architectural discrepancie
| N12 | MediaGallery Drawer | `MediaGallery.tsx` | 651661 | Drawer uses `position: 'fixed'` with hardcoded `width: '320px'` as inline styles on a `<Box>`**FIXED**: moved positioning/width into co-located `MediaGallery.css.ts` using `toRem(320)` + a `max-width: 750px` full-screen media query (mirrors `MembersDrawer`); border/header now use `config.borderWidth`/`config.space` tokens. Added Escape-to-close on the panel (previously only the lightbox handled Escape). **Full chrome redesign (round 2)** to match native conventions: panel + header switched from `Surface` to `Background` variant (matching `MembersDrawer`/Saved Messages); header now `Text size="H4"` + plain close `IconButton` (dropped the bespoke tooltip-wrapped button); tabs moved to a bordered toolbar strip with the `variant={active?'Primary':'Secondary'} fill={active?'Solid':'Soft'}` pattern from `PolicyListViewer` and now show per-tab counts; the centered "lines + label" month divider replaced with a left-aligned group label (Cinny group-label pattern); thumbnail tiles moved hover/focus styling to CSS `:hover`/`:focus-visible` (no JS hover state) and into `MediaGallery.css.ts`; file rows + grid tokenized. **Docking fix (round 3)** — the core of the finding: the gallery was a `position: fixed` overlay floating over the timeline, mounted from `RoomViewHeader`. It is now a **docked flex sibling** in the room layout row, exactly like `MembersDrawer`: open state lifted to a `mediaGalleryAtom` (mirrors `bookmarksPanelAtom`), rendered in `Room.tsx` with a vertical `Line` separator on desktop and `key={room.roomId}` to reset per room; the CSS is static-width on desktop and only `position: fixed; inset: 0` full-screen on mobile (identical strategy to `MembersDrawer.css`). It now shares the row with the timeline instead of overlapping it. | `MembersDrawer` uses a vanilla-extract class with `width: toRem(266)` and is placed by the layout system, not `position: fixed`. 54px width discrepancy also breaks visual rhythm if both panels could be open |
| N13 | ScheduledMessagesTray | `ScheduledMessagesTray.tsx` | 108126 | Collapsible tray header is `<Box as="button">` with `cursor: 'pointer'` inline style and no folds variant — no hover state, no focus ring — **FIXED**: replaced with folds `<Button variant="Secondary" fill="None" radii="0">` using `before`/`after` icon props (gains design-system hover/focus) | All clickable header/toggle elements in the room view use folds `<Button>` or `<IconButton>` with explicit variants for hover/focus; `<Box as="button">` with no variant is used nowhere else |
| N14 | ForwardMessageDialog | `ForwardMessageDialog.tsx` | 137154 | Dialog uses `<Modal>` but has no `<Header>` component and no close `<IconButton>` — only way to close is clicking outside — **FIXED**: added a folds `<Header variant="Surface" size="500">` with the title + close `<IconButton radii="300">`, matching every other modal | Every other modal using `<Modal>` or `<Box role="dialog">` includes a `<Header>` with a close `<IconButton>` in the top-right (EditHistoryModal, LeaveRoomPrompt, ScheduleMessageModal, RemindMeDialog, etc.) |
| N15 | ScheduleMessageModal | `ScheduleMessageModal.tsx` | 180193 | Modal root is `<Box as="form" role="dialog">` with manually assembled `borderRadius: config.radii.R400`/`boxShadow` | `ForwardMessageDialog` uses folds `<Modal size="400">` with `R500` radius; the R400 vs R500 mismatch is visible when both dialogs appear in the same session |
| N15 | ScheduleMessageModal | `ScheduleMessageModal.tsx` | 180193 | Modal root is `<Box as="form" role="dialog">` with manually assembled `borderRadius: config.radii.R400`/`boxShadow` **FIXED**: shell is now `<Dialog as="form" variant="Surface">`; removed inline surface styles | `ForwardMessageDialog` uses folds `<Modal size="400">` with `R500` radius; the R400 vs R500 mismatch is visible when both dialogs appear in the same session |
| N16 | Presence Picker | `SettingsTab.tsx` | 118144 | Presence trigger dot is raw `<button>` with `position: absolute; bottom: 2; right: 2` inline and no folds focus ring; no tooltip — **FIXED**: wrapped the trigger in a folds `TooltipProvider` (shows "Status: …"); replaced the undefined `var(--bg-surface)` with `color.Background.Container`. Kept the absolute-positioned `<button>` (it overlays the avatar corner; a full `IconButton` would be too large for the dot). | Every other sidebar icon button uses folds `IconButton` with `SidebarItemTooltip` and `TooltipProvider` |
| N17 | Presence Picker | `SettingsTab.tsx` | 8086 | `PresencePicker` `FocusTrap` missing `escapeDeactivates: stopPropagation` and `isKeyForward`/`isKeyBackward`**FIXED**: added all three options, matching the theme selector / sort menus | Every other `PopOut`+`FocusTrap`+`Menu` combo supplies both (theme selector `General.tsx:143160`, `SettingsSelect`, sort menus) — without it Escape bubbles past the trap and arrow-key navigation is absent |
| N18 | Profile Selects | `Profile.tsx` | 547575 / 816848 | `ProfileStatus` auto-clear and `ProfileTimezone` selectors are native `<select>` elements with hardcoded `colorScheme: 'dark'` — will render in dark mode on light themes | General.tsx uses folds `SettingsSelect<T>` (`Button`+`PopOut`+`Menu`) for all dropdowns; `colorScheme: 'dark'` breaks light/custom theme appearance |
@@ -340,7 +340,7 @@ This document tracks identified bugs, edge cases, and architectural discrepancie
| :------ | :--------------------------------- | :------------------------------------- | :---------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| N27 | GIF Picker | `GifPicker.tsx` | 103110 | `FocusTrap` omits `returnFocusOnDeactivate: false` — focus returns to GIF button on dismiss instead of staying in the editor — **FIXED**: added `returnFocusOnDeactivate: false` (matches EmojiBoard) | `EmojiBoard` in `RoomInput.tsx:978` explicitly sets `returnFocusOnDeactivate={false}`; GIF picker dismiss behaviour is inconsistent with emoji picker |
| N28 | Character Counter | `RoomInput.tsx` | 11591174 | Composer character counter rendered with `color: 'var(--tc-surface-low)'` and raw pixel padding — a CSS variable not used anywhere else in the codebase — **FIXED**: removed undefined var and raw opacity; now `<Text priority="300">` with `config.space.S100` padding | Use `color.*` folds tokens or `priority="300"` on a `Text` component |
| N29 | PollCreator Modal | `PollCreator.tsx` | 103116 | Modal root is `<Box as="form" role="dialog" aria-modal="true">` with manually assembled surface styles instead of folds `<Dialog variant="Surface">` | `MessageDeleteItem` and `MessageReportItem` in `Message.tsx:506,635` use `<Dialog variant="Surface">` inside `OverlayCenter > FocusTrap` |
| N29 | PollCreator Modal | `PollCreator.tsx` | 103116 | Modal root is `<Box as="form" role="dialog" aria-modal="true">` with manually assembled surface styles instead of folds `<Dialog variant="Surface">` **FIXED**: shell is now `<Dialog as="form" variant="Surface">`; removed inline surface styles | `MessageDeleteItem` and `MessageReportItem` in `Message.tsx:506,635` use `<Dialog variant="Surface">` inside `OverlayCenter > FocusTrap` |
| N30 | Playback Speed Chip | `AudioContent.tsx` | 163189 | Speed chip uses `variant="SurfaceVariant" radii="Pill"` while adjacent Play/Pause chip uses `variant="Secondary" radii="300"` — mismatched shape and variant within the same `leftControl` row — **FIXED**: changed speed chip to `variant="Secondary" radii="300"` | Controls grouped in the same row should share variant and radii |
| N31 | Collapsible Message Toggle | `MsgTypeRenderers.tsx` | 97105 | "Read more ↓" / "Show less ↑" uses `<Button size="300" variant="Secondary" fill="None">` — visually a padded form button — **FIXED**: replaced with the native flush inline-button pattern (`background:none;border:none;padding:0`) + `<Text size="T200">` tinted `color.Primary.Main`, matching `(edited)` in FallbackContent | Inline text toggles in message content (e.g. `(edited)` in `FallbackContent.tsx:74`) use bare `<button>` with `background: none; border: none; padding: 0` to stay flush with text |
| N32 | ReadReceiptAvatars Pill | `ReadReceiptAvatars.tsx` | 95103 | Pill border is `'1px solid rgba(0,212,255,0.30)'` hardcoded raw rgba string; `borderRadius: '999px'` not a folds radii token; padding in raw pixels — **FIXED**: replaced with `config.borderWidth.B300`, `config.radii.Pill`, `config.space.S100/S200` | Use `color.*` folds tokens and `config.radii.Pill` / `config.space.S*` |
@@ -397,9 +397,8 @@ This document tracks identified bugs, edge cases, and architectural discrepancie
**N56 — Report Modal Category Dropdown: Native `<select>` Instead of folds `Chip`+`PopOut`+`Menu`**
- **File:** `src/app/features/room/ReportRoomModal.tsx` lines 138163; `src/app/features/room/ReportUserModal.tsx` lines 144169
- **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 `<select>`.
- **Issue:** Both report modals render the "Category" field as `<Box as="select">` with hand-rolled inline styles (padding, border, background, color, fontSize, fontFamily). No other selector in the message-action modal context uses `<select>` — 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 63114).
- **Fix:** Replace native `<select>` with `<Chip>` trigger + `<PopOut>` + `<Menu>` + `<MenuItem>` pattern.
---
@@ -413,7 +412,7 @@ This document tracks identified bugs, edge cases, and architectural discrepancie
| N60 | Knock Badge on Members Button | `RoomViewHeader.tsx` | 744782 | Knock count badge wrapped in extra `<div style={{ position: 'relative' }}>` with hardcoded `fontSize: '9px'`, `minWidth: '14px'`, `height: '14px'`, `padding: '0 3px'` overriding folds `size="200"`**FIXED**: removed wrapper div, put `position: 'relative'` directly on the `IconButton`, `<Badge size="400">` with `toRem(3)` insets and `<Text size="L400">` — now matches the Pinned Messages badge pattern exactly | Pinned Messages badge (same header, lines 651677) uses `position: 'relative'` directly on `<IconButton>` + `toRem()` for inset; no extra wrapper div |
| N61 | Knock Member Rows | `MembersDrawer.tsx` | 441487 | Knock requester rows use raw `<Box>` with manually duplicated padding; no `<MenuItem>` wrapper → no hover/focus/active states — **WON'T FIX (deliberate)**: unlike a `MemberItem` (a clickable navigation row), a knock row contains two action buttons (Approve / Deny) and is **not itself clickable**. Wrapping it in `<MenuItem>` (a `<button>`) would nest interactive controls inside a button — invalid HTML/ARIA. The row has no interactive state to express. | Every joined/invited member uses `<MemberItem>` which wraps `<MenuItem variant="Background" radii="400">` with baked-in spacing and all interactive states |
| N62 | Unverified Device Banner | `RoomInput.tsx` | 860883 | Warning callout above composer uses inline `background: color.Warning.Container`, `borderLeft: '3px solid color.Warning.Main'` — a custom left-border accent pattern not present anywhere else in the folds system — **FIXED**: replaced the `borderLeft: '3px'` accent with a standard full `border` using `color.Warning.ContainerLine` + `config.borderWidth.B300`; removed the `opacity` hacks (folds `OnContainer` already meets contrast) | Warning indicators in the same codebase use `<Chip variant="Warning">` or `<Badge variant="Warning">`; the 3px left-border card pattern has no folds equivalent |
| N63 | Report Modals — Box Instead of Dialog | `ReportRoomModal.tsx` / `ReportUserModal.tsx` | 97110 / 103116 | Both modals render as `<Box as="form" role="dialog">` with inline `background`/`borderRadius`/`boxShadow`; use `config.radii.R400` (rounder) vs native `Dialog` which uses `R300` | Native `MessageReportItem` at `Message.tsx:634` and all other Cinny message-action modals use `<Dialog variant="Surface">` |
| N63 | Report Modals — Box Instead of Dialog | `ReportRoomModal.tsx` / `ReportUserModal.tsx` | 97110 / 103116 | Both modals render as `<Box as="form" role="dialog">` with inline `background`/`borderRadius`/`boxShadow`; use `config.radii.R400` (rounder) vs native `Dialog` which uses `R300` **FIXED**: both shells are now `<Dialog as="form" variant="Surface">`; removed inline surface styles (Dialog provides background/radius/shadow) | Native `MessageReportItem` at `Message.tsx:634` and all other Cinny message-action modals use `<Dialog variant="Surface">` |
| N64 | EditHistoryModal — `<Modal>` vs `<Dialog>` | `EditHistoryModal.tsx` | 166 | Uses `<Modal variant="Surface" size="500">` while sibling message-action modals (`DeleteMessageItem:505`, `MessageReportItem:634`) all use `<Dialog variant="Surface">` — different widths and internal padding | `<Dialog variant="Surface">` is the established modal shell for all message-triggered dialogs |
| N65 | EditHistoryModal — No "Load More" | `EditHistoryModal.tsx` | 253259 | When `hasMore` is true the modal shows passive `<Text>"Showing the 50 most recent edits"</Text>` with no action; older edits are inaccessible — **FIXED**: implemented real pagination — edits accumulate across `next_batch` fetches (de-duped by event id, re-sorted by ts), with a folds `<Button>Load more</Button>` (spinner while loading) replacing the passive text | `RoomActivityLog.tsx:425` and `MessageSearch.tsx:129` both render a folds `<Button size="300" variant="Secondary">Load more</Button>` to fetch the next page |
| N66 | DateRangeButton — Native `<input type="date">` | `SearchFilters.tsx` | 558589 | "From" and "To" date fields are raw `<input type="date">` with inline style overrides including `fontSize: '0.82rem'`**FIXED**: replaced both with folds `<Input type="date" variant="SurfaceVariant" size="300" radii="300">`; removed now-unused `color` import | `SelectRoomButton` (same file, line 224) and `SelectSenderButton` (line 424) both use folds `<Input size="300" radii="300">`; the date inputs are the only native browser inputs in the search filter row |
+5 -9
View File
@@ -3,6 +3,7 @@ import FocusTrap from 'focus-trap-react';
import {
Box,
Button,
Dialog,
Header,
Icon,
IconButton,
@@ -100,19 +101,14 @@ export function PollCreator({ roomId, onClose }: PollCreatorProps) {
escapeDeactivates: stopPropagation,
}}
>
<Box
<Dialog
as="form"
variant="Surface"
role="dialog"
aria-modal="true"
aria-labelledby="poll-creator-title"
onSubmit={handleSubmit}
direction="Column"
style={{
background: color.Surface.Container,
borderRadius: config.radii.R400,
boxShadow: color.Other.Shadow,
...modalStyle,
}}
style={modalStyle}
>
{/* Header */}
<Header
@@ -256,7 +252,7 @@ export function PollCreator({ roomId, onClose }: PollCreatorProps) {
</Button>
</Box>
</Box>
</Box>
</Dialog>
</FocusTrap>
</OverlayCenter>
</Overlay>
@@ -0,0 +1,85 @@
import React, { MouseEventHandler, useState } from 'react';
import { Box, Button, Icon, Icons, Menu, MenuItem, PopOut, RectCords, Text, config } from 'folds';
import FocusTrap from 'focus-trap-react';
import { stopPropagation } from '../../utils/keyboard';
type ReportCategorySelectProps = {
id?: string;
value: string;
labels: Record<string, string>;
onChange: (value: string) => void;
};
/**
* Category dropdown for the report modals folds `Button` + `PopOut` + `Menu`
* pattern (matching `OrderButton` in SearchFilters), replacing the OS-styled
* native `<select>` that looked foreign inside the modal.
*/
export function ReportCategorySelect({ id, value, labels, onChange }: ReportCategorySelectProps) {
const [anchor, setAnchor] = useState<RectCords>();
const handleOpen: MouseEventHandler<HTMLButtonElement> = (evt) => {
setAnchor(evt.currentTarget.getBoundingClientRect());
};
const handleSelect = (key: string) => {
onChange(key);
setAnchor(undefined);
};
return (
<PopOut
anchor={anchor}
position="Bottom"
align="Start"
offset={4}
content={
<FocusTrap
focusTrapOptions={{
initialFocus: false,
onDeactivate: () => setAnchor(undefined),
clickOutsideDeactivates: true,
escapeDeactivates: stopPropagation,
isKeyForward: (evt: KeyboardEvent) =>
evt.key === 'ArrowDown' || evt.key === 'ArrowRight',
isKeyBackward: (evt: KeyboardEvent) => evt.key === 'ArrowUp' || evt.key === 'ArrowLeft',
}}
>
<Menu style={{ padding: config.space.S100 }}>
<Box direction="Column" gap="100">
{Object.keys(labels).map((key) => (
<MenuItem
key={key}
size="300"
variant={key === value ? 'Primary' : 'Surface'}
radii="300"
aria-pressed={key === value}
onClick={() => handleSelect(key)}
>
<Text size="T300">{labels[key]}</Text>
</MenuItem>
))}
</Box>
</Menu>
</FocusTrap>
}
>
<Button
id={id}
type="button"
variant="Secondary"
fill="Soft"
size="400"
radii="300"
outlined
onClick={handleOpen}
aria-haspopup="listbox"
aria-expanded={!!anchor}
after={<Icon size="100" src={Icons.ChevronBottom} />}
style={{ width: '100%', justifyContent: 'space-between' }}
>
<Text size="T300">{labels[value] ?? value}</Text>
</Button>
</PopOut>
);
}
+10 -32
View File
@@ -5,6 +5,7 @@ import {
Text,
Input,
Button,
Dialog,
IconButton,
Icon,
Icons,
@@ -17,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';
@@ -94,19 +96,14 @@ export function ReportRoomModal({ roomId, onClose }: ReportRoomModalProps) {
escapeDeactivates: stopPropagation,
}}
>
<Box
<Dialog
as="form"
variant="Surface"
role="dialog"
aria-modal="true"
aria-labelledby="report-room-dialog-title"
onSubmit={handleSubmit}
direction="Column"
style={{
background: color.Surface.Container,
borderRadius: config.radii.R400,
boxShadow: color.Other.Shadow,
...modalStyle,
}}
style={modalStyle}
>
<Header
style={{
@@ -135,31 +132,12 @@ export function ReportRoomModal({ roomId, onClose }: ReportRoomModalProps) {
<Text as="label" htmlFor="report-category" size="L400">
Category
</Text>
<Box
as="select"
<ReportCategorySelect
id="report-category"
aria-label="Report category"
value={category}
onChange={(e: React.ChangeEvent<HTMLSelectElement>) =>
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) => (
<option key={key} value={key}>
{CATEGORY_LABELS[key]}
</option>
))}
</Box>
labels={CATEGORY_LABELS}
onChange={(v) => setCategory(v as ReportCategory)}
/>
</Box>
<Box direction="Column" gap="100">
@@ -206,7 +184,7 @@ export function ReportRoomModal({ roomId, onClose }: ReportRoomModalProps) {
</Button>
</Box>
</Box>
</Box>
</Dialog>
</FocusTrap>
</OverlayCenter>
</Overlay>
+10 -32
View File
@@ -5,6 +5,7 @@ import {
Text,
Input,
Button,
Dialog,
IconButton,
Icon,
Icons,
@@ -18,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';
@@ -100,19 +102,14 @@ export function ReportUserModal({ userId, onClose }: ReportUserModalProps) {
escapeDeactivates: stopPropagation,
}}
>
<Box
<Dialog
as="form"
variant="Surface"
role="dialog"
aria-modal="true"
aria-labelledby="report-user-dialog-title"
onSubmit={handleSubmit}
direction="Column"
style={{
background: color.Surface.Container,
borderRadius: config.radii.R400,
boxShadow: color.Other.Shadow,
...modalStyle,
}}
style={modalStyle}
>
<Header
style={{
@@ -141,31 +138,12 @@ export function ReportUserModal({ userId, onClose }: ReportUserModalProps) {
<Text as="label" htmlFor="report-user-category" size="L400">
Category
</Text>
<Box
as="select"
<ReportCategorySelect
id="report-user-category"
aria-label="Report category"
value={category}
onChange={(e: React.ChangeEvent<HTMLSelectElement>) =>
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) => (
<option key={key} value={key}>
{CATEGORY_LABELS[key]}
</option>
))}
</Box>
labels={CATEGORY_LABELS}
onChange={(v) => setCategory(v as ReportCategory)}
/>
</Box>
<Box direction="Column" gap="100">
@@ -212,7 +190,7 @@ export function ReportUserModal({ userId, onClose }: ReportUserModalProps) {
</Button>
</Box>
</Box>
</Box>
</Dialog>
</FocusTrap>
</OverlayCenter>
</Overlay>
@@ -3,6 +3,7 @@ import FocusTrap from 'focus-trap-react';
import {
Box,
Button,
Dialog,
Header,
Icon,
IconButton,
@@ -177,19 +178,14 @@ export function ScheduleMessageModal({
escapeDeactivates: stopPropagation,
}}
>
<Box
<Dialog
as="form"
variant="Surface"
role="dialog"
aria-modal="true"
aria-labelledby="schedule-message-title"
onSubmit={handleSubmit}
direction="Column"
style={{
background: color.Surface.Container,
borderRadius: config.radii.R400,
boxShadow: color.Other.Shadow,
...modalStyle,
}}
style={modalStyle}
>
{/* Header */}
<Header
@@ -341,7 +337,7 @@ export function ScheduleMessageModal({
<Text size="B400">Schedule</Text>
</Button>
</Box>
</Box>
</Dialog>
</FocusTrap>
</OverlayCenter>
</Overlay>
@@ -1587,7 +1587,7 @@ function Calls() {
<SequenceCard className={SequenceCardStyle} variant="SurfaceVariant" direction="Column">
<SettingTile
title="Join & Leave Sounds"
description="Play a sound when someone joins or leaves a call you are in."
description="Play a sound when someone joins or leaves a call you are in. Selecting an option plays a preview."
after={
<SettingsSelect
value={callJoinLeaveSound}