Skip to content

Comments

feat: accessible rings, accent colors & visual changes#904

Merged
danielroe merged 21 commits intonpmx-dev:mainfrom
jellydeck:visual-adjustments
Feb 4, 2026
Merged

feat: accessible rings, accent colors & visual changes#904
danielroe merged 21 commits intonpmx-dev:mainfrom
jellydeck:visual-adjustments

Conversation

@jellydeck
Copy link
Contributor

@jellydeck jellydeck commented Feb 4, 2026

closes #611
closes #633

  • use accent colors for focus rings in navbar
  • AppLogo component which changes color as per accent color
  • fixes in spacing for visual alignment
  • compare page searchbar icon aligned
  • copy package name button updates itself rather than calling popover for better UX

@vercel
Copy link

vercel bot commented Feb 4, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
npmx.dev Ready Ready Preview, Comment Feb 4, 2026 9:53am
2 Skipped Deployments
Project Deployment Actions Updated (UTC)
docs.npmx.dev Ignored Ignored Preview Feb 4, 2026 9:53am
npmx-lunaria Ignored Ignored Feb 4, 2026 9:53am

Request Review

@jellydeck jellydeck changed the title Visual adjustments feat: accessible rings, accent colors & visual changes Feb 4, 2026
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 4, 2026

📝 Walkthrough

Walkthrough

Restructures accent colours into theme-aware light/dark maps and updates lookups in prehydrate and the settings composable to select colours per current theme (including a type change for AccentColorId). Adds a new AppLogo Vue component and exposes it for tests. Replaces many focus-visible:ring-* utilities with focus-visible:outline-accent/70 or focus-visible:(outline-2 outline-accent/70), plus minor spacing/padding tweaks and two fixes to iterate reactive .value collections. Changes are primarily presentational; the only new public component prop is AppLogo's optional class prop.

Possibly related PRs

Suggested labels

idea

Suggested reviewers

  • danielroe
  • serhalp
  • wojtekmaj
🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description check ✅ Passed The PR description directly addresses the linked issues by describing changes to focus rings, accent colors, spacing fixes, and component updates.
Linked Issues check ✅ Passed The PR addresses both linked issues: #611 is resolved through systematic updates of focus styling across components to use accent-coloured outlines instead of rings, and #633 is addressed via accent colour adjustments in DownloadAnalytics.vue.
Out of Scope Changes check ✅ Passed All changes are directly related to focus styling improvements, accent colour implementation, and visual spacing adjustments. Minor scope additions like AppLogo component and button behaviour updates directly support the core objectives.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

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)
app/components/Header/ConnectorModal.vue (1)

165-173: ⚠️ Potential issue | 🟡 Minor

Avoid cancelling the accent outline on inputs.

focus-visible:outline-none suppresses the accent outline you just added, so the focus indication falls back to the default ring. Consider removing outline-none (and the ring if the outline is the intended cue).

Proposed adjustment
-            class="w-full px-3 py-2 font-mono text-sm bg-bg-subtle border border-border rounded-md text-fg placeholder:text-fg-subtle transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:outline-accent/70"
+            class="w-full px-3 py-2 font-mono text-sm bg-bg-subtle border border-border rounded-md text-fg placeholder:text-fg-subtle transition-colors duration-200 focus-visible:outline-accent/70"
-              class="w-full px-3 py-2 font-mono text-sm bg-bg-subtle border border-border rounded-md text-fg transition-colors duration-200 focus:border-border-hover focus-visible:outline-none focus-visible:ring-2 focus-visible:outline-accent/70"
+              class="w-full px-3 py-2 font-mono text-sm bg-bg-subtle border border-border rounded-md text-fg transition-colors duration-200 focus:border-border-hover focus-visible:outline-accent/70"

Also applies to: 189-197

🧹 Nitpick comments (1)
app/components/Package/ListToolbar.vue (1)

184-205: Consider updating the sort direction toggle button's focus styling for consistency.

The sort direction toggle button still uses ring-based focus styling (focus-visible:ring-2 focus-visible:ring-fg focus-visible:ring-offset-2), whilst the rest of this PR standardises on focus-visible:outline-accent/70. This creates a visual inconsistency.

♻️ Suggested fix
           <button
             v-if="!searchContext"
             type="button"
-            class="p-1.5 rounded border border-border bg-bg-subtle text-fg-muted hover:text-fg hover:border-border-hover transition-colors duration-200 focus-visible:ring-2 focus-visible:ring-fg focus-visible:ring-offset-2 focus-visible:ring-offset-bg"
+            class="p-1.5 rounded border border-border bg-bg-subtle text-fg-muted hover:text-fg hover:border-border-hover transition-colors duration-200 focus-visible:outline-accent/70"
             :aria-label="$t('filters.sort.toggle_direction')"

@github-actions
Copy link

