mirror of
https://github.com/strapi/strapi.git
synced 2025-12-12 07:27:46 +00:00
Add eslint to strapi-helper-plugin!
This commit is contained in:
parent
bf9451d720
commit
ac3ea588fa
@ -66,10 +66,10 @@ module.exports = require('./webpack.base.babel')({
|
||||
path.join(appPath, 'admin', 'admin', 'src', 'app.js'),
|
||||
],
|
||||
}, plugins.src.reduce((acc, current) => {
|
||||
acc[current] = path.resolve(plugins.folders[current], 'app.js');
|
||||
acc[current] = path.resolve(plugins.folders[current], 'app.js');
|
||||
|
||||
return acc;
|
||||
}, {})
|
||||
return acc;
|
||||
}, {})
|
||||
),
|
||||
|
||||
// Don't use hashes in dev mode for better performance
|
||||
|
||||
@ -7,6 +7,8 @@
|
||||
import React from 'react';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import cn from 'classnames';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import styles from './styles.scss';
|
||||
|
||||
/* eslint-disable react/require-default-props */
|
||||
@ -85,4 +87,11 @@ const renderButton = () => (
|
||||
</div>
|
||||
);
|
||||
|
||||
BlockerComponent.propTypes = {
|
||||
blockerComponentContent: PropTypes.string.isRequired,
|
||||
blockerComponentDescription: PropTypes.string.isRequired,
|
||||
blockerComponentIcon: PropTypes.string.isRequired,
|
||||
blockerComponentTitle: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
export default BlockerComponent;
|
||||
|
||||
@ -7,7 +7,6 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import styles from './styles.scss';
|
||||
|
||||
class ErrorBoundary extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
||||
constructor(props) {
|
||||
|
||||
@ -40,12 +40,12 @@ ExtendComponent.contextTypes = {
|
||||
plugins: PropTypes.object,
|
||||
router: PropTypes.object,
|
||||
updatePlugin: PropTypes.func,
|
||||
}
|
||||
};
|
||||
|
||||
ExtendComponent.propTypes = {
|
||||
area: PropTypes.string.isRequired,
|
||||
container: PropTypes.string.isRequired,
|
||||
children: PropTypes.node,
|
||||
container: PropTypes.string.isRequired,
|
||||
plugin: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
|
||||
@ -10,6 +10,7 @@ import PropTypes from 'prop-types';
|
||||
|
||||
import styles from './styles.scss';
|
||||
|
||||
/* eslint-disable jsx-a11y/anchor-is-valid */
|
||||
class GlobalPagination extends React.Component {
|
||||
getLastPageNumber = () => Math.ceil(this.props.count / this.props.params.limit);
|
||||
|
||||
@ -163,6 +164,7 @@ class GlobalPagination extends React.Component {
|
||||
}
|
||||
|
||||
GlobalPagination.defaultProps = {
|
||||
count: 0,
|
||||
onChangeParams: () => {},
|
||||
params: {
|
||||
page: 1,
|
||||
|
||||
@ -23,11 +23,13 @@ const handleClick = (e, onClick) => {
|
||||
|
||||
Ico.propTypes = {
|
||||
icoType: PropTypes.string,
|
||||
id: PropTypes.string,
|
||||
onClick: PropTypes.func,
|
||||
};
|
||||
|
||||
Ico.defaultProps = {
|
||||
icoType: 'trash',
|
||||
id: '',
|
||||
onClick: () => {},
|
||||
};
|
||||
|
||||
|
||||
@ -30,8 +30,8 @@ class ImgPreview extends React.Component {
|
||||
// We don't need the generateImgURL function here since the compo will
|
||||
// always have an init value here
|
||||
this.setState({
|
||||
imgURL: get(this.props.files, ['0', 'url'], '') || get(this.props.files, 'url', ''),
|
||||
isImg: this.isPictureType(get(this.props.files, ['0', 'name'], '')),
|
||||
imgURL: get(this.props.files, ['0', 'url'], '') || get(this.props.files, 'url', ''),
|
||||
isImg: this.isPictureType(get(this.props.files, ['0', 'name'], '')),
|
||||
});
|
||||
}
|
||||
|
||||
@ -47,7 +47,7 @@ class ImgPreview extends React.Component {
|
||||
// Update the preview or slide pictures or init the component
|
||||
if (nextProps.didDeleteFile !== this.props.didDeleteFile || nextProps.position !== this.props.position || size(nextProps.files) !== size(this.props.files) && !this.state.isInitValue) {
|
||||
const file = nextProps.files[nextProps.position] || nextProps.files || '';
|
||||
this.generateImgURL(file)
|
||||
this.generateImgURL(file);
|
||||
|
||||
if (!this.state.isInitValue) {
|
||||
this.setState({ isInitValue: true });
|
||||
@ -74,7 +74,7 @@ class ImgPreview extends React.Component {
|
||||
imgURL: reader.result,
|
||||
isImg: true,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
reader.readAsDataURL(file);
|
||||
} else if (has(file, 'url')) {
|
||||
@ -89,7 +89,7 @@ class ImgPreview extends React.Component {
|
||||
|
||||
handleClick = (type) => {
|
||||
const { files, position } = this.props;
|
||||
let file;
|
||||
let file; // eslint-disable-line no-unused-vars
|
||||
let nextPosition;
|
||||
|
||||
switch (type) {
|
||||
@ -134,12 +134,17 @@ class ImgPreview extends React.Component {
|
||||
// TODO change logic to depend on the type
|
||||
isPictureType = (fileName) => /\.(jpe?g|png|gif)$/i.test(fileName);
|
||||
|
||||
updateFilePosition = (newPosition) => {
|
||||
// this.setState({ position: newPosition });
|
||||
this.props.updateFilePosition(newPosition);
|
||||
}
|
||||
|
||||
renderContent = () => {
|
||||
const fileType = this.getFileType(this.state.imgURL);
|
||||
|
||||
if (this.state.isImg) {
|
||||
return (
|
||||
<img src={this.state.imgURL} />
|
||||
<img src={this.state.imgURL} alt="" />
|
||||
);
|
||||
}
|
||||
|
||||
@ -150,13 +155,8 @@ class ImgPreview extends React.Component {
|
||||
);
|
||||
}
|
||||
|
||||
updateFilePosition = (newPosition) => {
|
||||
// this.setState({ position: newPosition });
|
||||
this.props.updateFilePosition(newPosition);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { files, multiple, onBrowseClick } = this.props;
|
||||
const { files, onBrowseClick } = this.props;
|
||||
const { imgURL } = this.state;
|
||||
const containerStyle = isEmpty(imgURL) ?
|
||||
{
|
||||
@ -167,44 +167,43 @@ class ImgPreview extends React.Component {
|
||||
} : {};
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
styles.imgPreviewContainer,
|
||||
)}
|
||||
onDragOver={this.handleDragOver}
|
||||
onDragEnter={this.handleDragEnter}
|
||||
style={containerStyle}
|
||||
>
|
||||
<div
|
||||
className={cn(
|
||||
styles.imgPreviewContainer,
|
||||
)}
|
||||
className={cn(this.state.isDraging && styles.overlay)}
|
||||
onDragLeave={this.handleDragLeave}
|
||||
onDragOver={this.handleDragOver}
|
||||
onDragEnter={this.handleDragEnter}
|
||||
style={containerStyle}
|
||||
>
|
||||
<div
|
||||
className={cn(this.state.isDraging && styles.overlay)}
|
||||
onDragLeave={this.handleDragLeave}
|
||||
onDragOver={this.handleDragOver}
|
||||
onDrop={this.handleDrop}
|
||||
/>
|
||||
<ImgPreviewHint
|
||||
displayHint={isEmpty(files)}
|
||||
onClick={onBrowseClick}
|
||||
onDrop={this.handleDrop}
|
||||
showWhiteHint={this.state.isDraging || isEmpty(files)}
|
||||
/>
|
||||
{ !isEmpty(imgURL) && this.renderContent() }
|
||||
<ImgPreviewArrow
|
||||
enable={isArray(files) && size(files) > 1}
|
||||
onClick={this.handleClick}
|
||||
onMouseEnter={(e) => this.setState({ isOverArrow: true })}
|
||||
onMouseLeave={(e) => this.setState({ isOverArrow: false })}
|
||||
show={isArray(files) && size(files) > 1}
|
||||
type="right"
|
||||
/>
|
||||
<ImgPreviewArrow
|
||||
enable={isArray(files) && size(files) > 1}
|
||||
onClick={this.handleClick}
|
||||
onMouseEnter={(e) => this.setState({ isOverArrow: true })}
|
||||
onMouseLeave={(e) => this.setState({ isOverArrow: false })}
|
||||
show={isArray(files) && size(files) > 1}
|
||||
/>
|
||||
</div>
|
||||
|
||||
onDrop={this.handleDrop}
|
||||
/>
|
||||
<ImgPreviewHint
|
||||
displayHint={isEmpty(files)}
|
||||
onClick={onBrowseClick}
|
||||
onDrop={this.handleDrop}
|
||||
showWhiteHint={this.state.isDraging || isEmpty(files)}
|
||||
/>
|
||||
{ !isEmpty(imgURL) && this.renderContent() }
|
||||
<ImgPreviewArrow
|
||||
enable={isArray(files) && size(files) > 1}
|
||||
onClick={this.handleClick}
|
||||
onMouseEnter={() => this.setState({ isOverArrow: true })}
|
||||
onMouseLeave={() => this.setState({ isOverArrow: false })}
|
||||
show={isArray(files) && size(files) > 1}
|
||||
type="right"
|
||||
/>
|
||||
<ImgPreviewArrow
|
||||
enable={isArray(files) && size(files) > 1}
|
||||
onClick={this.handleClick}
|
||||
onMouseEnter={() => this.setState({ isOverArrow: true })}
|
||||
onMouseLeave={() => this.setState({ isOverArrow: false })}
|
||||
show={isArray(files) && size(files) > 1}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -214,9 +213,7 @@ ImgPreview.defaultProps = {
|
||||
files: [],
|
||||
isUploading: false,
|
||||
multiple: false,
|
||||
name: '',
|
||||
onBrowseClick: () => {},
|
||||
onChange: () => {},
|
||||
onDrop: () => {},
|
||||
position: 0,
|
||||
updateFilePosition: () => {},
|
||||
@ -230,9 +227,7 @@ ImgPreview.propTypes = {
|
||||
]),
|
||||
isUploading: PropTypes.bool,
|
||||
multiple: PropTypes.bool,
|
||||
name: PropTypes.string,
|
||||
onBrowseClick: PropTypes.func,
|
||||
onChange: PropTypes.func,
|
||||
onDrop: PropTypes.func,
|
||||
position: PropTypes.number,
|
||||
updateFilePosition: PropTypes.func,
|
||||
|
||||
@ -11,6 +11,7 @@ import cn from 'classnames';
|
||||
|
||||
import styles from './styles.scss';
|
||||
|
||||
/* eslint-disable jsx-a11y/no-autofocus */
|
||||
class InputAddon extends React.Component {
|
||||
state = { isFocused: false };
|
||||
|
||||
@ -47,7 +48,8 @@ class InputAddon extends React.Component {
|
||||
<div className={cn(styles.inputAddon, 'input-group', !isEmpty(className) && className)} style={style}>
|
||||
<FormattedMessage id={addon} defaultMessage={upperFirst(addon)}>
|
||||
{(message) => (
|
||||
<span className={cn(
|
||||
<span
|
||||
className={cn(
|
||||
'input-group-addon',
|
||||
styles.addon,
|
||||
this.state.isFocused && styles.addonFocus,
|
||||
@ -106,13 +108,13 @@ InputAddon.propTypes = {
|
||||
deactivateErrorHighlight: PropTypes.bool,
|
||||
disabled: PropTypes.bool,
|
||||
error: PropTypes.bool,
|
||||
name: PropTypes.string.isRequired,
|
||||
onBlur: PropTypes.oneOfType([
|
||||
PropTypes.func,
|
||||
PropTypes.bool,
|
||||
]),
|
||||
onChange: PropTypes.func.isRequired,
|
||||
onFocus: PropTypes.func,
|
||||
name: PropTypes.string.isRequired,
|
||||
placeholder: PropTypes.string,
|
||||
style: PropTypes.object,
|
||||
tabIndex: PropTypes.string,
|
||||
|
||||
@ -101,7 +101,8 @@ class InputAddonWithErrors extends React.Component { // eslint-disable-line reac
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={cn(
|
||||
<div
|
||||
className={cn(
|
||||
styles.containerAddon,
|
||||
customBootstrapClass,
|
||||
!isEmpty(className) && className,
|
||||
|
||||
@ -12,6 +12,8 @@ import cn from 'classnames';
|
||||
|
||||
import styles from './styles.scss';
|
||||
|
||||
/* eslint-disable jsx-a11y/no-autofocus */
|
||||
/* eslint-disable jsx-a11y/label-has-for */
|
||||
class InputCheckbox extends React.Component {
|
||||
handleChange = () => {
|
||||
const target = {
|
||||
@ -84,7 +86,8 @@ class InputCheckbox extends React.Component {
|
||||
);
|
||||
}
|
||||
return (
|
||||
<div className={cn(
|
||||
<div
|
||||
className={cn(
|
||||
'form-check',
|
||||
styles.inputCheckbox,
|
||||
!isEmpty(className) && className,
|
||||
|
||||
@ -11,7 +11,6 @@ import { isEmpty, isObject, isFunction } from 'lodash';
|
||||
import cn from 'classnames';
|
||||
|
||||
// Design
|
||||
import Label from 'components/Label';
|
||||
import InputDescription from 'components/InputDescription';
|
||||
import InputErrors from 'components/InputErrors';
|
||||
import InputCheckbox from 'components/InputCheckbox';
|
||||
@ -44,7 +43,6 @@ class InputCheckboxWithErrors extends React.Component {
|
||||
autoFocus,
|
||||
className,
|
||||
customBootstrapClass,
|
||||
deactivateErrorHighlight,
|
||||
disabled,
|
||||
errorsClassName,
|
||||
errorsStyle,
|
||||
@ -54,8 +52,6 @@ class InputCheckboxWithErrors extends React.Component {
|
||||
inputDescriptionStyle,
|
||||
inputStyle,
|
||||
label,
|
||||
labelClassName,
|
||||
labelStyle,
|
||||
name,
|
||||
noErrorsDescription,
|
||||
onBlur,
|
||||
@ -90,7 +86,8 @@ class InputCheckboxWithErrors extends React.Component {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={cn(
|
||||
<div
|
||||
className={cn(
|
||||
styles.container,
|
||||
customBootstrapClass,
|
||||
!isEmpty(className) && className,
|
||||
@ -122,7 +119,7 @@ class InputCheckboxWithErrors extends React.Component {
|
||||
errors={this.state.errors}
|
||||
style={errorsStyle}
|
||||
/>
|
||||
{spacer}
|
||||
{spacer}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@ -132,7 +129,6 @@ InputCheckboxWithErrors.defaultProps = {
|
||||
autoFocus: false,
|
||||
className: '',
|
||||
customBootstrapClass: 'col-md-3',
|
||||
deactivateErrorHighlight: false,
|
||||
didCheckErrors: false,
|
||||
disabled: false,
|
||||
onBlur: () => {},
|
||||
@ -146,21 +142,17 @@ InputCheckboxWithErrors.defaultProps = {
|
||||
inputDescriptionStyle: {},
|
||||
inputStyle: {},
|
||||
label: '',
|
||||
labelClassName: '',
|
||||
labelStyle: {},
|
||||
noErrorsDescription: false,
|
||||
placeholder: 'app.utils.placeholder.defaultMessage',
|
||||
style: {},
|
||||
tabIndex: '0',
|
||||
title: '',
|
||||
validations: {},
|
||||
value: false,
|
||||
};
|
||||
InputCheckboxWithErrors.propTypes = {
|
||||
autoFocus: PropTypes.bool,
|
||||
className: PropTypes.string,
|
||||
customBootstrapClass: PropTypes.string,
|
||||
deactivateErrorHighlight: PropTypes.bool,
|
||||
didCheckErrors: PropTypes.bool,
|
||||
disabled: PropTypes.bool,
|
||||
errors: PropTypes.array,
|
||||
@ -186,8 +178,6 @@ InputCheckboxWithErrors.propTypes = {
|
||||
params: PropTypes.object,
|
||||
}),
|
||||
]),
|
||||
labelClassName: PropTypes.string,
|
||||
labelStyle: PropTypes.object,
|
||||
name: PropTypes.string.isRequired,
|
||||
noErrorsDescription: PropTypes.bool,
|
||||
onBlur: PropTypes.oneOfType([
|
||||
@ -207,7 +197,6 @@ InputCheckboxWithErrors.propTypes = {
|
||||
params: PropTypes.object,
|
||||
}),
|
||||
]),
|
||||
validations: PropTypes.object,
|
||||
value: PropTypes.bool,
|
||||
};
|
||||
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
import React from 'react';
|
||||
import moment from 'moment';
|
||||
import PropTypes from 'prop-types';
|
||||
import DateTimeStyle from 'react-datetime/css/react-datetime.css';
|
||||
// import DateTimeStyle from 'react-datetime/css/react-datetime.css';
|
||||
import DateTime from 'react-datetime';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import { isEmpty, isObject } from 'lodash';
|
||||
@ -15,6 +15,7 @@ import cn from 'classnames';
|
||||
|
||||
import styles from './styles.scss';
|
||||
|
||||
/* eslint-disable react/jsx-boolean-value */
|
||||
function InputDate(props) {
|
||||
const value = isObject(props.value) && props.value._isAMomentObject === true ? props.value : moment(props.value);
|
||||
|
||||
@ -76,10 +77,10 @@ InputDate.propTypes = {
|
||||
deactivateErrorHighlight: PropTypes.bool,
|
||||
disabled: PropTypes.bool,
|
||||
error: PropTypes.bool,
|
||||
name: PropTypes.string.isRequired,
|
||||
onBlur: PropTypes.func,
|
||||
onChange: PropTypes.func.isRequired,
|
||||
onFocus: PropTypes.func,
|
||||
name: PropTypes.string.isRequired,
|
||||
placeholder: PropTypes.string,
|
||||
style: PropTypes.object,
|
||||
tabIndex: PropTypes.string,
|
||||
|
||||
@ -100,7 +100,8 @@ class InputDateWithErrors extends React.Component { // eslint-disable-line react
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={cn(
|
||||
<div
|
||||
className={cn(
|
||||
!isEmpty(customBootstrapClass) && customBootstrapClass || 'col-md-4',
|
||||
styles.containerDate,
|
||||
!isEmpty(className) && className,
|
||||
@ -145,77 +146,77 @@ class InputDateWithErrors extends React.Component { // eslint-disable-line react
|
||||
}
|
||||
|
||||
InputDateWithErrors.defaultProps = {
|
||||
autoFocus: false,
|
||||
className: '',
|
||||
customBootstrapClass: 'col-md-4',
|
||||
deactivateErrorHighlight: false,
|
||||
didCheckErrors: false,
|
||||
disabled: false,
|
||||
onBlur: false,
|
||||
onFocus: () => {},
|
||||
errors: [],
|
||||
errorsClassName: '',
|
||||
errorsStyle: {},
|
||||
inputClassName: '',
|
||||
inputDescription: '',
|
||||
inputDescriptionClassName: '',
|
||||
inputDescriptionStyle: {},
|
||||
inputStyle: {},
|
||||
label: '',
|
||||
labelClassName: '',
|
||||
labelStyle: {},
|
||||
noErrorsDescription: false,
|
||||
placeholder: 'app.utils.placeholder.defaultMessage',
|
||||
style: {},
|
||||
tabIndex: '0',
|
||||
validations: {},
|
||||
autoFocus: false,
|
||||
className: '',
|
||||
customBootstrapClass: 'col-md-4',
|
||||
deactivateErrorHighlight: false,
|
||||
didCheckErrors: false,
|
||||
disabled: false,
|
||||
onBlur: false,
|
||||
onFocus: () => {},
|
||||
errors: [],
|
||||
errorsClassName: '',
|
||||
errorsStyle: {},
|
||||
inputClassName: '',
|
||||
inputDescription: '',
|
||||
inputDescriptionClassName: '',
|
||||
inputDescriptionStyle: {},
|
||||
inputStyle: {},
|
||||
label: '',
|
||||
labelClassName: '',
|
||||
labelStyle: {},
|
||||
noErrorsDescription: false,
|
||||
placeholder: 'app.utils.placeholder.defaultMessage',
|
||||
style: {},
|
||||
tabIndex: '0',
|
||||
validations: {},
|
||||
};
|
||||
|
||||
InputDateWithErrors.propTypes = {
|
||||
autoFocus: PropTypes.bool,
|
||||
className: PropTypes.string,
|
||||
customBootstrapClass: PropTypes.string,
|
||||
deactivateErrorHighlight: PropTypes.bool,
|
||||
didCheckErrors: PropTypes.bool,
|
||||
disabled: PropTypes.bool,
|
||||
errors: PropTypes.array,
|
||||
errorsClassName: PropTypes.string,
|
||||
errorsStyle: PropTypes.object,
|
||||
inputClassName: PropTypes.string,
|
||||
inputDescription: PropTypes.oneOfType([
|
||||
PropTypes.string,
|
||||
PropTypes.func,
|
||||
PropTypes.shape({
|
||||
id: PropTypes.string,
|
||||
params: PropTypes.object,
|
||||
}),
|
||||
]),
|
||||
inputDescriptionClassName: PropTypes.string,
|
||||
inputDescriptionStyle: PropTypes.object,
|
||||
inputStyle: PropTypes.object,
|
||||
label: PropTypes.oneOfType([
|
||||
PropTypes.string,
|
||||
PropTypes.func,
|
||||
PropTypes.shape({
|
||||
id: PropTypes.string,
|
||||
params: PropTypes.object,
|
||||
}),
|
||||
]),
|
||||
labelClassName: PropTypes.string,
|
||||
labelStyle: PropTypes.object,
|
||||
name: PropTypes.string.isRequired,
|
||||
noErrorsDescription: PropTypes.bool,
|
||||
onBlur: PropTypes.oneOfType([
|
||||
PropTypes.bool,
|
||||
PropTypes.func,
|
||||
]),
|
||||
onChange: PropTypes.func.isRequired,
|
||||
onFocus: PropTypes.func,
|
||||
placeholder: PropTypes.string,
|
||||
style: PropTypes.object,
|
||||
tabIndex: PropTypes.string,
|
||||
validations: PropTypes.object,
|
||||
value: PropTypes.string.isRequired,
|
||||
autoFocus: PropTypes.bool,
|
||||
className: PropTypes.string,
|
||||
customBootstrapClass: PropTypes.string,
|
||||
deactivateErrorHighlight: PropTypes.bool,
|
||||
didCheckErrors: PropTypes.bool,
|
||||
disabled: PropTypes.bool,
|
||||
errors: PropTypes.array,
|
||||
errorsClassName: PropTypes.string,
|
||||
errorsStyle: PropTypes.object,
|
||||
inputClassName: PropTypes.string,
|
||||
inputDescription: PropTypes.oneOfType([
|
||||
PropTypes.string,
|
||||
PropTypes.func,
|
||||
PropTypes.shape({
|
||||
id: PropTypes.string,
|
||||
params: PropTypes.object,
|
||||
}),
|
||||
]),
|
||||
inputDescriptionClassName: PropTypes.string,
|
||||
inputDescriptionStyle: PropTypes.object,
|
||||
inputStyle: PropTypes.object,
|
||||
label: PropTypes.oneOfType([
|
||||
PropTypes.string,
|
||||
PropTypes.func,
|
||||
PropTypes.shape({
|
||||
id: PropTypes.string,
|
||||
params: PropTypes.object,
|
||||
}),
|
||||
]),
|
||||
labelClassName: PropTypes.string,
|
||||
labelStyle: PropTypes.object,
|
||||
name: PropTypes.string.isRequired,
|
||||
noErrorsDescription: PropTypes.bool,
|
||||
onBlur: PropTypes.oneOfType([
|
||||
PropTypes.bool,
|
||||
PropTypes.func,
|
||||
]),
|
||||
onChange: PropTypes.func.isRequired,
|
||||
onFocus: PropTypes.func,
|
||||
placeholder: PropTypes.string,
|
||||
style: PropTypes.object,
|
||||
tabIndex: PropTypes.string,
|
||||
validations: PropTypes.object,
|
||||
value: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
export default InputDateWithErrors;
|
||||
|
||||
@ -21,7 +21,8 @@ function InputDescription(props) {
|
||||
content = props.message();
|
||||
}
|
||||
return (
|
||||
<div className={cn(
|
||||
<div
|
||||
className={cn(
|
||||
styles.inputDescriptionContainer,
|
||||
!isEmpty(props.className) && props.className
|
||||
)}
|
||||
|
||||
@ -11,6 +11,7 @@ import cn from 'classnames';
|
||||
|
||||
import styles from './styles.scss';
|
||||
|
||||
/* eslint-disable jsx-a11y/no-autofocus */
|
||||
class InputEmail extends React.Component {
|
||||
state = { isFocused: false };
|
||||
|
||||
@ -41,7 +42,8 @@ class InputEmail extends React.Component {
|
||||
|
||||
return (
|
||||
<div className={cn(styles.inputEmail, 'input-group', !isEmpty(className) && className)} style={style}>
|
||||
<span className={cn(
|
||||
<span
|
||||
className={cn(
|
||||
'input-group-addon',
|
||||
styles.addonEmail,
|
||||
this.state.isFocused && styles.addonFocus,
|
||||
@ -94,10 +96,10 @@ InputEmail.propTypes = {
|
||||
deactivateErrorHighlight: PropTypes.bool,
|
||||
disabled: PropTypes.bool,
|
||||
error: PropTypes.bool,
|
||||
name: PropTypes.string.isRequired,
|
||||
onBlur: PropTypes.func,
|
||||
onChange: PropTypes.func.isRequired,
|
||||
onFocus: PropTypes.func,
|
||||
name: PropTypes.string.isRequired,
|
||||
placeholder: PropTypes.string,
|
||||
style: PropTypes.object,
|
||||
tabIndex: PropTypes.string,
|
||||
|
||||
@ -98,7 +98,8 @@ class InputEmailWithErrors extends React.Component { // eslint-disable-line reac
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={cn(
|
||||
<div
|
||||
className={cn(
|
||||
styles.containerEmail,
|
||||
this.props.customBootstrapClass,
|
||||
!isEmpty(this.props.className) && this.props.className,
|
||||
|
||||
@ -16,7 +16,8 @@ function InputErrors(props) {
|
||||
<FormattedMessage {...error} values={{ errorMessage: error.errorMessage }} /> : error;
|
||||
|
||||
return (
|
||||
<div className={cn(
|
||||
<div
|
||||
className={cn(
|
||||
'form-control-feedback',
|
||||
'invalid-feedback',
|
||||
styles.errorContainer,
|
||||
@ -24,10 +25,10 @@ function InputErrors(props) {
|
||||
)}
|
||||
key={key}
|
||||
style={divStyle}
|
||||
>
|
||||
>
|
||||
{displayError}
|
||||
</div>
|
||||
)
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -8,14 +8,15 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import { cloneDeep, isArray, isObject, isEmpty, last } from 'lodash';
|
||||
import cn from 'classnames';
|
||||
import { cloneDeep } from 'lodash';
|
||||
|
||||
import ImgPreview from 'components/ImgPreview';
|
||||
import InputFileDetails from 'components/InputFileDetails';
|
||||
|
||||
import styles from './styles.scss';
|
||||
|
||||
/* eslint-disable react/jsx-handler-names */
|
||||
/* eslint-disable jsx-a11y/label-has-for */
|
||||
class InputFile extends React.Component {
|
||||
state = {
|
||||
didDeleteFile: false,
|
||||
@ -23,6 +24,19 @@ class InputFile extends React.Component {
|
||||
position: 0,
|
||||
};
|
||||
|
||||
onDrop = (e) => {
|
||||
e.preventDefault();
|
||||
this.addFilesToProps(e.dataTransfer.files);
|
||||
}
|
||||
|
||||
handleClick = (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
this.inputFile.click();
|
||||
}
|
||||
|
||||
handleChange = ({ target }) => this.addFilesToProps(target.files);
|
||||
|
||||
addFilesToProps = (files) => {
|
||||
const initAcc = this.props.multiple ? cloneDeep(this.props.value) : {};
|
||||
const value = Object.keys(files).reduce((acc, current) => {
|
||||
@ -34,7 +48,7 @@ class InputFile extends React.Component {
|
||||
}
|
||||
|
||||
return acc;
|
||||
}, initAcc)
|
||||
}, initAcc);
|
||||
|
||||
const target = {
|
||||
name: this.props.name,
|
||||
@ -46,19 +60,6 @@ class InputFile extends React.Component {
|
||||
this.props.onChange({ target });
|
||||
}
|
||||
|
||||
handleChange = ({ target }) => this.addFilesToProps(target.files);
|
||||
|
||||
handleClick = (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
this.inputFile.click();
|
||||
}
|
||||
|
||||
onDrop = (e) => {
|
||||
e.preventDefault();
|
||||
this.addFilesToProps(e.dataTransfer.files);
|
||||
}
|
||||
|
||||
handleFileDelete = (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
@ -8,7 +8,6 @@ import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import { get, startsWith } from 'lodash';
|
||||
import cn from 'classnames';
|
||||
|
||||
import styles from './styles.scss';
|
||||
|
||||
@ -19,7 +18,7 @@ function InputFileDetails(props) {
|
||||
|
||||
// TODO improve logic
|
||||
if (!get(props.file, 'name') && !props.multiple) {
|
||||
return <div />
|
||||
return <div />;
|
||||
}
|
||||
|
||||
const url = startsWith(props.file.url, '/') ? `${strapi.backendURL}${props.file.url}` : props.file.url;
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import cn from 'classnames';
|
||||
import { differenceBy, isEmpty, isObject } from 'lodash';
|
||||
import { differenceBy, isEmpty } from 'lodash';
|
||||
|
||||
// Design
|
||||
import Label from 'components/Label';
|
||||
|
||||
@ -6,6 +6,7 @@ import cn from 'classnames';
|
||||
|
||||
import styles from './styles.scss';
|
||||
|
||||
/* eslint-disable jsx-a11y/no-autofocus */
|
||||
function InputNumber(props) {
|
||||
return (
|
||||
<FormattedMessage id={props.placeholder} defaultMessage={props.placeholder}>
|
||||
@ -32,7 +33,7 @@ function InputNumber(props) {
|
||||
/>
|
||||
)}
|
||||
</FormattedMessage>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
InputNumber.defaultProps = {
|
||||
@ -54,10 +55,10 @@ InputNumber.propTypes = {
|
||||
deactivateErrorHighlight: PropTypes.bool,
|
||||
disabled: PropTypes.bool,
|
||||
error: PropTypes.bool,
|
||||
name: PropTypes.string.isRequired,
|
||||
onBlur: PropTypes.func,
|
||||
onChange: PropTypes.func.isRequired,
|
||||
onFocus: PropTypes.func,
|
||||
name: PropTypes.string.isRequired,
|
||||
placeholder: PropTypes.string,
|
||||
style: PropTypes.object,
|
||||
tabIndex: PropTypes.string,
|
||||
|
||||
@ -94,7 +94,8 @@ class InputNumberWithErrors extends React.Component { // eslint-disable-line rea
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={cn(
|
||||
<div
|
||||
className={cn(
|
||||
styles.containerInputNumber,
|
||||
customBootstrapClass,
|
||||
!isEmpty(className) && className,
|
||||
@ -163,6 +164,7 @@ InputNumberWithErrors.defaultProps = {
|
||||
style: {},
|
||||
tabIndex: '0',
|
||||
validations: {},
|
||||
value: 0,
|
||||
};
|
||||
|
||||
InputNumberWithErrors.propTypes = {
|
||||
|
||||
@ -12,6 +12,7 @@ import cn from 'classnames';
|
||||
|
||||
import styles from './styles.scss';
|
||||
|
||||
/* eslint-disable jsx-a11y/no-autofocus */
|
||||
class InputPassword extends React.Component {
|
||||
state = { showPassword: false };
|
||||
|
||||
|
||||
@ -96,7 +96,8 @@ class InputPasswordWithErrors extends React.Component {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={cn(
|
||||
<div
|
||||
className={cn(
|
||||
styles.containerInputPassword,
|
||||
this.props.customBootstrapClass,
|
||||
!isEmpty(this.props.className) && this.props.className,
|
||||
|
||||
@ -12,6 +12,7 @@ import cn from 'classnames';
|
||||
|
||||
import styles from './styles.scss';
|
||||
|
||||
/* eslint-disable jsx-a11y/no-autofocus */
|
||||
class InputSearch extends React.Component {
|
||||
state = { isFocused: false };
|
||||
|
||||
@ -42,7 +43,8 @@ class InputSearch extends React.Component {
|
||||
|
||||
return (
|
||||
<div className={cn(styles.inputSearch, 'input-group', !isEmpty(className) && className)} style={style}>
|
||||
<span className={cn(
|
||||
<span
|
||||
className={cn(
|
||||
'input-group-addon',
|
||||
styles.addonSearch,
|
||||
this.state.isFocused && styles.addonFocus,
|
||||
@ -77,32 +79,32 @@ class InputSearch extends React.Component {
|
||||
}
|
||||
|
||||
InputSearch.defaultProps = {
|
||||
autoFocus: false,
|
||||
className: '',
|
||||
deactivateErrorHighlight: false,
|
||||
disabled: false,
|
||||
error: false,
|
||||
onBlur: () => {},
|
||||
onFocus: () => {},
|
||||
placeholder: 'app.utils.placeholder.defaultMessage',
|
||||
style: {},
|
||||
tabIndex: '0',
|
||||
autoFocus: false,
|
||||
className: '',
|
||||
deactivateErrorHighlight: false,
|
||||
disabled: false,
|
||||
error: false,
|
||||
onBlur: () => {},
|
||||
onFocus: () => {},
|
||||
placeholder: 'app.utils.placeholder.defaultMessage',
|
||||
style: {},
|
||||
tabIndex: '0',
|
||||
};
|
||||
|
||||
InputSearch.propTypes = {
|
||||
autoFocus: PropTypes.bool,
|
||||
className: PropTypes.string,
|
||||
deactivateErrorHighlight: PropTypes.bool,
|
||||
disabled: PropTypes.bool,
|
||||
error: PropTypes.bool,
|
||||
onBlur: PropTypes.func,
|
||||
onChange: PropTypes.func.isRequired,
|
||||
onFocus: PropTypes.func,
|
||||
name: PropTypes.string.isRequired,
|
||||
placeholder: PropTypes.string,
|
||||
style: PropTypes.object,
|
||||
tabIndex: PropTypes.string,
|
||||
value: PropTypes.string.isRequired,
|
||||
autoFocus: PropTypes.bool,
|
||||
className: PropTypes.string,
|
||||
deactivateErrorHighlight: PropTypes.bool,
|
||||
disabled: PropTypes.bool,
|
||||
error: PropTypes.bool,
|
||||
name: PropTypes.string.isRequired,
|
||||
onBlur: PropTypes.func,
|
||||
onChange: PropTypes.func.isRequired,
|
||||
onFocus: PropTypes.func,
|
||||
placeholder: PropTypes.string,
|
||||
style: PropTypes.object,
|
||||
tabIndex: PropTypes.string,
|
||||
value: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
export default InputSearch;
|
||||
|
||||
@ -98,7 +98,8 @@ class InputSearchWithErrors extends React.Component { // eslint-disable-line rea
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={cn(
|
||||
<div
|
||||
className={cn(
|
||||
styles.containerSearch,
|
||||
this.props.customBootstrapClass,
|
||||
!isEmpty(this.props.className) && this.props.className,
|
||||
|
||||
@ -14,6 +14,7 @@ import SelectOption from 'components/SelectOption';
|
||||
|
||||
import styles from './styles.scss';
|
||||
|
||||
/* eslint-disable jsx-a11y/no-autofocus */
|
||||
function InputSelect(props) {
|
||||
return (
|
||||
<select
|
||||
@ -39,7 +40,7 @@ function InputSelect(props) {
|
||||
return <SelectOption key={key} {...option} />;
|
||||
}
|
||||
|
||||
return <option key={key} value={option}>{option}</option>
|
||||
return <option key={key} value={option}>{option}</option>;
|
||||
})}
|
||||
</select>
|
||||
);
|
||||
|
||||
@ -13,7 +13,7 @@ import cn from 'classnames';
|
||||
import Label from 'components/Label';
|
||||
import InputDescription from 'components/InputDescription';
|
||||
import InputErrors from 'components/InputErrors';
|
||||
import InputSelect from 'components/InputSelect'
|
||||
import InputSelect from 'components/InputSelect';
|
||||
|
||||
import styles from './styles.scss';
|
||||
|
||||
@ -59,7 +59,6 @@ class InputSelectWithErrors extends React.Component {
|
||||
customBootstrapClass,
|
||||
deactivateErrorHighlight,
|
||||
disabled,
|
||||
errors,
|
||||
errorsClassName,
|
||||
errorsStyle,
|
||||
inputClassName,
|
||||
@ -81,7 +80,8 @@ class InputSelectWithErrors extends React.Component {
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<div className={cn(
|
||||
<div
|
||||
className={cn(
|
||||
styles.containerSelect,
|
||||
customBootstrapClass,
|
||||
!isEmpty(className) && className,
|
||||
@ -202,7 +202,7 @@ InputSelectWithErrors.propTypes = {
|
||||
).isRequired,
|
||||
style: PropTypes.object,
|
||||
tabIndex: PropTypes.string,
|
||||
validation: PropTypes.object,
|
||||
validations: PropTypes.object,
|
||||
value: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
|
||||
@ -4,11 +4,12 @@ import { isEmpty } from 'lodash';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import cn from 'classnames';
|
||||
|
||||
/* eslint-disable jsx-a11y/no-autofocus */
|
||||
import styles from './styles.scss';
|
||||
|
||||
function InputText(props) {
|
||||
const placeholder = isEmpty(props.placeholder) ? 'app.utils.placeholder.defaultMessage' : props.placeholder;
|
||||
|
||||
|
||||
return (
|
||||
<FormattedMessage id={placeholder} defaultMessage={placeholder}>
|
||||
{(message) => (
|
||||
@ -56,10 +57,10 @@ InputText.propTypes = {
|
||||
deactivateErrorHighlight: PropTypes.bool,
|
||||
disabled: PropTypes.bool,
|
||||
error: PropTypes.bool,
|
||||
name: PropTypes.string.isRequired,
|
||||
onBlur: PropTypes.func,
|
||||
onChange: PropTypes.func.isRequired,
|
||||
onFocus: PropTypes.func,
|
||||
name: PropTypes.string.isRequired,
|
||||
placeholder: PropTypes.string,
|
||||
style: PropTypes.object,
|
||||
tabIndex: PropTypes.string,
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
/* eslint-disable jsx-a11y/no-autofocus */
|
||||
import React from 'react';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import { isEmpty } from 'lodash';
|
||||
@ -60,7 +61,9 @@ InputTextArea.propTypes = {
|
||||
disabled: PropTypes.bool,
|
||||
error: PropTypes.bool,
|
||||
name: PropTypes.string.isRequired,
|
||||
onBlur: PropTypes.func,
|
||||
onChange: PropTypes.func.isRequired,
|
||||
onFocus: PropTypes.func,
|
||||
placeholder: PropTypes.string,
|
||||
style: PropTypes.object,
|
||||
tabIndex: PropTypes.string,
|
||||
|
||||
@ -94,7 +94,8 @@ class InputTextAreaWithErrors extends React.Component { // eslint-disable-line r
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={cn(
|
||||
<div
|
||||
className={cn(
|
||||
styles.containerTextArea,
|
||||
customBootstrapClass,
|
||||
!isEmpty(className) && className,
|
||||
|
||||
@ -15,6 +15,7 @@ import validateInput from 'utils/inputsValidations';
|
||||
|
||||
import styles from './styles.scss';
|
||||
|
||||
/* eslint-disable jsx-a11y/no-autofocus */
|
||||
class InputTextWithErrors extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
||||
state = { errors: [], hasInitialValue: false };
|
||||
|
||||
@ -94,7 +95,8 @@ class InputTextWithErrors extends React.Component { // eslint-disable-line react
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={cn(
|
||||
<div
|
||||
className={cn(
|
||||
styles.containerText,
|
||||
customBootstrapClass,
|
||||
!isEmpty(className) && className,
|
||||
|
||||
@ -9,6 +9,7 @@ import { isEmpty } from 'lodash';
|
||||
|
||||
import styles from './styles.scss';
|
||||
|
||||
/* eslint-disable jsx-a11y/no-autofocus */
|
||||
class InputToggle extends React.Component {
|
||||
handleClick = (e) => {
|
||||
const target = {
|
||||
@ -33,7 +34,8 @@ class InputToggle extends React.Component {
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<div className={cn(
|
||||
<div
|
||||
className={cn(
|
||||
'btn-group',
|
||||
styles.inputToggleContainer,
|
||||
!isEmpty(className) && className,
|
||||
|
||||
@ -24,7 +24,7 @@ class InputToggleWithErrors extends React.Component {
|
||||
|
||||
// Display input error if it already has some
|
||||
if (!isEmpty(errors)) {
|
||||
this.setState({ errors })
|
||||
this.setState({ errors });
|
||||
}
|
||||
}
|
||||
|
||||
@ -69,7 +69,8 @@ class InputToggleWithErrors extends React.Component {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={cn(
|
||||
<div
|
||||
className={cn(
|
||||
styles.containerToggleErrors,
|
||||
customBootstrapClass,
|
||||
!isEmpty(className) && className,
|
||||
@ -82,7 +83,7 @@ class InputToggleWithErrors extends React.Component {
|
||||
htmlFor={name}
|
||||
message={label}
|
||||
style={labelStyle}
|
||||
/>
|
||||
/>
|
||||
</div>
|
||||
<InputToggle
|
||||
autoFocus={autoFocus}
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
* InputsIndex references all the input with errors available
|
||||
*/
|
||||
|
||||
/* eslint-disable react/require-default-props */
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { isEmpty } from 'lodash';
|
||||
@ -22,7 +23,7 @@ import InputTextWithErrors from 'components/InputTextWithErrors';
|
||||
import InputToggleWithErrors from 'components/InputToggleWithErrors';
|
||||
import WysiwygWithErrors from 'components/WysiwygWithErrors';
|
||||
|
||||
const DefaultInputError = ({ type }) => <div>Your input type: <b>{type}</b> does not exist</div>
|
||||
const DefaultInputError = ({ type }) => <div>Your input type: <b>{type}</b> does not exist</div>;
|
||||
|
||||
const inputs = {
|
||||
addon: InputAddonWithErrors,
|
||||
@ -50,7 +51,7 @@ function InputsIndex(props) {
|
||||
inputValue = props.value || false;
|
||||
break;
|
||||
case 'number':
|
||||
inputValue = props.value === 0 ? props.values : props.value || '';
|
||||
inputValue = props.value === 0 ? props.value : props.value || '';
|
||||
break;
|
||||
case 'file':
|
||||
inputValue = props.value || [];
|
||||
@ -58,15 +59,19 @@ function InputsIndex(props) {
|
||||
default:
|
||||
inputValue = props.value || '';
|
||||
}
|
||||
|
||||
|
||||
const Input = inputs[type] ? inputs[type] : DefaultInputError;
|
||||
|
||||
return <Input {...props} value={inputValue} />;
|
||||
}
|
||||
|
||||
DefaultInputError.propTypes = {
|
||||
type: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
InputsIndex.defaultProps = {
|
||||
addon: false,
|
||||
}
|
||||
};
|
||||
|
||||
InputsIndex.propTypes = {
|
||||
addon: PropTypes.oneOfType([
|
||||
@ -74,6 +79,7 @@ InputsIndex.propTypes = {
|
||||
PropTypes.string,
|
||||
]),
|
||||
type: PropTypes.string.isRequired,
|
||||
value: PropTypes.any,
|
||||
};
|
||||
|
||||
export default InputsIndex;
|
||||
|
||||
@ -1,11 +1,12 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import { isFunction, isObject, upperFirst } from 'lodash';
|
||||
import { isFunction, isObject } from 'lodash';
|
||||
import cn from 'classnames';
|
||||
|
||||
import styles from './styles.scss';
|
||||
|
||||
/* eslint-disable jsx-a11y/label-has-for */
|
||||
function Label(props) {
|
||||
let content = props.children;
|
||||
|
||||
|
||||
@ -8,14 +8,13 @@ import React from 'react';
|
||||
import {
|
||||
ContentState,
|
||||
convertFromHTML,
|
||||
Editor,
|
||||
EditorState,
|
||||
getDefaultKeyBinding,
|
||||
Modifier,
|
||||
RichUtils,
|
||||
} from 'draft-js';
|
||||
import PropTypes from 'prop-types';
|
||||
import { cloneDeep, isEmpty, replace, trimStart, trimEnd } from 'lodash';
|
||||
import { isEmpty, replace, trimStart, trimEnd } from 'lodash';
|
||||
import cn from 'classnames';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import Controls from 'components/WysiwygInlineControls';
|
||||
@ -77,52 +76,6 @@ class Wysiwyg extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
addEntity = (text, style) => {
|
||||
const editorState = this.state.editorState;
|
||||
const currentContent = editorState.getCurrentContent();
|
||||
// Get the selected text
|
||||
const selection = editorState.getSelection();
|
||||
const anchorKey = selection.getAnchorKey();
|
||||
const currentContentBlock = currentContent.getBlockForKey(anchorKey);
|
||||
// Range of the text we want to replace
|
||||
const { start, end } = getOffSets(selection);
|
||||
// Retrieve the selected text
|
||||
const selectedText = currentContentBlock.getText().slice(start, end);
|
||||
const innerText = selectedText === '' ? getInnerText(style) : replace(text, 'innerText', selectedText);
|
||||
|
||||
const trimedStart = trimStart(innerText, START_REPLACER).length;
|
||||
const trimedEnd = trimEnd(innerText, END_REPLACER).length;
|
||||
// Set the correct offset
|
||||
const focusOffset = start === end ? trimedEnd : start + trimedEnd;
|
||||
const anchorOffset = start + innerText.length - trimedStart;
|
||||
// Merge the old selection with the new one so the editorState is updated
|
||||
const updateSelection = selection.merge({
|
||||
anchorOffset,
|
||||
focusOffset,
|
||||
});
|
||||
|
||||
// Dynamically add some content to the one selected
|
||||
const textWithEntity = Modifier.replaceText(currentContent, selection, innerText);
|
||||
|
||||
// Push the new content to the editorState
|
||||
const newEditorState = EditorState.push(editorState, textWithEntity, 'insert-characters');
|
||||
|
||||
// SetState and force focus
|
||||
this.setState({
|
||||
editorState: EditorState.forceSelection(newEditorState, updateSelection),
|
||||
headerValue: '',
|
||||
}, () => {
|
||||
this.focus();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
handleChangeSelect = ({ target }) => {
|
||||
this.setState({ headerValue: target.value });
|
||||
const splitData = target.value.split('.');
|
||||
this.addEntity(splitData[0], splitData[1]);
|
||||
}
|
||||
|
||||
onChange = (editorState) => {
|
||||
this.setState({ editorState });
|
||||
this.props.onChange({ target: {
|
||||
@ -132,22 +85,6 @@ class Wysiwyg extends React.Component {
|
||||
}});
|
||||
}
|
||||
|
||||
mapKeyToEditorCommand = (e) => {
|
||||
if (e.keyCode === 9 /* TAB */) {
|
||||
const newEditorState = RichUtils.onTab(
|
||||
e,
|
||||
this.state.editorState,
|
||||
4, /* maxDepth */
|
||||
);
|
||||
if (newEditorState !== this.state.editorState) {
|
||||
this.onChange(newEditorState);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
return getDefaultKeyBinding(e);
|
||||
}
|
||||
|
||||
// NOTE: leave these function if we change to HTML instead of markdown
|
||||
// toggleBlockType = (blockType) => {
|
||||
// this.onChange(
|
||||
@ -167,15 +104,6 @@ class Wysiwyg extends React.Component {
|
||||
// );
|
||||
// }
|
||||
|
||||
toggleFullScreen = (e) => {
|
||||
e.preventDefault();
|
||||
this.setState({
|
||||
toggleFullScreen: !this.state.toggleFullScreen,
|
||||
}, () => {
|
||||
this.focus();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Init the editor with data from
|
||||
* @param {[type]} props [description]
|
||||
@ -190,6 +118,76 @@ class Wysiwyg extends React.Component {
|
||||
this.setState({ editorState, hasInitialValue: true, initialValue: props.value });
|
||||
}
|
||||
|
||||
handleChangeSelect = ({ target }) => {
|
||||
this.setState({ headerValue: target.value });
|
||||
const splitData = target.value.split('.');
|
||||
this.addEntity(splitData[0], splitData[1]);
|
||||
}
|
||||
|
||||
mapKeyToEditorCommand = (e) => {
|
||||
if (e.keyCode === 9 /* TAB */) {
|
||||
const newEditorState = RichUtils.onTab(
|
||||
e,
|
||||
this.state.editorState,
|
||||
4, /* maxDepth */
|
||||
);
|
||||
if (newEditorState !== this.state.editorState) {
|
||||
this.onChange(newEditorState);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
return getDefaultKeyBinding(e);
|
||||
}
|
||||
|
||||
addEntity = (text, style) => {
|
||||
const editorState = this.state.editorState;
|
||||
const currentContent = editorState.getCurrentContent();
|
||||
// Get the selected text
|
||||
const selection = editorState.getSelection();
|
||||
const anchorKey = selection.getAnchorKey();
|
||||
const currentContentBlock = currentContent.getBlockForKey(anchorKey);
|
||||
// Range of the text we want to replace
|
||||
const { start, end } = getOffSets(selection);
|
||||
// Retrieve the selected text
|
||||
const selectedText = currentContentBlock.getText().slice(start, end);
|
||||
const innerText = selectedText === '' ? getInnerText(style) : replace(text, 'innerText', selectedText);
|
||||
|
||||
const trimedStart = trimStart(innerText, START_REPLACER).length;
|
||||
const trimedEnd = trimEnd(innerText, END_REPLACER).length;
|
||||
// Set the correct offset
|
||||
const focusOffset = start === end ? trimedEnd : start + trimedEnd;
|
||||
const anchorOffset = start + innerText.length - trimedStart;
|
||||
// Merge the old selection with the new one so the editorState is updated
|
||||
const updateSelection = selection.merge({
|
||||
anchorOffset,
|
||||
focusOffset,
|
||||
});
|
||||
|
||||
// Dynamically add some content to the one selected
|
||||
const textWithEntity = Modifier.replaceText(currentContent, selection, innerText);
|
||||
|
||||
// Push the new content to the editorState
|
||||
const newEditorState = EditorState.push(editorState, textWithEntity, 'insert-characters');
|
||||
|
||||
// SetState and force focus
|
||||
this.setState({
|
||||
editorState: EditorState.forceSelection(newEditorState, updateSelection),
|
||||
headerValue: '',
|
||||
}, () => {
|
||||
this.focus();
|
||||
});
|
||||
}
|
||||
|
||||
toggleFullScreen = (e) => {
|
||||
e.preventDefault();
|
||||
this.setState({
|
||||
toggleFullScreen: !this.state.toggleFullScreen,
|
||||
}, () => {
|
||||
this.focus();
|
||||
});
|
||||
}
|
||||
|
||||
handleKeyCommand(command, editorState) {
|
||||
const newState = RichUtils.handleKeyCommand(editorState, command);
|
||||
if (newState) {
|
||||
|
||||
@ -6,7 +6,6 @@
|
||||
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import cn from 'classnames';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
import styles from './styles.scss';
|
||||
@ -20,7 +19,7 @@ const WysiwygBottomControls = ({ charactersNumber, onClick }) => {
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
WysiwygBottomControls.defaultProps = {
|
||||
charactersNumber: 0,
|
||||
|
||||
@ -6,13 +6,22 @@
|
||||
|
||||
import React from 'react';
|
||||
import { Editor } from 'draft-js';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
class WysiwygEditor extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<Editor {...this.props} ref={this.props.setRef}/>
|
||||
<Editor {...this.props} ref={this.props.setRef} />
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
WysiwygEditor.defaultProps = {
|
||||
setRef: () => {},
|
||||
};
|
||||
|
||||
WysiwygEditor.propTypes = {
|
||||
setRef: PropTypes.func,
|
||||
};
|
||||
|
||||
export default WysiwygEditor;
|
||||
|
||||
@ -70,6 +70,7 @@ StyleButton.defaultProps = {
|
||||
onToggle: () => {},
|
||||
onToggleBlock: () => {},
|
||||
style: '',
|
||||
text: '',
|
||||
};
|
||||
|
||||
StyleButton.propTypes = {
|
||||
@ -82,6 +83,7 @@ StyleButton.propTypes = {
|
||||
// onToggle: PropTypes.func,
|
||||
// onToggleBlock: PropTypes.func,
|
||||
style: PropTypes.string,
|
||||
text: PropTypes.string,
|
||||
};
|
||||
|
||||
WysiwygInlineControls.defaultProps = {
|
||||
|
||||
@ -32,5 +32,5 @@ cd ../strapi-plugin-upload
|
||||
npm run test
|
||||
|
||||
# Test `strapi-helper-plugin`
|
||||
# cd ../strapi-helper-plugin/lib
|
||||
# npm run test
|
||||
cd ../strapi-helper-plugin/lib
|
||||
npm run test
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user