Skip to content

Commit 3136e83

Browse files
feat(vault): trash/download actions + path-bar theming seam (#177)
1 parent 61e17d3 commit 3136e83

2 files changed

Lines changed: 31 additions & 4 deletions

File tree

src/vault/VaultPane.tsx

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import {
2323
type MouseEvent,
2424
type ReactNode,
2525
} from 'react'
26+
import { Download, Trash2 } from 'lucide-react'
2627
import { ConfirmDialog } from './ConfirmDialog'
2728
import type {
2829
VaultEditorMode,
@@ -186,6 +187,8 @@ export function VaultPane(props: VaultPaneProps) {
186187
dockToggle,
187188
refreshKey,
188189
headerActions,
190+
onDownloadFile,
191+
pathBarClassName,
189192
} = props
190193

191194
const activeCodec = codec ?? IDENTITY_CODEC
@@ -501,8 +504,8 @@ export function VaultPane(props: VaultPaneProps) {
501504

502505
<div className="flex min-w-0 flex-1 flex-col overflow-hidden">
503506
{selectedFile && (
504-
<div className="flex shrink-0 items-center justify-between border-b border-border bg-card px-4 py-1.5">
505-
<span data-vault-path className="truncate text-xs text-muted-foreground">{selectedFile.path}</span>
507+
<div className={`flex shrink-0 items-center justify-between border-b border-border px-4 py-1.5 ${pathBarClassName ?? 'bg-card'}`}>
508+
<span data-vault-path className="truncate text-xs font-medium text-foreground">{selectedFile.path}</span>
506509
<div className="flex items-center gap-1">
507510
{canWrite && isMarkdownCapable && (
508511
<div className="mr-1 flex items-center gap-1">
@@ -551,15 +554,26 @@ export function VaultPane(props: VaultPaneProps) {
551554
{dockToggleCfg.label}
552555
</button>
553556
)}
557+
{onDownloadFile && (
558+
<button
559+
type="button"
560+
aria-label="Download this file"
561+
title="Download file"
562+
onClick={() => onDownloadFile(selectedFile)}
563+
className="inline-flex h-7 w-7 items-center justify-center rounded text-muted-foreground transition-colors hover:bg-muted hover:text-foreground"
564+
>
565+
<Download className="h-4 w-4" />
566+
</button>
567+
)}
554568
{canWrite && (
555569
<button
556570
type="button"
557571
aria-label="Delete this file"
558572
title="Delete file"
559573
onClick={() => setDeleteOpen(true)}
560-
className="p-1 text-muted-foreground transition-colors hover:text-destructive"
574+
className="inline-flex h-7 w-7 items-center justify-center rounded text-destructive/70 transition-colors hover:bg-destructive/10 hover:text-destructive"
561575
>
562-
576+
<Trash2 className="h-4 w-4" />
563577
</button>
564578
)}
565579
</div>

src/vault/contracts.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,19 @@ export interface VaultPaneProps {
150150
refreshKey?: number | string
151151
/** Extra controls rendered in the tree-pane header (e.g. an upload button). */
152152
headerActions?: ReactNode
153+
/**
154+
* When set, a download button renders in the open file's path row (before the
155+
* delete action). The product owns the actual download (mime, blob) via this
156+
* callback. Omit to hide the button — e.g. when a custom artifact renderer
157+
* provides its own download affordance.
158+
*/
159+
onDownloadFile?: (file: VaultFile) => void
160+
/**
161+
* Extra classes for the open file's path row (path + mode toggles + actions).
162+
* Use to align its surface with the artifact chrome. Replaces the default
163+
* `bg-card` when it carries a background utility.
164+
*/
165+
pathBarClassName?: string
153166
/**
154167
* When false, all write affordances (create / delete / save / source editor)
155168
* are hidden and the pane is read-only. Defaults to true.

0 commit comments

Comments
 (0)