Skip to content

Commit c09999d

Browse files
committed
refactor: use button and link components for code pages
1 parent 25237d3 commit c09999d

File tree

4 files changed

+47
-47
lines changed

4 files changed

+47
-47
lines changed

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+
noUnderline
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+
noUnderline
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-45 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/Link/Base.vue

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ const props = withDefaults(
3131
3232
/** always use `to` instead of `href` */
3333
href?: never
34+
35+
/** should only be used for links where the context makes it very clear they are clickable. Don't just use this, because you don't like underlines. */
36+
noUnderline?: boolean
3437
} & NuxtLinkProps
3538
>(),
3639
{ variant: 'link', size: 'medium' },
@@ -70,7 +73,8 @@ const isButtonMedium = computed(() => props.size === 'medium' && props.variant !
7073
v-else
7174
class="group inline-flex gap-x-1 items-center justify-center"
7275
:class="{
73-
'underline-offset-[0.2rem] underline decoration-1 decoration-fg/30': !isLinkAnchor && isLink,
76+
'underline-offset-[0.2rem] underline decoration-1 decoration-fg/30':
77+
!isLinkAnchor && isLink && !noUnderline,
7478
'font-mono text-fg hover:(decoration-accent text-accent) focus-visible:(decoration-accent text-accent) transition-colors duration-200':
7579
isLink,
7680
'font-mono border border-border rounded-md transition-all duration-200': isButton,

0 commit comments

Comments
 (0)