vigetlabs/ars-arsenal

View on GitHub
src/components/gallery.tsx

Summary

Maintainability
A
1 hr
Test Coverage
/**
 * Gallery
 * Displays tiles of photos
 */

import * as React from 'react'
import { CSSTransition, TransitionGroup } from 'react-transition-group'
import Figure from './figure'
import GalleryPanel from './gallery-panel'
import { Record, ID } from '../record'
import { itemAnimationDelay } from './animation'

interface Props {
  items: Record[]
  picked: ID[]
  onPicked: (id: ID) => void
  onKeyDown: (event: React.KeyboardEvent) => void
  onTagClick: (tag: String) => void
}

interface State {
  focus: Record | null
}

export default class Gallery extends React.PureComponent<Props, State> {
  offset: number = 0

  state: State = {
    focus: null
  }

  isPicked(id: ID) {
    const { picked } = this.props

    return picked.indexOf(id) >= 0
  }

  trackMount = (index: number) => {
    this.offset = Math.max(this.offset, itemAnimationDelay(index))
  }

  getItem(record: Record, index: number, list: Record[]) {
    const { onPicked } = this.props

    let isPicked = this.isPicked(record.id)
    let delay = Math.max(0, itemAnimationDelay(index) - this.offset)

    return (
      <CSSTransition
        key={index}
        appear={true}
        exit={false}
        classNames="ars-gallery"
        timeout={delay + 400}
        onEntered={this.trackMount.bind(this, index)}
        unmountOnExit={true}
      >
        <div
          className="ars-gallery-item"
          data-scroll={index == list.length - 1}
          style={{ transitionDelay: delay + 'ms' }}
        >
          <Figure picked={isPicked} record={record} onClick={onPicked} />
          <button
            className="ars-gallery-info"
            type="button"
            onClick={this.setFocus.bind(this, record)}
          >
            i
          </button>
        </div>
      </CSSTransition>
    )
  }

  render() {
    let { items, onKeyDown, onTagClick } = this.props
    let { focus } = this.state

    return (
      <div className="ars-gallery-wrapper" onKeyDown={onKeyDown}>
        <TransitionGroup className="ars-gallery" data-scroll-container="true">
          {items.map(this.getItem, this)}
        </TransitionGroup>
        <GalleryPanel record={focus} onTagClick={onTagClick} onExit={this.clearFocus} />
      </div>
    )
  }

  setFocus = (focus: Record) => {
    this.setState({ focus })
  }

  clearFocus = () => {
    this.setState({ focus: null })
  }
}