From 62c1f50704d7b2235a525e121d5ee6ea0bc449e1 Mon Sep 17 00:00:00 2001 From: Kai Hao Date: Mon, 18 Sep 2023 16:32:25 +0800 Subject: [PATCH 01/28] Fix React forwardRef warnings for `TooltipAnchor`s (#54492) * Forward refs for SVG and Icon components * Address code review * Fix unit test * Add changelog --- packages/icons/CHANGELOG.md | 4 +++ packages/icons/src/icon/index.js | 14 +++++---- packages/primitives/CHANGELOG.md | 4 +++ packages/primitives/src/svg/index.js | 44 +++++++++++++++------------- 4 files changed, 40 insertions(+), 26 deletions(-) diff --git a/packages/icons/CHANGELOG.md b/packages/icons/CHANGELOG.md index 3c1715455ad497..ec07610cee52d4 100644 --- a/packages/icons/CHANGELOG.md +++ b/packages/icons/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +### Enhancement + +- `` now forwards ref to the underlying child component ([#54492](https://github.com/WordPress/gutenberg/pull/54492)). + ## 9.32.0 (2023-08-31) ### Bug Fix diff --git a/packages/icons/src/icon/index.js b/packages/icons/src/icon/index.js index e8bd1477dcd025..c83a5179a41b8e 100644 --- a/packages/icons/src/icon/index.js +++ b/packages/icons/src/icon/index.js @@ -1,25 +1,27 @@ /** * WordPress dependencies */ -import { cloneElement } from '@wordpress/element'; +import { cloneElement, forwardRef } from '@wordpress/element'; /** @typedef {{icon: JSX.Element, size?: number} & import('@wordpress/primitives').SVGProps} IconProps */ /** * Return an SVG icon. * - * @param {IconProps} props icon is the SVG component to render - * size is a number specifiying the icon size in pixels - * Other props will be passed to wrapped SVG component + * @param {IconProps} props icon is the SVG component to render + * size is a number specifiying the icon size in pixels + * Other props will be passed to wrapped SVG component + * @param {import('react').ForwardedRef} ref The forwarded ref to the SVG element. * * @return {JSX.Element} Icon component */ -function Icon( { icon, size = 24, ...props } ) { +function Icon( { icon, size = 24, ...props }, ref ) { return cloneElement( icon, { width: size, height: size, ...props, + ref, } ); } -export default Icon; +export default forwardRef( Icon ); diff --git a/packages/primitives/CHANGELOG.md b/packages/primitives/CHANGELOG.md index 6beb37c1b9dd8a..a762a52ffbf974 100644 --- a/packages/primitives/CHANGELOG.md +++ b/packages/primitives/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +### Enhancement + +- `` now forwards ref to the underlying `` element ([#54492](https://github.com/WordPress/gutenberg/pull/54492)). + ## 3.39.0 (2023-08-31) ## 3.38.0 (2023-08-16) diff --git a/packages/primitives/src/svg/index.js b/packages/primitives/src/svg/index.js index 79a5e7f58e55d6..420432d0543e13 100644 --- a/packages/primitives/src/svg/index.js +++ b/packages/primitives/src/svg/index.js @@ -6,7 +6,7 @@ import classnames from 'classnames'; /** * WordPress dependencies */ -import { createElement } from '@wordpress/element'; +import { createElement, forwardRef } from '@wordpress/element'; /** @typedef {{isPressed?: boolean} & import('react').ComponentPropsWithoutRef<'svg'>} SVGProps */ @@ -82,23 +82,27 @@ export const LinearGradient = ( props ) => */ export const Stop = ( props ) => createElement( 'stop', props ); -/** - * - * @param {SVGProps} props isPressed indicates whether the SVG should appear as pressed. - * Other props will be passed through to svg component. - * - * @return {JSX.Element} Stop component - */ -export const SVG = ( { className, isPressed, ...props } ) => { - const appliedProps = { - ...props, - className: - classnames( className, { 'is-pressed': isPressed } ) || undefined, - 'aria-hidden': true, - focusable: false, - }; +export const SVG = forwardRef( + /** + * @param {SVGProps} props isPressed indicates whether the SVG should appear as pressed. + * Other props will be passed through to svg component. + * @param {import('react').ForwardedRef} ref The forwarded ref to the SVG element. + * + * @return {JSX.Element} Stop component + */ + ( { className, isPressed, ...props }, ref ) => { + const appliedProps = { + ...props, + className: + classnames( className, { 'is-pressed': isPressed } ) || + undefined, + 'aria-hidden': true, + focusable: false, + }; - // Disable reason: We need to have a way to render HTML tag for web. - // eslint-disable-next-line react/forbid-elements - return ; -}; + // Disable reason: We need to have a way to render HTML tag for web. + // eslint-disable-next-line react/forbid-elements + return ; + } +); +SVG.displayName = 'SVG'; From 6db51a6ee92db6c3324a875135656861bbd9e55d Mon Sep 17 00:00:00 2001 From: Aki Hamano <54422211+t-hamano@users.noreply.github.com> Date: Mon, 18 Sep 2023 18:17:30 +0900 Subject: [PATCH 02/28] Theme JSON schema: Fix "not allowed error" in settings property (#54521) --- schemas/json/theme.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/schemas/json/theme.json b/schemas/json/theme.json index e0f3efc01eb1fc..5a0b049f6d0d5d 100644 --- a/schemas/json/theme.json +++ b/schemas/json/theme.json @@ -298,7 +298,6 @@ }, "settingsPropertiesLightbox": { "type": "object", - "additionalProperties": false, "properties": { "lightbox": { "description": "Settings related to the lightbox.", @@ -312,7 +311,8 @@ "description": "Defines whether to show the Lightbox UI in the block editor. If set to `false`, the user won't be able to change the lightbox settings in the block editor.", "type": "boolean" } - } + }, + "additionalProperties": false } } }, From 65e9bf49029ba30d93b5d07c97b2fcb07cd7aca8 Mon Sep 17 00:00:00 2001 From: Ramon Date: Mon, 18 Sep 2023 20:29:13 +1000 Subject: [PATCH 03/28] Site editor: consolidate constants (#54484) * Consolidating constants in the edit-site package. Primarily hoisting pattern constants and removing duplicates. * Making the constant names consistent with edit site constants * Move constant definition to patterns package so it can be shared with block editor * Using named prop for post type labels Added clarification comment to category filtering. --------- Co-authored-by: Glen Davies --- .../src/components/add-new-template/index.js | 5 ++- .../add-new-template/new-template.js | 7 +++- .../src/components/add-new-template/utils.js | 15 +++++-- .../components/block-editor/back-button.js | 8 +++- .../edit-site/src/components/editor/index.js | 11 ++--- .../page-patterns/duplicate-menu-item.js | 26 +++++++----- .../src/components/page-patterns/grid-item.js | 27 ++++++++---- .../src/components/page-patterns/header.js | 6 +-- .../src/components/page-patterns/index.js | 6 +-- .../components/page-patterns/patterns-list.js | 14 +++---- .../page-patterns/rename-menu-item.js | 8 ++-- .../components/page-patterns/search-items.js | 8 ++-- .../components/page-patterns/use-patterns.js | 33 ++++++++------- .../src/components/page-patterns/utils.js | 19 --------- .../index.js | 10 ++--- .../use-pattern-categories.js | 6 +-- .../use-theme-patterns.js | 8 ++-- packages/edit-site/src/utils/constants.js | 41 +++++++++++++++++-- .../src/utils/is-template-removable.js | 9 +++- .../src/utils/is-template-revertable.js | 9 +++- .../src/components/create-pattern-modal.js | 22 +++++----- packages/patterns/src/constants.js | 16 ++++++++ packages/patterns/src/private-apis.js | 10 +++++ packages/patterns/src/store/actions.js | 7 +++- 24 files changed, 209 insertions(+), 122 deletions(-) create mode 100644 packages/patterns/src/constants.js diff --git a/packages/edit-site/src/components/add-new-template/index.js b/packages/edit-site/src/components/add-new-template/index.js index ffdf1b89376903..1f1e855ccf38d3 100644 --- a/packages/edit-site/src/components/add-new-template/index.js +++ b/packages/edit-site/src/components/add-new-template/index.js @@ -8,9 +8,10 @@ import { store as coreStore } from '@wordpress/core-data'; * Internal dependencies */ import NewTemplate from './new-template'; +import { TEMPLATE_POST_TYPE } from '../../utils/constants'; export default function AddNewTemplate( { - templateType = 'wp_template', + templateType = TEMPLATE_POST_TYPE, ...props } ) { const postType = useSelect( @@ -22,7 +23,7 @@ export default function AddNewTemplate( { return null; } - if ( templateType === 'wp_template' ) { + if ( templateType === TEMPLATE_POST_TYPE ) { return ; } diff --git a/packages/edit-site/src/components/add-new-template/new-template.js b/packages/edit-site/src/components/add-new-template/new-template.js index 31ddd754562dbf..377b26a8106e50 100644 --- a/packages/edit-site/src/components/add-new-template/new-template.js +++ b/packages/edit-site/src/components/add-new-template/new-template.js @@ -42,6 +42,11 @@ import { __, sprintf } from '@wordpress/i18n'; import { store as noticesStore } from '@wordpress/notices'; import { privateApis as routerPrivateApis } from '@wordpress/router'; +/** + * Internal dependencies + */ +import { TEMPLATE_POST_TYPE } from '../../utils/constants'; + /** * Internal dependencies */ @@ -190,7 +195,7 @@ export default function NewTemplate( { const { title, description, slug } = template; const newTemplate = await saveEntityRecord( 'postType', - 'wp_template', + TEMPLATE_POST_TYPE, { description, // Slugs need to be strings, so this is for template `404` diff --git a/packages/edit-site/src/components/add-new-template/utils.js b/packages/edit-site/src/components/add-new-template/utils.js index 1869cdb72f5929..f94c230196053a 100644 --- a/packages/edit-site/src/components/add-new-template/utils.js +++ b/packages/edit-site/src/components/add-new-template/utils.js @@ -9,6 +9,11 @@ import { useMemo, useCallback } from '@wordpress/element'; import { __, sprintf } from '@wordpress/i18n'; import { blockMeta, post, archive } from '@wordpress/icons'; +/** + * Internal dependencies + */ +import { TEMPLATE_POST_TYPE } from '../../utils/constants'; + /** * @typedef IHasNameAndId * @property {string|number} id The entity's id. @@ -48,9 +53,13 @@ export const mapToIHasNameAndId = ( entities, path ) => { export const useExistingTemplates = () => { return useSelect( ( select ) => - select( coreStore ).getEntityRecords( 'postType', 'wp_template', { - per_page: -1, - } ), + select( coreStore ).getEntityRecords( + 'postType', + TEMPLATE_POST_TYPE, + { + per_page: -1, + } + ), [] ); }; diff --git a/packages/edit-site/src/components/block-editor/back-button.js b/packages/edit-site/src/components/block-editor/back-button.js index ebe5af44c0250c..924dedd4f853e1 100644 --- a/packages/edit-site/src/components/block-editor/back-button.js +++ b/packages/edit-site/src/components/block-editor/back-button.js @@ -9,6 +9,10 @@ import { privateApis as routerPrivateApis } from '@wordpress/router'; /** * Internal dependencies */ +import { + TEMPLATE_PART_POST_TYPE, + NAVIGATION_POST_TYPE, +} from '../../utils/constants'; import { unlock } from '../../lock-unlock'; const { useLocation, useHistory } = unlock( routerPrivateApis ); @@ -16,8 +20,8 @@ const { useLocation, useHistory } = unlock( routerPrivateApis ); function BackButton() { const location = useLocation(); const history = useHistory(); - const isTemplatePart = location.params.postType === 'wp_template_part'; - const isNavigationMenu = location.params.postType === 'wp_navigation'; + const isTemplatePart = location.params.postType === TEMPLATE_PART_POST_TYPE; + const isNavigationMenu = location.params.postType === NAVIGATION_POST_TYPE; const previousTemplateId = location.state?.fromTemplateId; const isFocusMode = isTemplatePart || isNavigationMenu; diff --git a/packages/edit-site/src/components/editor/index.js b/packages/edit-site/src/components/editor/index.js index 4bdd98b5d170e9..25fcbff830553e 100644 --- a/packages/edit-site/src/components/editor/index.js +++ b/packages/edit-site/src/components/editor/index.js @@ -44,6 +44,7 @@ import CanvasLoader from '../canvas-loader'; import { unlock } from '../../lock-unlock'; import useEditedEntityRecord from '../use-edited-entity-record'; import { SidebarFixedBottomSlot } from '../sidebar-edit-mode/sidebar-fixed-bottom'; +import { POST_TYPE_LABELS, TEMPLATE_POST_TYPE } from '../../utils/constants'; const { BlockRemovalWarningModal } = unlock( blockEditorPrivateApis ); @@ -58,13 +59,6 @@ const interfaceLabels = { footer: __( 'Editor footer' ), }; -const typeLabels = { - wp_template: __( 'Template' ), - wp_template_part: __( 'Template Part' ), - wp_block: __( 'Pattern' ), - wp_navigation: __( 'Navigation' ), -}; - // Prevent accidental removal of certain blocks, asking the user for // confirmation. const blockRemovalRules = { @@ -171,7 +165,8 @@ export default function Editor( { isLoading } ) { // translators: A breadcrumb trail in browser tab. %1$s: title of template being edited, %2$s: type of template (Template or Template Part). __( '%1$s ‹ %2$s ‹ Editor' ), getTitle(), - typeLabels[ editedPostType ] ?? typeLabels.wp_template + POST_TYPE_LABELS[ editedPostType ] ?? + POST_TYPE_LABELS[ TEMPLATE_POST_TYPE ] ); } diff --git a/packages/edit-site/src/components/page-patterns/duplicate-menu-item.js b/packages/edit-site/src/components/page-patterns/duplicate-menu-item.js index 324b22e460447e..c562ffbeeb6c83 100644 --- a/packages/edit-site/src/components/page-patterns/duplicate-menu-item.js +++ b/packages/edit-site/src/components/page-patterns/duplicate-menu-item.js @@ -11,7 +11,11 @@ import { privateApis as routerPrivateApis } from '@wordpress/router'; /** * Internal dependencies */ -import { TEMPLATE_PARTS, PATTERNS, SYNC_TYPES, USER_PATTERNS } from './utils'; +import { + TEMPLATE_PART_POST_TYPE, + PATTERN_TYPES, + PATTERN_SYNC_TYPES, +} from '../../utils/constants'; import { useExistingTemplateParts, getUniqueTemplatePartTitle, @@ -23,12 +27,12 @@ import usePatternCategories from '../sidebar-navigation-screen-patterns/use-patt const { useHistory } = unlock( routerPrivateApis ); function getPatternMeta( item ) { - if ( item.type === PATTERNS ) { - return { wp_pattern_sync_status: SYNC_TYPES.unsynced }; + if ( item.type === PATTERN_TYPES.theme ) { + return { wp_pattern_sync_status: PATTERN_SYNC_TYPES.unsynced }; } const syncStatus = item.patternBlock.wp_pattern_sync_status; - const isUnsynced = syncStatus === SYNC_TYPES.unsynced; + const isUnsynced = syncStatus === PATTERN_SYNC_TYPES.unsynced; return { ...item.patternBlock.meta, @@ -84,9 +88,9 @@ export default function DuplicateMenuItem( { ); history.push( { - postType: TEMPLATE_PARTS, + postType: TEMPLATE_PART_POST_TYPE, postId: result?.id, - categoryType: TEMPLATE_PARTS, + categoryType: TEMPLATE_PART_POST_TYPE, categoryId, } ); @@ -148,7 +152,7 @@ export default function DuplicateMenuItem( { async function createPattern() { try { - const isThemePattern = item.type === PATTERNS; + const isThemePattern = item.type === PATTERN_TYPES.theme; const title = sprintf( /* translators: %s: Existing pattern title */ __( '%s (Copy)' ), @@ -184,9 +188,9 @@ export default function DuplicateMenuItem( { ); history.push( { - categoryType: PATTERNS, + categoryType: PATTERN_TYPES.theme, categoryId, - postType: USER_PATTERNS, + postType: PATTERN_TYPES.user, postId: result?.id, } ); @@ -206,7 +210,9 @@ export default function DuplicateMenuItem( { } const createItem = - item.type === TEMPLATE_PARTS ? createTemplatePart : createPattern; + item.type === TEMPLATE_PART_POST_TYPE + ? createTemplatePart + : createPattern; return { label }; } diff --git a/packages/edit-site/src/components/page-patterns/grid-item.js b/packages/edit-site/src/components/page-patterns/grid-item.js index 25aab2646cdfd0..5f79067f6ed299 100644 --- a/packages/edit-site/src/components/page-patterns/grid-item.js +++ b/packages/edit-site/src/components/page-patterns/grid-item.js @@ -38,7 +38,11 @@ import { store as reusableBlocksStore } from '@wordpress/reusable-blocks'; */ import RenameMenuItem from './rename-menu-item'; import DuplicateMenuItem from './duplicate-menu-item'; -import { PATTERNS, TEMPLATE_PARTS, USER_PATTERNS, SYNC_TYPES } from './utils'; +import { + PATTERN_TYPES, + TEMPLATE_PART_POST_TYPE, + PATTERN_SYNC_TYPES, +} from '../../utils/constants'; import { store as editSiteStore } from '../../store'; import { useLink } from '../routes/link'; @@ -54,9 +58,9 @@ function GridItem( { categoryId, item, ...props } ) { const { createErrorNotice, createSuccessNotice } = useDispatch( noticesStore ); - const isUserPattern = item.type === USER_PATTERNS; - const isNonUserPattern = item.type === PATTERNS; - const isTemplatePart = item.type === TEMPLATE_PARTS; + const isUserPattern = item.type === PATTERN_TYPES.user; + const isNonUserPattern = item.type === PATTERN_TYPES.theme; + const isTemplatePart = item.type === TEMPLATE_PART_POST_TYPE; const { onClick } = useLink( { postType: item.type, @@ -123,7 +127,8 @@ function GridItem( { categoryId, item, ...props } ) { if ( ! isUserPattern && templatePartIcons[ categoryId ] ) { itemIcon = templatePartIcons[ categoryId ]; } else { - itemIcon = item.syncStatus === SYNC_TYPES.full ? symbol : undefined; + itemIcon = + item.syncStatus === PATTERN_SYNC_TYPES.full ? symbol : undefined; } const confirmButtonText = hasThemeFile ? __( 'Clear' ) : __( 'Delete' ); @@ -143,8 +148,12 @@ function GridItem( { categoryId, item, ...props } ) { // @see https://reakit.io/docs/composite/#performance. id={ `edit-site-patterns-${ item.name }` } { ...props } - onClick={ item.type !== PATTERNS ? onClick : undefined } - aria-disabled={ item.type !== PATTERNS ? 'false' : 'true' } + onClick={ + item.type !== PATTERN_TYPES.theme ? onClick : undefined + } + aria-disabled={ + item.type !== PATTERN_TYPES.theme ? 'false' : 'true' + } aria-label={ item.title } aria-describedby={ ariaDescriptions.length @@ -194,7 +203,7 @@ function GridItem( { categoryId, item, ...props } ) { ) } - { item.type === PATTERNS ? ( + { item.type === PATTERN_TYPES.theme ? ( item.title ) : ( @@ -209,7 +218,7 @@ function GridItem( { categoryId, item, ...props } ) { ) } - { item.type === PATTERNS && ( + { item.type === PATTERN_TYPES.theme && ( area.area === categoryId ); title = templatePartArea?.label; description = templatePartArea?.description; - } else if ( type === PATTERNS ) { + } else if ( type === PATTERN_TYPES.theme ) { const patternCategory = patternCategories.find( ( category ) => category.name === categoryId ); diff --git a/packages/edit-site/src/components/page-patterns/index.js b/packages/edit-site/src/components/page-patterns/index.js index d90fc748442444..6861b26d653870 100644 --- a/packages/edit-site/src/components/page-patterns/index.js +++ b/packages/edit-site/src/components/page-patterns/index.js @@ -8,7 +8,7 @@ import { getQueryArgs } from '@wordpress/url'; /** * Internal dependencies */ -import { DEFAULT_CATEGORY, DEFAULT_TYPE } from './utils'; +import { PATTERN_DEFAULT_CATEGORY, PATTERN_TYPES } from '../../utils/constants'; import Page from '../page'; import PatternsList from './patterns-list'; import usePatternSettings from './use-pattern-settings'; @@ -18,8 +18,8 @@ const { ExperimentalBlockEditorProvider } = unlock( blockEditorPrivateApis ); export default function PagePatterns() { const { categoryType, categoryId } = getQueryArgs( window.location.href ); - const type = categoryType || DEFAULT_TYPE; - const category = categoryId || DEFAULT_CATEGORY; + const type = categoryType || PATTERN_TYPES.user; + const category = categoryId || PATTERN_DEFAULT_CATEGORY; const settings = usePatternSettings(); // Wrap everything in a block editor provider. diff --git a/packages/edit-site/src/components/page-patterns/patterns-list.js b/packages/edit-site/src/components/page-patterns/patterns-list.js index 57c342ca3caa9c..95e6824c58144a 100644 --- a/packages/edit-site/src/components/page-patterns/patterns-list.js +++ b/packages/edit-site/src/components/page-patterns/patterns-list.js @@ -27,23 +27,23 @@ import usePatterns from './use-patterns'; import SidebarButton from '../sidebar-button'; import useDebouncedInput from '../../utils/use-debounced-input'; import { unlock } from '../../lock-unlock'; -import { SYNC_TYPES, PATTERNS } from './utils'; +import { PATTERN_SYNC_TYPES, PATTERN_TYPES } from '../../utils/constants'; import Pagination from './pagination'; const { useLocation, useHistory } = unlock( routerPrivateApis ); const SYNC_FILTERS = { all: __( 'All' ), - [ SYNC_TYPES.full ]: __( 'Synced' ), - [ SYNC_TYPES.unsynced ]: __( 'Standard' ), + [ PATTERN_SYNC_TYPES.full ]: __( 'Synced' ), + [ PATTERN_SYNC_TYPES.unsynced ]: __( 'Standard' ), }; const SYNC_DESCRIPTIONS = { all: '', - [ SYNC_TYPES.full ]: __( + [ PATTERN_SYNC_TYPES.full ]: __( 'Patterns that are kept in sync across the site.' ), - [ SYNC_TYPES.unsynced ]: __( + [ PATTERN_SYNC_TYPES.unsynced ]: __( 'Patterns that can be changed freely without affecting the site.' ), }; @@ -64,7 +64,7 @@ export default function PatternsList( { categoryId, type } ) { const deferredSyncedFilter = useDeferredValue( syncFilter ); const isUncategorizedThemePatterns = - type === PATTERNS && categoryId === 'uncategorized'; + type === PATTERN_TYPES.theme && categoryId === 'uncategorized'; const { patterns, isResolving } = usePatterns( type, @@ -155,7 +155,7 @@ export default function PatternsList( { categoryId, type } ) { __nextHasNoMarginBottom /> - { type === PATTERNS && ( + { type === PATTERN_TYPES.theme && ( item.title ); @@ -29,7 +29,7 @@ export default function RenameMenuItem( { item, onClose } ) { const { createSuccessNotice, createErrorNotice } = useDispatch( noticesStore ); - if ( item.type === TEMPLATE_PARTS && ! item.isCustom ) { + if ( item.type === TEMPLATE_PART_POST_TYPE && ! item.isCustom ) { return null; } @@ -50,7 +50,7 @@ export default function RenameMenuItem( { item, onClose } ) { } ); createSuccessNotice( - item.type === TEMPLATE_PARTS + item.type === TEMPLATE_PART_POST_TYPE ? __( 'Template part renamed.' ) : __( 'Pattern renamed.' ), { @@ -59,7 +59,7 @@ export default function RenameMenuItem( { item, onClose } ) { ); } catch ( error ) { const fallbackErrorMessage = - item.type === TEMPLATE_PARTS + item.type === TEMPLATE_PART_POST_TYPE ? __( 'An error occurred while reverting the template part.' ) diff --git a/packages/edit-site/src/components/page-patterns/search-items.js b/packages/edit-site/src/components/page-patterns/search-items.js index 4ba9b9356af3cb..3c9beca587c24f 100644 --- a/packages/edit-site/src/components/page-patterns/search-items.js +++ b/packages/edit-site/src/components/page-patterns/search-items.js @@ -7,7 +7,7 @@ import { noCase } from 'change-case'; /** * Internal dependencies */ -import { ALL_PATTERNS_CATEGORY } from './utils'; +import { PATTERN_DEFAULT_CATEGORY } from '../../utils/constants'; // Default search helpers. const defaultGetName = ( item ) => item.name || ''; @@ -89,8 +89,9 @@ const removeMatchingTerms = ( unmatchedTerms, unprocessedTerms ) => { */ export const searchItems = ( items = [], searchInput = '', config = {} ) => { const normalizedSearchTerms = getNormalizedSearchTerms( searchInput ); + // Filter patterns by category: the default category indicates that all patterns will be shown. const onlyFilterByCategory = - config.categoryId !== ALL_PATTERNS_CATEGORY && + config.categoryId !== PATTERN_DEFAULT_CATEGORY && ! normalizedSearchTerms.length; const searchRankConfig = { ...config, onlyFilterByCategory }; @@ -139,7 +140,8 @@ function getItemSearchRank( item, searchTerm, config ) { } = config; let rank = - categoryId === ALL_PATTERNS_CATEGORY || hasCategory( item, categoryId ) + categoryId === PATTERN_DEFAULT_CATEGORY || + hasCategory( item, categoryId ) ? 1 : 0; diff --git a/packages/edit-site/src/components/page-patterns/use-patterns.js b/packages/edit-site/src/components/page-patterns/use-patterns.js index 25919d55567108..42455d201a87ca 100644 --- a/packages/edit-site/src/components/page-patterns/use-patterns.js +++ b/packages/edit-site/src/components/page-patterns/use-patterns.js @@ -10,14 +10,13 @@ import { decodeEntities } from '@wordpress/html-entities'; /** * Internal dependencies */ +import { filterOutDuplicatesByName } from './utils'; import { - CORE_PATTERN_SOURCES, - PATTERNS, - SYNC_TYPES, - TEMPLATE_PARTS, - USER_PATTERNS, - filterOutDuplicatesByName, -} from './utils'; + PATTERN_CORE_SOURCES, + PATTERN_TYPES, + PATTERN_SYNC_TYPES, + TEMPLATE_PART_POST_TYPE, +} from '../../utils/constants'; import { unlock } from '../../lock-unlock'; import { searchItems } from './search-items'; import { store as editSiteStore } from '../../store'; @@ -50,7 +49,7 @@ const selectTemplatePartsAsPatterns = ( const { __experimentalGetDefaultTemplatePartAreas } = select( editorStore ); const query = { per_page: -1 }; const rawTemplateParts = - getEntityRecords( 'postType', TEMPLATE_PARTS, query ) ?? + getEntityRecords( 'postType', TEMPLATE_PART_POST_TYPE, query ) ?? EMPTY_PATTERN_LIST; const templateParts = rawTemplateParts.map( ( templatePart ) => templatePartToPattern( templatePart ) @@ -101,14 +100,14 @@ const selectThemePatterns = ( select ) => { ...( restBlockPatterns || [] ), ] .filter( - ( pattern ) => ! CORE_PATTERN_SOURCES.includes( pattern.source ) + ( pattern ) => ! PATTERN_CORE_SOURCES.includes( pattern.source ) ) .filter( filterOutDuplicatesByName ) .filter( ( pattern ) => pattern.inserter !== false ) .map( ( pattern ) => ( { ...pattern, keywords: pattern.keywords || [], - type: 'pattern', + type: PATTERN_TYPES.theme, blocks: parse( pattern.content, { __unstableSkipMigrationLogs: true, } ), @@ -159,9 +158,9 @@ const patternBlockToPattern = ( patternBlock, categories ) => ( { } ), id: patternBlock.id, name: patternBlock.slug, - syncStatus: patternBlock.wp_pattern_sync_status || SYNC_TYPES.full, + syncStatus: patternBlock.wp_pattern_sync_status || PATTERN_SYNC_TYPES.full, title: patternBlock.title.raw, - type: USER_PATTERNS, + type: PATTERN_TYPES.user, patternBlock, } ); @@ -170,7 +169,7 @@ const selectUserPatterns = ( select, { search = '', syncStatus } = {} ) => { select( coreStore ); const query = { per_page: -1 }; - const records = getEntityRecords( 'postType', USER_PATTERNS, query ); + const records = getEntityRecords( 'postType', PATTERN_TYPES.user, query ); const categories = getUserPatternCategories(); let patterns = records @@ -181,7 +180,7 @@ const selectUserPatterns = ( select, { search = '', syncStatus } = {} ) => { const isResolving = getIsResolving( 'getEntityRecords', [ 'postType', - USER_PATTERNS, + PATTERN_TYPES.user, query, ] ); @@ -208,18 +207,18 @@ export const usePatterns = ( ) => { return useSelect( ( select ) => { - if ( categoryType === TEMPLATE_PARTS ) { + if ( categoryType === TEMPLATE_PART_POST_TYPE ) { return selectTemplatePartsAsPatterns( select, { categoryId, search, } ); - } else if ( categoryType === PATTERNS ) { + } else if ( categoryType === PATTERN_TYPES.theme ) { return selectPatterns( select, { categoryId, search, syncStatus, } ); - } else if ( categoryType === USER_PATTERNS ) { + } else if ( categoryType === PATTERN_TYPES.user ) { return selectUserPatterns( select, { search, syncStatus } ); } return { patterns: EMPTY_PATTERN_LIST, isResolving: false }; diff --git a/packages/edit-site/src/components/page-patterns/utils.js b/packages/edit-site/src/components/page-patterns/utils.js index 5ed57982e7cf16..f400d9855c5136 100644 --- a/packages/edit-site/src/components/page-patterns/utils.js +++ b/packages/edit-site/src/components/page-patterns/utils.js @@ -1,21 +1,2 @@ -export const ALL_PATTERNS_CATEGORY = 'all-patterns'; -export const DEFAULT_CATEGORY = ALL_PATTERNS_CATEGORY; -export const PATTERNS = 'pattern'; -export const DEFAULT_TYPE = PATTERNS; -export const TEMPLATE_PARTS = 'wp_template_part'; -export const USER_PATTERNS = 'wp_block'; - -export const CORE_PATTERN_SOURCES = [ - 'core', - 'pattern-directory/core', - 'pattern-directory/featured', - 'pattern-directory/theme', -]; - -export const SYNC_TYPES = { - full: 'fully', - unsynced: 'unsynced', -}; - export const filterOutDuplicatesByName = ( currentItem, index, items ) => index === items.findIndex( ( item ) => currentItem.name === item.name ); diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-patterns/index.js b/packages/edit-site/src/components/sidebar-navigation-screen-patterns/index.js index 0f77cd8e5c1af2..0b7be99812dd67 100644 --- a/packages/edit-site/src/components/sidebar-navigation-screen-patterns/index.js +++ b/packages/edit-site/src/components/sidebar-navigation-screen-patterns/index.js @@ -19,7 +19,7 @@ import AddNewPattern from '../add-new-pattern'; import SidebarNavigationItem from '../sidebar-navigation-item'; import SidebarNavigationScreen from '../sidebar-navigation-screen'; import CategoryItem from './category-item'; -import { DEFAULT_CATEGORY, DEFAULT_TYPE } from '../page-patterns/utils'; +import { PATTERN_DEFAULT_CATEGORY, PATTERN_TYPES } from '../../utils/constants'; import { useLink } from '../routes/link'; import usePatternCategories from './use-pattern-categories'; import useTemplatePartAreas from './use-template-part-areas'; @@ -70,8 +70,8 @@ function PatternCategoriesGroup( { type="pattern" isActive={ currentCategory === `${ category.name }` && - ( currentType === 'pattern' || - currentType === 'wp_block' ) + ( currentType === PATTERN_TYPES.theme || + currentType === PATTERN_TYPES.user ) } /> ) ) } @@ -83,8 +83,8 @@ function PatternCategoriesGroup( { export default function SidebarNavigationScreenPatterns() { const isMobileViewport = useViewportMatch( 'medium', '<' ); const { categoryType, categoryId } = getQueryArgs( window.location.href ); - const currentCategory = categoryId || DEFAULT_CATEGORY; - const currentType = categoryType || DEFAULT_TYPE; + const currentCategory = categoryId || PATTERN_DEFAULT_CATEGORY; + const currentType = categoryType || PATTERN_TYPES.user; const { templatePartAreas, hasTemplateParts, isLoading } = useTemplatePartAreas(); diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-patterns/use-pattern-categories.js b/packages/edit-site/src/components/sidebar-navigation-screen-patterns/use-pattern-categories.js index e3ab86e8b06151..367b293f2206dc 100644 --- a/packages/edit-site/src/components/sidebar-navigation-screen-patterns/use-pattern-categories.js +++ b/packages/edit-site/src/components/sidebar-navigation-screen-patterns/use-pattern-categories.js @@ -10,7 +10,7 @@ import { __ } from '@wordpress/i18n'; import useDefaultPatternCategories from './use-default-pattern-categories'; import useThemePatterns from './use-theme-patterns'; import usePatterns from '../page-patterns/use-patterns'; -import { USER_PATTERNS, ALL_PATTERNS_CATEGORY } from '../page-patterns/utils'; +import { PATTERN_TYPES, PATTERN_DEFAULT_CATEGORY } from '../../utils/constants'; export default function usePatternCategories() { const defaultCategories = useDefaultPatternCategories(); @@ -20,7 +20,7 @@ export default function usePatternCategories() { } ); const themePatterns = useThemePatterns(); const { patterns: userPatterns, categories: userPatternCategories } = - usePatterns( USER_PATTERNS ); + usePatterns( PATTERN_TYPES.user ); const patternCategories = useMemo( () => { const categoryMap = {}; @@ -81,7 +81,7 @@ export default function usePatternCategories() { a.label.localeCompare( b.label ) ); sortedCategories.unshift( { - name: ALL_PATTERNS_CATEGORY, + name: PATTERN_DEFAULT_CATEGORY, label: __( 'All Patterns' ), description: __( 'A list of all patterns from all sources' ), count: themePatterns.length + userPatterns.length, diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-patterns/use-theme-patterns.js b/packages/edit-site/src/components/sidebar-navigation-screen-patterns/use-theme-patterns.js index bf6decf3414222..9e4983450ae5a3 100644 --- a/packages/edit-site/src/components/sidebar-navigation-screen-patterns/use-theme-patterns.js +++ b/packages/edit-site/src/components/sidebar-navigation-screen-patterns/use-theme-patterns.js @@ -8,10 +8,8 @@ import { useMemo } from '@wordpress/element'; /** * Internal dependencies */ -import { - CORE_PATTERN_SOURCES, - filterOutDuplicatesByName, -} from '../page-patterns/utils'; +import { filterOutDuplicatesByName } from '../page-patterns/utils'; +import { PATTERN_CORE_SOURCES } from '../../utils/constants'; import { unlock } from '../../lock-unlock'; import { store as editSiteStore } from '../../store'; @@ -34,7 +32,7 @@ export default function useThemePatterns() { [ ...( blockPatterns || [] ), ...( restBlockPatterns || [] ) ] .filter( ( pattern ) => - ! CORE_PATTERN_SOURCES.includes( pattern.source ) + ! PATTERN_CORE_SOURCES.includes( pattern.source ) ) .filter( filterOutDuplicatesByName ) .filter( ( pattern ) => pattern.inserter !== false ), diff --git a/packages/edit-site/src/utils/constants.js b/packages/edit-site/src/utils/constants.js index ed88c3e14c9473..d12c7f84cc356c 100644 --- a/packages/edit-site/src/utils/constants.js +++ b/packages/edit-site/src/utils/constants.js @@ -1,5 +1,40 @@ +/** + * WordPress dependencies + */ +import { __ } from '@wordpress/i18n'; +import { privateApis as patternPrivateApis } from '@wordpress/patterns'; + +/** + * Internal dependencies + */ +import { unlock } from '../lock-unlock'; + +// Navigation +export const NAVIGATION_POST_TYPE = 'wp_navigation'; + +// Templates. +export const TEMPLATE_POST_TYPE = 'wp_template'; +export const TEMPLATE_PART_POST_TYPE = 'wp_template_part'; +export const TEMPLATE_CUSTOM_SOURCE = 'custom'; + +// Patterns. +export const { + PATTERN_TYPES, + PATTERN_DEFAULT_CATEGORY, + PATTERN_CORE_SOURCES, + PATTERN_SYNC_TYPES, +} = unlock( patternPrivateApis ); + +// Entities that are editable in focus mode. export const FOCUSABLE_ENTITIES = [ - 'wp_template_part', - 'wp_navigation', - 'wp_block', + TEMPLATE_PART_POST_TYPE, + NAVIGATION_POST_TYPE, + PATTERN_TYPES.user, ]; + +export const POST_TYPE_LABELS = { + [ TEMPLATE_POST_TYPE ]: __( 'Template' ), + [ TEMPLATE_PART_POST_TYPE ]: __( 'Template Part' ), + [ PATTERN_TYPES.user ]: __( 'Pattern' ), + [ NAVIGATION_POST_TYPE ]: __( 'Navigation' ), +}; diff --git a/packages/edit-site/src/utils/is-template-removable.js b/packages/edit-site/src/utils/is-template-removable.js index 7ec203a9e0db56..02682e97334e59 100644 --- a/packages/edit-site/src/utils/is-template-removable.js +++ b/packages/edit-site/src/utils/is-template-removable.js @@ -1,3 +1,8 @@ +/** + * Internal dependencies + */ +import { TEMPLATE_CUSTOM_SOURCE } from './constants'; + /** * Check if a template is removable. * @@ -9,5 +14,7 @@ export default function isTemplateRemovable( template ) { return false; } - return template.source === 'custom' && ! template.has_theme_file; + return ( + template.source === TEMPLATE_CUSTOM_SOURCE && ! template.has_theme_file + ); } diff --git a/packages/edit-site/src/utils/is-template-revertable.js b/packages/edit-site/src/utils/is-template-revertable.js index c2d42f51c97018..89d1d8ea552a19 100644 --- a/packages/edit-site/src/utils/is-template-revertable.js +++ b/packages/edit-site/src/utils/is-template-revertable.js @@ -1,3 +1,8 @@ +/** + * Internal dependencies + */ +import { TEMPLATE_CUSTOM_SOURCE } from './constants'; + /** * Check if a template is revertable to its original theme-provided template file. * @@ -9,6 +14,8 @@ export default function isTemplateRevertable( template ) { return false; } /* eslint-disable camelcase */ - return template?.source === 'custom' && template?.has_theme_file; + return ( + template?.source === TEMPLATE_CUSTOM_SOURCE && template?.has_theme_file + ); /* eslint-enable camelcase */ } diff --git a/packages/patterns/src/components/create-pattern-modal.js b/packages/patterns/src/components/create-pattern-modal.js index 2b8d89cbfae368..44f08f53ba8765 100644 --- a/packages/patterns/src/components/create-pattern-modal.js +++ b/packages/patterns/src/components/create-pattern-modal.js @@ -14,12 +14,10 @@ import { useState, useCallback } from '@wordpress/element'; import { useDispatch } from '@wordpress/data'; import { store as noticesStore } from '@wordpress/notices'; -export const ALL_PATTERNS_CATEGORY = 'all-patterns'; - -export const SYNC_TYPES = { - full: undefined, - unsynced: 'unsynced', -}; +/** + * Internal dependencies + */ +import { PATTERN_DEFAULT_CATEGORY, PATTERN_SYNC_TYPES } from '../constants'; /** * Internal dependencies @@ -34,7 +32,7 @@ export default function CreatePatternModal( { onClose, className = 'patterns-menu-items__convert-modal', } ) { - const [ syncType, setSyncType ] = useState( SYNC_TYPES.full ); + const [ syncType, setSyncType ] = useState( PATTERN_SYNC_TYPES.full ); const [ categories, setCategories ] = useState( [] ); const [ title, setTitle ] = useState( '' ); const { createPattern } = useDispatch( store ); @@ -51,7 +49,7 @@ export default function CreatePatternModal( { ); onSuccess( { pattern: newPattern, - categoryId: ALL_PATTERNS_CATEGORY, + categoryId: PATTERN_DEFAULT_CATEGORY, } ); } catch ( error ) { createErrorNotice( error.message, { @@ -108,12 +106,12 @@ export default function CreatePatternModal( { help={ __( 'Editing the pattern will update it anywhere it is used.' ) } - checked={ ! syncType } + checked={ syncType === PATTERN_SYNC_TYPES.full } onChange={ () => { setSyncType( - syncType === SYNC_TYPES.full - ? SYNC_TYPES.unsynced - : SYNC_TYPES.full + syncType === PATTERN_SYNC_TYPES.full + ? PATTERN_SYNC_TYPES.unsynced + : PATTERN_SYNC_TYPES.full ); } } /> diff --git a/packages/patterns/src/constants.js b/packages/patterns/src/constants.js new file mode 100644 index 00000000000000..ecf7c7ddb3740c --- /dev/null +++ b/packages/patterns/src/constants.js @@ -0,0 +1,16 @@ +export const PATTERN_TYPES = { + theme: 'pattern', + user: 'wp_block', +}; + +export const PATTERN_DEFAULT_CATEGORY = 'all-patterns'; +export const PATTERN_CORE_SOURCES = [ + 'core', + 'pattern-directory/core', + 'pattern-directory/featured', + 'pattern-directory/theme', +]; +export const PATTERN_SYNC_TYPES = { + full: 'fully', + unsynced: 'unsynced', +}; diff --git a/packages/patterns/src/private-apis.js b/packages/patterns/src/private-apis.js index 31f507c2b99143..306476efc31212 100644 --- a/packages/patterns/src/private-apis.js +++ b/packages/patterns/src/private-apis.js @@ -4,9 +4,19 @@ import { lock } from './lock-unlock'; import CreatePatternModal from './components/create-pattern-modal'; import PatternsMenuItems from './components'; +import { + PATTERN_TYPES, + PATTERN_DEFAULT_CATEGORY, + PATTERN_CORE_SOURCES, + PATTERN_SYNC_TYPES, +} from './constants'; export const privateApis = {}; lock( privateApis, { CreatePatternModal, PatternsMenuItems, + PATTERN_TYPES, + PATTERN_DEFAULT_CATEGORY, + PATTERN_CORE_SOURCES, + PATTERN_SYNC_TYPES, } ); diff --git a/packages/patterns/src/store/actions.js b/packages/patterns/src/store/actions.js index 07680757762c38..589dad326d3b62 100644 --- a/packages/patterns/src/store/actions.js +++ b/packages/patterns/src/store/actions.js @@ -6,6 +6,11 @@ import { parse, serialize, createBlock } from '@wordpress/blocks'; import { store as coreStore } from '@wordpress/core-data'; import { store as blockEditorStore } from '@wordpress/block-editor'; +/** + * Internal dependencies + */ +import { PATTERN_SYNC_TYPES } from '../constants'; + /** * Returns a generator converting one or more static blocks into a pattern, or creating a new empty pattern. * @@ -18,7 +23,7 @@ export const createPattern = ( title, syncType, clientIds, categories ) => async ( { registry, dispatch } ) => { const meta = - syncType === 'unsynced' + syncType === PATTERN_SYNC_TYPES.unsynced ? { wp_pattern_sync_status: syncType, } From ad5092dff5816645694d9299eb5c1aa86a759c0d Mon Sep 17 00:00:00 2001 From: Bart Kalisz Date: Mon, 18 Sep 2023 11:07:41 +0000 Subject: [PATCH 04/28] Performance Tests: Improve the environment setup (#54309) --- bin/plugin/commands/performance.js | 386 +++++++++++++++-------------- 1 file changed, 206 insertions(+), 180 deletions(-) diff --git a/bin/plugin/commands/performance.js b/bin/plugin/commands/performance.js index e153f482137e57..4be675a0a5d40d 100644 --- a/bin/plugin/commands/performance.js +++ b/bin/plugin/commands/performance.js @@ -1,6 +1,7 @@ /** * External dependencies */ +const os = require( 'os' ); const fs = require( 'fs' ); const path = require( 'path' ); const SimpleGit = require( 'simple-git' ); @@ -13,7 +14,6 @@ const { runShellScript, readJSONFile, askForConfirmation, - getRandomTemporaryPath, getFilesFromDir, } = require( '../lib/utils' ); const config = require( '../config' ); @@ -31,6 +31,19 @@ const RESULTS_FILE_SUFFIX = '.performance-results.json'; * @property {string=} wpVersion The WordPress version to be used as the base install for testing. */ +/** + * A logging helper for printing steps and their substeps. + * + * @param {number} indent Value to indent the log. + * @param {any} msg Message to log. + * @param {...any} args Rest of the arguments to pass to console.log. + */ +function logAtIndent( indent, msg, ...args ) { + const prefix = indent === 0 ? '▶ ' : '> '; + const newline = indent === 0 ? '\n' : ''; + return log( newline + ' '.repeat( indent ) + prefix + msg, ...args ); +} + /** * Sanitizes branch name to be used in a path or a filename. * @@ -64,14 +77,14 @@ function median( array ) { /** * Runs the performance tests on the current branch. * - * @param {string} testSuite Name of the tests set. - * @param {string} performanceTestDirectory Path to the performance tests' clone. - * @param {string} runKey Unique identifier for the test run. + * @param {string} testSuite Name of the tests set. + * @param {string} testRunnerDir Path to the performance tests' clone. + * @param {string} runKey Unique identifier for the test run. */ -async function runTestSuite( testSuite, performanceTestDirectory, runKey ) { +async function runTestSuite( testSuite, testRunnerDir, runKey ) { await runShellScript( `npm run test:performance -- ${ testSuite }`, - performanceTestDirectory, + testRunnerDir, { ...process.env, WP_ARTIFACTS_PATH: ARTIFACTS_PATH, @@ -95,23 +108,23 @@ async function runPerformanceTests( branches, options ) { branches = [ 'trunk' ]; } + log( formats.title( '\n💃 Performance Tests 🕺' ) ); log( - formats.title( '\n💃 Performance Tests 🕺\n' ), - '\nWelcome! This tool runs the performance tests on multiple branches and displays a comparison table.\n' + - 'In order to run the tests, the tool is going to load a WordPress environment on ports 8888 and 8889.\n' + - 'Make sure these ports are not used before continuing.\n' + '\nWelcome! This tool runs the performance tests on multiple branches and displays a comparison table.' ); if ( ! runningInCI ) { + log( + formats.warning( + '\nIn order to run the tests, the tool is going to load a WordPress environment on ports 8888 and 8889.' + + '\nMake sure these ports are not used before continuing.\n' + ) + ); + await askForConfirmation( 'Ready to go? ' ); } - /* - * 1- Preparing the tests directory. - */ - - log( '\n>> Preparing the tests directories' ); - log( ' >> Cloning the repository' ); + logAtIndent( 0, 'Setting up' ); /** * @type {string[]} git refs against which to run tests; @@ -121,121 +134,162 @@ async function runPerformanceTests( branches, options ) { throw new Error( `Need at least two git refs to run` ); } - const baseDirectory = getRandomTemporaryPath(); - fs.mkdirSync( baseDirectory, { recursive: true } ); + const baseDir = path.join( os.tmpdir(), 'wp-performance-tests' ); + + if ( fs.existsSync( baseDir ) ) { + logAtIndent( 1, 'Removing existing files' ); + fs.rmSync( baseDir, { recursive: true } ); + } + + logAtIndent( 1, 'Creating base directory:', formats.success( baseDir ) ); + fs.mkdirSync( baseDir ); + + logAtIndent( 1, 'Setting up repository' ); + const sourceDir = path.join( baseDir, 'source' ); + + logAtIndent( 2, 'Creating directory:', formats.success( sourceDir ) ); + fs.mkdirSync( sourceDir ); // @ts-ignore - const git = SimpleGit( baseDirectory ); - await git + const sourceGit = SimpleGit( sourceDir ); + logAtIndent( + 2, + 'Initializing:', + formats.success( config.gitRepositoryURL ) + ); + await sourceGit .raw( 'init' ) .raw( 'remote', 'add', 'origin', config.gitRepositoryURL ); - for ( const branch of branches ) { - await git.raw( 'fetch', '--depth=1', 'origin', branch ); + for ( const [ i, branch ] of branches.entries() ) { + logAtIndent( + 2, + `Fetching environment branch (${ i + 1 } of ${ branches.length }):`, + formats.success( branch ) + ); + await sourceGit.raw( 'fetch', '--depth=1', 'origin', branch ); } - await git.raw( 'checkout', branches[ 0 ] ); + const testRunnerBranch = options.testsBranch || branches[ 0 ]; + if ( options.testsBranch && ! branches.includes( options.testsBranch ) ) { + logAtIndent( + 2, + 'Fetching test runner branch:', + formats.success( options.testsBranch ) + ); + // @ts-ignore + await sourceGit.raw( + 'fetch', + '--depth=1', + 'origin', + options.testsBranch + ); + } else { + logAtIndent( + 2, + 'Using test runner branch:', + formats.success( testRunnerBranch ) + ); + } - const rootDirectory = getRandomTemporaryPath(); - const performanceTestDirectory = rootDirectory + '/tests'; - await runShellScript( 'mkdir -p ' + rootDirectory ); - await runShellScript( - 'cp -R ' + baseDirectory + ' ' + performanceTestDirectory - ); + logAtIndent( 1, 'Setting up test runner' ); - if ( !! options.testsBranch ) { - const branchName = formats.success( options.testsBranch ); - log( ` >> Fetching the test-runner branch: ${ branchName }` ); + const testRunnerDir = path.join( baseDir + '/tests' ); - // @ts-ignore - await SimpleGit( performanceTestDirectory ) - .raw( 'fetch', '--depth=1', 'origin', options.testsBranch ) - .raw( 'checkout', options.testsBranch ); - } + logAtIndent( 2, 'Copying source to:', formats.success( testRunnerDir ) ); + await runShellScript( `cp -R ${ sourceDir } ${ testRunnerDir }` ); - log( ' >> Installing dependencies and building packages' ); + logAtIndent( + 2, + 'Checking out branch:', + formats.success( testRunnerBranch ) + ); + // @ts-ignore + await SimpleGit( testRunnerDir ).raw( 'checkout', testRunnerBranch ); + + logAtIndent( 2, 'Installing dependencies and building' ); await runShellScript( - `bash -c "${ [ - 'source $HOME/.nvm/nvm.sh', - 'nvm install', - 'npm ci', - 'npx playwright install chromium --with-deps', - 'npm run build:packages', - ].join( ' && ' ) }"`, - performanceTestDirectory + `bash -c "source $HOME/.nvm/nvm.sh && nvm install && npm ci && npx playwright install chromium --with-deps && npm run build:packages"`, + testRunnerDir ); - log( ' >> Creating the environment folders' ); - await runShellScript( 'mkdir -p ' + rootDirectory + '/envs' ); - /* - * 2- Preparing the environment directories per branch. - */ + logAtIndent( 1, 'Setting up test environments' ); + + const envsDir = path.join( baseDir, 'environments' ); + logAtIndent( 2, 'Creating parent directory:', formats.success( envsDir ) ); + fs.mkdirSync( envsDir ); + + let wpZipUrl = null; + if ( options.wpVersion ) { + // In order to match the topology of ZIP files at wp.org, remap .0 + // patch versions to major versions: + // + // 5.7 -> 5.7 (unchanged) + // 5.7.0 -> 5.7 (changed) + // 5.7.2 -> 5.7.2 (unchanged) + const zipVersion = options.wpVersion.replace( /^(\d+\.\d+).0/, '$1' ); + wpZipUrl = `https://wordpress.org/wordpress-${ zipVersion }.zip`; + } - log( '\n>> Preparing an environment directory per branch' ); - const branchDirectories = {}; + const branchDirs = {}; for ( const branch of branches ) { - log( ` >> Branch: ${ branch }` ); - const sanitizedBranch = sanitizeBranchName( branch ); - const environmentDirectory = rootDirectory + '/envs/' + sanitizedBranch; + logAtIndent( 2, 'Branch:', formats.success( branch ) ); + const sanitizedBranchName = sanitizeBranchName( branch ); + const envDir = path.join( envsDir, sanitizedBranchName ); + + logAtIndent( 3, 'Creating directory:', formats.success( envDir ) ); + fs.mkdirSync( envDir ); // @ts-ignore - branchDirectories[ branch ] = environmentDirectory; - const buildPath = `${ environmentDirectory }/plugin`; - await runShellScript( 'mkdir ' + environmentDirectory ); - await runShellScript( `cp -R ${ baseDirectory } ${ buildPath }` ); + branchDirs[ branch ] = envDir; + const buildDir = path.join( envDir, 'plugin' ); - const fancyBranch = formats.success( branch ); + logAtIndent( 3, 'Copying source to:', formats.success( buildDir ) ); + await runShellScript( `cp -R ${ sourceDir } ${ buildDir }` ); - if ( branch === options.testsBranch ) { - log( - ` >> Re-using the testing branch for ${ fancyBranch }` - ); - await runShellScript( - `cp -R ${ performanceTestDirectory } ${ buildPath }` - ); - } else { - log( ` >> Fetching the ${ fancyBranch } branch` ); - // @ts-ignore - await SimpleGit( buildPath ).reset( 'hard' ).checkout( branch ); - } + logAtIndent( 3, 'Checking out:', formats.success( branch ) ); + // @ts-ignore + await SimpleGit( buildDir ).raw( 'checkout', branch ); - log( ` >> Building the ${ fancyBranch } branch` ); + logAtIndent( 3, 'Installing dependencies and building' ); await runShellScript( - 'bash -c "source $HOME/.nvm/nvm.sh && nvm install && npm ci && npm run prebuild:packages && node ./bin/packages/build.js && npx wp-scripts build"', - buildPath + `bash -c "source $HOME/.nvm/nvm.sh && nvm install && npm ci && npm run build"`, + buildDir + ); + + const wpEnvConfigPath = path.join( envDir, '.wp-env.json' ); + + logAtIndent( + 3, + 'Saving wp-env config to:', + formats.success( wpEnvConfigPath ) ); - // Create the config file for the current env. fs.writeFileSync( - path.join( environmentDirectory, '.wp-env.json' ), + wpEnvConfigPath, JSON.stringify( { config: { WP_DEBUG: false, SCRIPT_DEBUG: false, }, - core: 'WordPress/WordPress', - plugins: [ path.join( environmentDirectory, 'plugin' ) ], - themes: [ - path.join( - performanceTestDirectory, - 'test/emptytheme' - ), - ], + core: wpZipUrl || 'WordPress/WordPress', + plugins: [ buildDir ], + themes: [ path.join( testRunnerDir, 'test/emptytheme' ) ], env: { tests: { mappings: { 'wp-content/mu-plugins': path.join( - performanceTestDirectory, + testRunnerDir, 'packages/e2e-tests/mu-plugins' ), 'wp-content/plugins/gutenberg-test-plugins': path.join( - performanceTestDirectory, + testRunnerDir, 'packages/e2e-tests/plugins' ), 'wp-content/themes/gutenberg-test-themes': path.join( - performanceTestDirectory, + testRunnerDir, 'test/gutenberg-test-themes' ), 'wp-content/themes/gutenberg-test-themes/twentytwentyone': @@ -251,99 +305,61 @@ async function runPerformanceTests( branches, options ) { ), 'utf8' ); - - if ( options.wpVersion ) { - // In order to match the topology of ZIP files at wp.org, remap .0 - // patch versions to major versions: - // - // 5.7 -> 5.7 (unchanged) - // 5.7.0 -> 5.7 (changed) - // 5.7.2 -> 5.7.2 (unchanged) - const zipVersion = options.wpVersion.replace( - /^(\d+\.\d+).0/, - '$1' - ); - const zipUrl = `https://wordpress.org/wordpress-${ zipVersion }.zip`; - log( ` Using WordPress version ${ zipVersion }` ); - - // Patch the environment's .wp-env.json config to use the specified WP - // version: - // - // { - // "core": "https://wordpress.org/wordpress-$VERSION.zip", - // ... - // } - const confPath = `${ environmentDirectory }/.wp-env.json`; - const conf = { ...readJSONFile( confPath ), core: zipUrl }; - await fs.writeFileSync( - confPath, - JSON.stringify( conf, null, 2 ), - 'utf8' - ); - } } - // Printing the used folders. - log( - '\n>> Perf Tests Directory : ' + - formats.success( performanceTestDirectory ) - ); - for ( const branch of branches ) { - // @ts-ignore - const envPath = formats.success( branchDirectories[ branch ] ); - log( `>> Environment Directory (${ branch }) : ${ envPath }` ); - } - - /* - * 3- Running the tests. - */ - - log( '\n>> Running the tests' ); + logAtIndent( 0, 'Looking for test files' ); const testSuites = getFilesFromDir( - path.join( performanceTestDirectory, 'test/performance/specs' ) - ).map( ( file ) => path.basename( file, '.spec.js' ) ); + path.join( testRunnerDir, 'test/performance/specs' ) + ).map( ( file ) => { + logAtIndent( 1, 'Found:', formats.success( file ) ); + return path.basename( file, '.spec.js' ); + } ); + + logAtIndent( 0, 'Running tests' ); + + if ( wpZipUrl ) { + logAtIndent( + 1, + 'Using:', + formats.success( `WordPress v${ options.wpVersion }` ) + ); + } else { + logAtIndent( 1, 'Using:', formats.success( 'WordPress trunk' ) ); + } - const wpEnvPath = path.join( - performanceTestDirectory, - 'node_modules/.bin/wp-env' - ); + const wpEnvPath = path.join( testRunnerDir, 'node_modules/.bin/wp-env' ); for ( const testSuite of testSuites ) { for ( let i = 1; i <= TEST_ROUNDS; i++ ) { - const roundInfo = `round ${ i } of ${ TEST_ROUNDS }`; - log( ` >> Suite: ${ testSuite } (${ roundInfo })` ); + logAtIndent( + 1, + // prettier-ignore + `Suite: ${ formats.success( testSuite ) } (round ${ i } of ${ TEST_ROUNDS })` + ); + for ( const branch of branches ) { - const sanitizedBranch = sanitizeBranchName( branch ); - const runKey = `${ testSuite }_${ sanitizedBranch }_round-${ i }`; + logAtIndent( 2, 'Branch:', formats.success( branch ) ); + + const sanitizedBranchName = sanitizeBranchName( branch ); + const runKey = `${ testSuite }_${ sanitizedBranchName }_round-${ i }`; // @ts-ignore - const environmentDirectory = branchDirectories[ branch ]; - log( ` >> Branch: ${ branch }` ); - log( ' >> Starting the environment.' ); - await runShellScript( - `${ wpEnvPath } start`, - environmentDirectory - ); - log( ' >> Running the test.' ); - await runTestSuite( - testSuite, - performanceTestDirectory, - runKey - ); - log( ' >> Stopping the environment' ); - await runShellScript( - `${ wpEnvPath } stop`, - environmentDirectory - ); + const envDir = branchDirs[ branch ]; + + logAtIndent( 3, 'Starting environment' ); + await runShellScript( `${ wpEnvPath } start`, envDir ); + + logAtIndent( 3, 'Running tests' ); + await runTestSuite( testSuite, testRunnerDir, runKey ); + + logAtIndent( 3, 'Stopping environment' ); + await runShellScript( `${ wpEnvPath } stop`, envDir ); } } } - /* - * 4- Formatting and saving the results. - */ + logAtIndent( 0, 'Calculating results' ); - // Load curated results from each round. const resultFiles = getFilesFromDir( ARTIFACTS_PATH ).filter( ( file ) => file.endsWith( RESULTS_FILE_SUFFIX ) ); @@ -352,17 +368,21 @@ async function runPerformanceTests( branches, options ) { // Calculate medians from all rounds. for ( const testSuite of testSuites ) { - results[ testSuite ] = {}; + logAtIndent( 1, 'Test suite:', formats.success( testSuite ) ); + results[ testSuite ] = {}; for ( const branch of branches ) { - const sanitizedBranch = sanitizeBranchName( branch ); + const sanitizedBranchName = sanitizeBranchName( branch ); const resultsRounds = resultFiles .filter( ( file ) => file.includes( - `${ testSuite }_${ sanitizedBranch }_round-` + `${ testSuite }_${ sanitizedBranchName }_round-` ) ) - .map( ( file ) => readJSONFile( file ) ); + .map( ( file ) => { + logAtIndent( 2, 'Reading from:', formats.success( file ) ); + return readJSONFile( file ); + } ); const metrics = Object.keys( resultsRounds[ 0 ] ); results[ testSuite ][ branch ] = {}; @@ -378,25 +398,31 @@ async function runPerformanceTests( branches, options ) { } } } + const calculatedResultsPath = path.join( + ARTIFACTS_PATH, + testSuite + RESULTS_FILE_SUFFIX + ); - // Save calculated results to file. + logAtIndent( + 2, + 'Saving curated results to:', + formats.success( calculatedResultsPath ) + ); fs.writeFileSync( - path.join( ARTIFACTS_PATH, testSuite + RESULTS_FILE_SUFFIX ), + calculatedResultsPath, JSON.stringify( results[ testSuite ], null, 2 ) ); } - /* - * 5- Displaying the results. - */ - - log( '\n>> 🎉 Results.\n' ); + logAtIndent( 0, 'Printing results' ); log( - '\nPlease note that client side metrics EXCLUDE the server response time.\n' + formats.warning( + '\nPlease note that client side metrics EXCLUDE the server response time.' + ) ); for ( const testSuite of testSuites ) { - log( `\n>> ${ testSuite }\n` ); + logAtIndent( 0, formats.success( testSuite ) ); // Invert the results so we can display them in a table. /** @type {Record>} */ From b39fc10415b69e7b37245c5be08f516bc5dda8d5 Mon Sep 17 00:00:00 2001 From: mujuonly Date: Mon, 18 Sep 2023 16:46:24 +0530 Subject: [PATCH 05/28] Removed trailing space from string, to fix translations issue Removed unwanted space with translation --- packages/edit-site/src/components/welcome-guide/styles.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/edit-site/src/components/welcome-guide/styles.js b/packages/edit-site/src/components/welcome-guide/styles.js index e6ec75ed7243f3..03a3014b1b9fa5 100644 --- a/packages/edit-site/src/components/welcome-guide/styles.js +++ b/packages/edit-site/src/components/welcome-guide/styles.js @@ -77,7 +77,7 @@ export default function WelcomeGuideStyles() {

{ __( - 'You can customize your site as much as you like with different colors, typography, and layouts. Or if you prefer, just leave it up to your theme to handle! ' + 'You can customize your site as much as you like with different colors, typography, and layouts. Or if you prefer, just leave it up to your theme to handle!' ) }

@@ -117,7 +117,7 @@ export default function WelcomeGuideStyles() {

{ __( - 'New to block themes and styling your site? ' + 'New to block themes and styling your site?' ) } Date: Mon, 18 Sep 2023 12:58:06 +0100 Subject: [PATCH 06/28] Add a documentation page to explain how to implement undo/redo in a third-party editor (#54546) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Héctor <27339341+priethor@users.noreply.github.com> --- .../basic-concepts/internationalization.md | 2 +- .../docs/basic-concepts/rendering.md | 2 +- .../docs/basic-concepts/rich-text.md | 2 +- platform-docs/docs/basic-concepts/settings.md | 2 +- .../docs/basic-concepts/undo-redo.md | 67 +++++++++++++++++++ 5 files changed, 71 insertions(+), 4 deletions(-) create mode 100644 platform-docs/docs/basic-concepts/undo-redo.md diff --git a/platform-docs/docs/basic-concepts/internationalization.md b/platform-docs/docs/basic-concepts/internationalization.md index e4cfd4c7573307..3b808bd71e61b1 100644 --- a/platform-docs/docs/basic-concepts/internationalization.md +++ b/platform-docs/docs/basic-concepts/internationalization.md @@ -1,5 +1,5 @@ --- -sidebar_position: 5 +sidebar_position: 6 --- # Internationalization diff --git a/platform-docs/docs/basic-concepts/rendering.md b/platform-docs/docs/basic-concepts/rendering.md index e4a24b19ae3e5d..f5458df2e81e77 100644 --- a/platform-docs/docs/basic-concepts/rendering.md +++ b/platform-docs/docs/basic-concepts/rendering.md @@ -1,5 +1,5 @@ --- -sidebar_position: 6 +sidebar_position: 7 --- # Rendering blocks diff --git a/platform-docs/docs/basic-concepts/rich-text.md b/platform-docs/docs/basic-concepts/rich-text.md index 349224aa9fbe30..e3517bc93203e8 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: 4 +sidebar_position: 5 --- # RichText and Format Library diff --git a/platform-docs/docs/basic-concepts/settings.md b/platform-docs/docs/basic-concepts/settings.md index 3e68f712cecfe2..66d0691aef5f75 100644 --- a/platform-docs/docs/basic-concepts/settings.md +++ b/platform-docs/docs/basic-concepts/settings.md @@ -1,5 +1,5 @@ --- -sidebar_position: 3 +sidebar_position: 4 --- # Block Editor Settings diff --git a/platform-docs/docs/basic-concepts/undo-redo.md b/platform-docs/docs/basic-concepts/undo-redo.md new file mode 100644 index 00000000000000..26981e6e0f5c16 --- /dev/null +++ b/platform-docs/docs/basic-concepts/undo-redo.md @@ -0,0 +1,67 @@ +--- +sidebar_position: 3 +--- + +# Undo Redo + +## Undo/Redo using `useStateWithHistory` + +By default, the block editor doesn't enable undo/redo. This is because in most scenarios, the block editor is rendered as part of a larger application that already has its own undo/redo functionality. However, to help you implement undo/redo in your application, the block editor provides a set of APIs that you can use. + +The simplest approach is to rely on the `useStateWithHistory` hook provided by the `@wordpress/compose` package. This hook is a wrapper around the `useState` hook that adds undo/redo functionality to the state. + +First, make sure you add the `@wordpress/compose` package to your dependencies, then use the hook like so: + +```jsx +import { useStateWithHistory } from '@wordpress/compose'; +import { createRoot, createElement, useState } from "@wordpress/element"; +import { + BlockEditorProvider, + BlockCanvas, +} from "@wordpress/block-editor"; + +function Editor() { + const { value, setValue, hasUndo, hasRedo, undo, redo } = + useStateWithHistory( { blocks: [] } ); + + return ( + + setValue( { blocks, selection }, true ) + } + onChange={ ( blocks, { selection } ) => + setValue( { blocks, selection }, false ) + } + > +

+ + +
+ + + ); +} +``` + +The `useStateWithHistory` hook returns an object with the following properties: + +- `value`: the current value of the state. +- `setValue`: a function that can be used to update the state. +- `hasUndo`: a boolean indicating whether there are any actions that can be undone. +- `hasRedo`: a boolean indicating whether there are any actions that can be redone. +- `undo`: a function that can be used to undo the last action. +- `redo`: a function that can be used to redo the last action. + +Notice that in addition to the `blocks` property, the `value` object also tracks a `selection` property. This property is used to store and control the cursor position within the block editor. This allows the editor to restore the right position when undoing or redoing changes. + +## Going Further... + +Oftentimes, editors allow to track changes across multiple objects and properties. For instance, a basic writing experience might allow editing the title of a post in a normal input and the content of the post in the block editor. Or your editor might allow edits to related objects like categories, tags, etc... In these cases, you might want to implement undo/redo functionality that can be used to track changes across all of these objects and properties. + +The `useStateWithHistory` might not always be the right approach in these situations. Consider checking the `@wordpress/undo-manager` package that offers a lower level undo manager that can be adapted more easily to your specific needs. From cde5c4cd9bf2663ee047e05617394881fce8783a Mon Sep 17 00:00:00 2001 From: Aki Hamano <54422211+t-hamano@users.noreply.github.com> Date: Mon, 18 Sep 2023 21:16:52 +0900 Subject: [PATCH 07/28] Font Library: Fix notification error for actions related to custom fonts (#54535) --- .../components/global-styles/font-library-modal/context.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/edit-site/src/components/global-styles/font-library-modal/context.js b/packages/edit-site/src/components/global-styles/font-library-modal/context.js index 14b786ff085342..07c2da701e9e0a 100644 --- a/packages/edit-site/src/components/global-styles/font-library-modal/context.js +++ b/packages/edit-site/src/components/global-styles/font-library-modal/context.js @@ -253,7 +253,7 @@ function FontLibraryProvider( { children } ) { const deactivateFontFamily = ( font ) => { // If the user doesn't have custom fonts defined, include as custom fonts all the theme fonts // We want to save as active all the theme fonts at the beginning - const initialCustomFonts = fontFamilies[ font.source ] || []; + const initialCustomFonts = fontFamilies?.[ font.source ] ?? []; const newCustomFonts = initialCustomFonts.filter( ( f ) => f.slug !== font.slug ); @@ -266,7 +266,7 @@ function FontLibraryProvider( { children } ) { const activateCustomFontFamilies = ( fontsToAdd ) => { // Merge the existing custom fonts with the new fonts. const newCustomFonts = mergeFontFamilies( - fontFamilies.custom, + fontFamilies?.custom, fontsToAdd ); // Activate the fonts by set the new custom fonts array. @@ -290,7 +290,7 @@ function FontLibraryProvider( { children } ) { const toggleActivateFont = ( font, face ) => { // If the user doesn't have custom fonts defined, include as custom fonts all the theme fonts // We want to save as active all the theme fonts at the beginning - const initialFonts = fontFamilies[ font.source ] || []; + const initialFonts = fontFamilies?.[ font.source ] ?? []; // Toggles the received font family or font face const newFonts = toggleFont( font, face, initialFonts ); // Updates the font families activated in global settings: From 06a12223125de2afcb2505419c48775c95643879 Mon Sep 17 00:00:00 2001 From: Nick Diego Date: Mon, 18 Sep 2023 07:25:38 -0500 Subject: [PATCH 08/28] Docs: Overhaul the Development Environment section of the Block Editor Handbook (#54395) * Update main page and add sub-pages. * Update main Development Environment readme. * Add note on node versions and rearrange sections. * Remove Ubuntu troubleshooting doc. * Update wp-env guide and add Ubuntu troubleshooting info. * Fix typos. * Add additional resources sections and fix typos. * Add guide for wp-now. * Update page title. * Fix links. * Add separate node.js doc and rename pages. * Fix wording. * Fix wording. * Address feedback. Thanks @juanmaguitar! * Add links. * Address feedback. --- docs/getting-started/devenv/README.md | 237 +++--------------- docs/getting-started/devenv/docker-ubuntu.md | 60 ----- .../devenv/get-started-with-wp-env.md | 140 +++++++++++ .../devenv/get-started-with-wp-now.md | 66 +++++ .../devenv/nodejs-development-tools.md | 50 ++++ docs/manifest.json | 20 +- docs/toc.json | 8 +- 7 files changed, 309 insertions(+), 272 deletions(-) delete mode 100644 docs/getting-started/devenv/docker-ubuntu.md create mode 100644 docs/getting-started/devenv/get-started-with-wp-env.md create mode 100644 docs/getting-started/devenv/get-started-with-wp-now.md create mode 100644 docs/getting-started/devenv/nodejs-development-tools.md diff --git a/docs/getting-started/devenv/README.md b/docs/getting-started/devenv/README.md index 7c55bcb6393f1b..1fafd53af11300 100644 --- a/docs/getting-started/devenv/README.md +++ b/docs/getting-started/devenv/README.md @@ -1,228 +1,51 @@ -# Development Environment +# Block Development Environment -This guide is for setting up your local environment for JavaScript development for creating plugins and tools to extend WordPress and the block editor. If you are looking to contribute to Gutenberg project itself, see additional documentation in the [Getting Started guide](/docs/contributors/code/getting-started-with-code-contribution.md). +This guide will help you set up the right development environment to create blocks and other plugins that extend and modify the Block Editor in WordPress. -A development environment is a catch-all term for what you need setup on your computer to work. The three main pieces needed for our development environment are: +To contribute to the Gutenberg project itself, refer to the additional documentation in the [code contribution guide](/docs/contributors/code/getting-started-with-code-contribution.md).` -1. Node/NPM Development Tools -2. WordPress Development Site -3. Code Editor +A block development environment includes the tools you need on your computer to successfully develop for the Block Editor. The three essential requirements are: -## Quick Start +1. [Code editor](#code-editor) +2. [Node.js development tools](#nodejs-development-tools) +3. [Local WordPress environment (site)](#local-wordpress-environment) -Here is a summary of the guide. See each section for additional details and explanations. +## Code editor -**1. Install Node development tools** +A code editor is used to write code, and you can use whichever editor you're most comfortable with. The key is having a way to open, edit, and save text files. -Download and install [Node Version Manager](https://github.com/nvm-sh/nvm) (nvm) +If you do not already have a preferred code editor, [Visual Studio Code](https://code.visualstudio.com/) (VS Code) is a popular choice for JavaScript development among Core contributors. It works well across the three major platforms (Windows, Linux, and Mac) and is open-source and actively maintained by Microsoft. VS Code also has a vibrant community providing plugins and extensions, including many for WordPress development. -``` -curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash -``` +## Node.js development tools -Quit and restart terminal -Install Node.js v16. +Node.js (`node`) is an open-source runtime environment that allows you to execute JavaScript outside of the web browser. While Node.js is not required for all WordPress JavaScript development, it's essential when working with modern JavaScript tools and developing for the Block Editor. -``` -nvm install 16 -``` +Node.js and its accompanying development tools allow you to: -**2. WordPress Development Site** +- Install and run WordPress packages needed for Block Editor development, such as `wp-scripts` +- Setup local WordPress environments with `wp-env` and `wp-now` +- Use the latest ECMAScript features and write code in ESNext +- Lint, format, and test JavaScript code +- Scaffold custom blocks with the `create-block` package -First download, install, and start [Docker Desktop](https://www.docker.com/products/docker-desktop) following the instructions for your OS. +The list goes on. While modern JavaScript development can be challenging, WordPress provides several tools, like [`wp-scripts`](https://developer.wordpress.org/block-editor/reference-guides/packages/packages-scripts/) and [`create-block`](https://developer.wordpress.org/block-editor/reference-guides/packages/packages-create-block/), that streamline the process and are made possible by Node.js development tools. -- Install WordPress environment tool +**The recommended Node.js version for block development is [Active LTS](https://nodejs.dev/en/about/releases/) (Long Term Support)**. However, there are times when you need to to use different versions. A Node.js version manager tool like `nvm` is strongly recommended and allows you to easily change your `node` version when required. You will also need Node Package Manager (`npm`) and the Node Package eXecute (`npx`) to work with some WordPress packages. Both are installed automatically with Node.js. -``` -npm -g install @wordpress/env -``` +To install Node.js development tools and learn more about each, refer to the links below. -Start the environment from an existing plugin or theme directory, or a new working directory: +- [Install Node.js for Mac and Linux](/docs/getting-started/devenv/nodejs-development-tools.md#mac-and-linux-installations) +- [Install Node.js for Windows](/docs/getting-started/devenv/nodejs-development-tools.md#windows-or-alternative-installs) -``` -wp-env start -``` +## Local WordPress environment -You will have a full WordPress site installed, navigate to: http://localhost:8888/ using your browser, log in to the WordPress dashboard at http://localhost:8888/wp-admin/ using Username "admin" and Password "password", without the quotes. +A local WordPress environment (site) provides a controlled, efficient, and secure space for development, allowing you to build and test your code before deploying it to a production site. The [same requirements](https://en-gb.wordpress.org/about/requirements/) for WordPress apply to local sites. -**3. Code Editor** +Many tools are available for setting up a local WordPress environment on your computer. The Block Editor Handbook covers `wp-env` and `wp-now`, both of which are open-source and maintained by the WordPress project itself. -You can use any text editor to write code. For example, [Visual Studio Code](https://code.visualstudio.com/) is a popular open-source editor. You can follow instructions on their site to install it for your OS. +Refer to the individual guides below for setup instructions. -## Node Development Tools +- [Get started with `wp-env`](/docs/getting-started/devenv/get-started-with-wp-env.md) +- [Get started with `wp-now`](/docs/getting-started/devenv/get-started-with-wp-now.md) -The tools needed for development are **Node** and **NPM**. **Nodejs** is a runtime environment that allows running JavaScript outside of the browser. NPM is the Node Package Manager, it is used for installing dependencies and running scripts. The script `npx` is also installed with Nodejs—this script is used to run packages not yet installed—we will use `npx` to bootstrap a block. - -The tools are used to convert the JavaScript we are going to write into a format that browsers can run. This is called transpiling or the build step. - -For Mac and Linux, it is recommended to use the [Node Version Manager](https://github.com/nvm-sh/nvm) (nvm). Using `nvm` to install node allows installing specific versions, plus installs locally in your home directory and avoids any global permission issues. - -For Windows, or alternative installs, you can [download a Nodejs installer](https://nodejs.org/en/download/) directly from the main Node.js website, v14 is recommended. Installers are available for Windows and Mac, and binaries available for Linux. See Node.js site for additional installation methods. - -Here are the quick instructions to install using nvm, see the [full installation instructions](https://github.com/nvm-sh/nvm#installing-and-updating) for additional details. - -Run the following on the command-line to install nvm: - -```sh -curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash -``` - -Note: On macOS, the required developer tools are not installed by default, if not already installed you may be prompted to download the install. - -Mac git command requires command line developer tools - -After installing nvm, you need to use it to install Node.js, to install v16, run: - -```sh -nvm install 16 -``` - -If there is an error running the above command, for example a common error that occurs is: - -```sh -$ nvm install 16 -zsh: command not found: nvm -``` - -First, try quitting and restarting your terminal to pick up the installed config. - -If restarting did not resolve the problem, you might need to create the default profile file. - -On macOS Catalina, the default shell is zsh, to create the profile file type `touch ~/.zshrc` on the command-line. It is fine to run if the file already exists. Note, `~/` is a shortcut to your home directory. For Ubuntu, including WSL, the default profile is bash, use `touch ~/.bashrc` to create. - -After creating the profile file, re-run the install command: - -```sh -nvm install 16 -``` - -The important part after installing is being able to use them in your terminal. Open a terminal command-line and type `node -v` and `npm -v` to confirm they are installed. - -```sh -> node -v -v16.20.1 - -> npm -v -8.19.4 -``` - -Your versions may not match exactly, that is fine. The minimum version for Node.js is >= 12 and for npm >= 6.9, using v14 will be supported until upgrade is required. - -## WordPress Development Site - -There are several ways to run WordPress locally on your own computer, or you could even develop on a cloud hosted computer, though this may be slower. - -The WordPress [wp-env package](https://www.npmjs.com/package/@wordpress/env) lets you set up a local WordPress environment for building and testing plugins and themes, without any additional configuration. - -The `wp-env` tool uses Docker to create a virtual machine that runs the WordPress site. There are instructions available for installing Docker on [Windows 10 Pro](https://docs.docker.com/docker-for-windows/install/), [other versions of Windows 10](https://docs.docker.com/docker-for-windows/wsl/), [macOS](https://docs.docker.com/docker-for-mac/install/), and [Linux](https://docs.docker.com/v17.12/install/linux/docker-ce/ubuntu/#install-using-the-convenience-script). If using Ubuntu, see our additional notes for [help installing Docker on Ubuntu](/docs/getting-started/devenv/docker-ubuntu.md). - -After you have installed Docker, go ahead and install the `wp-env` tool. This command will install the tool globally, which means you can run it from any directory: - -```sh -npm -g install @wordpress/env -``` - -To confirm it is installed and available, run: - -```sh -wp-env --version -> 1.6.0 -``` - -The `wp-env` script is used to create a Docker WordPress environment. You can use this script to start an environment with your plugin activated by running it from the directory containing your plugin. For example if you are following the create block tutorial, this would be in the generated directory like so: - -```sh -npx @wordpress/create-block starter-block -cd starter-block -wp-env start -``` - -You can access your environment in your browser at: [http://localhost:8888/](http://localhost:8888/), the default username is `admin` and default password is `password`. For more information controlling the Docker environment see the [@wordpress/env package readme](/packages/env/README.md). - -When using the script while developing a single plugin, `wp-env start` can mount and activate the plugin automatically when run from the directory containing the plugin. Note: This also works for themes when run from the directory in which you are developing the theme. - -If you run `wp-env start` from a directory that is not a plugin or theme, a generic WordPress environment will be created. The script will display the following warning, it is fine if this is your intention. - -``` -!! Warning: could not find a .wp-env.json configuration file and could not determine if 'DIR' is a WordPress installation, a plugin, or a theme. -``` - -You can use the `.wp-env.json` configuration file to create an environment that works with multiple plugins and/or themes. See the [@wordpress/env package for additional details](/packages/env/README.md#wp-envjson). - -#### Troubleshooting - -A common issue when running `wp-env` is `Error while running docker-compose command.` - -- Check that Docker Desktop is started and running. -- Check Docker Desktop dashboard for logs, restart, or remove existing VMs. - -If you see the error: `Host is already in use by another container` - -- The container is already running, or another one is. You can stop an existing container running use `wp-env stop` from the directory you started it. -- If you do not remember the directory you started wp-env in, you can stop all containers with `docker stop $(docker ps -q)`. Please note, this will stop all containers, use caution with this command. - -### Alternative to Docker - -Docker is just one method to run a local WordPress environment. Block development and extending WordPress is done using normal plugins, so any WordPress environment can be used. Here are some alternatives that you can consider which do not require installing Docker. - -- [Local](https://localwp.com/) - Local is a single application you download and install. You will need to know where the plugin directory is located after install. If you create a site called `mywp` typically the plugin directory is installed at `~\Local Sites\mywp\app\public\wp-content\plugins`. When working with gutenberg it is recommended to place your install in your own gutenberg folder. This avoids potential issue with the build processes. - -- [WampServer](http://www.wampserver.com/en/) or [MAMP](https://www.mamp.info/) environments, both are quite similar to Local, combining a web server, PHP, and database. However these tools are not WordPress specific, so if you are not already using them, Local might be an easier option. - -- Remote server - you can work on a remote server, most hosts provide a quick WordPress setup. However, this will require additional time thorughout development syncing to the server, or working directly on the remote server. - -The important part is having a WordPress site installed, and know where and how to update files in the plugins directory. - -## Code Editor - -[Visual Studio Code](https://code.visualstudio.com/) is a popular code editor for JavaScript development. It works quite well across the three major platforms (Windows, Linux, and Mac), it is open-source and actively maintained by Microsoft. Plus Visual Studio Code has a vibrant community providing plugins and extensions; it is becoming the defacto standard for web development. - -Alternative editors include [Sublime Text](https://www.sublimetext.com/) that is also available across platforms, though is a commercial product; or other free alternatives include [Vim](https://www.vim.org/), [Atom](https://atom.io/), and [Notepad++](https://notepad-plus-plus.org/) all support standard JavaScript style development. - -You can use any editor you're comfortable with, it is more a personal preference. The development setup for WordPress block editor is a common JavaScript environment and most editors have plugins and support. The key is having a way to open, edit, and save text files. - -## Uninstall - Start Over - -Here are a few instructions if you need to start over, or want to remove what was installed. - -### Local Environment - -- If you just want to reset and clean the WordPress database: - -``` -wp-env clean all -``` - -- To remove the local environment completely for a specific project: - -``` -wp-env destroy -``` - -- To completely uninstall wp-env tool: - -``` -npm -g uninstall @wordpress/env -``` - -- To uninstall Docker, or Visual Studio Code use your OS method to remove packages. For example, on Windows run "Add or remove programs". You can additionally uninstall from the Docker Desktop app, click the bug icon at the top to switch to this Troubleshoot screen. Click Uninstall or remove. - -![Docker Troubleshoot Screenshot](https://developer.wordpress.org/files/2020/08/docker-uninstall-screen.png) - -### Uninstall Node/NVM - -To uninstall Node/NVM, delete the NVM directory, this is typically installed at `$HOME/.nvm`, delete using - -``` -rm -rf "$HOME/.nvm" -``` - -If this does not work and the `$NVM_DIR` environment variable is set you can remove using `rm -rf "$NVM_DIR"` - -To clean up any installed JavaScript packages remove the global `.npm` directory at `$HOME/.npm`, - -``` -rm -rf "$HOME/.npm" -``` - -Just as you confirmed the installation worked, you can confirm the uninstall worked. First quit and restart terminal and then try to run `npm -v`, `node -v`, and `nvm -v` you should then see a "command not found" error in the terminal. +Of the two, `wp-env` is the more solid and complete solution. It's also the recommended tool for Gutenberg development. On the other hand, `wp-now` offers a simplified setup but is more limited than `wp-env`. Both are valid options, so the choice is yours. diff --git a/docs/getting-started/devenv/docker-ubuntu.md b/docs/getting-started/devenv/docker-ubuntu.md deleted file mode 100644 index 680798d74f4e8c..00000000000000 --- a/docs/getting-started/devenv/docker-ubuntu.md +++ /dev/null @@ -1,60 +0,0 @@ -# How to setup local WordPress environment on Ubuntu - -This article covers setting up the local WordPress development environment using Docker on Ubuntu. - -For Ubuntu 20.04.1, the standard docker binaries in the repository work as needed: - -``` -sudo apt install docker.io docker-compose -``` - -For earlier versions of Ubuntu, the docker binaries included in repositories did not support the features needed for the WordPress environment. - -- For Ubuntu prior to 20.04.1, follow these [directions from Docker to install](https://docs.docker.com/install/linux/docker-ce/ubuntu/). Additionally `docker-compose` is required, you may need to install separately, see [ Docker compose documentation](https://docs.docker.com/compose/install/). - -## Troubleshooting - -If you run into this error, when running `npm run wp-env` from the Gutenberg directory: - -``` -ERROR: Couldn't connect to Docker daemon at http+docker://localhost - is it running? - -If it's at a non-standard location, specify the URL with the DOCKER_HOST environment variable. -``` - -First, make sure docker is running. You can check using `ps -ef | grep docker` which should show something like: - -``` -/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock -``` - -If docker is not running, try to start the service using: - -``` -sudo systemctl start docker.service -``` - -If docker is running, then it is not listening how the WordPress environment is trying to communicate. Try adding the following service override file to include listening on tcp. See [this Docker documentation](https://docs.docker.com/config/daemon/remote-access/) on how to configure remote access for Docker daemon. - -``` -# /etc/systemd/system/docker.service.d/override.conf -[Service] -ExecStart= -ExecStart=/usr/bin/dockerd -H fd:// -H tcp://0.0.0.0:2376 -``` - -Restart the service from the command-line - -``` -sudo systemctl daemon-reload -sudo systemctl restart docker.service -``` - -After restarting the services, set the environment variable DOCKER_HOST and try starting using: - -``` -export DOCKER_HOST=tcp://127.0.0.1:2376 -npm run wp-env start -``` - -Your environment should be setup at: http://localhost:8888/ diff --git a/docs/getting-started/devenv/get-started-with-wp-env.md b/docs/getting-started/devenv/get-started-with-wp-env.md new file mode 100644 index 00000000000000..dca3ca081317d6 --- /dev/null +++ b/docs/getting-started/devenv/get-started-with-wp-env.md @@ -0,0 +1,140 @@ +# Get started with wp-env + +The [@wordpress/env](https://www.npmjs.com/package/@wordpress/env) package (`wp-env`) lets you set up a local WordPress environment (site) for building and testing plugins and themes, without any additional configuration. + +Before following this guide, install [Node.js development tools](/docs/getting-started/devenv#install-nodejs-development-tools) if you have not already done so. + +## Quick start + +1. Download, install, and start [Docker Desktop](https://www.docker.com/products/docker-desktop) following the instructions for your operating system. +2. Run `npm -g install @wordpress/env` in the terminal to install `wp-env` globally. +3. In the terminal, navigate to an existing plugin directory, theme directory, or a new working directory. +4. Run `wp-env start` in the terminal to start the local WordPress environment. +5. After the script runs, navigate to `http://localhost:8888/wp-admin/` and log into the WordPress dashboard using username `admin` and password `password`. + +## Set up Docker Desktop + +The `wp-env` tool uses [Docker](https://www.docker.com/) to create a virtual machine that runs the local WordPress site. The Docker Desktop application is free for small businesses, personal use, education, and non-commercial open-source projects. See their [FAQ](https://docs.docker.com/desktop/faqs/general/#do-i-need-to-pay-to-use-docker-desktop) for more information. + +Use the links below to download and install Docker Desktop for your operating system. + +- [Docker Desktop for Mac](https://docs.docker.com/desktop/install/mac-install/) +- [Docker Desktop for Windows](https://docs.docker.com/desktop/install/windows-install/) +- [Docker Desktop for Linux](https://docs.docker.com/desktop/install/linux-install/) + +If you are using a version of Ubuntu prior to 20.04.1, see the additional [troubleshooting notes](#ubuntu-docker-setup) below. + +After successful installation, start the Docker Desktop application and follow the prompts to get set up. You should generally use the recommended (default) settings, and creating a Docker account is optional. + +## Install and run `wp-env` + +The `wp-env` tool is used to create a local WordPress environment with Docker. So, after you have set up Docker Desktop, open the terminal and install the `wp-env` by running the command: + +```sh +npm -g install @wordpress/env +``` + +This will install the `wp-env` globally, allowing the tool to be run from any directory. To confirm it's installed and available, run `wp-env --version`, and the version number should appear. + +Next, navigate to an existing plugin directory, theme directory, or a new working directory in the terminal and run: + +```sh +wp-env start +``` + +Once the script completes, you can access the local environment at: `http://localhost:8888`. Log into the WordPress dashboard using username `admin` and password `password`. + +
+ Some projects, like Gutenberg, include their own specific wp-env configurations, and the documentation might prompt you to run npm run start wp-env instead. +
+ +For more information on controlling the Docker environment, see the [@wordpress/env package](/packages/env/README.md) readme. + +### Where to run `wp-env` + +The `wp-env` tool can run from practically anywhere. When using the script while developing a single plugin, `wp-env start` can mount and activate the plugin automatically when run from the directory containing the plugin. This also works for themes when run from the directory in which you are developing the theme. + +A generic WordPress environment will be created if you run `wp-env start` from a directory that is not a plugin or theme. The script will display the following warning, but ignore if this is your intention. + +``` +!! Warning: could not find a .wp-env.json configuration file and could not determine if 'DIR' is a WordPress installation, a plugin, or a theme. +``` + +You can also use the `.wp-env.json` configuration file to create an environment that works with multiple plugins and/or themes. See the [@wordpress/env package](/packages/env/README.md#wp-envjson) readme for more configuration details. + +### Uninstall or reset `wp-env` + +Here are a few instructions if you need to start over or want to remove what was installed. + +- If you just want to reset and clean the WordPress database, run `wp-env clean all` +- To remove the local environment completely for a specific project, run `wp-env destroy` +- To globally uninstall the `wp-env` tool, run `npm -g uninstall @wordpress/env` + +## Troubleshooting + +### Common errors + +When using `wp-env`, it's common to get the error: `Error while running docker-compose command` + +- Check that Docker Desktop is started and running. +- Check Docker Desktop dashboard for logs, restart, or remove existing virtual machines. +- Then try rerunning `wp-env start`. + +If you see the error: `Host is already in use by another container` + +- The container you are attempting to start is already running, or another container is. You can stop an existing container by running `wp-env stop` from the directory that you started it in. +- If you do not remember the directory where you started `wp-env`, you can stop all containers by running `docker stop $(docker ps -q)`. This will stop all Docker containers, so use with caution. +- Then try rerunning `wp-env start`. + +### Ubuntu Docker setup + +If you are using a version of Ubuntu prior to 20.04.1, you may encounter errors when setting up a local WordPress environment with `wp-env`. + +To resolve this, start by following the [installation guide](https://docs.docker.com/install/linux/docker-ce/ubuntu/) from Docker. `docker-compose` is also required, which you may need to install separately. Refer to the [Docker compose documentation](https://docs.docker.com/compose/install/). + +Once Docker and `wp-env` are installed, and assuming `wp-env` is configured globally, try running `wp-env start` in a directory. If you run into this error: + +``` +ERROR: Couldn't connect to Docker daemon at http+docker://localhost - is it running? + +If it's at a non-standard location, specify the URL with the DOCKER_HOST environment variable. +``` + +First, make sure Docker is running. You can check by running `ps -ef | grep docker`, which should return something like: + +``` +/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock +``` + +If Docker is not running, try starting the service by running `sudo systemctl start docker.service`. + +If Docker is running, then it is not listening to how the WordPress environment is trying to communicate. Try adding the following service override file to include listening on `tcp`. See [this Docker documentation](https://docs.docker.com/config/daemon/remote-access/) on how to configure remote access for Docker daemon. + +``` +# /etc/systemd/system/docker.service.d/override.conf +[Service] +ExecStart= +ExecStart=/usr/bin/dockerd -H fd:// -H tcp://0.0.0.0:2376 +``` + +Restart the service from the command-line: + +``` +sudo systemctl daemon-reload +sudo systemctl restart docker.service +``` + +After restarting the services, set the environment variable `DOCKER_HOST` and try starting `wp-env` with: + +``` +export DOCKER_HOST=tcp://127.0.0.1:2376 +wp-env start +``` + +Your environment should now be set up at `http://localhost:8888/`. + +## Additional resources + +- [@wordpress/env](https://www.npmjs.com/package/@wordpress/env) (Official documentation) +- [Docker Desktop](https://docs.docker.com/desktop) (Official documentation) +- [Quick and easy local WordPress development with wp-env](https://developer.wordpress.org/news/2023/03/quick-and-easy-local-wordpress-development-with-wp-env/) (WordPress Developer Blog) diff --git a/docs/getting-started/devenv/get-started-with-wp-now.md b/docs/getting-started/devenv/get-started-with-wp-now.md new file mode 100644 index 00000000000000..8b95008dae4a4d --- /dev/null +++ b/docs/getting-started/devenv/get-started-with-wp-now.md @@ -0,0 +1,66 @@ +# Get started with wp-now + +The [@wp-now/wp-now](https://www.npmjs.com/package/@wordpress/env) package (`wp-now`) is a lightweight tool powered by [WordPress Playground](https://developer.wordpress.org/playground/) that streamlines setting up a local WordPress environment. + +Before following this guide, install [Node.js development tools](/docs/getting-started/devenv#install-nodejs-development-tools) if you have not already done so. It's recommended that you use the latest version of `node`. `wp-now` requires at least `node` v18 and v20 if you intend to use its [Blueprints](https://github.com/WordPress/playground-tools/tree/trunk/packages/wp-now#using-blueprints) feature. + +## Quick start + +1. Run `npm -g install @wp-now/wp-now` in the terminal to install `wp-now` globally. +2. In the terminal, navigate to an existing plugin directory, theme directory, or a new working directory. +3. Run `wp-now start` in the terminal to start the local WordPress environment. +4. After the script runs, your default web browser will automatically open the new local site, and you'll be logged in with the username `admin` and the password `password`. + +## Install and run `wp-now` + +Under the hood, `wp-now` is powered by WordPress Playground and only requires Node.js, unlike `wp-env`, which also requires Docker. To install `wp-now`, open the terminal and run the command: + +```sh +npm -g install @wp-now/wp-now +``` + +This will install the `wp-now` globally, allowing the tool to be run from any directory. To confirm it's installed and available, run `wp-now --version`, and the version number should appear. + +Next, navigate to an existing plugin directory, theme directory, or a new working directory in the terminal and run: + +```sh +wp-now start +``` + +After the script runs, your default web browser will automatically open the new local site, and you'll be logged in with the username `admin` and the password `password`. + +
+ If you encounter any errors when running wp-now start, make sure that you are using at least node v18, or v20 if you are using the Blueprint feature. +
+ +When running `wp-now` you can also pass arguments that modify the behavior of the WordPress environment. For example, `wp-now start --wp=6.3 --php=8` will start a site running WordPress 6.3 and PHP 8, which can be useful for testing purposes. + +Refer to the [@wp-now/wp-now](https://github.com/WordPress/playground-tools/tree/trunk/packages/wp-now) documentation for all available arguments. + +### Where to run `wp-now` + +The `wp-now` tool can be used practically anywhere and has different modes depending on how the directory is set up when you run `wp-now start`. Despite the many options, when developing for the Block Editor, you will likely use: + +- `plugin`, `theme`, or `wp-content`: Loads the project files into a virtual filesystem with WordPress and a SQLite-based database. Everything (including WordPress core files, the database, wp-config.php, etc.) is stored in the user's home directory and loaded into the virtual filesystem. The mode will be determined by: + - `plugin`: Presence of a PHP file with 'Plugin Name:' in its contents. + - `theme`: Presence of a `style.css` file with 'Theme Name:' in its contents. + - `wp-content`: Presence of `/plugins` and `/themes` subdirectories. +- `playground`: If no other mode conditions are matched, `wp-now` launches a completely virtualized WordPress site. + +Refer to the [@wp-now/wp-now](https://github.com/WordPress/playground-tools/tree/trunk/packages/wp-now) documentation for a more detailed explanation of all modes. + +### Known issues + +Since `wp-now` is a relatively new tool, there are a few [known issues](https://github.com/WordPress/playground-tools/tree/trunk/packages/wp-now#known-issues) to be aware of. However, these issues are unlikely to impact most block, theme, or plugin development. + +### Uninstall or reset `wp-now` + +Here are a few instructions if you need to start over or want to remove what was installed. + +- If you just want to reset and clean the WordPress database, run `wp-now --reset` +- To globally uninstall the `wp-now` tool, run `npm -g uninstall @wp-now/wp-now` + +## Additional resources + +- [@wp-now/wp-now](https://github.com/WordPress/playground-tools/tree/trunk/packages/wp-now) (Official documentation) +- [WordPress Playground](https://developer.wordpress.org/playground/) (Developer overview) \ No newline at end of file diff --git a/docs/getting-started/devenv/nodejs-development-tools.md b/docs/getting-started/devenv/nodejs-development-tools.md new file mode 100644 index 00000000000000..09a58a1beeb06e --- /dev/null +++ b/docs/getting-started/devenv/nodejs-development-tools.md @@ -0,0 +1,50 @@ +# Node.js development tools + +When developing for the Block Editor, you will need [Node.js](https://nodejs.org/en) development tools along with a code editor and a local WordPress environment. Node.js (`node`) is an open-source runtime environment that allows you to execute JavaScript code from the terminal (also known as a command-line interface, CLI, or shell) + +Installing `node` will automatically include the Node Package Manager (`npm`) and the Node Package eXecute (`npx`), two tools you will frequently use in block and plugin development. + +Node Package Manager ([`npm`](https://docs.npmjs.com/cli/v10/commands/npm)) serves multiple purposes, including dependency management and script execution. It's the recommended package manager and is extensively featured in all documentation. + +The Node Package eXecute ([`npx`](https://docs.npmjs.com/cli/v10/commands/npx)) tool is used to run commands from packages without installing them globally and is commonly used when scaffolding blocks with the [`create-block`](https://developer.wordpress.org/block-editor/reference-guides/packages/packages-create-block/) package. + + +## Node.js installation on Mac and Linux (with `nvm`) + +It's recommended that you use [Node Version Manager](https://github.com/nvm-sh/nvm) (`nvm`) to install Node.js. This allows you to install and manage specific versions of `node`, which are installed locally in your home directory, avoiding any global permission issues. + +Here are the quick instructions for installing `node` using `nvm`. See the [complete installation guide](https://github.com/nvm-sh/nvm#installing-and-updating) for more details. + +1. Open the terminal and run the following to install `nvm`. On macOS, the required developer tools are not installed by default. Install them if prompted. + +```sh +curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.5/install.sh | bash +``` + +2. Quit and restart the terminal. +3. Run `nvm install --lts` in the terminal to install the latest [LTS](https://nodejs.dev/en/about/releases/) (Long Term Support) version of Node.js. +4. Run `node -v` and `npm -v` in the terminal to verify the installed `node` and `npm` versions. + +If needed, you can also install specific versions of `node`. For example, install version 18 by running `nvm install 18`, and switch between different versions by running `nvm use [version-number]`. See the `nvm` [usage guide](https://github.com/nvm-sh/nvm#usage) for more details. + +Some projects, like Gutenberg, include an [`.nvmrc`](https://github.com/WordPress/gutenberg/blob/trunk/.nvmrc) file which specifies the version of `node` that should be used. In this case, running `nvm use` will automatically select the correct version. If the version is not yet installed, you will get an error that tells you what version needs to be added. Run `nvm install [version-number]` followed by `nvm use`. + +## Node.js installation on Windows and others + +You can [download a Node.js installer](https://nodejs.org/en/download/) directly from the main Node.js website. The latest version is recommended. Installers are available for Windows and Mac, and binaries are available for Linux. + +Microsoft also provides a [detailed guide](https://learn.microsoft.com/en-us/windows/dev-environment/javascript/nodejs-on-windows#install-nvm-windows-nodejs-and-npm) on how to install `nvm` and Node.js on Windows and WSL. + +## Troubleshooting + +If you encounter the error `zsh: command not found: nvm` when attempting to install `node`, you might need to create the default profile file. + +The default shell is `zsh` on macOS, so create the profile file by running `touch ~/.zshrc` in the terminal. It's fine to run if the file already exists. The default profile is `bash` for Ubuntu, including WSL, so use `touch ~/.bashrc` instead. Then repeat steps 2-4. + +The latest `node` version should work for most development projects, but be aware that some packages and tools have specific requirements. If you encounter issues, you might need to install and use a previous `node` version. Also, make sure to check if the project has an `.nvmrc` and use the `node` version indicated. + +## Additional resources + +- [Node.js](https://nodejs.org/en) (Official documentation) +- [Node Version Manager](https://github.com/nvm-sh/nvm) (Official documentation) +- [Installing Node.js and npm for local WordPress development](https://learn.wordpress.org/tutorial/installing-node-js-and-npm-for-local-wordpress-development/) (Learn WordPress tutorial) \ No newline at end of file diff --git a/docs/manifest.json b/docs/manifest.json index abaf2d4515c986..50061b9a3d6085 100644 --- a/docs/manifest.json +++ b/docs/manifest.json @@ -12,15 +12,27 @@ "parent": null }, { - "title": "Development Environment", + "title": "Block Development Environment", "slug": "devenv", "markdown_source": "../docs/getting-started/devenv/README.md", "parent": "getting-started" }, { - "title": "How to setup local WordPress environment on Ubuntu", - "slug": "docker-ubuntu", - "markdown_source": "../docs/getting-started/devenv/docker-ubuntu.md", + "title": "Node.js development tools", + "slug": "nodejs-development-tools", + "markdown_source": "../docs/getting-started/devenv/nodejs-development-tools.md", + "parent": "devenv" + }, + { + "title": "Get started with wp-env", + "slug": "get-started-with-wp-env", + "markdown_source": "../docs/getting-started/devenv/get-started-with-wp-env.md", + "parent": "devenv" + }, + { + "title": "Get started with wp-now", + "slug": "get-started-with-wp-now", + "markdown_source": "../docs/getting-started/devenv/get-started-with-wp-now.md", "parent": "devenv" }, { diff --git a/docs/toc.json b/docs/toc.json index 30c5544d28298b..a173621062e775 100644 --- a/docs/toc.json +++ b/docs/toc.json @@ -7,7 +7,13 @@ { "docs/getting-started/devenv/README.md": [ { - "docs/getting-started/devenv/docker-ubuntu.md": [] + "docs/getting-started/devenv/nodejs-development-tools.md": [] + }, + { + "docs/getting-started/devenv/get-started-with-wp-env.md": [] + }, + { + "docs/getting-started/devenv/get-started-with-wp-now.md": [] } ] }, From 7bfacfe88e7f619c3f889c41b30a29d1de355d13 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Mon, 18 Sep 2023 13:26:28 +0100 Subject: [PATCH 09/28] Prevent layout changes from saving the whole inherited settings object (#54500) --- .../src/components/global-styles/dimensions-panel.js | 12 ++++++++---- .../src/components/global-styles/screen-block.js | 10 +++++----- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/packages/edit-site/src/components/global-styles/dimensions-panel.js b/packages/edit-site/src/components/global-styles/dimensions-panel.js index 461ed7ab8dce8c..d70dd03e603c0f 100644 --- a/packages/edit-site/src/components/global-styles/dimensions-panel.js +++ b/packages/edit-site/src/components/global-styles/dimensions-panel.js @@ -33,6 +33,7 @@ export default function DimensionsPanel() { const [ inheritedStyle, setStyle ] = useGlobalStyle( '', undefined, 'all', { shouldDecodeEncode: false, } ); + const [ userSettings ] = useGlobalSetting( '', undefined, 'user' ); const [ rawSettings, setSettings ] = useGlobalSetting( '' ); const settings = useSettingsForBlockElement( rawSettings ); @@ -48,17 +49,20 @@ export default function DimensionsPanel() { const styleWithLayout = useMemo( () => { return { ...style, - layout: settings.layout, + layout: userSettings.layout, }; - }, [ style, settings.layout ] ); + }, [ style, userSettings.layout ] ); const onChange = ( newStyle ) => { const updatedStyle = { ...newStyle }; delete updatedStyle.layout; setStyle( updatedStyle ); - if ( newStyle.layout !== settings.layout ) { - const updatedSettings = { ...rawSettings, layout: newStyle.layout }; + if ( newStyle.layout !== userSettings.layout ) { + const updatedSettings = { + ...userSettings, + layout: newStyle.layout, + }; // Ensure any changes to layout definitions are not persisted. if ( updatedSettings.layout?.definitions ) { diff --git a/packages/edit-site/src/components/global-styles/screen-block.js b/packages/edit-site/src/components/global-styles/screen-block.js index f2bc5e920067d5..8a5a3d2572e08d 100644 --- a/packages/edit-site/src/components/global-styles/screen-block.js +++ b/packages/edit-site/src/components/global-styles/screen-block.js @@ -91,8 +91,8 @@ function ScreenBlock( { name, variation } ) { const [ inheritedStyle, setStyle ] = useGlobalStyle( prefix, name, 'all', { shouldDecodeEncode: false, } ); - const [ rawSettings, setSettings ] = useGlobalSetting( '', name ); const [ userSettings ] = useGlobalSetting( '', name, 'user' ); + const [ rawSettings, setSettings ] = useGlobalSetting( '', name ); const settings = useSettingsForBlockElement( rawSettings, name ); const blockType = getBlockType( name ); @@ -151,17 +151,17 @@ function ScreenBlock( { name, variation } ) { const styleWithLayout = useMemo( () => { return { ...style, - layout: settings.layout, + layout: userSettings.layout, }; - }, [ style, settings.layout ] ); + }, [ style, userSettings.layout ] ); const onChangeDimensions = ( newStyle ) => { const updatedStyle = { ...newStyle }; delete updatedStyle.layout; setStyle( updatedStyle ); - if ( newStyle.layout !== settings.layout ) { + if ( newStyle.layout !== userSettings.layout ) { setSettings( { - ...rawSettings, + ...userSettings, layout: newStyle.layout, } ); } From 58963ef4d2bd379b26ae4de57247a6ee5d03db3a Mon Sep 17 00:00:00 2001 From: Mario Santos <34552881+SantosGuillamot@users.noreply.github.com> Date: Mon, 18 Sep 2023 14:41:42 +0200 Subject: [PATCH 10/28] Prepare image lightbox for private version of the Interactivity API in 6 4 (#54547) * Add aria attributes to SSR * Rename `view-interactivity` to `view` * Use spaces instead of tabs --- packages/block-library/src/image/block.json | 2 +- packages/block-library/src/image/index.php | 4 +++- .../src/image/{view-interactivity.js => view.js} | 0 3 files changed, 4 insertions(+), 2 deletions(-) rename packages/block-library/src/image/{view-interactivity.js => view.js} (100%) diff --git a/packages/block-library/src/image/block.json b/packages/block-library/src/image/block.json index b8c0432866d968..d665a8a8f77085 100644 --- a/packages/block-library/src/image/block.json +++ b/packages/block-library/src/image/block.json @@ -131,5 +131,5 @@ ], "editorStyle": "wp-block-image-editor", "style": "wp-block-image", - "viewScript": "file:./view-interactivity.min.js" + "viewScript": "file:./view.min.js" } diff --git a/packages/block-library/src/image/index.php b/packages/block-library/src/image/index.php index edfa25bd91503d..561309f021727d 100644 --- a/packages/block-library/src/image/index.php +++ b/packages/block-library/src/image/index.php @@ -260,9 +260,11 @@ function block_core_image_render_lightbox( $block_content, $block ) { aria-label="$dialog_label" data-wp-class--initialized="context.core.image.initialized" data-wp-class--active="context.core.image.lightboxEnabled" - data-wp-class--hideAnimationEnabled="context.core.image.hideAnimationEnabled" + data-wp-class--hideAnimationEnabled="context.core.image.hideAnimationEnabled" data-wp-bind--aria-hidden="!context.core.image.lightboxEnabled" + aria-hidden="true" data-wp-bind--aria-modal="context.core.image.lightboxEnabled" + aria-modal="false" data-wp-effect="effects.core.image.initLightbox" data-wp-on--keydown="actions.core.image.handleKeydown" data-wp-on--mousewheel="actions.core.image.hideLightbox" diff --git a/packages/block-library/src/image/view-interactivity.js b/packages/block-library/src/image/view.js similarity index 100% rename from packages/block-library/src/image/view-interactivity.js rename to packages/block-library/src/image/view.js From cfe0bec7d21a6dc5bf35ee5f494f185419f31047 Mon Sep 17 00:00:00 2001 From: Ella <4710635+ellatrix@users.noreply.github.com> Date: Mon, 18 Sep 2023 15:58:55 +0300 Subject: [PATCH 11/28] Revert: Rich text: copy tag name on internal paste (#54301) --- docs/reference-guides/core-blocks.md | 2 +- .../components/rich-text/use-paste-handler.js | 18 +++-- packages/block-library/src/heading/block.json | 1 + packages/blocks/README.md | 1 - .../src/api/raw-handling/paste-handler.js | 70 +++++++------------ .../src/component/use-copy-handler.js | 9 +-- .../specs/editor/various/rich-text.spec.js | 27 +------ test/integration/blocks-raw-handling.test.js | 6 +- 8 files changed, 45 insertions(+), 89 deletions(-) diff --git a/docs/reference-guides/core-blocks.md b/docs/reference-guides/core-blocks.md index 2c54c7d044c640..9ae868115049b8 100644 --- a/docs/reference-guides/core-blocks.md +++ b/docs/reference-guides/core-blocks.md @@ -310,7 +310,7 @@ Introduce new sections and organize content to help visitors (and search engines - **Name:** core/heading - **Category:** text -- **Supports:** align (full, wide), anchor, className, color (background, gradients, link, text), spacing (margin, padding), typography (fontSize, lineHeight) +- **Supports:** __unstablePasteTextInline, align (full, wide), anchor, className, color (background, gradients, link, text), spacing (margin, padding), typography (fontSize, lineHeight) - **Attributes:** content, level, placeholder, textAlign ## Home Link diff --git a/packages/block-editor/src/components/rich-text/use-paste-handler.js b/packages/block-editor/src/components/rich-text/use-paste-handler.js index 6ebd33e507d6c3..5494b96a43eb7b 100644 --- a/packages/block-editor/src/components/rich-text/use-paste-handler.js +++ b/packages/block-editor/src/components/rich-text/use-paste-handler.js @@ -104,6 +104,20 @@ export function usePasteHandler( props ) { } const files = [ ...getFilesFromDataTransfer( clipboardData ) ]; + const isInternal = clipboardData.getData( 'rich-text' ) === 'true'; + + // If the data comes from a rich text instance, we can directly use it + // without filtering the data. The filters are only meant for externally + // pasted content and remove inline styles. + if ( isInternal ) { + const pastedValue = create( { + html, + preserveWhiteSpace, + } ); + addActiveFormats( pastedValue, value.activeFormats ); + onChange( insert( value, pastedValue ) ); + return; + } if ( pastePlainText ) { onChange( insert( value, create( { text: plainText } ) ) ); @@ -188,10 +202,6 @@ export function usePasteHandler( props ) { mode, tagName, preserveWhiteSpace, - // If the data comes from a rich text instance, we can directly - // use it without filtering the data. The filters are only meant - // for externally pasted content and remove inline styles. - disableFilters: !! clipboardData.getData( 'rich-text' ), } ); if ( typeof content === 'string' ) { diff --git a/packages/block-library/src/heading/block.json b/packages/block-library/src/heading/block.json index 9c544e8f95c4f4..80f1f0c47b5a8f 100644 --- a/packages/block-library/src/heading/block.json +++ b/packages/block-library/src/heading/block.json @@ -61,6 +61,7 @@ "textTransform": true } }, + "__unstablePasteTextInline": true, "__experimentalSlashInserter": true }, "editorStyle": "wp-block-heading-editor", diff --git a/packages/blocks/README.md b/packages/blocks/README.md index 01547ca24ef683..91cfec30c6a726 100644 --- a/packages/blocks/README.md +++ b/packages/blocks/README.md @@ -458,7 +458,6 @@ _Parameters_ - _options.mode_ `[string]`: Handle content as blocks or inline content. _ 'AUTO': Decide based on the content passed. _ 'INLINE': Always handle as inline content, and return string. \* 'BLOCKS': Always handle as blocks, and return array of blocks. - _options.tagName_ `[Array]`: The tag into which content will be inserted. - _options.preserveWhiteSpace_ `[boolean]`: Whether or not to preserve consequent white space. -- _options.disableFilters_ `[boolean]`: Whether or not to filter non semantic content. _Returns_ diff --git a/packages/blocks/src/api/raw-handling/paste-handler.js b/packages/blocks/src/api/raw-handling/paste-handler.js index f0acfac9fa7614..c4ad40e0b1f509 100644 --- a/packages/blocks/src/api/raw-handling/paste-handler.js +++ b/packages/blocks/src/api/raw-handling/paste-handler.js @@ -8,6 +8,7 @@ import { getPhrasingContentSchema, removeInvalidHTML } from '@wordpress/dom'; */ import { htmlToBlocks } from './html-to-blocks'; import { hasBlockSupport } from '../registration'; +import { getBlockInnerHTML } from '../serializer'; import parse from '../parser'; import normaliseBlocks from './normalise-blocks'; import specialCommentConverter from './special-comment-converter'; @@ -65,40 +66,6 @@ function filterInlineHTML( HTML, preserveWhiteSpace ) { return HTML; } -/** - * If we're allowed to return inline content, and there is only one inlineable - * block, and the original plain text content does not have any line breaks, - * then treat it as inline paste. - * - * @param {Object} options - * @param {Array} options.blocks - * @param {string} options.plainText - * @param {string} options.mode - */ -function maybeConvertToInline( { blocks, plainText, mode } ) { - if ( - mode === 'AUTO' && - blocks.length === 1 && - hasBlockSupport( blocks[ 0 ].name, '__unstablePasteTextInline', false ) - ) { - const trimRegex = /^[\n]+|[\n]+$/g; - // Don't catch line breaks at the start or end. - const trimmedPlainText = plainText.replace( trimRegex, '' ); - - if ( - trimmedPlainText !== '' && - trimmedPlainText.indexOf( '\n' ) === -1 - ) { - const target = blocks[ 0 ].innerBlocks.length - ? blocks[ 0 ].innerBlocks[ 0 ] - : blocks[ 0 ]; - return target.attributes.content; - } - } - - return blocks; -} - /** * Converts an HTML string to known blocks. Strips everything else. * @@ -112,7 +79,6 @@ function maybeConvertToInline( { blocks, plainText, mode } ) { * @param {Array} [options.tagName] The tag into which content will be inserted. * @param {boolean} [options.preserveWhiteSpace] Whether or not to preserve consequent white space. * - * @param {boolean} [options.disableFilters] Whether or not to filter non semantic content. * @return {Array|string} A list of blocks or a string, depending on `handlerMode`. */ export function pasteHandler( { @@ -121,7 +87,6 @@ export function pasteHandler( { mode = 'AUTO', tagName, preserveWhiteSpace, - disableFilters, } ) { // First of all, strip any meta tags. HTML = HTML.replace( /]+>/g, '' ); @@ -156,14 +121,6 @@ export function pasteHandler( { HTML = HTML.normalize(); } - if ( disableFilters ) { - return maybeConvertToInline( { - blocks: htmlToBlocks( normaliseBlocks( HTML ), pasteHandler ), - plainText, - mode, - } ); - } - // Parse Markdown (and encoded HTML) if: // * There is a plain text version. // * There is no HTML version, or it has no formatting. @@ -262,5 +219,28 @@ export function pasteHandler( { .flat() .filter( Boolean ); - return maybeConvertToInline( { blocks, plainText, mode } ); + // If we're allowed to return inline content, and there is only one + // inlineable block, and the original plain text content does not have any + // line breaks, then treat it as inline paste. + if ( + mode === 'AUTO' && + blocks.length === 1 && + hasBlockSupport( blocks[ 0 ].name, '__unstablePasteTextInline', false ) + ) { + const trimRegex = /^[\n]+|[\n]+$/g; + // Don't catch line breaks at the start or end. + const trimmedPlainText = plainText.replace( trimRegex, '' ); + + if ( + trimmedPlainText !== '' && + trimmedPlainText.indexOf( '\n' ) === -1 + ) { + return removeInvalidHTML( + getBlockInnerHTML( blocks[ 0 ] ), + phrasingContentSchema + ).replace( trimRegex, '' ); + } + } + + return blocks; } diff --git a/packages/rich-text/src/component/use-copy-handler.js b/packages/rich-text/src/component/use-copy-handler.js index c62d83351971c3..3be59354432158 100644 --- a/packages/rich-text/src/component/use-copy-handler.js +++ b/packages/rich-text/src/component/use-copy-handler.js @@ -28,17 +28,10 @@ export function useCopyHandler( props ) { const selectedRecord = slice( record.current ); const plainText = getTextContent( selectedRecord ); - const tagName = element.tagName.toLowerCase(); - - let html = toHTMLString( { + const html = toHTMLString( { value: selectedRecord, preserveWhiteSpace, } ); - - if ( tagName && tagName !== 'span' && tagName !== 'div' ) { - html = `<${ tagName }>${ html }`; - } - event.clipboardData.setData( 'text/plain', plainText ); event.clipboardData.setData( 'text/html', html ); event.clipboardData.setData( 'rich-text', 'true' ); diff --git a/test/e2e/specs/editor/various/rich-text.spec.js b/test/e2e/specs/editor/various/rich-text.spec.js index d39264eccc1ea3..4ebd2cd450e70b 100644 --- a/test/e2e/specs/editor/various/rich-text.spec.js +++ b/test/e2e/specs/editor/various/rich-text.spec.js @@ -656,11 +656,7 @@ test.describe( 'RichText', () => { innerBlocks: [ { name: 'core/list-item', - attributes: { content: '1' }, - }, - { - name: 'core/list-item', - attributes: { content: '2' }, + attributes: { content: '1
2' }, }, ], }, @@ -802,25 +798,4 @@ test.describe( 'RichText', () => { }, ] ); } ); - - test( 'should copy/paste heading', async ( { - page, - editor, - pageUtils, - } ) => { - await editor.insertBlock( { name: 'core/heading' } ); - await page.keyboard.type( 'Heading' ); - await pageUtils.pressKeys( 'primary+a' ); - await pageUtils.pressKeys( 'primary+c' ); - await page.keyboard.press( 'ArrowRight' ); - await page.keyboard.press( 'Enter' ); - await pageUtils.pressKeys( 'primary+v' ); - - expect( await editor.getBlocks() ).toMatchObject( - Array( 2 ).fill( { - name: 'core/heading', - attributes: { content: 'Heading' }, - } ) - ); - } ); } ); diff --git a/test/integration/blocks-raw-handling.test.js b/test/integration/blocks-raw-handling.test.js index 733ae308c851ae..2a31d0b0ceaa28 100644 --- a/test/integration/blocks-raw-handling.test.js +++ b/test/integration/blocks-raw-handling.test.js @@ -291,11 +291,9 @@ describe( 'Blocks raw handling', () => { HTML: '

FOO

', plainText: 'FOO\n', mode: 'AUTO', - } ) - .map( getBlockContent ) - .join( '' ); + } ); - expect( filtered ).toBe( '

FOO

' ); + expect( filtered ).toBe( 'FOO' ); expect( console ).toHaveLogged(); } ); From 0bee15148fe4330c20cf372cb46a33693e45cb5f Mon Sep 17 00:00:00 2001 From: Jarda Snajdr Date: Mon, 18 Sep 2023 15:14:26 +0200 Subject: [PATCH 12/28] Upgrade wp-prettier to v3.0.3 (#54539) * Upgrade wp-prettier to 3.0.3 beta 3 * Upgrade eslint-plugin-prettier to v5 * Reformat with Prettier 3.0.3 * Reformat to fix union types * compose package README fix * Format more markdown * Changelog entries for eslint-plugin and scripts --------- Co-authored-by: Marin Atanasov --- .../check-build-type-declaration-files.js | 4 +- bin/plugin/commands/packages.js | 7 +- docs/contributors/code/coding-guidelines.md | 61 +- package-lock.json | 1107 ++++++++++++++++- package.json | 3 +- .../src/components/colors/with-colors.js | 5 +- .../components/inserter/test/index.native.js | 20 +- .../src/components/link-control/test/index.js | 5 +- .../src/hooks/test/align.native.js | 7 +- .../src/block/test/edit.native.js | 5 +- .../src/buttons/test/edit.native.js | 52 +- .../src/cover/test/edit.native.js | 45 +- .../src/embed/test/index.native.js | 75 +- .../src/verse/test/edit.native.js | 5 +- .../src/circular-option-picker/types.ts | 2 +- .../components/src/color-palette/types.ts | 2 +- .../gradient-bar/control-points.tsx | 2 +- .../gradient-bar/test/utils.ts | 10 +- .../components/src/dropdown-menu/index.tsx | 2 +- .../components/src/duotone-picker/types.ts | 2 +- .../components/src/form-token-field/types.ts | 2 +- .../components/src/gradient-picker/types.ts | 2 +- .../higher-order/navigate-regions/index.tsx | 11 +- .../higher-order/with-filters/test/index.tsx | 79 +- .../with-spoken-messages/index.tsx | 15 +- .../global-styles-context/index.native.js | 15 +- .../navigation/use-navigation-tree-nodes.tsx | 2 +- .../components/src/popover/test/index.tsx | 6 +- packages/components/src/text/styles.js | 3 +- .../styles.ts | 9 +- .../toggle-group-control/as-button-group.tsx | 2 +- .../toggle-group-control/as-radio-group.tsx | 2 +- .../src/toolbar/toolbar-group/types.ts | 2 +- .../src/ui/context/context-connect.ts | 6 +- .../src/ui/context/wordpress-component.ts | 6 +- .../components/src/unit-control/index.tsx | 13 +- .../styles/unit-control-styles.ts | 4 +- .../components/src/unit-control/test/utils.ts | 2 +- .../src/utils/use-deprecated-props.ts | 2 +- packages/compose/README.md | 4 +- .../compose/src/higher-order/pure/index.tsx | 3 +- .../compose/src/hooks/use-dialog/index.ts | 2 +- .../src/hooks/use-resize-observer/index.tsx | 2 +- .../create-higher-order-component/index.ts | 2 +- .../core-data/src/entity-types/helpers.ts | 4 +- .../src/hooks/use-resource-permissions.ts | 2 +- packages/core-data/src/selectors.ts | 14 +- packages/create-block/lib/index.js | 5 +- packages/create-block/lib/templates.js | 8 +- .../src/components/with-registry/index.js | 15 +- packages/data/src/dispatch.ts | 2 +- packages/data/src/types.ts | 4 +- packages/e2e-test-utils/src/inserter.js | 2 +- .../specs/editor/plugins/annotations.test.js | 4 +- .../editor/plugins/container-blocks.test.js | 2 +- .../editor/plugins/custom-taxonomies.test.js | 2 +- .../inner-blocks-render-appender.test.js | 4 +- .../specs/editor/plugins/meta-boxes.test.js | 5 +- .../editor/various/change-detection.test.js | 2 +- .../editor/various/inserting-blocks.test.js | 4 +- .../site-editor/multi-entity-saving.test.js | 5 +- .../specs/widgets/editing-widgets.test.js | 10 +- packages/edit-site/src/store/actions.js | 2 +- packages/env/lib/download-sources.js | 2 +- packages/eslint-plugin/CHANGELOG.md | 3 +- packages/eslint-plugin/package.json | 2 +- packages/lazy-import/README.md | 2 +- .../__device-tests__/helpers/utils.js | 15 +- .../__device-tests__/pages/editor-page.js | 35 +- packages/scripts/CHANGELOG.md | 3 +- packages/scripts/package.json | 2 +- test/e2e/specs/editor/blocks/cover.spec.js | 5 +- test/e2e/specs/editor/blocks/image.spec.js | 5 +- .../blocks/navigation-list-view.spec.js | 15 +- .../e2e/specs/editor/blocks/paragraph.spec.js | 5 +- .../editor/various/draggable-blocks.spec.js | 10 +- .../interactivity/directive-bind.spec.ts | 2 +- .../specs/widgets/customizing-widgets.spec.js | 10 +- 78 files changed, 1423 insertions(+), 406 deletions(-) diff --git a/bin/packages/check-build-type-declaration-files.js b/bin/packages/check-build-type-declaration-files.js index cd8bad2a70b530..fff0b51e32fc24 100644 --- a/bin/packages/check-build-type-declaration-files.js +++ b/bin/packages/check-build-type-declaration-files.js @@ -83,7 +83,7 @@ async function checkUnverifiedDeclarationFiles() { const packageDir = path.resolve( 'packages' ); const packageDirs = ( await fs.readdir( packageDir, { withFileTypes: true } ) - ) + ) .filter( ( dirent ) => dirent.isDirectory() ) .map( ( dirent ) => path.join( packageDir, dirent.name ) ); @@ -97,7 +97,7 @@ async function checkUnverifiedDeclarationFiles() { : null ) ) - ).filter( Boolean ); + ).filter( Boolean ); const tscResults = await Promise.allSettled( declarations.map( typecheckDeclarations ) diff --git a/bin/plugin/commands/packages.js b/bin/plugin/commands/packages.js index 4cf509764436c6..fb83060b6e9240 100644 --- a/bin/plugin/commands/packages.js +++ b/bin/plugin/commands/packages.js @@ -198,10 +198,9 @@ async function updatePackages( config ) { ); const changelogFilesPublicPackages = changelogFiles.filter( ( changelogPath ) => { - const pkg = require( path.join( - path.dirname( changelogPath ), - 'package.json' - ) ); + const pkg = require( + path.join( path.dirname( changelogPath ), 'package.json' ) + ); return pkg.private !== true; } ); diff --git a/docs/contributors/code/coding-guidelines.md b/docs/contributors/code/coding-guidelines.md index e7ff0a40843060..12c3ad96cb85f3 100644 --- a/docs/contributors/code/coding-guidelines.md +++ b/docs/contributors/code/coding-guidelines.md @@ -207,24 +207,25 @@ You can attach private selectors and actions to a public store: ```js // In packages/package1/store.js: -import { privateHasContentRoleAttribute, ...selectors } from './selectors'; -import { privateToggleFeature, ...actions } from './selectors'; +import { privateHasContentRoleAttribute } from './private-selectors'; +import { privateToggleFeature } from './private-actions'; // The `lock` function is exported from the internal private-apis.js file where // the opt-in function was called. import { lock, unlock } from './lock-unlock'; -export const store = registerStore(/* ... */); +export const store = registerStore( /* ... */ ); // Attach a private action to the exported store: -unlock( store ).registerPrivateActions({ - privateToggleFeature +unlock( store ).registerPrivateActions( { + privateToggleFeature, } ); // Attach a private action to the exported store: -unlock( store ).registerPrivateSelectors({ - privateHasContentRoleAttribute +unlock( store ).registerPrivateSelectors( { + privateHasContentRoleAttribute, } ); +``` - +```js // In packages/package2/MyComponent.js: import { store } from '@wordpress/package1'; import { useSelect } from '@wordpress/data'; @@ -233,17 +234,18 @@ import { useSelect } from '@wordpress/data'; import { unlock } from './lock-unlock'; function MyComponent() { - const hasRole = useSelect( ( select ) => ( - // Use the private selector: - unlock( select( store ) ).privateHasContentRoleAttribute() + const hasRole = useSelect( + ( select ) => + // Use the private selector: + unlock( select( store ) ).privateHasContentRoleAttribute() // Note the unlock() is required. This line wouldn't work: - // select( store ).privateHasContentRoleAttribute() - ) ); + // select( store ).privateHasContentRoleAttribute() + ); // Use the private action: unlock( useDispatch( store ) ).privateToggleFeature(); - // ... + // ... } ``` @@ -263,7 +265,9 @@ lock( privateApis, { privateClass: class PrivateClass {}, privateVariable: 5, } ); +``` +```js // In packages/package2/index.js: import { privateApis } from '@wordpress/package1'; import { unlock } from './lock-unlock'; @@ -336,7 +340,9 @@ export function validateBlocks( blocks ) { export const privateApis = {}; lock( privateApis, { privateValidateBlocks } ); +``` +```js // In @wordpress/package2/index.js: import { privateApis as package1PrivateApis } from '@wordpress/package1'; import { unlock } from './lock-unlock'; @@ -363,30 +369,30 @@ const PrivateMyButton = ( { title, privateShowIcon = true } ) => { return ( ); -} +}; // The stable public component is a thin wrapper that calls the // private component with the private features disabled -export const MyButton = ( { title } ) => - +export const MyButton = ( { title } ) => ( + +); export const privateApis = {}; lock( privateApis, { PrivateMyButton } ); +``` - +```js // In @wordpress/package2/index.js: import { privateApis } from '@wordpress/package1'; import { unlock } from './lock-unlock'; // The private component may be "unlocked" given the stable component: -const { PrivateMyButton } = unlock(privateApis); +const { PrivateMyButton } = unlock( privateApis ); export function MyComponent() { - return ( - - ) + return ; } ``` @@ -438,13 +444,14 @@ function privateInCorePublicInPlugin() {} // Gutenberg treats both functions as private APIs internally: const privateApis = {}; -lock(privateApis, { privateEverywhere, privateInCorePublicInPlugin }); +lock( privateApis, { privateEverywhere, privateInCorePublicInPlugin } ); // The privateInCorePublicInPlugin function is explicitly exported, // but this export will not be merged into WordPress core thanks to // the process.env.IS_GUTENBERG_PLUGIN check. if ( process.env.IS_GUTENBERG_PLUGIN ) { - export const privateInCorePublicInPlugin = unlock( privateApis ).privateInCorePublicInPlugin; + export const privateInCorePublicInPlugin = + unlock( privateApis ).privateInCorePublicInPlugin; } ``` @@ -459,7 +466,7 @@ const a = 10; // Bad: const object = { a: a, - performAction: function() { + performAction: function () { // ... }, }; @@ -771,7 +778,7 @@ Documenting a function component should be treated the same as any other functio * * @return {?string} Block title. */ -``` +```` For class components, there is no recommendation for documenting the props of the component. Gutenberg does not use or endorse the [`propTypes` static class member](https://react.dev/reference/react/Component#static-proptypes). diff --git a/package-lock.json b/package-lock.json index 124be7f72bd69c..fb31bdaa0276b3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -183,6 +183,7 @@ "eslint-plugin-import": "2.25.2", "eslint-plugin-jest": "27.2.3", "eslint-plugin-jest-dom": "5.0.2", + "eslint-plugin-prettier": "5.0.0", "eslint-plugin-ssr-friendly": "1.0.6", "eslint-plugin-storybook": "0.6.13", "eslint-plugin-testing-library": "5.7.2", @@ -213,7 +214,7 @@ "patch-package": "6.2.2", "postcss": "8.4.16", "postcss-loader": "6.2.1", - "prettier": "npm:wp-prettier@2.8.5", + "prettier": "npm:wp-prettier@3.0.3-beta-3", "progress": "2.0.3", "react": "18.2.0", "react-dom": "18.2.0", @@ -5651,6 +5652,155 @@ "node": ">=14" } }, + "node_modules/@pkgr/utils": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@pkgr/utils/-/utils-2.4.2.tgz", + "integrity": "sha512-POgTXhjrTfbTV63DiFXav4lBHiICLKKwDeaKn9Nphwj7WH6m0hMMCaJkMyRWjgtPFyRKRVoMXXjczsTQRDEhYw==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "fast-glob": "^3.3.0", + "is-glob": "^4.0.3", + "open": "^9.1.0", + "picocolors": "^1.0.0", + "tslib": "^2.6.0" + }, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, + "node_modules/@pkgr/utils/node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@pkgr/utils/node_modules/define-lazy-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@pkgr/utils/node_modules/fast-glob": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", + "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/@pkgr/utils/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@pkgr/utils/node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@pkgr/utils/node_modules/open": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/open/-/open-9.1.0.tgz", + "integrity": "sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg==", + "dev": true, + "dependencies": { + "default-browser": "^4.0.0", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@pkgr/utils/node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@pkgr/utils/node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@pkgr/utils/node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@pkgr/utils/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/@playwright/test": { "version": "1.32.0", "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.32.0.tgz", @@ -10449,6 +10599,21 @@ "node": ">=8" } }, + "node_modules/@storybook/cli/node_modules/prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/@storybook/cli/node_modules/puppeteer-core": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-2.1.1.tgz", @@ -10947,6 +11112,21 @@ "node": ">=8" } }, + "node_modules/@storybook/codemod/node_modules/prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/@storybook/codemod/node_modules/recast": { "version": "0.23.3", "resolved": "https://registry.npmjs.org/recast/-/recast-0.23.3.tgz", @@ -12659,6 +12839,21 @@ "node": ">=4.0" } }, + "node_modules/@storybook/source-loader/node_modules/prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/@storybook/telemetry": { "version": "7.2.2", "resolved": "https://registry.npmjs.org/@storybook/telemetry/-/telemetry-7.2.2.tgz", @@ -24225,6 +24420,21 @@ "integrity": "sha512-uYBjakWipfaO/bXI7E8rq6kpwHRZK5cNYrUv2OzZSI/FvmdMyXJ2tG9dKcjEC5YHmHpUAwsargWIZNWdxb/bnQ==", "dev": true }, + "node_modules/bundle-name": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-3.0.0.tgz", + "integrity": "sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw==", + "dev": true, + "dependencies": { + "run-applescript": "^5.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/byte-size": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/byte-size/-/byte-size-8.1.1.tgz", @@ -27382,6 +27592,24 @@ } } }, + "node_modules/default-browser": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-4.0.0.tgz", + "integrity": "sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA==", + "dev": true, + "dependencies": { + "bundle-name": "^3.0.0", + "default-browser-id": "^3.0.0", + "execa": "^7.1.1", + "titleize": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/default-browser-id": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-3.0.0.tgz", @@ -27398,6 +27626,187 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/default-browser/node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/default-browser/node_modules/execa": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-7.2.0.tgz", + "integrity": "sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.1", + "human-signals": "^4.3.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^3.0.7", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": "^14.18.0 || ^16.14.0 || >=18.0.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/default-browser/node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser/node_modules/human-signals": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-4.3.1.tgz", + "integrity": "sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==", + "dev": true, + "engines": { + "node": ">=14.18.0" + } + }, + "node_modules/default-browser/node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser/node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser/node_modules/npm-run-path": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz", + "integrity": "sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==", + "dev": true, + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser/node_modules/npm-run-path/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser/node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser/node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/default-browser/node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/default-browser/node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/default-browser/node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/default-gateway": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", @@ -29145,22 +29554,30 @@ } }, "node_modules/eslint-plugin-prettier": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.3.0.tgz", - "integrity": "sha512-tMTwO8iUWlSRZIwS9k7/E4vrTsfvsrcM5p1eftyuqWH25nKsz/o6/54I7jwQ/3zobISyC7wMy9ZsFwgTxOcOpQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.0.0.tgz", + "integrity": "sha512-AgaZCVuYDXHUGxj/ZGu1u8H8CYgDY3iG6w5kUFw4AzMVXzB7VvbKgYR4nATIN+OvUrghMbiDLeimVjVY5ilq3w==", "dev": true, "dependencies": { - "prettier-linter-helpers": "^1.0.0" + "prettier-linter-helpers": "^1.0.0", + "synckit": "^0.8.5" }, "engines": { - "node": ">=6.0.0" + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/prettier" }, "peerDependencies": { - "eslint": ">=5.0.0", - "prettier": ">=1.13.0" + "@types/eslint": ">=8.0.0", + "eslint": ">=8.0.0", + "prettier": ">=3.0.0" }, "peerDependenciesMeta": { - "eslint-plugin-prettier": { + "@types/eslint": { + "optional": true + }, + "eslint-config-prettier": { "optional": true } } @@ -33653,6 +34070,39 @@ "integrity": "sha512-but/G3sapV3MNyqiDBLrOi4x8uCIw0RY3o/Vb5GT0sMFHrVV7731wFSVy41T5FO1og7G0gXLJh0MkgPRouko/A==", "dev": true }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "dev": true, + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-inside-container/node_modules/is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "dev": true, + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-interactive": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", @@ -45293,10 +45743,19 @@ }, "node_modules/prettier": { "name": "wp-prettier", - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/wp-prettier/-/wp-prettier-2.8.5.tgz", - "integrity": "sha512-gkphzYtVksWV6D7/V530bTehKkhrABUru/Gy4reOLOHJoKH4i9lcE1SxqU2VDxC3gCOx/Nk9alZmWk6xL/IBCw==", - "dev": true + "version": "3.0.3-beta-3", + "resolved": "https://registry.npmjs.org/wp-prettier/-/wp-prettier-3.0.3-beta-3.tgz", + "integrity": "sha512-R3+TD7j0rnqEpMgylrUrHdi1W6ypwh4QGeFOZQ9YjP9WvNnZzBAS71yry1h7xIcG/bVaNKBCoWNqbqJY6vkOKQ==", + "dev": true, + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } }, "node_modules/prettier-linter-helpers": { "version": "1.0.0", @@ -48171,6 +48630,172 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/run-applescript": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-5.0.0.tgz", + "integrity": "sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg==", + "dev": true, + "dependencies": { + "execa": "^5.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/run-applescript/node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/run-applescript/node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/run-applescript/node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/run-applescript/node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/run-applescript/node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/run-applescript/node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/run-applescript/node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/run-applescript/node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/run-applescript/node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/run-applescript/node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/run-applescript/node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/run-applescript/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/run-async": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", @@ -50654,6 +51279,22 @@ "integrity": "sha512-k8uzYIkIVwmT+TcglpdN50pS2y1BDcUnBPK9iJeGu0Pl1lOI8pD6wtzgw91Pjpe+RxtTncw32tLxs/R0yNL2Mg==", "dev": true }, + "node_modules/synckit": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.8.5.tgz", + "integrity": "sha512-L1dapNV6vu2s/4Sputv8xGsCdAVlb5nRDMFU/E27D44l5U6cw1g0dGd45uLc+OXjNMmF4ntiMdCimzcjFKQI8Q==", + "dev": true, + "dependencies": { + "@pkgr/utils": "^2.3.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, "node_modules/table": { "version": "6.8.0", "resolved": "https://registry.npmjs.org/table/-/table-6.8.0.tgz", @@ -51209,6 +51850,18 @@ "integrity": "sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==", "dev": true }, + "node_modules/titleize": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/titleize/-/titleize-3.0.0.tgz", + "integrity": "sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", @@ -55667,7 +56320,7 @@ "eslint-plugin-jsdoc": "^46.4.6", "eslint-plugin-jsx-a11y": "^6.5.1", "eslint-plugin-playwright": "^0.15.3", - "eslint-plugin-prettier": "^3.3.0", + "eslint-plugin-prettier": "^5.0.0", "eslint-plugin-react": "^7.27.0", "eslint-plugin-react-hooks": "^4.3.0", "globals": "^13.12.0", @@ -56450,7 +57103,7 @@ "playwright-core": "1.32.0", "postcss": "^8.4.5", "postcss-loader": "^6.2.1", - "prettier": "npm:wp-prettier@2.8.5", + "prettier": "npm:wp-prettier@3.0.3-beta-3", "puppeteer-core": "^13.2.0", "react-refresh": "^0.10.0", "read-pkg-up": "^7.0.1", @@ -60527,6 +61180,112 @@ "dev": true, "optional": true }, + "@pkgr/utils": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@pkgr/utils/-/utils-2.4.2.tgz", + "integrity": "sha512-POgTXhjrTfbTV63DiFXav4lBHiICLKKwDeaKn9Nphwj7WH6m0hMMCaJkMyRWjgtPFyRKRVoMXXjczsTQRDEhYw==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.3", + "fast-glob": "^3.3.0", + "is-glob": "^4.0.3", + "open": "^9.1.0", + "picocolors": "^1.0.0", + "tslib": "^2.6.0" + }, + "dependencies": { + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "define-lazy-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "dev": true + }, + "fast-glob": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", + "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "requires": { + "is-docker": "^2.0.0" + } + }, + "open": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/open/-/open-9.1.0.tgz", + "integrity": "sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg==", + "dev": true, + "requires": { + "default-browser": "^4.0.0", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "is-wsl": "^2.2.0" + } + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, "@playwright/test": { "version": "1.32.0", "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.32.0.tgz", @@ -63921,6 +64680,12 @@ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true }, + "prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "dev": true + }, "puppeteer-core": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-2.1.1.tgz", @@ -64310,6 +65075,12 @@ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true }, + "prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "dev": true + }, "recast": { "version": "0.23.3", "resolved": "https://registry.npmjs.org/recast/-/recast-0.23.3.tgz", @@ -65529,6 +66300,12 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true + }, + "prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "dev": true } } }, @@ -68383,7 +69160,7 @@ "eslint-plugin-jsdoc": "^46.4.6", "eslint-plugin-jsx-a11y": "^6.5.1", "eslint-plugin-playwright": "^0.15.3", - "eslint-plugin-prettier": "^3.3.0", + "eslint-plugin-prettier": "^5.0.0", "eslint-plugin-react": "^7.27.0", "eslint-plugin-react-hooks": "^4.3.0", "globals": "^13.12.0", @@ -68853,7 +69630,7 @@ "playwright-core": "1.32.0", "postcss": "^8.4.5", "postcss-loader": "^6.2.1", - "prettier": "npm:wp-prettier@2.8.5", + "prettier": "npm:wp-prettier@3.0.3-beta-3", "puppeteer-core": "^13.2.0", "react-refresh": "^0.10.0", "read-pkg-up": "^7.0.1", @@ -77148,6 +77925,15 @@ "integrity": "sha512-uYBjakWipfaO/bXI7E8rq6kpwHRZK5cNYrUv2OzZSI/FvmdMyXJ2tG9dKcjEC5YHmHpUAwsargWIZNWdxb/bnQ==", "dev": true }, + "bundle-name": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-3.0.0.tgz", + "integrity": "sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw==", + "dev": true, + "requires": { + "run-applescript": "^5.0.0" + } + }, "byte-size": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/byte-size/-/byte-size-8.1.1.tgz", @@ -79571,6 +80357,134 @@ "resolved": "https://registry.npmjs.org/deepsignal/-/deepsignal-1.3.6.tgz", "integrity": "sha512-yjd+vtiznL6YaMptOsKnEKkPr60OEApa+LRe+Qe6Ile/RfCOrELKk/YM3qVpXFZiyOI3Ng67GDEyjAlqVc697g==" }, + "default-browser": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-4.0.0.tgz", + "integrity": "sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA==", + "dev": true, + "requires": { + "bundle-name": "^3.0.0", + "default-browser-id": "^3.0.0", + "execa": "^7.1.1", + "titleize": "^3.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "execa": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-7.2.0.tgz", + "integrity": "sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.1", + "human-signals": "^4.3.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^3.0.7", + "strip-final-newline": "^3.0.0" + } + }, + "get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true + }, + "human-signals": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-4.3.1.tgz", + "integrity": "sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==", + "dev": true + }, + "is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true + }, + "mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true + }, + "npm-run-path": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz", + "integrity": "sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==", + "dev": true, + "requires": { + "path-key": "^4.0.0" + }, + "dependencies": { + "path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true + } + } + }, + "onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "requires": { + "mimic-fn": "^4.0.0" + } + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, "default-browser-id": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-3.0.0.tgz", @@ -81130,12 +82044,13 @@ "dev": true }, "eslint-plugin-prettier": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.3.0.tgz", - "integrity": "sha512-tMTwO8iUWlSRZIwS9k7/E4vrTsfvsrcM5p1eftyuqWH25nKsz/o6/54I7jwQ/3zobISyC7wMy9ZsFwgTxOcOpQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.0.0.tgz", + "integrity": "sha512-AgaZCVuYDXHUGxj/ZGu1u8H8CYgDY3iG6w5kUFw4AzMVXzB7VvbKgYR4nATIN+OvUrghMbiDLeimVjVY5ilq3w==", "dev": true, "requires": { - "prettier-linter-helpers": "^1.0.0" + "prettier-linter-helpers": "^1.0.0", + "synckit": "^0.8.5" } }, "eslint-plugin-react": { @@ -84390,6 +85305,23 @@ "integrity": "sha512-but/G3sapV3MNyqiDBLrOi4x8uCIw0RY3o/Vb5GT0sMFHrVV7731wFSVy41T5FO1og7G0gXLJh0MkgPRouko/A==", "dev": true }, + "is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "dev": true, + "requires": { + "is-docker": "^3.0.0" + }, + "dependencies": { + "is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "dev": true + } + } + }, "is-interactive": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", @@ -93303,9 +94235,9 @@ "dev": true }, "prettier": { - "version": "npm:wp-prettier@2.8.5", - "resolved": "https://registry.npmjs.org/wp-prettier/-/wp-prettier-2.8.5.tgz", - "integrity": "sha512-gkphzYtVksWV6D7/V530bTehKkhrABUru/Gy4reOLOHJoKH4i9lcE1SxqU2VDxC3gCOx/Nk9alZmWk6xL/IBCw==", + "version": "npm:wp-prettier@3.0.3-beta-3", + "resolved": "https://registry.npmjs.org/wp-prettier/-/wp-prettier-3.0.3-beta-3.tgz", + "integrity": "sha512-R3+TD7j0rnqEpMgylrUrHdi1W6ypwh4QGeFOZQ9YjP9WvNnZzBAS71yry1h7xIcG/bVaNKBCoWNqbqJY6vkOKQ==", "dev": true }, "prettier-linter-helpers": { @@ -95481,6 +96413,117 @@ } } }, + "run-applescript": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-5.0.0.tgz", + "integrity": "sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg==", + "dev": true, + "requires": { + "execa": "^5.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + } + }, + "get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true + }, + "human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true + }, + "is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "requires": { + "path-key": "^3.0.0" + } + }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, "run-async": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", @@ -97424,6 +98467,16 @@ "integrity": "sha512-k8uzYIkIVwmT+TcglpdN50pS2y1BDcUnBPK9iJeGu0Pl1lOI8pD6wtzgw91Pjpe+RxtTncw32tLxs/R0yNL2Mg==", "dev": true }, + "synckit": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.8.5.tgz", + "integrity": "sha512-L1dapNV6vu2s/4Sputv8xGsCdAVlb5nRDMFU/E27D44l5U6cw1g0dGd45uLc+OXjNMmF4ntiMdCimzcjFKQI8Q==", + "dev": true, + "requires": { + "@pkgr/utils": "^2.3.1", + "tslib": "^2.5.0" + } + }, "table": { "version": "6.8.0", "resolved": "https://registry.npmjs.org/table/-/table-6.8.0.tgz", @@ -97845,6 +98898,12 @@ "integrity": "sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==", "dev": true }, + "titleize": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/titleize/-/titleize-3.0.0.tgz", + "integrity": "sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ==", + "dev": true + }, "tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", diff --git a/package.json b/package.json index 1cd8535bfc803c..df1b0c7ba348a0 100644 --- a/package.json +++ b/package.json @@ -195,6 +195,7 @@ "eslint-plugin-import": "2.25.2", "eslint-plugin-jest": "27.2.3", "eslint-plugin-jest-dom": "5.0.2", + "eslint-plugin-prettier": "5.0.0", "eslint-plugin-ssr-friendly": "1.0.6", "eslint-plugin-storybook": "0.6.13", "eslint-plugin-testing-library": "5.7.2", @@ -225,7 +226,7 @@ "patch-package": "6.2.2", "postcss": "8.4.16", "postcss-loader": "6.2.1", - "prettier": "npm:wp-prettier@2.8.5", + "prettier": "npm:wp-prettier@3.0.3-beta-3", "progress": "2.0.3", "react": "18.2.0", "react-dom": "18.2.0", diff --git a/packages/block-editor/src/components/colors/with-colors.js b/packages/block-editor/src/components/colors/with-colors.js index c93ed8bf775a03..c5972286d4aa1e 100644 --- a/packages/block-editor/src/components/colors/with-colors.js +++ b/packages/block-editor/src/components/colors/with-colors.js @@ -36,8 +36,9 @@ const upperFirst = ( [ firstLetter, ...rest ] ) => */ const withCustomColorPalette = ( colorsArray ) => createHigherOrderComponent( - ( WrappedComponent ) => ( props ) => - , + ( WrappedComponent ) => ( props ) => ( + + ), 'withCustomColorPalette' ); diff --git a/packages/block-editor/src/components/inserter/test/index.native.js b/packages/block-editor/src/components/inserter/test/index.native.js index c86fb4c2d91ff4..d11eb5925c76ca 100644 --- a/packages/block-editor/src/components/inserter/test/index.native.js +++ b/packages/block-editor/src/components/inserter/test/index.native.js @@ -67,9 +67,8 @@ describe( 'Inserter', () => { fireEvent( addBlockButton, 'onLongPress' ); // Get Add To Beginning option - const addBlockToBeginningButton = await getByLabelText( - 'Add To Beginning' - ); + const addBlockToBeginningButton = + await getByLabelText( 'Add To Beginning' ); expect( addBlockToBeginningButton ).toBeVisible(); fireEvent.press( addBlockToBeginningButton ); @@ -97,9 +96,8 @@ describe( 'Inserter', () => { fireEvent( addBlockButton, 'onLongPress' ); // Get Add Block Before option - const addBlockBeforeButton = await getByLabelText( - 'Add Block Before' - ); + const addBlockBeforeButton = + await getByLabelText( 'Add Block Before' ); expect( addBlockBeforeButton ).toBeVisible(); fireEvent.press( addBlockBeforeButton ); @@ -135,9 +133,8 @@ describe( 'Inserter', () => { fireEvent( addBlockButton, 'onLongPress' ); // Get Add Block After option - const addBlockAfterButton = await getByLabelText( - 'Add Block After' - ); + const addBlockAfterButton = + await getByLabelText( 'Add Block After' ); expect( addBlockAfterButton ).toBeVisible(); fireEvent.press( addBlockAfterButton ); @@ -233,9 +230,8 @@ describe( 'Inserter', () => { await addBlock( screen, 'Heading' ); // Select the title - const titleInputElement = await getAllByLabelText( - 'Post title. test' - )[ 0 ]; + const titleInputElement = + await getAllByLabelText( 'Post title. test' )[ 0 ]; expect( titleInputElement ).toBeVisible(); fireEvent.press( titleInputElement ); diff --git a/packages/block-editor/src/components/link-control/test/index.js b/packages/block-editor/src/components/link-control/test/index.js index bce5ca5233192a..5c44f0295249c8 100644 --- a/packages/block-editor/src/components/link-control/test/index.js +++ b/packages/block-editor/src/components/link-control/test/index.js @@ -1218,9 +1218,8 @@ describe( 'Creating Entities (eg: Posts, Pages)', () => { // Resolve the `createSuggestion` promise. resolver(); - const currentLink = await screen.findByLabelText( - 'Currently selected' - ); + const currentLink = + await screen.findByLabelText( 'Currently selected' ); expect( currentLink ).toHaveTextContent( entityNameText ); expect( currentLink ).toHaveTextContent( '/?p=123' ); diff --git a/packages/block-editor/src/hooks/test/align.native.js b/packages/block-editor/src/hooks/test/align.native.js index c83ca398bab961..5b7ab25bb24b21 100644 --- a/packages/block-editor/src/hooks/test/align.native.js +++ b/packages/block-editor/src/hooks/test/align.native.js @@ -108,9 +108,10 @@ describe( 'Align options', () => { expect( groupBlock ).toBeVisible(); // Trigger inner blocks layout - const innerBlockListWrapper = await within( - groupBlock - ).findByTestId( 'block-list-wrapper' ); + const innerBlockListWrapper = + await within( groupBlock ).findByTestId( + 'block-list-wrapper' + ); fireEvent( innerBlockListWrapper, 'layout', { nativeEvent: { layout: { diff --git a/packages/block-library/src/block/test/edit.native.js b/packages/block-library/src/block/test/edit.native.js index 1e6c43b5bc4456..724b79c1d85d74 100644 --- a/packages/block-library/src/block/test/edit.native.js +++ b/packages/block-library/src/block/test/edit.native.js @@ -165,9 +165,8 @@ describe( 'Synced patterns', () => { /Pattern Block\. Row 1/ ); - const innerBlockListWrapper = await within( - reusableBlock - ).findByTestId( 'block-list-wrapper' ); + const innerBlockListWrapper = + await within( reusableBlock ).findByTestId( 'block-list-wrapper' ); // onLayout event has to be explicitly dispatched in BlockList component, // otherwise the inner blocks are not rendered. diff --git a/packages/block-library/src/buttons/test/edit.native.js b/packages/block-library/src/buttons/test/edit.native.js index 7d8d994d9af890..2fe70d034aa747 100644 --- a/packages/block-library/src/buttons/test/edit.native.js +++ b/packages/block-library/src/buttons/test/edit.native.js @@ -55,9 +55,10 @@ describe( 'Buttons block', () => { // onLayout event has to be explicitly dispatched in BlockList component, // otherwise the inner blocks are not rendered. - const innerBlockListWrapper = await within( - buttonsBlock - ).findByTestId( 'block-list-wrapper' ); + const innerBlockListWrapper = + await within( buttonsBlock ).findByTestId( + 'block-list-wrapper' + ); fireEvent( innerBlockListWrapper, 'layout', { nativeEvent: { layout: { @@ -66,19 +67,18 @@ describe( 'Buttons block', () => { }, } ); - const [ buttonInnerBlock ] = await within( - buttonsBlock - ).findAllByLabelText( /Button Block\. Row 1/ ); + const [ buttonInnerBlock ] = + await within( buttonsBlock ).findAllByLabelText( + /Button Block\. Row 1/ + ); fireEvent.press( buttonInnerBlock ); - const settingsButton = await editor.findByLabelText( - 'Open Settings' - ); + const settingsButton = + await editor.findByLabelText( 'Open Settings' ); fireEvent.press( settingsButton ); - const radiusStepper = await editor.findByLabelText( - /Border Radius/ - ); + const radiusStepper = + await editor.findByLabelText( /Border Radius/ ); const incrementButton = await within( radiusStepper ).findByTestId( 'Increment', @@ -98,9 +98,10 @@ describe( 'Buttons block', () => { const buttonsBlock = await getBlock( screen, 'Buttons' ); // Trigger inner blocks layout - const innerBlockListWrapper = await within( - buttonsBlock - ).findByTestId( 'block-list-wrapper' ); + const innerBlockListWrapper = + await within( buttonsBlock ).findByTestId( + 'block-list-wrapper' + ); fireEvent( innerBlockListWrapper, 'layout', { nativeEvent: { layout: { @@ -119,9 +120,10 @@ describe( 'Buttons block', () => { fireEvent.press( appenderButton ); // Check for new button - const [ secondButtonBlock ] = await within( - buttonsBlock - ).findAllByLabelText( /Button Block\. Row 2/ ); + const [ secondButtonBlock ] = + await within( buttonsBlock ).findAllByLabelText( + /Button Block\. Row 2/ + ); expect( secondButtonBlock ).toBeVisible(); // Add a Paragraph block using the empty placeholder at the bottom @@ -148,9 +150,10 @@ describe( 'Buttons block', () => { fireEvent.press( buttonsBlock ); // Trigger inner blocks layout - const innerBlockListWrapper = await within( - buttonsBlock - ).findByTestId( 'block-list-wrapper' ); + const innerBlockListWrapper = + await within( buttonsBlock ).findByTestId( + 'block-list-wrapper' + ); fireEvent( innerBlockListWrapper, 'layout', { nativeEvent: { layout: { @@ -207,9 +210,10 @@ describe( 'Buttons block', () => { const buttonsBlock = await getBlock( screen, 'Buttons' ); // Trigger inner blocks layout - const innerBlockListWrapper = await within( - buttonsBlock - ).findByTestId( 'block-list-wrapper' ); + const innerBlockListWrapper = + await within( buttonsBlock ).findByTestId( + 'block-list-wrapper' + ); fireEvent( innerBlockListWrapper, 'layout', { nativeEvent: { layout: { diff --git a/packages/block-library/src/cover/test/edit.native.js b/packages/block-library/src/cover/test/edit.native.js index 8ca3d40967a27b..3eedfc45ae123f 100644 --- a/packages/block-library/src/cover/test/edit.native.js +++ b/packages/block-library/src/cover/test/edit.native.js @@ -169,9 +169,8 @@ describe( 'when an image is attached', () => { /> ); fireEvent.press( screen.getByLabelText( 'Edit image' ) ); - const [ clearMediaButton ] = await screen.findAllByText( - 'Clear Media' - ); + const [ clearMediaButton ] = + await screen.findAllByText( 'Clear Media' ); fireEvent.press( clearMediaButton ); expect( setAttributes ).toHaveBeenCalledWith( @@ -191,9 +190,8 @@ describe( 'when an image is attached', () => { setAttributes={ setAttributes } /> ); - const fixedBackgroundButton = await screen.findByText( - 'Fixed background' - ); + const fixedBackgroundButton = + await screen.findByText( 'Fixed background' ); fireEvent.press( fixedBackgroundButton ); expect( setAttributes ).toHaveBeenCalledWith( @@ -210,9 +208,8 @@ describe( 'when an image is attached', () => { setAttributes={ setAttributes } /> ); - const editFocalPointButton = await screen.findByText( - 'Edit focal point' - ); + const editFocalPointButton = + await screen.findByText( 'Edit focal point' ); fireEvent.press( editFocalPointButton ); fireEvent( screen.getByTestId( 'Slider Y-Axis Position', { hidden: true } ), @@ -239,9 +236,8 @@ describe( 'when an image is attached', () => { setAttributes={ setAttributes } /> ); - const editFocalPointButton = await screen.findByText( - 'Edit focal point' - ); + const editFocalPointButton = + await screen.findByText( 'Edit focal point' ); fireEvent.press( editFocalPointButton ); fireEvent.press( screen.getByText( ( attributes.focalPoint.x * 100 ).toString(), { @@ -268,9 +264,8 @@ describe( 'when an image is attached', () => { setAttributes={ setAttributes } /> ); - const editFocalPointButton = await screen.findByText( - 'Edit focal point' - ); + const editFocalPointButton = + await screen.findByText( 'Edit focal point' ); fireEvent.press( editFocalPointButton ); fireEvent.press( screen.getByText( ( attributes.focalPoint.x * 100 ).toString(), { @@ -360,9 +355,8 @@ describe( 'color settings', () => { fireEvent.press( colorButton ); // Wait for the block to be created. - const [ coverBlockWithOverlay ] = await screen.findAllByLabelText( - /Cover Block\. Row 1/ - ); + const [ coverBlockWithOverlay ] = + await screen.findAllByLabelText( /Cover Block\. Row 1/ ); fireEvent.press( coverBlockWithOverlay ); // Open Block Settings. @@ -399,9 +393,8 @@ describe( 'color settings', () => { } ); // Wait for the block to be created. - const [ coverBlock ] = await screen.findAllByLabelText( - /Cover Block\. Row 1/ - ); + const [ coverBlock ] = + await screen.findAllByLabelText( /Cover Block\. Row 1/ ); fireEvent.press( coverBlock ); // Open Block Settings. @@ -455,9 +448,8 @@ describe( 'color settings', () => { fireEvent.press( colorButton ); // Wait for the block to be created. - const [ coverBlockWithOverlay ] = await screen.findAllByLabelText( - /Cover Block\. Row 1/ - ); + const [ coverBlockWithOverlay ] = + await screen.findAllByLabelText( /Cover Block\. Row 1/ ); fireEvent.press( coverBlockWithOverlay ); // Open Block Settings. @@ -511,9 +503,8 @@ describe( 'color settings', () => { } ); // Wait for the block to be created. - const [ coverBlock ] = await screen.findAllByLabelText( - /Cover Block\. Row 1/ - ); + const [ coverBlock ] = + await screen.findAllByLabelText( /Cover Block\. Row 1/ ); fireEvent.press( coverBlock ); // Open Block Settings. diff --git a/packages/block-library/src/embed/test/index.native.js b/packages/block-library/src/embed/test/index.native.js index b13b86b40d3fd3..761aed2ea32210 100644 --- a/packages/block-library/src/embed/test/index.native.js +++ b/packages/block-library/src/embed/test/index.native.js @@ -432,9 +432,8 @@ describe( 'Embed block', () => { describe( 'edit URL', () => { it( 'keeps the previous URL if no URL is set', async () => { - const editor = await initializeWithEmbedBlock( - RICH_TEXT_EMBED_HTML - ); + const editor = + await initializeWithEmbedBlock( RICH_TEXT_EMBED_HTML ); // Open Block Settings. fireEvent.press( await editor.findByLabelText( 'Open Settings' ) ); @@ -456,9 +455,8 @@ describe( 'Embed block', () => { const initialURL = 'https://twitter.com/notnownikki'; const expectedURL = 'https://www.youtube.com/watch?v=lXMskKTw3Bc'; - const editor = await initializeWithEmbedBlock( - RICH_TEXT_EMBED_HTML - ); + const editor = + await initializeWithEmbedBlock( RICH_TEXT_EMBED_HTML ); // Open Block Settings. fireEvent.press( await editor.findByLabelText( 'Open Settings' ) ); @@ -501,9 +499,8 @@ describe( 'Embed block', () => { const previousURL = 'https://twitter.com/notnownikki'; const invalidURL = 'http://'; - const editor = await initializeWithEmbedBlock( - RICH_TEXT_EMBED_HTML - ); + const editor = + await initializeWithEmbedBlock( RICH_TEXT_EMBED_HTML ); // Open Block Settings. fireEvent.press( await editor.findByLabelText( 'Open Settings' ) ); @@ -541,9 +538,8 @@ describe( 'Embed block', () => { it( 'sets empty state when setting an empty URL', async () => { const previousURL = 'https://twitter.com/notnownikki'; - const editor = await initializeWithEmbedBlock( - RICH_TEXT_EMBED_HTML - ); + const editor = + await initializeWithEmbedBlock( RICH_TEXT_EMBED_HTML ); // Open Block Settings. fireEvent.press( await editor.findByLabelText( 'Open Settings' ) ); @@ -570,9 +566,8 @@ describe( 'Embed block', () => { fireEvent( blockSettingsModal, MODAL_DISMISS_EVENT ); // Get empty embed link. - const emptyLinkTextInput = await editor.findByPlaceholderText( - 'Add link' - ); + const emptyLinkTextInput = + await editor.findByPlaceholderText( 'Add link' ); expect( emptyLinkTextInput ).toBeDefined(); expect( getEditorHtml() ).toMatchSnapshot(); @@ -680,9 +675,8 @@ describe( 'Embed block', () => { 'Full width', ].forEach( ( alignmentOption ) => it( `sets ${ alignmentOption } option`, async () => { - const editor = await initializeWithEmbedBlock( - RICH_TEXT_EMBED_HTML - ); + const editor = + await initializeWithEmbedBlock( RICH_TEXT_EMBED_HTML ); // Open alignment options. fireEvent.press( await editor.findByLabelText( 'Align' ) ); @@ -714,9 +708,8 @@ describe( 'Embed block', () => { return mockOtherResponses( req ); } ); - const editor = await initializeWithEmbedBlock( - RICH_TEXT_EMBED_HTML - ); + const editor = + await initializeWithEmbedBlock( RICH_TEXT_EMBED_HTML ); await editor.findByText( 'Unable to embed media' ); @@ -749,9 +742,8 @@ describe( 'Embed block', () => { return mockOtherResponses( req ); } ); - const editor = await initializeWithEmbedBlock( - RICH_TEXT_EMBED_HTML - ); + const editor = + await initializeWithEmbedBlock( RICH_TEXT_EMBED_HTML ); // Convert embed to link. fireEvent.press( editor.getByText( 'More options' ) ); @@ -826,9 +818,8 @@ describe( 'Embed block', () => { describe( 'preview coming soon', () => { it( 'previews post for providers which embed preview is not available yet', async () => { - const { getByText, getByTestId } = await initializeWithEmbedBlock( - PHOTO_EMBED_HTML - ); + const { getByText, getByTestId } = + await initializeWithEmbedBlock( PHOTO_EMBED_HTML ); // Try to preview the post. fireEvent.press( getByText( 'PREVIEW POST' ) ); @@ -848,9 +839,8 @@ describe( 'Embed block', () => { } ); it( 'dismisses no preview modal', async () => { - const { getByText, getByTestId } = await initializeWithEmbedBlock( - PHOTO_EMBED_HTML - ); + const { getByText, getByTestId } = + await initializeWithEmbedBlock( PHOTO_EMBED_HTML ); // Try to preview the post. fireEvent.press( getByText( 'PREVIEW POST' ) ); @@ -908,9 +898,8 @@ describe( 'Embed block', () => { ); // Get the created embed block. - const [ embedBlock ] = await editor.findAllByLabelText( - /Embed Block\. Row 1/ - ); + const [ embedBlock ] = + await editor.findAllByLabelText( /Embed Block\. Row 1/ ); expect( embedBlock ).toBeDefined(); @@ -996,9 +985,8 @@ describe( 'Embed block', () => { fireEvent.press( await editor.findByText( 'Embed' ) ); - const [ block ] = await editor.findAllByLabelText( - /Embed Block\. Row 1/ - ); + const [ block ] = + await editor.findAllByLabelText( /Embed Block\. Row 1/ ); const blockName = within( block ).getByText( 'Embed' ); @@ -1037,9 +1025,8 @@ describe( 'Embed block', () => { fireEvent.press( await editor.findByText( title ) ); - const [ block ] = await editor.findAllByLabelText( - /Embed Block\. Row 1/ - ); + const [ block ] = + await editor.findAllByLabelText( /Embed Block\. Row 1/ ); const blockName = within( block ).getByText( title ); @@ -1096,9 +1083,8 @@ describe( 'Embed block', () => { describe( 'block settings', () => { it( 'toggles resize for smaller devices media settings', async () => { - const screen = await initializeWithEmbedBlock( - RICH_TEXT_EMBED_HTML - ); + const screen = + await initializeWithEmbedBlock( RICH_TEXT_EMBED_HTML ); // Open Block Settings. fireEvent.press( await screen.findByLabelText( 'Open Settings' ) ); @@ -1120,9 +1106,8 @@ describe( 'Embed block', () => { // Wait for media settings panel. let mediaSettingsPanel; try { - mediaSettingsPanel = await screen.findByText( - 'Media settings' - ); + mediaSettingsPanel = + await screen.findByText( 'Media settings' ); } catch ( e ) { // NOOP. } diff --git a/packages/block-library/src/verse/test/edit.native.js b/packages/block-library/src/verse/test/edit.native.js index bbdacbb90366aa..c91c261c89c358 100644 --- a/packages/block-library/src/verse/test/edit.native.js +++ b/packages/block-library/src/verse/test/edit.native.js @@ -61,9 +61,8 @@ describe( 'Verse block', () => { await addBlock( screen, 'Verse' ); // Act - const verseTextInput = await screen.findByPlaceholderText( - 'Write verse…' - ); + const verseTextInput = + await screen.findByPlaceholderText( 'Write verse…' ); typeInRichText( verseTextInput, 'A great statement.' ); fireEvent( verseTextInput, 'onKeyDown', { nativeEvent: {}, diff --git a/packages/components/src/circular-option-picker/types.ts b/packages/components/src/circular-option-picker/types.ts index 5a54a334124351..da443c7691a95b 100644 --- a/packages/components/src/circular-option-picker/types.ts +++ b/packages/components/src/circular-option-picker/types.ts @@ -69,7 +69,7 @@ type FullListboxCircularOptionPickerProps = CommonCircularOptionPickerProps & { 'aria-label'?: never; 'aria-labelledby': string; } - ); + ); export type ListboxCircularOptionPickerProps = WithBaseId & Omit< FullListboxCircularOptionPickerProps, 'asButtons' >; diff --git a/packages/components/src/color-palette/types.ts b/packages/components/src/color-palette/types.ts index 0b097aa108d38e..b2a7a884fec57d 100644 --- a/packages/components/src/color-palette/types.ts +++ b/packages/components/src/color-palette/types.ts @@ -121,4 +121,4 @@ export type ColorPaletteProps = Pick< PaletteProps, 'onChange' > & { 'aria-labelledby'?: string; 'aria-label'?: never; } - ); + ); diff --git a/packages/components/src/custom-gradient-picker/gradient-bar/control-points.tsx b/packages/components/src/custom-gradient-picker/gradient-bar/control-points.tsx index e761df24823b99..4d09f256620219 100644 --- a/packages/components/src/custom-gradient-picker/gradient-bar/control-points.tsx +++ b/packages/components/src/custom-gradient-picker/gradient-bar/control-points.tsx @@ -93,7 +93,7 @@ function GradientColorPickerDropdown( { ( { placement: 'bottom', offset: 8, - } as const ), + } ) as const, [] ); diff --git a/packages/components/src/custom-gradient-picker/gradient-bar/test/utils.ts b/packages/components/src/custom-gradient-picker/gradient-bar/test/utils.ts index 01396d94f0581d..53804696ba2d3c 100644 --- a/packages/components/src/custom-gradient-picker/gradient-bar/test/utils.ts +++ b/packages/components/src/custom-gradient-picker/gradient-bar/test/utils.ts @@ -13,7 +13,7 @@ describe( 'getHorizontalRelativeGradientPosition', () => { ( { x: 0, width: 1000, - } as DOMRect ) + } ) as DOMRect ); const containerElement = document.createElement( 'div' ); @@ -31,7 +31,7 @@ describe( 'getHorizontalRelativeGradientPosition', () => { ( { x: 50, width: 1000, - } as DOMRect ) + } ) as DOMRect ); const containerElement = document.createElement( 'div' ); @@ -49,7 +49,7 @@ describe( 'getHorizontalRelativeGradientPosition', () => { ( { x: 0, width: 1000, - } as DOMRect ) + } ) as DOMRect ); const containerElement = document.createElement( 'div' ); @@ -68,7 +68,7 @@ describe( 'getHorizontalRelativeGradientPosition', () => { ( { x: 50, width: 1000, - } as DOMRect ) + } ) as DOMRect ); const containerElement = document.createElement( 'div' ); @@ -86,7 +86,7 @@ describe( 'getHorizontalRelativeGradientPosition', () => { ( { x: 50, width: 1000, - } as DOMRect ) + } ) as DOMRect ); const containerElement = document.createElement( 'div' ); diff --git a/packages/components/src/dropdown-menu/index.tsx b/packages/components/src/dropdown-menu/index.tsx index b5ccd92d68b907..9105555927f47c 100644 --- a/packages/components/src/dropdown-menu/index.tsx +++ b/packages/components/src/dropdown-menu/index.tsx @@ -22,7 +22,7 @@ import type { } from './types'; function mergeProps< - T extends { className?: string; [ key: string ]: unknown } + T extends { className?: string; [ key: string ]: unknown }, >( defaultProps: Partial< T > = {}, props: T = {} as T ) { const mergedProps: T = { ...defaultProps, diff --git a/packages/components/src/duotone-picker/types.ts b/packages/components/src/duotone-picker/types.ts index 9c5a71439f7cf0..382f7b364ba7f4 100644 --- a/packages/components/src/duotone-picker/types.ts +++ b/packages/components/src/duotone-picker/types.ts @@ -72,7 +72,7 @@ export type DuotonePickerProps = { 'aria-labelledby'?: string; 'aria-label'?: never; } - ); +); type Color = { color: string; diff --git a/packages/components/src/form-token-field/types.ts b/packages/components/src/form-token-field/types.ts index e343601106f411..e7eabd381a66a6 100644 --- a/packages/components/src/form-token-field/types.ts +++ b/packages/components/src/form-token-field/types.ts @@ -194,7 +194,7 @@ export interface FormTokenFieldProps * `T` can be either a `string` or an object which must have a `value` prop as a string. */ export interface SuggestionsListProps< - T = string | ( Record< string, unknown > & { value: string } ) + T = string | ( Record< string, unknown > & { value: string } ), > { selectedIndex: number; scrollIntoView: boolean; diff --git a/packages/components/src/gradient-picker/types.ts b/packages/components/src/gradient-picker/types.ts index b26a464df5e187..8deb9513cc0dbe 100644 --- a/packages/components/src/gradient-picker/types.ts +++ b/packages/components/src/gradient-picker/types.ts @@ -75,7 +75,7 @@ type GradientPickerBaseProps = { 'aria-labelledby'?: string; 'aria-label'?: never; } - ); +); export type GradientPickerComponentProps = GradientPickerBaseProps & { /** diff --git a/packages/components/src/higher-order/navigate-regions/index.tsx b/packages/components/src/higher-order/navigate-regions/index.tsx index f2b9c31bfbe957..1f4e79654e5bc1 100644 --- a/packages/components/src/higher-order/navigate-regions/index.tsx +++ b/packages/components/src/higher-order/navigate-regions/index.tsx @@ -139,11 +139,10 @@ export function useNavigateRegions( shortcuts: Shortcuts = defaultShortcuts ) { */ export default createHigherOrderComponent( ( Component ) => - ( { shortcuts, ...props } ) => - ( -
- -
- ), + ( { shortcuts, ...props } ) => ( +
+ +
+ ), 'navigateRegions' ); diff --git a/packages/components/src/higher-order/with-filters/test/index.tsx b/packages/components/src/higher-order/with-filters/test/index.tsx index 0f84054cee7376..fd816df59cfcfb 100644 --- a/packages/components/src/higher-order/with-filters/test/index.tsx +++ b/packages/components/src/higher-order/with-filters/test/index.tsx @@ -52,13 +52,12 @@ describe( 'withFilters', () => { addFilter( hookName, 'test/enhanced-component-compose', - ( FilteredComponent ) => () => - ( -
- - -
- ) + ( FilteredComponent ) => () => ( +
+ + +
+ ) ); const EnhancedComponent = withFilters( hookName )( MyComponent ); @@ -72,12 +71,11 @@ describe( 'withFilters', () => { addFilter( hookName, 'test/enhanced-component-spy-1', - ( FilteredComponent ) => () => - ( -
- -
- ) + ( FilteredComponent ) => () => ( +
+ +
+ ) ); const EnhancedComponent = withFilters( hookName )( SpiedComponent ); @@ -100,12 +98,11 @@ describe( 'withFilters', () => { addFilter( hookName, 'test/enhanced-component-spy-1', - ( FilteredComponent ) => () => - ( -
- -
- ) + ( FilteredComponent ) => () => ( +
+ +
+ ) ); await waitFor( () => @@ -125,22 +122,20 @@ describe( 'withFilters', () => { addFilter( hookName, 'test/enhanced-component-spy-1', - ( FilteredComponent ) => () => - ( -
- -
- ) + ( FilteredComponent ) => () => ( +
+ +
+ ) ); addFilter( hookName, 'test/enhanced-component-spy-2', - ( FilteredComponent ) => () => - ( -
- -
- ) + ( FilteredComponent ) => () => ( +
+ +
+ ) ); await waitFor( () => @@ -159,12 +154,11 @@ describe( 'withFilters', () => { addFilter( hookName, 'test/enhanced-component-spy', - ( FilteredComponent ) => () => - ( -
- -
- ) + ( FilteredComponent ) => () => ( +
+ +
+ ) ); await waitFor( () => @@ -196,12 +190,11 @@ describe( 'withFilters', () => { addFilter( hookName, 'test/enhanced-component-spy-1', - ( FilteredComponent ) => () => - ( -
- -
- ) + ( FilteredComponent ) => () => ( +
+ +
+ ) ); await waitFor( () => 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 4302c8f252d4f9..b987d44c4be315 100644 --- a/packages/components/src/higher-order/with-spoken-messages/index.tsx +++ b/packages/components/src/higher-order/with-spoken-messages/index.tsx @@ -17,13 +17,12 @@ import { speak } from '@wordpress/a11y'; * @return {WPComponent} The wrapped component. */ export default createHigherOrderComponent( - ( Component ) => ( props ) => - ( - - ), + ( Component ) => ( props ) => ( + + ), 'withSpokenMessages' ); diff --git a/packages/components/src/mobile/global-styles-context/index.native.js b/packages/components/src/mobile/global-styles-context/index.native.js index d5457c836223b7..cc9f6baf93348b 100644 --- a/packages/components/src/mobile/global-styles-context/index.native.js +++ b/packages/components/src/mobile/global-styles-context/index.native.js @@ -92,13 +92,12 @@ export const useGlobalStyles = () => { return globalStyles; }; -export const withGlobalStyles = ( WrappedComponent ) => ( props ) => - ( - - { ( globalStyles ) => ( - - ) } - - ); +export const withGlobalStyles = ( WrappedComponent ) => ( props ) => ( + + { ( globalStyles ) => ( + + ) } + +); export default GlobalStylesContext; diff --git a/packages/components/src/navigation/use-navigation-tree-nodes.tsx b/packages/components/src/navigation/use-navigation-tree-nodes.tsx index 2d13b967acbc75..45ed86e0262309 100644 --- a/packages/components/src/navigation/use-navigation-tree-nodes.tsx +++ b/packages/components/src/navigation/use-navigation-tree-nodes.tsx @@ -4,7 +4,7 @@ import { useState } from '@wordpress/element'; export function useNavigationTreeNodes< - TNode extends { children?: React.ReactNode; [ key: string ]: unknown } + TNode extends { children?: React.ReactNode; [ key: string ]: unknown }, >() { const [ nodes, setNodes ] = useState< Record< string, Omit< TNode, 'children' > > diff --git a/packages/components/src/popover/test/index.tsx b/packages/components/src/popover/test/index.tsx index fa96c74cffbf3f..33a2d8758c09db 100644 --- a/packages/components/src/popover/test/index.tsx +++ b/packages/components/src/popover/test/index.tsx @@ -23,17 +23,17 @@ import { PopoverInsideIframeRenderedInExternalSlot } from './utils'; type PositionToPlacementTuple = [ NonNullable< PopoverProps[ 'position' ] >, - NonNullable< PopoverProps[ 'placement' ] > + NonNullable< PopoverProps[ 'placement' ] >, ]; type PlacementToAnimationOriginTuple = [ NonNullable< PopoverProps[ 'placement' ] >, number, - number + number, ]; type PlacementToInitialTranslationTuple = [ NonNullable< PopoverProps[ 'placement' ] >, 'translateY' | 'translateX', - CSSProperties[ 'translate' ] + CSSProperties[ 'translate' ], ]; // There's no matching `placement` for 'middle center' positions, diff --git a/packages/components/src/text/styles.js b/packages/components/src/text/styles.js index 171e34fab9f46f..ed821923db9ffc 100644 --- a/packages/components/src/text/styles.js +++ b/packages/components/src/text/styles.js @@ -34,7 +34,8 @@ export const highlighterText = css` mark { background: ${ COLORS.alert.yellow }; border-radius: 2px; - box-shadow: 0 0 0 1px rgba( 0, 0, 0, 0.05 ) inset, + box-shadow: + 0 0 0 1px rgba( 0, 0, 0, 0.05 ) inset, 0 -1px 0 rgba( 0, 0, 0, 0.1 ) inset; } `; diff --git a/packages/components/src/toggle-group-control/toggle-group-control-option-base/styles.ts b/packages/components/src/toggle-group-control/toggle-group-control-option-base/styles.ts index e097f13cc6bf37..dac297fd3ddfa3 100644 --- a/packages/components/src/toggle-group-control/toggle-group-control-option-base/styles.ts +++ b/packages/components/src/toggle-group-control/toggle-group-control-option-base/styles.ts @@ -50,8 +50,10 @@ export const buttonView = ( { padding: 0 12px; position: relative; text-align: center; - transition: background ${ CONFIG.transitionDurationFast } linear, - color ${ CONFIG.transitionDurationFast } linear, font-weight 60ms linear; + transition: + background ${ CONFIG.transitionDurationFast } linear, + color ${ CONFIG.transitionDurationFast } linear, + font-weight 60ms linear; ${ reduceMotion( 'transition' ) } user-select: none; width: 100%; @@ -82,7 +84,8 @@ const deselectable = css` color: ${ COLORS.gray[ 900 ] }; &:focus { - box-shadow: inset 0 0 0 1px ${ COLORS.white }, + box-shadow: + inset 0 0 0 1px ${ COLORS.white }, 0 0 0 ${ CONFIG.borderWidthFocus } ${ COLORS.theme.accent }; outline: 2px solid transparent; } diff --git a/packages/components/src/toggle-group-control/toggle-group-control/as-button-group.tsx b/packages/components/src/toggle-group-control/toggle-group-control/as-button-group.tsx index e425bd135f21cd..7836cfa116a6fa 100644 --- a/packages/components/src/toggle-group-control/toggle-group-control/as-button-group.tsx +++ b/packages/components/src/toggle-group-control/toggle-group-control/as-button-group.tsx @@ -62,7 +62,7 @@ function UnforwardedToggleGroupControlAsButtonGroup( isBlock: ! isAdaptiveWidth, isDeselectable: true, size, - } as ToggleGroupControlContextProps ), + } ) as ToggleGroupControlContextProps, [ baseId, selectedValue, setSelectedValue, isAdaptiveWidth, size ] ); diff --git a/packages/components/src/toggle-group-control/toggle-group-control/as-radio-group.tsx b/packages/components/src/toggle-group-control/toggle-group-control/as-radio-group.tsx index cc842782312de4..e83306b91cb7cd 100644 --- a/packages/components/src/toggle-group-control/toggle-group-control/as-radio-group.tsx +++ b/packages/components/src/toggle-group-control/toggle-group-control/as-radio-group.tsx @@ -78,7 +78,7 @@ function UnforwardedToggleGroupControlAsRadioGroup( size, value: selectedValue, setValue, - } as ToggleGroupControlContextProps ), + } ) as ToggleGroupControlContextProps, [ baseId, isAdaptiveWidth, size, selectedValue, setValue ] ); diff --git a/packages/components/src/toolbar/toolbar-group/types.ts b/packages/components/src/toolbar/toolbar-group/types.ts index 6475f3cf927f4a..ea25a5ea855271 100644 --- a/packages/components/src/toolbar/toolbar-group/types.ts +++ b/packages/components/src/toolbar/toolbar-group/types.ts @@ -72,7 +72,7 @@ export type ToolbarGroupProps = ToolbarGroupPropsBase & */ title: string; } - ); + ); export type ToolbarGroupCollapsedProps = DropdownMenuProps; diff --git a/packages/components/src/ui/context/context-connect.ts b/packages/components/src/ui/context/context-connect.ts index 4e5fcfbf26795b..8db2bbc987c0df 100644 --- a/packages/components/src/ui/context/context-connect.ts +++ b/packages/components/src/ui/context/context-connect.ts @@ -18,7 +18,7 @@ import type { WordPressComponentFromProps } from '.'; type AcceptsTwoArgs< F extends ( ...args: any ) => any, - ErrorMessage = never + ErrorMessage = never, > = Parameters< F >[ 'length' ] extends 2 ? {} : ErrorMessage; type ContextConnectOptions = { @@ -34,7 +34,7 @@ type ContextConnectOptions = { * @return The connected WordPressComponent */ export function contextConnect< - C extends ( props: any, ref: ForwardedRef< any > ) => JSX.Element | null + C extends ( props: any, ref: ForwardedRef< any > ) => JSX.Element | null, >( Component: C & AcceptsTwoArgs< @@ -66,7 +66,7 @@ export function contextConnectWithoutRef< P >( // component wrappers. function _contextConnect< C extends ( props: any, ref: ForwardedRef< any > ) => JSX.Element | null, - O extends ContextConnectOptions + O extends ContextConnectOptions, >( Component: C, namespace: string, diff --git a/packages/components/src/ui/context/wordpress-component.ts b/packages/components/src/ui/context/wordpress-component.ts index bf70924b40bbbd..57e69abdc38093 100644 --- a/packages/components/src/ui/context/wordpress-component.ts +++ b/packages/components/src/ui/context/wordpress-component.ts @@ -10,7 +10,7 @@ export type WordPressComponentProps< /** The HTML element to inherit props from. */ T extends React.ElementType, /** Supports polymorphism through the `as` prop. */ - IsPolymorphic extends boolean = true + IsPolymorphic extends boolean = true, > = P & // The `children` prop is being explicitly omitted since it is otherwise implicitly added // by `ComponentPropsWithRef`. The context is that components should require the `children` @@ -26,7 +26,7 @@ export type WordPressComponentProps< export type WordPressComponent< T extends React.ElementType, O, - IsPolymorphic extends boolean + IsPolymorphic extends boolean, > = { < TT extends React.ElementType >( props: WordPressComponentProps< O, TT, IsPolymorphic > & @@ -49,7 +49,7 @@ export type WordPressComponent< export type WordPressComponentFromProps< Props, - ForwardsRef extends boolean = true + ForwardsRef extends boolean = true, > = Props extends WordPressComponentProps< infer P, infer T, infer I > ? WordPressComponent< T, diff --git a/packages/components/src/unit-control/index.tsx b/packages/components/src/unit-control/index.tsx index cd5bf4e4787682..ed57f4cc703fe6 100644 --- a/packages/components/src/unit-control/index.tsx +++ b/packages/components/src/unit-control/index.tsx @@ -76,10 +76,15 @@ function UnforwardedUnitControl( unitsProp ); const [ { value: firstUnitValue = '' } = {}, ...rest ] = list; - const firstCharacters = rest.reduce( ( carry, { value } ) => { - const first = escapeRegExp( value?.substring( 0, 1 ) || '' ); - return carry.includes( first ) ? carry : `${ carry }|${ first }`; - }, escapeRegExp( firstUnitValue.substring( 0, 1 ) ) ); + const firstCharacters = rest.reduce( + ( carry, { value } ) => { + const first = escapeRegExp( value?.substring( 0, 1 ) || '' ); + return carry.includes( first ) + ? carry + : `${ carry }|${ first }`; + }, + escapeRegExp( firstUnitValue.substring( 0, 1 ) ) + ); return [ list, new RegExp( `^(?:${ firstCharacters })$`, 'i' ) ]; }, [ nonNullValueProp, unitProp, unitsProp ] ); const [ parsedQuantity, parsedUnit ] = getParsedQuantityAndUnit( diff --git a/packages/components/src/unit-control/styles/unit-control-styles.ts b/packages/components/src/unit-control/styles/unit-control-styles.ts index e5557307b0b0d0..92b1f5f2fd8b4e 100644 --- a/packages/components/src/unit-control/styles/unit-control-styles.ts +++ b/packages/components/src/unit-control/styles/unit-control-styles.ts @@ -82,7 +82,9 @@ const unitSelectSizes = ( { selectSize = 'default' }: SelectProps ) => { default: css` height: 100%; border: 1px solid transparent; - transition: box-shadow 0.1s linear, border 0.1s linear; + transition: + box-shadow 0.1s linear, + border 0.1s linear; ${ rtl( { borderTopLeftRadius: 0, borderBottomLeftRadius: 0 } )() } diff --git a/packages/components/src/unit-control/test/utils.ts b/packages/components/src/unit-control/test/utils.ts index b843764f4a57ee..c35167ae49243c 100644 --- a/packages/components/src/unit-control/test/utils.ts +++ b/packages/components/src/unit-control/test/utils.ts @@ -248,7 +248,7 @@ describe( 'UnitControl utils', () => { const cases: [ number | string | undefined, number | undefined, - string | undefined + string | undefined, ][] = [ // Test undefined. [ undefined, undefined, undefined ], diff --git a/packages/components/src/utils/use-deprecated-props.ts b/packages/components/src/utils/use-deprecated-props.ts index ee5dcc67a75303..8c102906970d0e 100644 --- a/packages/components/src/utils/use-deprecated-props.ts +++ b/packages/components/src/utils/use-deprecated-props.ts @@ -7,7 +7,7 @@ export function useDeprecated36pxDefaultSizeProp< P extends Record< string, any > & { __next36pxDefaultSize?: boolean; __next40pxDefaultSize?: boolean; - } + }, >( props: P, /** The component identifier in dot notation, e.g. `wp.components.ComponentName`. */ diff --git a/packages/compose/README.md b/packages/compose/README.md index b0cff6e7128db4..5a3ec6437b1fdc 100644 --- a/packages/compose/README.md +++ b/packages/compose/README.md @@ -116,9 +116,7 @@ _Usage_ ```ts type Props = { foo: string }; const Component = ( props: Props ) =>
{ props.foo }
; -const ConditionalComponent = ifCondition( - ( props: Props ) => props.foo.length !== 0 -)( Component ); +const ConditionalComponent = ifCondition( ( props: Props ) => props.foo.length !== 0 )( Component ); ; // => null ; // =>
bar
; ``` diff --git a/packages/compose/src/higher-order/pure/index.tsx b/packages/compose/src/higher-order/pure/index.tsx index 28b2f45fada977..65684738b708ac 100644 --- a/packages/compose/src/higher-order/pure/index.tsx +++ b/packages/compose/src/higher-order/pure/index.tsx @@ -41,7 +41,6 @@ const pure = createHigherOrderComponent( function < Props extends {} >( return ; } }; -}, -'pure' ); +}, 'pure' ); export default pure; diff --git a/packages/compose/src/hooks/use-dialog/index.ts b/packages/compose/src/hooks/use-dialog/index.ts index dd7e47422eb567..66974b60e07035 100644 --- a/packages/compose/src/hooks/use-dialog/index.ts +++ b/packages/compose/src/hooks/use-dialog/index.ts @@ -34,7 +34,7 @@ type DialogOptions = { type useDialogReturn = [ RefCallback< HTMLElement >, - ReturnType< typeof useFocusOutside > & Pick< HTMLElement, 'tabIndex' > + ReturnType< typeof useFocusOutside > & Pick< HTMLElement, 'tabIndex' >, ]; /** diff --git a/packages/compose/src/hooks/use-resize-observer/index.tsx b/packages/compose/src/hooks/use-resize-observer/index.tsx index 2f531d9f9bffde..b2ff87f2c025f7 100644 --- a/packages/compose/src/hooks/use-resize-observer/index.tsx +++ b/packages/compose/src/hooks/use-resize-observer/index.tsx @@ -336,7 +336,7 @@ function useResizeObserver< T extends HTMLElement >( */ export default function useResizeAware(): [ WPElement, - { width: number | null; height: number | null } + { width: number | null; height: number | null }, ] { const { ref, width, height } = useResizeObserver(); const sizes = useMemo( () => { diff --git a/packages/compose/src/utils/create-higher-order-component/index.ts b/packages/compose/src/utils/create-higher-order-component/index.ts index 62da02d6c08db8..7c297b18ab2125 100644 --- a/packages/compose/src/utils/create-higher-order-component/index.ts +++ b/packages/compose/src/utils/create-higher-order-component/index.ts @@ -23,7 +23,7 @@ export type WithInjectedProps< C, I > = ComponentType< */ export function createHigherOrderComponent< TInner extends ComponentType< any >, - TOuter extends ComponentType< any > + TOuter extends ComponentType< any >, >( mapComponent: ( Inner: TInner ) => TOuter, modifierName: string ) { return ( Inner: TInner ) => { const Outer = mapComponent( Inner ); diff --git a/packages/core-data/src/entity-types/helpers.ts b/packages/core-data/src/entity-types/helpers.ts index 59ed25a72bc8b1..943dece90e353c 100644 --- a/packages/core-data/src/entity-types/helpers.ts +++ b/packages/core-data/src/entity-types/helpers.ts @@ -64,7 +64,7 @@ export type Context = 'view' | 'edit' | 'embed'; export type ContextualField< FieldType, AvailableInContexts extends Context, - C extends Context + C extends Context, > = AvailableInContexts extends C ? FieldType : never; /** @@ -93,7 +93,7 @@ export type OmitNevers< : T[ K ] extends Record< string, unknown > ? OmitNevers< T[ K ] > : T[ K ]; - } + }, > = Pick< Nevers, { diff --git a/packages/core-data/src/hooks/use-resource-permissions.ts b/packages/core-data/src/hooks/use-resource-permissions.ts index 1c9e95429d14cf..7da7189e2e5067 100644 --- a/packages/core-data/src/hooks/use-resource-permissions.ts +++ b/packages/core-data/src/hooks/use-resource-permissions.ts @@ -38,7 +38,7 @@ type ResourcePermissionsResolution< IdType > = [ HasResolved, ResolutionDetails & GlobalResourcePermissionsResolution & - ( IdType extends void ? SpecificResourcePermissionsResolution : {} ) + ( IdType extends void ? SpecificResourcePermissionsResolution : {} ), ]; /** diff --git a/packages/core-data/src/selectors.ts b/packages/core-data/src/selectors.ts index 3536a3ef55adf4..a75e2359261c32 100644 --- a/packages/core-data/src/selectors.ts +++ b/packages/core-data/src/selectors.ts @@ -278,7 +278,7 @@ export interface GetEntityRecord { < EntityRecord extends | ET.EntityRecord< any > - | Partial< ET.EntityRecord< any > > + | Partial< ET.EntityRecord< any > >, >( state: State, kind: string, @@ -290,7 +290,7 @@ export interface GetEntityRecord { CurriedSignature: < EntityRecord extends | ET.EntityRecord< any > - | Partial< ET.EntityRecord< any > > + | Partial< ET.EntityRecord< any > >, >( kind: string, name: string, @@ -317,7 +317,7 @@ export const getEntityRecord = createSelector( ( < EntityRecord extends | ET.EntityRecord< any > - | Partial< ET.EntityRecord< any > > + | Partial< ET.EntityRecord< any > >, >( state: State, kind: string, @@ -381,7 +381,7 @@ export const getEntityRecord = createSelector( * @return Record. */ export function __experimentalGetEntityRecordNoResolver< - EntityRecord extends ET.EntityRecord< any > + EntityRecord extends ET.EntityRecord< any >, >( state: State, kind: string, name: string, key: EntityRecordKey ) { return getEntityRecord< EntityRecord >( state, kind, name, key ); } @@ -478,7 +478,7 @@ export interface GetEntityRecords { < EntityRecord extends | ET.EntityRecord< any > - | Partial< ET.EntityRecord< any > > + | Partial< ET.EntityRecord< any > >, >( state: State, kind: string, @@ -489,7 +489,7 @@ export interface GetEntityRecords { CurriedSignature: < EntityRecord extends | ET.EntityRecord< any > - | Partial< ET.EntityRecord< any > > + | Partial< ET.EntityRecord< any > >, >( kind: string, name: string, @@ -511,7 +511,7 @@ export interface GetEntityRecords { export const getEntityRecords = ( < EntityRecord extends | ET.EntityRecord< any > - | Partial< ET.EntityRecord< any > > + | Partial< ET.EntityRecord< any > >, >( state: State, kind: string, diff --git a/packages/create-block/lib/index.js b/packages/create-block/lib/index.js index 785e593a379fe6..8e3d43c140460a 100644 --- a/packages/create-block/lib/index.js +++ b/packages/create-block/lib/index.js @@ -185,9 +185,8 @@ program ], variant ).filter( filterOptionsProvided ); - const result = await inquirer.prompt( - pluginPrompts - ); + const result = + await inquirer.prompt( pluginPrompts ); return result; } ) : {}; diff --git a/packages/create-block/lib/templates.js b/packages/create-block/lib/templates.js index 29f713499e3f23..e835e31c08425e 100644 --- a/packages/create-block/lib/templates.js +++ b/packages/create-block/lib/templates.js @@ -202,9 +202,11 @@ const getPluginTemplate = async ( templateName ) => { const { name } = npmPackageArg( templateName ); return await configToTemplate( - require( require.resolve( name, { - paths: [ tempCwd ], - } ) ) + require( + require.resolve( name, { + paths: [ tempCwd ], + } ) + ) ); } catch ( error ) { if ( error instanceof CLIError ) { diff --git a/packages/data/src/components/with-registry/index.js b/packages/data/src/components/with-registry/index.js index a5a6ce9503f885..faf3da8c009add 100644 --- a/packages/data/src/components/with-registry/index.js +++ b/packages/data/src/components/with-registry/index.js @@ -17,14 +17,13 @@ import { RegistryConsumer } from '../registry-provider'; * @return {WPComponent} Enhanced component. */ const withRegistry = createHigherOrderComponent( - ( OriginalComponent ) => ( props ) => - ( - - { ( registry ) => ( - - ) } - - ), + ( OriginalComponent ) => ( props ) => ( + + { ( registry ) => ( + + ) } + + ), 'withRegistry' ); diff --git a/packages/data/src/dispatch.ts b/packages/data/src/dispatch.ts index c1f28c21187cce..348865112a59c6 100644 --- a/packages/data/src/dispatch.ts +++ b/packages/data/src/dispatch.ts @@ -24,7 +24,7 @@ import defaultRegistry from './default-registry'; * @return Object containing the action creators. */ export function dispatch< - StoreNameOrDescriptor extends StoreDescriptor< AnyConfig > | string + StoreNameOrDescriptor extends StoreDescriptor< AnyConfig > | string, >( storeNameOrDescriptor: StoreNameOrDescriptor ): DispatchReturn< StoreNameOrDescriptor > { diff --git a/packages/data/src/types.ts b/packages/data/src/types.ts index af8cf823852755..570bb1e1890ceb 100644 --- a/packages/data/src/types.ts +++ b/packages/data/src/types.ts @@ -33,7 +33,7 @@ export interface StoreDescriptor< Config extends AnyConfig > { export interface ReduxStoreConfig< State, ActionCreators extends MapOf< ActionCreator >, - Selectors + Selectors, > { initialState?: State; reducer: ( state: any, action: any ) => any; @@ -182,7 +182,7 @@ export type ActionCreatorsOf< Config extends AnyConfig > = // return type of each action creator to account for internal registry details -- // for example, dispatched actions are wrapped with a Promise. export type PromisifiedActionCreators< - ActionCreators extends MapOf< ActionCreator > + ActionCreators extends MapOf< ActionCreator >, > = { [ Action in keyof ActionCreators ]: PromisifyActionCreator< ActionCreators[ Action ] diff --git a/packages/e2e-test-utils/src/inserter.js b/packages/e2e-test-utils/src/inserter.js index 68f2ffaff49ac2..ebbda244d18564 100644 --- a/packages/e2e-test-utils/src/inserter.js +++ b/packages/e2e-test-utils/src/inserter.js @@ -238,7 +238,7 @@ export async function insertFromGlobalInserter( category, searchTerm ) { await page.$x( `//*[@role='option' and contains(., '${ searchTerm }')]` ) - )[ 0 ]; + )[ 0 ]; } catch ( error ) { // noop } diff --git a/packages/e2e-tests/specs/editor/plugins/annotations.test.js b/packages/e2e-tests/specs/editor/plugins/annotations.test.js index 24eaebb7659665..50290aa1cc68bb 100644 --- a/packages/e2e-tests/specs/editor/plugins/annotations.test.js +++ b/packages/e2e-tests/specs/editor/plugins/annotations.test.js @@ -50,7 +50,7 @@ describe( 'Annotations', () => { // Click add annotation button. const addAnnotationButton = ( await page.$x( "//button[contains(text(), 'Add annotation')]" ) - )[ 0 ]; + )[ 0 ]; await addAnnotationButton.click(); await canvas().evaluate( () => document.querySelector( '.wp-block-paragraph' ).focus() @@ -66,7 +66,7 @@ describe( 'Annotations', () => { // Click remove annotations button. const addAnnotationButton = ( await page.$x( "//button[contains(text(), 'Remove annotations')]" ) - )[ 0 ]; + )[ 0 ]; await addAnnotationButton.click(); await canvas().evaluate( () => document.querySelector( '[contenteditable]' ).focus() diff --git a/packages/e2e-tests/specs/editor/plugins/container-blocks.test.js b/packages/e2e-tests/specs/editor/plugins/container-blocks.test.js index 88c1a7fc8271ae..7393b2700ff2b7 100644 --- a/packages/e2e-tests/specs/editor/plugins/container-blocks.test.js +++ b/packages/e2e-tests/specs/editor/plugins/container-blocks.test.js @@ -121,7 +121,7 @@ describe( 'Container block without paragraph support', () => { // Insert an image block. const insertButton = ( await page.$x( `//button//span[contains(text(), 'Image')]` ) - )[ 0 ]; + )[ 0 ]; await insertButton.click(); // Check the inserted content. diff --git a/packages/e2e-tests/specs/editor/plugins/custom-taxonomies.test.js b/packages/e2e-tests/specs/editor/plugins/custom-taxonomies.test.js index 42c476f9cf12a4..3d65b1ebc98f76 100644 --- a/packages/e2e-tests/specs/editor/plugins/custom-taxonomies.test.js +++ b/packages/e2e-tests/specs/editor/plugins/custom-taxonomies.test.js @@ -32,7 +32,7 @@ describe( 'Custom Taxonomies labels are used', () => { // Get the classes from the panel. const buttonClassName = await ( await openButton.getProperty( 'className' ) - ).jsonValue(); + ).jsonValue(); // Open the panel if needed. if ( -1 === buttonClassName.indexOf( 'is-opened' ) ) { diff --git a/packages/e2e-tests/specs/editor/plugins/inner-blocks-render-appender.test.js b/packages/e2e-tests/specs/editor/plugins/inner-blocks-render-appender.test.js index 81a7d943331bb4..1322713b033e24 100644 --- a/packages/e2e-tests/specs/editor/plugins/inner-blocks-render-appender.test.js +++ b/packages/e2e-tests/specs/editor/plugins/inner-blocks-render-appender.test.js @@ -58,7 +58,7 @@ describe( 'RenderAppender prop of InnerBlocks', () => { const inserterPopover = await page.$( INSERTER_RESULTS_SELECTOR ); const quoteButton = ( await inserterPopover.$x( QUOTE_INSERT_BUTTON_SELECTOR ) - )[ 0 ]; + )[ 0 ]; // Insert a quote block. await quoteButton.click(); @@ -93,7 +93,7 @@ describe( 'RenderAppender prop of InnerBlocks', () => { const inserterPopover = await page.$( INSERTER_RESULTS_SELECTOR ); const quoteButton = ( await inserterPopover.$x( QUOTE_INSERT_BUTTON_SELECTOR ) - )[ 0 ]; + )[ 0 ]; // Insert a quote block. await quoteButton.click(); diff --git a/packages/e2e-tests/specs/editor/plugins/meta-boxes.test.js b/packages/e2e-tests/specs/editor/plugins/meta-boxes.test.js index 6b3001c96d80bb..3a75f9656c71e5 100644 --- a/packages/e2e-tests/specs/editor/plugins/meta-boxes.test.js +++ b/packages/e2e-tests/specs/editor/plugins/meta-boxes.test.js @@ -103,9 +103,8 @@ describe( 'Meta boxes', () => { // Open the excerpt panel. await openDocumentSettingsSidebar(); - const excerptButton = await findSidebarPanelToggleButtonWithTitle( - 'Excerpt' - ); + const excerptButton = + await findSidebarPanelToggleButtonWithTitle( 'Excerpt' ); if ( excerptButton ) { await excerptButton.click( 'button' ); } diff --git a/packages/e2e-tests/specs/editor/various/change-detection.test.js b/packages/e2e-tests/specs/editor/various/change-detection.test.js index 97157060d36245..32e51150945330 100644 --- a/packages/e2e-tests/specs/editor/various/change-detection.test.js +++ b/packages/e2e-tests/specs/editor/various/change-detection.test.js @@ -102,7 +102,7 @@ describe( 'Change detection', () => { const postPendingReviewButton = ( await page.$x( "//label[contains(text(), 'Pending review')]" ) - )[ 0 ]; + )[ 0 ]; await postPendingReviewButton.click( 'button' ); // Force autosave to occur immediately. diff --git a/packages/e2e-tests/specs/editor/various/inserting-blocks.test.js b/packages/e2e-tests/specs/editor/various/inserting-blocks.test.js index 84c251d6534685..bed9002e303a20 100644 --- a/packages/e2e-tests/specs/editor/various/inserting-blocks.test.js +++ b/packages/e2e-tests/specs/editor/various/inserting-blocks.test.js @@ -259,7 +259,7 @@ describe( 'Inserting blocks', () => { const headingButton = ( await page.$x( `//button//span[contains(text(), 'Heading')]` ) - )[ 0 ]; + )[ 0 ]; // Hover over the block should show the blue line indicator. await headingButton.hover(); @@ -354,7 +354,7 @@ describe( 'Inserting blocks', () => { await openGlobalBlockInserter(); const paragraphButton = ( await page.$x( `//button//span[contains(text(), 'Paragraph')]` ) - )[ 0 ]; + )[ 0 ]; await paragraphButton.hover(); const preview = await page.waitForSelector( '.block-editor-inserter__preview', diff --git a/packages/e2e-tests/specs/site-editor/multi-entity-saving.test.js b/packages/e2e-tests/specs/site-editor/multi-entity-saving.test.js index c2bd3cb6d75076..fe5334d2a12769 100644 --- a/packages/e2e-tests/specs/site-editor/multi-entity-saving.test.js +++ b/packages/e2e-tests/specs/site-editor/multi-entity-saving.test.js @@ -77,9 +77,8 @@ describe( 'Multi-entity save flow', () => { // Reusable assertions inside Post editor. const assertMultiSaveEnabled = async () => { - const multiSaveButton = await page.waitForSelector( - multiSaveSelector - ); + const multiSaveButton = + await page.waitForSelector( multiSaveSelector ); expect( multiSaveButton ).not.toBeNull(); }; const assertMultiSaveDisabled = async () => { diff --git a/packages/e2e-tests/specs/widgets/editing-widgets.test.js b/packages/e2e-tests/specs/widgets/editing-widgets.test.js index 2d77e297aaeabc..9292867159e610 100644 --- a/packages/e2e-tests/specs/widgets/editing-widgets.test.js +++ b/packages/e2e-tests/specs/widgets/editing-widgets.test.js @@ -388,9 +388,8 @@ describe( 'Widgets screen', () => { name: 'Block: Widget Area', } ); await firstWidgetArea.focus(); - const marqueeBlock = await getBlockInGlobalInserter( - 'Marquee Greeting' - ); + const marqueeBlock = + await getBlockInGlobalInserter( 'Marquee Greeting' ); await marqueeBlock.click(); await page.waitForFunction( ( expectedMarquees ) => { @@ -721,9 +720,8 @@ describe( 'Widgets screen', () => { const [ firstWidgetArea, secondWidgetArea ] = widgetAreas; // Insert a paragraph it should be in the first widget area. - const inserterParagraphBlock = await getBlockInGlobalInserter( - 'Paragraph' - ); + const inserterParagraphBlock = + await getBlockInGlobalInserter( 'Paragraph' ); await inserterParagraphBlock.hover(); await inserterParagraphBlock.click(); const addedParagraphBlockInFirstWidgetArea = await find( diff --git a/packages/edit-site/src/store/actions.js b/packages/edit-site/src/store/actions.js index f690075c311489..3b4b9bd49387f1 100644 --- a/packages/edit-site/src/store/actions.js +++ b/packages/edit-site/src/store/actions.js @@ -285,7 +285,7 @@ export const setPage = .getEntityRecords( 'postType', 'wp_template', { per_page: -1, } ) - )?.find( ( { slug } ) => slug === currentTemplateSlug ); + )?.find( ( { slug } ) => slug === currentTemplateSlug ); if ( currentTemplate ) { template = currentTemplate; } else { diff --git a/packages/env/lib/download-sources.js b/packages/env/lib/download-sources.js index aec47f23203d19..45c65fe715de46 100644 --- a/packages/env/lib/download-sources.js +++ b/packages/env/lib/download-sources.js @@ -176,7 +176,7 @@ async function downloadZipSource( source, { onProgress, spinner, debug } ) { rimraf( source.path ), fs.promises.readdir( tempDir ), ] ) - )[ 2 ]; + )[ 2 ]; /** * The plugin container is the extracted directory which is the direct parent diff --git a/packages/eslint-plugin/CHANGELOG.md b/packages/eslint-plugin/CHANGELOG.md index e7ffc1345957b0..a5b8cbc05f26a7 100644 --- a/packages/eslint-plugin/CHANGELOG.md +++ b/packages/eslint-plugin/CHANGELOG.md @@ -7,9 +7,10 @@ - The bundled `@typescript-eslint/parser` and `@typescript-eslint/eslint-plugin` dependencies has been updated from requiring ^5.62.0 to requiring ^6.4.1 ([#53975](https://github.com/WordPress/gutenberg/pull/53975)): - Removes the deprecated `@typescript-eslint/no-duplicate-imports` rule in favor of `import/no-duplicates`. -### Enhancement +### Enhancements - Added a new `test-playwright` ruleset using [`eslint-plugin-playwright`](https://www.npmjs.com/package/eslint-plugin-playwright). +- The bundled `eslint-plugin-prettier` dependency has been updated from requiring `^3.3.0` to requiring `^5.0.0` ([#54539](https://github.com/WordPress/gutenberg/pull/54539)). ## 15.1.0 (2023-08-31) diff --git a/packages/eslint-plugin/package.json b/packages/eslint-plugin/package.json index a354b04626f55f..473e6cf9269c47 100644 --- a/packages/eslint-plugin/package.json +++ b/packages/eslint-plugin/package.json @@ -43,7 +43,7 @@ "eslint-plugin-jsdoc": "^46.4.6", "eslint-plugin-jsx-a11y": "^6.5.1", "eslint-plugin-playwright": "^0.15.3", - "eslint-plugin-prettier": "^3.3.0", + "eslint-plugin-prettier": "^5.0.0", "eslint-plugin-react": "^7.27.0", "eslint-plugin-react-hooks": "^4.3.0", "globals": "^13.12.0", diff --git a/packages/lazy-import/README.md b/packages/lazy-import/README.md index af19716c2ebc16..cd3dcb16eb6abb 100644 --- a/packages/lazy-import/README.md +++ b/packages/lazy-import/README.md @@ -55,7 +55,7 @@ function onInstall() { lazyImport( 'fbjs@^1.0.0', { localPath: './lib/shallowEqual', onInstall, -} ).then(/* ... */); +} ).then( /* ... */ ); ``` Note that `lazyImport` can throw an error when offline and unable to install the dependency using NPM. You may want to anticipate this and provide remediation steps for a failed install, such as logging a warning messsage: diff --git a/packages/react-native-editor/__device-tests__/helpers/utils.js b/packages/react-native-editor/__device-tests__/helpers/utils.js index 64fb2ed510a45e..9fb43452dcffca 100644 --- a/packages/react-native-editor/__device-tests__/helpers/utils.js +++ b/packages/react-native-editor/__device-tests__/helpers/utils.js @@ -526,9 +526,8 @@ const dragAndDropAfterElement = async ( driver, element, nextElement ) => { const toggleHtmlMode = async ( driver, toggleOn ) => { if ( isAndroid() ) { - const moreOptionsButton = await driver.elementByAccessibilityId( - 'More options' - ); + const moreOptionsButton = + await driver.elementByAccessibilityId( 'More options' ); await moreOptionsButton.click(); const showHtmlButtonXpath = @@ -536,9 +535,8 @@ const toggleHtmlMode = async ( driver, toggleOn ) => { await clickIfClickable( driver, showHtmlButtonXpath ); } else if ( toggleOn ) { - const moreOptionsButton = await driver.elementByAccessibilityId( - 'editor-menu-button' - ); + const moreOptionsButton = + await driver.elementByAccessibilityId( 'editor-menu-button' ); await moreOptionsButton.click(); await clickIfClickable( @@ -548,9 +546,8 @@ const toggleHtmlMode = async ( driver, toggleOn ) => { } else { // This is to wait for the clipboard paste notification to disappear, currently it overlaps with the menu button await driver.sleep( 3000 ); - const moreOptionsButton = await driver.elementByAccessibilityId( - 'editor-menu-button' - ); + const moreOptionsButton = + await driver.elementByAccessibilityId( 'editor-menu-button' ); await moreOptionsButton.click(); await clickIfClickable( driver, diff --git a/packages/react-native-editor/__device-tests__/pages/editor-page.js b/packages/react-native-editor/__device-tests__/pages/editor-page.js index 8e2bc02d657b9a..65446ca4b5dda8 100644 --- a/packages/react-native-editor/__device-tests__/pages/editor-page.js +++ b/packages/react-native-editor/__device-tests__/pages/editor-page.js @@ -57,9 +57,8 @@ class EditorPage { await launchApp( this.driver, { initialData } ); // Stores initial values from the editor for different helpers. - const addButton = await this.driver.elementsByAccessibilityId( - ADD_BLOCK_ID - ); + const addButton = + await this.driver.elementsByAccessibilityId( ADD_BLOCK_ID ); if ( addButton.length !== 0 ) { this.initialValues.addButtonLocation = @@ -74,9 +73,8 @@ class EditorPage { } async getAddBlockButton() { - const elements = await this.driver.elementsByAccessibilityId( - ADD_BLOCK_ID - ); + const elements = + await this.driver.elementsByAccessibilityId( ADD_BLOCK_ID ); return elements[ 0 ]; } @@ -197,9 +195,8 @@ class EditorPage { await swipeDown( this.driver ); } - const elements = await this.driver.elementsByAccessibilityId( - titleElement - ); + const elements = + await this.driver.elementsByAccessibilityId( titleElement ); if ( elements.length === 0 || @@ -530,9 +527,8 @@ class EditorPage { } async clickToolBarButton( buttonName ) { - const toolBarButton = await this.driver.elementByAccessibilityId( - buttonName - ); + const toolBarButton = + await this.driver.elementByAccessibilityId( buttonName ); await toolBarButton.click(); } @@ -540,9 +536,8 @@ class EditorPage { let navigateUpElements = []; do { await this.driver.sleep( 2000 ); - navigateUpElements = await this.driver.elementsByAccessibilityId( - 'Navigate Up' - ); + navigateUpElements = + await this.driver.elementsByAccessibilityId( 'Navigate Up' ); if ( navigateUpElements.length > 0 ) { await navigateUpElements[ 0 ].click(); } @@ -784,9 +779,8 @@ class EditorPage { this.driver, '//XCUIElementTypeOther[@name="Media Add image or video"]' ); - const addMediaButton = await mediaSection.elementByAccessibilityId( - 'Add image or video' - ); + const addMediaButton = + await mediaSection.elementByAccessibilityId( 'Add image or video' ); await addMediaButton.click(); } @@ -810,9 +804,8 @@ class EditorPage { this.accessibilityIdKey ); const blockLocator = `//*[@${ this.accessibilityIdXPathAttrib }="${ accessibilityId }"]//XCUIElementTypeButton[@name="Image block. Empty"]`; - const imageBlockInnerElement = await this.driver.elementByXPath( - blockLocator - ); + const imageBlockInnerElement = + await this.driver.elementByXPath( blockLocator ); await imageBlockInnerElement.click(); } diff --git a/packages/scripts/CHANGELOG.md b/packages/scripts/CHANGELOG.md index acf24a423c0aff..2c507e288f1c2f 100644 --- a/packages/scripts/CHANGELOG.md +++ b/packages/scripts/CHANGELOG.md @@ -2,9 +2,10 @@ ## Unreleased -### Enhancement +### Enhancements - Added support for `test-playwright` script ([#53108](https://github.com/WordPress/gutenberg/pull/53108)). +- The bundled `wp-prettier` dependency has been upgraded from `2.8.5` to `3.0.3` ([#54539](https://github.com/WordPress/gutenberg/pull/54539)). ### Bug Fix diff --git a/packages/scripts/package.json b/packages/scripts/package.json index 12ca7854da1913..b5af25a0eb1cfd 100644 --- a/packages/scripts/package.json +++ b/packages/scripts/package.json @@ -75,7 +75,7 @@ "playwright-core": "1.32.0", "postcss": "^8.4.5", "postcss-loader": "^6.2.1", - "prettier": "npm:wp-prettier@2.8.5", + "prettier": "npm:wp-prettier@3.0.3-beta-3", "puppeteer-core": "^13.2.0", "react-refresh": "^0.10.0", "read-pkg-up": "^7.0.1", diff --git a/test/e2e/specs/editor/blocks/cover.spec.js b/test/e2e/specs/editor/blocks/cover.spec.js index e6042648b0e8da..98be7b85304090 100644 --- a/test/e2e/specs/editor/blocks/cover.spec.js +++ b/test/e2e/specs/editor/blocks/cover.spec.js @@ -40,9 +40,8 @@ test.describe( 'Cover', () => { await expect( blackColorSwatch ).toBeVisible(); // Get the RGB value of Black. - const [ blackRGB ] = await coverBlockUtils.getBackgroundColorAndOpacity( - coverBlock - ); + const [ blackRGB ] = + await coverBlockUtils.getBackgroundColorAndOpacity( coverBlock ); // Create the block by clicking selected color button. await blackColorSwatch.click(); diff --git a/test/e2e/specs/editor/blocks/image.spec.js b/test/e2e/specs/editor/blocks/image.spec.js index 6006d5976d98f5..21ec3e2486c3a5 100644 --- a/test/e2e/specs/editor/blocks/image.spec.js +++ b/test/e2e/specs/editor/blocks/image.spec.js @@ -853,9 +853,8 @@ test.describe.skip( 'Image - interactivity', () => { '.entry-content figure img' ); - const wpContext = await contentFigure.getAttribute( - 'data-wp-context' - ); + const wpContext = + await contentFigure.getAttribute( 'data-wp-context' ); const imageUploadedSrc = JSON.parse( wpContext ).core.image.imageUploadedSrc; diff --git a/test/e2e/specs/editor/blocks/navigation-list-view.spec.js b/test/e2e/specs/editor/blocks/navigation-list-view.spec.js index 77039281faded5..6064ff394171b0 100644 --- a/test/e2e/specs/editor/blocks/navigation-list-view.spec.js +++ b/test/e2e/specs/editor/blocks/navigation-list-view.spec.js @@ -140,9 +140,8 @@ test.describe( 'Navigation block - List view editing', () => { requestUtils, linkControl, } ) => { - const { id: menuId } = await requestUtils.createNavigationMenu( - navMenuBlocksFixture - ); + const { id: menuId } = + await requestUtils.createNavigationMenu( navMenuBlocksFixture ); // Insert x2 blocks as a stress test as several bugs have been found with inserting // blocks into the navigation block when there are multiple blocks referencing the @@ -213,9 +212,8 @@ test.describe( 'Navigation block - List view editing', () => { const firstResult = await linkControl.getNthSearchResult( 0 ); // Grab the text from the first result so we can check (later on) that it was inserted. - const firstResultText = await linkControl.getSearchResultText( - firstResult - ); + const firstResultText = + await linkControl.getSearchResultText( firstResult ); // Create the link. await firstResult.click(); @@ -454,9 +452,8 @@ test.describe( 'Navigation block - List view editing', () => { // inserted block even if the block had been deselected and then reselected. // See: https://github.com/WordPress/gutenberg/issues/50601 - const { id: menuId } = await requestUtils.createNavigationMenu( - navMenuBlocksFixture - ); + const { id: menuId } = + await requestUtils.createNavigationMenu( navMenuBlocksFixture ); // Insert x2 blocks as a stress test as several bugs have been found with inserting // blocks into the navigation block when there are multiple blocks referencing the diff --git a/test/e2e/specs/editor/blocks/paragraph.spec.js b/test/e2e/specs/editor/blocks/paragraph.spec.js index 1c35f6ddc8958c..fa42fa59a09edc 100644 --- a/test/e2e/specs/editor/blocks/paragraph.spec.js +++ b/test/e2e/specs/editor/blocks/paragraph.spec.js @@ -78,9 +78,8 @@ test.describe( 'Paragraph', () => { testImageName ); - const { dragOver, drop } = await pageUtils.dragFiles( - testImagePath - ); + const { dragOver, drop } = + await pageUtils.dragFiles( testImagePath ); await dragOver( editor.canvas.locator( '[data-type="core/paragraph"]' ) diff --git a/test/e2e/specs/editor/various/draggable-blocks.spec.js b/test/e2e/specs/editor/various/draggable-blocks.spec.js index a66efe4540f38a..cd5fa12fca6f4d 100644 --- a/test/e2e/specs/editor/various/draggable-blocks.spec.js +++ b/test/e2e/specs/editor/various/draggable-blocks.spec.js @@ -394,9 +394,8 @@ test.describe( 'Draggable block', () => { ); { - const { dragOver, drop } = await pageUtils.dragFiles( - testImagePath - ); + const { dragOver, drop } = + await pageUtils.dragFiles( testImagePath ); const rowBlock = editor.canvas.getByRole( 'document', { name: 'Block: Row', @@ -434,9 +433,8 @@ test.describe( 'Draggable block', () => { } { - const { dragOver, drop } = await pageUtils.dragFiles( - testImagePath - ); + const { dragOver, drop } = + await pageUtils.dragFiles( testImagePath ); const columnAppender = editor.canvas .getByRole( 'document', { diff --git a/test/e2e/specs/interactivity/directive-bind.spec.ts b/test/e2e/specs/interactivity/directive-bind.spec.ts index 401bbcd6b24ddf..525fceab5ca6ae 100644 --- a/test/e2e/specs/interactivity/directive-bind.spec.ts +++ b/test/e2e/specs/interactivity/directive-bind.spec.ts @@ -126,7 +126,7 @@ test.describe( 'data-wp-bind', () => { * Value that the HTMLElement instance property should * contain after hydration. */ - entityPropValue: any + entityPropValue: any, ] >; }; diff --git a/test/e2e/specs/widgets/customizing-widgets.spec.js b/test/e2e/specs/widgets/customizing-widgets.spec.js index 8b2a585dc4e66d..d51d5cffbebb2b 100644 --- a/test/e2e/specs/widgets/customizing-widgets.spec.js +++ b/test/e2e/specs/widgets/customizing-widgets.spec.js @@ -352,9 +352,8 @@ test.describe( 'Widgets Customizer', () => { await widgetsCustomizerPage.visitCustomizerPage(); await widgetsCustomizerPage.expandWidgetArea( 'Footer #1' ); - const legacyWidgetBlock = await widgetsCustomizerPage.addBlock( - 'Legacy Widget' - ); + const legacyWidgetBlock = + await widgetsCustomizerPage.addBlock( 'Legacy Widget' ); await page .locator( 'role=combobox[name="Select a legacy widget to display:"i]' @@ -401,9 +400,8 @@ test.describe( 'Widgets Customizer', () => { await page.click( 'role=menuitem[name=/Delete/]' ); // Add it back again using the variant. - const testWidgetBlock = await widgetsCustomizerPage.addBlock( - 'Test Widget' - ); + const testWidgetBlock = + await widgetsCustomizerPage.addBlock( 'Test Widget' ); titleInput = testWidgetBlock.locator( 'role=textbox[name="Title:"i]' ); From a854ab55eb70bdf8ecc9675a29439eefd736a7a5 Mon Sep 17 00:00:00 2001 From: Carolina Nymark Date: Mon, 18 Sep 2023 15:34:03 +0200 Subject: [PATCH 13/28] Navigation: Add ariaLabel block support (#54418) * Navigation: Add ariaLabel block support * Update index.php * Update packages/block-library/src/navigation/index.php Co-authored-by: Ari Stathopoulos --------- Co-authored-by: Ari Stathopoulos --- docs/reference-guides/core-blocks.md | 2 +- packages/block-library/src/navigation/block.json | 1 + packages/block-library/src/navigation/index.php | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/reference-guides/core-blocks.md b/docs/reference-guides/core-blocks.md index 9ae868115049b8..98a744e30cf021 100644 --- a/docs/reference-guides/core-blocks.md +++ b/docs/reference-guides/core-blocks.md @@ -420,7 +420,7 @@ A collection of blocks that allow visitors to get around your site. ([Source](ht - **Name:** core/navigation - **Category:** theme -- **Supports:** align (full, wide), inserter, interactivity, layout (allowSizingOnChildren, default, ~~allowInheriting~~, ~~allowSwitching~~, ~~allowVerticalAlignment~~), spacing (blockGap, units), typography (fontSize, lineHeight), ~~html~~ +- **Supports:** align (full, wide), ariaLabel, inserter, interactivity, layout (allowSizingOnChildren, default, ~~allowInheriting~~, ~~allowSwitching~~, ~~allowVerticalAlignment~~), spacing (blockGap, units), typography (fontSize, lineHeight), ~~html~~ - **Attributes:** __unstableLocation, backgroundColor, customBackgroundColor, customOverlayBackgroundColor, customOverlayTextColor, customTextColor, hasIcon, icon, maxNestingLevel, openSubmenusOnClick, overlayBackgroundColor, overlayMenu, overlayTextColor, ref, rgbBackgroundColor, rgbTextColor, showSubmenuIcon, templateLock, textColor ## Custom Link diff --git a/packages/block-library/src/navigation/block.json b/packages/block-library/src/navigation/block.json index 7896ea147699f7..cb5ca4fec1b90f 100644 --- a/packages/block-library/src/navigation/block.json +++ b/packages/block-library/src/navigation/block.json @@ -91,6 +91,7 @@ }, "supports": { "align": [ "wide", "full" ], + "ariaLabel": true, "html": false, "inserter": true, "typography": { diff --git a/packages/block-library/src/navigation/index.php b/packages/block-library/src/navigation/index.php index 082db8c998a05d..7d2a8888afde14 100644 --- a/packages/block-library/src/navigation/index.php +++ b/packages/block-library/src/navigation/index.php @@ -393,7 +393,7 @@ function render_block_core_navigation( $attributes, $content, $block ) { // a fallback (i.e. the block has no menu associated with it). $is_fallback = false; - $nav_menu_name = ''; + $nav_menu_name = $attributes['ariaLabel'] ?? ''; /** * Deprecated: From 761c390e3ce0a92a9f4183509074d634799711ef Mon Sep 17 00:00:00 2001 From: Nick Diego Date: Mon, 18 Sep 2023 10:19:24 -0500 Subject: [PATCH 14/28] Add missing callout class. (#54558) --- docs/getting-started/devenv/get-started-with-wp-now.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/getting-started/devenv/get-started-with-wp-now.md b/docs/getting-started/devenv/get-started-with-wp-now.md index 8b95008dae4a4d..80fd09fe899e94 100644 --- a/docs/getting-started/devenv/get-started-with-wp-now.md +++ b/docs/getting-started/devenv/get-started-with-wp-now.md @@ -29,7 +29,7 @@ wp-now start After the script runs, your default web browser will automatically open the new local site, and you'll be logged in with the username `admin` and the password `password`. -
+
If you encounter any errors when running wp-now start, make sure that you are using at least node v18, or v20 if you are using the Blueprint feature.
From 596966838a8edff52816a981e65e9ad4ddbf1ab6 Mon Sep 17 00:00:00 2001 From: Matias Benedetto Date: Mon, 18 Sep 2023 14:54:58 -0300 Subject: [PATCH 15/28] Font Library: setting wp_font_family custom post type as _builtin and not plublic (#54559) * marking wp_font_family custom post type as _builtin and not plublic * add warning comment Co-authored-by: Tonya Mork --------- Co-authored-by: Tonya Mork --- lib/experimental/fonts/font-library/font-library.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/experimental/fonts/font-library/font-library.php b/lib/experimental/fonts/font-library/font-library.php index 6c2a9ac0743c46..55344ac34050b1 100644 --- a/lib/experimental/fonts/font-library/font-library.php +++ b/lib/experimental/fonts/font-library/font-library.php @@ -22,7 +22,8 @@ function gutenberg_init_font_library_routes() { // @core-merge: This code will go into Core's `create_initial_post_types()`. $args = array( - 'public' => true, + 'public' => false, + '_builtin' => true, /* internal use only. don't use this when registering your own post type. */ 'label' => 'Font Library', 'show_in_rest' => true, ); From b617b4704ce14981d801b2c44144b05537149523 Mon Sep 17 00:00:00 2001 From: Brooke <35543432+brookewp@users.noreply.github.com> Date: Mon, 18 Sep 2023 11:07:22 -0700 Subject: [PATCH 16/28] Tooltip: add `placement` prop to replace deprecated `position` (#54264) * Tooltip: add `placement` prop to replace `position` * Refine code based on feedback * Add details on floating-ui to readme * Update tests to expect warning * Revert "Update tests to expect warning" This reverts commit 1f6fa73b93320c64671ad739a77116253a0b33fe. * Replace internal Tooltip usage of `position` with `placement` * Documentation updates based on feedback * Move other tooltip change to new features in changelog * Remove extra comment from types --- .../border-radius-control/input-controls.js | 2 +- .../components/media-replace-flow/index.js | 2 +- packages/components/CHANGELOG.md | 6 ++++- .../src/box-control/unit-control.tsx | 2 +- packages/components/src/button/index.tsx | 10 ++++++++- .../src/date-time/time/timezone.tsx | 2 +- .../component.tsx | 2 +- packages/components/src/tooltip/README.md | 13 +++++++++-- packages/components/src/tooltip/index.tsx | 22 +++++++++++++++++-- packages/components/src/tooltip/types.ts | 17 +++++++++++++- .../src/components/page-patterns/grid-item.js | 4 ++-- 11 files changed, 68 insertions(+), 14 deletions(-) diff --git a/packages/block-editor/src/components/border-radius-control/input-controls.js b/packages/block-editor/src/components/border-radius-control/input-controls.js index b33b79a482435f..c0c5c672d6364f 100644 --- a/packages/block-editor/src/components/border-radius-control/input-controls.js +++ b/packages/block-editor/src/components/border-radius-control/input-controls.js @@ -68,7 +68,7 @@ export default function BoxInputControls( { : selectedUnits[ corner ] || selectedUnits.flat; return ( - +
- +
+
{ children }
); diff --git a/packages/components/src/button/index.tsx b/packages/components/src/button/index.tsx index cc91cf46425867..a199c1bb350cd7 100644 --- a/packages/components/src/button/index.tsx +++ b/packages/components/src/button/index.tsx @@ -24,6 +24,7 @@ import Tooltip from '../tooltip'; import Icon from '../icon'; import { VisuallyHidden } from '../visually-hidden'; import type { ButtonProps, DeprecatedButtonProps } from './types'; +import { positionToPlacement } from '../popover/utils'; const disabledEventsOnDisabledButton = [ 'onMouseDown', 'onClick' ] as const; @@ -225,6 +226,13 @@ export function UnforwardedButton( ); + // Convert legacy `position` values to be used with the new `placement` prop + let computedPlacement; + // if `tooltipPosition` is defined, compute value to `placement` + if ( tooltipPosition !== undefined ) { + computedPlacement = positionToPlacement( tooltipPosition ); + } + if ( ! shouldShowTooltip ) { return ( <> @@ -248,7 +256,7 @@ export function UnforwardedButton( : label } shortcut={ shortcut } - position={ tooltipPosition } + placement={ computedPlacement } > { element } diff --git a/packages/components/src/date-time/time/timezone.tsx b/packages/components/src/date-time/time/timezone.tsx index f878deddaa782a..9fac1ec094ed89 100644 --- a/packages/components/src/date-time/time/timezone.tsx +++ b/packages/components/src/date-time/time/timezone.tsx @@ -38,7 +38,7 @@ const TimeZone = () => { : `(${ zoneAbbr }) ${ timezone.string.replace( '_', ' ' ) }`; return ( - + { zoneAbbr } diff --git a/packages/components/src/toggle-group-control/toggle-group-control-option-base/component.tsx b/packages/components/src/toggle-group-control/toggle-group-control-option-base/component.tsx index 572a4b70785eb7..3682aa3a5f1f6d 100644 --- a/packages/components/src/toggle-group-control/toggle-group-control-option-base/component.tsx +++ b/packages/components/src/toggle-group-control/toggle-group-control-option-base/component.tsx @@ -38,7 +38,7 @@ const LAYOUT_ID = 'toggle-group-backdrop-shared-layout-id'; const WithToolTip = ( { showTooltip, text, children }: WithToolTipProps ) => { if ( showTooltip && text ) { return ( - + { children } ); diff --git a/packages/components/src/tooltip/README.md b/packages/components/src/tooltip/README.md index 5b4caecf6d5c75..9b214e8fc6b00e 100644 --- a/packages/components/src/tooltip/README.md +++ b/packages/components/src/tooltip/README.md @@ -42,12 +42,21 @@ Option to hide the tooltip when the anchor is clicked. - Required: No - Default: `true` +#### `placement`: `'top' | 'top-start' | 'top-end' | 'right' | 'right-start' | 'right-end' | 'bottom' | 'bottom-start' | 'bottom-end' | 'left' | 'left-start' | 'left-end'` + +Used to specify the tooltip's placement with respect to its anchor. + +- Required: No +- Default: `'bottom'` + #### `position`: `string` -The direction in which the tooltip should open relative to its parent node. Specify y- and x-axis as a space-separated string. Supports `"top"`, `"middle"`, `"bottom"` y axis, and `"left"`, `"center"`, `"right"` x axis. +_Note: use the `placement` prop instead when possible._ + +Legacy way to specify the popover's position with respect to its anchor. Specify y- and x-axis as a space-separated string. Supports `'top'`, `'middle'`, `'bottom'` y axis, and `'left'`, `'center'`, `'right'` x axis. - Required: No -- Default: `"bottom"` +- Default: `'bottom'` #### `shortcut`: `string` | `object` diff --git a/packages/components/src/tooltip/index.tsx b/packages/components/src/tooltip/index.tsx index f86bd5d2ade9c3..f31a2a4f264d90 100644 --- a/packages/components/src/tooltip/index.tsx +++ b/packages/components/src/tooltip/index.tsx @@ -8,6 +8,7 @@ import * as Ariakit from '@ariakit/react/tooltip'; */ import { useInstanceId } from '@wordpress/compose'; import { Children } from '@wordpress/element'; +import deprecated from '@wordpress/deprecated'; /** * Internal dependencies @@ -26,7 +27,8 @@ function Tooltip( props: TooltipProps ) { children, delay = TOOLTIP_DELAY, hideOnClick = true, - position = 'bottom', + placement, + position, shortcut, text, } = props; @@ -45,8 +47,24 @@ function Tooltip( props: TooltipProps ) { } } + // Compute tooltip's placement: + // - give priority to `placement` prop, if defined + // - otherwise, compute it from the legacy `position` prop (if defined) + // - finally, fallback to the default placement: 'bottom' + let computedPlacement; + if ( placement !== undefined ) { + computedPlacement = placement; + } else if ( position !== undefined ) { + computedPlacement = positionToPlacement( position ); + deprecated( '`position` prop in wp.components.tooltip', { + since: '6.4', + alternative: '`placement` prop', + } ); + } + computedPlacement = computedPlacement || 'bottom'; + const tooltipStore = Ariakit.useTooltipStore( { - placement: positionToPlacement( position ), + placement: computedPlacement, timeout: delay, } ); diff --git a/packages/components/src/tooltip/types.ts b/packages/components/src/tooltip/types.ts index 1487a382ff1b8f..8708ae7005f5b3 100644 --- a/packages/components/src/tooltip/types.ts +++ b/packages/components/src/tooltip/types.ts @@ -1,3 +1,8 @@ +/** + * External dependencies + */ +import type { Placement } from '@floating-ui/react-dom'; + /** * Internal dependencies */ @@ -24,10 +29,20 @@ export type TooltipProps = { */ delay?: number; /** - * The direction in which the tooltip should open relative to its parent node. + * Where the tooltip should be positioned relative to its parent. + * + * @default bottom + */ + placement?: Placement; + /** + * _Note: this prop is deprecated. Please use the `placement` prop instead._ + * + * Legacy way of specifying the tooltip's position relative to its parent. + * * Specify y- and x-axis as a space-separated string. Supports `"top"`, * `"bottom"` y axis, and `"left"`, `"center"`, `"right"` x axis. * + * @deprecated * @default bottom */ position?: PopoverProps[ 'position' ]; diff --git a/packages/edit-site/src/components/page-patterns/grid-item.js b/packages/edit-site/src/components/page-patterns/grid-item.js index 5f79067f6ed299..28ee73f728ad29 100644 --- a/packages/edit-site/src/components/page-patterns/grid-item.js +++ b/packages/edit-site/src/components/page-patterns/grid-item.js @@ -191,7 +191,7 @@ function GridItem( { categoryId, item, ...props } ) { > { itemIcon && ! isNonUserPattern && ( Date: Mon, 18 Sep 2023 19:11:42 +0100 Subject: [PATCH 17/28] [Docs: Getting Started / Block Development Environment] Updates on the text to improve clarity and preciseness (#54563) * updates on the text to improve clarity and preciseness * feedback incorporated * fixed links and page renaming to node development environment * updated manifest and toc * revert node to nodejs --- docs/getting-started/devenv/README.md | 6 +++--- docs/getting-started/devenv/get-started-with-wp-env.md | 2 +- docs/getting-started/devenv/get-started-with-wp-now.md | 2 +- ...velopment-tools.md => nodejs-development-environment.md} | 6 +++--- docs/manifest.json | 6 +++--- docs/toc.json | 2 +- 6 files changed, 12 insertions(+), 12 deletions(-) rename docs/getting-started/devenv/{nodejs-development-tools.md => nodejs-development-environment.md} (89%) diff --git a/docs/getting-started/devenv/README.md b/docs/getting-started/devenv/README.md index 1fafd53af11300..0b578e3df3b6a6 100644 --- a/docs/getting-started/devenv/README.md +++ b/docs/getting-started/devenv/README.md @@ -32,10 +32,10 @@ The list goes on. While modern JavaScript development can be challenging, WordPr **The recommended Node.js version for block development is [Active LTS](https://nodejs.dev/en/about/releases/) (Long Term Support)**. However, there are times when you need to to use different versions. A Node.js version manager tool like `nvm` is strongly recommended and allows you to easily change your `node` version when required. You will also need Node Package Manager (`npm`) and the Node Package eXecute (`npx`) to work with some WordPress packages. Both are installed automatically with Node.js. -To install Node.js development tools and learn more about each, refer to the links below. +To be able to use the Node.js tools and [packages provided by WordPress](https://github.com/WordPress/gutenberg/tree/trunk/packages) for block development, you'll need to set a proper Node.js runtime environment on your machine.. To learn more about how to do this, refer to the links below. -- [Install Node.js for Mac and Linux](/docs/getting-started/devenv/nodejs-development-tools.md#mac-and-linux-installations) -- [Install Node.js for Windows](/docs/getting-started/devenv/nodejs-development-tools.md#windows-or-alternative-installs) +- [Install Node.js for Mac and Linux](/docs/getting-started/devenv/nodejs-development-environment.md#node-js-installation-on-mac-and-linux-with-nvm) +- [Install Node.js for Windows](/docs/getting-started/devenv/nodejs-development-environment.md#node-js-installation-on-windows-and-others) ## Local WordPress environment diff --git a/docs/getting-started/devenv/get-started-with-wp-env.md b/docs/getting-started/devenv/get-started-with-wp-env.md index dca3ca081317d6..11a23fd9ac9e20 100644 --- a/docs/getting-started/devenv/get-started-with-wp-env.md +++ b/docs/getting-started/devenv/get-started-with-wp-env.md @@ -2,7 +2,7 @@ The [@wordpress/env](https://www.npmjs.com/package/@wordpress/env) package (`wp-env`) lets you set up a local WordPress environment (site) for building and testing plugins and themes, without any additional configuration. -Before following this guide, install [Node.js development tools](/docs/getting-started/devenv#install-nodejs-development-tools) if you have not already done so. +Before following this guide, install [Node.js development tools](/docs/getting-started/devenv#node-js-development-tools) if you have not already done so. ## Quick start diff --git a/docs/getting-started/devenv/get-started-with-wp-now.md b/docs/getting-started/devenv/get-started-with-wp-now.md index 80fd09fe899e94..cb0fd4986328f1 100644 --- a/docs/getting-started/devenv/get-started-with-wp-now.md +++ b/docs/getting-started/devenv/get-started-with-wp-now.md @@ -2,7 +2,7 @@ The [@wp-now/wp-now](https://www.npmjs.com/package/@wordpress/env) package (`wp-now`) is a lightweight tool powered by [WordPress Playground](https://developer.wordpress.org/playground/) that streamlines setting up a local WordPress environment. -Before following this guide, install [Node.js development tools](/docs/getting-started/devenv#install-nodejs-development-tools) if you have not already done so. It's recommended that you use the latest version of `node`. `wp-now` requires at least `node` v18 and v20 if you intend to use its [Blueprints](https://github.com/WordPress/playground-tools/tree/trunk/packages/wp-now#using-blueprints) feature. +Before following this guide, install [Node.js development tools](/docs/getting-started/devenv#nodejs-development-tools) if you have not already done so. It's recommended that you use the latest version of `node`. `wp-now` requires at least `node` v18 and v20 if you intend to use its [Blueprints](https://github.com/WordPress/playground-tools/tree/trunk/packages/wp-now#using-blueprints) feature. ## Quick start diff --git a/docs/getting-started/devenv/nodejs-development-tools.md b/docs/getting-started/devenv/nodejs-development-environment.md similarity index 89% rename from docs/getting-started/devenv/nodejs-development-tools.md rename to docs/getting-started/devenv/nodejs-development-environment.md index 09a58a1beeb06e..30cd2c861f2292 100644 --- a/docs/getting-started/devenv/nodejs-development-tools.md +++ b/docs/getting-started/devenv/nodejs-development-environment.md @@ -1,6 +1,6 @@ -# Node.js development tools +# Node.js development environment -When developing for the Block Editor, you will need [Node.js](https://nodejs.org/en) development tools along with a code editor and a local WordPress environment. Node.js (`node`) is an open-source runtime environment that allows you to execute JavaScript code from the terminal (also known as a command-line interface, CLI, or shell) +When developing for the Block Editor, you will need [Node.js](https://nodejs.org/en) development tools along with a code editor and a local WordPress environment (see [Block Development Environment](README.md)). Node.js (`node`) is an open-source runtime environment that allows you to execute JavaScript code from the terminal (also known as a command-line interface, CLI, or shell) Installing `node` will automatically include the Node Package Manager (`npm`) and the Node Package eXecute (`npx`), two tools you will frequently use in block and plugin development. @@ -13,7 +13,7 @@ The Node Package eXecute ([`npx`](https://docs.npmjs.com/cli/v10/commands/npx)) It's recommended that you use [Node Version Manager](https://github.com/nvm-sh/nvm) (`nvm`) to install Node.js. This allows you to install and manage specific versions of `node`, which are installed locally in your home directory, avoiding any global permission issues. -Here are the quick instructions for installing `node` using `nvm`. See the [complete installation guide](https://github.com/nvm-sh/nvm#installing-and-updating) for more details. +Here are the quick instructions for installing `node` using `nvm` and setting the recommended Node.js version for block development. See the [complete installation guide](https://github.com/nvm-sh/nvm#installing-and-updating) for more details. 1. Open the terminal and run the following to install `nvm`. On macOS, the required developer tools are not installed by default. Install them if prompted. diff --git a/docs/manifest.json b/docs/manifest.json index 50061b9a3d6085..7ceebaf69a4497 100644 --- a/docs/manifest.json +++ b/docs/manifest.json @@ -18,9 +18,9 @@ "parent": "getting-started" }, { - "title": "Node.js development tools", - "slug": "nodejs-development-tools", - "markdown_source": "../docs/getting-started/devenv/nodejs-development-tools.md", + "title": "Node.js development environment", + "slug": "nodejs-development-environment", + "markdown_source": "../docs/getting-started/devenv/nodejs-development-environment.md", "parent": "devenv" }, { diff --git a/docs/toc.json b/docs/toc.json index a173621062e775..c9f24dd9fad708 100644 --- a/docs/toc.json +++ b/docs/toc.json @@ -7,7 +7,7 @@ { "docs/getting-started/devenv/README.md": [ { - "docs/getting-started/devenv/nodejs-development-tools.md": [] + "docs/getting-started/devenv/nodejs-development-environment.md": [] }, { "docs/getting-started/devenv/get-started-with-wp-env.md": [] From e3eb81b429f65afaceed3a0ee03db719f24f0ee0 Mon Sep 17 00:00:00 2001 From: Michal Date: Mon, 18 Sep 2023 19:51:48 +0100 Subject: [PATCH 18/28] Fix the block serialization tests (#54570) --- ...image__deprecated-v8-deprecate-behaviors-lightbox.html | 2 +- ...image__deprecated-v8-deprecate-behaviors-lightbox.json | 8 ++++---- ...deprecated-v8-deprecate-behaviors-lightbox.parsed.json | 7 +++++-- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/test/integration/fixtures/blocks/core__image__deprecated-v8-deprecate-behaviors-lightbox.html b/test/integration/fixtures/blocks/core__image__deprecated-v8-deprecate-behaviors-lightbox.html index 9feeb105951daa..3cdb772864b4d8 100644 --- a/test/integration/fixtures/blocks/core__image__deprecated-v8-deprecate-behaviors-lightbox.html +++ b/test/integration/fixtures/blocks/core__image__deprecated-v8-deprecate-behaviors-lightbox.html @@ -1,3 +1,3 @@ - +
diff --git a/test/integration/fixtures/blocks/core__image__deprecated-v8-deprecate-behaviors-lightbox.json b/test/integration/fixtures/blocks/core__image__deprecated-v8-deprecate-behaviors-lightbox.json index a32f031dd34f43..73a483d911a780 100644 --- a/test/integration/fixtures/blocks/core__image__deprecated-v8-deprecate-behaviors-lightbox.json +++ b/test/integration/fixtures/blocks/core__image__deprecated-v8-deprecate-behaviors-lightbox.json @@ -6,12 +6,12 @@ "url": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAACklEQVR4nGMAAQAABQABDQottAAAAABJRU5ErkJggg==", "alt": "", "caption": "", - "lightbox": { - "enabled": true - }, "id": 8, "sizeSlug": "large", - "linkDestination": "none" + "linkDestination": "none", + "lightbox": { + "enabled": true + } }, "innerBlocks": [] } diff --git a/test/integration/fixtures/blocks/core__image__deprecated-v8-deprecate-behaviors-lightbox.parsed.json b/test/integration/fixtures/blocks/core__image__deprecated-v8-deprecate-behaviors-lightbox.parsed.json index 0ca652ff77f835..a582b93cab43b7 100644 --- a/test/integration/fixtures/blocks/core__image__deprecated-v8-deprecate-behaviors-lightbox.parsed.json +++ b/test/integration/fixtures/blocks/core__image__deprecated-v8-deprecate-behaviors-lightbox.parsed.json @@ -2,8 +2,11 @@ { "blockName": "core/image", "attrs": { - "lightbox": { - "enabled": true + "behaviors": { + "lightbox": { + "enabled": true, + "animation": "fade" + } }, "id": 8, "sizeSlug": "large", From 4c1df0a6ffe6f8e44b3cce5b8ecc7e30a6ccfe43 Mon Sep 17 00:00:00 2001 From: Rich Tabor Date: Mon, 18 Sep 2023 16:04:55 -0400 Subject: [PATCH 19/28] Update spacing sizes control metrics and icons (#54470) * Try more condensed icons * Use sidesAll instead of sidesAxial for default * Tweak settings icon * Adjust metrics of spacing sizes control * Try slightly larger icons * Remove fill --- .../src/components/spacing-sizes-control/style.scss | 12 +++++------- .../src/components/spacing-sizes-control/utils.js | 3 +-- packages/icons/src/library/settings.js | 3 ++- packages/icons/src/library/sides-all.js | 5 +---- packages/icons/src/library/sides-bottom.js | 6 +++--- packages/icons/src/library/sides-horizontal.js | 10 ++++------ packages/icons/src/library/sides-left.js | 6 +++--- packages/icons/src/library/sides-right.js | 6 +++--- packages/icons/src/library/sides-top.js | 6 +++--- packages/icons/src/library/sides-vertical.js | 10 ++++------ 10 files changed, 29 insertions(+), 38 deletions(-) diff --git a/packages/block-editor/src/components/spacing-sizes-control/style.scss b/packages/block-editor/src/components/spacing-sizes-control/style.scss index 2382aa76853d03..2fb33b5c565fba 100644 --- a/packages/block-editor/src/components/spacing-sizes-control/style.scss +++ b/packages/block-editor/src/components/spacing-sizes-control/style.scss @@ -39,15 +39,9 @@ } } -.spacing-sizes-control__wrapper { - & + & { - margin-top: $grid-unit-10; - } -} - .spacing-sizes-control__header { height: $grid-unit-20; - margin-bottom: $grid-unit-10; + margin-bottom: $grid-unit-15; } .spacing-sizes-control__dropdown { @@ -63,3 +57,7 @@ .spacing-sizes-control__custom-toggle { flex: 0 0 auto; } + +.spacing-sizes-control__icon { + margin-left: $grid-unit-05 * -1; // Aligns the icon to the control header. +} diff --git a/packages/block-editor/src/components/spacing-sizes-control/utils.js b/packages/block-editor/src/components/spacing-sizes-control/utils.js index 7ca0e1b6f660fd..32f0dbc59ac466 100644 --- a/packages/block-editor/src/components/spacing-sizes-control/utils.js +++ b/packages/block-editor/src/components/spacing-sizes-control/utils.js @@ -4,7 +4,6 @@ import { __ } from '@wordpress/i18n'; import { sidesAll, - sidesAxial, sidesBottom, sidesHorizontal, sidesLeft, @@ -24,7 +23,7 @@ export const DEFAULT_VALUES = { export const ICONS = { custom: sidesAll, - axial: sidesAxial, + axial: sidesAll, horizontal: sidesHorizontal, vertical: sidesVertical, top: sidesTop, diff --git a/packages/icons/src/library/settings.js b/packages/icons/src/library/settings.js index 31d6da68a71955..cc1593cf489d3e 100644 --- a/packages/icons/src/library/settings.js +++ b/packages/icons/src/library/settings.js @@ -5,7 +5,8 @@ import { SVG, Path } from '@wordpress/primitives'; const settings = ( - + + ); diff --git a/packages/icons/src/library/sides-all.js b/packages/icons/src/library/sides-all.js index d6e027685640a6..31717e244aadf9 100644 --- a/packages/icons/src/library/sides-all.js +++ b/packages/icons/src/library/sides-all.js @@ -5,10 +5,7 @@ import { SVG, Path } from '@wordpress/primitives'; const sidesAll = ( - + ); diff --git a/packages/icons/src/library/sides-bottom.js b/packages/icons/src/library/sides-bottom.js index d1615ebc2a93b0..48cd1516e7c16b 100644 --- a/packages/icons/src/library/sides-bottom.js +++ b/packages/icons/src/library/sides-bottom.js @@ -5,11 +5,11 @@ import { SVG, Path } from '@wordpress/primitives'; const sidesBottom = ( - + ); diff --git a/packages/icons/src/library/sides-horizontal.js b/packages/icons/src/library/sides-horizontal.js index 87402487689e3b..05509ef8dc2b5e 100644 --- a/packages/icons/src/library/sides-horizontal.js +++ b/packages/icons/src/library/sides-horizontal.js @@ -6,13 +6,11 @@ import { SVG, Path } from '@wordpress/primitives'; const sidesHorizontal = ( - + + ); diff --git a/packages/icons/src/library/sides-left.js b/packages/icons/src/library/sides-left.js index ff2189f76a0dc9..39a917e7d05b04 100644 --- a/packages/icons/src/library/sides-left.js +++ b/packages/icons/src/library/sides-left.js @@ -5,11 +5,11 @@ import { SVG, Path } from '@wordpress/primitives'; const sidesLeft = ( - + ); diff --git a/packages/icons/src/library/sides-right.js b/packages/icons/src/library/sides-right.js index 1abb83ad1bb689..b21e0668aeb55d 100644 --- a/packages/icons/src/library/sides-right.js +++ b/packages/icons/src/library/sides-right.js @@ -5,11 +5,11 @@ import { SVG, Path } from '@wordpress/primitives'; const sidesRight = ( - + ); diff --git a/packages/icons/src/library/sides-top.js b/packages/icons/src/library/sides-top.js index 8519397ffd63e1..f416a4c235f3b7 100644 --- a/packages/icons/src/library/sides-top.js +++ b/packages/icons/src/library/sides-top.js @@ -6,10 +6,10 @@ import { SVG, Path } from '@wordpress/primitives'; const sidesTop = ( - + ); diff --git a/packages/icons/src/library/sides-vertical.js b/packages/icons/src/library/sides-vertical.js index 09306cf72549a7..5352dffd4e50b3 100644 --- a/packages/icons/src/library/sides-vertical.js +++ b/packages/icons/src/library/sides-vertical.js @@ -6,13 +6,11 @@ import { SVG, Path } from '@wordpress/primitives'; const sidesVertical = ( - + + ); From cbc7245adeb3fda327ba928fa3bf3768de94a4b4 Mon Sep 17 00:00:00 2001 From: Rich Tabor Date: Mon, 18 Sep 2023 16:05:29 -0400 Subject: [PATCH 20/28] Update block styles UI (#54446) * showTooltip false * Fix resting and focus shadows * Use __next40pxDefaultSize * Use $border-width --- packages/block-editor/src/components/block-styles/index.js | 2 ++ .../block-editor/src/components/block-styles/style.scss | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/block-editor/src/components/block-styles/index.js b/packages/block-editor/src/components/block-styles/index.js index 9db5d4c87b2e0e..e5b8bc38ebeb9d 100644 --- a/packages/block-editor/src/components/block-styles/index.js +++ b/packages/block-editor/src/components/block-styles/index.js @@ -71,6 +71,7 @@ function BlockStyles( { clientId, onSwitch = noop, onHoverClassName = noop } ) { return ( { ariaDescriptions.map( ( ariaDescription, index ) => (
Date: Tue, 19 Sep 2023 09:25:20 +0400 Subject: [PATCH 27/28] Pattern Category: Set 'publicly_queryable' to false (#54567) --- lib/compat/wordpress-6.4/block-patterns.php | 21 ++++++++++--------- .../block-library/src/post-terms/index.php | 5 ----- 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/lib/compat/wordpress-6.4/block-patterns.php b/lib/compat/wordpress-6.4/block-patterns.php index 3a0a9ed1a9e52e..922dea910b47a0 100644 --- a/lib/compat/wordpress-6.4/block-patterns.php +++ b/lib/compat/wordpress-6.4/block-patterns.php @@ -16,19 +16,20 @@ */ function gutenberg_register_taxonomy_patterns() { $args = array( - 'public' => true, - 'hierarchical' => false, - 'labels' => array( + 'public' => true, + 'publicly_queryable' => false, + 'hierarchical' => false, + 'labels' => array( 'name' => _x( 'Pattern Categories', 'taxonomy general name' ), 'singular_name' => _x( 'Pattern Category', 'taxonomy singular name' ), ), - 'query_var' => false, - 'rewrite' => false, - 'show_ui' => true, - '_builtin' => true, - 'show_in_nav_menus' => false, - 'show_in_rest' => true, - 'show_admin_column' => true, + 'query_var' => false, + 'rewrite' => false, + 'show_ui' => true, + '_builtin' => true, + 'show_in_nav_menus' => false, + 'show_in_rest' => true, + 'show_admin_column' => true, ); register_taxonomy( 'wp_pattern_category', array( 'wp_block' ), $args ); } diff --git a/packages/block-library/src/post-terms/index.php b/packages/block-library/src/post-terms/index.php index d64b6eb5338838..c97155b81e3a95 100644 --- a/packages/block-library/src/post-terms/index.php +++ b/packages/block-library/src/post-terms/index.php @@ -78,11 +78,6 @@ function register_block_core_post_terms() { // Create and register the eligible taxonomies variations. foreach ( $taxonomies as $taxonomy ) { - // Skip the `wp_pattern_category` taxonomy as this should not be an - // available variation for the `core/post-terms` block. - if ( 'wp_pattern_category' === $taxonomy->name ) { - continue; - } $variation = array( 'name' => $taxonomy->name, 'title' => $taxonomy->label, From 2cfe1ba3fd15808f6b6b1ee76e42157794cd681f Mon Sep 17 00:00:00 2001 From: Aki Hamano <54422211+t-hamano@users.noreply.github.com> Date: Tue, 19 Sep 2023 14:48:59 +0900 Subject: [PATCH 28/28] Gutenberg Plugin: Add hook to allow `writing-mode` as a safe CSS property (#54581) --- lib/compat/wordpress-6.4/kses.php | 18 ++++++++++++++++++ lib/load.php | 1 + .../src/post-navigation-link/index.php | 5 ----- phpunit/style-engine/style-engine-test.php | 4 +++- 4 files changed, 22 insertions(+), 6 deletions(-) create mode 100644 lib/compat/wordpress-6.4/kses.php diff --git a/lib/compat/wordpress-6.4/kses.php b/lib/compat/wordpress-6.4/kses.php new file mode 100644 index 00000000000000..019d1cc9b06dbf --- /dev/null +++ b/lib/compat/wordpress-6.4/kses.php @@ -0,0 +1,18 @@ + $classes, - 'style' => $styles, ) ); // Set default values. diff --git a/phpunit/style-engine/style-engine-test.php b/phpunit/style-engine/style-engine-test.php index 7e71deb0dbf96a..6fb485e9a6f318 100644 --- a/phpunit/style-engine/style-engine-test.php +++ b/phpunit/style-engine/style-engine-test.php @@ -192,11 +192,12 @@ public function data_wp_style_engine_get_styles() { 'textDecoration' => 'underline', 'textTransform' => 'uppercase', 'letterSpacing' => '2', + 'writingMode' => 'vertical-rl', ), ), 'options' => null, 'expected_output' => array( - 'css' => 'font-size:clamp(2em, 2vw, 4em);font-family:Roboto,Oxygen-Sans,Ubuntu,sans-serif;font-style:italic;font-weight:800;line-height:1.3;column-count:2;text-decoration:underline;text-transform:uppercase;letter-spacing:2;', + 'css' => 'font-size:clamp(2em, 2vw, 4em);font-family:Roboto,Oxygen-Sans,Ubuntu,sans-serif;font-style:italic;font-weight:800;line-height:1.3;column-count:2;text-decoration:underline;text-transform:uppercase;letter-spacing:2;writing-mode:vertical-rl;', 'declarations' => array( 'font-size' => 'clamp(2em, 2vw, 4em)', 'font-family' => 'Roboto,Oxygen-Sans,Ubuntu,sans-serif', @@ -207,6 +208,7 @@ public function data_wp_style_engine_get_styles() { 'text-decoration' => 'underline', 'text-transform' => 'uppercase', 'letter-spacing' => '2', + 'writing-mode' => 'vertical-rl', ), ), ),