github-actions bot commented Feb 4, 2026

Lunaria Status Overview

🌕 This pull request will trigger status changes.

Learn more

By default, every PR changing files present in the Lunaria configuration's files property will be considered and trigger status changes accordingly.

You can change this by adding one of the keywords present in the ignoreKeywords property in your Lunaria configuration file in the PR's title (ignoring all files) or by including a tracker directive in the merged commit's description.

Tracked Files

File Note
lunaria/files/ar-EG.json Localization changed, will be marked as complete.
lunaria/files/en-GB.json Localization changed, will be marked as complete.
lunaria/files/en-US.json Source changed, localizations will be marked as outdated.
lunaria/files/es-419.json Localization changed, will be marked as complete.
lunaria/files/es-ES.json Localization changed, will be marked as complete.
Warnings reference
Icon Description
🔄️ The source for this localization has been updated since the creation of this pull request, make sure all changes in the source have been applied.

@codecov
Copy link

codecov bot commented Feb 4, 2026

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

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

⚠️ Outside diff range comments (1)
app/components/Package/InstallScripts.vue (1)

32-46: ⚠️ Potential issue | 🟡 Minor

Add explicit outline width and offset to ensure visible focus indicators on both elements.

The global CSS in app/assets/main.css defines outline width for button:focus-visible and a:focus-visible, but the <dd> element on line 34 is not covered by those rules. Using focus-visible:outline-accent/70 alone sets only the outline colour without explicit width or offset, which risks a missing or imperceptible focus indicator. For consistency and to ensure accessibility across browsers, add explicit outline utilities:

Suggested fix
-          class="font-mono text-sm text-fg-subtle m-0 truncate focus:whitespace-normal focus:overflow-visible cursor-help rounded focus-visible:outline-accent/70"
+          class="font-mono text-sm text-fg-subtle m-0 truncate focus:whitespace-normal focus:overflow-visible cursor-help rounded focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent/70"
-        class="flex items-center gap-1.5 text-xs text-fg-muted hover:text-fg transition-colors duration-200 focus-visible:outline-accent/70 rounded"
+        class="flex items-center gap-1.5 text-xs text-fg-muted hover:text-fg transition-colors duration-200 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent/70 rounded"

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (6)
app/components/Header/AuthModal.client.vue (1)

102-102: ring-offset-* classes have no effect when used with outline.

The focus-visible:ring-offset-2 and focus-visible:ring-offset-bg utilities are designed to work with Tailwind's ring utilities (which use box-shadow), not with outline. These classes will be ignored since you're using outline-accent/70 instead of a ring.

For consistency with the disconnect button (line 37) and handle input (line 64), consider removing the ineffective ring-offset classes:

🧹 Proposed cleanup
       <button
         type="submit"
         :disabled="!handleInput.trim()"
-        class="w-full px-4 py-2 font-mono text-sm text-bg bg-fg rounded-md transition-all duration-200 hover:bg-fg/90 disabled:opacity-50 disabled:cursor-not-allowed focus-visible:outline-accent/70 focus-visible:ring-offset-2 focus-visible:ring-offset-bg"
+        class="w-full px-4 py-2 font-mono text-sm text-bg bg-fg rounded-md transition-all duration-200 hover:bg-fg/90 disabled:opacity-50 disabled:cursor-not-allowed focus-visible:outline-accent/70"
       >

Apply the same change to the create-account button (line 108) and Bluesky button (line 116).

Also applies to: 108-108, 116-116

app/components/Package/ListControls.vue (1)

78-86: Consider updating the select's focus styling for consistency.

The search input above uses the new accent-based focus styling (focus-visible:outline-accent/70), but the sort select still uses focus:(border-border-hover outline-none). While the global CSS in main.css provides select:focus-visible styling, the inline outline-none may override it.

Consider updating the select to match the input's focus styling pattern for visual consistency within this component.

♻️ Suggested change
         <select
           id="package-sort"
           v-model="sortValue"
-          class="appearance-none bg-bg-subtle border border-border rounded-lg ps-3 pe-8 py-2 font-mono text-sm text-fg cursor-pointer transition-colors duration-200 focus:(border-border-hover outline-none) hover:border-border-hover"
+          class="appearance-none bg-bg-subtle border border-border rounded-lg ps-3 pe-8 py-2 font-mono text-sm text-fg cursor-pointer transition-colors duration-200 focus:border-accent focus-visible:(outline-2 outline-accent/70) hover:border-border-hover"
         >
app/components/Package/MetricsBadges.vue (1)

68-71: Consider adding explicit outline width.

The focus styling uses focus-visible:outline-accent/70 which sets the colour, but unlike the previous ring-2, there's no explicit outline width. Depending on the UnoCSS configuration, this may rely on browser defaults or inherited values.

