From 62704a0167913527203e48e5c7d5a2dda575f44d Mon Sep 17 00:00:00 2001 From: Marin Atanasov <8436925+tyxla@users.noreply.github.com> Date: Tue, 19 Nov 2024 15:59:41 +0200 Subject: [PATCH 01/16] ESLint: Bump `eslint-plugin-react-compiler` to latest beta (#67106) * Bump eslint-plugin-react-compiler to 19.0.0-beta-0dec889-20241115 * Use ref for prev heading level in DocumentOutline Co-authored-by: tyxla Co-authored-by: Mamaduka --- package-lock.json | 8 ++++---- package.json | 2 +- .../editor/src/components/document-outline/index.js | 10 ++++++---- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index 036acafe885fa6..376cd0b9e6edf6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -91,7 +91,7 @@ "eslint-plugin-jest": "27.2.3", "eslint-plugin-jest-dom": "5.0.2", "eslint-plugin-prettier": "5.0.0", - "eslint-plugin-react-compiler": "19.0.0-beta-8a03594-20241020", + "eslint-plugin-react-compiler": "19.0.0-beta-0dec889-20241115", "eslint-plugin-ssr-friendly": "1.0.6", "eslint-plugin-storybook": "0.6.13", "eslint-plugin-testing-library": "6.0.2", @@ -25365,9 +25365,9 @@ } }, "node_modules/eslint-plugin-react-compiler": { - "version": "19.0.0-beta-8a03594-20241020", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-compiler/-/eslint-plugin-react-compiler-19.0.0-beta-8a03594-20241020.tgz", - "integrity": "sha512-bYg1COih1s3r14IV/AKdQs/SN7CQmNI0ZaMtPdgZ6gp1S1Q/KGP9P43w7R6dHJ4wYpuMBvekNJHQdVu+x6UM+A==", + "version": "19.0.0-beta-0dec889-20241115", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-compiler/-/eslint-plugin-react-compiler-19.0.0-beta-0dec889-20241115.tgz", + "integrity": "sha512-jTjEHuE8/R6qD/CD2d+5YvWMy1q9/tX3kft4WDyg42/HktjHtHXrEToyZ6THEQf8t/YWMY1RGeCkykePbACtFA==", "dev": true, "dependencies": { "@babel/core": "^7.24.4", diff --git a/package.json b/package.json index 751bde40240811..a7470a1333ffad 100644 --- a/package.json +++ b/package.json @@ -100,7 +100,7 @@ "eslint-plugin-jest": "27.2.3", "eslint-plugin-jest-dom": "5.0.2", "eslint-plugin-prettier": "5.0.0", - "eslint-plugin-react-compiler": "19.0.0-beta-8a03594-20241020", + "eslint-plugin-react-compiler": "19.0.0-beta-0dec889-20241115", "eslint-plugin-ssr-friendly": "1.0.6", "eslint-plugin-storybook": "0.6.13", "eslint-plugin-testing-library": "6.0.2", diff --git a/packages/editor/src/components/document-outline/index.js b/packages/editor/src/components/document-outline/index.js index ab5caa8cf0f8a4..c5e59837362092 100644 --- a/packages/editor/src/components/document-outline/index.js +++ b/packages/editor/src/components/document-outline/index.js @@ -3,6 +3,7 @@ */ import { __ } from '@wordpress/i18n'; import { useDispatch, useSelect } from '@wordpress/data'; +import { useRef } from '@wordpress/element'; import { create, getTextContent } from '@wordpress/rich-text'; import { store as blockEditorStore } from '@wordpress/block-editor'; import { store as coreStore } from '@wordpress/core-data'; @@ -125,6 +126,8 @@ export default function DocumentOutline( { }; } ); + const prevHeadingLevelRef = useRef( 1 ); + const headings = computeOutlineHeadings( blocks ); if ( headings.length < 1 ) { return ( @@ -139,8 +142,6 @@ export default function DocumentOutline( { ); } - let prevHeadingLevel = 1; - // Not great but it's the simplest way to locate the title right now. const titleNode = document.querySelector( '.editor-post-title__input' ); const hasTitle = isTitleSupported && title && titleNode; @@ -170,7 +171,8 @@ export default function DocumentOutline( { { headings.map( ( item, index ) => { // Headings remain the same, go up by one, or down by any amount. // Otherwise there are missing levels. - const isIncorrectLevel = item.level > prevHeadingLevel + 1; + const isIncorrectLevel = + item.level > prevHeadingLevelRef.current + 1; const isValid = ! item.isEmpty && @@ -178,7 +180,7 @@ export default function DocumentOutline( { !! item.level && ( item.level !== 1 || ( ! hasMultipleH1 && ! hasTitle ) ); - prevHeadingLevel = item.level; + prevHeadingLevelRef.current = item.level; return ( Date: Tue, 19 Nov 2024 09:12:00 -0500 Subject: [PATCH 02/16] Bump gradle/actions from 4.2.0 to 4.2.1 in the react-native group (#67115) Bumps the react-native group with 1 update: [gradle/actions](https://github.com/gradle/actions). Updates `gradle/actions` from 4.2.0 to 4.2.1 - [Release notes](https://github.com/gradle/actions/releases) - [Commits](https://github.com/gradle/actions/compare/473878a77f1b98e2b5ac4af93489d1656a80a5ed...cc4fc85e6b35bafd578d5ffbc76a5518407e1af0) --- updated-dependencies: - dependency-name: gradle/actions dependency-type: direct:production update-type: version-update:semver-patch dependency-group: react-native ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: desrosj --- .github/workflows/rnmobile-android-runner.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/rnmobile-android-runner.yml b/.github/workflows/rnmobile-android-runner.yml index 43a71809b5bbe7..f8ff0441a95b7b 100644 --- a/.github/workflows/rnmobile-android-runner.yml +++ b/.github/workflows/rnmobile-android-runner.yml @@ -47,7 +47,7 @@ jobs: run: npm run native test:e2e:setup - name: Gradle cache - uses: gradle/actions/setup-gradle@473878a77f1b98e2b5ac4af93489d1656a80a5ed # v4.2.0 + uses: gradle/actions/setup-gradle@cc4fc85e6b35bafd578d5ffbc76a5518407e1af0 # v4.2.1 # AVD cache disabled as it caused emulator termination to hang indefinitely. # https://github.com/ReactiveCircus/android-emulator-runner/issues/385 From cf59c28e1b0cd0870eb82c21eedf221ebf92c606 Mon Sep 17 00:00:00 2001 From: George Mamadashvili Date: Tue, 19 Nov 2024 18:24:22 +0400 Subject: [PATCH 03/16] Inserter: Set initial active tab ID during render (#67103) Co-authored-by: Mamaduka Co-authored-by: tyxla --- .../components/inserter/category-tabs/index.js | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/packages/block-editor/src/components/inserter/category-tabs/index.js b/packages/block-editor/src/components/inserter/category-tabs/index.js index 7b6baaab398f82..ff0a130f1a8271 100644 --- a/packages/block-editor/src/components/inserter/category-tabs/index.js +++ b/packages/block-editor/src/components/inserter/category-tabs/index.js @@ -6,7 +6,7 @@ import { privateApis as componentsPrivateApis, __unstableMotion as motion, } from '@wordpress/components'; -import { useState, useEffect } from '@wordpress/element'; +import { useState } from '@wordpress/element'; /** * Internal dependencies @@ -35,14 +35,13 @@ function CategoryTabs( { const selectedTabId = selectedCategory ? selectedCategory.name : null; const [ activeTabId, setActiveId ] = useState(); const firstTabId = categories?.[ 0 ]?.name; - useEffect( () => { - // If there is no active tab, make the first tab the active tab, so that - // when focus is moved to the tablist, the first tab will be focused - // despite not being selected - if ( selectedTabId === null && ! activeTabId && firstTabId ) { - setActiveId( firstTabId ); - } - }, [ selectedTabId, activeTabId, firstTabId, setActiveId ] ); + + // If there is no active tab, make the first tab the active tab, so that + // when focus is moved to the tablist, the first tab will be focused + // despite not being selected + if ( selectedTabId === null && ! activeTabId && firstTabId ) { + setActiveId( firstTabId ); + } return ( Date: Tue, 19 Nov 2024 10:33:59 -0500 Subject: [PATCH 04/16] Feature: Set editor rendering mode by post type (#62304) Co-authored-by: TylerB24890 Co-authored-by: Sidsector9 Co-authored-by: fabiankaegy Co-authored-by: youknowriad Co-authored-by: dcalhoun Co-authored-by: ramonjd Co-authored-by: mcsf Co-authored-by: jasmussen Co-authored-by: annezazu Co-authored-by: jameskoster Co-authored-by: dinhtungdu --- backport-changelog/6.8/7129.md | 3 + ...tenberg-rest-post-types-controller-6-8.php | 61 ++++++++++++++ lib/compat/wordpress-6.8/post.php | 57 +++++++++++++ lib/compat/wordpress-6.8/rest-api.php | 22 +++++ lib/load.php | 3 + .../block-editor/use-site-editor-settings.js | 11 +-- .../edit-site/src/components/editor/index.js | 4 +- .../editor/src/components/provider/index.js | 83 ++++++++++++------- packages/editor/src/store/reducer.native.js | 2 + .../initialize-editor.js | 17 ++++ test/performance/fixtures/perf-utils.ts | 20 +++++ test/performance/specs/site-editor.spec.js | 2 + 12 files changed, 243 insertions(+), 42 deletions(-) create mode 100644 backport-changelog/6.8/7129.md create mode 100644 lib/compat/wordpress-6.8/class-gutenberg-rest-post-types-controller-6-8.php create mode 100644 lib/compat/wordpress-6.8/post.php create mode 100644 lib/compat/wordpress-6.8/rest-api.php diff --git a/backport-changelog/6.8/7129.md b/backport-changelog/6.8/7129.md new file mode 100644 index 00000000000000..90c9168cdc6f8a --- /dev/null +++ b/backport-changelog/6.8/7129.md @@ -0,0 +1,3 @@ +https://github.com/WordPress/wordpress-develop/pull/7129 + +* https://github.com/WordPress/gutenberg/pull/62304 diff --git a/lib/compat/wordpress-6.8/class-gutenberg-rest-post-types-controller-6-8.php b/lib/compat/wordpress-6.8/class-gutenberg-rest-post-types-controller-6-8.php new file mode 100644 index 00000000000000..da0489210e21f1 --- /dev/null +++ b/lib/compat/wordpress-6.8/class-gutenberg-rest-post-types-controller-6-8.php @@ -0,0 +1,61 @@ +default_rendering_mode, $item ); + + /** + * Filters the block editor rendering mode for a specific post type. + * Applied after the generic `post_type_default_rendering_mode` filter. + * + * The dynamic portion of the hook name, `$item->name`, refers to the post type slug. + * + * @since 6.8.0 + * @param string $default_rendering_mode Default rendering mode for the post type. + * @param WP_Post_Type $post_type Post type object. + * @return string Default rendering mode for the post type. + */ + $rendering_mode = apply_filters( "post_type_{$item->name}_default_rendering_mode", $rendering_mode, $item ); + + // Validate the filtered rendering mode. + if ( ! in_array( $rendering_mode, gutenberg_post_type_rendering_modes(), true ) ) { + $rendering_mode = 'post-only'; + } + + $response->data['default_rendering_mode'] = $rendering_mode; + } + + return rest_ensure_response( $response ); + } +} diff --git a/lib/compat/wordpress-6.8/post.php b/lib/compat/wordpress-6.8/post.php new file mode 100644 index 00000000000000..26e6c3adc07a3d --- /dev/null +++ b/lib/compat/wordpress-6.8/post.php @@ -0,0 +1,57 @@ +register_routes(); + } +} +add_action( 'rest_api_init', 'gutenberg_add_post_type_rendering_mode' ); diff --git a/lib/load.php b/lib/load.php index d7e4a33cd02c92..100160176f3911 100644 --- a/lib/load.php +++ b/lib/load.php @@ -49,6 +49,8 @@ function gutenberg_is_experiment_enabled( $name ) { // WordPress 6.8 compat. require __DIR__ . '/compat/wordpress-6.8/block-comments.php'; require __DIR__ . '/compat/wordpress-6.8/class-gutenberg-rest-comment-controller-6-8.php'; + require __DIR__ . '/compat/wordpress-6.8/class-gutenberg-rest-post-types-controller-6-8.php'; + require __DIR__ . '/compat/wordpress-6.8/rest-api.php'; // Plugin specific code. require_once __DIR__ . '/class-wp-rest-global-styles-controller-gutenberg.php'; @@ -120,6 +122,7 @@ function gutenberg_is_experiment_enabled( $name ) { require __DIR__ . '/compat/wordpress-6.8/preload.php'; require __DIR__ . '/compat/wordpress-6.8/blocks.php'; require __DIR__ . '/compat/wordpress-6.8/functions.php'; +require __DIR__ . '/compat/wordpress-6.8/post.php'; // Experimental features. require __DIR__ . '/experimental/block-editor-settings-mobile.php'; diff --git a/packages/edit-site/src/components/block-editor/use-site-editor-settings.js b/packages/edit-site/src/components/block-editor/use-site-editor-settings.js index 5c75de6d81e720..186f4aacf79232 100644 --- a/packages/edit-site/src/components/block-editor/use-site-editor-settings.js +++ b/packages/edit-site/src/components/block-editor/use-site-editor-settings.js @@ -36,9 +36,7 @@ function useNavigateToPreviousEntityRecord() { return goBack; } -export function useSpecificEditorSettings( - shouldUseTemplateAsDefaultRenderingMode -) { +export function useSpecificEditorSettings() { const { params } = useLocation(); const { canvas = 'view' } = params; const onNavigateToEntityRecord = useNavigateToEntityRecord(); @@ -49,11 +47,6 @@ export function useSpecificEditorSettings( }; }, [] ); - // TODO: The `shouldUseTemplateAsDefaultRenderingMode` check should be removed when the default rendering mode per post type is merged. - // @see https://github.com/WordPress/gutenberg/pull/62304/ - const defaultRenderingMode = shouldUseTemplateAsDefaultRenderingMode - ? 'template-locked' - : 'post-only'; const onNavigateToPreviousEntityRecord = useNavigateToPreviousEntityRecord(); const defaultEditorSettings = useMemo( () => { @@ -63,7 +56,6 @@ export function useSpecificEditorSettings( richEditingEnabled: true, supportsTemplateMode: true, focusMode: canvas !== 'view', - defaultRenderingMode, onNavigateToEntityRecord, onNavigateToPreviousEntityRecord, isPreviewMode: canvas === 'view', @@ -71,7 +63,6 @@ export function useSpecificEditorSettings( }, [ settings, canvas, - defaultRenderingMode, onNavigateToEntityRecord, onNavigateToPreviousEntityRecord, ] ); diff --git a/packages/edit-site/src/components/editor/index.js b/packages/edit-site/src/components/editor/index.js index 51d734f25c6adb..1d115dca7518df 100644 --- a/packages/edit-site/src/components/editor/index.js +++ b/packages/edit-site/src/components/editor/index.js @@ -131,9 +131,7 @@ export default function EditSiteEditor( { isPostsList = false } ) { 'edit-site-editor__loading-progress' ); - const settings = useSpecificEditorSettings( - !! context?.postId && context?.postType !== 'post' - ); + const settings = useSpecificEditorSettings(); const styles = useMemo( () => [ ...settings.styles, diff --git a/packages/editor/src/components/provider/index.js b/packages/editor/src/components/provider/index.js index 50d02610062c00..6c05e5b58235b3 100644 --- a/packages/editor/src/components/provider/index.js +++ b/packages/editor/src/components/provider/index.js @@ -72,8 +72,7 @@ const NON_CONTEXTUAL_POST_TYPES = [ * @return {Array} Block editor props. */ function useBlockEditorProps( post, template, mode ) { - const rootLevelPost = - mode === 'post-only' || ! template ? 'post' : 'template'; + const rootLevelPost = mode === 'template-locked' ? 'template' : 'post'; const [ postBlocks, onInput, onChange ] = useEntityBlockEditor( 'postType', post.type, @@ -164,30 +163,48 @@ export const ExperimentalEditorProvider = withRegistryProvider( BlockEditorProviderComponent = ExperimentalBlockEditorProvider, __unstableTemplate: template, } ) => { - const { editorSettings, selection, isReady, mode, postTypeEntities } = - useSelect( - ( select ) => { - const { - getEditorSettings, - getEditorSelection, - getRenderingMode, - __unstableIsEditorReady, - } = select( editorStore ); - const { getEntitiesConfig } = select( coreStore ); + const { + editorSettings, + selection, + isReady, + mode, + defaultMode, + postTypeEntities, + hasLoadedPostObject, + } = useSelect( + ( select ) => { + const { + getEditorSettings, + getEditorSelection, + getRenderingMode, + __unstableIsEditorReady, + } = select( editorStore ); + const { getEntitiesConfig } = select( coreStore ); + + const postTypeObject = select( coreStore ).getPostType( + post.type + ); + + const _hasLoadedPostObject = select( + coreStore + ).hasFinishedResolution( 'getPostType', [ post.type ] ); - return { - editorSettings: getEditorSettings(), - isReady: __unstableIsEditorReady(), - mode: getRenderingMode(), - selection: getEditorSelection(), - postTypeEntities: - post.type === 'wp_template' - ? getEntitiesConfig( 'postType' ) - : null, - }; - }, - [ post.type ] - ); + return { + hasLoadedPostObject: _hasLoadedPostObject, + editorSettings: getEditorSettings(), + isReady: __unstableIsEditorReady(), + mode: getRenderingMode(), + defaultMode: + postTypeObject?.default_rendering_mode ?? 'post-only', + selection: getEditorSelection(), + postTypeEntities: + post.type === 'wp_template' + ? getEntitiesConfig( 'postType' ) + : null, + }; + }, + [ post.type ] + ); const shouldRenderTemplate = !! template && mode !== 'post-only'; const rootLevelPost = shouldRenderTemplate ? template : post; const defaultBlockContext = useMemo( () => { @@ -282,7 +299,15 @@ export const ExperimentalEditorProvider = withRegistryProvider( } ); } - }, [] ); + }, [ + createWarningNotice, + initialEdits, + settings, + post, + recovery, + setupEditor, + updatePostLock, + ] ); // Synchronizes the active post with the state useEffect( () => { @@ -301,15 +326,15 @@ export const ExperimentalEditorProvider = withRegistryProvider( // Sets the right rendering mode when loading the editor. useEffect( () => { - setRenderingMode( settings.defaultRenderingMode ?? 'post-only' ); - }, [ settings.defaultRenderingMode, setRenderingMode ] ); + setRenderingMode( defaultMode ); + }, [ defaultMode, setRenderingMode ] ); useHideBlocksFromInserter( post.type, mode ); // Register the editor commands. useCommands(); - if ( ! isReady ) { + if ( ! isReady || ! mode || ! hasLoadedPostObject ) { return null; } diff --git a/packages/editor/src/store/reducer.native.js b/packages/editor/src/store/reducer.native.js index 7566dfc5dfd038..fbf6c968f57d08 100644 --- a/packages/editor/src/store/reducer.native.js +++ b/packages/editor/src/store/reducer.native.js @@ -9,6 +9,7 @@ import { combineReducers } from '@wordpress/data'; import { postId, postType, + renderingMode, saving, postLock, postSavingLock, @@ -82,6 +83,7 @@ export default combineReducers( { postId, postType, postTitle, + renderingMode, saving, postLock, postSavingLock, diff --git a/test/native/integration-test-helpers/initialize-editor.js b/test/native/integration-test-helpers/initialize-editor.js index 511f0223e11356..3b89da979aee3a 100644 --- a/test/native/integration-test-helpers/initialize-editor.js +++ b/test/native/integration-test-helpers/initialize-editor.js @@ -10,6 +10,8 @@ import { v4 as uuid } from 'uuid'; import { createElement, cloneElement } from '@wordpress/element'; // eslint-disable-next-line no-restricted-imports import { initializeEditor as internalInitializeEditor } from '@wordpress/edit-post'; +import { store as coreStore } from '@wordpress/core-data'; +import { select } from '@wordpress/data'; /** * Internal dependencies @@ -28,6 +30,21 @@ import { getGlobalStyles } from './get-global-styles'; * @return {import('@testing-library/react-native').RenderAPI} A Testing Library screen. */ export async function initializeEditor( props, { component } = {} ) { + const resolutionSpy = jest.spyOn( + select( coreStore ), + 'hasFinishedResolution' + ); + const actualResolution = resolutionSpy.getMockImplementation(); + resolutionSpy.mockImplementation( ( selectorName, args ) => { + // The mobile editor only supports the `post-only` rendering mode, so we + // presume a resolved `getPostType` selector to unblock editor rendering. + if ( 'getPostType' === selectorName ) { + return true; + } + + return actualResolution( selectorName, args ); + } ); + const uniqueId = uuid(); const postId = `post-id-${ uniqueId }`; const postType = 'post'; diff --git a/test/performance/fixtures/perf-utils.ts b/test/performance/fixtures/perf-utils.ts index 592e8194852e3b..8d23d91ff91bfd 100644 --- a/test/performance/fixtures/perf-utils.ts +++ b/test/performance/fixtures/perf-utils.ts @@ -97,6 +97,26 @@ export class PerfUtils { return canvas; } + /** + * Change the rendering mode of the editor. + * + * Setting the rendering mode to something other than the default is sometimes + * needed when for example we want to update the contents of the editor from a + * HTML file. Calling the resetBlocks method of the core/block-editor store will + * replace the contents of the template if the rendering mode is not post-only. + * So this should always be called before the resetBlocks method is used. + * + * @param newRenderingMode Rendering mode to set + * + * @return Promise + */ + async setRenderingMode( newRenderingMode: string ) { + await this.page.evaluate( ( _newRenderingMode ) => { + const { dispatch } = window.wp.data; + dispatch( 'core/editor' ).setRenderingMode( _newRenderingMode ); + }, newRenderingMode ); + } + /** * Loads blocks from the small post with containers fixture into the editor * canvas. diff --git a/test/performance/specs/site-editor.spec.js b/test/performance/specs/site-editor.spec.js index 9c9d8aec71da4a..e72d83fa8b3aa4 100644 --- a/test/performance/specs/site-editor.spec.js +++ b/test/performance/specs/site-editor.spec.js @@ -64,6 +64,7 @@ test.describe( 'Site Editor Performance', () => { test( 'Setup the test page', async ( { admin, perfUtils } ) => { await admin.createNewPost( { postType: 'page' } ); + await perfUtils.setRenderingMode( 'post-only' ); await perfUtils.loadBlocksForLargePost(); draftId = await perfUtils.saveDraft(); @@ -122,6 +123,7 @@ test.describe( 'Site Editor Performance', () => { test( 'Setup the test post', async ( { admin, editor, perfUtils } ) => { await admin.createNewPost( { postType: 'page' } ); + await perfUtils.setRenderingMode( 'post-only' ); await perfUtils.loadBlocksForLargePost(); await editor.insertBlock( { name: 'core/paragraph' } ); From d478c08d4c0827864e7be4e2df487297ad36d7b0 Mon Sep 17 00:00:00 2001 From: Lena Morita Date: Wed, 20 Nov 2024 01:52:35 +0900 Subject: [PATCH 05/16] ColorPicker: Update sizes of format select and copy button (#67093) * ColorPicker: Update sizes of format select and copy button * Add changelog Co-authored-by: mirka <0mirka00@git.wordpress.org> Co-authored-by: tyxla --- packages/components/CHANGELOG.md | 4 ++++ .../src/color-picker/color-copy-button.tsx | 6 +++--- packages/components/src/color-picker/component.tsx | 1 + packages/components/src/color-picker/styles.ts | 13 ------------- 4 files changed, 8 insertions(+), 16 deletions(-) diff --git a/packages/components/CHANGELOG.md b/packages/components/CHANGELOG.md index d93eb30ac0ec50..dfb9454d8da1f0 100644 --- a/packages/components/CHANGELOG.md +++ b/packages/components/CHANGELOG.md @@ -12,6 +12,10 @@ - `ToggleGroupControl`: Fix active background for `0` value ([#66855](https://github.com/WordPress/gutenberg/pull/66855)). - `SlotFill`: Fix a bug where a stale value of `fillProps` could be used ([#67000](https://github.com/WordPress/gutenberg/pull/67000)). +### Enhancements + +- `ColorPicker`: Update sizes of color format select and copy button ([#67093](https://github.com/WordPress/gutenberg/pull/67093)). + ### Experimental - `SlotFill`: Remove registration API methods from return value of `__experimentalUseSlot` ([#67070](https://github.com/WordPress/gutenberg/pull/67070)). diff --git a/packages/components/src/color-picker/color-copy-button.tsx b/packages/components/src/color-picker/color-copy-button.tsx index b8a4822544322c..0076a2125d00c0 100644 --- a/packages/components/src/color-picker/color-copy-button.tsx +++ b/packages/components/src/color-picker/color-copy-button.tsx @@ -9,7 +9,7 @@ import { __ } from '@wordpress/i18n'; /** * Internal dependencies */ -import { CopyButton } from './styles'; +import { Button } from '../button'; import Tooltip from '../tooltip'; import type { ColorCopyButtonProps } from './types'; @@ -63,8 +63,8 @@ export const ColorCopyButton = ( props: ColorCopyButtonProps ) => { copiedColor === color.toHex() ? __( 'Copied!' ) : __( 'Copy' ) } > - diff --git a/packages/components/src/color-picker/styles.ts b/packages/components/src/color-picker/styles.ts index a78f10de2e4a32..50ce33da9f2333 100644 --- a/packages/components/src/color-picker/styles.ts +++ b/packages/components/src/color-picker/styles.ts @@ -11,7 +11,6 @@ import InnerSelectControl from '../select-control'; import InnerRangeControl from '../range-control'; import { space } from '../utils/space'; import { boxSizingReset } from '../utils'; -import Button from '../button'; import { Flex } from '../flex'; import { HStack } from '../h-stack'; import CONFIG from '../utils/config-values'; @@ -22,7 +21,6 @@ export const NumberControlWrapper = styled( NumberControl )` export const SelectControl = styled( InnerSelectControl )` margin-left: ${ space( -2 ) }; - width: 5em; `; export const RangeControl = styled( InnerRangeControl )` @@ -101,14 +99,3 @@ export const ColorfulWrapper = styled.div` ${ interactiveHueStyles } `; - -export const CopyButton = styled( Button )` - &&&&& { - min-width: ${ space( 6 ) }; - padding: 0; - - > svg { - margin-right: 0; - } - } -`; From dea308b86eb32c23d384cd2d0f756fc9a047cca1 Mon Sep 17 00:00:00 2001 From: Lena Morita Date: Wed, 20 Nov 2024 07:28:07 +0900 Subject: [PATCH 06/16] ColorPicker: Add accessible label for copy button (#67094) * ColorPicker: Add accessible label for copy button * Add changelog * Use variable Co-authored-by: mirka <0mirka00@git.wordpress.org> Co-authored-by: tyxla --- packages/components/CHANGELOG.md | 1 + .../src/color-picker/color-copy-button.tsx | 12 +++++------- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/packages/components/CHANGELOG.md b/packages/components/CHANGELOG.md index dfb9454d8da1f0..34a90b6ca23b3c 100644 --- a/packages/components/CHANGELOG.md +++ b/packages/components/CHANGELOG.md @@ -11,6 +11,7 @@ - `ToggleGroupControl`: Fix active background for `0` value ([#66855](https://github.com/WordPress/gutenberg/pull/66855)). - `SlotFill`: Fix a bug where a stale value of `fillProps` could be used ([#67000](https://github.com/WordPress/gutenberg/pull/67000)). +- `ColorPicker`: Add accessible label for copy button ([#67094](https://github.com/WordPress/gutenberg/pull/67094)). ### Enhancements diff --git a/packages/components/src/color-picker/color-copy-button.tsx b/packages/components/src/color-picker/color-copy-button.tsx index 0076a2125d00c0..6e49fa7ae85e74 100644 --- a/packages/components/src/color-picker/color-copy-button.tsx +++ b/packages/components/src/color-picker/color-copy-button.tsx @@ -55,16 +55,14 @@ export const ColorCopyButton = ( props: ColorCopyButtonProps ) => { }; }, [] ); + const label = + copiedColor === color.toHex() ? __( 'Copied!' ) : __( 'Copy' ); + return ( - + - - ); - } ); - } + { __( 'Edit' ) } + + + ); + } ); + return ( - - - { __( 'Edit track' ) } - - - { __( 'File' ) }: { fileName } - - - - onChange( { - ...track, - label: newLabel, - } ) - } - label={ __( 'Label' ) } - value={ label } - help={ __( 'Title of track' ) } - /> - + + { __( 'Edit track' ) } + + + { __( 'File' ) }: { fileName } + + + + onChange( { + ...track, + label: newLabel, + } ) + } + label={ __( 'Label' ) } + value={ label } + help={ __( 'Title of track' ) } + /> + + onChange( { + ...track, + srcLang: newSrcLang, + } ) + } + label={ __( 'Source language' ) } + value={ srcLang } + help={ __( 'Language tag (en, fr, etc.)' ) } + /> + + + { + onChange( { + ...track, + kind: newKind, + } ); + } } + /> + + + - - - + > + { __( 'Apply' ) } + + - + ); } @@ -194,6 +179,11 @@ export default function TracksEditor( { tracks = [], onChange } ) { return select( blockEditorStore ).getSettings().mediaUpload; }, [] ); const [ trackBeingEdited, setTrackBeingEdited ] = useState( null ); + const dropdownPopoverRef = useRef(); + + useEffect( () => { + dropdownPopoverRef.current?.focus(); + }, [ trackBeingEdited ] ); if ( ! mediaUpload ) { return null; @@ -201,17 +191,32 @@ export default function TracksEditor( { tracks = [], onChange } ) { return ( ( - - - { __( 'Text tracks' ) } - - - ) } + focusOnMount + popoverProps={ { + ref: dropdownPopoverRef, + } } + renderToggle={ ( { isOpen, onToggle } ) => { + const handleOnToggle = () => { + if ( ! isOpen ) { + // When the Popover opens make sure the initial view is + // always the track list rather than the edit track UI. + setTrackBeingEdited( null ); + } + onToggle(); + }; + + return ( + + + { __( 'Text tracks' ) } + + + ); + } } renderContent={ () => { if ( trackBeingEdited !== null ) { return ( @@ -235,8 +240,21 @@ export default function TracksEditor( { tracks = [], onChange } ) { /> ); } + return ( <> + { tracks.length === 0 && ( +
+

+ { __( 'Text tracks' ) } +

+

+ { __( + 'Tracks can be subtitles, captions, chapters, or descriptions. They help make your content more accessible to a wider range of users.' + ) } +

+
+ ) } Date: Wed, 20 Nov 2024 15:44:36 +0530 Subject: [PATCH 16/16] Blocks: Adds check for parent type before showing convert to pattern button (#66158) Co-authored-by: vipul0425 Co-authored-by: gziolo Co-authored-by: ntsekouras Co-authored-by: Mamaduka Co-authored-by: mtias Co-authored-by: aristath Co-authored-by: jordesign Co-authored-by: fabiankaegy --- .../src/components/pattern-convert-button.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/packages/patterns/src/components/pattern-convert-button.js b/packages/patterns/src/components/pattern-convert-button.js index d670cd85946aa9..4573a6a5de4e82 100644 --- a/packages/patterns/src/components/pattern-convert-button.js +++ b/packages/patterns/src/components/pattern-convert-button.js @@ -6,6 +6,7 @@ import { isReusableBlock, createBlock, serialize, + getBlockType, } from '@wordpress/blocks'; import { store as blockEditorStore } from '@wordpress/block-editor'; import { useState, useCallback } from '@wordpress/element'; @@ -60,6 +61,15 @@ export default function PatternConvertButton( { const blocks = getBlocksByClientId( clientIds ) ?? []; + // Check if the block has reusable support defined. + const hasReusableBlockSupport = ( blockName ) => { + const blockType = getBlockType( blockName ); + const hasParent = blockType && 'parent' in blockType; + + // If the block has a parent, check with false as default, otherwise with true. + return hasBlockSupport( blockName, 'reusable', ! hasParent ); + }; + const isReusable = blocks.length === 1 && blocks[ 0 ] && @@ -82,7 +92,7 @@ export default function PatternConvertButton( { // Hide on invalid blocks. block.isValid && // Hide when block doesn't support being made into a pattern. - hasBlockSupport( block.name, 'reusable', true ) + hasReusableBlockSupport( block.name ) ) && // Hide when current doesn't have permission to do that. // Blocks refers to the wp_block post type, this checks the ability to create a post of that type.