From 7d23acfbe6c5cf4dc7c0d7da98d6b559b5be5e5c Mon Sep 17 00:00:00 2001 From: cyril lopez Date: Mon, 5 Feb 2018 12:08:16 +0100 Subject: [PATCH 1/8] Created InputPassword --- .../lib/src/components/InputPassword/index.js | 104 ++++++++++++++++++ .../src/components/InputPassword/styles.scss | 26 +++++ 2 files changed, 130 insertions(+) create mode 100644 packages/strapi-helper-plugin/lib/src/components/InputPassword/index.js create mode 100644 packages/strapi-helper-plugin/lib/src/components/InputPassword/styles.scss diff --git a/packages/strapi-helper-plugin/lib/src/components/InputPassword/index.js b/packages/strapi-helper-plugin/lib/src/components/InputPassword/index.js new file mode 100644 index 0000000000..9e8b8d6d56 --- /dev/null +++ b/packages/strapi-helper-plugin/lib/src/components/InputPassword/index.js @@ -0,0 +1,104 @@ +/** + * + * InputPassword + * + */ + +import React, { Fragment } from 'react'; +import { FormattedMessage } from 'react-intl'; +import PropTypes from 'prop-types'; +import { isEmpty } from 'lodash'; +import cn from 'classnames'; + +import styles from './styles.scss'; + +class InputPassword extends React.Component { + state = { showPassword: false }; + + handleClick = () => this.setState({ showPassword: !this.state.showPassword }); + + render() { + const { + autoFocus, + className, + deactivateErrorHighlight, + disabled, + error, + name, + onBlur, + onChange, + onFocus, + placeholder, + style, + tabIndex, + value, + } = this.props; + + const eyeColor = this.state.showPassword ? { color: 'black' } : { color: '#9EA7B8' }; + + return ( + + + {(message) => ( + + )} + +
+
+ +
+
+
+ ); + } +} + +InputPassword.defaultProps = { + autoFocus: false, + className: '', + deactivateErrorHighlight: false, + disabled: false, + error: false, + onBlur: () => {}, + onFocus: () => {}, + placeholder: 'app.utils.placeholder.defaultMessage', + style: {}, + tabIndex: '0', +}; + +InputPassword.propTypes = { + 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 InputPassword; diff --git a/packages/strapi-helper-plugin/lib/src/components/InputPassword/styles.scss b/packages/strapi-helper-plugin/lib/src/components/InputPassword/styles.scss new file mode 100644 index 0000000000..f124411154 --- /dev/null +++ b/packages/strapi-helper-plugin/lib/src/components/InputPassword/styles.scss @@ -0,0 +1,26 @@ +.inputPassword { + height: 3.4rem; + margin-top: .9rem; + padding-left: 1rem; + background-size: 0 !important; + border: 1px solid #E3E9F3; + border-radius: 0.25rem; + line-height: 3.4rem; + font-size: 1.3rem; + font-family: 'Lato' !important; + box-shadow: 0px 1px 1px rgba(104, 118, 142, 0.05); +} + +.iconEyeSubWrapper { + position: absolute; + top: -2.8rem; + right: 2.7rem; + color: #9EA7B8; + &:hover { + color: black!important; + } +} + +.iconEyeWrapper { + position: relative; +} From fb9a50dacd311d7ceee8bec317684838bd374a35 Mon Sep 17 00:00:00 2001 From: cyril lopez Date: Mon, 5 Feb 2018 12:27:34 +0100 Subject: [PATCH 2/8] Created InputPasswordWithErrors and added it to InputsIndex --- .../src/components/InputPassword/styles.scss | 2 +- .../InputPasswordWithErrors/index.js | 240 ++++++++++++++++++ .../InputPasswordWithErrors/styles.scss | 5 + .../lib/src/components/InputsIndex/index.js | 3 + 4 files changed, 249 insertions(+), 1 deletion(-) create mode 100644 packages/strapi-helper-plugin/lib/src/components/InputPasswordWithErrors/index.js create mode 100644 packages/strapi-helper-plugin/lib/src/components/InputPasswordWithErrors/styles.scss diff --git a/packages/strapi-helper-plugin/lib/src/components/InputPassword/styles.scss b/packages/strapi-helper-plugin/lib/src/components/InputPassword/styles.scss index f124411154..f7dfd20424 100644 --- a/packages/strapi-helper-plugin/lib/src/components/InputPassword/styles.scss +++ b/packages/strapi-helper-plugin/lib/src/components/InputPassword/styles.scss @@ -13,7 +13,7 @@ .iconEyeSubWrapper { position: absolute; - top: -2.8rem; + top: -2.6rem; right: 2.7rem; color: #9EA7B8; &:hover { diff --git a/packages/strapi-helper-plugin/lib/src/components/InputPasswordWithErrors/index.js b/packages/strapi-helper-plugin/lib/src/components/InputPasswordWithErrors/index.js new file mode 100644 index 0000000000..77acca6641 --- /dev/null +++ b/packages/strapi-helper-plugin/lib/src/components/InputPasswordWithErrors/index.js @@ -0,0 +1,240 @@ +/** + * + * InputPasswordWithErrors + * + */ + +import React from 'react'; +import PropTypes from 'prop-types'; +import { includes, isEmpty, isFunction, mapKeys, reject } from 'lodash'; +import cn from 'classnames'; + +// Design +import Label from 'components/Label'; +import InputDescription from 'components/InputDescription'; +import InputErrors from 'components/InputErrors'; +import InputPassword from 'components/InputPassword'; + +import styles from './styles.scss'; + +class InputPasswordWithErrors extends React.Component { + 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 (value && !isEmpty(value)) { + this.setState({ hasInitialValue: true }); + } + + // Display input error if it already has some + if (!isEmpty(errors)) { + this.setState({ errors }); + } + } + + componentWillReceiveProps(nextProps) { + // Check if errors have been updated during validations + if (nextProps.didCheckErrors !== this.props.didCheckErrors) { + // Remove from the state the errors that have already been set + const errors = isEmpty(nextProps.errors) ? [] : nextProps.errors; + this.setState({ errors }); + } + } + + /** + * 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 = this.validate(target.value); + this.setState({ errors, hasInitialValue: true }); + } + } + + render() { + const { + autoFocus, + deactivateErrorHighlight, + disabled, + errorsClassName, + errorsStyle, + inputClassName, + inputDescriptionClassName, + inputDescriptionStyle, + inputStyle, + labelClassName, + labelStyle, + name, + onChange, + onFocus, + placeholder, + style, + tabIndex, + value, + } = this.props; + const handleBlur = isFunction(this.props.onBlur) ? this.props.onBlur : this.handleBlur; + + return ( +
+
+ ); + } + + validate = (value) => { + const requiredError = { id: 'components.Input.error.validation.required' }; + let errors = []; + + mapKeys(this.props.validations, (validationValue, validationKey) => { + switch (validationKey) { + case 'maxLength': { + if (value.length > validationValue) { + errors.push({ id: 'components.Input.error.validation.maxLength' }); + } + break; + } + case 'minLength': { + if (value.length < validationValue) { + errors.push({ id: 'components.Input.error.validation.minLength' }); + } + break; + } + case 'required': { + if (value.length === 0) { + errors.push({ id: 'components.Input.error.validation.required' }); + } + break; + } + case 'regex': { + if (!new RegExp(validationValue).test(value)) { + errors.push({ id: 'components.Input.error.validation.regex' }); + } + break; + } + default: + errors = []; + } + }); + + if (includes(errors, requiredError)) { + errors = reject(errors, (error) => error !== requiredError); + } + + return errors; + } +} + +InputPasswordWithErrors.defaultProps = { + autoFocus: false, + className: '', + customBootstrapClass: 'col-md-6', + deactivateErrorHighlight: false, + didCheckErrors: false, + disabled: false, + onBlur: false, + onFocus: () => {}, + errors: [], + errorsClassName: '', + errorsStyle: {}, + inputClassName: '', + inputDescription: '', + inputDescriptionClassName: '', + inputDescriptionStyle: {}, + inputStyle: {}, + label: '', + labelClassName: '', + labelStyle: {}, + placeholder: 'app.utils.placeholder.defaultMessage', + style: {}, + tabIndex: '0', + validations: {}, +}; + + +InputPasswordWithErrors.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, + 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 InputPasswordWithErrors; diff --git a/packages/strapi-helper-plugin/lib/src/components/InputPasswordWithErrors/styles.scss b/packages/strapi-helper-plugin/lib/src/components/InputPasswordWithErrors/styles.scss new file mode 100644 index 0000000000..5d8578e7d5 --- /dev/null +++ b/packages/strapi-helper-plugin/lib/src/components/InputPasswordWithErrors/styles.scss @@ -0,0 +1,5 @@ +.container { + min-width: 200px; + margin-bottom: 1.5rem; + font-size: 1.3rem; +} diff --git a/packages/strapi-helper-plugin/lib/src/components/InputsIndex/index.js b/packages/strapi-helper-plugin/lib/src/components/InputsIndex/index.js index 26e3fa6ba7..111957f5e7 100644 --- a/packages/strapi-helper-plugin/lib/src/components/InputsIndex/index.js +++ b/packages/strapi-helper-plugin/lib/src/components/InputsIndex/index.js @@ -8,11 +8,13 @@ import PropTypes from 'prop-types'; // Design import InputNumberWithErrors from 'components/InputNumberWithErrors'; +import InputPasswordWithErrors from 'components/InputPasswordWithErrors'; import InputTextWithErrors from 'components/InputTextWithErrors'; import InputToggleWithErrors from 'components/InputToggleWithErrors'; const inputs = { number: InputNumberWithErrors, + password: InputPasswordWithErrors, string: InputTextWithErrors, text: InputTextWithErrors, toggle: InputToggleWithErrors, @@ -31,6 +33,7 @@ InputsIndex.propTypes = { export default InputsIndex; export { InputNumberWithErrors, + InputPasswordWithErrors, InputTextWithErrors, InputToggleWithErrors, }; From 386ca5bd4ea1fb7b32b137b4bd82b92f58cfc5a6 Mon Sep 17 00:00:00 2001 From: cyril lopez Date: Mon, 5 Feb 2018 15:41:09 +0100 Subject: [PATCH 3/8] Created InputSelectWithErrors and add documentation --- .../en/plugin-development/ui-components.md | 61 ++++++ .../admin/src/translations/en.json | 3 +- .../admin/src/translations/fr.json | 3 +- .../lib/src/components/InputSelect/index.js | 77 ++++++++ .../src/components/InputSelect/styles.scss | 17 ++ .../components/InputSelectWithErrors/index.js | 186 ++++++++++++++++++ .../InputSelectWithErrors/styles.scss | 5 + .../lib/src/components/InputsIndex/index.js | 3 + .../lib/src/components/SelectOption/index.js | 49 +++++ 9 files changed, 402 insertions(+), 2 deletions(-) create mode 100644 packages/strapi-helper-plugin/lib/src/components/InputSelect/index.js create mode 100644 packages/strapi-helper-plugin/lib/src/components/InputSelect/styles.scss create mode 100644 packages/strapi-helper-plugin/lib/src/components/InputSelectWithErrors/index.js create mode 100644 packages/strapi-helper-plugin/lib/src/components/InputSelectWithErrors/styles.scss create mode 100644 packages/strapi-helper-plugin/lib/src/components/SelectOption/index.js diff --git a/docs/3.x.x/en/plugin-development/ui-components.md b/docs/3.x.x/en/plugin-development/ui-components.md index 6dd8a9b14a..8b4af99345 100644 --- a/docs/3.x.x/en/plugin-development/ui-components.md +++ b/docs/3.x.x/en/plugin-development/ui-components.md @@ -424,6 +424,30 @@ InputNumber component. *** +*** + +## InputSelect + +InputSelect component. + +| Property | Type | Required | Description | +| -------- | ---- | -------- | ----------- | +| autoFocus | bool | no | Sets the input's autoFocus | +| className | string | no | custom className for the input | +| deactivateErrorHighlight | bool | no | Allow to deactivate the red border on the input when there is an error | +| disabled | bool | no | Disables the input | +| errors | array | no | Sets the red border on the input | +| onBlur | func | no | Function executed when the user leaves the input | +| onFocus | func | no | Function executed when the user enters the input | +| name | string | yes | The name of the input | +| placeholder | string | no | Input's placeholder, works with i18n | +| selectOptions | array of objects | yes | Options for the select. | +| style | object | no | Input's style property | +| tabIndex | string | no | Input's tabIndex | +| value | string or number | yes | Input's value | + +*** + ## InputText InputText Component @@ -493,6 +517,43 @@ Please refer to the [InputTextWithErrors](#InputTextWithErrors) documentation. *** +## InputSelectWithErrors + +Component integrates Label, InputSelect, InputDescription and InputErrors. + +| Property | Type | Required | Description | +| -------- | ---- | -------- | ----------- | +| autoFocus | bool | no | Sets the input's autoFocus | +| className | string | no | Overrides the container className | +| customBootstrapClass | string | no | Allows to override the input bootstrap col system | +| deactivateErrorHighlight | bool | no | Allow to deactivate the red border on the input when there is an error | +| didCheckErrors | bool | no | Use this props to display errors after submitting a form. | +| disabled | bool | no | Disables the input | +| errors | array | no | Array of errors | +| errorsClassName | string | no | Overrides the InputErrors' className | +| errorsStyle | object | no | Overrides the InputErrors' style | +| inputClassName | string | no | Overrides the InputText's className | +| inputDescriptionClassName | string | no | Overrides the InputDescription's className | +| inputDescriptionStyle | object | no | Overrides the InputDescription's style| +| inputStyle | object | no | Overrides the InputText's style | +| labelClassName | string | no | Overrides the Label's className | +| labelStyle | object | no | Overrides the Label's style | +| onBlur | func | no | Function executed when the user leaves the input | +| onChange | func | yes | Handler to modify the input's value | +| onFocus | func | no | Function executed when the user enters the input | +| name | string | yes | The name of the input | +| placeholder | string | no | Input's placeholder, works with i18n | +| style | object | no | Overrides the container style | +| selectOptions | array of objects | yes | Options for the select. | +| tabIndex | string | no | Input's tabIndex | +| value | string | yes | Input's value | + +### Usage + +Please refer to the [InputTextWithErrors](#InputTextWithErrors) documentation. + +*** + ## InputTextWithErrors Component integrates Label, InputText, InputDescription and InputErrors. diff --git a/packages/strapi-admin/admin/src/translations/en.json b/packages/strapi-admin/admin/src/translations/en.json index c2e8403d73..0066975dd8 100755 --- a/packages/strapi-admin/admin/src/translations/en.json +++ b/packages/strapi-admin/admin/src/translations/en.json @@ -55,7 +55,8 @@ "app.components.PluginCard.price.free": "Free", "app.components.PluginCard.more-details": "More details", - "app.utils.placeholder.defaultMessage": " ", + "app.utils.placeholder.defaultMessage": "\u0020", + "app.utils.SelectOption.defaultMessage": "\u0020", "components.AutoReloadBlocker.header": "Reload feature is required for this plugin.", "components.AutoReloadBlocker.description": "Open the following file and enable the feature.", diff --git a/packages/strapi-admin/admin/src/translations/fr.json b/packages/strapi-admin/admin/src/translations/fr.json index 3ad0b981c2..6a876aa37f 100755 --- a/packages/strapi-admin/admin/src/translations/fr.json +++ b/packages/strapi-admin/admin/src/translations/fr.json @@ -55,7 +55,8 @@ "app.components.PluginCard.price.free": "Gratuit", "app.components.PluginCard.more-details": "Plus de détails", - "app.utils.placeholder.defaultMessage": " ", + "app.utils.placeholder.defaultMessage": "\u0020", + "app.utils.SelectOption.defaultMessage": "\u0020", "components.AutoReloadBlocker.header": "L'autoReload doit être activé pour ce plugin.", "components.AutoReloadBlocker.description": "Ouvrez le fichier suivant pour activer cette fonctionnalité.", diff --git a/packages/strapi-helper-plugin/lib/src/components/InputSelect/index.js b/packages/strapi-helper-plugin/lib/src/components/InputSelect/index.js new file mode 100644 index 0000000000..13d6ddabee --- /dev/null +++ b/packages/strapi-helper-plugin/lib/src/components/InputSelect/index.js @@ -0,0 +1,77 @@ +/** + * + * InputSelect + * + */ + +import React from 'react'; +import PropTypes from 'prop-types'; +import { isEmpty, map } from 'lodash'; +import cn from 'classnames'; + +// Design +import SelectOption from 'components/SelectOption'; + +import styles from './styles.scss'; + +function InputSelect(props) { + return ( + + ); +} + +InputSelect.defaultProps = { + autoFocus: false, + className: '', + deactivateErrorHighlight: false, + disabled: false, + error: false, + onBlur: () => {}, + onFocus: () => {}, + style: {}, + tabIndex: '0', +}; + +InputSelect.propTypes = { + 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, + selectOptions: PropTypes.arrayOf( + PropTypes.shape({ + id: PropTypes.string, + name: PropTypes.string, + params: PropTypes.object, + value: PropTypes.string.isRequired, + }).isRequired, + ).isRequired, + style: PropTypes.object, + tabIndex: PropTypes.string, + value: PropTypes.string.isRequired, +}; + +export default InputSelect; diff --git a/packages/strapi-helper-plugin/lib/src/components/InputSelect/styles.scss b/packages/strapi-helper-plugin/lib/src/components/InputSelect/styles.scss new file mode 100644 index 0000000000..35ecefc655 --- /dev/null +++ b/packages/strapi-helper-plugin/lib/src/components/InputSelect/styles.scss @@ -0,0 +1,17 @@ +.inputSelect { + height: 3.4rem !important; + margin-top: .9rem; + padding-top: 0rem; + padding-left: 1rem; + background-position: right -1px center; + background-repeat: no-repeat; + background-image: url('../../assets/images/background_input.svg'); + border: 1px solid #E3E9F3; + border-radius: 0.25rem; + line-height: 3.2rem; + font-size: 1.3rem; + font-family: 'Lato' !important; + -moz-appearance: none; + -webkit-appearance: none; + box-shadow: 0px 1px 1px rgba(104, 118, 142, 0.05); +} diff --git a/packages/strapi-helper-plugin/lib/src/components/InputSelectWithErrors/index.js b/packages/strapi-helper-plugin/lib/src/components/InputSelectWithErrors/index.js new file mode 100644 index 0000000000..32a8948157 --- /dev/null +++ b/packages/strapi-helper-plugin/lib/src/components/InputSelectWithErrors/index.js @@ -0,0 +1,186 @@ +/** + * + * InputSelectWithErrors; + * + */ + +import React from 'react'; +import PropTypes from 'prop-types'; +import { includes, isEmpty, isFunction, mapKeys, reject } from 'lodash'; +import cn from 'classnames'; + +// Design +import Label from 'components/Label'; +import InputDescription from 'components/InputDescription'; +import InputErrors from 'components/InputErrors'; +import InputSelect from 'components/InputSelect' + +import styles from './styles.scss'; + +class InputSelectWithErrors extends React.Component { + state = { errors: [] }; + + componentDidMount() { + const { errors } = this.props; + // Display input error if it already has some + if (!isEmpty(errors)) { + this.setState({ errors }); + } + } + + componentWillReceiveProps(nextProps) { + // Check if errors have been updated during validations + if (nextProps.didCheckErrors !== this.props.didCheckErrors) { + // Remove from the state the errors that have already been set + const errors = isEmpty(nextProps.errors) ? [] : nextProps.errors; + this.setState({ errors }); + } + } + + render() { + const { + autoFocus, + className, + customBootstrapClass, + deactivateErrorHighlight, + disabled, + errors, + errorsClassName, + errorsStyle, + inputClassName, + inputDescription, + inputDescriptionClassName, + inputDescriptionStyle, + inputStyle, + label, + labelClassName, + labelStyle, + name, + onBlur, + onChange, + onFocus, + selectOptions, + style, + tabIndex, + value, + } = this.props; + + return ( +
+
+ ); + } +} + +InputSelectWithErrors.defaultProps = { + autoFocus: false, + className: '', + customBootstrapClass: 'col-md-6', + deactivateErrorHighlight: false, + didCheckErrors: false, + disabled: false, + errors: [], + errorsClassName: '', + errorsStyle: {}, + inputClassName: '', + inputDescription: '', + inputDescriptionClassName: '', + inputDescriptionStyle: {}, + inputStyle: {}, + label: '', + labelClassName: '', + labelStyle: {}, + onBlur: () => {}, + onFocus: () => {}, + selectOptions: [], + style: {}, + tabIndex: '0', +}; + +InputSelectWithErrors.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, + onBlur: PropTypes.func, + onChange: PropTypes.func.isRequired, + onFocus: PropTypes.func, + selectOptions: PropTypes.arrayOf( + PropTypes.shape({ + id: PropTypes.string, + name: PropTypes.string, + params: PropTypes.object, + value: PropTypes.string.isRequired, + }).isRequired, + ), + style: PropTypes.object, + tabIndex: PropTypes.string, + value: PropTypes.string.isRequired, +}; + +export default InputSelectWithErrors; diff --git a/packages/strapi-helper-plugin/lib/src/components/InputSelectWithErrors/styles.scss b/packages/strapi-helper-plugin/lib/src/components/InputSelectWithErrors/styles.scss new file mode 100644 index 0000000000..5d8578e7d5 --- /dev/null +++ b/packages/strapi-helper-plugin/lib/src/components/InputSelectWithErrors/styles.scss @@ -0,0 +1,5 @@ +.container { + min-width: 200px; + margin-bottom: 1.5rem; + font-size: 1.3rem; +} diff --git a/packages/strapi-helper-plugin/lib/src/components/InputsIndex/index.js b/packages/strapi-helper-plugin/lib/src/components/InputsIndex/index.js index 45b69deb8e..0aac476b2b 100644 --- a/packages/strapi-helper-plugin/lib/src/components/InputsIndex/index.js +++ b/packages/strapi-helper-plugin/lib/src/components/InputsIndex/index.js @@ -8,6 +8,7 @@ import PropTypes from 'prop-types'; // Design import InputNumberWithErrors from 'components/InputNumberWithErrors'; +import InputSelectWithErrors from 'components/InputSelectWithErrors'; import InputTextAreaWithErrors from 'components/InputTextAreaWithErrors'; import InputTextWithErrors from 'components/InputTextWithErrors'; import InputToggleWithErrors from 'components/InputToggleWithErrors'; @@ -16,6 +17,7 @@ const DefaultInputError = ({ type }) =>
Your input type: {type} does const inputs = { number: InputNumberWithErrors, + select: InputSelectWithErrors, string: InputTextWithErrors, text: InputTextWithErrors, textarea: InputTextAreaWithErrors, @@ -35,6 +37,7 @@ InputsIndex.propTypes = { export default InputsIndex; export { InputNumberWithErrors, + InputSelectWithErrors, InputTextWithErrors, InputTextAreaWithErrors, InputToggleWithErrors, diff --git a/packages/strapi-helper-plugin/lib/src/components/SelectOption/index.js b/packages/strapi-helper-plugin/lib/src/components/SelectOption/index.js new file mode 100644 index 0000000000..b57f9158b8 --- /dev/null +++ b/packages/strapi-helper-plugin/lib/src/components/SelectOption/index.js @@ -0,0 +1,49 @@ +/** + * + * SelectOption + * + */ + +import React from 'react'; +import { FormattedMessage } from 'react-intl'; +import { isEmpty } from 'lodash'; +import PropTypes from 'prop-types'; + +function SelectOption({ id, name, params, value }) { + const messageId = generateMessageId(id, name, value); + + return ( + + {(message) => } + + ); +} + +function generateMessageId(id, name, value) { + if (!isEmpty(id)) { + return id; + } + + if (!isEmpty(name)) { + return name; + } + + // NOTE: Some plugins uses name to set i18n + return value; +} + +SelectOption.defaultProps = { + id: '', + name: '', + params: {}, + value: 'app.utils.SelectOption.defaultMessage' +}; + +SelectOption.propTypes = { + id: PropTypes.string, + name: PropTypes.string, + params: PropTypes.object, + value: PropTypes.string, +}; + +export default SelectOption; From 1b8f9747f2c465bf7d76cd41783b2733b796260b Mon Sep 17 00:00:00 2001 From: cyril lopez Date: Mon, 5 Feb 2018 17:16:15 +0100 Subject: [PATCH 4/8] CreatedInputEmailWithErrors and associated documentation Reorganize Inputs*WithErrors props and add noErrorsDescription prop so it can set a spacer in order to keep the input s alignment correct --- .../en/plugin-development/ui-components.md | 17 +- .../lib/src/components/InputEmail/index.js | 108 ++++++++ .../lib/src/components/InputEmail/styles.scss | 71 +++++ .../components/InputEmailWithErrors/index.js | 257 ++++++++++++++++++ .../InputEmailWithErrors/styles.scss | 9 + .../components/InputNumberWithErrors/index.js | 27 +- .../InputNumberWithErrors/styles.scss | 4 + .../InputTextAreaWithErrors/index.js | 33 ++- .../components/InputTextWithErrors/index.js | 27 +- .../InputTextWithErrors/styles.scss | 4 + .../components/InputToggleWithErrors/index.js | 12 +- .../InputToggleWithErrors/styles.scss | 4 + .../lib/src/components/InputsIndex/index.js | 3 + 13 files changed, 553 insertions(+), 23 deletions(-) create mode 100644 packages/strapi-helper-plugin/lib/src/components/InputEmail/index.js create mode 100644 packages/strapi-helper-plugin/lib/src/components/InputEmail/styles.scss create mode 100644 packages/strapi-helper-plugin/lib/src/components/InputEmailWithErrors/index.js create mode 100644 packages/strapi-helper-plugin/lib/src/components/InputEmailWithErrors/styles.scss diff --git a/docs/3.x.x/en/plugin-development/ui-components.md b/docs/3.x.x/en/plugin-development/ui-components.md index 6dd8a9b14a..9c4d0746f6 100644 --- a/docs/3.x.x/en/plugin-development/ui-components.md +++ b/docs/3.x.x/en/plugin-development/ui-components.md @@ -403,6 +403,12 @@ export default Foo; *** +## InputEmail + +Please refer to the [InputText documentation](#InputText); + +*** + ## InputNumber InputNumber component. @@ -487,6 +493,12 @@ Input type: 'toggle' component *** +## InputEmailWithErrors + +Please refer to the [InputTextWithErrors](#InputTextWithErrors) documentation. + +*** + ## InputNumberWithErrors Please refer to the [InputTextWithErrors](#InputTextWithErrors) documentation. @@ -518,6 +530,7 @@ Component integrates Label, InputText, InputDescription and InputErrors. | onChange | func | yes | Handler to modify the input's value | | onFocus | func | no | Function executed when the user enters the input | | name | string | yes | The name of the input | +| noErrorsDescription | bool | no | Remove the input's errors description | | placeholder | string | no | Input's placeholder, works with i18n | | style | object | no | Overrides the container style | | tabIndex | string | no | Input's tabIndex | @@ -618,8 +631,9 @@ Component integrates Label, InputToggle, InputDescription and InputErrors. | label | string or func or object | no sets the input's label | | labelClassName | string | no | Overrides the Label's className | | labelStyle | object | no | Overrides the Label's style | -| onChange | func | yes | Handler to modify the input's value | | name | string | yes | The name of the input | +| noErrorsDescription | bool | no | Remove the input's errors description | +| onChange | func | yes | Handler to modify the input's value | | style | object | no | Overrides the container style | | tabIndex | string | no | Input's tabIndex | | validations | object | no | Input's validations | @@ -656,6 +670,7 @@ Component integrates Label, InputTextArea, InputDescription and InputErrors. | onChange | func | yes | Handler to modify the input's value | | onFocus | func | no | Function executed when the user enters the input | | name | string | yes | The name of the input | +| noErrorsDescription | bool | no | Remove the input's errors description | | placeholder | string | no | Input's placeholder, works with i18n | | style | object | no | Overrides the container style | | tabIndex | string | no | Input's tabIndex | diff --git a/packages/strapi-helper-plugin/lib/src/components/InputEmail/index.js b/packages/strapi-helper-plugin/lib/src/components/InputEmail/index.js new file mode 100644 index 0000000000..ce157a0aab --- /dev/null +++ b/packages/strapi-helper-plugin/lib/src/components/InputEmail/index.js @@ -0,0 +1,108 @@ +/** + * + * InputEmail + */ + +import React from 'react'; +import PropTypes from 'prop-types'; +import { isEmpty } from 'lodash'; +import { FormattedMessage } from 'react-intl'; +import cn from 'classnames'; + +import styles from './styles.scss'; + +class InputEmail extends React.Component { + state = { isFocused: false }; + + handleBlur = (e) => { + this.setState({ isFocused: !this.state.isFocused }); + this.props.onBlur(e); + } + + handleFocus = (e) => { + console.log('ok'); + this.setState({ isFocused: !this.state.isFocused }); + this.props.onFocus(e); + } + + render() { + const { + autoFocus, + className, + deactivateErrorHighlight, + disabled, + error, + name, + onChange, + placeholder, + style, + tabIndex, + value, + } = this.props; + + return ( +
+ + + {(message) => ( + + )} + +
+ ); + } +} + +InputEmail.defaultProps = { + autoFocus: false, + className: '', + deactivateErrorHighlight: false, + disabled: false, + error: false, + onBlur: () => {}, + onFocus: () => {}, + placeholder: 'app.utils.placeholder.defaultMessage', + style: {}, + tabIndex: '0', +}; + +InputEmail.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, +}; + +export default InputEmail; diff --git a/packages/strapi-helper-plugin/lib/src/components/InputEmail/styles.scss b/packages/strapi-helper-plugin/lib/src/components/InputEmail/styles.scss new file mode 100644 index 0000000000..2e2c98315e --- /dev/null +++ b/packages/strapi-helper-plugin/lib/src/components/InputEmail/styles.scss @@ -0,0 +1,71 @@ +.addonEmail { + width: 3.4rem; + height: 3.4rem; + margin-top: .9rem; + padding-left: 0.9rem; + background-color: rgba(16, 22, 34, 0.02); + border: 1px solid #E3E9F3; + border-radius: 0.25rem; + color: rgba(16, 22, 34, 0.5); + line-height: 3.2rem; + font-size: 1.3rem; + font-family: 'Lato'; + font-weight: 600!important; + text-transform: capitalize; + -moz-appearance: none; + -webkit-appearance: none; + -webkit-font-smoothing: antialiased; + &:after { + content: '@'; + display: inline-table; + color: #B3B5B9; + font-size: 16px; + font-weight: 900; + font-family: Lato; + } + + & + input { + border-left: 0px !important; + } +} + +.inputEmail { + min-width: 200px; + margin-bottom: 1rem; + font-size: 1.3rem; + + > input { + height: 3.4rem; + margin-top: .9rem; + padding-left: 1rem; + background-size: 0 !important; + border: 1px solid #E3E9F3; + border-radius: 0.25rem; + line-height: 3.4rem; + font-size: 1.3rem; + font-family: 'Lato' !important; + box-shadow: 0px 1px 1px rgba(104, 118, 142, 0.05); + &:focus { + border-color: #78caff; + } + } + + & + span { + border-color: #E3E9F3; + } +} + +.errorAddon { + border: 1px solid #ff203c!important; + border-right: none!important; +} + +.addonFocus { + border-color: #78caff; + border-right: 0; +} + +.invalidEmail { + border-color: #ff203c !important; + border-left: 0; +} diff --git a/packages/strapi-helper-plugin/lib/src/components/InputEmailWithErrors/index.js b/packages/strapi-helper-plugin/lib/src/components/InputEmailWithErrors/index.js new file mode 100644 index 0000000000..818b2a3908 --- /dev/null +++ b/packages/strapi-helper-plugin/lib/src/components/InputEmailWithErrors/index.js @@ -0,0 +1,257 @@ +/** + * + * InputEmailWithErrors + * + */ + +import React from 'react'; +import PropTypes from 'prop-types'; +import { includes, isEmpty, isFunction, mapKeys, reject } from 'lodash'; +import cn from 'classnames'; + +// Design +import Label from 'components/Label'; +import InputDescription from 'components/InputDescription'; +import InputErrors from 'components/InputErrors'; +import InputEmail from 'components/InputEmail'; + +import styles from './styles.scss'; + +class InputEmailWithErrors 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 (value && !isEmpty(value)) { + this.setState({ hasInitialValue: true }); + } + + // Display input error if it already has some + if (!isEmpty(errors)) { + this.setState({ errors }); + } + } + + componentWillReceiveProps(nextProps) { + // Check if errors have been updated during validations + if (nextProps.didCheckErrors !== this.props.didCheckErrors) { + // Remove from the state the errors that have already been set + const errors = isEmpty(nextProps.errors) ? [] : nextProps.errors; + this.setState({ errors }); + } + } + + /** + * 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 = this.validate(target.value); + this.setState({ errors, hasInitialValue: true }); + } + } + + render() { + const { + autoFocus, + deactivateErrorHighlight, + disabled, + errorsClassName, + errorsStyle, + inputClassName, + inputDescription, + inputDescriptionClassName, + inputDescriptionStyle, + inputStyle, + label, + labelClassName, + labelStyle, + name, + noErrorsDescription, + onBlur, + onChange, + onFocus, + placeholder, + style, + tabIndex, + value, + } = this.props; + const handleBlur = isFunction(onBlur) ? onBlur : this.handleBlur; + + let spacer = !isEmpty(inputDescription) ?
:
; + + if (!noErrorsDescription && !isEmpty(this.state.errors)) { + spacer =
; + } + + return ( +
+
+ ); + } + + validate = (value) => { + const emailRegex = new RegExp(/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/); + const requiredError = { id: 'components.Input.error.validation.required' }; + let errors = []; + + mapKeys(this.props.validations, (validationValue, validationKey) => { + switch (validationKey) { + case 'maxLength': { + if (value.length > validationValue) { + errors.push({ id: 'components.Input.error.validation.maxLength' }); + } + break; + } + case 'minLength': { + if (value.length < validationValue) { + errors.push({ id: 'components.Input.error.validation.minLength' }); + } + break; + } + case 'required': { + if (value.length === 0) { + errors.push({ id: 'components.Input.error.validation.required' }); + } + break; + } + case 'regex': { + if (!new RegExp(validationValue).test(value)) { + errors.push({ id: 'components.Input.error.validation.regex' }); + } + break; + } + default: + errors = []; + } + }); + + if (!emailRegex.test(value)) { + errors.push({ id: 'components.Input.error.validation.email' }); + } + + if (includes(errors, requiredError)) { + errors = reject(errors, (error) => error !== requiredError); + } + + return errors; + } +} + +InputEmailWithErrors.defaultProps = { + autoFocus: false, + className: '', + customBootstrapClass: 'col-md-6', + 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: {}, +}; + +InputEmailWithErrors.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, +}; + +export default InputEmailWithErrors; diff --git a/packages/strapi-helper-plugin/lib/src/components/InputEmailWithErrors/styles.scss b/packages/strapi-helper-plugin/lib/src/components/InputEmailWithErrors/styles.scss new file mode 100644 index 0000000000..f94650a966 --- /dev/null +++ b/packages/strapi-helper-plugin/lib/src/components/InputEmailWithErrors/styles.scss @@ -0,0 +1,9 @@ +.container { + min-width: 200px; + margin-bottom: 1.5rem; + font-size: 1.3rem; +} + +.spacer { + height: .5rem; +} diff --git a/packages/strapi-helper-plugin/lib/src/components/InputNumberWithErrors/index.js b/packages/strapi-helper-plugin/lib/src/components/InputNumberWithErrors/index.js index 2fc9c42280..3abc7d999d 100644 --- a/packages/strapi-helper-plugin/lib/src/components/InputNumberWithErrors/index.js +++ b/packages/strapi-helper-plugin/lib/src/components/InputNumberWithErrors/index.js @@ -52,17 +52,23 @@ class InputNumberWithErrors extends React.Component { // eslint-disable-line rea render() { const { autoFocus, + className, + customBootstrapClass, deactivateErrorHighlight, disabled, errorsClassName, errorsStyle, inputClassName, + inputDescription, inputDescriptionClassName, inputDescriptionStyle, inputStyle, + label, labelClassName, labelStyle, name, + noErrorsDescription, + onBlur, onChange, onFocus, placeholder, @@ -70,20 +76,26 @@ class InputNumberWithErrors extends React.Component { // eslint-disable-line rea tabIndex, value, } = this.props; - const handleBlur = isFunction(this.props.onBlur) ? this.props.onBlur : this.handleBlur; + const handleBlur = isFunction(onBlur) ? onBlur : this.handleBlur; + + let spacer = !isEmpty(inputDescription) ?
:
; + + if (!noErrorsDescription && !isEmpty(this.state.errors)) { + spacer =
; + } return (
); } @@ -178,6 +191,7 @@ InputNumberWithErrors.defaultProps = { label: '', labelClassName: '', labelStyle: {}, + noErrorsDescription: false, placeholder: 'app.utils.placeholder.defaultMessage', style: {}, tabIndex: '0', @@ -217,6 +231,7 @@ InputNumberWithErrors.propTypes = { labelClassName: PropTypes.string, labelStyle: PropTypes.object, name: PropTypes.string.isRequired, + noErrorsDescription: PropTypes.bool, onBlur: PropTypes.oneOfType([ PropTypes.bool, PropTypes.func, diff --git a/packages/strapi-helper-plugin/lib/src/components/InputNumberWithErrors/styles.scss b/packages/strapi-helper-plugin/lib/src/components/InputNumberWithErrors/styles.scss index 5d8578e7d5..f94650a966 100644 --- a/packages/strapi-helper-plugin/lib/src/components/InputNumberWithErrors/styles.scss +++ b/packages/strapi-helper-plugin/lib/src/components/InputNumberWithErrors/styles.scss @@ -3,3 +3,7 @@ margin-bottom: 1.5rem; font-size: 1.3rem; } + +.spacer { + height: .5rem; +} diff --git a/packages/strapi-helper-plugin/lib/src/components/InputTextAreaWithErrors/index.js b/packages/strapi-helper-plugin/lib/src/components/InputTextAreaWithErrors/index.js index 99ab883749..c3461c6038 100644 --- a/packages/strapi-helper-plugin/lib/src/components/InputTextAreaWithErrors/index.js +++ b/packages/strapi-helper-plugin/lib/src/components/InputTextAreaWithErrors/index.js @@ -52,17 +52,23 @@ class InputTextAreaWithErrors extends React.Component { // eslint-disable-line r render() { const { autoFocus, + className, + customBootstrapClass, deactivateErrorHighlight, disabled, errorsClassName, errorsStyle, inputClassName, + inputDescription, inputDescriptionClassName, inputDescriptionStyle, inputStyle, + label, labelClassName, labelStyle, name, + noErrorsDescription, + onBlur, onChange, onFocus, placeholder, @@ -70,23 +76,29 @@ class InputTextAreaWithErrors extends React.Component { // eslint-disable-line r tabIndex, value, } = this.props; - const handleBlur = isFunction(this.props.onBlur) ? this.props.onBlur : this.handleBlur; + const handleBlur = isFunction(onBlur) ? onBlur : this.handleBlur; + + let spacer = !isEmpty(inputDescription) ?
:
; + + if (!noErrorsDescription && !isEmpty(this.state.errors)) { + spacer =
; + } return (
); } @@ -165,8 +178,6 @@ InputTextAreaWithErrors.defaultProps = { deactivateErrorHighlight: false, didCheckErrors: false, disabled: false, - onBlur: false, - onFocus: () => {}, errors: [], errorsClassName: '', errorsStyle: {}, @@ -178,6 +189,9 @@ InputTextAreaWithErrors.defaultProps = { label: '', labelClassName: '', labelStyle: {}, + noErrorsDescription: false, + onBlur: false, + onFocus: () => {}, placeholder: 'app.utils.placeholder.defaultMessage', style: {}, tabIndex: '0', @@ -217,6 +231,7 @@ InputTextAreaWithErrors.propTypes = { labelClassName: PropTypes.string, labelStyle: PropTypes.object, name: PropTypes.string.isRequired, + noErrorsDescription: PropTypes.bool, onBlur: PropTypes.oneOfType([ PropTypes.bool, PropTypes.func, diff --git a/packages/strapi-helper-plugin/lib/src/components/InputTextWithErrors/index.js b/packages/strapi-helper-plugin/lib/src/components/InputTextWithErrors/index.js index e9a5a7bb10..0724d3d313 100644 --- a/packages/strapi-helper-plugin/lib/src/components/InputTextWithErrors/index.js +++ b/packages/strapi-helper-plugin/lib/src/components/InputTextWithErrors/index.js @@ -52,17 +52,23 @@ class InputTextWithErrors extends React.Component { // eslint-disable-line react render() { const { autoFocus, + className, + customBootstrapClass, deactivateErrorHighlight, disabled, errorsClassName, errorsStyle, inputClassName, + inputDescription, inputDescriptionClassName, inputDescriptionStyle, inputStyle, + label, labelClassName, labelStyle, name, + noErrorsDescription, + onBlur, onChange, onFocus, placeholder, @@ -70,20 +76,26 @@ class InputTextWithErrors extends React.Component { // eslint-disable-line react tabIndex, value, } = this.props; - const handleBlur = isFunction(this.props.onBlur) ? this.props.onBlur : this.handleBlur; + const handleBlur = isFunction(onBlur) ? onBlur : this.handleBlur; + + let spacer = !isEmpty(inputDescription) ?
:
; + + if (!noErrorsDescription && !isEmpty(this.state.errors)) { + spacer =
; + } return (
); } @@ -178,6 +191,7 @@ InputTextWithErrors.defaultProps = { label: '', labelClassName: '', labelStyle: {}, + noErrorsDescription: false, placeholder: 'app.utils.placeholder.defaultMessage', style: {}, tabIndex: '0', @@ -217,6 +231,7 @@ InputTextWithErrors.propTypes = { labelClassName: PropTypes.string, labelStyle: PropTypes.object, name: PropTypes.string.isRequired, + noErrorsDescription: PropTypes.bool, onBlur: PropTypes.oneOfType([ PropTypes.bool, PropTypes.func, diff --git a/packages/strapi-helper-plugin/lib/src/components/InputTextWithErrors/styles.scss b/packages/strapi-helper-plugin/lib/src/components/InputTextWithErrors/styles.scss index 5d8578e7d5..f94650a966 100644 --- a/packages/strapi-helper-plugin/lib/src/components/InputTextWithErrors/styles.scss +++ b/packages/strapi-helper-plugin/lib/src/components/InputTextWithErrors/styles.scss @@ -3,3 +3,7 @@ margin-bottom: 1.5rem; font-size: 1.3rem; } + +.spacer { + height: .5rem; +} diff --git a/packages/strapi-helper-plugin/lib/src/components/InputToggleWithErrors/index.js b/packages/strapi-helper-plugin/lib/src/components/InputToggleWithErrors/index.js index 3f5d437ba8..ef05c133ee 100644 --- a/packages/strapi-helper-plugin/lib/src/components/InputToggleWithErrors/index.js +++ b/packages/strapi-helper-plugin/lib/src/components/InputToggleWithErrors/index.js @@ -54,12 +54,19 @@ class InputToggleWithErrors extends React.Component { labelClassName, labelStyle, name, + noErrorsDescription, onChange, style, tabIndex, value, } = this.props; + let spacer = !isEmpty(inputDescription) ?
:
; + + if (!noErrorsDescription && !isEmpty(this.state.errors)) { + spacer =
; + } + return (
+ {spacer}
); } @@ -121,6 +129,7 @@ InputToggleWithErrors.defaultProps = { label: '', labelClassName: '', labelStyle: {}, + noErrorsDescription: false, style: {}, tabIndex: '0', value: true, @@ -161,6 +170,7 @@ InputToggleWithErrors.propTypes = { labelClassName: PropTypes.string, labelStyle: PropTypes.object, name: PropTypes.string.isRequired, + noErrorsDescription: PropTypes.bool, onChange: PropTypes.func.isRequired, style: PropTypes.object, tabIndex: PropTypes.string, diff --git a/packages/strapi-helper-plugin/lib/src/components/InputToggleWithErrors/styles.scss b/packages/strapi-helper-plugin/lib/src/components/InputToggleWithErrors/styles.scss index 0d108c48ce..da7136b777 100644 --- a/packages/strapi-helper-plugin/lib/src/components/InputToggleWithErrors/styles.scss +++ b/packages/strapi-helper-plugin/lib/src/components/InputToggleWithErrors/styles.scss @@ -7,3 +7,7 @@ margin-bottom: 0 !important; font-weight: 500 !important; } + +.spacer { + height: .5rem; +} diff --git a/packages/strapi-helper-plugin/lib/src/components/InputsIndex/index.js b/packages/strapi-helper-plugin/lib/src/components/InputsIndex/index.js index 45b69deb8e..d35f8fb451 100644 --- a/packages/strapi-helper-plugin/lib/src/components/InputsIndex/index.js +++ b/packages/strapi-helper-plugin/lib/src/components/InputsIndex/index.js @@ -7,6 +7,7 @@ import React from 'react'; import PropTypes from 'prop-types'; // Design +import InputEmailWithErrors from 'components/InputEmailWithErrors'; import InputNumberWithErrors from 'components/InputNumberWithErrors'; import InputTextAreaWithErrors from 'components/InputTextAreaWithErrors'; import InputTextWithErrors from 'components/InputTextWithErrors'; @@ -15,6 +16,7 @@ import InputToggleWithErrors from 'components/InputToggleWithErrors'; const DefaultInputError = ({ type }) =>
Your input type: {type} does not exist
const inputs = { + email: InputEmailWithErrors, number: InputNumberWithErrors, string: InputTextWithErrors, text: InputTextWithErrors, @@ -34,6 +36,7 @@ InputsIndex.propTypes = { export default InputsIndex; export { + InputEmailWithErrors, InputNumberWithErrors, InputTextWithErrors, InputTextAreaWithErrors, From cc4166e683cb7c336f5f0d4d768464dc1418e79d Mon Sep 17 00:00:00 2001 From: cyril lopez Date: Mon, 5 Feb 2018 17:24:15 +0100 Subject: [PATCH 5/8] Add new input in users-permissions plugin Advanced settings --- .../admin/src/components/EditForm/index.js | 12 +++++------- .../config/advanced.json | 2 +- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/packages/strapi-plugin-users-permissions/admin/src/components/EditForm/index.js b/packages/strapi-plugin-users-permissions/admin/src/components/EditForm/index.js index ad6cebfb8e..5e7be0e294 100644 --- a/packages/strapi-plugin-users-permissions/admin/src/components/EditForm/index.js +++ b/packages/strapi-plugin-users-permissions/admin/src/components/EditForm/index.js @@ -8,7 +8,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { get } from 'lodash'; -import Input from 'components/Input'; +import Input from 'components/InputsIndex'; import styles from './styles.scss'; @@ -18,13 +18,12 @@ class EditForm extends React.Component { // eslint-disable-line react/prefer-sta
@@ -56,13 +55,12 @@ class EditForm extends React.Component { // eslint-disable-line react/prefer-sta */}
diff --git a/packages/strapi-plugin-users-permissions/config/advanced.json b/packages/strapi-plugin-users-permissions/config/advanced.json index 0979d94ffe..0cb4fbe9a9 100644 --- a/packages/strapi-plugin-users-permissions/config/advanced.json +++ b/packages/strapi-plugin-users-permissions/config/advanced.json @@ -3,4 +3,4 @@ "unique_email": true, "allow_register": true } -} \ No newline at end of file +} From c9281f0c38bf4a0430a440821e846e8fd569ae01 Mon Sep 17 00:00:00 2001 From: cyril lopez Date: Mon, 5 Feb 2018 17:41:49 +0100 Subject: [PATCH 6/8] Add new input lib in PopUpForm compon in users plugin --- .../lib/src/components/InputEmail/index.js | 1 - .../admin/src/components/PopUpForm/index.js | 29 +++++++++++++------ .../admin/src/translations/en.json | 2 +- .../admin/src/translations/fr.json | 2 +- 4 files changed, 22 insertions(+), 12 deletions(-) diff --git a/packages/strapi-helper-plugin/lib/src/components/InputEmail/index.js b/packages/strapi-helper-plugin/lib/src/components/InputEmail/index.js index ce157a0aab..f830409c09 100644 --- a/packages/strapi-helper-plugin/lib/src/components/InputEmail/index.js +++ b/packages/strapi-helper-plugin/lib/src/components/InputEmail/index.js @@ -20,7 +20,6 @@ class InputEmail extends React.Component { } handleFocus = (e) => { - console.log('ok'); this.setState({ isFocused: !this.state.isFocused }); this.props.onFocus(e); } diff --git a/packages/strapi-plugin-users-permissions/admin/src/components/PopUpForm/index.js b/packages/strapi-plugin-users-permissions/admin/src/components/PopUpForm/index.js index f0a277e6e9..8b3ebba020 100644 --- a/packages/strapi-plugin-users-permissions/admin/src/components/PopUpForm/index.js +++ b/packages/strapi-plugin-users-permissions/admin/src/components/PopUpForm/index.js @@ -26,7 +26,7 @@ import { // Translations import en from 'translations/en.json'; -import Input from 'components/Input'; +import Input from 'components/InputsIndex'; import styles from './styles.scss'; @@ -102,8 +102,8 @@ class PopUpForm extends React.Component { // eslint-disable-line react/prefer-st return (
{}} onBlur={includes(value, 'callback') || includes(value, 'redirect_uri') ? this.handleBlur : false} @@ -134,7 +134,7 @@ class PopUpForm extends React.Component { // eslint-disable-line react/prefer-st {}} @@ -146,6 +146,14 @@ class PopUpForm extends React.Component { // eslint-disable-line react/prefer-st ); } + const params = { + link: ( + + + + ), + }; + return (
{map(take(form, 3), (value, key) => ( @@ -154,7 +162,7 @@ class PopUpForm extends React.Component { // eslint-disable-line react/prefer-st key={value} didCheckErrors={this.props.didCheckErrors} errors={get(this.props.formErrors, [findIndex(this.props.formErrors, ['name', value]), 'errors'], [])} - label={`users-permissions.PopUpForm.Email.${value}.label`} + label={{ id: `users-permissions.PopUpForm.Email.${value}.label` }} name={`${dataToEdit}.${value}`} onChange={this.props.onChange} placeholder={`users-permissions.PopUpForm.Email.${value}.placeholder`} @@ -170,15 +178,18 @@ class PopUpForm extends React.Component { // eslint-disable-line react/prefer-st customBootstrapClass="col-md-12" didCheckErrors={this.props.didCheckErrors} errors={get(this.props.formErrors, [findIndex(this.props.formErrors, ['name', value]), 'errors'], [])} - label={`users-permissions.PopUpForm.Email.${value}.label`} + label={{ id: `users-permissions.PopUpForm.Email.${value}.label` }} name={`${dataToEdit}.${value}`} - inputDescription={includes(value, 'object') ? 'users-permissions.PopUpForm.Email.email_templates.inputDescription' : ''} - linkContent={includes(value, 'object') ? { link: 'https://github.com/strapi/strapi/blob/master/packages/strapi-plugin-users-permissions/docs/email-templates.md', description: 'users-permissions.PopUpForm.Email.link.documentation' } : {}} + inputDescription={{ + id: includes(value, 'object') ? 'users-permissions.PopUpForm.Email.email_templates.inputDescription' : '', + params, + }} onChange={this.props.onChange} placeholder={`users-permissions.PopUpForm.Email.${this.props.dataToEdit}.${value}.placeholder`} type={includes(value, 'object') ? 'text' : 'textarea'} validations={{ required: true }} value={get(values, value)} + inputStyle={!includes(value, 'object') ? { height: '16rem' } : {}} /> ))}
diff --git a/packages/strapi-plugin-users-permissions/admin/src/translations/en.json b/packages/strapi-plugin-users-permissions/admin/src/translations/en.json index 52c5bf09b2..26fd5b45e1 100755 --- a/packages/strapi-plugin-users-permissions/admin/src/translations/en.json +++ b/packages/strapi-plugin-users-permissions/admin/src/translations/en.json @@ -168,6 +168,6 @@ "PopUpForm.Providers.twitter.providerConfig.redirectURL": "The redirect URL to add in your Twitter application configurations", "PopUpForm.Providers.callback.placeholder": "TEXT", - "PopUpForm.Email.email_templates.inputDescription": "Don't know how to set variables", + "PopUpForm.Email.email_templates.inputDescription": "Don't know how to set variables, {link}", "PopUpForm.Email.link.documentation": "check out our documentation." } diff --git a/packages/strapi-plugin-users-permissions/admin/src/translations/fr.json b/packages/strapi-plugin-users-permissions/admin/src/translations/fr.json index 64b9166782..26eb1e462b 100755 --- a/packages/strapi-plugin-users-permissions/admin/src/translations/fr.json +++ b/packages/strapi-plugin-users-permissions/admin/src/translations/fr.json @@ -167,6 +167,6 @@ "PopUpForm.Providers.twitter.providerConfig.redirectURL": "L'URL de redirection à ajouter dans les configurations Twitter de votre application", "PopUpForm.Providers.callback.placeholder": "TEXT", - "PopUpForm.Email.email_templates.inputDescription": "Regardez la documentation des variables", + "PopUpForm.Email.email_templates.inputDescription": "Regardez la documentation des variables, {link}", "PopUpForm.Email.link.documentation": "afin de templeter vos emails" } From 98bdac602d625769522ab44eb8209bb6b63ebadd Mon Sep 17 00:00:00 2001 From: cyril lopez Date: Tue, 6 Feb 2018 12:02:37 +0100 Subject: [PATCH 7/8] Remove logs and fix indent --- .../strapi-helper-plugin/lib/src/components/InputEmail/index.js | 1 - .../lib/src/components/InputEmailWithErrors/index.js | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/strapi-helper-plugin/lib/src/components/InputEmail/index.js b/packages/strapi-helper-plugin/lib/src/components/InputEmail/index.js index ce157a0aab..f830409c09 100644 --- a/packages/strapi-helper-plugin/lib/src/components/InputEmail/index.js +++ b/packages/strapi-helper-plugin/lib/src/components/InputEmail/index.js @@ -20,7 +20,6 @@ class InputEmail extends React.Component { } handleFocus = (e) => { - console.log('ok'); this.setState({ isFocused: !this.state.isFocused }); this.props.onFocus(e); } diff --git a/packages/strapi-helper-plugin/lib/src/components/InputEmailWithErrors/index.js b/packages/strapi-helper-plugin/lib/src/components/InputEmailWithErrors/index.js index 818b2a3908..35ba1deb9e 100644 --- a/packages/strapi-helper-plugin/lib/src/components/InputEmailWithErrors/index.js +++ b/packages/strapi-helper-plugin/lib/src/components/InputEmailWithErrors/index.js @@ -102,7 +102,7 @@ class InputEmailWithErrors extends React.Component { // eslint-disable-line reac message={label} style={labelStyle} /> - Date: Tue, 6 Feb 2018 14:28:12 +0100 Subject: [PATCH 8/8] fix #318 --- packages/strapi-admin/admin/.gitignore | 1 + .../files/config/environments/development/server.json | 2 +- .../files/config/environments/production/database.json | 2 +- .../files/config/environments/production/server.json | 2 +- .../files/config/environments/test/database.json | 2 +- .../files/config/environments/test/server.json | 2 +- packages/strapi-generate-new/lib/before.js | 2 +- 7 files changed, 7 insertions(+), 6 deletions(-) diff --git a/packages/strapi-admin/admin/.gitignore b/packages/strapi-admin/admin/.gitignore index e7039d8a78..ad2318a4a0 100644 --- a/packages/strapi-admin/admin/.gitignore +++ b/packages/strapi-admin/admin/.gitignore @@ -1,6 +1,7 @@ # Don't check auto-generated stuff into git coverage node_modules +manifest.json plugins.json stats.json package-lock.json diff --git a/packages/strapi-generate-new/files/config/environments/development/server.json b/packages/strapi-generate-new/files/config/environments/development/server.json index 2c9235833f..d891a7547c 100755 --- a/packages/strapi-generate-new/files/config/environments/development/server.json +++ b/packages/strapi-generate-new/files/config/environments/development/server.json @@ -1,5 +1,5 @@ { - "host": "localhost", + "host": "127.0.0.1", "port": 1337, "autoReload": { "enabled": true diff --git a/packages/strapi-generate-new/files/config/environments/production/database.json b/packages/strapi-generate-new/files/config/environments/production/database.json index 6b283d6ebd..5197ec20a4 100755 --- a/packages/strapi-generate-new/files/config/environments/production/database.json +++ b/packages/strapi-generate-new/files/config/environments/production/database.json @@ -5,7 +5,7 @@ "connector": "strapi-mongoose", "settings": { "client": "mongo", - "host": "${process.env.DATABASE_HOST || 'localhost'}", + "host": "${process.env.DATABASE_HOST || '127.0.0.1'}", "port": "${process.env.DATABASE_PORT || 27017}", "database": "${process.env.DATABASE_NAME || 'production'}", "username": "${process.env.DATABASE_USERNAME || ''}", diff --git a/packages/strapi-generate-new/files/config/environments/production/server.json b/packages/strapi-generate-new/files/config/environments/production/server.json index fd731f3c21..6a78348d7e 100755 --- a/packages/strapi-generate-new/files/config/environments/production/server.json +++ b/packages/strapi-generate-new/files/config/environments/production/server.json @@ -1,5 +1,5 @@ { - "host": "localhost", + "host": "127.0.0.1", "port": 1337, "autoReload": { "enabled": false diff --git a/packages/strapi-generate-new/files/config/environments/test/database.json b/packages/strapi-generate-new/files/config/environments/test/database.json index 74443c1c1a..9241d26dbe 100755 --- a/packages/strapi-generate-new/files/config/environments/test/database.json +++ b/packages/strapi-generate-new/files/config/environments/test/database.json @@ -5,7 +5,7 @@ "connector": "strapi-mongoose", "settings": { "client": "mongo", - "host": "localhost", + "host": "127.0.0.1", "port": 27017, "database": "test", "username": "", diff --git a/packages/strapi-generate-new/files/config/environments/test/server.json b/packages/strapi-generate-new/files/config/environments/test/server.json index 2c9235833f..d891a7547c 100755 --- a/packages/strapi-generate-new/files/config/environments/test/server.json +++ b/packages/strapi-generate-new/files/config/environments/test/server.json @@ -1,5 +1,5 @@ { - "host": "localhost", + "host": "127.0.0.1", "port": 1337, "autoReload": { "enabled": true diff --git a/packages/strapi-generate-new/lib/before.js b/packages/strapi-generate-new/lib/before.js index 9989091348..c0297c8e66 100755 --- a/packages/strapi-generate-new/lib/before.js +++ b/packages/strapi-generate-new/lib/before.js @@ -136,7 +136,7 @@ module.exports = (scope, cb) => { prefix: '', name: 'host', message: 'Host:', - default: _.get(scope.database, 'host', 'localhost') + default: _.get(scope.database, 'host', '127.0.0.1') }, { type: 'input',