@wordpress/block-library
Version:
Block library for the WordPress editor.
347 lines (344 loc) • 13.6 kB
JavaScript
/**
* WordPress dependencies
*/
import { TextControl, SelectControl, Notice, __experimentalVStack as VStack, __experimentalToolsPanel as ToolsPanel, __experimentalToolsPanelItem as ToolsPanelItem, __experimentalToggleGroupControl as ToggleGroupControl, __experimentalToggleGroupControlOption as ToggleGroupControlOption } from '@wordpress/components';
import { useSelect } from '@wordpress/data';
import { store as coreStore } from '@wordpress/core-data';
import { __ } from '@wordpress/i18n';
import { debounce } from '@wordpress/compose';
import { useState, useMemo } from '@wordpress/element';
/**
* Internal dependencies
*/
import OrderControl from './order-control';
import AuthorControl from './author-control';
import ParentControl from './parent-control';
import { TaxonomyControls } from './taxonomy-controls';
import FormatControls from './format-controls';
import StickyControl from './sticky-control';
import PerPageControl from './per-page-control';
import OffsetControl from './offset-controls';
import PagesControl from './pages-control';
import { usePostTypes, useIsPostTypeHierarchical, useAllowedControls, isControlAllowed, useTaxonomies, useOrderByOptions } from '../../utils';
import { useToolsPanelDropdownMenuProps } from '../../../utils/hooks';
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
export default function QueryInspectorControls(props) {
const {
attributes,
setQuery,
isSingular
} = props;
const {
query
} = attributes;
const {
order,
orderBy,
author: authorIds,
pages,
postType,
perPage,
offset,
sticky,
inherit,
taxQuery,
parents,
format
} = query;
const allowedControls = useAllowedControls(attributes);
const showSticky = postType === 'post';
const {
postTypesTaxonomiesMap,
postTypesSelectOptions,
postTypeFormatSupportMap
} = usePostTypes();
const taxonomies = useTaxonomies(postType);
const isPostTypeHierarchical = useIsPostTypeHierarchical(postType);
const onPostTypeChange = newValue => {
const updateQuery = {
postType: newValue
};
// We need to dynamically update the `taxQuery` property,
// by removing any not supported taxonomy from the query.
const supportedTaxonomies = postTypesTaxonomiesMap[newValue];
const updatedTaxQuery = Object.entries(taxQuery || {}).reduce((accumulator, [taxonomySlug, terms]) => {
if (supportedTaxonomies.includes(taxonomySlug)) {
accumulator[taxonomySlug] = terms;
}
return accumulator;
}, {});
updateQuery.taxQuery = !!Object.keys(updatedTaxQuery).length ? updatedTaxQuery : undefined;
if (newValue !== 'post') {
updateQuery.sticky = '';
}
// We need to reset `parents` because they are tied to each post type.
updateQuery.parents = [];
// Post types can register post format support with `add_post_type_support`.
// But we need to reset the `format` property when switching to post types
// that do not support post formats.
const hasFormatSupport = postTypeFormatSupportMap[newValue];
if (!hasFormatSupport) {
updateQuery.format = [];
}
setQuery(updateQuery);
};
const [querySearch, setQuerySearch] = useState(query.search);
const debouncedQuerySearch = useMemo(() => {
return debounce(newQuerySearch => {
setQuery({
search: newQuerySearch
});
}, 250);
}, [setQuery]);
const orderByOptions = useOrderByOptions(postType);
const showInheritControl = isControlAllowed(allowedControls, 'inherit');
const showPostTypeControl = !inherit && isControlAllowed(allowedControls, 'postType');
const postTypeControlLabel = __('Post type');
const postTypeControlHelp = __('Select the type of content to display: posts, pages, or custom post types.');
const showOrderControl = !inherit && isControlAllowed(allowedControls, 'order');
const showStickyControl = !inherit && showSticky && isControlAllowed(allowedControls, 'sticky');
const showSettingsPanel = showInheritControl || showPostTypeControl || showOrderControl || showStickyControl;
const showTaxControl = !!taxonomies?.length && isControlAllowed(allowedControls, 'taxQuery');
const showAuthorControl = isControlAllowed(allowedControls, 'author');
const showSearchControl = isControlAllowed(allowedControls, 'search');
const showParentControl = isControlAllowed(allowedControls, 'parents') && isPostTypeHierarchical;
const postTypeHasFormatSupport = postTypeFormatSupportMap[postType];
const showFormatControl = useSelect(select => {
// Check if the post type supports post formats and if the control is allowed.
if (!postTypeHasFormatSupport || !isControlAllowed(allowedControls, 'format')) {
return false;
}
const themeSupports = select(coreStore).getThemeSupports();
// If there are no supported formats, getThemeSupports still includes the default 'standard' format,
// and in this case the control should not be shown since the user has no other formats to choose from.
return themeSupports.formats && themeSupports.formats.length > 0 && themeSupports.formats.some(type => type !== 'standard');
}, [allowedControls, postTypeHasFormatSupport]);
const showFiltersPanel = showTaxControl || showAuthorControl || showSearchControl || showParentControl || showFormatControl;
const dropdownMenuProps = useToolsPanelDropdownMenuProps();
const showPostCountControl = isControlAllowed(allowedControls, 'postCount');
const showOffSetControl = isControlAllowed(allowedControls, 'offset');
const showPagesControl = isControlAllowed(allowedControls, 'pages');
const showDisplayPanel = showPostCountControl || showOffSetControl || showPagesControl;
// The block cannot inherit a default WordPress query in singular content (e.g., post, page, 404, blank).
// Warn users but still permit this type of query for exceptional cases in Classic and Hybrid themes.
const hasInheritanceWarning = isSingular && inherit;
return /*#__PURE__*/_jsxs(_Fragment, {
children: [showSettingsPanel && /*#__PURE__*/_jsxs(ToolsPanel, {
label: __('Settings'),
resetAll: () => {
setQuery({
postType: 'post',
order: 'desc',
orderBy: 'date',
sticky: '',
inherit: true
});
},
dropdownMenuProps: dropdownMenuProps,
children: [showInheritControl && /*#__PURE__*/_jsx(ToolsPanelItem, {
hasValue: () => !inherit,
label: __('Query type'),
onDeselect: () => setQuery({
inherit: true
}),
isShownByDefault: true,
children: /*#__PURE__*/_jsxs(VStack, {
spacing: 4,
children: [/*#__PURE__*/_jsxs(ToggleGroupControl, {
__next40pxDefaultSize: true,
__nextHasNoMarginBottom: true,
label: __('Query type'),
isBlock: true,
onChange: value => {
setQuery({
inherit: value === 'default'
});
},
help: inherit ? __('Display a list of posts or custom post types based on the current template.') : __('Display a list of posts or custom post types based on specific criteria.'),
value: !!inherit ? 'default' : 'custom',
children: [/*#__PURE__*/_jsx(ToggleGroupControlOption, {
value: "default",
label: __('Default')
}), /*#__PURE__*/_jsx(ToggleGroupControlOption, {
value: "custom",
label: __('Custom')
})]
}), hasInheritanceWarning && /*#__PURE__*/_jsx(Notice, {
status: "warning",
isDismissible: false,
children: __('Cannot inherit the current template query when placed inside the singular content (e.g., post, page, 404, blank).')
})]
})
}), showPostTypeControl && /*#__PURE__*/_jsx(ToolsPanelItem, {
hasValue: () => postType !== 'post',
label: postTypeControlLabel,
onDeselect: () => onPostTypeChange('post'),
isShownByDefault: true,
children: postTypesSelectOptions.length > 2 ? /*#__PURE__*/_jsx(SelectControl, {
__nextHasNoMarginBottom: true,
__next40pxDefaultSize: true,
options: postTypesSelectOptions,
value: postType,
label: postTypeControlLabel,
onChange: onPostTypeChange,
help: postTypeControlHelp
}) : /*#__PURE__*/_jsx(ToggleGroupControl, {
__nextHasNoMarginBottom: true,
__next40pxDefaultSize: true,
isBlock: true,
value: postType,
label: postTypeControlLabel,
onChange: onPostTypeChange,
help: postTypeControlHelp,
children: postTypesSelectOptions.map(option => /*#__PURE__*/_jsx(ToggleGroupControlOption, {
value: option.value,
label: option.label
}, option.value))
})
}), showOrderControl && /*#__PURE__*/_jsx(ToolsPanelItem, {
hasValue: () => order !== 'desc' || orderBy !== 'date',
label: __('Order by'),
onDeselect: () => setQuery({
order: 'desc',
orderBy: 'date'
}),
isShownByDefault: true,
children: /*#__PURE__*/_jsx(OrderControl, {
order,
orderBy,
orderByOptions,
onChange: setQuery
})
}), showStickyControl && /*#__PURE__*/_jsx(ToolsPanelItem, {
hasValue: () => !!sticky,
label: __('Sticky posts'),
onDeselect: () => setQuery({
sticky: ''
}),
isShownByDefault: true,
children: /*#__PURE__*/_jsx(StickyControl, {
value: sticky,
onChange: value => setQuery({
sticky: value
})
})
})]
}), !inherit && showDisplayPanel && /*#__PURE__*/_jsxs(ToolsPanel, {
className: "block-library-query-toolspanel__display",
label: __('Display'),
resetAll: () => {
setQuery({
offset: 0,
pages: 0
});
},
dropdownMenuProps: dropdownMenuProps,
children: [/*#__PURE__*/_jsx(ToolsPanelItem, {
label: __('Items per page'),
hasValue: () => perPage > 0,
children: /*#__PURE__*/_jsx(PerPageControl, {
perPage: perPage,
offset: offset,
onChange: setQuery
})
}), /*#__PURE__*/_jsx(ToolsPanelItem, {
label: __('Offset'),
hasValue: () => offset > 0,
onDeselect: () => setQuery({
offset: 0
}),
children: /*#__PURE__*/_jsx(OffsetControl, {
offset: offset,
onChange: setQuery
})
}), /*#__PURE__*/_jsx(ToolsPanelItem, {
label: __('Max pages to show'),
hasValue: () => pages > 0,
onDeselect: () => setQuery({
pages: 0
}),
children: /*#__PURE__*/_jsx(PagesControl, {
pages: pages,
onChange: setQuery
})
})]
}), !inherit && showFiltersPanel && /*#__PURE__*/_jsxs(ToolsPanel, {
className: "block-library-query-toolspanel__filters" // unused but kept for backward compatibility
,
label: __('Filters'),
resetAll: () => {
setQuery({
author: '',
parents: [],
search: '',
taxQuery: null,
format: []
});
setQuerySearch('');
},
dropdownMenuProps: dropdownMenuProps,
children: [showTaxControl && /*#__PURE__*/_jsx(ToolsPanelItem, {
label: __('Taxonomies'),
hasValue: () => Object.values(taxQuery || {}).some(terms => !!terms.length),
onDeselect: () => setQuery({
taxQuery: null
}),
children: /*#__PURE__*/_jsx(TaxonomyControls, {
onChange: setQuery,
query: query
})
}), showAuthorControl && /*#__PURE__*/_jsx(ToolsPanelItem, {
hasValue: () => !!authorIds,
label: __('Authors'),
onDeselect: () => setQuery({
author: ''
}),
children: /*#__PURE__*/_jsx(AuthorControl, {
value: authorIds,
onChange: setQuery
})
}), showSearchControl && /*#__PURE__*/_jsx(ToolsPanelItem, {
hasValue: () => !!querySearch,
label: __('Keyword'),
onDeselect: () => {
setQuery({
search: ''
});
setQuerySearch('');
},
children: /*#__PURE__*/_jsx(TextControl, {
__nextHasNoMarginBottom: true,
__next40pxDefaultSize: true,
label: __('Keyword'),
value: querySearch,
onChange: newQuerySearch => {
debouncedQuerySearch(newQuerySearch);
setQuerySearch(newQuerySearch);
}
})
}), showParentControl && /*#__PURE__*/_jsx(ToolsPanelItem, {
hasValue: () => !!parents?.length,
label: __('Parents'),
onDeselect: () => setQuery({
parents: []
}),
children: /*#__PURE__*/_jsx(ParentControl, {
parents: parents,
postType: postType,
onChange: setQuery
})
}), showFormatControl && /*#__PURE__*/_jsx(ToolsPanelItem, {
hasValue: () => !!format?.length,
label: __('Formats'),
onDeselect: () => setQuery({
format: []
}),
children: /*#__PURE__*/_jsx(FormatControls, {
onChange: setQuery,
query: query
})
})]
})]
});
}
//# sourceMappingURL=index.js.map