diff --git a/src/components/CanvasLayers.js b/src/components/CanvasLayers.js index eb3e9b279..212322c0f 100644 --- a/src/components/CanvasLayers.js +++ b/src/components/CanvasLayers.js @@ -148,7 +148,7 @@ export class CanvasLayers extends Component { maxHeight={height} maxWidth={width} resource={resource} - imageStyle + border /> ({ + ...theme.typography.caption, +})); + +const Image = styled('img', { name: 'IIIFThumbnail', slot: 'image' })(() => ({ + height: 'auto', + width: 'auto', +})); /** * A lazy-loaded image that uses IntersectionObserver to determine when to * try to load the image (or even calculate that the image url/height/width are) */ const LazyLoadedImage = ({ - placeholder, style = {}, thumbnail, resource, maxHeight, maxWidth, thumbnailsConfig, ...props + border, placeholder, style = {}, thumbnail, resource, maxHeight, maxWidth, thumbnailsConfig, ...props }) => { const { ref, inView } = useInView(); const [loaded, setLoaded] = useState(false); @@ -44,9 +48,14 @@ const LazyLoadedImage = ({ }, [resource, thumbnail, maxWidth, maxHeight, thumbnailsConfig]); const imageStyles = useMemo(() => { - const styleProps = { height: 'auto', width: 'auto' }; + const styleProps = { + height: undefined, + maxHeight: undefined, + maxWidth: undefined, + width: undefined, + }; - if (!image) return { ...style, height: maxHeight || 'auto', width: maxWidth || 'auto' }; + if (!image) return { ...style, height: maxHeight, width: maxWidth }; const { height: thumbHeight, width: thumbWidth } = image; if (thumbHeight && thumbWidth) { @@ -93,7 +102,8 @@ const LazyLoadedImage = ({ const { url: src = placeholder } = (loaded && (thumbnail || image)) || {}; return ( - ({ - -})); - LazyLoadedImage.propTypes = { + border: PropTypes.bool, maxHeight: PropTypes.number.isRequired, maxWidth: PropTypes.number.isRequired, placeholder: PropTypes.string.isRequired, @@ -123,6 +130,7 @@ LazyLoadedImage.propTypes = { }; LazyLoadedImage.defaultProps = { + border: false, style: {}, thumbnail: null, thumbnailsConfig: {}, @@ -152,30 +160,21 @@ export class IIIFThumbnail extends Component { */ render() { const { + border, children, imagePlaceholder, labelled, - imageStyle, maxHeight, maxWidth, resource, style, thumbnail, thumbnailsConfig, - variant, } = this.props; return ( - - + { labelled && ( - - - {this.label()} - - + )} {children} - + ); } } IIIFThumbnail.propTypes = { + border: PropTypes.bool, children: PropTypes.node, imagePlaceholder: PropTypes.string, - imageStyle: PropTypes.bool, label: PropTypes.string, labelled: PropTypes.bool, maxHeight: PropTypes.number, @@ -251,14 +212,14 @@ IIIFThumbnail.propTypes = { width: PropTypes.number, }), thumbnailsConfig: PropTypes.object, // eslint-disable-line react/forbid-prop-types - variant: PropTypes.oneOf(['inside', 'outside']), + variant: PropTypes.oneOf(['inside', 'outside']), // eslint-disable-line react/no-unused-prop-types }; IIIFThumbnail.defaultProps = { + border: false, children: null, // Transparent "gray" imagePlaceholder: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mMMDQmtBwADgwF/Op8FmAAAAABJRU5ErkJggg==', - imageStyle: false, label: undefined, labelled: false, maxHeight: null, diff --git a/src/config/settings.js b/src/config/settings.js index fbdb72d89..240f2562e 100644 --- a/src/config/settings.js +++ b/src/config/settings.js @@ -184,6 +184,48 @@ export default { }, }, }, + IIIFThumbnail: { + styleOverrides: { + root: ({ ownerState }) => ({ + ...(ownerState?.variant === 'inside' && { + display: 'inline-block', + height: 'inherit', + position: 'relative', + }), + }), + label: ({ ownerState }) => ({ + overflow: 'hidden', + textOverflow: 'ellipsis', + lineHeight: '1.5em', + wordBreak: 'break-word', + ...(ownerState?.variant === 'inside' && { + color: '#ffffff', + WebkitLineClamp: 1, + whiteSpace: 'nowrap', + }), + ...(ownerState?.variant === 'outside' && { + display: '-webkit-box', + maxHeight: '3em', + MozBoxOrient: 'vertical', + WebkitLineClamp: 2, + }), + ...(ownerState?.variant === 'inside' && { + background: 'linear-gradient(to top, rgba(0,0,0,0.7) 0%, rgba(0,0,0,0.3) 70%, rgba(0,0,0,0) 100%)', + bottom: '5px', + boxSizing: 'border-box', + left: '0px', + padding: '4px', + position: 'absolute', + width: '100%', + }), + }), + image: ({ ownerState }) => ({ + ...(ownerState?.border && { + border: '1px solid rgba(0, 0, 0, 0.125)', + }), + }) + } + }, MuiAccordion: { variants: [ {