Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Editor: Add ifPostTypeSupports higher-order component (try conditional render HoC pattern) #4815

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 28 additions & 18 deletions edit-post/components/sidebar/discussion-panel/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ import { connect } from 'react-redux';
/**
* WordPress dependencies
*/
import { compose } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { PanelBody, PanelRow } from '@wordpress/components';
import { PostComments, PostPingbacks, PostTypeSupportCheck } from '@wordpress/editor';
import { PostComments, PostPingbacks, ifPostTypeSupports } from '@wordpress/editor';

/**
* Internal Dependencies
Expand All @@ -21,27 +22,32 @@ import { toggleSidebarPanel } from '../../../store/actions';
*/
const PANEL_NAME = 'discussion-panel';

const PostCommentsRow = ifPostTypeSupports( 'comments' )( () => (
<PanelRow>
<PostComments />
</PanelRow>
) );

const PostPingbacksRow = ifPostTypeSupports( 'trackbacks' )( () => (
<PanelRow>
<PostPingbacks />
</PanelRow>
) );

function DiscussionPanel( { isOpened, onTogglePanel } ) {
return (
<PostTypeSupportCheck supportKeys={ [ 'comments', 'trackbacks' ] }>
<PanelBody title={ __( 'Discussion' ) } opened={ isOpened } onToggle={ onTogglePanel }>
<PostTypeSupportCheck supportKeys="comments">
<PanelRow>
<PostComments />
</PanelRow>
</PostTypeSupportCheck>

<PostTypeSupportCheck supportKeys="trackbacks">
<PanelRow>
<PostPingbacks />
</PanelRow>
</PostTypeSupportCheck>
</PanelBody>
</PostTypeSupportCheck>
<PanelBody
title={ __( 'Discussion' ) }
opened={ isOpened }
onToggle={ onTogglePanel }
>
<PostCommentsRow />
<PostPingbacksRow />
</PanelBody>
);
}