For consistency with other components in this PR (e.g., focus-visible:(outline-2 outline-accent/70) in ListControls.vue), consider adding an explicit width.

♻️ Suggested change
           typesHref
-              ? 'hover:text-fg hover:border-border-hover focus-visible:outline-accent/70'
+              ? 'hover:text-fg hover:border-border-hover focus-visible:(outline-2 outline-accent/70)'
               : '',
app/components/Package/Versions.vue (1)

365-365: Consider using outline instead of text colour for focus indication.

The version link uses focus-visible:text-accent which only changes text colour on focus. This may be less perceivable than an outline, especially for users with colour vision deficiencies. Consider using focus-visible:outline-accent/70 for consistency with other elements in this PR, or keep both for enhanced visibility.

app/composables/useSettings.ts (1)

9-9: Type assumption relies on light/dark key parity.

The type AccentColorId is derived solely from ACCENT_COLORS.light. This works correctly as long as both light and dark objects in ACCENT_COLORS have identical keys. Consider adding a compile-time check or a comment to document this invariant, so future maintainers don't accidentally break it.

app/utils/prehydrate.ts (1)

17-35: Hardcoded colour values must stay synchronised with ACCENT_COLORS.

The prehydrate callback is stringified, so hardcoding is necessary. However, this creates a maintenance burden: any change to ACCENT_COLORS in shared/utils/constants.ts must be manually mirrored here. Consider adding a comment referencing the source of truth, or a build-time/test-time check to detect drift.

📝 Suggested comment
     // Accent colors - hardcoded since ACCENT_COLORS can't be referenced
+    // IMPORTANT: Keep in sync with ACCENT_COLORS in shared/utils/constants.ts

     const colors = {

type="button"
class="px-2 py-0.5 font-mono text-xs text-fg-muted bg-bg-subtle/80 border border-border rounded transition-colors duration-200 opacity-0 group-hover/executecmd:opacity-100 hover:(text-fg border-border-hover) active:scale-95 focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-fg/50"
class="px-2 py-0.5 font-mono text-xs text-fg-muted bg-bg-subtle/80 border border-border rounded transition-colors duration-200 opacity-0 group-hover/executecmd:opacity-100 hover:(text-fg border-border-hover) active:scale-95 focus-visible:opacity-100 focus-visible:outline-accent/70"
:aria-label="$t('package.get_started.copy_command')"
Copy link
Member

Choose a reason for hiding this comment

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

I think these type of buttons should announce when copied with an aria-live section somewhere.... (probably beyond the scope of this PR, but just mentioning it as I saw your last commit)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

so that'd be something like this?

  <div aria-live="polite" aria-atomic="true" class="sr-only">
    {{ copiedPkgName ? $t('common.copied') : '' }}
  </div>

my naive guess with quick ai check.

@danielroe
Copy link
Member

just pushed a few changes to apply what you've done to more components, as well as address some clipping issues in the sidebar

would you check to make sure that everything still looks good to you? 🙏❤️

@jellydeck
Copy link
Contributor Author

just pushed a few changes to apply what you've done to more components, as well as address some clipping issues in the sidebar

would you check to make sure that everything still looks good to you? 🙏❤️

all clear 🫡

@danielroe danielroe added this pull request to the merge queue Feb 4, 2026
Merged via the queue into npmx-dev:main with commit ac1171a Feb 4, 2026
16 checks passed
@jellydeck jellydeck deleted the visual-adjustments branch February 4, 2026 09:59
<span
class="relative inline-flex h-6 w-11 shrink-0 items-center rounded-full border-2 transition-colors duration-200 ease-in-out motion-reduce:transition-none cursor-pointer"
:class="checked ? 'bg-accent border-transparent shadow-sm' : 'bg-bg border border-border'"
:class="checked ? 'bg-accent border-transparent shadow-sm' : 'bg-bg border border-border/50'"
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you explain this change? It seems to have just reduced the contrast for this border and I can't work out the upside from it?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

on light mode borders came out looking really harsh, so for a good visual effect modified the opacity. also, It passes accessibility tests.

Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm, on dark mode its pretty borderline to my eyes. Perhaps we can remove the opacity when prefers-contrast: more

Copy link
Contributor Author

Choose a reason for hiding this comment

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

then i suppose it's better without opacity, since there are plans for redesign. what do you think?

Copy link
Contributor

Choose a reason for hiding this comment

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

To my eyes it's better without opacity but I use high contrast mode so I mainly care about what it looks like in that mode. I'm happy to defer on standard mode if it's too contrasty for some, then a contrast-more:border-border should fix override the standard one with opacity.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

have a look at #1011

@garthdw
Copy link
Contributor

garthdw commented Feb 5, 2026

This PR seems to have reverted #881

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.

Download chart tooltip is not visible in light mode Missing focus indicators in banner connect menu [Safari/a11y]

4 participants