fix: add breadcrumb to editor header

This commit is contained in:
Kha Nguyen 2025-07-23 17:08:56 -05:00
parent b208f355e2
commit 7bd952b080
1 changed files with 60 additions and 43 deletions

View File

@ -2,14 +2,21 @@
import Link from "next/link"; import Link from "next/link";
import { Button } from "./ui/button"; import { Button } from "./ui/button";
import { ChevronLeft, Download } from "lucide-react"; import { ChevronLeft, Download, SquarePen } from "lucide-react";
import { useTimelineStore } from "@/stores/timeline-store"; import { useTimelineStore } from "@/stores/timeline-store";
import { HeaderBase } from "./header-base"; import { HeaderBase } from "./header-base";
import { formatTimeCode } from "@/lib/time"; import { formatTimeCode } from "@/lib/time";
import { useProjectStore } from "@/stores/project-store"; import { useProjectStore } from "@/stores/project-store";
import { KeyboardShortcutsHelp } from "./keyboard-shortcuts-help"; import { KeyboardShortcutsHelp } from "./keyboard-shortcuts-help";
import { useState, useRef } from "react"; import { useState, useRef, MouseEvent } from "react";
import { Input } from "@/components/ui/input"; import { Input } from "@/components/ui/input";
import {
Breadcrumb,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbList,
BreadcrumbSeparator,
} from "./ui/breadcrumb";
export function EditorHeader() { export function EditorHeader() {
const { getTotalDuration } = useTimelineStore(); const { getTotalDuration } = useTimelineStore();
@ -24,10 +31,11 @@ export function EditorHeader() {
console.log("Export project"); console.log("Export project");
}; };
const handleNameClick = () => { const handleNameEdit = (e: MouseEvent<HTMLButtonElement>) => {
if (!activeProject) return; if (!activeProject) return;
setNewName(activeProject.name); e.stopPropagation();
setIsEditing(true); setIsEditing(true);
setNewName(activeProject.name);
}; };
const handleNameSave = async () => { const handleNameSave = async () => {
@ -49,58 +57,67 @@ export function EditorHeader() {
const leftContent = ( const leftContent = (
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<Link <Breadcrumb>
href="/projects" <BreadcrumbList className="text-current">
className="font-medium tracking-tight flex items-center gap-2 hover:opacity-80 transition-opacity" <BreadcrumbItem>
> <BreadcrumbLink asChild>
<ChevronLeft className="h-4 w-4" /> <Link
</Link> href="/projects"
<div className="w-[14rem] h-9 flex items-center"> className="hover:text-muted-foreground inline-flex items-center"
{isEditing ? ( >
<Input All Projects
ref={inputRef} </Link>
className="text-sm font-medium px-2 py-1 h-9 truncate" </BreadcrumbLink>
value={newName} </BreadcrumbItem>
onChange={(e) => setNewName(e.target.value)} <BreadcrumbSeparator />
onBlur={handleNameSave} <BreadcrumbItem>
onKeyDown={handleInputKeyDown} {isEditing ? (
onFocus={(e) => e.target.select()} <Input
maxLength={64} ref={inputRef}
aria-label="Project name" className="text-sm font-medium w-40 xl:w-60 px-2 py-1 h-9 truncate"
autoFocus value={newName}
/> onChange={(e) => setNewName(e.target.value)}
) : ( onBlur={handleNameSave}
<span onKeyDown={handleInputKeyDown}
className="text-sm font-medium cursor-pointer hover:underline" onFocus={(e) => e.target.select()}
title="Click to rename" maxLength={64}
role="button" aria-label="Project name"
tabIndex={0} autoFocus
onClick={handleNameClick} />
onKeyDown={(e) => e.key === "Enter" && handleNameClick()} ) : (
> <span
<div className="truncate text-ellipsis overflow-clip w-40"> className="text-sm font-medium cursor-pointer hover:text-muted-foreground flex items-center gap-2 group"
{activeProject?.name} title="Click to rename"
</div> role="button"
</span> tabIndex={0}
)} onClick={handleNameEdit}
</div> >
<div className="truncate text-ellipsis overflow-clip max-w-40 xl:max-w-60">
{activeProject?.name}
</div>
<SquarePen className="w-3 h-3 opacity-0 group-hover:opacity-100 transition-opacity" />
</span>
)}
</BreadcrumbItem>
</BreadcrumbList>
</Breadcrumb>
</div> </div>
); );
const centerContent = ( const centerContent = (
<div className="flex items-center gap-2 text-xs"> <div className="flex items-center justify-center gap-2 text-xs">
<span> <span>
{formatTimeCode( {formatTimeCode(
getTotalDuration(), getTotalDuration(),
"HH:MM:SS:FF", "HH:MM:SS:FF",
activeProject?.fps || 30 activeProject?.fps || 30,
)} )}
</span> </span>
</div> </div>
); );
const rightContent = ( const rightContent = (
<nav className="flex items-center gap-2"> <nav className="flex items-center justify-end gap-2">
<KeyboardShortcutsHelp /> <KeyboardShortcutsHelp />
<Button <Button
size="sm" size="sm"
@ -119,7 +136,7 @@ export function EditorHeader() {
leftContent={leftContent} leftContent={leftContent}
centerContent={centerContent} centerContent={centerContent}
rightContent={rightContent} rightContent={rightContent}
className="bg-background h-[3.2rem] px-4 items-center" className="bg-background h-[3.2rem] px-4 items-center grid grid-cols-3"
/> />
); );
} }