126 lines
3.6 KiB
TypeScript
126 lines
3.6 KiB
TypeScript
"use client";
|
|
import {
|
|
Download,
|
|
Play,
|
|
Ungroup,
|
|
Share2,
|
|
Grid3X3,
|
|
ScanLine,
|
|
} from "lucide-react";
|
|
export function CanvasGroupToolbar({
|
|
title,
|
|
color,
|
|
status,
|
|
busy,
|
|
storyboard,
|
|
canStoryboard,
|
|
onRename,
|
|
onColor,
|
|
onLayout,
|
|
onRun,
|
|
onUngroup,
|
|
onSave,
|
|
onDownload,
|
|
onStoryboard,
|
|
onCancel,
|
|
}: {
|
|
title: string;
|
|
color: string;
|
|
status: string;
|
|
busy: boolean;
|
|
storyboard: boolean;
|
|
canStoryboard: boolean;
|
|
onRename: (s: string) => void;
|
|
onColor: (s: string) => void;
|
|
onLayout: (s: "grid" | "horizontal" | "vertical") => void;
|
|
onRun: () => void;
|
|
onUngroup: () => void;
|
|
onSave: () => void;
|
|
onDownload: () => void;
|
|
onStoryboard: () => void;
|
|
onCancel: () => void;
|
|
}) {
|
|
return (
|
|
<div
|
|
data-canvas-overlay="true"
|
|
data-group-toolbar="true"
|
|
className="absolute left-1/2 top-[80px] z-[70] -translate-x-1/2 rounded-[22px] border border-white/10 bg-[#252525] p-4 text-white shadow-xl"
|
|
onPointerDown={(e) => e.stopPropagation()}
|
|
>
|
|
<div className="flex items-center gap-5 whitespace-nowrap text-[16px]">
|
|
<input
|
|
aria-label="编组颜色"
|
|
type="color"
|
|
value={color}
|
|
onChange={(e) => onColor(e.target.value)}
|
|
className="h-7 w-7 cursor-pointer rounded-full border-0 bg-transparent"
|
|
/>
|
|
<label title="编组布局" className="flex items-center gap-1">
|
|
<Grid3X3 size={20} />
|
|
<select
|
|
aria-label="编组布局"
|
|
defaultValue=""
|
|
onChange={(e) => {
|
|
onLayout(e.target.value as any);
|
|
e.target.value = "";
|
|
}}
|
|
className="w-5 bg-[#252525]"
|
|
>
|
|
<option value="" disabled>
|
|
⌄
|
|
</option>
|
|
<option value="grid">网格布局</option>
|
|
<option value="horizontal">横向布局</option>
|
|
<option value="vertical">纵向布局</option>
|
|
</select>
|
|
</label>
|
|
<span className="h-8 w-px bg-white/10" />
|
|
<button
|
|
type="button"
|
|
disabled={busy}
|
|
onClick={onRun}
|
|
className="flex items-center gap-2 disabled:opacity-40"
|
|
>
|
|
<Play size={22} />
|
|
整组执行
|
|
</button>
|
|
<button onClick={onSave} className="flex items-center gap-2">
|
|
<Share2 size={22} />
|
|
添加到工具箱
|
|
</button>
|
|
<button
|
|
type="button"
|
|
disabled={!canStoryboard}
|
|
title={
|
|
canStoryboard ? "" : "分镜组需要全部成员都是已就绪的图片或视频"
|
|
}
|
|
onClick={onStoryboard}
|
|
className="flex items-center gap-2 disabled:opacity-35"
|
|
>
|
|
<ScanLine size={22} />
|
|
{storyboard ? "预览分镜" : "转分镜组"}
|
|
</button>
|
|
<button onClick={onUngroup} className="flex items-center gap-2">
|
|
<Ungroup size={22} />
|
|
解组
|
|
</button>
|
|
<span className="h-8 w-px bg-white/10" />
|
|
<button title="下载编组模板" onClick={onDownload}>
|
|
<Download size={22} />
|
|
</button>
|
|
</div>
|
|
<div className="mt-3 flex items-center justify-between gap-4 text-xs text-white/55">
|
|
<input
|
|
aria-label="编组名称"
|
|
value={title}
|
|
onChange={(e) => onRename(e.target.value)}
|
|
maxLength={120}
|
|
className="w-48 border-b border-white/10 bg-transparent py-1"
|
|
/>
|
|
<span>{status || "Shift 点击多选 · ⌘/Ctrl+G 编组"}</span>
|
|
{busy && <button onClick={onCancel}>取消未开始任务</button>}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|