Skip to content

feat(jef-78): icon-only buttons on mobile - #218

Merged
mankatcheung merged 2 commits into
mainfrom
feat/jef-78-icon-only-buttons
Aug 4, 2026
Merged

mankatcheung merged 2 commits into
mainfrom
feat/jef-78-icon-only-buttons

Conversation

@mankatcheung

@mankatcheung mankatcheung commented Aug 4, 2026 •

Copy link
Copy Markdown
Owner

Summary

Converts text buttons to icon-only buttons on mobile (< sm) to save horizontal space. On desktop (>= sm), the current text + icon layout is preserved via hidden sm:inline on the text span.

33 buttons updated across 10 files with aria-label for accessibility.


Changes

Bulk action bar (applications/index.tsx)

  • Star, Unstar, Delete — text hidden on mobile, icons always visible

Application detail page (applicationId/index.tsx)

  • Add note, Save/Cancel (notes, interview rounds, contacts), Add interview round, Export to Calendar, Add contact, Confirm upload, Cancel (documents), Copy (cover letter), Preview (resume match)
  • Added CopyIcon, EyeIcon, XIcon imports

Notification inbox (-notification-inbox.tsx)

  • Mark read, Mark unread — added CheckCheckIcon, EyeOffIcon

Settings pages (profile, security, data, integrations)

  • Theme toggle (Light/Dark/System), Remove avatar, Unlink OAuth, I saved these codes, Sign out other sessions, Revoke session, Download/Import, Make default/Remove LLM, Copy/Done/Revoke API token

ErrorState component

  • Try again — added RefreshCwIcon

Pattern

For buttons that already have icons, wrap text in hidden span and add aria-label:

Add note

For buttons without icons, add icon + hidden span + aria-label:

Save

Tests

  • 243/243 passing (updated test queries to match new aria-labels)
  • Typecheck clean, lint clean (0 errors)

Summary by CodeRabbit

  • Accessibility

    • Added clear accessible labels to action buttons across applications, settings, security and integrations.
    • Improved screen-reader support for retry, import/export, session management, notification and profile actions.
  • Style

    • Added intuitive icons and improved button spacing and alignment throughout the authenticated experience.
    • Action labels now adapt responsively, keeping controls compact on smaller screens while retaining visible icons.
  • Tests

    • Updated interaction checks to reflect the improved accessible button names.

- Wrap button text in hidden sm:inline spans to hide on mobile
- Add lucide-react icons to buttons that lacked them (Save, Cancel, Copy, Preview, Mark read/unread, etc.)
- Add aria-labels to all updated buttons for accessibility
- Update 33 buttons across 10 files (applications, notifications, settings, ErrorState)
- Fix test queries to match new aria-labels
@coderabbitai

coderabbitai Bot commented Aug 4, 2026 •

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@mankatcheung, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 38 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: fdd3d9ec-61ac-4dae-b732-1379abc72429

📥 Commits

Reviewing files that changed from the base of the PR and between 4174982 and 64ff378.

📒 Files selected for processing (2)
  • apps/web/src/routes/_authenticated/applications/-board-page.tsx
  • apps/web/src/routes/_authenticated/applications/index.tsx

Walkthrough

The PR adds icons, explicit accessible labels, and responsive text visibility to action controls across application, notification, error, and settings pages. Related tests now use the updated accessible names.

Changes

Responsive action controls

Layer / File(s) Summary
Shared and application controls
apps/web/src/components/ErrorState.tsx, apps/web/src/routes/_authenticated/-notification-inbox.tsx, apps/web/src/routes/_authenticated/applications/...
Retry, notification, application detail, and bulk application actions now use icons, accessible labels, and responsive text labels.
Settings controls
apps/web/src/routes/_authenticated/settings/data.tsx, apps/web/src/routes/_authenticated/settings/integrations.tsx, apps/web/src/routes/_authenticated/settings/profile.tsx, apps/web/src/routes/_authenticated/settings/security.tsx
Settings actions now use icons, accessible labels, and responsive text layouts while preserving existing actions and state text.
Test selector updates
apps/web/src/__tests__/components/ApplicationsPage.test.tsx, apps/web/src/__tests__/components/settings/SettingsSecurityPage.test.tsx
Tests now target explicit accessible names for bulk application actions and session revocation.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related issues

Possibly related PRs

Poem

A rabbit checks each button’s name,
Adds icons bright without a game.
Small screens show the marks with care,
Labels stay clear everywhere.
Tests hop after, precise and spry.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarises the main change: buttons display icons only on mobile.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 2
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/jef-78-icon-only-buttons

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/web/src/routes/_authenticated/settings/data.tsx (1)

122-132: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Keep the import control labelled on small screens.

hidden sm:inline removes the only textual label below the sm breakpoint. The file input also uses className="hidden", so assistive technology receives no labelled, focusable import control. Keep the text visually hidden with sr-only sm:not-sr-only and make the input visually hidden but focusable with sr-only, or provide another keyboard-focusable control with an explicit accessible name.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/web/src/routes/_authenticated/settings/data.tsx` around lines 122 - 132,
Update the import control in the onImport flow so its accessible label remains
available below the sm breakpoint by changing the text span’s hidden styling to
sr-only sm:not-sr-only. Replace the file input’s hidden class with sr-only so it
remains visually hidden but focusable, preserving the existing importing state
and file-selection behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/web/src/routes/_authenticated/applications/`$applicationId/index.tsx:
- Around line 1988-1992: Update the copy button’s accessible feedback around the
copied state so assistive technology announces confirmation when copied is true.
Adjust the aria-label to reflect the existing copied value, or add a separate
aria-live element exposing “Copied,” while preserving the current visible label
behavior.

