Skip to content

Commit 81f68b6

Browse files
authored
Merge branch 'main' into feat/changelog-1
2 parents 5f4520f + 7a4871f commit 81f68b6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+6800
-150
lines changed

app/assets/main.css

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,17 @@
2424
--border-hover: oklch(0.371 0 0);
2525

2626
/* accent color, set by user from settings */
27-
--accent: var(--accent-color, oklch(1 0 0));
27+
--accent: var(--accent-color, oklch(0.787 0.128 230.318));
2828
--accent-muted: var(--accent-color, oklch(0.922 0 0));
2929

3030
/* accent colors */
31+
--swatch-sky: oklch(0.787 0.128 230.318);
3132
--swatch-coral: oklch(0.704 0.177 14.75);
3233
--swatch-amber: oklch(0.828 0.165 84.429);
3334
--swatch-emerald: oklch(0.792 0.153 166.95);
34-
--swatch-sky: oklch(0.787 0.128 230.318);
3535
--swatch-violet: oklch(0.78 0.148 286.067);
3636
--swatch-magenta: oklch(0.78 0.15 330);
37+
--swatch-neutral: oklch(1 0 0);
3738

3839
/* syntax highlighting colors */
3940
--syntax-fn: oklch(0.727 0.137 299.149);
@@ -94,16 +95,17 @@
9495
--border-subtle: oklch(0.922 0 0);
9596
--border-hover: oklch(0.715 0 0);
9697

97-
--accent: var(--accent-color, oklch(0.145 0 0));
98+
--accent: var(--accent-color, oklch(0.53 0.16 247.27));
9899
--accent-muted: var(--accent-color, oklch(0.205 0 0));
99100

100101
/* accent colors */
101-
--swatch-coral: oklch(0.7 0.19 14.75);
102-
--swatch-amber: oklch(0.8 0.25 84.429);
103-
--swatch-emerald: oklch(0.7 0.17 166.95);
104-
--swatch-sky: oklch(0.7 0.15 230.318);
105-
--swatch-violet: oklch(0.7 0.17 286.067);
106-
--swatch-magenta: oklch(0.75 0.18 330);
102+
--swatch-sky: oklch(0.53 0.16 247.27);
103+
--swatch-coral: oklch(0.56 0.17 10.75);
104+
--swatch-amber: oklch(0.58 0.18 46.34);
105+
--swatch-emerald: oklch(0.51 0.13 162.4);
106+
--swatch-violet: oklch(0.56 0.13 282.067);
107+
--swatch-magenta: oklch(0.56 0.14 325);
108+
--swatch-neutral: oklch(0.145 0 0);
107109

108110
--syntax-fn: oklch(0.502 0.188 294.988);
109111
--syntax-str: oklch(0.425 0.152 252);

