Skip to content

Commit fb62aa7

Browse files
9romisedanielroe
andauthored
refactor: prefer VueUse where possible (#267)
Co-authored-by: Daniel Roe <daniel@roe.dev>
1 parent e53da33 commit fb62aa7

7 files changed

Lines changed: 27 additions & 58 deletions

File tree

app/components/AppHeader.vue

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,6 @@ onKeyStroke(',', e => {
9494
:placeholder="$t('search.placeholder')"
9595
v-bind="noCorrect"
9696
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"
9897
@input="handleSearchInput"
9998
@focus="isSearchFocused = true"
10099
@blur="isSearchFocused = false"

app/components/CodeMobileTreeDrawer.vue

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,19 +18,9 @@ watch(
1818
},
1919
)
2020
21+
const isLocked = useScrollLock(document)
2122
// 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))
3424
</script>
3525

3626
<template>

app/components/DependencyPathPopup.vue

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ defineProps<{
44
path: readonly string[]
55
}>()
66
7-
const { t } = useI18n()
8-
97
const isOpen = shallowRef(false)
108
const popupEl = ref<HTMLElement | null>(null)
119
const popupPosition = shallowRef<{ top: number; left: number } | null>(null)
@@ -29,15 +27,8 @@ function handleKeydown(e: KeyboardEvent) {
2927
if (e.key === 'Escape') closePopup()
3028
}
3129
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)
4132
4233
function togglePopup(event: MouseEvent) {
4334
if (isOpen.value) {
@@ -81,7 +72,7 @@ function parsePackageString(pkg: string): { name: string; version: string } {
8172
@click.stop="togglePopup"
8273
>
8374
<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>
8576
</button>
8677

8778
<!-- Tree popup -->

app/components/OperationsQueue.vue

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -103,19 +103,14 @@ function getStatusIcon(status: string): string {
103103
}
104104
105105
// 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+
})
107109
watch(isExecuting, executing => {
108110
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()
119114
}
120115
})
121116
</script>

app/components/PackageVulnerabilityTree.vue

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ const props = defineProps<{
77
version: string
88
}>()
99
10-
const { t } = useI18n()
11-
1210
const {
1311
data: vulnTree,
1412
status,
@@ -34,7 +32,7 @@ const summaryText = computed(() => {
3432
if (!vulnTree.value) return ''
3533
const { totalCounts } = vulnTree.value
3634
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}`)}`)
3836
.join(', ')
3937
})
4038
@@ -83,7 +81,7 @@ function getDepthStyle(depth: string | undefined) {
8381
<span class="i-carbon-warning-alt w-4 h-4 shrink-0" aria-hidden="true" />
8482
<span class="font-mono text-sm font-medium truncate">
8583
{{
86-
t(
84+
$t(
8785
'package.vulnerabilities.tree_found',
8886
{
8987
vulns: vulnTree!.totalCounts.total,
@@ -137,7 +135,7 @@ function getDepthStyle(depth: string | undefined) {
137135
class="px-1.5 py-0.5 text-[10px] font-mono rounded border"
138136
:class="SEVERITY_COLORS[s]"
139137
>
140-
{{ pkg.counts[s] }} {{ t(`package.vulnerabilities.severity.${s}`) }}
138+
{{ pkg.counts[s] }} {{ $t(`package.vulnerabilities.severity.${s}`) }}
141139
</span>
142140
</div>
143141
</div>
@@ -159,7 +157,7 @@ function getDepthStyle(depth: string | undefined) {
159157
<span class="truncate">{{ vuln.summary }}</span>
160158
</li>
161159
<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 }) }}
163161
</li>
164162
</ul>
165163
</li>
@@ -172,7 +170,7 @@ function getDepthStyle(depth: string | undefined) {
172170
@click="showAllPackages = true"
173171
>
174172
{{
175-
t('package.vulnerabilities.show_all_packages', {
173+
$t('package.vulnerabilities.show_all_packages', {
176174
count: vulnTree!.vulnerablePackages.length,
177175
})
178176
}}
@@ -184,7 +182,7 @@ function getDepthStyle(depth: string | undefined) {
184182
class="px-4 py-2 text-xs text-fg-subtle border-t border-border flex items-center gap-2"
185183
>
186184
<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>
188186
</div>
189187
</div>
190188
</div>
@@ -201,7 +199,7 @@ function getDepthStyle(depth: string | undefined) {
201199
class="i-carbon-circle-dash w-4 h-4 animate-spin motion-reduce:animate-none text-fg-subtle"
202200
aria-hidden="true"
203201
/>
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>
205203
</div>
206204
</div>
207205
</section>
@@ -215,7 +213,7 @@ function getDepthStyle(depth: string | undefined) {
215213
<div class="flex items-center gap-2">
216214
<span class="i-carbon-checkmark w-4 h-4 text-fg-subtle" aria-hidden="true" />
217215
<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 }) }}
219217
</span>
220218
</div>
221219
<!-- Warning if some queries failed -->
@@ -224,7 +222,7 @@ function getDepthStyle(depth: string | undefined) {
224222
class="flex items-center gap-2 mt-2 text-xs text-fg-subtle"
225223
>
226224
<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>
228226
</div>
229227
</div>
230228
</section>
@@ -235,7 +233,7 @@ function getDepthStyle(depth: string | undefined) {
235233
<div class="flex items-center gap-2">
236234
<span class="i-carbon-warning w-4 h-4 text-fg-subtle" aria-hidden="true" />
237235
<span class="text-sm text-fg-muted">
238-
{{ t('package.vulnerabilities.scan_failed') }}
236+
{{ $t('package.vulnerabilities.scan_failed') }}
239237
</span>
240238
</div>
241239
</div>

app/pages/index.vue

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
<script setup lang="ts">
22
const router = useRouter()
33
const searchQuery = ref('')
4-
const isSearchFocused = ref(false)
4+
const searchInputRef = useTemplateRef('searchInputRef')
5+
const { focused: isSearchFocused } = useFocus(searchInputRef)
56
67
function handleSearch() {
78
router.push({
@@ -68,17 +69,15 @@ defineOgImageComponent('Default')
6869

6970
<input
7071
id="home-search"
72+
ref="searchInputRef"
7173
v-model="searchQuery"
7274
type="search"
7375
name="q"
7476
:placeholder="$t('search.placeholder')"
7577
v-bind="noCorrect"
7678
autofocus
7779
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"
7980
@input="handleSearch"
80-
@focus="isSearchFocused = true"
81-
@blur="isSearchFocused = false"
8281
/>
8382

8483
<button

app/pages/search.vue

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ watch(
4444
)
4545
4646
// For glow effect
47-
const isSearchFocused = ref(false)
4847
const searchInputRef = useTemplateRef('searchInputRef')
48+
const { focused: isSearchFocused } = useFocus(searchInputRef)
4949
5050
const selectedIndex = ref(0)
5151
const packageListRef = useTemplateRef('packageListRef')
@@ -78,8 +78,6 @@ onMounted(() => {
7878
// Load enough pages to show the initial page
7979
loadedPages.value = initialPage.value
8080
}
81-
// Focus search input
82-
searchInputRef.value?.focus()
8381
})
8482
8583
// fetch all pages up to current
@@ -730,15 +728,14 @@ defineOgImageComponent('Default', {
730728
name="q"
731729
:placeholder="$t('search.placeholder')"
732730
v-bind="noCorrect"
731+
autofocus
733732
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"
736733
@keydown="handleResultsKeydown"
737734
/>
738735
<button
739736
v-show="inputValue"
740737
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"
742739
:aria-label="$t('search.clear')"
743740
@click="inputValue = ''"
744741
>

0 commit comments

Comments
 (0)