In `@apps/web/src/routes/_authenticated/settings/integrations.tsx`:
- Around line 211-230: Update the repeated action labels in
apps/web/src/routes/_authenticated/settings/integrations.tsx#L211-L230 to
include the row’s provider name for both Make default and Remove; update the
Revoke token label in
apps/web/src/routes/_authenticated/settings/integrations.tsx#L423-L429 to
include token.name; and update the Revoke session label in
apps/web/src/routes/_authenticated/settings/security.tsx#L557-L560 to include
the session device or user-agent.

---

Outside diff comments:
In `@apps/web/src/routes/_authenticated/settings/data.tsx`:
- Around line 122-132: Update the import control in the onImport flow so its
accessible label remains available below the sm breakpoint by changing the text
span’s hidden styling to sr-only sm:not-sr-only. Replace the file input’s hidden
class with sr-only so it remains visually hidden but focusable, preserving the
existing importing state and file-selection behavior.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 9b99ea87-8642-4ffb-9b0b-7cb6479e928a

📥 Commits

Reviewing files that changed from the base of the PR and between ff19511 and 4174982.

📒 Files selected for processing (10)
  • apps/web/src/__tests__/components/ApplicationsPage.test.tsx
  • apps/web/src/__tests__/components/settings/SettingsSecurityPage.test.tsx
  • apps/web/src/components/ErrorState.tsx
  • apps/web/src/routes/_authenticated/-notification-inbox.tsx
  • apps/web/src/routes/_authenticated/applications/$applicationId/index.tsx
  • apps/web/src/routes/_authenticated/applications/index.tsx
  • apps/web/src/routes/_authenticated/settings/data.tsx
  • apps/web/src/routes/_authenticated/settings/integrations.tsx
  • apps/web/src/routes/_authenticated/settings/profile.tsx
  • apps/web/src/routes/_authenticated/settings/security.tsx

Comment on lines +1988 to +1992
aria-label="Copy"
className="flex items-center gap-1 px-3 py-1.5 text-xs font-medium border border-gray-300 dark:border-gray-600 rounded-lg text-gray-600 dark:text-gray-400 hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors"
>
{copied ? '✓ Copied' : 'Copy'}
<CopyIcon size={14} />{' '}
<span className="hidden sm:inline">{copied ? '✓ Copied' : 'Copy'}</span>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Expose the copy result to assistive technology.

aria-label="Copy" overrides the child text. When copied becomes true, the accessible name remains Copy, so a screen reader receives no confirmation. Make the label reflect copied or expose Copied through a separate aria-live element.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/web/src/routes/_authenticated/applications/`$applicationId/index.tsx
around lines 1988 - 1992, Update the copy button’s accessible feedback around
the copied state so assistive technology announces confirmation when copied is
true. Adjust the aria-label to reflect the existing copied value, or add a
separate aria-live element exposing “Copied,” while preserving the current
visible label behavior.

Comment on lines +211 to +230
aria-label="Make default"
className="flex items-center gap-1 text-xs text-blue-600 hover:underline disabled:opacity-60"
>
{settingDefaultProvider === key.provider ? 'Setting…' : 'Make default'}
<StarIcon size={14} />{' '}
<span className="hidden sm:inline">
{settingDefaultProvider === key.provider ? 'Setting…' : 'Make default'}
</span>
</button>
)}
<button
type="button"
onClick={() => onRemoveLlmApiKey(key.provider)}
disabled={removingProvider === key.provider}
className="text-xs text-red-600 hover:underline disabled:opacity-60"
aria-label="Remove"
className="flex items-center gap-1 text-xs text-red-600 hover:underline disabled:opacity-60"
>
{removingProvider === key.provider ? 'Removing…' : 'Remove'}
<Trash2Icon size={14} />{' '}
<span className="hidden sm:inline">
{removingProvider === key.provider ? 'Removing…' : 'Remove'}
</span>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Include the target resource in repeated action labels.

The new aria-label values are identical across repeated rows. Because aria-label replaces the button content as the accessible name, a screen reader cannot identify the provider, token, or session that the focused button will affect. Build each label from the row identity.

  • apps/web/src/routes/_authenticated/settings/integrations.tsx#L211-L230: include the provider name in Make default and Remove.
  • apps/web/src/routes/_authenticated/settings/integrations.tsx#L423-L429: include token.name in Revoke token.
  • apps/web/src/routes/_authenticated/settings/security.tsx#L557-L560: include the session device or user-agent in Revoke session.
📍 Affects 2 files
  • apps/web/src/routes/_authenticated/settings/integrations.tsx#L211-L230 (this comment)
  • apps/web/src/routes/_authenticated/settings/integrations.tsx#L423-L429
  • apps/web/src/routes/_authenticated/settings/security.tsx#L557-L560
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/web/src/routes/_authenticated/settings/integrations.tsx` around lines
211 - 230, Update the repeated action labels in
apps/web/src/routes/_authenticated/settings/integrations.tsx#L211-L230 to
include the row’s provider name for both Make default and Remove; update the
Revoke token label in
apps/web/src/routes/_authenticated/settings/integrations.tsx#L423-L429 to
include token.name; and update the Revoke session label in
apps/web/src/routes/_authenticated/settings/security.tsx#L557-L560 to include
the session device or user-agent.

@github-actions

github-actions Bot commented Aug 4, 2026 •

Copy link
Copy Markdown

@mankatcheung
mankatcheung merged commit 7e3ab3b into main Aug 4, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant