diff --git a/packages/block-library/CHANGELOG.md b/packages/block-library/CHANGELOG.md
index 226183e04396e..652c89fd3540e 100644
--- a/packages/block-library/CHANGELOG.md
+++ b/packages/block-library/CHANGELOG.md
@@ -2,6 +2,10 @@
## Unreleased
+### New Feature
+
+- Query Loop Block: Moves per page, offset, and pages controls into Inspector Controls. ([#58207](https://github.com/WordPress/gutenberg/pull/58207))
+
## 9.4.0 (2024-07-24)
## 9.3.0 (2024-07-10)
diff --git a/packages/block-library/src/query/edit/inspector-controls/index.js b/packages/block-library/src/query/edit/inspector-controls/index.js
index 5e83ea3aaa973..2601430329092 100644
--- a/packages/block-library/src/query/edit/inspector-controls/index.js
+++ b/packages/block-library/src/query/edit/inspector-controls/index.js
@@ -27,6 +27,9 @@ import { TaxonomyControls } from './taxonomy-controls';
import StickyControl from './sticky-control';
import EnhancedPaginationControl from './enhanced-pagination-control';
import CreateNewPostLink from './create-new-post-link';
+import PerPageControl from './per-page-control';
+import OffsetControl from './offset-controls';
+import PagesControl from './pages-control';
import { unlock } from '../../../lock-unlock';
import {
usePostTypes,
@@ -47,7 +50,10 @@ export default function QueryInspectorControls( props ) {
order,
orderBy,
author: authorIds,
+ pages,
postType,
+ perPage,
+ offset,
sticky,
inherit,
taxQuery,
@@ -135,6 +141,16 @@ export default function QueryInspectorControls( props ) {
showParentControl;
const dropdownMenuProps = useToolsPanelDropdownMenuProps();
+ const showPostCountControl = isControlAllowed(
+ allowedControls,
+ 'postCount'
+ );
+ const showOffSetControl = isControlAllowed( allowedControls, 'offset' );
+ const showPagesControl = isControlAllowed( allowedControls, 'pages' );
+
+ const showDisplayPanel =
+ showPostCountControl || showOffSetControl || showPagesControl;
+
return (
<>
{ !! postType && (
@@ -253,6 +269,47 @@ export default function QueryInspectorControls( props ) {
/>
) }
+ { ! inherit && showDisplayPanel && (
+ {
+ setQuery( {
+ offset: 0,
+ pages: 0,
+ } );
+ } }
+ dropdownMenuProps={ dropdownMenuProps }
+ >
+ perPage > 0 }
+ >
+
+
+ offset > 0 }
+ onDeselect={ () => setQuery( { offset: 0 } ) }
+ >
+
+
+ pages > 0 }
+ onDeselect={ () => setQuery( { pages: 0 } ) }
+ >
+
+
+
+ ) }
{ ! inherit && showFiltersPanel && (
{
+ return (
+ {
+ if (
+ isNaN( newOffset ) ||
+ newOffset < MIN_OFFSET ||
+ newOffset > MAX_OFFSET
+ ) {
+ return;
+ }
+ onChange( { offset: newOffset } );
+ } }
+ />
+ );
+};
+
+export default OffsetControl;
diff --git a/packages/block-library/src/query/edit/inspector-controls/order-control.js b/packages/block-library/src/query/edit/inspector-controls/order-control.js
index 2f6fa0e589d47..d50d3349bcbaf 100644
--- a/packages/block-library/src/query/edit/inspector-controls/order-control.js
+++ b/packages/block-library/src/query/edit/inspector-controls/order-control.js
@@ -27,7 +27,6 @@ const orderOptions = [
function OrderControl( { order, orderBy, onChange } ) {
return (
{
+ return (
+ {
+ if ( isNaN( newPages ) || newPages < 0 ) {
+ return;
+ }
+ onChange( { pages: newPages } );
+ } }
+ help={ __(
+ 'Limit the pages you want to show, even if the query has more results. To show all pages use 0 (zero).'
+ ) }
+ />
+ );
+};
+
+export default PagesControl;
diff --git a/packages/block-library/src/query/edit/inspector-controls/per-page-control.js b/packages/block-library/src/query/edit/inspector-controls/per-page-control.js
new file mode 100644
index 0000000000000..3e0dfbf50b70b
--- /dev/null
+++ b/packages/block-library/src/query/edit/inspector-controls/per-page-control.js
@@ -0,0 +1,33 @@
+/**
+ * WordPress dependencies
+ */
+import { RangeControl } from '@wordpress/components';
+import { __ } from '@wordpress/i18n';
+
+const MIN_POSTS_PER_PAGE = 1;
+const MAX_POSTS_PER_PAGE = 100;
+
+const PerPageControl = ( { perPage, offset = 0, onChange } ) => {
+ return (
+ {
+ if (
+ isNaN( newPerPage ) ||
+ newPerPage < MIN_POSTS_PER_PAGE ||
+ newPerPage > MAX_POSTS_PER_PAGE
+ ) {
+ return;
+ }
+ onChange( { perPage: newPerPage, offset } );
+ } }
+ value={ parseInt( perPage, 10 ) }
+ />
+ );
+};
+
+export default PerPageControl;
diff --git a/packages/block-library/src/query/edit/query-toolbar.js b/packages/block-library/src/query/edit/query-toolbar.js
index ff670d7c001a6..cc2d62a54d529 100644
--- a/packages/block-library/src/query/edit/query-toolbar.js
+++ b/packages/block-library/src/query/edit/query-toolbar.js
@@ -1,14 +1,8 @@
/**
* WordPress dependencies
*/
-import {
- ToolbarGroup,
- Dropdown,
- ToolbarButton,
- __experimentalNumberControl as NumberControl,
-} from '@wordpress/components';
+import { ToolbarGroup, ToolbarButton } from '@wordpress/components';
import { __ } from '@wordpress/i18n';
-import { settings } from '@wordpress/icons';
/**
* Internal dependencies
@@ -16,8 +10,6 @@ import { settings } from '@wordpress/icons';
import { usePatterns } from '../utils';
export default function QueryToolbar( {
- attributes: { query },
- setQuery,
openPatternSelectionModal,
name,
clientId,
@@ -26,87 +18,6 @@ export default function QueryToolbar( {
return (
<>
- { ! query.inherit && (
-
- (
-
- ) }
- renderContent={ () => (
- <>
- {
- if (
- isNaN( value ) ||
- value < 1 ||
- value > 100
- ) {
- return;
- }
- setQuery( {
- perPage: value,
- } );
- } }
- step="1"
- value={ query.perPage }
- isDragEnabled={ false }
- />
- {
- if (
- isNaN( value ) ||
- value < 0 ||
- value > 100
- ) {
- return;
- }
- setQuery( { offset: value } );
- } }
- step="1"
- value={ query.offset }
- isDragEnabled={ false }
- />
- {
- if ( isNaN( value ) || value < 0 ) {
- return;
- }
- setQuery( { pages: value } );
- } }
- step="1"
- value={ query.pages }
- isDragEnabled={ false }
- help={ __(
- 'Limit the pages you want to show, even if the query has more results. To show all pages use 0 (zero).'
- ) }
- />
- >
- ) }
- />
-
- ) }
{ hasPatterns && (
diff --git a/packages/e2e-tests/plugins/observe-typing.php b/packages/e2e-tests/plugins/observe-typing.php
new file mode 100644
index 0000000000000..a9152bc79684c
--- /dev/null
+++ b/packages/e2e-tests/plugins/observe-typing.php
@@ -0,0 +1,28 @@
+
+ el(
+ ToolbarButton,
+ {
+ onClick: onToggle,
+ },
+ 'Open Dropdown'
+ ),
+ renderContent: () =>
+ el( TextControl, {
+ label: 'Dropdown field',
+ value,
+ onChange: setValue,
+ __next40pxDefaultSize: true,
+ } ),
+ } )
+ ),
+ el( 'p', {}, 'Hello Editor!' )
+ );
+ },
+ save: () => null,
+ } );
+} )();
diff --git a/test/e2e/specs/editor/various/is-typing.spec.js b/test/e2e/specs/editor/various/is-typing.spec.js
index 10ac90d108412..da4492a89bef3 100644
--- a/test/e2e/specs/editor/various/is-typing.spec.js
+++ b/test/e2e/specs/editor/various/is-typing.spec.js
@@ -4,10 +4,18 @@
const { test, expect } = require( '@wordpress/e2e-test-utils-playwright' );
test.describe( 'isTyping', () => {
+ test.beforeAll( async ( { requestUtils } ) => {
+ await requestUtils.activatePlugin( 'gutenberg-test-observe-typing' );
+ } );
+
test.beforeEach( async ( { admin } ) => {
await admin.createNewPost();
} );
+ test.afterAll( async ( { requestUtils } ) => {
+ await requestUtils.deactivatePlugin( 'gutenberg-test-observe-typing' );
+ } );
+
test( 'should hide the toolbar when typing', async ( { editor, page } ) => {
// Enter to reach paragraph block.
await page.keyboard.press( 'Enter' );
@@ -42,33 +50,23 @@ test.describe( 'isTyping', () => {
page,
} ) => {
// Add a block with a dropdown in the toolbar that contains an input.
- await editor.insertBlock( { name: 'core/query' } );
-
- await editor.canvas
- .getByRole( 'document', { name: 'Block: Query Loop' } )
- .getByRole( 'button', { name: 'Start blank' } )
- .click();
-
- await editor.canvas
- .getByRole( 'button', { name: 'Title & Date' } )
- .click();
-
- await editor.openDocumentSettingsSidebar();
- await page.getByLabel( 'Custom' ).click();
+ await editor.insertBlock( { name: 'e2e-tests/observe-typing' } );
// Moving the mouse shows the toolbar.
await editor.showBlockToolbar();
// Open the dropdown.
- const displaySettings = page.getByRole( 'button', {
- name: 'Display settings',
+ await page
+ .getByRole( 'button', {
+ name: 'Open Dropdown',
+ } )
+ .click();
+
+ const textControl = page.getByRole( 'textbox', {
+ name: 'Dropdown field',
} );
- await displaySettings.click();
- const itemsPerPageInput = page.getByLabel( 'Items per Page' );
- // Make sure we're where we think we are
- await expect( itemsPerPageInput ).toBeFocused();
// Type inside the dropdown's input
- await page.keyboard.type( '00' );
+ await textControl.pressSequentially( 'Hello' );
// The input should still be visible.
- await expect( itemsPerPageInput ).toBeVisible();
+ await expect( textControl ).toBeVisible();
} );
} );