UNPKG

kitten-components

Version:
412 lines (364 loc) 13.1 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.ImageCropper = undefined; 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 _reactCropper = require('react-cropper'); var _reactCropper2 = _interopRequireDefault(_reactCropper); var _marger = require('kitten/components/layout/marger'); var _grid = require('kitten/components/grid/grid'); var _text = require('kitten/components/typography/text'); var _label = require('kitten/components/form/label'); var _paragraph = require('kitten/components/typography/paragraph'); var _simpleUploader = require('kitten/components/uploaders/simple-uploader'); var _slider = require('kitten/components/form/slider'); var _elementHelper = require('kitten/helpers/dom/element-helper'); 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; } var ImageCropper = exports.ImageCropper = function (_React$Component) { _inherits(ImageCropper, _React$Component); function ImageCropper(props) { _classCallCheck(this, ImageCropper); var _this = _possibleConstructorReturn(this, (ImageCropper.__proto__ || Object.getPrototypeOf(ImageCropper)).call(this, props)); _this.state = _extends({}, _this.initialState(), { hasErrorOnUploader: false, cropperWidth: null, cropperHeight: null, imageSrc: _this.props.imageSrc, fileName: _this.props.fileName }); _this.handleUploaderSuccess = _this.handleUploaderSuccess.bind(_this); _this.handleUploaderError = _this.handleUploaderError.bind(_this); _this.handleUploaderReset = _this.handleUploaderReset.bind(_this); _this.handleSliderChange = _this.handleSliderChange.bind(_this); _this.handleSliderAction = _this.handleSliderAction.bind(_this); _this.handleReady = _this.handleReady.bind(_this); _this.handleCrop = _this.handleCrop.bind(_this); _this.renderError = _this.renderError.bind(_this); _this.setCropperHeight = _this.setCropperHeight.bind(_this); return _this; } _createClass(ImageCropper, [{ key: 'initialState', value: function initialState() { return { imageSrc: null, imageCropSrc: null, fileName: null, touched: false, sliderValue: 0, sliderMin: this.props.sliderMin, sliderMax: this.props.sliderMax }; } }, { key: 'componentDidMount', value: function componentDidMount() { this.setCropperHeight(); window.addEventListener('resize', this.setCropperHeight); } }, { key: 'componentWillUnmount', value: function componentWillUnmount() { window.removeEventListener('resize', this.setCropperHeight); } }, { key: 'handleUploaderSuccess', value: function handleUploaderSuccess(data) { this.setState({ imageSrc: data.preview, imageCropSrc: null, fileName: data.name, sliderValue: 0 }, this.setCropperHeight); } }, { key: 'handleUploaderError', value: function handleUploaderError(hasError) { var resetState = hasError ? this.initialState() : {}; this.setState(_extends({ hasErrorOnUploader: hasError }, resetState)); } }, { key: 'handleUploaderReset', value: function handleUploaderReset() { this.setState(this.initialState()); this.props.onChange({ value: null, name: null }); } }, { key: 'handleSliderChange', value: function handleSliderChange(value) { this.setState({ sliderValue: value }); this.refs.cropper.zoomTo(value / 100); } }, { key: 'handleSliderAction', value: function handleSliderAction() { this.setState({ touched: true }); } // Calculate the right range for the zoom slider. }, { key: 'handleReady', value: function handleReady() { var imageData = this.refs.cropper.getImageData(); var naturalWidth = imageData.naturalWidth; var width = imageData.width; var ratio = width / naturalWidth * 100; var min = this.props.sliderMin + ratio; var max = this.props.sliderMax + ratio; this.setState({ sliderMin: min, sliderMax: max, sliderValue: min }); } }, { key: 'handleCrop', value: function handleCrop() { if (!this.state.imageSrc) return; var croppedCanvas = this.refs.cropper.getCroppedCanvas(); if (croppedCanvas) { var imageCropSrc = croppedCanvas.toDataURL(); this.setState({ imageCropSrc: imageCropSrc }); this.props.onChange({ value: imageCropSrc, base: this.state.imageSrc, name: this.state.fileName, cropperData: this.refs.cropper.getData() }); } } }, { key: 'setCropperHeight', value: function setCropperHeight() { if (this.cropperContainer) { var width = _elementHelper.domElementHelper.getComputedWidth(this.cropperContainer); var height = width / this.props.aspectRatio; this.setState({ cropperWidth: width, cropperHeight: height }); } } }, { key: 'renderCropper', value: function renderCropper() { var _this2 = this; var styles = { width: this.state.cropperWidth, height: this.state.cropperHeight }; var dragMode = this.props.disabled || !this.props.isCropEnabled ? 'none' : 'move'; return _react2.default.createElement( _marger.Marger, { top: '2', key: 'cropper' }, _react2.default.createElement( 'div', { ref: function ref(node) { _this2.cropperContainer = node; } }, this.state.cropperWidth && this.state.cropperHeight && _react2.default.createElement(_reactCropper2.default // This helps unmount and remount a new cropper to keep // the component responsive. , { key: 'cropper-' + this.state.cropperHeight, ref: 'cropper', className: 'k-Cropper', src: this.state.imageSrc, style: styles, aspectRatio: this.props.aspectRatio, viewMode: 3, guides: false, modal: false, autoCropArea: 1, cropBoxMovable: false, cropBoxResizable: false, toggleDragModeOnDblclick: false, zoomOnTouch: false, zoomOnWheel: false, dragMode: dragMode, crop: this.handleCrop, ready: this.handleReady }) ) ); } }, { key: 'renderCropperInfo', value: function renderCropperInfo() { return _react2.default.createElement( _marger.Marger, { top: '2', bottom: '1.5' }, _react2.default.createElement( _paragraph.Paragraph, { modifier: 'quaternary', margin: false }, this.props.cropperInfo ) ); } }, { key: 'renderSlider', value: function renderSlider() { return _react2.default.createElement( _marger.Marger, { top: '1' }, _react2.default.createElement(_slider.Slider, { name: 'zoom', min: this.state.sliderMin, max: this.state.sliderMax, value: this.state.sliderValue, onChange: this.handleSliderChange, onAction: this.handleSliderAction }) ); } }, { key: 'renderSliderTitle', value: function renderSliderTitle() { return _react2.default.createElement( _marger.Marger, { top: '1.5', bottom: '1' }, _react2.default.createElement( _label.Label, { size: 'tiny' }, this.props.sliderTitle ) ); } }, { key: 'renderSliderAndCropperInfo', value: function renderSliderAndCropperInfo() { if (this.props.disabled) return; return _react2.default.createElement( _grid.GridCol, { col: '12', 'col-m': '6' }, this.renderCropperInfo(), this.renderSliderTitle(), this.renderSlider() ); } }, { key: 'renderCroppingImage', value: function renderCroppingImage() { if (!this.state.imageSrc) return; return _react2.default.createElement( _grid.Grid, null, _react2.default.createElement( _grid.GridCol, { col: '12', 'col-m': '6' }, this.renderCropper() ), this.props.isCropEnabled && this.renderSliderAndCropperInfo() ); } }, { key: 'renderError', value: function renderError(error) { if (!this.state.hasErrorOnUploader) return; return _react2.default.createElement( _marger.Marger, { top: '1', bottom: '1' }, _react2.default.createElement( _text.Text, { color: 'error', size: 'tiny', weight: 'regular' }, this.props.uploaderErrorLabel ) ); } }, { key: 'renderUploader', value: function renderUploader() { return _react2.default.createElement(_simpleUploader.SimpleUploader, { name: this.props.name, maxSize: this.props.maxSize, acceptedFiles: this.props.acceptedFiles, onSuccess: this.handleUploaderSuccess, onError: this.handleUploaderError, onReset: this.handleUploaderReset, buttonLabel: this.props.buttonLabel, fileName: this.props.fileName, disabled: this.props.disabled, deletable: this.props.deletable, base64: this.props.base64 }); } }, { key: 'render', value: function render() { return _react2.default.createElement( 'section', null, _react2.default.createElement( _grid.Grid, null, _react2.default.createElement( _grid.GridCol, { col: '12' }, _react2.default.createElement( _marger.Marger, { bottom: '1.5' }, _react2.default.createElement( _label.Label, { size: 'tiny' }, this.props.label ) ), _react2.default.createElement( _marger.Marger, { top: '1.5', bottom: '1' }, this.renderUploader() ), this.renderError(), _react2.default.createElement( _marger.Marger, { top: '1' }, _react2.default.createElement( _paragraph.Paragraph, { modifier: 'quaternary', margin: false }, this.props.description ) ) ) ), this.renderCroppingImage() ); } }]); return ImageCropper; }(_react2.default.Component); ImageCropper.defaultProps = { name: 'picture', imageSrc: null, fileName: null, uploaderErrorLabel: 'You have an error on upload.', sliderMin: 0, sliderMax: 500, aspectRatio: 16 / 9, maxSize: 5 * 1024 * 1024, // 5 Mo. acceptedFiles: '.jpg,.jpeg,.gif,.png', label: 'Lorem ipsum…', cropperInfo: 'Move the image…', sliderTitle: 'Zoom…', buttonLabel: 'Choose a file…', description: 'Lorem ipsum…', disabled: false, isCropEnabled: true, base64: true, onChange: function onChange(_fileData) {} };