Phone hit: settings B, auth and verification icon buttons #136

Merged
void merged 2 commits from void/phone-hit-settings-b into dev 2026-11-13 12:49:59 +00:00
9 changed files with 44 additions and 4 deletions

View file

@ -30,6 +30,7 @@ import {
} from '../hooks/useKeyBackup';
import { stopPropagation } from '../utils/keyboard';
import { useRestoreBackupOnVerification } from '../hooks/useRestoreBackupOnVerification';
import { PhoneHit } from '../styles/PhoneHit.css';
type BackupStatusProps = {
enabled: boolean;
@ -177,6 +178,7 @@ export function BackupRestoreTile({ crypto }: BackupRestoreTileProps) {
<BackupSyncing count={remainingSession} />
)}
<IconButton
className={PhoneHit}
aria-pressed={!!menuCords}
size="300"
variant="Surface"

View file

@ -30,6 +30,7 @@ import {
} from '../hooks/useVerificationRequest';
import { AsyncStatus, useAsyncCallback } from '../hooks/useAsyncCallback';
import { ContainerColor } from '../styles/ContainerColor.css';
import { PhoneHit } from '../styles/PhoneHit.css';
const DialogHeaderStyles: CSSProperties = {
padding: `0 ${config.space.S200} 0 ${config.space.S400}`,
@ -261,7 +262,7 @@ export function DeviceVerification({ request, onExit }: DeviceVerificationProps)
<Box grow="Yes">
<Text size="H4">Device Verification</Text>
</Box>
<IconButton size="300" radii="300" onClick={handleCancel}>
<IconButton className={PhoneHit} size="300" radii="300" onClick={handleCancel}>
<Icon src={Icons.Cross} />
</IconButton>
</Header>

View file

@ -25,6 +25,7 @@ import { ActionUIA, ActionUIAFlowsLoader } from './ActionUIA';
import { useMatrixClient } from '../hooks/useMatrixClient';
import { useAlive } from '../hooks/useAlive';
import { UseStateProvider } from './UseStateProvider';
import { PhoneHit } from '../styles/PhoneHit.css';
type UIACallback<T> = (
authDict: AuthDict | null
@ -301,7 +302,7 @@ export const DeviceVerificationSetup = forwardRef<HTMLDivElement, DeviceVerifica
<Box grow="Yes">
<Text size="H4">Setup Device Verification</Text>
</Box>
<IconButton size="300" radii="300" onClick={onCancel}>
<IconButton className={PhoneHit} size="300" radii="300" onClick={onCancel}>
<Icon src={Icons.Cross} />
</IconButton>
</Header>
@ -336,7 +337,7 @@ export const DeviceVerificationReset = forwardRef<HTMLDivElement, DeviceVerifica
<Box grow="Yes">
<Text size="H4">Reset Device Verification</Text>
</Box>
<IconButton size="300" radii="300" onClick={onCancel}>
<IconButton className={PhoneHit} size="300" radii="300" onClick={onCancel}>
<Icon src={Icons.Cross} />
</IconButton>
</Header>

View file

@ -8,6 +8,7 @@ import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback';
import { isUserId } from '../../../utils/matrix';
import { useIgnoredUsers } from '../../../hooks/useIgnoredUsers';
import { useAlive } from '../../../hooks/useAlive';
import { PhoneHit } from '../../../styles/PhoneHit.css';
function IgnoreUserInput({ userList }: { userList: string[] }) {
const mx = useMatrixClient();
@ -67,6 +68,7 @@ function IgnoreUserInput({ userList }: { userList: string[] }) {
userId &&
!ignoring && (
<IconButton
className={PhoneHit}
type="reset"
onClick={handleReset}
size="300"

View file

@ -43,6 +43,7 @@ import { ModalWide } from '../../../styles/Modal.css';
import { createUploadAtom, UploadSuccess } from '../../../state/upload';
import { CompactUploadCardRenderer } from '../../../components/upload-card';
import { useCapabilities } from '../../../hooks/useCapabilities';
import { PhoneHit } from '../../../styles/PhoneHit.css';
type ProfileProps = {
profile: UserProfile;
@ -185,7 +186,12 @@ function ProfileAvatar({ profile, userId }: ProfileProps) {
<Box grow="Yes">
<Text size="H4">Remove Avatar</Text>
</Box>
<IconButton size="300" onClick={() => setAlertRemove(false)} radii="300">
<IconButton
className={PhoneHit}
size="300"
onClick={() => setAlertRemove(false)}
radii="300"
>
<Icon src={Icons.Cross} />
</IconButton>
</Header>
@ -273,6 +279,7 @@ function ProfileDisplayName({ profile, userId }: ProfileProps) {
hasChanges &&
!changingDisplayName && (
<IconButton
className={PhoneHit}
type="reset"
onClick={handleReset}
size="300"

View file

@ -29,6 +29,7 @@ import { LogoutDialog } from '../../../components/LogoutDialog';
import { stopPropagation } from '../../../utils/keyboard';
import { useSetting } from '../../../state/hooks/settings';
import { settingsAtom } from '../../../state/settings';
import { PhoneHit } from '../../../styles/PhoneHit.css';
export function DeviceTilePlaceholder() {
return (
@ -288,6 +289,7 @@ export function DeviceTile({
<SettingTile
before={
<IconButton
className={PhoneHit}
variant={deleted ? 'Critical' : 'Secondary'}
outlined={deleted}
radii="300"

View file

@ -35,6 +35,7 @@ import { stopPropagation } from '../../../utils/keyboard';
import { useAuthMetadata } from '../../../hooks/useAuthMetadata';
import { withSearchParam } from '../../../pages/pathUtils';
import { useAccountManagementActions } from '../../../hooks/useAccountManagement';
import { PhoneHit } from '../../../styles/PhoneHit.css';
type VerificationStatusBadgeProps = {
verificationStatus: VerificationStatus;
@ -288,6 +289,7 @@ export function DeviceVerificationOptions() {
return (
<>
<IconButton
className={PhoneHit}
aria-pressed={!!menuCords}
variant="SurfaceVariant"
size="300"

View file

@ -23,6 +23,7 @@ import FocusTrap from 'focus-trap-react';
import { useDebounce } from '../../hooks/useDebounce';
import { stopPropagation } from '../../utils/keyboard';
import { PhoneHit } from '../../styles/PhoneHit.css';
export function ServerPicker({
server,
@ -129,6 +130,7 @@ export function ServerPicker({
}
>
<IconButton
className={PhoneHit}
onClick={handleOpenServerMenu}
variant={allowCustomServer ? 'Background' : 'Surface'}
size="300"

View file

@ -0,0 +1,21 @@
import { describe, it } from 'vitest';
import { expectPhoneHitClasses, expectSizeTie } from './phoneHitTestKit';
// Each IconButton here is alone in its slot (a dialog header's close, an input's clear button, a tile's lone
// menu or chevron button, its neighbours being text or a badge), so each takes PhoneHit. Every size is derivable
// from the source, so nothing is allow-listed; plain PhoneHit has no number to tie.
const files: [string, string[]][] = [
['features/settings/account/Profile.tsx', ['PhoneHit', 'PhoneHit']],
['features/settings/account/IgnoredUserList.tsx', ['PhoneHit']],
['features/settings/devices/Verification.tsx', ['PhoneHit']],
['features/settings/devices/DeviceTile.tsx', ['PhoneHit']],
['pages/auth/ServerPicker.tsx', ['PhoneHit']],
['components/BackupRestore.tsx', ['PhoneHit']],
['components/DeviceVerification.tsx', ['PhoneHit']],
['components/DeviceVerificationSetup.tsx', ['PhoneHit', 'PhoneHit']],
];
describe.each(files)('phone hit area: %s', (file, want) => {
it('gives each icon button its variant', () => expectPhoneHitClasses(file, want));
it('ties each sized variant to the size it draws', () => expectSizeTie(file));
});