Skip to content

HOLD: Distinguish new-tab links from same-tab jumps#1687

Draft
maebeale wants to merge 1 commit into
mainfrom
maebeale/jump-link-behavior
Draft

HOLD: Distinguish new-tab links from same-tab jumps#1687
maebeale wants to merge 1 commit into
mainfrom
maebeale/jump-link-behavior

Conversation

@maebeale

Copy link
Copy Markdown
Collaborator

What is the goal of this PR and why is this important?

  • The box-arrow icon (fa-arrow-up-right-from-square) was used for two different behaviors: links that open in a new tab and links that just navigate in place (Turbo _top break-outs, drill-ins). Users couldn't tell what a link would do before clicking.
  • New-tab links also lacked the screen-reader warning WCAG G201 expects, and the icon's size was set ad-hoc per call site (text-[0.55rem], text-[10px], w-3 h-3, …).
  • Establishes one clear standard so the affordance always matches the behavior, grounded in NN/G and current accessibility guidance.

How did you approach the change?

  • New new_tab_link helper (app/helpers/application_helper.rb) is now the only origin of the box-arrow icon. It sets target="_blank" + rel="noopener" and appends screen-reader-only (opens in new tab) text. Named for the behavior (opens a new tab), not destination — these are internal links, not external sites.
  • Migrated every genuine new-tab link (payments, forms, event registrations, scholarships, events) to the helper — adding the missing a11y text and collapsing the size drift into one default.
  • Same-tab navigation now uses a directional arrow (fa-arrow-right) or no icon; the box-arrow no longer leaks onto in-place links. Also fixes the lone fa-external-link-alt outlier in taggings/index.
  • Documented the standard in .impeccable.md so future design work (and the impeccable skills) follow it.

How was it tested?

  • New helper specs cover target/rel merging, sr-only text, block form, and icon_class sizing.
  • Request specs that render the migrated views pass (payments, event_registrations, scholarships, grants, allocations, taggings, events — 350+ examples).
  • Rubocop clean.

Anything else to add?

Same-tab links were kept same-tab (the principled fix: prefer same-tab, just correct the icon). If any of those should actually open a new tab instead, that's a per-link product call — happy to flip specific ones.

🤖 Generated with Claude Code

The box-arrow icon was doing double duty: it marked links that open in a
new tab AND links that just navigate in place (Turbo `_top` break-outs,
drill-ins), so users couldn't trust what a link would do. New-tab links
also lacked the screen-reader warning WCAG G201 expects.

- Add `new_tab_link` helper as the single origin of the box-arrow icon:
  sets target=_blank + rel=noopener and appends sr-only "(opens in new
  tab)". Named for the behavior (new tab), not destination — these are
  internal links, not external sites.
- Migrate all genuine new-tab links to the helper, adding the missing
  a11y text and reconciling ad-hoc icon sizes.
- Same-tab navigation now uses a directional arrow (or no icon); the
  box-arrow no longer leaks onto in-place links. Fixes the lone
  fa-external-link-alt outlier too.
- Record the standard in .impeccable.md so future design work follows it.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
#
# <%= new_tab_link "View receipt", receipt_url, class: "underline" %>
# <%= new_tab_link grants_path, class: "..." do %>View all grants<% end %>
def new_tab_link(name = nil, options = nil, html_options = nil, &block)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

🤖 From Claude: This helper is intentionally the only place fa-arrow-up-right-from-square is emitted — that keeps the box-arrow meaning exactly "opens in a new tab" and prevents it from drifting back onto same-tab links. rel merges with any caller value (so rel: "noreferrer" becomes noreferrer noopener).

class: "relative block rounded-lg border border-gray-300 bg-white px-3 py-2 pr-8 transition-colors hover:border-gray-400 hover:bg-gray-50",
data: { turbo_frame: "_top" } do %>
<i class="fa-solid fa-arrow-up-right-from-square absolute right-2 top-2 text-[0.6rem] text-gray-400"></i>
<i class="fa-solid fa-arrow-right absolute right-2 top-2 text-[0.6rem] text-gray-400"></i>

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

🤖 From Claude: This link breaks out of the Turbo frame in the same tab (turbo_frame: "_top"), so it now uses a directional arrow instead of the box-arrow, which had implied a new window.

@maebeale maebeale changed the title Distinguish new-tab links from same-tab jumps HOLD: Distinguish new-tab links from same-tab jumps Jun 16, 2026
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