PhoneHit: Spread24 for the nav row's 24 px buttons, Spread26 for the unpin button; tests pin position, ::after declarations, className and import alias
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
Soul pass on fc92809e: RoomNavItem's buttons are 24 px, not 32 (36 px pitch, hit areas overlapped); the unpin button is 26 px
beside the Open chip. Six mutants survived (position: relative, pointer-events, z-index, title for className, aliased
import); all now killed.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
fc92809eb9
commit
446306b1e7
4 changed files with 26 additions and 11 deletions
|
|
@ -66,7 +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';
|
||||
import { PhoneHitSpread24 } from '../../styles/PhoneHit.css';
|
||||
|
||||
type RoomNavItemMenuProps = {
|
||||
room: Room;
|
||||
|
|
@ -230,7 +230,7 @@ function CallChatToggle() {
|
|||
|
||||
return (
|
||||
<IconButton
|
||||
className={PhoneHitSpread32}
|
||||
className={PhoneHitSpread24}
|
||||
onClick={() => setChat(!chat)}
|
||||
aria-pressed={chat}
|
||||
aria-label="Toggle Chat"
|
||||
|
|
@ -438,7 +438,7 @@ export function RoomNavItem({
|
|||
}
|
||||
>
|
||||
<IconButton
|
||||
className={PhoneHitSpread32}
|
||||
className={PhoneHitSpread24}
|
||||
onClick={handleOpenMenu}
|
||||
aria-pressed={!!menuAnchor}
|
||||
aria-controls={`menu-${room.roomId}`}
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ import {
|
|||
useGetMemberPowerTag,
|
||||
} from '../../../hooks/useMemberPowerTag';
|
||||
import { useRoomCreatorsTag } from '../../../hooks/useRoomCreatorsTag';
|
||||
import { PhoneHit } from '../../../styles/PhoneHit.css';
|
||||
import { PhoneHit, PhoneHitSpread26 } from '../../../styles/PhoneHit.css';
|
||||
|
||||
type PinnedMessageProps = {
|
||||
room: Room;
|
||||
|
|
@ -147,7 +147,7 @@ function PinnedMessage({
|
|||
</Chip>
|
||||
{canPinEvent && (
|
||||
<IconButton
|
||||
className={PhoneHit}
|
||||
className={PhoneHitSpread26}
|
||||
data-event-id={eventId}
|
||||
variant="Secondary"
|
||||
size="300"
|
||||
|
|
|
|||
|
|
@ -133,6 +133,16 @@ describe('phone icon-button hit areas', () => {
|
|||
expect(css).toMatch(/::after \{[^}]*top: 50%;/);
|
||||
expect(css).toMatch(/::after \{[^}]*left: 50%;/);
|
||||
expect(css).toMatch(/::after \{[^}]*transform: translate\(-50%, -50%\);/);
|
||||
// the box anchors to its own button, receives the tap, and sits above nothing it should not
|
||||
expect(css).toMatch(/@media [^{]+ \{\n\s*\.PhoneHit_PhoneHit__\w+ \{\n\s*position: relative;/);
|
||||
const afterDecls = [...css.matchAll(/::after \{\n([^}]*)\}/g)].flatMap((m) =>
|
||||
m[1]
|
||||
.split('\n')
|
||||
.map((l) => l.trim().split(':')[0])
|
||||
.filter(Boolean)
|
||||
);
|
||||
expect(afterDecls).not.toContain('pointer-events');
|
||||
expect(afterDecls).not.toContain('z-index');
|
||||
expect(stripPhone(css).trim()).toBe('');
|
||||
});
|
||||
|
||||
|
|
@ -142,7 +152,7 @@ describe('phone icon-button hit areas', () => {
|
|||
rulesFor(css, selector, PHONE).map((d) => d['margin-inline']);
|
||||
// 32 px composer buttons, 40 px header buttons, 26 px message-option buttons (which also open vertically,
|
||||
// the menu around them clips a hit area drawn outside its box)
|
||||
expect(margins(/PhoneHit_spread__/)).toEqual(expect.arrayContaining([9, 6, 2]));
|
||||
expect(margins(/PhoneHit_spread__/)).toEqual(expect.arrayContaining([10, 9, 6, 2]));
|
||||
expect(rulesFor(css, /PhoneHit_PhoneHitRoom26__/, PHONE)).toEqual([{ 'margin-block': 9 }]);
|
||||
});
|
||||
|
||||
|
|
@ -194,10 +204,10 @@ describe('icon buttons in the room view', () => {
|
|||
'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-nav/RoomNavItem.tsx': ['PhoneHitSpread24', 'PhoneHitSpread24'], // chat toggle, options: 16 px icon + 8 padding = 24 px, 0 gap
|
||||
'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/room-pin-menu/RoomPinMenu.tsx': ['PhoneHitSpread26', 'PhoneHit'], // unpin (26 px, 8 px from the Open chip), close
|
||||
'features/room/RoomViewTyping.tsx': ['PhoneHit'],
|
||||
'features/room/CallChatView.tsx': ['PhoneHit'],
|
||||
'features/room/jump-to-time/JumpToTime.tsx': ['PhoneHit'],
|
||||
|
|
@ -212,11 +222,15 @@ describe('icon buttons in the room view', () => {
|
|||
'%s: each IconButton carries its own PhoneHit class',
|
||||
(file, want) => {
|
||||
const src = readFileSync(`${process.cwd()}/src/app/${file}`, 'utf8');
|
||||
expect(iconButtonTags(src).map((t) => t.match(/\bPhoneHit\w*/)?.[0] ?? null)).toEqual(want);
|
||||
expect(
|
||||
iconButtonTags(src).map((t) => t.match(/className=\{[^}]*?\b(PhoneHit\w*)\b/)?.[1] ?? 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'`)
|
||||
new RegExp(
|
||||
`import \\{[^}]*\\b${name}\\b(?!\\s+as\\b)[^}]*\\} from '(\\.\\./)+styles/PhoneHit\\.css'`
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,8 @@ export const PhoneHit = style({
|
|||
const spread = (visual: number) =>
|
||||
style([PhoneHit, { '@media': { [PHONE]: { marginInline: (PHONE_TAP - visual) / 2 } } }]);
|
||||
|
||||
const PhoneHitSpread26 = spread(26);
|
||||
export const PhoneHitSpread24 = spread(24);
|
||||
export const PhoneHitSpread26 = spread(26);
|
||||
export const PhoneHitSpread32 = spread(32);
|
||||
export const PhoneHitSpread40 = spread(40);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue