-
-
Notifications
You must be signed in to change notification settings - Fork 147
chore(ui): make package name selectable #594
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
chore(ui): make package name selectable #594
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
2 Skipped Deployments
|
|
this is a good change, but I'm not wild about adding ui elements to this part of the page. copying the package name is nice but 'discoverable' because you'd click on it anyway to copy it. can you think of another solution that isn't an extra icon/button? |
…Adebesin-Cell/npmx.dev into ux/make-package-name-selectable
Good point! I’ve updated the implementation to remove the extra icon/button entirely. The package name itself is now the click target for copying, but it’s rendered as plain text, so it can be selected normally. Let me know what you think! |
|
I like that it’s more easily selectable considering before it wasn’t immediately clear that there was a button there (presentational-to-semantic mismatch). With that said, it’s still acting like a button without any of the semantics. Users navigating by keyboard now have no way to copy the name (and
We don’t have to follow that conventional wisdom, but then that’s going to take a bit more intentioned research and design. |
|
what about adding a button that's has aria-text, is in the tab order and is only visible when tabbed to, a la skip to content? here's my thinking: copying a package name is a minor enough benefit we don't care if users know about it - they can discover it if/when they go to try to select the text... and adding an additional button-with-icon is not worth the visual distraction in this area. |
I think the least bad option given the current design and avoiding clutter would be to do something like this and you could even reveal said (perhaps visually labelled) button for sighted/mouse users when they hover the area. That could ensure folks could use the package scope link, select the package name, and have a distinct button to copy the package name. Where that falls short for accessibility purposes is that you aren’t really supposed to make stuff only show up on hover for various reasons (it also affects touch users who often can’t hover). It fails the “perceivable” principle of WCAG, but like I said, I think it could be the least bad option at least for now (doing weird things with UI overlap/omitting semantics is worse IMO). And I guess, even without a persistently visible labelled button, sighted mouse/touch users still do have the affordance of the text itself which they know they can select and copy, so it’s not like their access is being impeded. |
|
Quick sanity check before I tweak this again, would a real copy button that’s keyboard-accessible but only visible on focus (skip-link style, maybe also on hover) be an acceptable direction? Or would you prefer dropping the copy interaction altogether and just relying on normal text selection? cc: @danielroe |
|
let's go for the button, for now happy to remove the functionality later if there are a11y concerns but my reading of @knowler s comments indicates we are just about OK here |
Screen.Recording.2026-02-01.at.12.24.28.movLooks like this now! |
…selectable # Conflicts: # app/pages/[...package].vue
app/pages/[...package].vue
Outdated
| <button | ||
| @click="copyPkgName()" | ||
| aria-describedby="copy-pkg-name" | ||
| class="cursor-copy active:scale-95 transition-transform" | ||
| type="button" | ||
| @click="() => copyPkgName()" | ||
| class="opacity-100 sm:opacity-0 sm:group-hover:opacity-100 focus:opacity-100 transition-opacity p-2 rounded text-fg-muted hover:text-fg hover:bg-bg-subtle focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-fg/50 align-middle ms-1" | ||
| :aria-label="$t('package.copy_name')" | ||
| > | ||
| {{ orgName ? pkg.name.replace(`@${orgName}/`, '') : pkg.name }} | ||
| <span class="i-carbon:copy w-5 h-5 block" aria-hidden="true" /> | ||
| </button> | ||
| </TooltipAnnounce> | ||
| </h1> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now that the <button> is a distinct thing, it shouldn’t be within the <h1> element because it’s accessible name (i.e. “Copy package name”) is contributing to the accessible name of the <h1> element which means that it appears in page outlines (e.g. VoiceOver rotor, NVDA element list).
This is the very simplified structure I think it should have (obviously, keep whatever spans and whatnot within the <h1>):
<h1><a href>@nuxt</a>/devtools</h1>
<button>Copy package name</button>|
I think that the button shouldn’t take up space when it’s visible or hidden as it’s negatively affecting the layout. It should probably be floating in some way. I had (roughly) imagined something like this: demo (demo with “open in codepen” button)
I’m curious to hear what others think. cc: @danielroe Also, for situations without hover capabilities, I would just completely hide the button for now using a media query for the |
|
exactly 👍 |
…Adebesin-Cell/npmx.dev into ux/make-package-name-selectable
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Works good! I did a quick screen reader test with NVDA + Firefox on Windows 11 and VoiceOver on macOS + Safari 26.2, and it’s working as expected (the rotor/element listing is correct the headings + the focus order + visibility is good). I have not done a code review so I’ll defer to others for that.
Thanks for rolling with the design changes for this one.
Fixes #568
The package name in the header was difficult to select, especially for scoped packages, because it was split across interactive elements.
This PR refactors the header so the package name is rendered as plain text and is easy to select across all browsers. Clicking the package name still copies it to the clipboard, but the copy action is now suppressed when the user is actively selecting text, allowing normal text selection without accidental copies.
BEFORE:
Screen.Recording.2026-02-01.at.01.44.21.mov
AFTER:
Screen.Recording.2026-02-01.at.08.35.47.mov