UNPKG

react-conventions

Version:

An open source set of React components that implement Ambassador's Design and UX patterns.

79 lines (67 loc) 1.71 kB
import React from 'react' import style from './style.scss' import classNames from 'classnames/bind' class Avatar extends React.Component { constructor(props) { super(props) } state = { loaded: false } static propTypes = { /** * The source of the image to load. */ src: React.PropTypes.string.isRequired, /** * Optional alt text for the image */ alt: React.PropTypes.string, /** * Optional size to constrain the image (only supports square images) */ size: React.PropTypes.string, /** * Optional CSS class to pass to the badge. */ optClass: React.PropTypes.string } componentWillReceiveProps = (nextProps) => { if (nextProps.src !== this.props.src) { this.setState({ loaded: false }) } } shouldComponentUpdate = (nextProps, nextState) => { return ( nextProps.src !== this.props.src || nextProps.size !== this.props.size || nextState.loaded !== this.state.loaded ) } inlineStyle = () => { return { width: this.props.size + 'px', height: this.props.size + 'px' } } handleLoad = () => { this.setState({ loaded: true }) } loadAvatar = () => { return <img src={this.props.src} onLoad={this.handleLoad} alt={this.props.alt} height={this.props.size} /> } render() { const cx = classNames.bind(style) const avatarClasses = cx(style['avatar-wrapper'], (this.state.loaded ? 'loaded' : null), this.props.optClass) return ( <div className={avatarClasses} style={this.props.size ? this.inlineStyle() : null}> {this.loadAvatar()} </div> ) } } export default Avatar