fix(desktop): keep profile edit button out of screenshots

The profile edit affordance is useful but low-frequency, and it was always visible in the token activity header. Hide it by default so shared screenshots keep the profile header clean while hover and keyboard focus still expose the action.

Constraint: The edit action must remain discoverable for pointer users and reachable for keyboard users.
Rejected: Remove the edit button entirely | profile customization still needs an obvious local entry point.
Confidence: high
Scope-risk: narrow
Reversibility: clean
Tested: cd desktop && bun run test -- src/pages/ActivitySettings.test.tsx --run --reporter=verbose --pool=forks --maxWorkers=1 --minWorkers=1
Tested: git diff --check -- desktop/src/pages/ActivitySettings.tsx desktop/src/pages/ActivitySettings.test.tsx
Not-tested: Manual packaged desktop screenshot capture.
This commit is contained in:
程序员阿江(Relakkes) 2026-06-01 02:01:20 +08:00
parent a09d9aa009
commit c2feac8220
2 changed files with 14 additions and 2 deletions

View File

@ -227,6 +227,18 @@ describe('ActivitySettings', () => {
expect(screen.queryByText('Selected day')).not.toBeInTheDocument()
})
it('keeps the profile edit control out of screenshots until hover or keyboard focus', async () => {
render(<ActivitySettings />)
await flushActivityLoad()
const editButton = screen.getByRole('button', { name: 'Edit profile' })
expect(editButton).toHaveClass('opacity-0')
expect(editButton).toHaveClass('group-hover/activity-profile:opacity-100')
expect(editButton).toHaveClass('focus-visible:opacity-100')
expect(editButton.closest('div')).toHaveClass('group/activity-profile')
})
it('supports localized heatmap mode switches and persisted display name edits', async () => {
useSettingsStore.setState({ locale: 'zh' })
render(<ActivitySettings />)

View File

@ -573,13 +573,13 @@ export function ActivitySettings() {
}}
/>
</div>
<div className="mt-6 flex max-w-full items-center justify-center gap-2">
<div className="group/activity-profile mt-6 flex max-w-full items-center justify-center gap-2">
<h1 className="max-w-[min(720px,calc(100%-2.25rem))] truncate text-4xl font-semibold tracking-tight text-[var(--color-text-primary)] sm:text-[44px]">{profile.displayName}</h1>
<button
type="button"
aria-label={t('settings.activity.editProfile')}
title={t('settings.activity.editProfile')}
className="mt-1 inline-flex h-7 w-7 shrink-0 items-center justify-center rounded-md text-[var(--color-text-tertiary)] transition-[background-color,color,transform] hover:bg-[var(--color-surface-hover)] hover:text-[var(--color-text-primary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-brand)] focus:ring-offset-2 focus:ring-offset-[var(--color-surface)] active:translate-y-[1px] disabled:opacity-50"
className="mt-1 inline-flex h-7 w-7 shrink-0 items-center justify-center rounded-md text-[var(--color-text-tertiary)] opacity-0 transition-[background-color,color,opacity,transform] group-hover/activity-profile:opacity-100 hover:bg-[var(--color-surface-hover)] hover:text-[var(--color-text-primary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-brand)] focus:ring-offset-2 focus:ring-offset-[var(--color-surface)] focus-visible:opacity-100 active:translate-y-[1px] disabled:pointer-events-none disabled:opacity-0"
onClick={() => {
setIsEditingProfile(true)
setDraftDisplayName(profile.displayName)