diff --git a/src/components/FieldSelect/FieldSelect.css b/src/components/FieldSelect/FieldSelect.css new file mode 100644 index 00000000..0aa58c74 --- /dev/null +++ b/src/components/FieldSelect/FieldSelect.css @@ -0,0 +1,18 @@ +@import '../../marketplace.css'; + +.root { +} + +.select { + color: var(--matterColorAnti); + border-bottom-color: var(--attentionColor); +} + +.selectSuccess { + color: var(--matterColor); + border-bottom-color: var(--successColor); +} + +.selectError { + border-bottom-color: var(--failColor); +} diff --git a/src/components/FieldSelect/FieldSelect.example.js b/src/components/FieldSelect/FieldSelect.example.js new file mode 100644 index 00000000..de6fae6a --- /dev/null +++ b/src/components/FieldSelect/FieldSelect.example.js @@ -0,0 +1,51 @@ +/* eslint-disable no-console */ +import React from 'react'; +import { Form as FinalForm, FormSpy } from 'react-final-form'; +import * as validators from '../../util/validators'; +import { Button } from '../../components'; +import FieldSelect from './FieldSelect'; + +const FormComponent = props => ( + { + const { form, handleSubmit, onChange, invalid, pristine, submitting } = fieldRenderProps; + const required = validators.required('This field is required'); + const submitDisabled = invalid || pristine || submitting; + return ( +
{ + e.preventDefault(); + handleSubmit(e); + }} + > + + + + + + + + + ); + }} + /> +); + +export const Select = { + component: FormComponent, + props: { + onChange: formState => { + if (formState.values.select1) { + console.log('form values changed to:', formState.values); + } + }, + onSubmit: values => { + console.log('submit values:', values); + return false; + }, + }, + group: 'inputs', +}; diff --git a/src/components/FieldSelect/FieldSelect.js b/src/components/FieldSelect/FieldSelect.js new file mode 100644 index 00000000..dd13589d --- /dev/null +++ b/src/components/FieldSelect/FieldSelect.js @@ -0,0 +1,72 @@ +/** + * NOTE this component is part of react-final-form instead of Redux Form. + */ + +import React from 'react'; +import PropTypes from 'prop-types'; +import { Field } from 'react-final-form'; +import classNames from 'classnames'; +import { ValidationError } from '../../components'; + +import css from './FieldSelect.css'; + +const FieldSelectComponent = props => { + const { rootClassName, className, id, label, input, meta, children, ...rest } = props; + + if (label && !id) { + throw new Error('id required when a label is given'); + } + + const { valid, invalid, touched, error } = meta; + + // 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 selectClasses = classNames(css.select, { + [css.selectSuccess]: valid, + [css.selectError]: hasError, + }); + const selectProps = { className: selectClasses, id, ...input, ...rest }; + + const classes = classNames(rootClassName || css.root, className); + return ( +
+ {label ? : null} + + +
+ ); +}; + +FieldSelectComponent.defaultProps = { + rootClassName: null, + className: null, + id: null, + label: null, + children: null, +}; + +const { string, object, node } = PropTypes; + +FieldSelectComponent.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, + + // Generated by final-form's Field component + input: object.isRequired, + meta: object.isRequired, + + children: node, +}; + +const FieldSelect = props => { + return ; +}; + +export default FieldSelect; diff --git a/src/components/index.js b/src/components/index.js index ab485876..9be9fd6e 100644 --- a/src/components/index.js +++ b/src/components/index.js @@ -38,6 +38,7 @@ export { default as FieldDateRangeInput } from './FieldDateRangeInput/FieldDateR export { default as FieldGroupCheckbox } from './FieldGroupCheckbox/FieldGroupCheckbox'; export { default as FieldPhoneNumberInput } from './FieldPhoneNumberInput/FieldPhoneNumberInput'; export { default as FieldReviewRating } from './FieldReviewRating/FieldReviewRating'; +export { default as FieldSelect } from './FieldSelect/FieldSelect'; export { default as FieldTextInput } from './FieldTextInput/FieldTextInput'; export { default as Footer } from './Footer/Footer'; export { default as Form } from './Form/Form'; diff --git a/src/examples.js b/src/examples.js index 776a2f20..eac38cad 100644 --- a/src/examples.js +++ b/src/examples.js @@ -14,6 +14,7 @@ import * as FieldDateRangeInput from './components/FieldDateRangeInput/FieldDate import * as FieldGroupCheckbox from './components/FieldGroupCheckbox/FieldGroupCheckbox.example'; import * as FieldPhoneNumberInput from './components/FieldPhoneNumberInput/FieldPhoneNumberInput.example'; import * as FieldReviewRating from './components/FieldReviewRating/FieldReviewRating.example'; +import * as FieldSelect from './components/FieldSelect/FieldSelect.example'; import * as FieldTextInput from './components/FieldTextInput/FieldTextInput.example'; import * as Footer from './components/Footer/Footer.example'; import * as IconBannedUser from './components/IconBannedUser/IconBannedUser.example'; @@ -105,6 +106,7 @@ export { FieldGroupCheckbox, FieldPhoneNumberInput, FieldReviewRating, + FieldSelect, FieldTextInput, Footer, IconBannedUser,