diff --git a/assets/js/base/components/label/index.js b/assets/js/base/components/label/index.js new file mode 100644 index 00000000000..9079b225a91 --- /dev/null +++ b/assets/js/base/components/label/index.js @@ -0,0 +1,63 @@ +/** + * External dependencies + */ +import PropTypes from 'prop-types'; +import { Fragment } from 'react'; +import classNames from 'classnames'; + +/** + * Component used to render an accessible text given a label and/or a + * screenReaderLabel. The wrapper element and wrapper props can also be + * specified via props. + */ +const Label = ( { label, screenReaderLabel, wrapperElement, wrapperProps } ) => { + let Wrapper; + + if ( ! label && screenReaderLabel ) { + Wrapper = wrapperElement || 'span'; + wrapperProps = { + ...wrapperProps, + className: classNames( wrapperProps.className, 'screen-reader-text' ), + }; + + return ( + + { screenReaderLabel } + + ); + } + + Wrapper = wrapperElement || Fragment; + + if ( label && screenReaderLabel && label !== screenReaderLabel ) { + return ( + + + { label } + + + { screenReaderLabel } + + + ); + } + + return ( + + { label } + + ); +}; + +Label.propTypes = { + label: PropTypes.string, + screenReaderLabel: PropTypes.string, + wrapperElement: PropTypes.elementType, + wrapperProps: PropTypes.object, +}; + +Label.defaultProps = { + wrapperProps: {}, +}; + +export default Label; diff --git a/assets/js/base/components/label/test/__snapshots__/index.js.snap b/assets/js/base/components/label/test/__snapshots__/index.js.snap new file mode 100644 index 00000000000..980093315ad --- /dev/null +++ b/assets/js/base/components/label/test/__snapshots__/index.js.snap @@ -0,0 +1,62 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Label with wrapperElement should render both label and screen reader label 1`] = ` + +`; + +exports[`Label with wrapperElement should render only the label 1`] = ` + +`; + +exports[`Label with wrapperElement should render only the screen reader label 1`] = ` + +`; + +exports[`Label without wrapperElement should render both label and screen reader label 1`] = ` +Array [ + + Lorem + , + + Ipsum + , +] +`; + +exports[`Label without wrapperElement should render only the label 1`] = `"Lorem"`; + +exports[`Label without wrapperElement should render only the screen reader label 1`] = ` + + Ipsum + +`; diff --git a/assets/js/base/components/label/test/index.js b/assets/js/base/components/label/test/index.js new file mode 100644 index 00000000000..bd573d051d8 --- /dev/null +++ b/assets/js/base/components/label/test/index.js @@ -0,0 +1,85 @@ +/** + * External dependencies + */ +import TestRenderer from 'react-test-renderer'; + +/** + * Internal dependencies + */ +import Label from '../'; + +describe( 'Label', () => { + describe( 'without wrapperElement', () => { + test( 'should render both label and screen reader label', () => { + const component = TestRenderer.create( +