-## Usage
-
-Render a GradientPicker.
+GradientPicker is a React component that renders a color gradient picker to
+define a multi step gradient. There's either a _linear_ or a _radial_ type
+available.
```jsx
import { useState } from 'react';
import { GradientPicker } from '@wordpress/components';
-const myGradientPicker = () => {
- const [ gradient, setGradient ] = useState( null );
-
- return (
- setGradient( currentGradient ) }
- gradients={ [
- {
- name: 'JShine',
- gradient:
- 'linear-gradient(135deg,#12c2e9 0%,#c471ed 50%,#f64f59 100%)',
- slug: 'jshine',
- },
- {
- name: 'Moonlit Asteroid',
- gradient:
- 'linear-gradient(135deg,#0F2027 0%, #203A43 0%, #2c5364 100%)',
- slug: 'moonlit-asteroid',
- },
- {
- name: 'Rastafarie',
- gradient:
- 'linear-gradient(135deg,#1E9600 0%, #FFF200 0%, #FF0000 100%)',
- slug: 'rastafari',
- },
- ] }
- />
- );
+const MyGradientPicker = () => {
+ const [ gradient, setGradient ] = useState( null );
+
+ return (
+ setGradient( currentGradient ) }
+ gradients={ [
+ {
+ name: 'JShine',
+ gradient:
+ 'linear-gradient(135deg,#12c2e9 0%,#c471ed 50%,#f64f59 100%)',
+ slug: 'jshine',
+ },
+ {
+ name: 'Moonlit Asteroid',
+ gradient:
+ 'linear-gradient(135deg,#0F2027 0%, #203A43 0%, #2c5364 100%)',
+ slug: 'moonlit-asteroid',
+ },
+ {
+ name: 'Rastafarie',
+ gradient:
+ 'linear-gradient(135deg,#1E9600 0%, #FFF200 0%, #FF0000 100%)',
+ slug: 'rastafari',
+ },
+ ] }
+ />
+ );
};
```
-
## Props
-The component accepts the following props:
+### `__experimentalIsRenderedInSidebar`
-### `className`: `string`
+Whether this is rendered in the sidebar.
-The class name added to the wrapper.
+ - Type: `boolean`
+ - Required: No
+ - Default: `false`
-- Required: No
+### `asButtons`
-### `value`: `string`
+Whether the control should present as a set of buttons,
+each with its own tab stop.
-The current value of the gradient. Pass a css gradient like `linear-gradient(90deg, rgb(6, 147, 227) 0%, rgb(155, 81, 224) 100%)`. Optionally pass in a `null` value to specify no gradient is currently selected.
+ - Type: `boolean`
+ - Required: No
+ - Default: `false`
-- Required: No
-- Default: `linear-gradient(90deg, rgb(6, 147, 227) 0%, rgb(155, 81, 224) 100%)`
+### `aria-label`
-### `onChange`: `( currentGradient: string | undefined ) => void`
+A label to identify the purpose of the control.
-The function called when a new gradient has been defined. It is passed the `currentGradient` as an argument.
+ - Type: `string`
+ - Required: No
-- Required: Yes
+### `aria-labelledby`
-### `gradients`: `GradientsProp[]`
+An ID of an element to provide a label for the control.
-An array of objects of predefined gradients displayed above the gradient selector.
+ - Type: `string`
+ - Required: No
+
+### `className`
+
+The class name added to the wrapper.
-- Required: No
-- Default: `[]`
+ - Type: `string`
+ - Required: No
-### `clearable`: `boolean`
+### `clearable`
Whether the palette should have a clearing button or not.
-- Required: No
-- Default: true
+ - Type: `boolean`
+ - Required: No
+ - Default: `true`
+
+### `disableCustomGradients`
+
+If true, the gradient picker will not be displayed and only defined
+gradients from `gradients` will be shown.
+
+ - Type: `boolean`
+ - Required: No
+ - Default: `false`
+
+### `gradients`
+
+An array of objects as predefined gradients displayed above the gradient
+selector. Alternatively, if there are multiple sets (or 'origins') of
+gradients, you can pass an array of objects each with a `name` and a
+`gradients` array which will in turn contain the predefined gradient objects.
+
+ - Type: `GradientsProp`
+ - Required: No
+ - Default: `[]`
-### `disableCustomGradients`: `boolean`
+### `headingLevel`
-If true, the gradient picker will not be displayed and only defined gradients from `gradients` are available.
+The heading level. Only applies in cases where gradients are provided
+from multiple origins (i.e. when the array passed as the `gradients` prop
+contains two or more items).
-- Required: No
-- Default: false
+ - Type: `1 | 2 | 3 | 4 | 5 | 6 | "1" | "2" | "3" | "4" | ...`
+ - Required: No
+ - Default: `2`
-### `headingLevel`: `1 | 2 | 3 | 4 | 5 | 6 | '1' | '2' | '3' | '4' | '5' | '6'`
+### `loop`
-The heading level. Only applies in cases where gradients are provided from multiple origins (ie. when the array passed as the `gradients` prop contains two or more items).
+Prevents keyboard interaction from wrapping around.
+Only used when `asButtons` is not true.
-- Required: No
-- Default: `2`
+ - Type: `boolean`
+ - Required: No
+ - Default: `true`
-### `asButtons`: `boolean`
+### `onChange`
-Whether the control should present as a set of buttons, each with its own tab stop.
+The function called when a new gradient has been defined. It is passed to
+the `currentGradient` as an argument.
-- Required: No
-- Default: `false`
+ - Type: `(currentGradient: string) => void`
+ - Required: Yes
-### `loop`: `boolean`
+### `value`
-Prevents keyboard interaction from wrapping around. Only used when `asButtons` is not true.
+The current value of the gradient. Pass a css gradient string (See default value for example).
+Optionally pass in a `null` value to specify no gradient is currently selected.
-- Required: No
-- Default: `true`
+ - Type: `string`
+ - Required: No
+ - Default: `'linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%)'`
diff --git a/packages/components/src/gradient-picker/docs-manifest.json b/packages/components/src/gradient-picker/docs-manifest.json
new file mode 100644
index 00000000000000..6bea56ccc678c6
--- /dev/null
+++ b/packages/components/src/gradient-picker/docs-manifest.json
@@ -0,0 +1,5 @@
+{
+ "$schema": "../../schemas/docs-manifest.json",
+ "displayName": "GradientPicker",
+ "filePath": "./index.tsx"
+}
diff --git a/packages/components/src/gradient-picker/index.tsx b/packages/components/src/gradient-picker/index.tsx
index f0607badd1b03a..124a89c7e016e1 100644
--- a/packages/components/src/gradient-picker/index.tsx
+++ b/packages/components/src/gradient-picker/index.tsx
@@ -166,44 +166,44 @@ function Component( props: PickerProps< any > ) {
}
/**
- * GradientPicker is a React component that renders a color gradient picker to
+ * GradientPicker is a React component that renders a color gradient picker to
* define a multi step gradient. There's either a _linear_ or a _radial_ type
* available.
*
* ```jsx
- *import { GradientPicker } from '@wordpress/components';
- *import { useState } from '@wordpress/element';
+ * import { useState } from 'react';
+ * import { GradientPicker } from '@wordpress/components';
*
- *const myGradientPicker = () => {
- * const [ gradient, setGradient ] = useState( null );
+ * const MyGradientPicker = () => {
+ * const [ gradient, setGradient ] = useState( null );
*
- * return (
- * setGradient( currentGradient ) }
- * gradients={ [
- * {
- * name: 'JShine',
- * gradient:
- * 'linear-gradient(135deg,#12c2e9 0%,#c471ed 50%,#f64f59 100%)',
- * slug: 'jshine',
- * },
- * {
- * name: 'Moonlit Asteroid',
- * gradient:
- * 'linear-gradient(135deg,#0F2027 0%, #203A43 0%, #2c5364 100%)',
- * slug: 'moonlit-asteroid',
- * },
- * {
- * name: 'Rastafarie',
- * gradient:
- * 'linear-gradient(135deg,#1E9600 0%, #FFF200 0%, #FF0000 100%)',
- * slug: 'rastafari',
- * },
- * ] }
- * />
- * );
- *};
+ * return (
+ * setGradient( currentGradient ) }
+ * gradients={ [
+ * {
+ * name: 'JShine',
+ * gradient:
+ * 'linear-gradient(135deg,#12c2e9 0%,#c471ed 50%,#f64f59 100%)',
+ * slug: 'jshine',
+ * },
+ * {
+ * name: 'Moonlit Asteroid',
+ * gradient:
+ * 'linear-gradient(135deg,#0F2027 0%, #203A43 0%, #2c5364 100%)',
+ * slug: 'moonlit-asteroid',
+ * },
+ * {
+ * name: 'Rastafarie',
+ * gradient:
+ * 'linear-gradient(135deg,#1E9600 0%, #FFF200 0%, #FF0000 100%)',
+ * slug: 'rastafari',
+ * },
+ * ] }
+ * />
+ * );
+ * };
*```
*
*/
diff --git a/packages/components/src/gradient-picker/types.ts b/packages/components/src/gradient-picker/types.ts
index b563653e33e4c4..8ac2c6de9f2cf3 100644
--- a/packages/components/src/gradient-picker/types.ts
+++ b/packages/components/src/gradient-picker/types.ts
@@ -36,7 +36,7 @@ type GradientPickerBaseProps = {
clearable?: boolean;
/**
* The heading level. Only applies in cases where gradients are provided
- * from multiple origins (ie. when the array passed as the `gradients` prop
+ * from multiple origins (i.e. when the array passed as the `gradients` prop
* contains two or more items).
*
* @default 2
@@ -58,19 +58,17 @@ type GradientPickerBaseProps = {
loop?: boolean;
} & (
| {
+ // TODO: [#54055] Either this or `aria-labelledby` should be required
/**
* A label to identify the purpose of the control.
- *
- * @todo [#54055] Either this or `aria-labelledby` should be required
*/
'aria-label'?: string;
'aria-labelledby'?: never;
}
| {
+ // TODO: [#54055] Either this or `aria-label` should be required
/**
* An ID of an element to provide a label for the control.
- *
- * @todo [#54055] Either this or `aria-label` should be required
*/
'aria-labelledby'?: string;
'aria-label'?: never;
diff --git a/packages/components/src/menu-group/stories/index.story.tsx b/packages/components/src/menu-group/stories/index.story.tsx
index 7cb9004b45a8c2..f53cbbf5b7b0a0 100644
--- a/packages/components/src/menu-group/stories/index.story.tsx
+++ b/packages/components/src/menu-group/stories/index.story.tsx
@@ -16,8 +16,9 @@ import MenuItemsChoice from '../../menu-items-choice';
import type { Meta, StoryFn } from '@storybook/react';
const meta: Meta< typeof MenuGroup > = {
- title: 'Components/MenuGroup',
+ title: 'Components/Actions/MenuGroup',
component: MenuGroup,
+ id: 'components-menugroup',
argTypes: {
children: { control: { type: null } },
},
diff --git a/packages/components/src/menu-item/stories/index.story.tsx b/packages/components/src/menu-item/stories/index.story.tsx
index 763ee6e96be922..24c592b66f3aea 100644
--- a/packages/components/src/menu-item/stories/index.story.tsx
+++ b/packages/components/src/menu-item/stories/index.story.tsx
@@ -17,7 +17,8 @@ import Shortcut from '../../shortcut';
const meta: Meta< typeof MenuItem > = {
component: MenuItem,
- title: 'Components/MenuItem',
+ title: 'Components/Actions/MenuItem',
+ id: 'components-menuitem',
argTypes: {
children: { control: { type: null } },
icon: {
diff --git a/packages/components/src/menu-items-choice/stories/index.story.tsx b/packages/components/src/menu-items-choice/stories/index.story.tsx
index 02e76158981e8e..f4a14054e8f27f 100644
--- a/packages/components/src/menu-items-choice/stories/index.story.tsx
+++ b/packages/components/src/menu-items-choice/stories/index.story.tsx
@@ -16,7 +16,8 @@ import MenuGroup from '../../menu-group';
const meta: Meta< typeof MenuItemsChoice > = {
component: MenuItemsChoice,
- title: 'Components/MenuItemsChoice',
+ title: 'Components/Actions/MenuItemsChoice',
+ id: 'components-menuitemschoice',
argTypes: {
onHover: { action: 'onHover' },
onSelect: { action: 'onSelect' },
diff --git a/packages/components/src/private-apis.ts b/packages/components/src/private-apis.ts
index bea16b719a463d..2ced100dc576be 100644
--- a/packages/components/src/private-apis.ts
+++ b/packages/components/src/private-apis.ts
@@ -2,7 +2,6 @@
* Internal dependencies
*/
import { positionToPlacement as __experimentalPopoverLegacyPositionToPlacement } from './popover/utils';
-import { createPrivateSlotFill } from './slot-fill';
import { Menu } from './menu';
import { ComponentsContext } from './context/context-system-provider';
import Theme from './theme';
@@ -13,7 +12,6 @@ import { lock } from './lock-unlock';
export const privateApis = {};
lock( privateApis, {
__experimentalPopoverLegacyPositionToPlacement,
- createPrivateSlotFill,
ComponentsContext,
Tabs,
Theme,
diff --git a/packages/components/src/range-control/README.md b/packages/components/src/range-control/README.md
index cfa8c76740e74f..f21285c5f26256 100644
--- a/packages/components/src/range-control/README.md
+++ b/packages/components/src/range-control/README.md
@@ -88,9 +88,10 @@ import { RangeControl } from '@wordpress/components';
const MyRangeControl = () => {
const [ columns, setColumns ] = useState( 2 );
- return(
+ return (
setColumns( value ) }
@@ -153,7 +154,6 @@ Disables the `input`, preventing new values from being applied.
- Required: No
- Platform: Web
-
### `help`: `string|Element`
If this property is added, a help text will be generated using help property as the content.
@@ -165,7 +165,7 @@ If this property is added, a help text will be generated using help property as
Provides control over whether the label will only be visible to screen readers.
-- Required: No
+- Required: No
### `icon`: `string`
@@ -334,6 +334,7 @@ The minimum amount by which `value` changes. It is also a factor in validation a
- Required: No
- Platform: Web
+
### `trackColor`: `CSSProperties[ 'color' ]`
CSS color string to customize the track element's background.
diff --git a/packages/components/src/range-control/index.tsx b/packages/components/src/range-control/index.tsx
index c9fbdc0055c855..916571c3ee0e05 100644
--- a/packages/components/src/range-control/index.tsx
+++ b/packages/components/src/range-control/index.tsx
@@ -38,6 +38,7 @@ import {
import type { RangeControlProps } from './types';
import type { WordPressComponentProps } from '../context';
import { space } from '../utils/space';
+import { maybeWarnDeprecated36pxSize } from '../utils/deprecated-36px-size';
const noop = () => {};
@@ -96,6 +97,7 @@ function UnforwardedRangeControl(
trackColor,
value: valueProp,
withInputField = true,
+ __shouldNotWarnDeprecated36pxSize,
...otherProps
} = props;
@@ -229,6 +231,14 @@ function UnforwardedRangeControl(
[ isRTL() ? 'right' : 'left' ]: fillValueOffset,
};
+ // Add default size deprecation warning.
+ maybeWarnDeprecated36pxSize( {
+ componentName: 'RangeControl',
+ __next40pxDefaultSize,
+ size: undefined,
+ __shouldNotWarnDeprecated36pxSize,
+ } );
+
return (
= ( { onChange, ...args } ) => {
export const Default: StoryFn< typeof RangeControl > = Template.bind( {} );
Default.args = {
__nextHasNoMarginBottom: true,
+ __next40pxDefaultSize: true,
help: 'Please select how transparent you would like this.',
initialPosition: 50,
label: 'Opacity',
@@ -107,6 +108,7 @@ export const WithAnyStep: StoryFn< typeof RangeControl > = ( {
};
WithAnyStep.args = {
__nextHasNoMarginBottom: true,
+ __next40pxDefaultSize: true,
label: 'Brightness',
step: 'any',
};
@@ -171,6 +173,7 @@ export const WithIntegerStepAndMarks: StoryFn< typeof RangeControl > =
WithIntegerStepAndMarks.args = {
__nextHasNoMarginBottom: true,
+ __next40pxDefaultSize: true,
label: 'Integer Step',
marks: marksBase,
max: 10,
@@ -188,6 +191,7 @@ export const WithDecimalStepAndMarks: StoryFn< typeof RangeControl > =
WithDecimalStepAndMarks.args = {
__nextHasNoMarginBottom: true,
+ __next40pxDefaultSize: true,
marks: [
...marksBase,
{ value: 3.5, label: '3.5' },
@@ -208,6 +212,7 @@ export const WithNegativeMinimumAndMarks: StoryFn< typeof RangeControl > =
WithNegativeMinimumAndMarks.args = {
__nextHasNoMarginBottom: true,
+ __next40pxDefaultSize: true,
marks: marksWithNegatives,
max: 10,
min: -10,
@@ -224,6 +229,7 @@ export const WithNegativeRangeAndMarks: StoryFn< typeof RangeControl > =
WithNegativeRangeAndMarks.args = {
__nextHasNoMarginBottom: true,
+ __next40pxDefaultSize: true,
marks: marksWithNegatives,
max: -1,
min: -10,
@@ -240,6 +246,7 @@ export const WithAnyStepAndMarks: StoryFn< typeof RangeControl > =
WithAnyStepAndMarks.args = {
__nextHasNoMarginBottom: true,
+ __next40pxDefaultSize: true,
marks: marksBase,
max: 10,
min: 0,
diff --git a/packages/components/src/range-control/test/index.tsx b/packages/components/src/range-control/test/index.tsx
index 3ce741867d0dbc..3d2db30eea186f 100644
--- a/packages/components/src/range-control/test/index.tsx
+++ b/packages/components/src/range-control/test/index.tsx
@@ -18,7 +18,13 @@ const fireChangeEvent = ( input: HTMLInputElement, value?: number | string ) =>
const RangeControl = (
props: React.ComponentProps< typeof _RangeControl >
) => {
- return <_RangeControl { ...props } __nextHasNoMarginBottom />;
+ return (
+ <_RangeControl
+ { ...props }
+ __nextHasNoMarginBottom
+ __next40pxDefaultSize
+ />
+ );
};
describe( 'RangeControl', () => {
diff --git a/packages/components/src/range-control/types.ts b/packages/components/src/range-control/types.ts
index a427ab4f942af6..e4792296f83144 100644
--- a/packages/components/src/range-control/types.ts
+++ b/packages/components/src/range-control/types.ts
@@ -233,6 +233,13 @@ export type RangeControlProps = Pick<
* @default true
*/
withInputField?: boolean;
+ /**
+ * Do not throw a warning for the deprecated 36px default size.
+ * For internal components of other components that already throw the warning.
+ *
+ * @ignore
+ */
+ __shouldNotWarnDeprecated36pxSize?: boolean;
};
export type RailProps = MarksProps & {
diff --git a/packages/components/src/slot-fill/README.md b/packages/components/src/slot-fill/README.md
index 9059566deefdf4..3f14b9ccde9eeb 100644
--- a/packages/components/src/slot-fill/README.md
+++ b/packages/components/src/slot-fill/README.md
@@ -1,18 +1,18 @@
-# Slot Fill
+# Slot/Fill
-Slot and Fill are a pair of components which enable developers to render elsewhere in a React element tree, a pattern often referred to as "portal" rendering. It is a pattern for component extensibility, where a single Slot may be occupied by an indeterminate number of Fills elsewhere in the application.
+`Slot` and `Fill` are a pair of components which enable developers to render React UI elsewhere in a React element tree, a pattern often referred to as "portal" rendering. It is a pattern for component extensibility, where a single `Slot` may be occupied by multiple `Fill`s rendered in different parts of the application.
-Slot Fill is heavily inspired by the [`react-slot-fill` library](https://github.com/camwest/react-slot-fill), but uses React's own portal rendering API.
+Slot/Fill was originally inspired by the [`react-slot-fill` library](https://github.com/camwest/react-slot-fill).
## Usage
-At the root of your application, you must render a `SlotFillProvider` which coordinates Slot and Fill rendering.
+At the root of your application, you must render a `SlotFillProvider` which coordinates `Slot` and `Fill` rendering.
-Then, render a Slot component anywhere in your application, giving it a name.
+Then, render a `Slot` component anywhere in your application, giving it a `name`. The `name` is either a `string` or a symbol. Symbol names are useful for slots that are supposed to be private, accessible only to clients that have access to the symbol value.
-Any Fill will automatically occupy this Slot space, even if rendered elsewhere in the application.
+Any `Fill` will render its UI in this `Slot` space, even if rendered elsewhere in the application.
-You can either use the Fill component directly, or a wrapper component type as in the below example to abstract the slot name from consumer awareness.
+You can either use the `Fill` component directly, or create a wrapper component (as in the following example) to hide the slot name from the consumer.
```jsx
import {
@@ -43,7 +43,7 @@ const MySlotFillProvider = () => {
};
```
-There is also `createSlotFill` helper method which was created to simplify the process of matching the corresponding `Slot` and `Fill` components:
+There is also the `createSlotFill` helper method which was created to simplify the process of matching the corresponding `Slot` and `Fill` components:
```jsx
const { Fill, Slot } = createSlotFill( 'Toolbar' );
@@ -59,18 +59,27 @@ const Toolbar = () => (
## Props
-The `SlotFillProvider` component does not accept any props.
+The `SlotFillProvider` component does not accept any props (except `children`).
Both `Slot` and `Fill` accept a `name` string prop, where a `Slot` with a given `name` will render the `children` of any associated `Fill`s.
-`Slot` accepts a `bubblesVirtually` prop which changes the event bubbling behaviour:
+`Slot` accepts a `bubblesVirtually` prop which changes the method how the `Fill` children are rendered. With `bubblesVirtually`, the `Fill` is rendered using a React portal. That affects the event bubbling and React context propagation behaviour:
-- By default, events will bubble to their parents on the DOM hierarchy (native event bubbling)
-- If `bubblesVirtually` is set to true, events will bubble to their virtual parent in the React elements hierarchy instead.
+### `bubblesVirtually=false`
-`Slot` with `bubblesVirtually` set to true also accept optional `className` and `style` props to add to the slot container.
+- events will bubble to their parents on the DOM hierarchy (native event bubbling)
+- the React elements inside the `Fill` will be rendered with React context of the `Slot`
+- renders the `Fill` elements directly, inside a `Fragment`, with no wrapper DOM element
-`Slot` **without** `bubblesVirtually` accepts an optional `children` function prop, which takes `fills` as a param. It allows you to perform additional processing and wrap `fills` conditionally.
+### `bubblesVirtually=true`
+
+- events will bubble to their virtual (React) parent in the React elements hierarchy
+- the React elements inside the `Fill` will keep the React context of the `Fill` and its parents
+- renders a wrapper DOM element inside which the `Fill` elements are rendered (used as an argument for React `createPortal`)
+
+`Slot` with `bubblesVirtually=true` renders a wrapper DOM element (a `div` by default) and accepts additional props that customize this element, like `className` or `style`. You can also replace the `div` with another element by passing an `as` prop.
+
+`Slot` **without** `bubblesVirtually` accepts an optional `children` prop, which is a function that receives `fills` array as a param. It allows you to perform additional processing: render a placeholder when there are no fills, or render a wrapper only when there are fills.
_Example_:
@@ -90,7 +99,9 @@ const Toolbar = ( { isMobile } ) => (
);
```
-Props can also be passed from a `Slot` to a `Fill` by using the prop `fillProps` on the `Slot`:
+Additional information (props) can also be passed from a `Slot` to a `Fill` by a combination of:
+1. Adding a `fillProps` prop to the `Slot`.
+2. Passing a function as `children` to the `Fill`. This function will receive the `fillProps` as an argument.
```jsx
const { Fill, Slot } = createSlotFill( 'Toolbar' );
diff --git a/packages/components/src/slot-fill/index.tsx b/packages/components/src/slot-fill/index.tsx
index 03ed33a67f13b6..caf97091b67ac8 100644
--- a/packages/components/src/slot-fill/index.tsx
+++ b/packages/components/src/slot-fill/index.tsx
@@ -84,17 +84,15 @@ export function createSlotFill( key: SlotKey ) {
props: DistributiveOmit< SlotComponentProps, 'name' >
) => ;
SlotComponent.displayName = `${ baseName }Slot`;
+ /**
+ * @deprecated 6.8.0
+ * Please use `slotFill.name` instead of `slotFill.Slot.__unstableName`.
+ */
SlotComponent.__unstableName = key;
return {
+ name: key,
Fill: FillComponent,
Slot: SlotComponent,
};
}
-
-export const createPrivateSlotFill = ( name: string ) => {
- const privateKey = Symbol( name );
- const privateSlotFill = createSlotFill( privateKey );
-
- return { privateKey, ...privateSlotFill };
-};
diff --git a/packages/components/src/text-control/stories/index.story.tsx b/packages/components/src/text-control/stories/index.story.tsx
index 948eca84a634c7..481ae714f0ce2f 100644
--- a/packages/components/src/text-control/stories/index.story.tsx
+++ b/packages/components/src/text-control/stories/index.story.tsx
@@ -15,7 +15,8 @@ import TextControl from '..';
const meta: Meta< typeof TextControl > = {
component: TextControl,
- title: 'Components/TextControl',
+ title: 'Components/Selection & Input/Common/TextControl',
+ id: 'components-textcontrol',
argTypes: {
help: { control: { type: 'text' } },
label: { control: { type: 'text' } },
diff --git a/packages/core-data/src/entities.js b/packages/core-data/src/entities.js
index 3c10676750a2ab..2730cdf3d64bf4 100644
--- a/packages/core-data/src/entities.js
+++ b/packages/core-data/src/entities.js
@@ -31,6 +31,8 @@ export const rootEntitiesConfig = [
'site_icon_url',
'site_logo',
'timezone_string',
+ 'default_template_part_areas',
+ 'default_template_types',
'url',
].join( ',' ),
},
diff --git a/packages/dataviews/src/components/dataviews-context/index.ts b/packages/dataviews/src/components/dataviews-context/index.ts
index 87acade73bc819..19f6b4178b7b55 100644
--- a/packages/dataviews/src/components/dataviews-context/index.ts
+++ b/packages/dataviews/src/components/dataviews-context/index.ts
@@ -28,7 +28,6 @@ type DataViewsContextType< Item > = {
getItemId: ( item: Item ) => string;
onClickItem: ( item: Item ) => void;
isItemClickable: ( item: Item ) => boolean;
- density: number;
};
const DataViewsContext = createContext< DataViewsContextType< any > >( {
@@ -47,7 +46,6 @@ const DataViewsContext = createContext< DataViewsContextType< any > >( {
getItemId: ( item ) => item.id,
onClickItem: () => {},
isItemClickable: () => false,
- density: 0,
} );
export default DataViewsContext;
diff --git a/packages/dataviews/src/components/dataviews-layout/index.tsx b/packages/dataviews/src/components/dataviews-layout/index.tsx
index 4ef0125b1f64b5..ebc251eae36a7a 100644
--- a/packages/dataviews/src/components/dataviews-layout/index.tsx
+++ b/packages/dataviews/src/components/dataviews-layout/index.tsx
@@ -27,7 +27,6 @@ export default function DataViewsLayout() {
selection,
onChangeSelection,
setOpenedFilter,
- density,
onClickItem,
isItemClickable,
} = useContext( DataViewsContext );
@@ -49,7 +48,6 @@ export default function DataViewsLayout() {
onClickItem={ onClickItem }
isItemClickable={ isItemClickable }
view={ view }
- density={ density }
/>
);
}
diff --git a/packages/dataviews/src/components/dataviews-view-config/index.tsx b/packages/dataviews/src/components/dataviews-view-config/index.tsx
index c8b26c51275891..f13670f27cdab7 100644
--- a/packages/dataviews/src/components/dataviews-view-config/index.tsx
+++ b/packages/dataviews/src/components/dataviews-view-config/index.tsx
@@ -35,7 +35,6 @@ import { useInstanceId } from '@wordpress/compose';
*/
import {
SORTING_DIRECTIONS,
- LAYOUT_GRID,
LAYOUT_TABLE,
sortIcons,
sortLabels,
@@ -49,7 +48,6 @@ import {
import type { SupportedLayouts, View, Field } from '../../types';
import DataViewsContext from '../dataviews-context';
import { unlock } from '../../lock-unlock';
-import DensityPicker from '../../dataviews-layouts/grid/density-picker';
const { Menu } = unlock( componentsPrivateApis );
@@ -512,19 +510,15 @@ function SettingsSection( {
);
}
-function DataviewsViewConfigDropdown( {
- density,
- setDensity,
-}: {
- density: number;
- setDensity: React.Dispatch< React.SetStateAction< number > >;
-} ) {
+function DataviewsViewConfigDropdown() {
const { view } = useContext( DataViewsContext );
const popoverId = useInstanceId(
_DataViewsViewConfig,
'dataviews-view-config-dropdown'
);
-
+ const activeLayout = VIEW_LAYOUTS.find(
+ ( layout ) => layout.type === view.type
+ );
return (
- { view.type === LAYOUT_GRID && (
-
+ { !! activeLayout?.viewConfigOptions && (
+
) }
@@ -570,21 +561,14 @@ function DataviewsViewConfigDropdown( {
}
function _DataViewsViewConfig( {
- density,
- setDensity,
defaultLayouts = { list: {}, grid: {}, table: {} },
}: {
- density: number;
- setDensity: React.Dispatch< React.SetStateAction< number > >;
defaultLayouts?: SupportedLayouts;
} ) {
return (
<>
-
+
>
);
}
diff --git a/packages/dataviews/src/components/dataviews/index.tsx b/packages/dataviews/src/components/dataviews/index.tsx
index 3e8224e61bc5d5..ee6073f40bf3d8 100644
--- a/packages/dataviews/src/components/dataviews/index.tsx
+++ b/packages/dataviews/src/components/dataviews/index.tsx
@@ -75,7 +75,6 @@ export default function DataViews< Item >( {
header,
}: DataViewsProps< Item > ) {
const [ selectionState, setSelectionState ] = useState< string[] >( [] );
- const [ density, setDensity ] = useState< number >( 0 );
const isUncontrolled =
selectionProperty === undefined || onChangeSelection === undefined;
const selection = isUncontrolled ? selectionState : selectionProperty;
@@ -119,7 +118,6 @@ export default function DataViews< Item >( {
getItemId,
isItemClickable,
onClickItem,
- density,
} }
>
diff --git a/packages/dataviews/src/dataviews-layouts/table/style.scss b/packages/dataviews/src/dataviews-layouts/table/style.scss
index ea2c614e4339df..3bbb045c73a9d9 100644
--- a/packages/dataviews/src/dataviews-layouts/table/style.scss
+++ b/packages/dataviews/src/dataviews-layouts/table/style.scss
@@ -169,6 +169,38 @@
opacity: 1;
}
}
+
+ // Density style overrides.
+ &.has-compact-density {
+ thead {
+ th {
+ &:has(.dataviews-view-table-header-button):not(:first-child) {
+ padding-left: 0;
+ }
+ }
+ }
+ td,
+ th {
+ padding: $grid-unit-05 $grid-unit-10;
+ }
+ }
+
+ &.has-comfortable-density {
+ td,
+ th {
+ padding: $grid-unit-20 $grid-unit-15;
+ }
+ }
+
+ &.has-compact-density,
+ &.has-comfortable-density {
+ td,
+ th {
+ &.dataviews-view-table__checkbox-column {
+ padding-right: 0;
+ }
+ }
+ }
}
/* stylelint-disable-next-line scss/at-rule-no-unknown -- '@container' not globally permitted */
diff --git a/packages/dataviews/src/types.ts b/packages/dataviews/src/types.ts
index 8c4276f2541ecc..861dc53404f914 100644
--- a/packages/dataviews/src/types.ts
+++ b/packages/dataviews/src/types.ts
@@ -329,6 +329,8 @@ export interface ColumnStyle {
minWidth?: string | number;
}
+export type Density = 'compact' | 'balanced' | 'comfortable';
+
export interface ViewTable extends ViewBase {
type: 'table';
@@ -347,6 +349,11 @@ export interface ViewTable extends ViewBase {
* The styles for the columns.
*/
styles?: Record< string, ColumnStyle >;
+
+ /**
+ * The density of the view.
+ */
+ density?: Density;
};
}
@@ -389,6 +396,11 @@ export interface ViewGrid extends ViewBase {
* The fields to use as badge fields.
*/
badgeFields?: string[];
+
+ /**
+ * The preview size of the grid.
+ */
+ previewSize?: number;
};
}
@@ -501,7 +513,6 @@ export interface ViewBaseProps< Item > {
onClickItem: ( item: Item ) => void;
isItemClickable: ( item: Item ) => boolean;
view: View;
- density: number;
}
export interface ViewTableProps< Item > extends ViewBaseProps< Item > {
diff --git a/packages/edit-post/src/components/browser-url/index.js b/packages/edit-post/src/components/browser-url/index.js
index 12292cb8447217..00492afbdc2624 100644
--- a/packages/edit-post/src/components/browser-url/index.js
+++ b/packages/edit-post/src/components/browser-url/index.js
@@ -27,14 +27,13 @@ export class BrowserURL extends Component {
}
componentDidUpdate( prevProps ) {
- const { postId, postStatus, hasHistory } = this.props;
+ const { postId, postStatus } = this.props;
const { historyId } = this.state;
if (
( postId !== prevProps.postId || postId !== historyId ) &&
postStatus !== 'auto-draft' &&
- postId &&
- ! hasHistory
+ postId
) {
this.setBrowserURL( postId );
}
diff --git a/packages/edit-post/src/components/layout/index.js b/packages/edit-post/src/components/layout/index.js
index aec14eab989f03..5dcbfa2c82cea1 100644
--- a/packages/edit-post/src/components/layout/index.js
+++ b/packages/edit-post/src/components/layout/index.js
@@ -392,7 +392,6 @@ function Layout( {
showIconLabels,
isDistractionFree,
showMetaBoxes,
- hasHistory,
isWelcomeGuideVisible,
templateId,
enablePaddingAppender,
@@ -595,7 +594,7 @@ function Layout( {
-
+
diff --git a/packages/edit-site/src/components/add-new-template/utils.js b/packages/edit-site/src/components/add-new-template/utils.js
index e3e2faf9457926..759f3f478cadaf 100644
--- a/packages/edit-site/src/components/add-new-template/utils.js
+++ b/packages/edit-site/src/components/add-new-template/utils.js
@@ -3,7 +3,6 @@
*/
import { useSelect } from '@wordpress/data';
import { store as coreStore } from '@wordpress/core-data';
-import { store as editorStore } from '@wordpress/editor';
import { decodeEntities } from '@wordpress/html-entities';
import { useMemo, useCallback } from '@wordpress/element';
import { __, _x, sprintf } from '@wordpress/i18n';
@@ -69,7 +68,8 @@ export const useExistingTemplates = () => {
export const useDefaultTemplateTypes = () => {
return useSelect(
( select ) =>
- select( editorStore ).__experimentalGetDefaultTemplateTypes(),
+ select( coreStore ).getEntityRecord( 'root', '__unstableBase' )
+ ?.default_template_types || [],
[]
);
};
diff --git a/packages/edit-site/src/components/editor-canvas-container/index.js b/packages/edit-site/src/components/editor-canvas-container/index.js
index ac1083e69abd7e..050d2e19585cc4 100644
--- a/packages/edit-site/src/components/editor-canvas-container/index.js
+++ b/packages/edit-site/src/components/editor-canvas-container/index.js
@@ -141,7 +141,7 @@ function EditorCanvasContainer( {
}
function useHasEditorCanvasContainer() {
- const fills = useSlotFills( EditorContentSlotFill.privateKey );
+ const fills = useSlotFills( EditorContentSlotFill.name );
return !! fills?.length;
}
diff --git a/packages/edit-site/src/components/editor/use-editor-title.js b/packages/edit-site/src/components/editor/use-editor-title.js
index 2ad4e94ccc3e80..727b190117e02a 100644
--- a/packages/edit-site/src/components/editor/use-editor-title.js
+++ b/packages/edit-site/src/components/editor/use-editor-title.js
@@ -4,33 +4,46 @@
import { _x, sprintf } from '@wordpress/i18n';
import { useSelect } from '@wordpress/data';
import { store as coreStore } from '@wordpress/core-data';
-import { store as editorStore } from '@wordpress/editor';
import { decodeEntities } from '@wordpress/html-entities';
+import { privateApis as editorPrivateApis } from '@wordpress/editor';
/**
* Internal dependencies
*/
import useTitle from '../routes/use-title';
import { POST_TYPE_LABELS, TEMPLATE_POST_TYPE } from '../../utils/constants';
+import { unlock } from '../../lock-unlock';
+
+const { getTemplateInfo } = unlock( editorPrivateApis );
function useEditorTitle( postType, postId ) {
const { title, isLoaded } = useSelect(
( select ) => {
const { getEditedEntityRecord, hasFinishedResolution } =
select( coreStore );
- const { __experimentalGetTemplateInfo: getTemplateInfo } =
- select( editorStore );
+
const _record = getEditedEntityRecord(
'postType',
postType,
postId
);
+
+ const { default_template_types: templateTypes = [] } =
+ select( coreStore ).getEntityRecord(
+ 'root',
+ '__unstableBase'
+ ) ?? {};
+
+ const templateInfo = getTemplateInfo( {
+ template: _record,
+ templateTypes,
+ } );
+
const _isLoaded = hasFinishedResolution( 'getEditedEntityRecord', [
'postType',
postType,
postId,
] );
- const templateInfo = getTemplateInfo( _record );
return {
title: templateInfo.title,
diff --git a/packages/edit-site/src/components/page-patterns/header.js b/packages/edit-site/src/components/page-patterns/header.js
index 641dc577cb7fe0..0d3763aec62c1a 100644
--- a/packages/edit-site/src/components/page-patterns/header.js
+++ b/packages/edit-site/src/components/page-patterns/header.js
@@ -9,7 +9,7 @@ import {
__experimentalText as Text,
__experimentalVStack as VStack,
} from '@wordpress/components';
-import { store as editorStore } from '@wordpress/editor';
+import { store as coreStore } from '@wordpress/core-data';
import { useSelect } from '@wordpress/data';
import { __, sprintf } from '@wordpress/i18n';
import { moreVertical } from '@wordpress/icons';
@@ -32,7 +32,8 @@ export default function PatternsHeader( {
const { patternCategories } = usePatternCategories();
const templatePartAreas = useSelect(
( select ) =>
- select( editorStore ).__experimentalGetDefaultTemplatePartAreas(),
+ select( coreStore ).getEntityRecord( 'root', '__unstableBase' )
+ ?.default_template_part_areas || [],
[]
);
diff --git a/packages/edit-site/src/components/page-patterns/use-patterns.js b/packages/edit-site/src/components/page-patterns/use-patterns.js
index e226298857c4da..3b3e33d5650e63 100644
--- a/packages/edit-site/src/components/page-patterns/use-patterns.js
+++ b/packages/edit-site/src/components/page-patterns/use-patterns.js
@@ -4,7 +4,6 @@
import { parse } from '@wordpress/blocks';
import { useSelect, createSelector } from '@wordpress/data';
import { store as coreStore } from '@wordpress/core-data';
-import { store as editorStore } from '@wordpress/editor';
import { useMemo } from '@wordpress/element';
/**
@@ -28,8 +27,7 @@ const selectTemplateParts = createSelector(
( select, categoryId, search = '' ) => {
const { getEntityRecords, isResolving: isResolvingSelector } =
select( coreStore );
- const { __experimentalGetDefaultTemplatePartAreas } =
- select( editorStore );
+
const query = { per_page: -1 };
const templateParts =
getEntityRecords( 'postType', TEMPLATE_PART_POST_TYPE, query ) ??
@@ -38,7 +36,10 @@ const selectTemplateParts = createSelector(
// In the case where a custom template part area has been removed we need
// the current list of areas to cross check against so orphaned template
// parts can be treated as uncategorized.
- const knownAreas = __experimentalGetDefaultTemplatePartAreas() || [];
+ const knownAreas =
+ select( coreStore ).getEntityRecord( 'root', '__unstableBase' )
+ ?.default_template_part_areas || [];
+
const templatePartAreas = knownAreas.map( ( area ) => area.area );
const templatePartHasCategory = ( item, category ) => {
@@ -78,7 +79,8 @@ const selectTemplateParts = createSelector(
TEMPLATE_PART_POST_TYPE,
{ per_page: -1 },
] ),
- select( editorStore ).__experimentalGetDefaultTemplatePartAreas(),
+ select( coreStore ).getEntityRecord( 'root', '__unstableBase' )
+ ?.default_template_part_areas,
]
);
diff --git a/packages/edit-site/src/components/page-templates/style.scss b/packages/edit-site/src/components/page-templates/style.scss
index 6a753921f6f40a..4432cf6bec4923 100644
--- a/packages/edit-site/src/components/page-templates/style.scss
+++ b/packages/edit-site/src/components/page-templates/style.scss
@@ -60,6 +60,7 @@
.dataviews-view-table & {
margin-bottom: $grid-unit-10;
+ display: block;
}
}
diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-details-footer/index.js b/packages/edit-site/src/components/sidebar-navigation-screen-details-footer/index.js
index 51833443d8d85c..f7e5f8bbec34de 100644
--- a/packages/edit-site/src/components/sidebar-navigation-screen-details-footer/index.js
+++ b/packages/edit-site/src/components/sidebar-navigation-screen-details-footer/index.js
@@ -1,24 +1,14 @@
/**
* WordPress dependencies
*/
-import { __, sprintf } from '@wordpress/i18n';
-import { humanTimeDiff } from '@wordpress/date';
-import { createInterpolateElement } from '@wordpress/element';
+import { _n, sprintf } from '@wordpress/i18n';
import { addQueryArgs } from '@wordpress/url';
-import {
- Icon,
- __experimentalItemGroup as ItemGroup,
-} from '@wordpress/components';
+import { __experimentalItemGroup as ItemGroup } from '@wordpress/components';
import { backup } from '@wordpress/icons';
/**
* Internal dependencies
*/
-import {
- SidebarNavigationScreenDetailsPanelRow,
- SidebarNavigationScreenDetailsPanelLabel,
- SidebarNavigationScreenDetailsPanelValue,
-} from '../sidebar-navigation-screen-details-panel';
import SidebarNavigationItem from '../sidebar-navigation-item';
export default function SidebarNavigationScreenDetailsFooter( {
@@ -56,33 +46,20 @@ export default function SidebarNavigationScreenDetailsFooter( {
hrefProps.as = 'a';
}
return (
-
+
-
-
- { __( 'Last modified' ) }
-
-
- { createInterpolateElement(
- sprintf(
- /* translators: %s: is the relative time when the post was last modified. */
- __( '' ),
- humanTimeDiff( record.modified )
- ),
- {
- time: ,
- }
- ) }
-
-
-
+ { sprintf(
+ /* translators: %d: Number of Styles revisions. */
+ _n( '%d Revision', '%d Revisions', revisionsCount ),
+ revisionsCount
+ ) }
);
diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-details-footer/style.scss b/packages/edit-site/src/components/sidebar-navigation-screen-details-footer/style.scss
index 866a36c02174d3..0b48d451129662 100644
--- a/packages/edit-site/src/components/sidebar-navigation-screen-details-footer/style.scss
+++ b/packages/edit-site/src/components/sidebar-navigation-screen-details-footer/style.scss
@@ -5,8 +5,4 @@
div.edit-site-sidebar-navigation-item.components-item[aria-current] {
background: none;
}
- .edit-site-sidebar-navigation-screen-details-footer__icon {
- margin-left: auto;
- fill: $gray-600;
- }
}
diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-details-panel/index.js b/packages/edit-site/src/components/sidebar-navigation-screen-details-panel/index.js
deleted file mode 100644
index 7d7a3932c99473..00000000000000
--- a/packages/edit-site/src/components/sidebar-navigation-screen-details-panel/index.js
+++ /dev/null
@@ -1,40 +0,0 @@
-/**
- * WordPress dependencies
- */
-import {
- __experimentalVStack as VStack,
- __experimentalHeading as Heading,
-} from '@wordpress/components';
-
-/**
- * Internal dependencies
- */
-import SidebarNavigationScreenDetailsPanelLabel from './sidebar-navigation-screen-details-panel-label';
-import SidebarNavigationScreenDetailsPanelRow from './sidebar-navigation-screen-details-panel-row';
-import SidebarNavigationScreenDetailsPanelValue from './sidebar-navigation-screen-details-panel-value';
-
-function SidebarNavigationScreenDetailsPanel( { title, children, spacing } ) {
- return (
-
- { title && (
-
- { title }
-
- ) }
- { children }
-
- );
-}
-
-export {
- SidebarNavigationScreenDetailsPanel,
- SidebarNavigationScreenDetailsPanelRow,
- SidebarNavigationScreenDetailsPanelLabel,
- SidebarNavigationScreenDetailsPanelValue,
-};
diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-details-panel/sidebar-navigation-screen-details-panel-label.js b/packages/edit-site/src/components/sidebar-navigation-screen-details-panel/sidebar-navigation-screen-details-panel-label.js
deleted file mode 100644
index 157eecd557519c..00000000000000
--- a/packages/edit-site/src/components/sidebar-navigation-screen-details-panel/sidebar-navigation-screen-details-panel-label.js
+++ /dev/null
@@ -1,14 +0,0 @@
-/**
- * WordPress dependencies
- */
-import { __experimentalText as Text } from '@wordpress/components';
-
-export default function SidebarNavigationScreenDetailsPanelLabel( {
- children,
-} ) {
- return (
-
- { children }
-
- );
-}
diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-details-panel/sidebar-navigation-screen-details-panel-row.js b/packages/edit-site/src/components/sidebar-navigation-screen-details-panel/sidebar-navigation-screen-details-panel-row.js
deleted file mode 100644
index 1c7f9abafdf503..00000000000000
--- a/packages/edit-site/src/components/sidebar-navigation-screen-details-panel/sidebar-navigation-screen-details-panel-row.js
+++ /dev/null
@@ -1,31 +0,0 @@
-/**
- * External dependencies
- */
-import clsx from 'clsx';
-
-/**
- * WordPress dependencies
- */
-import { __experimentalHStack as HStack } from '@wordpress/components';
-
-export default function SidebarNavigationScreenDetailsPanelRow( {
- label,
- children,
- className,
- ...extraProps
-} ) {
- return (
-
- { children }
-
- );
-}
diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-details-panel/sidebar-navigation-screen-details-panel-value.js b/packages/edit-site/src/components/sidebar-navigation-screen-details-panel/sidebar-navigation-screen-details-panel-value.js
deleted file mode 100644
index 80e8ba8cf1d538..00000000000000
--- a/packages/edit-site/src/components/sidebar-navigation-screen-details-panel/sidebar-navigation-screen-details-panel-value.js
+++ /dev/null
@@ -1,14 +0,0 @@
-/**
- * WordPress dependencies
- */
-import { __experimentalText as Text } from '@wordpress/components';
-
-export default function SidebarNavigationScreenDetailsPanelValue( {
- children,
-} ) {
- return (
-
- { children }
-
- );
-}
diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-details-panel/style.scss b/packages/edit-site/src/components/sidebar-navigation-screen-details-panel/style.scss
deleted file mode 100644
index 2757ce5a620c58..00000000000000
--- a/packages/edit-site/src/components/sidebar-navigation-screen-details-panel/style.scss
+++ /dev/null
@@ -1,26 +0,0 @@
-.edit-site-sidebar-navigation-details-screen-panel {
- margin: $grid-unit-30 0;
-
- &:last-of-type {
- margin-bottom: 0;
- }
-
- .edit-site-sidebar-navigation-details-screen-panel__heading {
- color: $gray-400;
- text-transform: uppercase;
- font-weight: 500;
- font-size: 11px;
- padding: 0;
- margin-bottom: 0;
- }
-}
-
-.edit-site-sidebar-navigation-details-screen-panel__label.edit-site-sidebar-navigation-details-screen-panel__label {
- color: $gray-600;
- width: 100px;
- flex-shrink: 0;
-}
-
-.edit-site-sidebar-navigation-details-screen-panel__value.edit-site-sidebar-navigation-details-screen-panel__value {
- color: $gray-200;
-}
diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-global-styles/index.js b/packages/edit-site/src/components/sidebar-navigation-screen-global-styles/index.js
index 772b15aec2a294..72671714479ac0 100644
--- a/packages/edit-site/src/components/sidebar-navigation-screen-global-styles/index.js
+++ b/packages/edit-site/src/components/sidebar-navigation-screen-global-styles/index.js
@@ -86,9 +86,8 @@ export default function SidebarNavigationScreenGlobalStyles() {
}, [ openGlobalStyles, setEditorCanvasContainerView ] );
// If there are no revisions, do not render a footer.
- const modifiedDateTime = revisions?.[ 0 ]?.modified;
const shouldShowGlobalStylesFooter =
- revisionsCount > 0 && ! isLoadingRevisions && modifiedDateTime;
+ !! revisionsCount && ! isLoadingRevisions;
return (
<>
diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-patterns/use-template-part-areas.js b/packages/edit-site/src/components/sidebar-navigation-screen-patterns/use-template-part-areas.js
index 77cbf87b3d439e..6a67a8f8a30fb9 100644
--- a/packages/edit-site/src/components/sidebar-navigation-screen-patterns/use-template-part-areas.js
+++ b/packages/edit-site/src/components/sidebar-navigation-screen-patterns/use-template-part-areas.js
@@ -1,9 +1,8 @@
/**
* WordPress dependencies
*/
-import { useEntityRecords } from '@wordpress/core-data';
+import { useEntityRecords, store as coreStore } from '@wordpress/core-data';
import { useSelect } from '@wordpress/data';
-import { store as editorStore } from '@wordpress/editor';
/**
* Internal dependencies
@@ -18,7 +17,8 @@ const useTemplatePartsGroupedByArea = ( items ) => {
const templatePartAreas = useSelect(
( select ) =>
- select( editorStore ).__experimentalGetDefaultTemplatePartAreas(),
+ select( coreStore ).getEntityRecord( 'root', '__unstableBase' )
+ ?.default_template_part_areas || [],
[]
);
@@ -43,7 +43,7 @@ const useTemplatePartsGroupedByArea = ( items ) => {
const key = accumulator[ item.area ]
? item.area
: TEMPLATE_PART_AREA_DEFAULT_CATEGORY;
- accumulator[ key ].templateParts.push( item );
+ accumulator[ key ]?.templateParts?.push( item );
return accumulator;
}, knownAreas );
diff --git a/packages/edit-site/src/components/sidebar-navigation-screen/style.scss b/packages/edit-site/src/components/sidebar-navigation-screen/style.scss
index 1d57472f7e9f94..959115e0fac8ca 100644
--- a/packages/edit-site/src/components/sidebar-navigation-screen/style.scss
+++ b/packages/edit-site/src/components/sidebar-navigation-screen/style.scss
@@ -18,7 +18,7 @@
.edit-site-sidebar-navigation-screen__content {
padding: 0 $grid-unit-20;
- .components-item-group {
+ .edit-site-sidebar-navigation-screen-details-footer {
margin-left: -$grid-unit-20;
margin-right: -$grid-unit-20;
}
@@ -127,9 +127,14 @@
bottom: 0;
background-color: $gray-900;
gap: 0;
- padding: $grid-unit-20 0;
+ padding: $grid-unit-10 $grid-unit-20;
margin: $grid-unit-20 0 0;
border-top: 1px solid $gray-800;
+
+ .components-item-group {
+ margin-left: -$grid-unit-20;
+ margin-right: -$grid-unit-20;
+ }
}
/* In general style overrides are discouraged.
diff --git a/packages/edit-site/src/index.js b/packages/edit-site/src/index.js
index 7f124e6b5f7ac6..b96ce5cb67f5e1 100644
--- a/packages/edit-site/src/index.js
+++ b/packages/edit-site/src/index.js
@@ -10,10 +10,7 @@ import {
import { dispatch } from '@wordpress/data';
import deprecated from '@wordpress/deprecated';
import { createRoot, StrictMode } from '@wordpress/element';
-import {
- store as editorStore,
- privateApis as editorPrivateApis,
-} from '@wordpress/editor';
+import { privateApis as editorPrivateApis } from '@wordpress/editor';
import { store as preferencesStore } from '@wordpress/preferences';
import {
registerLegacyWidgetBlock,
@@ -88,15 +85,6 @@ export function initializeEditor( id, settings ) {
dispatch( editSiteStore ).updateSettings( settings );
- // Keep the defaultTemplateTypes in the core/editor settings too,
- // so that they can be selected with core/editor selectors in any editor.
- // This is needed because edit-site doesn't initialize with EditorProvider,
- // which internally uses updateEditorSettings as well.
- dispatch( editorStore ).updateEditorSettings( {
- defaultTemplateTypes: settings.defaultTemplateTypes,
- defaultTemplatePartAreas: settings.defaultTemplatePartAreas,
- } );
-
// Prevent the default browser action for files dropped outside of dropzones.
window.addEventListener( 'dragover', ( e ) => e.preventDefault(), false );
window.addEventListener( 'drop', ( e ) => e.preventDefault(), false );
diff --git a/packages/edit-site/src/style.scss b/packages/edit-site/src/style.scss
index 63ad8244a7c95e..dce945a48ee700 100644
--- a/packages/edit-site/src/style.scss
+++ b/packages/edit-site/src/style.scss
@@ -20,7 +20,6 @@
@import "./components/sidebar-navigation-screen/style.scss";
@import "./components/sidebar-navigation-screen-details-footer/style.scss";
@import "./components/sidebar-navigation-screen-navigation-menu/style.scss";
-@import "components/sidebar-navigation-screen-details-panel/style.scss";
@import "./components/sidebar-navigation-screen-patterns/style.scss";
@import "./components/sidebar-dataviews/style.scss";
@import "./components/site-hub/style.scss";
diff --git a/packages/editor/README.md b/packages/editor/README.md
index bc00e15c8fb892..ac655bd1c99d8c 100644
--- a/packages/editor/README.md
+++ b/packages/editor/README.md
@@ -270,7 +270,7 @@ _Parameters_
_Returns_
-- `JSX.Element`: The rendered DocumentBar component.
+- `React.ReactNode`: The rendered DocumentBar component.
### DocumentOutline
@@ -284,7 +284,7 @@ _Parameters_
_Returns_
-- `Component`: The component to be rendered.
+- `React.ReactNode`: The rendered component.
### DocumentOutlineCheck
@@ -293,11 +293,11 @@ Component check if there are any headings (core/heading blocks) present in the d
_Parameters_
- _props_ `Object`: Props.
-- _props.children_ `Element`: Children to be rendered.
+- _props.children_ `React.ReactElement`: Children to be rendered.
_Returns_
-- `Component|null`: The component to be rendered or null if there are headings.
+- `React.ReactElement`: The component to be rendered or null if there are headings.
### EditorHistoryRedo
@@ -310,7 +310,7 @@ _Parameters_
_Returns_
-- `Component`: The component to be rendered.
+- `React.ReactNode`: The rendered component.
### EditorHistoryUndo
@@ -323,7 +323,7 @@ _Parameters_
_Returns_
-- `Component`: The component to be rendered.
+- `React.ReactNode`: The rendered component.
### EditorKeyboardShortcuts
@@ -351,7 +351,7 @@ _Usage_
_Returns_
-- `JSX.Element`: The rendered EditorNotices component.
+- `React.ReactNode`: The rendered EditorNotices component.
### EditorProvider
@@ -383,7 +383,7 @@ _Parameters_
_Returns_
-- `JSX.Element`: The rendered EditorProvider component.
+- `React.ReactNode`: The rendered EditorProvider component.
### EditorSnackbars
@@ -391,7 +391,7 @@ Renders the editor snackbars component.
_Returns_
-- `JSX.Element`: The rendered component.
+- `React.ReactNode`: The rendered component.
### EntitiesSavedStates
@@ -405,7 +405,7 @@ _Parameters_
_Returns_
-- `JSX.Element`: The rendered component.
+- `React.ReactNode`: The rendered component.
### ErrorBoundary
@@ -523,11 +523,11 @@ Wrapper component that renders its children only if the post type supports page
_Parameters_
- _props_ `Object`: - The component props.
-- _props.children_ `Element`: - The child components to render.
+- _props.children_ `React.ReactElement`: - The child components to render.
_Returns_
-- `Component|null`: The rendered child components or null if page attributes are not supported.
+- `React.ReactElement`: The rendered child components or null if page attributes are not supported.
### PageAttributesOrder
@@ -535,7 +535,7 @@ Renders the Page Attributes Order component. A number input in an editor interfa
_Returns_
-- `Component`: The component to be rendered.
+- `React.ReactNode`: The rendered component.
### PageAttributesPanel
@@ -543,7 +543,7 @@ Renders the Page Attributes Panel component.
_Returns_
-- `Component`: The component to be rendered.
+- `React.ReactNode`: The rendered component.
### PageAttributesParent
@@ -551,7 +551,7 @@ Renders the Page Attributes Parent component. A dropdown menu in an editor inter
_Returns_
-- `Component|null`: The component to be rendered. Return null if post type is not hierarchical.
+- `React.ReactNode`: The component to be rendered. Return null if post type is not hierarchical.
### PageTemplate
@@ -561,7 +561,7 @@ The dropdown menu includes a button for toggling the menu, a list of available t
_Returns_
-- `JSX.Element`: The rendered ClassicThemeControl component.
+- `React.ReactNode`: The rendered ClassicThemeControl component.
### PanelColorSettings
@@ -627,7 +627,7 @@ _Parameters_
_Returns_
-- `Component`: The component to be rendered.
+- `React.ReactNode`: The rendered component.
### PluginDocumentSettingPanel
@@ -684,11 +684,11 @@ _Parameters_
- _props.className_ `[string]`: An optional class name added to the row.
- _props.title_ `[string]`: The title of the panel
- _props.icon_ `[WPBlockTypeIconRender]`: The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered when the sidebar is pinned to toolbar.
-- _props.children_ `Element`: Children to be rendered
+- _props.children_ `React.ReactNode`: Children to be rendered
_Returns_
-- `Component`: The component to be rendered.
+- `React.ReactNode`: The component to be rendered.
### PluginMoreMenuItem
@@ -738,6 +738,7 @@ const MyButtonMoreMenuItem = () => (
_Parameters_
- _props_ `Object`: Component properties.
+- _props.children_ `[React.ReactNode]`: Children to be rendered.
- _props.href_ `[string]`: When `href` is provided then the menu item is represented as an anchor rather than button. It corresponds to the `href` attribute of the anchor.
- _props.icon_ `[WPBlockTypeIconRender]`: The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered to the left of the menu item label.
- _props.onClick_ `[Function]`: The callback function to be executed when the user clicks the menu item.
@@ -745,7 +746,7 @@ _Parameters_
_Returns_
-- `Component`: The component to be rendered.
+- `React.ReactNode`: The rendered component.
### PluginPostPublishPanel
@@ -776,11 +777,11 @@ _Parameters_
- _props.title_ `[string]`: Title displayed at the top of the panel.
- _props.initialOpen_ `[boolean]`: Whether to have the panel initially opened. When no title is provided it is always opened.
- _props.icon_ `[WPBlockTypeIconRender]`: The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered when the sidebar is pinned to toolbar.
-- _props.children_ `Element`: Children to be rendered
+- _props.children_ `React.ReactNode`: Children to be rendered
_Returns_
-- `Component`: The component to be rendered.
+- `React.ReactNode`: The rendered component.
### PluginPostStatusInfo
@@ -820,11 +821,11 @@ _Parameters_
- _props_ `Object`: Component properties.
- _props.className_ `[string]`: An optional class name added to the row.
-- _props.children_ `Element`: Children to be rendered.
+- _props.children_ `React.ReactNode`: Children to be rendered.
_Returns_
-- `Component`: The component to be rendered.
+- `React.ReactNode`: The rendered component.
### PluginPrePublishPanel
@@ -855,11 +856,11 @@ _Parameters_
- _props.title_ `[string]`: Title displayed at the top of the panel.
- _props.initialOpen_ `[boolean]`: Whether to have the panel initially opened. When no title is provided it is always opened.
- _props.icon_ `[WPBlockTypeIconRender]`: The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered when the sidebar is pinned to toolbar.
-- _props.children_ `Element`: Children to be rendered
+- _props.children_ `React.ReactNode`: Children to be rendered
_Returns_
-- `Component`: The component to be rendered.
+- `React.ReactNode`: The rendered component.
### PluginPreviewMenuItem
@@ -889,6 +890,7 @@ registerPlugin( 'external-preview-menu-item', {
_Parameters_
- _props_ `Object`: Component properties.
+- _props.children_ `[React.ReactNode]`: Children to be rendered.
- _props.href_ `[string]`: When `href` is provided, the menu item is rendered as an anchor instead of a button. It corresponds to the `href` attribute of the anchor.
- _props.icon_ `[WPBlockTypeIconRender]`: The icon to be rendered to the left of the menu item label. Can be a Dashicon slug or an SVG WP element.
- _props.onClick_ `[Function]`: The callback function to be executed when the user clicks the menu item.
@@ -896,7 +898,7 @@ _Parameters_
_Returns_
-- `Component`: The rendered menu item component.
+- `React.ReactNode`: The rendered menu item component.
### PluginSidebar
@@ -953,6 +955,7 @@ _Parameters_
- _props_ `Object`: Element props.
- _props.name_ `string`: A string identifying the sidebar. Must be unique for every sidebar registered within the scope of your plugin.
+- _props.children_ `[React.ReactNode]`: Children to be rendered.
- _props.className_ `[string]`: An optional class name added to the sidebar body.
- _props.title_ `string`: Title displayed at the top of the sidebar.
- _props.isPinnable_ `[boolean]`: Whether to allow to pin sidebar to the toolbar. When set to `true` it also automatically renders a corresponding menu item.
@@ -999,11 +1002,12 @@ _Parameters_
- _props_ `Object`: Component props.
- _props.target_ `string`: A string identifying the target sidebar you wish to be activated by this menu item. Must be the same as the `name` prop you have given to that sidebar.
+- _props.children_ `[React.ReactNode]`: Children to be rendered.
- _props.icon_ `[WPBlockTypeIconRender]`: The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered to the left of the menu item label.
_Returns_
-- `Component`: The component to be rendered.
+- `React.ReactNode`: The rendered component.
### PostAuthor
@@ -1011,7 +1015,7 @@ Renders the component for selecting the post author.
_Returns_
-- `Component`: The component to be rendered.
+- `React.ReactNode`: The rendered component.
### PostAuthorCheck
@@ -1020,11 +1024,11 @@ Wrapper component that renders its children only if the post type supports the a
_Parameters_
- _props_ `Object`: The component props.
-- _props.children_ `Element`: Children to be rendered.
+- _props.children_ `React.ReactNode`: Children to be rendered.
_Returns_
-- `Component|null`: The component to be rendered. Return `null` if the post type doesn't supports the author or if there are no authors available.
+- `React.ReactNode`: The component to be rendered. Return `null` if the post type doesn't supports the author or if there are no authors available.
### PostAuthorPanel
@@ -1032,7 +1036,7 @@ Renders the Post Author Panel component.
_Returns_
-- `Component`: The component to be rendered.
+- `React.ReactNode`: The rendered component.
### PostComments
@@ -1040,7 +1044,7 @@ A form for managing comment status.
_Returns_
-- `JSX.Element`: The rendered PostComments component.
+- `React.ReactNode`: The rendered PostComments component.
### PostDiscussionPanel
@@ -1048,7 +1052,7 @@ This component allows to update comment and pingback settings for the current po
_Returns_
-- `JSX.Element|null`: The rendered PostDiscussionPanel component.
+- `React.ReactNode`: The rendered PostDiscussionPanel component.
### PostExcerpt
@@ -1067,11 +1071,11 @@ Component for checking if the post type supports the excerpt field.
_Parameters_
- _props_ `Object`: Props.
-- _props.children_ `Element`: Children to be rendered.
+- _props.children_ `React.ReactNode`: Children to be rendered.
_Returns_
-- `Component`: The component to be rendered.
+- `React.ReactNode`: The rendered component.
### PostExcerptPanel
@@ -1079,7 +1083,7 @@ Is rendered if the post type supports excerpts and allows editing the excerpt.
_Returns_
-- `JSX.Element`: The rendered PostExcerptPanel component.
+- `React.ReactNode`: The rendered PostExcerptPanel component.
### PostFeaturedImage
@@ -1108,11 +1112,11 @@ Wrapper component that renders its children only if the post type supports a fea
_Parameters_
- _props_ `Object`: Props.
-- _props.children_ `Element`: Children to be rendered.
+- _props.children_ `React.ReactNode`: Children to be rendered.
_Returns_
-- `Component`: The component to be rendered.
+- `React.ReactNode`: The rendered component.
### PostFeaturedImagePanel
@@ -1125,7 +1129,7 @@ _Parameters_
_Returns_
-- `Component|null`: The component to be rendered. Return Null if the editor panel is disabled for featured image.
+- `React.ReactNode`: The component to be rendered. Return Null if the editor panel is disabled for featured image.
### PostFormat
@@ -1139,7 +1143,7 @@ _Usage_
_Returns_
-- `JSX.Element`: The rendered PostFormat component.
+- `React.ReactNode`: The rendered PostFormat component.
### PostFormatCheck
@@ -1148,11 +1152,11 @@ Component check if there are any post formats.
_Parameters_
- _props_ `Object`: The component props.
-- _props.children_ `Element`: The child elements to render.
+- _props.children_ `React.ReactNode`: The child elements to render.
_Returns_
-- `Component|null`: The rendered component or null if post formats are disabled.
+- `React.ReactNode`: The rendered component or null if post formats are disabled.
### PostLastRevision
@@ -1160,7 +1164,7 @@ Renders the component for displaying the last revision of a post.
_Returns_
-- `Component`: The component to be rendered.
+- `React.ReactNode`: The rendered component.
### PostLastRevisionCheck
@@ -1169,11 +1173,11 @@ Wrapper component that renders its children if the post has more than one revisi
_Parameters_
- _props_ `Object`: Props.
-- _props.children_ `Element`: Children to be rendered.
+- _props.children_ `React.ReactNode`: Children to be rendered.
_Returns_
-- `Component|null`: Rendered child components if post has more than one revision, otherwise null.
+- `React.ReactNode`: Rendered child components if post has more than one revision, otherwise null.
### PostLastRevisionPanel
@@ -1181,7 +1185,7 @@ Renders the panel for displaying the last revision of a post.
_Returns_
-- `Component`: The component to be rendered.
+- `React.ReactNode`: The rendered component.
### PostLockedModal
@@ -1189,7 +1193,7 @@ A modal component that is displayed when a post is locked for editing by another
_Returns_
-- `JSX.Element|null`: The rendered PostLockedModal component.
+- `React.ReactNode`: The rendered PostLockedModal component.
### PostPendingStatus
@@ -1197,7 +1201,7 @@ A component for displaying and toggling the pending status of a post.
_Returns_
-- `JSX.Element`: The rendered component.
+- `React.ReactNode`: The rendered component.
### PostPendingStatusCheck
@@ -1206,11 +1210,11 @@ This component checks the publishing status of the current post. If the post is
_Parameters_
- _props_ `Object`: Component properties.
-- _props.children_ `Element`: Children to be rendered.
+- _props.children_ `React.ReactElement`: Children to be rendered.
_Returns_
-- `JSX.Element|null`: The rendered child elements or null if the post is already published or the user doesn't have the capability to publish.
+- `React.ReactElement`: The rendered child elements or null if the post is already published or the user doesn't have the capability to publish.
### PostPingbacks
@@ -1231,7 +1235,7 @@ _Parameters_
_Returns_
-- `JSX.Element|null`: The rendered button component.
+- `React.ReactNode`: The rendered button component.
### PostPublishButton
@@ -1273,7 +1277,7 @@ _Parameters_
_Returns_
-- `Component`: The component to be rendered.
+- `React.ReactNode`: The rendered component.
### PostScheduleCheck
@@ -1282,11 +1286,11 @@ Wrapper component that renders its children only if post has a publish action.
_Parameters_
- _props_ `Object`: Props.
-- _props.children_ `Element`: Children to be rendered.
+- _props.children_ `React.ReactElement`: Children to be rendered.
_Returns_
-- `Component`: - The component to be rendered or null if there is no publish action.
+- `React.ReactElement`: - The component to be rendered or null if there is no publish action.
### PostScheduleLabel
@@ -1298,7 +1302,7 @@ _Parameters_
_Returns_
-- `Component`: The component to be rendered.
+- `React.ReactNode`: The rendered component.
### PostSchedulePanel
@@ -1306,7 +1310,7 @@ Renders the Post Schedule Panel component.
_Returns_
-- `Component`: The component to be rendered.
+- `React.ReactNode`: The rendered component.
### PostSlug
@@ -1314,7 +1318,7 @@ Renders the PostSlug component. It provide a control for editing the post slug.
_Returns_
-- `Component`: The component to be rendered.
+- `React.ReactNode`: The rendered component.
### PostSlugCheck
@@ -1323,11 +1327,11 @@ Wrapper component that renders its children only if the post type supports the s
_Parameters_
- _props_ `Object`: Props.
-- _props.children_ `Element`: Children to be rendered.
+- _props.children_ `React.ReactNode`: Children to be rendered.
_Returns_
-- `Component`: The component to be rendered.
+- `React.ReactNode`: The rendered component.
### PostSticky
@@ -1335,7 +1339,7 @@ Renders the PostSticky component. It provides a checkbox control for the sticky
_Returns_
-- `Component`: The component to be rendered.
+- `React.ReactNode`: The rendered component.
### PostStickyCheck
@@ -1344,11 +1348,11 @@ Wrapper component that renders its children only if post has a sticky action.
_Parameters_
- _props_ `Object`: Props.
-- _props.children_ `Element`: Children to be rendered.
+- _props.children_ `React.ReactElement`: Children to be rendered.
_Returns_
-- `Component`: The component to be rendered or null if post type is not 'post' or hasStickyAction is false.
+- `React.ReactElement`: The component to be rendered or null if post type is not 'post' or hasStickyAction is false.
### PostSwitchToDraftButton
@@ -1356,7 +1360,7 @@ Renders a button component that allows the user to switch a post to draft status
_Returns_
-- `JSX.Element`: The rendered component.
+- `React.ReactNode`: The rendered component.
### PostSyncStatus
@@ -1364,7 +1368,7 @@ Renders the sync status of a post.
_Returns_
-- `JSX.Element|null`: The rendered sync status component.
+- `React.ReactNode`: The rendered sync status component.
### PostTaxonomies
@@ -1386,11 +1390,11 @@ Renders the children components only if the current post type has taxonomies.
_Parameters_
- _props_ `Object`: The component props.
-- _props.children_ `Element`: The children components to render.
+- _props.children_ `React.ReactNode`: The children components to render.
_Returns_
-- `Component|null`: The rendered children components or null if the current post type has no taxonomies.
+- `React.ReactElement`: The rendered children components or null if the current post type has no taxonomies.
### PostTaxonomiesFlatTermSelector
@@ -1404,7 +1408,7 @@ _Parameters_
_Returns_
-- `JSX.Element`: The rendered flat term selector component.
+- `React.ReactNode`: The rendered flat term selector component.
### PostTaxonomiesHierarchicalTermSelector
@@ -1421,17 +1425,11 @@ _Returns_
### PostTaxonomiesPanel
-Renders a panel for a specific taxonomy.
-
-_Parameters_
-
-- _props_ `Object`: The component props.
-- _props.taxonomy_ `Object`: The taxonomy object.
-- _props.children_ `Element`: The child components.
+Component that renders the post taxonomies panel.
_Returns_
-- `Component`: The rendered taxonomy panel.
+- `React.ReactNode`: The rendered component.
### PostTemplatePanel
@@ -1439,7 +1437,7 @@ Displays the template controls based on the current editor settings and user per
_Returns_
-- `JSX.Element|null`: The rendered PostTemplatePanel component.
+- `React.ReactNode`: The rendered PostTemplatePanel component.
### PostTextEditor
@@ -1447,7 +1445,7 @@ Displays the Post Text Editor along with content in Visual and Text mode.
_Returns_
-- `JSX.Element|null`: The rendered PostTextEditor component.
+- `React.ReactNode`: The rendered PostTextEditor component.
### PostTitle
@@ -1460,7 +1458,7 @@ _Parameters_
_Returns_
-- `Component`: The rendered PostTitle component.
+- `React.ReactNode`: The rendered PostTitle component.
### PostTitleRaw
@@ -1476,7 +1474,7 @@ _Parameters_
_Returns_
-- `JSX.Element|null`: The rendered PostTrash component.
+- `React.ReactNode`: The rendered PostTrash component.
### PostTrashCheck
@@ -1485,11 +1483,11 @@ Wrapper component that renders its children only if the post can trashed.
_Parameters_
- _props_ `Object`: - The component props.
-- _props.children_ `Element`: - The child components to render.
+- _props.children_ `React.ReactEl`: - The child components to render.
_Returns_
-- `Component|null`: The rendered child components or null if the post can not trashed.
+- `React.ReactElement`: The rendered child components or null if the post can not trashed.
### PostTypeSupportCheck
@@ -1498,12 +1496,12 @@ A component which renders its own children only if the current editor post type
_Parameters_
- _props_ `Object`: Props.
-- _props.children_ `Element`: Children to be rendered if post type supports.
+- _props.children_ `React.ReactElement`: Children to be rendered if post type supports.
- _props.supportKeys_ `(string|string[])`: String or string array of keys to test.
_Returns_
-- `Component`: The component to be rendered.
+- `React.ReactElement`: The component to be rendered.
### PostURL
@@ -1521,7 +1519,7 @@ _Parameters_
_Returns_
-- `Component`: The rendered PostURL component.
+- `React.ReactNode`: The rendered PostURL component.
### PostURLCheck
@@ -1530,11 +1528,11 @@ Check if the post URL is valid and visible.
_Parameters_
- _props_ `Object`: The component props.
-- _props.children_ `Element`: The child components.
+- _props.children_ `React.ReactElement`: The child components.
_Returns_
-- `Component|null`: The child components if the post URL is valid and visible, otherwise null.
+- `React.ReactElement`: The child components if the post URL is valid and visible, otherwise null.
### PostURLLabel
@@ -1542,7 +1540,7 @@ Represents a label component for a post URL.
_Returns_
-- `Component`: The PostURLLabel component.
+- `React.ReactNode`: The PostURLLabel component.
### PostURLPanel
@@ -1550,7 +1548,7 @@ Renders the `PostURLPanel` component.
_Returns_
-- `JSX.Element`: The rendered PostURLPanel component.
+- `React.ReactNode`: The rendered PostURLPanel component.
### PostVisibility
@@ -1563,7 +1561,7 @@ _Parameters_
_Returns_
-- `JSX.Element`: The rendered component.
+- `React.ReactNode`: The rendered component.
### PostVisibilityCheck
@@ -1576,7 +1574,7 @@ _Parameters_
_Returns_
-- `JSX.Element`: The rendered component.
+- `React.ReactNode`: The rendered component.
### PostVisibilityLabel
@@ -1663,7 +1661,7 @@ _Parameters_
_Returns_
-- `JSX.Element`: The rendered table of contents component.
+- `React.ReactNode`: The rendered table of contents component.
### TextEditorGlobalKeyboardShortcuts
@@ -1678,12 +1676,12 @@ Checks if the current theme supports specific features and renders the children
_Parameters_
- _props_ `Object`: The component props.
-- _props.children_ `Element`: The children to render if the theme supports the specified features.
+- _props.children_ `React.ReactElement`: The children to render if the theme supports the specified features.
- _props.supportKeys_ `string|string[]`: The key(s) of the theme support(s) to check.
_Returns_
-- `JSX.Element|null`: The rendered children if the theme supports the specified features, otherwise null.
+- `React.ReactElement`: The rendered children if the theme supports the specified features, otherwise null.
### TimeToRead
@@ -1691,7 +1689,7 @@ Component for showing Time To Read in Content.
_Returns_
-- `JSX.Element`: The rendered TimeToRead component.
+- `React.ReactNode`: The rendered TimeToRead component.
### transformStyles
@@ -1727,7 +1725,7 @@ Warns the user if there are unsaved changes before leaving the editor. Compatibl
_Returns_
-- `Component`: The component.
+- `React.ReactNode`: The component.
### URLInput
@@ -1814,7 +1812,7 @@ Renders the word count of the post content.
_Returns_
-- `JSX.Element|null`: The rendered WordCount component.
+- `React.ReactNode`: The rendered WordCount component.
### WritingFlow
diff --git a/packages/editor/src/components/block-settings-menu/plugin-block-settings-menu-item.js b/packages/editor/src/components/block-settings-menu/plugin-block-settings-menu-item.js
index 59c9e9c32d4a4b..df1e75d2d0e8b5 100644
--- a/packages/editor/src/components/block-settings-menu/plugin-block-settings-menu-item.js
+++ b/packages/editor/src/components/block-settings-menu/plugin-block-settings-menu-item.js
@@ -76,7 +76,7 @@ const shouldRenderItem = ( selectedBlocks, allowedBlocks ) =>
* );
* ```
*
- * @return {Component} The component to be rendered.
+ * @return {React.ReactNode} The rendered component.
*/
const PluginBlockSettingsMenuItem = ( {
allowedBlocks,
diff --git a/packages/editor/src/components/collab-sidebar/add-comment.js b/packages/editor/src/components/collab-sidebar/add-comment.js
index fce47e821e2065..2330017ac5db53 100644
--- a/packages/editor/src/components/collab-sidebar/add-comment.js
+++ b/packages/editor/src/components/collab-sidebar/add-comment.js
@@ -22,7 +22,7 @@ import CommentForm from './comment-form';
* @param {Function} props.onSubmit - A callback function to be called when the user submits a comment.
* @param {boolean} props.showCommentBoard - The function to edit the comment.
* @param {Function} props.setShowCommentBoard - The function to delete the comment.
- * @return {JSX.Element} The rendered comment input UI.
+ * @return {React.ReactNode} The rendered comment input UI.
*/
export function AddComment( {
onSubmit,
diff --git a/packages/editor/src/components/collab-sidebar/comment-author-info.js b/packages/editor/src/components/collab-sidebar/comment-author-info.js
index 89d09a2b52261f..d8b5f72a2fc25f 100644
--- a/packages/editor/src/components/collab-sidebar/comment-author-info.js
+++ b/packages/editor/src/components/collab-sidebar/comment-author-info.js
@@ -16,7 +16,7 @@ import { store as blockEditorStore } from '@wordpress/block-editor';
* @param {string} props.name - Name of the author.
* @param {string} props.date - Date of the comment.
*
- * @return {JSX.Element} The JSX element representing the author's information.
+ * @return {React.ReactNode} The JSX element representing the author's information.
*/
function CommentAuthorInfo( { avatar, name, date } ) {
const dateSettings = getDateSettings();
diff --git a/packages/editor/src/components/collab-sidebar/comment-button-toolbar.js b/packages/editor/src/components/collab-sidebar/comment-button-toolbar.js
index 2e378a7eaabab0..b673ee87fe86ce 100644
--- a/packages/editor/src/components/collab-sidebar/comment-button-toolbar.js
+++ b/packages/editor/src/components/collab-sidebar/comment-button-toolbar.js
@@ -11,18 +11,18 @@ import { privateApis as blockEditorPrivateApis } from '@wordpress/block-editor';
*/
import { unlock } from '../../lock-unlock';
-const { __unstableCommentIconToolbarFill } = unlock( blockEditorPrivateApis );
+const { CommentIconToolbarSlotFill } = unlock( blockEditorPrivateApis );
const AddCommentToolbarButton = ( { onClick } ) => {
return (
- <__unstableCommentIconToolbarFill>
+
-
+
);
};
diff --git a/packages/editor/src/components/collab-sidebar/comment-button.js b/packages/editor/src/components/collab-sidebar/comment-button.js
index 3b020661816660..373ee0becd92df 100644
--- a/packages/editor/src/components/collab-sidebar/comment-button.js
+++ b/packages/editor/src/components/collab-sidebar/comment-button.js
@@ -12,11 +12,11 @@ import { privateApis as blockEditorPrivateApis } from '@wordpress/block-editor';
*/
import { unlock } from '../../lock-unlock';
-const { __unstableCommentIconFill } = unlock( blockEditorPrivateApis );
+const { CommentIconSlotFill } = unlock( blockEditorPrivateApis );
const AddCommentButton = ( { onClick } ) => {
return (
- <__unstableCommentIconFill>
+
-
+
);
};
diff --git a/packages/editor/src/components/collab-sidebar/comment-form.js b/packages/editor/src/components/collab-sidebar/comment-form.js
index 28622f9f52a6f8..052fd3cdd26568 100644
--- a/packages/editor/src/components/collab-sidebar/comment-form.js
+++ b/packages/editor/src/components/collab-sidebar/comment-form.js
@@ -22,7 +22,7 @@ import { sanitizeCommentString } from './utils';
* @param {Function} props.onCancel - The function to call when canceling the comment update.
* @param {Object} props.thread - The comment thread object.
* @param {string} props.submitButtonText - The text to display on the submit button.
- * @return {JSX.Element} The CommentForm component.
+ * @return {React.ReactNode} The CommentForm component.
*/
function CommentForm( { onSubmit, onCancel, thread, submitButtonText } ) {
const [ inputComment, setInputComment ] = useState(
diff --git a/packages/editor/src/components/collab-sidebar/comments.js b/packages/editor/src/components/collab-sidebar/comments.js
index 808ea0acf04b31..7a03068787c81e 100644
--- a/packages/editor/src/components/collab-sidebar/comments.js
+++ b/packages/editor/src/components/collab-sidebar/comments.js
@@ -35,7 +35,7 @@ import CommentForm from './comment-form';
* @param {Function} props.onAddReply - The function to add a reply to a comment.
* @param {Function} props.onCommentDelete - The function to delete a comment.
* @param {Function} props.onCommentResolve - The function to mark a comment as resolved.
- * @return {JSX.Element} The rendered Comments component.
+ * @return {React.ReactNode} The rendered Comments component.
*/
export function Comments( {
threads,
@@ -270,7 +270,7 @@ export function Comments( {
* @param {Function} props.onDelete - The function to delete the comment.
* @param {Function} props.onReply - The function to reply to the comment.
* @param {string} props.status - The status of the comment.
- * @return {JSX.Element} The rendered comment header.
+ * @return {React.ReactNode} The rendered comment header.
*/
function CommentHeader( {
thread,
diff --git a/packages/editor/src/components/create-template-part-modal/index.js b/packages/editor/src/components/create-template-part-modal/index.js
index 5d594cd646cc10..660439ded2300f 100644
--- a/packages/editor/src/components/create-template-part-modal/index.js
+++ b/packages/editor/src/components/create-template-part-modal/index.js
@@ -27,7 +27,6 @@ import { serialize } from '@wordpress/blocks';
/**
* Internal dependencies
*/
-import { store as editorStore } from '../../store';
import {
TEMPLATE_PART_POST_TYPE,
TEMPLATE_PART_AREA_DEFAULT_CATEGORY,
@@ -81,9 +80,11 @@ export function CreateTemplatePartModalContents( {
const templatePartAreas = useSelect(
( select ) =>
- select( editorStore ).__experimentalGetDefaultTemplatePartAreas(),
+ select( coreStore ).getEntityRecord( 'root', '__unstableBase' )
+ ?.default_template_part_areas || [],
[]
);
+
async function createTemplatePart() {
if ( ! title || isSubmitting ) {
return;
diff --git a/packages/editor/src/components/document-bar/index.js b/packages/editor/src/components/document-bar/index.js
index 30990379fe6301..7b94a6fbeb3be9 100644
--- a/packages/editor/src/components/document-bar/index.js
+++ b/packages/editor/src/components/document-bar/index.js
@@ -29,6 +29,7 @@ import { decodeEntities } from '@wordpress/html-entities';
import { TEMPLATE_POST_TYPES } from '../../store/constants';
import { store as editorStore } from '../../store';
import usePageTypeBadge from '../../utils/pageTypeBadge';
+import { getTemplateInfo } from '../../utils/get-template-info';
/** @typedef {import("@wordpress/components").IconType} IconType */
@@ -49,7 +50,7 @@ const MotionButton = motion( Button );
* @param {IconType} props.icon An icon for the document, no default.
* (A default icon indicating the document post type is no longer used.)
*
- * @return {JSX.Element} The rendered DocumentBar component.
+ * @return {React.ReactNode} The rendered DocumentBar component.
*/
export default function DocumentBar( props ) {
const {
@@ -65,9 +66,9 @@ export default function DocumentBar( props ) {
getCurrentPostType,
getCurrentPostId,
getEditorSettings,
- __experimentalGetTemplateInfo: getTemplateInfo,
getRenderingMode,
} = select( editorStore );
+
const {
getEditedEntityRecord,
getPostType,
@@ -80,7 +81,15 @@ export default function DocumentBar( props ) {
_postType,
_postId
);
- const _templateInfo = getTemplateInfo( _document );
+
+ const { default_template_types: templateTypes = [] } =
+ select( coreStore ).getEntityRecord( 'root', '__unstableBase' ) ??
+ {};
+
+ const _templateInfo = getTemplateInfo( {
+ templateTypes,
+ template: _document,
+ } );
const _postTypeLabel = getPostType( _postType )?.labels?.singular_name;
return {
diff --git a/packages/editor/src/components/document-outline/check.js b/packages/editor/src/components/document-outline/check.js
index d0676aa9037ffe..87864cbb34a369 100644
--- a/packages/editor/src/components/document-outline/check.js
+++ b/packages/editor/src/components/document-outline/check.js
@@ -7,10 +7,10 @@ import { store as blockEditorStore } from '@wordpress/block-editor';
/**
* Component check if there are any headings (core/heading blocks) present in the document.
*
- * @param {Object} props Props.
- * @param {Element} props.children Children to be rendered.
+ * @param {Object} props Props.
+ * @param {React.ReactElement} props.children Children to be rendered.
*
- * @return {Component|null} The component to be rendered or null if there are headings.
+ * @return {React.ReactElement} The component to be rendered or null if there are headings.
*/
export default function DocumentOutlineCheck( { children } ) {
const hasHeadings = useSelect( ( select ) => {
diff --git a/packages/editor/src/components/document-outline/index.js b/packages/editor/src/components/document-outline/index.js
index c5e59837362092..89f853798296ae 100644
--- a/packages/editor/src/components/document-outline/index.js
+++ b/packages/editor/src/components/document-outline/index.js
@@ -106,7 +106,7 @@ const isEmptyHeading = ( heading ) =>
* @param {Function} props.onSelect Function to be called when an outline item is selected
* @param {boolean} props.hasOutlineItemsDisabled Indicates whether the outline items are disabled.
*
- * @return {Component} The component to be rendered.
+ * @return {React.ReactNode} The rendered component.
*/
export default function DocumentOutline( {
onSelect,
diff --git a/packages/editor/src/components/editor-history/redo.js b/packages/editor/src/components/editor-history/redo.js
index 46a263bb89926b..b2b20555f30544 100644
--- a/packages/editor/src/components/editor-history/redo.js
+++ b/packages/editor/src/components/editor-history/redo.js
@@ -50,6 +50,6 @@ function EditorHistoryRedo( props, ref ) {
* @param {Object} props - Props.
* @param {Ref} ref - Forwarded ref.
*
- * @return {Component} The component to be rendered.
+ * @return {React.ReactNode} The rendered component.
*/
export default forwardRef( EditorHistoryRedo );
diff --git a/packages/editor/src/components/editor-history/undo.js b/packages/editor/src/components/editor-history/undo.js
index 6ba6055706e993..fe8cce72c4197e 100644
--- a/packages/editor/src/components/editor-history/undo.js
+++ b/packages/editor/src/components/editor-history/undo.js
@@ -46,6 +46,6 @@ function EditorHistoryUndo( props, ref ) {
* @param {Object} props - Props.
* @param {Ref} ref - Forwarded ref.
*
- * @return {Component} The component to be rendered.
+ * @return {React.ReactNode} The rendered component.
*/
export default forwardRef( EditorHistoryUndo );
diff --git a/packages/editor/src/components/editor-interface/content-slot-fill.js b/packages/editor/src/components/editor-interface/content-slot-fill.js
index 1aab394e87230f..ce1070b30da802 100644
--- a/packages/editor/src/components/editor-interface/content-slot-fill.js
+++ b/packages/editor/src/components/editor-interface/content-slot-fill.js
@@ -1,15 +1,10 @@
/**
* WordPress dependencies
*/
-import { privateApis as componentsPrivateApis } from '@wordpress/components';
+import { createSlotFill } from '@wordpress/components';
-/**
- * Internal dependencies
- */
-import { unlock } from '../../lock-unlock';
-
-const { createPrivateSlotFill } = unlock( componentsPrivateApis );
-const SLOT_FILL_NAME = 'EditCanvasContainerSlot';
-const EditorContentSlotFill = createPrivateSlotFill( SLOT_FILL_NAME );
+const EditorContentSlotFill = createSlotFill(
+ Symbol( 'EditCanvasContainerSlot' )
+);
export default EditorContentSlotFill;
diff --git a/packages/editor/src/components/editor-notices/index.js b/packages/editor/src/components/editor-notices/index.js
index 28341bfda3f236..5f095ef1a813c6 100644
--- a/packages/editor/src/components/editor-notices/index.js
+++ b/packages/editor/src/components/editor-notices/index.js
@@ -18,7 +18,7 @@ import TemplateValidationNotice from '../template-validation-notice';
*
* ```
*
- * @return {JSX.Element} The rendered EditorNotices component.
+ * @return {React.ReactNode} The rendered EditorNotices component.
*/
export function EditorNotices() {
const { notices } = useSelect(
diff --git a/packages/editor/src/components/editor-snackbars/index.js b/packages/editor/src/components/editor-snackbars/index.js
index 6530e1ec7ea902..9b781ee60dcaa5 100644
--- a/packages/editor/src/components/editor-snackbars/index.js
+++ b/packages/editor/src/components/editor-snackbars/index.js
@@ -11,7 +11,7 @@ const MAX_VISIBLE_NOTICES = -3;
/**
* Renders the editor snackbars component.
*
- * @return {JSX.Element} The rendered component.
+ * @return {React.ReactNode} The rendered component.
*/
export default function EditorSnackbars() {
const notices = useSelect(
diff --git a/packages/editor/src/components/entities-saved-states/entity-record-item.js b/packages/editor/src/components/entities-saved-states/entity-record-item.js
index ca9fb2e0b169c3..e8219c4cca7ae1 100644
--- a/packages/editor/src/components/entities-saved-states/entity-record-item.js
+++ b/packages/editor/src/components/entities-saved-states/entity-record-item.js
@@ -12,6 +12,7 @@ import { decodeEntities } from '@wordpress/html-entities';
*/
import { store as editorStore } from '../../store';
import { unlock } from '../../lock-unlock';
+import { getTemplateInfo } from '../../utils/get-template-info';
export default function EntityRecordItem( { record, checked, onChange } ) {
const { name, kind, title, key } = record;
@@ -33,11 +34,18 @@ export default function EntityRecordItem( { record, checked, onChange } ) {
name,
key
);
+
+ const { default_template_types: templateTypes = [] } =
+ select( coreStore ).getEntityRecord(
+ 'root',
+ '__unstableBase'
+ ) ?? {};
+
return {
- entityRecordTitle:
- select( editorStore ).__experimentalGetTemplateInfo(
- template
- ).title,
+ entityRecordTitle: getTemplateInfo( {
+ template,
+ templateTypes,
+ } ).title,
hasPostMetaChanges: unlock(
select( editorStore )
).hasPostMetaChanges( name, key ),
diff --git a/packages/editor/src/components/entities-saved-states/index.js b/packages/editor/src/components/entities-saved-states/index.js
index 849bd2d0d71c8c..ea05bca522941b 100644
--- a/packages/editor/src/components/entities-saved-states/index.js
+++ b/packages/editor/src/components/entities-saved-states/index.js
@@ -33,7 +33,7 @@ function identity( values ) {
* @param {Function} props.close The function to close the dialog.
* @param {Function} props.renderDialog The function to render the dialog.
*
- * @return {JSX.Element} The rendered component.
+ * @return {React.ReactNode} The rendered component.
*/
export default function EntitiesSavedStates( {
close,
@@ -64,7 +64,7 @@ export default function EntitiesSavedStates( {
* @param {Function} props.setUnselectedEntities Function to set unselected entities.
* @param {Array} props.unselectedEntities Array of unselected entities.
*
- * @return {JSX.Element} The rendered component.
+ * @return {React.ReactNode} The rendered component.
*/
export function EntitiesSavedStatesExtensible( {
additionalPrompt = undefined,
diff --git a/packages/editor/src/components/page-attributes/check.js b/packages/editor/src/components/page-attributes/check.js
index bed2b1a353842a..3c08a3d8e53514 100644
--- a/packages/editor/src/components/page-attributes/check.js
+++ b/packages/editor/src/components/page-attributes/check.js
@@ -12,10 +12,10 @@ import { store as editorStore } from '../../store';
/**
* Wrapper component that renders its children only if the post type supports page attributes.
*
- * @param {Object} props - The component props.
- * @param {Element} props.children - The child components to render.
+ * @param {Object} props - The component props.
+ * @param {React.ReactElement} props.children - The child components to render.
*
- * @return {Component|null} The rendered child components or null if page attributes are not supported.
+ * @return {React.ReactElement} The rendered child components or null if page attributes are not supported.
*/
export function PageAttributesCheck( { children } ) {
const supportsPageAttributes = useSelect( ( select ) => {
diff --git a/packages/editor/src/components/page-attributes/order.js b/packages/editor/src/components/page-attributes/order.js
index c5f02c71b613d4..04c6ce186a9701 100644
--- a/packages/editor/src/components/page-attributes/order.js
+++ b/packages/editor/src/components/page-attributes/order.js
@@ -59,7 +59,7 @@ function PageAttributesOrder() {
* for setting the order of a given page.
* The component is now not used in core but was kept for backward compatibility.
*
- * @return {Component} The component to be rendered.
+ * @return {React.ReactNode} The rendered component.
*/
export default function PageAttributesOrderWithChecks() {
return (
diff --git a/packages/editor/src/components/page-attributes/panel.js b/packages/editor/src/components/page-attributes/panel.js
index 7fcaf4b90d9ffe..8ecf7f1642f718 100644
--- a/packages/editor/src/components/page-attributes/panel.js
+++ b/packages/editor/src/components/page-attributes/panel.js
@@ -33,7 +33,7 @@ function AttributesPanel() {
/**
* Renders the Page Attributes Panel component.
*
- * @return {Component} The component to be rendered.
+ * @return {React.ReactNode} The rendered component.
*/
export default function PageAttributesPanel() {
return (
diff --git a/packages/editor/src/components/page-attributes/parent.js b/packages/editor/src/components/page-attributes/parent.js
index 17395589cd313b..bd2861766c334a 100644
--- a/packages/editor/src/components/page-attributes/parent.js
+++ b/packages/editor/src/components/page-attributes/parent.js
@@ -56,7 +56,7 @@ export const getItemPriority = ( name, searchValue ) => {
* Renders the Page Attributes Parent component. A dropdown menu in an editor interface
* for selecting the parent page of a given page.
*
- * @return {Component|null} The component to be rendered. Return null if post type is not hierarchical.
+ * @return {React.ReactNode} The component to be rendered. Return null if post type is not hierarchical.
*/
export function PageAttributesParent() {
const { editPost } = useDispatch( editorStore );
diff --git a/packages/editor/src/components/plugin-document-setting-panel/index.js b/packages/editor/src/components/plugin-document-setting-panel/index.js
index 7466acffc0c4b1..6408d82fe7e118 100644
--- a/packages/editor/src/components/plugin-document-setting-panel/index.js
+++ b/packages/editor/src/components/plugin-document-setting-panel/index.js
@@ -22,7 +22,7 @@ const { Fill, Slot } = createSlotFill( 'PluginDocumentSettingPanel' );
* @param {string} [props.className] An optional class name added to the row.
* @param {string} [props.title] The title of the panel
* @param {WPBlockTypeIconRender} [props.icon=inherits from the plugin] The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered when the sidebar is pinned to toolbar.
- * @param {Element} props.children Children to be rendered
+ * @param {React.ReactNode} props.children Children to be rendered
*
* @example
* ```js
@@ -64,7 +64,7 @@ const { Fill, Slot } = createSlotFill( 'PluginDocumentSettingPanel' );
* registerPlugin( 'document-setting-test', { render: MyDocumentSettingTest } );
* ```
*
- * @return {Component} The component to be rendered.
+ * @return {React.ReactNode} The component to be rendered.
*/
const PluginDocumentSettingPanel = ( {
name,
diff --git a/packages/editor/src/components/plugin-more-menu-item/index.js b/packages/editor/src/components/plugin-more-menu-item/index.js
index 28173c24ebcefa..1d8e124b03e604 100644
--- a/packages/editor/src/components/plugin-more-menu-item/index.js
+++ b/packages/editor/src/components/plugin-more-menu-item/index.js
@@ -10,6 +10,7 @@ import { ActionItem } from '@wordpress/interface';
* The text within the component appears as the menu item label.
*
* @param {Object} props Component properties.
+ * @param {React.ReactNode} [props.children] Children to be rendered.
* @param {string} [props.href] When `href` is provided then the menu item is represented as an anchor rather than button. It corresponds to the `href` attribute of the anchor.
* @param {WPBlockTypeIconRender} [props.icon=inherits from the plugin] The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered to the left of the menu item label.
* @param {Function} [props.onClick=noop] The callback function to be executed when the user clicks the menu item.
@@ -59,7 +60,7 @@ import { ActionItem } from '@wordpress/interface';
* );
* ```
*
- * @return {Component} The component to be rendered.
+ * @return {React.ReactNode} The rendered component.
*/
export default function PluginMoreMenuItem( props ) {
const context = usePluginContext();
diff --git a/packages/editor/src/components/plugin-post-publish-panel/index.js b/packages/editor/src/components/plugin-post-publish-panel/index.js
index 086045b1c1fee1..b93f0a15c237f5 100644
--- a/packages/editor/src/components/plugin-post-publish-panel/index.js
+++ b/packages/editor/src/components/plugin-post-publish-panel/index.js
@@ -15,7 +15,7 @@ const { Fill, Slot } = createSlotFill( 'PluginPostPublishPanel' );
* @param {string} [props.title] Title displayed at the top of the panel.
* @param {boolean} [props.initialOpen=false] Whether to have the panel initially opened. When no title is provided it is always opened.
* @param {WPBlockTypeIconRender} [props.icon=inherits from the plugin] The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered when the sidebar is pinned to toolbar.
- * @param {Element} props.children Children to be rendered
+ * @param {React.ReactNode} props.children Children to be rendered
*
* @example
* ```jsx
@@ -34,7 +34,7 @@ const { Fill, Slot } = createSlotFill( 'PluginPostPublishPanel' );
* );
* ```
*
- * @return {Component} The component to be rendered.
+ * @return {React.ReactNode} The rendered component.
*/
const PluginPostPublishPanel = ( {
children,
diff --git a/packages/editor/src/components/plugin-post-status-info/index.js b/packages/editor/src/components/plugin-post-status-info/index.js
index a4a216b78ae78b..f9f3293047ddd3 100644
--- a/packages/editor/src/components/plugin-post-status-info/index.js
+++ b/packages/editor/src/components/plugin-post-status-info/index.js
@@ -14,9 +14,9 @@ const { Fill, Slot } = createSlotFill( 'PluginPostStatusInfo' );
* It should be noted that this is named and implemented around the function it serves
* and not its location, which may change in future iterations.
*
- * @param {Object} props Component properties.
- * @param {string} [props.className] An optional class name added to the row.
- * @param {Element} props.children Children to be rendered.
+ * @param {Object} props Component properties.
+ * @param {string} [props.className] An optional class name added to the row.
+ * @param {React.ReactNode} props.children Children to be rendered.
*
* @example
* ```js
@@ -50,7 +50,7 @@ const { Fill, Slot } = createSlotFill( 'PluginPostStatusInfo' );
* );
* ```
*
- * @return {Component} The component to be rendered.
+ * @return {React.ReactNode} The rendered component.
*/
const PluginPostStatusInfo = ( { children, className } ) => (
diff --git a/packages/editor/src/components/plugin-pre-publish-panel/index.js b/packages/editor/src/components/plugin-pre-publish-panel/index.js
index c9f556dc534a80..412af36c5176e0 100644
--- a/packages/editor/src/components/plugin-pre-publish-panel/index.js
+++ b/packages/editor/src/components/plugin-pre-publish-panel/index.js
@@ -18,7 +18,7 @@ const { Fill, Slot } = createSlotFill( 'PluginPrePublishPanel' );
* @param {WPBlockTypeIconRender} [props.icon=inherits from the plugin] The [Dashicon](https://developer.wordpress.org/resource/dashicons/)
* icon slug string, or an SVG WP element, to be rendered when
* the sidebar is pinned to toolbar.
- * @param {Element} props.children Children to be rendered
+ * @param {React.ReactNode} props.children Children to be rendered
*
* @example
* ```jsx
@@ -37,7 +37,7 @@ const { Fill, Slot } = createSlotFill( 'PluginPrePublishPanel' );
* );
* ```
*
- * @return {Component} The component to be rendered.
+ * @return {React.ReactNode} The rendered component.
*/
const PluginPrePublishPanel = ( {
children,
diff --git a/packages/editor/src/components/plugin-preview-menu-item/index.js b/packages/editor/src/components/plugin-preview-menu-item/index.js
index 8038da04595aae..949f02808a7b03 100644
--- a/packages/editor/src/components/plugin-preview-menu-item/index.js
+++ b/packages/editor/src/components/plugin-preview-menu-item/index.js
@@ -10,6 +10,7 @@ import { ActionItem } from '@wordpress/interface';
* The text within the component appears as the menu item label.
*
* @param {Object} props Component properties.
+ * @param {React.ReactNode} [props.children] Children to be rendered.
* @param {string} [props.href] When `href` is provided, the menu item is rendered as an anchor instead of a button. It corresponds to the `href` attribute of the anchor.
* @param {WPBlockTypeIconRender} [props.icon=inherits from the plugin] The icon to be rendered to the left of the menu item label. Can be a Dashicon slug or an SVG WP element.
* @param {Function} [props.onClick] The callback function to be executed when the user clicks the menu item.
@@ -38,7 +39,7 @@ import { ActionItem } from '@wordpress/interface';
* } );
* ```
*
- * @return {Component} The rendered menu item component.
+ * @return {React.ReactNode} The rendered menu item component.
*/
export default function PluginPreviewMenuItem( props ) {
const context = usePluginContext();
diff --git a/packages/editor/src/components/plugin-sidebar-more-menu-item/index.js b/packages/editor/src/components/plugin-sidebar-more-menu-item/index.js
index 0d7695c9abfe12..379a0720dc8a91 100644
--- a/packages/editor/src/components/plugin-sidebar-more-menu-item/index.js
+++ b/packages/editor/src/components/plugin-sidebar-more-menu-item/index.js
@@ -10,6 +10,7 @@ import { ComplementaryAreaMoreMenuItem } from '@wordpress/interface';
*
* @param {Object} props Component props.
* @param {string} props.target A string identifying the target sidebar you wish to be activated by this menu item. Must be the same as the `name` prop you have given to that sidebar.
+ * @param {React.ReactNode} [props.children] Children to be rendered.
* @param {WPBlockTypeIconRender} [props.icon=inherits from the plugin] The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered to the left of the menu item label.
*
* @example
@@ -48,9 +49,8 @@ import { ComplementaryAreaMoreMenuItem } from '@wordpress/interface';
* );
* ```
*
- * @return {Component} The component to be rendered.
+ * @return {React.ReactNode} The rendered component.
*/
-
export default function PluginSidebarMoreMenuItem( props ) {
return (
{
diff --git a/packages/editor/src/components/post-author/panel.js b/packages/editor/src/components/post-author/panel.js
index 6c6a51918902dc..5a413aedac09cf 100644
--- a/packages/editor/src/components/post-author/panel.js
+++ b/packages/editor/src/components/post-author/panel.js
@@ -39,7 +39,7 @@ function PostAuthorToggle( { isOpen, onClick } ) {
/**
* Renders the Post Author Panel component.
*
- * @return {Component} The component to be rendered.
+ * @return {React.ReactNode} The rendered component.
*/
export function PostAuthor() {
// Use internal state instead of a ref to make sure that the component
diff --git a/packages/editor/src/components/post-card-panel/index.js b/packages/editor/src/components/post-card-panel/index.js
index 410b8cfd4447d9..8fcca6c6bd6d40 100644
--- a/packages/editor/src/components/post-card-panel/index.js
+++ b/packages/editor/src/components/post-card-panel/index.js
@@ -22,6 +22,7 @@ import {
import { unlock } from '../../lock-unlock';
import PostActions from '../post-actions';
import usePageTypeBadge from '../../utils/pageTypeBadge';
+import { getTemplateInfo } from '../../utils/get-template-info';
export default function PostCardPanel( {
postType,
@@ -30,17 +31,29 @@ export default function PostCardPanel( {
} ) {
const { title, icon } = useSelect(
( select ) => {
- const { __experimentalGetTemplateInfo } = select( editorStore );
const { getEditedEntityRecord } = select( coreStore );
const _record = getEditedEntityRecord(
'postType',
postType,
postId
);
- const _templateInfo =
- [ TEMPLATE_POST_TYPE, TEMPLATE_PART_POST_TYPE ].includes(
- postType
- ) && __experimentalGetTemplateInfo( _record );
+
+ const { default_template_types: templateTypes = [] } =
+ select( coreStore ).getEntityRecord(
+ 'root',
+ '__unstableBase'
+ ) ?? {};
+
+ const _templateInfo = [
+ TEMPLATE_POST_TYPE,
+ TEMPLATE_PART_POST_TYPE,
+ ].includes( postType )
+ ? getTemplateInfo( {
+ template: _record,
+ templateTypes,
+ } )
+ : {};
+
return {
title: _templateInfo?.title || _record?.title,
icon: unlock( select( editorStore ) ).getPostIcon( postType, {
diff --git a/packages/editor/src/components/post-comments/index.js b/packages/editor/src/components/post-comments/index.js
index 1d331811b46b26..6e69f9bce4f838 100644
--- a/packages/editor/src/components/post-comments/index.js
+++ b/packages/editor/src/components/post-comments/index.js
@@ -61,6 +61,6 @@ function PostComments() {
/**
* A form for managing comment status.
*
- * @return {JSX.Element} The rendered PostComments component.
+ * @return {React.ReactNode} The rendered PostComments component.
*/
export default PostComments;
diff --git a/packages/editor/src/components/post-discussion/panel.js b/packages/editor/src/components/post-discussion/panel.js
index c539791d404dec..280ab11b0447e7 100644
--- a/packages/editor/src/components/post-discussion/panel.js
+++ b/packages/editor/src/components/post-discussion/panel.js
@@ -93,7 +93,7 @@ function PostDiscussionToggle( { isOpen, onClick } ) {
* checks whether the current post has support for the
* above and if the `discussion-panel` panel is enabled.
*
- * @return {JSX.Element|null} The rendered PostDiscussionPanel component.
+ * @return {React.ReactNode} The rendered PostDiscussionPanel component.
*/
export default function PostDiscussionPanel() {
const { isEnabled } = useSelect( ( select ) => {
diff --git a/packages/editor/src/components/post-excerpt/check.js b/packages/editor/src/components/post-excerpt/check.js
index 77436ecfed218a..c518d90e424a9b 100644
--- a/packages/editor/src/components/post-excerpt/check.js
+++ b/packages/editor/src/components/post-excerpt/check.js
@@ -6,10 +6,10 @@ import PostTypeSupportCheck from '../post-type-support-check';
/**
* Component for checking if the post type supports the excerpt field.
*
- * @param {Object} props Props.
- * @param {Element} props.children Children to be rendered.
+ * @param {Object} props Props.
+ * @param {React.ReactNode} props.children Children to be rendered.
*
- * @return {Component} The component to be rendered.
+ * @return {React.ReactNode} The rendered component.
*/
function PostExcerptCheck( { children } ) {
return (
diff --git a/packages/editor/src/components/post-excerpt/panel.js b/packages/editor/src/components/post-excerpt/panel.js
index 9c09796f467040..d4f2b27126c7c1 100644
--- a/packages/editor/src/components/post-excerpt/panel.js
+++ b/packages/editor/src/components/post-excerpt/panel.js
@@ -83,7 +83,7 @@ function ExcerptPanel() {
/**
* Is rendered if the post type supports excerpts and allows editing the excerpt.
*
- * @return {JSX.Element} The rendered PostExcerptPanel component.
+ * @return {React.ReactNode} The rendered PostExcerptPanel component.
*/
export default function PostExcerptPanel() {
return (
diff --git a/packages/editor/src/components/post-excerpt/plugin.js b/packages/editor/src/components/post-excerpt/plugin.js
index 64861162a0f637..50c494c01cb6d8 100644
--- a/packages/editor/src/components/post-excerpt/plugin.js
+++ b/packages/editor/src/components/post-excerpt/plugin.js
@@ -12,9 +12,9 @@ const { Fill, Slot } = createSlotFill( 'PluginPostExcerpt' );
/**
* Renders a post excerpt panel in the post sidebar.
*
- * @param {Object} props Component properties.
- * @param {string} [props.className] An optional class name added to the row.
- * @param {Element} props.children Children to be rendered.
+ * @param {Object} props Component properties.
+ * @param {string} [props.className] An optional class name added to the row.
+ * @param {React.ReactNode} props.children Children to be rendered.
*
* @example
* ```js
@@ -46,7 +46,7 @@ const { Fill, Slot } = createSlotFill( 'PluginPostExcerpt' );
* );
* ```
*
- * @return {Component} The component to be rendered.
+ * @return {React.ReactNode} The rendered component.
*/
const PluginPostExcerpt = ( { children, className } ) => {
return (
diff --git a/packages/editor/src/components/post-featured-image/check.js b/packages/editor/src/components/post-featured-image/check.js
index 823559f766bc35..700a3b8edfd032 100644
--- a/packages/editor/src/components/post-featured-image/check.js
+++ b/packages/editor/src/components/post-featured-image/check.js
@@ -8,10 +8,10 @@ import ThemeSupportCheck from '../theme-support-check';
* Wrapper component that renders its children only if the post type supports a featured image
* and the theme supports post thumbnails.
*
- * @param {Object} props Props.
- * @param {Element} props.children Children to be rendered.
+ * @param {Object} props Props.
+ * @param {React.ReactNode} props.children Children to be rendered.
*
- * @return {Component} The component to be rendered.
+ * @return {React.ReactNode} The rendered component.
*/
function PostFeaturedImageCheck( { children } ) {
return (
diff --git a/packages/editor/src/components/post-featured-image/index.js b/packages/editor/src/components/post-featured-image/index.js
index 46a194f311a5e7..acf366506cc41e 100644
--- a/packages/editor/src/components/post-featured-image/index.js
+++ b/packages/editor/src/components/post-featured-image/index.js
@@ -18,7 +18,7 @@ import {
Notice,
} from '@wordpress/components';
import { isBlobURL } from '@wordpress/blob';
-import { useState, useRef, useEffect } from '@wordpress/element';
+import { useState, useRef } from '@wordpress/element';
import { compose } from '@wordpress/compose';
import { useSelect, withDispatch, withSelect } from '@wordpress/data';
import {
@@ -102,17 +102,10 @@ function PostFeaturedImage( {
noticeOperations,
isRequestingFeaturedImageMedia,
} ) {
- const toggleRef = useRef();
+ const returnsFocusRef = useRef( false );
const [ isLoading, setIsLoading ] = useState( false );
const { getSettings } = useSelect( blockEditorStore );
const { mediaSourceUrl } = getMediaDetails( media, currentPostId );
- const toggleFocusTimerRef = useRef();
-
- useEffect( () => {
- return () => {
- clearTimeout( toggleFocusTimerRef.current );
- };
- }, [] );
function onDropFiles( filesList ) {
getSettings().mediaUpload( {
@@ -164,6 +157,13 @@ function PostFeaturedImage( {
);
}
+ function returnFocus( node ) {
+ if ( returnsFocusRef.current && node ) {
+ node.focus();
+ returnsFocusRef.current = false;
+ }
+ }
+
const isMissingMedia =
! isRequestingFeaturedImageMedia && !! featuredImageId && ! media;
@@ -203,7 +203,7 @@ function PostFeaturedImage( {
) : (
+
+
+
+ comment
+
+
+
+
🍒
@@ -289,6 +304,21 @@ exports[`recordToDom should preserve emoji in formatting 1`] = `
+
+
+
+ /funky
+
+
+
+
test test
diff --git a/packages/rich-text/src/test/helpers/index.js b/packages/rich-text/src/test/helpers/index.js
index f246ab956db3a7..7658ede7e37737 100644
--- a/packages/rich-text/src/test/helpers/index.js
+++ b/packages/rich-text/src/test/helpers/index.js
@@ -551,6 +551,58 @@ export const spec = [
text: '\ufffc',
},
},
+ {
+ description: 'should preserve comments',
+ html: '',
+ createRange: ( element ) => ( {
+ startOffset: 0,
+ startContainer: element,
+ endOffset: 1,
+ endContainer: element,
+ } ),
+ startPath: [ 0, 0 ],
+ endPath: [ 2, 0 ],
+ record: {
+ start: 0,
+ end: 1,
+ formats: [ , ],
+ replacements: [
+ {
+ attributes: {
+ 'data-rich-text-comment': 'comment',
+ },
+ type: '#comment',
+ },
+ ],
+ text: '\ufffc',
+ },
+ },
+ {
+ description: 'should preserve funky comments',
+ html: '/funky>',
+ createRange: ( element ) => ( {
+ startOffset: 0,
+ startContainer: element,
+ endOffset: 1,
+ endContainer: element,
+ } ),
+ startPath: [ 0, 0 ],
+ endPath: [ 2, 0 ],
+ record: {
+ start: 0,
+ end: 1,
+ formats: [ , ],
+ replacements: [
+ {
+ attributes: {
+ 'data-rich-text-comment': '/funky',
+ },
+ type: '#comment',
+ },
+ ],
+ text: '\ufffc',
+ },
+ },
];
export const specWithRegistration = [
diff --git a/packages/rich-text/src/to-dom.js b/packages/rich-text/src/to-dom.js
index e7288e4ba16332..ac8308c7274b58 100644
--- a/packages/rich-text/src/to-dom.js
+++ b/packages/rich-text/src/to-dom.js
@@ -68,10 +68,16 @@ function append( element, child ) {
const { type, attributes } = child;
if ( type ) {
- child = element.ownerDocument.createElement( type );
+ if ( type === '#comment' ) {
+ child = element.ownerDocument.createComment(
+ attributes[ 'data-rich-text-comment' ]
+ );
+ } else {
+ child = element.ownerDocument.createElement( type );
- for ( const key in attributes ) {
- child.setAttribute( key, attributes[ key ] );
+ for ( const key in attributes ) {
+ child.setAttribute( key, attributes[ key ] );
+ }
}
}
diff --git a/packages/rich-text/src/to-html-string.js b/packages/rich-text/src/to-html-string.js
index f770dfdefc128a..a4c12b4c47f00d 100644
--- a/packages/rich-text/src/to-html-string.js
+++ b/packages/rich-text/src/to-html-string.js
@@ -88,6 +88,15 @@ function remove( object ) {
}
function createElementHTML( { type, attributes, object, children } ) {
+ if ( type === '#comment' ) {
+ // We can't restore the original comment delimiters, because once parsed
+ // into DOM nodes, we don't have the information. But in the future we
+ // could allow comment handlers to specify custom delimiters, for
+ // example `{comment-content}>` for Bits, where `comment-content`
+ // would be `/{bit-name}` or `__{translatable-string}` (TBD).
+ return ``;
+ }
+
let attributeString = '';
for ( const key in attributes ) {
diff --git a/packages/rich-text/src/to-tree.js b/packages/rich-text/src/to-tree.js
index 46671c951bc09d..0e3caad4f70c83 100644
--- a/packages/rich-text/src/to-tree.js
+++ b/packages/rich-text/src/to-tree.js
@@ -229,7 +229,20 @@ export function toTree( {
const { type, attributes, innerHTML } = replacement;
const formatType = getFormatType( type );
- if ( ! isEditableTree && type === 'script' ) {
+ if ( isEditableTree && type === '#comment' ) {
+ pointer = append( getParent( pointer ), {
+ type: 'span',
+ attributes: {
+ contenteditable: 'false',
+ 'data-rich-text-comment':
+ attributes[ 'data-rich-text-comment' ],
+ },
+ } );
+ append(
+ append( pointer, { type: 'span' } ),
+ attributes[ 'data-rich-text-comment' ].trim()
+ );
+ } else if ( ! isEditableTree && type === 'script' ) {
pointer = append(
getParent( pointer ),
fromFormat( {
diff --git a/test/e2e/specs/site-editor/zoom-out.spec.js b/test/e2e/specs/site-editor/zoom-out.spec.js
index 464bd4a4a4efad..e698a94b7cf0dc 100644
--- a/test/e2e/specs/site-editor/zoom-out.spec.js
+++ b/test/e2e/specs/site-editor/zoom-out.spec.js
@@ -3,6 +3,63 @@
*/
const { test, expect } = require( '@wordpress/e2e-test-utils-playwright' );
+const EDITOR_ZOOM_OUT_CONTENT = `
+
+
+
First Section Start
+
+
+
+
First Section Center
+
+
+
+
First Section End
+
+
+
+
+
+
Second Section Start
+
+
+
+
Second Section Center
+
+
+
+
Second Section End
+
+
+
+
+
+
Third Section Start
+
+
+
+
Third Section Center
+
+
+
+
Third Section End
+
+
+
+
+
+
Fourth Section Start
+
+
+
+
Fourth Section Center
+
+
+
+
Fourth Section End
+
+`;
+
test.describe( 'Zoom Out', () => {
test.beforeAll( async ( { requestUtils } ) => {
await requestUtils.activateTheme( 'twentytwentyfour' );
@@ -47,4 +104,115 @@ test.describe( 'Zoom Out', () => {
expect( htmlRect.y + paddingTop ).toBeGreaterThan( iframeRect.y );
expect( htmlRect.x ).toBeGreaterThan( iframeRect.x );
} );
+
+ test( 'Toggling zoom state should keep content centered', async ( {
+ page,
+ editor,
+ } ) => {
+ // Add some patterns into the page.
+ await editor.setContent( EDITOR_ZOOM_OUT_CONTENT );
+ // Find the scroll container element
+ await page.evaluate( () => {
+ const { activeElement } =
+ document.activeElement?.contentDocument ?? document;
+ window.scrollContainer =
+ window.wp.dom.getScrollContainer( activeElement );
+ return window.scrollContainer;
+ } );
+
+ // Test: Test from top of page (scrollTop 0)
+ // Enter Zoom Out
+ await page.getByRole( 'button', { name: 'Zoom Out' } ).click();
+
+ const scrollTopZoomed = await page.evaluate( () => {
+ return window.scrollContainer.scrollTop;
+ } );
+
+ expect( scrollTopZoomed ).toBe( 0 );
+
+ // Exit Zoom Out
+ await page.getByRole( 'button', { name: 'Zoom Out' } ).click();
+
+ const scrollTopNoZoom = await page.evaluate( () => {
+ return window.scrollContainer.scrollTop;
+ } );
+
+ expect( scrollTopNoZoom ).toBe( 0 );
+
+ // Test: Should center the scroll position when zooming out/in
+ const firstSectionEnd = editor.canvas.locator(
+ 'text=First Section End'
+ );
+ const secondSectionStart = editor.canvas.locator(
+ 'text=Second Section Start'
+ );
+ const secondSectionCenter = editor.canvas.locator(
+ 'text=Second Section Center'
+ );
+ const secondSectionEnd = editor.canvas.locator(
+ 'text=Second Section End'
+ );
+ const thirdSectionStart = editor.canvas.locator(
+ 'text=Third Section Start'
+ );
+ const thirdSectionCenter = editor.canvas.locator(
+ 'text=Third Section Center'
+ );
+ const thirdSectionEnd = editor.canvas.locator(
+ 'text=Third Section End'
+ );
+ const fourthSectionStart = editor.canvas.locator(
+ 'text=Fourth Section Start'
+ );
+
+ // Test for second section
+ // Playwright scrolls it to the center of the viewport, so this is what we scroll to.
+ await secondSectionCenter.scrollIntoViewIfNeeded();
+
+ // Because the text is spread with a group height of 100vh, they should both be visible.
+ await expect( firstSectionEnd ).not.toBeInViewport();
+ await expect( secondSectionStart ).toBeInViewport();
+ await expect( secondSectionEnd ).toBeInViewport();
+ await expect( thirdSectionStart ).not.toBeInViewport();
+
+ // After zooming, if we zoomed out with the correct central point, they should both still be visible when toggling zoom out state
+ // Enter Zoom Out
+ await page.getByRole( 'button', { name: 'Zoom Out' } ).click();
+ await expect( firstSectionEnd ).toBeInViewport();
+ await expect( secondSectionStart ).toBeInViewport();
+ await expect( secondSectionEnd ).toBeInViewport();
+ await expect( thirdSectionStart ).toBeInViewport();
+
+ // Exit Zoom Out
+ await page.getByRole( 'button', { name: 'Zoom Out' } ).click();
+ await expect( firstSectionEnd ).not.toBeInViewport();
+ await expect( secondSectionStart ).toBeInViewport();
+ await expect( secondSectionEnd ).toBeInViewport();
+ await expect( thirdSectionStart ).not.toBeInViewport();
+
+ // Test for third section
+ // Playwright scrolls it to the center of the viewport, so this is what we scroll to.
+ await thirdSectionCenter.scrollIntoViewIfNeeded();
+
+ // Because the text is spread with a group height of 100vh, they should both be visible.
+ await expect( secondSectionEnd ).not.toBeInViewport();
+ await expect( thirdSectionStart ).toBeInViewport();
+ await expect( thirdSectionEnd ).toBeInViewport();
+ await expect( fourthSectionStart ).not.toBeInViewport();
+
+ // After zooming, if we zoomed out with the correct central point, they should both still be visible when toggling zoom out state
+ // Enter Zoom Out
+ await page.getByRole( 'button', { name: 'Zoom Out' } ).click();
+ await expect( secondSectionEnd ).toBeInViewport();
+ await expect( thirdSectionStart ).toBeInViewport();
+ await expect( thirdSectionEnd ).toBeInViewport();
+ await expect( fourthSectionStart ).toBeInViewport();
+
+ // Exit Zoom Out
+ await page.getByRole( 'button', { name: 'Zoom Out' } ).click();
+ await expect( secondSectionEnd ).not.toBeInViewport();
+ await expect( thirdSectionStart ).toBeInViewport();
+ await expect( thirdSectionEnd ).toBeInViewport();
+ await expect( fourthSectionStart ).not.toBeInViewport();
+ } );
} );