feat: add button press feedback
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
# Button Press Feedback Design
|
||||
|
||||
## Context
|
||||
|
||||
Buttons currently change on hover, but many provide little or no visible acknowledgment while the pointer is pressed. The interface mixes a shared Base UI button with native buttons, so changing only the shared component would leave inconsistent behavior.
|
||||
|
||||
## Chosen interaction
|
||||
|
||||
Apply one CSS press vocabulary to every enabled native button. During `:active`, the button compresses to `scale(0.97)`, loses raised shadow, and receives a restrained brightness change. The transition lasts 140 ms and uses an ease-out-quint curve (`cubic-bezier(0.22, 1, 0.36, 1)`). This reads as a physical press without bounce, ripple, layout movement, or JavaScript state.
|
||||
|
||||
The existing one-pixel translation on the shared button is removed so shared and native buttons do not combine two motion patterns.
|
||||
|
||||
## Accessibility
|
||||
|
||||
Under `prefers-reduced-motion: reduce`, scale is disabled. The brightness and shadow change remain, providing a clear pressed state without kinetic motion. Disabled buttons receive no press treatment.
|
||||
|
||||
## Verification
|
||||
|
||||
A focused contract test checks the global enabled-button selector, scale, timing, easing, and reduced-motion override. The full frontend suite and typecheck guard regressions. Playwright then holds a real button in the active state and confirms its computed transform, followed by a visual screenshot/snapshot check.
|
||||
@@ -0,0 +1,72 @@
|
||||
# Button Press Feedback Implementation Plan
|
||||
|
||||
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
|
||||
|
||||
**Goal:** Give every enabled button immediate, consistent click acknowledgment while preserving a non-kinetic reduced-motion alternative.
|
||||
|
||||
**Architecture:** Define the interaction once in the global Tailwind base layer so both Base UI and native buttons inherit it. Remove the shared button's older translation-only active state to avoid compounded transforms. Verify the CSS contract first, then exercise the real interaction in Playwright.
|
||||
|
||||
**Tech Stack:** React 18, Tailwind CSS 3, Vitest, Playwright CLI.
|
||||
|
||||
---
|
||||
|
||||
### Task 1: Specify the global press contract
|
||||
|
||||
**Files:**
|
||||
- Create: `frontend/src/button-press-feedback.test.ts`
|
||||
- Test: `frontend/src/button-press-feedback.test.ts`
|
||||
|
||||
**Step 1: Write the failing test**
|
||||
|
||||
Read `src/index.css` and assert the enabled-button active selector, `scale(0.97)`, 140 ms duration, ease-out-quint curve, disabled exclusion, and reduced-motion transform override. Assert that `components/ui/button.tsx` no longer contains the legacy translation active class.
|
||||
|
||||
**Step 2: Run test to verify it fails**
|
||||
|
||||
Run: `npx vitest run src/button-press-feedback.test.ts`
|
||||
|
||||
Expected: FAIL because the global press rules do not exist and the shared button still uses translation.
|
||||
|
||||
### Task 2: Implement the press feedback
|
||||
|
||||
**Files:**
|
||||
- Modify: `frontend/src/index.css`
|
||||
- Modify: `frontend/src/components/ui/button.tsx`
|
||||
- Test: `frontend/src/button-press-feedback.test.ts`
|
||||
|
||||
**Step 1: Add the minimal CSS**
|
||||
|
||||
Add a global enabled-button transition and active state using only transform, filter, and shadow. Add a `prefers-reduced-motion` override that removes scale while preserving non-kinetic contrast feedback.
|
||||
|
||||
**Step 2: Remove the legacy shared-button translation**
|
||||
|
||||
Delete `active:not-aria-[haspopup]:translate-y-px` from the shared variant base string.
|
||||
|
||||
**Step 3: Run the focused test**
|
||||
|
||||
Run: `npx vitest run src/button-press-feedback.test.ts`
|
||||
|
||||
Expected: PASS.
|
||||
|
||||
### Task 3: Verify regressions and real-browser behavior
|
||||
|
||||
**Files:**
|
||||
- Verify: `frontend/src/index.css`
|
||||
- Verify: `frontend/src/components/ui/button.tsx`
|
||||
|
||||
**Step 1: Run frontend verification**
|
||||
|
||||
Run: `npx vitest run`
|
||||
|
||||
Run: `npx tsc -b`
|
||||
|
||||
Expected: all tests pass and typecheck exits 0.
|
||||
|
||||
**Step 2: Verify in Playwright**
|
||||
|
||||
Open `http://localhost:5173`, hold pointer-down on an enabled button, and inspect its computed transform and filter before release. Repeat with reduced motion emulation and confirm transform remains `none` while contrast feedback remains.
|
||||
|
||||
**Step 3: Review the final diff**
|
||||
|
||||
Run: `git diff --check` and inspect `git diff --stat`.
|
||||
|
||||
Expected: no whitespace errors and only the intended product/design, CSS, component, and test files changed.
|
||||
Reference in New Issue
Block a user