@hypothesis/frontend-shared
Version:
Shared components, styles and utilities for Hypothesis projects
78 lines (76 loc) • 2.9 kB
JavaScript
var _jsxFileName = "/home/runner/work/frontend-shared/frontend-shared/src/components/Thumbnail.js";
import classnames from 'classnames';
import { toChildArray } from 'preact';
import { Spinner } from './Spinner';
/**
* @typedef {import('preact').ComponentChildren} Children
*
* @typedef ThumbnailProps
* @prop {Children|null} [children] - Thumbnail content (typically an img)
* @prop {string} [classes] - Additional CSS classes to apply
* @prop {boolean} [isLoading=false] - Is the thumbnail loading?
* @prop {object} [placeholder='...'] - Optional placeholder to replace default
* @prop {'small'|'medium'|'large'} [size='medium'] - Relative size of spinner
* to surrounding content. Typically the `large` size is appropriate, but for
* small thumbnails, `medium` might feel more appropriate.
*/
/**
* Render a container with thumbnail content.
*
* Thumbnail content (e.g. img) may or may not be present. This component
* provides support for three states:
*
* - Content not yet loaded or is not available: Show a placeholder
* - Content is loading: Show a loading spinner
* - Content is present: Show the content, unless `isLoading` is `true`
*
* Thumbnail dimensions will remain constant even when content is not present,
* avoiding layout shifts. Applied styling will constrain content to dimensions
* of parent container. Apply explicit width and height rules to the parent
* container of this component to dictate sizing.
*
* Examples:
*
* <Thumbnail><img src="http://placekitten.com/200/300" alt="kitty" /></Thumbnail>
* <Thumbnail /> // -> Empty, shows placeholder
* <Thumbnail isLoading /> // -> Empty, shows loading spinner
*
* TODO: There is an implied sub-pattern/-component here to do with rendering
* embedded media within constraints, preventing layout shift, and handling
* loading states. See https://github.com/hypothesis/frontend-shared/issues/134
*
* @param {ThumbnailProps} props
*/
import { jsxDEV as _jsxDEV } from "preact/jsx-dev-runtime";
export function Thumbnail({
children,
classes = '',
isLoading = false,
placeholder = '...',
size = 'medium'
}) {
// If there are no `children`, render a placeholder (unless loading)
const content = toChildArray(children).length ? children : placeholder;
return _jsxDEV("div", {
className: classnames('Hyp-Thumbnail', classes),
children: _jsxDEV("div", {
className: "Hyp-Thumbnail__content",
children: [isLoading && _jsxDEV(Spinner, {
size: size
}, void 0, false, {
fileName: _jsxFileName,
lineNumber: 59,
columnNumber: 23
}, this), !isLoading && content]
}, void 0, true, {
fileName: _jsxFileName,
lineNumber: 58,
columnNumber: 7
}, this)
}, void 0, false, {
fileName: _jsxFileName,
lineNumber: 57,
columnNumber: 5
}, this);
}
//# sourceMappingURL=Thumbnail.js.map