diff --git a/.github/workflows/build-plugin-zip.yml b/.github/workflows/build-plugin-zip.yml index 0f813267b586b..9a3a9abb84963 100644 --- a/.github/workflows/build-plugin-zip.yml +++ b/.github/workflows/build-plugin-zip.yml @@ -72,7 +72,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 with: token: ${{ secrets.GUTENBERG_TOKEN }} show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} @@ -168,7 +168,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 with: ref: ${{ needs.bump-version.outputs.release_branch || github.ref }} show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} @@ -225,7 +225,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 with: fetch-depth: 2 ref: ${{ needs.bump-version.outputs.release_branch }} @@ -314,14 +314,14 @@ jobs: if: ${{ endsWith( needs.bump-version.outputs.new_version, '-rc.1' ) }} steps: - name: Checkout (for CLI) - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 with: path: main ref: trunk show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} - name: Checkout (for publishing) - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 with: path: publish # Later, we switch this branch in the script that publishes packages. diff --git a/.github/workflows/bundle-size.yml b/.github/workflows/bundle-size.yml index 2de66f77e3918..4b0b93ac959ed 100644 --- a/.github/workflows/bundle-size.yml +++ b/.github/workflows/bundle-size.yml @@ -37,7 +37,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 with: fetch-depth: 1 show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} diff --git a/.github/workflows/check-backport-changelog.yml b/.github/workflows/check-backport-changelog.yml index cf07b1a3936b9..889e1cfb47725 100644 --- a/.github/workflows/check-backport-changelog.yml +++ b/.github/workflows/check-backport-changelog.yml @@ -22,7 +22,7 @@ jobs: runs-on: ubuntu-latest if: ${{ !contains(github.event.pull_request.labels.*.name, 'No Core Sync Required') && !contains(github.event.pull_request.labels.*.name, 'Backport from WordPress Core') }} steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 with: ref: ${{ github.event.pull_request.head.ref }} repository: ${{ github.event.pull_request.head.repo.full_name }} diff --git a/.github/workflows/check-components-changelog.yml b/.github/workflows/check-components-changelog.yml index 40fbfe22bea56..2c0d52c77ea4e 100644 --- a/.github/workflows/check-components-changelog.yml +++ b/.github/workflows/check-components-changelog.yml @@ -22,7 +22,7 @@ jobs: - name: 'Get PR commit count' run: echo "PR_COMMIT_COUNT=$(( ${{ github.event.pull_request.commits }} + 1 ))" >> "${GITHUB_ENV}" - name: Checkout code - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 with: ref: ${{ github.event.pull_request.head.ref }} repository: ${{ github.event.pull_request.head.repo.full_name }} diff --git a/.github/workflows/cherry-pick-wp-release.yml b/.github/workflows/cherry-pick-wp-release.yml index 11688a7cfba98..5771a21d5b068 100644 --- a/.github/workflows/cherry-pick-wp-release.yml +++ b/.github/workflows/cherry-pick-wp-release.yml @@ -70,7 +70,7 @@ jobs: - name: Checkout repository if: env.cherry_pick == 'true' - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 with: token: ${{ secrets.GUTENBERG_TOKEN }} fetch-depth: 0 diff --git a/.github/workflows/create-block.yml b/.github/workflows/create-block.yml index d20b3e353c31e..4d99d396996c5 100644 --- a/.github/workflows/create-block.yml +++ b/.github/workflows/create-block.yml @@ -24,7 +24,7 @@ jobs: os: ['macos-latest', 'ubuntu-latest', 'windows-latest'] steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 with: show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} diff --git a/.github/workflows/end2end-test.yml b/.github/workflows/end2end-test.yml index bbf033222a4b3..2ea5949d20946 100644 --- a/.github/workflows/end2end-test.yml +++ b/.github/workflows/end2end-test.yml @@ -27,7 +27,7 @@ jobs: totalParts: [8] steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 with: show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} @@ -102,7 +102,7 @@ jobs: steps: # Checkout defaults to using the branch which triggered the event, which # isn't necessarily `trunk` (e.g. in the case of a merge). - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 with: ref: trunk show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} diff --git a/.github/workflows/gradle-wrapper-validation.yml b/.github/workflows/gradle-wrapper-validation.yml index 4715e1e09c2b8..f268ac7183ee2 100644 --- a/.github/workflows/gradle-wrapper-validation.yml +++ b/.github/workflows/gradle-wrapper-validation.yml @@ -6,7 +6,7 @@ jobs: name: 'Validation' runs-on: ubuntu-latest steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 with: show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} - uses: gradle/wrapper-validation-action@v3 diff --git a/.github/workflows/performance.yml b/.github/workflows/performance.yml index 9c4bee3af473c..a79f2eee9315a 100644 --- a/.github/workflows/performance.yml +++ b/.github/workflows/performance.yml @@ -33,7 +33,7 @@ jobs: WP_ARTIFACTS_PATH: ${{ github.workspace }}/artifacts steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 with: show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} diff --git a/.github/workflows/publish-npm-packages.yml b/.github/workflows/publish-npm-packages.yml index 66f8130ece2f0..b95a4baaf5075 100644 --- a/.github/workflows/publish-npm-packages.yml +++ b/.github/workflows/publish-npm-packages.yml @@ -31,7 +31,7 @@ jobs: steps: - name: Checkout (for CLI) if: ${{ github.event.inputs.release_type != 'wp' }} - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 with: path: cli ref: trunk @@ -39,7 +39,7 @@ jobs: - name: Checkout (for publishing) if: ${{ github.event.inputs.release_type != 'wp' }} - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 with: path: publish # Later, we switch this branch in the script that publishes packages. @@ -49,7 +49,7 @@ jobs: - name: Checkout (for publishing WP major version) if: ${{ github.event.inputs.release_type == 'wp' && github.event.inputs.wp_version }} - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 with: path: publish ref: wp/${{ github.event.inputs.wp_version }} diff --git a/.github/workflows/pull-request-automation.yml b/.github/workflows/pull-request-automation.yml index f85b851006756..9aecafc2009e7 100644 --- a/.github/workflows/pull-request-automation.yml +++ b/.github/workflows/pull-request-automation.yml @@ -12,7 +12,7 @@ jobs: steps: # Checkout defaults to using the branch which triggered the event, which # isn't necessarily `trunk` (e.g. in the case of a merge). - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 with: ref: trunk show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} @@ -24,7 +24,7 @@ jobs: check-latest: true - name: Cache NPM packages - uses: actions/cache@2cdf405574d6ef1f33a1d12acccd3ae82f47b3f2 # v4.1.0 + uses: actions/cache@3624ceb22c1c5a301c8db4169662070a689d9ea8 # v4.1.1 with: # npm cache files are stored in `~/.npm` on Linux/macOS path: ~/.npm diff --git a/.github/workflows/rnmobile-android-runner.yml b/.github/workflows/rnmobile-android-runner.yml index 729d1d20fd7e7..a1e332be78303 100644 --- a/.github/workflows/rnmobile-android-runner.yml +++ b/.github/workflows/rnmobile-android-runner.yml @@ -23,7 +23,7 @@ jobs: steps: - name: checkout - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 with: show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} @@ -37,7 +37,7 @@ jobs: uses: ./.github/setup-node - name: Restore tests setup cache - uses: actions/cache@2cdf405574d6ef1f33a1d12acccd3ae82f47b3f2 # v4.1.0 + uses: actions/cache@3624ceb22c1c5a301c8db4169662070a689d9ea8 # v4.1.1 with: path: | ~/.appium @@ -50,7 +50,7 @@ jobs: uses: gradle/actions/setup-gradle@d156388eb19639ec20ade50009f3d199ce1e2808 # v4.1.0 - name: AVD cache - uses: actions/cache@2cdf405574d6ef1f33a1d12acccd3ae82f47b3f2 # v4.1.0 + uses: actions/cache@3624ceb22c1c5a301c8db4169662070a689d9ea8 # v4.1.1 id: avd-cache with: path: | diff --git a/.github/workflows/rnmobile-ios-runner.yml b/.github/workflows/rnmobile-ios-runner.yml index 475937eb58f5f..a5c5dfd3f96f9 100644 --- a/.github/workflows/rnmobile-ios-runner.yml +++ b/.github/workflows/rnmobile-ios-runner.yml @@ -23,11 +23,11 @@ jobs: native-test-name: [gutenberg-editor-rendering] steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 with: show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} - - uses: ruby/setup-ruby@086ffb1a2090c870a3f881cc91ea83aa4243d408 # v1.195.0 + - uses: ruby/setup-ruby@f26937343756480a8cb3ae1f623b9c8d89ed6984 # v1.196.0 with: # `.ruby-version` file location working-directory: packages/react-native-editor/ios @@ -42,7 +42,7 @@ jobs: uses: ./.github/setup-node - name: Restore tests setup cache - uses: actions/cache@2cdf405574d6ef1f33a1d12acccd3ae82f47b3f2 # v4.1.0 + uses: actions/cache@3624ceb22c1c5a301c8db4169662070a689d9ea8 # v4.1.1 with: path: | ~/.appium @@ -55,7 +55,7 @@ jobs: run: find package-lock.json packages/react-native-editor/ios packages/react-native-aztec/ios packages/react-native-bridge/ios -type f -print0 | sort -z | xargs -0 shasum | tee ios-checksums.txt - name: Restore build cache - uses: actions/cache@2cdf405574d6ef1f33a1d12acccd3ae82f47b3f2 # v4.1.0 + uses: actions/cache@3624ceb22c1c5a301c8db4169662070a689d9ea8 # v4.1.1 with: path: | packages/react-native-editor/ios/build/GutenbergDemo/Build/Products/Release-iphonesimulator/GutenbergDemo.app @@ -63,7 +63,7 @@ jobs: key: ${{ runner.os }}-ios-build-${{ matrix.xcode }}-${{ matrix.device }}-${{ hashFiles('ios-checksums.txt') }} - name: Restore pods cache - uses: actions/cache@2cdf405574d6ef1f33a1d12acccd3ae82f47b3f2 # v4.1.0 + uses: actions/cache@3624ceb22c1c5a301c8db4169662070a689d9ea8 # v4.1.1 with: path: | packages/react-native-editor/ios/Pods diff --git a/.github/workflows/static-checks.yml b/.github/workflows/static-checks.yml index 1af2bb0ec7927..bf1a70d3adefc 100644 --- a/.github/workflows/static-checks.yml +++ b/.github/workflows/static-checks.yml @@ -22,7 +22,7 @@ jobs: if: ${{ github.repository == 'WordPress/gutenberg' || github.event_name == 'pull_request' }} steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 with: show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} diff --git a/.github/workflows/storybook-pages.yml b/.github/workflows/storybook-pages.yml index 83f7fdb96f926..a0a7d0f12db1e 100644 --- a/.github/workflows/storybook-pages.yml +++ b/.github/workflows/storybook-pages.yml @@ -12,7 +12,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 with: ref: trunk show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} diff --git a/.github/workflows/sync-backport-changelog.yml b/.github/workflows/sync-backport-changelog.yml index b71d9440c38a1..31b00459c24c6 100644 --- a/.github/workflows/sync-backport-changelog.yml +++ b/.github/workflows/sync-backport-changelog.yml @@ -20,7 +20,7 @@ jobs: ) steps: - name: Checkout - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 with: fetch-depth: 2 # Fetch the last two commits to compare changes - name: Check for changes in backport-changelog diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml index 47b5e9f76ea7b..272d7e12d7193 100644 --- a/.github/workflows/unit-test.yml +++ b/.github/workflows/unit-test.yml @@ -32,7 +32,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 with: show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} @@ -70,7 +70,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 with: show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} @@ -121,7 +121,7 @@ jobs: name: Build JavaScript assets for PHP unit tests runs-on: ubuntu-latest steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 with: show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} @@ -173,7 +173,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 with: show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} @@ -278,7 +278,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 with: show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} @@ -296,7 +296,7 @@ jobs: run: echo "date=$(/bin/date -u --date='last Mon' "+%F")" >> $GITHUB_OUTPUT - name: Cache PHPCS scan cache - uses: actions/cache@2cdf405574d6ef1f33a1d12acccd3ae82f47b3f2 # v4.1.0 + uses: actions/cache@3624ceb22c1c5a301c8db4169662070a689d9ea8 # v4.1.1 with: path: .cache/phpcs.json key: ${{ runner.os }}-date-${{ steps.get-date.outputs.date }}-phpcs-cache-${{ hashFiles('**/composer.json', 'phpcs.xml.dist') }} @@ -348,7 +348,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 with: show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} diff --git a/.github/workflows/upload-release-to-plugin-repo.yml b/.github/workflows/upload-release-to-plugin-repo.yml index d09e2af3dd213..e8d3e3e245abd 100644 --- a/.github/workflows/upload-release-to-plugin-repo.yml +++ b/.github/workflows/upload-release-to-plugin-repo.yml @@ -96,7 +96,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 with: ref: ${{ matrix.branch }} token: ${{ secrets.GUTENBERG_TOKEN }} diff --git a/docs/how-to-guides/curating-the-editor-experience/disable-editor-functionality.md b/docs/how-to-guides/curating-the-editor-experience/disable-editor-functionality.md index ce8478f024131..a20d2cf9d8b8a 100644 --- a/docs/how-to-guides/curating-the-editor-experience/disable-editor-functionality.md +++ b/docs/how-to-guides/curating-the-editor-experience/disable-editor-functionality.md @@ -6,6 +6,37 @@ This page is dedicated to the many ways you can disable specific functionality i There might be times when you don’t want access to a block at all to be available for users. To control what’s available in the inserter, you can take two approaches: [an allow list](/docs/reference-guides/filters/block-filters.md#using-an-allow-list) that disables all blocks except those on the list or a [deny list that unregisters specific blocks](/docs/reference-guides/filters/block-filters.md#using-a-deny-list). +## Curate heading levels + +Core WordPress blocks with a heading level dropdown include support for the `levelOptions` attribute. This applies to the Heading, Site Title, Site Tagline, Query Title, Post Title, and Comments Title blocks. The `levelOptions` attribute accepts an array of numbers corresponding to heading levels, where `1` represents H1, `2` represents H2, and so on. + +This attribute allows you to specify which heading levels should appear in the dropdown UI, providing a lightweight curation method that does not require block deprecations. Any existing heading levels are preserved in the markup, while `levelOptions` only affects the UI display. + +You can apply this attribute directly in the block markup, a technique that will be commonly used in block templates, template parts, and patterns. For example, the following markup disables H1, H2, and H6 in the Heading block by setting `"levelOptions":[3,4,5]`. + +```html + +

