Phone hit: room/space settings, lobby, message search, explore (group 7) #137

Merged
void merged 2 commits from void/phone-hit-room-space into dev 2026-11-13 12:58:50 +00:00
11 changed files with 53 additions and 7 deletions

View file

@ -30,6 +30,7 @@ import { IPowerLevels } from '../../hooks/usePowerLevels';
import { getRoomCreatorsForRoomId } from '../../hooks/useRoomCreators';
import { getRoomPermissionsAPI } from '../../hooks/useRoomPermissions';
import { InviteUserPrompt } from '../../components/invite-user-prompt';
import { PhoneHitSpread24 } from '../../styles/PhoneHit.css';
type HierarchyItemWithParent = HierarchyItem & {
parentId: string;
@ -231,6 +232,7 @@ export function HierarchyItemMenu({
return (
<Box gap="200" alignItems="Center" shrink="No">
<IconButton
className={PhoneHitSpread24}
onClick={handleOpenMenu}
size="300"
variant="SurfaceVariant"

View file

@ -48,6 +48,7 @@ import { useGetRoom } from '../../hooks/useGetRoom';
import { AsyncStatus, useAsyncCallback } from '../../hooks/useAsyncCallback';
import { getRoomPermissionsAPI } from '../../hooks/useRoomPermissions';
import { getRoomCreatorsForRoomId } from '../../hooks/useRoomCreators';
import { PhoneHit } from '../../styles/PhoneHit.css';
const useCanDropLobbyItem = (
space: Room,
@ -413,6 +414,7 @@ export function Lobby() {
onVisibilityChange={setOnTop}
>
<IconButton
className={PhoneHit}
onClick={() => virtualizer.scrollToOffset(0)}
variant="SurfaceVariant"
radii="Pill"

View file

@ -23,6 +23,7 @@ import { SearchResultGroup } from './SearchResultGroup';
import { SearchInput } from './SearchInput';
import { SearchFilters } from './SearchFilters';
import { VirtualTile } from '../../components/virtualizer';
import { PhoneHit } from '../../styles/PhoneHit.css';
const useSearchPathSearchParams = (searchParams: URLSearchParams): _SearchPathSearchParams =>
useMemo(
@ -193,6 +194,7 @@ export function MessageSearch({
<Box direction="Column" gap="700">
<ScrollTopContainer scrollRef={scrollRef} anchorRef={scrollTopAnchorRef}>
<IconButton
className={PhoneHit}
onClick={() => virtualizer.scrollToOffset(0)}
variant="SurfaceVariant"
radii="Pill"

View file

@ -17,6 +17,7 @@ import { Permissions } from './permissions';
import { RoomSettingsPage } from '../../state/roomSettings';
import { useRoom } from '../../hooks/useRoom';
import { DeveloperTools } from '../common-settings/developer-tools';
import { PhoneHit } from '../../styles/PhoneHit.css';
type RoomSettingsMenuItem = {
page: RoomSettingsPage;
@ -117,7 +118,7 @@ export function RoomSettings({ initialPage, requestClose }: RoomSettingsProps) {
</Box>
<Box shrink="No">
{screenSize === ScreenSize.Mobile && (
<IconButton onClick={requestClose} variant="Background">
<IconButton className={PhoneHit} onClick={requestClose} variant="Background">
<Icon src={Icons.Cross} />
</IconButton>
)}

View file

@ -15,6 +15,7 @@ import {
} from '../../common-settings/general';
import { useRoomCreators } from '../../../hooks/useRoomCreators';
import { useRoomPermissions } from '../../../hooks/useRoomPermissions';
import { PhoneHit } from '../../../styles/PhoneHit.css';
type GeneralProps = {
requestClose: () => void;
@ -35,7 +36,7 @@ export function General({ requestClose }: GeneralProps) {
</Text>
</Box>
<Box shrink="No">
<IconButton onClick={requestClose} variant="Surface">
<IconButton className={PhoneHit} onClick={requestClose} variant="Surface">
<Icon src={Icons.Cross} />
</IconButton>
</Box>

View file

@ -9,6 +9,7 @@ import { usePermissionGroups } from './usePermissionItems';
import { PermissionGroups, Powers, PowersEditor } from '../../common-settings/permissions';
import { useRoomCreators } from '../../../hooks/useRoomCreators';
import { useRoomPermissions } from '../../../hooks/useRoomPermissions';
import { PhoneHit } from '../../../styles/PhoneHit.css';
type PermissionsProps = {
requestClose: () => void;
@ -45,7 +46,7 @@ export function Permissions({ requestClose }: PermissionsProps) {
</Text>
</Box>
<Box shrink="No">
<IconButton onClick={requestClose} variant="Surface">
<IconButton className={PhoneHit} onClick={requestClose} variant="Surface">
<Icon src={Icons.Cross} />
</IconButton>
</Box>

View file

@ -17,6 +17,7 @@ import { Members } from '../common-settings/members';
import { DeveloperTools } from '../common-settings/developer-tools';
import { General } from './general';
import { Permissions } from './permissions';
import { PhoneHit } from '../../styles/PhoneHit.css';
type SpaceSettingsMenuItem = {
page: SpaceSettingsPage;
@ -117,7 +118,7 @@ export function SpaceSettings({ initialPage, requestClose }: SpaceSettingsProps)
</Box>
<Box shrink="No">
{screenSize === ScreenSize.Mobile && (
<IconButton onClick={requestClose} variant="Background">
<IconButton className={PhoneHit} onClick={requestClose} variant="Background">
<Icon src={Icons.Cross} />
</IconButton>
)}

View file

@ -13,6 +13,7 @@ import {
} from '../../common-settings/general';
import { useRoomCreators } from '../../../hooks/useRoomCreators';
import { useRoomPermissions } from '../../../hooks/useRoomPermissions';
import { PhoneHit } from '../../../styles/PhoneHit.css';
type GeneralProps = {
requestClose: () => void;
@ -33,7 +34,7 @@ export function General({ requestClose }: GeneralProps) {
</Text>
</Box>
<Box shrink="No">
<IconButton onClick={requestClose} variant="Surface">
<IconButton className={PhoneHit} onClick={requestClose} variant="Surface">
<Icon src={Icons.Cross} />
</IconButton>
</Box>

View file

@ -9,6 +9,7 @@ import { usePermissionGroups } from './usePermissionItems';
import { PermissionGroups, Powers, PowersEditor } from '../../common-settings/permissions';
import { useRoomCreators } from '../../../hooks/useRoomCreators';
import { useRoomPermissions } from '../../../hooks/useRoomPermissions';
import { PhoneHit } from '../../../styles/PhoneHit.css';
type PermissionsProps = {
requestClose: () => void;
@ -45,7 +46,7 @@ export function Permissions({ requestClose }: PermissionsProps) {
</Text>
</Box>
<Box shrink="No">
<IconButton onClick={requestClose} variant="Surface">
<IconButton className={PhoneHit} onClick={requestClose} variant="Surface">
<Icon src={Icons.Cross} />
</IconButton>
</Box>

View file

@ -37,6 +37,7 @@ import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback';
import { useNavToActivePathMapper } from '../../../hooks/useNavToActivePathMapper';
import { PageNav, PageNavContent, PageNavHeader } from '../../../components/page';
import { stopPropagation } from '../../../utils/keyboard';
import { PhoneHit } from '../../../styles/PhoneHit.css';
export function AddServer() {
const mx = useMatrixClient();
@ -96,7 +97,12 @@ export function AddServer() {
<Box grow="Yes">
<Text size="H4">Add Server</Text>
</Box>
<IconButton size="300" onClick={() => setDialog(false)} radii="300">
<IconButton
className={PhoneHit}
size="300"
onClick={() => setDialog(false)}
radii="300"
>
<Icon src={Icons.Cross} />
</IconButton>
</Header>

View file

@ -0,0 +1,28 @@
import { describe, it } from 'vitest';
import { expectPhoneHitClasses, expectSizeTie } from './phoneHitTestKit';
describe('icon buttons in room settings, space settings, lobby, search and explore', () => {
// The class each IconButton must carry, in source order. Vertical stacks and lone buttons: the plain PhoneHit.
const expected: Record<string, string[]> = {
'features/room-settings/RoomSettings.tsx': ['PhoneHit'], // close, phone only, alone at the header end
'features/room-settings/general/General.tsx': ['PhoneHit'], // close, 40 px
'features/room-settings/permissions/Permissions.tsx': ['PhoneHit'],
'features/space-settings/SpaceSettings.tsx': ['PhoneHit'],
'features/space-settings/general/General.tsx': ['PhoneHit'],
'features/space-settings/permissions/Permissions.tsx': ['PhoneHit'],
// 16 px icon + 8 padding = 24 px, 8-12 px from the Open / Add chips beside it in a hierarchy card
'features/lobby/HierarchyItemMenu.tsx': ['PhoneHitSpread24'],
'features/lobby/Lobby.tsx': ['PhoneHit'], // floating scroll-to-top, alone
'features/message-search/MessageSearch.tsx': ['PhoneHit'], // floating scroll-to-top, alone
'pages/client/explore/Explore.tsx': ['PhoneHit'], // Add Server dialog close
};
it.each(Object.entries(expected))(
'%s: each IconButton carries its own PhoneHit class',
(file, want) => expectPhoneHitClasses(file, want)
);
it.each(Object.keys(expected))('%s: a sized variant matches the drawn size', (file) =>
expectSizeTie(file)
);
});