@wordpress/block-library
Version:
Block library for the WordPress editor.
241 lines (213 loc) • 7.98 kB
JavaScript
import _extends from "@babel/runtime/helpers/esm/extends";
import { createElement } from "@wordpress/element";
/**
* External dependencies
*/
import classnames from 'classnames';
/**
* WordPress dependencies
*/
import { memo, useMemo, useState } from '@wordpress/element';
import { useSelect } from '@wordpress/data';
import { __ } from '@wordpress/i18n';
import { BlockContextProvider, __experimentalUseBlockPreview as useBlockPreview, useBlockProps, useInnerBlocksProps, store as blockEditorStore } from '@wordpress/block-editor';
import { Spinner } from '@wordpress/components';
import { store as coreStore } from '@wordpress/core-data';
const TEMPLATE = [['core/post-title'], ['core/post-date'], ['core/post-excerpt']];
function PostTemplateInnerBlocks() {
const innerBlocksProps = useInnerBlocksProps({
className: 'wp-block-post'
}, {
template: TEMPLATE
});
return createElement("li", innerBlocksProps);
}
function PostTemplateBlockPreview(_ref) {
let {
blocks,
blockContextId,
isHidden,
setActiveBlockContextId
} = _ref;
const blockPreviewProps = useBlockPreview({
blocks,
props: {
className: 'wp-block-post'
}
});
const handleOnClick = () => {
setActiveBlockContextId(blockContextId);
};
const style = {
display: isHidden ? 'none' : undefined
};
return createElement("li", _extends({}, blockPreviewProps, {
tabIndex: 0 // eslint-disable-next-line jsx-a11y/no-noninteractive-element-to-interactive-role
,
role: "button",
onClick: handleOnClick,
onKeyPress: handleOnClick,
style: style
}));
}
const MemoizedPostTemplateBlockPreview = memo(PostTemplateBlockPreview);
export default function PostTemplateEdit(_ref2) {
let {
clientId,
context: {
query: {
perPage,
offset,
postType,
order,
orderBy,
author,
search,
exclude,
sticky,
inherit,
taxQuery,
parents,
pages,
// We gather extra query args to pass to the REST API call.
// This way extenders of Query Loop can add their own query args,
// and have accurate previews in the editor.
// Noting though that these args should either be supported by the
// REST API or be handled by custom REST filters like `rest_{$this->post_type}_query`.
...restQueryArgs
} = {},
queryContext = [{
page: 1
}],
templateSlug,
displayLayout: {
type: layoutType = 'flex',
columns = 1
} = {},
previewPostType
}
} = _ref2;
const [{
page
}] = queryContext;
const [activeBlockContextId, setActiveBlockContextId] = useState();
const {
posts,
blocks
} = useSelect(select => {
const {
getEntityRecords,
getTaxonomies
} = select(coreStore);
const {
getBlocks
} = select(blockEditorStore);
const taxonomies = getTaxonomies({
type: postType,
per_page: -1,
context: 'view'
});
const templateCategory = inherit && (templateSlug === null || templateSlug === void 0 ? void 0 : templateSlug.startsWith('category-')) && getEntityRecords('taxonomy', 'category', {
context: 'view',
per_page: 1,
_fields: ['id'],
slug: templateSlug.replace('category-', '')
});
const query = {
offset: perPage ? perPage * (page - 1) + offset : 0,
order,
orderby: orderBy
}; // There is no need to build the taxQuery if we inherit.
if (taxQuery && !inherit) {
// We have to build the tax query for the REST API and use as
// keys the taxonomies `rest_base` with the `term ids` as values.
const builtTaxQuery = Object.entries(taxQuery).reduce((accumulator, _ref3) => {
let [taxonomySlug, terms] = _ref3;
const taxonomy = taxonomies === null || taxonomies === void 0 ? void 0 : taxonomies.find(_ref4 => {
let {
slug
} = _ref4;
return slug === taxonomySlug;
});
if (taxonomy !== null && taxonomy !== void 0 && taxonomy.rest_base) {
accumulator[taxonomy === null || taxonomy === void 0 ? void 0 : taxonomy.rest_base] = terms;
}
return accumulator;
}, {});
if (!!Object.keys(builtTaxQuery).length) {
Object.assign(query, builtTaxQuery);
}
}
if (perPage) {
query.per_page = perPage;
}
if (author) {
query.author = author;
}
if (search) {
query.search = search;
}
if (exclude !== null && exclude !== void 0 && exclude.length) {
query.exclude = exclude;
}
if (parents !== null && parents !== void 0 && parents.length) {
query.parent = parents;
} // If sticky is not set, it will return all posts in the results.
// If sticky is set to `only`, it will limit the results to sticky posts only.
// If it is anything else, it will exclude sticky posts from results. For the record the value stored is `exclude`.
if (sticky) {
query.sticky = sticky === 'only';
} // If `inherit` is truthy, adjust conditionally the query to create a better preview.
if (inherit) {
// Change the post-type if needed.
if (templateSlug !== null && templateSlug !== void 0 && templateSlug.startsWith('archive-')) {
query.postType = templateSlug.replace('archive-', '');
postType = query.postType;
} else if (templateCategory) {
var _templateCategory$;
query.categories = (_templateCategory$ = templateCategory[0]) === null || _templateCategory$ === void 0 ? void 0 : _templateCategory$.id;
}
} // When we preview Query Loop blocks we should prefer the current
// block's postType, which is passed through block context.
const usedPostType = previewPostType || postType;
return {
posts: getEntityRecords('postType', usedPostType, { ...query,
...restQueryArgs
}),
blocks: getBlocks(clientId)
};
}, [perPage, page, offset, order, orderBy, clientId, author, search, postType, exclude, sticky, inherit, templateSlug, taxQuery, parents, restQueryArgs, previewPostType]);
const blockContexts = useMemo(() => posts === null || posts === void 0 ? void 0 : posts.map(post => ({
postType: post.type,
postId: post.id
})), [posts]);
const hasLayoutFlex = layoutType === 'flex' && columns > 1;
const blockProps = useBlockProps({
className: classnames({
'is-flex-container': hasLayoutFlex,
[`columns-${columns}`]: hasLayoutFlex
})
});
if (!posts) {
return createElement("p", blockProps, createElement(Spinner, null));
}
if (!posts.length) {
return createElement("p", blockProps, " ", __('No results found.'));
} // To avoid flicker when switching active block contexts, a preview is rendered
// for each block context, but the preview for the active block context is hidden.
// This ensures that when it is displayed again, the cached rendering of the
// block preview is used, instead of having to re-render the preview from scratch.
return createElement("ul", blockProps, blockContexts && blockContexts.map(blockContext => {
var _blockContexts$, _blockContexts$2;
return createElement(BlockContextProvider, {
key: blockContext.postId,
value: blockContext
}, blockContext.postId === (activeBlockContextId || ((_blockContexts$ = blockContexts[0]) === null || _blockContexts$ === void 0 ? void 0 : _blockContexts$.postId)) ? createElement(PostTemplateInnerBlocks, null) : null, createElement(MemoizedPostTemplateBlockPreview, {
blocks: blocks,
blockContextId: blockContext.postId,
setActiveBlockContextId: setActiveBlockContextId,
isHidden: blockContext.postId === (activeBlockContextId || ((_blockContexts$2 = blockContexts[0]) === null || _blockContexts$2 === void 0 ? void 0 : _blockContexts$2.postId))
}));
}));
}
//# sourceMappingURL=edit.js.map