Skip to content

Commit

Permalink
Refactor Categories to function component (#25806)
Browse files Browse the repository at this point in the history
* refactor Categories to function component

* remove useCallback
  • Loading branch information
ntsekouras authored Oct 13, 2020
1 parent a9267fe commit f3f13f7
Showing 1 changed file with 96 additions and 165 deletions.
261 changes: 96 additions & 165 deletions packages/block-library/src/categories/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,128 +13,85 @@ import {
ToggleControl,
VisuallyHidden,
} from '@wordpress/components';
import { compose, withInstanceId } from '@wordpress/compose';
import { withSelect } from '@wordpress/data';
import { useInstanceId } from '@wordpress/compose';
import { useSelect } from '@wordpress/data';
import { InspectorControls } from '@wordpress/block-editor';
import { Component } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { pin } from '@wordpress/icons';

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 ) {
export default function CategoriesEdit( {
attributes: { displayAsDropdown, showHierarchy, showPostCounts },
className,
setAttributes,
} ) {
const selectId = useInstanceId( CategoriesEdit, 'blocks-category-select' );
const { categories, isRequesting } = useSelect( ( 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,
] ),
};
}, [] );
const getCategoriesList = ( parentId ) => {
if ( ! categories?.length ) {
return [];
}

if ( parentId === null ) {
return categories;
}

return categories.filter(
( category ) => category.parent === parentId
);
}

getCategoryListClassName( level ) {
return categories.filter( ( { parent } ) => parent === parentId );
};
const getCategoryListClassName = ( level ) => {
return `wp-block-categories__list wp-block-categories__list-level-${ level }`;
}

renderCategoryName( category ) {
if ( ! category.name ) {
return __( '(Untitled)' );
}
};
const toggleAttribute = ( attributeName ) => ( newValue ) =>
setAttributes( { [ attributeName ]: newValue } );
const renderCategoryName = ( name ) =>
! name ? __( '(Untitled)' ) : unescape( name ).trim();

return unescape( category.name ).trim();
}

renderCategoryList() {
const { showHierarchy } = this.props.attributes;
const renderCategoryList = () => {
const parentId = showHierarchy ? 0 : null;
const categories = this.getCategories( parentId );

const categoriesList = getCategoriesList( parentId );
return (
<ul className={ this.getCategoryListClassName( 0 ) }>
{ categories.map( ( category ) =>
this.renderCategoryListItem( category, 0 )
<ul className={ getCategoryListClassName( 0 ) }>
{ categoriesList.map( ( category ) =>
renderCategoryListItem( category, 0 )
) }
</ul>
);
}

renderCategoryListItem( category, level ) {
const { showHierarchy, showPostCounts } = this.props.attributes;
const childCategories = this.getCategories( category.id );

};
const renderCategoryListItem = ( category, level ) => {
const childCategories = getCategoriesList( category.id );
const { id, link, count, name } = category;
return (
<li key={ category.id }>
<a
href={ category.link }
target="_blank"
rel="noreferrer noopener"
>
{ this.renderCategoryName( category ) }
<li key={ id }>
<a href={ link } target="_blank" rel="noreferrer noopener">
{ renderCategoryName( name ) }
</a>
{ showPostCounts && (
<span className="wp-block-categories__post-count">
{ ' ' }
({ category.count })
{ ` (${ count })` }
</span>
) }

{ showHierarchy && !! childCategories.length && (
<ul
className={ this.getCategoryListClassName( level + 1 ) }
>
<ul className={ getCategoryListClassName( level + 1 ) }>
{ childCategories.map( ( childCategory ) =>
this.renderCategoryListItem(
childCategory,
level + 1
)
renderCategoryListItem( childCategory, level + 1 )
) }
</ul>
) }
</li>
);
}

renderCategoryDropdown() {
const { instanceId } = this.props;
const { showHierarchy } = this.props.attributes;
};
const renderCategoryDropdown = () => {
const parentId = showHierarchy ? 0 : null;
const categories = this.getCategories( parentId );
const selectId = `blocks-category-select-${ instanceId }`;
const categoriesList = getCategoriesList( parentId );
return (
<>
<VisuallyHidden as="label" htmlFor={ selectId }>
Expand All @@ -144,95 +101,69 @@ class CategoriesEdit extends Component {
id={ selectId }
className="wp-block-categories__dropdown"
>
{ categories.map( ( category ) =>
this.renderCategoryDropdownItem( category, 0 )
{ categoriesList.map( ( category ) =>
renderCategoryDropdownItem( category, 0 )
) }
</select>
</>
);
}

renderCategoryDropdownItem( category, level ) {
const { showHierarchy, showPostCounts } = this.props.attributes;
const childCategories = this.getCategories( category.id );

};
const renderCategoryDropdownItem = ( category, level ) => {
const { id, count, name } = category;
const childCategories = getCategoriesList( id );
return [
<option key={ category.id }>
<option key={ id }>
{ times( level * 3, () => '\xa0' ) }
{ this.renderCategoryName( category ) }
{ !! showPostCounts ? ` (${ category.count })` : '' }
{ renderCategoryName( name ) }
{ showPostCounts && ` (${ count })` }
</option>,
showHierarchy &&
!! childCategories.length &&
childCategories.map( ( childCategory ) =>
this.renderCategoryDropdownItem( childCategory, level + 1 )
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 (
<>
{ inspectorControls }
<Placeholder icon={ pin } label={ __( 'Categories' ) }>
<Spinner />
</Placeholder>
</>
);
}

};

const inspectorControls = (
<InspectorControls>
<PanelBody title={ __( 'Categories settings' ) }>
<ToggleControl
label={ __( 'Display as dropdown' ) }
checked={ displayAsDropdown }
onChange={ toggleAttribute( 'displayAsDropdown' ) }
/>
<ToggleControl
label={ __( 'Show hierarchy' ) }
checked={ showHierarchy }
onChange={ toggleAttribute( 'showHierarchy' ) }
/>
<ToggleControl
label={ __( 'Show post counts' ) }
checked={ showPostCounts }
onChange={ toggleAttribute( 'showPostCounts' ) }
/>
</PanelBody>
</InspectorControls>
);
if ( isRequesting ) {
return (
<>
{ inspectorControls }
<div className={ this.props.className }>
{ displayAsDropdown
? this.renderCategoryDropdown()
: this.renderCategoryList() }
</div>
<Placeholder icon={ pin } label={ __( 'Categories' ) }>
<Spinner />
</Placeholder>
</>
);
}
return (
<>
{ inspectorControls }
<div className={ className }>
{ displayAsDropdown
? renderCategoryDropdown()
: renderCategoryList() }
</div>
</>
);
}
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 );

0 comments on commit f3f13f7

Please sign in to comment.