-
-
Notifications
You must be signed in to change notification settings - Fork 389
feat: add sidebar toggle to package code browser #2352
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
60a722b
4ce9fea
0aaefd8
3efdba1
22fee07
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -288,6 +288,24 @@ | |||||||||||||
| primaryColor: '#60a5fa', | ||||||||||||||
| }) | ||||||||||||||
|
|
||||||||||||||
|
|
||||||||||||||
| // Sidebar visibility | ||||||||||||||
| const { settings } = useSettings() | ||||||||||||||
| const isSidebarCollapsed = computed({ | ||||||||||||||
| get: () => settings.value.sidebar.collapsed.includes('code'), | ||||||||||||||
| set: value => { | ||||||||||||||
| const collapsed = settings.value.sidebar.collapsed.filter(id => id !== 'code') | ||||||||||||||
| if (value) { | ||||||||||||||
| collapsed.push('code') | ||||||||||||||
| } | ||||||||||||||
| settings.value.sidebar.collapsed = collapsed | ||||||||||||||
| }, | ||||||||||||||
| }) | ||||||||||||||
|
|
||||||||||||||
| function toggleSidebar() { | ||||||||||||||
| isSidebarCollapsed.value = !isSidebarCollapsed.value | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| onPrehydrate(el => { | ||||||||||||||
| const settingsSaved = JSON.parse(localStorage.getItem('npmx-settings') || '{}') | ||||||||||||||
| const container = el.querySelector('#code-page-container') | ||||||||||||||
|
|
@@ -296,6 +314,7 @@ | |||||||||||||
| container.classList.add('container-full') | ||||||||||||||
| } | ||||||||||||||
| }) | ||||||||||||||
|
|
||||||||||||||
| </script> | ||||||||||||||
|
|
||||||||||||||
| <template> | ||||||||||||||
|
|
@@ -341,7 +360,13 @@ | |||||||||||||
| > | ||||||||||||||
| <!-- File tree sidebar - sticky with internal scroll --> | ||||||||||||||
| <aside | ||||||||||||||
|
|
||||||||||||||
| id="file-tree-sidebar" | ||||||||||||||
| v-show="!isSidebarCollapsed" | ||||||||||||||
| class="w-64 lg:w-72 border-ie border-border shrink-0 hidden md:block bg-bg-subtle sticky top-25 self-start h-[calc(100vh-7rem)] overflow-y-auto" | ||||||||||||||
|
|
||||||||||||||
| class="sticky top-25 w-64 lg:w-72 hidden md:block h-[calc(100vh-10.5rem)] shrink-0 self-start bg-bg-subtle border-ie border-border" | ||||||||||||||
|
|
||||||||||||||
| > | ||||||||||||||
| <div class="h-[calc(100vh-10.5rem)] overflow-y-auto"> | ||||||||||||||
| <CodeFileTree | ||||||||||||||
|
|
@@ -354,6 +379,110 @@ | |||||||||||||
| </aside> | ||||||||||||||
|
|
||||||||||||||
| <!-- File content / Directory listing - sticky with internal scroll on desktop --> | ||||||||||||||
|
|
||||||||||||||
| <div class="flex-1 min-w-0 self-start"> | ||||||||||||||
| <div | ||||||||||||||
| class="sticky z-5 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" | ||||||||||||||
| > | ||||||||||||||
| <div class="flex items-center gap-2"> | ||||||||||||||
| <!-- Sidebar toggle button --> | ||||||||||||||
| <button | ||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider adding
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sure will add those 👍 |
||||||||||||||
| type="button" | ||||||||||||||
| class="hidden md:flex items-center justify-center w-8 h-8 text-fg-subtle hover:text-fg transition-colors focus-visible:outline-accent/70 rounded" | ||||||||||||||
| :aria-label="$t(isSidebarCollapsed ? 'code.show_sidebar' : 'code.hide_sidebar')" | ||||||||||||||
| :aria-expanded="!isSidebarCollapsed" | ||||||||||||||
| aria-controls="file-tree-sidebar" | ||||||||||||||
| @click="toggleSidebar" | ||||||||||||||
| > | ||||||||||||||
| <span | ||||||||||||||
| class="w-4 h-4" | ||||||||||||||
| :class="isSidebarCollapsed ? 'i-lucide:sidebar-open' : 'i-lucide:sidebar-close'" | ||||||||||||||
| aria-hidden="true" | ||||||||||||||
| /> | ||||||||||||||
| </button> | ||||||||||||||
|
|
||||||||||||||
| <div | ||||||||||||||
| v-if="fileContent?.markdownHtml" | ||||||||||||||
| class="flex items-center gap-1 p-0.5 bg-bg-subtle border border-border-subtle rounded-md overflow-x-auto" | ||||||||||||||
| role="tablist" | ||||||||||||||
| aria-label="Markdown view mode selector" | ||||||||||||||
| > | ||||||||||||||
| <button | ||||||||||||||
| v-for="mode in markdownViewModes" | ||||||||||||||
|
Check failure on line 411 in app/pages/package-code/[[org]]/[packageName]/v/[version]/[...filePath].vue
|
||||||||||||||
| :key="mode.key" | ||||||||||||||
| role="tab" | ||||||||||||||
| 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" | ||||||||||||||
| :class=" | ||||||||||||||
| markdownViewMode === mode.key | ||||||||||||||
| ? 'bg-bg shadow text-fg border-border' | ||||||||||||||
| : 'text-fg-subtle hover:text-fg border-transparent' | ||||||||||||||
| " | ||||||||||||||
| :aria-selected="markdownViewMode === mode.key" | ||||||||||||||
| @click="markdownViewMode = mode.key" | ||||||||||||||
| > | ||||||||||||||
| <span class="inline-block h-3 w-3" :class="mode.icon" aria-hidden="true" /> | ||||||||||||||
| {{ mode.label }} | ||||||||||||||
| </button> | ||||||||||||||
| </div> | ||||||||||||||
| <!-- Breadcrumb navigation --> | ||||||||||||||
| <nav | ||||||||||||||
| :aria-label="$t('code.file_path')" | ||||||||||||||
| class="flex items-center gap-0.5 font-mono text-sm overflow-x-auto" | ||||||||||||||
| dir="ltr" | ||||||||||||||
| > | ||||||||||||||
| <NuxtLink | ||||||||||||||
| v-if="filePath" | ||||||||||||||
| :to="getCurrentCodeUrlWithPath()" | ||||||||||||||
| class="text-fg-muted hover:text-fg transition-colors shrink-0" | ||||||||||||||
| > | ||||||||||||||
| {{ $t('code.root') }} | ||||||||||||||
| </NuxtLink> | ||||||||||||||
| <span v-else class="text-fg shrink-0">{{ $t('code.root') }}</span> | ||||||||||||||
| <template v-for="(crumb, i) in breadcrumbs" :key="crumb.path"> | ||||||||||||||
|
Check failure on line 441 in app/pages/package-code/[[org]]/[packageName]/v/[version]/[...filePath].vue
|
||||||||||||||
| <span class="text-fg-subtle">/</span> | ||||||||||||||
| <NuxtLink | ||||||||||||||
| v-if="i < breadcrumbs.length - 1" | ||||||||||||||
|
Check failure on line 444 in app/pages/package-code/[[org]]/[packageName]/v/[version]/[...filePath].vue
|
||||||||||||||
| :to="getCurrentCodeUrlWithPath(crumb.path)" | ||||||||||||||
| class="text-fg-muted hover:text-fg transition-colors" | ||||||||||||||
| > | ||||||||||||||
| {{ crumb.name }} | ||||||||||||||
| </NuxtLink> | ||||||||||||||
| <span v-else class="text-fg">{{ crumb.name }}</span> | ||||||||||||||
| </template> | ||||||||||||||
| </nav> | ||||||||||||||
| </div> | ||||||||||||||
| <div class="flex items-center gap-2" v-if="isViewingFile && !isBinaryFile && fileContent"> | ||||||||||||||
| <button | ||||||||||||||
| v-if="selectedLines" | ||||||||||||||
| type="button" | ||||||||||||||
| 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" | ||||||||||||||
| @click="copyPermalinkUrl" | ||||||||||||||
|
Check failure on line 459 in app/pages/package-code/[[org]]/[packageName]/v/[version]/[...filePath].vue
|
||||||||||||||
| > | ||||||||||||||
| {{ permalinkCopied ? $t('common.copied') : $t('code.copy_link') }} | ||||||||||||||
|
Check failure on line 461 in app/pages/package-code/[[org]]/[packageName]/v/[version]/[...filePath].vue
|
||||||||||||||
| </button> | ||||||||||||||
| <button | ||||||||||||||
| v-if="!!fileContent?.content" | ||||||||||||||
| type="button" | ||||||||||||||
| 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" | ||||||||||||||
| @click="copyFileContent()" | ||||||||||||||
|
Check failure on line 467 in app/pages/package-code/[[org]]/[packageName]/v/[version]/[...filePath].vue
|
||||||||||||||
| > | ||||||||||||||
| <span | ||||||||||||||
| class="w-3 h-3" | ||||||||||||||
| :class="fileContentCopied ? 'i-lucide:check' : 'i-lucide:file'" | ||||||||||||||
|
Check failure on line 471 in app/pages/package-code/[[org]]/[packageName]/v/[version]/[...filePath].vue
|
||||||||||||||
| /> | ||||||||||||||
| {{ fileContentCopied ? $t('common.copied') : $t('common.copy') }} | ||||||||||||||
|
Check failure on line 473 in app/pages/package-code/[[org]]/[packageName]/v/[version]/[...filePath].vue
|
||||||||||||||
|
Comment on lines
+411
to
+473
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Missing function and variable definitions cause type check failures. The template references several identifiers that are not defined in the
These are likely defined in the existing 🧰 Tools🪛 GitHub Check: 💪 Type check[failure] 473-473: [failure] 471-471: [failure] 467-467: [failure] 461-461: [failure] 459-459: [failure] 444-444: [failure] 441-441: [failure] 411-411: |
||||||||||||||
| </button> | ||||||||||||||
| <a | ||||||||||||||
| :href="`https://cdn.jsdelivr.net/npm/${packageName}@${version}/${filePath}`" | ||||||||||||||
| target="_blank" | ||||||||||||||
| rel="noopener noreferrer" | ||||||||||||||
| 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" | ||||||||||||||
| > | ||||||||||||||
| {{ $t('code.raw') }} | ||||||||||||||
| <span class="i-lucide:external-link w-3 h-3" /> | ||||||||||||||
| </a> | ||||||||||||||
| </div> | ||||||||||||||
| </div> | ||||||||||||||
| <div class="flex-1 grid grid-rows-[auto_1fr_auto] h-full min-h-full min-w-0 self-start"> | ||||||||||||||
|
Comment on lines
+382
to
486
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Template structure is broken — orphaned div and duplicate header components. The new toolbar div starting at line 383 appears to be incomplete or improperly merged with the existing code. Observations:
It looks like the new toolbar (lines 384-485) was intended to replace
🧰 Tools🪛 GitHub Check: 💪 Type check[failure] 473-473: [failure] 471-471: [failure] 467-467: [failure] 461-461: [failure] 459-459: [failure] 444-444: [failure] 441-441: [failure] 411-411: |
||||||||||||||
| <CodeHeader | ||||||||||||||
| :file-path="filePath" | ||||||||||||||
|
|
@@ -371,6 +500,7 @@ | |||||||||||||
| <!-- Loading file/directory content --> | ||||||||||||||
| <CodeSkeletonLoader v-if="isLoading" /> | ||||||||||||||
|
|
||||||||||||||
|
|
||||||||||||||
| <!-- File viewer --> | ||||||||||||||
| <template v-else-if="isViewingFile && !isBinaryFile && fileContent"> | ||||||||||||||
| <div | ||||||||||||||
|
|
||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Duplicate
classattribute causes build failure.The
<aside>element has twoclassattributes (lines 366 and 368), which is invalid HTML and is causing the Storybook/Chromatic build to fail with "Duplicate attribute" error. You need to merge these into a singleclassattribute.🐛 Proposed fix to merge the duplicate class attributes
<aside id="file-tree-sidebar" v-show="!isSidebarCollapsed" - class="w-64 lg:w-72 border-ie border-border shrink-0 hidden md:block bg-bg-subtle sticky top-25 self-start h-[calc(100vh-7rem)] overflow-y-auto" - - class="sticky top-25 w-64 lg:w-72 hidden md:block h-[calc(100vh-10.5rem)] shrink-0 self-start bg-bg-subtle border-ie border-border" - + class="sticky top-25 w-64 lg:w-72 hidden md:block h-[calc(100vh-10.5rem)] shrink-0 self-start bg-bg-subtle border-ie border-border overflow-y-auto" >📝 Committable suggestion
🧰 Tools
🪛 GitHub Actions: chromatic
[error] 368-368: Storybook build failed (plugin vite:vue). RolldownError/SyntaxError: Duplicate attribute.