woocommerce/plugins/woocommerce-admin/client/components/animation-slider/index.js

88 lines
2.2 KiB
JavaScript

/** @format */
/**
* External dependencies
*/
import { Component, createRef } from '@wordpress/element';
import classnames from 'classnames';
import PropTypes from 'prop-types';
/**
* Internal dependencies
*/
import { CSSTransition, TransitionGroup } from 'react-transition-group';
import './style.scss';
/**
* This component creates slideable content controlled by an animate prop to direct the contents to slide left or right.
* All other props are passed to `CSSTransition`. More info at http://reactcommunity.org/react-transition-group/css-transition
*/
class AnimationSlider extends Component {
constructor() {
super();
this.state = {
animate: null,
};
this.container = createRef();
this.onExited = this.onExited.bind( this );
}
onExited() {
const { onExited, focusOnChange } = this.props;
if ( onExited ) {
onExited();
}
if ( focusOnChange ) {
const focusable = this.container.current.querySelector(
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
);
if ( focusable ) {
focusable.focus();
}
}
}
render() {
const { children, animationKey, animate } = this.props;
const containerClasses = classnames(
'woocommerce-slide-animation',
animate && `animate-${ animate }`
);
return (
<div className={ containerClasses } ref={ this.container }>
<TransitionGroup>
<CSSTransition
timeout={ 200 }
classNames="slide"
key={ animationKey }
{ ...this.props }
onExited={ this.onExited }
>
{ status => children( { status } ) }
</CSSTransition>
</TransitionGroup>
</div>
);
}
}
AnimationSlider.propTypes = {
/**
* A function returning rendered content with argument status, reflecting `CSSTransition` status.
*/
children: PropTypes.func.isRequired,
/**
* A unique identifier for each slideable page.
*/
animationKey: PropTypes.any.isRequired,
/**
* null, 'left', 'right', to designate which direction to slide on a change.
*/
animate: PropTypes.oneOf( [ null, 'left', 'right' ] ),
/**
* When set to true, the first focusable element will be focused after an animation has finished.
*/
focusOnChange: PropTypes.bool,
};
export default AnimationSlider;