({
asset,
vaultRoot,
onOpen,
onContextMenu
}: {
asset: AssetMeta
vaultRoot: string | null
onOpen: () => void
onContextMenu?: (e: React.MouseEvent) => void
})
| 1100 | } |
| 1101 | |
| 1102 | function AssetRow({ |
| 1103 | asset, |
| 1104 | vaultRoot, |
| 1105 | onOpen, |
| 1106 | onContextMenu |
| 1107 | }: { |
| 1108 | asset: AssetMeta |
| 1109 | vaultRoot: string | null |
| 1110 | onOpen: () => void |
| 1111 | onContextMenu?: (e: React.MouseEvent) => void |
| 1112 | }): JSX.Element { |
| 1113 | const url = assetUrl(vaultRoot, asset.path) |
| 1114 | |
| 1115 | return ( |
| 1116 | <button |
| 1117 | type="button" |
| 1118 | onClick={onOpen} |
| 1119 | onContextMenu={onContextMenu} |
| 1120 | draggable |
| 1121 | onDragStart={(e) => setDragPayload(e, { kind: 'asset', path: asset.path })} |
| 1122 | className="flex h-[60px] items-center gap-3 rounded-lg border border-transparent px-3 py-2 text-left transition-colors hover:border-paper-300/70 hover:bg-paper-200/45" |
| 1123 | > |
| 1124 | <div className="flex h-12 w-12 shrink-0 items-center justify-center overflow-hidden rounded-lg bg-paper-200/45"> |
| 1125 | {asset.kind === 'image' && url ? ( |
| 1126 | <img |
| 1127 | src={url} |
| 1128 | alt={asset.name} |
| 1129 | className="h-full w-full object-cover" |
| 1130 | loading="lazy" |
| 1131 | /> |
| 1132 | ) : ( |
| 1133 | <span className="text-2xs uppercase tracking-[0.16em] text-ink-500">{asset.kind}</span> |
| 1134 | )} |
| 1135 | </div> |
| 1136 | <div className="min-w-0 flex-1"> |
| 1137 | <div className="truncate text-sm font-medium text-ink-900">{asset.name}</div> |
| 1138 | <div className="truncate text-xs text-ink-500">{asset.path}</div> |
| 1139 | </div> |
| 1140 | <div className="shrink-0 text-xs text-ink-500"> |
| 1141 | {formatBytes(asset.size)} |
| 1142 | </div> |
| 1143 | </button> |
| 1144 | ) |
| 1145 | } |
nothing calls this directly
no test coverage detected