import {assume, Maybe} from '@pinyin/maybe' import {nothing} from '@pinyin/types' import randomcolor from 'randomcolor' import {CSSProperties, default as React} from 'react' import {getTweenState} from '../src/getTweenState' import {tweenExit} from '../src/tweenExit' import {tweenHere} from '../src/tweenHere' import {TweenState} from '../src/TweenState' import {DemoContainer} from './DemoContainer' import {DemoProps} from './DemoProps' export class OpenListItem extends React.Component { constructor(props: DemoProps) { super(props) this.state = {opening: false} } getSnapshotBeforeUpdate(): Snapshot { const item = assume(this.item.current, ref => getTweenState(ref)) const text = assume(this.text.current, ref => getTweenState(ref)) if (this.list.current) { const ref = this.list.current tweenExit(ref, from => ({...from, opacity: 0}), {duration: 300}) this.scrollTop = ref.scrollTop } if (this.item.current) { const ref = this.item.current tweenExit(ref, from => ({...from, opacity: 0}), {duration: 300}) } return {item, text} } render() { const listStyle: CSSProperties = { width: `${this.props.width}px`, height: `${this.props.height}px`, WebkitOverflowScrolling: 'touch', overflowX: 'hidden', overflowY: 'auto', willChange: 'transform', overflowAnchor: 'none', zIndex: 9, } const listItemStyle: CSSProperties = { width: `${this.props.width}px`, } const itemStyle = (color: string): CSSProperties => ({ width: `${this.props.width}px`, height: `${this.props.height / 6}px`, backgroundColor: `${color}`, willChange: 'transform, opacity', textAlign: 'center', }) const openedItemStyle: CSSProperties = { width: this.props.width, height: this.props.height, backgroundColor: 'aliceblue', textAlign: 'center', willChange: 'transform, opacity', zIndex: 10, } return {this.state.opening ? // must provide key or this div will be reused unexpectedly
:
{ this.items.map(({id, color}) => id === 4 ?
:
, ) }
} } componentDidUpdate(prevProps: DemoProps, prevState: State, snapshot: Snapshot) { if (this.text.current) { const ref = this.text.current tweenHere(ref, snapshot.text, {duration: 400, easing: [0.645, 0.045, 0.355, 1]}) } if (this.item.current) { const ref = this.item.current tweenHere(ref, snapshot.item, {duration: 400, easing: [0.645, 0.045, 0.355, 1]}) } if (this.list.current) { const ref = this.list.current ref.scrollTop = this.scrollTop } } private list = React.createRef() private item = React.createRef() private text = React.createRef() private items = new Array(10) .fill(nothing) .map((_, id) => ({id, color: randomcolor({luminosity: 'light'})})) private scrollTop = 0 private onClick = () => { this.setState(state => ({opening: !state.opening})) } } type State = { opening: boolean } type Snapshot = { item: Maybe text: Maybe }