Phone: 44 px hit areas for the chat path's remaining icon buttons; pin variant, import and ::after content
Some checks failed
Build pull request / Build pull request (pull_request) Has been cancelled
Some checks failed
Build pull request / Build pull request (pull_request) Has been cancelled
MessageEditor, RoomNavItem, MembersDrawer, ReactionViewer, RoomPinMenu, RoomViewTyping, CallChatView and JumpToTime get PhoneHit (alone) or PhoneHitSpread32 (two neighbours in a row). phoneTapTargets.test.ts now lists them, plus PasswordInput, Desk, SkyStateControl and PasswordLoginForm, which had no test, checks each class is imported from styles/PhoneHit.css, and pins the ::after content (a mutant without it passed before). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
2aa468c36a
commit
fc92809eb9
9 changed files with 55 additions and 7 deletions
|
|
@ -66,6 +66,7 @@ import { useAutoDiscoveryInfo } from '../../hooks/useAutoDiscoveryInfo';
|
|||
import { livekitSupport } from '../../hooks/useLivekitSupport';
|
||||
import { StateEvent } from '../../../types/matrix/room';
|
||||
import { webRTCSupported } from '../../utils/rtc';
|
||||
import { PhoneHitSpread32 } from '../../styles/PhoneHit.css';
|
||||
|
||||
type RoomNavItemMenuProps = {
|
||||
room: Room;
|
||||
|
|
@ -229,6 +230,7 @@ function CallChatToggle() {
|
|||
|
||||
return (
|
||||
<IconButton
|
||||
className={PhoneHitSpread32}
|
||||
onClick={() => setChat(!chat)}
|
||||
aria-pressed={chat}
|
||||
aria-label="Toggle Chat"
|
||||
|
|
@ -436,6 +438,7 @@ export function RoomNavItem({
|
|||
}
|
||||
>
|
||||
<IconButton
|
||||
className={PhoneHitSpread32}
|
||||
onClick={handleOpenMenu}
|
||||
aria-pressed={!!menuAnchor}
|
||||
aria-controls={`menu-${room.roomId}`}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import { Page, PageHeader } from '../../components/page';
|
|||
import { callChatAtom } from '../../state/callEmbed';
|
||||
import { RoomView } from './RoomView';
|
||||
import { ScreenSize, useScreenSizeContext } from '../../hooks/useScreenSize';
|
||||
import { PhoneHit } from '../../styles/PhoneHit.css';
|
||||
|
||||
export function CallChatView() {
|
||||
const { eventId } = useParams();
|
||||
|
|
@ -41,7 +42,12 @@ export function CallChatView() {
|
|||
}
|
||||
>
|
||||
{(triggerRef) => (
|
||||
<IconButton ref={triggerRef} variant="Surface" onClick={handleClose}>
|
||||
<IconButton
|
||||
className={PhoneHit}
|
||||
ref={triggerRef}
|
||||
variant="Surface"
|
||||
onClick={handleClose}
|
||||
>
|
||||
<Icon src={Icons.Cross} />
|
||||
</IconButton>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ import { useSpaceOptionally } from '../../hooks/useSpace';
|
|||
import { ContainerColor } from '../../styles/ContainerColor.css';
|
||||
import { useFlattenPowerTagMembers, useGetMemberPowerTag } from '../../hooks/useMemberPowerTag';
|
||||
import { useRoomCreators } from '../../hooks/useRoomCreators';
|
||||
import { PhoneHit } from '../../styles/PhoneHit.css';
|
||||
|
||||
type MemberDrawerHeaderProps = {
|
||||
room: Room;
|
||||
|
|
@ -87,6 +88,7 @@ function MemberDrawerHeader({ room }: MemberDrawerHeaderProps) {
|
|||
>
|
||||
{(triggerRef) => (
|
||||
<IconButton
|
||||
className={PhoneHit}
|
||||
ref={triggerRef}
|
||||
variant="Background"
|
||||
onClick={() => setPeopleDrawer(false)}
|
||||
|
|
@ -359,6 +361,7 @@ export function MembersDrawer({ room, members }: MembersDrawerProps) {
|
|||
|
||||
<ScrollTopContainer scrollRef={scrollRef} anchorRef={scrollTopAnchorRef}>
|
||||
<IconButton
|
||||
className={PhoneHit}
|
||||
onClick={() => virtualizer.scrollToOffset(0)}
|
||||
variant="Surface"
|
||||
radii="Pill"
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import { getMxIdLocalPart } from '../../utils/matrix';
|
|||
import * as css from './RoomViewTyping.css';
|
||||
import { useMatrixClient } from '../../hooks/useMatrixClient';
|
||||
import { useRoomTypingMember } from '../../hooks/useRoomTypingMembers';
|
||||
import { PhoneHit } from '../../styles/PhoneHit.css';
|
||||
|
||||
export type RoomViewTypingProps = {
|
||||
room: Room;
|
||||
|
|
@ -111,7 +112,13 @@ export const RoomViewTyping = as<'div', RoomViewTypingProps>(
|
|||
</>
|
||||
)}
|
||||
</Text>
|
||||
<IconButton title="Drop Typing Status" size="300" radii="Pill" onClick={handleDropAll}>
|
||||
<IconButton
|
||||
className={PhoneHit}
|
||||
title="Drop Typing Status"
|
||||
size="300"
|
||||
radii="Pill"
|
||||
onClick={handleDropAll}
|
||||
>
|
||||
<Icon size="50" src={Icons.Cross} />
|
||||
</IconButton>
|
||||
</Box>
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ import { getToday, getYesterday, timeDayMonthYear, timeHourMinute } from '../../
|
|||
import { DatePicker, TimePicker } from '../../../components/time-date';
|
||||
import { useSetting } from '../../../state/hooks/settings';
|
||||
import { settingsAtom } from '../../../state/settings';
|
||||
import { PhoneHit } from '../../../styles/PhoneHit.css';
|
||||
|
||||
type JumpToTimeProps = {
|
||||
onCancel: () => void;
|
||||
|
|
@ -108,7 +109,7 @@ export function JumpToTime({ onCancel, onSubmit }: JumpToTimeProps) {
|
|||
<Box grow="Yes">
|
||||
<Text size="H4">Jump to Time</Text>
|
||||
</Box>
|
||||
<IconButton size="300" onClick={onCancel} radii="300">
|
||||
<IconButton className={PhoneHit} size="300" onClick={onCancel} radii="300">
|
||||
<Icon src={Icons.Cross} />
|
||||
</IconButton>
|
||||
</Header>
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ import { useMatrixClient } from '../../../hooks/useMatrixClient';
|
|||
import { getEditedEvent, getMentionContent, trimReplyFromFormattedBody } from '../../../utils/room';
|
||||
import { mobileOrTablet } from '../../../utils/user-agent';
|
||||
import { useComposingCheck } from '../../../hooks/useComposingCheck';
|
||||
import { PhoneHitSpread32 } from '../../../styles/PhoneHit.css';
|
||||
|
||||
type MessageEditorProps = {
|
||||
roomId: string;
|
||||
|
|
@ -289,6 +290,7 @@ export const MessageEditor = as<'div', MessageEditorProps>(
|
|||
</Box>
|
||||
<Box gap="Inherit">
|
||||
<IconButton
|
||||
className={PhoneHitSpread32}
|
||||
variant="SurfaceVariant"
|
||||
size="300"
|
||||
radii="300"
|
||||
|
|
@ -322,6 +324,7 @@ export const MessageEditor = as<'div', MessageEditorProps>(
|
|||
}
|
||||
>
|
||||
<IconButton
|
||||
className={PhoneHitSpread32}
|
||||
aria-pressed={anchor !== undefined}
|
||||
onClick={
|
||||
((evt) =>
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ import { useMediaAuthentication } from '../../../hooks/useMediaAuthentication';
|
|||
import { useOpenUserRoomProfile } from '../../../state/hooks/userRoomProfile';
|
||||
import { useSpaceOptionally } from '../../../hooks/useSpace';
|
||||
import { getMouseEventCords } from '../../../utils/dom';
|
||||
import { PhoneHit } from '../../../styles/PhoneHit.css';
|
||||
|
||||
export type ReactionViewerProps = {
|
||||
room: Room;
|
||||
|
|
@ -100,7 +101,7 @@ export const ReactionViewer = as<'div', ReactionViewerProps>(
|
|||
<Box grow="Yes">
|
||||
<Text size="H3" truncate>{`Reacted with :${selectedShortcode}:`}</Text>
|
||||
</Box>
|
||||
<IconButton size="300" onClick={requestClose}>
|
||||
<IconButton className={PhoneHit} size="300" onClick={requestClose}>
|
||||
<Icon src={Icons.Cross} />
|
||||
</IconButton>
|
||||
</Header>
|
||||
|
|
|
|||
|
|
@ -86,6 +86,7 @@ import {
|
|||
useGetMemberPowerTag,
|
||||
} from '../../../hooks/useMemberPowerTag';
|
||||
import { useRoomCreatorsTag } from '../../../hooks/useRoomCreatorsTag';
|
||||
import { PhoneHit } from '../../../styles/PhoneHit.css';
|
||||
|
||||
type PinnedMessageProps = {
|
||||
room: Room;
|
||||
|
|
@ -146,6 +147,7 @@ function PinnedMessage({
|
|||
</Chip>
|
||||
{canPinEvent && (
|
||||
<IconButton
|
||||
className={PhoneHit}
|
||||
data-event-id={eventId}
|
||||
variant="Secondary"
|
||||
size="300"
|
||||
|
|
@ -457,7 +459,7 @@ export const RoomPinMenu = forwardRef<HTMLDivElement, RoomPinMenuProps>(
|
|||
<Text size="H5">Pinned Messages</Text>
|
||||
</Box>
|
||||
<Box shrink="No">
|
||||
<IconButton size="300" onClick={requestClose} radii="300">
|
||||
<IconButton className={PhoneHit} size="300" onClick={requestClose} radii="300">
|
||||
<Icon src={Icons.Cross} size="400" />
|
||||
</IconButton>
|
||||
</Box>
|
||||
|
|
|
|||
|
|
@ -126,6 +126,8 @@ describe('phone icon-button hit areas', () => {
|
|||
const phone = [...css.matchAll(/@media ([^{]+) \{\n([\s\S]*?\n)\}(?:\n|$)/g)];
|
||||
expect(phone.map((m) => m[1])).toEqual([PHONE]);
|
||||
expect(css).toMatch(/::after \{[^}]*width: max\(100%, 44px\);[^}]*height: max\(100%, 44px\);/);
|
||||
// no content, no box: the pseudo-element is not rendered at all
|
||||
expect(css).toMatch(/::after \{[^}]*content: "";/);
|
||||
expect(css).toMatch(/::after \{[^}]*position: absolute;/);
|
||||
// centred on the button: top and left at half, pulled back by half its own size
|
||||
expect(css).toMatch(/::after \{[^}]*top: 50%;/);
|
||||
|
|
@ -190,13 +192,33 @@ describe('icon buttons in the room view', () => {
|
|||
],
|
||||
'features/room/RoomInput.tsx': Array(6).fill('PhoneHitSpread32'),
|
||||
'features/room/RoomViewHeader.tsx': Array(6).fill('PhoneHitSpread40'),
|
||||
// The chat path's other buttons. Two neighbours in a row: Spread32. One on its own: the plain PhoneHit.
|
||||
'features/room/message/MessageEditor.tsx': ['PhoneHitSpread32', 'PhoneHitSpread32'], // toolbar, emoji
|
||||
'features/room-nav/RoomNavItem.tsx': ['PhoneHitSpread32', 'PhoneHitSpread32'], // chat toggle, options
|
||||
'features/room/MembersDrawer.tsx': ['PhoneHit', 'PhoneHit'], // close, scroll to top
|
||||
'features/room/reaction-viewer/ReactionViewer.tsx': ['PhoneHit'],
|
||||
'features/room/room-pin-menu/RoomPinMenu.tsx': ['PhoneHit', 'PhoneHit'], // unpin, close
|
||||
'features/room/RoomViewTyping.tsx': ['PhoneHit'],
|
||||
'features/room/CallChatView.tsx': ['PhoneHit'],
|
||||
'features/room/jump-to-time/JumpToTime.tsx': ['PhoneHit'],
|
||||
// Buttons that were fixed with #125 and had no test.
|
||||
'components/password-input/PasswordInput.tsx': ['PhoneHit'],
|
||||
'features/desk/Desk.tsx': ['PhoneHit'],
|
||||
'features/scene/SkyStateControl.tsx': ['PhoneHit'],
|
||||
'pages/auth/login/PasswordLoginForm.tsx': ['PhoneHit'],
|
||||
};
|
||||
|
||||
it.each(Object.entries(expected))(
|
||||
'%s: each IconButton carries its own PhoneHit class',
|
||||
(file, want) => {
|
||||
const tags = iconButtonTags(readFileSync(`${process.cwd()}/src/app/${file}`, 'utf8'));
|
||||
expect(tags.map((t) => t.match(/\bPhoneHit\w+/)?.[0] ?? null)).toEqual(want);
|
||||
const src = readFileSync(`${process.cwd()}/src/app/${file}`, 'utf8');
|
||||
expect(iconButtonTags(src).map((t) => t.match(/\bPhoneHit\w*/)?.[0] ?? null)).toEqual(want);
|
||||
// the name is the one PhoneHit.css.ts exports, not a local of the same name
|
||||
[...new Set(want)].forEach((name) =>
|
||||
expect(src).toMatch(
|
||||
new RegExp(`import \\{[^}]*\\b${name}\\b[^}]*\\} from '(\\.\\./)+styles/PhoneHit\\.css'`)
|
||||
)
|
||||
);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue