UNPKG

wix-style-react

Version:
201 lines (175 loc) • 5.58 kB
import React from 'react'; import PropTypes from 'prop-types'; import Card from '../Card'; import Button from '../Button'; import TextButton from '../TextButton'; import Text from '../Text'; import Heading from '../Heading'; import Proportion from '../Proportion'; import Tooltip from '../Tooltip'; import MediaOverlay from '../MediaOverlay'; import { DataHook } from './constants'; import { st, classes } from './CardGalleryItem.st.css'; class CardGalleryItem extends React.PureComponent { static displayName = 'CardGalleryItem'; static propTypes = { /** Accepts a <Badge/> or any other static indicator. Passed element will be displayed at the top left corner of a card. */ badge: PropTypes.node, /** Set card title. */ title: PropTypes.node, /** Set card subtitle. */ subtitle: PropTypes.node, /** Specifies background image URL. */ backgroundImageUrl: PropTypes.string, /** Accepts any component to be rendered as a background image. */ backgroundImageNode: PropTypes.node, /** Defines properties for the primary action button. */ primaryActionProps: PropTypes.shape({ /** Label of primary action button */ label: PropTypes.node, /** On click handler of primary action button and of the whole card */ onClick: PropTypes.func, /** Disable the primary action button */ disabled: PropTypes.bool, /** Message to be displayed when primary action button is disabled */ disabledMessage: PropTypes.string, }).isRequired, /** Defines properties for the secondary action button. */ secondaryActionProps: PropTypes.shape({ /** Label of secondary action text button */ label: PropTypes.node, /** On click handler of secondary action text button */ onClick: PropTypes.func, }).isRequired, /** Defines a popover menu to be displayed on hover at the top right corner or a card. */ settingsMenu: PropTypes.node, /** Applies a data-hook HTML attribute that can be used in the tests. */ dataHook: PropTypes.string, }; static defaultProps = { primaryActionProps: { onClick: () => {}, }, secondaryActionProps: { onClick: () => {}, }, }; state = { isHovered: false, }; _onMouseEnter = () => { this.setState({ isHovered: true }); }; _onMouseLeave = () => { this.setState({ isHovered: false }); }; _hasFooter() { const { title, subtitle } = this.props; return !!(title || subtitle); } _renderBadge() { return ( <div className={classes.badgeWrapper} data-hook={DataHook.Badge}> {this.props.badge} </div> ); } _renderFooter() { const { title, subtitle } = this.props; return ( <> <Card.Divider /> <div className={classes.footer}> <Heading appearance="H3" ellipsis dataHook={DataHook.Title}> {title} </Heading> <Text size="small" secondary ellipsis dataHook={DataHook.Subtitle}> {subtitle} </Text> </div> </> ); } _renderActions() { const { primaryActionProps: { label, disabled, disabledMessage }, secondaryActionProps, } = this.props; const primaryAction = ( <Button dataHook={DataHook.PrimaryAction} disabled={disabled}> {label} </Button> ); return ( <div className={classes.primaryAction} data-hook={DataHook.HoverContent}> {disabled && disabledMessage ? ( <Tooltip disabled={!disabled} content={disabledMessage}> {primaryAction} </Tooltip> ) : ( primaryAction )} <div className={classes.secondaryAction}> <TextButton skin="light" onClick={event => { secondaryActionProps.onClick(event); event.stopPropagation(); }} dataHook={DataHook.SecondaryAction} > {secondaryActionProps.label} </TextButton> </div> </div> ); } _renderSettingsMenu() { return ( <div data-hook={DataHook.SettingsMenu}>{this.props.settingsMenu}</div> ); } render() { const { primaryActionProps, dataHook, badge, backgroundImageUrl, backgroundImageNode, settingsMenu, } = this.props; return ( <Proportion dataHook={dataHook}> <div className={st(classes.root, { withFooter: !!this._hasFooter() })} onMouseEnter={this._onMouseEnter} onMouseLeave={this._onMouseLeave} onClick={primaryActionProps.onClick} data-hook={DataHook.Container} > <Card stretchVertically> <MediaOverlay media={backgroundImageUrl || backgroundImageNode || ''} className={classes.overlay} hoverSkin="dark" hovered={this.state.isHovered} dataHook={DataHook.HoverComponent} > <MediaOverlay.Content visible="hover"> {this._renderActions()} </MediaOverlay.Content> {settingsMenu && ( <MediaOverlay.Content visible="hover" placement="top-end"> {this._renderSettingsMenu()} </MediaOverlay.Content> )} </MediaOverlay> {badge && this._renderBadge()} {this._hasFooter() && this._renderFooter()} </Card> </div> </Proportion> ); } } export default CardGalleryItem;