31 lines
2.0 KiB
TypeScript
31 lines
2.0 KiB
TypeScript
import { FolderSimple, ImageBroken, SlidersHorizontal } from "@phosphor-icons/react";
|
|
import type { LayerThumbnailModel, RasterThumbnailModel } from "./thumbnailModel";
|
|
|
|
export function LayerThumbnail({ model, label, compact = false }: { model: LayerThumbnailModel; label: string; compact?: boolean }) {
|
|
const sizeClass = compact ? "h-7 w-9 rounded-md" : "h-8 w-10 rounded-lg";
|
|
return (
|
|
<span role="img" aria-label={label} className={`relative grid shrink-0 place-items-center overflow-hidden bg-black/25 ring-1 ring-inset ring-white/15 ${sizeClass}`}>
|
|
{model.kind === "raster" ? <RasterPreview model={model} /> : null}
|
|
{model.kind === "group" ? (
|
|
<>
|
|
<span className="absolute inset-1 grid grid-cols-2 gap-px overflow-hidden rounded">
|
|
{model.previews.map((preview, index) => <RasterPreview key={`${preview.source}-${index}`} model={preview} />)}
|
|
</span>
|
|
<FolderSimple size={compact ? 14 : 17} weight="fill" className="relative drop-shadow-[0_1px_2px_rgba(0,0,0,0.8)]" />
|
|
</>
|
|
) : null}
|
|
{model.kind === "empty" ? <ImageBroken size={compact ? 14 : 17} className="text-white/35" /> : null}
|
|
{model.kind === "adjustment" ? <SlidersHorizontal size={compact ? 14 : 17} className="text-violet-200" /> : null}
|
|
</span>
|
|
);
|
|
}
|
|
|
|
function RasterPreview({ model }: { model: RasterThumbnailModel }) {
|
|
const { x, y, w, h } = model.viewBox;
|
|
return (
|
|
<svg aria-hidden="true" className="h-full w-full bg-[linear-gradient(45deg,rgba(255,255,255,.06)_25%,transparent_25%,transparent_75%,rgba(255,255,255,.06)_75%),linear-gradient(45deg,rgba(255,255,255,.06)_25%,transparent_25%,transparent_75%,rgba(255,255,255,.06)_75%)] bg-[length:8px_8px] bg-[position:0_0,4px_4px]" viewBox={`${x} ${y} ${w} ${h}`} preserveAspectRatio="xMidYMid meet">
|
|
<image href={model.source} x="0" y="0" width={model.intrinsicWidth} height={model.intrinsicHeight} onError={(event) => event.currentTarget.setAttribute("visibility", "hidden")} />
|
|
</svg>
|
|
);
|
|
}
|