Introduce `ToggleButtonControl` for Product Category List display type (https://github.com/woocommerce/woocommerce-blocks/pull/675)

* Toggle control component

* README

* Use toggle component for list settings
This commit is contained in:
Mike Jolley 2019-07-03 15:39:10 +01:00 committed by GitHub
parent bfd83c959e
commit 882e8ad322
5 changed files with 188 additions and 10 deletions

View File

@ -11,6 +11,7 @@ import { PanelBody, ToggleControl } from '@wordpress/components';
*/
import './editor.scss';
import Block from './block.js';
import ToggleButtonControl from '../../components/toggle-button-control';
export default function( { attributes, setAttributes } ) {
const { hasCount, hasEmpty, isDropdown, isHierarchical } = attributes;
@ -22,16 +23,6 @@ export default function( { attributes, setAttributes } ) {
title={ __( 'Content', 'woo-gutenberg-products-block' ) }
initialOpen
>
<ToggleControl
label={ __( 'Show as dropdown', 'woo-gutenberg-products-block' ) }
help={
isDropdown ?
__( 'Categories are shown in a dropdown.', 'woo-gutenberg-products-block' ) :
__( 'Categories are shown in a list.', 'woo-gutenberg-products-block' )
}
checked={ isDropdown }
onChange={ () => setAttributes( { isDropdown: ! isDropdown } ) }
/>
<ToggleControl
label={ __( 'Show product count', 'woo-gutenberg-products-block' ) }
help={
@ -63,6 +54,20 @@ export default function( { attributes, setAttributes } ) {
onChange={ () => setAttributes( { hasEmpty: ! hasEmpty } ) }
/>
</PanelBody>
<PanelBody
title={ __( 'List Settings', 'woo-gutenberg-products-block' ) }
initialOpen
>
<ToggleButtonControl
label={ __( 'Display style', 'woo-gutenberg-products-block' ) }
value={ isDropdown ? 'dropdown' : 'list' }
options={ [
{ label: __( 'List', 'woo-gutenberg-products-block' ), value: 'list' },
{ label: __( 'Dropdown', 'woo-gutenberg-products-block' ), value: 'dropdown' },
] }
onChange={ ( value ) => setAttributes( { isDropdown: 'dropdown' === value } ) }
/>
</PanelBody>
</InspectorControls>
<Block attributes={ attributes } isPreview />
</Fragment>

View File

@ -0,0 +1,72 @@
# ToggleButtonControl
ToggleButtonControl is used to generate a series of toggle buttons where only one selection is possible. It uses a ButtonGroup component to output each toggle button.
![A toggle button control](screenshot.png)
## Usage
Render a user interface to select multiple users from a list.
```jsx
<ToggleButtonControl
label={ __( 'Display style', 'woo-gutenberg-products-block' ) }
value={ isDropdown ? 'dropdown' : 'list' }
help="This is some helper text that shows below the controls."
options={ [
{ label: __( 'List', 'woo-gutenberg-products-block' ), value: 'list' },
{ label: __( 'Dropdown', 'woo-gutenberg-products-block' ), value: 'dropdown' },
] }
onChange={ ( value ) => setAttributes( { isDropdown: 'dropdown' === value } ) }
/>
) );
```
## Props
The component accepts the following props:
### label
If this property is added, a label will be generated using label property as the content.
- Type: `String`
- Required: No
### help
If this property is added, a help text will be generated using help property as the content.
- Type: `String|WPElement`
- Required: No
### value
If value is passed, one of the options will have pressed state.
If no value is passed no button will have pressed state.
- Type: `String`
- Required: No
### onChange
A function that receives the selected value (string) as input.
- Type: `function`
- Required: Yes
### className
The class that will be added with `components-base-control` and `components-toggle-button-control` to the classes of the wrapper div. If no className is passed only `components-base-control` and `components-toggle-button-control` are used.
Type: String
Required: No
#### options
An array of objects containing the following properties:
- `label`: (string) The label to be shown to the user.
- `value`: (Object) The internal value used to choose the selected value. This is also the value passed to onChange when the option is selected.
Type: `Array`
Required: No

View File

@ -0,0 +1,88 @@
/**
* External dependencies
*/
import { isFunction } from 'lodash';
import classnames from 'classnames';
import { BaseControl, ButtonGroup, Button } from '@wordpress/components';
/**
* WordPress dependencies
*/
import { Component } from '@wordpress/element';
import { withInstanceId } from '@wordpress/compose';
/**
* Internal dependencies
*/
import './style.scss';
class ToggleButtonControl extends Component {
constructor() {
super( ...arguments );
this.onClick = this.onClick.bind( this );
}
onClick( event ) {
if ( this.props.onChange ) {
this.props.onChange( event.target.value );
}
}
render() {
const { label, checked, instanceId, className, help, options, value } = this.props;
const id = `inspector-toggle-button-control-${ instanceId }`;
let helpLabel;
if ( help ) {
helpLabel = isFunction( help ) ? help( checked ) : help;
}
return (
<BaseControl
id={ id }
help={ helpLabel }
className={ classnames( 'components-toggle-button-control', className ) }
>
<label
id={ id + '__label' }
htmlFor={ id }
className="components-toggle-button-control__label"
>
{ label }
</label>
<ButtonGroup
aria-labelledby={ id + '__label' }
>
{ options.map( ( option, index ) => {
const buttonArgs = {};
// Change button depending on pressed state.
if ( value === option.value ) {
buttonArgs.isPrimary = true;
buttonArgs[ 'aria-pressed' ] = true;
} else {
buttonArgs.isDefault = true;
buttonArgs[ 'aria-pressed' ] = false;
}
return (
<Button
key={ `${ option.label }-${ option.value }-${ index }` }
value={ option.value }
onClick={ this.onClick }
aria-label={ label + ': ' + option.label }
{ ...buttonArgs }
>
{ option.label }
</Button>
);
} ) }
</ButtonGroup>
</BaseControl>
);
}
}
export default withInstanceId( ToggleButtonControl );

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

View File

@ -0,0 +1,13 @@
.components-toggle-button-control {
.components-base-control__field {
flex-wrap: wrap;
}
.components-toggle-button-control__label {
width: 100%;
margin-bottom: 8px;
display: block;
}
.components-base-control__help {
margin-top: 0;
}
}