diff --git a/package.json b/package.json index 2b261e7..209b559 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,8 @@ "redux": "^3.7.2", "redux-devtools-extension": "^2.13.2", "redux-logger": "^3.0.6", - "redux-thunk": "^2.2.0" + "redux-thunk": "^2.2.0", + "styled-components": "^2.2.1" }, "jest": { "collectCoverage": true, diff --git a/src/components/Field.jsx b/src/components/Field.jsx new file mode 100644 index 0000000..0b24e2f --- /dev/null +++ b/src/components/Field.jsx @@ -0,0 +1,51 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import styled from 'styled-components'; + +import Input from './Input'; + + +export const StyledLabel = styled.label` + display: block; + font-weight: bold; + line-height: 1.618; +`; + + +/** + * A wrapper around a form input and label. + * + * @param {string} props.label A descriptive label for the field. + * @param {string} props.name The input field's name. + * @param {string[]} [props.errors] A list of errors for the field. + * @param {string} [props.id] The ID to give the input. Defaults to the input's name. + * @param {...object} [props.extraProps] Additional props to pass to the input component. + */ +const Field = ({ errors, id, label, name, ...extraProps }) => ( +
+ {label} + + {errors.length > 0 && ( + + )} +
+); + +Field.defaultProps = { + errors: [], + id: '', +}; + +Field.propTypes = { + errors: PropTypes.arrayOf(PropTypes.string), + id: PropTypes.string, + label: PropTypes.string.isRequired, + name: PropTypes.string.isRequired, +}; + + +export default Field; diff --git a/src/components/Input.jsx b/src/components/Input.jsx new file mode 100644 index 0000000..9ef6adf --- /dev/null +++ b/src/components/Input.jsx @@ -0,0 +1,35 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import styled from 'styled-components'; + + +export const StyledInput = styled.input` + border: 1px solid #e2e2e2; + border-radius: 3px; + display: block; + padding: .5em; + width: 100%; + + &:focus { + border-color: #b7eaff; + outline: none; + } +`; + + +/** + * Component for accepting text input. + * + * @param {string} props.name The name to give the input field. + * @param {...object} [props.extraProps] Any additional props to pass to the input field. + */ +const Input = ({ name, ...extraProps }) => ( + +); + +Input.propTypes = { + name: PropTypes.string.isRequired, +}; + + +export default Input; diff --git a/src/components/RegistrationForm.jsx b/src/components/RegistrationForm.jsx index 76c2f69..8b0ccaa 100644 --- a/src/components/RegistrationForm.jsx +++ b/src/components/RegistrationForm.jsx @@ -4,6 +4,7 @@ import { connect } from 'react-redux'; import { Redirect } from 'react-router-dom'; import { register } from '../actionCreators'; +import Field from './Field'; import { getRegistrationComplete, getRegistrationErrors, getRegistrationLoading } from '../selectors'; @@ -39,33 +40,25 @@ export class RegistrationForm extends React.Component { return (
- - - - - - -