export default connect(
const applyConnect = connect(
( state ) => {
return {
isOpened: isEditorSidebarPanelOpened( state, PANEL_NAME ),
Expand All @@ -54,5 +60,9 @@ export default connect(
},
undefined,
{ storeKey: 'edit-post' }
)( DiscussionPanel );
);

export default compose( [
ifPostTypeSupports( [ 'comments', 'trackbacks' ] ),
applyConnect,
] )( DiscussionPanel );
29 changes: 14 additions & 15 deletions edit-post/components/sidebar/featured-image/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ import { get } from 'lodash';
/**
* WordPress dependencies
*/
import { compose } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { PanelBody, withAPIData } from '@wordpress/components';
import { PostFeaturedImage, PostFeaturedImageCheck } from '@wordpress/editor';
import { compose } from '@wordpress/element';
import { PostFeaturedImage, ifPostTypeSupports } from '@wordpress/editor';
import { query } from '@wordpress/data';

/**
Expand All @@ -26,19 +26,17 @@ const PANEL_NAME = 'featured-image';

function FeaturedImage( { isOpened, postType, onTogglePanel } ) {
return (
<PostFeaturedImageCheck>
<PanelBody
title={ get(
postType,
[ 'data', 'labels', 'featured_image' ],
__( 'Featured Image' )
) }
opened={ isOpened }
onToggle={ onTogglePanel }
>
<PostFeaturedImage />
</PanelBody>
</PostFeaturedImageCheck>
<PanelBody
title={ get(
postType,
[ 'data', 'labels', 'featured_image' ],
__( 'Featured Image' )
) }
opened={ isOpened }
onToggle={ onTogglePanel }
>
<PostFeaturedImage />
</PanelBody>
);
}

Expand Down Expand Up @@ -69,6 +67,7 @@ const applyWithAPIData = withAPIData( ( props ) => {
} );

export default compose(
ifPostTypeSupports( 'thumbnail' ),
applyQuery,
applyConnect,
applyWithAPIData,
Expand Down
19 changes: 11 additions & 8 deletions edit-post/components/sidebar/post-excerpt/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ import { connect } from 'react-redux';
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
import { compose } from '@wordpress/element';
import { PanelBody } from '@wordpress/components';
import { PostExcerpt as PostExcerptForm, PostExcerptCheck } from '@wordpress/editor';
import { PostExcerpt as PostExcerptForm, ifPostTypeSupports } from '@wordpress/editor';

/**
* Internal Dependencies
Expand All @@ -23,15 +24,13 @@ const PANEL_NAME = 'post-excerpt';

function PostExcerpt( { isOpened, onTogglePanel } ) {
return (
<PostExcerptCheck>
<PanelBody title={ __( 'Excerpt' ) } opened={ isOpened } onToggle={ onTogglePanel }>
<PostExcerptForm />
</PanelBody>
</PostExcerptCheck>
<PanelBody title={ __( 'Excerpt' ) } opened={ isOpened } onToggle={ onTogglePanel }>
<PostExcerptForm />
</PanelBody>
);
}

export default connect(
const applyConnect = connect(
( state ) => {
return {
isOpened: isEditorSidebarPanelOpened( state, PANEL_NAME ),
Expand All @@ -44,5 +43,9 @@ export default connect(
},
undefined,
{ storeKey: 'edit-post' }
)( PostExcerpt );
);

export default compose( [
ifPostTypeSupports( 'excerpt' ),
applyConnect,
] )( PostExcerpt );
12 changes: 5 additions & 7 deletions edit-post/components/sidebar/post-format/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,14 @@
* WordPress dependencies
*/
import { PanelRow } from '@wordpress/components';
import { PostFormat as PostFormatForm, PostFormatCheck } from '@wordpress/editor';
import { PostFormat as PostFormatForm, ifPostTypeSupports } from '@wordpress/editor';

export function PostFormat() {
return (
<PostFormatCheck>
<PanelRow>
<PostFormatForm />
</PanelRow>
</PostFormatCheck>
<PanelRow>
<PostFormatForm />
</PanelRow>
);
}

export default PostFormat;
export default ifPostTypeSupports( 'post-formats' )( PostFormat );
45 changes: 45 additions & 0 deletions editor/components/higher-order/if-post-type-supports/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
ifPostTypeSupports
==================

`ifPostTypeSupports` is a higher-order component creator which only renders its wrapped component if the current post type supports the given support key(s).

## Usage

Call `ifPostTypeSupports` with a support key or array of keys, one of which must be supported for the current post type being edited.

The return value is a function which can be called with a component that should render only if the post type offers the required support. This results in a new enhanced component.

```jsx
function MyFeaturedImage() {
return <img />;
}

export default ifPostTypeSupports( 'thumbnail' )( MyFeaturedImage );
```

For a full list of post type support keys, refer to [the `add_post_type_support` function documentation](https://codex.wordpress.org/Function_Reference/add_post_type_support).

## Multiple Supports

`ifPostTypeSupports` can be called with a single support key:

```js
ifPostTypeSupports( 'thumbnail' )( MyFeaturedImage );
```

…or an array of support keys:

```js
ifPostTypeSupports( [ 'thumbnail', 'post-formats' ] )( MyFeaturedImage );
```

In this example, the original component will be rendered if the post type supports _either_ thumbnail _or_ post formats.

If you want the component to render only if the post type supports _both_ thumbnail _and_ post formats, chain multiple `ifPostTypeSupports`:

```js
compose( [
ifPostTypeSupports( 'thumbnail' ),
ifPostTypeSupports( 'post-formats' ),
] )( MyFeaturedImage );
```
62 changes: 62 additions & 0 deletions editor/components/higher-order/if-post-type-supports/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/**
* External dependencies
*/
import { connect } from 'react-redux';
import { some, castArray, get, omit } from 'lodash';

/**
* WordPress dependencies
*/
import { withAPIData } from '@wordpress/components';
import { compose } from '@wordpress/element';

/**
* Internal dependencies
*/
import { getCurrentPostType } from '../../../store/selectors';

const ifPostTypeSupports = ( supports ) => ( WrappedComponent ) => {
// Normalize supports as an array, while supporting passing singular key
supports = castArray( supports );

function PostTypeSupportsCheck( props ) {
const { postType } = props;
const isSupported = some( supports, ( support ) => (
get( postType.data, [ 'supports', support ], false )
) );

if ( ! isSupported ) {
return null;
}

return (
<WrappedComponent
{ ...omit( props, [
'postType',
'postTypeSlug',
] ) }
/>
);
}

const applyConnect = connect( ( state ) => {
return {
postTypeSlug: getCurrentPostType( state ),
};
} );

const applyWithAPIData = withAPIData( ( props ) => {
const { postTypeSlug } = props;

return {
postType: `/wp/v2/types/${ postTypeSlug }?context=edit`,
};
} );

return compose( [
applyConnect,
applyWithAPIData,
] )( PostTypeSupportsCheck );
};

export default ifPostTypeSupports;
7 changes: 3 additions & 4 deletions editor/components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,8 @@ export { default as PostAuthor } from './post-author';
export { default as PostAuthorCheck } from './post-author/check';
export { default as PostComments } from './post-comments';
export { default as PostExcerpt } from './post-excerpt';
export { default as PostExcerptCheck } from './post-excerpt/check';
export { default as PostFeaturedImage } from './post-featured-image';
export { default as PostFeaturedImageCheck } from './post-featured-image/check';
export { default as PostFormat } from './post-format';
export { default as PostFormatCheck } from './post-format/check';
export { default as PostLastRevision } from './post-last-revision';
export { default as PostLastRevisionCheck } from './post-last-revision/check';
export { default as PostPendingStatus } from './post-pending-status';
Expand All @@ -44,7 +41,6 @@ export { default as PostTextEditor } from './post-text-editor';
export { default as PostTitle } from './post-title';
export { default as PostTrash } from './post-trash';
export { default as PostTrashCheck } from './post-trash/check';
export { default as PostTypeSupportCheck } from './post-type-support-check';
export { default as PostVisibility } from './post-visibility';
export { default as PostVisibilityLabel } from './post-visibility/label';
export { default as PostVisibilityCheck } from './post-visibility/check';
Expand All @@ -69,3 +65,6 @@ export { default as WritingFlow } from './writing-flow';

// State Related Components
export { default as EditorProvider } from './provider';

// Higher-Order Components
export { default as ifPostTypeSupports } from './higher-order/if-post-type-supports';
13 changes: 3 additions & 10 deletions editor/components/page-attributes/order.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { compose, Fragment } from '@wordpress/element';
/**
* Internal dependencies
*/
import PostTypeSupportCheck from '../post-type-support-check';
import ifPostTypeSupports from '../higher-order/if-post-type-supports';
import { editPost } from '../../store/actions';
import { getEditedPostAttribute } from '../../store/selectors';

Expand Down Expand Up @@ -43,14 +43,6 @@ export function PageAttributesOrder( { onUpdateOrder, instanceId, order } ) {
);
}

function PageAttributesOrderWithChecks( props ) {
return (
<PostTypeSupportCheck supportKeys="page-attributes">
<PageAttributesOrder { ...props } />
</PostTypeSupportCheck>
);
}

const applyConnect = connect(
( state ) => {
return {
Expand All @@ -67,6 +59,7 @@ const applyConnect = connect(
);

export default compose( [
ifPostTypeSupports( 'page-attributes' ),
applyConnect,
withInstanceId,
] )( PageAttributesOrderWithChecks );
] )( PageAttributesOrder );
5 changes: 3 additions & 2 deletions editor/components/post-author/check.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { compose } from '@wordpress/element';
/**
* Internal dependencies
*/
import PostTypeSupportCheck from '../post-type-support-check';
import ifPostTypeSupports from '../higher-order/if-post-type-supports';
import { getCurrentPostType } from '../../store/selectors';

export function PostAuthorCheck( { user, users, children } ) {
Expand All @@ -24,7 +24,7 @@ export function PostAuthorCheck( { user, users, children } ) {
return null;
}

return <PostTypeSupportCheck supportKeys="author">{ children }</PostTypeSupportCheck>;
return children;
}

const applyConnect = connect(
Expand All @@ -45,6 +45,7 @@ const applyWithAPIData = withAPIData( ( props ) => {
} );

export default compose( [
ifPostTypeSupports( 'author' ),
applyConnect,
applyWithAPIData,
withInstanceId,
Expand Down
10 changes: 0 additions & 10 deletions editor/components/post-excerpt/check.js

This file was deleted.

Loading