This repository has been archived by the owner on Feb 23, 2024. It is now read-only.
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Create OrderSelect and Label components (#905)
* Create Label and OrderSelect components * Update review list item so it uses 'classnames' * Split review order select styles from generic component * Update snapshots * Refactor Label so we don't need to check Symbol * Add description to Label and OrderSelect components * Use prop-types instead of prop-types-elementtype * Simplify Label propTypes * Update package-lock
- Loading branch information
Showing
10 changed files
with
315 additions
and
67 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 ( | ||
<Wrapper { ...wrapperProps }> | ||
{ screenReaderLabel } | ||
</Wrapper> | ||
); | ||
} | ||
|
||
Wrapper = wrapperElement || Fragment; | ||
|
||
if ( label && screenReaderLabel && label !== screenReaderLabel ) { | ||
return ( | ||
<Wrapper { ...wrapperProps }> | ||
<span aria-hidden> | ||
{ label } | ||
</span> | ||
<span className="screen-reader-text"> | ||
{ screenReaderLabel } | ||
</span> | ||
</Wrapper> | ||
); | ||
} | ||
|
||
return ( | ||
<Wrapper { ...wrapperProps }> | ||
{ label } | ||
</Wrapper> | ||
); | ||
}; | ||
|
||
Label.propTypes = { | ||
label: PropTypes.string, | ||
screenReaderLabel: PropTypes.string, | ||
wrapperElement: PropTypes.elementType, | ||
wrapperProps: PropTypes.object, | ||
}; | ||
|
||
Label.defaultProps = { | ||
wrapperProps: {}, | ||
}; | ||
|
||
export default Label; |
62 changes: 62 additions & 0 deletions
62
assets/js/base/components/label/test/__snapshots__/index.js.snap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
// Jest Snapshot v1, https://goo.gl/fbAQLP | ||
|
||
exports[`Label with wrapperElement should render both label and screen reader label 1`] = ` | ||
<label | ||
className="foo-bar" | ||
data-foo="bar" | ||
> | ||
<span | ||
aria-hidden={true} | ||
> | ||
Lorem | ||
</span> | ||
<span | ||
className="screen-reader-text" | ||
> | ||
Ipsum | ||
</span> | ||
</label> | ||
`; | ||
|
||
exports[`Label with wrapperElement should render only the label 1`] = ` | ||
<label | ||
className="foo-bar" | ||
data-foo="bar" | ||
> | ||
Lorem | ||
</label> | ||
`; | ||
|
||
exports[`Label with wrapperElement should render only the screen reader label 1`] = ` | ||
<label | ||
className="foo-bar screen-reader-text" | ||
data-foo="bar" | ||
> | ||
Ipsum | ||
</label> | ||
`; | ||
|
||
exports[`Label without wrapperElement should render both label and screen reader label 1`] = ` | ||
Array [ | ||
<span | ||
aria-hidden={true} | ||
> | ||
Lorem | ||
</span>, | ||
<span | ||
className="screen-reader-text" | ||
> | ||
Ipsum | ||
</span>, | ||
] | ||
`; | ||
|
||
exports[`Label without wrapperElement should render only the label 1`] = `"Lorem"`; | ||
|
||
exports[`Label without wrapperElement should render only the screen reader label 1`] = ` | ||
<span | ||
className="screen-reader-text" | ||
> | ||
Ipsum | ||
</span> | ||
`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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( | ||
<Label label="Lorem" screenReaderLabel="Ipsum" /> | ||
); | ||
|
||
expect( component.toJSON() ).toMatchSnapshot(); | ||
} ); | ||
|
||
test( 'should render only the label', () => { | ||
const component = TestRenderer.create( | ||
<Label label="Lorem" /> | ||
); | ||
|
||
expect( component.toJSON() ).toMatchSnapshot(); | ||
} ); | ||
|
||
test( 'should render only the screen reader label', () => { | ||
const component = TestRenderer.create( | ||
<Label screenReaderLabel="Ipsum" /> | ||
); | ||
|
||
expect( component.toJSON() ).toMatchSnapshot(); | ||
} ); | ||
} ); | ||
|
||
describe( 'with wrapperElement', () => { | ||
test( 'should render both label and screen reader label', () => { | ||
const component = TestRenderer.create( | ||
<Label | ||
label="Lorem" | ||
screenReaderLabel="Ipsum" | ||
wrapperElement="label" | ||
wrapperProps={ { | ||
className: 'foo-bar', | ||
'data-foo': 'bar', | ||
} } | ||
/> | ||
); | ||
|
||
expect( component.toJSON() ).toMatchSnapshot(); | ||
} ); | ||
|
||
test( 'should render only the label', () => { | ||
const component = TestRenderer.create( | ||
<Label | ||
label="Lorem" | ||
wrapperElement="label" | ||
wrapperProps={ { | ||
className: 'foo-bar', | ||
'data-foo': 'bar', | ||
} } | ||
/> | ||
); | ||
|
||
expect( component.toJSON() ).toMatchSnapshot(); | ||
} ); | ||
|
||
test( 'should render only the screen reader label', () => { | ||
const component = TestRenderer.create( | ||
<Label | ||
screenReaderLabel="Ipsum" | ||
wrapperElement="label" | ||
wrapperProps={ { | ||
className: 'foo-bar', | ||
'data-foo': 'bar', | ||
} } | ||
/> | ||
); | ||
|
||
expect( component.toJSON() ).toMatchSnapshot(); | ||
} ); | ||
} ); | ||
} ); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import PropTypes from 'prop-types'; | ||
import classNames from 'classnames'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import Label from '../label'; | ||
import './style.scss'; | ||
|
||
/** | ||
* Component used for 'Order by' selectors, which renders a label | ||
* and a <select> with the options provided in the props. | ||
*/ | ||
const OrderSelect = ( { className, componentId, defaultValue, label, onChange, options, screenReaderLabel, readOnly, value } ) => { | ||
const selectId = `wc-block-order-select__select-${ componentId }`; | ||
|
||
return ( | ||
<p className={ classNames( 'wc-block-order-select', className ) }> | ||
<Label | ||
label={ label } | ||
screenReaderLabel={ screenReaderLabel } | ||
wrapperElement="label" | ||
wrapperProps={ { | ||
className: 'wc-block-order-select__label', | ||
htmlFor: selectId, | ||
} } | ||
/> | ||
<select // eslint-disable-line jsx-a11y/no-onchange | ||
id={ selectId } | ||
className="wc-block-order-select__select" | ||
defaultValue={ defaultValue } | ||
onChange={ onChange } | ||
readOnly={ readOnly } | ||
value={ value } | ||
> | ||
{ options.map( ( option ) => ( | ||
<option key={ option.key } value={ option.key }> | ||
{ option.label } | ||
</option> | ||
) ) } | ||
</select> | ||
</p> | ||
); | ||
}; | ||
|
||
OrderSelect.propTypes = { | ||
componentId: PropTypes.number.isRequired, | ||
defaultValue: PropTypes.string, | ||
label: PropTypes.string, | ||
onChange: PropTypes.func, | ||
options: PropTypes.arrayOf( PropTypes.shape( { | ||
key: PropTypes.string.isRequired, | ||
label: PropTypes.string.isRequired, | ||
} ) ), | ||
readOnly: PropTypes.bool, | ||
screenReaderLabel: PropTypes.string, | ||
value: PropTypes.string, | ||
}; | ||
|
||
export default OrderSelect; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
.wc-block-order-select { | ||
margin-bottom: $gap-small; | ||
} | ||
|
||
.wc-block-order-select__label { | ||
margin-right: $gap-small; | ||
display: inline-block; | ||
font-weight: normal; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.