Skip to content

Commit 26f7bbb

Browse files
committed
feat: add new useVisibleItems composable
This adds a new `useVisibleItems` composable and initially adopts it in the dependencies view of a package. In follow ups, we can adopt it in more pages to reduce duplicated logic.
1 parent 5324b96 commit 26f7bbb

File tree

2 files changed

+52
-17
lines changed

2 files changed

+52
-17
lines changed

app/components/Package/Dependencies.vue

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,6 @@ function getDeprecatedDepInfo(depName: string) {
3737
return vulnTree.value.deprecatedPackages.find(p => p.name === depName && p.depth === 'direct')
3838
}
3939
40-
// Expanded state for each section
41-
const depsExpanded = shallowRef(false)
42-
const peerDepsExpanded = shallowRef(false)
43-
const optionalDepsExpanded = shallowRef(false)
44-
4540
// Sort dependencies alphabetically
4641
const sortedDependencies = computed(() => {
4742
if (!props.dependencies) return []
@@ -89,6 +84,24 @@ function getDepVersionClass(dep: string) {
8984
return getVersionClass(undefined)
9085
}
9186
87+
const {
88+
visibleItems: visibleDeps,
89+
hasMore: hasMoreDeps,
90+
expand: expandDeps,
91+
} = useVisibleItems(sortedDependencies, 10)
92+
93+
const {
94+
visibleItems: visiblePeerDeps,
95+
hasMore: hasMorePeerDeps,
96+
expand: expandPeerDeps,
97+
} = useVisibleItems(sortedPeerDependencies, 10)
98+
99+
const {
100+
visibleItems: visibleOptionalDeps,
101+
hasMore: hasMoreOptionalDeps,
102+
expand: expandOptionalDeps,
103+
} = useVisibleItems(sortedOptionalDependencies, 10)
104+
92105
const numberFormatter = useNumberFormatter()
93106
</script>
94107

@@ -110,7 +123,7 @@ const numberFormatter = useNumberFormatter()
110123
>
111124
<ul class="space-y-1 list-none m-0" :aria-label="$t('package.dependencies.list_label')">
112125
<li
113-
v-for="[dep, version] in sortedDependencies.slice(0, depsExpanded ? undefined : 10)"
126+
v-for="[dep, version] in visibleDeps"
114127
:key="dep"
115128
class="flex items-center justify-between py-1 text-sm gap-2"
116129
>
@@ -190,10 +203,10 @@ const numberFormatter = useNumberFormatter()
190203
</li>
191204
</ul>
192205
<button
193-
v-if="sortedDependencies.length > 10 && !depsExpanded"
206+
v-if="hasMoreDeps"
194207
type="button"
195208
class="my-2 ms-1 font-mono text-xs text-fg-muted hover:text-fg transition-colors duration-200 rounded focus-visible:outline-accent/70"
196-
@click="depsExpanded = true"
209+
@click="expandDeps"
197210
>
198211
{{
199212
$t(
@@ -222,7 +235,7 @@ const numberFormatter = useNumberFormatter()
222235
:aria-label="$t('package.peer_dependencies.list_label')"
223236
>
224237
<li
225-
v-for="peer in sortedPeerDependencies.slice(0, peerDepsExpanded ? undefined : 10)"
238+
v-for="peer in visiblePeerDeps"
226239
:key="peer.name"
227240
class="flex items-center justify-between py-1 text-sm gap-1 min-w-0"
228241
>
@@ -245,10 +258,10 @@ const numberFormatter = useNumberFormatter()
245258
</li>
246259
</ul>
247260
<button
248-
v-if="sortedPeerDependencies.length > 10 && !peerDepsExpanded"
261+
v-if="hasMorePeerDeps"
249262
type="button"
250263
class="mt-2 font-mono text-xs text-fg-muted hover:text-fg transition-colors duration-200 rounded focus-visible:outline-accent/70"
251-
@click="peerDepsExpanded = true"
264+
@click="expandPeerDeps"
252265
>
253266
{{
254267
$t(
@@ -281,10 +294,7 @@ const numberFormatter = useNumberFormatter()
281294
:aria-label="$t('package.optional_dependencies.list_label')"
282295
>
283296
<li
284-
v-for="[dep, version] in sortedOptionalDependencies.slice(
285-
0,
286-
optionalDepsExpanded ? undefined : 10,
287-
)"
297+
v-for="[dep, version] in visibleOptionalDeps"
288298
:key="dep"
289299
class="flex items-baseline justify-between py-1 text-sm gap-2"
290300
>
@@ -302,10 +312,10 @@ const numberFormatter = useNumberFormatter()
302312
</li>
303313
</ul>
304314
<button
305-
v-if="sortedOptionalDependencies.length > 10 && !optionalDepsExpanded"
315+
v-if="hasMoreOptionalDeps"
306316
type="button"
307317
class="mt-2 truncate"
308-
@click="optionalDepsExpanded = true"
318+
@click="expandOptionalDeps"
309319
>
310320
{{
311321
$t(

app/composables/useVisibleItems.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
export function useVisibleItems<T>(
2+
items: MaybeRefOrGetter<T[]>,
3+
limit: number,
4+
) {
5+
const showAll = shallowRef(false)
6+
7+
const visibleItems = computed(() => {
8+
const list = toValue(items)
9+
return showAll.value ? list : list.slice(0, limit)
10+
})
11+
12+
const hiddenCount = computed(() =>
13+
Math.max(0, toValue(items).length - limit),
14+
)
15+
16+
const hasMore = computed(
17+
() => !showAll.value && toValue(items).length > limit,
18+
)
19+
20+
const expand = () => { showAll.value = true }
21+
const collapse = () => { showAll.value = false }
22+
const toggle = () => { showAll.value = !showAll.value }
23+
24+
return { visibleItems, hiddenCount, hasMore, showAll, expand, collapse, toggle }
25+
}

0 commit comments

Comments
 (0)