Skip to content

Commit 85b5226

Browse files
essenmitsosseautofix-ci[bot]coderabbitai[bot]
authored
refactor: replace links and buttons for compare and code page (#1243)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
1 parent 893a3d3 commit 85b5226

File tree

13 files changed

+132
-173
lines changed

13 files changed

+132
-173
lines changed

app/components/AppHeader.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ onKeyStroke(
259259
class="border-none"
260260
variant="button-secondary"
261261
:to="link.to"
262-
:keyshortcut="link.keyshortcut"
262+
:aria-keyshortcuts="link.keyshortcut"
263263
>
264264
{{ link.label }}
265265
</LinkBase>

app/components/Button/Base.vue

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,13 @@
11
<script setup lang="ts">
22
const props = withDefaults(
33
defineProps<{
4-
'disabled'?: boolean
5-
'type'?: 'button' | 'submit'
6-
'variant'?: 'primary' | 'secondary'
7-
'size'?: 'small' | 'medium'
8-
'keyshortcut'?: string
4+
disabled?: boolean
5+
type?: 'button' | 'submit'
6+
variant?: 'primary' | 'secondary'
7+
size?: 'small' | 'medium'
8+
ariaKeyshortcuts?: string
99
10-
/**
11-
* Do not use this directly. Use keyshortcut instead; it generates the correct HTML and displays the shortcut in the UI.
12-
*/
13-
'aria-keyshortcuts'?: never
14-
15-
'classicon'?: string
10+
classicon?: string
1611
}>(),
1712
{
1813
type: 'button',
@@ -36,7 +31,7 @@ defineExpose({
3631
:class="{
3732
'text-sm px-4 py-2': size === 'medium',
3833
'text-xs px-2 py-0.5': size === 'small',
39-
'bg-transparent text-fg hover:enabled:(bg-fg/10) focus-visible:enabled:(bg-fg/10) aria-pressed:(bg-fg text-bg border-fg hover:enabled:(bg-fg text-bg/50))':
34+
'bg-transparent text-fg hover:enabled:(bg-fg/10) focus-visible:enabled:(bg-fg/10) aria-pressed:(bg-fg/10 border-fg/20 hover:enabled:(bg-fg/20 text-fg/50))':
4035
variant === 'secondary',
4136
'text-bg bg-fg hover:enabled:(bg-fg/50) focus-visible:enabled:(bg-fg/50) aria-pressed:(bg-fg text-bg border-fg hover:enabled:(text-bg/50))':
4237
variant === 'primary',
@@ -51,7 +46,7 @@ defineExpose({
5146
*/
5247
disabled ? true : undefined
5348
"
54-
:aria-keyshortcuts="keyshortcut"
49+
:aria-keyshortcuts="ariaKeyshortcuts"
5550
>
5651
<span
5752
v-if="classicon"
@@ -60,11 +55,11 @@ defineExpose({
6055
/>
6156
<slot />
6257
<kbd
63-
v-if="keyshortcut"
58+
v-if="ariaKeyshortcuts"
6459
class="ms-2 inline-flex items-center justify-center w-4 h-4 text-xs text-fg bg-bg-muted border border-border rounded no-underline"
6560
aria-hidden="true"
6661
>
67-
{{ keyshortcut }}
62+
{{ ariaKeyshortcuts }}
6863
</kbd>
6964
</button>
7065
</template>

app/components/Code/DirectoryListing.vue

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -76,13 +76,14 @@ const bytesFormatter = useBytesFormatter()
7676
class="border-b border-border hover:bg-bg-subtle transition-colors"
7777
>
7878
<td colspan="2">
79-
<NuxtLink
79+
<LinkBase
8080
:to="getCodeRoute(parentPath || undefined)"
81-
class="flex items-center gap-2 py-2 px-4 font-mono text-sm text-fg-muted hover:text-fg transition-colors"
81+
class="py-2 px-4 font-mono text-sm w-full"
82+
no-underline
83+
classicon="i-carbon:folder text-yellow-600"
8284
>
83-
<span class="i-carbon:folder w-4 h-4 text-yellow-600" />
84-
<span>..</span>
85-
</NuxtLink>
85+
<span class="w-full flex justify-self-stretch items-center gap-2"> .. </span>
86+
</LinkBase>
8687
</td>
8788
</tr>
8889

@@ -93,24 +94,26 @@ const bytesFormatter = useBytesFormatter()
9394
class="border-b border-border hover:bg-bg-subtle transition-colors"
9495
>
9596
<td colspan="2">
96-
<NuxtLink
97+
<LinkBase
9798
:to="getCodeRoute(node.path)"
98-
class="flex items-center gap-2 py-2 px-4 font-mono text-sm hover:text-fg transition-colors"
99-
:class="node.type === 'directory' ? 'text-fg' : 'text-fg-muted'"
99+
class="py-2 px-4 font-mono text-sm w-full"
100+
no-underline
101+
:classicon="
102+
node.type === 'directory'
103+
? 'i-carbon:folder text-yellow-600'
104+
: getFileIcon(node.name)
105+
"
100106
>
101-
<span
102-
v-if="node.type === 'directory'"
103-
class="i-carbon:folder w-4 h-4 text-yellow-600"
104-
/>
105-
<span v-else class="w-4 h-4" :class="getFileIcon(node.name)" />
106-
<span class="flex-1">{{ node.name }}</span>
107-
<span
108-
v-if="node.type === 'file' && node.size"
109-
class="text-end font-mono text-xs text-fg-subtle"
110-
>
111-
{{ bytesFormatter.format(node.size) }}
107+
<span class="w-full flex justify-self-stretch items-center gap-2">
108+
<span class="flex-1">{{ node.name }}</span>
109+
<span
110+
v-if="node.type === 'file' && node.size"
111+
class="text-end text-xs text-fg-subtle"
112+
>
113+
{{ bytesFormatter.format(node.size) }}
114+
</span>
112115
</span>
113-
</NuxtLink>
116+
</LinkBase>
114117
</td>
115118
</tr>
116119
</tbody>

app/components/Code/FileTree.vue

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -49,17 +49,13 @@ watch(
4949
<li v-for="node in tree" :key="node.path">
5050
<!-- Directory -->
5151
<template v-if="node.type === 'directory'">
52-
<button
53-
type="button"
54-
class="w-full flex items-center gap-1.5 py-1.5 px-3 text-start font-mono text-sm transition-colors hover:bg-bg-muted"
55-
:class="isNodeActive(node) ? 'text-fg' : 'text-fg-muted'"
52+
<ButtonBase
53+
class="w-full flex! justify-start! rounded-none! border-none!"
54+
:aria-pressed="isNodeActive(node)"
5655
:style="{ paddingLeft: `${depth * 12 + 12}px` }"
5756
@click="toggleDir(node.path)"
57+
:classicon="isExpanded(node.path) ? 'i-carbon:chevron-down' : 'i-carbon:chevron-right'"
5858
>
59-
<span
60-
class="w-4 h-4 shrink-0 transition-transform"
61-
:class="[isExpanded(node.path) ? 'i-carbon:chevron-down' : 'i-carbon:chevron-right']"
62-
/>
6359
<span
6460
class="w-4 h-4 shrink-0"
6561
:class="
@@ -69,7 +65,7 @@ watch(
6965
"
7066
/>
7167
<span class="truncate">{{ node.name }}</span>
72-
</button>
68+
</ButtonBase>
7369
<CodeFileTree
7470
v-if="isExpanded(node.path) && node.children"
7571
:tree="node.children"
@@ -82,15 +78,16 @@ watch(
8278

8379
<!-- File -->
8480
<template v-else>
85-
<NuxtLink
81+
<LinkBase
82+
variant="button-secondary"
8683
:to="getFileRoute(node.path)"
87-
class="flex items-center gap-1.5 py-1.5 px-3 font-mono text-sm transition-colors hover:bg-bg-muted"
88-
:class="currentPath === node.path ? 'bg-bg-muted text-fg' : 'text-fg-muted'"
84+
:aria-current="currentPath === node.path"
85+
class="w-full flex! justify-start! rounded-none! border-none!"
8986
:style="{ paddingLeft: `${depth * 12 + 32}px` }"
87+
:classicon="getFileIcon(node.name)"
9088
>
91-
<span class="w-4 h-4 shrink-0" :class="getFileIcon(node.name)" />
9289
<span class="truncate">{{ node.name }}</span>
93-
</NuxtLink>
90+
</LinkBase>
9491
</template>
9592
</li>
9693
</ul>

app/components/Code/MobileTreeDrawer.vue

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,13 @@ watch(isOpen, open => (isLocked.value = open))
2727

2828
<template>
2929
<!-- Toggle button (mobile only) -->
30-
<button
31-
type="button"
32-
class="md:hidden fixed bottom-4 inset-ie-4 z-40 w-12 h-12 bg-bg-elevated border border-border rounded-full shadow-lg flex items-center justify-center text-fg-muted hover:text-fg transition-colors"
30+
<ButtonBase
31+
variant="primary"
32+
class="md:hidden fixed bottom-4 inset-ie-4 z-45"
3333
:aria-label="$t('code.toggle_tree')"
3434
@click="isOpen = !isOpen"
35-
>
36-
<span class="w-5 h-5" :class="isOpen ? 'i-carbon:close' : 'i-carbon:folder'" />
37-
</button>
35+
:classicon="isOpen ? 'i-carbon:close' : 'i-carbon:folder'"
36+
/>
3837

3938
<!-- Backdrop -->
4039
<Transition
@@ -66,14 +65,11 @@ watch(isOpen, open => (isLocked.value = open))
6665
>
6766
<span class="font-mono text-sm text-fg-muted">{{ $t('code.files_label') }}</span>
6867
<span aria-hidden="true" class="flex-shrink-1 flex-grow-1" />
69-
<button
70-
type="button"
71-
class="text-fg-muted hover:text-fg transition-colors"
68+
<ButtonBase
7269
:aria-label="$t('code.close_tree')"
7370
@click="isOpen = false"
74-
>
75-
<span class="i-carbon:close w-5 h-5" />
76-
</button>
71+
classicon="i-carbon-close"
72+
/>
7773
</div>
7874
<CodeFileTree
7975
:tree="tree"

app/components/Code/Viewer.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ watch(
6767
:style="{ '--line-digits': lineDigits }"
6868
aria-hidden="true"
6969
>
70+
<!-- This needs to be a native <a> element, because `LinkBase` (or specifically `NuxtLink`) does not seem to work when trying to prevent default behavior (jumping to the anchor) -->
7071
<a
7172
v-for="lineNum in lineNumbers"
7273
:id="`L${lineNum}`"

app/components/Compare/ComparisonGrid.vue

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,13 @@ function getReplacementTooltip(col: ComparisonGridColumn): string {
4040
<!-- Package columns -->
4141
<div v-for="col in columns" :key="col.name" class="comparison-cell comparison-cell-header">
4242
<span class="inline-flex items-center gap-1.5 truncate">
43-
<NuxtLink
43+
<LinkBase
4444
:to="packageRoute(col.name, col.version)"
45-
class="link-subtle font-mono text-sm font-medium text-fg truncate"
45+
class="text-sm flex! truncate"
4646
:title="col.version ? `${col.name}@${col.version}` : col.name"
4747
>
4848
{{ col.name }}<template v-if="col.version">@{{ col.version }}</template>
49-
</NuxtLink>
49+
</LinkBase>
5050
<TooltipApp v-if="col.replacement" :text="getReplacementTooltip(col)" position="bottom">
5151
<span
5252
class="i-carbon:idea w-3.5 h-3.5 text-amber-500 shrink-0 cursor-help"
@@ -79,13 +79,9 @@ function getReplacementTooltip(col: ComparisonGridColumn): string {
7979
<p class="text-xs text-fg-muted">
8080
<i18n-t keypath="compare.no_dependency.tooltip_description" tag="span">
8181
<template #link>
82-
<a
83-
href="https://e18e.dev/docs/replacements/"
84-
target="_blank"
85-
rel="noopener noreferrer"
86-
class="text-accent hover:underline"
87-
>{{ $t('compare.no_dependency.e18e_community') }}</a
88-
>
82+
<LinkBase to="https://e18e.dev/docs/replacements/">{{
83+
$t('compare.no_dependency.e18e_community')
84+
}}</LinkBase>
8985
</template>
9086
</i18n-t>
9187
</p>

app/components/Compare/FacetSelector.vue

Lines changed: 20 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -32,47 +32,39 @@ function isCategoryNoneSelected(category: string): boolean {
3232
<span class="text-3xs text-fg-subtle uppercase tracking-wider">
3333
{{ getCategoryLabel(category) }}
3434
</span>
35-
<button
36-
type="button"
37-
class="text-3xs transition-colors focus-visible:outline-none focus-visible:underline focus-visible:underline-accent"
38-
:class="
39-
isCategoryAllSelected(category)
40-
? 'text-fg-muted'
41-
: 'text-fg-muted/60 hover:text-fg-muted'
42-
"
35+
<!-- TODO: These should be radios, since they are mutually exclusive, and currently this behavior is faked with buttons -->
36+
<ButtonBase
4337
:aria-label="
4438
$t('compare.facets.select_category', { category: getCategoryLabel(category) })
4539
"
40+
:aria-pressed="isCategoryAllSelected(category)"
4641
:disabled="isCategoryAllSelected(category)"
4742
@click="selectCategory(category)"
43+
size="small"
4844
>
4945
{{ $t('compare.facets.all') }}
50-
</button>
46+
</ButtonBase>
5147
<span class="text-2xs text-fg-muted/40">/</span>
52-
<button
53-
type="button"
54-
class="text-3xs transition-colors focus-visible:outline-none focus-visible:underline focus-visible:underline-accent"
55-
:class="
56-
isCategoryNoneSelected(category)
57-
? 'text-fg-muted'
58-
: 'text-fg-muted/60 hover:text-fg-muted'
59-
"
48+
<ButtonBase
6049
:aria-label="
6150
$t('compare.facets.deselect_category', { category: getCategoryLabel(category) })
6251
"
52+
:aria-pressed="isCategoryNoneSelected(category)"
6353
:disabled="isCategoryNoneSelected(category)"
6454
@click="deselectCategory(category)"
55+
size="small"
6556
>
6657
{{ $t('compare.facets.none') }}
67-
</button>
58+
</ButtonBase>
6859
</div>
6960

7061
<!-- Facet buttons -->
7162
<div class="flex items-center gap-1.5 flex-wrap" role="group">
72-
<button
63+
<!-- TODO: These should be checkboxes -->
64+
<ButtonBase
7365
v-for="facet in facetsByCategory[category]"
7466
:key="facet.id"
75-
type="button"
67+
size="small"
7668
:title="facet.comingSoon ? $t('compare.facets.coming_soon') : facet.description"
7769
:disabled="facet.comingSoon"
7870
:aria-pressed="isFacetSelected(facet.id)"
@@ -86,18 +78,19 @@ function isCategoryNoneSelected(category: string): boolean {
8678
: 'text-fg-subtle bg-bg-subtle border-border-subtle hover:text-fg-muted hover:border-border'
8779
"
8880
@click="!facet.comingSoon && toggleFacet(facet.id)"
81+
:classicon="
82+
facet.comingSoon
83+
? undefined
84+
: isFacetSelected(facet.id)
85+
? 'i-carbon:checkmark'
86+
: 'i-carbon:add'
87+
"
8988
>
90-
<span
91-
v-if="!facet.comingSoon"
92-
class="w-3 h-3"
93-
:class="isFacetSelected(facet.id) ? 'i-carbon:checkmark' : 'i-carbon:add'"
94-
aria-hidden="true"
95-
/>
9689
{{ facet.label }}
9790
<span v-if="facet.comingSoon" class="text-4xs"
9891
>({{ $t('compare.facets.coming_soon') }})</span
9992
>
100-
</button>
93+
</ButtonBase>
10194
</div>
10295
</div>
10396
</div>

0 commit comments

Comments
 (0)