Phone hit: page back buttons and Lobby/Notifications lone buttons
All checks were successful
Build pull request / Build pull request (pull_request) Successful in 3m59s
All checks were successful
Build pull request / Build pull request (pull_request) Successful in 3m59s
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
54ac1ba480
commit
cd90a044ed
12 changed files with 53 additions and 12 deletions
|
|
@ -10,6 +10,7 @@ import { useMatrixClient } from '../../hooks/useMatrixClient';
|
|||
import { allRoomsAtom } from '../../state/room-list/roomList';
|
||||
import { ScreenSize, useScreenSizeContext } from '../../hooks/useScreenSize';
|
||||
import { BackRouteHandler } from '../../components/BackRouteHandler';
|
||||
import { PhoneHit } from '../../styles/PhoneHit.css';
|
||||
|
||||
type JoinBeforeNavigateProps = { roomIdOrAlias: string; eventId?: string; viaServers?: string[] };
|
||||
export function JoinBeforeNavigate({
|
||||
|
|
@ -38,7 +39,7 @@ export function JoinBeforeNavigate({
|
|||
{screenSize === ScreenSize.Mobile && (
|
||||
<BackRouteHandler>
|
||||
{(onBack) => (
|
||||
<IconButton onClick={onBack}>
|
||||
<IconButton className={PhoneHit} onClick={onBack}>
|
||||
<Icon src={Icons.ArrowLeft} />
|
||||
</IconButton>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ import { useOpenSpaceSettings } from '../../state/hooks/spaceSettings';
|
|||
import { useRoomCreators } from '../../hooks/useRoomCreators';
|
||||
import { useRoomPermissions } from '../../hooks/useRoomPermissions';
|
||||
import { InviteUserPrompt } from '../../components/invite-user-prompt';
|
||||
import { PhoneHit } from '../../styles/PhoneHit.css';
|
||||
|
||||
type LobbyMenuProps = {
|
||||
powerLevels: IPowerLevels;
|
||||
|
|
@ -165,7 +166,7 @@ export function LobbyHeader({ showProfile, powerLevels }: LobbyHeaderProps) {
|
|||
<Box shrink="No">
|
||||
<BackRouteHandler>
|
||||
{(onBack) => (
|
||||
<IconButton fill="None" onClick={onBack}>
|
||||
<IconButton className={PhoneHit} fill="None" onClick={onBack}>
|
||||
<Icon src={Icons.ArrowLeft} />
|
||||
</IconButton>
|
||||
)}
|
||||
|
|
@ -240,6 +241,7 @@ export function LobbyHeader({ showProfile, powerLevels }: LobbyHeaderProps) {
|
|||
>
|
||||
{(triggerRef) => (
|
||||
<IconButton
|
||||
className={PhoneHit}
|
||||
fill="None"
|
||||
onClick={handleOpenMenu}
|
||||
ref={triggerRef}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import {
|
|||
} from '../../../components/page';
|
||||
import { BackRouteHandler } from '../../../components/BackRouteHandler';
|
||||
import { CreateChat } from '../../../features/create-chat';
|
||||
import { PhoneHit } from '../../../styles/PhoneHit.css';
|
||||
|
||||
export function DirectCreate() {
|
||||
const mx = useMatrixClient();
|
||||
|
|
@ -44,7 +45,7 @@ export function DirectCreate() {
|
|||
<Box grow="Yes" alignItems="Center" gap="200">
|
||||
<BackRouteHandler>
|
||||
{(onBack) => (
|
||||
<IconButton onClick={onBack}>
|
||||
<IconButton className={PhoneHit} onClick={onBack}>
|
||||
<Icon src={Icons.ArrowLeft} />
|
||||
</IconButton>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ import * as css from './style.css';
|
|||
import { useRoomNavigate } from '../../../hooks/useRoomNavigate';
|
||||
import { ScreenSize, useScreenSizeContext } from '../../../hooks/useScreenSize';
|
||||
import { BackRouteHandler } from '../../../components/BackRouteHandler';
|
||||
import { PhoneHit } from '../../../styles/PhoneHit.css';
|
||||
|
||||
export function FeaturedRooms() {
|
||||
const { featuredCommunities } = useClientConfig();
|
||||
|
|
@ -33,7 +34,7 @@ export function FeaturedRooms() {
|
|||
<Box shrink="No">
|
||||
<BackRouteHandler>
|
||||
{(onBack) => (
|
||||
<IconButton onClick={onBack}>
|
||||
<IconButton className={PhoneHit} onClick={onBack}>
|
||||
<Icon src={Icons.ArrowLeft} />
|
||||
</IconButton>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ import { getMxIdServer } from '../../../utils/matrix';
|
|||
import { stopPropagation } from '../../../utils/keyboard';
|
||||
import { ScreenSize, useScreenSizeContext } from '../../../hooks/useScreenSize';
|
||||
import { BackRouteHandler } from '../../../components/BackRouteHandler';
|
||||
import { PhoneHit } from '../../../styles/PhoneHit.css';
|
||||
|
||||
const useServerSearchParams = (searchParams: URLSearchParams): ExploreServerPathSearchParams =>
|
||||
useMemo(
|
||||
|
|
@ -499,7 +500,7 @@ export function PublicRooms() {
|
|||
{screenSize === ScreenSize.Mobile && (
|
||||
<BackRouteHandler>
|
||||
{(onBack) => (
|
||||
<IconButton onClick={onBack}>
|
||||
<IconButton className={PhoneHit} onClick={onBack}>
|
||||
<Icon src={Icons.ArrowLeft} />
|
||||
</IconButton>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import { ScreenSize, useScreenSizeContext } from '../../../hooks/useScreenSize';
|
|||
import { BackRouteHandler } from '../../../components/BackRouteHandler';
|
||||
import { CreateRoomForm } from '../../../features/create-room';
|
||||
import { useRoomNavigate } from '../../../hooks/useRoomNavigate';
|
||||
import { PhoneHit } from '../../../styles/PhoneHit.css';
|
||||
|
||||
export function HomeCreateRoom() {
|
||||
const screenSize = useScreenSizeContext();
|
||||
|
|
@ -25,7 +26,7 @@ export function HomeCreateRoom() {
|
|||
<Box grow="Yes" alignItems="Center" gap="200">
|
||||
<BackRouteHandler>
|
||||
{(onBack) => (
|
||||
<IconButton onClick={onBack}>
|
||||
<IconButton className={PhoneHit} onClick={onBack}>
|
||||
<Icon src={Icons.ArrowLeft} />
|
||||
</IconButton>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import { MessageSearch } from '../../../features/message-search';
|
|||
import { useHomeRooms } from './useHomeRooms';
|
||||
import { ScreenSize, useScreenSizeContext } from '../../../hooks/useScreenSize';
|
||||
import { BackRouteHandler } from '../../../components/BackRouteHandler';
|
||||
import { PhoneHit } from '../../../styles/PhoneHit.css';
|
||||
|
||||
export function HomeSearch() {
|
||||
const scrollRef = useRef<HTMLDivElement>(null);
|
||||
|
|
@ -19,7 +20,7 @@ export function HomeSearch() {
|
|||
{screenSize === ScreenSize.Mobile && (
|
||||
<BackRouteHandler>
|
||||
{(onBack) => (
|
||||
<IconButton onClick={onBack}>
|
||||
<IconButton className={PhoneHit} onClick={onBack}>
|
||||
<Icon src={Icons.ArrowLeft} />
|
||||
</IconButton>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ import { useIgnoredUsers } from '../../../hooks/useIgnoredUsers';
|
|||
import { useReportRoomSupported } from '../../../hooks/useReportRoomSupported';
|
||||
import { useSetting } from '../../../state/hooks/settings';
|
||||
import { settingsAtom } from '../../../state/settings';
|
||||
import { PhoneHit } from '../../../styles/PhoneHit.css';
|
||||
|
||||
const COMPACT_CARD_WIDTH = 548;
|
||||
|
||||
|
|
@ -745,7 +746,7 @@ export function Invites() {
|
|||
{screenSize === ScreenSize.Mobile && (
|
||||
<BackRouteHandler>
|
||||
{(onBack) => (
|
||||
<IconButton onClick={onBack}>
|
||||
<IconButton className={PhoneHit} onClick={onBack}>
|
||||
<Icon src={Icons.ArrowLeft} />
|
||||
</IconButton>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -97,6 +97,7 @@ import {
|
|||
} from '../../../hooks/useMemberPowerTag';
|
||||
import { useRoomCreatorsTag } from '../../../hooks/useRoomCreatorsTag';
|
||||
import { useRoomCreators } from '../../../hooks/useRoomCreators';
|
||||
import { PhoneHit } from '../../../styles/PhoneHit.css';
|
||||
|
||||
type RoomNotificationsGroup = {
|
||||
roomId: string;
|
||||
|
|
@ -642,7 +643,7 @@ export function Notifications() {
|
|||
{screenSize === ScreenSize.Mobile && (
|
||||
<BackRouteHandler>
|
||||
{(onBack) => (
|
||||
<IconButton onClick={onBack}>
|
||||
<IconButton className={PhoneHit} onClick={onBack}>
|
||||
<Icon src={Icons.ArrowLeft} />
|
||||
</IconButton>
|
||||
)}
|
||||
|
|
@ -694,6 +695,7 @@ export function Notifications() {
|
|||
onVisibilityChange={handleScrollTopVisibility}
|
||||
>
|
||||
<IconButton
|
||||
className={PhoneHit}
|
||||
onClick={() => virtualizer.scrollToOffset(0)}
|
||||
variant="SurfaceVariant"
|
||||
radii="Pill"
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import { roomToParentsAtom } from '../../../state/room/roomToParents';
|
|||
import { useMatrixClient } from '../../../hooks/useMatrixClient';
|
||||
import { ScreenSize, useScreenSizeContext } from '../../../hooks/useScreenSize';
|
||||
import { BackRouteHandler } from '../../../components/BackRouteHandler';
|
||||
import { PhoneHit } from '../../../styles/PhoneHit.css';
|
||||
|
||||
export function SpaceSearch() {
|
||||
const mx = useMatrixClient();
|
||||
|
|
@ -34,7 +35,7 @@ export function SpaceSearch() {
|
|||
{screenSize === ScreenSize.Mobile && (
|
||||
<BackRouteHandler>
|
||||
{(onBack) => (
|
||||
<IconButton onClick={onBack}>
|
||||
<IconButton className={PhoneHit} onClick={onBack}>
|
||||
<Icon src={Icons.ArrowLeft} />
|
||||
</IconButton>
|
||||
)}
|
||||
|
|
|
|||
29
src/app/phoneHit.pages.test.ts
Normal file
29
src/app/phoneHit.pages.test.ts
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
import { describe, it } from 'vitest';
|
||||
import { expectPhoneHitClasses, expectSizeTie } from './phoneHitTestKit';
|
||||
|
||||
// Page back buttons (and two lone buttons beside them). Every one is alone in its row, 40 px drawn (default
|
||||
// IconButton and Icon), so plain PhoneHit; the vertical stacks of the page have no variant.
|
||||
// null = deliberately without: LobbyHeader's Members button renders only when screenSize !== Mobile.
|
||||
const files: Record<string, (string | null)[]> = {
|
||||
'features/lobby/LobbyHeader.tsx': ['PhoneHit', null, 'PhoneHit'],
|
||||
'features/join-before-navigate/JoinBeforeNavigate.tsx': ['PhoneHit'],
|
||||
'pages/client/space/Search.tsx': ['PhoneHit'],
|
||||
'pages/client/explore/Server.tsx': ['PhoneHit'],
|
||||
'pages/client/explore/Featured.tsx': ['PhoneHit'],
|
||||
'pages/client/home/CreateRoom.tsx': ['PhoneHit'],
|
||||
'pages/client/home/Search.tsx': ['PhoneHit'],
|
||||
// the second is the 30 px scroll-to-top pill, floating alone at the top centre
|
||||
'pages/client/inbox/Notifications.tsx': ['PhoneHit', 'PhoneHit'],
|
||||
'pages/client/inbox/Invites.tsx': ['PhoneHit'],
|
||||
'pages/client/direct/DirectCreate.tsx': ['PhoneHit'],
|
||||
};
|
||||
|
||||
describe.each(Object.entries(files))('phone hit area: %s', (file, want) => {
|
||||
it('gives each IconButton its variant', () => {
|
||||
expectPhoneHitClasses(file, want);
|
||||
});
|
||||
// plain PhoneHit has no size to tie; this fails when a sized variant appears whose number is not the drawn px
|
||||
it('ties any sized variant to the drawn size', () => {
|
||||
expectSizeTie(file);
|
||||
});
|
||||
});
|
||||
|
|
@ -90,10 +90,10 @@ const phoneHitOf = (tag: string) => tag.match(/className=\{[^}]*?\b(PhoneHit\w*)
|
|||
/** The class each IconButton must carry, in source order: the variant is chosen by the button's drawn size and
|
||||
* whether a clipping container or neighbours surround it, so a swapped variant is a wrong hit area. Also checks
|
||||
* the name is the one PhoneHit.css.ts exports, not a local of the same name. */
|
||||
export const expectPhoneHitClasses = (file: string, want: string[]) => {
|
||||
export const expectPhoneHitClasses = (file: string, want: (string | null)[]) => {
|
||||
const src = readSource(file);
|
||||
expect(iconButtonTags(src).map(phoneHitOf)).toEqual(want);
|
||||
[...new Set(want)].forEach((name) =>
|
||||
[...new Set(want.filter((w): w is string => w !== null))].forEach((name) =>
|
||||
expect(src).toMatch(
|
||||
new RegExp(
|
||||
`import \\{(?:[^}]*,)?\\s*${name}\\s*(?:,[^}]*)?\\} from '(\\.\\./)+styles/PhoneHit\\.css'`
|
||||
|
|
|
|||
Loading…
Reference in a new issue