diff --git a/src/components/checkboxfield/CheckboxField.js b/src/components/checkboxfield/CheckboxField.js index 5a0a84e..ffb7627 100644 --- a/src/components/checkboxfield/CheckboxField.js +++ b/src/components/checkboxfield/CheckboxField.js @@ -12,26 +12,32 @@ class CheckboxField extends Component { constructor(props) { super(props); this.forId = `stxField${generateUniqueId()}`; + this.messageId = `stxFieldMessage${generateUniqueId()}`; } render() { - const { id, className, helpText, messageType, messageText, label, ...remainingProps } = this.props; + const { id, className, helpText, messageType, messageText, messageId, label, ...remainingProps } = this.props; const classNames = cn([ 'stx-checkbox-field__field', className, ]); + const hasValidationError = messageType === 'alert' || messageType === 'error'; + return (
@@ -58,6 +64,8 @@ CheckboxField.propTypes = { messageText: PropTypes.string, /** The type of message to display */ messageType: PropTypes.oneOf(['alert', 'warning', 'success', '']), + /** The ID of the associated message element (automatically generated if not provided) */ + messageId: PropTypes.oneOf([PropTypes.string, PropTypes.undefined]), /** Whether or not the checkbox is disabled */ disabled: PropTypes.bool, }; diff --git a/src/components/checkboxfield/__snapshots__/CheckboxField.test.js.snap b/src/components/checkboxfield/__snapshots__/CheckboxField.test.js.snap index 87666e1..b934e42 100644 --- a/src/components/checkboxfield/__snapshots__/CheckboxField.test.js.snap +++ b/src/components/checkboxfield/__snapshots__/CheckboxField.test.js.snap @@ -3,18 +3,20 @@ exports[`CheckboxField CheckboxField render additional props 1`] = `
@@ -23,18 +25,20 @@ exports[`CheckboxField CheckboxField render additional props 1`] = ` exports[`CheckboxField CheckboxField render disabled when disabled is true 1`] = `
@@ -43,18 +47,20 @@ exports[`CheckboxField CheckboxField render disabled when disabled is true 1`] = exports[`CheckboxField CheckboxField renders checked 1`] = `
@@ -63,6 +69,7 @@ exports[`CheckboxField CheckboxField renders checked 1`] = ` exports[`CheckboxField CheckboxField renders with a success messageText 1`] = ` @@ -70,12 +77,13 @@ exports[`CheckboxField CheckboxField renders with a success messageText 1`] = ` className="stx-checkbox-field__div" >
@@ -84,6 +92,7 @@ exports[`CheckboxField CheckboxField renders with a success messageText 1`] = ` exports[`CheckboxField CheckboxField renders with a warning messageText 1`] = ` @@ -91,12 +100,13 @@ exports[`CheckboxField CheckboxField renders with a warning messageText 1`] = ` className="stx-checkbox-field__div" > @@ -105,6 +115,7 @@ exports[`CheckboxField CheckboxField renders with a warning messageText 1`] = ` exports[`CheckboxField CheckboxField renders with an alert messageText 1`] = ` @@ -112,12 +123,14 @@ exports[`CheckboxField CheckboxField renders with an alert messageText 1`] = ` className="stx-checkbox-field__div" > @@ -126,11 +139,13 @@ exports[`CheckboxField CheckboxField renders with an alert messageText 1`] = ` exports[`CheckboxField CheckboxField renders with basic props 1`] = `
@@ -171,17 +188,19 @@ exports[`CheckboxField CheckboxField renders with helpText 1`] = ` exports[`CheckboxField CheckboxField renders without any props 1`] = `
diff --git a/src/components/field/Field.js b/src/components/field/Field.js index 404cde3..fb3317e 100644 --- a/src/components/field/Field.js +++ b/src/components/field/Field.js @@ -6,7 +6,7 @@ import './Field.css'; function Field(props) { const { - children, className, disabled, helpText, htmlFor, id, label, messageText, messageType, ariaLive, ...otherProps + children, className, disabled, helpText, htmlFor, id, messageId, label, messageText, messageType, ariaLive, ...otherProps } = props; const classNames = cn([ @@ -19,7 +19,7 @@ function Field(props) { ]); const renderMessageText = () => { - return messageText &&
{ messageText }
; + return messageText &&
{ messageText }
; }; const renderHelpText = () => { @@ -73,6 +73,9 @@ Field.propTypes = { /** The text to display for the message */ messageText: PropTypes.string, + /** A unique ID for the message element */ + messageId: PropTypes.string, + /** Child elements */ children: PropTypes.node, }; diff --git a/src/components/inputfield/InputField.js b/src/components/inputfield/InputField.js index 1c3216b..c1b1994 100644 --- a/src/components/inputfield/InputField.js +++ b/src/components/inputfield/InputField.js @@ -12,15 +12,18 @@ class InputField extends Component { constructor(props) { super(props); this.forId = `stxField${generateUniqueId()}`; + this.messageId = `stxFieldMessage${generateUniqueId()}`; } render() { - const { className, disabled, helpText, id, label, messageText, messageType, readOnly, ariaLive, ...otherProps } = this.props; + const { className, disabled, helpText, id, label, messageText, messageType, messageId, readOnly, ariaLive, ...otherProps } = this.props; const classNames = cn([ 'stx-field--with-input', className, ]); + const hasValidationError = messageType === 'alert' || messageType === 'error'; + return ( ); @@ -59,6 +65,8 @@ InputField.propTypes = { messageType: PropTypes.oneOf(['success', 'warning', 'alert', '']), /** The text that should appear as a message */ messageText: PropTypes.string, + /** The ID of the associated message element */ + messageId: PropTypes.oneOf([PropTypes.string, PropTypes.undefined]), /** The aria-live attribute value that will be set on the message if one is given */ ariaLive: PropTypes.oneOf(['assertive', 'polite']), /** Whether or not the field is disabled */ diff --git a/src/components/inputfield/__snapshots__/InputField.test.js.snap b/src/components/inputfield/__snapshots__/InputField.test.js.snap index 1387f41..7671437 100644 --- a/src/components/inputfield/__snapshots__/InputField.test.js.snap +++ b/src/components/inputfield/__snapshots__/InputField.test.js.snap @@ -4,11 +4,13 @@ exports[`InputField InputField render disabled when disabled is true 1`] = ` @@ -18,11 +20,13 @@ exports[`InputField InputField render disabled when disabled is true 1`] = ` exports[`InputField InputField render readOnly when readOnly is true 1`] = ` @@ -61,11 +69,14 @@ exports[`InputField InputField renders with a autoComplete value 1`] = ` exports[`InputField InputField renders with a message type of alert 1`] = ` @@ -242,10 +275,12 @@ exports[`InputField InputField renders with type date 1`] = ` exports[`InputField InputField renders with type datetime-local 1`] = ` @@ -255,10 +290,12 @@ exports[`InputField InputField renders with type datetime-local 1`] = ` exports[`InputField InputField renders with type email 1`] = ` @@ -268,10 +305,12 @@ exports[`InputField InputField renders with type email 1`] = ` exports[`InputField InputField renders with type file 1`] = ` @@ -281,10 +320,12 @@ exports[`InputField InputField renders with type file 1`] = ` exports[`InputField InputField renders with type number 1`] = ` @@ -294,10 +335,12 @@ exports[`InputField InputField renders with type number 1`] = ` exports[`InputField InputField renders with type password 1`] = ` @@ -307,10 +350,12 @@ exports[`InputField InputField renders with type password 1`] = ` exports[`InputField InputField renders with type search 1`] = ` @@ -320,10 +365,12 @@ exports[`InputField InputField renders with type search 1`] = ` exports[`InputField InputField renders with type tel 1`] = ` @@ -333,10 +380,12 @@ exports[`InputField InputField renders with type tel 1`] = ` exports[`InputField InputField renders with type text 1`] = ` @@ -346,10 +395,12 @@ exports[`InputField InputField renders with type text 1`] = ` exports[`InputField InputField renders with type time 1`] = ` @@ -359,10 +410,12 @@ exports[`InputField InputField renders with type time 1`] = ` exports[`InputField InputField renders with type url 1`] = ` @@ -372,10 +425,12 @@ exports[`InputField InputField renders with type url 1`] = ` exports[`InputField InputField renders without any props 1`] = ` diff --git a/src/components/pill/Pill.test.js b/src/components/pill/Pill.test.js index ea40ff4..1b614a1 100644 --- a/src/components/pill/Pill.test.js +++ b/src/components/pill/Pill.test.js @@ -1,3 +1,4 @@ +/* global describe, test, expect, jest */ import React from 'react'; import { shallow } from 'enzyme'; import toJson from 'enzyme-to-json'; @@ -6,8 +7,8 @@ import Pill from './Pill'; describe('Pill', () => { test('Pill renders with basic props', () => { const component = shallow(); expect(toJson(component)).toMatchSnapshot(); @@ -15,7 +16,7 @@ describe('Pill', () => { test('Pill renders with a11y props', () => { const component = shallow(); const span = component.find('span.stx-pill'); @@ -39,7 +40,7 @@ describe('Pill', () => { test('Pill renders with alert status', () => { const component = shallow(); const span = component.find('span.stx-pill--with-alert'); @@ -48,7 +49,7 @@ describe('Pill', () => { test('Pill renders with warning status', () => { const component = shallow(); const span = component.find('span.stx-pill--with-warning'); @@ -57,7 +58,7 @@ describe('Pill', () => { test('Pill renders with success status', () => { const component = shallow(); const span = component.find('span.stx-pill--with-success'); @@ -66,7 +67,7 @@ describe('Pill', () => { test('Pill renders with info status', () => { const component = shallow(); const span = component.find('span.stx-pill--with-info'); diff --git a/src/components/radiofield/RadioField.js b/src/components/radiofield/RadioField.js index 61c7522..1c238af 100644 --- a/src/components/radiofield/RadioField.js +++ b/src/components/radiofield/RadioField.js @@ -12,15 +12,18 @@ class RadioField extends Component { constructor(props) { super(props); this.forId = `stxField${generateUniqueId()}`; + this.messageId = `stxFieldMessage${generateUniqueId()}`; } render() { - const { className, disabled, helpText, id, label, messageType, messageText, value, ...otherProps } = this.props; + const { className, disabled, helpText, id, label, messageType, messageText, messageId, value, ...otherProps } = this.props; const classNames = cn([ 'stx-field--with-radio-field', className, ]); + const hasValidationError = messageType === 'alert' || messageType === 'error'; + return (
@@ -48,6 +49,8 @@ exports[`RadioField RadioField renders with basic props 1`] = ` className="stx-radio-field" > - + ); @@ -68,6 +74,9 @@ SelectField.propTypes = { /** The type of message to display */ messageType: PropTypes.oneOf(['alert', 'warning', 'success', '']), + /** The ID of the associated message element (automatically generated if not provided) */ + messageId: PropTypes.oneOf([PropTypes.string, PropTypes.undefined]), + /** The aria-live attribute value that will be set on the message if one is given */ ariaLive: PropTypes.oneOf(['assertive', 'polite']), diff --git a/src/components/selectfield/__snapshots__/SelectField.test.js.snap b/src/components/selectfield/__snapshots__/SelectField.test.js.snap index 14bba84..6aa09a9 100644 --- a/src/components/selectfield/__snapshots__/SelectField.test.js.snap +++ b/src/components/selectfield/__snapshots__/SelectField.test.js.snap @@ -15,11 +15,13 @@ exports[`SelectField SelectField renders with basic props 1`] = ` ariaLive="assertive" className="stx-field--with-select the-class" htmlFor="stxField1" + messageId="stxFieldMessage2" >