Merge pull request #228 from sharetribe/textinputfield

TextInputField
This commit is contained in:
Kimmo Puputti 2017-06-20 15:30:27 +03:00 committed by GitHub
commit 3ece68c707
7 changed files with 187 additions and 3 deletions

View file

@ -53,5 +53,5 @@ const ButtonsComponent = () => {
export const Buttons = {
component: ButtonsComponent,
group: 'inputs and buttons',
group: 'buttons',
};

View file

@ -0,0 +1,17 @@
@import '../../marketplace.css';
.root {
}
.input {
border-bottom-color: var(--attentionColor);
}
.inputError {
border-bottom-color: var(--failColor);
}
.inputSuccess {
border-bottom-color: var(--successColor);
}

View file

@ -0,0 +1,7 @@
.field {
margin-top: 24px;
}
.submit {
margin-top: 24px;
}

View file

@ -0,0 +1,79 @@
/* eslint-disable no-console */
import React from 'react';
import { reduxForm, propTypes as formPropTypes } from 'redux-form';
import * as validators from '../../util/validators';
import { Button } from '../../components';
import TextInputField from './TextInputField';
import css from './TextInputField.example.css';
const formName = 'Styleguide.TextInputField.Form';
const FormComponent = props => {
const { handleSubmit, invalid, pristine, submitting } = props;
const required = validators.required('This field is required');
const submitDisabled = invalid || pristine || submitting;
return (
<form onSubmit={handleSubmit}>
<TextInputField
className={css.field}
type="text"
id={`${formName}.input1`}
name="input1"
label="Input that requires a value:"
validate={required}
/>
<TextInputField
className={css.field}
type="text"
id={`${formName}.input2`}
name="input2"
label="Input that does not require a value:"
/>
<TextInputField
className={css.field}
type="text"
name="input3"
placeholder="Input without label..."
/>
<TextInputField
className={css.field}
type="textarea"
id={`${formName}.textarea1`}
name="textarea1"
label="Textarea that requires a value:"
validate={required}
/>
<TextInputField
className={css.field}
type="textarea"
id={`${formName}.textarea2`}
name="textarea2"
label="Textarea that does not require a value:"
/>
<TextInputField
className={css.field}
type="textarea"
name="textarea3"
placeholder="Textarea without label..."
/>
<Button className={css.submit} type="submit" disabled={submitDisabled}>Submit</Button>
</form>
);
};
FormComponent.propTypes = formPropTypes;
const Form = reduxForm({
form: formName,
})(FormComponent);
export const Inputs = {
component: Form,
props: {
onSubmit: values => {
console.log('submit values:', values);
},
},
group: 'inputs',
};

View file

@ -0,0 +1,79 @@
import React, { PropTypes } from 'react';
import { Field } from 'redux-form';
import classNames from 'classnames';
import { ValidationError } from '../../components';
import css from './TextInputField.css';
const TextInputFieldComponent = props => {
const {
rootClassName,
className,
id,
label,
type,
input,
meta,
...rest
} = props;
if (label && !id) {
throw new Error('id required when a label is given');
}
const { valid, invalid, touched, error } = meta;
const isTextarea = type === 'textarea';
// Error message and input error styles are only shown if the
// field has been touched and the validation has failed.
const hasError = touched && invalid && error;
const inputClasses = classNames(css.input, {
[css.inputSuccess]: valid,
[css.inputError]: hasError,
});
const inputProps = isTextarea
? { className: inputClasses, id, ...input, ...rest }
: { className: inputClasses, id, type, ...input, ...rest };
const classes = classNames(rootClassName || css.root, className);
return (
<div className={classes}>
{label ? <label htmlFor={id}>{label}</label> : null}
{isTextarea ? <textarea {...inputProps} /> : <input {...inputProps} />}
<ValidationError fieldMeta={meta} />
</div>
);
};
TextInputFieldComponent.defaultProps = {
rootClassName: null,
className: null,
id: null,
label: null,
};
const { string, object } = PropTypes;
TextInputFieldComponent.propTypes = {
rootClassName: string,
className: string,
// Label is optional, but if it is given, an id is also required so
// the label can reference the input in the `for` attribute
id: string,
label: string,
// Either 'textarea' or something that is passed to the input element
type: string.isRequired,
// Generated by redux-form's Field component
input: object.isRequired,
meta: object.isRequired,
};
const TextInputField = props => {
return <Field component={TextInputFieldComponent} {...props} />;
};
export default TextInputField;

View file

@ -43,6 +43,7 @@ import Select from './Select/Select';
import StripeBankAccountToken from './StripeBankAccountToken/StripeBankAccountToken';
import TabNav from './TabNav/TabNav';
import Tabs from './Tabs/Tabs';
import TextInputField from './TextInputField/TextInputField';
import TopbarDesktop from './TopbarDesktop/TopbarDesktop';
import TopbarMobileMenu from './TopbarMobileMenu/TopbarMobileMenu';
import ValidationError from './ValidationError/ValidationError';
@ -94,6 +95,7 @@ export {
StripeBankAccountToken,
TabNav,
Tabs,
TextInputField,
TopbarDesktop,
TopbarMobileMenu,
ValidationError,

View file

@ -6,7 +6,6 @@ import * as Button from './components/Button/Button.example';
import * as CurrencyInput from './components/CurrencyInput/CurrencyInput.example';
import * as DateInput from './components/DateInput/DateInput.example';
import * as EditListingWizard from './components/EditListingWizard/EditListingWizard.example';
import * as InputFieldOld from './components/InputFieldOld/InputFieldOld.example';
import * as ListingCard from './components/ListingCard/ListingCard.example';
import * as Map from './components/Map/Map.example';
import * as Menu from './components/Menu/Menu.example';
@ -20,6 +19,7 @@ import * as StripeBankAccountToken
from './components/StripeBankAccountToken/StripeBankAccountToken.example';
import * as TabNav from './components/TabNav/TabNav.example';
import * as Tabs from './components/Tabs/Tabs.example';
import * as TextInputField from './components/TextInputField/TextInputField.example';
import * as TopbarDesktop from './components/TopbarDesktop/TopbarDesktop.example';
// containers
@ -60,7 +60,6 @@ export {
EditListingPhotosForm,
EditListingPricingForm,
EditListingWizard,
InputFieldOld,
ListingCard,
LocationAutocompleteInput,
LoginForm,
@ -77,6 +76,7 @@ export {
StripePaymentForm,
TabNav,
Tabs,
TextInputField,
TopbarDesktop,
Typography,
};