From b5b23ac28dbbf1eadc982962f189b0030bc9a453 Mon Sep 17 00:00:00 2001 From: inveterateliterate Date: Mon, 28 Jan 2019 14:20:16 -0600 Subject: [PATCH] add an indicator for required fields (#310) * add an indicator for required fields * documentation, cleanup, classname * no default required indicator * pr comments * Version bump: 3.16.0 --- docs.md | 6 ++-- package.json | 2 +- src/forms/labels/input-label.js | 40 ++++++++++++++++------- src/forms/labels/labeled-field.js | 4 ++- stories/forms/inputs/input.story.js | 25 +++++++++----- stories/forms/labels/input-label.story.js | 17 +++++++++- test/forms/labels/input-label.test.js | 10 ++++++ 7 files changed, 80 insertions(+), 24 deletions(-) diff --git a/docs.md b/docs.md index c2db88aa..cedb7549 100644 --- a/docs.md +++ b/docs.md @@ -1051,13 +1051,15 @@ For instance: `'person.firstName'` becomes `'First Name'` - `hint` **[String][131]?** A usage hint for the associated input - `label` **([String][131] \| [Boolean][133])?** Custom text for the label - `tooltip` **[String][131]?** A message to display in a tooltip +- `required` **[Boolean][133]?** A boolean value to indicate whether the field is required +- `requiredIndicator` **[String][131]?** Custom character to denote a field is required (optional, default `''`) ### Examples ```javascript // A custom input to use with redux-forms -function EmailInput ({ +function EmailInput ({ input: { name, value, onBlur, onChange }, label, }) { @@ -1069,7 +1071,7 @@ function EmailInput ({ name, value, onBlur, - onChange, + onChange, }} ) diff --git a/package.json b/package.json index bdbfe9a3..5ddcbd14 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@launchpadlab/lp-components", - "version": "3.15.10", + "version": "3.16.0", "engines": { "node": "^8.0.0" }, diff --git a/src/forms/labels/input-label.js b/src/forms/labels/input-label.js index b564c7fc..a3ad5d6c 100644 --- a/src/forms/labels/input-label.js +++ b/src/forms/labels/input-label.js @@ -7,7 +7,7 @@ import { toggle, togglePropTypes } from '../../utils' /** * * A dynamic label associated with an input component. - * + * * This component is used within {@link LabeledField}, and therefore is incorporated into most `lp-components` input components by default. * * The text of the label is set using the following rules: @@ -18,19 +18,21 @@ import { toggle, togglePropTypes } from '../../utils' * If `name` is used to set the text, it will be stripped of its prefixes and converted to [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage). * * For instance: `'person.firstName'` becomes `'First Name'` - * + * * @name InputLabel * @type Function * @param {String} name - The name of the associated input * @param {String} [hint] - A usage hint for the associated input * @param {String|Boolean} [label] - Custom text for the label * @param {String} [tooltip] - A message to display in a tooltip + * @param {Boolean} [required] - A boolean value to indicate whether the field is required + * @param {String} [requiredIndicator] - Custom character to denote a field is required (optional, default `''`) * @example - * + * * // A custom input to use with redux-forms - * - * function EmailInput ({ + * + * function EmailInput ({ * input: { name, value, onBlur, onChange }, * label, * }) { @@ -42,7 +44,7 @@ import { toggle, togglePropTypes } from '../../utils' * name, * value, * onBlur, - * onChange, + * onChange, * }} * * ) @@ -55,6 +57,8 @@ const propTypes = { label: PropTypes.oneOfType([ PropTypes.string, PropTypes.bool ]), name: PropTypes.string.isRequired, tooltip: PropTypes.string, + required: PropTypes.bool, + requiredIndicator: PropTypes.string, ...togglePropTypes('tooltipShown') } @@ -62,27 +66,41 @@ const defaultProps = { hint: '', label: '', tooltip: '', + requiredIndicator: '', } -function InputLabel ({ hint, label, name, tooltip, tooltipShown, toggleTooltipShown }) { +function InputLabel ({ + hint, + label, + name, + tooltip, + tooltipShown, + toggleTooltipShown, + required, + requiredIndicator, +}) { const labelText = label || convertNameToLabel(name) return ( - { + { label !== false && } - { + { tooltip && } - { + { tooltip &&
{ tooltip } diff --git a/src/forms/labels/labeled-field.js b/src/forms/labels/labeled-field.js index c169295a..99f4b610 100644 --- a/src/forms/labels/labeled-field.js +++ b/src/forms/labels/labeled-field.js @@ -61,12 +61,14 @@ function LabeledField ({ hint, label, tooltip, + required, + requiredIndicator, children, hideErrorLabel, }) { return (
- + { children } { !hideErrorLabel && }
diff --git a/stories/forms/inputs/input.story.js b/stories/forms/inputs/input.story.js index 02d3fb3a..51616d12 100644 --- a/stories/forms/inputs/input.story.js +++ b/stories/forms/inputs/input.story.js @@ -15,33 +15,42 @@ const inputProps = { storiesOf('Input', module) .add('with default label', () => ( - )) .add('with custom label', () => ( - )) .add('with no label', () => ( - )) + .add('with required true custom indicator', () => ( + + )) .add('with error', () => ( - - )) \ No newline at end of file + )) diff --git a/stories/forms/labels/input-label.story.js b/stories/forms/labels/input-label.story.js index 4f6a7cda..c5653b42 100644 --- a/stories/forms/labels/input-label.story.js +++ b/stories/forms/labels/input-label.story.js @@ -4,7 +4,7 @@ import { InputLabel } from 'src' storiesOf('InputLabel', module) .add('with default label', () => ( - )) @@ -20,6 +20,21 @@ storiesOf('InputLabel', module) label={false} /> )) + .add('with required true default indicator', () => ( + + )) + .add('with required true custom indicator', () => ( + + )) .add('with hint', () => ( { wrapper.find('span.tooltip-trigger').simulate('click') expect(wrapper.find('div.tooltip-content.is-active').exists()).toEqual(false) }) + +test('when no custom required indicator provided, do not show required indicator', () => { + const wrapper = mount() + expect(wrapper.find('span.required-indicator').exists()).toEqual(false) +}) + +test('when required true and custom requiredIndicator provided, show custom indicator', () => { + const wrapper = mount() + expect(wrapper.find('label > span').text()).toEqual('*') +})