app/components/Button/Base.stories.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ export const Disabled: Story = {
3939
export const WithIcon: Story = {
4040
args: {
4141
default: 'Search',
42-
classicon: 'i-carbon:search',
42+
classicon: 'i-lucide:search',
4343
variant: 'secondary',
4444
},
4545
}

app/components/ColumnPicker.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ function handleReset() {
8585
v-if="isOpen"
8686
ref="menuRef"
8787
:id="menuId"
88-
class="absolute top-full inset-ie-0 sm:inset-is-auto sm:inset-ie-0 mt-2 w-60 bg-bg-subtle border border-border rounded-lg shadow-lg z-20"
88+
class="absolute top-full inset-is-auto sm:inset-ie-0 mt-2 w-60 bg-bg-subtle border border-border rounded-lg shadow-lg z-20"
8989
role="group"
9090
:aria-label="$t('filters.columns.show')"
9191
>

app/components/Compare/PackageSelector.vue

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -183,18 +183,12 @@ watch(highlightedIndex, index => {
183183
}
184184
})
185185
186-
const { start, stop } = useTimeoutFn(() => {
187-
isInputFocused.value = false
188-
}, 200)
189-
190-
function handleBlur() {
191-
start()
192-
}
186+
const containerRef = useTemplateRef('containerRef')
193187
194-
function handleFocus() {
195-
stop()
196-
isInputFocused.value = true
197-
}
188+
onClickOutside(containerRef, () => {
189+
isInputFocused.value = false
190+
highlightedIndex.value = -1
191+
})
198192
</script>
199193

200194
<template>
@@ -226,7 +220,7 @@ function handleFocus() {
226220
</div>
227221

228222
<!-- Add package input -->
229-
<div v-if="packages.length < maxPackages" class="relative">
223+
<div v-if="packages.length < maxPackages" ref="containerRef" class="relative">
230224
<div class="relative group flex items-center">
231225
<label for="package-search" class="sr-only">
232226
{{ $t('compare.selector.search_label') }}
@@ -249,8 +243,8 @@ function handleFocus() {
249243
size="medium"
250244
class="w-full min-w-25 ps-7"
251245
aria-autocomplete="list"
252-
@focus="handleFocus"
253-
@blur="handleBlur"
246+
ref="inputRef"
247+
@focus="isInputFocused = true"
254248
@keydown="handleKeydown"
255249
/>
256250
</div>

app/components/Package/ListToolbar.vue

Lines changed: 5 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -157,11 +157,9 @@ function getSortKeyLabelKey(key: SortKey): string {
157157

158158
<div class="flex-1" />
159159

160-
<div
161-
class="flex flex-wrap items-center gap-3 sm:justify-end justify-between w-full sm:w-auto"
162-
>
160+
<div class="flex flex-col sm:flex-row items-start sm:items-center gap-3">
163161
<!-- Sort controls -->
164-
<div class="flex items-center gap-1 shrink-0 order-1 sm:order-1">
162+
<div class="flex items-center gap-1 shrink-0">
165163
<!-- Sort key dropdown -->
166164
<SelectField
167165
:label="$t('filters.sort.label')"
@@ -203,29 +201,15 @@ function getSortKeyLabelKey(key: SortKey): string {
203201
</div>
204202

205203
<!-- View mode toggle - mobile (left side, row 2) -->
206-
<div class="flex sm:hidden items-center gap-1 order-2">
207-
<ViewModeToggle v-model="viewMode" />
208-
</div>
209-
210-
<!-- Column picker - mobile (right side, row 2) -->
211-
<ColumnPicker
212-
v-if="viewMode === 'table'"
213-
class="flex sm:hidden order-3"
214-
:columns="columns"
215-
@toggle="emit('toggleColumn', $event)"
216-
@reset="emit('resetColumns')"
217-
/>
218-
219-
<!-- View mode toggle + Column picker - desktop (right side, row 1) -->
220-
<div class="hidden sm:flex items-center gap-1 order-2">
221-
<ViewModeToggle v-model="viewMode" />
222-
204+
<div class="flex flex-row-reverse sm:flex-row items-center gap-1">
223205
<ColumnPicker
224206
v-if="viewMode === 'table'"
225207
:columns="columns"
226208
@toggle="emit('toggleColumn', $event)"
227209
@reset="emit('resetColumns')"
228210
/>
211+
212+
<ViewModeToggle v-model="viewMode" />
229213
</div>
230214
</div>
231215
</div>
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<script setup lang="ts">
2+
import type { InstallSizeDiff } from '~/composables/useInstallSizeDiff'
3+
4+
const props = defineProps<{
5+
diff: InstallSizeDiff
6+
}>()
7+
8+
const bytesFormatter = useBytesFormatter()
9+
const numberFormatter = useNumberFormatter()
10+
11+
const sizePercent = computed(() => Math.round(props.diff.sizeRatio * 100))
12+
</script>
13+
14+
<template>
15+
<div
16+
class="border border-amber-600/40 bg-amber-500/10 rounded-lg px-3 py-2 text-base text-amber-800 dark:text-amber-400"
17+
>
18+
<h2 class="font-medium mb-1 flex items-center gap-2">
19+
<span class="i-lucide:trending-up w-4 h-4" aria-hidden="true" />
20+
{{
21+
diff.sizeThresholdExceeded && diff.depThresholdExceeded
22+
? $t('package.size_increase.title_both', { version: diff.comparisonVersion })
23+
: diff.sizeThresholdExceeded
24+
? $t('package.size_increase.title_size', { version: diff.comparisonVersion })
25+
: $t('package.size_increase.title_deps', { version: diff.comparisonVersion })
26+
}}
27+
</h2>
28+
<p class="text-sm m-0 mt-1">
29+
<i18n-t v-if="diff.sizeThresholdExceeded" keypath="package.size_increase.size" scope="global">
30+
<template #percent
31+
><strong>{{ sizePercent }}%</strong></template
32+
>
33+
<template #size
34+
><strong>{{ bytesFormatter.format(diff.sizeIncrease) }}</strong></template
35+
>
36+
</i18n-t>
37+
<template v-if="diff.sizeThresholdExceeded && diff.depThresholdExceeded"> · </template>
38+
<i18n-t v-if="diff.depThresholdExceeded" keypath="package.size_increase.deps" scope="global">
39+
<template #count
40+
><strong>+{{ numberFormatter.format(diff.depDiff) }}</strong></template
41+
>
42+
</i18n-t>
43+
</p>
44+
</div>
45+
</template>

app/components/Settings/AccentColorPicker.vue

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ const { accentColors, selectedAccentColor, setAccentColor } = useAccentColor()
55
66
onPrehydrate(el => {
77
const settings = JSON.parse(localStorage.getItem('npmx-settings') || '{}')
8+
const defaultId = 'sky'
89
const id = settings.accentColorId
910
if (id) {
1011
const input = el.querySelector<HTMLInputElement>(`input[value="${id}"]`)
@@ -13,10 +14,12 @@ onPrehydrate(el => {
1314
input.setAttribute('checked', '')
1415
}
1516
// 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')
17+
if (id !== defaultId) {
18+
const clearInput = el.querySelector<HTMLInputElement>(`input[value="${defaultId}"]`)
19+
if (clearInput) {
20+
clearInput.checked = false
21+
clearInput.removeAttribute('checked')
22+
}
2023
}
2124
}
2225
})
@@ -31,31 +34,19 @@ onPrehydrate(el => {
3134
v-for="color in accentColors"
3235
:key="color.id"
3336
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)"
37+
:class="color.id === 'neutral' ? 'flex items-center justify-center bg-fg' : ''"
3438
:style="{ backgroundColor: `var(--swatch-${color.id})` }"
3539
>
3640
<input
3741
type="radio"
3842
name="accent-color"
3943
class="sr-only"
4044
:value="color.id"
41-
:checked="selectedAccentColor === color.id"
42-
:aria-label="color.name"
45+
:checked="selectedAccentColor === color.id || (!selectedAccentColor && color.id === 'sky')"
46+
:aria-label="color.id === 'neutral' ? $t('settings.clear_accent') : color.name"
4347
@change="setAccentColor(color.id)"
4448
/>
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" />
49+
<span v-if="color.id === 'neutral'" class="i-lucide:ban size-4 text-bg" aria-hidden="true" />
5950
</label>
6051
</fieldset>
6152
</template>

app/components/Settings/BgThemePicker.vue

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,22 @@ const { backgroundThemes, selectedBackgroundTheme, setBackgroundTheme } = useBac
33
44
onPrehydrate(el => {
55
const settings = JSON.parse(localStorage.getItem('npmx-settings') || '{}')
6+
const defaultId = 'neutral'
67
const id = settings.preferredBackgroundTheme
78
if (id) {
89
const input = el.querySelector<HTMLInputElement>(`input[value="${id}"]`)
910
if (input) {
1011
input.checked = true
1112
input.setAttribute('checked', '')
1213
}
14+
// Remove checked from the server-default (clear button, value="")
15+
if (id !== defaultId) {
16+
const clearInput = el.querySelector<HTMLInputElement>(`input[value="${defaultId}"]`)
17+
if (clearInput) {
18+
clearInput.checked = false
19+
clearInput.removeAttribute('checked')
20+
}
21+
}
1322
}
1423
})
1524
</script>
@@ -30,7 +39,10 @@ onPrehydrate(el => {
3039
name="background-theme"
3140
class="sr-only"
3241
:value="theme.id"
33-
:checked="selectedBackgroundTheme === theme.id"
42+
:checked="
43+
selectedBackgroundTheme === theme.id ||
44+
(!selectedBackgroundTheme && theme.id === 'neutral')
45+
"
3446
:aria-label="theme.name"
3547
@change="setBackgroundTheme(theme.id)"
3648
/>

0 commit comments

Comments
 (0)