[READ-ONLY] a fast, modern browser for the npm registry
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

refactor: prefer `VueUse` where possible (#267)

Co-authored-by: Daniel Roe <daniel@roe.dev>

authored by

Vida Xie
Daniel Roe
and committed by
GitHub
fb62aa75 e53da338

+27 -58
-1
app/components/AppHeader.vue
··· 94 94 :placeholder="$t('search.placeholder')" 95 95 v-bind="noCorrect" 96 96 class="w-full bg-bg-subtle border border-border rounded-md pl-7 pr-3 py-1.5 font-mono text-sm text-fg placeholder:text-fg-subtle transition-border-color duration-300 motion-reduce:transition-none focus:border-accent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent/50" 97 - autocomplete="off" 98 97 @input="handleSearchInput" 99 98 @focus="isSearchFocused = true" 100 99 @blur="isSearchFocused = false"
+2 -12
app/components/CodeMobileTreeDrawer.vue
··· 18 18 }, 19 19 ) 20 20 21 + const isLocked = useScrollLock(document) 21 22 // Prevent body scroll when drawer is open 22 - watch(isOpen, open => { 23 - if (open) { 24 - document.body.style.overflow = 'hidden' 25 - } else { 26 - document.body.style.overflow = '' 27 - } 28 - }) 29 - 30 - // Cleanup on unmount 31 - onUnmounted(() => { 32 - document.body.style.overflow = '' 33 - }) 23 + watch(isOpen, open => (isLocked.value = open)) 34 24 </script> 35 25 36 26 <template>
+3 -12
app/components/DependencyPathPopup.vue
··· 4 4 path: readonly string[] 5 5 }>() 6 6 7 - const { t } = useI18n() 8 - 9 7 const isOpen = shallowRef(false) 10 8 const popupEl = ref<HTMLElement | null>(null) 11 9 const popupPosition = shallowRef<{ top: number; left: number } | null>(null) ··· 29 27 if (e.key === 'Escape') closePopup() 30 28 } 31 29 32 - onMounted(() => { 33 - document.addEventListener('keydown', handleKeydown) 34 - window.addEventListener('scroll', closePopup, true) 35 - }) 36 - 37 - onUnmounted(() => { 38 - document.removeEventListener('keydown', handleKeydown) 39 - window.removeEventListener('scroll', closePopup, true) 40 - }) 30 + useEventListener(document, 'keydown', handleKeydown) 31 + useEventListener('scroll', closePopup, true) 41 32 42 33 function togglePopup(event: MouseEvent) { 43 34 if (isOpen.value) { ··· 81 72 @click.stop="togglePopup" 82 73 > 83 74 <span class="i-carbon-tree-view w-3 h-3" aria-hidden="true" /> 84 - <span>{{ t('package.vulnerabilities.path') }}</span> 75 + <span>{{ $t('package.vulnerabilities.path') }}</span> 85 76 </button> 86 77 87 78 <!-- Tree popup -->
+6 -11
app/components/OperationsQueue.vue
··· 103 103 } 104 104 105 105 // Auto-refresh while executing 106 - let refreshInterval: ReturnType<typeof setInterval> | null = null 106 + const { pause: pauseRefresh, resume: resumeRefresh } = useIntervalFn(() => refreshState(), 1000, { 107 + immediate: false, 108 + }) 107 109 watch(isExecuting, executing => { 108 110 if (executing) { 109 - refreshInterval = setInterval(() => refreshState(), 1000) 110 - } else if (refreshInterval) { 111 - clearInterval(refreshInterval) 112 - refreshInterval = null 113 - } 114 - }) 115 - 116 - onUnmounted(() => { 117 - if (refreshInterval) { 118 - clearInterval(refreshInterval) 111 + resumeRefresh() 112 + } else { 113 + pauseRefresh() 119 114 } 120 115 }) 121 116 </script>
+10 -12
app/components/PackageVulnerabilityTree.vue
··· 7 7 version: string 8 8 }>() 9 9 10 - const { t } = useI18n() 11 - 12 10 const { 13 11 data: vulnTree, 14 12 status, ··· 34 32 if (!vulnTree.value) return '' 35 33 const { totalCounts } = vulnTree.value 36 34 return SEVERITY_LEVELS.filter(s => totalCounts[s] > 0) 37 - .map(s => `${totalCounts[s]} ${t(`package.vulnerabilities.severity.${s}`)}`) 35 + .map(s => `${totalCounts[s]} ${$t(`package.vulnerabilities.severity.${s}`)}`) 38 36 .join(', ') 39 37 }) 40 38 ··· 83 81 <span class="i-carbon-warning-alt w-4 h-4 shrink-0" aria-hidden="true" /> 84 82 <span class="font-mono text-sm font-medium truncate"> 85 83 {{ 86 - t( 84 + $t( 87 85 'package.vulnerabilities.tree_found', 88 86 { 89 87 vulns: vulnTree!.totalCounts.total, ··· 137 135 class="px-1.5 py-0.5 text-[10px] font-mono rounded border" 138 136 :class="SEVERITY_COLORS[s]" 139 137 > 140 - {{ pkg.counts[s] }} {{ t(`package.vulnerabilities.severity.${s}`) }} 138 + {{ pkg.counts[s] }} {{ $t(`package.vulnerabilities.severity.${s}`) }} 141 139 </span> 142 140 </div> 143 141 </div> ··· 159 157 <span class="truncate">{{ vuln.summary }}</span> 160 158 </li> 161 159 <li v-if="pkg.vulnerabilities.length > 2" class="text-xs text-fg-subtle"> 162 - {{ t('package.vulnerabilities.more', { count: pkg.vulnerabilities.length - 2 }) }} 160 + {{ $t('package.vulnerabilities.more', { count: pkg.vulnerabilities.length - 2 }) }} 163 161 </li> 164 162 </ul> 165 163 </li> ··· 172 170 @click="showAllPackages = true" 173 171 > 174 172 {{ 175 - t('package.vulnerabilities.show_all_packages', { 173 + $t('package.vulnerabilities.show_all_packages', { 176 174 count: vulnTree!.vulnerablePackages.length, 177 175 }) 178 176 }} ··· 184 182 class="px-4 py-2 text-xs text-fg-subtle border-t border-border flex items-center gap-2" 185 183 > 186 184 <span class="i-carbon-warning w-3 h-3" aria-hidden="true" /> 187 - <span>{{ t('package.vulnerabilities.packages_failed', vulnTree!.failedQueries) }}</span> 185 + <span>{{ $t('package.vulnerabilities.packages_failed', vulnTree!.failedQueries) }}</span> 188 186 </div> 189 187 </div> 190 188 </div> ··· 201 199 class="i-carbon-circle-dash w-4 h-4 animate-spin motion-reduce:animate-none text-fg-subtle" 202 200 aria-hidden="true" 203 201 /> 204 - <span class="text-sm text-fg-muted">{{ t('package.vulnerabilities.scanning_tree') }}</span> 202 + <span class="text-sm text-fg-muted">{{ $t('package.vulnerabilities.scanning_tree') }}</span> 205 203 </div> 206 204 </div> 207 205 </section> ··· 215 213 <div class="flex items-center gap-2"> 216 214 <span class="i-carbon-checkmark w-4 h-4 text-fg-subtle" aria-hidden="true" /> 217 215 <span class="text-sm text-fg-muted"> 218 - {{ t('package.vulnerabilities.no_known', { count: vulnTree?.totalPackages ?? 0 }) }} 216 + {{ $t('package.vulnerabilities.no_known', { count: vulnTree?.totalPackages ?? 0 }) }} 219 217 </span> 220 218 </div> 221 219 <!-- Warning if some queries failed --> ··· 224 222 class="flex items-center gap-2 mt-2 text-xs text-fg-subtle" 225 223 > 226 224 <span class="i-carbon-warning w-3 h-3" aria-hidden="true" /> 227 - <span>{{ t('package.vulnerabilities.packages_failed', vulnTree.failedQueries) }}</span> 225 + <span>{{ $t('package.vulnerabilities.packages_failed', vulnTree.failedQueries) }}</span> 228 226 </div> 229 227 </div> 230 228 </section> ··· 235 233 <div class="flex items-center gap-2"> 236 234 <span class="i-carbon-warning w-4 h-4 text-fg-subtle" aria-hidden="true" /> 237 235 <span class="text-sm text-fg-muted"> 238 - {{ t('package.vulnerabilities.scan_failed') }} 236 + {{ $t('package.vulnerabilities.scan_failed') }} 239 237 </span> 240 238 </div> 241 239 </div>
+3 -4
app/pages/index.vue
··· 1 1 <script setup lang="ts"> 2 2 const router = useRouter() 3 3 const searchQuery = ref('') 4 - const isSearchFocused = ref(false) 4 + const searchInputRef = useTemplateRef('searchInputRef') 5 + const { focused: isSearchFocused } = useFocus(searchInputRef) 5 6 6 7 function handleSearch() { 7 8 router.push({ ··· 68 69 69 70 <input 70 71 id="home-search" 72 + ref="searchInputRef" 71 73 v-model="searchQuery" 72 74 type="search" 73 75 name="q" ··· 75 77 v-bind="noCorrect" 76 78 autofocus 77 79 class="w-full bg-bg-subtle border border-border rounded-lg pl-8 pr-24 py-4 font-mono text-base text-fg placeholder:text-fg-subtle transition-border-color duration-300 focus:border-accent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent/50" 78 - autocomplete="off" 79 80 @input="handleSearch" 80 - @focus="isSearchFocused = true" 81 - @blur="isSearchFocused = false" 82 81 /> 83 82 84 83 <button
+3 -6
app/pages/search.vue
··· 44 44 ) 45 45 46 46 // For glow effect 47 - const isSearchFocused = ref(false) 48 47 const searchInputRef = useTemplateRef('searchInputRef') 48 + const { focused: isSearchFocused } = useFocus(searchInputRef) 49 49 50 50 const selectedIndex = ref(0) 51 51 const packageListRef = useTemplateRef('packageListRef') ··· 78 78 // Load enough pages to show the initial page 79 79 loadedPages.value = initialPage.value 80 80 } 81 - // Focus search input 82 - searchInputRef.value?.focus() 83 81 }) 84 82 85 83 // fetch all pages up to current ··· 730 728 name="q" 731 729 :placeholder="$t('search.placeholder')" 732 730 v-bind="noCorrect" 731 + autofocus 733 732 class="w-full max-w-full bg-bg-subtle border border-border rounded-lg pl-8 pr-10 py-3 font-mono text-base text-fg placeholder:text-fg-subtle transition-colors duration-300 focus:border-accent focus-visible:outline-none appearance-none" 734 - @focus="isSearchFocused = true" 735 - @blur="isSearchFocused = false" 736 733 @keydown="handleResultsKeydown" 737 734 /> 738 735 <button 739 736 v-show="inputValue" 740 737 type="button" 741 - class="absolute right-3 text-fg-subtle hover:text-fg transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-fg/50 rounded" 738 + class="absolute right-3 p-2 text-fg-subtle hover:text-fg transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-fg/50 rounded" 742 739 :aria-label="$t('search.clear')" 743 740 @click="inputValue = ''" 744 741 >