mirror of
https://github.com/strapi/strapi.git
synced 2025-12-28 07:33:17 +00:00
Input JSON UI with error
This commit is contained in:
parent
b35e5b022d
commit
8174e9dae8
@ -21,7 +21,8 @@
|
||||
"type": "string"
|
||||
},
|
||||
"geolocation": {
|
||||
"type": "json"
|
||||
"type": "json",
|
||||
"required": true
|
||||
},
|
||||
"country": {
|
||||
"model": "country"
|
||||
|
||||
@ -2,8 +2,7 @@ import styled from 'styled-components';
|
||||
|
||||
const Wrapper = styled.div`
|
||||
position: relative;
|
||||
margin-top: 14px;
|
||||
margin-bottom: -14px;
|
||||
margin-bottom: 3px;
|
||||
line-height: 18px;
|
||||
|
||||
.CodeMirror {
|
||||
|
||||
@ -0,0 +1,32 @@
|
||||
import styled from 'styled-components';
|
||||
|
||||
const Wrapper = styled.div`
|
||||
padding-bottom: 30px;
|
||||
|
||||
label {
|
||||
margin-bottom: 1rem;
|
||||
line-height: 18px;
|
||||
display: block;
|
||||
}
|
||||
> div {
|
||||
border-radius: 4px;
|
||||
border: 1px solid #090300;
|
||||
}
|
||||
&.bordered {
|
||||
> div {
|
||||
border-color: red;
|
||||
}
|
||||
}
|
||||
> p {
|
||||
width 100%;
|
||||
padding-top: 14px;
|
||||
font-size: 1.2rem;
|
||||
line-height: normal;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
margin-bottom: -11px;
|
||||
}
|
||||
`;
|
||||
|
||||
export default Wrapper;
|
||||
@ -9,66 +9,13 @@ import PropTypes from 'prop-types';
|
||||
import { isEmpty, isFunction } from 'lodash';
|
||||
import cn from 'classnames';
|
||||
|
||||
// Design
|
||||
import {
|
||||
Label,
|
||||
InputDescription,
|
||||
InputErrors,
|
||||
InputSpacer,
|
||||
validateInput,
|
||||
} from 'strapi-helper-plugin';
|
||||
import { Description, ErrorMessage, Label } from '@buffetjs/styles';
|
||||
import { Error } from '@buffetjs/core';
|
||||
|
||||
import InputJSON from '../InputJSON';
|
||||
import Wrapper from './Wrapper';
|
||||
|
||||
class InputJSONWithErrors extends React.Component {
|
||||
// eslint-disable-line react/prefer-stateless-function
|
||||
state = { errors: [], hasInitialValue: false };
|
||||
|
||||
componentDidMount() {
|
||||
const { value, errors } = this.props;
|
||||
|
||||
// Prevent the input from displaying an error when the user enters and leaves without filling it
|
||||
if (!isEmpty(value)) {
|
||||
this.setState({ hasInitialValue: true });
|
||||
}
|
||||
|
||||
// Display input error if it already has some
|
||||
if (!isEmpty(errors)) {
|
||||
this.setState({ errors });
|
||||
}
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
// Show required error if the input's value is received after the compo is mounted
|
||||
if (!isEmpty(this.props.value) && !this.state.hasInitialValue) {
|
||||
this.setInit();
|
||||
}
|
||||
|
||||
// Check if errors have been updated during validations
|
||||
if (prevProps.didCheckErrors !== this.props.didCheckErrors) {
|
||||
// Remove from the state the errors that have already been set
|
||||
const errors = isEmpty(this.props.errors) ? [] : this.props.errors;
|
||||
this.setErrors(errors);
|
||||
}
|
||||
}
|
||||
|
||||
setErrors = errors => this.setState({ errors });
|
||||
|
||||
setInit = () => this.setState({ hasInitialValue: true });
|
||||
|
||||
/**
|
||||
* Set the errors depending on the validations given to the input
|
||||
* @param {Object} target
|
||||
*/
|
||||
handleBlur = ({ target }) => {
|
||||
// Prevent from displaying error if the input is initially isEmpty
|
||||
if (!isEmpty(target.value) || this.state.hasInitialValue) {
|
||||
const errors = validateInput(target.value, this.props.validations);
|
||||
this.setErrors(errors);
|
||||
this.setInit();
|
||||
}
|
||||
};
|
||||
|
||||
handleChange = e => {
|
||||
this.setState({ errors: [] });
|
||||
this.props.onChange(e);
|
||||
@ -80,74 +27,75 @@ class InputJSONWithErrors extends React.Component {
|
||||
className,
|
||||
deactivateErrorHighlight,
|
||||
disabled,
|
||||
errorsClassName,
|
||||
errorsStyle,
|
||||
error: inputError,
|
||||
inputClassName,
|
||||
inputDescription,
|
||||
inputDescriptionClassName,
|
||||
inputStyle,
|
||||
label,
|
||||
labelClassName,
|
||||
labelStyle,
|
||||
name,
|
||||
noErrorsDescription,
|
||||
onBlur,
|
||||
placeholder,
|
||||
resetProps,
|
||||
tabIndex,
|
||||
validations,
|
||||
value,
|
||||
...rest
|
||||
} = this.props;
|
||||
|
||||
const handleBlur = isFunction(onBlur) ? onBlur : this.handleBlur;
|
||||
|
||||
let spacer = !isEmpty(inputDescription) ? <InputSpacer /> : <div />;
|
||||
|
||||
if (!noErrorsDescription && !isEmpty(this.state.errors)) {
|
||||
spacer = <div />;
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cn(!isEmpty(className) && className)}
|
||||
style={{
|
||||
marginBottom: '1.5rem',
|
||||
fontSize: '1.3rem',
|
||||
fontFamily: 'Lato',
|
||||
}}
|
||||
<Error
|
||||
inputError={inputError}
|
||||
name={name}
|
||||
type="text"
|
||||
validations={validations}
|
||||
>
|
||||
<Label
|
||||
className={labelClassName}
|
||||
htmlFor={name}
|
||||
message={label}
|
||||
style={labelStyle}
|
||||
/>
|
||||
<InputJSON
|
||||
autoFocus={autoFocus}
|
||||
className={inputClassName}
|
||||
disabled={disabled}
|
||||
deactivateErrorHighlight={deactivateErrorHighlight}
|
||||
name={name}
|
||||
onBlur={handleBlur}
|
||||
onChange={this.handleChange}
|
||||
placeholder={placeholder}
|
||||
resetProps={resetProps}
|
||||
style={inputStyle}
|
||||
tabIndex={tabIndex}
|
||||
value={value}
|
||||
/>
|
||||
<InputDescription
|
||||
className={inputDescriptionClassName}
|
||||
message={inputDescription}
|
||||
style={{ marginTop: '2.9rem' }}
|
||||
/>
|
||||
<InputErrors
|
||||
className={errorsClassName}
|
||||
errors={(!noErrorsDescription && this.state.errors) || []}
|
||||
name={name}
|
||||
style={errorsStyle}
|
||||
/>
|
||||
{spacer}
|
||||
</div>
|
||||
{({ canCheck, onBlur, error, dispatch }) => {
|
||||
const hasError = error && error !== null;
|
||||
|
||||
return (
|
||||
<Wrapper
|
||||
className={`${cn(!isEmpty(className) && className)} ${
|
||||
hasError ? 'bordered' : ''
|
||||
}`}
|
||||
>
|
||||
<Label htmlFor={name}>{label}</Label>
|
||||
<InputJSON
|
||||
{...rest}
|
||||
autoFocus={autoFocus}
|
||||
className={inputClassName}
|
||||
disabled={disabled}
|
||||
deactivateErrorHighlight={deactivateErrorHighlight}
|
||||
name={name}
|
||||
onBlur={isFunction(handleBlur) ? handleBlur : onBlur}
|
||||
onChange={e => {
|
||||
if (!canCheck) {
|
||||
dispatch({
|
||||
type: 'SET_CHECK',
|
||||
});
|
||||
}
|
||||
|
||||
dispatch({
|
||||
type: 'SET_ERROR',
|
||||
error: null,
|
||||
});
|
||||
this.handleChange(e);
|
||||
}}
|
||||
placeholder={placeholder}
|
||||
resetProps={resetProps}
|
||||
style={inputStyle}
|
||||
tabIndex={tabIndex}
|
||||
value={value}
|
||||
/>
|
||||
{!hasError && inputDescription && (
|
||||
<Description>{inputDescription}</Description>
|
||||
)}
|
||||
{hasError && <ErrorMessage>{error}</ErrorMessage>}
|
||||
</Wrapper>
|
||||
);
|
||||
}}
|
||||
</Error>
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -158,17 +106,13 @@ InputJSONWithErrors.defaultProps = {
|
||||
deactivateErrorHighlight: false,
|
||||
didCheckErrors: false,
|
||||
disabled: false,
|
||||
errors: [],
|
||||
errorsClassName: '',
|
||||
errorsStyle: {},
|
||||
error: null,
|
||||
inputClassName: '',
|
||||
inputDescription: '',
|
||||
inputDescriptionClassName: '',
|
||||
inputStyle: {},
|
||||
label: '',
|
||||
labelClassName: '',
|
||||
labelStyle: {},
|
||||
noErrorsDescription: false,
|
||||
onBlur: false,
|
||||
placeholder: '',
|
||||
resetProps: false,
|
||||
@ -183,9 +127,7 @@ InputJSONWithErrors.propTypes = {
|
||||
deactivateErrorHighlight: PropTypes.bool,
|
||||
didCheckErrors: PropTypes.bool,
|
||||
disabled: PropTypes.bool,
|
||||
errors: PropTypes.array,
|
||||
errorsClassName: PropTypes.string,
|
||||
errorsStyle: PropTypes.object,
|
||||
error: PropTypes.string,
|
||||
inputClassName: PropTypes.string,
|
||||
inputDescription: PropTypes.oneOfType([
|
||||
PropTypes.string,
|
||||
@ -195,7 +137,6 @@ InputJSONWithErrors.propTypes = {
|
||||
params: PropTypes.object,
|
||||
}),
|
||||
]),
|
||||
inputDescriptionClassName: PropTypes.string,
|
||||
inputStyle: PropTypes.object,
|
||||
label: PropTypes.oneOfType([
|
||||
PropTypes.string,
|
||||
@ -208,7 +149,6 @@ InputJSONWithErrors.propTypes = {
|
||||
labelClassName: PropTypes.string,
|
||||
labelStyle: PropTypes.object,
|
||||
name: PropTypes.string.isRequired,
|
||||
noErrorsDescription: PropTypes.bool,
|
||||
onBlur: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),
|
||||
onChange: PropTypes.func.isRequired,
|
||||
placeholder: PropTypes.string,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user