wix-style-react
Version:
wix-style-react
144 lines • 8.36 kB
JavaScript
import React from 'react';
import PropTypes from 'prop-types';
import { st, classes } from './Thumbnail.st.css';
import { CheckboxChecked } from '@wix/wix-ui-icons-common/system';
import Text from '../Text';
import { withFocusable } from '../common/Focusable';
import { dataHooks } from './constants';
import Box from '../Box';
import { WixStyleReactContext } from '../WixStyleReactProvider/context';
const isString = a => typeof a === 'string';
/**
* # Thumbnail
* Component for showing thumbnails
*
* It takes full space of parent component, works well together with `<Proportion/>`
* */
class Thumbnail extends React.PureComponent {
constructor() {
super(...arguments);
this._renderBackgroundLayout = () => {
const { disabled } = this.props;
return isString(this.props.backgroundImage) ? (React.createElement("div", { className: st(classes.backgroundImage, { disabled }), "data-hook": dataHooks.thumbnailBackgroundImage, style: { backgroundImage: `url(${this.props.backgroundImage})` } })) : (this.props.backgroundImage);
};
this._renderBottomTitle = () => {
const { size, title, selected, disabled } = this.props;
return (React.createElement(Box, { align: "center" },
React.createElement(Text, { className: st(classes.bottomTitle, { selected, disabled }), dataHook: dataHooks.thumbnailBottomTitle, size: size, tagName: "div", weight: "thin", ellipsis: true, children: title })));
};
this._renderThumbnailImage = () => {
const { textPosition, image } = this.props;
return (React.createElement("div", { className: st(classes.imageContainer, { textPosition }), "data-hook": dataHooks.thumbnailImage }, isString(image) ? (React.createElement("img", { src: image, className: st(classes.image, { textPosition }) })) : (image)));
};
this._renderTitleAndDescription = () => {
const { size, title, disabled, ellipsis, maxLines, description, textPosition, } = this.props;
return (React.createElement("div", { className: st(classes.thumbnailTextContent, { textPosition, size }) },
title && (React.createElement(Text, { className: st(classes.title, { size, textPosition }), dataHook: dataHooks.thumbnailTitle, size: size, weight: size === 'tiny' ? 'bold' : 'normal', children: title, skin: disabled ? 'disabled' : undefined, ellipsis: ellipsis, maxLines: maxLines })),
description && (React.createElement(Text, { className: classes.description, dataHook: dataHooks.thumbnailDescription, size: size, weight: "thin", secondary: true, children: description, skin: disabled ? 'disabled' : undefined, ellipsis: ellipsis, maxLines: maxLines }))));
};
this._renderSelectedIcon = () => (React.createElement("div", { className: classes.selectedIcon, "data-hook": dataHooks.thumbnailSelectedIcon },
React.createElement(CheckboxChecked, { height: "7.8", width: "10" })));
this._renderThumbnail = () => {
const { selected, disabled, size, width, height, textPosition, children, backgroundImage, image, contentAlignment, newColorsBranding, noPadding, } = this.props;
const hasChildren = !!this.props.children;
const hasBackground = !!backgroundImage;
const getThumbnailContent = () => {
/**
* Ignores the rest of the properties and just renders children
*/
if (hasChildren) {
return (React.createElement("div", { className: st(classes.customChild, { disabled }) }, children));
}
/**
* @deprecated flow
*/
if (hasBackground) {
return this._renderBackgroundLayout();
}
return (React.createElement("div", { className: st(classes.contentContainer, { textPosition }) },
image && this._renderThumbnailImage(),
textPosition === 'inside' && this._renderTitleAndDescription()));
};
return (React.createElement("div", { style: { height }, className: st(classes.thumbnail, {
selected,
disabled,
size,
hasBackground,
hasChildren,
textPosition,
contentAlignment,
newColorsBranding,
noPadding,
}), "data-selected": selected, "data-disabled": disabled, tabIndex: disabled ? null : 0, "data-hook": dataHooks.thumbnailWrapper },
!this.props.hideSelectedIcon && selected && this._renderSelectedIcon(),
getThumbnailContent()));
};
this._onKeyDown = event => [13 /* enter */, 32 /* space */].some(key => event.keyCode === key) &&
this.props.onClick(event);
}
render() {
const { children, backgroundImage, title, width, disabled, className, onClick, dataHook, textPosition, } = this.props;
const hasChildren = !!children;
const hasBackground = !!backgroundImage;
const showBottomTitle = (hasChildren || hasBackground) && title;
return (React.createElement(WixStyleReactContext.Consumer, null, ({ newColorsBranding }) => (React.createElement("div", { style: { width }, className: st(classes.root, { disabled }, className), onClick: disabled ? null : onClick, onKeyDown: disabled ? null : this._onKeyDown, "data-hook": dataHook },
this._renderThumbnail(),
textPosition === 'outside' && this._renderTitleAndDescription(),
showBottomTitle ? this._renderBottomTitle() : null))));
}
}
Thumbnail.displayName = 'Thumbnail';
Thumbnail.propTypes = {
/** Applies a data-hook HTML attribute that can be used in the tests. */
dataHook: PropTypes.string,
/** Specifies a CSS class name to be appended to the component’s root element. */
className: PropTypes.string,
/** Renders specified children items inside of the thumbnail. Accepts any kind of content. When passed, title will be rendered below a thumbnail. */
children: PropTypes.node,
/** Sets the title of a thumbnail. */
title: PropTypes.node,
/** Sets thumbnail description. */
description: PropTypes.node,
/** Specifies an image to be displayed inside of a thumbnail.
* If given as string, it will be used within `<img/>`.
* Otherwise can be given as React.Node
*/
image: PropTypes.node,
/** Controls the size of a thumbnail. */
size: PropTypes.oneOf(['tiny', 'small', 'medium']),
/** Specifies whether a thumbnail is selected. */
selected: PropTypes.bool,
/** Specifies whether thumbnail interactions are disabled. */
disabled: PropTypes.bool,
/** Hides a checkmark icon that indicates selected thumbnail. Selected option will be highlighted with border only. */
hideSelectedIcon: PropTypes.bool,
/** Render image as a background of a thumbnail. As a result, title is rendered below the image thumbnail. */
backgroundImage: PropTypes.node,
/** Defines a callback function which is called every time a thumbnail is clicked. */
onClick: PropTypes.func,
/** Controls the width of a thumbnail. */
width: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
/** Controls the height of a thumbnail. */
height: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
/** Controls vertical alignment of content. */
contentAlignment: PropTypes.oneOf(['top', 'center']),
/** Enables ellipsis text truncation. */
ellipsis: PropTypes.bool,
/** Controls maximum lines that is allowed before ellipsis text truncation is applied */
maxLines: PropTypes.number,
/** Controls text position whether it is outside or inside of a thumbnail */
textPosition: PropTypes.oneOf(['inside', 'outside']),
/** Turns off padding for thumbnail with textPosition='inside' */
noPadding: PropTypes.bool,
};
Thumbnail.defaultProps = {
size: 'medium',
selected: false,
disabled: false,
contentAlignment: 'center',
textPosition: 'inside',
ellipsis: false,
noPadding: false,
};
export default withFocusable(Thumbnail);
//# sourceMappingURL=Thumbnail.js.map