-
-
Notifications
You must be signed in to change notification settings - Fork 271
refactor(ui): fetch results on submit instead of on type #1107
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
Changes from all commits
fc08134
67a79b3
8f40b1d
ef876a2
e8ac1e1
ef5bec4
a772aa3
0791856
65e7cf1
c91e729
c7b2d2a
97861a1
e2b8a21
29a84e2
d4a3281
ce7e64b
cc69daf
2f09f27
3176d58
6cc780c
6c285e3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,95 @@ | ||
| <script setup lang="ts"> | ||
| defineProps<{ | ||
| compact?: boolean | ||
| }>() | ||
|
|
||
| const emit = defineEmits<{ | ||
| (e: 'submit', searchQuery: string): void | ||
| (e: 'blur'): void | ||
| (e: 'focus'): void | ||
| }>() | ||
|
|
||
| const searchQuery = defineModel<string>({ | ||
| default: '', | ||
| }) | ||
MatteoGabriele marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| function handleSubmit() { | ||
| emit('submit', searchQuery.value) | ||
| } | ||
|
|
||
| function handleBlur() { | ||
| emit('blur') | ||
| } | ||
| function handleFocus() { | ||
| emit('focus') | ||
| } | ||
|
|
||
| // Expose focus method for parent components | ||
| const inputRef = useTemplateRef('inputRef') | ||
| function focus() { | ||
| inputRef.value?.focus() | ||
| } | ||
|
|
||
| defineExpose({ | ||
| focus, | ||
| }) | ||
| </script> | ||
|
|
||
| <template> | ||
| <search class="w-full @container"> | ||
| <form method="GET" action="/search" class="relative" @submit.prevent="handleSubmit"> | ||
| <label for="search-box" class="sr-only"> | ||
| {{ $t('search.label') }} | ||
ghostdevv marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| </label> | ||
|
|
||
| <div class="relative group"> | ||
| <div | ||
| class="absolute -inset-px rounded-lg bg-gradient-to-r from-fg/0 via-fg/5 to-fg/0 opacity-0 transition-opacity duration-500 blur-sm group-[.is-focused]:opacity-100" | ||
| /> | ||
|
|
||
| <div class="search-box relative flex items-center"> | ||
| <span | ||
| class="absolute text-fg-subtle font-mono pointer-events-none transition-colors duration-200 motion-reduce:transition-none [.group:hover:not(:focus-within)_&]:text-fg/80 group-focus-within:text-accent z-1" | ||
| :class="compact ? 'inset-is-3 text-sm' : 'inset-is-4 text-xl'" | ||
| > | ||
| / | ||
| </span> | ||
|
|
||
| <input | ||
| id="search-box" | ||
| ref="inputRef" | ||
| v-model.trim="searchQuery" | ||
| type="search" | ||
| name="q" | ||
| :placeholder="$t('search.placeholder')" | ||
ghostdevv marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| v-bind="noCorrect" | ||
| class="w-full bg-bg-subtle border border-border text-base font-mono text-fg placeholder:text-fg-subtle transition-[border-color,outline-color] duration-300 motion-reduce:transition-none hover:border-fg-subtle outline-2 outline-transparent focus:border-accent focus-visible:(outline-2 outline-accent/70)" | ||
| :class=" | ||
| compact ? 'ps-7 pe-3 py-1.5 rounded-md text-sm!' : 'ps-8 pe-24 h-14 py-4 rounded-xl' | ||
| " | ||
| @blur="handleBlur" | ||
| @focus="handleFocus" | ||
| /> | ||
|
|
||
| <button | ||
| type="submit" | ||
| class="absolute hidden @xs:block group inset-ie-2.5 font-mono text-sm transition-[background-color,transform] duration-200 active:scale-95" | ||
| :class=" | ||
| compact | ||
| ? 'px-1.5 py-0.5 @md:ps-4 @md:pe-4' | ||
| : 'rounded-md px-2.5 @md:ps-4 @md:pe-4 py-2 text-bg bg-fg/90 hover:bg-fg! group-focus-within:bg-fg/80' | ||
| " | ||
| > | ||
| <span | ||
| class="inline-block i-carbon:search align-middle w-4 h-4 @md:me-2" | ||
| aria-hidden="true" | ||
| ></span> | ||
| <span class="sr-only @md:not-sr-only"> | ||
| {{ $t('search.button') }} | ||
ghostdevv marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| </span> | ||
| </button> | ||
| </div> | ||
| </div> | ||
| </form> | ||
| </search> | ||
| </template> | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -42,6 +42,7 @@ export function packumentToSearchResult( | |||||||||||||||||||||||||
| export interface NpmSearchOptions { | ||||||||||||||||||||||||||
| /** Number of results to fetch */ | ||||||||||||||||||||||||||
| size?: number | ||||||||||||||||||||||||||
| onResponse?: (result: { query: string }) => void | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| export const emptySearchResponse = { | ||||||||||||||||||||||||||
|
|
@@ -99,6 +100,8 @@ export function useNpmSearch( | |||||||||||||||||||||||||
| size: opts.size ?? 25, | ||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| opts.onResponse?.({ query: q }) | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| if (q !== toValue(query)) { | ||||||||||||||||||||||||||
| return emptySearchResponse | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
Comment on lines
+103
to
107
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The callback fires before verifying Consider moving the callback invocation after the stale check, or rename to Proposed fix const response = await searchAlgolia(q, {
size: opts.size ?? 25,
})
- opts.onResponse?.({ query: q })
-
if (q !== toValue(query)) {
return emptySearchResponse
}
+ opts.onResponse?.({ query: q })
+
isRateLimited.value = false📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||
|
|
@@ -130,6 +133,8 @@ export function useNpmSearch( | |||||||||||||||||||||||||
| }), | ||||||||||||||||||||||||||
| ]) | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| opts.onResponse?.({ query: q }) | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| if (!pkg) { | ||||||||||||||||||||||||||
| return emptySearchResponse | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
|
@@ -165,6 +170,8 @@ export function useNpmSearch( | |||||||||||||||||||||||||
| 60, | ||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| opts.onResponse?.({ query: q }) | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| // If query changed/outdated, return empty search response | ||||||||||||||||||||||||||
| if (q !== toValue(query)) { | ||||||||||||||||||||||||||
| return emptySearchResponse | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| import { debounce } from 'perfect-debounce' | ||
|
|
||
| export function usePackageSearchQuery() { | ||
| const searchQuery = useState<string>('package_search_query', () => '') | ||
|
|
||
| const route = useRoute() | ||
| onMounted(() => { | ||
| if (route.query.q) { | ||
| searchQuery.value = normalizeSearchParam(route.query.q) | ||
| } | ||
| }) | ||
|
|
||
| const updateSearchQuery = debounce((newSearchQuery: string) => { | ||
| searchQuery.value = newSearchQuery | ||
| }, 400) | ||
|
|
||
| return { | ||
| searchQuery, | ||
| updateSearchQuery, | ||
| } | ||
| } | ||
|
Comment on lines
+1
to
+21
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: # Search for normalizeSearchParam definition and usage
rg "normalizeSearchParam" --type=ts --type=vue -B2 -A2Repository: npmx-dev/npmx.dev Length of output: 88 🏁 Script executed: # Check the actual imports in usePackageSearchQuery.ts
cat app/composables/usePackageSearchQuery.tsRepository: npmx-dev/npmx.dev Length of output: 541 🏁 Script executed: # Check nuxt.config for auto-import configuration
fd "nuxt.config" -type f | xargs catRepository: npmx-dev/npmx.dev Length of output: 231 🏁 Script executed: # Search for normalizeSearchParam definition
rg "normalizeSearchParam" -A3 -B3Repository: npmx-dev/npmx.dev Length of output: 5756 🏁 Script executed: # Find nuxt.config files
find . -name "nuxt.config*" -type fRepository: npmx-dev/npmx.dev Length of output: 99 🏁 Script executed: # Check for utils/url.ts where normalizeSearchParam might be defined
find app -name "url.ts" -o -name "url.js"Repository: npmx-dev/npmx.dev Length of output: 43 🏁 Script executed: # Check nuxt.config for auto-import configuration
cat -n nuxt.config.tsRepository: npmx-dev/npmx.dev Length of output: 9567 🏁 Script executed: # Check the useStructuredFilters composable which also uses normalizeSearchParam
cat app/composables/useStructuredFilters.tsRepository: npmx-dev/npmx.dev Length of output: 14869 Add missing import for The composable uses |
||
Uh oh!
There was an error while loading. Please reload this page.