UNPKG

@wordpress/block-library

Version:
132 lines (128 loc) 4.13 kB
/** * WordPress dependencies */ import { useSelect, useDispatch } from '@wordpress/data'; import { useInstanceId } from '@wordpress/compose'; import { useEffect } from '@wordpress/element'; import { BlockControls, InspectorControls, useBlockProps, useSetting, store as blockEditorStore, useInnerBlocksProps, } from '@wordpress/block-editor'; import { SelectControl } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; /** * Internal dependencies */ import QueryToolbar from './query-toolbar'; import QueryInspectorControls from './inspector-controls'; import { DEFAULTS_POSTS_PER_PAGE } from '../constants'; const TEMPLATE = [ [ 'core/post-template' ] ]; export default function QueryContent( { attributes, setAttributes, openPatternSelectionModal, name, clientId, } ) { const { queryId, query, displayLayout, tagName: TagName = 'div', layout = {}, } = attributes; const { __unstableMarkNextChangeAsNotPersistent } = useDispatch( blockEditorStore ); const instanceId = useInstanceId( QueryContent ); const { themeSupportsLayout } = useSelect( ( select ) => { const { getSettings } = select( blockEditorStore ); return { themeSupportsLayout: getSettings()?.supportsLayout }; }, [] ); const defaultLayout = useSetting( 'layout' ) || {}; const usedLayout = ! layout?.type ? { ...defaultLayout, ...layout, type: 'default' } : { ...defaultLayout, ...layout }; const blockProps = useBlockProps(); const innerBlocksProps = useInnerBlocksProps( blockProps, { template: TEMPLATE, __experimentalLayout: themeSupportsLayout ? usedLayout : undefined, } ); const { postsPerPage } = useSelect( ( select ) => { const { getSettings } = select( blockEditorStore ); return { postsPerPage: +getSettings().postsPerPage || DEFAULTS_POSTS_PER_PAGE, }; }, [] ); // There are some effects running where some initialization logic is // happening and setting some values to some attributes (ex. queryId). // These updates can cause an `undo trap` where undoing will result in // resetting again, so we need to mark these changes as not persistent // with `__unstableMarkNextChangeAsNotPersistent`. // Changes in query property (which is an object) need to be in the same callback, // because updates are batched after the render and changes in different query properties // would cause to override previous wanted changes. useEffect( () => { const newQuery = {}; if ( ! query.perPage && postsPerPage ) { newQuery.perPage = postsPerPage; } if ( !! Object.keys( newQuery ).length ) { __unstableMarkNextChangeAsNotPersistent(); updateQuery( newQuery ); } }, [ query.perPage ] ); // We need this for multi-query block pagination. // Query parameters for each block are scoped to their ID. useEffect( () => { if ( ! Number.isFinite( queryId ) ) { __unstableMarkNextChangeAsNotPersistent(); setAttributes( { queryId: instanceId } ); } }, [ queryId, instanceId ] ); const updateQuery = ( newQuery ) => setAttributes( { query: { ...query, ...newQuery } } ); const updateDisplayLayout = ( newDisplayLayout ) => setAttributes( { displayLayout: { ...displayLayout, ...newDisplayLayout }, } ); return ( <> <QueryInspectorControls attributes={ attributes } setQuery={ updateQuery } setDisplayLayout={ updateDisplayLayout } /> <BlockControls> <QueryToolbar name={ name } clientId={ clientId } attributes={ attributes } setQuery={ updateQuery } setDisplayLayout={ updateDisplayLayout } openPatternSelectionModal={ openPatternSelectionModal } /> </BlockControls> <InspectorControls __experimentalGroup="advanced"> <SelectControl label={ __( 'HTML element' ) } options={ [ { label: __( 'Default (<div>)' ), value: 'div' }, { label: '<main>', value: 'main' }, { label: '<section>', value: 'section' }, { label: '<aside>', value: 'aside' }, ] } value={ TagName } onChange={ ( value ) => setAttributes( { tagName: value } ) } /> </InspectorControls> <TagName { ...innerBlocksProps } /> </> ); }