mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-19 05:26:47 +00:00
fix(ui): defuse the press-scale click trap on three more composite buttons (#2158)
Same trap the task-list fix hardened: the press animation shrinks the container mid-click and the release lands next to the target. The collections rows, the journey gallery tiles and the shared vacay calendar cards carry the established no-press attribute now.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
// FE-COMP-COLLIST-001 to FE-COMP-COLLIST-010
|
||||
// FE-COMP-COLLIST-001 to FE-COMP-COLLIST-011
|
||||
import { render, screen } from '../../../tests/helpers/render';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import type { CollectionPlace } from '@trek/shared';
|
||||
@@ -157,4 +157,14 @@ describe('CollectionList', () => {
|
||||
expect(screen.getByText('Blue Bottle Coffee').closest('.col-lrow')).toBeInTheDocument();
|
||||
expect(screen.getByText('Golden Gate Bridge').closest('.col-lrow')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('FE-COMP-COLLIST-011: the row opts out of the global press-scale (#2158)', () => {
|
||||
// jsdom cannot replay the browser mechanics behind #2158: the :active scale on
|
||||
// the row-wide role="button" shifted the status badge out from under the pointer,
|
||||
// so the click retargeted onto the row and opened the place instead of cycling the
|
||||
// status. The data-no-press attribute is the pin.
|
||||
renderList();
|
||||
|
||||
expect(screen.getByText('Blue Bottle Coffee').closest('.col-lrow')).toHaveAttribute('data-no-press');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -44,6 +44,10 @@ export default function CollectionList({
|
||||
key={place.id}
|
||||
ref={active ? selectedRef : undefined}
|
||||
role="button"
|
||||
// Opt out of the global :active press-scale: shrinking the row-wide button
|
||||
// slides the status badge out from under the pointer mid-click, so the click
|
||||
// retargets onto the row and opens the place instead of cycling (#2158).
|
||||
data-no-press
|
||||
tabIndex={0}
|
||||
onClick={() => (selectMode ? onToggleSelect(place.id) : onOpenPlace(place.id))}
|
||||
onKeyDown={e => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); if (selectMode) onToggleSelect(place.id); else onOpenPlace(place.id) } }}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// FE-JRN-GALLERY-001 to FE-JRN-GALLERY-016
|
||||
// FE-JRN-GALLERY-001 to FE-JRN-GALLERY-019
|
||||
|
||||
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'
|
||||
import { act, useRef, useState } from 'react'
|
||||
@@ -373,4 +373,14 @@ describe('GalleryView', () => {
|
||||
expect(container.querySelectorAll('.aspect-square')).toHaveLength(2)
|
||||
expect(container.querySelector('.animate-spin')).toBeNull()
|
||||
})
|
||||
|
||||
it('FE-JRN-GALLERY-019: the tile opts out of the global press-scale (#2158)', () => {
|
||||
// jsdom cannot replay the browser mechanics behind #2158: the :active scale on
|
||||
// the tile shifted its corner delete button out from under the pointer, so the
|
||||
// click retargeted onto the tile and opened the lightbox instead of deleting.
|
||||
// The data-no-press attribute is the pin.
|
||||
const { container } = mountGallery([buildGalleryPhoto()])
|
||||
|
||||
expect(container.querySelector('.aspect-square')).toHaveAttribute('data-no-press')
|
||||
})
|
||||
})
|
||||
|
||||
@@ -142,6 +142,10 @@ export function GalleryView({ entries, gallery, journeyId, userId, trips, onPhot
|
||||
<div
|
||||
key={photo.id}
|
||||
role="button"
|
||||
// No press-scale on the tile: shrinking it mid-click slides the corner
|
||||
// delete button out from under the pointer, so the click retargets onto
|
||||
// the tile and opens the lightbox instead (#2158).
|
||||
data-no-press
|
||||
tabIndex={0}
|
||||
className="relative aspect-square rounded-lg overflow-hidden cursor-pointer group"
|
||||
onClick={() => onPhotoClick(allPhotos, i)}
|
||||
|
||||
@@ -141,4 +141,15 @@ describe('VacaySharedCalendars', () => {
|
||||
|
||||
expect(shareWithMock).toHaveBeenCalledWith(2)
|
||||
})
|
||||
|
||||
it('FE-COMP-VACAYSHARED-008: Incoming row opts out of the global press-scale (#2158)', () => {
|
||||
// jsdom cannot replay the browser mechanics behind #2158: the :active scale on
|
||||
// the row shifted the remove X out from under the pointer, so the click retargeted
|
||||
// onto the row and only toggled visibility. The data-no-press attribute is the pin.
|
||||
seedShares({ incomingShares: [incoming] })
|
||||
|
||||
render(<VacaySharedCalendars />)
|
||||
|
||||
expect(screen.getByText('Carol').closest('[role="button"]')).toHaveAttribute('data-no-press')
|
||||
})
|
||||
})
|
||||
|
||||
@@ -78,6 +78,10 @@ export default function VacaySharedCalendars() {
|
||||
{incomingShares.map(s => (
|
||||
<div key={s.id}
|
||||
role="button"
|
||||
// No press-scale on the row: shrinking it mid-click slides the remove X
|
||||
// out from under the pointer, so the click retargets onto the row and
|
||||
// toggles visibility instead of removing the share (#2158).
|
||||
data-no-press
|
||||
tabIndex={0}
|
||||
onClick={() => handleToggleHidden(s.id, !s.hidden)}
|
||||
onKeyDown={e => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); handleToggleHidden(s.id, !s.hidden) } }}
|
||||
|
||||
Reference in New Issue
Block a user