UNPKG

kitten-components

Version:
203 lines (176 loc) 4.76 kB
import React, { Component } from 'react' import PropTypes from 'prop-types' import COLORS from 'kitten/constants/colors-config' import Radium, { StyleRoot } from 'radium' import { Text } from 'kitten/components/typography/text' import { ResponsiveIframeContainer } from 'kitten/components/layout/responsive-iframe-container' import { parseHtml } from 'kitten/helpers/utils/parser' import { ScreenConfig } from 'kitten/constants/screen-config' import { NUM_COLUMNS, GUTTER, CONTAINER_PADDING, CONTAINER_PADDING_MOBILE, } from 'kitten/constants/grid-config' const PlayerButton = props => ( <StyleRoot> <div style={styles.playerButton}> <Text size="default" weight="regular" aria-label={props.playButtonLabel}></Text> </div> </StyleRoot> ) PlayerButton.propTypes = { playButtonLabel: PropTypes.string.isRequired, } class EmbedPlayerBase extends Component { constructor(props) { super(props) this.state = { showPlayer: false } } handleClick = () => { this.setState({ showPlayer: true }) this.previewVideo.blur() } handleKeyPress = event => { event.preventDefault() const enterKey = event.key === 'Enter' const spaceKey = event.key === ' ' if (enterKey || spaceKey) this.handleClick() } handleFocus = event => { event.preventDefault() this.previewVideo.focus() this.handleKeyPress(event) } a11yOnClickProps = () => { if (!this.props.iframeHtml) return return { onClick: this.handleClick, onKeyPress: this.handleKeyPress, onFocus: this.handleFocus, role: 'button', tabIndex: 0, } } render() { const { ratio, previewProps, iframeHtml, playButtonLabel, style: mainStyle = void 0, t, } = this.props const validRatio = parseInt(ratio, 10) const { thumbnail, badgeComponent, style } = previewProps const isVideoPlaying = iframeHtml && this.state.showPlayer const playerPreviewStyle = [ styles.player.base, iframeHtml ? { cursor: 'pointer' } : null, isVideoPlaying ? styles.player.hide : styles.player.show, ] return ( <StyleRoot> <div style={{ ...mainStyle, ...styles.container }} ref={node => { this.previewVideo = node }} {...this.a11yOnClickProps()} > <div style={playerPreviewStyle}> {iframeHtml && <PlayerButton playButtonLabel={playButtonLabel} />} <img style={styles.thumbnail} src={thumbnail.src} alt={thumbnail.alt} /> {badgeComponent} </div> {iframeHtml && ( <div style={styles.embedPlayer}> <ResponsiveIframeContainer ratio={validRatio}> {parseHtml(iframeHtml)} </ResponsiveIframeContainer> </div> )} </div> </StyleRoot> ) } } EmbedPlayerBase.propTypes = { previewProps: PropTypes.shape({ thumbnail: PropTypes.shape({ src: PropTypes.string.isRequired, alt: PropTypes.string.isRequired, style: PropTypes.string, }).isRequired, }).isRequired, badgeComponent: PropTypes.node, playButtonLabel: PropTypes.string.isRequired, ratio: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired, iframeHtml: PropTypes.string, } EmbedPlayerBase.defaultProps = { previewProps: { thumbnail: { style: {}, }, }, badgeComponent: null, iframeHtml: null, } const playerButtonSize = 90 const playerButtonXSSize = 50 const styles = { container: { position: 'relative', display: 'block', width: '100%', }, thumbnail: { display: 'block', width: '100%', }, embedPlayer: { position: 'absolute', top: 0, width: '100%', height: '100%', }, playerButton: { width: `${playerButtonSize}px`, height: `${playerButtonSize}px`, background: COLORS.background1, position: 'absolute', top: `calc(50% - ${playerButtonSize / 2}px)`, left: `calc(50% - ${playerButtonSize / 2}px)`, display: 'flex', alignItems: 'center', justifyContent: 'center', [`@media (max-width: ${ScreenConfig.XS.max}px)`]: { width: `${playerButtonXSSize}px`, height: `${playerButtonXSSize}px`, top: `calc(50% - ${playerButtonXSSize / 2}px)`, left: `calc(50% - ${playerButtonXSSize / 2}px)`, }, }, player: { base: { position: 'relative', transition: 'opacity ease 600ms, z-index ease 600ms', zIndex: 1, }, show: { opacity: 1, }, hide: { opacity: 0, zIndex: 0, }, }, } export const EmbedPlayer = Radium(EmbedPlayerBase)