forked from
npmx.dev/npmx.dev
[READ-ONLY]
a fast, modern browser for the npm registry
1<script setup lang="ts">
2import { useAccentColor } from '~/composables/useSettings'
3
4const { accentColors, selectedAccentColor, setAccentColor } = useAccentColor()
5
6onPrehydrate(el => {
7 const settings = JSON.parse(localStorage.getItem('npmx-settings') || '{}')
8 const id = settings.accentColorId
9 if (id) {
10 const input = el.querySelector<HTMLInputElement>(`input[value="${id}"]`)
11 if (input) {
12 input.checked = true
13 input.setAttribute('checked', '')
14 }
15 // Remove checked from the server-default (clear button, value="")
16 const clearInput = el.querySelector<HTMLInputElement>('input[value=""]')
17 if (clearInput) {
18 clearInput.checked = false
19 clearInput.removeAttribute('checked')
20 }
21 }
22})
23</script>
24
25<template>
26 <fieldset
27 class="flex items-center gap-4 has-[input:focus-visible]:(outline-solid outline-accent/70 outline-offset-4) rounded-xl w-fit"
28 >
29 <legend class="sr-only">{{ $t('settings.accent_colors') }}</legend>
30 <label
31 v-for="color in accentColors"
32 :key="color.id"
33 class="size-6 rounded-full transition-transform duration-150 motion-safe:hover:scale-110 has-[:checked]:(ring-2 ring-fg ring-offset-2 ring-offset-bg-subtle) has-[:focus-visible]:(ring-2 ring-fg ring-offset-2 ring-offset-bg-subtle)"
34 :style="{ backgroundColor: `var(--swatch-${color.id})` }"
35 >
36 <input
37 type="radio"
38 name="accent-color"
39 class="sr-only"
40 :value="color.id"
41 :checked="selectedAccentColor === color.id"
42 :aria-label="color.name"
43 @change="setAccentColor(color.id)"
44 />
45 </label>
46 <label
47 class="size-6 rounded-full transition-transform duration-150 motion-safe:hover:scale-110 has-[:checked]:(ring-2 ring-fg ring-offset-2 ring-offset-bg-subtle) has-[:focus-visible]:(ring-2 ring-fg ring-offset-2 ring-offset-bg-subtle) flex items-center justify-center bg-fg"
48 >
49 <input
50 type="radio"
51 name="accent-color"
52 class="sr-only"
53 value=""
54 :checked="selectedAccentColor === null"
55 :aria-label="$t('settings.clear_accent')"
56 @change="setAccentColor(null)"
57 />
58 <span class="i-lucide:ban size-4 text-bg" aria-hidden="true" />
59 </label>
60 </fieldset>
61</template>
62
63<style scoped>
64@media (forced-colors: active) {
65 /* keep accent radio swatches visible in forced colors. */
66 label {
67 forced-color-adjust: none;
68 border: 1px solid CanvasText;
69
70 &:has(> input:checked) {
71 outline: 2px solid Highlight;
72 outline-offset: 2px;
73 }
74 }
75}
76</style>