Skip to content

Commit 425e73c

Browse files
committed
feat: improve package-header ui
1 parent 897244e commit 425e73c

3 files changed

Lines changed: 105 additions & 109 deletions

File tree

app/components/Code/MobileTreeDrawer.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ watch(isOpen, open => (isLocked.value = open))
2929
<!-- Toggle button (mobile only) -->
3030
<ButtonBase
3131
variant="primary"
32-
class="md:hidden fixed bottom-4 inset-ie-4 z-45"
32+
class="md:hidden fixed bottom-9 inset-ie-4 z-45"
3333
:aria-label="$t('code.toggle_tree')"
3434
@click="isOpen = !isOpen"
3535
:classicon="isOpen ? 'i-lucide:x' : 'i-lucide:folder'"

app/components/Package/Header.vue

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ const likeAction = async () => {
248248

249249
<template>
250250
<!-- Package header -->
251-
<header class="bg-bg pt-2 w-full container">
251+
<header class="bg-bg pt-5 w-full container">
252252
<!-- Package name and version -->
253253
<div class="flex items-baseline justify-between gap-x-2 gap-y-1 flex-wrap min-w-0">
254254
<CopyToClipboardButton
@@ -357,7 +357,7 @@ const likeAction = async () => {
357357
:to="packageRoute(packageName, resolvedVersion, '#provenance')"
358358
:aria-label="$t('package.provenance_section.view_more_details')"
359359
classicon="i-lucide:shield-check"
360-
class="py-1.5 px-2.5 me-2"
360+
class="py-1.25 px-2 me-2"
361361
/>
362362
</TooltipApp>
363363
</template>
@@ -387,7 +387,7 @@ const likeAction = async () => {
387387
<nav
388388
v-if="resolvedVersion"
389389
:aria-label="$t('package.navigation')"
390-
class="flex gap-4 me-auto -mb-px"
390+
class="flex gap-4 me-auto -mb-px max-w-full overflow-x-auto"
391391
:style="navExtraOffsetStyle"
392392
:class="$style.packageNav"
393393
>
@@ -444,11 +444,16 @@ const likeAction = async () => {
444444
word-break: break-word;
445445
}
446446
447-
@media (max-width: 639.9px) {
448-
.packageNav {
449-
bottom: calc(1.25rem + var(--package-nav-extra, 0px) + env(safe-area-inset-bottom, 0px));
450-
}
447+
.packageNav {
448+
scrollbar-width: none;
449+
-ms-overflow-style: none;
450+
}
451451
452+
.packageNav::-webkit-scrollbar {
453+
display: none;
454+
}
455+
456+
@media (max-width: 639.9px) {
452457
.packageNav > :global(a kbd) {
453458
display: none;
454459
}

app/pages/package-code/[[org]]/[packageName]/v/[version]/[...filePath].vue

Lines changed: 92 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -384,113 +384,94 @@ defineOgImageComponent('Default', {
384384
</aside>
385385

386386
<!-- File content / Directory listing - sticky with internal scroll on desktop -->
387-
<div
388-
class="flex-1 min-w-0 overflow-x-hidden sticky top-25 self-start overflow-y-auto"
389-
ref="contentContainer"
390-
>
391-
<!-- File viewer -->
392-
<template v-if="isViewingFile && !isBinaryFile && fileContent">
393-
<div
394-
class="sticky z-10 top-0 bg-bg border-b border-border px-4 py-2 flex items-center justify-between"
395-
>
396-
<div class="flex items-center gap-2">
397-
<div
398-
v-if="fileContent.markdownHtml"
399-
class="flex items-center gap-1 p-0.5 bg-bg-subtle border border-border-subtle rounded-md overflow-x-auto"
400-
role="tablist"
401-
aria-label="Markdown view mode selector"
387+
<div class="flex-1 min-w-0 self-start" ref="contentContainer">
388+
<div
389+
class="sticky z-10 top-25 bg-bg border-b border-border px-4 py-2 flex items-center justify-between gap-2 text-nowrap overflow-x-auto max-w-full"
390+
>
391+
<div class="flex items-center gap-2">
392+
<div
393+
v-if="fileContent?.markdownHtml"
394+
class="flex items-center gap-1 p-0.5 bg-bg-subtle border border-border-subtle rounded-md overflow-x-auto"
395+
role="tablist"
396+
aria-label="Markdown view mode selector"
397+
>
398+
<button
399+
v-for="mode in markdownViewModes"
400+
:key="mode.key"
401+
role="tab"
402+
class="px-2 py-1.5 font-mono text-xs rounded transition-colors duration-150 border border-solid focus-visible:outline-accent/70 inline-flex items-center gap-1.5"
403+
:class="
404+
markdownViewMode === mode.key
405+
? 'bg-bg shadow text-fg border-border'
406+
: 'text-fg-subtle hover:text-fg border-transparent'
407+
"
408+
@click="markdownViewMode = mode.key"
402409
>
403-
<button
404-
v-for="mode in markdownViewModes"
405-
:key="mode.key"
406-
role="tab"
407-
class="px-2 py-1.5 font-mono text-xs rounded transition-colors duration-150 border border-solid focus-visible:outline-accent/70 inline-flex items-center gap-1.5"
408-
:class="
409-
markdownViewMode === mode.key
410-
? 'bg-bg shadow text-fg border-border'
411-
: 'text-fg-subtle hover:text-fg border-transparent'
412-
"
413-
@click="markdownViewMode = mode.key"
414-
>
415-
<span class="inline-block h-3 w-3" :class="mode.icon" aria-hidden="true" />
416-
{{ mode.label }}
417-
</button>
418-
</div>
419-
<!-- Breadcrumb navigation -->
420-
<nav
421-
:aria-label="$t('code.file_path')"
422-
class="flex items-center gap-0.5 font-mono text-sm overflow-x-auto"
423-
dir="ltr"
410+
<span class="inline-block h-3 w-3" :class="mode.icon" aria-hidden="true" />
411+
{{ mode.label }}
412+
</button>
413+
</div>
414+
<!-- Breadcrumb navigation -->
415+
<nav
416+
:aria-label="$t('code.file_path')"
417+
class="flex items-center gap-0.5 font-mono text-sm overflow-x-auto"
418+
dir="ltr"
419+
>
420+
<NuxtLink
421+
v-if="filePath"
422+
:to="getCurrentCodeUrlWithPath()"
423+
class="text-fg-muted hover:text-fg transition-colors shrink-0"
424424
>
425+
{{ $t('code.root') }}
426+
</NuxtLink>
427+
<span v-else class="text-fg shrink-0">{{ $t('code.root') }}</span>
428+
<template v-for="(crumb, i) in breadcrumbs" :key="crumb.path">
429+
<span class="text-fg-subtle">/</span>
425430
<NuxtLink
426-
v-if="filePath"
427-
:to="getCurrentCodeUrlWithPath()"
428-
class="text-fg-muted hover:text-fg transition-colors shrink-0"
431+
v-if="i < breadcrumbs.length - 1"
432+
:to="getCurrentCodeUrlWithPath(crumb.path)"
433+
class="text-fg-muted hover:text-fg transition-colors"
429434
>
430-
{{ $t('code.root') }}
435+
{{ crumb.name }}
431436
</NuxtLink>
432-
<span v-else class="text-fg shrink-0">{{ $t('code.root') }}</span>
433-
<template v-for="(crumb, i) in breadcrumbs" :key="crumb.path">
434-
<span class="text-fg-subtle">/</span>
435-
<NuxtLink
436-
v-if="i < breadcrumbs.length - 1"
437-
:to="getCurrentCodeUrlWithPath(crumb.path)"
438-
class="text-fg-muted hover:text-fg transition-colors"
439-
>
440-
{{ crumb.name }}
441-
</NuxtLink>
442-
<span v-else class="text-fg">{{ crumb.name }}</span>
443-
</template>
444-
</nav>
445-
<!-- <div class="flex items-center gap-3 text-sm">
446-
<span class="text-fg-muted" dir="auto">{{
447-
$t('code.lines', { count: fileContent.lines })
448-
}}</span>
449-
<span v-if="currentNode?.size" class="text-fg-subtle">{{
450-
bytesFormatter.format(currentNode.size)
451-
}}</span>
452-
</div> -->
453-
</div>
454-
<div class="flex items-center gap-2">
455-
<button
456-
type="button"
457-
class="px-2 py-1 font-mono text-xs text-fg-muted bg-bg-subtle border border-border rounded hover:text-fg hover:border-border-hover transition-colors items-center inline-flex gap-1"
458-
@click="scrollToTop"
459-
>
460-
<span class="i-lucide:arrow-up w-3 h-3" />
461-
{{ $t('code.scroll_to_top') }}
462-
</button>
463-
<button
464-
v-if="selectedLines"
465-
type="button"
466-
class="px-2 py-1 font-mono text-xs text-fg-muted bg-bg-subtle border border-border rounded hover:text-fg hover:border-border-hover transition-colors active:scale-95"
467-
@click="copyPermalinkUrl"
468-
>
469-
{{ permalinkCopied ? $t('common.copied') : $t('code.copy_link') }}
470-
</button>
471-
<button
472-
v-if="!!fileContent?.content"
473-
type="button"
474-
class="px-2 py-1 font-mono text-xs text-fg-muted bg-bg-subtle border border-border rounded hover:text-fg hover:border-border-hover transition-colors inline-flex items-center gap-1 capitalize"
475-
@click="copyFileContent()"
476-
>
477-
<span
478-
class="w-3 h-3"
479-
:class="fileContentCopied ? 'i-lucide:check' : 'i-lucide:file'"
480-
/>
481-
{{ fileContentCopied ? $t('common.copied') : $t('common.copy') }}
482-
</button>
483-
<a
484-
:href="`https://cdn.jsdelivr.net/npm/${packageName}@${version}/${filePath}`"
485-
target="_blank"
486-
rel="noopener noreferrer"
487-
class="px-2 py-1 font-mono text-xs text-fg-muted bg-bg-subtle border border-border rounded hover:text-fg hover:border-border-hover transition-colors inline-flex items-center gap-1"
488-
>
489-
{{ $t('code.raw') }}
490-
<span class="i-lucide:external-link w-3 h-3" />
491-
</a>
492-
</div>
437+
<span v-else class="text-fg">{{ crumb.name }}</span>
438+
</template>
439+
</nav>
440+
</div>
441+
<div class="flex items-center gap-2" v-if="isViewingFile && !isBinaryFile && fileContent">
442+
<button
443+
v-if="selectedLines"
444+
type="button"
445+
class="px-2 py-1 font-mono text-xs text-fg-muted bg-bg-subtle border border-border rounded hover:text-fg hover:border-border-hover transition-colors active:scale-95"
446+
@click="copyPermalinkUrl"
447+
>
448+
{{ permalinkCopied ? $t('common.copied') : $t('code.copy_link') }}
449+
</button>
450+
<button
451+
v-if="!!fileContent?.content"
452+
type="button"
453+
class="px-2 py-1 font-mono text-xs text-fg-muted bg-bg-subtle border border-border rounded hover:text-fg hover:border-border-hover transition-colors inline-flex items-center gap-1 capitalize"
454+
@click="copyFileContent()"
455+
>
456+
<span
457+
class="w-3 h-3"
458+
:class="fileContentCopied ? 'i-lucide:check' : 'i-lucide:file'"
459+
/>
460+
{{ fileContentCopied ? $t('common.copied') : $t('common.copy') }}
461+
</button>
462+
<a
463+
:href="`https://cdn.jsdelivr.net/npm/${packageName}@${version}/${filePath}`"
464+
target="_blank"
465+
rel="noopener noreferrer"
466+
class="px-2 py-1 font-mono text-xs text-fg-muted bg-bg-subtle border border-border rounded hover:text-fg hover:border-border-hover transition-colors inline-flex items-center gap-1"
467+
>
468+
{{ $t('code.raw') }}
469+
<span class="i-lucide:external-link w-3 h-3" />
470+
</a>
493471
</div>
472+
</div>
473+
<!-- File viewer -->
474+
<template v-if="isViewingFile && !isBinaryFile && fileContent">
494475
<div
495476
v-if="fileContent.markdownHtml"
496477
v-show="markdownViewMode === 'preview'"
@@ -506,6 +487,16 @@ defineOgImageComponent('Default', {
506487
:selected-lines="selectedLines"
507488
@line-click="handleLineClick"
508489
/>
490+
<div class="sticky bottom-0 left-0 right-0 bg-bg border-t border-border px-4 py-1">
491+
<div class="flex items-center gap-3 text-sm justify-end">
492+
<span class="text-fg-muted" dir="auto">{{
493+
$t('code.lines', { count: fileContent.lines })
494+
}}</span>
495+
<span v-if="currentNode?.size" class="text-fg-subtle">{{
496+
bytesFormatter.format(currentNode.size)
497+
}}</span>
498+
</div>
499+
</div>
509500
</template>
510501

511502
<!-- Binary file warning -->

0 commit comments

Comments
 (0)