Skip to content

Commit d3215ee

Browse files
IdrisGitdanielroeautofix-ci[bot]
authored
fix: make version cards clickable and highlight the active version (#1050)
Co-authored-by: Daniel Roe <daniel@roe.dev> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
1 parent a5fe55d commit d3215ee

File tree

2 files changed

+109
-46
lines changed

2 files changed

+109
-46
lines changed

app/components/Package/Versions.vue

Lines changed: 64 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -571,14 +571,14 @@ function majorGroupContainsCurrent(group: (typeof otherMajorGroups.value)[0]): b
571571
<!-- Dist-tag rows (limited to MAX_VISIBLE_TAGS) -->
572572
<div v-for="row in visibleTagRows" :key="row.id">
573573
<div
574-
class="flex items-center gap-2 pe-2 px-1"
575-
:class="rowContainsCurrentVersion(row) ? 'bg-bg-subtle rounded-lg' : ''"
574+
class="flex items-center gap-2 pe-2 px-1 relative group/version-row hover:bg-bg-subtle focus-within:bg-bg-subtle transition-colors duration-200 rounded-lg"
575+
:class="rowContainsCurrentVersion(row) ? 'bg-bg-subtle' : ''"
576576
>
577577
<!-- Expand button (only if there are more versions to show) -->
578578
<button
579579
v-if="getTagVersions(row.tag).length > 1 || !hasLoadedAll"
580580
type="button"
581-
class="size-5 -me-1 flex items-center justify-center text-fg-subtle hover:text-fg transition-colors rounded-sm"
581+
class="size-5 -me-1 flex items-center justify-center text-fg-subtle hover:text-fg transition-colors rounded-sm relative z-10"
582582
:aria-expanded="expandedTags.has(row.tag)"
583583
:aria-label="
584584
expandedTags.has(row.tag)
@@ -611,10 +611,10 @@ function majorGroupContainsCurrent(group: (typeof otherMajorGroups.value)[0]): b
611611
<LinkBase
612612
:to="versionRoute(row.primaryVersion.version)"
613613
block
614-
class="text-sm"
614+
class="text-sm after:absolute after:inset-0 after:content-['']"
615615
:class="
616616
row.primaryVersion.deprecated
617-
? 'text-red-800 hover:text-red-700 dark:text-red-400 dark:hover:text-red-300'
617+
? 'text-red-800 group-hover/version-row:text-red-700 dark:text-red-400 dark:group-hover/version-row:text-red-300'
618618
: undefined
619619
"
620620
:title="
@@ -630,18 +630,22 @@ function majorGroupContainsCurrent(group: (typeof otherMajorGroups.value)[0]): b
630630
{{ row.primaryVersion.version }}
631631
</span>
632632
</LinkBase>
633-
<div v-if="row.tags.length" class="flex items-center gap-1 mt-0.5 flex-wrap">
633+
<div
634+
v-if="row.tags.length"
635+
class="flex items-center gap-1 mt-0.5 flex-wrap relative z-10"
636+
>
634637
<span
635638
v-for="tag in row.tags"
636639
:key="tag"
637-
class="text-4xs font-semibold text-fg-subtle uppercase tracking-wide truncate"
640+
class="text-4xs font-semibold uppercase tracking-wide truncate"
641+
:class="tag === 'latest' ? 'text-accent' : 'text-fg-subtle'"
638642
:title="tag"
639643
>
640644
{{ tag }}
641645
</span>
642646
</div>
643647
</div>
644-
<div class="flex items-center gap-2 shrink-0">
648+
<div class="flex items-center gap-2 shrink-0 relative z-10">
645649
<DateTime
646650
v-if="row.primaryVersion.time"
647651
:datetime="row.primaryVersion.time"
@@ -655,6 +659,7 @@ function majorGroupContainsCurrent(group: (typeof otherMajorGroups.value)[0]): b
655659
:package-name="packageName"
656660
:version="row.primaryVersion.version"
657661
compact
662+
:linked="false"
658663
/>
659664
</div>
660665
</div>
@@ -668,17 +673,17 @@ function majorGroupContainsCurrent(group: (typeof otherMajorGroups.value)[0]): b
668673
<div
669674
v-for="v in getFilteredTagVersions(row.tag).slice(1)"
670675
:key="v.version"
671-
class="py-1"
672-
:class="v.version === effectiveCurrentVersion ? 'rounded bg-bg-subtle px-2 -mx-2' : ''"
676+
class="py-1 relative group/version-row hover:bg-bg-elevated/20 focus-within:bg-bg-elevated/20 transition-colors duration-200"
677+
:class="v.version === effectiveCurrentVersion ? 'bg-bg-elevated/20 rounded' : ''"
673678
>
674679
<div class="flex items-center justify-between gap-2">
675680
<LinkBase
676681
:to="versionRoute(v.version)"
677682
block
678-
class="text-xs"
683+
class="text-xs after:absolute after:inset-0 after:content-['']"
679684
:class="
680685
v.deprecated
681-
? 'text-red-800 hover:text-red-700 dark:text-red-400 dark:hover:text-red-300'
686+
? 'text-red-800 group-hover/version-row:text-red-700 dark:text-red-400 dark:group-hover/version-row:text-red-300'
682687
: undefined
683688
"
684689
:title="
@@ -694,7 +699,7 @@ function majorGroupContainsCurrent(group: (typeof otherMajorGroups.value)[0]): b
694699
{{ v.version }}
695700
</span>
696701
</LinkBase>
697-
<div class="flex items-center gap-2 shrink-0">
702+
<div class="flex items-center gap-2 shrink-0 relative z-10">
698703
<DateTime
699704
v-if="v.time"
700705
:datetime="v.time"
@@ -708,17 +713,19 @@ function majorGroupContainsCurrent(group: (typeof otherMajorGroups.value)[0]): b
708713
:package-name="packageName"
709714
:version="v.version"
710715
compact
716+
:linked="false"
711717
/>
712718
</div>
713719
</div>
714720
<div
715721
v-if="v.tags?.length && filterExcludedTags(v.tags, row.tags).length"
716-
class="flex items-center gap-1 mt-0.5"
722+
class="flex items-center gap-1 mt-0.5 relative z-10"
717723
>
718724
<span
719725
v-for="tag in filterExcludedTags(v.tags, row.tags)"
720726
:key="tag"
721-
class="text-5xs font-semibold text-fg-subtle uppercase tracking-wide truncate max-w-[120px]"
727+
class="text-5xs font-semibold uppercase tracking-wide truncate max-w-[120px]"
728+
:class="tag === 'latest' ? 'text-accent' : 'text-fg-subtle'"
722729
:title="tag"
723730
>
724731
{{ tag }}
@@ -778,17 +785,17 @@ function majorGroupContainsCurrent(group: (typeof otherMajorGroups.value)[0]): b
778785
<div
779786
v-for="row in hiddenTagRows"
780787
:key="row.id"
781-
class="py-1"
782-
:class="hiddenRowContainsCurrent(row) ? 'rounded bg-bg-subtle px-2 -mx-2' : ''"
788+
class="py-1 relative group/version-row hover:bg-bg-subtle focus-within:bg-bg-subtle transition-colors duration-200 rounded-lg"
789+
:class="hiddenRowContainsCurrent(row) ? 'bg-bg-subtle' : ''"
783790
>
784791
<div class="flex items-center justify-between gap-2">
785792
<LinkBase
786793
:to="versionRoute(row.primaryVersion.version)"
787794
block
788-
class="text-xs"
795+
class="text-xs after:absolute after:inset-0 after:content-['']"
789796
:class="
790797
row.primaryVersion.deprecated
791-
? 'text-red-800 hover:text-red-700 dark:text-red-400 dark:hover:text-red-300'
798+
? 'text-red-800 group-hover/version-row:text-red-700 dark:text-red-400 dark:group-hover/version-row:text-red-300'
792799
: undefined
793800
"
794801
:title="
@@ -804,7 +811,7 @@ function majorGroupContainsCurrent(group: (typeof otherMajorGroups.value)[0]): b
804811
{{ row.primaryVersion.version }}
805812
</span>
806813
</LinkBase>
807-
<div class="flex items-center gap-2 shrink-0 pe-2">
814+
<div class="flex items-center gap-2 shrink-0 pe-2 relative z-10">
808815
<DateTime
809816
v-if="row.primaryVersion.time"
810817
:datetime="row.primaryVersion.time"
@@ -815,11 +822,15 @@ function majorGroupContainsCurrent(group: (typeof otherMajorGroups.value)[0]): b
815822
/>
816823
</div>
817824
</div>
818-
<div v-if="row.tags.length" class="flex items-center gap-1 mt-0.5 flex-wrap">
825+
<div
826+
v-if="row.tags.length"
827+
class="flex items-center gap-1 mt-0.5 flex-wrap relative z-10"
828+
>
819829
<span
820830
v-for="tag in row.tags"
821831
:key="tag"
822-
class="text-5xs font-semibold text-fg-subtle uppercase tracking-wide truncate max-w-[120px]"
832+
class="text-5xs font-semibold uppercase tracking-wide truncate max-w-[120px]"
833+
:class="tag === 'latest' ? 'text-accent' : 'text-fg-subtle'"
823834
:title="tag"
824835
>
825836
{{ tag }}
@@ -833,14 +844,14 @@ function majorGroupContainsCurrent(group: (typeof otherMajorGroups.value)[0]): b
833844
<!-- Version group header -->
834845
<div
835846
v-if="group.versions.length > 1"
836-
class="py-1"
837-
:class="majorGroupContainsCurrent(group) ? 'rounded bg-bg-subtle px-2 -mx-2' : ''"
847+
class="py-1 relative group/version-row hover:bg-bg-subtle focus-within:bg-bg-subtle transition-colors duration-200 rounded-lg"
848+
:class="majorGroupContainsCurrent(group) ? 'bg-bg-subtle' : ''"
838849
>
839850
<div class="flex items-center justify-between gap-2">
840851
<div class="flex items-center gap-2 min-w-0">
841852
<button
842853
type="button"
843-
class="w-4 h-4 flex items-center justify-center text-fg-subtle hover:text-fg transition-colors shrink-0 rounded-sm"
854+
class="w-4 h-4 flex items-center justify-center text-fg-subtle hover:text-fg transition-colors shrink-0 rounded-sm relative z-10"
844855
:aria-expanded="expandedMajorGroups.has(group.groupKey)"
845856
:aria-label="
846857
expandedMajorGroups.has(group.groupKey)
@@ -868,10 +879,10 @@ function majorGroupContainsCurrent(group: (typeof otherMajorGroups.value)[0]): b
868879
v-if="group.versions[0]?.version"
869880
:to="versionRoute(group.versions[0]?.version)"
870881
block
871-
class="text-xs"
882+
class="text-xs after:absolute after:inset-0 after:content-['']"
872883
:class="
873884
group.versions[0]?.deprecated
874-
? 'text-red-800 hover:text-red-700 dark:text-red-400 dark:hover:text-red-300'
885+
? 'text-red-800 group-hover/version-row:text-red-700 dark:text-red-400 dark:group-hover/version-row:text-red-300'
875886
: undefined
876887
"
877888
:title="
@@ -890,7 +901,7 @@ function majorGroupContainsCurrent(group: (typeof otherMajorGroups.value)[0]): b
890901
</span>
891902
</LinkBase>
892903
</div>
893-
<div class="flex items-center gap-2 shrink-0 pe-2">
904+
<div class="flex items-center gap-2 shrink-0 pe-2 relative z-10">
894905
<DateTime
895906
v-if="group.versions[0]?.time"
896907
:datetime="group.versions[0]?.time"
@@ -904,17 +915,19 @@ function majorGroupContainsCurrent(group: (typeof otherMajorGroups.value)[0]): b
904915
:package-name="packageName"
905916
:version="group.versions[0]?.version"
906917
compact
918+
:linked="false"
907919
/>
908920
</div>
909921
</div>
910922
<div
911923
v-if="group.versions[0]?.tags?.length"
912-
class="flex items-center gap-1 ms-5 flex-wrap"
924+
class="flex items-center gap-1 ms-5 flex-wrap relative z-10"
913925
>
914926
<span
915927
v-for="tag in group.versions[0].tags"
916928
:key="tag"
917-
class="text-5xs font-semibold text-fg-subtle uppercase tracking-wide truncate max-w-[120px]"
929+
class="text-5xs font-semibold uppercase tracking-wide truncate max-w-[120px]"
930+
:class="tag === 'latest' ? 'text-accent' : 'text-fg-subtle'"
918931
:title="tag"
919932
>
920933
{{ tag }}
@@ -924,19 +937,19 @@ function majorGroupContainsCurrent(group: (typeof otherMajorGroups.value)[0]): b
924937
<!-- Single version (no expand needed) -->
925938
<div
926939
v-else
927-
class="py-1"
928-
:class="majorGroupContainsCurrent(group) ? 'rounded bg-bg-subtle px-2 -mx-2' : ''"
940+
class="py-1 relative group/version-row hover:bg-bg-subtle focus-within:bg-bg-subtle transition-colors duration-200 rounded-lg"
941+
:class="majorGroupContainsCurrent(group) ? 'bg-bg-subtle' : ''"
929942
>
930943
<div class="flex items-center justify-between gap-2">
931944
<div class="flex items-center gap-2 min-w-0">
932945
<LinkBase
933946
v-if="group.versions[0]?.version"
934947
:to="versionRoute(group.versions[0]?.version)"
935948
block
936-
class="text-xs ms-6"
949+
class="text-xs ms-6 after:absolute after:inset-0 after:content-['']"
937950
:class="
938951
group.versions[0]?.deprecated
939-
? 'text-red-800 hover:text-red-700 dark:text-red-400 dark:hover:text-red-300'
952+
? 'text-red-800 group-hover/version-row:text-red-700 dark:text-red-400 dark:group-hover/version-row:text-red-300'
940953
: undefined
941954
"
942955
:title="
@@ -955,7 +968,7 @@ function majorGroupContainsCurrent(group: (typeof otherMajorGroups.value)[0]): b
955968
</span>
956969
</LinkBase>
957970
</div>
958-
<div class="flex items-center gap-2 shrink-0 pe-2">
971+
<div class="flex items-center gap-2 shrink-0 pe-2 relative z-10">
959972
<DateTime
960973
v-if="group.versions[0]?.time"
961974
:datetime="group.versions[0]?.time"
@@ -969,14 +982,19 @@ function majorGroupContainsCurrent(group: (typeof otherMajorGroups.value)[0]): b
969982
:package-name="packageName"
970983
:version="group.versions[0]?.version"
971984
compact
985+
:linked="false"
972986
/>
973987
</div>
974988
</div>
975-
<div v-if="group.versions[0]?.tags?.length" class="flex items-center gap-1 ms-5">
989+
<div
990+
v-if="group.versions[0]?.tags?.length"
991+
class="flex items-center gap-1 ms-5 relative z-10"
992+
>
976993
<span
977994
v-for="tag in group.versions[0].tags"
978995
:key="tag"
979-
class="text-5xs font-semibold text-fg-subtle uppercase tracking-wide"
996+
class="text-5xs font-semibold uppercase tracking-wide"
997+
:class="tag === 'latest' ? 'text-accent' : 'text-fg-subtle'"
980998
>
981999
{{ tag }}
9821000
</span>
@@ -991,19 +1009,17 @@ function majorGroupContainsCurrent(group: (typeof otherMajorGroups.value)[0]): b
9911009
<div
9921010
v-for="v in group.versions.slice(1)"
9931011
:key="v.version"
994-
class="py-1"
995-
:class="
996-
v.version === effectiveCurrentVersion ? 'rounded bg-bg-subtle px-2 -mx-2' : ''
997-
"
1012+
class="py-1 relative group/version-row hover:bg-bg-elevated/20 focus-within:bg-bg-elevated/20 transition-colors duration-200"
1013+
:class="v.version === effectiveCurrentVersion ? 'bg-bg-elevated/20 rounded' : ''"
9981014
>
9991015
<div class="flex items-center justify-between gap-2">
10001016
<LinkBase
10011017
:to="versionRoute(v.version)"
10021018
block
1003-
class="text-xs"
1019+
class="text-xs after:absolute after:inset-0 after:content-['']"
10041020
:class="
10051021
v.deprecated
1006-
? 'text-red-800 hover:text-red-700 dark:text-red-400 dark:hover:text-red-300'
1022+
? 'text-red-800 group-hover/version-row:text-red-700 dark:text-red-400 dark:group-hover/version-row:text-red-300'
10071023
: undefined
10081024
"
10091025
:title="
@@ -1019,7 +1035,7 @@ function majorGroupContainsCurrent(group: (typeof otherMajorGroups.value)[0]): b
10191035
{{ v.version }}
10201036
</span>
10211037
</LinkBase>
1022-
<div class="flex items-center gap-2 shrink-0 pe-2">
1038+
<div class="flex items-center gap-2 shrink-0 pe-2 relative z-10">
10231039
<DateTime
10241040
v-if="v.time"
10251041
:datetime="v.time"
@@ -1033,14 +1049,16 @@ function majorGroupContainsCurrent(group: (typeof otherMajorGroups.value)[0]): b
10331049
:package-name="packageName"
10341050
:version="v.version"
10351051
compact
1052+
:linked="false"
10361053
/>
10371054
</div>
10381055
</div>
1039-
<div v-if="v.tags?.length" class="flex items-center gap-1 mt-0.5">
1056+
<div v-if="v.tags?.length" class="flex items-center gap-1 mt-0.5 relative z-10">
10401057
<span
10411058
v-for="tag in v.tags"
10421059
:key="tag"
1043-
class="text-5xs font-semibold text-fg-subtle uppercase tracking-wide"
1060+
class="text-5xs font-semibold uppercase tracking-wide"
1061+
:class="tag === 'latest' ? 'text-accent' : 'text-fg-subtle'"
10441062
>
10451063
{{ tag }}
10461064
</span>

test/nuxt/components/PackageVersions.spec.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,51 @@ describe('PackageVersions', () => {
100100
expect(versionLinks.length).toBeGreaterThan(0)
101101
expect(versionLinks[0]?.text()).toBe('1.0.0')
102102
})
103+
104+
it('highlights the current version row when selectedVersion prop matches', async () => {
105+
const component = await mountSuspended(PackageVersions, {
106+
props: {
107+
packageName: 'test-package',
108+
versions: {
109+
'2.0.0': createVersion('2.0.0'),
110+
'1.0.0': createVersion('1.0.0'),
111+
},
112+
distTags: { latest: '2.0.0', stable: '1.0.0' },
113+
time: {
114+
'2.0.0': '2024-01-15T12:00:00.000Z',
115+
'1.0.0': '2024-01-01T12:00:00.000Z',
116+
},
117+
selectedVersion: '1.0.0',
118+
},
119+
})
120+
121+
// Find the version row divs that are direct children of the tag row containers
122+
const versionRows = component.findAll('[class*="group/version-row"]')
123+
const highlightedRows = versionRows.filter(row => row.classes().includes('bg-bg-subtle'))
124+
expect(highlightedRows.length).toBe(1)
125+
expect(highlightedRows[0]!.text()).toContain('1.0.0')
126+
})
127+
128+
it('uses accent color for latest tag', async () => {
129+
const component = await mountSuspended(PackageVersions, {
130+
props: {
131+
packageName: 'test-package',
132+
versions: {
133+
'2.0.0': createVersion('2.0.0'),
134+
'1.0.0': createVersion('1.0.0'),
135+
},
136+
distTags: { latest: '2.0.0', stable: '1.0.0' },
137+
time: {
138+
'2.0.0': '2024-01-15T12:00:00.000Z',
139+
'1.0.0': '2024-01-01T12:00:00.000Z',
140+
},
141+
selectedVersion: '1.0.0',
142+
},
143+
})
144+
145+
const latestTag = component.findAll('span').find(span => span.text() === 'latest')
146+
expect(latestTag?.classes()).toContain('text-accent')
147+
})
103148
})
104149

105150
describe('dist-tag display', () => {

0 commit comments

Comments
 (0)