@wordpress/block-library
Version:
Block library for the WordPress editor.
214 lines (185 loc) • 5.77 kB
JavaScript
/**
* External dependencies
*/
import { times, unescape } from 'lodash';
/**
* WordPress dependencies
*/
import { PanelBody, Placeholder, Spinner, ToggleControl } from '@wordpress/components';
import { compose, withInstanceId } from '@wordpress/compose';
import { withSelect } from '@wordpress/data';
import { InspectorControls } from '@wordpress/block-editor';
import { Component, Fragment } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
class CategoriesEdit extends Component {
constructor() {
super( ...arguments );
this.toggleDisplayAsDropdown = this.toggleDisplayAsDropdown.bind( this );
this.toggleShowPostCounts = this.toggleShowPostCounts.bind( this );
this.toggleShowHierarchy = this.toggleShowHierarchy.bind( this );
}
toggleDisplayAsDropdown() {
const { attributes, setAttributes } = this.props;
const { displayAsDropdown } = attributes;
setAttributes( { displayAsDropdown: ! displayAsDropdown } );
}
toggleShowPostCounts() {
const { attributes, setAttributes } = this.props;
const { showPostCounts } = attributes;
setAttributes( { showPostCounts: ! showPostCounts } );
}
toggleShowHierarchy() {
const { attributes, setAttributes } = this.props;
const { showHierarchy } = attributes;
setAttributes( { showHierarchy: ! showHierarchy } );
}
getCategories( parentId = null ) {
const categories = this.props.categories;
if ( ! categories || ! categories.length ) {
return [];
}
if ( parentId === null ) {
return categories;
}
return categories.filter( ( category ) => category.parent === parentId );
}
getCategoryListClassName( level ) {
return `wp-block-categories__list wp-block-categories__list-level-${ level }`;
}
renderCategoryName( category ) {
if ( ! category.name ) {
return __( '(Untitled)' );
}
return unescape( category.name ).trim();
}
renderCategoryList() {
const { showHierarchy } = this.props.attributes;
const parentId = showHierarchy ? 0 : null;
const categories = this.getCategories( parentId );
return (
<ul className={ this.getCategoryListClassName( 0 ) }>
{ categories.map( ( category ) => this.renderCategoryListItem( category, 0 ) ) }
</ul>
);
}
renderCategoryListItem( category, level ) {
const { showHierarchy, showPostCounts } = this.props.attributes;
const childCategories = this.getCategories( category.id );
return (
<li key={ category.id }>
<a href={ category.link } target="_blank" rel="noreferrer noopener">{ this.renderCategoryName( category ) }</a>
{ showPostCounts &&
<span className="wp-block-categories__post-count">
{ ' ' }({ category.count })
</span>
}
{
showHierarchy &&
!! childCategories.length && (
<ul className={ this.getCategoryListClassName( level + 1 ) }>
{ childCategories.map( ( childCategory ) => this.renderCategoryListItem( childCategory, level + 1 ) ) }
</ul>
)
}
</li>
);
}
renderCategoryDropdown() {
const { instanceId } = this.props;
const { showHierarchy } = this.props.attributes;
const parentId = showHierarchy ? 0 : null;
const categories = this.getCategories( parentId );
const selectId = `blocks-category-select-${ instanceId }`;
return (
<Fragment>
<label htmlFor={ selectId } className="screen-reader-text">
{ __( 'Categories' ) }
</label>
<select id={ selectId } className="wp-block-categories__dropdown">
{ categories.map( ( category ) => this.renderCategoryDropdownItem( category, 0 ) ) }
</select>
</Fragment>
);
}
renderCategoryDropdownItem( category, level ) {
const { showHierarchy, showPostCounts } = this.props.attributes;
const childCategories = this.getCategories( category.id );
return [
<option key={ category.id }>
{ times( level * 3, () => '\xa0' ) }
{ this.renderCategoryName( category ) }
{
!! showPostCounts ?
` (${ category.count })` :
''
}
</option>,
showHierarchy &&
!! childCategories.length && (
childCategories.map( ( childCategory ) => this.renderCategoryDropdownItem( childCategory, level + 1 ) )
),
];
}
render() {
const { attributes, isRequesting } = this.props;
const { displayAsDropdown, showHierarchy, showPostCounts } = attributes;
const inspectorControls = (
<InspectorControls>
<PanelBody title={ __( 'Categories Settings' ) }>
<ToggleControl
label={ __( 'Display as Dropdown' ) }
checked={ displayAsDropdown }
onChange={ this.toggleDisplayAsDropdown }
/>
<ToggleControl
label={ __( 'Show Hierarchy' ) }
checked={ showHierarchy }
onChange={ this.toggleShowHierarchy }
/>
<ToggleControl
label={ __( 'Show Post Counts' ) }
checked={ showPostCounts }
onChange={ this.toggleShowPostCounts }
/>
</PanelBody>
</InspectorControls>
);
if ( isRequesting ) {
return (
<Fragment>
{ inspectorControls }
<Placeholder
icon="admin-post"
label={ __( 'Categories' ) }
>
<Spinner />
</Placeholder>
</Fragment>
);
}
return (
<Fragment>
{ inspectorControls }
<div className={ this.props.className }>
{
displayAsDropdown ?
this.renderCategoryDropdown() :
this.renderCategoryList()
}
</div>
</Fragment>
);
}
}
export default compose(
withSelect( ( select ) => {
const { getEntityRecords } = select( 'core' );
const { isResolving } = select( 'core/data' );
const query = { per_page: -1, hide_empty: true };
return {
categories: getEntityRecords( 'taxonomy', 'category', query ),
isRequesting: isResolving( 'core', 'getEntityRecords', [ 'taxonomy', 'category', query ] ),
};
} ),
withInstanceId
)( CategoriesEdit );