Markup example

+ +``` + +You can also use [block filters](/docs/reference-guides/filters/block-filters.md) to set the default value of this attribute globally or for specific blocks. The example below disables H1, H2, and H6 for all Heading blocks. You can further customize this by restricting certain heading levels based on conditions like user capabilities. + +```php +function example_modify_heading_levels_globally( $args, $block_type ) { + + if ( 'core/heading' !== $block_type ) { + return $args; + } + + // Remove H1, H2, and H6. + $args['attributes']['levelOptions']['default'] = [ 3, 4, 5 ]; + + return $args; +} +add_filter( 'register_block_type_args', 'example_modify_heading_levels_globally', 10, 2 ); +``` + ## Disable the Pattern Directory To fully remove patterns bundled with WordPress core from being accessed in the Inserter, the following can be added to your `functions.php` file: diff --git a/packages/base-styles/_z-index.scss b/packages/base-styles/_z-index.scss index ff61c5793e787..77238c6f38608 100644 --- a/packages/base-styles/_z-index.scss +++ b/packages/base-styles/_z-index.scss @@ -31,10 +31,12 @@ $z-layers: ( ".interface-interface-skeleton__header": 30, ".interface-interface-skeleton__content": 20, ".edit-widgets-header": 30, + ".wp-block-cover__inner-container": 1, // InnerBlocks area inside cover image block. ".wp-block-cover.is-placeholder .components-placeholder.is-large": 1, // Cover block resizer component inside a large placeholder. - ".wp-block-cover.has-background-dim::before": 0, // Overlay area inside block cover need to be higher than the video background. - ".wp-block-cover__image-background": -1, // Image background inside cover block. - ".wp-block-cover__video-background": -1, // Video background inside cover block. + ".wp-block-cover.has-background-dim::before": 1, // Overlay area inside block cover need to be higher than the video background. + ".block-library-cover__padding-visualizer": 2, // BoxControl visualizer needs to be +1 higher than .wp-block-cover.has-background-dim::before + ".wp-block-cover__image-background": 0, // Image background inside cover block. + ".wp-block-cover__video-background": 0, // Video background inside cover block. ".wp-block-template-part__placeholder-preview-filter-input": 1, // Fixed position appender: diff --git a/packages/block-editor/README.md b/packages/block-editor/README.md index 36f3dc0ba73fa..7fc44c2ead943 100644 --- a/packages/block-editor/README.md +++ b/packages/block-editor/README.md @@ -1077,11 +1077,11 @@ _Parameters_ ### useZoomOut -A hook used to set the zoomed out view, invoking the hook sets the mode. +A hook used to set the editor mode to zoomed out mode, invoking the hook sets the mode. _Parameters_ -- _zoomOut_ `boolean`: If we should zoom out or not. +- _zoomOut_ `boolean`: If we should enter into zoomOut mode or not ### Warning diff --git a/packages/block-editor/src/components/iframe/content.scss b/packages/block-editor/src/components/iframe/content.scss index 206f1adf32946..069274e66bdfd 100644 --- a/packages/block-editor/src/components/iframe/content.scss +++ b/packages/block-editor/src/components/iframe/content.scss @@ -1,5 +1,6 @@ .block-editor-iframe__body { position: relative; + border: 0.01px solid transparent; } .block-editor-iframe__html { @@ -32,8 +33,6 @@ body { min-height: calc((#{$inner-height} - #{$total-frame-height}) / #{$scale}); - display: flex; - flex-direction: column; > .is-root-container:not(.wp-block-post-content) { flex: 1; diff --git a/packages/block-editor/src/components/inserter/menu.js b/packages/block-editor/src/components/inserter/menu.js index fa72728f6de20..bdd4ff11abcee 100644 --- a/packages/block-editor/src/components/inserter/menu.js +++ b/packages/block-editor/src/components/inserter/menu.js @@ -322,7 +322,7 @@ function InserterMenu( onSelect={ handleSetSelectedTab } onClose={ onClose } selectedTab={ selectedTab } - closeButtonLabel={ __( 'Close block inserter' ) } + closeButtonLabel={ __( 'Close Block Inserter' ) } tabs={ [ { name: 'blocks', diff --git a/packages/block-editor/src/hooks/grid-visualizer.js b/packages/block-editor/src/hooks/grid-visualizer.js index 44102208c4d1d..26650c85ea509 100644 --- a/packages/block-editor/src/hooks/grid-visualizer.js +++ b/packages/block-editor/src/hooks/grid-visualizer.js @@ -16,20 +16,34 @@ function GridLayoutSync( props ) { } function GridTools( { clientId, layout } ) { - const { isSelected, isDragging } = useSelect( ( select ) => { - const { isBlockSelected, isDraggingBlocks } = - select( blockEditorStore ); + const isVisible = useSelect( + ( select ) => { + const { + isBlockSelected, + isDraggingBlocks, + getTemplateLock, + getBlockEditingMode, + } = select( blockEditorStore ); - return { - isSelected: isBlockSelected( clientId ), - isDragging: isDraggingBlocks(), - }; - } ); + // These calls are purposely ordered from least expensive to most expensive. + // Hides the visualizer in cases where the user is not or cannot interact with it. + if ( + ( ! isDraggingBlocks() && ! isBlockSelected( clientId ) ) || + getTemplateLock( clientId ) || + getBlockEditingMode( clientId ) !== 'default' + ) { + return false; + } + + return true; + }, + [ clientId ] + ); return ( <> - { ( isSelected || isDragging ) && ( + { isVisible && ( ) } diff --git a/packages/block-editor/src/hooks/layout-child.js b/packages/block-editor/src/hooks/layout-child.js index 558d5e2cc626b..7a8e039c68969 100644 --- a/packages/block-editor/src/hooks/layout-child.js +++ b/packages/block-editor/src/hooks/layout-child.js @@ -175,9 +175,54 @@ function ChildLayoutControlsPure( { clientId, style, setAttributes } ) { isManualPlacement, } = parentLayout; - const rootClientId = useSelect( + if ( parentLayoutType !== 'grid' ) { + return null; + } + + return ( + + ); +} + +function GridTools( { + clientId, + style, + setAttributes, + allowSizingOnChildren, + isManualPlacement, + parentLayout, +} ) { + const { rootClientId, isVisible } = useSelect( ( select ) => { - return select( blockEditorStore ).getBlockRootClientId( clientId ); + const { + getBlockRootClientId, + getBlockEditingMode, + getTemplateLock, + } = select( blockEditorStore ); + + const _rootClientId = getBlockRootClientId( clientId ); + + if ( + getTemplateLock( _rootClientId ) || + getBlockEditingMode( _rootClientId ) !== 'default' + ) { + return { + rootClientId: _rootClientId, + isVisible: false, + }; + } + + return { + rootClientId: _rootClientId, + isVisible: true, + }; }, [ clientId ] ); @@ -185,7 +230,7 @@ function ChildLayoutControlsPure( { clientId, style, setAttributes } ) { // Use useState() instead of useRef() so that GridItemResizer updates when ref is set. const [ resizerBounds, setResizerBounds ] = useState(); - if ( parentLayoutType !== 'grid' ) { + if ( ! isVisible ) { return null; } diff --git a/packages/block-editor/src/hooks/use-zoom-out.js b/packages/block-editor/src/hooks/use-zoom-out.js index 2a1b43060c00a..23511487a54bf 100644 --- a/packages/block-editor/src/hooks/use-zoom-out.js +++ b/packages/block-editor/src/hooks/use-zoom-out.js @@ -9,39 +9,55 @@ import { useEffect, useRef } from '@wordpress/element'; */ import { store as blockEditorStore } from '../store'; import { unlock } from '../lock-unlock'; - /** - * A hook used to set the zoomed out view, invoking the hook sets the mode. + * A hook used to set the editor mode to zoomed out mode, invoking the hook sets the mode. * - * @param {boolean} zoomOut If we should zoom out or not. + * @param {boolean} zoomOut If we should enter into zoomOut mode or not */ export function useZoomOut( zoomOut = true ) { - const { setZoomLevel } = unlock( useDispatch( blockEditorStore ) ); - const { isZoomOut } = unlock( useSelect( blockEditorStore ) ); + const { __unstableSetEditorMode, setZoomLevel } = unlock( + useDispatch( blockEditorStore ) + ); + const { __unstableGetEditorMode } = unlock( useSelect( blockEditorStore ) ); - const originalIsZoomOutRef = useRef( null ); + const originalEditingModeRef = useRef( null ); + const mode = __unstableGetEditorMode(); useEffect( () => { // Only set this on mount so we know what to return to when we unmount. - if ( ! originalIsZoomOutRef.current ) { - originalIsZoomOutRef.current = isZoomOut(); + if ( ! originalEditingModeRef.current ) { + originalEditingModeRef.current = mode; } - // The effect opens the zoom-out view if we want it open and the canvas is not currently zoomed-out. - if ( zoomOut && isZoomOut() === false ) { + return () => { + // We need to use __unstableGetEditorMode() here and not `mode`, as mode may not update on unmount + if ( + __unstableGetEditorMode() === 'zoom-out' && + __unstableGetEditorMode() !== originalEditingModeRef.current + ) { + __unstableSetEditorMode( originalEditingModeRef.current ); + setZoomLevel( 100 ); + } + }; + }, [] ); + + // The effect opens the zoom-out view if we want it open and it's not currently in zoom-out mode. + useEffect( () => { + if ( zoomOut && mode !== 'zoom-out' ) { + __unstableSetEditorMode( 'zoom-out' ); setZoomLevel( 50 ); } else if ( ! zoomOut && - isZoomOut() && - originalIsZoomOutRef.current !== isZoomOut() + __unstableGetEditorMode() === 'zoom-out' && + originalEditingModeRef.current !== mode ) { - setZoomLevel( originalIsZoomOutRef.current ? 50 : 100 ); + __unstableSetEditorMode( originalEditingModeRef.current ); + setZoomLevel( 100 ); } - - return () => { - if ( isZoomOut() && isZoomOut() !== originalIsZoomOutRef.current ) { - setZoomLevel( originalIsZoomOutRef.current ? 50 : 100 ); - } - }; - }, [ isZoomOut, setZoomLevel, zoomOut ] ); + }, [ + __unstableGetEditorMode, + __unstableSetEditorMode, + zoomOut, + setZoomLevel, + ] ); // Mode is deliberately excluded from the dependencies so that the effect does not run when mode changes. } diff --git a/packages/block-editor/src/store/actions.js b/packages/block-editor/src/store/actions.js index ee11838395ec5..d92f8bc08569d 100644 --- a/packages/block-editor/src/store/actions.js +++ b/packages/block-editor/src/store/actions.js @@ -21,6 +21,7 @@ import { __, _n, sprintf } from '@wordpress/i18n'; import { store as noticesStore } from '@wordpress/notices'; import { create, insert, remove, toHTMLString } from '@wordpress/rich-text'; import deprecated from '@wordpress/deprecated'; +import { store as preferencesStore } from '@wordpress/preferences'; /** * Internal dependencies @@ -1668,7 +1669,7 @@ export const setNavigationMode = */ export const __unstableSetEditorMode = ( mode ) => - ( { dispatch, select } ) => { + ( { dispatch, select, registry } ) => { // When switching to zoom-out mode, we need to select the parent section if ( mode === 'zoom-out' ) { const firstSelectedClientId = select.getBlockSelectionStart(); @@ -1708,7 +1709,7 @@ export const __unstableSetEditorMode = } } - dispatch( { type: 'SET_EDITOR_MODE', mode } ); + registry.dispatch( preferencesStore ).set( 'core', 'editorTool', mode ); if ( mode === 'navigation' ) { speak( diff --git a/packages/block-editor/src/store/reducer.js b/packages/block-editor/src/store/reducer.js index f6445f8a3681c..1435e815813c4 100644 --- a/packages/block-editor/src/store/reducer.js +++ b/packages/block-editor/src/store/reducer.js @@ -1786,22 +1786,6 @@ export const blockListSettings = ( state = {}, action ) => { return state; }; -/** - * Reducer returning which mode is enabled. - * - * @param {string} state Current state. - * @param {Object} action Dispatched action. - * - * @return {string} Updated state. - */ -export function editorMode( state = 'edit', action ) { - if ( action.type === 'SET_EDITOR_MODE' ) { - return action.mode; - } - - return state; -} - /** * Reducer return an updated state representing the most recent block attribute * update. The state is structured as an object where the keys represent the @@ -2117,7 +2101,6 @@ const combinedReducers = combineReducers( { preferences, lastBlockAttributesChange, lastFocus, - editorMode, expandedBlock, highlightedBlock, lastBlockInserted, diff --git a/packages/block-editor/src/store/selectors.js b/packages/block-editor/src/store/selectors.js index 6cf6aae296141..a81d88de33466 100644 --- a/packages/block-editor/src/store/selectors.js +++ b/packages/block-editor/src/store/selectors.js @@ -16,6 +16,7 @@ import { symbol } from '@wordpress/icons'; import { create, remove, toHTMLString } from '@wordpress/rich-text'; import deprecated from '@wordpress/deprecated'; import { createSelector, createRegistrySelector } from '@wordpress/data'; +import { store as preferencesStore } from '@wordpress/preferences'; /** * Internal dependencies @@ -2691,7 +2692,7 @@ export function __experimentalGetLastBlockAttributeChanges( state ) { * @return {boolean} Is navigation mode enabled. */ export function isNavigationMode( state ) { - return state.editorMode === 'navigation'; + return __unstableGetEditorMode( state ) === 'navigation'; } /** @@ -2701,9 +2702,11 @@ export function isNavigationMode( state ) { * * @return {string} the editor mode. */ -export function __unstableGetEditorMode( state ) { - return state.editorMode; -} +export const __unstableGetEditorMode = createRegistrySelector( + ( select ) => () => { + return select( preferencesStore ).get( 'core', 'editorTool' ); + } +); /** * Returns whether block moving mode is enabled. diff --git a/packages/block-editor/src/store/test/private-selectors.js b/packages/block-editor/src/store/test/private-selectors.js index cbb75daa4baaa..73c14faa6fd06 100644 --- a/packages/block-editor/src/store/test/private-selectors.js +++ b/packages/block-editor/src/store/test/private-selectors.js @@ -11,7 +11,7 @@ import { isDragging, getBlockStyles, } from '../private-selectors'; -import { getBlockEditingMode } from '../selectors'; +import { getBlockEditingMode, __unstableGetEditorMode } from '../selectors'; describe( 'private selectors', () => { describe( 'isBlockInterfaceHidden', () => { @@ -125,11 +125,17 @@ describe( 'private selectors', () => { }; const hasContentRoleAttribute = jest.fn( () => false ); + const get = jest.fn( () => 'edit' ); getBlockEditingMode.registry = { select: jest.fn( () => ( { hasContentRoleAttribute, } ) ), }; + __unstableGetEditorMode.registry = { + select: jest.fn( () => ( { + get, + } ) ), + }; it( 'should return false when top level block is not disabled', () => { const state = { diff --git a/packages/block-editor/src/store/test/selectors.js b/packages/block-editor/src/store/test/selectors.js index a08c2e0dde150..00aa085f66709 100644 --- a/packages/block-editor/src/store/test/selectors.js +++ b/packages/block-editor/src/store/test/selectors.js @@ -9,6 +9,7 @@ import { import { RawHTML } from '@wordpress/element'; import { symbol } from '@wordpress/icons'; import { select, dispatch } from '@wordpress/data'; +import { store as preferencesStore } from '@wordpress/preferences'; /** * Internal dependencies @@ -4470,7 +4471,6 @@ describe( 'getBlockEditingMode', () => { const navigationModeStateWithRootSection = { ...baseState, - editorMode: 'navigation', settings: { [ sectionRootClientIdKey ]: 'ef45d5fd-5234-4fd5-ac4f-c3736c7f9337', // The group is the "main" container }, @@ -4480,12 +4480,18 @@ describe( 'getBlockEditingMode', () => { const fauxPrivateAPIs = {}; - lock( fauxPrivateAPIs, { hasContentRoleAttribute } ); + lock( fauxPrivateAPIs, { + hasContentRoleAttribute, + } ); getBlockEditingMode.registry = { select: jest.fn( () => fauxPrivateAPIs ), }; + afterEach( () => { + dispatch( preferencesStore ).set( 'core', 'editorTool', undefined ); + } ); + it( 'should return default by default', () => { expect( getBlockEditingMode( @@ -4610,6 +4616,7 @@ describe( 'getBlockEditingMode', () => { } ); it( 'in navigation mode, the root section container is default', () => { + dispatch( preferencesStore ).set( 'core', 'editorTool', 'navigation' ); expect( getBlockEditingMode( navigationModeStateWithRootSection, @@ -4619,6 +4626,7 @@ describe( 'getBlockEditingMode', () => { } ); it( 'in navigation mode, anything outside the section container is disabled', () => { + dispatch( preferencesStore ).set( 'core', 'editorTool', 'navigation' ); expect( getBlockEditingMode( navigationModeStateWithRootSection, @@ -4628,6 +4636,7 @@ describe( 'getBlockEditingMode', () => { } ); it( 'in navigation mode, sections are contentOnly', () => { + dispatch( preferencesStore ).set( 'core', 'editorTool', 'navigation' ); expect( getBlockEditingMode( navigationModeStateWithRootSection, @@ -4643,6 +4652,7 @@ describe( 'getBlockEditingMode', () => { } ); it( 'in navigation mode, blocks with content attributes within sections are contentOnly', () => { + dispatch( preferencesStore ).set( 'core', 'editorTool', 'navigation' ); hasContentRoleAttribute.mockReturnValueOnce( true ); expect( getBlockEditingMode( @@ -4661,6 +4671,7 @@ describe( 'getBlockEditingMode', () => { } ); it( 'in navigation mode, blocks without content attributes within sections are disabled', () => { + dispatch( preferencesStore ).set( 'core', 'editorTool', 'navigation' ); expect( getBlockEditingMode( navigationModeStateWithRootSection, diff --git a/packages/block-library/src/code/style.scss b/packages/block-library/src/code/style.scss index 670a4f7f1ef4c..ccc950d19b552 100644 --- a/packages/block-library/src/code/style.scss +++ b/packages/block-library/src/code/style.scss @@ -9,5 +9,10 @@ font-family: inherit; overflow-wrap: break-word; white-space: pre-wrap; + // Set direction and avoid inheriting alignment from a parent element. + /*!rtl:begin:ignore*/ + direction: ltr; + text-align: initial; + /*!rtl:end:ignore*/ } } diff --git a/packages/block-library/src/cover/editor.scss b/packages/block-library/src/cover/editor.scss index a72b928b55b97..b92c401311bee 100644 --- a/packages/block-library/src/cover/editor.scss +++ b/packages/block-library/src/cover/editor.scss @@ -42,6 +42,7 @@ // Shown while media is being uploaded .components-spinner { position: absolute; + z-index: z-index(".wp-block-cover__inner-container"); top: 50%; left: 50%; transform: translate(-50%, -50%); // Account for spinner dimensions diff --git a/packages/block-library/src/cover/style.scss b/packages/block-library/src/cover/style.scss index 4b2bee7a66597..41b3acf1833fc 100644 --- a/packages/block-library/src/cover/style.scss +++ b/packages/block-library/src/cover/style.scss @@ -95,8 +95,8 @@ } .wp-block-cover__inner-container { - position: relative; width: 100%; + z-index: z-index(".wp-block-cover__inner-container"); color: inherit; // Reset the fixed LTR direction at the root of the block in RTL languages. /*rtl:raw: direction: rtl; */ diff --git a/packages/block-library/src/query/edit/inspector-controls/index.js b/packages/block-library/src/query/edit/inspector-controls/index.js index 28a6113620fb7..b373e0933fe71 100644 --- a/packages/block-library/src/query/edit/inspector-controls/index.js +++ b/packages/block-library/src/query/edit/inspector-controls/index.js @@ -123,21 +123,18 @@ export default function QueryInspectorControls( props ) { const showInheritControl = isTemplate && isControlAllowed( allowedControls, 'inherit' ); const showPostTypeControl = - ( ! inherit && isControlAllowed( allowedControls, 'postType' ) ) || - ! isTemplate; + ! inherit && isControlAllowed( allowedControls, 'postType' ); const postTypeControlLabel = __( 'Post type' ); const postTypeControlHelp = __( 'Select the type of content to display: posts, pages, or custom post types.' ); const showColumnsControl = false; const showOrderControl = - ( ! inherit && isControlAllowed( allowedControls, 'order' ) ) || - ! isTemplate; + ! inherit && isControlAllowed( allowedControls, 'order' ); const showStickyControl = - ( ! inherit && - showSticky && - isControlAllowed( allowedControls, 'sticky' ) ) || - ( showSticky && ! isTemplate ); + ! inherit && + showSticky && + isControlAllowed( allowedControls, 'sticky' ); const showSettingsPanel = showInheritControl || showPostTypeControl || diff --git a/packages/components/CHANGELOG.md b/packages/components/CHANGELOG.md index 870f96308aa46..48113f874af3a 100644 --- a/packages/components/CHANGELOG.md +++ b/packages/components/CHANGELOG.md @@ -9,6 +9,7 @@ - `RangeControl`: do not tooltip contents to the DOM when not shown ([#65875](https://github.com/WordPress/gutenberg/pull/65875)). - `Tabs`: fix skipping indication animation glitch ([#65878](https://github.com/WordPress/gutenberg/pull/65878)). - `ToggleGroupControl`: Don't autoselect option on first group focus ([#65892](https://github.com/WordPress/gutenberg/pull/65892)). +- `Button`: fix `box-shadow` transition for secondary variation ([#66045](https://github.com/WordPress/gutenberg/pull/66045)). ### Deprecations @@ -16,6 +17,7 @@ ### Enhancements +- `Modal`: Modal dialog small improvement for elementShouldBeHidden ([#65941](https://github.com/WordPress/gutenberg/pull/65941)). - `Tabs`: revamped vertical orientation styles ([#65387](https://github.com/WordPress/gutenberg/pull/65387)). ## 28.9.0 (2024-10-03) diff --git a/packages/components/src/button/style.scss b/packages/components/src/button/style.scss index 444e4d397b3ef..61455a54e26f6 100644 --- a/packages/components/src/button/style.scss +++ b/packages/components/src/button/style.scss @@ -133,7 +133,7 @@ */ &.is-secondary { - box-shadow: inset 0 0 0 $border-width $components-color-accent; + box-shadow: inset 0 0 0 $border-width $components-color-accent, 0 0 0 currentColor; outline: 1px solid transparent; // Shown in high contrast mode. white-space: nowrap; color: $components-color-accent; @@ -148,6 +148,10 @@ &[aria-disabled="true"]:hover:not(:focus) { box-shadow: inset 0 0 0 $border-width $gray-300; } + + &:focus:not(:disabled) { + box-shadow: 0 0 0 currentColor inset, 0 0 0 var(--wp-admin-border-width-focus) $components-color-accent; + } } /** diff --git a/packages/components/src/modal/aria-helper.ts b/packages/components/src/modal/aria-helper.ts index 6a1d39c0a4ed3..bd11fb71253e1 100644 --- a/packages/components/src/modal/aria-helper.ts +++ b/packages/components/src/modal/aria-helper.ts @@ -47,6 +47,7 @@ export function elementShouldBeHidden( element: Element ) { const role = element.getAttribute( 'role' ); return ! ( element.tagName === 'SCRIPT' || + element.hasAttribute( 'hidden' ) || element.hasAttribute( 'aria-hidden' ) || element.hasAttribute( 'aria-live' ) || ( role && LIVE_REGION_ARIA_ROLES.has( role ) ) diff --git a/packages/dataviews/src/dataviews-layouts/list/index.tsx b/packages/dataviews/src/dataviews-layouts/list/index.tsx index fb46521fe217b..e737b18f5b02a 100644 --- a/packages/dataviews/src/dataviews-layouts/list/index.tsx +++ b/packages/dataviews/src/dataviews-layouts/list/index.tsx @@ -145,11 +145,9 @@ function ListItem< Item >( { const descriptionId = `${ idPrefix }-description`; const [ isHovered, setIsHovered ] = useState( false ); - const handleMouseEnter = () => { - setIsHovered( true ); - }; - const handleMouseLeave = () => { - setIsHovered( false ); + const handleHover: React.MouseEventHandler = ( { type } ) => { + const isHover = type === 'mouseenter'; + setIsHovered( isHover ); }; useEffect( () => { @@ -187,6 +185,45 @@ function ListItem< Item >( { ) : null; + const usedActions = eligibleActions?.length > 0 && ( + + { primaryAction && ( + + ) } +
+ + } + /> + } + placement="bottom-end" + > + + +
+
+ ); + return ( ( { 'is-selected': isSelected, 'is-hovered': isHovered, } ) } - onMouseEnter={ handleMouseEnter } - onMouseLeave={ handleMouseLeave } + onMouseEnter={ handleHover } + onMouseLeave={ handleHover } > - +
} - role="button" id={ generateItemWrapperCompositeId( idPrefix ) } aria-pressed={ isSelected } aria-labelledby={ labelId } aria-describedby={ descriptionId } className="dataviews-view-list__item" onClick={ () => onSelect( item ) } + /> +
+ +
+ { renderedMediaField } +
+ - -
- { renderedMediaField } -
- +
- - { renderedPrimaryField } - + { renderedPrimaryField } +
+ { usedActions } +
+
+ { visibleFields.map( ( field ) => (
- { visibleFields.map( ( field ) => ( -
- - { field.label } - - - - -
- ) ) } + + { field.label } + + + +
- - - -
- { eligibleActions?.length > 0 && ( - - { primaryAction && ( - - ) } -
- - } - /> - } - placement="bottom-end" - > - - + ) ) }
-
- ) } +
+
); diff --git a/packages/dataviews/src/dataviews-layouts/list/style.scss b/packages/dataviews/src/dataviews-layouts/list/style.scss index ea3236f6d75e1..9a3128c14b76a 100644 --- a/packages/dataviews/src/dataviews-layouts/list/style.scss +++ b/packages/dataviews/src/dataviews-layouts/list/style.scss @@ -7,63 +7,40 @@ ul.dataviews-view-list { li { margin: 0; - cursor: pointer; border-top: 1px solid $gray-100; .dataviews-view-list__item-wrapper { position: relative; - border-radius: $grid-unit-05; - - > * { - width: 100%; - } + padding: $grid-unit-20 $grid-unit-30; } .dataviews-view-list__item-actions { - position: absolute; - top: $grid-unit-20; - right: 0; - + flex: 0; + overflow: hidden; > div { height: $button-size-small; } .components-button { + position: relative; + z-index: 1; opacity: 0; } } - &:has(.dataviews-view-list__fields:empty) { - .dataviews-view-list__item-actions { - top: 50%; - transform: translateY(-50%); - } - } - - &.is-selected, - &.is-hovered, - &:focus-within { + &:where(.is-selected, .is-hovered, :focus-within) { .dataviews-view-list__item-actions { - background: #f8f8f8; - padding-left: $grid-unit-10; - margin-right: $grid-unit-30; - box-shadow: -12px 0 8px 0 #f8f8f8; + flex-basis: min-content; + overflow: unset; + margin-inline: $grid-unit-10 0; .components-button { opacity: 1; - position: static; } } } - &.is-selected { - .dataviews-view-list__item-actions { - background-color: rgb(247 248 255); - box-shadow: -12px 0 8px 0 rgb(247 248 255); - } - } - &.is-selected.is-selected { border-top: 1px solid rgba(var(--wp-admin-theme-color--rgb), 0.12); @@ -105,27 +82,38 @@ ul.dataviews-view-list { } .dataviews-view-list__item { - box-sizing: border-box; - padding: $grid-unit-20 $grid-unit-30; - width: 100%; + position: absolute; + z-index: 1; + inset: 0; scroll-margin: $grid-unit-10 0; + appearance: none; + border: none; + background: none; + padding: 0; + cursor: pointer; &:focus-visible { + outline: none; + &::before { position: absolute; content: ""; - top: var(--wp-admin-border-width-focus); - right: var(--wp-admin-border-width-focus); - bottom: var(--wp-admin-border-width-focus); - left: var(--wp-admin-border-width-focus); + inset: var(--wp-admin-border-width-focus); box-shadow: inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); border-radius: $radius-small; + // Windows High Contrast mode will show this outline, but not the box-shadow. + outline: 2px solid transparent; } } - .dataviews-view-list__primary-field { - min-height: $grid-unit-30; - line-height: $grid-unit-30; - overflow: hidden; + } + .dataviews-view-list__primary-field { + flex: 1; + min-height: $grid-unit-30; + line-height: $grid-unit-30; + overflow: hidden; + // The field should be in front of the main button in case it has a link/button. + &:has(a, button) { + z-index: 1; } } @@ -164,6 +152,7 @@ ul.dataviews-view-list { .dataviews-view-list__field-wrapper { min-height: $grid-unit-05 * 13; // Ensures title is centrally aligned when all fields are hidden + flex-grow: 1; } .dataviews-view-list__fields { diff --git a/packages/e2e-test-utils/src/inserter.js b/packages/e2e-test-utils/src/inserter.js index 5beab3c6205b6..90ea39b49f00d 100644 --- a/packages/e2e-test-utils/src/inserter.js +++ b/packages/e2e-test-utils/src/inserter.js @@ -49,12 +49,12 @@ async function isGlobalInserterOpen() { return !! document.querySelector( '.edit-post-header [aria-label="Add block"].is-pressed,' + '.edit-site-header-edit-mode [aria-label="Add block"].is-pressed,' + - '.edit-post-header [aria-label="Toggle block inserter"].is-pressed,' + - '.edit-site-header [aria-label="Toggle block inserter"].is-pressed,' + - '.edit-widgets-header [aria-label="Toggle block inserter"].is-pressed,' + + '.edit-post-header [aria-label="Block Inserter"].is-pressed,' + + '.edit-site-header [aria-label="Block Inserter"].is-pressed,' + + '.edit-widgets-header [aria-label="Block Inserter"].is-pressed,' + '.edit-widgets-header [aria-label="Add block"].is-pressed,' + '.edit-site-header-edit-mode__inserter-toggle.is-pressed,' + - '.editor-header [aria-label="Toggle block inserter"].is-pressed' + '.editor-header [aria-label="Block Inserter"].is-pressed' ); } ); } @@ -68,10 +68,10 @@ export async function toggleGlobalBlockInserter() { '.editor-document-tools__inserter-toggle,' + '.edit-post-header [aria-label="Add block"],' + '.edit-site-header [aria-label="Add block"],' + - '.edit-post-header [aria-label="Toggle block inserter"],' + - '.edit-site-header [aria-label="Toggle block inserter"],' + + '.edit-post-header [aria-label="Block Inserter"],' + + '.edit-site-header [aria-label="Block Inserter"],' + '.edit-widgets-header [aria-label="Add block"],' + - '.edit-widgets-header [aria-label="Toggle block inserter"],' + + '.edit-widgets-header [aria-label="Block Inserter"],' + '.edit-site-header-edit-mode__inserter-toggle' ); } diff --git a/packages/edit-site/src/store/private-actions.js b/packages/edit-site/src/store/private-actions.js index 37164690ed7fc..94bcc490b6fd6 100644 --- a/packages/edit-site/src/store/private-actions.js +++ b/packages/edit-site/src/store/private-actions.js @@ -19,9 +19,6 @@ export const setCanvasMode = registry.batch( () => { registry.dispatch( blockEditorStore ).clearSelectedBlock(); registry.dispatch( editorStore ).setDeviceType( 'Desktop' ); - registry - .dispatch( blockEditorStore ) - .__unstableSetEditorMode( 'edit' ); const isPublishSidebarOpened = registry .select( editorStore ) .isPublishSidebarOpened(); diff --git a/packages/edit-widgets/src/components/header/document-tools/index.js b/packages/edit-widgets/src/components/header/document-tools/index.js index a0d69cde376cf..567a5e1240747 100644 --- a/packages/edit-widgets/src/components/header/document-tools/index.js +++ b/packages/edit-widgets/src/components/header/document-tools/index.js @@ -72,7 +72,7 @@ function DocumentTools() { /* translators: button label text should, if possible, be under 16 characters. */ label={ _x( - 'Toggle block inserter', + 'Block Inserter', 'Generic label for block inserter button' ) } size="compact" diff --git a/packages/edit-widgets/src/components/secondary-sidebar/inserter-sidebar.js b/packages/edit-widgets/src/components/secondary-sidebar/inserter-sidebar.js index 156a15e2f460c..4b26dd306ea0a 100644 --- a/packages/edit-widgets/src/components/secondary-sidebar/inserter-sidebar.js +++ b/packages/edit-widgets/src/components/secondary-sidebar/inserter-sidebar.js @@ -47,7 +47,7 @@ export default function InserterSidebar() { __next40pxDefaultSize icon={ close } onClick={ closeInserter } - label={ __( 'Close block inserter' ) } + label={ __( 'Close Block Inserter' ) } />
diff --git a/packages/editor/src/components/document-tools/index.js b/packages/editor/src/components/document-tools/index.js index 6a8c20c8d7055..146945f7343bf 100644 --- a/packages/editor/src/components/document-tools/index.js +++ b/packages/editor/src/components/document-tools/index.js @@ -96,7 +96,7 @@ function DocumentTools( { className, disableBlockTools = false } ) { /* translators: button label text should, if possible, be under 16 characters. */ const longLabel = _x( - 'Toggle block inserter', + 'Block Inserter', 'Generic label for block inserter button' ); const shortLabel = ! isInserterOpened ? __( 'Add' ) : __( 'Close' ); diff --git a/packages/editor/src/components/header/style.scss b/packages/editor/src/components/header/style.scss index 8712121fff3ea..4259ef4b8a208 100644 --- a/packages/editor/src/components/header/style.scss +++ b/packages/editor/src/components/header/style.scss @@ -130,6 +130,7 @@ // ... and display labels. &::after { content: attr(aria-label); + white-space: nowrap; } &[aria-disabled="true"] { background-color: transparent; diff --git a/packages/editor/src/components/post-url/index.js b/packages/editor/src/components/post-url/index.js index 8d072fa2eeb5d..c7dc5712dcac4 100644 --- a/packages/editor/src/components/post-url/index.js +++ b/packages/editor/src/components/post-url/index.js @@ -17,7 +17,7 @@ import { import { store as noticesStore } from '@wordpress/notices'; import { copySmall } from '@wordpress/icons'; import { store as coreStore } from '@wordpress/core-data'; -import { useCopyToClipboard } from '@wordpress/compose'; +import { useCopyToClipboard, useInstanceId } from '@wordpress/compose'; /** * Internal dependencies @@ -70,25 +70,29 @@ export default function PostURL( { onClose } ) { const { createNotice } = useDispatch( noticesStore ); const [ forceEmptyField, setForceEmptyField ] = useState( false ); const copyButtonRef = useCopyToClipboard( permalink, () => { - createNotice( 'info', __( 'Copied URL to clipboard.' ), { + createNotice( 'info', __( 'Copied Permalink to clipboard.' ), { isDismissible: true, type: 'snackbar', } ); } ); + const postUrlSlugDescriptionId = + 'editor-post-url__slug-descriotion-' + useInstanceId( PostURL ); + return (
{ isEditable && ( -
+

{ createInterpolateElement( __( - 'Customize the last part of the URL. Learn more.' + 'Customize the last part of the Permalink. Learn more.' ), { + span: , a: ( +

) }
{ isEditable && ( - - / - - } - suffix={ - - ); } + +function FrontPageLink() { + const { postLink } = useSelect( ( select ) => { + const { getCurrentPost } = select( editorStore ); + return { + postLink: getCurrentPost()?.link, + }; + }, [] ); + + return ( + + { postLink } + + ); +} diff --git a/packages/editor/src/components/post-url/style.scss b/packages/editor/src/components/post-url/style.scss index c815f89682cb2..f8a70f5fdf760 100644 --- a/packages/editor/src/components/post-url/style.scss +++ b/packages/editor/src/components/post-url/style.scss @@ -9,14 +9,19 @@ } /* rtl:begin:ignore */ -.editor-post-url__link { +.editor-post-url__link, +.editor-post-url__front-page-link { direction: ltr; word-break: break-word; - margin-top: $grid-unit-05; - color: $gray-700; } /* rtl:end:ignore */ +.editor-post-url__front-page-link { + // Match padding on tertiary buttons for alignment. + padding: $grid-unit-15 * 0.5 0 $grid-unit-15 * 0.5 $grid-unit-15; +} + + .editor-post-url__link-slug { font-weight: 600; } @@ -30,3 +35,16 @@ .editor-post-url__panel-toggle { word-break: break-word; } + +.editor-post-url__intro { + margin: 0; +} + +.editor-post-url__permalink { + margin-top: $grid-unit-10; + margin-bottom: 0; + + &-visual-label { + display: block; + } +} diff --git a/packages/reusable-blocks/src/store/test/actions.js b/packages/reusable-blocks/src/store/test/actions.js index b2feae1195ee1..debd656868389 100644 --- a/packages/reusable-blocks/src/store/test/actions.js +++ b/packages/reusable-blocks/src/store/test/actions.js @@ -12,6 +12,7 @@ import { import { store as coreStore } from '@wordpress/core-data'; import apiFetch from '@wordpress/api-fetch'; +import { store as preferencesStore } from '@wordpress/preferences'; /** * Internal dependencies @@ -31,6 +32,7 @@ function createRegistryWithStores() { registry.register( blockEditorStore ); registry.register( reusableBlocksStore ); registry.register( blocksStore ); + registry.register( preferencesStore ); // Register entity here instead of mocking API handlers for loadPostTypeEntities() registry.dispatch( coreStore ).addEntities( [ diff --git a/test/e2e/specs/editor/blocks/columns.spec.js b/test/e2e/specs/editor/blocks/columns.spec.js index e322a52eeba10..eea6e321aacb1 100644 --- a/test/e2e/specs/editor/blocks/columns.spec.js +++ b/test/e2e/specs/editor/blocks/columns.spec.js @@ -33,10 +33,8 @@ test.describe( 'Columns', () => { .first() .click(); - // Toggle Block inserter - await page - .locator( 'role=button[name="Toggle block inserter"i]' ) - .click(); + // Block Inserter + await page.locator( 'role=button[name="Block Inserter"i]' ).click(); // Verify Column const inserterOptions = page.locator( diff --git a/test/e2e/specs/editor/blocks/group.spec.js b/test/e2e/specs/editor/blocks/group.spec.js index 871974c1f44dd..0d815872c0bbb 100644 --- a/test/e2e/specs/editor/blocks/group.spec.js +++ b/test/e2e/specs/editor/blocks/group.spec.js @@ -14,7 +14,7 @@ test.describe( 'Group', () => { } ) => { // Search for the group block and insert it. const inserterButton = page.locator( - 'role=button[name="Toggle block inserter"i]' + 'role=button[name="Block Inserter"i]' ); await inserterButton.click(); diff --git a/test/e2e/specs/editor/blocks/image.spec.js b/test/e2e/specs/editor/blocks/image.spec.js index 43527b48fbf70..6110a125ff6f7 100644 --- a/test/e2e/specs/editor/blocks/image.spec.js +++ b/test/e2e/specs/editor/blocks/image.spec.js @@ -437,7 +437,8 @@ test.describe( 'Image', () => { async function openMediaTab() { const blockInserter = page.getByRole( 'button', { - name: 'Toggle block inserter', + name: 'Block Inserter', + exact: true, } ); const isClosed = ( await blockInserter.getAttribute( 'aria-pressed' ) ) === diff --git a/test/e2e/specs/editor/plugins/allowed-blocks.spec.js b/test/e2e/specs/editor/plugins/allowed-blocks.spec.js index 6c8f4ead41c6f..ed7490afe84fe 100644 --- a/test/e2e/specs/editor/plugins/allowed-blocks.spec.js +++ b/test/e2e/specs/editor/plugins/allowed-blocks.spec.js @@ -21,7 +21,7 @@ test.describe( 'Allowed Blocks Filter', () => { } ) => { // The paragraph block is available. await page - .getByRole( 'button', { name: 'Toggle block inserter' } ) + .getByRole( 'button', { name: 'Block Inserter', exact: true } ) .click(); const searchbox = page diff --git a/test/e2e/specs/editor/plugins/block-directory.spec.js b/test/e2e/specs/editor/plugins/block-directory.spec.js index f9bf1f8515186..2fa4ee33e6c1a 100644 --- a/test/e2e/specs/editor/plugins/block-directory.spec.js +++ b/test/e2e/specs/editor/plugins/block-directory.spec.js @@ -122,7 +122,7 @@ test.describe( 'Block Directory', () => { await page .getByRole( 'toolbar', { name: 'Document tools' } ) - .getByRole( 'button', { name: 'Toggle block inserter' } ) + .getByRole( 'button', { name: 'Block Inserter', exact: true } ) .click(); const blockLibrary = page.getByRole( 'region', { @@ -209,7 +209,7 @@ test.describe( 'Block Directory', () => { await page .getByRole( 'toolbar', { name: 'Document tools' } ) - .getByRole( 'button', { name: 'Toggle block inserter' } ) + .getByRole( 'button', { name: 'Block Inserter', exact: true } ) .click(); const blockLibrary = page.getByRole( 'region', { diff --git a/test/e2e/specs/editor/plugins/block-icons.spec.js b/test/e2e/specs/editor/plugins/block-icons.spec.js index 0418f4200afc0..3a00b41b9e71e 100644 --- a/test/e2e/specs/editor/plugins/block-icons.spec.js +++ b/test/e2e/specs/editor/plugins/block-icons.spec.js @@ -26,7 +26,7 @@ test.describe( 'Block Icons', () => { test( 'Block with svg icon', async ( { editor, page } ) => { await page .getByRole( 'toolbar', { name: 'Document tools' } ) - .getByRole( 'button', { name: 'Toggle block inserter' } ) + .getByRole( 'button', { name: 'Block Inserter', exact: true } ) .click(); const blockLibrary = page.getByRole( 'region', { @@ -60,7 +60,7 @@ test.describe( 'Block Icons', () => { test( 'Block with dash icon', async ( { editor, page } ) => { await page .getByRole( 'toolbar', { name: 'Document tools' } ) - .getByRole( 'button', { name: 'Toggle block inserter' } ) + .getByRole( 'button', { name: 'Block Inserter', exact: true } ) .click(); const blockLibrary = page.getByRole( 'region', { @@ -100,7 +100,7 @@ test.describe( 'Block Icons', () => { test( 'Block with function icon', async ( { editor, page } ) => { await page .getByRole( 'toolbar', { name: 'Document tools' } ) - .getByRole( 'button', { name: 'Toggle block inserter' } ) + .getByRole( 'button', { name: 'Block Inserter', exact: true } ) .click(); const blockLibrary = page.getByRole( 'region', { @@ -137,7 +137,7 @@ test.describe( 'Block Icons', () => { } ) => { await page .getByRole( 'toolbar', { name: 'Document tools' } ) - .getByRole( 'button', { name: 'Toggle block inserter' } ) + .getByRole( 'button', { name: 'Block Inserter', exact: true } ) .click(); const blockLibrary = page.getByRole( 'region', { @@ -185,7 +185,7 @@ test.describe( 'Block Icons', () => { } ) => { await page .getByRole( 'toolbar', { name: 'Document tools' } ) - .getByRole( 'button', { name: 'Toggle block inserter' } ) + .getByRole( 'button', { name: 'Block Inserter', exact: true } ) .click(); const blockLibrary = page.getByRole( 'region', { diff --git a/test/e2e/specs/editor/plugins/block-variations.spec.js b/test/e2e/specs/editor/plugins/block-variations.spec.js index 653680b48e1e6..3f71d2b57d9fd 100644 --- a/test/e2e/specs/editor/plugins/block-variations.spec.js +++ b/test/e2e/specs/editor/plugins/block-variations.spec.js @@ -22,7 +22,7 @@ test.describe( 'Block variations', () => { page, } ) => { await page - .getByRole( 'button', { name: 'Toggle block inserter' } ) + .getByRole( 'button', { name: 'Block Inserter', exact: true } ) .click(); await page @@ -63,7 +63,7 @@ test.describe( 'Block variations', () => { page, } ) => { await page - .getByRole( 'button', { name: 'Toggle block inserter' } ) + .getByRole( 'button', { name: 'Block Inserter', exact: true } ) .click(); await page diff --git a/test/e2e/specs/editor/plugins/child-blocks.spec.js b/test/e2e/specs/editor/plugins/child-blocks.spec.js index 0cd043c6a4610..765b4040a4b97 100644 --- a/test/e2e/specs/editor/plugins/child-blocks.spec.js +++ b/test/e2e/specs/editor/plugins/child-blocks.spec.js @@ -19,7 +19,7 @@ test.describe( 'Child Blocks', () => { test( 'are hidden from the global block inserter', async ( { page } ) => { const blockInserter = page .getByRole( 'toolbar', { name: 'Document tools' } ) - .getByRole( 'button', { name: 'Toggle block inserter' } ); + .getByRole( 'button', { name: 'Block Inserter', exact: true } ); const blockLibrary = page.getByRole( 'region', { name: 'Block Library', } ); @@ -47,7 +47,7 @@ test.describe( 'Child Blocks', () => { const blockInserter = page .getByRole( 'toolbar', { name: 'Document tools' } ) - .getByRole( 'button', { name: 'Toggle block inserter' } ); + .getByRole( 'button', { name: 'Block Inserter', exact: true } ); const blockLibrary = page .getByRole( 'region', { name: 'Block Library', @@ -85,7 +85,7 @@ test.describe( 'Child Blocks', () => { const blockInserter = page .getByRole( 'toolbar', { name: 'Document tools' } ) - .getByRole( 'button', { name: 'Toggle block inserter' } ); + .getByRole( 'button', { name: 'Block Inserter', exact: true } ); const blockLibrary = page .getByRole( 'region', { name: 'Block Library', diff --git a/test/e2e/specs/editor/plugins/inner-blocks-allowed-blocks.spec.js b/test/e2e/specs/editor/plugins/inner-blocks-allowed-blocks.spec.js index d2dc521f0196b..4ee6d7a0fc4fe 100644 --- a/test/e2e/specs/editor/plugins/inner-blocks-allowed-blocks.spec.js +++ b/test/e2e/specs/editor/plugins/inner-blocks-allowed-blocks.spec.js @@ -45,7 +45,7 @@ test.describe( 'Allowed Blocks Setting on InnerBlocks', () => { const blockInserter = page .getByRole( 'toolbar', { name: 'Document tools' } ) - .getByRole( 'button', { name: 'Toggle block inserter' } ); + .getByRole( 'button', { name: 'Block Inserter', exact: true } ); const blockLibrary = page .getByRole( 'region', { name: 'Block Library', @@ -92,7 +92,7 @@ test.describe( 'Allowed Blocks Setting on InnerBlocks', () => { const blockInserter = page .getByRole( 'toolbar', { name: 'Document tools' } ) - .getByRole( 'button', { name: 'Toggle block inserter' } ); + .getByRole( 'button', { name: 'Block Inserter', exact: true } ); const blockLibrary = page .getByRole( 'region', { name: 'Block Library', diff --git a/test/e2e/specs/editor/plugins/pattern-recursion.spec.js b/test/e2e/specs/editor/plugins/pattern-recursion.spec.js index 9a8292271be8e..c688f3580c370 100644 --- a/test/e2e/specs/editor/plugins/pattern-recursion.spec.js +++ b/test/e2e/specs/editor/plugins/pattern-recursion.spec.js @@ -59,9 +59,9 @@ test.describe( 'Preventing Pattern Recursion (server)', () => { page, editor, } ) => { - // Click the Toggle block inserter button + // Click the Block Inserter button await page - .getByRole( 'button', { name: 'Toggle block inserter' } ) + .getByRole( 'button', { name: 'Block Inserter', exact: true } ) .click(); // Click the Patterns tab await page.getByRole( 'tab', { name: 'Patterns' } ).click(); diff --git a/test/e2e/specs/editor/plugins/post-type-locking.spec.js b/test/e2e/specs/editor/plugins/post-type-locking.spec.js index af6256d05e02e..ff02d18c51464 100644 --- a/test/e2e/specs/editor/plugins/post-type-locking.spec.js +++ b/test/e2e/specs/editor/plugins/post-type-locking.spec.js @@ -208,7 +208,10 @@ test.describe( 'Post-type locking', () => { await expect( page .getByRole( 'toolbar', { name: 'Document tools' } ) - .getByRole( 'button', { name: 'Toggle block inserter' } ) + .getByRole( 'button', { + name: 'Block Inserter', + exact: true, + } ) ).toBeEnabled(); await editor.insertBlock( { name: 'core/list' } ); diff --git a/test/e2e/specs/editor/plugins/register-block-type-hooks.spec.js b/test/e2e/specs/editor/plugins/register-block-type-hooks.spec.js index 2ec62ffd056d3..a7e6f970179a4 100644 --- a/test/e2e/specs/editor/plugins/register-block-type-hooks.spec.js +++ b/test/e2e/specs/editor/plugins/register-block-type-hooks.spec.js @@ -18,7 +18,7 @@ test.describe( 'Register block type hooks', () => { } ); test( 'has a custom category for Paragraph block', async ( { page } ) => { - await page.click( 'role=button[name="Toggle block inserter"i]' ); + await page.click( 'role=button[name="Block Inserter"i]' ); expect( page.locator( diff --git a/test/e2e/specs/editor/various/a11y.spec.js b/test/e2e/specs/editor/various/a11y.spec.js index 8f63b57fda657..f116476989a13 100644 --- a/test/e2e/specs/editor/various/a11y.spec.js +++ b/test/e2e/specs/editor/various/a11y.spec.js @@ -40,10 +40,10 @@ test.describe( 'a11y (@firefox, @webkit)', () => { // This test assumes the Editor is not in Fullscreen mode. Check the // first tabbable element within the 'Editor top bar' region is the - // 'Toggle block inserter' button. + // 'Block Inserter' button. await pageUtils.pressKeys( 'Tab' ); await expect( - page.locator( 'role=button[name=/Toggle block inserter/i]' ) + page.locator( 'role=button[name=/Block Inserter/i]' ) ).toBeFocused(); } ); diff --git a/test/e2e/specs/editor/various/adding-patterns.spec.js b/test/e2e/specs/editor/various/adding-patterns.spec.js index b634798b45540..3226965b18d70 100644 --- a/test/e2e/specs/editor/various/adding-patterns.spec.js +++ b/test/e2e/specs/editor/various/adding-patterns.spec.js @@ -9,7 +9,7 @@ test.describe( 'adding patterns', () => { } ); test( 'should insert a block pattern', async ( { page, editor } ) => { - await page.getByLabel( 'Toggle block inserter' ).click(); + await page.getByLabel( 'Block Inserter' ).click(); await page.getByRole( 'tab', { name: 'Patterns' } ).click(); await page.fill( diff --git a/test/e2e/specs/editor/various/allowed-patterns.spec.js b/test/e2e/specs/editor/various/allowed-patterns.spec.js index a99b1f5c29106..01ca5ba0480c3 100644 --- a/test/e2e/specs/editor/various/allowed-patterns.spec.js +++ b/test/e2e/specs/editor/various/allowed-patterns.spec.js @@ -18,7 +18,7 @@ test.describe( 'Allowed Patterns', () => { await admin.createNewPost(); await page .getByRole( 'toolbar', { name: 'Document tools' } ) - .getByRole( 'button', { name: 'Toggle block inserter' } ) + .getByRole( 'button', { name: 'Block Inserter', exact: true } ) .click(); await page @@ -61,7 +61,7 @@ test.describe( 'Allowed Patterns', () => { await admin.createNewPost(); await page .getByRole( 'toolbar', { name: 'Document tools' } ) - .getByRole( 'button', { name: 'Toggle block inserter' } ) + .getByRole( 'button', { name: 'Block Inserter', exact: true } ) .click(); await page diff --git a/test/e2e/specs/editor/various/block-visibility.spec.js b/test/e2e/specs/editor/various/block-visibility.spec.js index 814276af6e25f..6e4163f4ed583 100644 --- a/test/e2e/specs/editor/various/block-visibility.spec.js +++ b/test/e2e/specs/editor/various/block-visibility.spec.js @@ -43,7 +43,7 @@ test.describe( 'Block Visibility', () => { .getByRole( 'button', { name: 'Close' } ) .click(); await page - .getByRole( 'button', { name: 'Toggle block inserter' } ) + .getByRole( 'button', { name: 'Block Inserter', exact: true } ) .click(); await page .getByRole( 'region', { name: 'Block Library' } ) @@ -60,7 +60,7 @@ test.describe( 'Block Visibility', () => { ).toBeHidden(); await page - .getByRole( 'button', { name: 'Toggle block inserter' } ) + .getByRole( 'button', { name: 'Block Inserter', exact: true } ) .click(); // Show heading block again. @@ -84,7 +84,7 @@ test.describe( 'Block Visibility', () => { .getByRole( 'button', { name: 'Close' } ) .click(); await page - .getByRole( 'button', { name: 'Toggle block inserter' } ) + .getByRole( 'button', { name: 'Block Inserter', exact: true } ) .click(); await page .getByRole( 'region', { name: 'Block Library' } ) @@ -118,7 +118,7 @@ test.describe( 'Block Visibility', () => { .getByRole( 'button', { name: 'Close' } ) .click(); await page - .getByRole( 'button', { name: 'Toggle block inserter' } ) + .getByRole( 'button', { name: 'Block Inserter', exact: true } ) .click(); await expect( @@ -129,7 +129,7 @@ test.describe( 'Block Visibility', () => { ).toBeHidden(); await page - .getByRole( 'button', { name: 'Toggle block inserter' } ) + .getByRole( 'button', { name: 'Block Inserter', exact: true } ) .click(); // Show Media category blocks again. @@ -153,7 +153,7 @@ test.describe( 'Block Visibility', () => { .getByRole( 'button', { name: 'Close' } ) .click(); await page - .getByRole( 'button', { name: 'Toggle block inserter' } ) + .getByRole( 'button', { name: 'Block Inserter', exact: true } ) .click(); await expect( diff --git a/test/e2e/specs/editor/various/editor-modes.spec.js b/test/e2e/specs/editor/various/editor-modes.spec.js index 95c409f0589e3..4e856e6214ca8 100644 --- a/test/e2e/specs/editor/various/editor-modes.spec.js +++ b/test/e2e/specs/editor/various/editor-modes.spec.js @@ -115,7 +115,7 @@ test.describe( 'Editing modes (visual/HTML)', () => { await expect( page .getByRole( 'toolbar', { name: 'Document tools' } ) - .getByRole( 'button', { name: 'Toggle block inserter' } ) + .getByRole( 'button', { name: 'Block Inserter', exact: true } ) ).toBeDisabled(); // Go back to the visual editor. diff --git a/test/e2e/specs/editor/various/inserting-blocks.spec.js b/test/e2e/specs/editor/various/inserting-blocks.spec.js index 83b919585a695..29b59b727acfe 100644 --- a/test/e2e/specs/editor/various/inserting-blocks.spec.js +++ b/test/e2e/specs/editor/various/inserting-blocks.spec.js @@ -72,7 +72,7 @@ test.describe( 'Inserting blocks (@firefox, @webkit)', () => { ); await page.click( - 'role=region[name="Editor top bar"i] >> role=button[name="Toggle block inserter"i]' + 'role=region[name="Editor top bar"i] >> role=button[name="Block Inserter"i]' ); await page.fill( @@ -135,7 +135,7 @@ test.describe( 'Inserting blocks (@firefox, @webkit)', () => { ); await page.click( - 'role=region[name="Editor top bar"i] >> role=button[name="Toggle block inserter"i]' + 'role=region[name="Editor top bar"i] >> role=button[name="Block Inserter"i]' ); await page.fill( @@ -191,7 +191,7 @@ test.describe( 'Inserting blocks (@firefox, @webkit)', () => { ); await page.click( - 'role=region[name="Editor top bar"i] >> role=button[name="Toggle block inserter"i]' + 'role=region[name="Editor top bar"i] >> role=button[name="Block Inserter"i]' ); const PATTERN_NAME = 'Standard'; @@ -283,7 +283,7 @@ test.describe( 'Inserting blocks (@firefox, @webkit)', () => { // Insert a synced pattern. await page.click( - 'role=region[name="Editor top bar"i] >> role=button[name="Toggle block inserter"i]' + 'role=region[name="Editor top bar"i] >> role=button[name="Block Inserter"i]' ); await page.fill( 'role=region[name="Block Library"i] >> role=searchbox[name="Search"i]', @@ -347,7 +347,7 @@ test.describe( 'Inserting blocks (@firefox, @webkit)', () => { ); await page.click( - 'role=region[name="Editor top bar"i] >> role=button[name="Toggle block inserter"i]' + 'role=region[name="Editor top bar"i] >> role=button[name="Block Inserter"i]' ); const PATTERN_NAME = 'Standard'; @@ -389,7 +389,8 @@ test.describe( 'Inserting blocks (@firefox, @webkit)', () => { await admin.createNewPost(); const inserterButton = page.getByRole( 'button', { - name: 'Toggle block inserter', + name: 'Block Inserter', + exact: true, } ); const blockLibrary = page.getByRole( 'region', { name: 'Block Library', @@ -503,7 +504,7 @@ test.describe( 'Inserting blocks (@firefox, @webkit)', () => { await editor.selectBlocks( paragraphBlock ); await page .getByRole( 'toolbar', { name: 'Document tools' } ) - .getByRole( 'button', { name: 'Toggle block inserter' } ) + .getByRole( 'button', { name: 'Block Inserter', exact: true } ) .click(); await page .getByRole( 'listbox', { name: 'Text' } ) @@ -624,7 +625,7 @@ test.describe( 'Inserting blocks (@firefox, @webkit)', () => { await admin.createNewPost(); await page .getByRole( 'toolbar', { name: 'Document tools' } ) - .getByRole( 'button', { name: 'Toggle block inserter' } ) + .getByRole( 'button', { name: 'Block Inserter', exact: true } ) .click(); await page.getByRole( 'option', { name: 'More', exact: true } ).click(); @@ -646,7 +647,7 @@ test.describe( 'Inserting blocks (@firefox, @webkit)', () => { await admin.createNewPost(); await page .getByRole( 'toolbar', { name: 'Document tools' } ) - .getByRole( 'button', { name: 'Toggle block inserter' } ) + .getByRole( 'button', { name: 'Block Inserter', exact: true } ) .click(); await page .getByRole( 'listbox', { name: 'Text' } ) @@ -674,7 +675,7 @@ test.describe( 'Inserting blocks (@firefox, @webkit)', () => { await page .getByRole( 'toolbar', { name: 'Document tools' } ) - .getByRole( 'button', { name: 'Toggle block inserter' } ) + .getByRole( 'button', { name: 'Block Inserter', exact: true } ) .click(); await page .getByRole( 'listbox', { name: 'Media' } ) @@ -726,7 +727,7 @@ test.describe( 'insert media from inserter', () => { } ) => { await admin.createNewPost(); - await page.getByLabel( 'Toggle block inserter' ).click(); + await page.getByLabel( 'Block Inserter' ).click(); await page.getByRole( 'tab', { name: 'Media' } ).click(); await page.getByRole( 'tab', { name: 'Images' } ).click(); await page.getByLabel( uploadedMedia.title.raw ).click(); diff --git a/test/e2e/specs/editor/various/parsing-patterns.spec.js b/test/e2e/specs/editor/various/parsing-patterns.spec.js index 62c8ba2de2410..d8edc544ffa03 100644 --- a/test/e2e/specs/editor/various/parsing-patterns.spec.js +++ b/test/e2e/specs/editor/various/parsing-patterns.spec.js @@ -15,7 +15,7 @@ test.describe( 'Parsing patterns', () => { innerBlocks: [ { name: 'core/button', attributes: { text: 'a' } } ], } ); await page.keyboard.press( 'ArrowDown' ); - await page.getByLabel( 'Toggle block inserter' ).click(); + await page.getByLabel( 'Block Inserter' ).click(); await page.getByRole( 'tab', { name: 'Patterns' } ).click(); await page.evaluate( () => { @@ -36,6 +36,14 @@ test.describe( 'Parsing patterns', () => { ], } ); } ); + + // Exit zoom out mode and select the inner buttons block to ensure + // the correct insertion point is selected. + await page.getByRole( 'button', { name: 'Zoom Out' } ).click(); + await editor.selectBlocks( + editor.canvas.locator( 'role=document[name="Block: Button"i]' ) + ); + await page.fill( 'role=region[name="Block Library"i] >> role=searchbox[name="Search"i]', 'whitespace' @@ -43,7 +51,7 @@ test.describe( 'Parsing patterns', () => { await page .locator( 'role=option[name="Pattern with top-level whitespace"i]' ) .click(); - expect( await editor.getBlocks() ).toMatchObject( [ + await expect.poll( editor.getBlocks ).toMatchObject( [ { name: 'core/buttons', innerBlocks: [ diff --git a/test/e2e/specs/editor/various/patterns.spec.js b/test/e2e/specs/editor/various/patterns.spec.js index 7204f2bace51a..00a68a9f08ea5 100644 --- a/test/e2e/specs/editor/various/patterns.spec.js +++ b/test/e2e/specs/editor/various/patterns.spec.js @@ -63,7 +63,7 @@ test.describe( 'Unsynced pattern', () => { // Check that the new pattern is available in the inserter and that it gets inserted as // a plain paragraph block. - await page.getByLabel( 'Toggle block inserter' ).click(); + await page.getByLabel( 'Block Inserter' ).click(); await page .getByRole( 'tab', { name: 'Patterns', @@ -166,7 +166,7 @@ test.describe( 'Synced pattern', () => { ).toBe( true ); // Check that the new pattern is available in the inserter. - await page.getByLabel( 'Toggle block inserter' ).click(); + await page.getByLabel( 'Block Inserter' ).click(); await page .getByRole( 'tab', { name: 'Patterns', @@ -496,7 +496,7 @@ test.describe( 'Synced pattern', () => { } ); await page - .getByRole( 'button', { name: 'Toggle block inserter' } ) + .getByRole( 'button', { name: 'Block Inserter', exact: true } ) .click(); await page .getByRole( 'searchbox', { diff --git a/test/e2e/specs/editor/various/shortcut-focus-toolbar.spec.js b/test/e2e/specs/editor/various/shortcut-focus-toolbar.spec.js index cfaf4e0be9188..fc54a1a71c8da 100644 --- a/test/e2e/specs/editor/various/shortcut-focus-toolbar.spec.js +++ b/test/e2e/specs/editor/various/shortcut-focus-toolbar.spec.js @@ -201,11 +201,11 @@ class ToolbarUtils { this.pageUtils = pageUtils; this.documentToolbarButton = this.page.getByRole( 'button', { - name: 'Toggle block inserter', + name: 'Block Inserter', exact: true, } ); this.documentToolbarTooltip = this.page.locator( - 'text=Toggle block inserter' + 'text=Block Inserter' ); this.blockToolbarParagraphButton = this.page.getByRole( 'button', { name: 'Paragraph', diff --git a/test/e2e/specs/site-editor/block-style-variations.spec.js b/test/e2e/specs/site-editor/block-style-variations.spec.js index 97ebc74db8308..3c642ea9d1299 100644 --- a/test/e2e/specs/site-editor/block-style-variations.spec.js +++ b/test/e2e/specs/site-editor/block-style-variations.spec.js @@ -318,7 +318,7 @@ async function draftNewPage( page ) { // Create a Group block with 2 nested Group blocks. async function addPageContent( editor, page ) { const inserterButton = page.locator( - 'role=button[name="Toggle block inserter"i]' + 'role=button[name="Block Inserter"i]' ); await inserterButton.click(); await page.type( 'role=searchbox[name="Search"i]', 'Group' ); diff --git a/test/e2e/specs/site-editor/pages.spec.js b/test/e2e/specs/site-editor/pages.spec.js index 7a76db40337c2..4817651bac8f9 100644 --- a/test/e2e/specs/site-editor/pages.spec.js +++ b/test/e2e/specs/site-editor/pages.spec.js @@ -36,7 +36,9 @@ async function addPageContent( editor, page ) { .fill( 'Lorem ipsum dolor sit amet' ); // Insert into Page Content using global inserter. - await page.getByRole( 'button', { name: 'Toggle block inserter' } ).click(); + await page + .getByRole( 'button', { name: 'Block Inserter', exact: true } ) + .click(); await page.getByRole( 'option', { name: 'Heading', exact: true } ).click(); await editor.canvas .getByRole( 'document', { diff --git a/test/e2e/specs/site-editor/site-editor-inserter.spec.js b/test/e2e/specs/site-editor/site-editor-inserter.spec.js index acb0c5409f9b0..04075cbedab30 100644 --- a/test/e2e/specs/site-editor/site-editor-inserter.spec.js +++ b/test/e2e/specs/site-editor/site-editor-inserter.spec.js @@ -24,13 +24,13 @@ test.describe( 'Site Editor Inserter', () => { test( 'inserter toggle button should toggle global inserter', async ( { page, } ) => { - await page.click( 'role=button[name="Toggle block inserter"i]' ); + await page.click( 'role=button[name="Block Inserter"i]' ); // Visibility check await expect( page.locator( 'role=searchbox[name="Search"i]' ) ).toBeVisible(); - await page.click( 'role=button[name="Toggle block inserter"i]' ); + await page.click( 'role=button[name="Block Inserter"i]' ); //Hidden State check await expect( page.locator( 'role=searchbox[name="Search"i]' ) @@ -43,7 +43,8 @@ test.describe( 'Site Editor Inserter', () => { editor, } ) => { const inserterButton = page.getByRole( 'button', { - name: 'Toggle block inserter', + name: 'Block Inserter', + exact: true, } ); const blockLibrary = page.getByRole( 'region', { name: 'Block Library', diff --git a/test/e2e/specs/site-editor/style-book.spec.js b/test/e2e/specs/site-editor/style-book.spec.js index 3f871d28ef941..9a34f30f82ff9 100644 --- a/test/e2e/specs/site-editor/style-book.spec.js +++ b/test/e2e/specs/site-editor/style-book.spec.js @@ -29,7 +29,7 @@ test.describe( 'Style Book', () => { test( 'should disable toolbar buttons when open', async ( { page } ) => { await expect( - page.locator( 'role=button[name="Toggle block inserter"i]' ) + page.locator( 'role=button[name="Block Inserter"i]' ) ).toBeDisabled(); await expect( page.locator( 'role=button[name="Tools"i]' ) diff --git a/test/e2e/specs/widgets/editing-widgets.spec.js b/test/e2e/specs/widgets/editing-widgets.spec.js index 92a264492c018..019e07fe87daa 100644 --- a/test/e2e/specs/widgets/editing-widgets.spec.js +++ b/test/e2e/specs/widgets/editing-widgets.spec.js @@ -56,7 +56,7 @@ test.describe( 'Widgets screen', () => { await page .getByRole( 'toolbar', { name: 'Document tools' } ) - .getByRole( 'button', { name: 'Toggle block inserter' } ) + .getByRole( 'button', { name: 'Block Inserter', exact: true } ) .click(); const blockLibrary = page.getByRole( 'region', { name: 'Block Library', @@ -698,7 +698,7 @@ class WidgetsScreen { if ( await blockLibrary.isHidden() ) { await this.#page .getByRole( 'toolbar', { name: 'Document tools' } ) - .getByRole( 'button', { name: 'Toggle block inserter' } ) + .getByRole( 'button', { name: 'Block Inserter', exact: true } ) .click(); } diff --git a/test/performance/specs/post-editor.spec.js b/test/performance/specs/post-editor.spec.js index 20925ebb36587..becbf375eff2a 100644 --- a/test/performance/specs/post-editor.spec.js +++ b/test/performance/specs/post-editor.spec.js @@ -368,9 +368,11 @@ test.describe( 'Post Editor Performance', () => { // Go to the test page. await admin.editPost( draftId ); await perfUtils.disableAutosave(); - const globalInserterToggle = page.getByRole( 'button', { - name: 'Toggle block inserter', - } ); + const globalInserterToggle = page + .getByRole( 'region', { name: 'Editor top bar' } ) + .getByRole( 'button', { + name: 'Block Inserter', + } ); const samples = 10; const throwaway = 1; @@ -424,9 +426,11 @@ test.describe( 'Post Editor Performance', () => { // Go to the test page. await admin.editPost( draftId ); await perfUtils.disableAutosave(); - const globalInserterToggle = page.getByRole( 'button', { - name: 'Toggle block inserter', - } ); + const globalInserterToggle = page + .getByRole( 'region', { name: 'Editor top bar' } ) + .getByRole( 'button', { + name: 'Block Inserter', + } ); // Open Inserter. await globalInserterToggle.click(); @@ -483,9 +487,11 @@ test.describe( 'Post Editor Performance', () => { await admin.editPost( draftId ); await perfUtils.disableAutosave(); - const globalInserterToggle = page.getByRole( 'button', { - name: 'Toggle block inserter', - } ); + const globalInserterToggle = page + .getByRole( 'region', { name: 'Editor top bar' } ) + .getByRole( 'button', { + name: 'Block Inserter', + } ); const paragraphBlockItem = page.locator( '.block-editor-inserter__menu .editor-block-list-item-paragraph' ); @@ -535,9 +541,11 @@ test.describe( 'Post Editor Performance', () => { test( 'Run the test', async ( { page, admin, perfUtils } ) => { await admin.createNewPost(); await perfUtils.disableAutosave(); - const globalInserterToggle = page.getByRole( 'button', { - name: 'Toggle block inserter', - } ); + const globalInserterToggle = page + .getByRole( 'region', { name: 'Editor top bar' } ) + .getByRole( 'button', { + name: 'Block Inserter', + } ); const testPatterns = [ { diff --git a/test/storybook-playwright/storybook/main.js b/test/storybook-playwright/storybook/main.js index e3023f844da2d..b80833ca725f9 100644 --- a/test/storybook-playwright/storybook/main.js +++ b/test/storybook-playwright/storybook/main.js @@ -7,6 +7,7 @@ const config = { ...baseConfig, addons: [ '@storybook/addon-toolbars' ], docs: undefined, + staticDirs: undefined, stories: [ '../../../packages/components/src/**/stories/e2e/*.story.@(js|tsx|mdx)', ],