From 8b264bf816cb8acad08f0d376e2c694ac0c81225 Mon Sep 17 00:00:00 2001 From: "them.es" Date: Tue, 3 Oct 2023 18:58:02 +0200 Subject: [PATCH 01/19] Query view.js: Code quality (#54982) Fixing a typo and improving some JS comments --- packages/block-library/src/query/view.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/block-library/src/query/view.js b/packages/block-library/src/query/view.js index 3e50d521ea6ef7..96be4ee513fcec 100644 --- a/packages/block-library/src/query/view.js +++ b/packages/block-library/src/query/view.js @@ -11,10 +11,10 @@ const isValidLink = ( ref ) => ref.origin === window.location.origin; const isValidEvent = ( event ) => - event.button === 0 && // left clicks only - ! event.metaKey && // open in new tab (mac) - ! event.ctrlKey && // open in new tab (windows) - ! event.altKey && // download + event.button === 0 && // Left clicks only. + ! event.metaKey && // Open in new tab (Mac). + ! event.ctrlKey && // Open in new tab (Windows). + ! event.altKey && // Download. ! event.shiftKey && ! event.defaultPrevented; @@ -39,7 +39,7 @@ store( { const id = ref.closest( '[data-wp-navigation-id]' ) .dataset.wpNavigationId; - // Don't announce the navigation immediately, wait 300 ms. + // Don't announce the navigation immediately, wait 400 ms. const timeout = setTimeout( () => { context.core.query.message = context.core.query.loadingText; From 39b57b0c63d91c6dc1b1b9998c441f22b4cdfb61 Mon Sep 17 00:00:00 2001 From: Ben Dwyer Date: Tue, 3 Oct 2023 21:13:48 +0100 Subject: [PATCH 02/19] Add template replace flow to template inspector (#54609) * Add a modal to allow template switching * fetch template info * Allow switching to different patterns * Allow switching to different patterns * Add columns * move availble templates to the actions * filter for the correct templates * create the right data structure in the use select * move to a hook * inject theme attribute into pattern again * put the overlay over the top of the dropdown * fix the pattern to templates hook * set the template on click * Also set the blocks * remove calls to set template with the current template, since setting blocks correctly updates the content in the editor * serialize blocks so that we have correctly processed template parts * remove duplicated code * Remove unnecessary mapping * refactor * memoize the patterns * combine the useSelect * Update packages/edit-site/src/components/sidebar-edit-mode/page-panels/hooks.js Co-authored-by: Andrei Draganescu * Fix ESLint error * Only show the button is there is more than 1 pattern * Copy update * Move the hook to a subdir * check that there are patterns * move the check * remove useCallback * change condition to show the button * change condition * move to use editEntityRecord * combine filters * add comments * Update packages/edit-site/src/components/sidebar-edit-mode/template-panel/replace-template-button.js Co-authored-by: Andrei Draganescu --------- Co-authored-by: Andrei Draganescu Co-authored-by: Andrei Draganescu Co-authored-by: George Mamadashvili --- packages/base-styles/_z-index.scss | 1 + .../sidebar-edit-mode/template-panel/hooks.js | 97 +++++++++++++++++++ .../template-panel/replace-template-button.js | 89 +++++++++++++++++ .../template-panel/style.scss | 18 ++++ .../template-panel/template-actions.js | 39 +++++--- 5 files changed, 232 insertions(+), 12 deletions(-) create mode 100644 packages/edit-site/src/components/sidebar-edit-mode/template-panel/hooks.js create mode 100644 packages/edit-site/src/components/sidebar-edit-mode/template-panel/replace-template-button.js diff --git a/packages/base-styles/_z-index.scss b/packages/base-styles/_z-index.scss index 12443a30a96656..cbe495d3787cd9 100644 --- a/packages/base-styles/_z-index.scss +++ b/packages/base-styles/_z-index.scss @@ -128,6 +128,7 @@ $z-layers: ( ".block-editor-block-rename-modal": 1000001, ".edit-site-list__rename-modal": 1000001, ".edit-site-swap-template-modal": 1000001, + ".edit-site-template-panel__replace-template-modal": 1000001, // Note: The ConfirmDialog component's z-index is being set to 1000001 in packages/components/src/confirm-dialog/styles.ts // because it uses emotion and not sass. We need it to render on top its parent popover. diff --git a/packages/edit-site/src/components/sidebar-edit-mode/template-panel/hooks.js b/packages/edit-site/src/components/sidebar-edit-mode/template-panel/hooks.js new file mode 100644 index 00000000000000..b5e5988491396a --- /dev/null +++ b/packages/edit-site/src/components/sidebar-edit-mode/template-panel/hooks.js @@ -0,0 +1,97 @@ +/** + * WordPress dependencies + */ +import { useSelect } from '@wordpress/data'; +import { useMemo } from '@wordpress/element'; +import { store as coreStore } from '@wordpress/core-data'; +import { parse } from '@wordpress/blocks'; + +/** + * Internal dependencies + */ +import { store as editSiteStore } from '../../../store'; +import { PATTERN_CORE_SOURCES, PATTERN_TYPES } from '../../../utils/constants'; +import { unlock } from '../../../lock-unlock'; + +function injectThemeAttributeInBlockTemplateContent( + block, + currentThemeStylesheet +) { + block.innerBlocks = block.innerBlocks.map( ( innerBlock ) => { + return injectThemeAttributeInBlockTemplateContent( + innerBlock, + currentThemeStylesheet + ); + } ); + + if ( + block.name === 'core/template-part' && + block.attributes.theme === undefined + ) { + block.attributes.theme = currentThemeStylesheet; + } + return block; +} + +function preparePatterns( patterns, template, currentThemeStylesheet ) { + // Filter out duplicates. + const filterOutDuplicatesByName = ( currentItem, index, items ) => + index === items.findIndex( ( item ) => currentItem.name === item.name ); + + // Filter out core patterns. + const filterOutCorePatterns = ( pattern ) => + ! PATTERN_CORE_SOURCES.includes( pattern.source ); + + // Filter only the patterns that are compatible with the current template. + const filterCompatiblePatterns = ( pattern ) => + pattern.templateTypes?.includes( template.slug ); + + return patterns + .filter( + filterOutCorePatterns && + filterOutDuplicatesByName && + filterCompatiblePatterns + ) + .map( ( pattern ) => ( { + ...pattern, + keywords: pattern.keywords || [], + type: PATTERN_TYPES.theme, + blocks: parse( pattern.content, { + __unstableSkipMigrationLogs: true, + } ).map( ( block ) => + injectThemeAttributeInBlockTemplateContent( + block, + currentThemeStylesheet + ) + ), + } ) ); +} + +export function useAvailablePatterns( template ) { + const { blockPatterns, restBlockPatterns, currentThemeStylesheet } = + useSelect( ( select ) => { + const { getSettings } = unlock( select( editSiteStore ) ); + const settings = getSettings(); + + return { + blockPatterns: + settings.__experimentalAdditionalBlockPatterns ?? + settings.__experimentalBlockPatterns, + restBlockPatterns: select( coreStore ).getBlockPatterns(), + currentThemeStylesheet: + select( coreStore ).getCurrentTheme().stylesheet, + }; + }, [] ); + + return useMemo( () => { + const mergedPatterns = [ + ...( blockPatterns || [] ), + ...( restBlockPatterns || [] ), + ]; + return preparePatterns( + mergedPatterns, + template, + currentThemeStylesheet + ); + }, [ blockPatterns, restBlockPatterns, template, currentThemeStylesheet ] ); +} diff --git a/packages/edit-site/src/components/sidebar-edit-mode/template-panel/replace-template-button.js b/packages/edit-site/src/components/sidebar-edit-mode/template-panel/replace-template-button.js new file mode 100644 index 00000000000000..658aacd331debc --- /dev/null +++ b/packages/edit-site/src/components/sidebar-edit-mode/template-panel/replace-template-button.js @@ -0,0 +1,89 @@ +/** + * WordPress dependencies + */ +import { useSelect, useDispatch } from '@wordpress/data'; +import { useState } from '@wordpress/element'; +import { __experimentalBlockPatternsList as BlockPatternsList } from '@wordpress/block-editor'; +import { MenuItem, Modal } from '@wordpress/components'; +import { __ } from '@wordpress/i18n'; +import { store as coreStore } from '@wordpress/core-data'; +import { useAsyncList } from '@wordpress/compose'; +import { serialize } from '@wordpress/blocks'; + +/** + * Internal dependencies + */ +import { store as editSiteStore } from '../../../store'; + +export default function ReplaceTemplateButton( { + onClick, + availableTemplates, +} ) { + const { editEntityRecord } = useDispatch( coreStore ); + const [ showModal, setShowModal ] = useState( false ); + const onClose = () => { + setShowModal( false ); + }; + + const { postId, postType } = useSelect( ( select ) => { + return { + postId: select( editSiteStore ).getEditedPostId(), + postType: select( editSiteStore ).getEditedPostType(), + }; + }, [] ); + + const onTemplateSelect = async ( selectedTemplate ) => { + onClose(); // Close the template suggestions modal first. + onClick(); + await editEntityRecord( 'postType', postType, postId, { + blocks: selectedTemplate.blocks, + content: serialize( selectedTemplate.blocks ), + } ); + }; + + if ( ! availableTemplates.length || availableTemplates.length < 1 ) { + return null; + } + + return ( + <> + setShowModal( true ) } + > + { __( 'Replace template' ) } + + + { showModal && ( + +
+ +
+
+ ) } + + ); +} + +function TemplatesList( { availableTemplates, onSelect } ) { + const shownTemplates = useAsyncList( availableTemplates ); + + return ( + + ); +} diff --git a/packages/edit-site/src/components/sidebar-edit-mode/template-panel/style.scss b/packages/edit-site/src/components/sidebar-edit-mode/template-panel/style.scss index 4c8ef94855dcb1..6eab753e8ad285 100644 --- a/packages/edit-site/src/components/sidebar-edit-mode/template-panel/style.scss +++ b/packages/edit-site/src/components/sidebar-edit-mode/template-panel/style.scss @@ -37,3 +37,21 @@ h3.edit-site-template-card__template-areas-title { font-weight: 500; margin: 0 0 $grid-unit-10; } + + +.edit-site-template-panel__replace-template-modal { + z-index: z-index(".edit-site-template-panel__replace-template-modal"); +} + +.edit-site-template-panel__replace-template-modal__content { + column-count: 2; + column-gap: $grid-unit-30; + + @include break-medium() { + column-count: 3; + } + + @include break-wide() { + column-count: 4; + } +} diff --git a/packages/edit-site/src/components/sidebar-edit-mode/template-panel/template-actions.js b/packages/edit-site/src/components/sidebar-edit-mode/template-panel/template-actions.js index b68cf1ff617579..81acb244a11863 100644 --- a/packages/edit-site/src/components/sidebar-edit-mode/template-panel/template-actions.js +++ b/packages/edit-site/src/components/sidebar-edit-mode/template-panel/template-actions.js @@ -11,13 +11,21 @@ import { moreVertical } from '@wordpress/icons'; */ import { store as editSiteStore } from '../../../store'; import isTemplateRevertable from '../../../utils/is-template-revertable'; +import ReplaceTemplateButton from './replace-template-button'; +import { useAvailablePatterns } from './hooks'; export default function Actions( { template } ) { + const availablePatterns = useAvailablePatterns( template ); const { revertTemplate } = useDispatch( editSiteStore ); const isRevertable = isTemplateRevertable( template ); - if ( ! isRevertable ) { + + if ( + ! isRevertable && + ( ! availablePatterns.length || availablePatterns.length < 1 ) + ) { return null; } + return ( { ( { onClose } ) => ( - { - revertTemplate( template ); - onClose(); - } } - > - { __( 'Clear customizations' ) } - + { isRevertable && ( + { + revertTemplate( template ); + onClose(); + } } + > + { __( 'Clear customizations' ) } + + ) } + ) } From 059928a1acb3288977d4b0098ab58e1e2ca7502a Mon Sep 17 00:00:00 2001 From: Andrew Serong <14988353+andrewserong@users.noreply.github.com> Date: Wed, 4 Oct 2023 13:21:31 +1100 Subject: [PATCH 03/19] List View: Fix performance issue when selecting all blocks (#54900) * List View: Fix performance issue when selecting all blocks within the editor canvas in long posts * Add a comment, rename const * Move block focus to be performed only once at the root of the list view, instead of within each block --- .../src/components/list-view/block.js | 46 ++----------------- .../src/components/list-view/branch.js | 12 ++++- .../src/components/list-view/index.js | 12 +++-- .../src/components/list-view/utils.js | 37 +++++++++++++++ 4 files changed, 59 insertions(+), 48 deletions(-) diff --git a/packages/block-editor/src/components/list-view/block.js b/packages/block-editor/src/components/list-view/block.js index 43fe4df4cb75aa..375f39a7cc3c81 100644 --- a/packages/block-editor/src/components/list-view/block.js +++ b/packages/block-editor/src/components/list-view/block.js @@ -13,16 +13,9 @@ import { } from '@wordpress/components'; import { useInstanceId } from '@wordpress/compose'; import { moreVertical } from '@wordpress/icons'; -import { - useState, - useRef, - useEffect, - useCallback, - memo, -} from '@wordpress/element'; +import { useState, useRef, useCallback, memo } from '@wordpress/element'; import { useDispatch, useSelect } from '@wordpress/data'; import { sprintf, __ } from '@wordpress/i18n'; -import { focus } from '@wordpress/dom'; import { ESCAPE } from '@wordpress/keycodes'; /** @@ -36,7 +29,7 @@ import { } from '../block-mover/button'; import ListViewBlockContents from './block-contents'; import { useListViewContext } from './context'; -import { getBlockPositionDescription } from './utils'; +import { getBlockPositionDescription, focusListItem } from './utils'; import { store as blockEditorStore } from '../../store'; import useBlockDisplayInformation from '../use-block-display-information'; import { useBlockLock } from '../block-lock'; @@ -120,7 +113,6 @@ function ListViewBlock( { ); const { - isTreeGridMounted, expand, collapse, BlockSettingsMenu, @@ -142,15 +134,6 @@ function ListViewBlock( { { 'is-visible': isHovered || isFirstSelectedBlock } ); - // If ListView has experimental features related to the Persistent List View, - // only focus the selected list item on mount; otherwise the list would always - // try to steal the focus from the editor canvas. - useEffect( () => { - if ( ! isTreeGridMounted && isSelected ) { - cellRef.current.focus(); - } - }, [] ); - // If multiple blocks are selected, deselect all blocks when the user // presses the escape key. const onKeyDown = ( event ) => { @@ -188,30 +171,7 @@ function ListViewBlock( { selectBlock( undefined, focusClientId, null, null ); } - const getFocusElement = () => { - const row = treeGridElementRef.current?.querySelector( - `[role=row][data-block="${ focusClientId }"]` - ); - if ( ! row ) return null; - // Focus the first focusable in the row, which is the ListViewBlockSelectButton. - return focus.focusable.find( row )[ 0 ]; - }; - - let focusElement = getFocusElement(); - if ( focusElement ) { - focusElement.focus(); - } else { - // The element hasn't been painted yet. Defer focusing on the next frame. - // This could happen when all blocks have been deleted and the default block - // hasn't been added to the editor yet. - window.requestAnimationFrame( () => { - focusElement = getFocusElement(); - // Ignore if the element still doesn't exist. - if ( focusElement ) { - focusElement.focus(); - } - } ); - } + focusListItem( focusClientId, treeGridElementRef ); }, [ selectBlock, treeGridElementRef ] ); diff --git a/packages/block-editor/src/components/list-view/branch.js b/packages/block-editor/src/components/list-view/branch.js index d3b555c055afd1..e2e27f5f2cb5af 100644 --- a/packages/block-editor/src/components/list-view/branch.js +++ b/packages/block-editor/src/components/list-view/branch.js @@ -168,8 +168,18 @@ function ListViewBranch( props ) { ); const isSelectedBranch = isBranchSelected || ( isSelected && hasNestedBlocks ); + + // To avoid performance issues, we only render blocks that are in view, + // or blocks that are selected or dragged. If a block is selected, + // it is only counted if it is the first of the block selection. + // This prevents the entire tree from being rendered when a branch is + // selected, or a user selects all blocks, while still enabling scroll + // into view behavior when selecting a block or opening the list view. const showBlock = - isDragged || blockInView || isSelected || isBranchDragged; + isDragged || + blockInView || + isBranchDragged || + ( isSelected && clientId === selectedClientIds[ 0 ] ); return ( { showBlock && ( diff --git a/packages/block-editor/src/components/list-view/index.js b/packages/block-editor/src/components/list-view/index.js index 917ebd883aa8d1..085864c4c88f45 100644 --- a/packages/block-editor/src/components/list-view/index.js +++ b/packages/block-editor/src/components/list-view/index.js @@ -32,6 +32,7 @@ import useListViewDropZone from './use-list-view-drop-zone'; import useListViewExpandSelectedItem from './use-list-view-expand-selected-item'; import { store as blockEditorStore } from '../../store'; import { BlockSettingsDropdown } from '../block-settings-menu/block-settings-dropdown'; +import { focusListItem } from './utils'; const expanded = ( state, action ) => { if ( Array.isArray( action.clientIds ) ) { @@ -132,8 +133,6 @@ function ListViewComponent( const elementRef = useRef(); const treeGridRef = useMergeRefs( [ elementRef, dropZoneRef, ref ] ); - const isMounted = useRef( false ); - const [ insertedBlock, setInsertedBlock ] = useState( null ); const { setSelectedTreeId } = useListViewExpandSelectedItem( { @@ -156,7 +155,13 @@ function ListViewComponent( [ setSelectedTreeId, updateBlockSelection, onSelect, getBlock ] ); useEffect( () => { - isMounted.current = true; + // If a blocks are already selected when the list view is initially + // mounted, shift focus to the first selected block. + if ( selectedClientIds?.length ) { + focusListItem( selectedClientIds[ 0 ], elementRef ); + } + // Disable reason: Only focus on the selected item when the list view is mounted. + // eslint-disable-next-line react-hooks/exhaustive-deps }, [] ); const expand = useCallback( @@ -204,7 +209,6 @@ function ListViewComponent( const contextValue = useMemo( () => ( { - isTreeGridMounted: isMounted.current, draggedClientIds, expandedState, expand, diff --git a/packages/block-editor/src/components/list-view/utils.js b/packages/block-editor/src/components/list-view/utils.js index f53f5a4cd4884a..632173e120691f 100644 --- a/packages/block-editor/src/components/list-view/utils.js +++ b/packages/block-editor/src/components/list-view/utils.js @@ -2,6 +2,7 @@ * WordPress dependencies */ import { __, sprintf } from '@wordpress/i18n'; +import { focus } from '@wordpress/dom'; export const getBlockPositionDescription = ( position, siblingCount, level ) => sprintf( @@ -56,3 +57,39 @@ export function getCommonDepthClientIds( end, }; } + +/** + * Shift focus to the list view item associated with a particular clientId. + * + * @typedef {import('@wordpress/element').RefObject} RefObject + * + * @param {string} focusClientId The client ID of the block to focus. + * @param {RefObject} treeGridElementRef The container element to search within. + */ +export function focusListItem( focusClientId, treeGridElementRef ) { + const getFocusElement = () => { + const row = treeGridElementRef.current?.querySelector( + `[role=row][data-block="${ focusClientId }"]` + ); + if ( ! row ) return null; + // Focus the first focusable in the row, which is the ListViewBlockSelectButton. + return focus.focusable.find( row )[ 0 ]; + }; + + let focusElement = getFocusElement(); + if ( focusElement ) { + focusElement.focus(); + } else { + // The element hasn't been painted yet. Defer focusing on the next frame. + // This could happen when all blocks have been deleted and the default block + // hasn't been added to the editor yet. + window.requestAnimationFrame( () => { + focusElement = getFocusElement(); + + // Ignore if the element still doesn't exist. + if ( focusElement ) { + focusElement.focus(); + } + } ); + } +} From e6cd5519c2f982f0ffbefe3b1031ee91dbcb2094 Mon Sep 17 00:00:00 2001 From: Derek Blank Date: Wed, 4 Oct 2023 13:12:13 +1000 Subject: [PATCH 04/19] [RNMobile] Update mobile iOS Ruby version to from 2.7.4 to 3.2.2. (#54897) * Update mobile ios ruby version to 3.2.2 * Update CHANGELOG --- packages/react-native-editor/CHANGELOG.md | 1 + packages/react-native-editor/ios/.ruby-version | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/react-native-editor/CHANGELOG.md b/packages/react-native-editor/CHANGELOG.md index 86161840ea1482..9316c4693cfaa6 100644 --- a/packages/react-native-editor/CHANGELOG.md +++ b/packages/react-native-editor/CHANGELOG.md @@ -15,6 +15,7 @@ For each user feature we should also add a importance categorization label to i - [*] Limit inner blocks nesting depth to avoid call stack size exceeded crash [#54382] - [*] Prevent crashes when setting an invalid media URL for Video or Audio blocks [#54834] - [**] Fallback to Twitter provider when embedding X URLs [#54876] +- [*] [internal] Update Ruby version from 2.7.4 to 3.2.2 [#54897] ## 1.104.0 - [*] Fix the obscurred "Insert from URL" input for media blocks when using a device in landscape orientation. [#54096] diff --git a/packages/react-native-editor/ios/.ruby-version b/packages/react-native-editor/ios/.ruby-version index a4dd9dba4fbfc5..be94e6f53db6b3 100644 --- a/packages/react-native-editor/ios/.ruby-version +++ b/packages/react-native-editor/ios/.ruby-version @@ -1 +1 @@ -2.7.4 +3.2.2 From 99d5c7c1dc1361be726458e8f41152148f75f858 Mon Sep 17 00:00:00 2001 From: tellthemachines Date: Wed, 4 Oct 2023 15:17:07 +1100 Subject: [PATCH 05/19] Fix left and right aligmnent in children of Post Template (#54997) * Fix left and right aligmnent in children of Post Template * Add align center styles * Fix image placeholder disappearing --- .../src/post-featured-image/style.scss | 4 ++++ .../src/post-template/style.scss | 20 +++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/packages/block-library/src/post-featured-image/style.scss b/packages/block-library/src/post-featured-image/style.scss index 4821e634b60327..e740b8c56e608c 100644 --- a/packages/block-library/src/post-featured-image/style.scss +++ b/packages/block-library/src/post-featured-image/style.scss @@ -39,4 +39,8 @@ } } } + + &:where(.alignleft, .alignright) { + width: 100%; + } } diff --git a/packages/block-library/src/post-template/style.scss b/packages/block-library/src/post-template/style.scss index 00305a17123369..4af30e30b23098 100644 --- a/packages/block-library/src/post-template/style.scss +++ b/packages/block-library/src/post-template/style.scss @@ -37,3 +37,23 @@ grid-template-columns: 1fr; } } + +.wp-block-post-template-is-layout-constrained > li > .alignright, +.wp-block-post-template-is-layout-flow > li > .alignright { + float: right; + margin-inline-start: 2em; + margin-inline-end: 0; +} + +.wp-block-post-template-is-layout-constrained > li > .alignleft, +.wp-block-post-template-is-layout-flow > li > .alignleft { + float: left; + margin-inline-start: 0; + margin-inline-end: 2em; +} + +.wp-block-post-template-is-layout-constrained > li > .aligncenter, +.wp-block-post-template-is-layout-flow > li > .aligncenter { + margin-inline-start: auto; + margin-inline-end: auto; +} From ac81cda0b95afd1703bfbb72692f05dc636f3b07 Mon Sep 17 00:00:00 2001 From: George Mamadashvili Date: Wed, 4 Oct 2023 08:20:36 +0400 Subject: [PATCH 06/19] Migrate 'iframed block editor settings styles' tests to Playwright (#55014) * Migrate 'iframed block editor settings styles' tests to Playwright * Remove old test file * Missing comments --- ...amed-enqueue-block-editor-settings.test.js | 108 ------------------ ...amed-enqueue-block-editor-settings.spec.js | 99 ++++++++++++++++ 2 files changed, 99 insertions(+), 108 deletions(-) delete mode 100644 packages/e2e-tests/specs/editor/plugins/iframed-enqueue-block-editor-settings.test.js create mode 100644 test/e2e/specs/editor/plugins/iframed-enqueue-block-editor-settings.spec.js diff --git a/packages/e2e-tests/specs/editor/plugins/iframed-enqueue-block-editor-settings.test.js b/packages/e2e-tests/specs/editor/plugins/iframed-enqueue-block-editor-settings.test.js deleted file mode 100644 index df6eb4bf840328..00000000000000 --- a/packages/e2e-tests/specs/editor/plugins/iframed-enqueue-block-editor-settings.test.js +++ /dev/null @@ -1,108 +0,0 @@ -/** - * WordPress dependencies - */ -import { - activatePlugin, - createNewPost, - deactivatePlugin, - canvas, - activateTheme, -} from '@wordpress/e2e-test-utils'; - -async function getComputedStyle( context, selector, property ) { - return await context.evaluate( - ( sel, prop ) => - window.getComputedStyle( document.querySelector( sel ) )[ prop ], - selector, - property - ); -} - -describe( 'iframed block editor settings styles', () => { - beforeEach( async () => { - // Activate the empty theme (block based theme), which is iframed. - await activateTheme( 'emptytheme' ); - await activatePlugin( - 'gutenberg-test-iframed-enqueue-block-editor-settings' - ); - await createNewPost(); - } ); - - afterEach( async () => { - await deactivatePlugin( - 'gutenberg-test-iframed-enqueue-block-editor-settings' - ); - await activateTheme( 'twentytwentyone' ); - } ); - - it( 'should load styles added through block editor settings', async () => { - await page.waitForSelector( 'iframe[name="editor-canvas"]' ); - // Expect a red border (added in PHP). - expect( await getComputedStyle( canvas(), 'p', 'border-color' ) ).toBe( - 'rgb(255, 0, 0)' - ); - - await page.evaluate( () => { - const settings = window.wp.data - .select( 'core/editor' ) - .getEditorSettings(); - wp.data.dispatch( 'core/editor' ).updateEditorSettings( { - ...settings, - styles: [ - ...settings.styles, - { - css: 'p { border-width: 2px; }', - __unstableType: 'plugin', - }, - ], - } ); - } ); - - // Expect a 2px border (added in JS). - expect( await getComputedStyle( canvas(), 'p', 'border-width' ) ).toBe( - '2px' - ); - } ); - - it( 'should load theme styles added through block editor settings', async () => { - await page.waitForSelector( 'iframe[name="editor-canvas"]' ); - - await page.evaluate( () => { - // Make sure that theme styles are added even if the theme styles - // preference is off. - window.wp.data - .dispatch( 'core/edit-post' ) - .toggleFeature( 'themeStyles' ); - const settings = window.wp.data - .select( 'core/editor' ) - .getEditorSettings(); - wp.data.dispatch( 'core/editor' ).updateEditorSettings( { - ...settings, - styles: [ - ...settings.styles, - { - css: 'p { border-width: 2px; }', - __unstableType: 'theme', - }, - ], - } ); - } ); - - // Expect a 1px border because theme styles are disabled. - expect( await getComputedStyle( canvas(), 'p', 'border-width' ) ).toBe( - '1px' - ); - - await page.evaluate( () => { - // Now enable theme styles. - window.wp.data - .dispatch( 'core/edit-post' ) - .toggleFeature( 'themeStyles' ); - } ); - - // Expect a 2px border because theme styles are enabled. - expect( await getComputedStyle( canvas(), 'p', 'border-width' ) ).toBe( - '2px' - ); - } ); -} ); diff --git a/test/e2e/specs/editor/plugins/iframed-enqueue-block-editor-settings.spec.js b/test/e2e/specs/editor/plugins/iframed-enqueue-block-editor-settings.spec.js new file mode 100644 index 00000000000000..b4f502b2c9d0ba --- /dev/null +++ b/test/e2e/specs/editor/plugins/iframed-enqueue-block-editor-settings.spec.js @@ -0,0 +1,99 @@ +/** + * WordPress dependencies + */ +const { test, expect } = require( '@wordpress/e2e-test-utils-playwright' ); + +test.describe( 'iframed block editor settings styles', () => { + test.beforeAll( async ( { requestUtils } ) => { + await requestUtils.activatePlugin( + 'gutenberg-test-iframed-enqueue-block-editor-settings' + ); + } ); + + test.beforeEach( async ( { admin } ) => { + await admin.createNewPost(); + } ); + + test.afterAll( async ( { requestUtils } ) => { + await requestUtils.deactivatePlugin( + 'gutenberg-test-iframed-enqueue-block-editor-settings' + ); + } ); + + test( 'should load styles added through block editor settings', async ( { + editor, + page, + } ) => { + const defaultBlock = editor.canvas.getByRole( 'button', { + name: 'Add default block', + } ); + + // Expect a red border (added in PHP). + await expect( defaultBlock ).toHaveCSS( + 'border-color', + 'rgb(255, 0, 0)' + ); + + await page.evaluate( () => { + const settings = window.wp.data + .select( 'core/editor' ) + .getEditorSettings(); + window.wp.data.dispatch( 'core/editor' ).updateEditorSettings( { + ...settings, + styles: [ + ...settings.styles, + { + css: 'p { border-width: 2px; }', + __unstableType: 'plugin', + }, + ], + } ); + } ); + + // Expect a 2px border (added in JS). + await expect( defaultBlock ).toHaveCSS( 'border-width', '2px' ); + } ); + + test( 'should load theme styles added through block editor settings', async ( { + editor, + page, + } ) => { + const defaultBlock = editor.canvas.getByRole( 'button', { + name: 'Add default block', + } ); + + await page.evaluate( () => { + // Make sure that theme styles are added even if the theme styles + // preference is off. + window.wp.data + .dispatch( 'core/edit-post' ) + .toggleFeature( 'themeStyles' ); + const settings = window.wp.data + .select( 'core/editor' ) + .getEditorSettings(); + window.wp.data.dispatch( 'core/editor' ).updateEditorSettings( { + ...settings, + styles: [ + ...settings.styles, + { + css: 'p { border-width: 2px; }', + __unstableType: 'theme', + }, + ], + } ); + } ); + + // Expect a 1px border because theme styles are disabled. + await expect( defaultBlock ).toHaveCSS( 'border-width', '1px' ); + + await page.evaluate( () => { + // Now enable theme styles. + window.wp.data + .dispatch( 'core/edit-post' ) + .toggleFeature( 'themeStyles' ); + } ); + + // Expect a 2px border because theme styles are enabled. + await expect( defaultBlock ).toHaveCSS( 'border-width', '2px' ); + } ); +} ); From b4c0938ef62115d08211076867586b22fa667ef0 Mon Sep 17 00:00:00 2001 From: George Mamadashvili Date: Wed, 4 Oct 2023 08:42:03 +0400 Subject: [PATCH 07/19] Site Editor: Avoid stale navigation block values when parsing entity record (#54996) --- .../use-navigation-menu-content.js | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-pattern/use-navigation-menu-content.js b/packages/edit-site/src/components/sidebar-navigation-screen-pattern/use-navigation-menu-content.js index 6c44ea5fbc9bbe..249124b1054cec 100644 --- a/packages/edit-site/src/components/sidebar-navigation-screen-pattern/use-navigation-menu-content.js +++ b/packages/edit-site/src/components/sidebar-navigation-screen-pattern/use-navigation-menu-content.js @@ -10,6 +10,16 @@ import TemplatePartNavigationMenus from './template-part-navigation-menus'; import useEditedEntityRecord from '../use-edited-entity-record'; import { TEMPLATE_PART_POST_TYPE } from '../../utils/constants'; +function getBlocksFromRecord( record ) { + if ( record?.blocks ) { + return record?.blocks; + } + + return record?.content && typeof record.content !== 'function' + ? parse( record.content ) + : []; +} + /** * Retrieves a list of specific blocks from a given tree of blocks. * @@ -60,11 +70,7 @@ export default function useNavigationMenuContent( postType, postId ) { return; } - const blocks = - record?.content && typeof record.content !== 'function' - ? parse( record.content ) - : []; - + const blocks = getBlocksFromRecord( record ); const navigationBlocks = getBlocksOfTypeFromBlocks( 'core/navigation', blocks From 8f80a1186a67651385c0980effe10a1783614bd3 Mon Sep 17 00:00:00 2001 From: George Mamadashvili Date: Wed, 4 Oct 2023 08:57:20 +0400 Subject: [PATCH 08/19] Migrate 'iframed masonry block' tests to Playwright (#55016) * Migrate 'iframed masonry block' tests to Playwright * Remove old test files * Use boundingBox --- .../plugins/iframed-masonry-block.php | 7 --- .../iframed-masonry-block.test.js.snap | 7 --- .../plugins/iframed-masonry-block.test.js | 49 ------------------- .../plugins/iframed-masonry-block.spec.js | 44 +++++++++++++++++ 4 files changed, 44 insertions(+), 63 deletions(-) delete mode 100644 packages/e2e-tests/specs/editor/plugins/__snapshots__/iframed-masonry-block.test.js.snap delete mode 100644 packages/e2e-tests/specs/editor/plugins/iframed-masonry-block.test.js create mode 100644 test/e2e/specs/editor/plugins/iframed-masonry-block.spec.js diff --git a/packages/e2e-tests/plugins/iframed-masonry-block.php b/packages/e2e-tests/plugins/iframed-masonry-block.php index ebfbdb6b1257ec..51109bbbfb8195 100644 --- a/packages/e2e-tests/plugins/iframed-masonry-block.php +++ b/packages/e2e-tests/plugins/iframed-masonry-block.php @@ -7,13 +7,6 @@ * @package gutenberg-test-iframed-masonry-block */ -add_action( - 'setup_theme', - static function () { - add_theme_support( 'block-templates' ); - } -); - add_action( 'init', static function () { diff --git a/packages/e2e-tests/specs/editor/plugins/__snapshots__/iframed-masonry-block.test.js.snap b/packages/e2e-tests/specs/editor/plugins/__snapshots__/iframed-masonry-block.test.js.snap deleted file mode 100644 index a37b33cdc3f410..00000000000000 --- a/packages/e2e-tests/specs/editor/plugins/__snapshots__/iframed-masonry-block.test.js.snap +++ /dev/null @@ -1,7 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`iframed masonry block should load script and dependencies in iframe 1`] = ` -" -
-" -`; diff --git a/packages/e2e-tests/specs/editor/plugins/iframed-masonry-block.test.js b/packages/e2e-tests/specs/editor/plugins/iframed-masonry-block.test.js deleted file mode 100644 index 503beeb92e1642..00000000000000 --- a/packages/e2e-tests/specs/editor/plugins/iframed-masonry-block.test.js +++ /dev/null @@ -1,49 +0,0 @@ -/** - * WordPress dependencies - */ -import { - activatePlugin, - createNewPost, - deactivatePlugin, - insertBlock, - getEditedPostContent, - canvas, - createNewTemplate, -} from '@wordpress/e2e-test-utils'; - -async function didMasonryLoadCorrectly( context ) { - return await context.evaluate( () => { - const container = document.querySelector( - '.wp-block-test-iframed-masonry-block' - ); - return ( - // Expect Masonry to set a non-zero height. - parseInt( container.style.height, 10 ) > 0 && - // Expect Masonry to absolute position items. - container.firstElementChild.style.position === 'absolute' - ); - } ); -} - -describe( 'iframed masonry block', () => { - beforeEach( async () => { - await activatePlugin( 'gutenberg-test-iframed-masonry-block' ); - await createNewPost( { postType: 'page' } ); - } ); - - afterEach( async () => { - await deactivatePlugin( 'gutenberg-test-iframed-masonry-block' ); - } ); - - it( 'should load script and dependencies in iframe', async () => { - await insertBlock( 'Iframed Masonry Block' ); - - expect( await getEditedPostContent() ).toMatchSnapshot(); - expect( await didMasonryLoadCorrectly( canvas() ) ).toBe( true ); - - await createNewTemplate( 'Iframed Test' ); - await canvas().waitForSelector( '.grid-item[style]' ); - - expect( await didMasonryLoadCorrectly( canvas() ) ).toBe( true ); - } ); -} ); diff --git a/test/e2e/specs/editor/plugins/iframed-masonry-block.spec.js b/test/e2e/specs/editor/plugins/iframed-masonry-block.spec.js new file mode 100644 index 00000000000000..edc6b0a68cd4ab --- /dev/null +++ b/test/e2e/specs/editor/plugins/iframed-masonry-block.spec.js @@ -0,0 +1,44 @@ +/** + * WordPress dependencies + */ +const { test, expect } = require( '@wordpress/e2e-test-utils-playwright' ); + +test.describe( 'iframed masonry block', () => { + test.beforeAll( async ( { requestUtils } ) => { + await requestUtils.activatePlugin( + 'gutenberg-test-iframed-masonry-block' + ); + } ); + + test.beforeEach( async ( { admin } ) => { + await admin.createNewPost(); + } ); + + test.afterAll( async ( { requestUtils } ) => { + await requestUtils.deactivatePlugin( + 'gutenberg-test-iframed-masonry-block' + ); + } ); + + test( 'should load script and dependencies in iframe', async ( { + editor, + } ) => { + await editor.insertBlock( { name: 'test/iframed-masonry-block' } ); + + const masonry = editor.canvas.getByRole( 'document', { + name: 'Block: Iframed Masonry Block', + } ); + await expect( masonry ).toBeVisible(); + + const masonryBox = await masonry.boundingBox(); + + // Expect Masonry to set a non-zero height. + expect( masonryBox.height ).toBeGreaterThan( 0 ); + + // Expect Masonry to absolute position items. + await expect( masonry.locator( '.grid-item' ).first() ).toHaveCSS( + 'position', + 'absolute' + ); + } ); +} ); From 795f79f624329bded095d2a0f920d36ca90292d0 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Wed, 4 Oct 2023 09:31:24 +0100 Subject: [PATCH 09/19] Platform Docs: Add a documentation page explaining how to use the block library (#54967) Co-authored-by: Aaron Robertshaw <60436221+aaronrobertshaw@users.noreply.github.com> --- .../docs/basic-concepts/block-library.md | 112 ++++++++++++++++++ .../basic-concepts/internationalization.md | 4 +- .../docs/basic-concepts/rendering.md | 2 +- .../docs/basic-concepts/rich-text.md | 2 +- 4 files changed, 117 insertions(+), 3 deletions(-) create mode 100644 platform-docs/docs/basic-concepts/block-library.md diff --git a/platform-docs/docs/basic-concepts/block-library.md b/platform-docs/docs/basic-concepts/block-library.md new file mode 100644 index 00000000000000..0e7de53ce36dfc --- /dev/null +++ b/platform-docs/docs/basic-concepts/block-library.md @@ -0,0 +1,112 @@ +--- +sidebar_position: 6 +--- + +# Block Library + +The block editor relies on a registry of block types to render and edit blocks. The `@wordpress/block-library` package provides a set of core blocks that you can register in your application. + +## Registring all block types + +Registering blocks requires both loading the JavaScript code that makes the block type available for use and including the corresponding stylesheets. + +To register all blocks from the block library, you can use the `registerCoreBlocks` function: + +```js +import { registerCoreBlocks } from '@wordpress/block-library'; + +registerCoreBlocks(); +``` + +And make sure to also load the stylesheets required for these blocks. + +```js +import "@wordpress/block-library/build-style/common.css"; +import "@wordpress/block-library/build-style/style.css"; +import "@wordpress/block-library/build-style/editor.css"; +``` + +## Registering individual blocks + +That said, by default the block library includes a very big number of blocks and some of them may contain some WordPress-specific logic. For this reason, if you're building a third-party block editor, it's recommended to only register the blocks that you need. + +### The paragraph block type + +The main block type that almost all block editors need is the paragraph block. You can register it with the following code: + +```js +import '@wordpress/block-library/build-module/paragraph/init'; +import '@wordpress/block-library/build-style/paragraph/style.css'; +import '@wordpress/block-library/build-style/paragraph/editor.css'; +``` + +Also, the paragraph block is often used as the "default block" in the block editor. The default block has multiple purposes: + + - It's the block that is selected when the user starts typing or hits Enter. + - It's the block that is inserted when the user clicks on the "Add block" button. + - It's the block where the user can hit `/` to search for alternative block types. + +You can mark the paragraph block as the default block with the following code: + +```js +import { setDefaultBlockName } from '@wordpress/blocks'; + +setDefaultBlockName( 'core/paragraph' ); +``` + +### The HTML block type + +Another important block type that most block editors would want to use is the HTML block. This block allows users to insert arbitrary HTML code in the block editor and is often used to insert embeds or external content. + +It is also used by the block editor to render blocks that are not registered in the block editor or as a fallback block type for random HTML content that can't be properly parsed into blocks. + +You can register the HTML block with the following code: + +```js +import '@wordpress/block-library/build-module/html/init'; +import '@wordpress/block-library/build-style/html/editor.css'; +``` + +And mark it as the fallback block type with the following code: + +```js +import { + setFreeformContentHandlerName, + setUnregisteredTypeHandlerName +} from '@wordpress/blocks'; + +setFreeformContentHandlerName( 'core/html' ); +setUnregisteredTypeHandlerName( 'core/html' ); +``` + +### Extra blocks + +In addition to these two default blocks, here's a non-exhaustive list of blocks that can be registered and used by any block editor: + + - **Heading block**: `heading` + - **List block**: `list` and `list-item` + - **Quote block**: `quote` + - **Image block**: `image` + - **Gallery block**: `gallery` + - **Video block**: `video` + - **Audio block**: `audio` + - **Cover block**: `cover` + - **File block**: `file` + - **Code block**: `code` + - **Preformatted block**: `preformatted` + - **Pullquote block**: `pullquote` + - **Table block**: `table` + - **Verse block**: `verse` + - **Separator block**: `separator` + - **Spacer block**: `spacer` + - **Columns block**: `columns` and `column` + - **Group block**: `group` + - **Button block**: `buttons` and `button` + - **Social links block**: `social-links` and `social-link` + +For each block, you'll need to load the JavaScript code and stylesheets. Some blocks have two stylesheets (`style.css` and `editor.css`). For example, to register the heading block, you can use the following code: + +```js +import '@wordpress/block-library/build-module/heading/init'; +import '@wordpress/block-library/build-style/heading/editor.css'; +``` diff --git a/platform-docs/docs/basic-concepts/internationalization.md b/platform-docs/docs/basic-concepts/internationalization.md index 3b808bd71e61b1..a6e2ba90a38d96 100644 --- a/platform-docs/docs/basic-concepts/internationalization.md +++ b/platform-docs/docs/basic-concepts/internationalization.md @@ -1,5 +1,7 @@ --- -sidebar_position: 6 +sidebar_position: 8 --- # Internationalization + +# RTL Support diff --git a/platform-docs/docs/basic-concepts/rendering.md b/platform-docs/docs/basic-concepts/rendering.md index f5458df2e81e77..d18eeb3ae1dbbc 100644 --- a/platform-docs/docs/basic-concepts/rendering.md +++ b/platform-docs/docs/basic-concepts/rendering.md @@ -1,5 +1,5 @@ --- -sidebar_position: 7 +sidebar_position: 9 --- # Rendering blocks diff --git a/platform-docs/docs/basic-concepts/rich-text.md b/platform-docs/docs/basic-concepts/rich-text.md index e3517bc93203e8..d46aa49dcb42f5 100644 --- a/platform-docs/docs/basic-concepts/rich-text.md +++ b/platform-docs/docs/basic-concepts/rich-text.md @@ -1,5 +1,5 @@ --- -sidebar_position: 5 +sidebar_position: 7 --- # RichText and Format Library From dbe1948c6b8063a0a8285a59c50bd34e84c537f5 Mon Sep 17 00:00:00 2001 From: George Mamadashvili Date: Wed, 4 Oct 2023 13:36:35 +0400 Subject: [PATCH 10/19] Migrate 'iframed inline styles' tests to Playwright (#55009) * Migrate 'iframed inline styles' tests to Playwright * Remove old test file * Fix incorrect test name * Remove snapshot --- .../plugins/iframed-inline-styles.php | 7 --- .../iframed-inline-styles.test.js.snap | 7 --- .../plugins/iframed-inline-styles.test.js | 56 ------------------- .../iframed-equeue-block-assets.spec.js | 2 +- .../plugins/iframed-inline-styles.spec.js | 46 +++++++++++++++ 5 files changed, 47 insertions(+), 71 deletions(-) delete mode 100644 packages/e2e-tests/specs/editor/plugins/__snapshots__/iframed-inline-styles.test.js.snap delete mode 100644 packages/e2e-tests/specs/editor/plugins/iframed-inline-styles.test.js create mode 100644 test/e2e/specs/editor/plugins/iframed-inline-styles.spec.js diff --git a/packages/e2e-tests/plugins/iframed-inline-styles.php b/packages/e2e-tests/plugins/iframed-inline-styles.php index 0f8c69e1073337..ef3484e1a6498f 100644 --- a/packages/e2e-tests/plugins/iframed-inline-styles.php +++ b/packages/e2e-tests/plugins/iframed-inline-styles.php @@ -7,13 +7,6 @@ * @package gutenberg-test-iframed-inline-styles */ -add_action( - 'setup_theme', - static function () { - add_theme_support( 'block-templates' ); - } -); - add_action( 'init', static function () { diff --git a/packages/e2e-tests/specs/editor/plugins/__snapshots__/iframed-inline-styles.test.js.snap b/packages/e2e-tests/specs/editor/plugins/__snapshots__/iframed-inline-styles.test.js.snap deleted file mode 100644 index 49823edc5b1ea5..00000000000000 --- a/packages/e2e-tests/specs/editor/plugins/__snapshots__/iframed-inline-styles.test.js.snap +++ /dev/null @@ -1,7 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`iframed inline styles should load inline styles in iframe 1`] = ` -" -
Save
-" -`; diff --git a/packages/e2e-tests/specs/editor/plugins/iframed-inline-styles.test.js b/packages/e2e-tests/specs/editor/plugins/iframed-inline-styles.test.js deleted file mode 100644 index eafc0b1f48b614..00000000000000 --- a/packages/e2e-tests/specs/editor/plugins/iframed-inline-styles.test.js +++ /dev/null @@ -1,56 +0,0 @@ -/** - * WordPress dependencies - */ -import { - activatePlugin, - createNewPost, - deactivatePlugin, - insertBlock, - getEditedPostContent, - canvas, - createNewTemplate, -} from '@wordpress/e2e-test-utils'; - -async function getComputedStyle( context, property ) { - await context.waitForSelector( '.wp-block-test-iframed-inline-styles' ); - return await context.evaluate( ( prop ) => { - const container = document.querySelector( - '.wp-block-test-iframed-inline-styles' - ); - return window.getComputedStyle( container )[ prop ]; - }, property ); -} - -describe( 'iframed inline styles', () => { - beforeEach( async () => { - await activatePlugin( 'gutenberg-test-iframed-inline-styles' ); - await createNewPost( { postType: 'page' } ); - } ); - - afterEach( async () => { - await deactivatePlugin( 'gutenberg-test-iframed-inline-styles' ); - } ); - - it( 'should load inline styles in iframe', async () => { - await insertBlock( 'Iframed Inline Styles' ); - - expect( await getEditedPostContent() ).toMatchSnapshot(); - expect( await getComputedStyle( canvas(), 'padding' ) ).toBe( '20px' ); - expect( await getComputedStyle( canvas(), 'border-width' ) ).toBe( - '2px' - ); - - await createNewTemplate( 'Iframed Test' ); - - // Inline styles of properly enqueued stylesheet should load. - expect( await getComputedStyle( canvas(), 'padding' ) ).toBe( '20px' ); - - // Inline styles of stylesheet loaded with the compatibility layer - // should load. - expect( await getComputedStyle( canvas(), 'border-width' ) ).toBe( - '2px' - ); - - expect( console ).toHaveWarned(); - } ); -} ); diff --git a/test/e2e/specs/editor/plugins/iframed-equeue-block-assets.spec.js b/test/e2e/specs/editor/plugins/iframed-equeue-block-assets.spec.js index 391e1fdc17ec72..a523ba1f8e9e3d 100644 --- a/test/e2e/specs/editor/plugins/iframed-equeue-block-assets.spec.js +++ b/test/e2e/specs/editor/plugins/iframed-equeue-block-assets.spec.js @@ -3,7 +3,7 @@ */ const { test, expect } = require( '@wordpress/e2e-test-utils-playwright' ); -test.describe( 'iframed inline styles', () => { +test.describe( 'iframed enqueue block assets', () => { test.beforeAll( async ( { requestUtils } ) => { await Promise.all( [ requestUtils.activateTheme( 'emptytheme' ), diff --git a/test/e2e/specs/editor/plugins/iframed-inline-styles.spec.js b/test/e2e/specs/editor/plugins/iframed-inline-styles.spec.js new file mode 100644 index 00000000000000..8fa4cbffa9df8c --- /dev/null +++ b/test/e2e/specs/editor/plugins/iframed-inline-styles.spec.js @@ -0,0 +1,46 @@ +/** + * WordPress dependencies + */ +const { test, expect } = require( '@wordpress/e2e-test-utils-playwright' ); + +test.describe( 'iframed inline styles', () => { + test.beforeAll( async ( { requestUtils } ) => { + await requestUtils.activatePlugin( + 'gutenberg-test-iframed-inline-styles' + ); + } ); + + test.afterAll( async ( { requestUtils } ) => { + await requestUtils.deactivatePlugin( + 'gutenberg-test-iframed-inline-styles' + ); + } ); + + test( 'should load inline styles in iframe', async ( { + admin, + editor, + page, + } ) => { + let hasWarning; + page.on( 'console', ( msg ) => { + if ( msg.type() === 'warning' ) { + hasWarning = true; + } + } ); + + await admin.createNewPost( { postType: 'page' } ); + await editor.insertBlock( { name: 'test/iframed-inline-styles' } ); + + const block = editor.canvas.getByRole( 'document', { + name: 'Block: Iframed Inline Styles', + } ); + await expect( block ).toBeVisible(); + + // Inline styles of properly enqueued stylesheet should load. + await expect( block ).toHaveCSS( 'padding', '20px' ); + + // Inline styles of stylesheet loaded with the compatibility layer should load. + await expect( block ).toHaveCSS( 'border-width', '2px' ); + expect( hasWarning ).toBe( true ); + } ); +} ); From 8a5dd61f89576e22a1dec26b28744aa0bdad6eee Mon Sep 17 00:00:00 2001 From: George Mamadashvili Date: Wed, 4 Oct 2023 13:41:48 +0400 Subject: [PATCH 11/19] Migrate 'iframed multiple block stylesheets' tests to Playwright (#55003) * Migrate 'iframed multiple block stylesheets' tests to Playwright * Remove old test file --- .../plugins/iframed-multiple-stylesheets.php | 7 --- ...iframed-multiple-block-stylesheets.test.js | 58 ------------------- ...iframed-multiple-block-stylesheets.spec.js | 42 ++++++++++++++ 3 files changed, 42 insertions(+), 65 deletions(-) delete mode 100644 packages/e2e-tests/specs/editor/plugins/iframed-multiple-block-stylesheets.test.js create mode 100644 test/e2e/specs/editor/plugins/iframed-multiple-block-stylesheets.spec.js diff --git a/packages/e2e-tests/plugins/iframed-multiple-stylesheets.php b/packages/e2e-tests/plugins/iframed-multiple-stylesheets.php index 6a4505ed065228..06e0125e2ac0c9 100644 --- a/packages/e2e-tests/plugins/iframed-multiple-stylesheets.php +++ b/packages/e2e-tests/plugins/iframed-multiple-stylesheets.php @@ -7,13 +7,6 @@ * @package gutenberg-test-iframed-multiple-stylesheets */ -add_action( - 'setup_theme', - static function () { - add_theme_support( 'block-templates' ); - } -); - add_action( 'init', static function () { diff --git a/packages/e2e-tests/specs/editor/plugins/iframed-multiple-block-stylesheets.test.js b/packages/e2e-tests/specs/editor/plugins/iframed-multiple-block-stylesheets.test.js deleted file mode 100644 index 23058b48b8da43..00000000000000 --- a/packages/e2e-tests/specs/editor/plugins/iframed-multiple-block-stylesheets.test.js +++ /dev/null @@ -1,58 +0,0 @@ -/** - * WordPress dependencies - */ -import { - activatePlugin, - createNewPost, - deactivatePlugin, - insertBlock, - canvas, - createNewTemplate, -} from '@wordpress/e2e-test-utils'; - -async function getComputedStyle( context, property ) { - await context.waitForSelector( - '.wp-block-test-iframed-multiple-stylesheets' - ); - return await context.evaluate( ( prop ) => { - const container = document.querySelector( - '.wp-block-test-iframed-multiple-stylesheets' - ); - return window.getComputedStyle( container )[ prop ]; - }, property ); -} - -describe( 'iframed multiple block stylesheets', () => { - beforeEach( async () => { - await activatePlugin( 'gutenberg-test-iframed-multiple-stylesheets' ); - await createNewPost( { postType: 'page' } ); - } ); - - afterEach( async () => { - await deactivatePlugin( 'gutenberg-test-iframed-multiple-stylesheets' ); - } ); - - it( 'should load multiple block stylesheets in iframe', async () => { - await insertBlock( 'Iframed Multiple Stylesheets' ); - - await canvas().waitForSelector( - '.wp-block-test-iframed-multiple-stylesheets' - ); - await createNewTemplate( 'Iframed Test' ); - - // Style loaded from the main stylesheet. - expect( await getComputedStyle( canvas(), 'border-style' ) ).toBe( - 'dashed' - ); - - // Style loaded from the additional stylesheet. - expect( await getComputedStyle( canvas(), 'border-color' ) ).toBe( - 'rgb(255, 0, 0)' - ); - - // Style loaded from the a stylesheet using path instead of handle. - expect( await getComputedStyle( canvas(), 'background-color' ) ).toBe( - 'rgb(0, 0, 0)' - ); - } ); -} ); diff --git a/test/e2e/specs/editor/plugins/iframed-multiple-block-stylesheets.spec.js b/test/e2e/specs/editor/plugins/iframed-multiple-block-stylesheets.spec.js new file mode 100644 index 00000000000000..2e6f5b6b0cb6a0 --- /dev/null +++ b/test/e2e/specs/editor/plugins/iframed-multiple-block-stylesheets.spec.js @@ -0,0 +1,42 @@ +/** + * WordPress dependencies + */ +const { test, expect } = require( '@wordpress/e2e-test-utils-playwright' ); + +test.describe( 'iframed multiple block stylesheets', () => { + test.beforeAll( async ( { requestUtils } ) => { + await requestUtils.activatePlugin( + 'gutenberg-test-iframed-multiple-stylesheets' + ); + } ); + + test.beforeEach( async ( { admin } ) => { + await admin.createNewPost( { postType: 'page' } ); + } ); + + test.afterAll( async ( { requestUtils } ) => { + await requestUtils.deactivatePlugin( + 'gutenberg-test-iframed-multiple-stylesheets' + ); + } ); + + test( 'should load multiple block stylesheets in iframe', async ( { + editor, + } ) => { + await editor.insertBlock( { + name: 'test/iframed-multiple-stylesheets', + } ); + const block = editor.canvas.getByRole( 'document', { + name: 'Block: Iframed Multiple Stylesheets', + } ); + + await expect( block ).toBeVisible(); + + // Style loaded from the main stylesheet. + await expect( block ).toHaveCSS( 'border-style', 'dashed' ); + // Style loaded from the additional stylesheet. + await expect( block ).toHaveCSS( 'border-color', 'rgb(255, 0, 0)' ); + // Style loaded from the a stylesheet using path instead of handle. + await expect( block ).toHaveCSS( 'border-color', 'rgb(255, 0, 0)' ); + } ); +} ); From f943b698c7f3534fd2f0f26f99194774bff6504f Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Wed, 4 Oct 2023 10:44:37 +0100 Subject: [PATCH 12/19] Fix Deleted Navigation Menu warning string (#55033) --- .../navigation/edit/deleted-navigation-warning.js | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/packages/block-library/src/navigation/edit/deleted-navigation-warning.js b/packages/block-library/src/navigation/edit/deleted-navigation-warning.js index b9dd11763f77c6..6386cee71431e0 100644 --- a/packages/block-library/src/navigation/edit/deleted-navigation-warning.js +++ b/packages/block-library/src/navigation/edit/deleted-navigation-warning.js @@ -4,14 +4,19 @@ import { Warning } from '@wordpress/block-editor'; import { Button } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; +import { createInterpolateElement } from '@wordpress/element'; function DeletedNavigationWarning( { onCreateNew } ) { return ( - { __( 'Navigation menu has been deleted or is unavailable.' ) } - + { createInterpolateElement( + __( + 'Navigation menu has been deleted or is unavailable. ' + ), + { + button: + + + { createInterpolateElement( + sprintf( + // translators: %1$s: Current page number, %2$s: Total number of pages. + _x( ' of %2$s', 'paging' ), + currentPage, + numPages + ), + { + CurrenPageControl: ( + { + if ( value > numPages ) return; + dataView.setPageIndex( value - 1 ); + } } + step="1" + value={ currentPage } + isDragEnabled={ false } + spinControls="none" + /> + ), + } + ) } + + + + + ) } + + + ); +} diff --git a/packages/edit-site/src/components/dataviews/style.scss b/packages/edit-site/src/components/dataviews/style.scss new file mode 100644 index 00000000000000..47e80782255a4a --- /dev/null +++ b/packages/edit-site/src/components/dataviews/style.scss @@ -0,0 +1,36 @@ +.dataviews-wrapper { + width: 100%; + padding: $grid-unit-40; +} + +.dataviews-list-view { + width: 100%; + text-indent: 0; + border-color: inherit; + border-collapse: collapse; + position: relative; + a { + text-decoration: none; + } + th { + text-align: left; + font-weight: normal; + padding: 0 $grid-unit-20 $grid-unit-20; + color: $gray-700; + } + td, + th { + padding: $grid-unit-15; + &:last-child { + text-align: right; + } + } + tr { + border-bottom: 1px solid $gray-100; + } +} + +.dataviews__per-page-control-prefix { + color: $gray-700; + text-wrap: nowrap; +} diff --git a/packages/edit-site/src/components/dataviews/text-filter.js b/packages/edit-site/src/components/dataviews/text-filter.js new file mode 100644 index 00000000000000..76a06c14486170 --- /dev/null +++ b/packages/edit-site/src/components/dataviews/text-filter.js @@ -0,0 +1,37 @@ +/** + * External dependencies + */ +import classnames from 'classnames'; + +/** + * WordPress dependencies + */ +import { __ } from '@wordpress/i18n'; +import { useEffect } from '@wordpress/element'; +import { SearchControl } from '@wordpress/components'; + +/** + * Internal dependencies + */ +import useDebouncedInput from '../../utils/use-debounced-input'; + +export default function TextFilter( { + className, + searchLabel = __( 'Filter list' ), + onChange, +} ) { + const [ search, setSearch, debouncedSearch ] = useDebouncedInput(); + useEffect( () => { + onChange( debouncedSearch ); + }, [ debouncedSearch, onChange ] ); + return ( + + ); +} diff --git a/packages/edit-site/src/components/dataviews/view-actions.js b/packages/edit-site/src/components/dataviews/view-actions.js new file mode 100644 index 00000000000000..1ede6ebcd8b75a --- /dev/null +++ b/packages/edit-site/src/components/dataviews/view-actions.js @@ -0,0 +1,246 @@ +/** + * WordPress dependencies + */ +import { + Button, + Icon, + SelectControl, + privateApis as componentsPrivateApis, + __experimentalInputControlPrefixWrapper as InputControlPrefixWrapper, +} from '@wordpress/components'; +import { + chevronRightSmall, + check, + blockTable, + chevronDown, + arrowUp, + arrowDown, +} from '@wordpress/icons'; +import { __ } from '@wordpress/i18n'; + +/** + * Internal dependencies + */ +import { unlock } from '../../lock-unlock'; + +const { + DropdownMenuV2, + DropdownMenuGroupV2, + DropdownMenuItemV2, + DropdownSubMenuV2, + DropdownSubMenuTriggerV2, +} = unlock( componentsPrivateApis ); + +export const PAGE_SIZE_VALUES = [ 5, 20, 50 ]; + +export function PageSizeControl( { dataView } ) { + const label = __( 'Rows per page:' ); + return ( + + { label } + + } + value={ dataView.getState().pagination.pageSize } + options={ PAGE_SIZE_VALUES.map( ( pageSize ) => ( { + value: pageSize, + label: pageSize, + } ) ) } + onChange={ ( value ) => dataView.setPageSize( +value ) } + /> + ); +} + +function PageSizeMenu( { dataView } ) { + const currenPageSize = dataView.getState().pagination.pageSize; + return ( + + { currenPageSize } + + + } + > + { /* TODO: probably label per view type. */ } + { __( 'Rows per page' ) } + + } + > + { PAGE_SIZE_VALUES.map( ( size ) => { + return ( + + } + onSelect={ ( event ) => { + // We need to handle this on DropDown component probably.. + event.preventDefault(); + dataView.setPageSize( size ); + } } + // TODO: check about role and a11y. + role="menuitemcheckbox" + > + { size } + + ); + } ) } + + ); +} + +function FieldsVisibilityMenu( { dataView } ) { + const hideableFields = dataView + .getAllColumns() + .filter( ( columnn ) => columnn.getCanHide() ); + if ( ! hideableFields?.length ) { + return null; + } + return ( + } + > + { __( 'Fields' ) } + + } + > + { hideableFields?.map( ( field ) => { + return ( + + } + onSelect={ ( event ) => { + event.preventDefault(); + field.getToggleVisibilityHandler()( event ); + } } + role="menuitemcheckbox" + > + { field.columnDef.header } + + ); + } ) } + + ); +} + +// This object is used to construct the sorting options per sortable field. +const sortingItemsInfo = { + asc: { icon: arrowUp, label: __( 'Sort ascending' ) }, + desc: { icon: arrowDown, label: __( 'Sort descending' ) }, +}; +function SortMenu( { dataView } ) { + const sortableFields = dataView + .getAllColumns() + .filter( ( columnn ) => columnn.getCanSort() ); + if ( ! sortableFields?.length ) { + return null; + } + const currentSortedField = sortableFields.find( ( field ) => + field.getIsSorted() + ); + return ( + + { currentSortedField?.columnDef.header } + + + } + > + { __( 'Sort by' ) } + + } + > + { sortableFields?.map( ( field ) => { + const sortedDirection = field.getIsSorted(); + return ( + } + > + { field.columnDef.header } + + } + side="left" + > + { Object.entries( sortingItemsInfo ).map( + ( [ direction, info ] ) => { + return ( + } + suffix={ + sortedDirection === direction && ( + + ) + } + onSelect={ ( event ) => { + event.preventDefault(); + if ( + sortedDirection === direction + ) { + dataView.resetSorting(); + } else { + dataView.setSorting( [ + { + id: field.id, + desc: + direction === + 'desc', + }, + ] ); + } + } } + > + { info.label } + + ); + } + ) } + + ); + } ) } + + ); +} + +export default function ViewActions( { dataView, className } ) { + return ( + + { __( 'View' ) } + + + } + > + + + + + + + ); +} diff --git a/packages/edit-site/src/components/page-main/index.js b/packages/edit-site/src/components/page-main/index.js index af017a8db9700a..10b5b99dc2fbf5 100644 --- a/packages/edit-site/src/components/page-main/index.js +++ b/packages/edit-site/src/components/page-main/index.js @@ -9,6 +9,7 @@ import { privateApis as routerPrivateApis } from '@wordpress/router'; import PagePatterns from '../page-patterns'; import PageTemplateParts from '../page-template-parts'; import PageTemplates from '../page-templates'; +import PagePages from '../page-pages'; import { unlock } from '../../lock-unlock'; const { useLocation } = unlock( routerPrivateApis ); @@ -24,6 +25,8 @@ export default function PageMain() { return ; } else if ( path === '/patterns' ) { return ; + } else if ( window?.__experimentalAdminViews && path === '/pages' ) { + return ; } return null; diff --git a/packages/edit-site/src/components/page-pages/index.js b/packages/edit-site/src/components/page-pages/index.js new file mode 100644 index 00000000000000..e7b8f913efe7ca --- /dev/null +++ b/packages/edit-site/src/components/page-pages/index.js @@ -0,0 +1,190 @@ +/** + * WordPress dependencies + */ +import apiFetch from '@wordpress/api-fetch'; +import { addQueryArgs } from '@wordpress/url'; +import { + VisuallyHidden, + __experimentalHeading as Heading, + __experimentalVStack as VStack, +} from '@wordpress/components'; +import { __ } from '@wordpress/i18n'; +import { useEntityRecords } from '@wordpress/core-data'; +import { decodeEntities } from '@wordpress/html-entities'; +import { useState, useEffect, useMemo } from '@wordpress/element'; + +/** + * Internal dependencies + */ +import Page from '../page'; +import Link from '../routes/link'; +import PageActions from '../page-actions'; +import { DataViews, PAGE_SIZE_VALUES } from '../dataviews'; + +const EMPTY_ARRAY = []; + +export default function PagePages() { + const [ reset, setResetQuery ] = useState( ( v ) => ! v ); + const [ globalFilter, setGlobalFilter ] = useState( '' ); + const [ paginationInfo, setPaginationInfo ] = useState(); + const [ { pageIndex, pageSize }, setPagination ] = useState( { + pageIndex: 0, + pageSize: PAGE_SIZE_VALUES[ 0 ], + } ); + // Request post statuses to get the proper labels. + const [ postStatuses, setPostStatuses ] = useState( EMPTY_ARRAY ); + useEffect( () => { + apiFetch( { + path: '/wp/v2/statuses', + } ).then( setPostStatuses ); + }, [] ); + + // TODO: probably memo other objects passed as state(ex:https://tanstack.com/table/v8/docs/examples/react/pagination-controlled). + const pagination = useMemo( + () => ( { pageIndex, pageSize } ), + [ pageIndex, pageSize ] + ); + const [ sorting, setSorting ] = useState( [ + { order: 'desc', orderby: 'date' }, + ] ); + const queryArgs = useMemo( + () => ( { + per_page: pageSize, + page: pageIndex + 1, // tanstack starts from zero. + _embed: 'author', + order: sorting[ 0 ]?.desc ? 'desc' : 'asc', + orderby: sorting[ 0 ]?.id, + search: globalFilter, + status: [ 'publish', 'draft' ], + } ), + [ + globalFilter, + sorting[ 0 ]?.id, + sorting[ 0 ]?.desc, + pageSize, + pageIndex, + reset, + ] + ); + const { records, isResolving: isLoading } = useEntityRecords( + 'postType', + 'page', + queryArgs + ); + useEffect( () => { + // Make extra request to handle controlled pagination. + apiFetch( { + path: addQueryArgs( '/wp/v2/pages', { + ...queryArgs, + _fields: 'id', + } ), + method: 'HEAD', + parse: false, + } ).then( ( res ) => { + const totalPages = parseInt( res.headers.get( 'X-WP-TotalPages' ) ); + const totalItems = parseInt( res.headers.get( 'X-WP-Total' ) ); + setPaginationInfo( { + totalPages, + totalItems, + } ); + } ); + // Status should not make extra request if already did.. + }, [ globalFilter, pageSize, reset ] ); + + const fields = useMemo( + () => [ + { + header: __( 'Title' ), + id: 'title', + accessorFn: ( page ) => page.title?.rendered || page.slug, + cell: ( props ) => { + const page = props.row.original; + return ( + + + + { decodeEntities( props.getValue() ) } + + + + ); + }, + maxWidth: 400, + sortingFn: 'alphanumeric', + enableHiding: false, + }, + { + header: __( 'Author' ), + id: 'author', + accessorFn: ( page ) => page._embedded?.author[ 0 ]?.name, + cell: ( props ) => { + const author = props.row.original._embedded?.author[ 0 ]; + return ( + + { author.name } + + ); + }, + }, + { + header: 'Status', + id: 'status', + cell: ( props ) => + postStatuses[ props.row.original.status ]?.name, + }, + { + header: { __( 'Actions' ) }, + id: 'actions', + cell: ( props ) => { + const page = props.row.original; + return ( + setResetQuery() } + /> + ); + }, + enableHiding: false, + }, + ], + [ postStatuses ] + ); + + // TODO: we need to handle properly `data={ data || EMPTY_ARRAY }` for when `isLoading`. + return ( + + { + setGlobalFilter( value ); + setPagination( { pageIndex: 0, pageSize } ); + }, + // TODO: check these callbacks and maybe reset the query when needed... + onPaginationChange: setPagination, + meta: { resetQuery: setResetQuery }, + } } + /> + + ); +} diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-pages/index.js b/packages/edit-site/src/components/sidebar-navigation-screen-pages/index.js index 4d143235e9597e..e9a6163a0047e9 100644 --- a/packages/edit-site/src/components/sidebar-navigation-screen-pages/index.js +++ b/packages/edit-site/src/components/sidebar-navigation-screen-pages/index.js @@ -136,6 +136,16 @@ export default function SidebarNavigationScreenPages() { }; }; + const pagesLink = useLink( { path: '/pages' } ); + const manageAllPagesProps = window?.__experimentalAdminViews + ? { ...pagesLink } + : { + href: 'edit.php?post_type=page', + onClick: () => { + document.location = 'edit.php?post_type=page'; + }, + }; + return ( <> { showAddPage && ( @@ -220,10 +230,7 @@ export default function SidebarNavigationScreenPages() { ) ) } { - document.location = 'edit.php?post_type=page'; - } } + { ...manageAllPagesProps } > { __( 'Manage all pages' ) } diff --git a/packages/edit-site/src/components/sidebar/index.js b/packages/edit-site/src/components/sidebar/index.js index 9e035759ea9ad6..a233cf1eca1988 100644 --- a/packages/edit-site/src/components/sidebar/index.js +++ b/packages/edit-site/src/components/sidebar/index.js @@ -2,6 +2,7 @@ * WordPress dependencies */ import { memo, useRef } from '@wordpress/element'; +import { __ } from '@wordpress/i18n'; import { __experimentalNavigatorProvider as NavigatorProvider, __experimentalNavigatorScreen as NavigatorScreen, @@ -27,6 +28,7 @@ import SaveHub from '../save-hub'; import { unlock } from '../../lock-unlock'; import SidebarNavigationScreenPages from '../sidebar-navigation-screen-pages'; import SidebarNavigationScreenPage from '../sidebar-navigation-screen-page'; +import SidebarNavigationScreen from '../sidebar-navigation-screen'; const { useLocation } = unlock( routerPrivateApis ); @@ -53,6 +55,15 @@ function SidebarScreens() { + { window?.__experimentalAdminViews && ( + + + + ) } diff --git a/packages/edit-site/src/style.scss b/packages/edit-site/src/style.scss index 111696241d0d69..e95cd3571c419f 100644 --- a/packages/edit-site/src/style.scss +++ b/packages/edit-site/src/style.scss @@ -4,6 +4,7 @@ @import "./components/block-editor/style.scss"; @import "./components/canvas-loader/style.scss"; @import "./components/code-editor/style.scss"; +@import "./components/dataviews/style.scss"; @import "./components/global-styles/style.scss"; @import "./components/global-styles/screen-revisions/style.scss"; @import "./components/header-edit-mode/style.scss"; diff --git a/packages/edit-site/src/utils/get-is-list-page.js b/packages/edit-site/src/utils/get-is-list-page.js index 600e686618bf94..2ee661253cf063 100644 --- a/packages/edit-site/src/utils/get-is-list-page.js +++ b/packages/edit-site/src/utils/get-is-list-page.js @@ -14,8 +14,9 @@ export default function getIsListPage( isMobileViewport ) { return ( - path === '/wp_template/all' || - path === '/wp_template_part/all' || + [ '/wp_template/all', '/wp_template_part/all', '/pages' ].includes( + path + ) || ( path === '/patterns' && // Don't treat "/patterns" without categoryType and categoryId as a // list page in mobile because the sidebar covers the whole page. From 0f16fec31bf2bd12b50a2ba1ec256d57787f4dea Mon Sep 17 00:00:00 2001 From: Nik Tsekouras Date: Wed, 4 Oct 2023 14:31:57 +0300 Subject: [PATCH 15/19] [Inserter]: Fix reset of registered media categories (#55012) * [Inserter]: Fix reset of registered media categories * convert `useInserterMediaCategories` to selector and make private --- .../components/inserter/media-tab/hooks.js | 54 +++----------- packages/block-editor/src/store/actions.js | 18 ++--- .../src/store/private-selectors.js | 72 +++++++++++++++++++ packages/block-editor/src/store/reducer.js | 17 +++++ .../block-editor/src/store/test/actions.js | 26 +++---- 5 files changed, 116 insertions(+), 71 deletions(-) diff --git a/packages/block-editor/src/components/inserter/media-tab/hooks.js b/packages/block-editor/src/components/inserter/media-tab/hooks.js index 3d248c237be7c1..3a4c8fa9da7df5 100644 --- a/packages/block-editor/src/components/inserter/media-tab/hooks.js +++ b/packages/block-editor/src/components/inserter/media-tab/hooks.js @@ -1,16 +1,17 @@ /** * WordPress dependencies */ -import { useEffect, useState, useRef, useMemo } from '@wordpress/element'; +import { useEffect, useState, useRef } from '@wordpress/element'; import { useSelect } from '@wordpress/data'; /** * Internal dependencies */ import { store as blockEditorStore } from '../../../store'; +import { unlock } from '../../../lock-unlock'; -/** @typedef {import('./api').InserterMediaRequest} InserterMediaRequest */ -/** @typedef {import('./api').InserterMediaItem} InserterMediaItem */ +/** @typedef {import('../../../store/actions').InserterMediaRequest} InserterMediaRequest */ +/** @typedef {import('../../../store/actions').InserterMediaItem} InserterMediaItem */ /** * Fetches media items based on the provided category. @@ -50,48 +51,14 @@ export function useMediaResults( category, query = {} ) { return { mediaList, isLoading }; } -function useInserterMediaCategories() { - const { - inserterMediaCategories, - allowedMimeTypes, - enableOpenverseMediaCategory, - } = useSelect( ( select ) => { - const settings = select( blockEditorStore ).getSettings(); - return { - inserterMediaCategories: settings.inserterMediaCategories, - allowedMimeTypes: settings.allowedMimeTypes, - enableOpenverseMediaCategory: settings.enableOpenverseMediaCategory, - }; - }, [] ); - // The allowed `mime_types` can be altered by `upload_mimes` filter and restrict - // some of them. In this case we shouldn't add the category to the available media - // categories list in the inserter. - const allowedCategories = useMemo( () => { - if ( ! inserterMediaCategories || ! allowedMimeTypes ) { - return; - } - return inserterMediaCategories.filter( ( category ) => { - // Check if Openverse category is enabled. - if ( - ! enableOpenverseMediaCategory && - category.name === 'openverse' - ) { - return false; - } - return Object.values( allowedMimeTypes ).some( ( mimeType ) => - mimeType.startsWith( `${ category.mediaType }/` ) - ); - } ); - }, [ - inserterMediaCategories, - allowedMimeTypes, - enableOpenverseMediaCategory, - ] ); - return allowedCategories; -} - export function useMediaCategories( rootClientId ) { const [ categories, setCategories ] = useState( [] ); + + const inserterMediaCategories = useSelect( + ( select ) => + unlock( select( blockEditorStore ) ).getInserterMediaCategories(), + [] + ); const { canInsertImage, canInsertVideo, canInsertAudio } = useSelect( ( select ) => { const { canInsertBlockType } = select( blockEditorStore ); @@ -112,7 +79,6 @@ export function useMediaCategories( rootClientId ) { }, [ rootClientId ] ); - const inserterMediaCategories = useInserterMediaCategories(); useEffect( () => { ( async () => { const _categories = []; diff --git a/packages/block-editor/src/store/actions.js b/packages/block-editor/src/store/actions.js index 1740543744aaa2..ae4b64a645d3ed 100644 --- a/packages/block-editor/src/store/actions.js +++ b/packages/block-editor/src/store/actions.js @@ -1893,9 +1893,10 @@ export const registerInserterMediaCategory = ); return; } - const { inserterMediaCategories = [] } = select.getSettings(); + const registeredInserterMediaCategories = + select.getRegisteredInserterMediaCategories(); if ( - inserterMediaCategories.some( + registeredInserterMediaCategories.some( ( { name } ) => name === category.name ) ) { @@ -1905,8 +1906,8 @@ export const registerInserterMediaCategory = return; } if ( - inserterMediaCategories.some( - ( { labels: { name } } ) => name === category.labels?.name + registeredInserterMediaCategories.some( + ( { labels: { name } = {} } ) => name === category.labels?.name ) ) { console.error( @@ -1919,13 +1920,8 @@ export const registerInserterMediaCategory = // private, so extenders can only add new inserter media categories and don't have any // control over the core media categories. dispatch( { - type: 'UPDATE_SETTINGS', - settings: { - inserterMediaCategories: [ - ...inserterMediaCategories, - { ...category, isExternalResource: true }, - ], - }, + type: 'REGISTER_INSERTER_MEDIA_CATEGORY', + category: { ...category, isExternalResource: true }, } ); }; diff --git a/packages/block-editor/src/store/private-selectors.js b/packages/block-editor/src/store/private-selectors.js index 698da537728e01..c4220e6e7e516c 100644 --- a/packages/block-editor/src/store/private-selectors.js +++ b/packages/block-editor/src/store/private-selectors.js @@ -164,3 +164,75 @@ export function getOpenedBlockSettingsMenu( state ) { export function getStyleOverrides( state ) { return state.styleOverrides; } + +/** @typedef {import('./actions').InserterMediaCategory} InserterMediaCategory */ +/** + * Returns the registered inserter media categories through the public API. + * + * @param {Object} state Editor state. + * + * @return {InserterMediaCategory[]} Inserter media categories. + */ +export function getRegisteredInserterMediaCategories( state ) { + return state.registeredInserterMediaCategories; +} + +/** + * Returns an array containing the allowed inserter media categories. + * It merges the registered media categories from extenders with the + * core ones. It also takes into account the allowed `mime_types`, which + * can be altered by `upload_mimes` filter and restrict some of them. + * + * @param {Object} state Global application state. + * + * @return {InserterMediaCategory[]} Client IDs of descendants. + */ +export const getInserterMediaCategories = createSelector( + ( state ) => { + const { + settings: { + inserterMediaCategories, + allowedMimeTypes, + enableOpenverseMediaCategory, + }, + registeredInserterMediaCategories, + } = state; + // The allowed `mime_types` can be altered by `upload_mimes` filter and restrict + // some of them. In this case we shouldn't add the category to the available media + // categories list in the inserter. + if ( + ( ! inserterMediaCategories && + ! registeredInserterMediaCategories.length ) || + ! allowedMimeTypes + ) { + return; + } + const coreInserterMediaCategoriesNames = + inserterMediaCategories?.map( ( { name } ) => name ) || []; + const mergedCategories = [ + ...( inserterMediaCategories || [] ), + ...( registeredInserterMediaCategories || [] ).filter( + ( { name } ) => + ! coreInserterMediaCategoriesNames.includes( name ) + ), + ]; + return mergedCategories.filter( ( category ) => { + // Check if Openverse category is enabled. + if ( + ! enableOpenverseMediaCategory && + category.name === 'openverse' + ) { + return false; + } + return Object.values( allowedMimeTypes ).some( ( mimeType ) => + mimeType.startsWith( `${ category.mediaType }/` ) + ); + } ); + }, + ( state ) => [ + state.settings.inserterMediaCategories, + state.settings.allowedMimeTypes, + state.settings.enableOpenverseMediaCategory, + state.registeredInserterMediaCategories, + ] +); diff --git a/packages/block-editor/src/store/reducer.js b/packages/block-editor/src/store/reducer.js index 18048ce138eb23..4373182d986622 100644 --- a/packages/block-editor/src/store/reducer.js +++ b/packages/block-editor/src/store/reducer.js @@ -1949,6 +1949,22 @@ export function styleOverrides( state = new Map(), action ) { return state; } +/** + * Reducer returning a map of the registered inserter media categories. + * + * @param {Array} state Current state. + * @param {Object} action Dispatched action. + * + * @return {Array} Updated state. + */ +export function registeredInserterMediaCategories( state = [], action ) { + switch ( action.type ) { + case 'REGISTER_INSERTER_MEDIA_CATEGORY': + return [ ...state, action.category ]; + } + return state; +} + const combinedReducers = combineReducers( { blocks, isTyping, @@ -1976,6 +1992,7 @@ const combinedReducers = combineReducers( { removalPromptData, blockRemovalRules, openedBlockSettingsMenu, + registeredInserterMediaCategories, } ); function withAutomaticChangeReset( reducer ) { diff --git a/packages/block-editor/src/store/test/actions.js b/packages/block-editor/src/store/test/actions.js index f1f8cb29f1406e..e65921e30a6ce7 100644 --- a/packages/block-editor/src/store/test/actions.js +++ b/packages/block-editor/src/store/test/actions.js @@ -1279,9 +1279,9 @@ describe( 'actions', () => { fetch: () => {}, } )( { select: { - getSettings: () => ( { - inserterMediaCategories: [ { name: 'a' } ], - } ), + getRegisteredInserterMediaCategories: () => [ + { name: 'a' }, + ], }, } ); expect( console ).toHaveErroredWith( @@ -1296,11 +1296,9 @@ describe( 'actions', () => { fetch: () => {}, } )( { select: { - getSettings: () => ( { - inserterMediaCategories: [ - { labels: { name: 'a' } }, - ], - } ), + getRegisteredInserterMediaCategories: () => [ + { labels: { name: 'a' } }, + ], }, } ); expect( console ).toHaveErroredWith( @@ -1321,18 +1319,14 @@ describe( 'actions', () => { const dispatch = jest.fn(); registerInserterMediaCategory( category )( { select: { - getSettings: () => ( { inserterMediaCategories } ), + getRegisteredInserterMediaCategories: () => + inserterMediaCategories, }, dispatch, } ); expect( dispatch ).toHaveBeenLastCalledWith( { - type: 'UPDATE_SETTINGS', - settings: { - inserterMediaCategories: [ - ...inserterMediaCategories, - { ...category, isExternalResource: true }, - ], - }, + type: 'REGISTER_INSERTER_MEDIA_CATEGORY', + category: { ...category, isExternalResource: true }, } ); } ); } ); From b90ed86aaaf2c54f3b54c2ddcab2cb4454de8b97 Mon Sep 17 00:00:00 2001 From: Marin Atanasov <8436925+tyxla@users.noreply.github.com> Date: Wed, 4 Oct 2023 16:04:33 +0300 Subject: [PATCH 16/19] Block Editor: Subscribe only to block editor store in useBlockSync (#55041) --- packages/block-editor/src/components/provider/use-block-sync.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-editor/src/components/provider/use-block-sync.js b/packages/block-editor/src/components/provider/use-block-sync.js index d788c7b4442304..32dff45d8be679 100644 --- a/packages/block-editor/src/components/provider/use-block-sync.js +++ b/packages/block-editor/src/components/provider/use-block-sync.js @@ -293,7 +293,7 @@ export default function useBlockSync( { } ); } previousAreBlocksDifferent = areBlocksDifferent; - } ); + }, blockEditorStore ); return () => { subscribed.current = false; From ca2ee4d6fa8c7044cd1d3045c0985a77659f44fa Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Wed, 4 Oct 2023 14:44:43 +0100 Subject: [PATCH 17/19] Update the documentation of the block editor and replace @wordpress/element with react (#54908) Co-authored-by: Marin Atanasov <8436925+tyxla@users.noreply.github.com> --- docs/contributors/code/coding-guidelines.md | 4 +- docs/explanations/architecture/modularity.md | 2 +- .../applying-styles-with-stylesheets.md | 14 +-- .../block-controls-toolbar-and-sidebar.md | 6 +- .../block-supports-in-static-blocks.md | 6 +- .../block-tutorial/creating-dynamic-blocks.md | 12 +-- ...roducing-attributes-and-editable-fields.md | 6 +- .../nested-blocks-inner-blocks.md | 24 ++--- .../writing-your-first-block-type.md | 8 +- .../data-basics/1-data-basics-setup.md | 6 +- .../data-basics/2-building-a-list-of-pages.md | 16 ++-- .../data-basics/5-adding-a-delete-button.md | 6 +- docs/how-to-guides/internationalization.md | 4 +- .../javascript/js-build-setup.md | 2 +- .../platform/custom-block-editor.md | 10 ++- docs/how-to-guides/plugin-sidebar-0.md | 22 ++--- .../block-api/block-deprecation.md | 6 +- .../block-api/block-edit-save.md | 28 +++--- .../block-api/block-metadata.md | 2 +- .../block-api/block-templates.md | 2 +- .../data/data-core-customize-widgets.md | 2 +- .../data/data-core-keyboard-shortcuts.md | 4 +- .../filters/autocomplete-filters.md | 2 +- .../reference-guides/filters/block-filters.md | 12 +-- docs/reference-guides/packages.md | 2 +- docs/reference-guides/richtext.md | 4 +- packages/block-editor/README.md | 18 ++-- .../src/components/block-breadcrumb/index.js | 2 +- .../src/components/block-canvas/index.js | 10 +-- .../src/components/block-context/README.md | 2 +- .../heading-level-icon.js | 4 +- .../block-heading-level-dropdown/index.js | 4 +- .../index.native.js | 4 +- .../block-list/block-list-item.native.js | 4 +- .../components/block-parent-selector/index.js | 2 +- .../src/components/block-preview/index.js | 2 +- .../block-settings-menu-controls/index.js | 2 +- .../block-tools/block-selection-button.js | 2 +- .../components/border-radius-control/index.js | 2 +- .../components/child-layout-control/index.js | 2 +- .../src/components/colors/with-colors.js | 2 +- .../src/components/dimensions-tool/index.js | 2 +- .../components/dimensions-tool/scale-tool.js | 2 +- .../dimensions-tool/width-height-tool.js | 2 +- .../src/components/editable-text/README.md | 4 +- .../font-appearance-control/index.js | 2 +- .../src/components/font-family/README.md | 2 +- .../src/components/height-control/README.md | 2 +- .../src/components/height-control/index.js | 2 +- .../components/image-size-control/README.md | 4 +- .../src/components/inserter/index.js | 4 +- .../src/components/inserter/index.native.js | 4 +- .../letter-spacing-control/index.js | 2 +- .../components/media-placeholder/README.md | 6 +- .../src/components/media-upload/index.js | 2 +- .../components/panel-color-settings/README.md | 6 +- .../src/components/plain-text/README.md | 2 +- .../src/components/provider/README.md | 2 +- .../publish-date-time-picker/README.md | 2 +- .../responsive-block-control/README.md | 4 +- .../src/components/rich-text/README.md | 6 +- .../text-decoration-control/index.js | 2 +- .../text-transform-control/index.js | 2 +- .../src/components/typewriter/index.js | 2 +- .../src/components/unit-control/README.md | 2 +- .../src/components/url-input/README.md | 8 +- .../src/components/use-on-block-drop/index.js | 4 +- .../src/components/writing-flow/index.js | 4 +- .../components/writing-mode-control/index.js | 2 +- packages/block-editor/src/hooks/anchor.js | 4 +- .../src/hooks/custom-class-name.js | 4 +- .../block-editor/src/hooks/custom-fields.js | 4 +- packages/block-editor/src/hooks/font-size.js | 2 +- .../block-editor/src/hooks/line-height.js | 2 +- packages/block-editor/src/hooks/position.js | 2 +- .../src/comment-template/edit.js | 4 +- .../src/embed/wp-embed-preview.js | 2 +- .../src/social-link/social-list.js | 2 +- .../src/table-of-contents/edit.js | 2 +- .../src/table-of-contents/list.tsx | 9 +- packages/blocks/README.md | 4 +- packages/blocks/src/api/children.js | 2 +- packages/blocks/src/api/registration.js | 6 +- packages/blocks/src/api/serializer.js | 6 +- packages/blocks/src/api/test/matchers.js | 8 +- packages/blocks/src/deprecated.js | 4 +- .../src/alignment-matrix-control/README.md | 2 +- .../src/angle-picker-control/README.md | 2 +- packages/components/src/autocomplete/types.ts | 8 +- .../border-box-control/README.md | 2 +- .../border-control/border-control/README.md | 2 +- packages/components/src/box-control/README.md | 2 +- .../components/src/checkbox-control/README.md | 4 +- .../src/circular-option-picker/README.md | 2 +- .../components/src/clipboard-button/README.md | 2 +- .../components/src/color-palette/README.md | 2 +- .../components/src/color-picker/README.md | 2 +- .../components/src/combobox-control/README.md | 2 +- .../components/src/confirm-dialog/README.md | 2 +- .../src/custom-select-control/README.md | 5 +- packages/components/src/date-time/README.md | 2 +- .../src/dimension-control/README.md | 2 +- packages/components/src/disabled/README.md | 2 +- packages/components/src/drop-zone/README.md | 2 +- .../components/src/duotone-picker/README.md | 2 +- .../src/focal-point-picker/README.md | 2 +- .../components/src/focusable-iframe/README.md | 4 +- .../components/src/font-size-picker/README.md | 2 +- .../components/src/form-file-upload/README.md | 4 +- packages/components/src/form-toggle/README.md | 2 +- .../components/src/form-token-field/README.md | 2 +- .../components/src/gradient-picker/README.md | 2 +- .../with-constrained-tabbing/README.md | 2 +- .../higher-order/with-focus-return/README.md | 2 +- .../higher-order/with-focus-return/index.tsx | 2 +- .../with-spoken-messages/index.tsx | 6 +- packages/components/src/icon/README.md | 4 +- .../src/keyboard-shortcuts/README.md | 2 +- packages/components/src/menu-item/README.md | 6 +- .../src/menu-items-choice/README.md | 2 +- .../mobile/bottom-sheet/sub-sheet/README.md | 2 +- .../keyboard-aware-flat-list/index.ios.js | 2 +- packages/components/src/modal/README.md | 2 +- packages/components/src/placeholder/README.md | 2 +- packages/components/src/popover/README.md | 13 ++- .../components/src/query-controls/README.md | 2 +- .../components/src/radio-control/README.md | 4 +- packages/components/src/radio-group/README.md | 4 +- .../components/src/range-control/README.md | 8 +- packages/components/src/scroll-lock/README.md | 2 +- .../components/src/search-control/README.md | 4 +- .../components/src/select-control/README.md | 4 +- .../components/src/text-control/README.md | 2 +- .../components/src/textarea-control/README.md | 4 +- .../components/src/toggle-control/README.md | 4 +- .../README.md | 2 +- packages/components/src/tree-select/README.md | 2 +- .../components/src/unit-control/README.md | 4 +- .../compose/src/hooks/use-dragging/README.md | 2 +- .../compose/src/hooks/use-drop-zone/README.md | 2 +- .../compose/src/hooks/use-previous/README.md | 2 +- .../src/hooks/use-resize-observer/index.tsx | 5 +- packages/core-data/README.md | 2 +- .../core-data/src/hooks/use-entity-record.ts | 2 +- .../block-templates/edit.js.mustache | 2 +- .../block-templates/edit.js.mustache | 2 +- .../block-templates/save.js.mustache | 2 +- .../lib/templates/block/edit.js.mustache | 2 +- .../lib/templates/block/save.js.mustache | 2 +- .../lib/templates/es5/index.js.mustache | 4 +- .../customize-widgets/src/store/actions.js | 2 +- packages/data/README.md | 12 +-- .../components/async-mode-provider/context.js | 2 +- .../components/use-dispatch/use-dispatch.js | 2 +- .../src/components/with-dispatch/index.js | 4 +- .../src/components/with-registry/index.js | 4 +- .../data/src/components/with-select/index.js | 4 +- .../README.md | 4 +- packages/edit-post/README.md | 44 ++++----- .../plugin-block-settings-menu-item.js | 4 +- .../header/plugin-more-menu-item/index.js | 6 +- .../plugin-sidebar-more-menu-item/index.js | 6 +- .../meta-boxes/meta-boxes-area/index.js | 2 +- .../plugin-document-setting-panel/index.js | 6 +- .../plugin-post-publish-panel/index.js | 6 +- .../sidebar/plugin-post-status-info/index.js | 10 +-- .../sidebar/plugin-pre-publish-panel/index.js | 6 +- .../sidebar/plugin-sidebar/index.js | 4 +- .../src/hooks/validate-multiple-use/index.js | 4 +- .../default-block-editor-provider.js | 4 +- .../plugin-more-menu-item/index.js | 2 +- .../plugin-sidebar-more-menu-item/index.js | 2 +- .../plugin-template-setting-panel/index.js | 2 +- .../layout/unsaved-changes-warning.js | 2 +- packages/editor/README.md | 12 +-- .../components/post-featured-image/README.md | 6 +- .../src/components/post-saved-state/index.js | 2 +- .../src/components/post-taxonomies/README.md | 4 +- .../hierarchical-term-selector.js | 2 +- .../post-type-support-check/README.md | 2 +- .../post-type-support-check/index.js | 4 +- .../unsaved-changes-warning/index.js | 2 +- packages/element/CHANGELOG.md | 4 + packages/element/README.md | 89 +++---------------- .../element/src/create-interpolate-element.js | 62 +++++++------ packages/element/src/react-platform.js | 8 +- packages/element/src/react.js | 22 ++--- packages/element/src/serialize.js | 12 +-- packages/eslint-plugin/configs/jsdoc.js | 6 +- .../docs/rules/dependency-group.md | 4 +- .../docs/rules/react-no-unsafe-timeout.md | 4 +- .../components/complementary-area/README.md | 2 +- packages/keyboard-shortcuts/README.md | 2 +- .../src/components/shortcut-provider.js | 2 +- .../keyboard-shortcuts/src/store/actions.js | 4 +- packages/notices/src/store/actions.js | 2 +- .../src/components/pattern-convert-button.js | 2 +- packages/plugins/README.md | 10 +-- packages/plugins/src/api/index.ts | 11 ++- .../src/components/plugin-area/index.tsx | 4 +- .../src/components/plugin-context/index.tsx | 2 +- .../reusable-block-convert-button.js | 2 +- .../docs/basic-concepts/undo-redo.md | 3 +- platform-docs/docs/intro.md | 44 +-------- 204 files changed, 506 insertions(+), 591 deletions(-) diff --git a/docs/contributors/code/coding-guidelines.md b/docs/contributors/code/coding-guidelines.md index 12c3ad96cb85f3..90fb5c7adf81f6 100644 --- a/docs/contributors/code/coding-guidelines.md +++ b/docs/contributors/code/coding-guidelines.md @@ -529,7 +529,7 @@ alert( `My name is ${ name }.` ); - Example: `document.body.classList.toggle( 'has-focus', nodeRef.current?.contains( document.activeElement ) );` may wrongly _add_ the class, since [the second argument is optional](https://developer.mozilla.org/en-US/docs/Web/API/DOMTokenList/toggle). If `undefined` is passed, it would not unset the class as it would when `false` is passed. - Example: `` may inadvertently cause warnings in React by toggling between [controlled and uncontrolled inputs](https://reactjs.org/docs/uncontrolled-components.html). This is an easy trap to fall into when eagerly assuming that a result of `trim()` will always return a string value, overlooking the fact the optional chaining may have caused evaluation to abort earlier with a value of `undefined`. -### `@wordpress/element` (React) Components +### React Components It is preferred to implement all components as [function components](https://reactjs.org/docs/components-and-props.html), using [hooks](https://reactjs.org/docs/hooks-reference.html) to manage component state and lifecycle. With the exception of [error boundaries](https://reactjs.org/docs/error-boundaries.html), you should never encounter a situation where you must use a class component. Note that the [WordPress guidance on Code Refactoring](https://make.wordpress.org/core/handbook/contribute/code-refactoring/) applies here: There needn't be a concentrated effort to update class components in bulk. Instead, consider it as a good refactoring opportunity in combination with some other change. @@ -756,7 +756,7 @@ When documenting an example, use the markdown \`\`\` code block to */ ```` -### Documenting `@wordpress/element` (React) Components +### Documenting React Components When possible, all components should be implemented as [function components](https://reactjs.org/docs/components-and-props.html#function-and-class-components), using [hooks](https://reactjs.org/docs/hooks-intro.html) for managing component lifecycle and state. diff --git a/docs/explanations/architecture/modularity.md b/docs/explanations/architecture/modularity.md index 266e4da1d2325b..dc815d92174dde 100644 --- a/docs/explanations/architecture/modularity.md +++ b/docs/explanations/architecture/modularity.md @@ -43,7 +43,7 @@ function MyApp() { ```php // myplugin.php // Example of script registration dependending on the "components" and "element packages. -wp_register_script( 'myscript', 'pathtomyscript.js', array ('wp-components', "wp-element" ) ); +wp_register_script( 'myscript', 'pathtomyscript.js', array ('wp-components', "react" ) ); ``` ```js diff --git a/docs/how-to-guides/block-tutorial/applying-styles-with-stylesheets.md b/docs/how-to-guides/block-tutorial/applying-styles-with-stylesheets.md index fc8dc01531c5d9..2cd79198b70b9f 100644 --- a/docs/how-to-guides/block-tutorial/applying-styles-with-stylesheets.md +++ b/docs/how-to-guides/block-tutorial/applying-styles-with-stylesheets.md @@ -58,8 +58,8 @@ registerBlockType( 'gutenberg-examples/example-02-stylesheets', { {% Plain %} ```js -( function ( blocks, element, blockEditor ) { - var el = element.createElement; +( function ( blocks, React, blockEditor ) { + var el = React.createElement; blocks.registerBlockType( 'gutenberg-examples/example-02-stylesheets', { edit: function ( props ) { @@ -93,7 +93,7 @@ registerBlockType( 'gutenberg-examples/example-02-stylesheets', { ); }, } ); -} )( window.wp.blocks, window.wp.element, window.wp.blockEditor ); +} )( window.wp.blocks, window.React, window.wp.blockEditor ); ``` {% end %} @@ -134,8 +134,8 @@ registerBlockType( 'gutenberg-examples/example-02-stylesheets', { {% Plain %} ```js -( function ( blocks, element, blockEditor ) { - var el = element.createElement; +( function ( blocks, React, blockEditor ) { + var el = React.createElement; blocks.registerBlockType( 'gutenberg-examples/example-02-stylesheets', { edit: function ( props ) { @@ -155,7 +155,7 @@ registerBlockType( 'gutenberg-examples/example-02-stylesheets', { ); }, } ); -} )( window.wp.blocks, window.wp.element, window.wp.blockEditor ); +} )( window.wp.blocks, window.React, window.wp.blockEditor ); ``` {% end %} @@ -180,8 +180,8 @@ Edit the asset file to include the block-editor dependency for the scripts. array( + 'react', 'wp-blocks', - 'wp-element', 'wp-block-editor', 'wp-polyfill' ), diff --git a/docs/how-to-guides/block-tutorial/block-controls-toolbar-and-sidebar.md b/docs/how-to-guides/block-tutorial/block-controls-toolbar-and-sidebar.md index 93e5e54d848690..1b3a54592b9967 100644 --- a/docs/how-to-guides/block-tutorial/block-controls-toolbar-and-sidebar.md +++ b/docs/how-to-guides/block-tutorial/block-controls-toolbar-and-sidebar.md @@ -95,8 +95,8 @@ registerBlockType( 'gutenberg-examples/example-04-controls-esnext', { {% Plain %} ```js -( function ( blocks, blockEditor, element ) { - var el = element.createElement; +( function ( blocks, blockEditor, React ) { + var el = React.createElement; var RichText = blockEditor.RichText; var AlignmentToolbar = blockEditor.AlignmentToolbar; var BlockControls = blockEditor.BlockControls; @@ -176,7 +176,7 @@ registerBlockType( 'gutenberg-examples/example-04-controls-esnext', { ); }, } ); -} )( window.wp.blocks, window.wp.blockEditor, window.wp.element ); +} )( window.wp.blocks, window.wp.blockEditor, window.React ); ``` {% end %} diff --git a/docs/how-to-guides/block-tutorial/block-supports-in-static-blocks.md b/docs/how-to-guides/block-tutorial/block-supports-in-static-blocks.md index b343280cae43f9..a6350470bb797c 100644 --- a/docs/how-to-guides/block-tutorial/block-supports-in-static-blocks.md +++ b/docs/how-to-guides/block-tutorial/block-supports-in-static-blocks.md @@ -67,8 +67,8 @@ registerBlockType( 'gutenberg-examples/example-03-editable-esnext', { {% Plain %} ```js -( function ( blocks, blockEditor, element ) { - var el = element.createElement; +( function ( blocks, blockEditor, React ) { + var el = React.createElement; var RichText = blockEditor.RichText; var useBlockProps = blockEditor.useBlockProps; @@ -118,7 +118,7 @@ registerBlockType( 'gutenberg-examples/example-03-editable-esnext', { ); }, } ); -} )( window.wp.blocks, window.wp.blockEditor, window.wp.element ); +} )( window.wp.blocks, window.wp.blockEditor, window.React ); ``` {% end %} diff --git a/docs/how-to-guides/block-tutorial/creating-dynamic-blocks.md b/docs/how-to-guides/block-tutorial/creating-dynamic-blocks.md index 9d1e4dbdf52553..f8d4041c4542e4 100644 --- a/docs/how-to-guides/block-tutorial/creating-dynamic-blocks.md +++ b/docs/how-to-guides/block-tutorial/creating-dynamic-blocks.md @@ -55,8 +55,8 @@ registerBlockType( 'gutenberg-examples/example-dynamic', { {% Plain %} ```js -( function ( blocks, element, data, blockEditor ) { - var el = element.createElement, +( function ( blocks, React, data, blockEditor ) { + var el = React.createElement, registerBlockType = blocks.registerBlockType, useSelect = data.useSelect, useBlockProps = blockEditor.useBlockProps; @@ -86,7 +86,7 @@ registerBlockType( 'gutenberg-examples/example-dynamic', { } ); } )( window.wp.blocks, - window.wp.element, + window.React, window.wp.data, window.wp.blockEditor ); @@ -187,8 +187,8 @@ registerBlockType( 'gutenberg-examples/example-dynamic', { {% Plain %} ```js -( function ( blocks, element, serverSideRender, blockEditor ) { - var el = element.createElement, +( function ( blocks, React, serverSideRender, blockEditor ) { + var el = React.createElement, registerBlockType = blocks.registerBlockType, ServerSideRender = serverSideRender, useBlockProps = blockEditor.useBlockProps; @@ -213,7 +213,7 @@ registerBlockType( 'gutenberg-examples/example-dynamic', { } ); } )( window.wp.blocks, - window.wp.element, + window.React, window.wp.serverSideRender, window.wp.blockEditor ); diff --git a/docs/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields.md b/docs/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields.md index 8f4c54451cdb2f..7586081af4216d 100644 --- a/docs/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields.md +++ b/docs/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields.md @@ -111,8 +111,8 @@ registerBlockType( 'gutenberg-examples/example-03-editable-esnext', { {% Plain %} ```js -( function ( blocks, blockEditor, element ) { - var el = element.createElement; +( function ( blocks, blockEditor, React ) { + var el = React.createElement; var RichText = blockEditor.RichText; var useBlockProps = blockEditor.useBlockProps; @@ -162,7 +162,7 @@ registerBlockType( 'gutenberg-examples/example-03-editable-esnext', { ); }, } ); -} )( window.wp.blocks, window.wp.blockEditor, window.wp.element ); +} )( window.wp.blocks, window.wp.blockEditor, window.React ); ``` {% end %} diff --git a/docs/how-to-guides/block-tutorial/nested-blocks-inner-blocks.md b/docs/how-to-guides/block-tutorial/nested-blocks-inner-blocks.md index 8ab024a5c32e54..553b9c48425c37 100644 --- a/docs/how-to-guides/block-tutorial/nested-blocks-inner-blocks.md +++ b/docs/how-to-guides/block-tutorial/nested-blocks-inner-blocks.md @@ -41,8 +41,8 @@ registerBlockType( 'gutenberg-examples/example-06', { {% Plain %} ```js -( function ( blocks, element, blockEditor ) { - var el = element.createElement; +( function ( blocks, React, blockEditor ) { + var el = React.createElement; var InnerBlocks = blockEditor.InnerBlocks; var useBlockProps = blockEditor.useBlockProps; @@ -62,7 +62,7 @@ registerBlockType( 'gutenberg-examples/example-06', { return el( 'div', blockProps, el( InnerBlocks.Content ) ); }, } ); -} )( window.wp.blocks, window.wp.element, window.wp.blockEditor ); +} )( window.wp.blocks, window.React, window.wp.blockEditor ); ``` {% end %} @@ -241,8 +241,8 @@ registerBlockType( 'gutenberg-examples/example-06', { {% Plain %} ```js -( function ( blocks, element, blockEditor ) { - var el = element.createElement; +( function ( blocks, React, blockEditor ) { + var el = React.createElement; var InnerBlocks = blockEditor.InnerBlocks; var useBlockProps = blockEditor.useBlockProps; var useInnerBlocksProps = blockEditor.useInnerBlocksProps; @@ -265,7 +265,7 @@ registerBlockType( 'gutenberg-examples/example-06', { return el( 'div', blockProps, el( 'div', innerBlocksProps ) ); }, } ); -} )( window.wp.blocks, window.wp.element, window.wp.blockEditor ); +} )( window.wp.blocks, window.React, window.wp.blockEditor ); ``` {% end %} @@ -305,8 +305,8 @@ registerBlockType( 'gutenberg-examples/example-06', { {% Plain %} ```js -( function ( blocks, element, blockEditor ) { - var el = element.createElement; +( function ( blocks, React, blockEditor ) { + var el = React.createElement; var InnerBlocks = blockEditor.InnerBlocks; var useBlockProps = blockEditor.useBlockProps; var useInnerBlocksProps = blockEditor.useInnerBlocksProps; @@ -328,7 +328,7 @@ registerBlockType( 'gutenberg-examples/example-06', { return el( 'div', innerBlocksProps ); }, } ); -} )( window.wp.blocks, window.wp.element, window.wp.blockEditor ); +} )( window.wp.blocks, window.React, window.wp.blockEditor ); ``` {% end %} @@ -372,8 +372,8 @@ registerBlockType( 'gutenberg-examples/example-06', { {% Plain %} ```js -( function ( blocks, element, blockEditor ) { - var el = element.createElement; +( function ( blocks, React, blockEditor ) { + var el = React.createElement; var InnerBlocks = blockEditor.InnerBlocks; var useBlockProps = blockEditor.useBlockProps; var useInnerBlocksProps = blockEditor.useInnerBlocksProps; @@ -398,7 +398,7 @@ registerBlockType( 'gutenberg-examples/example-06', { }, // ... } ); -} )( window.wp.blocks, window.wp.element, window.wp.blockEditor ); +} )( window.wp.blocks, window.React, window.wp.blockEditor ); ``` {% end %} diff --git a/docs/how-to-guides/block-tutorial/writing-your-first-block-type.md b/docs/how-to-guides/block-tutorial/writing-your-first-block-type.md index b441a714a1c886..a9dfc0d51a682c 100644 --- a/docs/how-to-guides/block-tutorial/writing-your-first-block-type.md +++ b/docs/how-to-guides/block-tutorial/writing-your-first-block-type.md @@ -145,8 +145,8 @@ registerBlockType( 'gutenberg-examples/example-01-basic-esnext', { Add the following to `block.js` ```js -( function ( blocks, element ) { - var el = element.createElement; +( function ( blocks, React ) { + var el = React.createElement; blocks.registerBlockType( 'gutenberg-examples/example-01-basic', { edit: function () { @@ -156,7 +156,7 @@ Add the following to `block.js` return el( 'p', {}, 'Hola mundo (from the frontend).' ); }, } ); -} )( window.wp.blocks, window.wp.element ); +} )( window.wp.blocks, window.React ); ``` {% end %} @@ -182,8 +182,8 @@ Create the asset file to load the dependencies for the scripts. The name of this array( + 'react', 'wp-blocks', - 'wp-element', 'wp-polyfill' ), 'version' => '0.1' diff --git a/docs/how-to-guides/data-basics/1-data-basics-setup.md b/docs/how-to-guides/data-basics/1-data-basics-setup.md index d9abd07967c8ce..3657b65791a658 100644 --- a/docs/how-to-guides/data-basics/1-data-basics-setup.md +++ b/docs/how-to-guides/data-basics/1-data-basics-setup.md @@ -18,18 +18,18 @@ Go ahead and create these files using the following snippets: **src/index.js:** ```js -import { render } from '@wordpress/element'; +import { createRoot } from 'react-dom'; function MyFirstApp() { return Hello from JavaScript!; } +const root = createRoot( document.getElementById( 'my-first-gutenberg-app' ) ); window.addEventListener( 'load', function () { - render( + root.render( , - document.querySelector( '#my-first-gutenberg-app' ) ); }, false diff --git a/docs/how-to-guides/data-basics/2-building-a-list-of-pages.md b/docs/how-to-guides/data-basics/2-building-a-list-of-pages.md index 282578fbb66dce..aee5575cdb5adb 100644 --- a/docs/how-to-guides/data-basics/2-building-a-list-of-pages.md +++ b/docs/how-to-guides/data-basics/2-building-a-list-of-pages.md @@ -150,8 +150,8 @@ The list of pages is short for now; however, the longer it grows, the harder it Let’s start by adding a search field: ```js +import { useState } from 'react'; import { SearchControl } from '@wordpress/components'; -import { useState, render } from '@wordpress/element'; function MyFirstApp() { const [searchTerm, setSearchTerm] = useState( '' ); @@ -211,8 +211,9 @@ The `searchTerm` is now used as a `search` query parameter when provided. Note t Finally, here’s how `MyFirstApp` looks once we wire it all together: ```js +import { useState } from 'react'; +import { createRoot } from 'react-dom'; import { SearchControl } from '@wordpress/components'; -import { useState, render } from '@wordpress/element'; import { useSelect } from '@wordpress/data'; import { store as coreDataStore } from '@wordpress/core-data'; @@ -359,8 +360,9 @@ And voilà! That's it. All the pieces are in place, great! Here’s the complete JavaScript code of our app: ```js +import { useState } from 'react'; +import { createRoot } from 'react-dom'; import { SearchControl, Spinner } from '@wordpress/components'; -import { useState, render } from '@wordpress/element'; import { useSelect } from '@wordpress/data'; import { store as coreDataStore } from '@wordpress/core-data'; import { decodeEntities } from '@wordpress/html-entities'; @@ -421,12 +423,14 @@ function PagesList( { hasResolved, pages } ) { ); } +const root = createRoot( + document.querySelector( '#my-first-gutenberg-app' ) +); window.addEventListener( 'load', function () { - render( - , - document.querySelector( '#my-first-gutenberg-app' ) + root.render( + ); }, false diff --git a/docs/how-to-guides/data-basics/5-adding-a-delete-button.md b/docs/how-to-guides/data-basics/5-adding-a-delete-button.md index 261c4bda071ab7..07b10ac822c546 100644 --- a/docs/how-to-guides/data-basics/5-adding-a-delete-button.md +++ b/docs/how-to-guides/data-basics/5-adding-a-delete-button.md @@ -142,7 +142,7 @@ wp.data.select( 'core' ).getLastEntityDeleteError( 'postType', 'page', 9 ) Here's how we can apply it in `DeletePageButton`: ```js -import { useEffect } from '@wordpress/element'; +import { useEffect } from 'react'; const DeletePageButton = ({ pageId }) => { // ... const { error, /* ... */ } = useSelect( @@ -252,8 +252,8 @@ Now we're ready to tell the user about any errors that may have occurred. With the SnackbarNotices component in place, we're ready to dispatch some notifications! Here's how: ```js +import { useEffect } from 'react'; import { store as noticesStore } from '@wordpress/notices'; -import { useEffect } from '@wordpress/element'; function DeletePageButton( { pageId } ) { const { createSuccessNotice, createErrorNotice } = useDispatch( noticesStore ); // useSelect returns a list of selectors if you pass the store handle @@ -307,8 +307,8 @@ And that's it! All the pieces are in place, great! Here’s all the changes we've made in this chapter: ```js +import { useState, useEffect } from 'react'; import { useSelect, useDispatch } from '@wordpress/data'; -import { useState, useEffect } from '@wordpress/element'; import { Button, Modal, TextControl } from '@wordpress/components'; function MyFirstApp() { diff --git a/docs/how-to-guides/internationalization.md b/docs/how-to-guides/internationalization.md index af68da27193355..c3194f309fca63 100644 --- a/docs/how-to-guides/internationalization.md +++ b/docs/how-to-guides/internationalization.md @@ -24,7 +24,7 @@ function myguten_block_init() { wp_register_script( 'myguten-script', plugins_url( 'block.js', __FILE__ ), - array( 'wp-blocks', 'wp-element', 'wp-i18n', 'wp-block-editor' ) + array( 'wp-blocks', 'react', 'wp-i18n', 'wp-block-editor' ) ); register_block_type( 'myguten/simple', array( @@ -67,8 +67,8 @@ registerBlockType( 'myguten/simple', { {% Plain %} ```js +const el = React.createElement; const { __ } = wp.i18n; -const el = wp.element.createElement; const { registerBlockType } = wp.blocks; const { useBlockProps } = wp.blockEditor; diff --git a/docs/how-to-guides/javascript/js-build-setup.md b/docs/how-to-guides/javascript/js-build-setup.md index d6a2669da50378..b915f4dd444f90 100644 --- a/docs/how-to-guides/javascript/js-build-setup.md +++ b/docs/how-to-guides/javascript/js-build-setup.md @@ -153,7 +153,7 @@ Likewise, you do not need to include `node_modules` or any of the above configur ## Dependency Management Using `wp-scripts` ver 5.0.0+ build step will also produce an `index.asset.php` file that contains an array of dependencies and a version number for your block. For our simple example above, it is something like: -`array('dependencies' => array('wp-element', 'wp-polyfill'), 'version' => 'fc93c4a9675c108725227db345898bcc');` +`array('dependencies' => array('react', 'wp-polyfill'), 'version' => 'fc93c4a9675c108725227db345898bcc');` Here is how to use this asset file to automatically set the dependency list for enqueuing the script. This prevents having to manually update the dependencies, it will be created based on the package imports used within your block. diff --git a/docs/how-to-guides/platform/custom-block-editor.md b/docs/how-to-guides/platform/custom-block-editor.md index bb2639ddf706fd..88dad59960d029 100644 --- a/docs/how-to-guides/platform/custom-block-editor.md +++ b/docs/how-to-guides/platform/custom-block-editor.md @@ -215,9 +215,11 @@ Begin by opening the main `src/index.js` file. Then pull in the required JavaScr ```js // File: src/index.js +// External dependencies. +import { createRoot } from 'react-dom'; + // WordPress dependencies. import domReady from '@wordpress/dom-ready'; -import { render } from '@wordpress/element'; import { registerCoreBlocks } from '@wordpress/block-library'; // Internal dependencies. @@ -233,11 +235,11 @@ Next, once the DOM is ready you will need to run a function which: ```jsx domReady( function () { + const root = createRoot( document.getElementById( 'getdave-sbe-block-editor' ) ); const settings = window.getdaveSbeSettings || {}; registerCoreBlocks(); - render( - , - document.getElementById( 'getdave-sbe-block-editor' ) + root.render( + ); } ); ``` diff --git a/docs/how-to-guides/plugin-sidebar-0.md b/docs/how-to-guides/plugin-sidebar-0.md index d7e767db93dd75..9543eaf8761549 100644 --- a/docs/how-to-guides/plugin-sidebar-0.md +++ b/docs/how-to-guides/plugin-sidebar-0.md @@ -16,15 +16,15 @@ The tutorial assumes you have an existing plugin setup and are ready to add PHP ### Step 1: Get a Sidebar up and Running -The first step is to tell the editor that there is a new plugin that will have its own sidebar. Use the [registerPlugin](/packages/plugins/README.md), [PluginSidebar](/packages/edit-post/README.md#pluginsidebar), and [createElement](/packages/element/README.md) utilities provided by the `@wordpress/plugins`, `@wordpress/edit-post`, and `@wordpress/element` packages, respectively. +The first step is to tell the editor that there is a new plugin that will have its own sidebar. Use the [registerPlugin](/packages/plugins/README.md), [PluginSidebar](/packages/edit-post/README.md#pluginsidebar), and [createElement](/packages/element/README.md) utilities provided by the `@wordpress/plugins`, `@wordpress/edit-post`, and `react` packages, respectively. Add the following code to a JavaScript file called `plugin-sidebar.js` and save it within your plugin's directory: ```js -( function ( wp ) { +( function ( wp, React ) { + var el = React.createElement; var registerPlugin = wp.plugins.registerPlugin; var PluginSidebar = wp.editPost.PluginSidebar; - var el = wp.element.createElement; registerPlugin( 'my-plugin-sidebar', { render: function () { @@ -39,10 +39,10 @@ Add the following code to a JavaScript file called `plugin-sidebar.js` and save ); }, } ); -} )( window.wp ); +} )( window.wp, window.React ); ``` -For this code to work, those utilities need to be available in the browser, so you must specify `wp-plugins`, `wp-edit-post`, and `wp-element` as dependencies of your script. +For this code to work, those utilities need to be available in the browser, so you must specify `wp-plugins`, `wp-edit-post`, and `react` as dependencies of your script. Here is the PHP code to register your script and specify the dependencies: @@ -57,7 +57,7 @@ function sidebar_plugin_register() { wp_register_script( 'plugin-sidebar-js', plugins_url( 'plugin-sidebar.js', __FILE__ ), - array( 'wp-plugins', 'wp-edit-post', 'wp-element' ) + array( 'wp-plugins', 'wp-edit-post', 'react' ) ); } add_action( 'init', 'sidebar_plugin_register' ); @@ -80,9 +80,9 @@ To visualize and edit the meta field value you'll use an input component. The `@ ```js ( function ( wp ) { + var el = React.createElement; var registerPlugin = wp.plugins.registerPlugin; var PluginSidebar = wp.editPost.PluginSidebar; - var el = wp.element.createElement; var TextControl = wp.components.TextControl; registerPlugin( 'my-plugin-sidebar', { @@ -142,9 +142,9 @@ function sidebar_plugin_register() { 'plugin-sidebar-js', plugins_url( 'plugin-sidebar.js', __FILE__ ), array( + 'react', 'wp-plugins', 'wp-edit-post', - 'wp-element', 'wp-components' ) ); @@ -200,9 +200,9 @@ With the field available in the editor store, it can now be surfaced to the UI. ```js ( function ( wp ) { + var el = React.createElement; var registerPlugin = wp.plugins.registerPlugin; var PluginSidebar = wp.editPost.PluginSidebar; - var el = wp.element.createElement; var TextControl = wp.components.TextControl; var MetaBlockField = function () { @@ -241,9 +241,9 @@ The `useSelect` function is used to fetch data when the component loads and will ```js ( function ( wp ) { + var el = React.createElement; var registerPlugin = wp.plugins.registerPlugin; var PluginSidebar = wp.editPost.PluginSidebar; - var el = wp.element.createElement; var Text = wp.components.TextControl; var useSelect = wp.data.useSelect; @@ -304,9 +304,9 @@ The `useDispatch` function takes a store name as its only argument and returns m ```js ( function ( wp ) { + var el = React.createElement; var registerPlugin = wp.plugins.registerPlugin; var PluginSidebar = wp.editPost.PluginSidebar; - var el = wp.element.createElement; var TextControl = wp.components.TextControl; var useSelect = wp.data.useSelect; var useDispatch = wp.data.useDispatch; diff --git a/docs/reference-guides/block-api/block-deprecation.md b/docs/reference-guides/block-api/block-deprecation.md index d40c13c0406124..a1497ec346936d 100644 --- a/docs/reference-guides/block-api/block-deprecation.md +++ b/docs/reference-guides/block-api/block-deprecation.md @@ -104,7 +104,7 @@ registerBlockType( 'gutenberg/block-with-deprecated-version', { {% Plain %} ```js -var el = wp.element.createElement, +var el = React.createElement, registerBlockType = wp.blocks.registerBlockType, attributes = { text: { @@ -195,7 +195,7 @@ registerBlockType( 'gutenberg/block-with-deprecated-version', { {% Plain %} ```js -var el = wp.element.createElement, +var el = React.createElement, registerBlockType = wp.blocks.registerBlockType; registerBlockType( 'gutenberg/block-with-deprecated-version', { @@ -295,7 +295,7 @@ registerBlockType( 'gutenberg/block-with-deprecated-version', { {% Plain %} ```js -var el = wp.element.createElement, +var el = React.createElement, registerBlockType = wp.blocks.registerBlockType; registerBlockType( 'gutenberg/block-with-deprecated-version', { diff --git a/docs/reference-guides/block-api/block-edit-save.md b/docs/reference-guides/block-api/block-edit-save.md index f38573f35a5f25..35bbd5ae13e1e0 100644 --- a/docs/reference-guides/block-api/block-edit-save.md +++ b/docs/reference-guides/block-api/block-edit-save.md @@ -37,7 +37,7 @@ var blockSettings = { edit: function () { var blockProps = wp.blockEditor.useBlockProps(); - return wp.element.createElement( 'div', blockProps, 'Your block.' ); + return React.createElement( 'div', blockProps, 'Your block.' ); }, }; ``` @@ -85,7 +85,7 @@ var blockSettings = { className: 'my-random-classname', } ); - return wp.element.createElement( 'div', blockProps, 'Your block.' ); + return React.createElement( 'div', blockProps, 'Your block.' ); }, }; ``` @@ -117,7 +117,7 @@ edit: ( { attributes } ) => { edit: function( props ) { var blockProps = wp.blockEditor.useBlockProps(); - return wp.element.createElement( + return React.createElement( 'div', blockProps, props.attributes.content @@ -157,12 +157,12 @@ edit: ( { attributes, isSelected } ) => { edit: function( props ) { var blockProps = wp.blockEditor.useBlockProps(); - return wp.element.createElement( + return React.createElement( 'div', blockProps, [ 'Your block.', - props.isSelected ? wp.element.createElement( + props.isSelected ? React.createElement( 'span', null, 'Shows only when the block is selected.' @@ -213,12 +213,12 @@ edit: function( props ) { // Toggle a setting when the user clicks the button let toggleSetting = () => props.setAttributes( { mySetting: ! mySetting } ); - return wp.element.createElement( + return React.createElement( 'div', blockProps, [ content, - props.isSelected ? wp.element.createElement( + props.isSelected ? React.createElement( 'button', { onClick: toggleSetting }, 'Toggle setting' @@ -292,7 +292,7 @@ save: () => { save: function() { var blockProps = wp.blockEditor.useBlockProps.save(); - return wp.element.createElement( + return React.createElement( 'div', blockProps, 'Your block.' @@ -343,7 +343,7 @@ save: ( { attributes } ) => { save: function( props ) { var blockProps = wp.blockEditor.useBlockProps.save(); - return wp.element.createElement( + return React.createElement( 'div', blockProps, props.attributes.content @@ -413,10 +413,10 @@ edit: function( props ) { props.setAttributes( { content: val } ); } - return wp.element.createElement( + return React.createElement( 'div', blockProps, - wp.element.createElement( + React.createElement( wp.components.TextControl, { label: 'My Text Field', @@ -431,7 +431,7 @@ edit: function( props ) { save: function( props ) { var blockProps = wp.blockEditor.useBlockProps.save(); - return wp.element.createElement( 'div', blockProps, props.attributes.content ); + return React.createElement( 'div', blockProps, props.attributes.content ); }, ``` @@ -486,10 +486,10 @@ attributes: { edit: function( props ) { var blockProps = wp.blockEditor.useBlockProps(); - return wp.element.createEleement( + return React.createEleement( 'div', blockProps, - wp.element.createElement( + React.createElement( wp.components.TextControl, { label: 'Number Posts to Show', diff --git a/docs/reference-guides/block-api/block-metadata.md b/docs/reference-guides/block-api/block-metadata.md index 22d9d66b4f4626..f380683f39ccdd 100644 --- a/docs/reference-guides/block-api/block-metadata.md +++ b/docs/reference-guides/block-api/block-metadata.md @@ -697,8 +697,8 @@ In `build/index.asset.php`: array( + 'react', 'wp-blocks', - 'wp-element', 'wp-i18n', ), 'version' => '3be55b05081a63d8f9d0ecb466c42cfd', diff --git a/docs/reference-guides/block-api/block-templates.md b/docs/reference-guides/block-api/block-templates.md index 2d8a21d510691c..b71625082a4d61 100644 --- a/docs/reference-guides/block-api/block-templates.md +++ b/docs/reference-guides/block-api/block-templates.md @@ -35,7 +35,7 @@ add_action( 'init', 'myplugin_register_template' ); The following example in JavaScript creates a new block using [InnerBlocks](https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/inner-blocks/README.md) and templates, when inserted creates a set of blocks based off the template. ```js -const el = wp.element.createElement; +const el = React.createElement; const { registerBlockType } = wp.blocks; const { InnerBlocks } = wp.blockEditor; diff --git a/docs/reference-guides/data/data-core-customize-widgets.md b/docs/reference-guides/data/data-core-customize-widgets.md index 78433e8991a81c..8796f4cfea5ddf 100644 --- a/docs/reference-guides/data/data-core-customize-widgets.md +++ b/docs/reference-guides/data/data-core-customize-widgets.md @@ -50,11 +50,11 @@ Returns an action object used to open/close the inserter. _Usage_ ```js +import { useState } from 'react'; import { store as customizeWidgetsStore } from '@wordpress/customize-widgets'; import { __ } from '@wordpress/i18n'; import { useDispatch } from '@wordpress/data'; import { Button } from '@wordpress/components'; -import { useState } from '@wordpress/element'; const ExampleComponent = () => { const { setIsInserterOpened } = useDispatch( customizeWidgetsStore ); diff --git a/docs/reference-guides/data/data-core-keyboard-shortcuts.md b/docs/reference-guides/data/data-core-keyboard-shortcuts.md index 076333720786ed..613c5e009e8b07 100644 --- a/docs/reference-guides/data/data-core-keyboard-shortcuts.md +++ b/docs/reference-guides/data/data-core-keyboard-shortcuts.md @@ -350,9 +350,9 @@ Returns an action object used to register a new keyboard shortcut. _Usage_ ```js +import { useEffect } from 'react'; import { store as keyboardShortcutsStore } from '@wordpress/keyboard-shortcuts'; import { useSelect, useDispatch } from '@wordpress/data'; -import { useEffect } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; const ExampleComponent = () => { @@ -401,9 +401,9 @@ Returns an action object used to unregister a keyboard shortcut. _Usage_ ```js +import { useEffect } from 'react'; import { store as keyboardShortcutsStore } from '@wordpress/keyboard-shortcuts'; import { useSelect, useDispatch } from '@wordpress/data'; -import { useEffect } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; const ExampleComponent = () => { diff --git a/docs/reference-guides/filters/autocomplete-filters.md b/docs/reference-guides/filters/autocomplete-filters.md index 1b00710b7b0ba7..1ce47219529181 100644 --- a/docs/reference-guides/filters/autocomplete-filters.md +++ b/docs/reference-guides/filters/autocomplete-filters.md @@ -66,7 +66,7 @@ var acronymCompleter = { return acronym.letters; }, getOptionCompletion: function ( abbr ) { - return wp.element.createElement( + return React.createElement( 'abbr', { title: abbr.expansion }, abbr.letters diff --git a/docs/reference-guides/filters/block-filters.md b/docs/reference-guides/filters/block-filters.md index f1784f893ecb26..3b3846abbcfb5a 100644 --- a/docs/reference-guides/filters/block-filters.md +++ b/docs/reference-guides/filters/block-filters.md @@ -85,7 +85,7 @@ The following filters are available to change the behavior of blocks while editi ### `blocks.getSaveElement` -A filter that applies to the result of a block's `save` function. This filter is used to replace or extend the element, for example using `wp.element.cloneElement` to modify the element's props or replace its children, or returning an entirely new element. +A filter that applies to the result of a block's `save` function. This filter is used to replace or extend the element, for example using `React.cloneElement` to modify the element's props or replace its children, or returning an entirely new element. The filter's callback receives an element, a block type definition object and the block attributes as arguments. It should return an element. @@ -210,14 +210,14 @@ wp.hooks.addFilter( {% Plain %} ```js -var el = wp.element.createElement; +var el = React.createElement; var withInspectorControls = wp.compose.createHigherOrderComponent( function ( BlockEdit ) { return function ( props ) { return el( - wp.element.Fragment, + React.Fragment, {}, el( BlockEdit, props ), el( @@ -275,7 +275,7 @@ wp.hooks.addFilter( {% Plain %} ```js -var el = wp.element.createElement; +var el = React.createElement; var withClientIdClassName = wp.compose.createHigherOrderComponent( function ( BlockListBlock @@ -328,7 +328,7 @@ wp.hooks.addFilter( {% Plain %} ```js -var el = wp.element.createElement; +var el = React.createElement; var hoc = wp.compose.createHigherOrderComponent; var withMyWrapperProp = hoc( function ( BlockListBlock ) { @@ -482,7 +482,7 @@ To set an SVG icon for the category shown in the previous example, add the follo ```js ( function () { - var el = wp.element.createElement; + var el = React.createElement; var SVG = wp.primitives.SVG; var circle = el( 'circle', { cx: 10, diff --git a/docs/reference-guides/packages.md b/docs/reference-guides/packages.md index bd1edf1ae629aa..7dbe06769c42e9 100644 --- a/docs/reference-guides/packages.md +++ b/docs/reference-guides/packages.md @@ -12,7 +12,7 @@ If you wanted to use the `PlainText` component from the block editor module, fir wp_enqueue_script( 'my-custom-block', plugins_url( $block_path, __FILE__ ), - array( 'wp-blocks', 'wp-block-editor', 'wp-element', 'wp-i18n' ) + array( 'react', 'wp-blocks', 'wp-block-editor', 'wp-i18n' ) ); ``` diff --git a/docs/reference-guides/richtext.md b/docs/reference-guides/richtext.md index e0b73826308f16..f908c7585bc1b8 100644 --- a/docs/reference-guides/richtext.md +++ b/docs/reference-guides/richtext.md @@ -83,7 +83,7 @@ wp.blocks.registerBlockType( /* ... */, { edit: function( props ) { var blockProps = wp.blockEditor.useBlockProps(); - return wp.element.createElement( wp.blockEditor.RichText, Object.assign( blockProps, { + return React.createElement( wp.blockEditor.RichText, Object.assign( blockProps, { tagName: 'h2', // The tag here is the element output and editable in the admin value: props.attributes.content, // Any existing content, either from the database or an attribute default allowedFormats: [ 'core/bold', 'core/italic' ], // Allow the content to be made bold or italic, but do not allow other formatting options @@ -97,7 +97,7 @@ wp.blocks.registerBlockType( /* ... */, { save: function( props ) { var blockProps = wp.blockEditor.useBlockProps.save(); - return wp.element.createElement( wp.blockEditor.RichText.Content, Object.assign( blockProps, { + return React.createElement( wp.blockEditor.RichText.Content, Object.assign( blockProps, { tagName: 'h2', value: props.attributes.content // Saves

Content added in the editor...

to the database for frontend display } ) ); } diff --git a/packages/block-editor/README.md b/packages/block-editor/README.md index e56a78a9f768be..837a8c35aacfa2 100644 --- a/packages/block-editor/README.md +++ b/packages/block-editor/README.md @@ -15,13 +15,13 @@ _This package assumes that your code will run in an **ES2015+** environment. If ## Usage ```js +import { useState } from 'react'; import { BlockEditorProvider, BlockList, BlockTools, WritingFlow, } from '@wordpress/block-editor'; -import { useState } from '@wordpress/element'; function MyEditorComponent() { const [ blocks, updateBlocks ] = useState( [] ); @@ -114,7 +114,7 @@ _Parameters_ _Returns_ -- `WPElement`: Block Breadcrumb. +- `Element`: Block Breadcrumb. ### BlockCanvas @@ -142,11 +142,11 @@ _Parameters_ - _props_ `Object`: Component props. - _props.height_ `string`: Canvas height, defaults to 300px. - _props.styles_ `Array`: Content styles to inject into the iframe. -- _props.children_ `WPElement`: Content of the canvas, defaults to the BlockList component. +- _props.children_ `Element`: Content of the canvas, defaults to the BlockList component. _Returns_ -- `WPElement`: Block Breadcrumb. +- `Element`: Block Breadcrumb. ### BlockColorsStyleSelector @@ -226,7 +226,7 @@ _Parameters_ _Returns_ -- `WPComponent`: The component to be rendered. +- `Component`: The component to be rendered. ### BlockSelectionClearer @@ -248,7 +248,7 @@ _Parameters_ _Returns_ -- `WPElement`: Element. +- `Element`: Element. ### BlockStyles @@ -578,7 +578,7 @@ _Parameters_ _Returns_ -- `WPComponent`: The toolbar. +- `ComponentType`: The toolbar. ### HeightControl @@ -597,7 +597,7 @@ _Parameters_ _Returns_ -- `WPComponent`: The component to be rendered. +- `Component`: The component to be rendered. ### InnerBlocks @@ -1012,7 +1012,7 @@ Handles selection and navigation across blocks. This component should be wrapped _Parameters_ - _props_ `Object`: Component properties. -- _props.children_ `WPElement`: Children to be rendered. +- _props.children_ `Element`: Children to be rendered. diff --git a/packages/block-editor/src/components/block-breadcrumb/index.js b/packages/block-editor/src/components/block-breadcrumb/index.js index 13cc93d41a981d..b1fd13dbf3475a 100644 --- a/packages/block-editor/src/components/block-breadcrumb/index.js +++ b/packages/block-editor/src/components/block-breadcrumb/index.js @@ -18,7 +18,7 @@ import { unlock } from '../../lock-unlock'; * * @param {Object} props Component props. * @param {string} props.rootLabelText Translated label for the root element of the breadcrumb trail. - * @return {WPElement} Block Breadcrumb. + * @return {Element} Block Breadcrumb. */ function BlockBreadcrumb( { rootLabelText } ) { const { selectBlock, clearSelectedBlock } = useDispatch( blockEditorStore ); diff --git a/packages/block-editor/src/components/block-canvas/index.js b/packages/block-editor/src/components/block-canvas/index.js index 70d6bbad99e522..435655de3cc269 100644 --- a/packages/block-editor/src/components/block-canvas/index.js +++ b/packages/block-editor/src/components/block-canvas/index.js @@ -91,11 +91,11 @@ export function ExperimentalBlockCanvas( { * } * ``` * - * @param {Object} props Component props. - * @param {string} props.height Canvas height, defaults to 300px. - * @param {Array} props.styles Content styles to inject into the iframe. - * @param {WPElement} props.children Content of the canvas, defaults to the BlockList component. - * @return {WPElement} Block Breadcrumb. + * @param {Object} props Component props. + * @param {string} props.height Canvas height, defaults to 300px. + * @param {Array} props.styles Content styles to inject into the iframe. + * @param {Element} props.children Content of the canvas, defaults to the BlockList component. + * @return {Element} Block Breadcrumb. */ function BlockCanvas( { children, height, styles } ) { return ( diff --git a/packages/block-editor/src/components/block-context/README.md b/packages/block-editor/src/components/block-context/README.md index 9c28b853045ce5..581517466d3c0c 100644 --- a/packages/block-editor/src/components/block-context/README.md +++ b/packages/block-editor/src/components/block-context/README.md @@ -23,7 +23,7 @@ function MyCustomPostEditor() { Internal to the `@wordpress/block-editor` module, a component can access the [full Context object](https://reactjs.org/docs/context.html#api), typically for use in combination with [`useContext`](https://reactjs.org/docs/hooks-reference.html#usecontext). ```js -import { useContext } from '@wordpress/element'; +import { useContext } from 'react'; // Only available internally within `@wordpress/block-editor`! import BlockContext from '../block-context'; diff --git a/packages/block-editor/src/components/block-heading-level-dropdown/heading-level-icon.js b/packages/block-editor/src/components/block-heading-level-dropdown/heading-level-icon.js index dfdc7f824dfbc8..397b1a27e65253 100644 --- a/packages/block-editor/src/components/block-heading-level-dropdown/heading-level-icon.js +++ b/packages/block-editor/src/components/block-heading-level-dropdown/heading-level-icon.js @@ -12,7 +12,7 @@ import { } from '@wordpress/icons'; import { Icon } from '@wordpress/components'; -/** @typedef {import('@wordpress/element').WPComponent} WPComponent */ +/** @typedef {import('react').ComponentType} ComponentType */ /** * HeadingLevelIcon props. @@ -37,7 +37,7 @@ const LEVEL_TO_PATH = { * * @param {WPHeadingLevelIconProps} props Component props. * - * @return {?WPComponent} The icon. + * @return {?ComponentType} The icon. */ export default function HeadingLevelIcon( { level } ) { if ( LEVEL_TO_PATH[ level ] ) { diff --git a/packages/block-editor/src/components/block-heading-level-dropdown/index.js b/packages/block-editor/src/components/block-heading-level-dropdown/index.js index 40d60b08436cc0..be580042bb85e1 100644 --- a/packages/block-editor/src/components/block-heading-level-dropdown/index.js +++ b/packages/block-editor/src/components/block-heading-level-dropdown/index.js @@ -15,7 +15,7 @@ const POPOVER_PROPS = { className: 'block-library-heading-level-dropdown', }; -/** @typedef {import('@wordpress/element').WPComponent} WPComponent */ +/** @typedef {import('react').ComponentType} ComponentType */ /** * HeadingLevelDropdown props. @@ -33,7 +33,7 @@ const POPOVER_PROPS = { * * @param {WPHeadingLevelDropdownProps} props Component props. * - * @return {WPComponent} The toolbar. + * @return {ComponentType} The toolbar. */ export default function HeadingLevelDropdown( { options = HEADING_LEVELS, diff --git a/packages/block-editor/src/components/block-heading-level-dropdown/index.native.js b/packages/block-editor/src/components/block-heading-level-dropdown/index.native.js index fecb608e692e27..25516da29cf106 100644 --- a/packages/block-editor/src/components/block-heading-level-dropdown/index.native.js +++ b/packages/block-editor/src/components/block-heading-level-dropdown/index.native.js @@ -11,7 +11,7 @@ import HeadingLevelIcon from './heading-level-icon'; const HEADING_LEVELS = [ 1, 2, 3, 4, 5, 6 ]; -/** @typedef {import('@wordpress/element').WPComponent} WPComponent */ +/** @typedef {import('react').ComponentType} ComponentType */ /** * HeadingLevelDropdown props. @@ -28,7 +28,7 @@ const HEADING_LEVELS = [ 1, 2, 3, 4, 5, 6 ]; * * @param {WPHeadingLevelDropdownProps} props Component props. * - * @return {WPComponent} The toolbar. + * @return {ComponentType} The toolbar. */ export default function HeadingLevelDropdown( { options = HEADING_LEVELS, diff --git a/packages/block-editor/src/components/block-list/block-list-item.native.js b/packages/block-editor/src/components/block-list/block-list-item.native.js index f1885196f67f75..c91bee36a10c4a 100644 --- a/packages/block-editor/src/components/block-list/block-list-item.native.js +++ b/packages/block-editor/src/components/block-list/block-list-item.native.js @@ -35,7 +35,7 @@ import { useEditorWrapperStyles } from '../../hooks/use-editor-wrapper-styles'; * @param {string} props.rootClientId The root client ID. * @param {Function} props.shouldShowInnerBlockAppender Whether to show the inner block appender. * - * @return {WPComponent} The rendered block list item content. + * @return {Component} The rendered block list item content. */ function BlockListItemContent( { blockWidth, @@ -180,7 +180,7 @@ function BlockListItemContent( { * @param {string} props.rootClientId The root client ID. * @param {Function} props.shouldShowInnerBlockAppender Whether to show the inner block appender. * - * @return {WPComponent|null} The rendered block list item or null if the block width is not provided. + * @return {Component|null} The rendered block list item or null if the block width is not provided. */ function BlockListItem( props ) { const { isGridItem, numOfColumns, tileCount, tileIndex, ...restProps } = diff --git a/packages/block-editor/src/components/block-parent-selector/index.js b/packages/block-editor/src/components/block-parent-selector/index.js index e4a4ff3b6a0a23..31e0b1b8fd8cf4 100644 --- a/packages/block-editor/src/components/block-parent-selector/index.js +++ b/packages/block-editor/src/components/block-parent-selector/index.js @@ -19,7 +19,7 @@ import { store as blockEditorStore } from '../../store'; * Block parent selector component, displaying the hierarchy of the * current block selection as a single icon to "go up" a level. * - * @return {WPComponent} Parent block selector. + * @return {Component} Parent block selector. */ export default function BlockParentSelector() { const { selectBlock } = useDispatch( blockEditorStore ); diff --git a/packages/block-editor/src/components/block-preview/index.js b/packages/block-editor/src/components/block-preview/index.js index b0d5ebb098815f..cf0937507be095 100644 --- a/packages/block-editor/src/components/block-preview/index.js +++ b/packages/block-editor/src/components/block-preview/index.js @@ -88,7 +88,7 @@ export function BlockPreview( { * @param {Array|Object} preview.blocks A block instance (object) or an array of blocks to be previewed. * @param {number} preview.viewportWidth Width of the preview container in pixels. Controls at what size the blocks will be rendered inside the preview. Default: 700. * - * @return {WPComponent} The component to be rendered. + * @return {Component} The component to be rendered. */ export default memo( BlockPreview ); diff --git a/packages/block-editor/src/components/block-settings-menu-controls/index.js b/packages/block-editor/src/components/block-settings-menu-controls/index.js index 53b3835fad1a1b..9063765e72a031 100644 --- a/packages/block-editor/src/components/block-settings-menu-controls/index.js +++ b/packages/block-editor/src/components/block-settings-menu-controls/index.js @@ -112,7 +112,7 @@ const BlockSettingsMenuControlsSlot = ( { * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/block-settings-menu-controls/README.md * * @param {Object} props Fill props. - * @return {WPElement} Element. + * @return {Element} Element. */ function BlockSettingsMenuControls( { ...props } ) { return ( diff --git a/packages/block-editor/src/components/block-tools/block-selection-button.js b/packages/block-editor/src/components/block-tools/block-selection-button.js index 7bac18f14bf400..29cfdf2170817a 100644 --- a/packages/block-editor/src/components/block-tools/block-selection-button.js +++ b/packages/block-editor/src/components/block-tools/block-selection-button.js @@ -49,7 +49,7 @@ import BlockMover from '../block-mover'; * @param {string} props Component props. * @param {string} props.clientId Client ID of block. * - * @return {WPComponent} The component to be rendered. + * @return {Component} The component to be rendered. */ function BlockSelectionButton( { clientId, rootClientId } ) { const blockInformation = useBlockDisplayInformation( clientId ); diff --git a/packages/block-editor/src/components/border-radius-control/index.js b/packages/block-editor/src/components/border-radius-control/index.js index 8754d39ac570f4..0f9041389f244a 100644 --- a/packages/block-editor/src/components/border-radius-control/index.js +++ b/packages/block-editor/src/components/border-radius-control/index.js @@ -44,7 +44,7 @@ const MAX_BORDER_RADIUS_VALUES = { * @param {Function} props.onChange Callback to handle onChange. * @param {Object} props.values Border radius values. * - * @return {WPElement} Custom border radius control. + * @return {Element} Custom border radius control. */ export default function BorderRadiusControl( { onChange, values } ) { const [ isLinked, setIsLinked ] = useState( diff --git a/packages/block-editor/src/components/child-layout-control/index.js b/packages/block-editor/src/components/child-layout-control/index.js index b7679234ae5939..10dffa0eeed8de 100644 --- a/packages/block-editor/src/components/child-layout-control/index.js +++ b/packages/block-editor/src/components/child-layout-control/index.js @@ -31,7 +31,7 @@ function helpText( selfStretch, parentLayout ) { * @param {Function} props.onChange Function to update the child layout value. * @param {Object} props.parentLayout The parent layout value. * - * @return {WPElement} child layout edit element. + * @return {Element} child layout edit element. */ export default function ChildLayoutControl( { value: childLayout = {}, diff --git a/packages/block-editor/src/components/colors/with-colors.js b/packages/block-editor/src/components/colors/with-colors.js index c5972286d4aa1e..e2fbd0b89b5ada 100644 --- a/packages/block-editor/src/components/colors/with-colors.js +++ b/packages/block-editor/src/components/colors/with-colors.js @@ -77,7 +77,7 @@ const withEditorColorPalette = () => * @param {Array} colorTypes An array of color types (e.g. 'backgroundColor, borderColor). * @param {Function} withColorPalette A HOC for injecting the 'colors' prop into the WrappedComponent. * - * @return {WPComponent} The component that can be used as a HOC. + * @return {Component} The component that can be used as a HOC. */ function createColorHOC( colorTypes, withColorPalette ) { const colorMap = colorTypes.reduce( ( colorObject, colorType ) => { diff --git a/packages/block-editor/src/components/dimensions-tool/index.js b/packages/block-editor/src/components/dimensions-tool/index.js index 6fd2c69ed5fe7e..5e39cb47ab9685 100644 --- a/packages/block-editor/src/components/dimensions-tool/index.js +++ b/packages/block-editor/src/components/dimensions-tool/index.js @@ -47,7 +47,7 @@ import WidthHeightTool from './width-height-tool'; * * @param {DimensionsControlsProps} props The component props. * - * @return {WPElement} The dimensions controls. + * @return {Element} The dimensions controls. */ function DimensionsTool( { panelId, diff --git a/packages/block-editor/src/components/dimensions-tool/scale-tool.js b/packages/block-editor/src/components/dimensions-tool/scale-tool.js index e39ee1d837f5c7..a62481160616ff 100644 --- a/packages/block-editor/src/components/dimensions-tool/scale-tool.js +++ b/packages/block-editor/src/components/dimensions-tool/scale-tool.js @@ -76,7 +76,7 @@ const DEFAULT_SCALE_OPTIONS = [ * * @param {ScaleToolProps} props * - * @return {import('@wordpress/element').WPElement} The scale tool. + * @return {import('react').ReactElement} The scale tool. */ export default function ScaleTool( { panelId, diff --git a/packages/block-editor/src/components/dimensions-tool/width-height-tool.js b/packages/block-editor/src/components/dimensions-tool/width-height-tool.js index 2c1db64954ff93..6a4609f9a0bf2d 100644 --- a/packages/block-editor/src/components/dimensions-tool/width-height-tool.js +++ b/packages/block-editor/src/components/dimensions-tool/width-height-tool.js @@ -46,7 +46,7 @@ const SingleColumnToolsPanelItem = styled( ToolsPanelItem )` * * @param {WidthHeightToolProps} props The component props. * - * @return {import('@wordpress/element').WPElement} The width and height tool. + * @return {import('react').ReactElement} The width and height tool. */ export default function WidthHeightTool( { panelId, diff --git a/packages/block-editor/src/components/editable-text/README.md b/packages/block-editor/src/components/editable-text/README.md index 601b996e50be2a..86607349ae8176 100644 --- a/packages/block-editor/src/components/editable-text/README.md +++ b/packages/block-editor/src/components/editable-text/README.md @@ -62,7 +62,7 @@ wp.blocks.registerBlockType( /* ... */, { }, edit: function( props ) { - return wp.element.createElement( wp.editor.EditableText, { + return React.createElement( wp.editor.EditableText, { className: props.className, value: props.attributes.content, onChange: function( content ) { @@ -72,7 +72,7 @@ wp.blocks.registerBlockType( /* ... */, { }, save: function( props ) { - return wp.element.createElement( wp.editor.EditableText.Content, { + return React.createElement( wp.editor.EditableText.Content, { value: props.attributes.content } ); } diff --git a/packages/block-editor/src/components/font-appearance-control/index.js b/packages/block-editor/src/components/font-appearance-control/index.js index 120ade21c568e8..b635cb71d39a5e 100644 --- a/packages/block-editor/src/components/font-appearance-control/index.js +++ b/packages/block-editor/src/components/font-appearance-control/index.js @@ -80,7 +80,7 @@ const getFontAppearanceLabel = ( hasFontStyles, hasFontWeights ) => { * * @param {Object} props Component props. * - * @return {WPElement} Font appearance control. + * @return {Element} Font appearance control. */ export default function FontAppearanceControl( props ) { const { diff --git a/packages/block-editor/src/components/font-family/README.md b/packages/block-editor/src/components/font-family/README.md index 2f6f2c0e5717c3..5300873ab83459 100644 --- a/packages/block-editor/src/components/font-family/README.md +++ b/packages/block-editor/src/components/font-family/README.md @@ -9,8 +9,8 @@ Optionally, you can provide a `fontFamilies` prop that overrides the predefined ## Usage ```jsx +import { useState } from 'react'; import { FontFamilyControl } from '@wordpress/block-editor'; -import { useState } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; // ... diff --git a/packages/block-editor/src/components/height-control/README.md b/packages/block-editor/src/components/height-control/README.md index 9f179abec6cbc8..334829ea9cf51f 100644 --- a/packages/block-editor/src/components/height-control/README.md +++ b/packages/block-editor/src/components/height-control/README.md @@ -16,8 +16,8 @@ _Note:_ It is worth noting that the minimum height option is an opt-in feature. Renders the markup for height control component, to be used in the block inspector. ```jsx +import { useState } from 'react'; import { HeightControl } from '@wordpress/block-editor'; -import { useState } from '@wordpress/element'; const MyLineHeightControl = () => ( const [ value, setValue ] = useState(); diff --git a/packages/block-editor/src/components/height-control/index.js b/packages/block-editor/src/components/height-control/index.js index fe041013d55a02..6d4fc1148cf2fc 100644 --- a/packages/block-editor/src/components/height-control/index.js +++ b/packages/block-editor/src/components/height-control/index.js @@ -38,7 +38,7 @@ const RANGE_CONTROL_CUSTOM_SETTINGS = { * @param {( value: string ) => void } props.onChange Called when the height changes. * @param {string} props.value The current height value. * - * @return {WPComponent} The component to be rendered. + * @return {Component} The component to be rendered. */ export default function HeightControl( { label = __( 'Height' ), diff --git a/packages/block-editor/src/components/image-size-control/README.md b/packages/block-editor/src/components/image-size-control/README.md index 2fc078c773b5a1..17e3b1ea85928a 100644 --- a/packages/block-editor/src/components/image-size-control/README.md +++ b/packages/block-editor/src/components/image-size-control/README.md @@ -7,8 +7,8 @@ Allow users to control the width & height of an image. Render a ImageSizeControl. ```jsx +import { useState } from 'react'; import { __experimentalImageSizeControl as ImageSizeControl } from '@wordpress/block-editor'; -import { useState } from '@wordpress/element'; const MyImageSizeControl = () => { const [ size, setSize ] = useState( { width: null, height: null } ); @@ -36,7 +36,7 @@ The component accepts the following props: If this property is added, a help text will be generated for the image size control, using imageSizeHelp property as the content. -- Type: `String|WPElement` +- Type: `String|Element` - Required: No ### slug diff --git a/packages/block-editor/src/components/inserter/index.js b/packages/block-editor/src/components/inserter/index.js index 8e2972fbe2bf5e..c048ee7b3b138c 100644 --- a/packages/block-editor/src/components/inserter/index.js +++ b/packages/block-editor/src/components/inserter/index.js @@ -102,7 +102,7 @@ class PrivateInserter extends Component { * pressed. * @param {boolean} options.isOpen Whether dropdown is currently open. * - * @return {WPElement} Dropdown toggle element. + * @return {Element} Dropdown toggle element. */ renderToggle( { onToggle, isOpen } ) { const { @@ -135,7 +135,7 @@ class PrivateInserter extends Component { * @param {Function} options.onClose Callback to invoke when dropdown is * closed. * - * @return {WPElement} Dropdown content element. + * @return {Element} Dropdown content element. */ renderContent( { onClose } ) { const { diff --git a/packages/block-editor/src/components/inserter/index.native.js b/packages/block-editor/src/components/inserter/index.native.js index 6edef19583b3fc..5966b3d90c66fb 100644 --- a/packages/block-editor/src/components/inserter/index.native.js +++ b/packages/block-editor/src/components/inserter/index.native.js @@ -225,7 +225,7 @@ export class Inserter extends Component { * pressed. * @param {boolean} options.isOpen Whether dropdown is currently open. * - * @return {WPElement} Dropdown toggle element. + * @return {Element} Dropdown toggle element. */ renderInserterToggle( { onToggle, isOpen } ) { const { @@ -305,7 +305,7 @@ export class Inserter extends Component { * closed. * @param {boolean} options.isOpen Whether dropdown is currently open. * - * @return {WPElement} Dropdown content element. + * @return {Element} Dropdown content element. */ renderContent( { onClose, isOpen } ) { const { clientId, isAppender } = this.props; diff --git a/packages/block-editor/src/components/letter-spacing-control/index.js b/packages/block-editor/src/components/letter-spacing-control/index.js index 0b67a74cda0cd2..757eab60e50ae0 100644 --- a/packages/block-editor/src/components/letter-spacing-control/index.js +++ b/packages/block-editor/src/components/letter-spacing-control/index.js @@ -20,7 +20,7 @@ import useSetting from '../../components/use-setting'; * @param {Function} props.onChange Handles change in letter-spacing selection. * @param {string|number|undefined} props.__unstableInputWidth Input width to pass through to inner UnitControl. Should be a valid CSS value. * - * @return {WPElement} Letter-spacing control. + * @return {Element} Letter-spacing control. */ export default function LetterSpacingControl( { value, diff --git a/packages/block-editor/src/components/media-placeholder/README.md b/packages/block-editor/src/components/media-placeholder/README.md index 001c18673f45c6..6cb00206d93d72 100644 --- a/packages/block-editor/src/components/media-placeholder/README.md +++ b/packages/block-editor/src/components/media-placeholder/README.md @@ -98,9 +98,9 @@ The `disableDropZone` prop still takes precedence over `dropZoneUIOnly` – spec ### icon -Icon to display left of the title. When passed as a `String`, the icon will be resolved as a [Dashicon](https://developer.wordpress.org/resource/dashicons/). Alternatively, you can pass in a `WPComponent` such as `BlockIcon`to render instead. +Icon to display left of the title. When passed as a `String`, the icon will be resolved as a [Dashicon](https://developer.wordpress.org/resource/dashicons/). Alternatively, you can pass in a `Component` such as `BlockIcon`to render instead. -- Type: `String|WPComponent` +- Type: `String|Component` - Required: No - Platform: Web | Mobile @@ -216,7 +216,7 @@ Replace implementation of the placeholder: ```js function replaceMediaPlaceholder() { return function () { - return wp.element.createElement( + return React.createElement( 'div', {}, 'The replacement contents or components.' diff --git a/packages/block-editor/src/components/media-upload/index.js b/packages/block-editor/src/components/media-upload/index.js index ccaf902e497f43..0b129a14726a50 100644 --- a/packages/block-editor/src/components/media-upload/index.js +++ b/packages/block-editor/src/components/media-upload/index.js @@ -8,7 +8,7 @@ import { withFilters } from '@wordpress/components'; * an integration with the core blocks that handle media files. By default it renders nothing but * it provides a way to have it overridden with the `editor.MediaUpload` filter. * - * @return {WPComponent} The component to be rendered. + * @return {Component} The component to be rendered. */ const MediaUpload = () => null; diff --git a/packages/block-editor/src/components/panel-color-settings/README.md b/packages/block-editor/src/components/panel-color-settings/README.md index 94b82eb3869b1a..e9f3818fab55c3 100644 --- a/packages/block-editor/src/components/panel-color-settings/README.md +++ b/packages/block-editor/src/components/panel-color-settings/README.md @@ -6,11 +6,15 @@ It is essentially a wrapper around the `PanelColorGradientSettings` component, b ## Usage ```jsx +/** + * External dependencies + */ +import { useState } from 'react'; + /** * WordPress dependencies */ import { PanelColorSettings } from '@wordpress/block-editor'; -import { useState } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; // ... diff --git a/packages/block-editor/src/components/plain-text/README.md b/packages/block-editor/src/components/plain-text/README.md index 64d1c04b5c09bc..25b18fcddc48fd 100644 --- a/packages/block-editor/src/components/plain-text/README.md +++ b/packages/block-editor/src/components/plain-text/README.md @@ -34,7 +34,7 @@ wp.blocks.registerBlockType( /* ... */, { }, edit: function( props ) { - return wp.element.createElement( wp.editor.PlainText, { + return React.createElement( wp.editor.PlainText, { className: props.className, value: props.attributes.content, onChange: function( content ) { diff --git a/packages/block-editor/src/components/provider/README.md b/packages/block-editor/src/components/provider/README.md index 8d78e5b85db0e7..4f72386cba2a56 100644 --- a/packages/block-editor/src/components/provider/README.md +++ b/packages/block-editor/src/components/provider/README.md @@ -33,7 +33,7 @@ A callback invoked when the blocks have been modified in a non-persistent manner ### `children` -- **Type:** `WPElement` +- **Type:** `Element` - **Required** `no` Children elements for which the BlockEditorProvider context should apply. diff --git a/packages/block-editor/src/components/publish-date-time-picker/README.md b/packages/block-editor/src/components/publish-date-time-picker/README.md index af98bebfdfda95..a7d92250c7cb0f 100644 --- a/packages/block-editor/src/components/publish-date-time-picker/README.md +++ b/packages/block-editor/src/components/publish-date-time-picker/README.md @@ -10,9 +10,9 @@ for more information. ## Usage ```jsx +import { useState } from 'react'; import { Dropdown, Button } from '@wordpress/components'; import { __experimentalPublishDateTimePicker as PublishDateTimePicker } from '@wordpress/block-editor'; -import { useState } from '@wordpress/element'; const MyDateTimePicker = () => { const [ date, setDate ] = useState( new Date() ); diff --git a/packages/block-editor/src/components/responsive-block-control/README.md b/packages/block-editor/src/components/responsive-block-control/README.md index c9704ab7ca3eff..ec6e1f4beb018d 100644 --- a/packages/block-editor/src/components/responsive-block-control/README.md +++ b/packages/block-editor/src/components/responsive-block-control/README.md @@ -21,14 +21,12 @@ In a block's `edit` implementation, render a `` compon By default the default control will be used to render the default (ie: "All") setting _as well as_ the per-viewport responsive settings. ```jsx +import { useState } from 'react'; import { registerBlockType } from '@wordpress/blocks'; import { InspectorControls, ResponsiveBlockControl, } from '@wordpress/block-editor'; - -import { useState } from '@wordpress/element'; - import { DimensionControl, } from '@wordpress/components'; diff --git a/packages/block-editor/src/components/rich-text/README.md b/packages/block-editor/src/components/rich-text/README.md index 91161414899bfb..eea63d0b2912db 100644 --- a/packages/block-editor/src/components/rich-text/README.md +++ b/packages/block-editor/src/components/rich-text/README.md @@ -94,7 +94,7 @@ wp.blocks.registerBlockType( /* ... */, { }, edit: function( props ) { - return wp.element.createElement( wp.editor.RichText, { + return React.createElement( wp.editor.RichText, { tagName: 'h2', className: props.className, value: props.attributes.content, @@ -105,7 +105,7 @@ wp.blocks.registerBlockType( /* ... */, { }, save: function( props ) { - return wp.element.createElement( wp.editor.RichText.Content, { + return React.createElement( wp.editor.RichText.Content, { tagName: 'h2', value: props.attributes.content } ); } @@ -160,7 +160,7 @@ Slot to extend the format toolbar. Use it in the edit function of a `registerFor wp.richText.registerFormatType( /* ... */, { /* ... */ edit: function( props ) { - return wp.element.createElement( + return React.createElement( wp.editor.RichTextToolbarButton, { icon: 'editor-code', title: 'My formatting button', diff --git a/packages/block-editor/src/components/text-decoration-control/index.js b/packages/block-editor/src/components/text-decoration-control/index.js index 36211185acb77c..973fb71a7448f1 100644 --- a/packages/block-editor/src/components/text-decoration-control/index.js +++ b/packages/block-editor/src/components/text-decoration-control/index.js @@ -36,7 +36,7 @@ const TEXT_DECORATIONS = [ * @param {Function} props.onChange Handles change in text decoration selection. * @param {string} [props.className] Additional class name to apply. * - * @return {WPElement} Text decoration control. + * @return {Element} Text decoration control. */ export default function TextDecorationControl( { value, diff --git a/packages/block-editor/src/components/text-transform-control/index.js b/packages/block-editor/src/components/text-transform-control/index.js index 9674b49d5ed5ac..c5d0ce37e9acd1 100644 --- a/packages/block-editor/src/components/text-transform-control/index.js +++ b/packages/block-editor/src/components/text-transform-control/index.js @@ -46,7 +46,7 @@ const TEXT_TRANSFORMS = [ * @param {string} props.value Currently selected text transform. * @param {Function} props.onChange Handles change in text transform selection. * - * @return {WPElement} Text transform control. + * @return {Element} Text transform control. */ export default function TextTransformControl( { className, value, onChange } ) { return ( diff --git a/packages/block-editor/src/components/typewriter/index.js b/packages/block-editor/src/components/typewriter/index.js index ac83d173a95d9d..b5e230d314a7e2 100644 --- a/packages/block-editor/src/components/typewriter/index.js +++ b/packages/block-editor/src/components/typewriter/index.js @@ -273,7 +273,7 @@ function Typewriter( { children } ) { * challenges in Internet Explorer, and is simply skipped, rendering the given * props children instead. * - * @type {WPComponent} + * @type {Component} */ const TypewriterOrIEBypass = isIE ? ( props ) => props.children : Typewriter; diff --git a/packages/block-editor/src/components/unit-control/README.md b/packages/block-editor/src/components/unit-control/README.md index 4d99d85254decb..e5126e7bf45242 100644 --- a/packages/block-editor/src/components/unit-control/README.md +++ b/packages/block-editor/src/components/unit-control/README.md @@ -26,8 +26,8 @@ UnitControl component allows the user to set a value as well as a unit (e.g. `px Renders a control (`input` and `select`) with the values `10` and `px` parsed from `10px`. ```jsx +import { useState } from 'react'; import { __experimentalUnitControl as UnitControl } from '@wordpress/block-editor/'; -import { useState } from '@wordpress/element'; const Example = () => { const [ value, setValue ] = useState( '10px' ); diff --git a/packages/block-editor/src/components/url-input/README.md b/packages/block-editor/src/components/url-input/README.md index a10ae409ef61a1..46f673ecd35545 100644 --- a/packages/block-editor/src/components/url-input/README.md +++ b/packages/block-editor/src/components/url-input/README.md @@ -53,7 +53,7 @@ wp.blocks.registerBlockType( /* ... */, { }, edit: function( props ) { - return wp.element.createElement( wp.blockEditor.URLInputButton, { + return React.createElement( wp.blockEditor.URLInputButton, { className: props.className, url: props.attributes.url, onChange: function( url, post ) { @@ -63,7 +63,7 @@ wp.blocks.registerBlockType( /* ... */, { }, save: function( props ) { - return wp.element.createElement( 'a', { + return React.createElement( 'a', { href: props.attributes.url, }, props.attributes.text ); } @@ -189,7 +189,7 @@ wp.blocks.registerBlockType( /* ... */, { }, edit: function( props ) { - return wp.element.createElement( wp.blockEditor.URLInput, { + return React.createElement( wp.blockEditor.URLInput, { className: props.className, value: props.attributes.url, onChange: function( url, post ) { @@ -199,7 +199,7 @@ wp.blocks.registerBlockType( /* ... */, { }, save: function( props ) { - return wp.element.createElement( 'a', { + return React.createElement( 'a', { href: props.attributes.url, }, props.attributes.text ); } diff --git a/packages/block-editor/src/components/use-on-block-drop/index.js b/packages/block-editor/src/components/use-on-block-drop/index.js index 6b0a9300124493..72ea6a698c3439 100644 --- a/packages/block-editor/src/components/use-on-block-drop/index.js +++ b/packages/block-editor/src/components/use-on-block-drop/index.js @@ -16,13 +16,13 @@ import { getFilesFromDataTransfer } from '@wordpress/dom'; */ import { store as blockEditorStore } from '../../store'; -/** @typedef {import('@wordpress/element').WPSyntheticEvent} WPSyntheticEvent */ +/** @typedef {import('react').SyntheticEvent} SyntheticEvent */ /** @typedef {import('./types').WPDropOperation} WPDropOperation */ /** * Retrieve the data for a block drop event. * - * @param {WPSyntheticEvent} event The drop event. + * @param {SyntheticEvent} event The drop event. * * @return {Object} An object with block drag and drop data. */ diff --git a/packages/block-editor/src/components/writing-flow/index.js b/packages/block-editor/src/components/writing-flow/index.js index e3100dc3464c65..03d7e43f5285ed 100644 --- a/packages/block-editor/src/components/writing-flow/index.js +++ b/packages/block-editor/src/components/writing-flow/index.js @@ -93,7 +93,7 @@ function WritingFlow( { children, ...props }, forwardedRef ) { * Handles selection and navigation across blocks. This component should be * wrapped around BlockList. * - * @param {Object} props Component properties. - * @param {WPElement} props.children Children to be rendered. + * @param {Object} props Component properties. + * @param {Element} props.children Children to be rendered. */ export default forwardRef( WritingFlow ); diff --git a/packages/block-editor/src/components/writing-mode-control/index.js b/packages/block-editor/src/components/writing-mode-control/index.js index 99acc34570e99f..2adf8be14ad395 100644 --- a/packages/block-editor/src/components/writing-mode-control/index.js +++ b/packages/block-editor/src/components/writing-mode-control/index.js @@ -31,7 +31,7 @@ const WRITING_MODES = [ * @param {string} props.value Currently selected writing mode. * @param {Function} props.onChange Handles change in the writing mode selection. * - * @return {WPElement} Writing Mode control. + * @return {Element} Writing Mode control. */ export default function WritingModeControl( { className, value, onChange } ) { return ( diff --git a/packages/block-editor/src/hooks/anchor.js b/packages/block-editor/src/hooks/anchor.js index b3fdcd65c541b7..6e8acd5eb7f2e7 100644 --- a/packages/block-editor/src/hooks/anchor.js +++ b/packages/block-editor/src/hooks/anchor.js @@ -56,9 +56,9 @@ export function addAttribute( settings ) { * Override the default edit UI to include a new block inspector control for * assigning the anchor ID, if block supports anchor. * - * @param {WPComponent} BlockEdit Original component. + * @param {Component} BlockEdit Original component. * - * @return {WPComponent} Wrapped component. + * @return {Component} Wrapped component. */ export const withInspectorControl = createHigherOrderComponent( ( BlockEdit ) => { diff --git a/packages/block-editor/src/hooks/custom-class-name.js b/packages/block-editor/src/hooks/custom-class-name.js index 5505c5fcae2cca..087fdffe23255a 100644 --- a/packages/block-editor/src/hooks/custom-class-name.js +++ b/packages/block-editor/src/hooks/custom-class-name.js @@ -44,9 +44,9 @@ export function addAttribute( settings ) { * assigning the custom class name, if block supports custom class name. * The control is displayed within the Advanced panel in the block inspector. * - * @param {WPComponent} BlockEdit Original component. + * @param {Component} BlockEdit Original component. * - * @return {WPComponent} Wrapped component. + * @return {Component} Wrapped component. */ export const withInspectorControl = createHigherOrderComponent( ( BlockEdit ) => { diff --git a/packages/block-editor/src/hooks/custom-fields.js b/packages/block-editor/src/hooks/custom-fields.js index dbc8c3ec2c089f..9affb55c3ea71f 100644 --- a/packages/block-editor/src/hooks/custom-fields.js +++ b/packages/block-editor/src/hooks/custom-fields.js @@ -40,9 +40,9 @@ function addAttribute( settings ) { * Currently, only the `core/paragraph` block is supported and there is only a relation * between paragraph content and a custom field. * - * @param {WPComponent} BlockEdit Original component. + * @param {Component} BlockEdit Original component. * - * @return {WPComponent} Wrapped component. + * @return {Component} Wrapped component. */ const withInspectorControl = createHigherOrderComponent( ( BlockEdit ) => { return ( props ) => { diff --git a/packages/block-editor/src/hooks/font-size.js b/packages/block-editor/src/hooks/font-size.js index 54d6836a1ef0ad..a9d2facfa26702 100644 --- a/packages/block-editor/src/hooks/font-size.js +++ b/packages/block-editor/src/hooks/font-size.js @@ -115,7 +115,7 @@ function addEditProps( settings ) { * * @param {Object} props * - * @return {WPElement} Font size edit element. + * @return {Element} Font size edit element. */ export function FontSizeEdit( props ) { const { diff --git a/packages/block-editor/src/hooks/line-height.js b/packages/block-editor/src/hooks/line-height.js index 363766e91b4978..b835f54a12b6c4 100644 --- a/packages/block-editor/src/hooks/line-height.js +++ b/packages/block-editor/src/hooks/line-height.js @@ -17,7 +17,7 @@ export const LINE_HEIGHT_SUPPORT_KEY = 'typography.lineHeight'; * * @param {Object} props * - * @return {WPElement} Line height edit element. + * @return {Element} Line height edit element. */ export function LineHeightEdit( props ) { const { diff --git a/packages/block-editor/src/hooks/position.js b/packages/block-editor/src/hooks/position.js index 640fda33d2c72b..7c1bff6e99692f 100644 --- a/packages/block-editor/src/hooks/position.js +++ b/packages/block-editor/src/hooks/position.js @@ -209,7 +209,7 @@ export function useIsPositionDisabled( { name: blockName } = {} ) { * * @param {Object} props * - * @return {WPElement} Position panel. + * @return {Element} Position panel. */ export function PositionPanel( props ) { const { diff --git a/packages/block-library/src/comment-template/edit.js b/packages/block-library/src/comment-template/edit.js index 3d33428f6f4585..50d83289e1ed92 100644 --- a/packages/block-library/src/comment-template/edit.js +++ b/packages/block-library/src/comment-template/edit.js @@ -105,7 +105,7 @@ const getCommentsPlaceholder = ( { * @param {Array} [props.firstCommentId] - ID of the first comment in the array. * @param {Array} [props.blocks] - Array of blocks returned from * getBlocks() in parent . - * @return {WPElement} Inner blocks of the Comment Template + * @return {Element} Inner blocks of the Comment Template */ function CommentTemplateInnerBlocks( { comment, @@ -202,7 +202,7 @@ const MemoizedCommentTemplatePreview = memo( CommentTemplatePreview ); * @param {Array} [props.blocks] - Array of blocks returned from getBlocks() in parent. * @param {Object} [props.firstCommentId] - The ID of the first comment in the array of * comment objects. - * @return {WPElement} List of comments. + * @return {Element} List of comments. */ const CommentsList = ( { comments, diff --git a/packages/block-library/src/embed/wp-embed-preview.js b/packages/block-library/src/embed/wp-embed-preview.js index 0e812ffa647e3e..1992310217aca4 100644 --- a/packages/block-library/src/embed/wp-embed-preview.js +++ b/packages/block-library/src/embed/wp-embed-preview.js @@ -4,7 +4,7 @@ import { useMergeRefs, useFocusableIframe } from '@wordpress/compose'; import { useRef, useEffect, useMemo } from '@wordpress/element'; -/** @typedef {import('@wordpress/element').WPSyntheticEvent} WPSyntheticEvent */ +/** @typedef {import('react').SyntheticEvent} SyntheticEvent */ const attributeMap = { class: 'className', diff --git a/packages/block-library/src/social-link/social-list.js b/packages/block-library/src/social-link/social-list.js index 38c1ef91f99384..909e9b90a54c5c 100644 --- a/packages/block-library/src/social-link/social-list.js +++ b/packages/block-library/src/social-link/social-list.js @@ -14,7 +14,7 @@ import { ChainIcon } from './icons'; * * @param {string} name key for a social service (lowercase slug) * - * @return {WPComponent} Icon component for social service. + * @return {Component} Icon component for social service. */ export const getIconBySite = ( name ) => { const variation = variations.find( ( v ) => v.name === name ); diff --git a/packages/block-library/src/table-of-contents/edit.js b/packages/block-library/src/table-of-contents/edit.js index 30101fe9419b9f..7c2d7e1f8eb148 100644 --- a/packages/block-library/src/table-of-contents/edit.js +++ b/packages/block-library/src/table-of-contents/edit.js @@ -42,7 +42,7 @@ import { useObserveHeadings } from './hooks'; * @param {string} props.clientId * @param {(attributes: Object) => void} props.setAttributes * - * @return {WPComponent} The component. + * @return {Component} The component. */ export default function TableOfContentsEdit( { attributes: { headings = [], onlyIncludeCurrentPage }, diff --git a/packages/block-library/src/table-of-contents/list.tsx b/packages/block-library/src/table-of-contents/list.tsx index c5a5192b9e4f1c..fcb4736bab091d 100644 --- a/packages/block-library/src/table-of-contents/list.tsx +++ b/packages/block-library/src/table-of-contents/list.tsx @@ -1,12 +1,7 @@ /** * External dependencies */ -import type { MouseEvent } from 'react'; - -/** - * WordPress dependencies - */ -import type { WPElement } from '@wordpress/element'; +import type { MouseEvent, ReactElement } from 'react'; /** * Internal dependencies @@ -23,7 +18,7 @@ export default function TableOfContentsList( { nestedHeadingList: NestedHeadingData[]; disableLinkActivation?: boolean; onClick?: ( event: MouseEvent< HTMLAnchorElement > ) => void; -} ): WPElement { +} ): ReactElement { return ( <> { nestedHeadingList.map( ( node, index ) => { diff --git a/packages/blocks/README.md b/packages/blocks/README.md index 91cfec30c6a726..cbde04f72fd95b 100644 --- a/packages/blocks/README.md +++ b/packages/blocks/README.md @@ -914,11 +914,11 @@ A Higher Order Component used to inject BlockContent using context to the wrappe _Parameters_ -- _OriginalComponent_ `WPComponent`: The component to enhance. +- _OriginalComponent_ `Component`: The component to enhance. _Returns_ -- `WPComponent`: The same component. +- `Component`: The same component. diff --git a/packages/blocks/src/api/children.js b/packages/blocks/src/api/children.js index 8d0b3488017d5d..fe46a30870af97 100644 --- a/packages/blocks/src/api/children.js +++ b/packages/blocks/src/api/children.js @@ -20,7 +20,7 @@ import * as node from './node'; * * @param {WPBlockChildren} children Block children object to convert. * - * @return {WPElement} A serialize-capable element. + * @return {Element} A serialize-capable element. */ export function getSerializeCapableElement( children ) { // The fact that block children are compatible with the element serializer is diff --git a/packages/blocks/src/api/registration.js b/packages/blocks/src/api/registration.js index 818a26fdb4e5c4..b1dbee47b9b7cb 100644 --- a/packages/blocks/src/api/registration.js +++ b/packages/blocks/src/api/registration.js @@ -17,7 +17,7 @@ import { unlock } from '../lock-unlock'; * An icon type definition. One of a Dashicon slug, an element, * or a component. * - * @typedef {(string|WPElement|WPComponent)} WPIcon + * @typedef {(string|Element|Component)} WPIcon * * @see https://developer.wordpress.org/resource/dashicons/ */ @@ -112,10 +112,10 @@ import { unlock } from '../lock-unlock'; * @property {string[]} [keywords] Additional keywords to produce block * type as result in search interfaces. * @property {Object} [attributes] Block type attributes. - * @property {WPComponent} [save] Optional component describing + * @property {Component} [save] Optional component describing * serialized markup structure of a * block type. - * @property {WPComponent} edit Component rendering an element to + * @property {Component} edit Component rendering an element to * manipulate the attributes of a block * in the context of an editor. * @property {WPBlockVariation[]} [variations] The list of block variations. diff --git a/packages/blocks/src/api/serializer.js b/packages/blocks/src/api/serializer.js index 29ac9f9a2228f3..5883f47536431d 100644 --- a/packages/blocks/src/api/serializer.js +++ b/packages/blocks/src/api/serializer.js @@ -174,9 +174,9 @@ export function getSaveElement( /** * Filters the save result of a block during serialization. * - * @param {WPElement} element Block save result. - * @param {WPBlock} blockType Block type definition. - * @param {Object} attributes Block attributes. + * @param {Element} element Block save result. + * @param {WPBlock} blockType Block type definition. + * @param {Object} attributes Block attributes. */ return applyFilters( 'blocks.getSaveElement', diff --git a/packages/blocks/src/api/test/matchers.js b/packages/blocks/src/api/test/matchers.js index 2068ae18c6e066..894c18abe3a01a 100644 --- a/packages/blocks/src/api/test/matchers.js +++ b/packages/blocks/src/api/test/matchers.js @@ -22,9 +22,9 @@ describe( 'matchers', () => { expect( typeof source ).toBe( 'function' ); } ); - it( 'should return HTML equivalent WPElement of matched element', () => { + it( 'should return HTML equivalent React Element of matched element', () => { // Assumption here is that we can cleanly convert back and forth - // between a string and WPElement representation. + // between a string and React Element representation. const html = '

A delicious sundae dessert

'; const match = parse( html, sources.children() ); @@ -42,9 +42,9 @@ describe( 'matchers', () => { expect( typeof source ).toBe( 'function' ); } ); - it( 'should return HTML equivalent WPElement of matched element', () => { + it( 'should return HTML equivalent React Element of matched element', () => { // Assumption here is that we can cleanly convert back and forth - // between a string and WPElement representation. + // between a string and React Element representation. const html = '

A delicious sundae dessert

'; const match = parse( html, sources.node() ); diff --git a/packages/blocks/src/deprecated.js b/packages/blocks/src/deprecated.js index ec8a5b7bddb3c8..b3d01d1167bf51 100644 --- a/packages/blocks/src/deprecated.js +++ b/packages/blocks/src/deprecated.js @@ -9,8 +9,8 @@ import deprecated from '@wordpress/deprecated'; * * @deprecated * - * @param {WPComponent} OriginalComponent The component to enhance. - * @return {WPComponent} The same component. + * @param {Component} OriginalComponent The component to enhance. + * @return {Component} The same component. */ export function withBlockContentContext( OriginalComponent ) { deprecated( 'wp.blocks.withBlockContentContext', { diff --git a/packages/components/src/alignment-matrix-control/README.md b/packages/components/src/alignment-matrix-control/README.md index 576fe77c1f25a4..d087a177d8d414 100644 --- a/packages/components/src/alignment-matrix-control/README.md +++ b/packages/components/src/alignment-matrix-control/README.md @@ -9,8 +9,8 @@ AlignmentMatrixControl components enable adjustments to horizontal and vertical ## Usage ```jsx +import { useState } from 'react'; import { __experimentalAlignmentMatrixControl as AlignmentMatrixControl } from '@wordpress/components'; -import { useState } from '@wordpress/element'; const Example = () => { const [ alignment, setAlignment ] = useState( 'center center' ); diff --git a/packages/components/src/angle-picker-control/README.md b/packages/components/src/angle-picker-control/README.md index c91a24272e0f7c..3cbc1f6c8d9e1a 100644 --- a/packages/components/src/angle-picker-control/README.md +++ b/packages/components/src/angle-picker-control/README.md @@ -6,7 +6,7 @@ Users can choose an angle in a visual UI with the mouse by dragging an angle ind ## Usage ```jsx -import { useState } from '@wordpress/element'; +import { useState } from 'react'; import { AnglePickerControl } from '@wordpress/components'; function Example() { diff --git a/packages/components/src/autocomplete/types.ts b/packages/components/src/autocomplete/types.ts index cd0e5029580ba8..ebe69648fc7e96 100644 --- a/packages/components/src/autocomplete/types.ts +++ b/packages/components/src/autocomplete/types.ts @@ -1,7 +1,11 @@ +/** + * External dependencies + */ +import type { ReactElement } from 'react'; + /** * WordPress dependencies */ -import type { WPElement } from '@wordpress/element'; import type { RichTextValue } from '@wordpress/rich-text'; /** @@ -20,7 +24,7 @@ export type ReplaceOption = { action: 'replace'; value: RichTextValue }; export type OptionCompletion = React.ReactNode | InsertOption | ReplaceOption; -type OptionLabel = string | WPElement | Array< string | WPElement >; +type OptionLabel = string | ReactElement | Array< string | ReactElement >; export type KeyedOption = { key: string; value: any; diff --git a/packages/components/src/border-box-control/border-box-control/README.md b/packages/components/src/border-box-control/border-box-control/README.md index 4efe365cb50b7b..20352e03c8243d 100644 --- a/packages/components/src/border-box-control/border-box-control/README.md +++ b/packages/components/src/border-box-control/border-box-control/README.md @@ -27,9 +27,9 @@ show "Mixed" placeholder text. ## Usage ```jsx +import { useState } from 'react'; import { __experimentalBorderBoxControl as BorderBoxControl } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; -import { useState } from '@wordpress/element'; const colors = [ { name: 'Blue 20', color: '#72aee6' }, diff --git a/packages/components/src/border-control/border-control/README.md b/packages/components/src/border-control/border-control/README.md index 55c860720f2394..51fb7172b7c553 100644 --- a/packages/components/src/border-control/border-control/README.md +++ b/packages/components/src/border-control/border-control/README.md @@ -20,9 +20,9 @@ a "shape" abstraction. ## Usage ```jsx +import { useState } from 'react'; import { __experimentalBorderControl as BorderControl } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; -import { useState } from '@wordpress/element'; const colors = [ { name: 'Blue 20', color: '#72aee6' }, diff --git a/packages/components/src/box-control/README.md b/packages/components/src/box-control/README.md index 83ccd50a6f1ffc..2fd214b79157f7 100644 --- a/packages/components/src/box-control/README.md +++ b/packages/components/src/box-control/README.md @@ -9,8 +9,8 @@ BoxControl components let users set values for Top, Right, Bottom, and Left. Thi ## Usage ```jsx +import { useState } from 'react'; import { __experimentalBoxControl as BoxControl } from '@wordpress/components'; -import { useState } from '@wordpress/element'; const Example = () => { const [ values, setValues ] = useState( { diff --git a/packages/components/src/checkbox-control/README.md b/packages/components/src/checkbox-control/README.md index 4bc19ed9bfe5f0..12f792ea8577bf 100644 --- a/packages/components/src/checkbox-control/README.md +++ b/packages/components/src/checkbox-control/README.md @@ -56,8 +56,8 @@ If only a few child checkboxes are checked, the parent checkbox becomes a mixed Render an is author checkbox: ```jsx +import { useState } from 'react'; import { CheckboxControl } from '@wordpress/components'; -import { useState } from '@wordpress/element'; const MyCheckboxControl = () => { const [ isChecked, setChecked ] = useState( true ); @@ -85,7 +85,7 @@ If no prop is passed an empty label is rendered. - Required: No -#### `help`: `string|WPElement` +#### `help`: `string|Element` If this property is added, a help text will be generated using help property as the content. diff --git a/packages/components/src/circular-option-picker/README.md b/packages/components/src/circular-option-picker/README.md index a7595daa349cd7..1dc230686cae17 100644 --- a/packages/components/src/circular-option-picker/README.md +++ b/packages/components/src/circular-option-picker/README.md @@ -9,8 +9,8 @@ This component is not exported, and therefore can only be used internally to the ## Usage ```jsx +import { useState } from 'react'; import { CircularOptionPicker } from '../circular-option-picker'; -import { useState } from '@wordpress/element'; const Example = () => { const [ currentColor, setCurrentColor ] = useState(); diff --git a/packages/components/src/clipboard-button/README.md b/packages/components/src/clipboard-button/README.md index 0f1bbdf44b99db..94bd50b0476a58 100644 --- a/packages/components/src/clipboard-button/README.md +++ b/packages/components/src/clipboard-button/README.md @@ -11,8 +11,8 @@ With a clipboard button, users copy text (or other elements) with a single click ## Usage ```jsx +import { useState } from 'react'; import { ClipboardButton } from '@wordpress/components'; -import { useState } from '@wordpress/element'; const MyClipboardButton = () => { const [ hasCopied, setHasCopied ] = useState( false ); diff --git a/packages/components/src/color-palette/README.md b/packages/components/src/color-palette/README.md index 7b13b3905dd4ae..0fbfbd4d710013 100644 --- a/packages/components/src/color-palette/README.md +++ b/packages/components/src/color-palette/README.md @@ -5,8 +5,8 @@ ## Usage ```jsx +import { useState } from 'react'; import { ColorPalette } from '@wordpress/components'; -import { useState } from '@wordpress/element'; const MyColorPalette = () => { const [ color, setColor ] = useState ( '#f00' ) diff --git a/packages/components/src/color-picker/README.md b/packages/components/src/color-picker/README.md index 91656ca32851a9..ed6ab104cd26ab 100644 --- a/packages/components/src/color-picker/README.md +++ b/packages/components/src/color-picker/README.md @@ -5,8 +5,8 @@ ## Usage ```jsx +import { useState } from 'react'; import { ColorPicker } from '@wordpress/components'; -import { useState } from '@wordpress/element'; function Example() { const [color, setColor] = useState(); diff --git a/packages/components/src/combobox-control/README.md b/packages/components/src/combobox-control/README.md index 86b760e694a9aa..30f1f47e653e87 100644 --- a/packages/components/src/combobox-control/README.md +++ b/packages/components/src/combobox-control/README.md @@ -17,8 +17,8 @@ These are the same as [the ones for `SelectControl`s](/packages/components/src/s ### Usage ```jsx +import { useState } from 'react'; import { ComboboxControl } from '@wordpress/components'; -import { useState } from '@wordpress/element'; const options = [ { diff --git a/packages/components/src/confirm-dialog/README.md b/packages/components/src/confirm-dialog/README.md index 9274a8fa2eaea1..86d38bccdec3c6 100644 --- a/packages/components/src/confirm-dialog/README.md +++ b/packages/components/src/confirm-dialog/README.md @@ -43,8 +43,8 @@ Let the parent component control when the dialog is open/closed. It's activated - You'll want to update the state that controls `isOpen` by updating it from the `onCancel` and `onConfirm` callbacks. ```jsx +import { useState } from 'react'; import { __experimentalConfirmDialog as ConfirmDialog } from '@wordpress/components'; -import { useState } from '@wordpress/element'; function Example() { const [ isOpen, setIsOpen ] = useState( true ); diff --git a/packages/components/src/custom-select-control/README.md b/packages/components/src/custom-select-control/README.md index 3f93291c34dde4..696fca338e465c 100644 --- a/packages/components/src/custom-select-control/README.md +++ b/packages/components/src/custom-select-control/README.md @@ -17,11 +17,8 @@ These are the same as [the ones for `SelectControl`s](/packages/components/src/s ### Usage ```jsx -/** - * WordPress dependencies - */ +import { useState } from 'react'; import { CustomSelectControl } from '@wordpress/components'; -import { useState } from '@wordpress/element'; const options = [ { diff --git a/packages/components/src/date-time/README.md b/packages/components/src/date-time/README.md index c65cf6d3a1aaea..3d6b0e7761d6a6 100644 --- a/packages/components/src/date-time/README.md +++ b/packages/components/src/date-time/README.md @@ -15,8 +15,8 @@ Date pickers should: Render a DateTimePicker. ```jsx +import { useState } from 'react'; import { DateTimePicker } from '@wordpress/components'; -import { useState } from '@wordpress/element'; const MyDateTimePicker = () => { const [ date, setDate ] = useState( new Date() ); diff --git a/packages/components/src/dimension-control/README.md b/packages/components/src/dimension-control/README.md index 0dea7ed40e13b8..498322931b7ab6 100644 --- a/packages/components/src/dimension-control/README.md +++ b/packages/components/src/dimension-control/README.md @@ -9,8 +9,8 @@ This feature is still experimental. “Experimental” means this is an early im ## Usage ```jsx +import { useState } from 'react'; import { __experimentalDimensionControl as DimensionControl } from '@wordpress/components'; -import { useState } from '@wordpress/element'; export default function MyCustomDimensionControl() { const [ paddingSize, setPaddingSize ] = useState( '' ); diff --git a/packages/components/src/disabled/README.md b/packages/components/src/disabled/README.md index c36afc2044bd20..918f6b785e3876 100644 --- a/packages/components/src/disabled/README.md +++ b/packages/components/src/disabled/README.md @@ -7,8 +7,8 @@ Disabled is a component which disables descendant tabbable elements and prevents Assuming you have a form component, you can disable all form inputs by wrapping the form with ``. ```jsx +import { useState } from 'react'; import { Button, Disabled, TextControl } from '@wordpress/components'; -import { useState } from '@wordpress/element'; const MyDisabled = () => { const [ isDisabled, setIsDisabled ] = useState( true ); diff --git a/packages/components/src/drop-zone/README.md b/packages/components/src/drop-zone/README.md index b06d278c5d1e5d..e06327ec774361 100644 --- a/packages/components/src/drop-zone/README.md +++ b/packages/components/src/drop-zone/README.md @@ -5,8 +5,8 @@ ## Usage ```jsx +import { useState } from 'react'; import { DropZone } from '@wordpress/components'; -import { useState } from '@wordpress/element'; const MyDropZone = () => { const [ hasDropped, setHasDropped ] = useState( false ); diff --git a/packages/components/src/duotone-picker/README.md b/packages/components/src/duotone-picker/README.md index 4c1b5c13c4be10..550cf5774b2a76 100644 --- a/packages/components/src/duotone-picker/README.md +++ b/packages/components/src/duotone-picker/README.md @@ -3,8 +3,8 @@ ## Usage ```jsx +import { useState } from 'react'; import { DuotonePicker, DuotoneSwatch } from '@wordpress/components'; -import { useState } from '@wordpress/element'; const DUOTONE_PALETTE = [ { colors: [ '#8c00b7', '#fcff41' ], name: 'Purple and yellow', slug: 'purple-yellow' }, diff --git a/packages/components/src/focal-point-picker/README.md b/packages/components/src/focal-point-picker/README.md index 4d8c1324328766..9abb147831409a 100644 --- a/packages/components/src/focal-point-picker/README.md +++ b/packages/components/src/focal-point-picker/README.md @@ -8,8 +8,8 @@ Focal Point Picker is a component which creates a UI for identifying the most im ## Usage ```jsx +import { useState } from 'react'; import { FocalPointPicker } from '@wordpress/components'; -import { useState } from '@wordpress/element'; const Example = () => { const [ focalPoint, setFocalPoint ] = useState( { diff --git a/packages/components/src/focusable-iframe/README.md b/packages/components/src/focusable-iframe/README.md index a7cd2f0b31b5b4..f083cff58cacb8 100644 --- a/packages/components/src/focusable-iframe/README.md +++ b/packages/components/src/focusable-iframe/README.md @@ -32,7 +32,7 @@ Callback to invoke when iframe receives focus. Passes an emulated `FocusEvent` o ### `iframeRef` -- Type: `wp.element.Ref` +- Type: `React.Ref` - Required: No -If a reference to the underlying DOM element is needed, pass `iframeRef` as the result of a `wp.element.createRef` called from your component. +If a reference to the underlying DOM element is needed, pass `iframeRef` as the result of a `React.createRef` called from your component. diff --git a/packages/components/src/font-size-picker/README.md b/packages/components/src/font-size-picker/README.md index 3eee5683407075..56391ad0c7c33f 100644 --- a/packages/components/src/font-size-picker/README.md +++ b/packages/components/src/font-size-picker/README.md @@ -6,8 +6,8 @@ The component renders a user interface that allows the user to select predefined ## Usage ```jsx +import { useState } from 'react'; import { FontSizePicker } from '@wordpress/components'; -import { useState } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; const fontSizes = [ diff --git a/packages/components/src/form-file-upload/README.md b/packages/components/src/form-file-upload/README.md index 38dd50dd039155..f4dc4d1ef5a023 100644 --- a/packages/components/src/form-file-upload/README.md +++ b/packages/components/src/form-file-upload/README.md @@ -38,9 +38,9 @@ Children are passed as children of `Button`. ### icon -The icon to render. Supported values are: Dashicons (specified as strings), functions, WPComponent instances and `null`. +The icon to render. Supported values are: Dashicons (specified as strings), functions, Component instances and `null`. -- Type: `String|Function|WPComponent|null` +- Type: `String|Function|Component|null` - Required: No - Default: `null` diff --git a/packages/components/src/form-toggle/README.md b/packages/components/src/form-toggle/README.md index 941e431654e50b..5d385e23f7bdec 100644 --- a/packages/components/src/form-toggle/README.md +++ b/packages/components/src/form-toggle/README.md @@ -54,8 +54,8 @@ When a user switches a toggle, its corresponding action takes effect immediately ### Usage ```jsx +import { useState } from 'react'; import { FormToggle } from '@wordpress/components'; -import { useState } from '@wordpress/element'; const MyFormToggle = () => { const [ isChecked, setChecked ] = useState( true ); diff --git a/packages/components/src/form-token-field/README.md b/packages/components/src/form-token-field/README.md index 3a4ce2a143624a..41083789f1340f 100644 --- a/packages/components/src/form-token-field/README.md +++ b/packages/components/src/form-token-field/README.md @@ -67,8 +67,8 @@ The `value` property is handled in a manner similar to controlled form component ## Usage ```jsx +import { useState } from 'react'; import { FormTokenField } from '@wordpress/components'; -import { useState } from '@wordpress/element'; const continents = [ 'Africa', diff --git a/packages/components/src/gradient-picker/README.md b/packages/components/src/gradient-picker/README.md index 6d7a482df82820..c092c8b5673cc9 100644 --- a/packages/components/src/gradient-picker/README.md +++ b/packages/components/src/gradient-picker/README.md @@ -9,8 +9,8 @@ GradientPicker is a React component that renders a color gradient picker to defi Render a GradientPicker. ```jsx +import { useState } from 'react'; import { GradientPicker } from '@wordpress/components'; -import { useState } from '@wordpress/element'; const myGradientPicker = () => { const [ gradient, setGradient ] = useState( null ); diff --git a/packages/components/src/higher-order/with-constrained-tabbing/README.md b/packages/components/src/higher-order/with-constrained-tabbing/README.md index e6ef44b061e3c7..47cb8a033dfbdd 100644 --- a/packages/components/src/higher-order/with-constrained-tabbing/README.md +++ b/packages/components/src/higher-order/with-constrained-tabbing/README.md @@ -7,12 +7,12 @@ Wrap your original component with `withConstrainedTabbing`. ```jsx +import { useState } from 'react'; import { withConstrainedTabbing, TextControl, Button, } from '@wordpress/components'; -import { useState } from '@wordpress/element'; const ConstrainedTabbing = withConstrainedTabbing( ( { children } ) => children diff --git a/packages/components/src/higher-order/with-focus-return/README.md b/packages/components/src/higher-order/with-focus-return/README.md index b038e090390040..b99d76bc6f1c9a 100644 --- a/packages/components/src/higher-order/with-focus-return/README.md +++ b/packages/components/src/higher-order/with-focus-return/README.md @@ -7,8 +7,8 @@ ### `withFocusReturn` ```jsx +import { useState } from 'react'; import { withFocusReturn, TextControl, Button } from '@wordpress/components'; -import { useState } from '@wordpress/element'; const EnhancedComponent = withFocusReturn( () => (
diff --git a/packages/components/src/higher-order/with-focus-return/index.tsx b/packages/components/src/higher-order/with-focus-return/index.tsx index 2596617ad382d2..196226def624c1 100644 --- a/packages/components/src/higher-order/with-focus-return/index.tsx +++ b/packages/components/src/higher-order/with-focus-return/index.tsx @@ -36,7 +36,7 @@ type Props = { */ export default createHigherOrderComponent( // @ts-expect-error TODO: Reconcile with intended `createHigherOrderComponent` types - ( options: WPComponent | Record< string, unknown > ) => { + ( options: React.ComponentType | Record< string, unknown > ) => { const HoC = ( { onFocusReturn }: Props = {} ) => ( WrappedComponent: React.ComponentType ) => { diff --git a/packages/components/src/higher-order/with-spoken-messages/index.tsx b/packages/components/src/higher-order/with-spoken-messages/index.tsx index b987d44c4be315..5e0d52c81ad438 100644 --- a/packages/components/src/higher-order/with-spoken-messages/index.tsx +++ b/packages/components/src/higher-order/with-spoken-messages/index.tsx @@ -4,7 +4,7 @@ import { createHigherOrderComponent, useDebounce } from '@wordpress/compose'; import { speak } from '@wordpress/a11y'; -/** @typedef {import('@wordpress/element').WPComponent} WPComponent */ +/** @typedef {import('react').ComponentType} ComponentType */ /** * A Higher Order Component used to be provide speak and debounced speak @@ -12,9 +12,9 @@ import { speak } from '@wordpress/a11y'; * * @see https://developer.wordpress.org/block-editor/packages/packages-a11y/#speak * - * @param {WPComponent} Component The component to be wrapped. + * @param {ComponentType} Component The component to be wrapped. * - * @return {WPComponent} The wrapped component. + * @return {ComponentType} The wrapped component. */ export default createHigherOrderComponent( ( Component ) => ( props ) => ( diff --git a/packages/components/src/icon/README.md b/packages/components/src/icon/README.md index 4566ed9831a5df..5e78f029f169f7 100644 --- a/packages/components/src/icon/README.md +++ b/packages/components/src/icon/README.md @@ -67,9 +67,9 @@ The component accepts the following props. Any additional props are passed throu ### icon -The icon to render. Supported values are: Dashicons (specified as strings), functions, WPComponent instances and `null`. +The icon to render. Supported values are: Dashicons (specified as strings), functions, Component instances and `null`. -- Type: `String|Function|WPComponent|null` +- Type: `String|Function|Component|null` - Required: No - Default: `null` diff --git a/packages/components/src/keyboard-shortcuts/README.md b/packages/components/src/keyboard-shortcuts/README.md index 081e5519582595..9e7d8d51c0cc23 100644 --- a/packages/components/src/keyboard-shortcuts/README.md +++ b/packages/components/src/keyboard-shortcuts/README.md @@ -11,8 +11,8 @@ It uses the [Mousetrap](https://craig.is/killing/mice) library to implement keyb Render `` with a `shortcuts` prop object: ```jsx +import { useState } from 'react'; import { KeyboardShortcuts } from '@wordpress/components'; -import { useState } from '@wordpress/element'; const MyKeyboardShortcuts = () => { const [ isAllSelected, setIsAllSelected ] = useState( false ); diff --git a/packages/components/src/menu-item/README.md b/packages/components/src/menu-item/README.md index a13d8dbd5eabed..9a0f97e97ac890 100644 --- a/packages/components/src/menu-item/README.md +++ b/packages/components/src/menu-item/README.md @@ -5,8 +5,8 @@ MenuItem is a component which renders a button intended to be used in combinatio ## Usage ```jsx +import { useState } from 'react'; import { MenuItem } from '@wordpress/components'; -import { useState } from '@wordpress/element'; const MyMenuItem = () => { const [ isActive, setIsActive ] = useState( true ); @@ -29,7 +29,7 @@ MenuItem supports the following props. Any additional props are passed through t ### `children` -- Type: `WPElement` +- Type: `Element` - Required: No Element to render as child of button. @@ -89,7 +89,7 @@ If shortcut is a string, it is expecting the display text. If shortcut is an obj ### `suffix` -- Type: `WPElement` +- Type: `Element` - Required: No Allows for markup other than icons or shortcuts to be added to the menu item. diff --git a/packages/components/src/menu-items-choice/README.md b/packages/components/src/menu-items-choice/README.md index b5527c3bc33e3a..7aa12bbbb74ff9 100644 --- a/packages/components/src/menu-items-choice/README.md +++ b/packages/components/src/menu-items-choice/README.md @@ -54,8 +54,8 @@ Designs with a `MenuItemsChoice` option selected by default make a strong sugges ### Usage ```jsx +import { useState } from 'react'; import { MenuGroup, MenuItemsChoice } from '@wordpress/components'; -import { useState } from '@wordpress/element'; const MyMenuItemsChoice = () => { const [ mode, setMode ] = useState( 'visual' ); diff --git a/packages/components/src/mobile/bottom-sheet/sub-sheet/README.md b/packages/components/src/mobile/bottom-sheet/sub-sheet/README.md index 1e60bb74ac5347..4953f294d40970 100644 --- a/packages/components/src/mobile/bottom-sheet/sub-sheet/README.md +++ b/packages/components/src/mobile/bottom-sheet/sub-sheet/README.md @@ -8,13 +8,13 @@ BottomSheetSubSheet allows for adding controls inside the React Native bottom sh /** * External dependencies */ +import { useState } from 'react'; import { SafeAreaView, View } from 'react-native'; import { useNavigation } from '@react-navigation/native'; /** * WordPress dependencies */ -import { useState } from '@wordpress/element'; import { Icon, chevronRight } from '@wordpress/icons'; import { BottomSheet } from '@wordpress/components'; diff --git a/packages/components/src/mobile/keyboard-aware-flat-list/index.ios.js b/packages/components/src/mobile/keyboard-aware-flat-list/index.ios.js index 8b233612763814..8dc58008a3600d 100644 --- a/packages/components/src/mobile/keyboard-aware-flat-list/index.ios.js +++ b/packages/components/src/mobile/keyboard-aware-flat-list/index.ios.js @@ -36,7 +36,7 @@ const AnimatedScrollView = Animated.createAnimatedComponent( ScrollView ); * @param {Object} props.scrollViewStyle Additional style for the ScrollView component. * @param {boolean} props.shouldPreventAutomaticScroll Whether to prevent scrolling when there's a Keyboard offset set. * @param {Object} props... Other props to pass to the FlatList component. - * @return {WPComponent} KeyboardAwareFlatList component. + * @return {Component} KeyboardAwareFlatList component. */ export const KeyboardAwareFlatList = ( { extraScrollHeight, diff --git a/packages/components/src/modal/README.md b/packages/components/src/modal/README.md index 6420d07ee15b88..a2165afde9d5ca 100644 --- a/packages/components/src/modal/README.md +++ b/packages/components/src/modal/README.md @@ -120,8 +120,8 @@ The modal is used to create an accessible modal over an application. The following example shows you how to properly implement a modal. For the modal to properly work it's important you implement the close logic for the modal properly. ```jsx +import { useState } from 'react'; import { Button, Modal } from '@wordpress/components'; -import { useState } from '@wordpress/element'; const MyModal = () => { const [ isOpen, setOpen ] = useState( false ); diff --git a/packages/components/src/placeholder/README.md b/packages/components/src/placeholder/README.md index f260ab15378f0f..a23fcac0e066ef 100644 --- a/packages/components/src/placeholder/README.md +++ b/packages/components/src/placeholder/README.md @@ -17,7 +17,7 @@ Class to set on the container div. - Required: No -### `icon`: `string|Function|WPComponent|null` +### `icon`: `string|Function|Component|null` If provided, renders an icon next to the label. diff --git a/packages/components/src/popover/README.md b/packages/components/src/popover/README.md index 709254672be8b2..32648aa67edf76 100644 --- a/packages/components/src/popover/README.md +++ b/packages/components/src/popover/README.md @@ -11,8 +11,8 @@ Render a Popover adjacent to its container. If a Popover is returned by your component, it will be shown. To hide the popover, simply omit it from your component's render value. ```jsx +import { useState } from 'react'; import { Button, Popover } from '@wordpress/components'; -import { useState } from '@wordpress/element'; const MyPopover = () => { const [ isVisible, setIsVisible ] = useState( false ); @@ -32,8 +32,8 @@ const MyPopover = () => { In order to pass an explicit anchor, you can use the `anchor` prop. When doing so, **the anchor element should be stored in local state** rather than a plain React ref to ensure reactive updating when it changes. ```jsx +import { useState } from 'react'; import { Button, Popover } from '@wordpress/components'; -import { useState } from '@wordpress/element'; const MyPopover = () => { // Use internal state instead of a ref to make sure that the component @@ -63,18 +63,17 @@ const MyPopover = () => { By default Popovers render at the end of the body of your document. If you want Popover elements to render to a specific location on the page, you must render a `Popover.Slot` further up the element tree: ```jsx -import { render } from '@wordpress/element'; +import { createRoot } from 'react-dom/client'; import { Popover } from '@wordpress/components'; import Content from './Content'; const app = document.getElementById( 'app' ); - -render( +const root = createRoot( app ); +root.render(
-
, - app +
); ``` diff --git a/packages/components/src/query-controls/README.md b/packages/components/src/query-controls/README.md index 6eea31e2af1a07..83cae88952d407 100644 --- a/packages/components/src/query-controls/README.md +++ b/packages/components/src/query-controls/README.md @@ -5,8 +5,8 @@ ### Usage ```jsx +import { useState } from 'react'; import { QueryControls } from '@wordpress/components'; -import { useState } from '@wordpress/element'; const QUERY_DEFAULTS = { category: 1, diff --git a/packages/components/src/radio-control/README.md b/packages/components/src/radio-control/README.md index 28708f6dbb387f..e9be7b3c669da6 100644 --- a/packages/components/src/radio-control/README.md +++ b/packages/components/src/radio-control/README.md @@ -58,7 +58,7 @@ Render a user interface to select the user type using radio inputs. ```jsx import { RadioControl } from '@wordpress/components'; -import { useState } from '@wordpress/element'; +import { useState } from 'react'; const MyRadioControl = () => { const [ option, setOption ] = useState( 'a' ); @@ -82,7 +82,7 @@ const MyRadioControl = () => { The component accepts the following props: -#### `help`: `string | WPElement` +#### `help`: `string | Element` If this property is added, a help text will be generated using help property as the content. diff --git a/packages/components/src/radio-group/README.md b/packages/components/src/radio-group/README.md index 239205ec428f75..c285e1a5d27731 100644 --- a/packages/components/src/radio-group/README.md +++ b/packages/components/src/radio-group/README.md @@ -53,11 +53,11 @@ Radio groups that cannot be selected can either be given a disabled state, or be #### Controlled ```jsx +import { useState } from 'react'; import { __experimentalRadio as Radio, __experimentalRadioGroup as RadioGroup, } from '@wordpress/components'; -import { useState } from '@wordpress/element'; const MyControlledRadioRadioGroup = () => { const [ checked, setChecked ] = useState( '25' ); @@ -77,11 +77,11 @@ const MyControlledRadioRadioGroup = () => { When using the RadioGroup component as an uncontrolled component, the default value can be set with the `defaultChecked` prop. ```jsx +import { useState } from 'react'; import { __experimentalRadio as Radio, __experimentalRadioGroup as RadioGroup, } from '@wordpress/components'; -import { useState } from '@wordpress/element'; const MyUncontrolledRadioRadioGroup = () => { return ( diff --git a/packages/components/src/range-control/README.md b/packages/components/src/range-control/README.md index 2a8f7ae7a05ab1..0dd822200a7bf5 100644 --- a/packages/components/src/range-control/README.md +++ b/packages/components/src/range-control/README.md @@ -90,8 +90,8 @@ RangeControls should provide the full range of choices available for the user to Render a RangeControl to make a selection from a range of incremental values. ```jsx +import { useState } from 'react'; import { RangeControl } from '@wordpress/components'; -import { useState } from '@wordpress/element'; const MyRangeControl = () => { const [ columns, setColumns ] = useState( 2 ); @@ -113,7 +113,7 @@ const MyRangeControl = () => { The set of props accepted by the component will be specified below. Props not included in this set will be applied to the input elements. -### `afterIcon`: `string|Function|WPComponent|null` +### `afterIcon`: `string|Function|Component|null` If this property is added, an [Icon component](/packages/components/src/icon/README.md) will be rendered after the slider with the icon equal to `afterIcon`. @@ -130,7 +130,7 @@ If this property is true, a button to reset the slider is rendered. - Default: `false` - Platform: Web | Mobile -### `beforeIcon`: `string|Function|WPComponent|null` +### `beforeIcon`: `string|Function|Component|null` If this property is added, an [Icon component](/packages/components/src/icon/README.md) will be rendered before the slider with the icon equal to `beforeIcon`. @@ -161,7 +161,7 @@ Disables the `input`, preventing new values from being applied. - Platform: Web -### `help`: `string|WPElement` +### `help`: `string|Element` If this property is added, a help text will be generated using help property as the content. diff --git a/packages/components/src/scroll-lock/README.md b/packages/components/src/scroll-lock/README.md index 33c5948ac0367e..4b8542966c3660 100644 --- a/packages/components/src/scroll-lock/README.md +++ b/packages/components/src/scroll-lock/README.md @@ -7,8 +7,8 @@ ScrollLock is a content-free React component for declaratively preventing scroll Declare scroll locking as part of modal UI. ```jsx +import { useState } from 'react'; import { ScrollLock, Button } from '@wordpress/components'; -import { useState } from '@wordpress/element'; const MyScrollLock = () => { const [ isScrollLocked, setIsScrollLocked ] = useState( false ); diff --git a/packages/components/src/search-control/README.md b/packages/components/src/search-control/README.md index 31c6c21e5222a6..bd12580f3c8780 100644 --- a/packages/components/src/search-control/README.md +++ b/packages/components/src/search-control/README.md @@ -15,9 +15,9 @@ SearchControl components let users display a search control. Render a user interface to input the name of an additional css class. ```jsx +import { useState } from 'react'; import { __ } from '@wordpress/i18n'; import { SearchControl } from '@wordpress/components'; -import { useState } from '@wordpress/element'; function MySearchControl( { className, setState } ) { const [ searchInput, setSearchInput ] = useState( '' ); @@ -80,7 +80,7 @@ A function that receives the value of the input. If this property is added, a help text will be generated using help property as the content. -- Type: `String|WPElement` +- Type: `String|Element` - Required: No ### hideLabelFromVision diff --git a/packages/components/src/select-control/README.md b/packages/components/src/select-control/README.md index dc6e884a5e12be..e113c7cf01620d 100644 --- a/packages/components/src/select-control/README.md +++ b/packages/components/src/select-control/README.md @@ -82,8 +82,8 @@ Use sentences in your menu. Render a user interface to select the size of an image. ```jsx +import { useState } from 'react'; import { SelectControl } from '@wordpress/components'; -import { useState } from '@wordpress/element'; const MySelectControl = () => { const [ size, setSize ] = useState( '50%' ); @@ -182,7 +182,7 @@ If true, the label will only be visible to screen readers. If this property is added, a help text will be generated using help property as the content. -- Type: `String|WPElement` +- Type: `String|Element` - Required: No #### multiple diff --git a/packages/components/src/text-control/README.md b/packages/components/src/text-control/README.md index 11834ddefbd21e..6dfdb9ab6545da 100644 --- a/packages/components/src/text-control/README.md +++ b/packages/components/src/text-control/README.md @@ -60,8 +60,8 @@ Don’t use unclear visual markers to indicate a text field. Render a user interface to input the name of an additional css class. ```js +import { useState } from 'react'; import { TextControl } from '@wordpress/components'; -import { useState } from '@wordpress/element'; const MyTextControl = () => { const [ className, setClassName ] = useState( '' ); diff --git a/packages/components/src/textarea-control/README.md b/packages/components/src/textarea-control/README.md index 1da2617ef60b5b..2b9a5a1f70e7e7 100644 --- a/packages/components/src/textarea-control/README.md +++ b/packages/components/src/textarea-control/README.md @@ -77,8 +77,8 @@ When text input isn’t accepted, an error message can display instructions on h ### Usage ```jsx +import { useState } from 'react'; import { TextareaControl } from '@wordpress/components'; -import { useState } from '@wordpress/element'; const MyTextareaControl = () => { const [ text, setText ] = useState( '' ); @@ -100,7 +100,7 @@ The set of props accepted by the component will be specified below. Props not included in this set will be applied to the textarea element. -#### `help`: `string | WPElement` +#### `help`: `string | Element` If this property is added, a help text will be generated using help property as the content. diff --git a/packages/components/src/toggle-control/README.md b/packages/components/src/toggle-control/README.md index d22c99a414d165..5e2732fb07416f 100644 --- a/packages/components/src/toggle-control/README.md +++ b/packages/components/src/toggle-control/README.md @@ -7,8 +7,8 @@ ToggleControl is used to generate a toggle user interface. Render a user interface to change fixed background setting. ```jsx +import { useState } from 'react'; import { ToggleControl } from '@wordpress/components'; -import { useState } from '@wordpress/element'; const MyToggleControl = () => { const [ hasFixedBackground, setHasFixedBackground ] = useState( false ); @@ -47,7 +47,7 @@ If this property is added, a help text will be generated using help property as For controlled components the `help` prop can also be a function which will return a help text dynamically depending on the boolean `checked` parameter. -- Type: `String|WPElement|Function` +- Type: `String|Element|Function` - Required: No ### checked diff --git a/packages/components/src/toggle-group-control/toggle-group-control-option-icon/README.md b/packages/components/src/toggle-group-control/toggle-group-control-option-icon/README.md index ad25c21a8ae03c..d82700ae21b1f5 100644 --- a/packages/components/src/toggle-group-control/toggle-group-control-option-icon/README.md +++ b/packages/components/src/toggle-group-control/toggle-group-control-option-icon/README.md @@ -41,7 +41,7 @@ The value of the `ToggleGroupControlOption`. - Required: Yes -### `icon`: `WPComponent` +### `icon`: `Component` Icon displayed as the content of the option. Usually one of the icons from the `@wordpress/icons` package, or a custom React `` icon. diff --git a/packages/components/src/tree-select/README.md b/packages/components/src/tree-select/README.md index 3306dfb0b71316..753e7bd6d052db 100644 --- a/packages/components/src/tree-select/README.md +++ b/packages/components/src/tree-select/README.md @@ -7,8 +7,8 @@ TreeSelect component is used to generate select input fields. Render a user interface to select the parent page in a hierarchy of pages: ```jsx +import { useState } from 'react'; import { TreeSelect } from '@wordpress/components'; -import { useState } from '@wordpress/element'; const MyTreeSelect = () => { const [ page, setPage ] = useState( 'p21' ); diff --git a/packages/components/src/unit-control/README.md b/packages/components/src/unit-control/README.md index 8fab32611f3bf6..b3c0496f86b800 100644 --- a/packages/components/src/unit-control/README.md +++ b/packages/components/src/unit-control/README.md @@ -9,8 +9,8 @@ This feature is still experimental. “Experimental” means this is an early im ## Usage ```jsx +import { useState } from 'react'; import { __experimentalUnitControl as UnitControl } from '@wordpress/components'; -import { useState } from '@wordpress/element'; const Example = () => { const [ value, setValue ] = useState( '10px' ); @@ -115,8 +115,8 @@ Collection of available units. Example: ```jsx +import { useState } from 'react'; import { __experimentalUnitControl as UnitControl } from '@wordpress/components'; -import { useState } from '@wordpress/element'; const Example = () => { const [ value, setValue ] = useState( '10px' ); diff --git a/packages/compose/src/hooks/use-dragging/README.md b/packages/compose/src/hooks/use-dragging/README.md index d90758ff576693..c941adb8cd5474 100644 --- a/packages/compose/src/hooks/use-dragging/README.md +++ b/packages/compose/src/hooks/use-dragging/README.md @@ -57,7 +57,7 @@ The following example allows us to drag & drop a red square around the entire vi /** * WordPress dependencies */ -import { useState, useCallback } from '@wordpress/element'; +import { useState, useCallback } from 'react'; import { __experimentalUseDragging as useDragging } from '@wordpress/compose'; const UseDraggingExample = () => { diff --git a/packages/compose/src/hooks/use-drop-zone/README.md b/packages/compose/src/hooks/use-drop-zone/README.md index 558a5f6866b54e..7f6f1febc1bb7b 100644 --- a/packages/compose/src/hooks/use-drop-zone/README.md +++ b/packages/compose/src/hooks/use-drop-zone/README.md @@ -7,8 +7,8 @@ When using a `dropZoneElement`, it is expected that the `ref` will be attached t ## Usage ```js +import { useState } from 'react'; import { useDropZone } from '@wordpress/compose'; -import { useState } from '@wordpress/element'; const WithWrapperDropZoneElement = () => { const [ dropZoneElement, setDropZoneElement ] = useState( null ); diff --git a/packages/compose/src/hooks/use-previous/README.md b/packages/compose/src/hooks/use-previous/README.md index a22dfb69b96e3e..5eeaad52d53279 100644 --- a/packages/compose/src/hooks/use-previous/README.md +++ b/packages/compose/src/hooks/use-previous/README.md @@ -8,8 +8,8 @@ Sometimes you need to get the value something had on the previous render. `usePr /** * WordPress dependencies */ +import { useEffect, useState } from 'react'; import { usePrevious } from '@wordpress/compose'; -import { useEffect, useState } from '@wordpress/element'; function MyCustomElement() { const [ myNumber, setMyNumber ] = useState( 5 ); diff --git a/packages/compose/src/hooks/use-resize-observer/index.tsx b/packages/compose/src/hooks/use-resize-observer/index.tsx index b2ff87f2c025f7..21fcd0bff4f4d0 100644 --- a/packages/compose/src/hooks/use-resize-observer/index.tsx +++ b/packages/compose/src/hooks/use-resize-observer/index.tsx @@ -1,7 +1,7 @@ /** * External dependencies */ -import type { RefCallback, RefObject } from 'react'; +import type { ReactElement, RefCallback, RefObject } from 'react'; /** * WordPress dependencies @@ -13,7 +13,6 @@ import { useEffect, useState, } from '@wordpress/element'; -import type { WPElement } from '@wordpress/element'; type SubscriberCleanup = () => void; type SubscriberResponse = SubscriberCleanup | void; @@ -335,7 +334,7 @@ function useResizeObserver< T extends HTMLElement >( * ``` */ export default function useResizeAware(): [ - WPElement, + ReactElement, { width: number | null; height: number | null }, ] { const { ref, width, height } = useResizeObserver(); diff --git a/packages/core-data/README.md b/packages/core-data/README.md index 6024f4db2f12d4..87233a2c206bf0 100644 --- a/packages/core-data/README.md +++ b/packages/core-data/README.md @@ -782,8 +782,8 @@ application, the page and the resolution details will be retrieved from the store state using `getEntityRecord()`, or resolved if missing. ```js +import { useCallback } from 'react'; import { useDispatch } from '@wordpress/data'; -import { useCallback } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; import { TextControl } from '@wordpress/components'; import { store as noticeStore } from '@wordpress/notices'; diff --git a/packages/core-data/src/hooks/use-entity-record.ts b/packages/core-data/src/hooks/use-entity-record.ts index 7f3630b1dd4ceb..6c755c7bad6a60 100644 --- a/packages/core-data/src/hooks/use-entity-record.ts +++ b/packages/core-data/src/hooks/use-entity-record.ts @@ -89,8 +89,8 @@ export interface Options { * * @example * ```js + * import { useCallback } from 'react'; * import { useDispatch } from '@wordpress/data'; - * import { useCallback } from '@wordpress/element'; * import { __ } from '@wordpress/i18n'; * import { TextControl } from '@wordpress/components'; * import { store as noticeStore } from '@wordpress/notices'; diff --git a/packages/create-block-interactive-template/block-templates/edit.js.mustache b/packages/create-block-interactive-template/block-templates/edit.js.mustache index 1a0aeeac8d6979..b7d273cee07b92 100644 --- a/packages/create-block-interactive-template/block-templates/edit.js.mustache +++ b/packages/create-block-interactive-template/block-templates/edit.js.mustache @@ -23,7 +23,7 @@ import { useBlockProps } from '@wordpress/block-editor'; * @param {Object} props.attributes Available block attributes. * @param {Function} props.setAttributes Function that updates individual attributes. * - * @return {WPElement} Element to render. + * @return {Element} Element to render. */ export default function Edit( { attributes, setAttributes } ) { const blockProps = useBlockProps(); diff --git a/packages/create-block-tutorial-template/block-templates/edit.js.mustache b/packages/create-block-tutorial-template/block-templates/edit.js.mustache index af0cb1629f62f2..fbb6864d869df6 100644 --- a/packages/create-block-tutorial-template/block-templates/edit.js.mustache +++ b/packages/create-block-tutorial-template/block-templates/edit.js.mustache @@ -23,7 +23,7 @@ import { useBlockProps } from '@wordpress/block-editor'; * @param {Object} props.attributes Available block attributes. * @param {Function} props.setAttributes Function that updates individual attributes. * - * @return {WPElement} Element to render. + * @return {Element} Element to render. */ export default function Edit( { attributes, setAttributes } ) { const blockProps = useBlockProps(); diff --git a/packages/create-block-tutorial-template/block-templates/save.js.mustache b/packages/create-block-tutorial-template/block-templates/save.js.mustache index d390552490a579..a11ee432a4d442 100644 --- a/packages/create-block-tutorial-template/block-templates/save.js.mustache +++ b/packages/create-block-tutorial-template/block-templates/save.js.mustache @@ -16,7 +16,7 @@ import { useBlockProps } from '@wordpress/block-editor'; * * @param {Object} props Properties passed to the function. * @param {Object} props.attributes Available block attributes. - * @return {WPElement} Element to render. + * @return {Element} Element to render. */ export default function save( { attributes } ) { const blockProps = useBlockProps.save(); diff --git a/packages/create-block/lib/templates/block/edit.js.mustache b/packages/create-block/lib/templates/block/edit.js.mustache index 89574380a3c2e3..1824892f3e282d 100644 --- a/packages/create-block/lib/templates/block/edit.js.mustache +++ b/packages/create-block/lib/templates/block/edit.js.mustache @@ -27,7 +27,7 @@ import './editor.scss'; * * @see https://developer.wordpress.org/block-editor/reference-guides/block-api/block-edit-save/#edit * - * @return {WPElement} Element to render. + * @return {Element} Element to render. */ export default function Edit() { return ( diff --git a/packages/create-block/lib/templates/block/save.js.mustache b/packages/create-block/lib/templates/block/save.js.mustache index 70452e60a6a4fa..285931becea2a6 100644 --- a/packages/create-block/lib/templates/block/save.js.mustache +++ b/packages/create-block/lib/templates/block/save.js.mustache @@ -14,7 +14,7 @@ import { useBlockProps } from '@wordpress/block-editor'; * * @see https://developer.wordpress.org/block-editor/reference-guides/block-api/block-edit-save/#save * - * @return {WPElement} Element to render. + * @return {Element} Element to render. */ export default function save() { return ( diff --git a/packages/create-block/lib/templates/es5/index.js.mustache b/packages/create-block/lib/templates/es5/index.js.mustache index 9738885ac87421..10370672295cb3 100644 --- a/packages/create-block/lib/templates/es5/index.js.mustache +++ b/packages/create-block/lib/templates/es5/index.js.mustache @@ -39,7 +39,7 @@ * * @see https://developer.wordpress.org/block-editor/reference-guides/block-api/block-edit-save/#edit * - * @return {WPElement} Element to render. + * @return {Element} Element to render. */ edit: function() { return el( @@ -56,7 +56,7 @@ * * @see https://developer.wordpress.org/block-editor/reference-guides/block-api/block-edit-save/#save * - * @return {WPElement} Element to render. + * @return {Element} Element to render. */ save: function() { return el( diff --git a/packages/customize-widgets/src/store/actions.js b/packages/customize-widgets/src/store/actions.js index 844617b4142aa0..8656ef8854c9f5 100644 --- a/packages/customize-widgets/src/store/actions.js +++ b/packages/customize-widgets/src/store/actions.js @@ -10,11 +10,11 @@ * * @example * ```js + * import { useState } from 'react'; * import { store as customizeWidgetsStore } from '@wordpress/customize-widgets'; * import { __ } from '@wordpress/i18n'; * import { useDispatch } from '@wordpress/data'; * import { Button } from '@wordpress/components'; - * import { useState } from '@wordpress/element'; * * const ExampleComponent = () => { * const { setIsInserterOpened } = useDispatch( customizeWidgetsStore ); diff --git a/packages/data/README.md b/packages/data/README.md index 8ee5213f7f66c4..96115e734266ef 100644 --- a/packages/data/README.md +++ b/packages/data/README.md @@ -315,7 +315,7 @@ _Parameters_ _Returns_ -- `WPComponent`: The component to be rendered. +- `Component`: The component to be rendered. ### combineReducers @@ -702,8 +702,8 @@ the server via the `useSelect` hook to use in combination with the dispatch action. ```jsx +import { useCallback } from 'react'; import { useDispatch, useSelect } from '@wordpress/data'; -import { useCallback } from '@wordpress/element'; import { store as myCustomStore } from 'my-custom-store'; function Button( { onClick, children } ) { @@ -939,7 +939,7 @@ _Parameters_ _Returns_ -- `WPComponent`: Enhanced component with merged dispatcher props. +- `ComponentType`: Enhanced component with merged dispatcher props. ### withRegistry @@ -947,11 +947,11 @@ Higher-order component which renders the original component with the current reg _Parameters_ -- _OriginalComponent_ `WPComponent`: Original component. +- _OriginalComponent_ `Component`: Original component. _Returns_ -- `WPComponent`: Enhanced component. +- `Component`: Enhanced component. ### withSelect @@ -995,7 +995,7 @@ _Parameters_ _Returns_ -- `WPComponent`: Enhanced component with merged state data props. +- `ComponentType`: Enhanced component with merged state data props. diff --git a/packages/data/src/components/async-mode-provider/context.js b/packages/data/src/components/async-mode-provider/context.js index fdaa203b1afb6e..fe0c8acc99333b 100644 --- a/packages/data/src/components/async-mode-provider/context.js +++ b/packages/data/src/components/async-mode-provider/context.js @@ -42,6 +42,6 @@ export const AsyncModeConsumer = Consumer; * It is possible to nest multiple levels of AsyncModeProvider to fine-tune the rendering behavior. * * @param {boolean} props.value Enable Async Mode. - * @return {WPComponent} The component to be rendered. + * @return {Component} The component to be rendered. */ export default Provider; diff --git a/packages/data/src/components/use-dispatch/use-dispatch.js b/packages/data/src/components/use-dispatch/use-dispatch.js index c0da1bb81fd0dd..742fdc2a6e9654 100644 --- a/packages/data/src/components/use-dispatch/use-dispatch.js +++ b/packages/data/src/components/use-dispatch/use-dispatch.js @@ -31,8 +31,8 @@ import useRegistry from '../registry-provider/use-registry'; * action. * * ```jsx + * import { useCallback } from 'react'; * import { useDispatch, useSelect } from '@wordpress/data'; - * import { useCallback } from '@wordpress/element'; * import { store as myCustomStore } from 'my-custom-store'; * * function Button( { onClick, children } ) { diff --git a/packages/data/src/components/with-dispatch/index.js b/packages/data/src/components/with-dispatch/index.js index a9ef2fb6c61946..cc67c8d9806375 100644 --- a/packages/data/src/components/with-dispatch/index.js +++ b/packages/data/src/components/with-dispatch/index.js @@ -8,7 +8,7 @@ import { createHigherOrderComponent } from '@wordpress/compose'; */ import { useDispatchWithMap } from '../use-dispatch'; -/** @typedef {import('@wordpress/element').WPComponent} WPComponent */ +/** @typedef {import('react').ComponentType} ComponentType */ /** * Higher-order component used to add dispatch props using registered action @@ -89,7 +89,7 @@ import { useDispatchWithMap } from '../use-dispatch'; * returns an object with the same keys. For example, it should not contain * conditions under which a different value would be returned. * - * @return {WPComponent} Enhanced component with merged dispatcher props. + * @return {ComponentType} Enhanced component with merged dispatcher props. */ const withDispatch = ( mapDispatchToProps ) => createHigherOrderComponent( diff --git a/packages/data/src/components/with-registry/index.js b/packages/data/src/components/with-registry/index.js index faf3da8c009add..4ccd38ed398d73 100644 --- a/packages/data/src/components/with-registry/index.js +++ b/packages/data/src/components/with-registry/index.js @@ -12,9 +12,9 @@ import { RegistryConsumer } from '../registry-provider'; * Higher-order component which renders the original component with the current * registry context passed as its `registry` prop. * - * @param {WPComponent} OriginalComponent Original component. + * @param {Component} OriginalComponent Original component. * - * @return {WPComponent} Enhanced component. + * @return {Component} Enhanced component. */ const withRegistry = createHigherOrderComponent( ( OriginalComponent ) => ( props ) => ( diff --git a/packages/data/src/components/with-select/index.js b/packages/data/src/components/with-select/index.js index 0f869f6b0a1a76..12a56b70da2b65 100644 --- a/packages/data/src/components/with-select/index.js +++ b/packages/data/src/components/with-select/index.js @@ -8,7 +8,7 @@ import { createHigherOrderComponent, pure } from '@wordpress/compose'; */ import useSelect from '../use-select'; -/** @typedef {import('@wordpress/element').WPComponent} WPComponent */ +/** @typedef {import('react').ComponentType} ComponentType */ /** * Higher-order component used to inject state-derived props using registered @@ -48,7 +48,7 @@ import useSelect from '../use-select'; * component and update automatically if the price of a hammer ever changes in * the store. * - * @return {WPComponent} Enhanced component with merged state data props. + * @return {ComponentType} Enhanced component with merged state data props. */ const withSelect = ( mapSelectToProps ) => createHigherOrderComponent( diff --git a/packages/dependency-extraction-webpack-plugin/README.md b/packages/dependency-extraction-webpack-plugin/README.md index 0885a38e1c8251..eac1e8e27ffc5c 100644 --- a/packages/dependency-extraction-webpack-plugin/README.md +++ b/packages/dependency-extraction-webpack-plugin/README.md @@ -62,13 +62,13 @@ For example: ``` // Source file entrypoint.js -import { Component } from '@wordpress/element'; +import { Component } from 'react'; // Webpack will produce the output output/entrypoint.js /* bundled JavaScript output */ // Webpack will also produce output/entrypoint.asset.php declaring script dependencies - array('wp-element'), 'version' => 'dd4c2dc50d046ed9d4c063a7ca95702f'); + array('react'), 'version' => 'dd4c2dc50d046ed9d4c063a7ca95702f'); ``` By default, the following module requests are handled: diff --git a/packages/edit-post/README.md b/packages/edit-post/README.md index bf592bb5e22052..ef96e0b16f3488 100644 --- a/packages/edit-post/README.md +++ b/packages/edit-post/README.md @@ -55,7 +55,7 @@ function doOnClick() { } function MyPluginBlockSettingsMenuItem() { - return wp.element.createElement( PluginBlockSettingsMenuItem, { + return React.createElement( PluginBlockSettingsMenuItem, { allowedBlocks: [ 'core/paragraph' ], icon: 'dashicon-name', label: __( 'Menu item text' ), @@ -95,7 +95,7 @@ _Parameters_ _Returns_ -- `WPComponent`: The component to be rendered. +- `Component`: The component to be rendered. ### PluginDocumentSettingPanel @@ -105,7 +105,7 @@ _Usage_ ```js // Using ES5 syntax -var el = wp.element.createElement; +var el = React.createElement; var __ = wp.i18n.__; var registerPlugin = wp.plugins.registerPlugin; var PluginDocumentSettingPanel = wp.editPost.PluginDocumentSettingPanel; @@ -152,11 +152,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_ `WPElement`: Children to be rendered +- _props.children_ `Element`: Children to be rendered _Returns_ -- `WPComponent`: The component to be rendered. +- `Component`: The component to be rendered. ### PluginMoreMenuItem @@ -168,14 +168,14 @@ _Usage_ // Using ES5 syntax var __ = wp.i18n.__; var PluginMoreMenuItem = wp.editPost.PluginMoreMenuItem; -var moreIcon = wp.element.createElement( 'svg' ); //... svg element. +var moreIcon = React.createElement( 'svg' ); //... svg element. function onButtonClick() { alert( 'Button clicked.' ); } function MyButtonMoreMenuItem() { - return wp.element.createElement( + return React.createElement( PluginMoreMenuItem, { icon: moreIcon, @@ -213,7 +213,7 @@ _Parameters_ _Returns_ -- `WPComponent`: The component to be rendered. +- `Component`: The component to be rendered. ### PluginPostPublishPanel @@ -227,7 +227,7 @@ var __ = wp.i18n.__; var PluginPostPublishPanel = wp.editPost.PluginPostPublishPanel; function MyPluginPostPublishPanel() { - return wp.element.createElement( + return React.createElement( PluginPostPublishPanel, { className: 'my-plugin-post-publish-panel', @@ -262,11 +262,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_ `WPElement`: Children to be rendered +- _props.children_ `Element`: Children to be rendered _Returns_ -- `WPComponent`: The component to be rendered. +- `Component`: The component to be rendered. ### PluginPostStatusInfo @@ -280,7 +280,7 @@ var __ = wp.i18n.__; var PluginPostStatusInfo = wp.editPost.PluginPostStatusInfo; function MyPluginPostStatusInfo() { - return wp.element.createElement( + return React.createElement( PluginPostStatusInfo, { className: 'my-plugin-post-status-info', @@ -306,11 +306,11 @@ _Parameters_ - _props_ `Object`: Component properties. - _props.className_ `[string]`: An optional class name added to the row. -- _props.children_ `WPElement`: Children to be rendered. +- _props.children_ `Element`: Children to be rendered. _Returns_ -- `WPComponent`: The component to be rendered. +- `Component`: The component to be rendered. ### PluginPrePublishPanel @@ -324,7 +324,7 @@ var __ = wp.i18n.__; var PluginPrePublishPanel = wp.editPost.PluginPrePublishPanel; function MyPluginPrePublishPanel() { - return wp.element.createElement( + return React.createElement( PluginPrePublishPanel, { className: 'my-plugin-pre-publish-panel', @@ -359,11 +359,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_ `WPElement`: Children to be rendered +- _props.children_ `Element`: Children to be rendered _Returns_ -- `WPComponent`: The component to be rendered. +- `Component`: The component to be rendered. ### PluginSidebar @@ -384,10 +384,10 @@ _Usage_ ```js // Using ES5 syntax var __ = wp.i18n.__; -var el = wp.element.createElement; +var el = React.createElement; var PanelBody = wp.components.PanelBody; var PluginSidebar = wp.editPost.PluginSidebar; -var moreIcon = wp.element.createElement( 'svg' ); //... svg element. +var moreIcon = React.createElement( 'svg' ); //... svg element. function MyPluginSidebar() { return el( @@ -435,10 +435,10 @@ _Usage_ // Using ES5 syntax var __ = wp.i18n.__; var PluginSidebarMoreMenuItem = wp.editPost.PluginSidebarMoreMenuItem; -var moreIcon = wp.element.createElement( 'svg' ); //... svg element. +var moreIcon = React.createElement( 'svg' ); //... svg element. function MySidebarMoreMenuItem() { - return wp.element.createElement( + return React.createElement( PluginSidebarMoreMenuItem, { target: 'my-sidebar', @@ -470,7 +470,7 @@ _Parameters_ _Returns_ -- `WPComponent`: The component to be rendered. +- `Component`: The component to be rendered. ### reinitializeEditor diff --git a/packages/edit-post/src/components/block-settings-menu/plugin-block-settings-menu-item.js b/packages/edit-post/src/components/block-settings-menu/plugin-block-settings-menu-item.js index f0390267259b66..322aa07db80f86 100644 --- a/packages/edit-post/src/components/block-settings-menu/plugin-block-settings-menu-item.js +++ b/packages/edit-post/src/components/block-settings-menu/plugin-block-settings-menu-item.js @@ -45,7 +45,7 @@ const shouldRenderItem = ( selectedBlocks, allowedBlocks ) => * } * * function MyPluginBlockSettingsMenuItem() { - * return wp.element.createElement( + * return React.createElement( * PluginBlockSettingsMenuItem, * { * allowedBlocks: [ 'core/paragraph' ], @@ -76,7 +76,7 @@ const shouldRenderItem = ( selectedBlocks, allowedBlocks ) => * ); * ``` * - * @return {WPComponent} The component to be rendered. + * @return {Component} The component to be rendered. */ const PluginBlockSettingsMenuItem = ( { allowedBlocks, diff --git a/packages/edit-post/src/components/header/plugin-more-menu-item/index.js b/packages/edit-post/src/components/header/plugin-more-menu-item/index.js index 6e8c4daa24d461..d9675974704626 100644 --- a/packages/edit-post/src/components/header/plugin-more-menu-item/index.js +++ b/packages/edit-post/src/components/header/plugin-more-menu-item/index.js @@ -21,14 +21,14 @@ import { withPluginContext } from '@wordpress/plugins'; * // Using ES5 syntax * var __ = wp.i18n.__; * var PluginMoreMenuItem = wp.editPost.PluginMoreMenuItem; - * var moreIcon = wp.element.createElement( 'svg' ); //... svg element. + * var moreIcon = React.createElement( 'svg' ); //... svg element. * * function onButtonClick() { * alert( 'Button clicked.' ); * } * * function MyButtonMoreMenuItem() { - * return wp.element.createElement( + * return React.createElement( * PluginMoreMenuItem, * { * icon: moreIcon, @@ -60,7 +60,7 @@ import { withPluginContext } from '@wordpress/plugins'; * ); * ``` * - * @return {WPComponent} The component to be rendered. + * @return {Component} The component to be rendered. */ export default compose( withPluginContext( ( context, ownProps ) => { diff --git a/packages/edit-post/src/components/header/plugin-sidebar-more-menu-item/index.js b/packages/edit-post/src/components/header/plugin-sidebar-more-menu-item/index.js index 1bb1a5e43153e7..133e5ae2ba301f 100644 --- a/packages/edit-post/src/components/header/plugin-sidebar-more-menu-item/index.js +++ b/packages/edit-post/src/components/header/plugin-sidebar-more-menu-item/index.js @@ -17,10 +17,10 @@ import { ComplementaryAreaMoreMenuItem } from '@wordpress/interface'; * // Using ES5 syntax * var __ = wp.i18n.__; * var PluginSidebarMoreMenuItem = wp.editPost.PluginSidebarMoreMenuItem; - * var moreIcon = wp.element.createElement( 'svg' ); //... svg element. + * var moreIcon = React.createElement( 'svg' ); //... svg element. * * function MySidebarMoreMenuItem() { - * return wp.element.createElement( + * return React.createElement( * PluginSidebarMoreMenuItem, * { * target: 'my-sidebar', @@ -48,7 +48,7 @@ import { ComplementaryAreaMoreMenuItem } from '@wordpress/interface'; * ); * ``` * - * @return {WPComponent} The component to be rendered. + * @return {Component} The component to be rendered. */ export default function PluginSidebarMoreMenuItem( props ) { diff --git a/packages/edit-post/src/components/meta-boxes/meta-boxes-area/index.js b/packages/edit-post/src/components/meta-boxes/meta-boxes-area/index.js index 33baf50f0f6618..6d66115923e7b0 100644 --- a/packages/edit-post/src/components/meta-boxes/meta-boxes-area/index.js +++ b/packages/edit-post/src/components/meta-boxes/meta-boxes-area/index.js @@ -20,7 +20,7 @@ import { store as editPostStore } from '../../../store'; * * @param {Object} props Component props. * @param {string} props.location metabox location. - * @return {WPComponent} The component to be rendered. + * @return {Component} The component to be rendered. */ function MetaBoxesArea( { location } ) { const container = useRef( null ); diff --git a/packages/edit-post/src/components/sidebar/plugin-document-setting-panel/index.js b/packages/edit-post/src/components/sidebar/plugin-document-setting-panel/index.js index 506de5bc907e80..7ee3f96498e53c 100644 --- a/packages/edit-post/src/components/sidebar/plugin-document-setting-panel/index.js +++ b/packages/edit-post/src/components/sidebar/plugin-document-setting-panel/index.js @@ -22,12 +22,12 @@ 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 {WPElement} props.children Children to be rendered + * @param {Element} props.children Children to be rendered * * @example * ```js * // Using ES5 syntax - * var el = wp.element.createElement; + * var el = React.createElement; * var __ = wp.i18n.__; * var registerPlugin = wp.plugins.registerPlugin; * var PluginDocumentSettingPanel = wp.editPost.PluginDocumentSettingPanel; @@ -64,7 +64,7 @@ const { Fill, Slot } = createSlotFill( 'PluginDocumentSettingPanel' ); * registerPlugin( 'document-setting-test', { render: MyDocumentSettingTest } ); * ``` * - * @return {WPComponent} The component to be rendered. + * @return {Component} The component to be rendered. */ const PluginDocumentSettingPanel = ( { name, diff --git a/packages/edit-post/src/components/sidebar/plugin-post-publish-panel/index.js b/packages/edit-post/src/components/sidebar/plugin-post-publish-panel/index.js index f355cacd763084..71de03b35b56ab 100644 --- a/packages/edit-post/src/components/sidebar/plugin-post-publish-panel/index.js +++ b/packages/edit-post/src/components/sidebar/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 {WPElement} props.children Children to be rendered + * @param {Element} props.children Children to be rendered * * @example * ```js @@ -24,7 +24,7 @@ const { Fill, Slot } = createSlotFill( 'PluginPostPublishPanel' ); * var PluginPostPublishPanel = wp.editPost.PluginPostPublishPanel; * * function MyPluginPostPublishPanel() { - * return wp.element.createElement( + * return React.createElement( * PluginPostPublishPanel, * { * className: 'my-plugin-post-publish-panel', @@ -53,7 +53,7 @@ const { Fill, Slot } = createSlotFill( 'PluginPostPublishPanel' ); * ); * ``` * - * @return {WPComponent} The component to be rendered. + * @return {Component} The component to be rendered. */ const PluginPostPublishPanel = ( { children, diff --git a/packages/edit-post/src/components/sidebar/plugin-post-status-info/index.js b/packages/edit-post/src/components/sidebar/plugin-post-status-info/index.js index cbef3858cb2749..29af3832947d6f 100644 --- a/packages/edit-post/src/components/sidebar/plugin-post-status-info/index.js +++ b/packages/edit-post/src/components/sidebar/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 {WPElement} props.children Children to be rendered. + * @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. * * @example * ```js @@ -25,7 +25,7 @@ const { Fill, Slot } = createSlotFill( 'PluginPostStatusInfo' ); * var PluginPostStatusInfo = wp.editPost.PluginPostStatusInfo; * * function MyPluginPostStatusInfo() { - * return wp.element.createElement( + * return React.createElement( * PluginPostStatusInfo, * { * className: 'my-plugin-post-status-info', @@ -50,7 +50,7 @@ const { Fill, Slot } = createSlotFill( 'PluginPostStatusInfo' ); * ); * ``` * - * @return {WPComponent} The component to be rendered. + * @return {Component} The component to be rendered. */ const PluginPostStatusInfo = ( { children, className } ) => ( diff --git a/packages/edit-post/src/components/sidebar/plugin-pre-publish-panel/index.js b/packages/edit-post/src/components/sidebar/plugin-pre-publish-panel/index.js index 91392ab7883ed5..014a7b31176a29 100644 --- a/packages/edit-post/src/components/sidebar/plugin-pre-publish-panel/index.js +++ b/packages/edit-post/src/components/sidebar/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 {WPElement} props.children Children to be rendered + * @param {Element} props.children Children to be rendered * * @example * ```js @@ -27,7 +27,7 @@ const { Fill, Slot } = createSlotFill( 'PluginPrePublishPanel' ); * var PluginPrePublishPanel = wp.editPost.PluginPrePublishPanel; * * function MyPluginPrePublishPanel() { - * return wp.element.createElement( + * return React.createElement( * PluginPrePublishPanel, * { * className: 'my-plugin-pre-publish-panel', @@ -56,7 +56,7 @@ const { Fill, Slot } = createSlotFill( 'PluginPrePublishPanel' ); * ); * ``` * - * @return {WPComponent} The component to be rendered. + * @return {Component} The component to be rendered. */ const PluginPrePublishPanel = ( { children, diff --git a/packages/edit-post/src/components/sidebar/plugin-sidebar/index.js b/packages/edit-post/src/components/sidebar/plugin-sidebar/index.js index c6b09f0343a00b..39b9e4362ce32c 100644 --- a/packages/edit-post/src/components/sidebar/plugin-sidebar/index.js +++ b/packages/edit-post/src/components/sidebar/plugin-sidebar/index.js @@ -34,10 +34,10 @@ import { store as editPostStore } from '../../../store'; * ```js * // Using ES5 syntax * var __ = wp.i18n.__; - * var el = wp.element.createElement; + * var el = React.createElement; * var PanelBody = wp.components.PanelBody; * var PluginSidebar = wp.editPost.PluginSidebar; - * var moreIcon = wp.element.createElement( 'svg' ); //... svg element. + * var moreIcon = React.createElement( 'svg' ); //... svg element. * * function MyPluginSidebar() { * return el( diff --git a/packages/edit-post/src/hooks/validate-multiple-use/index.js b/packages/edit-post/src/hooks/validate-multiple-use/index.js index 3877a894632c9a..31444a86467c70 100644 --- a/packages/edit-post/src/hooks/validate-multiple-use/index.js +++ b/packages/edit-post/src/hooks/validate-multiple-use/index.js @@ -23,9 +23,9 @@ const enhance = compose( * "original" block is not the current one. Thus, an inexisting * `originalBlockClientId` prop signals that the block is valid. * - * @param {WPComponent} WrappedBlockEdit A filtered BlockEdit instance. + * @param {Component} WrappedBlockEdit A filtered BlockEdit instance. * - * @return {WPComponent} Enhanced component with merged state data props. + * @return {Component} Enhanced component with merged state data props. */ withSelect( ( select, block ) => { const multiple = hasBlockSupport( block.name, 'multiple', true ); diff --git a/packages/edit-site/src/components/block-editor/block-editor-provider/default-block-editor-provider.js b/packages/edit-site/src/components/block-editor/block-editor-provider/default-block-editor-provider.js index a29552edaef226..c91c687ce5284c 100644 --- a/packages/edit-site/src/components/block-editor/block-editor-provider/default-block-editor-provider.js +++ b/packages/edit-site/src/components/block-editor/block-editor-provider/default-block-editor-provider.js @@ -27,8 +27,8 @@ const noop = () => {}; * mimic the look and feel of the post editor and * allow editing of the page content only. * - * @param {Object} props - * @param {WPElement} props.children + * @param {Object} props + * @param {Element} props.children */ export default function DefaultBlockEditorProvider( { children } ) { const settings = useSiteEditorSettings(); diff --git a/packages/edit-site/src/components/header-edit-mode/plugin-more-menu-item/index.js b/packages/edit-site/src/components/header-edit-mode/plugin-more-menu-item/index.js index e507b1bf2fbc59..edb093a487e772 100644 --- a/packages/edit-site/src/components/header-edit-mode/plugin-more-menu-item/index.js +++ b/packages/edit-site/src/components/header-edit-mode/plugin-more-menu-item/index.js @@ -60,7 +60,7 @@ import { withPluginContext } from '@wordpress/plugins'; * ); * ``` * - * @return {WPComponent} The component to be rendered. + * @return {Component} The component to be rendered. */ export default compose( withPluginContext( ( context, ownProps ) => { diff --git a/packages/edit-site/src/components/header-edit-mode/plugin-sidebar-more-menu-item/index.js b/packages/edit-site/src/components/header-edit-mode/plugin-sidebar-more-menu-item/index.js index 3b9bbd9288142a..4d6c8008497241 100644 --- a/packages/edit-site/src/components/header-edit-mode/plugin-sidebar-more-menu-item/index.js +++ b/packages/edit-site/src/components/header-edit-mode/plugin-sidebar-more-menu-item/index.js @@ -48,7 +48,7 @@ import { ComplementaryAreaMoreMenuItem } from '@wordpress/interface'; * ); * ``` * - * @return {WPComponent} The component to be rendered. + * @return {Component} The component to be rendered. */ export default function PluginSidebarMoreMenuItem( props ) { diff --git a/packages/edit-site/src/components/plugin-template-setting-panel/index.js b/packages/edit-site/src/components/plugin-template-setting-panel/index.js index 6a059dc2520ad2..0c279c91039a79 100644 --- a/packages/edit-site/src/components/plugin-template-setting-panel/index.js +++ b/packages/edit-site/src/components/plugin-template-setting-panel/index.js @@ -28,6 +28,6 @@ PluginTemplateSettingPanel.Slot = Slot; * ); * ``` * - * @return {WPComponent} The component to be rendered. + * @return {Component} The component to be rendered. */ export default PluginTemplateSettingPanel; diff --git a/packages/edit-widgets/src/components/layout/unsaved-changes-warning.js b/packages/edit-widgets/src/components/layout/unsaved-changes-warning.js index 4d1675222ef99f..382bc6fa0d8905 100644 --- a/packages/edit-widgets/src/components/layout/unsaved-changes-warning.js +++ b/packages/edit-widgets/src/components/layout/unsaved-changes-warning.js @@ -16,7 +16,7 @@ import { store as editWidgetsStore } from '../../store'; * This is a duplicate of the component implemented in the editor package. * Duplicated here as edit-widgets doesn't depend on editor. * - * @return {WPComponent} The component. + * @return {Component} The component. */ export default function UnsavedChangesWarning() { const isDirty = useSelect( ( select ) => { diff --git a/packages/editor/README.md b/packages/editor/README.md index 157136b28d0d66..12cb885db857e8 100644 --- a/packages/editor/README.md +++ b/packages/editor/README.md @@ -37,8 +37,8 @@ When returned by your block's `edit` implementation, renders a toolbar of icon b Example: ```js -( function ( editor, element ) { - var el = element.createElement, +( function ( editor, React ) { + var el = React.createElement, BlockControls = editor.BlockControls, AlignmentToolbar = editor.AlignmentToolbar; @@ -64,7 +64,7 @@ Example: ), ]; } -} )( window.wp.editor, window.wp.element ); +} )( window.wp.editor, window.React ); ``` Note in this example that we render `AlignmentToolbar` as a child of the `BlockControls` element. This is another pre-configured component you can use to simplify block text alignment. @@ -95,8 +95,8 @@ The following properties (non-exhaustive list) are made available: Example: ```js -( function ( editor, element ) { - var el = element.createElement, +( function ( editor, React ) { + var el = React.createElement, RichText = editor.RichText; function edit( props ) { @@ -111,7 +111,7 @@ Example: } // blocks.registerBlockType( ..., { edit: edit, ... } ); -} )( window.wp.editor, window.wp.element ); +} )( window.wp.editor, window.React ); ``` ## Contributing to this package diff --git a/packages/editor/src/components/post-featured-image/README.md b/packages/editor/src/components/post-featured-image/README.md index 9b1520228703fb..369e4d7ef94399 100644 --- a/packages/editor/src/components/post-featured-image/README.md +++ b/packages/editor/src/components/post-featured-image/README.md @@ -13,7 +13,7 @@ Replace the contents of the panel: ```js function replacePostFeaturedImage() { return function () { - return wp.element.createElement( + return React.createElement( 'div', {}, 'The replacement contents or components.' @@ -31,12 +31,12 @@ wp.hooks.addFilter( Prepend and append to the panel contents: ```js -var el = wp.element.createElement; +var el = React.createElement; function wrapPostFeaturedImage( OriginalComponent ) { return function ( props ) { return el( - wp.element.Fragment, + React.Fragment, {}, 'Prepend above', el( OriginalComponent, props ), diff --git a/packages/editor/src/components/post-saved-state/index.js b/packages/editor/src/components/post-saved-state/index.js index ed3115d5a6c54a..9d6cb49d91e8e8 100644 --- a/packages/editor/src/components/post-saved-state/index.js +++ b/packages/editor/src/components/post-saved-state/index.js @@ -30,7 +30,7 @@ import { store as editorStore } from '../../store'; * @param {?boolean} props.forceIsDirty Whether to force the post to be marked * as dirty. * @param {?boolean} props.showIconLabels Whether interface buttons show labels instead of icons - * @return {import('@wordpress/element').WPComponent} The component. + * @return {import('react').ComponentType} The component. */ export default function PostSavedState( { forceIsDirty, diff --git a/packages/editor/src/components/post-taxonomies/README.md b/packages/editor/src/components/post-taxonomies/README.md index 90dcfcf95eb9df..941c28d4639314 100644 --- a/packages/editor/src/components/post-taxonomies/README.md +++ b/packages/editor/src/components/post-taxonomies/README.md @@ -19,7 +19,7 @@ For example, to render alternative UI for the taxonomy `product-type`, we can render custom markup or use the original component as shown below. ```js -var el = wp.element.createElement; +var el = React.createElement; function customizeProductTypeSelector( OriginalComponent ) { return function ( props ) { @@ -42,7 +42,7 @@ Or, to use the hierarchical term selector with a non-hierarchical taxonomy `trac you can set the `HierarchicalTermSelector` component as shown below. ```js -const el = wp.element.createElement; +const el = React.createElement; const HierarchicalTermSelector = wp.editor.PostTaxonomiesHierarchicalTermSelector; function customizeTrackSelector( OriginalComponent ) { diff --git a/packages/editor/src/components/post-taxonomies/hierarchical-term-selector.js b/packages/editor/src/components/post-taxonomies/hierarchical-term-selector.js index aeed0b4f4b6d9f..c93458ed3cfef2 100644 --- a/packages/editor/src/components/post-taxonomies/hierarchical-term-selector.js +++ b/packages/editor/src/components/post-taxonomies/hierarchical-term-selector.js @@ -149,7 +149,7 @@ export function getFilterMatcher( filterValue ) { * * @param {Object} props Component props. * @param {string} props.slug Taxonomy slug. - * @return {WPElement} Hierarchical term selector component. + * @return {Element} Hierarchical term selector component. */ export function HierarchicalTermSelector( { slug } ) { const [ adding, setAdding ] = useState( false ); diff --git a/packages/editor/src/components/post-type-support-check/README.md b/packages/editor/src/components/post-type-support-check/README.md index 565882fab758ba..eab70d088999b7 100644 --- a/packages/editor/src/components/post-type-support-check/README.md +++ b/packages/editor/src/components/post-type-support-check/README.md @@ -16,7 +16,7 @@ If the post type is not yet known, it will be assumed to be supported. ### `children` -_Type:_ `WPElement` +_Type:_ `Element` Children to be rendered if post type supports. diff --git a/packages/editor/src/components/post-type-support-check/index.js b/packages/editor/src/components/post-type-support-check/index.js index fffabf6ab247c9..c716593f458f17 100644 --- a/packages/editor/src/components/post-type-support-check/index.js +++ b/packages/editor/src/components/post-type-support-check/index.js @@ -14,12 +14,12 @@ import { store as editorStore } from '../../store'; * type supports one of the given `supportKeys` prop. * * @param {Object} props Props. - * @param {WPElement} props.children Children to be rendered if post + * @param {Element} props.children Children to be rendered if post * type supports. * @param {(string|string[])} props.supportKeys String or string array of keys * to test. * - * @return {WPComponent} The component to be rendered. + * @return {Component} The component to be rendered. */ function PostTypeSupportCheck( { children, supportKeys } ) { const postType = useSelect( ( select ) => { diff --git a/packages/editor/src/components/unsaved-changes-warning/index.js b/packages/editor/src/components/unsaved-changes-warning/index.js index b5c78644082133..49e2b7edf1f293 100644 --- a/packages/editor/src/components/unsaved-changes-warning/index.js +++ b/packages/editor/src/components/unsaved-changes-warning/index.js @@ -10,7 +10,7 @@ import { store as coreStore } from '@wordpress/core-data'; * Warns the user if there are unsaved changes before leaving the editor. * Compatible with Post Editor and Site Editor. * - * @return {WPComponent} The component. + * @return {Component} The component. */ export default function UnsavedChangesWarning() { const { __experimentalGetDirtyEntityRecords } = useSelect( coreStore ); diff --git a/packages/element/CHANGELOG.md b/packages/element/CHANGELOG.md index 7b3e83b2572c96..30ff172259d2e3 100644 --- a/packages/element/CHANGELOG.md +++ b/packages/element/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## Breaking Changes + +- Remove the WPElement, WPComponent, and WPSyntheticEvent types. + ## 5.19.0 (2023-09-20) ## 5.18.0 (2023-08-31) diff --git a/packages/element/README.md b/packages/element/README.md index 879aefb5a46f48..96aeeea37a462e 100755 --- a/packages/element/README.md +++ b/packages/element/README.md @@ -1,17 +1,6 @@ # Element -Element is, quite simply, an abstraction layer atop [React](https://reactjs.org/). - -You may find yourself asking, "Why an abstraction layer?". For a few reasons: - -- In many applications, especially those extended by a rich plugin ecosystem as is the case with WordPress, it's wise to create interfaces to underlying third-party code. The thinking is that if ever a need arises to change or even replace the underlying implementation, it can be done without catastrophic rippling effects to dependent code, so long as the interface stays the same. -- It provides a mechanism to shield implementers by omitting features with uncertain futures (`createClass`, `PropTypes`). -- It helps avoid incompatibilities between versions by ensuring that every plugin operates on a single centralized version of the code. - -On the `wp.element` global object, you will find the following, ordered roughly by the likelihood you'll encounter it in your code: - -- [`createElement`](https://reactjs.org/docs/react-api.html#createelement) -- [`render`](https://reactjs.org/docs/react-dom.html#render) +Element is a package that builds on top of [React](https://reactjs.org/) and provide a set of utilities to work with React components and React elements. ## Installation @@ -23,39 +12,6 @@ npm install @wordpress/element --save _This package assumes that your code will run in an **ES2015+** environment. If you're using an environment that has limited or no support for such language features and APIs, you should include [the polyfill shipped in `@wordpress/babel-preset-default`](https://github.com/WordPress/gutenberg/tree/HEAD/packages/babel-preset-default#polyfill) in your code._ -## Usage - -Let's render a customized greeting into an empty element. - -**Note:** `createRoot` was introduced with React 18, which is bundled with WordPress 6.2. Therefore it may be necessary to mount your component depending on which version of WordPress (and therefore React) you are currently using. This is possible by checking for an undefined import and falling back to the React 17 method of mounting an app using `render`. - -Assuming the following root element is present in the page: - -```html -
-``` - -We can mount our app: - -```js -import { createRoot, render, createElement } from '@wordpress/element'; - -function Greeting( props ) { - return createElement( 'span', null, 'Hello ' + props.toWhom + '!' ); -} - -const domElement = document.getElementById( 'greeting' ); -const uiElement = createElement( Greeting, { toWhom: 'World' } ); - -if ( createRoot ) { - createRoot( domElement ).render( uiElement ); -} else { - render( uiElement, domElement ); -} -``` - -Refer to the [official React Quick Start guide](https://reactjs.org/docs/hello-world.html) for a more thorough walkthrough, in most cases substituting `React` and `ReactDOM` with `wp.element` in code examples. - ## Why React? At the risk of igniting debate surrounding any single "best" front-end framework, the choice to use any tool should be motivated specifically to serve the requirements of the system. In modeling the concept of a [block](https://github.com/WordPress/gutenberg/tree/HEAD/packages/blocks/README.md), we observe the following technical requirements: @@ -67,27 +23,6 @@ At its most basic, React provides a simple input / output mechanism. **Given a s The offerings of any framework necessarily become more complex as these requirements increase; many front-end frameworks prescribe ideas around page routing, retrieving and updating data, and managing layout. React is not immune to this, but the introduced complexity is rarely caused by React itself, but instead managing an arrangement of supporting tools. By moving these concerns out of sight to the internals of the system (WordPress core code), we can minimize the responsibilities of plugin authors to a small, clear set of touch points. -## JSX - -While not at all a requirement to use React, [JSX](https://reactjs.org/docs/introducing-jsx.html) is a recommended syntax extension to compose elements more expressively. Through a build process, JSX is converted back to the `createElement` syntax you see earlier in this document. - -If you've configured [Babel](http://babeljs.io/) for your project, you can opt in to JSX syntax by specifying the `pragma` option of the [`transform-react-jsx` plugin](https://www.npmjs.com/package/babel-plugin-transform-react-jsx) in your [`.babelrc` configuration](http://babeljs.io/docs/usage/babelrc/). - -```json -{ - "plugins": [ - [ - "transform-react-jsx", - { - "pragma": "createElement" - } - ] - ] -} -``` - -This assumes that you will import the `createElement` function in any file where you use JSX. Alternatively, consider using the [`@wordpress/babel-plugin-import-jsx-pragma` Babel plugin](https://www.npmjs.com/package/@wordpress/babel-plugin-import-jsx-pragma) to automate the import of this function. - ## API @@ -102,12 +37,12 @@ Creates a copy of an element with extended props. _Parameters_ -- _element_ `WPElement`: Element +- _element_ `Element`: Element - _props_ `?Object`: Props to apply to cloned element _Returns_ -- `WPElement`: Cloned element. +- `Element`: Cloned element. ### Component @@ -145,11 +80,11 @@ _Parameters_ - _type_ `?(string|Function)`: Tag name or element creator - _props_ `Object`: Element properties, either attribute set to apply to DOM node or values to pass through to element creator -- _children_ `...WPElement`: Descendant elements +- _children_ `...Element`: Descendant elements _Returns_ -- `WPElement`: Element. +- `Element`: Element. ### createInterpolateElement @@ -175,11 +110,11 @@ You would have something like this as the conversionMap value: _Parameters_ - _interpolatedString_ `string`: The interpolation string to be parsed. -- _conversionMap_ `Record`: The map used to convert the string to a react element. +- _conversionMap_ `Record`: The map used to convert the string to a react element. _Returns_ -- `WPElement`: A wp element. +- `Element`: A wp element. ### createPortal @@ -191,7 +126,7 @@ _Related_ _Parameters_ -- _child_ `import('./react').WPElement`: Any renderable child, such as an element, string, or fragment. +- _child_ `import('react').ReactElement`: Any renderable child, such as an element, string, or fragment. - _container_ `HTMLElement`: DOM node into which element should be rendered. ### createRef @@ -220,7 +155,7 @@ Finds the dom node of a React component. _Parameters_ -- _component_ `import('./react').WPComponent`: Component's instance. +- _component_ `import('react').ComponentType`: Component's instance. ### flushSync @@ -240,7 +175,7 @@ _Parameters_ _Returns_ -- `WPComponent`: Enhanced component. +- `Component`: Enhanced component. ### Fragment @@ -282,7 +217,7 @@ _Returns_ ### isValidElement -Checks if an object is a valid WPElement. +Checks if an object is a valid React Element. _Parameters_ @@ -290,7 +225,7 @@ _Parameters_ _Returns_ -- `boolean`: true if objectToTest is a valid WPElement and false otherwise. +- `boolean`: true if objectToTest is a valid React Element and false otherwise. ### lazy diff --git a/packages/element/src/create-interpolate-element.js b/packages/element/src/create-interpolate-element.js index 761a01079f5a14..88f6254dad7d6e 100644 --- a/packages/element/src/create-interpolate-element.js +++ b/packages/element/src/create-interpolate-element.js @@ -3,7 +3,11 @@ */ import { createElement, cloneElement, Fragment, isValidElement } from './react'; -/** @typedef {import('./react').WPElement} WPElement */ +/** + * Object containing a React element. + * + * @typedef {import('react').ReactElement} Element + */ let indoc, offset, output, stack; @@ -29,17 +33,17 @@ const tokenizer = /<(\/)?(\w+)\s*(\/)?>/g; * * @typedef Frame * - * @property {WPElement} element A parent element which may still have - * @property {number} tokenStart Offset at which parent element first - * appears. - * @property {number} tokenLength Length of string marking start of parent - * element. - * @property {number} [prevOffset] Running offset at which parsing should - * continue. - * @property {number} [leadingTextStart] Offset at which last closing element - * finished, used for finding text between - * elements. - * @property {WPElement[]} children Children. + * @property {Element} element A parent element which may still have + * @property {number} tokenStart Offset at which parent element first + * appears. + * @property {number} tokenLength Length of string marking start of parent + * element. + * @property {number} [prevOffset] Running offset at which parsing should + * continue. + * @property {number} [leadingTextStart] Offset at which last closing element + * finished, used for finding text between + * elements. + * @property {Element[]} children Children. */ /** @@ -49,17 +53,17 @@ const tokenizer = /<(\/)?(\w+)\s*(\/)?>/g; * parsed. * * @private - * @param {WPElement} element A parent element which may still have - * nested children not yet parsed. - * @param {number} tokenStart Offset at which parent element first - * appears. - * @param {number} tokenLength Length of string marking start of parent - * element. - * @param {number} [prevOffset] Running offset at which parsing should - * continue. - * @param {number} [leadingTextStart] Offset at which last closing element - * finished, used for finding text between - * elements. + * @param {Element} element A parent element which may still have + * nested children not yet parsed. + * @param {number} tokenStart Offset at which parent element first + * appears. + * @param {number} tokenLength Length of string marking start of parent + * element. + * @param {number} [prevOffset] Running offset at which parsing should + * continue. + * @param {number} [leadingTextStart] Offset at which last closing element + * finished, used for finding text between + * elements. * * @return {Frame} The stack frame tracking parse progress. */ @@ -101,11 +105,11 @@ function createFrame( * } * ``` * - * @param {string} interpolatedString The interpolation string to be parsed. - * @param {Record} conversionMap The map used to convert the string to - * a react element. + * @param {string} interpolatedString The interpolation string to be parsed. + * @param {Record} conversionMap The map used to convert the string to + * a react element. * @throws {TypeError} - * @return {WPElement} A wp element. + * @return {Element} A wp element. */ const createInterpolateElement = ( interpolatedString, conversionMap ) => { indoc = interpolatedString; @@ -116,7 +120,7 @@ const createInterpolateElement = ( interpolatedString, conversionMap ) => { if ( ! isValidConversionMap( conversionMap ) ) { throw new TypeError( - 'The conversionMap provided is not valid. It must be an object with values that are WPElements' + 'The conversionMap provided is not valid. It must be an object with values that are React Elements' ); } @@ -130,7 +134,7 @@ const createInterpolateElement = ( interpolatedString, conversionMap ) => { * Validate conversion map. * * A map is considered valid if it's an object and every value in the object - * is a WPElement + * is a React Element * * @private * diff --git a/packages/element/src/react-platform.js b/packages/element/src/react-platform.js index bd444b2828bef7..862b02706876d2 100644 --- a/packages/element/src/react-platform.js +++ b/packages/element/src/react-platform.js @@ -16,16 +16,16 @@ import { createRoot, hydrateRoot } from 'react-dom/client'; * * @see https://github.com/facebook/react/issues/10309#issuecomment-318433235 * - * @param {import('./react').WPElement} child Any renderable child, such as an element, - * string, or fragment. - * @param {HTMLElement} container DOM node into which element should be rendered. + * @param {import('react').ReactElement} child Any renderable child, such as an element, + * string, or fragment. + * @param {HTMLElement} container DOM node into which element should be rendered. */ export { createPortal }; /** * Finds the dom node of a React component. * - * @param {import('./react').WPComponent} component Component's instance. + * @param {import('react').ComponentType} component Component's instance. */ export { findDOMNode }; diff --git a/packages/element/src/react.js b/packages/element/src/react.js index 1eb49ac6742c2d..6882f9ad3344a5 100644 --- a/packages/element/src/react.js +++ b/packages/element/src/react.js @@ -37,19 +37,19 @@ import { /** * Object containing a React element. * - * @typedef {import('react').ReactElement} WPElement + * @typedef {import('react').ReactElement} Element */ /** * Object containing a React component. * - * @typedef {import('react').ComponentType} WPComponent + * @typedef {import('react').ComponentType} ComponentType */ /** * Object containing a React synthetic event. * - * @typedef {import('react').SyntheticEvent} WPSyntheticEvent + * @typedef {import('react').SyntheticEvent} SyntheticEvent */ /** @@ -67,10 +67,10 @@ export { Children }; /** * Creates a copy of an element with extended props. * - * @param {WPElement} element Element - * @param {?Object} props Props to apply to cloned element + * @param {Element} element Element + * @param {?Object} props Props to apply to cloned element * - * @return {WPElement} Cloned element. + * @return {Element} Cloned element. */ export { cloneElement }; @@ -96,9 +96,9 @@ export { createContext }; * @param {Object} props Element properties, either attribute * set to apply to DOM node or values to * pass through to element creator - * @param {...WPElement} children Descendant elements + * @param {...Element} children Descendant elements * - * @return {WPElement} Element. + * @return {Element} Element. */ export { createElement }; @@ -120,7 +120,7 @@ export { createRef }; * @param {Function} forwarder Function passed `props` and `ref`, expected to * return an element. * - * @return {WPComponent} Enhanced component. + * @return {Component} Enhanced component. */ export { forwardRef }; @@ -130,11 +130,11 @@ export { forwardRef }; export { Fragment }; /** - * Checks if an object is a valid WPElement. + * Checks if an object is a valid React Element. * * @param {Object} objectToCheck The object to be checked. * - * @return {boolean} true if objectToTest is a valid WPElement and false otherwise. + * @return {boolean} true if objectToTest is a valid React Element and false otherwise. */ export { isValidElement }; diff --git a/packages/element/src/serialize.js b/packages/element/src/serialize.js index d18a6f00fa941f..e047ccad432dc8 100644 --- a/packages/element/src/serialize.js +++ b/packages/element/src/serialize.js @@ -46,7 +46,7 @@ import { import { createContext, Fragment, StrictMode, forwardRef } from './react'; import RawHTML from './raw-html'; -/** @typedef {import('./react').WPElement} WPElement */ +/** @typedef {import('react').ReactElement} ReactElement */ const { Provider, Consumer } = createContext( undefined ); const ForwardRef = forwardRef( () => { @@ -672,15 +672,15 @@ export function renderNativeComponent( return '<' + type + attributes + '>' + content + ''; } -/** @typedef {import('./react').WPComponent} WPComponent */ +/** @typedef {import('react').ComponentType} ComponentType */ /** * Serializes a non-native component type to string. * - * @param {WPComponent} Component Component type to serialize. - * @param {Object} props Props object. - * @param {Object} [context] Context object. - * @param {Object} [legacyContext] Legacy context object. + * @param {ComponentType} Component Component type to serialize. + * @param {Object} props Props object. + * @param {Object} [context] Context object. + * @param {Object} [legacyContext] Legacy context object. * * @return {string} Serialized element */ diff --git a/packages/eslint-plugin/configs/jsdoc.js b/packages/eslint-plugin/configs/jsdoc.js index 4aaed834363996..62effdb709b39e 100644 --- a/packages/eslint-plugin/configs/jsdoc.js +++ b/packages/eslint-plugin/configs/jsdoc.js @@ -21,9 +21,11 @@ const temporaryWordPressInternalTypes = [ 'WPBlockTypeIcon', 'WPBlockTypeIconRender', 'WPBlockTypeIconDescriptor', - 'WPComponent', - 'WPElement', 'WPIcon', + + // These two should be removed once we use the TS types from "react". + 'Component', + 'Element', ]; /** diff --git a/packages/eslint-plugin/docs/rules/dependency-group.md b/packages/eslint-plugin/docs/rules/dependency-group.md index e3910544aedb71..8d0b53996ce22b 100644 --- a/packages/eslint-plugin/docs/rules/dependency-group.md +++ b/packages/eslint-plugin/docs/rules/dependency-group.md @@ -12,7 +12,7 @@ Examples of **incorrect** code for this rule: ```js import { camelCase } from 'change-case'; -import { Component } from '@wordpress/element'; +import { Component } from 'react'; import edit from './edit'; ``` @@ -27,7 +27,7 @@ import { camelCase } from 'change-case'; /* * WordPress dependencies */ -import { Component } from '@wordpress/element'; +import { Component } from 'react'; /* * Internal dependencies diff --git a/packages/eslint-plugin/docs/rules/react-no-unsafe-timeout.md b/packages/eslint-plugin/docs/rules/react-no-unsafe-timeout.md index 87dc07bc9e62a2..8e203a2c82ba6d 100644 --- a/packages/eslint-plugin/docs/rules/react-no-unsafe-timeout.md +++ b/packages/eslint-plugin/docs/rules/react-no-unsafe-timeout.md @@ -19,7 +19,7 @@ class MyComponent extends Component { } } -class MyComponent extends wp.element.Component { +class MyComponent extends React.Component { componentDidMount() { setTimeout( fn ); } @@ -48,7 +48,7 @@ class MyNotComponent { } } -class MyComponent extends wp.element.Component { +class MyComponent extends React.Component { componentDidMount() { const { setTimeout } = this.props; setTimeout( fn ); diff --git a/packages/interface/src/components/complementary-area/README.md b/packages/interface/src/components/complementary-area/README.md index 0013f0b9d4dcc4..bca534b30af970 100644 --- a/packages/interface/src/components/complementary-area/README.md +++ b/packages/interface/src/components/complementary-area/README.md @@ -50,7 +50,7 @@ A className passed to the header container. The icon to render. -- Type: `Function|WPComponent|null` +- Type: `Function|Component|null` - Required: No - Default: `null` diff --git a/packages/keyboard-shortcuts/README.md b/packages/keyboard-shortcuts/README.md index 281ef698526e71..1721279a6e99da 100644 --- a/packages/keyboard-shortcuts/README.md +++ b/packages/keyboard-shortcuts/README.md @@ -26,7 +26,7 @@ _Parameters_ _Returns_ -- `import('@wordpress/element').WPElement`: Component. +- `Element`: Component. ### store diff --git a/packages/keyboard-shortcuts/src/components/shortcut-provider.js b/packages/keyboard-shortcuts/src/components/shortcut-provider.js index feda767a2ca6bf..485350bb3c0e90 100644 --- a/packages/keyboard-shortcuts/src/components/shortcut-provider.js +++ b/packages/keyboard-shortcuts/src/components/shortcut-provider.js @@ -17,7 +17,7 @@ const { Provider } = context; * * @param {Object} props Props to pass to `div`. * - * @return {import('@wordpress/element').WPElement} Component. + * @return {Element} Component. */ export function ShortcutProvider( props ) { const [ keyboardShortcuts ] = useState( () => new Set() ); diff --git a/packages/keyboard-shortcuts/src/store/actions.js b/packages/keyboard-shortcuts/src/store/actions.js index d45a23a09f21da..2b77b6c1e1fe45 100644 --- a/packages/keyboard-shortcuts/src/store/actions.js +++ b/packages/keyboard-shortcuts/src/store/actions.js @@ -29,9 +29,9 @@ * @example * *```js + * import { useEffect } from 'react'; * import { store as keyboardShortcutsStore } from '@wordpress/keyboard-shortcuts'; * import { useSelect, useDispatch } from '@wordpress/data'; - * import { useEffect } from '@wordpress/element'; * import { __ } from '@wordpress/i18n'; * * const ExampleComponent = () => { @@ -91,9 +91,9 @@ export function registerShortcut( { * @example * *```js + * import { useEffect } from 'react'; * import { store as keyboardShortcutsStore } from '@wordpress/keyboard-shortcuts'; * import { useSelect, useDispatch } from '@wordpress/data'; - * import { useEffect } from '@wordpress/element'; * import { __ } from '@wordpress/i18n'; * * const ExampleComponent = () => { diff --git a/packages/notices/src/store/actions.js b/packages/notices/src/store/actions.js index 11c38a9c931ae4..445eed10650b61 100644 --- a/packages/notices/src/store/actions.js +++ b/packages/notices/src/store/actions.js @@ -81,7 +81,7 @@ export function createNotice( status = DEFAULT_STATUS, content, options = {} ) { } = options; // The supported value shape of content is currently limited to plain text - // strings. To avoid setting expectation that e.g. a WPElement could be + // strings. To avoid setting expectation that e.g. a React Element could be // supported, cast to a string. content = String( content ); diff --git a/packages/patterns/src/components/pattern-convert-button.js b/packages/patterns/src/components/pattern-convert-button.js index 002dbbd8c0181d..e110be22938df9 100644 --- a/packages/patterns/src/components/pattern-convert-button.js +++ b/packages/patterns/src/components/pattern-convert-button.js @@ -29,7 +29,7 @@ import { PATTERN_SYNC_TYPES } from '../constants'; * @param {Object} props Component props. * @param {string[]} props.clientIds Client ids of selected blocks. * @param {string} props.rootClientId ID of the currently selected top-level block. - * @return {import('@wordpress/element').WPComponent} The menu control or null. + * @return {import('react').ComponentType} The menu control or null. */ export default function PatternConvertButton( { clientIds, rootClientId } ) { const { createSuccessNotice } = useDispatch( noticesStore ); diff --git a/packages/plugins/README.md b/packages/plugins/README.md index a0e8441513e5d7..e9e5a704aeca71 100644 --- a/packages/plugins/README.md +++ b/packages/plugins/README.md @@ -48,7 +48,7 @@ _Usage_ ```js // Using ES5 syntax -var el = wp.element.createElement; +var el = React.createElement; var PluginArea = wp.plugins.PluginArea; function Layout() { @@ -76,7 +76,7 @@ _Parameters_ _Returns_ -- `WPComponent`: The component to be rendered. +- `Component`: The component to be rendered. #### registerPlugin @@ -86,12 +86,12 @@ _Usage_ ```js // Using ES5 syntax -var el = wp.element.createElement; +var el = React.createElement; var Fragment = wp.element.Fragment; var PluginSidebar = wp.editPost.PluginSidebar; var PluginSidebarMoreMenuItem = wp.editPost.PluginSidebarMoreMenuItem; var registerPlugin = wp.plugins.registerPlugin; -var moreIcon = wp.element.createElement( 'svg' ); //... svg element. +var moreIcon = React.createElement( 'svg' ); //... svg element. function Component() { return el( @@ -200,7 +200,7 @@ _Parameters_ _Returns_ -- `WPComponent`: Enhanced component with injected context as props. +- `Component`: Enhanced component with injected context as props. diff --git a/packages/plugins/src/api/index.ts b/packages/plugins/src/api/index.ts index a5217e0fe2bdc6..45c8f931634198 100644 --- a/packages/plugins/src/api/index.ts +++ b/packages/plugins/src/api/index.ts @@ -1,4 +1,8 @@ /* eslint no-console: [ 'error', { allow: [ 'error' ] } ] */ +/** + * External dependencies + */ +import type { ComponentType } from 'react'; /** * WordPress dependencies @@ -6,7 +10,6 @@ import { applyFilters, doAction } from '@wordpress/hooks'; import { plugins as pluginsIcon } from '@wordpress/icons'; import type { IconType } from '@wordpress/components'; -import type { WPComponent } from '@wordpress/element'; /** * Defined behavior of a plugin type. @@ -27,7 +30,7 @@ export interface WPPlugin { /** * A component containing the UI elements to be rendered. */ - render: WPComponent; + render: ComponentType; /** * The optional scope to be used when rendering inside a plugin area. @@ -53,12 +56,12 @@ const plugins = {} as Record< string, WPPlugin >; * @example * ```js * // Using ES5 syntax - * var el = wp.element.createElement; + * var el = React.createElement; * var Fragment = wp.element.Fragment; * var PluginSidebar = wp.editPost.PluginSidebar; * var PluginSidebarMoreMenuItem = wp.editPost.PluginSidebarMoreMenuItem; * var registerPlugin = wp.plugins.registerPlugin; - * var moreIcon = wp.element.createElement( 'svg' ); //... svg element. + * var moreIcon = React.createElement( 'svg' ); //... svg element. * * function Component() { * return el( diff --git a/packages/plugins/src/components/plugin-area/index.tsx b/packages/plugins/src/components/plugin-area/index.tsx index 9410c9cef4e5ff..231a519b030d01 100644 --- a/packages/plugins/src/components/plugin-area/index.tsx +++ b/packages/plugins/src/components/plugin-area/index.tsx @@ -35,7 +35,7 @@ const getPluginContext = memoize( * @example * ```js * // Using ES5 syntax - * var el = wp.element.createElement; + * var el = React.createElement; * var PluginArea = wp.plugins.PluginArea; * * function Layout() { @@ -61,7 +61,7 @@ const getPluginContext = memoize( * ); * ``` * - * @return {WPComponent} The component to be rendered. + * @return {Component} The component to be rendered. */ function PluginArea( { scope, diff --git a/packages/plugins/src/components/plugin-context/index.tsx b/packages/plugins/src/components/plugin-context/index.tsx index 76fbdabe048293..c2e6f8eaa232d8 100644 --- a/packages/plugins/src/components/plugin-context/index.tsx +++ b/packages/plugins/src/components/plugin-context/index.tsx @@ -38,7 +38,7 @@ export function usePluginContext() { * expected to return object of props to * merge with the component's own props. * - * @return {WPComponent} Enhanced component with injected context as props. + * @return {Component} Enhanced component with injected context as props. */ export const withPluginContext = ( mapContextToProps: < T >( diff --git a/packages/reusable-blocks/src/components/reusable-blocks-menu-items/reusable-block-convert-button.js b/packages/reusable-blocks/src/components/reusable-blocks-menu-items/reusable-block-convert-button.js index 347638baeaf059..c9ed4b6502bb60 100644 --- a/packages/reusable-blocks/src/components/reusable-blocks-menu-items/reusable-block-convert-button.js +++ b/packages/reusable-blocks/src/components/reusable-blocks-menu-items/reusable-block-convert-button.js @@ -35,7 +35,7 @@ import { unlock } from '../../lock-unlock'; * @param {string[]} props.clientIds Client ids of selected blocks. * @param {string} props.rootClientId ID of the currently selected top-level block. * @param {()=>void} props.onClose Callback to close the menu. - * @return {import('@wordpress/element').WPComponent} The menu control or null. + * @return {import('react').ComponentType} The menu control or null. */ export default function ReusableBlockConvertButton( { clientIds, diff --git a/platform-docs/docs/basic-concepts/undo-redo.md b/platform-docs/docs/basic-concepts/undo-redo.md index 26981e6e0f5c16..21497f57c9b5d0 100644 --- a/platform-docs/docs/basic-concepts/undo-redo.md +++ b/platform-docs/docs/basic-concepts/undo-redo.md @@ -14,7 +14,8 @@ First, make sure you add the `@wordpress/compose` package to your dependencies, ```jsx import { useStateWithHistory } from '@wordpress/compose'; -import { createRoot, createElement, useState } from "@wordpress/element"; +import { createElement, useState } from "react"; +import { createRoot } from 'react-dom/client'; import { BlockEditorProvider, BlockCanvas, diff --git a/platform-docs/docs/intro.md b/platform-docs/docs/intro.md index 41732843164e2b..79a142731891e5 100644 --- a/platform-docs/docs/intro.md +++ b/platform-docs/docs/intro.md @@ -23,49 +23,12 @@ Once done, you can navigate to your application folder and run it locally using To build a block editor, you need to install the following dependencies: - `@wordpress/block-editor` - - `@wordpress/element` - `@wordpress/block-library` - `@wordpress/components` -## Setup vite to use JSX and @wordpress/element as a pragma +## JSX -We're going to be using JSX to write our UI and components. So one of the first steps we need to do is to configure our build tooling. - -If you're using vite, you can create a `vite.config.js` file at the root of your application and paste the following content: - -```js -// vite.config.js -import { defineConfig } from 'vite' - -export default defineConfig({ - esbuild: { - jsxFactory: 'createElement', - jsxFragment: 'Fragment', - }, - define: { - // This is not necessary to make JSX work - // but it's a requirement for some @wordpress packages. - 'process.env': {} - }, -}) -``` - -With the config above, you should be able to write JSX in your `*.jsx` files, just make sure you import createElement and Fragment at the top of each of your files: `import { createElement, Fragment } from '@wordpress/element';` - -We can now check that everything is working as expected: - - - Remove the default content created by vite: `main.js` and `counter.js` files. - - Create an `index.jsx` file at the root of your application containing some JSX, example: -```jsx -import { createRoot, createElement } from '@wordpress/element'; - -// Render your React component instead -const root = createRoot(document.getElementById('app')); -root.render(

Hello, world

); -``` - - Update the script file in your `index.html` to `index.jsx` instead of `main.js`. - -After restarting your local build (aka `npm run dev`), you should see the **"Hello, world"** heading appearing in your browser. +We're going to be using JSX to write our UI and components. So one of the first steps we need to do is to configure our build tooling, By default vite supports JSX and and outputs the result as a React pragma. The Block editor uses React so there's no need to configure anything here but if you're using a different bundler/build tool, make sure the JSX transpilation is setup properly. ## Bootstrap your block editor @@ -73,7 +36,8 @@ It's time to render our first block editor. - Update your `index.jsx` file with the following code: ```jsx -import { createRoot, createElement, useState } from "@wordpress/element"; +import { createElement, useState } from "react"; +import { createRoot } from 'react-dom/client'; import { BlockEditorProvider, BlockCanvas, From 1be856b0d0833828326beef8bb0c16e39d8115f1 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Wed, 4 Oct 2023 15:05:46 +0100 Subject: [PATCH 18/19] Documentation: Add a page about the format library to the platform docs site (#55037) --- .../docs/basic-concepts/block-library.md | 2 +- .../docs/basic-concepts/internationalization.md | 2 +- platform-docs/docs/basic-concepts/rendering.md | 2 +- platform-docs/docs/basic-concepts/rich-text.md | 17 ++++++++++++++++- platform-docs/docs/basic-concepts/settings.md | 2 +- platform-docs/docs/basic-concepts/undo-redo.md | 2 +- 6 files changed, 21 insertions(+), 6 deletions(-) diff --git a/platform-docs/docs/basic-concepts/block-library.md b/platform-docs/docs/basic-concepts/block-library.md index 0e7de53ce36dfc..dba569f34fac13 100644 --- a/platform-docs/docs/basic-concepts/block-library.md +++ b/platform-docs/docs/basic-concepts/block-library.md @@ -1,5 +1,5 @@ --- -sidebar_position: 6 +sidebar_position: 4 --- # Block Library diff --git a/platform-docs/docs/basic-concepts/internationalization.md b/platform-docs/docs/basic-concepts/internationalization.md index a6e2ba90a38d96..c15a1e2e68145f 100644 --- a/platform-docs/docs/basic-concepts/internationalization.md +++ b/platform-docs/docs/basic-concepts/internationalization.md @@ -1,5 +1,5 @@ --- -sidebar_position: 8 +sidebar_position: 7 --- # Internationalization diff --git a/platform-docs/docs/basic-concepts/rendering.md b/platform-docs/docs/basic-concepts/rendering.md index d18eeb3ae1dbbc..9c823f4931aaa1 100644 --- a/platform-docs/docs/basic-concepts/rendering.md +++ b/platform-docs/docs/basic-concepts/rendering.md @@ -1,5 +1,5 @@ --- -sidebar_position: 9 +sidebar_position: 8 --- # Rendering blocks diff --git a/platform-docs/docs/basic-concepts/rich-text.md b/platform-docs/docs/basic-concepts/rich-text.md index d46aa49dcb42f5..bfd8119f02ce41 100644 --- a/platform-docs/docs/basic-concepts/rich-text.md +++ b/platform-docs/docs/basic-concepts/rich-text.md @@ -1,5 +1,20 @@ --- -sidebar_position: 7 +sidebar_position: 5 --- # RichText and Format Library + +Several block types (like paragraph, heading, and more) allow users to type and manipulate rich text content. In order to do so, they use the `RichText` component and the `@wordpress/rich-text` package. + +The `RichText` component is a wrapper around the `@wordpress/rich-text` package that provides a React-friendly API to manipulate rich text content. It allows the user to add and apply formats to the text content. + +By default, no format is available. You need to register formats in order to make them available to the user. The `@wordpress/format-library` provides a set of default formats to include in your application. It includes: + +- bold, italic, superscript, subscript, strikethrough, links, inline code, inline image, text color, keyboard input (kbd), language (bdo). + +In order to register all formats from the format library, add the `@wordpress/format-library` as a dependency of your app and you can use the following code. + +```js +import '@wordpress/format-library'; +import '@wordpress/format-library/build-style/style.css'; +``` diff --git a/platform-docs/docs/basic-concepts/settings.md b/platform-docs/docs/basic-concepts/settings.md index 11e25996b2ec10..a2d376e71a29dd 100644 --- a/platform-docs/docs/basic-concepts/settings.md +++ b/platform-docs/docs/basic-concepts/settings.md @@ -1,5 +1,5 @@ --- -sidebar_position: 4 +sidebar_position: 3 --- # Block Editor Settings diff --git a/platform-docs/docs/basic-concepts/undo-redo.md b/platform-docs/docs/basic-concepts/undo-redo.md index 21497f57c9b5d0..d3041a21eebe9b 100644 --- a/platform-docs/docs/basic-concepts/undo-redo.md +++ b/platform-docs/docs/basic-concepts/undo-redo.md @@ -1,5 +1,5 @@ --- -sidebar_position: 3 +sidebar_position: 6 --- # Undo Redo From 1710facd57ad89595c6b0dedc5f30cd0f4e694d3 Mon Sep 17 00:00:00 2001 From: Ella <4710635+ellatrix@users.noreply.github.com> Date: Wed, 4 Oct 2023 17:42:43 +0300 Subject: [PATCH 19/19] Writing flow: absorb clipboard handler (#55006) --- packages/block-editor/CHANGELOG.md | 2 + packages/block-editor/README.md | 6 +- .../src/components/block-actions/index.js | 2 +- .../src/components/block-canvas/index.js | 8 +- .../src/components/copy-handler/README.md | 2 + .../src/components/copy-handler/index.js | 312 ++---------------- packages/block-editor/src/components/index.js | 2 +- .../src/components/writing-flow/index.js | 2 + .../writing-flow/use-clipboard-handler.js | 242 ++++++++++++++ .../block-editor/src/utils/use-notify-copy.js | 63 ++++ .../index.js | 7 +- 11 files changed, 341 insertions(+), 307 deletions(-) create mode 100644 packages/block-editor/src/components/writing-flow/use-clipboard-handler.js create mode 100644 packages/block-editor/src/utils/use-notify-copy.js diff --git a/packages/block-editor/CHANGELOG.md b/packages/block-editor/CHANGELOG.md index cba698b8689c23..40ff46fca50b34 100644 --- a/packages/block-editor/CHANGELOG.md +++ b/packages/block-editor/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +- Deprecated `CopyHandler`, absorbed into `WritingFlow`. + ## 12.10.0 (2023-09-20) - The Deprecated multiline prop on RichText will now fall back to using multiple diff --git a/packages/block-editor/README.md b/packages/block-editor/README.md index 837a8c35aacfa2..063a96384708cb 100644 --- a/packages/block-editor/README.md +++ b/packages/block-editor/README.md @@ -334,9 +334,11 @@ _Related_ ### CopyHandler -_Related_ +> **Deprecated** -- +_Parameters_ + +- _props_ `Object`: ### createCustomColorsHOC diff --git a/packages/block-editor/src/components/block-actions/index.js b/packages/block-editor/src/components/block-actions/index.js index b672bee63fc5b1..5d942d2b25c708 100644 --- a/packages/block-editor/src/components/block-actions/index.js +++ b/packages/block-editor/src/components/block-actions/index.js @@ -11,7 +11,7 @@ import { /** * Internal dependencies */ -import { useNotifyCopy } from '../copy-handler'; +import { useNotifyCopy } from '../../utils/use-notify-copy'; import usePasteStyles from '../use-paste-styles'; import { store as blockEditorStore } from '../../store'; diff --git a/packages/block-editor/src/components/block-canvas/index.js b/packages/block-editor/src/components/block-canvas/index.js index 435655de3cc269..97aec461df7d86 100644 --- a/packages/block-editor/src/components/block-canvas/index.js +++ b/packages/block-editor/src/components/block-canvas/index.js @@ -11,7 +11,6 @@ import EditorStyles from '../editor-styles'; import Iframe from '../iframe'; import WritingFlow from '../writing-flow'; import { useMouseMoveTypingReset } from '../observe-typing'; -import { useClipboardHandler } from '../copy-handler'; import { useBlockSelectionClearer } from '../block-selection-clearer'; export function ExperimentalBlockCanvas( { @@ -23,13 +22,8 @@ export function ExperimentalBlockCanvas( { iframeProps, } ) { const resetTypingRef = useMouseMoveTypingReset(); - const copyHandler = useClipboardHandler(); const clearerRef = useBlockSelectionClearer(); - const contentRef = useMergeRefs( [ - copyHandler, - contentRefProp, - clearerRef, - ] ); + const contentRef = useMergeRefs( [ contentRefProp, clearerRef ] ); if ( ! shouldIframe ) { return ( diff --git a/packages/block-editor/src/components/copy-handler/README.md b/packages/block-editor/src/components/copy-handler/README.md index 089d1ce0b73f1c..b70c841ce0ea53 100644 --- a/packages/block-editor/src/components/copy-handler/README.md +++ b/packages/block-editor/src/components/copy-handler/README.md @@ -1,5 +1,7 @@ # Copy Handler +**Deprecated** + The `CopyHandler` component handles the copy/cut and paste events of its children blocks. It handles multiple selection of blocks as well. Concretely, it handles the display of success messages and takes care of copying the block to the clipboard. It uses for that the [serialize function](https://github.com/WordPress/gutenberg/blob/HEAD/packages/blocks/src/api/serializer.js), which outputs HTML augmented with the HTML-comment demarcations to denote blocks. diff --git a/packages/block-editor/src/components/copy-handler/index.js b/packages/block-editor/src/components/copy-handler/index.js index c6d41cf0be3fec..0b0318c387fab7 100644 --- a/packages/block-editor/src/components/copy-handler/index.js +++ b/packages/block-editor/src/components/copy-handler/index.js @@ -1,304 +1,34 @@ /** * WordPress dependencies */ -import { useCallback } from '@wordpress/element'; -import { - serialize, - pasteHandler, - store as blocksStore, - createBlock, - findTransform, - getBlockTransforms, -} from '@wordpress/blocks'; -import { - documentHasSelection, - documentHasUncollapsedSelection, - __unstableStripHTML as stripHTML, -} from '@wordpress/dom'; -import { useDispatch, useSelect } from '@wordpress/data'; -import { __, _n, sprintf } from '@wordpress/i18n'; -import { store as noticesStore } from '@wordpress/notices'; -import { useRefEffect } from '@wordpress/compose'; +import deprecated from '@wordpress/deprecated'; /** * Internal dependencies */ -import { getPasteEventData } from '../../utils/pasting'; -import { store as blockEditorStore } from '../../store'; - -export function useNotifyCopy() { - const { getBlockName } = useSelect( blockEditorStore ); - const { getBlockType } = useSelect( blocksStore ); - const { createSuccessNotice } = useDispatch( noticesStore ); - - return useCallback( ( eventType, selectedBlockClientIds ) => { - let notice = ''; - if ( selectedBlockClientIds.length === 1 ) { - const clientId = selectedBlockClientIds[ 0 ]; - const title = getBlockType( getBlockName( clientId ) )?.title; - notice = - eventType === 'copy' - ? sprintf( - // Translators: Name of the block being copied, e.g. "Paragraph". - __( 'Copied "%s" to clipboard.' ), - title - ) - : sprintf( - // Translators: Name of the block being cut, e.g. "Paragraph". - __( 'Moved "%s" to clipboard.' ), - title - ); - } else { - notice = - eventType === 'copy' - ? sprintf( - // Translators: %d: Number of blocks being copied. - _n( - 'Copied %d block to clipboard.', - 'Copied %d blocks to clipboard.', - selectedBlockClientIds.length - ), - selectedBlockClientIds.length - ) - : sprintf( - // Translators: %d: Number of blocks being cut. - _n( - 'Moved %d block to clipboard.', - 'Moved %d blocks to clipboard.', - selectedBlockClientIds.length - ), - selectedBlockClientIds.length - ); - } - createSuccessNotice( notice, { - type: 'snackbar', - } ); - }, [] ); -} - -export function useClipboardHandler() { - const { - getBlocksByClientId, - getSelectedBlockClientIds, - hasMultiSelection, - getSettings, - __unstableIsFullySelected, - __unstableIsSelectionCollapsed, - __unstableIsSelectionMergeable, - __unstableGetSelectedBlocksWithPartialSelection, - canInsertBlockType, - } = useSelect( blockEditorStore ); - const { - flashBlock, - removeBlocks, - replaceBlocks, - __unstableDeleteSelection, - __unstableExpandSelection, - insertBlocks, - } = useDispatch( blockEditorStore ); - const notifyCopy = useNotifyCopy(); - - return useRefEffect( ( node ) => { - function handler( event ) { - if ( event.defaultPrevented ) { - // This was likely already handled in rich-text/use-paste-handler.js. - return; - } - - const selectedBlockClientIds = getSelectedBlockClientIds(); - - if ( selectedBlockClientIds.length === 0 ) { - return; - } - - // Always handle multiple selected blocks. - if ( ! hasMultiSelection() ) { - const { target } = event; - const { ownerDocument } = target; - // If copying, only consider actual text selection as selection. - // Otherwise, any focus on an input field is considered. - const hasSelection = - event.type === 'copy' || event.type === 'cut' - ? documentHasUncollapsedSelection( ownerDocument ) - : documentHasSelection( ownerDocument ); - - // Let native copy behaviour take over in input fields. - if ( hasSelection ) { - return; - } - } - - if ( ! node.contains( event.target.ownerDocument.activeElement ) ) { - return; - } - - event.preventDefault(); - - const isSelectionMergeable = __unstableIsSelectionMergeable(); - const shouldHandleWholeBlocks = - __unstableIsSelectionCollapsed() || __unstableIsFullySelected(); - const expandSelectionIsNeeded = - ! shouldHandleWholeBlocks && ! isSelectionMergeable; - if ( event.type === 'copy' || event.type === 'cut' ) { - if ( selectedBlockClientIds.length === 1 ) { - flashBlock( selectedBlockClientIds[ 0 ] ); - } - // If we have a partial selection that is not mergeable, just - // expand the selection to the whole blocks. - if ( expandSelectionIsNeeded ) { - __unstableExpandSelection(); - } else { - notifyCopy( event.type, selectedBlockClientIds ); - let blocks; - // Check if we have partial selection. - if ( shouldHandleWholeBlocks ) { - blocks = getBlocksByClientId( selectedBlockClientIds ); - } else { - const [ head, tail ] = - __unstableGetSelectedBlocksWithPartialSelection(); - const inBetweenBlocks = getBlocksByClientId( - selectedBlockClientIds.slice( - 1, - selectedBlockClientIds.length - 1 - ) - ); - blocks = [ head, ...inBetweenBlocks, tail ]; - } - - const wrapperBlockName = event.clipboardData.getData( - '__unstableWrapperBlockName' - ); - - if ( wrapperBlockName ) { - blocks = createBlock( - wrapperBlockName, - JSON.parse( - event.clipboardData.getData( - '__unstableWrapperBlockAttributes' - ) - ), - blocks - ); - } - - const serialized = serialize( blocks ); - - event.clipboardData.setData( - 'text/plain', - toPlainText( serialized ) - ); - event.clipboardData.setData( 'text/html', serialized ); - } - } - - if ( event.type === 'cut' ) { - // We need to also check if at the start we needed to - // expand the selection, as in this point we might have - // programmatically fully selected the blocks above. - if ( shouldHandleWholeBlocks && ! expandSelectionIsNeeded ) { - removeBlocks( selectedBlockClientIds ); - } else { - event.target.ownerDocument.activeElement.contentEditable = false; - __unstableDeleteSelection(); - } - } else if ( event.type === 'paste' ) { - const { - __experimentalCanUserUseUnfilteredHTML: - canUserUseUnfilteredHTML, - } = getSettings(); - const { plainText, html, files } = getPasteEventData( event ); - let blocks = []; - - if ( files.length ) { - const fromTransforms = getBlockTransforms( 'from' ); - blocks = files - .reduce( ( accumulator, file ) => { - const transformation = findTransform( - fromTransforms, - ( transform ) => - transform.type === 'files' && - transform.isMatch( [ file ] ) - ); - if ( transformation ) { - accumulator.push( - transformation.transform( [ file ] ) - ); - } - return accumulator; - }, [] ) - .flat(); - } else { - blocks = pasteHandler( { - HTML: html, - plainText, - mode: 'BLOCKS', - canUserUseUnfilteredHTML, - } ); - } - - if ( selectedBlockClientIds.length === 1 ) { - const [ selectedBlockClientId ] = selectedBlockClientIds; - - if ( - blocks.every( ( block ) => - canInsertBlockType( - block.name, - selectedBlockClientId - ) - ) - ) { - insertBlocks( - blocks, - undefined, - selectedBlockClientId - ); - return; - } - } - - replaceBlocks( - selectedBlockClientIds, - blocks, - blocks.length - 1, - -1 - ); - } - } - - node.ownerDocument.addEventListener( 'copy', handler ); - node.ownerDocument.addEventListener( 'cut', handler ); - node.ownerDocument.addEventListener( 'paste', handler ); - - return () => { - node.ownerDocument.removeEventListener( 'copy', handler ); - node.ownerDocument.removeEventListener( 'cut', handler ); - node.ownerDocument.removeEventListener( 'paste', handler ); - }; - }, [] ); -} - -function CopyHandler( { children } ) { - return
{ children }
; -} +import useClipboardHandler from '../writing-flow/use-clipboard-handler'; /** - * Given a string of HTML representing serialized blocks, returns the plain - * text extracted after stripping the HTML of any tags and fixing line breaks. - * - * @param {string} html Serialized blocks. - * @return {string} The plain-text content with any html removed. + * @deprecated */ -function toPlainText( html ) { - // Manually handle BR tags as line breaks prior to `stripHTML` call - html = html.replace( /
/g, '\n' ); - - const plainText = stripHTML( html ).trim(); - - // Merge any consecutive line breaks - return plainText.replace( /\n\n+/g, '\n\n' ); -} +export const __unstableUseClipboardHandler = () => { + deprecated( '__unstableUseClipboardHandler', { + alternative: 'BlockCanvas or WritingFlow', + since: '6.4', + version: '6.7', + } ); + return useClipboardHandler(); +}; /** - * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/copy-handler/README.md + * @deprecated + * @param {Object} props */ -export default CopyHandler; +export default function CopyHandler( props ) { + deprecated( 'CopyHandler', { + alternative: 'BlockCanvas or WritingFlow', + since: '6.4', + version: '6.7', + } ); + return
; +} diff --git a/packages/block-editor/src/components/index.js b/packages/block-editor/src/components/index.js index 6edcd460e31ac4..1622cecc150ed4 100644 --- a/packages/block-editor/src/components/index.js +++ b/packages/block-editor/src/components/index.js @@ -128,7 +128,7 @@ export { default as BlockToolbar } from './block-toolbar'; export { default as BlockTools } from './block-tools'; export { default as CopyHandler, - useClipboardHandler as __unstableUseClipboardHandler, + __unstableUseClipboardHandler, } from './copy-handler'; export { default as DefaultBlockAppender } from './default-block-appender'; export { default as __unstableEditorStyles } from './editor-styles'; diff --git a/packages/block-editor/src/components/writing-flow/index.js b/packages/block-editor/src/components/writing-flow/index.js index 03d7e43f5285ed..f15c1dac0267fd 100644 --- a/packages/block-editor/src/components/writing-flow/index.js +++ b/packages/block-editor/src/components/writing-flow/index.js @@ -22,6 +22,7 @@ import useDragSelection from './use-drag-selection'; import useSelectionObserver from './use-selection-observer'; import useClickSelection from './use-click-selection'; import useInput from './use-input'; +import useClipboardHandler from './use-clipboard-handler'; import { store as blockEditorStore } from '../../store'; export function useWritingFlow() { @@ -35,6 +36,7 @@ export function useWritingFlow() { before, useMergeRefs( [ ref, + useClipboardHandler(), useInput(), useDragSelection(), useSelectionObserver(), diff --git a/packages/block-editor/src/components/writing-flow/use-clipboard-handler.js b/packages/block-editor/src/components/writing-flow/use-clipboard-handler.js new file mode 100644 index 00000000000000..5b78d2f8656b61 --- /dev/null +++ b/packages/block-editor/src/components/writing-flow/use-clipboard-handler.js @@ -0,0 +1,242 @@ +/** + * WordPress dependencies + */ +import { + serialize, + pasteHandler, + createBlock, + findTransform, + getBlockTransforms, +} from '@wordpress/blocks'; +import { + documentHasSelection, + documentHasUncollapsedSelection, + __unstableStripHTML as stripHTML, +} from '@wordpress/dom'; +import { useDispatch, useSelect } from '@wordpress/data'; +import { useRefEffect } from '@wordpress/compose'; + +/** + * Internal dependencies + */ +import { getPasteEventData } from '../../utils/pasting'; +import { store as blockEditorStore } from '../../store'; +import { useNotifyCopy } from '../../utils/use-notify-copy'; + +export default function useClipboardHandler() { + const { + getBlocksByClientId, + getSelectedBlockClientIds, + hasMultiSelection, + getSettings, + __unstableIsFullySelected, + __unstableIsSelectionCollapsed, + __unstableIsSelectionMergeable, + __unstableGetSelectedBlocksWithPartialSelection, + canInsertBlockType, + } = useSelect( blockEditorStore ); + const { + flashBlock, + removeBlocks, + replaceBlocks, + __unstableDeleteSelection, + __unstableExpandSelection, + insertBlocks, + } = useDispatch( blockEditorStore ); + const notifyCopy = useNotifyCopy(); + + return useRefEffect( ( node ) => { + function handler( event ) { + if ( event.defaultPrevented ) { + // This was likely already handled in rich-text/use-paste-handler.js. + return; + } + + const selectedBlockClientIds = getSelectedBlockClientIds(); + + if ( selectedBlockClientIds.length === 0 ) { + return; + } + + // Always handle multiple selected blocks. + if ( ! hasMultiSelection() ) { + const { target } = event; + const { ownerDocument } = target; + // If copying, only consider actual text selection as selection. + // Otherwise, any focus on an input field is considered. + const hasSelection = + event.type === 'copy' || event.type === 'cut' + ? documentHasUncollapsedSelection( ownerDocument ) + : documentHasSelection( ownerDocument ); + + // Let native copy behaviour take over in input fields. + if ( hasSelection ) { + return; + } + } + + if ( ! node.contains( event.target.ownerDocument.activeElement ) ) { + return; + } + + event.preventDefault(); + + const isSelectionMergeable = __unstableIsSelectionMergeable(); + const shouldHandleWholeBlocks = + __unstableIsSelectionCollapsed() || __unstableIsFullySelected(); + const expandSelectionIsNeeded = + ! shouldHandleWholeBlocks && ! isSelectionMergeable; + if ( event.type === 'copy' || event.type === 'cut' ) { + if ( selectedBlockClientIds.length === 1 ) { + flashBlock( selectedBlockClientIds[ 0 ] ); + } + // If we have a partial selection that is not mergeable, just + // expand the selection to the whole blocks. + if ( expandSelectionIsNeeded ) { + __unstableExpandSelection(); + } else { + notifyCopy( event.type, selectedBlockClientIds ); + let blocks; + // Check if we have partial selection. + if ( shouldHandleWholeBlocks ) { + blocks = getBlocksByClientId( selectedBlockClientIds ); + } else { + const [ head, tail ] = + __unstableGetSelectedBlocksWithPartialSelection(); + const inBetweenBlocks = getBlocksByClientId( + selectedBlockClientIds.slice( + 1, + selectedBlockClientIds.length - 1 + ) + ); + blocks = [ head, ...inBetweenBlocks, tail ]; + } + + const wrapperBlockName = event.clipboardData.getData( + '__unstableWrapperBlockName' + ); + + if ( wrapperBlockName ) { + blocks = createBlock( + wrapperBlockName, + JSON.parse( + event.clipboardData.getData( + '__unstableWrapperBlockAttributes' + ) + ), + blocks + ); + } + + const serialized = serialize( blocks ); + + event.clipboardData.setData( + 'text/plain', + toPlainText( serialized ) + ); + event.clipboardData.setData( 'text/html', serialized ); + } + } + + if ( event.type === 'cut' ) { + // We need to also check if at the start we needed to + // expand the selection, as in this point we might have + // programmatically fully selected the blocks above. + if ( shouldHandleWholeBlocks && ! expandSelectionIsNeeded ) { + removeBlocks( selectedBlockClientIds ); + } else { + event.target.ownerDocument.activeElement.contentEditable = false; + __unstableDeleteSelection(); + } + } else if ( event.type === 'paste' ) { + const { + __experimentalCanUserUseUnfilteredHTML: + canUserUseUnfilteredHTML, + } = getSettings(); + const { plainText, html, files } = getPasteEventData( event ); + let blocks = []; + + if ( files.length ) { + const fromTransforms = getBlockTransforms( 'from' ); + blocks = files + .reduce( ( accumulator, file ) => { + const transformation = findTransform( + fromTransforms, + ( transform ) => + transform.type === 'files' && + transform.isMatch( [ file ] ) + ); + if ( transformation ) { + accumulator.push( + transformation.transform( [ file ] ) + ); + } + return accumulator; + }, [] ) + .flat(); + } else { + blocks = pasteHandler( { + HTML: html, + plainText, + mode: 'BLOCKS', + canUserUseUnfilteredHTML, + } ); + } + + if ( selectedBlockClientIds.length === 1 ) { + const [ selectedBlockClientId ] = selectedBlockClientIds; + + if ( + blocks.every( ( block ) => + canInsertBlockType( + block.name, + selectedBlockClientId + ) + ) + ) { + insertBlocks( + blocks, + undefined, + selectedBlockClientId + ); + return; + } + } + + replaceBlocks( + selectedBlockClientIds, + blocks, + blocks.length - 1, + -1 + ); + } + } + + node.ownerDocument.addEventListener( 'copy', handler ); + node.ownerDocument.addEventListener( 'cut', handler ); + node.ownerDocument.addEventListener( 'paste', handler ); + + return () => { + node.ownerDocument.removeEventListener( 'copy', handler ); + node.ownerDocument.removeEventListener( 'cut', handler ); + node.ownerDocument.removeEventListener( 'paste', handler ); + }; + }, [] ); +} + +/** + * Given a string of HTML representing serialized blocks, returns the plain + * text extracted after stripping the HTML of any tags and fixing line breaks. + * + * @param {string} html Serialized blocks. + * @return {string} The plain-text content with any html removed. + */ +function toPlainText( html ) { + // Manually handle BR tags as line breaks prior to `stripHTML` call + html = html.replace( /
/g, '\n' ); + + const plainText = stripHTML( html ).trim(); + + // Merge any consecutive line breaks + return plainText.replace( /\n\n+/g, '\n\n' ); +} diff --git a/packages/block-editor/src/utils/use-notify-copy.js b/packages/block-editor/src/utils/use-notify-copy.js new file mode 100644 index 00000000000000..0f98577f11bf65 --- /dev/null +++ b/packages/block-editor/src/utils/use-notify-copy.js @@ -0,0 +1,63 @@ +/** + * WordPress dependencies + */ +import { useCallback } from '@wordpress/element'; +import { store as blocksStore } from '@wordpress/blocks'; +import { useDispatch, useSelect } from '@wordpress/data'; +import { __, _n, sprintf } from '@wordpress/i18n'; +import { store as noticesStore } from '@wordpress/notices'; + +/** + * Internal dependencies + */ +import { store as blockEditorStore } from '../store'; + +export function useNotifyCopy() { + const { getBlockName } = useSelect( blockEditorStore ); + const { getBlockType } = useSelect( blocksStore ); + const { createSuccessNotice } = useDispatch( noticesStore ); + + return useCallback( ( eventType, selectedBlockClientIds ) => { + let notice = ''; + if ( selectedBlockClientIds.length === 1 ) { + const clientId = selectedBlockClientIds[ 0 ]; + const title = getBlockType( getBlockName( clientId ) )?.title; + notice = + eventType === 'copy' + ? sprintf( + // Translators: Name of the block being copied, e.g. "Paragraph". + __( 'Copied "%s" to clipboard.' ), + title + ) + : sprintf( + // Translators: Name of the block being cut, e.g. "Paragraph". + __( 'Moved "%s" to clipboard.' ), + title + ); + } else { + notice = + eventType === 'copy' + ? sprintf( + // Translators: %d: Number of blocks being copied. + _n( + 'Copied %d block to clipboard.', + 'Copied %d blocks to clipboard.', + selectedBlockClientIds.length + ), + selectedBlockClientIds.length + ) + : sprintf( + // Translators: %d: Number of blocks being cut. + _n( + 'Moved %d block to clipboard.', + 'Moved %d blocks to clipboard.', + selectedBlockClientIds.length + ), + selectedBlockClientIds.length + ); + } + createSuccessNotice( notice, { + type: 'snackbar', + } ); + }, [] ); +} diff --git a/packages/edit-widgets/src/components/widget-areas-block-editor-provider/index.js b/packages/edit-widgets/src/components/widget-areas-block-editor-provider/index.js index f3a7b84d5ded68..d538e37ad1ec8a 100644 --- a/packages/edit-widgets/src/components/widget-areas-block-editor-provider/index.js +++ b/packages/edit-widgets/src/components/widget-areas-block-editor-provider/index.js @@ -10,10 +10,7 @@ import { useResourcePermissions, } from '@wordpress/core-data'; import { useMemo } from '@wordpress/element'; -import { - CopyHandler, - privateApis as blockEditorPrivateApis, -} from '@wordpress/block-editor'; +import { privateApis as blockEditorPrivateApis } from '@wordpress/block-editor'; import { privateApis as editPatternsPrivateApis } from '@wordpress/patterns'; import { store as preferencesStore } from '@wordpress/preferences'; @@ -107,7 +104,7 @@ export default function WidgetAreasBlockEditorProvider( { useSubRegistry={ false } { ...props } > - { children } + { children }