UNPKG

react-images

Version:

A mobile-friendly, highly customizable, carousel component for displaying media in ReactJS

447 lines (346 loc) 14.2 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _react = require('react'); var _react2 = _interopRequireDefault(_react); var _reactDom = require('react-dom'); var _glam = require('glam'); var _glam2 = _interopRequireDefault(_glam); var _rafSchd = require('raf-schd'); var _rafSchd2 = _interopRequireDefault(_rafSchd); var _reactViewPager = require('react-view-pager'); var _defaultComponents = require('./defaultComponents'); var _styles = require('../styles'); require('./Modal/Modal'); var _utils = require('../utils'); var _formatters = require('../formatters'); var _formatters2 = _interopRequireDefault(_formatters); require('../types'); var _componentBaseClassNames = require('./componentBaseClassNames'); var _componentBaseClassNames2 = _interopRequireDefault(_componentBaseClassNames); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } // @jsx glam var viewPagerStyles = { flex: '1 1 auto', position: 'relative' }; var frameStyles = { outline: 0 }; var defaultProps = { currentIndex: 0, formatters: _formatters2.default, hideControlsWhenIdle: 3000, showNavigationOnTouchDevice: false, styles: {}, trackProps: { instant: !(0, _utils.isTouch)(), swipe: 'touch' } }; var trackBaseClassName = _componentBaseClassNames2.default.Track; var Carousel = function (_Component) { _inherits(Carousel, _Component); function Carousel(props) { _classCallCheck(this, Carousel); var _this = _possibleConstructorReturn(this, (Carousel.__proto__ || Object.getPrototypeOf(Carousel)).call(this, props)); _initialiseProps.call(_this); _this.cacheComponents(props.components); _this.state = { currentIndex: props.currentIndex, interactionIsIdle: (0, _utils.isTouch)() }; return _this; } // TODO _createClass(Carousel, [{ key: 'componentDidMount', value: function componentDidMount() { var _props = this.props, hideControlsWhenIdle = _props.hideControlsWhenIdle, modalProps = _props.modalProps; var isModal = Boolean(modalProps); this.mounted = true; if (hideControlsWhenIdle && this.container) { this.container.addEventListener('mousedown', this.handleMouseActivity); this.container.addEventListener('mousemove', this.handleMouseActivity); this.container.addEventListener('touchmove', this.handleMouseActivity); } if (isModal) { this.focusViewFrame(); } } }, { key: 'componentDidUpdate', value: function componentDidUpdate(prevProps) { if (prevProps.components !== this.props.components) { this.cacheComponents(prevProps.components); } if (this.props.currentIndex !== prevProps.currentIndex) { this.setState({ currentIndex: this.props.currentIndex }); } } }, { key: 'componentWillUnmount', value: function componentWillUnmount() { this.mounted = false; if (this.props.hideControlsWhenIdle && this.container) { this.container.removeEventListener('mousedown', this.handleMouseActivity); this.container.removeEventListener('mousemove', this.handleMouseActivity); this.container.removeEventListener('touchmove', this.handleMouseActivity); this.handleMouseActivity.cancel(); } } // ============================== // Refs // ============================== // ============================== // Utilities // ============================== // combine defaultProps with consumer props to maintain expected behaviour // combine defaultProps with consumer props to maintain expected behaviour // ============================== // Handlers // ============================== // ============================== // Renderers // ============================== }, { key: 'getCommonProps', value: function getCommonProps() { var _props2 = this.props, frameProps = _props2.frameProps, trackProps = _props2.trackProps, modalProps = _props2.modalProps, views = _props2.views, showNavigationOnTouchDevice = _props2.showNavigationOnTouchDevice; var isModal = Boolean(modalProps); var isFullscreen = Boolean(modalProps && modalProps.isFullscreen); var _state = this.state, currentIndex = _state.currentIndex, interactionIsIdle = _state.interactionIsIdle; var currentView = this.getViewData(); return { carouselProps: this.props, currentIndex: currentIndex, currentView: currentView, formatters: this.props.formatters, frameProps: frameProps, getStyles: this.getStyles, showNavigationOnTouchDevice: showNavigationOnTouchDevice, isFullscreen: isFullscreen, isModal: isModal, modalProps: modalProps, interactionIsIdle: interactionIsIdle, trackProps: trackProps, views: views }; } }, { key: 'render', value: function render() { var _components = this.components, Container = _components.Container, View = _components.View; var currentIndex = this.state.currentIndex; var _props3 = this.props, frameProps = _props3.frameProps, views = _props3.views; var commonProps = this.commonProps = this.getCommonProps(); return (0, _glam2.default)( Container, _extends({}, commonProps, { innerProps: { innerRef: this.getContainer } }), this.renderHeader(), (0, _glam2.default)( _reactViewPager.ViewPager, { tag: 'main', style: viewPagerStyles, className: (0, _utils.className)('pager') }, (0, _glam2.default)( _reactViewPager.Frame, _extends({}, frameProps, { ref: this.getFrame, className: (0, _utils.className)('frame'), style: frameStyles, tabIndex: '-1' }), (0, _glam2.default)( _reactViewPager.Track, _extends({}, this.getTrackProps(this.props), { style: { display: 'flex', alignItems: 'center' }, currentView: currentIndex, className: (0, _utils.className)(trackBaseClassName), onViewChange: this.handleViewChange, ref: this.getTrack }), views && views.map(function (data, index) { return (0, _glam2.default)( _reactViewPager.View, { className: (0, _utils.className)('view-wrapper'), key: index }, (0, _glam2.default)(View, _extends({}, commonProps, { data: data, index: index })) ); }) ) ), this.renderNavigation() ), this.renderFooter() ); } }]); return Carousel; }(_react.Component); Carousel.defaultProps = defaultProps; var _initialiseProps = function _initialiseProps() { var _this2 = this; this.mounted = false; this.cacheComponents = function (comps) { _this2.components = (0, _defaultComponents.defaultCarouselComponents)(comps); }; this.getContainer = function (ref) { _this2.container = ref; }; this.getFooter = function (ref) { _this2.footer = ref; }; this.getFrame = function (ref) { _this2.frame = (0, _reactDom.findDOMNode)(ref); }; this.getHeader = function (ref) { _this2.header = ref; }; this.getTrack = function (ref) { _this2.track = ref; }; this.hasPreviousView = function () { var trackProps = _this2.props.trackProps; var currentIndex = _this2.state.currentIndex; return trackProps.infinite || currentIndex !== 0; }; this.hasNextView = function () { var _props4 = _this2.props, trackProps = _props4.trackProps, views = _props4.views; var currentIndex = _this2.state.currentIndex; return trackProps.infinite || currentIndex !== views.length - 1; }; this.getStyles = function (key, props) { var base = _styles.defaultCarouselStyles[key](props); base.boxSizing = 'border-box'; var custom = _this2.props.styles[key]; return custom ? custom(base, props) : base; }; this.getTrackProps = function (props) { return _extends({}, defaultProps.trackProps, props.trackProps); }; this.getFormatters = function () { return _extends({}, defaultProps.formatters, _this2.props.formatters); }; this.getViewData = function () { var views = _this2.props.views; var currentIndex = _this2.state.currentIndex; return views[currentIndex]; }; this.focusViewFrame = function () { if (_this2.frame && document.activeElement !== _this2.frame) { _this2.frame.focus(); } }; this.prev = function (event) { event.stopPropagation(); _this2.track.prev(); _this2.focusViewFrame(); }; this.next = function (event) { event.stopPropagation(); _this2.track.next(); _this2.focusViewFrame(); }; this.handleMouseActivity = (0, _rafSchd2.default)(function () { clearTimeout(_this2.timer); if (_this2.state.interactionIsIdle) { _this2.setState({ interactionIsIdle: false }); } _this2.timer = setTimeout(function () { if (_this2.mounted) { _this2.setState({ interactionIsIdle: true }); } }, _this2.props.hideControlsWhenIdle); }); this.handleViewChange = function (indicies) { var trackProps = _this2.props.trackProps; // simplify by enforcing number var currentIndex = indicies[0]; _this2.setState({ currentIndex: currentIndex }); // call the consumer's onViewChange fn if (trackProps && trackProps.onViewChange) { trackProps.onViewChange(currentIndex); } }; this.renderNavigation = function () { var _getFormatters = _this2.getFormatters(), getNextLabel = _getFormatters.getNextLabel, getPrevLabel = _getFormatters.getPrevLabel, getNextTitle = _getFormatters.getNextTitle, getPrevTitle = _getFormatters.getPrevTitle; var _components2 = _this2.components, Navigation = _components2.Navigation, NavigationPrev = _components2.NavigationPrev, NavigationNext = _components2.NavigationNext; var commonProps = _this2.commonProps; var showPrev = _this2.hasPreviousView(); var showNext = _this2.hasNextView(); var showNav = (showPrev || showNext) && Navigation; return showNav ? (0, _glam2.default)( Navigation, commonProps, showPrev && (0, _glam2.default)(NavigationPrev, _extends({}, commonProps, { align: 'left', innerProps: { 'aria-label': getPrevLabel(commonProps), onClick: _this2.prev, title: getPrevTitle(commonProps) } })), showNext && (0, _glam2.default)(NavigationNext, _extends({}, commonProps, { align: 'right', innerProps: { 'aria-label': getNextLabel(commonProps), onClick: _this2.next, title: getNextTitle(commonProps) } })) ) : null; }; this.renderFooter = function () { var _components3 = _this2.components, Footer = _components3.Footer, FooterCaption = _components3.FooterCaption, FooterCount = _components3.FooterCount; var commonProps = _this2.commonProps; return Footer ? (0, _glam2.default)(Footer, _extends({}, commonProps, { components: { Caption: FooterCaption, Count: FooterCount }, innerProps: { innerRef: _this2.getFooter } })) : null; }; this.renderHeader = function () { var _components4 = _this2.components, Header = _components4.Header, HeaderClose = _components4.HeaderClose, HeaderFullscreen = _components4.HeaderFullscreen; var _getFormatters2 = _this2.getFormatters(), getCloseLabel = _getFormatters2.getCloseLabel, getFullscreenLabel = _getFormatters2.getFullscreenLabel; var commonProps = _this2.commonProps; return Header ? (0, _glam2.default)(Header, _extends({}, commonProps, { getCloseLabel: getCloseLabel, getFullscreenLabel: getFullscreenLabel, components: { CloseButton: HeaderClose, FullscreenButton: HeaderFullscreen }, data: _this2.getViewData(), innerProps: { innerRef: _this2.getHeader } })) : null; }; }; exports.default = Carousel;