Skip to content

Commit ca7c6d5

Browse files
authored
chore: release v0.1.0 (#1878)
2 parents 45d0baf + 2ea6f11 commit ca7c6d5

File tree

8 files changed

+116
-4
lines changed

8 files changed

+116
-4
lines changed

.github/workflows/release-tag.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ jobs:
7777
env:
7878
VERSION: ${{ steps.version.outputs.next }}
7979
run: |
80+
git config user.name "github-actions[bot]"
81+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
8082
git tag -a "$VERSION" -m "Release $VERSION"
8183
git push origin "$VERSION"
8284

app/app.vue

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,17 @@ if (import.meta.server) {
4848
}
4949
5050
const keyboardShortcuts = useKeyboardShortcuts()
51+
const { settings } = useSettings()
5152
5253
onKeyDown(
5354
'/',
5455
e => {
56+
if (e.ctrlKey) {
57+
e.preventDefault()
58+
settings.value.instantSearch = !settings.value.instantSearch
59+
return
60+
}
61+
5562
if (!keyboardShortcuts.value || isEditableElement(e.target)) return
5663
e.preventDefault()
5764

app/components/InstantSearch.vue

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<script setup lang="ts">
2+
import { useSettings } from '~/composables/useSettings'
3+
4+
const { settings } = useSettings()
5+
6+
onPrehydrate(el => {
7+
const settingsSaved = JSON.parse(localStorage.getItem('npmx-settings') || '{}')
8+
const enabled = settingsSaved.instantSearch
9+
if (enabled === false) {
10+
el.querySelector('[data-instant-search-on]')!.className = 'hidden'
11+
el.querySelector('[data-instant-search-off]')!.className = ''
12+
}
13+
})
14+
</script>
15+
16+
<template>
17+
<p id="instant-search-advisory" class="text-fg-muted text-sm text-pretty">
18+
<span
19+
class="i-lucide:zap align-middle text-fg relative top-[-0.1em] me-1"
20+
style="font-size: 0.8em"
21+
aria-hidden="true"
22+
/>
23+
<span data-instant-search-on :class="settings.instantSearch ? '' : 'hidden'">
24+
<i18n-t keypath="search.instant_search_advisory">
25+
<template #label>
26+
{{ $t('search.instant_search') }}
27+
</template>
28+
<template #state>
29+
<strong>{{ $t('search.instant_search_on') }}</strong>
30+
</template>
31+
<template #action>
32+
<button type="button" class="underline" @click="settings.instantSearch = false">
33+
{{ $t('search.instant_search_turn_off') }}
34+
</button>
35+
</template>
36+
</i18n-t>
37+
</span>
38+
<span data-instant-search-off :class="settings.instantSearch ? 'hidden' : ''">
39+
<i18n-t keypath="search.instant_search_advisory">
40+
<template #label>
41+
{{ $t('search.instant_search') }}
42+
</template>
43+
<template #state>
44+
<strong>{{ $t('search.instant_search_off') }}</strong>
45+
</template>
46+
<template #action>
47+
<button type="button" class="underline" @click="settings.instantSearch = true">
48+
{{ $t('search.instant_search_turn_on') }}
49+
</button>
50+
</template>
51+
</i18n-t>
52+
</span>
53+
</p>
54+
</template>

app/pages/index.vue

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,15 +52,20 @@ defineOgImageComponent('Default', {
5252
{{ $t('tagline') }}
5353
</p>
5454
<search
55-
class="w-full max-w-xl motion-safe:animate-slide-up motion-safe:animate-fill-both"
55+
class="w-full max-w-2xl motion-safe:animate-slide-up motion-safe:animate-fill-both"
5656
style="animation-delay: 0.2s"
5757
>
58-
<form method="GET" action="/search" class="relative" @submit.prevent.trim="search">
58+
<form
59+
method="GET"
60+
action="/search"
61+
class="relative grid justify-items-center gap-4"
62+
@submit.prevent.trim="search"
63+
>
5964
<label for="home-search" class="sr-only">
6065
{{ $t('search.label') }}
6166
</label>
6267

63-
<div class="relative group" :class="{ 'is-focused': isSearchFocused }">
68+
<div class="relative group w-full max-w-xl" :class="{ 'is-focused': isSearchFocused }">
6469
<div
6570
class="absolute z-1 -inset-px pointer-events-none rounded-lg bg-gradient-to-r from-fg/0 to-accent/5 opacity-0 transition-opacity duration-500 blur-sm group-[.is-focused]:opacity-100"
6671
/>
@@ -82,6 +87,7 @@ defineOgImageComponent('Default', {
8287
no-correct
8388
size="large"
8489
class="w-full ps-8 pe-24"
90+
aria-describedby="instant-search-advisory"
8591
@focus="isSearchFocused = true"
8692
@blur="isSearchFocused = false"
8793
/>
@@ -98,6 +104,8 @@ defineOgImageComponent('Default', {
98104
</ButtonBase>
99105
</div>
100106
</div>
107+
108+
<InstantSearch />
101109
</form>
102110
</search>
103111

i18n/locales/en.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,13 @@
6565
"org": "org",
6666
"view_user_packages": "View packages by this user",
6767
"view_org_packages": "View packages by this organization"
68-
}
68+
},
69+
"instant_search": "Instant search",
70+
"instant_search_on": "on",
71+
"instant_search_off": "off",
72+
"instant_search_turn_on": "turn on",
73+
"instant_search_turn_off": "turn off",
74+
"instant_search_advisory": "{label} {state} — {action}"
6975
},
7076
"nav": {
7177
"main_navigation": "Main",

i18n/schema.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,24 @@
201201
}
202202
},
203203
"additionalProperties": false
204+
},
205+
"instant_search": {
206+
"type": "string"
207+
},
208+
"instant_search_on": {
209+
"type": "string"
210+
},
211+
"instant_search_off": {
212+
"type": "string"
213+
},
214+
"instant_search_turn_on": {
215+
"type": "string"
216+
},
217+
"instant_search_turn_off": {
218+
"type": "string"
219+
},
220+
"instant_search_advisory": {
221+
"type": "string"
204222
}
205223
},
206224
"additionalProperties": false

nuxt.config.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,14 @@ export default defineNuxtConfig({
136136
// never cache
137137
'/api/auth/**': { isr: false, cache: false },
138138
'/api/social/**': { isr: false, cache: false },
139+
'/api/atproto/bluesky-author-profiles': {
140+
isr: {
141+
expiration: 60 * 60 /* one hour */,
142+
passQuery: true,
143+
allowQuery: ['authors'],
144+
},
145+
cache: { maxAge: 3600 },
146+
},
139147
'/api/opensearch/suggestions': {
140148
isr: {
141149
expiration: 60 * 60 * 24 /* one day */,

test/nuxt/a11y.spec.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ import {
156156
HeaderAccountMenu,
157157
HeaderConnectorModal,
158158
HeaderSearchBox,
159+
InstantSearch,
159160
InputBase,
160161
LicenseDisplay,
161162
LoadingSpinner,
@@ -2657,6 +2658,14 @@ describe('component accessibility audits', () => {
26572658
})
26582659
})
26592660

2661+
describe('InstantSearch', () => {
2662+
it('should have no accessibility violations', async () => {
2663+
const component = await mountSuspended(InstantSearch)
2664+
const results = await runAxe(component)
2665+
expect(results.violations).toEqual([])
2666+
})
2667+
})
2668+
26602669
describe('SearchProviderToggle', () => {
26612670
it('should have no accessibility violations', async () => {
26622671
const component = await mountSuspended(SearchProviderToggle)

0 commit comments

Comments
 (0)