Created InputDescription component and associated doc

This commit is contained in:
cyril lopez 2018-02-01 15:32:07 +01:00
parent d212c7aba0
commit e5f74a7022
5 changed files with 181 additions and 4 deletions

View File

@ -326,6 +326,101 @@ class FooPage extends React.Component {
export default FooPage;
```
***
## InputDescription
Component that allows to put a description under an input, it works with or without i18n
| Property | Type | Required | Description |
| -------- | ---- | -------- | ----------- |
| children | node | no | Anything that is wrapped inside the Description |
| className | string | no | custom className for the Description |
| message | func or string or object | no | Define the content of the Description |
| style | object | no | Label style property |
### Usage
**Path -** `my-plugin/admin/src/translations.en.json`.
```json
{
"Email.inputDescription": "Don't know how to set variables, {documentationLink}",
"Tel.inputDescription": "Make sure to provide a phone number where you can be reached"
}
```
**Path -** `my-plugin/admin/src/components/Foo/index.js`;
```js
import React from 'react';
import InputText from 'components/InputText';
import InputDescription from 'components/InputDescription';
import styles from './styles.scss';
function Foo({ onChange, value }) {
return (
<div className={`col-md-6 ${styles.inputContainer}`}>
<InputText name="tel" value={value} onChange={onChange} />
{/* Usage without i18n, custom className and style */}
<InputDescription
className={styles.inputDescription}
message="Make sure to provide a phone number where you can be reached"
style={{ paddingTop: '10px'}}
/>
{/* Usage with function */}
<InputText name="email" value={value} onChange={onChange} />
<InputDescription
message={ () => <span>Don&#44;t know how to set variables, <a href="strapi.io" target="_blank">check out our doc!</a></span>}
/>
{/* Usage with i18n and rich text formatting */}
<InputText name="email" value={value} onChange={onChange} />
<InputDescription
message={{
id: 'my-plugin.Email.inputDescription',
params: {
documentationLink: <a href="strapi.io" target="_blank">check out our doc!</a>
}
}}
/>
{/* Usage with i18n only */}
<InputText name="tel" value={value} onChange={onChange} />
<InputDescription
message={{ id: 'my-plugin.Tel.inputDescription' }}
/>
</div>
);
}
export default Foo;
```
***
## InputText
InputText 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 |
| style | object | no | Input's style property |
| tabIndex | string | Input's tabIndex |
| value | string | yes | Input's value |
***
## Label
@ -353,6 +448,7 @@ Label component that integrates FormattedMessage if needed
```
**Path -** `my-plugin/admin/src/components/Foo/index.js`;
```js
import React from 'react';
import Label from 'components/Label';

View File

@ -0,0 +1,58 @@
import React from 'react';
import PropTypes from 'prop-types';
import { FormattedMessage } from 'react-intl';
import { isEmpty, isFunction, isObject } from 'lodash';
import cn from 'classnames';
import styles from './styles.scss';
function InputDescription(props) {
let content = props.children;
if (typeof(props.message) === 'string') {
content = props.message;
}
if (isObject(props.message) && props.message.id) {
content = <FormattedMessage id={props.message.id} defaultMessage={props.message.id} values={props.message.params} />;
}
if (isFunction(props.message)) {
content = props.message();
}
return (
<div className={cn(
styles.inputDescriptionContainer,
!isEmpty(props.className) && props.className
)}
style={props.style}
>
<small>
{content}
</small>
</div>
);
}
InputDescription.defaultProps = {
children: '',
className: '',
message: '',
style: {},
};
InputDescription.propTypes = {
children: PropTypes.node,
className: PropTypes.string,
message: PropTypes.oneOfType([
PropTypes.string,
PropTypes.func,
PropTypes.shape({
id: PropTypes.string,
params: PropTypes.object,
}),
]),
style: PropTypes.object,
};
export default InputDescription;

View File

@ -0,0 +1,11 @@
.inputDescriptionContainer {
width: 200%;
margin-top: 1.3rem;
line-height: 1.2rem;
> small {
color: #9EA7B8;
font-family: 'Lato';
font-size: 1.2rem;
}
}

View File

@ -1,10 +1,11 @@
import React from 'react';
import PropTypes from 'prop-types';
import { includes, isEmpty, mapKeys, reject } from 'lodash';
import { includes, isEmpty, isFunction, mapKeys, reject } from 'lodash';
import cn from 'classnames';
// Design
import Label from 'components/Label';
import InputDescription from 'components/InputDescription';
import InputText from 'components/InputText';
import styles from './styles.scss';
@ -48,7 +49,8 @@ class InputTextWithErrors extends React.Component { // eslint-disable-line react
}
render() {
const { autoFocus, inputClassName, name, onChange, placeholder, value } = this.props;
const { autoFocus, inputClassName, name, onChange, onFocus, placeholder, value } = this.props;
const handleBlur = isFunction(this.props.onBlur) ? this.props.onBlur : this.handleBlur;
return (
<div className={cn(
@ -63,11 +65,13 @@ class InputTextWithErrors extends React.Component { // eslint-disable-line react
className={inputClassName}
errors={this.state.errors}
name={name}
onBlur={this.handleBlur}
onBlur={handleBlur}
onChange={onChange}
onFocus={onFocus}
placeholder={placeholder}
value={value}
/>
<InputDescription message={this.props.inputDescription && this.props.inputDescription.message || this.props.inputDescription} />
</div>
);
}
@ -112,6 +116,8 @@ class InputTextWithErrors extends React.Component { // eslint-disable-line react
InputTextWithErrors.defaultProps = {
customBootstrapClass: false,
didCheckErrors: false,
onBlur: false,
onFocus: () => {},
errors: [],
inputClassName: '',
placeholder: 'app.utils.placeholder.defaultMessage',
@ -126,6 +132,12 @@ InputTextWithErrors.propTypes = {
didCheckErrors: PropTypes.bool,
errors: PropTypes.array,
inputClassName: PropTypes.string,
onBlur: PropTypes.oneOfType([
PropTypes.bool,
PropTypes.func,
]),
onChange: PropTypes.func.isRequired,
onFocus: PropTypes.func,
validations: PropTypes.object,
value: PropTypes.string.isRequired
};

View File

@ -14,7 +14,7 @@ function Label(props) {
}
if (isObject(props.message) && props.message.id) {
content = <FormattedMessage id={props.message.id} defaultMessage=" " values={props.message.params} />;
content = <FormattedMessage id={props.message.id} defaultMessage={props.message.id} values={props.message.params} />;
}
if (isFunction(props.message)) {