Files
dashfront/src/components/brand/BrandThumb.jsx
2026-10-10 02:37:38 +02:00

101 lines
2.5 KiB
JavaScript

import { PureComponent } from 'react';
import Box from '@mui/material/Box';
import ThumbHashImage from '../article/ThumbHashImage';
import {
SHADOW_THUMB_RING,
TINT_ROW_HOVER,
} from '../../colors';
export default class BrandThumb extends PureComponent {
render() {
const {
brand,
size = 40,
fallback = null,
sx,
} = this.props;
const pic = brand?.pics?.[0];
if (!pic?.thumbHash && !pic?.fullHash) {
return fallback;
}
const { thumbHash, fullHash, thumbW, thumbH } = pic;
const ratio = thumbW && thumbH ? thumbW / thumbH : 1;
// Contain-fit inside a square `size x size` box, preserving aspect ratio.
let innerW = size;
let innerH = size;
if (Number.isFinite(ratio) && ratio > 0) {
if (ratio >= 1) {
innerW = size;
innerH = Math.max(1, Math.round(size / ratio));
} else {
innerH = size;
innerW = Math.max(1, Math.round(size * ratio));
}
}
return (
<Box
component="span"
sx={{
display: 'inline-flex',
alignItems: 'center',
justifyContent: 'center',
height: size,
width: size,
minWidth: size,
maxWidth: size,
flexShrink: 0,
verticalAlign: 'middle',
lineHeight: 0,
my: 0,
boxSizing: 'border-box',
...sx,
}}
>
<Box
component="span"
sx={{
display: 'block',
position: 'relative',
width: innerW,
height: innerH,
borderRadius: size >= 24 ? '4px' : '3px',
overflow: 'hidden',
flexShrink: 0,
lineHeight: 0,
boxSizing: 'border-box',
bgcolor: TINT_ROW_HOVER,
boxShadow: SHADOW_THUMB_RING,
}}
>
{thumbHash ? (
<ThumbHashImage
thumbHash={thumbHash}
width={innerW}
height={innerH}
sx={{ width: innerW, height: innerH, flexShrink: 0 }}
/>
) : null}
{fullHash ? (
<Box
component="img"
src={`/api/smallthumb/${encodeURIComponent(fullHash)}`}
alt=""
draggable={false}
sx={{
position: 'absolute',
inset: 0,
width: '100%',
height: '100%',
display: 'block',
}}
/>
) : null}
</Box>
</Box>
);
}
}