47 lines
1.4 KiB
TypeScript
47 lines
1.4 KiB
TypeScript
export type MediaSetEntry = string | { url: string; name?: string };
|
|
|
|
export function mediaSetEntryUrl(e: MediaSetEntry): string {
|
|
return typeof e === 'string' ? e : e.url;
|
|
}
|
|
|
|
function entryLabel(e: MediaSetEntry, index: number): string {
|
|
if (typeof e === 'object' && e.name) return `${index + 1}: ${e.name}`;
|
|
const file = mediaSetEntryUrl(e);
|
|
const fileName = file.split('/').pop() || file;
|
|
return `${index + 1}: ${fileName.replace(/\.[^.]+$/, '')}`;
|
|
}
|
|
|
|
interface MediaSetProps {
|
|
files: MediaSetEntry[];
|
|
activeUrl: string;
|
|
onSwitch: (url: string) => void;
|
|
}
|
|
|
|
export default function MediaSet({ files, activeUrl, onSwitch }: MediaSetProps) {
|
|
return (
|
|
<div>
|
|
<div className="text-sm text-neutral-500 mb-2">Media Set</div>
|
|
<div className="flex gap-2 flex-wrap">
|
|
{files.map((entry, index) => {
|
|
const url = mediaSetEntryUrl(entry);
|
|
const label = entryLabel(entry, index);
|
|
const active = activeUrl === url;
|
|
return (
|
|
<button
|
|
key={url}
|
|
onClick={() => onSwitch(url)}
|
|
className={`px-3 py-1.5 rounded-lg text-sm ${
|
|
active
|
|
? 'bg-blue-600 text-white'
|
|
: 'bg-neutral-100 text-neutral-700 hover:bg-neutral-200'
|
|
}`}
|
|
>
|
|
{label}
|
|
</button>
|
|
);
|
|
})}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|