diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 1ff7397f6c7c6f..94e2bce07afc13 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -18,8 +18,8 @@ ## Checklist: - [ ] My code is tested. -- [ ] My code follows the WordPress code style. -- [ ] My code follows the accessibility standards. -- [ ] My code has proper inline documentation. +- [ ] My code follows the WordPress code style. +- [ ] My code follows the accessibility standards. +- [ ] My code has proper inline documentation. - [ ] I've included developer documentation if appropriate. - [ ] I've updated all React Native files affected by any refactorings/renamings in this PR. diff --git a/.github/workflows/rnmobile-ios-runner.yml b/.github/workflows/rnmobile-ios-runner.yml index 840e49a55ee078..bb7f6a59cf249f 100644 --- a/.github/workflows/rnmobile-ios-runner.yml +++ b/.github/workflows/rnmobile-ios-runner.yml @@ -30,7 +30,7 @@ jobs: - name: Restore build cache uses: actions/cache@v2 with: - path: packages/react-native-editor/ios/build/gutenberg/Build/Products/Release-iphonesimulator/gutenberg.app + path: packages/react-native-editor/ios/build/GutenbergDemo/Build/Products/Release-iphonesimulator/GutenbergDemo.app key: ${{ runner.os }}-ios-build-${{ hashFiles('ios-checksums.txt') }} - name: Restore pods cache @@ -55,13 +55,13 @@ jobs: run: sudo xcode-select --switch /Applications/Xcode_11.4.1.app - name: Build (if needed) - run: test -e packages/react-native-editor/ios/build/gutenberg/Build/Products/Release-iphonesimulator/gutenberg.app/gutenberg || SKIP_BUNDLING=true npm run native test:e2e:build-app:ios + run: test -e packages/react-native-editor/ios/build/GutenbergDemo/Build/Products/Release-iphonesimulator/GutenbergDemo.app/gutenberg || SKIP_BUNDLING=true npm run native test:e2e:build-app:ios - name: Run iOS Device Tests run: TEST_RN_PLATFORM=ios npm run native device-tests:local ${{ matrix.native-test-name }} - name: Prepare build cache - run: rm packages/react-native-editor/ios/build/gutenberg/Build/Products/Release-iphonesimulator/gutenberg.app/main.jsbundle + run: rm packages/react-native-editor/ios/build/GutenbergDemo/Build/Products/Release-iphonesimulator/GutenbergDemo.app/main.jsbundle - uses: actions/upload-artifact@v2 if: always() diff --git a/bin/build-plugin-zip.sh b/bin/build-plugin-zip.sh index 059df8063f2923..c44e5e3db50811 100755 --- a/bin/build-plugin-zip.sh +++ b/bin/build-plugin-zip.sh @@ -109,7 +109,12 @@ npm run build php bin/generate-gutenberg-php.php > gutenberg.tmp.php mv gutenberg.tmp.php gutenberg.php -build_files=$(ls build/*/*.{js,css,asset.php} build/block-library/blocks/*.php build/block-library/blocks/*/block.json) +build_files=$( + ls build/*/*.{js,css,asset.php} \ + build/block-library/blocks/*.php build/block-library/blocks/*/block.json \ + build/edit-widgets/blocks/*.php build/edit-widgets/blocks/*/block.json \ +) + # Generate the plugin zip file. status "Creating archive... 🎁" diff --git a/bin/tsconfig.json b/bin/tsconfig.json index fb4b29fb702e42..86d2a07c742f8c 100644 --- a/bin/tsconfig.json +++ b/bin/tsconfig.json @@ -6,11 +6,13 @@ "target": "ES6", "lib": [ "ES6", "ES2020.string" ], "rootDir": ".", - "declarationMap": false, - // We're not interested in the output, but we must generate - // something as part of a composite project. Use the - // ignored `.cache` file to hide tsbuildinfo and d.ts files. + // These scripts aren't published and packages don't depend on them. + // Don't generate types, this is strictly for validation. + "incremental": true, + "declarationMap": false, + "emitDeclarationOnly": false, + "noEmit": true, "outDir": ".cache" }, "files": [ @@ -24,6 +26,6 @@ "./plugin/lib/logger.js", "./plugin/lib/utils.js", "./plugin/lib/git.js", - "./validate-package-lock.js", + "./validate-package-lock.js" ] } diff --git a/changelog.txt b/changelog.txt index 07d7b4cd0214ae..9bc39db2a4630f 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,8 +1,166 @@ == Changelog == -= 9.1.0-rc.1 = += 9.1.0 = -TODO: Changelog will be provided later. +### Features + +- Add "open in new tab" feature to Social Links Block. ([25468](https://github.com/WordPress/gutenberg/pull/25468)) +- Add Image Size control to the Media & Text block. ([24795](https://github.com/WordPress/gutenberg/pull/24795)) + +### Enhancements + +- Inserter: Add block pattern category selection. ([24954](https://github.com/WordPress/gutenberg/pull/24954)) +- Reduce minimum height to 1px for the Spacer block. ([25528](https://github.com/WordPress/gutenberg/pull/25528)) +- Show the Fullscreen keyboard shortcut. ([25395](https://github.com/WordPress/gutenberg/pull/25395)) +- Improve the Audio block shortcode transform to account for all sources. ([25114](https://github.com/WordPress/gutenberg/pull/25114)) +- Code block: Allow HTML editing & rich text content. ([24689](https://github.com/WordPress/gutenberg/pull/24689)) +- Remove appender from unselected Buttons and Social Icons block. ([25518](https://github.com/WordPress/gutenberg/pull/25518)) +- Widgets Screen: + - Register legacy widgets as block variations. ([24905](https://github.com/WordPress/gutenberg/pull/24905)) + - Use the default block list appender for the widget areas. ([25635](https://github.com/WordPress/gutenberg/pull/25635)) + - Add titles to Legacy Widgets. ([25638](https://github.com/WordPress/gutenberg/pull/25638)) +- Buttons block: Lighten editor DOM. ([23222](https://github.com/WordPress/gutenberg/pull/23222)) +- Copy: Reword block settings menu item labels. ([22955](https://github.com/WordPress/gutenberg/pull/22955)) +- Add a tooltip to the Drag & Drop handle. ([25606](https://github.com/WordPress/gutenberg/pull/25606)) ([25614](https://github.com/WordPress/gutenberg/pull/25614)) +- A11y: + - Add aria-haspopup property to the BlockNavigation component. ([25605](https://github.com/WordPress/gutenberg/pull/25605)) + - Add aria-haspopup property to the TableOfContents component. ([25603](https://github.com/WordPress/gutenberg/pull/25603)) + - Add aria-haspopup to the ToolSelector. ([25600](https://github.com/WordPress/gutenberg/pull/25600)) + - Add aria-haspopup to the MediaReplaceFlow button. ([25597](https://github.com/WordPress/gutenberg/pull/25597)) + - Add aria-haspopup attribute to CustomGradientBar component. ([25571](https://github.com/WordPress/gutenberg/pull/25571)) + - Add aria-haspopup to CircularOptionPicker component. ([25564](https://github.com/WordPress/gutenberg/pull/25564)) + - Add aria-describedby to featured-image button. ([24888](https://github.com/WordPress/gutenberg/pull/24888)) +- Don't show heading ancestor blocks in Document Outline. ([25599](https://github.com/WordPress/gutenberg/pull/25599)) +- Support the default link config for the Gallery and Image blocks (`image_default_link_type`). ([25578](https://github.com/WordPress/gutenberg/pull/25578)) ([25582](https://github.com/WordPress/gutenberg/pull/25582)) +- Social Icons Block: Let icons wrap. ([25334](https://github.com/WordPress/gutenberg/pull/25334)) + +### New APIs + +- Add new ComboboxControl. ([25442](https://github.com/WordPress/gutenberg/pull/25442)) +- Data Controls: Add new syncSelect control. ([25336](https://github.com/WordPress/gutenberg/pull/25336)) +- DateTimePicker: Add support for highlighting days. ([22032](https://github.com/WordPress/gutenberg/pull/22032)) + +### Bug Fixes + +- Widgets Screen: + - Auto expand the last selected widget area when opening the inserter. ([25669](https://github.com/WordPress/gutenberg/pull/25669)) + - Ensure all widgets are properly initialized when they're added, do not unmount widgets once they're mounted. ([25645](https://github.com/WordPress/gutenberg/pull/25645)) + - Fix Legacy widget block previews and use iFrames. ([25443](https://github.com/WordPress/gutenberg/pull/25443)) ([14643](https://github.com/WordPress/gutenberg/pull/14643)) + - Report save errors. ([25408](https://github.com/WordPress/gutenberg/pull/25408)) + - Fix global inserter. ([24908](https://github.com/WordPress/gutenberg/pull/24908)) +- Fix RangeControl direct entry in input field. ([25609](https://github.com/WordPress/gutenberg/pull/25609)) +- A11y: + - Fix the color contrast in the code editor. ([25593](https://github.com/WordPress/gutenberg/pull/25593)) + - Fix Publish sidebar Cancel button not usable through screen readers. ([25441](https://github.com/WordPress/gutenberg/pull/25441)) + - Fix keyboard navigation on the Image block toolbar. ([25127](https://github.com/WordPress/gutenberg/pull/25127)) + - More block: Use an actual placeholder for input text. ([23836](https://github.com/WordPress/gutenberg/pull/23836)) +- Fix nested container smart margins. ([25527](https://github.com/WordPress/gutenberg/pull/25527)) +- Fix add_filter instead of apply_filters. ([25512](https://github.com/WordPress/gutenberg/pull/25512)) +- Fix the WordPress embed preview in the editor. ([25370](https://github.com/WordPress/gutenberg/pull/25370)) +- Remove Embed block aspect ratio classes on url change. ([25295](https://github.com/WordPress/gutenberg/pull/25295)) +- Remove duplicate help item. ([25283](https://github.com/WordPress/gutenberg/pull/25283)) +- Fix Block Directory author average rating formating. ([24732](https://github.com/WordPress/gutenberg/pull/24732)) +- @wordpress/api-fetch: + - Fix preloading middleware referencing stale data. ([25550](https://github.com/WordPress/gutenberg/pull/25550)) + - Check nonce header value before skipping adding it. ([25458](https://github.com/WordPress/gutenberg/pull/25458)) +- Use esc_html instead of esc_attr in the Archives block. ([25476](https://github.com/WordPress/gutenberg/pull/25476)) +- Fix Canceling Drag and Drop using ESC key. ([25317](https://github.com/WordPress/gutenberg/pull/25317)) +- Cover block: Add explilcit box-sizing style. ([25115](https://github.com/WordPress/gutenberg/pull/25115)) +- Use a ComboboxControl for the post author selector to fix loading issues for sites with a big number of authors. ([23237](https://github.com/WordPress/gutenberg/pull/23237)) + +### Performance + +- Avoid relying on DOM events to measure the loading time. ([25288](https://github.com/WordPress/gutenberg/pull/25288)) + +### Experiments + +- Site Editor Screen: + - Fix wrong close label in the block inspector. ([25424](https://github.com/WordPress/gutenberg/pull/25424)) + - Add basic template information to editor header. ([25320](https://github.com/WordPress/gutenberg/pull/25320)) + - Fix the footer styling. ([25152](https://github.com/WordPress/gutenberg/pull/25152)) + - Add a reset button to global styles sidebar. ([25426](https://github.com/WordPress/gutenberg/pull/25426)) + - Show document subtext if template part child is selected. ([25544](https://github.com/WordPress/gutenberg/pull/25544)) + - Add navigation panel. ([25506](https://github.com/WordPress/gutenberg/pull/25506)) + - Fix site base URL. ([25409](https://github.com/WordPress/gutenberg/pull/25409)) +- Post and Site Blocks: + - Add link option in PostTitle block. ([25341](https://github.com/WordPress/gutenberg/pull/25341)) ([25397](https://github.com/WordPress/gutenberg/pull/25397)) + - Register the Site Logo block using `register_block_type_from_metadata`. ([25289](https://github.com/WordPress/gutenberg/pull/25289)) +- Themes and global styles: + - Support defining colors and gradients config from theme.json. ([25419](https://github.com/WordPress/gutenberg/pull/25419)) + - Support defining font sizes config from theme.json. ([25516](https://github.com/WordPress/gutenberg/pull/25516)) + - Support custom units on theme.json. ([25217](https://github.com/WordPress/gutenberg/pull/25217)) + - Add separate support keys for color and background color. ([25314](https://github.com/WordPress/gutenberg/pull/25314)) + - Allow themes to enqueue custom CSS variables via theme.json. ([25446](https://github.com/WordPress/gutenberg/pull/25446)) ([25619](https://github.com/WordPress/gutenberg/pull/25619)) + - Refactor theme.json format. ([25301](https://github.com/WordPress/gutenberg/pull/25301)) ([25407](https://github.com/WordPress/gutenberg/pull/25407)) + - Update theme json documentation to account for latest changes. ([25369](https://github.com/WordPress/gutenberg/pull/25369)) +- Block API: Introduce useBlockWrapperProps hook to use light block DOM in the editor. ([23034](https://github.com/WordPress/gutenberg/pull/23034)) ([25679](https://github.com/WordPress/gutenberg/pull/25679)) ([25554](https://github.com/WordPress/gutenberg/pull/25554)) ([25515](https://github.com/WordPress/gutenberg/pull/25515)) +- Navigation block and screen: + - Handle block menu items. ([24846](https://github.com/WordPress/gutenberg/pull/24846)) + - Avoid auto-focusing Navigation block in Navigation screen. ([25592](https://github.com/WordPress/gutenberg/pull/25592)) + - Change the block description. ([25531](https://github.com/WordPress/gutenberg/pull/25531)) ([25555](https://github.com/WordPress/gutenberg/pull/25555)) + - Allow Social Links within Navigation Block. ([25357](https://github.com/WordPress/gutenberg/pull/25357)) + - Wrap navigation editing features with filters. ([25329](https://github.com/WordPress/gutenberg/pull/25329)) + - Add move markers to list view. ([25205](https://github.com/WordPress/gutenberg/pull/25205)) +- Iterating on the Navigation Component ([25608](https://github.com/WordPress/gutenberg/pull/25608)) ([25495](https://github.com/WordPress/gutenberg/pull/25495)) ([25572](https://github.com/WordPress/gutenberg/pull/25572)) ([25540](https://github.com/WordPress/gutenberg/pull/25540)) ([25520](https://github.com/WordPress/gutenberg/pull/25520)) ([25507](https://github.com/WordPress/gutenberg/pull/25507)) ([25367](https://github.com/WordPress/gutenberg/pull/25367)) ([25364](https://github.com/WordPress/gutenberg/pull/25364)) ([25340](https://github.com/WordPress/gutenberg/pull/25340)) ([25327](https://github.com/WordPress/gutenberg/pull/25327)) ([25281](https://github.com/WordPress/gutenberg/pull/25281)) ([25280](https://github.com/WordPress/gutenberg/pull/25280)) + + +### Documentation + +- Add a data format and flow architecture document. ([25299](https://github.com/WordPress/gutenberg/pull/25299)) +- @wordpress/env: Add documentation for inspecting the docker compose file. ([25666](https://github.com/WordPress/gutenberg/pull/25666)) +- Add new block supports page to the handbook. ([25647](https://github.com/WordPress/gutenberg/pull/25647)) +- Block Directory: Add developer documentation. ([25591](https://github.com/WordPress/gutenberg/pull/25591)) +- Move custom-fields note to the 'Register Meta Field' documentation. ([25584](https://github.com/WordPress/gutenberg/pull/25584)) +- Add Block Editor Components documentation: + - Warning ([25574](https://github.com/WordPress/gutenberg/pull/25574)) + - FontSizePicker ([25568](https://github.com/WordPress/gutenberg/pull/25568)) + - UnitControl ([25565](https://github.com/WordPress/gutenberg/pull/25565)) + - CopyHandler ([25342](https://github.com/WordPress/gutenberg/pull/25342)) + - MultiSelection ([25306](https://github.com/WordPress/gutenberg/pull/25306)) + - LineHeightControl ([25303](https://github.com/WordPress/gutenberg/pull/25303)) + - BlockAlignmentToolbar ([25212](https://github.com/WordPress/gutenberg/pull/25212)) + - AlignmentToolbar ([25210](https://github.com/WordPress/gutenberg/pull/25210)) + - BlockFormatControls ([25573](https://github.com/WordPress/gutenberg/pull/25573)) +- Add Caveats section for MAMP. ([25444](https://github.com/WordPress/gutenberg/pull/25444)) +- Add FormTokenField story. ([25439](https://github.com/WordPress/gutenberg/pull/25439)) +- Improve documentation for the data registry control and selector creators. ([25335](https://github.com/WordPress/gutenberg/pull/25335)) +- Update git workflow documentation. ([25164](https://github.com/WordPress/gutenberg/pull/25164)) +- Refresh the Getting Started guide. ([25090](https://github.com/WordPress/gutenberg/pull/25090)) +- Update JavaScript troubleshooting guide. ([24105](https://github.com/WordPress/gutenberg/pull/24105)) +- Enhance the Block Context documentation. ([25272](https://github.com/WordPress/gutenberg/pull/25272)) +- Typos: ([25359](https://github.com/WordPress/gutenberg/pull/25359)) ([25653](https://github.com/WordPress/gutenberg/pull/25653)) + +### Code Quality + +- Update the Dashicon component to rely on the font that ships with WordPress. ([20003](https://github.com/WordPress/gutenberg/pull/20003)) +- Add new $gray-200 SASS variable and use for skeleton borders. ([25491](https://github.com/WordPress/gutenberg/pull/25491)) +- Block Editor: Remove empty module focus-detector. ([25561](https://github.com/WordPress/gutenberg/pull/25561)) +- Image block: Avoid remounting to focus caption. ([25493](https://github.com/WordPress/gutenberg/pull/25493)) +- Add explicit boxSizing style to Placeholder component. ([25463](https://github.com/WordPress/gutenberg/pull/25463)) +- Remove classic block code used to support WP 4.9. ([25365](https://github.com/WordPress/gutenberg/pull/25365)) +- Add RichText value type definition. ([25363](https://github.com/WordPress/gutenberg/pull/25363)) +- Avoid global DOM dependencies. ([25332](https://github.com/WordPress/gutenberg/pull/25332)) +- Use controls from the Data Controls package instead of local ones. ([25235](https://github.com/WordPress/gutenberg/pull/25235)) +- RichText: Simplify withFormatTypes as hook. ([23145](https://github.com/WordPress/gutenberg/pull/23145)) +- Video block: Use hooks. ([25513](https://github.com/WordPress/gutenberg/pull/25513)) +- Remove wp_area custom post type. ([25497](https://github.com/WordPress/gutenberg/pull/25497)) +- Post Featured Image: Remove redundant condition. ([25490](https://github.com/WordPress/gutenberg/pull/25490)) +- Move legacy-widget block over to edit-widgets package. ([25371](https://github.com/WordPress/gutenberg/pull/25371)) ([25404](https://github.com/WordPress/gutenberg/pull/25404)) +- Don't use percent units for line-height. ([25398](https://github.com/WordPress/gutenberg/pull/25398)) +- Change wording and names to not include "whitelist". ([25396](https://github.com/WordPress/gutenberg/pull/25396)) +- Don't discard all promises results when one of them rejects. ([25302](https://github.com/WordPress/gutenberg/pull/25302)) +- Block Directory: Switch to `blocks.registerBlockType` filter. ([25264](https://github.com/WordPress/gutenberg/pull/25264)) +- Fix some javascript warnings. ([24996](https://github.com/WordPress/gutenberg/pull/24996)) + +### Various + +- Remove the Block-based widgets editor from the customizer. ([25626](https://github.com/WordPress/gutenberg/pull/25626)) +- Cover block: Remove default position (center/center) className from rendering. ([25346](https://github.com/WordPress/gutenberg/pull/25346)) +- Fix the default label position in SelectControl. ([25427](https://github.com/WordPress/gutenberg/pull/25427)) +- DropdownMenu tooltip default to true. ([25391](https://github.com/WordPress/gutenberg/pull/25391)) +- Pass block pattern name when using replaceBlocks and insertBlocks. ([25165](https://github.com/WordPress/gutenberg/pull/25165)). ([25433](https://github.com/WordPress/gutenberg/pull/25433)) +- Babel Preset: Update Babel version to 7.11.x. ([25351](https://github.com/WordPress/gutenberg/pull/25351)) +- InputControl: Remove floating label variant. ([25308](https://github.com/WordPress/gutenberg/pull/25308)) = 9.0.0 = diff --git a/docs/contributors/git-workflow.md b/docs/contributors/git-workflow.md index 3acfd27a36f0c8..0894945e8a2850 100644 --- a/docs/contributors/git-workflow.md +++ b/docs/contributors/git-workflow.md @@ -51,7 +51,7 @@ git switch -c update/my-branch **Step 4**: Make the code changes. Build, confirm, and test your change thoroughly. See [coding guidelines](/docs/contributors/coding-guidelines.md) and [testing overview](/docs/contributors/testing-overview.md) for guidance. -**Step 5**: Commit your change with a [good commmit message](https://make.wordpress.org/core/handbook/best-practices/commit-messages/). This will commit your change to your local copy of the repository. +**Step 5**: Commit your change with a [good commit message](https://make.wordpress.org/core/handbook/best-practices/commit-messages/). This will commit your change to your local copy of the repository. ```bash git commit -m "Your Good Commit Message" path/to/FILE diff --git a/docs/designers-developers/developers/block-api/block-metadata.md b/docs/designers-developers/developers/block-api/block-metadata.md index c159d7c1391071..24d1468121ba29 100644 --- a/docs/designers-developers/developers/block-api/block-metadata.md +++ b/docs/designers-developers/developers/block-api/block-metadata.md @@ -11,6 +11,7 @@ To register a new block type using metadata that can be shared between codebase ```json { + "apiVersion": 2, "name": "my-plugin/notice", "title": "Notice", "category": "text", @@ -32,7 +33,6 @@ To register a new block type using metadata that can be shared between codebase "usesContext": [ "groupId" ], "supports": { "align": true, - "lightBlockWrapper": true }, "styles": [ { "name": "default", "label": "Default", "isDefault": true }, diff --git a/docs/designers-developers/developers/themes/block-based-themes.md b/docs/designers-developers/developers/themes/block-based-themes.md index 4889a36580bd48..03f4f278b9a256 100644 --- a/docs/designers-developers/developers/themes/block-based-themes.md +++ b/docs/designers-developers/developers/themes/block-based-themes.md @@ -17,6 +17,7 @@ A very simple block-based theme is structured like so: ``` theme |__ style.css +|__ experimental-theme.json |__ functions.php |__ block-templates |__ index.html @@ -30,7 +31,7 @@ theme |__ ... ``` -The difference with existing WordPress themes is that the different templates in the template hierarchy, and template parts, are block templates instead of php files. +The difference with existing WordPress themes is that the different templates in the template hierarchy, and template parts, are block templates instead of php files. In addition, this example includes an [`experimental-theme.json`](/docs/designers-developers/developers/themes/theme-json.md) file for some styles. ## What is a block template? @@ -111,17 +112,21 @@ As we're still early in the process, the number of blocks specifically dedicated - Post Title - Post Content - Post Author +- Post Comment +- Post Comment Author +- Post Comment Date - Post Comments -- Post CommentsCount -- Post CommentsForm +- Post Comments Count +- Post Comments Form - Post Date - Post Excerpt - Post Featured Image +- Post Hierarchical Terms - Post Tags ## Styling -One of the most important aspects of themes (if not the most important) is the styling. While initially you'll be able to provide styles and enqueue them using the same hooks themes have always used, this is an area that is still [being explored](https://github.com/WordPress/gutenberg/issues/9534). +One of the most important aspects of themes (if not the most important) is the styling. While initially you'll be able to provide styles and enqueue them using the same hooks themes have always used, the [Global Styles](/docs/designers-developers/developers/themes/theme-json.md) effort will provide a scaffolding for adding many theme styles in the future. ## Resources diff --git a/docs/designers-developers/developers/themes/theme-json.md b/docs/designers-developers/developers/themes/theme-json.md index 1deafc2e0d0f84..58a4ca6cb27578 100644 --- a/docs/designers-developers/developers/themes/theme-json.md +++ b/docs/designers-developers/developers/themes/theme-json.md @@ -87,7 +87,7 @@ The settings section has the following structure and default values: "palette": [ ... ], /* color presets, as in add_theme_support('editor-color-palette', ... ) */ }, "spacing": { - "customPadding": false, /* true to opt-in, as in add_theme_support('experimental-custom-spacing') */ + "customPadding": false, /* true to opt-in, as in add_theme_support('custom-spacing') */ "units": [ "px", "em", "rem", "vh", "vw" ], /* filter values, as in add_theme_support('custom-units', ... ) */ }, "typography": { diff --git a/docs/designers-developers/developers/themes/theme-support.md b/docs/designers-developers/developers/themes/theme-support.md index bc0d8080503ab5..8331a41d2d935b 100644 --- a/docs/designers-developers/developers/themes/theme-support.md +++ b/docs/designers-developers/developers/themes/theme-support.md @@ -388,12 +388,12 @@ To make the content resize and keep its aspect ratio, the `` element needs add_theme_support( 'responsive-embeds' ); ``` -## Experimental — Cover block padding +## Cover block padding -Using the Gutenberg plugin (version 8.3 or later), Cover blocks can provide padding controls in the editor for users. This is off by default, and requires the theme to opt in by declaring support: +Some blocks can provide padding controls in the editor for users. This is off by default, and requires the theme to opt in by declaring support: ```php -add_theme_support('experimental-custom-spacing'); +add_theme_support('custom-spacing'); ``` ## Experimental — Link color control diff --git a/docs/designers-developers/developers/tutorials/block-based-themes/README.md b/docs/designers-developers/developers/tutorials/block-based-themes/README.md index 820403bdbc656a..5739b34b44229a 100644 --- a/docs/designers-developers/developers/tutorials/block-based-themes/README.md +++ b/docs/designers-developers/developers/tutorials/block-based-themes/README.md @@ -7,9 +7,11 @@ You will learn about the required files, how to combine templates and template p how to add presets for global styles, and how to add blocks and export the templates in the site editor. Full site editing is an experimental feature and the workflow in this tutorial is likely to change. -This tutorial was written for Gutenberg version 8.5. + +This tutorial is up to date as of Gutenberg version 9.1. ## Table of Contents + 1. [What is needed to create a block-based theme?](/docs/designers-developers/developers/tutorials/block-based-themes/README.md#what-is-needed-to-create-a-block-based-theme) 2. [Creating the theme](/docs/designers-developers/developers/tutorials/block-based-themes/README.md#creating-the-theme) 3. [Creating the templates and template parts](/docs/designers-developers/developers/tutorials/block-based-themes/README.md#creating-the-templates-and-template-parts) @@ -19,24 +21,20 @@ This tutorial was written for Gutenberg version 8.5. ## What is needed to create a block-based theme? To use a block based theme you need to have Gutenberg installed and full site editing must be enabled. + Full site editing can be enabled from the Gutenberg experiments menu in the WordPress admin area. -A block-based theme is built using HTML templates and template parts. -Templates are the main files used in the [template hierarchy](https://developer.wordpress.org/themes/basics/template-hierarchy/), -for example index, single or archive. -Templates can optionally include structural template parts, for example a header, footer or sidebar. +A block-based theme is built using HTML templates and template parts. Templates are the main files used in the [template hierarchy](https://developer.wordpress.org/themes/basics/template-hierarchy/), for example index, single or archive. Templates can optionally include structural template parts, for example a header, footer or sidebar. -Each template or template part contains the [block grammar](https://developer.wordpress.org/block-editor/principles/key-concepts/#blocks), the HTML, for the selected blocks. -The block HTML is generated in and exported from the **site editor**. It can also be added to the theme's HTML files manually. +Each template or template part contains the [block grammar](https://developer.wordpress.org/block-editor/principles/key-concepts/#blocks), the HTML, for the selected blocks. The block HTML is generated in and exported from the **site editor**. It can also be added to the theme's HTML files manually. ### Required files and file structure -A block based theme requires an index.php file, an index template file, a style.css file, and a functions.php file. -The theme may optionally include an experimental-theme.json file to manage global styles. -You decide what additional templates and template parts to include in your theme. +A block based theme requires an `index.php` file, an index template file, a `style.css` file, and a `functions.php` file. + +The theme may optionally include an [experimental-theme.json file](/docs/designers-developers/developers/themes/theme-json.md) to manage global styles. You decide what additional templates and template parts to include in your theme. -Templates are placed inside the block-templates folder, -and template parts are placed inside the block-template-parts folder: +Templates are placed inside the block-templates folder, and template parts are placed inside the block-template-parts folder: ``` theme @@ -58,12 +56,10 @@ theme ## Creating the theme -Create a new folder for your theme in /wp-content/themes/. +Create a new folder for your theme in `/wp-content/themes/`. Inside this folder, create the block-templates and block-template-parts folders. -Create a style.css file. -The file header in the style.css file has the same items that you would use in a traditional theme. -https://developer.wordpress.org/themes/basics/main-stylesheet-style-css/#explanations +Create a `style.css` file. The file header in the `style.css` file has [the same items that you would use in a traditional theme](https://developer.wordpress.org/themes/basics/main-stylesheet-style-css/#explanations). ``` /* @@ -86,12 +82,11 @@ Use it to make something cool, have fun, and share what you've learned with othe */ ``` -Create a functions.php file. +Create a `functions.php` file. -In this file, you will enqueue the style.css file and add any theme support that you want to use. -For example colors, wide blocks and featured images. +In this file, you will enqueue the `style.css` file and add any theme support that you want to use. For example colors, wide blocks and featured images. --You no longer need to add theme support for the title tag. It is already enabled with full site editing. +_You no longer need to add theme support for the title tag. It is already enabled with full site editing._ https://developer.wordpress.org/themes/basics/theme-functions/#what-is-functions-php @@ -152,7 +147,7 @@ function myfirsttheme_scripts() { add_action( 'wp_enqueue_scripts', 'myfirsttheme_scripts' ); ``` -Create an index.php file. +Create an `index.php` file. This file is used as a fallback if the theme is activated when full site editing is not enabled. You may leave the file empty for this tutorial. @@ -171,15 +166,13 @@ theme ### Creating the templates and template parts -Create two template parts called footer.html and header.html and place them inside the block-template-parts folder. -You can leave the files empty for now. +Create two template parts called `footer.html` and `header.html` and place them inside the block-template-parts folder. You can leave the files empty for now. -Inside the block-templates folder, create an index.html file. +Inside the block-templates folder, create an `index.html` file. -In index.html, include the template parts by adding two HTML comments. +In `index.html`, include the template parts by adding two HTML comments. -The HTML comments starts with `wp:template-part` which is the name of the template-part block type. -Inside the curly brackets are two keys and their values: The slug of the template part, and the theme name. +The HTML comments starts with `wp:template-part` which is the name of the template-part block type. Inside the curly brackets are two keys and their values: The slug of the template part, and the theme name. ``` @@ -193,7 +186,7 @@ Eventually, you will be able to create and combine templates and template parts ### Experimental-theme.json - Global styles -The purpose of the experimental-theme.json file is to make it easier to style blocks by setting defaults. +The purpose of the `experimental-theme.json` file is to make it easier to style blocks by setting defaults. It is used to: * Create CSS variables (also called CSS custom properties) that can be used to style blocks both on the front and in the editor. @@ -202,45 +195,46 @@ It is used to: [The documentation for global styles contains a list of available block and style combinations.](https://developer.wordpress.org/block-editor/developers/themes/theme-json/) -Create a file called experimental-theme.json and save it inside the main folder. +Create a file called `experimental-theme.json` and save it inside the main folder. -CSS variables are generated using **Global presets**. -The variables are added to the `:root` on the front, and to the `.editor-styles-wrapper` class in the editor. +CSS variables are generated using **Global presets**. The variables are added to the `:root` on the front, and to the `.editor-styles-wrapper` class in the editor. -Styles that are added to the themes style.css file or an editor style sheet are loaded after global styles. +Styles that are added to the themes `style.css` file or an editor style sheet are loaded after global styles. -Add the following global presets to the experimental-theme.json file: +Add the following global presets to the `experimental-theme.json` file: ``` { "global": { - "presets": { - "color": [ - { - "slug": "strong-magenta", - "value": "#a156b4" - }, - { - "slug": "very-dark-gray", - "value": "#444" - }, - ], - "line-height": [ - { - "slug": "small", - "value": "1.3" - }, - { - "slug": "medium", - "value": "2" - }, - { - "slug": "large", - "value": "2.5" - } - ], - }, - }, + "setttings": { + "color": { + "palette": [ + { + "slug": "strong-magenta", + "color": "#a156b4" + }, + { + "slug": "very-dark-gray", + "color": "#444" + }, + ] + }, + "custom": { + "line-height": [ + { + "small": "1.3" + }, + { + "medium": "2" + }, + { + large": "2.5" + } + ] + } + } + } +} ``` This code generates the following variables: @@ -248,9 +242,9 @@ This code generates the following variables: --wp--preset--color--strong-magenta: #a156b4; --wp--preset--color--very-dark-gray: #444; - --wp--preset--line-height--small: 1.3; - --wp--preset--line-height--medium: 2; - --wp--preset--line-height--large: 2.5; + --wp--custom--line-height--small: 1.3; + --wp--custom--line-height--medium: 2; + --wp--custom--line-height--large: 2.5; ``` **Global styles** are used to set default values for the website and for the blocks. @@ -282,20 +276,20 @@ Block styles are separate from global styles. Add the code after the globals, bu }, "typography": { "fontSize": "2.5rem", - "lineHeight": "var(--wp--preset--line-height--medium)" + "lineHeight": "var(--wp--custom--line-height--medium)" } } }, ``` CSS variables for font sizes are generated using the `editor-font-sizes` theme support or by adding a global preset. + https://developer.wordpress.org/block-editor/developers/themes/theme-support/#block-font-sizes If the theme does not add any custom font sizes, variables are created using the default sizes. This example adds the default medium font size to the paragraph block. -The font sizes are unit less, which is why calc is used: -https://developer.mozilla.org/en-US/docs/Web/CSS/calc +The font sizes are unitless, which is why calc is used: https://developer.mozilla.org/en-US/docs/Web/CSS/calc ``` "core/paragraph": { @@ -307,8 +301,7 @@ https://developer.mozilla.org/en-US/docs/Web/CSS/calc }, ``` -Using the CSS variables is optional. -In this example, the default background color for the group block is changed to white using a color code: +Using the CSS variables is optional. In this example, the default background color for the group block is changed to white using a color code: ``` "core/group": { @@ -325,35 +318,31 @@ Below are the presets and styles combined: ``` { "global": { - "presets": { - "color": [ - { - "slug": "strong-magenta", - "value": "#a156b4" - }, - { - "slug": "very-dark-gray", - "value": "#444" - } - ], - "line-height": [ - { - "slug": "small", - "value": "1.3" - }, - { - "slug": "medium", - "value": "2" - }, - { - "slug": "large", - "value": "2.5" - } - ] - }, - "styles": { + "setttings": { "color": { - "background": "var(--wp--preset--color--very-dark-gray)" + "palette": [ + { + "slug": "strong-magenta", + "color": "#a156b4" + }, + { + "slug": "very-dark-gray", + "color": "#444" + }, + ] + }, + "custom": { + "line-height": [ + { + "small": "1.3" + }, + { + "medium": "2" + }, + { + large": "2.5" + } + ] } } }, @@ -365,7 +354,7 @@ Below are the presets and styles combined: }, "typography": { "fontSize": "2.5rem", - "lineHeight": "var(--wp--preset--line-height--medium)" + "lineHeight": "var(--wp--custom--line-height--medium)" } } }, diff --git a/docs/designers-developers/developers/tutorials/block-based-themes/block-based-themes-2-adding-blocks.md b/docs/designers-developers/developers/tutorials/block-based-themes/block-based-themes-2-adding-blocks.md index 6a32769b71ece2..c1e5a2d6a4658c 100644 --- a/docs/designers-developers/developers/tutorials/block-based-themes/block-based-themes-2-adding-blocks.md +++ b/docs/designers-developers/developers/tutorials/block-based-themes/block-based-themes-2-adding-blocks.md @@ -7,11 +7,9 @@ There is more than one way to add blocks to the theme files: - Adding and editing blocks in the site editor and exporting the theme. - Adding block HTML and comments to the HTML files manually. - ## Working with blocks and templates in the site editor -The beta site editor is available from the WordPress admin area when full site editing is enabled. -To use the site editor, a full site editing theme must be installed and active. +The beta site editor is available from the WordPress admin area when full site editing is enabled. To use the site editor, a full site editing theme must be installed and active. The site editor is similar to the block editor, but is used for the site layout instead of the post and page content. @@ -29,17 +27,13 @@ Template parts can be selected and edited directly in the site editor, like othe ![A selected template part is highlighted. When selected, the template part has a limited set of alignment controls in the block toolbar](https://wordpress.org/gutenberg/files/2020/07/block-based-themes-editor-template-part.png) -Select the header template part in the menu to view and edit it individually. -Add the blocks that you would like in your header, for example a site title block, a navigation block, and an image. +Select the header template part in the menu to view and edit it individually. Add the blocks that you would like in your header, for example a site title block, a navigation block, and an image. Next, select the footer template part and add some content, for example widget blocks. Select the index template again to view the template parts together in the page context. -To add a post loop to the index template, add a **query** block. -The query block includes the query loop and the query pagination. -The default loop displays the post title and post content. -The query loop and query pagination are also available as individual blocks. +To add a post loop to the index template, add a **query** block. The query block includes the query loop and the query pagination. The default loop displays the post title and post content. The query loop and query pagination are also available as individual blocks. ## Saving templates and template parts @@ -51,14 +45,11 @@ Select the templates and template parts that you want to save: ![The save menu displays a list of templates and template parts with checkboxes](https://wordpress.org/gutenberg/files/2020/07/block-based-themes-save.png) - -When you save changes in the site editor, the files in the active theme are not updated. -Instead, the templates and template parts are saved as custom post types, that are accessed via the appearance menu. +When you save changes in the site editor, the files in the active theme are not updated. Instead, the templates and template parts are saved as custom post types, that are accessed via the appearance menu. ![The template parts view in the admin area displays a list of all saved template parts](https://wordpress.org/gutenberg/files/2020/07/block-based-themes-appearance-template-parts.png) ## Exporting changes -Saved templates and template parts can be exported as a partial theme from the Tools menu in the site editor. -The block HTML code can then be copied to the theme that you are editing. +Saved templates and template parts can be exported as a partial theme from the Tools menu in the site editor. The block HTML code can then be copied to the theme that you are editing. diff --git a/gutenberg.php b/gutenberg.php index 54e972091ed194..4cf9aacec6ce6a 100644 --- a/gutenberg.php +++ b/gutenberg.php @@ -5,7 +5,7 @@ * Description: Printing since 1440. This is the development plugin for the new block editor in core. * Requires at least: 5.3 * Requires PHP: 5.6 - * Version: 9.1.0-rc.1 + * Version: 9.1.0 * Author: Gutenberg Team * Text Domain: gutenberg * diff --git a/lib/block-supports/colors.php b/lib/block-supports/colors.php index 8649b14d6d6095..b0bb4e1e22ada9 100644 --- a/lib/block-supports/colors.php +++ b/lib/block-supports/colors.php @@ -13,7 +13,7 @@ function gutenberg_register_colors_support( $block_type ) { $color_support = false; if ( property_exists( $block_type, 'supports' ) ) { - $color_support = gutenberg_experimental_get( $block_type->supports, array( '__experimentalColor' ), false ); + $color_support = gutenberg_experimental_get( $block_type->supports, array( 'color' ), false ); } $has_text_colors_support = true === $color_support || ( is_array( $color_support ) && gutenberg_experimental_get( $color_support, array( 'text' ), true ) ); $has_background_colors_support = true === $color_support || ( is_array( $color_support ) && gutenberg_experimental_get( $color_support, array( 'background' ), true ) ); @@ -60,10 +60,10 @@ function gutenberg_register_colors_support( $block_type ) { * @return array Colors CSS classes and inline styles. */ function gutenberg_apply_colors_support( $attributes, $block_attributes, $block_type ) { - $color_support = gutenberg_experimental_get( $block_type->supports, array( '__experimentalColor' ), false ); + $color_support = gutenberg_experimental_get( $block_type->supports, array( 'color' ), false ); $has_text_colors_support = true === $color_support || ( is_array( $color_support ) && gutenberg_experimental_get( $color_support, array( 'text' ), true ) ); $has_background_colors_support = true === $color_support || ( is_array( $color_support ) && gutenberg_experimental_get( $color_support, array( 'background' ), true ) ); - $has_link_colors_support = gutenberg_experimental_get( $color_support, array( 'linkColor' ), false ); + $has_link_colors_support = gutenberg_experimental_get( $color_support, array( 'link' ), false ); $has_gradients_support = gutenberg_experimental_get( $color_support, array( 'gradients' ), false ); // Text Colors. diff --git a/lib/block-supports/typography.php b/lib/block-supports/typography.php index 083a6ee477b900..ef33c3249ade17 100644 --- a/lib/block-supports/typography.php +++ b/lib/block-supports/typography.php @@ -13,12 +13,12 @@ function gutenberg_register_typography_support( $block_type ) { $has_font_size_support = false; if ( property_exists( $block_type, 'supports' ) ) { - $has_font_size_support = gutenberg_experimental_get( $block_type->supports, array( '__experimentalFontSize' ), false ); + $has_font_size_support = gutenberg_experimental_get( $block_type->supports, array( 'fontSize' ), false ); } $has_line_height_support = false; if ( property_exists( $block_type, 'supports' ) ) { - $has_line_height_support = gutenberg_experimental_get( $block_type->supports, array( '__experimentalLineHeight' ), false ); + $has_line_height_support = gutenberg_experimental_get( $block_type->supports, array( 'lineHeight' ), false ); } if ( ! $block_type->attributes ) { @@ -51,12 +51,12 @@ function gutenberg_register_typography_support( $block_type ) { function gutenberg_apply_typography_support( $attributes, $block_attributes, $block_type ) { $has_font_size_support = false; if ( property_exists( $block_type, 'supports' ) ) { - $has_font_size_support = gutenberg_experimental_get( $block_type->supports, array( '__experimentalFontSize' ), false ); + $has_font_size_support = gutenberg_experimental_get( $block_type->supports, array( 'fontSize' ), false ); } $has_line_height_support = false; if ( property_exists( $block_type, 'supports' ) ) { - $has_line_height_support = gutenberg_experimental_get( $block_type->supports, array( '__experimentalLineHeight' ), false ); + $has_line_height_support = gutenberg_experimental_get( $block_type->supports, array( 'lineHeight' ), false ); } // Font Size. diff --git a/lib/class-wp-rest-widget-utils-controller.php b/lib/class-wp-rest-widget-utils-controller.php index 832a25a6252807..ac02218d48333d 100644 --- a/lib/class-wp-rest-widget-utils-controller.php +++ b/lib/class-wp-rest-widget-utils-controller.php @@ -88,8 +88,9 @@ public function permissions_check() { * * @return boolean| True if the widget being referenced exists and false otherwise. * @since 5.2.0 + * @access public */ - private function is_valid_widget( $widget_class ) { + public function is_valid_widget( $widget_class ) { $widget_class = urldecode( $widget_class ); global $wp_widget_factory; if ( ! $widget_class ) { diff --git a/lib/client-assets.php b/lib/client-assets.php index fae60149ceaea6..f1a72422ba00da 100644 --- a/lib/client-assets.php +++ b/lib/client-assets.php @@ -619,3 +619,23 @@ function gutenberg_extend_block_editor_styles( $settings ) { return $settings; } add_filter( 'block_editor_settings', 'gutenberg_extend_block_editor_styles' ); + +/** + * Load the default editor styles. + * These styles are used if the "no theme styles" options is triggered. + * + * @param array $settings Default editor settings. + * + * @return array Filtered editor settings. + */ +function gutenberg_extend_block_editor_settings_with_default_editor_styles( $settings ) { + $editor_styles_file = gutenberg_dir_path() . 'build/editor/editor-styles.css'; + $settings['defaultEditorStyles'] = array( + array( + 'css' => file_get_contents( $editor_styles_file ), + ), + ); + + return $settings; +} +add_filter( 'block_editor_settings', 'gutenberg_extend_block_editor_settings_with_default_editor_styles' ); diff --git a/lib/global-styles.php b/lib/global-styles.php index 1fbdf36f00d95c..c385b72f18bcac 100644 --- a/lib/global-styles.php +++ b/lib/global-styles.php @@ -289,7 +289,7 @@ function gutenberg_experimental_global_styles_get_theme_support_settings() { } $theme_settings['global']['settings']['typography']['customLineHeight'] = true; } - if ( get_theme_support( 'experimental-custom-spacing' ) ) { + if ( get_theme_support( 'custom-spacing' ) ) { if ( ! isset( $theme_settings['global']['settings']['spacing'] ) ) { $theme_settings['global']['settings']['spacing'] = array(); } @@ -417,12 +417,12 @@ function gutenberg_experimental_global_styles_get_style_property() { */ function gutenberg_experimental_global_styles_get_support_keys() { return array( - '--wp--style--color--link' => array( '__experimentalColor', 'linkColor' ), - 'background' => array( '__experimentalColor', 'gradients' ), - 'backgroundColor' => array( '__experimentalColor' ), - 'color' => array( '__experimentalColor' ), - 'fontSize' => array( '__experimentalFontSize' ), - 'lineHeight' => array( '__experimentalLineHeight' ), + '--wp--style--color--link' => array( 'color', 'linkColor' ), + 'background' => array( 'color', 'gradients' ), + 'backgroundColor' => array( 'color' ), + 'color' => array( 'color' ), + 'fontSize' => array( 'fontSize' ), + 'lineHeight' => array( 'lineHeight' ), ); } @@ -484,8 +484,8 @@ function gutenberg_experimental_global_styles_get_block_data() { array( 'supports' => array( '__experimentalSelector' => ':root', - '__experimentalFontSize' => true, - '__experimentalColor' => array( + 'fontSize' => true, + 'color' => array( 'linkColor' => true, 'gradients' => true, ), diff --git a/lib/widgets-page.php b/lib/widgets-page.php index f69451a22a6c84..f620d27865b68a 100644 --- a/lib/widgets-page.php +++ b/lib/widgets-page.php @@ -77,7 +77,29 @@ function gutenberg_widgets_init( $hook ) { gutenberg_get_legacy_widget_settings() ); + // This purposefully does not rely on apply_filters( 'block_editor_settings', $settings, null ); + // Applying that filter would bring over multitude of features from the post editor, some of which + // may be undesirable. Instead of using that filter, we simply pick just the settings that are needed. $settings = gutenberg_experimental_global_styles_settings( $settings ); + $settings = gutenberg_extend_block_editor_styles( $settings ); + + $preload_paths = array( + array( '/wp/v2/media', 'OPTIONS' ), + '/__experimental/sidebars?context=edit', + ); + $preload_data = array_reduce( + $preload_paths, + 'rest_preload_api_request', + array() + ); + wp_add_inline_script( + 'wp-api-fetch', + sprintf( + 'wp.apiFetch.use( wp.apiFetch.createPreloadingMiddleware( %s ) );', + wp_json_encode( $preload_data ) + ), + 'after' + ); wp_add_inline_script( 'wp-edit-widgets', diff --git a/package-lock.json b/package-lock.json index cd429d019d8838..8ca2bd93249c56 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "gutenberg", - "version": "9.1.0-rc.1", + "version": "9.1.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -7874,8 +7874,8 @@ "integrity": "sha512-ng6Tm537E/M42GjE4TRUxQyL8sRfClcL7bQWblOCoxPZzJ2J3bdALsjeG3vDnVCIfI/R0AeFalN9KjMt0+Z/Zg==" }, "@react-native-community/masked-view": { - "version": "git+https://github.com/wordpress-mobile/react-native-masked-view.git#098004d0968f853fc7d96c2aa5f96afe7a133c58", - "from": "git+https://github.com/wordpress-mobile/react-native-masked-view.git#098004d0968f853fc7d96c2aa5f96afe7a133c58" + "version": "git+https://github.com/wordpress-mobile/react-native-masked-view.git#f65a51a3320e58404d7f38d967bfd1f42b439ca9", + "from": "git+https://github.com/wordpress-mobile/react-native-masked-view.git#f65a51a3320e58404d7f38d967bfd1f42b439ca9" }, "@react-native-community/slider": { "version": "git+https://github.com/wordpress-mobile/react-native-slider.git#d263ff16cdd9fb7352b354342522ff030f220f42", @@ -17469,6 +17469,7 @@ "@wordpress/url": "file:packages/url", "classnames": "^2.2.5", "lodash": "^4.17.19", + "reakit": "^1.1.0", "rememo": "^3.0.0" }, "dependencies": { @@ -18231,7 +18232,7 @@ "requires": { "@babel/runtime": "^7.11.2", "@react-native-community/blur": "3.6.0", - "@react-native-community/masked-view": "git+https://github.com/wordpress-mobile/react-native-masked-view.git#098004d0968f853fc7d96c2aa5f96afe7a133c58", + "@react-native-community/masked-view": "git+https://github.com/wordpress-mobile/react-native-masked-view.git#f65a51a3320e58404d7f38d967bfd1f42b439ca9", "@react-native-community/slider": "git+https://github.com/wordpress-mobile/react-native-slider.git#d263ff16cdd9fb7352b354342522ff030f220f42", "@react-navigation/native": "^5.6.1", "@react-navigation/stack": "5.6.2", @@ -59943,9 +59944,9 @@ } }, "typescript": { - "version": "3.8.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.8.3.tgz", - "integrity": "sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.0.3.tgz", + "integrity": "sha512-tEu6DGxGgRJPb/mVPIZ48e69xCn2yRmCgYmDugAVwmJ6o+0u1RI18eO7E7WBTLYLaEVVOhwQmcdhQHweux/WPg==", "dev": true }, "ua-parser-js": { diff --git a/package.json b/package.json index 9e1fadc5512373..118ac43c643078 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gutenberg", - "version": "9.1.0-rc.1", + "version": "9.1.0", "private": true, "description": "A new WordPress editor experience.", "author": "The WordPress Contributors", @@ -195,7 +195,7 @@ "style-loader": "1.0.0", "stylelint-config-wordpress": "17.0.0", "terser-webpack-plugin": "3.0.3", - "typescript": "3.8.3", + "typescript": "4.0.3", "uuid": "7.0.2", "wd": "1.12.1", "webpack": "4.42.0", diff --git a/packages/a11y/package.json b/packages/a11y/package.json index 800c9ba2d154dc..4d4be5cdbfa660 100644 --- a/packages/a11y/package.json +++ b/packages/a11y/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/a11y", - "version": "2.12.0", + "version": "2.13.0", "description": "Accessibility (a11y) utilities for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/annotations/package.json b/packages/annotations/package.json index 64eed3e119d406..dac2a023e90153 100644 --- a/packages/annotations/package.json +++ b/packages/annotations/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/annotations", - "version": "1.21.1", + "version": "1.22.0", "description": "Annotate content in the Gutenberg editor.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/api-fetch/package.json b/packages/api-fetch/package.json index 4b26e00fb8bb93..8f5225db3178bb 100644 --- a/packages/api-fetch/package.json +++ b/packages/api-fetch/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/api-fetch", - "version": "3.19.1", + "version": "3.20.0", "description": "Utility to make WordPress REST API requests.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/autop/package.json b/packages/autop/package.json index 1ba204882524d2..46d41447a9d5f3 100644 --- a/packages/autop/package.json +++ b/packages/autop/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/autop", - "version": "2.9.0", + "version": "2.10.0", "description": "WordPress's automatic paragraph functions `autop` and `removep`.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/babel-plugin-makepot/package.json b/packages/babel-plugin-makepot/package.json index 5f9a3649424dbc..6b44ddfbe85352 100644 --- a/packages/babel-plugin-makepot/package.json +++ b/packages/babel-plugin-makepot/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/babel-plugin-makepot", - "version": "3.8.0", + "version": "3.9.0", "description": "WordPress Babel internationalization (i18n) plugin.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/babel-preset-default/package.json b/packages/babel-preset-default/package.json index ad002d869a836e..38fac877c8f836 100644 --- a/packages/babel-preset-default/package.json +++ b/packages/babel-preset-default/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/babel-preset-default", - "version": "4.18.1", + "version": "4.19.0", "description": "Default Babel preset for WordPress development.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/base-styles/package.json b/packages/base-styles/package.json index d0c835a0e310ce..1cbd52fa812dea 100644 --- a/packages/base-styles/package.json +++ b/packages/base-styles/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/base-styles", - "version": "3.0.0", + "version": "3.1.0", "description": "Base SCSS utilities and variables for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/blob/CHANGELOG.md b/packages/blob/CHANGELOG.md index 1f8cd68b1aaafc..da92c6e537cd83 100644 --- a/packages/blob/CHANGELOG.md +++ b/packages/blob/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +### New feature + +- Added a new `getBlobTypeByURL` function. Returns the file type of the blob or undefined if not a blob. + ## 2.8.0 (2020-04-15) ### New feature diff --git a/packages/blob/README.md b/packages/blob/README.md index d9cd997185f4e2..91a371d1d71260 100644 --- a/packages/blob/README.md +++ b/packages/blob/README.md @@ -40,6 +40,20 @@ _Returns_ - `(File|undefined)`: The file for the blob URL. +# **getBlobTypeByURL** + +Retrieve a blob type based on URL. The file must have been created by +`createBlobURL` and not removed by `revokeBlobURL`, otherwise it will return +`undefined`. + +_Parameters_ + +- _url_ `string`: The blob URL. + +_Returns_ + +- `(string|undefined)`: The blob type. + # **isBlobURL** Check whether a url is a blob url. diff --git a/packages/blob/package.json b/packages/blob/package.json index fe38146e65b22c..4dc45ba63ecd51 100644 --- a/packages/blob/package.json +++ b/packages/blob/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/blob", - "version": "2.9.0", + "version": "2.10.0", "description": "Blob utilities for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/blob/src/index.js b/packages/blob/src/index.js index ef8ba7e2f7e394..3af66755c011e8 100644 --- a/packages/blob/src/index.js +++ b/packages/blob/src/index.js @@ -36,6 +36,19 @@ export function getBlobByURL( url ) { return cache[ url ]; } +/** + * Retrieve a blob type based on URL. The file must have been created by + * `createBlobURL` and not removed by `revokeBlobURL`, otherwise it will return + * `undefined`. + * + * @param {string} url The blob URL. + * + * @return {string|undefined} The blob type. + */ +export function getBlobTypeByURL( url ) { + return getBlobByURL( url )?.type.split( '/' )[ 0 ]; // 0: media type , 1: file extension eg ( type: 'image/jpeg' ). +} + /** * Remove the resource and file cache from memory. * diff --git a/packages/blob/src/test/index.js b/packages/blob/src/test/index.js index 110340e13639e2..4e59917522b519 100644 --- a/packages/blob/src/test/index.js +++ b/packages/blob/src/test/index.js @@ -1,7 +1,7 @@ /** * Internal dependencies */ -import { isBlobURL } from '../'; +import { isBlobURL, getBlobTypeByURL } from '../'; describe( 'isBlobURL', () => { it( 'returns true if the url starts with "blob:"', () => { @@ -16,3 +16,13 @@ describe( 'isBlobURL', () => { expect( isBlobURL() ).toBe( false ); } ); } ); + +describe( 'getBlobTypeByURL', () => { + it( 'returns undefined if the blob is not found', () => { + expect( getBlobTypeByURL( 'blob:notexisting' ) ).toBe( undefined ); + } ); + + it( 'returns undefined if the url is not defined', () => { + expect( getBlobTypeByURL() ).toBe( undefined ); + } ); +} ); diff --git a/packages/block-directory/package.json b/packages/block-directory/package.json index 075f05713a225e..96d4a8c5858adf 100644 --- a/packages/block-directory/package.json +++ b/packages/block-directory/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/block-directory", - "version": "1.15.0", + "version": "1.16.0", "description": "Extend editor with block directory features to search, download and install blocks.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/block-directory/src/store/test/actions.js b/packages/block-directory/src/store/test/actions.js index b74f7f1a657725..516f6deef3fe1d 100644 --- a/packages/block-directory/src/store/test/actions.js +++ b/packages/block-directory/src/store/test/actions.js @@ -81,7 +81,7 @@ describe( 'actions', () => { args: [], selectorName: 'getBlockTypes', storeKey: 'core/blocks', - type: 'SELECT', + type: '@@data/RESOLVE_SELECT', } ); expect( generator.next( [ block ] ).value ).toEqual( { @@ -143,7 +143,7 @@ describe( 'actions', () => { args: [], selectorName: 'getBlockTypes', storeKey: 'core/blocks', - type: 'SELECT', + type: '@@data/RESOLVE_SELECT', } ); expect( generator.next( [ inactiveBlock ] ).value ).toEqual( { @@ -274,7 +274,7 @@ describe( 'actions', () => { data: null, }; expect( generator.throw( apiError ).value ).toMatchObject( { - type: 'DISPATCH', + type: '@@data/DISPATCH', actionName: 'createErrorNotice', storeKey: 'core/notices', } ); diff --git a/packages/block-editor/CHANGELOG.md b/packages/block-editor/CHANGELOG.md index 9f6628a24fb1ee..7179c21f6cb6fb 100644 --- a/packages/block-editor/CHANGELOG.md +++ b/packages/block-editor/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 5.0.0 (2020-10-06) + ### Breaking Changes - The block editor does not contain default colors, gradients, and font sizes anymore. If one wants to take advantage of these features, please explicitly pass colors, gradients, and/or settings or use the new __experimentalFeatures setting that is available. diff --git a/packages/block-editor/README.md b/packages/block-editor/README.md index a6cf4764bf57a6..705eb7c4148897 100644 --- a/packages/block-editor/README.md +++ b/packages/block-editor/README.md @@ -30,8 +30,8 @@ function MyEditorComponent () { return ( updateBlocks( blocks ) } + onChange={ ( blocks ) => updateBlocks( blocks ) } > @@ -400,6 +400,10 @@ _Related_ - +# **LineHeightControl** + +Undocumented declaration. + # **MediaPlaceholder** _Related_ @@ -558,6 +562,26 @@ _Related_ Undocumented declaration. +# **useBlockProps** + +This hook is used to lightly mark an element as a block element. The element +should be the outermost element of a block. Call this hook and pass the +returned props to the element to mark as a block. If you define a ref for the +element, it is important to pass the ref to this hook, which the hook in turn +will pass to the component through the props it returns. Optionally, you can +also pass any other props through this hook, and they will be merged and +returned. + +_Parameters_ + +- _props_ `Object`: Optional. Props to pass to the element. Must contain the ref if one is defined. +- _options_ `Object`: Options for internal use only. +- _options.\_\_unstableIsHtml_ `boolean`: + +_Returns_ + +- `Object`: Props to pass to the element to mark as a block. + # **validateThemeColors** Given an array of theme colors checks colors for validity diff --git a/packages/block-editor/package.json b/packages/block-editor/package.json index 4b7cc0aaf5e689..dee14d5468e36a 100644 --- a/packages/block-editor/package.json +++ b/packages/block-editor/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/block-editor", - "version": "4.5.0", + "version": "5.0.0", "description": "Generic block editor.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/block-editor/src/components/block-edit/edit.js b/packages/block-editor/src/components/block-edit/edit.js index 84044be7cc60db..0746699eb145dc 100644 --- a/packages/block-editor/src/components/block-edit/edit.js +++ b/packages/block-editor/src/components/block-edit/edit.js @@ -50,13 +50,11 @@ export const Edit = ( props ) => { // with which a block is displayed. If `blockType` is valid, assign // them preferentially as the render value for the block. const Component = blockType.edit || blockType.save; - const lightBlockWrapper = hasBlockSupport( - blockType, - 'lightBlockWrapper', - false - ); - if ( lightBlockWrapper ) { + if ( + blockType.apiVersion > 1 || + hasBlockSupport( blockType, 'lightBlockWrapper', false ) + ) { return ; } diff --git a/packages/block-editor/src/components/block-edit/test/edit.js b/packages/block-editor/src/components/block-edit/test/edit.js index 3e89608bb096e5..5525bcf30aaab0 100644 --- a/packages/block-editor/src/components/block-edit/test/edit.js +++ b/packages/block-editor/src/components/block-edit/test/edit.js @@ -104,12 +104,10 @@ describe( 'Edit', () => { it( 'should assign context', () => { const edit = ( { context } ) => context.value; registerBlockType( 'core/test-block', { + apiVersion: 2, category: 'text', title: 'block title', usesContext: [ 'value' ], - supports: { - lightBlockWrapper: true, - }, edit, save: noop, } ); diff --git a/packages/block-editor/src/components/block-list-appender/index.js b/packages/block-editor/src/components/block-list-appender/index.js index e2a4dbb0ebd6bc..f81e1af2458609 100644 --- a/packages/block-editor/src/components/block-list-appender/index.js +++ b/packages/block-editor/src/components/block-list-appender/index.js @@ -7,6 +7,7 @@ import classnames from 'classnames'; /** * WordPress dependencies */ +import { createContext, useContext } from '@wordpress/element'; import { withSelect } from '@wordpress/data'; import { getDefaultBlockName } from '@wordpress/blocks'; @@ -16,6 +17,9 @@ import { getDefaultBlockName } from '@wordpress/blocks'; import DefaultBlockAppender from '../default-block-appender'; import ButtonBlockAppender from '../button-block-appender'; +// A Context to store the map of the appender map. +export const AppenderContext = createContext(); + function stopPropagation( event ) { event.stopPropagation(); } @@ -30,6 +34,8 @@ function BlockListAppender( { selectedBlockClientId, tagName: TagName = 'div', } ) { + const appenderMap = useContext( AppenderContext ); + if ( isLocked || CustomAppender === false ) { return null; } @@ -89,7 +95,20 @@ function BlockListAppender( { // Prevent the block from being selected when the appender is // clicked. onFocus={ stopPropagation } - className={ classnames( 'block-list-appender', className ) } + className={ classnames( + 'block-list-appender', + 'wp-block', + className + ) } + ref={ ( ref ) => { + if ( ref ) { + // Set the reference of the "Appender" with `rootClientId` as key. + appenderMap.set( rootClientId || '', ref ); + } else { + // If it un-mounts, cleanup the map. + appenderMap.delete( rootClientId || '' ); + } + } } > { appender } diff --git a/packages/block-editor/src/components/block-list/block-wrapper.js b/packages/block-editor/src/components/block-list/block-wrapper.js index 4aef321a0bf20b..bca876163cc28f 100644 --- a/packages/block-editor/src/components/block-list/block-wrapper.js +++ b/packages/block-editor/src/components/block-list/block-wrapper.js @@ -19,6 +19,7 @@ import { ENTER, BACKSPACE, DELETE } from '@wordpress/keycodes'; import { __, sprintf } from '@wordpress/i18n'; import { useSelect, useDispatch } from '@wordpress/data'; import deprecated from '@wordpress/deprecated'; +import { __unstableGetBlockProps as getBlockProps } from '@wordpress/blocks'; /** * Internal dependencies @@ -30,12 +31,13 @@ import { BlockListBlockContext } from './block'; import ELEMENTS from './block-wrapper-elements'; /** - * This hook is used to lighly mark an element as a block element. Call this - * hook and pass the returned props to the element to mark as a block. If you - * define a ref for the element, it is important to pass the ref to this hook, - * which the hooks in turn will pass to the component through the props it - * returns. Optionally, you can also pass any other props through this hook, and - * they will be merged and returned. + * This hook is used to lightly mark an element as a block element. The element + * should be the outermost element of a block. Call this hook and pass the + * returned props to the element to mark as a block. If you define a ref for the + * element, it is important to pass the ref to this hook, which the hook in turn + * will pass to the component through the props it returns. Optionally, you can + * also pass any other props through this hook, and they will be merged and + * returned. * * @param {Object} props Optional. Props to pass to the element. Must contain * the ref if one is defined. @@ -44,7 +46,7 @@ import ELEMENTS from './block-wrapper-elements'; * * @return {Object} Props to pass to the element to mark as a block. */ -export function useBlockWrapperProps( props = {}, { __unstableIsHtml } = {} ) { +export function useBlockProps( props = {}, { __unstableIsHtml } = {} ) { const fallbackRef = useRef(); const ref = props.ref || fallbackRef; const onSelectionStart = useContext( Context ); @@ -111,6 +113,20 @@ export function useBlockWrapperProps( props = {}, { __unstableIsHtml } = {} ) { } }, [ isSelected, isFirstMultiSelected, isLastMultiSelected ] ); + // Set new block node if it changes. + // This effect should happen on every render, so no dependencies should be + // added. + useEffect( () => { + const node = ref.current; + setBlockNodes( ( nodes ) => { + if ( ! nodes[ clientId ] || nodes[ clientId ] === node ) { + return nodes; + } + + return { ...nodes, [ clientId ]: node }; + } ); + } ); + // translators: %s: Type of block (i.e. Text, Image etc) const blockLabel = sprintf( __( 'Block: %s' ), blockTitle ); @@ -286,13 +302,20 @@ export function useBlockWrapperProps( props = {}, { __unstableIsHtml } = {} ) { }; } +/** + * Call within a save function to get the props for the block wrapper. + * + * @param {Object} props Optional. Props to pass to the element. + */ +useBlockProps.save = getBlockProps; + const BlockComponent = forwardRef( ( { children, tagName: TagName = 'div', ...props }, ref ) => { deprecated( 'wp.blockEditor.__experimentalBlock', { - alternative: 'wp.blockEditor.__experimentalUseBlockWrapperProps', + alternative: 'wp.blockEditor.useBlockProps', } ); - const blockWrapperProps = useBlockWrapperProps( { ...props, ref } ); - return { children }; + const blockProps = useBlockProps( { ...props, ref } ); + return { children }; } ); diff --git a/packages/block-editor/src/components/block-list/block-wrapper.native.js b/packages/block-editor/src/components/block-list/block-wrapper.native.js index 10aea4bb9edd71..122ff1e4f514c5 100644 --- a/packages/block-editor/src/components/block-list/block-wrapper.native.js +++ b/packages/block-editor/src/components/block-list/block-wrapper.native.js @@ -1,12 +1,19 @@ +/** + * WordPress dependencies + */ +import { __unstableGetBlockProps as getBlockProps } from '@wordpress/blocks'; + /** * Internal dependencies */ import ELEMENTS from './block-wrapper-elements'; -export function useBlockWrapperProps( props = {} ) { +export function useBlockProps( props = {} ) { return props; } +useBlockProps.save = getBlockProps; + const ExtendedBlockComponent = ELEMENTS.reduce( ( acc, element ) => { acc[ element ] = element; return acc; diff --git a/packages/block-editor/src/components/block-list/block.js b/packages/block-editor/src/components/block-list/block.js index 345005caf1daaa..9d151b9793d3cf 100644 --- a/packages/block-editor/src/components/block-list/block.js +++ b/packages/block-editor/src/components/block-list/block.js @@ -40,7 +40,7 @@ import BlockInvalidWarning from './block-invalid-warning'; import BlockCrashWarning from './block-crash-warning'; import BlockCrashBoundary from './block-crash-boundary'; import BlockHtml from './block-html'; -import { useBlockWrapperProps } from './block-wrapper'; +import { useBlockProps } from './block-wrapper'; export const BlockListBlockContext = createContext(); @@ -70,7 +70,7 @@ function mergeWrapperProps( propsA, propsB ) { function Block( { children, isHtml, ...props } ) { return ( -
+
{ children }
); @@ -126,11 +126,9 @@ function BlockListBlock( { const onBlockError = () => setErrorState( true ); const blockType = getBlockType( name ); - const lightBlockWrapper = hasBlockSupport( - blockType, - 'lightBlockWrapper', - false - ); + const lightBlockWrapper = + blockType.apiVersion > 1 || + hasBlockSupport( blockType, 'lightBlockWrapper', false ); const isUnregisteredBlock = name === getUnregisteredTypeHandlerName(); // Determine whether the block has props to apply to the wrapper. diff --git a/packages/block-editor/src/components/block-list/index.js b/packages/block-editor/src/components/block-list/index.js index 22ede3bc48e677..85992de8532967 100644 --- a/packages/block-editor/src/components/block-list/index.js +++ b/packages/block-editor/src/components/block-list/index.js @@ -13,10 +13,15 @@ import { useRef, forwardRef } from '@wordpress/element'; * Internal dependencies */ import BlockListBlock from './block'; -import BlockListAppender from '../block-list-appender'; +import BlockListAppender, { AppenderContext } from '../block-list-appender'; import RootContainer from './root-container'; import useBlockDropZone from '../use-block-drop-zone'; +/** + * A map to store the reference of each "Appenders" rendered with `rootClientId` as key. + */ +const appenderMap = new Map(); + /** * If the block count exceeds the threshold, we disable the reordering animation * to avoid laginess. @@ -82,57 +87,60 @@ function BlockList( dropTargetIndex === blockClientIds.length && isDraggingBlocks; return ( - - { blockClientIds.map( ( clientId, index ) => { - const isBlockInSelection = hasMultiSelection - ? multiSelectedBlockClientIds.includes( clientId ) - : selectedBlockClientId === clientId; + + + { blockClientIds.map( ( clientId, index ) => { + const isBlockInSelection = hasMultiSelection + ? multiSelectedBlockClientIds.includes( clientId ) + : selectedBlockClientId === clientId; - const isDropTarget = - dropTargetIndex === index && isDraggingBlocks; + const isDropTarget = + dropTargetIndex === index && isDraggingBlocks; - return ( - - - - ); - } ) } - + + + ); } ) } - /> - + + + ); } diff --git a/packages/block-editor/src/components/block-list/insertion-point.js b/packages/block-editor/src/components/block-list/insertion-point.js index c7eb0e8d6ee80a..a54da4b719ec32 100644 --- a/packages/block-editor/src/components/block-list/insertion-point.js +++ b/packages/block-editor/src/components/block-list/insertion-point.js @@ -7,7 +7,7 @@ import classnames from 'classnames'; * WordPress dependencies */ import { useSelect } from '@wordpress/data'; -import { useState, useRef } from '@wordpress/element'; +import { useState, useRef, useMemo, useContext } from '@wordpress/element'; import { Popover } from '@wordpress/components'; import { placeCaretAtVerticalEdge } from '@wordpress/dom'; @@ -17,6 +17,7 @@ import { placeCaretAtVerticalEdge } from '@wordpress/dom'; import Inserter from '../inserter'; import { getClosestTabbable } from '../writing-flow'; import { getBlockDOMNode } from '../../utils/dom'; +import { AppenderContext } from '../block-list-appender'; function InsertionPointInserter( { clientId, @@ -31,10 +32,14 @@ function InsertionPointInserter( { getMultiSelectedBlockClientIds, getSelectedBlockClientId, hasMultiSelection, + getSettings, } = select( 'core/block-editor' ); + const { hasReducedUI } = getSettings(); + if ( hasReducedUI ) { + return true; + } const multiSelectedBlockClientIds = getMultiSelectedBlockClientIds(); const selectedBlockClientId = getSelectedBlockClientId(); - return hasMultiSelection() ? multiSelectedBlockClientIds.includes( clientId ) : clientId === selectedBlockClientId; @@ -94,13 +99,24 @@ function InsertionPointInserter( { function InsertionPointPopover( { clientId, + rootClientId, isInserterShown, isInserterForced, setIsInserterForced, containerRef, showInsertionPoint, } ) { - const element = getBlockDOMNode( clientId ); + const appenderMap = useContext( AppenderContext ); + const element = useMemo( () => { + if ( clientId ) { + return getBlockDOMNode( clientId ); + } + + // Can't find the element, might be at the end of the block list, or inside an empty block list. + // We instead try to find the "Appender" and place the indicator above it. + // `rootClientId` could be null or undefined when there's no parent block, we normalize it to an empty string. + return appenderMap.get( rootClientId || '' ); + }, [ clientId, rootClientId, appenderMap ] ); return ( { - const { - isMultiSelecting: _isMultiSelecting, - isBlockInsertionPointVisible, - getBlockInsertionPoint, - getBlockOrder, - } = select( 'core/block-editor' ); - - const insertionPoint = getBlockInsertionPoint(); - const order = getBlockOrder( insertionPoint.rootClientId ); - - return { - isMultiSelecting: _isMultiSelecting(), - isInserterVisible: isBlockInsertionPointVisible(), - selectedClientId: order[ insertionPoint.index ], - }; - }, - [] - ); + const { + isMultiSelecting, + isInserterVisible, + selectedClientId, + selectedRootClientId, + } = useSelect( ( select ) => { + const { + isMultiSelecting: _isMultiSelecting, + isBlockInsertionPointVisible, + getBlockInsertionPoint, + getBlockOrder, + } = select( 'core/block-editor' ); + + const insertionPoint = getBlockInsertionPoint(); + const order = getBlockOrder( insertionPoint.rootClientId ); + + return { + isMultiSelecting: _isMultiSelecting(), + isInserterVisible: isBlockInsertionPointVisible(), + selectedClientId: order[ insertionPoint.index ], + selectedRootClientId: insertionPoint.rootClientId, + }; + }, [] ); function onMouseMove( event ) { if ( @@ -211,6 +230,7 @@ export default function InsertionPoint( { children, containerRef } ) { clientId={ isInserterVisible ? selectedClientId : inserterClientId } + rootClientId={ selectedRootClientId } isInserterShown={ isInserterShown } isInserterForced={ isInserterForced } setIsInserterForced={ setIsInserterForced } diff --git a/packages/block-editor/src/components/block-list/style.scss b/packages/block-editor/src/components/block-list/style.scss index 83b63b4ee31dcf..77b2a30a9dab8f 100644 --- a/packages/block-editor/src/components/block-list/style.scss +++ b/packages/block-editor/src/components/block-list/style.scss @@ -365,6 +365,10 @@ position: relative; z-index: z-index(".block-editor-block-list__insertion-point"); margin-top: -$block-padding * 2; + + &.is-insert-after { + margin-top: $block-padding; + } } .block-editor-block-list__insertion-point-indicator { @@ -538,63 +542,20 @@ .block-editor-block-mover.is-horizontal .block-editor-block-mover-button.block-editor-block-mover-button { min-width: $block-toolbar-height/2; width: $block-toolbar-height/2; - - // Animate buttons on hover. - &.is-up-button { - svg { - transition: ease-in-out transform 0.1s; - @include reduce-motion("transition"); - } - &:focus, - &:hover { - svg { - transform: translateX(-2px); - } - } - } - - &.is-down-button { - svg { - transition: ease-in-out transform 0.1s; - @include reduce-motion("transition"); - } - &:focus, - &:hover { - svg { - transform: translateX(2px); - } - } - } } .block-editor-block-mover:not(.is-horizontal) { - // Position SVGs. Animate buttons on hover. + // Position SVGs. .block-editor-block-mover-button { &.is-up-button { svg { margin-top: 2px; - transition: ease-in-out transform 0.1s; - @include reduce-motion("transition"); - } - &:focus, - &:hover { - svg { - transform: translateY(-2px); - } } } &.is-down-button { svg { margin-bottom: 3px; - transition: ease-in-out transform 0.1s; - @include reduce-motion("transition"); - } - &:focus, - &:hover { - svg { - transform: translateY(2px); - } } } diff --git a/packages/block-editor/src/components/block-list/use-multi-selection.js b/packages/block-editor/src/components/block-list/use-multi-selection.js index 3e1b86564eff76..696ed2f55c5396 100644 --- a/packages/block-editor/src/components/block-list/use-multi-selection.js +++ b/packages/block-editor/src/components/block-list/use-multi-selection.js @@ -229,19 +229,19 @@ export default function useMultiSelection( ref ) { }, [ onSelectionChange, stopMultiSelect ] ); // Only clean up when unmounting, these are added and cleaned up elsewhere. - useEffect( - () => () => { - const { ownerDocument } = ref.current; - const { defaultView } = ownerDocument; + useEffect( () => { + const { ownerDocument } = ref.current; + const { defaultView } = ownerDocument; + + return () => { ownerDocument.removeEventListener( 'selectionchange', onSelectionChange ); defaultView.removeEventListener( 'mouseup', onSelectionEnd ); defaultView.cancelAnimationFrame( rafId.current ); - }, - [ onSelectionChange, onSelectionEnd ] - ); + }; + }, [ onSelectionChange, onSelectionEnd ] ); /** * Binds event handlers to the document for tracking a pending multi-select diff --git a/packages/block-editor/src/components/block-selection-clearer/index.js b/packages/block-editor/src/components/block-selection-clearer/index.js index 69f49a37b4dcee..b97b8895b5a9bb 100644 --- a/packages/block-editor/src/components/block-selection-clearer/index.js +++ b/packages/block-editor/src/components/block-selection-clearer/index.js @@ -1,78 +1,26 @@ -/** - * External dependencies - */ -import { omit } from 'lodash'; - /** * WordPress dependencies */ -import { Component } from '@wordpress/element'; -import { withSelect, withDispatch } from '@wordpress/data'; -import { compose } from '@wordpress/compose'; - -class BlockSelectionClearer extends Component { - constructor() { - super( ...arguments ); +import { useSelect, useDispatch } from '@wordpress/data'; - this.bindContainer = this.bindContainer.bind( this ); - this.clearSelectionIfFocusTarget = this.clearSelectionIfFocusTarget.bind( - this +function useBlockSelectionClearer() { + const hasSelection = useSelect( ( select ) => { + const { hasSelectedBlock, hasMultiSelection } = select( + 'core/block-editor' ); - } - - bindContainer( ref ) { - this.container = ref; - } - /** - * Clears the selected block on focus if the container is the target of the - * focus. This assumes no other descendents have received focus until event - * has bubbled to the container. - * - * @param {FocusEvent} event Focus event. - */ - clearSelectionIfFocusTarget( event ) { - const { - hasSelectedBlock, - hasMultiSelection, - clearSelectedBlock, - } = this.props; + return hasSelectedBlock() || hasMultiSelection(); + } ); + const { clearSelectedBlock } = useDispatch( 'core/block-editor' ); - const hasSelection = hasSelectedBlock || hasMultiSelection; - if ( event.target === this.container && hasSelection ) { + return ( event ) => { + if ( event.target === event.currentTarget && hasSelection ) { clearSelectedBlock(); } - } - - render() { - return ( -
- ); - } + }; } -export default compose( [ - withSelect( ( select ) => { - const { hasSelectedBlock, hasMultiSelection } = select( - 'core/block-editor' - ); - - return { - hasSelectedBlock: hasSelectedBlock(), - hasMultiSelection: hasMultiSelection(), - }; - } ), - withDispatch( ( dispatch ) => { - const { clearSelectedBlock } = dispatch( 'core/block-editor' ); - return { clearSelectedBlock }; - } ), -] )( BlockSelectionClearer ); +export default function BlockSelectionClearer( props ) { + const onFocus = useBlockSelectionClearer(); + return
; +} diff --git a/packages/block-editor/src/components/block-toolbar/index.js b/packages/block-editor/src/components/block-toolbar/index.js index 06929a56076c08..bed8b921a2fe91 100644 --- a/packages/block-editor/src/components/block-toolbar/index.js +++ b/packages/block-editor/src/components/block-toolbar/index.js @@ -33,6 +33,7 @@ export default function BlockToolbar( { blockClientId, blockType, hasFixedToolbar, + hasReducedUI, isValid, isVisual, } = useSelect( ( select ) => { @@ -47,6 +48,7 @@ export default function BlockToolbar( { const selectedBlockClientIds = getSelectedBlockClientIds(); const selectedBlockClientId = selectedBlockClientIds[ 0 ]; const blockRootClientId = getBlockRootClientId( selectedBlockClientId ); + const settings = getSettings(); return { blockClientIds: selectedBlockClientIds, @@ -54,7 +56,8 @@ export default function BlockToolbar( { blockType: selectedBlockClientId && getBlockType( getBlockName( selectedBlockClientId ) ), - hasFixedToolbar: getSettings().hasFixedToolbar, + hasFixedToolbar: settings.hasFixedToolbar, + hasReducedUI: settings.hasReducedUI, rootClientId: blockRootClientId, isValid: selectedBlockClientIds.every( ( id ) => isBlockValid( id ) @@ -72,6 +75,9 @@ export default function BlockToolbar( { { ref: nodeRef, onChange( isFocused ) { + if ( isFocused && hasReducedUI ) { + return; + } toggleBlockHighlight( blockClientId, isFocused ); }, } @@ -117,7 +123,7 @@ export default function BlockToolbar( { ) } diff --git a/packages/block-editor/src/components/block-toolbar/style.scss b/packages/block-editor/src/components/block-toolbar/style.scss index b1f97a9eb60ddd..bffe229b714e04 100644 --- a/packages/block-editor/src/components/block-toolbar/style.scss +++ b/packages/block-editor/src/components/block-toolbar/style.scss @@ -105,11 +105,6 @@ opacity: 1; transform: translateY(-($block-toolbar-height + $grid-unit-15)); } - - // Hide the Parent button in Top Toolbar mode. - .edit-post-header-toolbar__block-toolbar & { - display: none; - } } .block-editor-block-toolbar-animated-width-container { diff --git a/packages/block-editor/src/components/index.js b/packages/block-editor/src/components/index.js index ab75507f8a1714..7719bfff230e89 100644 --- a/packages/block-editor/src/components/index.js +++ b/packages/block-editor/src/components/index.js @@ -36,7 +36,7 @@ export { default as InnerBlocks } from './inner-blocks'; export { default as InspectorAdvancedControls } from './inspector-advanced-controls'; export { default as InspectorControls } from './inspector-controls'; export { default as __experimentalLinkControl } from './link-control'; -export { default as __experimentalLineHeightControl } from './line-height-control'; +export { default as LineHeightControl } from './line-height-control'; export { default as MediaReplaceFlow } from './media-replace-flow'; export { default as MediaPlaceholder } from './media-placeholder'; export { default as MediaUpload } from './media-upload'; @@ -70,7 +70,7 @@ export { default as BlockInspector } from './block-inspector'; export { default as BlockList } from './block-list'; export { Block as __experimentalBlock, - useBlockWrapperProps as __experimentalUseBlockWrapperProps, + useBlockProps, } from './block-list/block-wrapper'; export { default as BlockMover } from './block-mover'; export { default as BlockPreview } from './block-preview'; diff --git a/packages/block-editor/src/components/index.native.js b/packages/block-editor/src/components/index.native.js index e15f4b6c252e01..8fa8e93b903040 100644 --- a/packages/block-editor/src/components/index.native.js +++ b/packages/block-editor/src/components/index.native.js @@ -13,7 +13,7 @@ export { default as AlignmentToolbar } from './alignment-toolbar'; export { default as InnerBlocks } from './inner-blocks'; export { default as InspectorAdvancedControls } from './inspector-advanced-controls'; export { default as InspectorControls } from './inspector-controls'; -export { default as __experimentalLineHeightControl } from './line-height-control'; +export { default as LineHeightControl } from './line-height-control'; export { default as PlainText } from './plain-text'; export { default as RichText, @@ -59,7 +59,7 @@ export { default as __unstableEditorStyles } from './editor-styles'; export { default as Inserter } from './inserter'; export { Block as __experimentalBlock, - useBlockWrapperProps as __experimentalUseBlockWrapperProps, + useBlockProps, } from './block-list/block-wrapper'; export { default as FloatingToolbar } from './floating-toolbar'; diff --git a/packages/block-editor/src/components/inserter/hooks/use-insertion-point.js b/packages/block-editor/src/components/inserter/hooks/use-insertion-point.js index 2ee224d96a4d77..bb240e67859d43 100644 --- a/packages/block-editor/src/components/inserter/hooks/use-insertion-point.js +++ b/packages/block-editor/src/components/inserter/hooks/use-insertion-point.js @@ -32,6 +32,7 @@ function useInsertionPoint( { clientId, isAppender, selectBlockOnInsert, + insertionIndex, } ) { const { destinationRootClientId, @@ -76,12 +77,16 @@ function useInsertionPoint( { } = useDispatch( 'core/block-editor' ); function getInsertionIndex() { + if ( insertionIndex !== undefined ) { + return insertionIndex; + } + // If the clientId is defined, we insert at the position of the block. if ( clientId ) { return getBlockIndex( clientId, destinationRootClientId ); } - // If there a selected block, we insert after the selected block. + // If there's a selected block, and the selected block is not the destination root block, we insert after the selected block. const end = getBlockSelectionEnd(); if ( ! isAppender && end ) { return getBlockIndex( end, destinationRootClientId ) + 1; diff --git a/packages/block-editor/src/components/inserter/library.js b/packages/block-editor/src/components/inserter/library.js index d22966dff2f67c..74e72702042d1f 100644 --- a/packages/block-editor/src/components/inserter/library.js +++ b/packages/block-editor/src/components/inserter/library.js @@ -19,7 +19,8 @@ function InserterLibrary( { isAppender, showInserterHelpPanel, showMostUsedBlocks = false, - __experimentalSelectBlockOnInsert: selectBlockOnInsert, + __experimentalSelectBlockOnInsert, + __experimentalInsertionIndex, onSelect = noop, } ) { const destinationRootClientId = useSelect( @@ -41,7 +42,10 @@ function InserterLibrary( { isAppender={ isAppender } showInserterHelpPanel={ showInserterHelpPanel } showMostUsedBlocks={ showMostUsedBlocks } - __experimentalSelectBlockOnInsert={ selectBlockOnInsert } + __experimentalSelectBlockOnInsert={ + __experimentalSelectBlockOnInsert + } + __experimentalInsertionIndex={ __experimentalInsertionIndex } /> ); } diff --git a/packages/block-editor/src/components/inserter/menu.js b/packages/block-editor/src/components/inserter/menu.js index 3d59359799397a..8669d52b51a6a0 100644 --- a/packages/block-editor/src/components/inserter/menu.js +++ b/packages/block-editor/src/components/inserter/menu.js @@ -26,6 +26,7 @@ function InserterMenu( { clientId, isAppender, __experimentalSelectBlockOnInsert, + __experimentalInsertionIndex, onSelect, showInserterHelpPanel, showMostUsedBlocks, @@ -46,6 +47,7 @@ function InserterMenu( { clientId, isAppender, selectBlockOnInsert: __experimentalSelectBlockOnInsert, + insertionIndex: __experimentalInsertionIndex, } ); const { hasPatterns, hasReusableBlocks } = useSelect( ( select ) => { const { diff --git a/packages/block-editor/src/components/media-upload/index.native.js b/packages/block-editor/src/components/media-upload/index.native.js index 1e9c5415580310..d413171cd114be 100644 --- a/packages/block-editor/src/components/media-upload/index.native.js +++ b/packages/block-editor/src/components/media-upload/index.native.js @@ -160,7 +160,7 @@ export class MediaUpload extends React.Component { } render() { - const { allowedTypes = [], isReplacingMedia } = this.props; + const { allowedTypes = [], isReplacingMedia, multiple } = this.props; const isOneType = allowedTypes.length === 1; const isImage = isOneType && allowedTypes.includes( MEDIA_TYPE_IMAGE ); const isVideo = isOneType && allowedTypes.includes( MEDIA_TYPE_VIDEO ); @@ -174,7 +174,9 @@ export class MediaUpload extends React.Component { if ( isReplacingMedia ) { pickerTitle = __( 'Replace image' ); } else { - pickerTitle = __( 'Choose image' ); + pickerTitle = multiple + ? __( 'Choose images' ) + : __( 'Choose image' ); } } else if ( isVideo ) { if ( isReplacingMedia ) { diff --git a/packages/block-editor/src/components/warning/style.scss b/packages/block-editor/src/components/warning/style.scss index 1fdb061d2af34b..cc082b0ea4e69c 100644 --- a/packages/block-editor/src/components/warning/style.scss +++ b/packages/block-editor/src/components/warning/style.scss @@ -14,6 +14,7 @@ line-height: $default-line-height; font-family: $default-font; font-size: $default-font-size; + color: $gray-900; margin: 0 0 1em; } diff --git a/packages/block-editor/src/hooks/color.js b/packages/block-editor/src/hooks/color.js index d1962e7011cb2f..2f083d9af2f942 100644 --- a/packages/block-editor/src/hooks/color.js +++ b/packages/block-editor/src/hooks/color.js @@ -30,7 +30,7 @@ import { cleanEmptyObject } from './utils'; import ColorPanel from './color-panel'; import useEditorFeature from '../components/use-editor-feature'; -export const COLOR_SUPPORT_KEY = '__experimentalColor'; +export const COLOR_SUPPORT_KEY = 'color'; const EMPTY_ARRAY = []; const hasColorSupport = ( blockType ) => { @@ -40,7 +40,7 @@ const hasColorSupport = ( blockType ) => { const colorSupport = getBlockSupport( blockType, COLOR_SUPPORT_KEY ); return ( colorSupport && - ( colorSupport.linkColor === true || + ( colorSupport.link === true || colorSupport.gradient === true || colorSupport.background !== false || colorSupport.text !== false ) @@ -54,7 +54,7 @@ const hasLinkColorSupport = ( blockType ) => { const colorSupport = getBlockSupport( blockType, COLOR_SUPPORT_KEY ); - return isObject( colorSupport ) && !! colorSupport.linkColor; + return isObject( colorSupport ) && !! colorSupport.link; }; const hasGradientSupport = ( blockType ) => { diff --git a/packages/block-editor/src/hooks/font-size.js b/packages/block-editor/src/hooks/font-size.js index f993da5c8e0d76..c82855de332ca7 100644 --- a/packages/block-editor/src/hooks/font-size.js +++ b/packages/block-editor/src/hooks/font-size.js @@ -18,7 +18,7 @@ import { import { cleanEmptyObject } from './utils'; import useEditorFeature from '../components/use-editor-feature'; -export const FONT_SIZE_SUPPORT_KEY = '__experimentalFontSize'; +export const FONT_SIZE_SUPPORT_KEY = 'fontSize'; /** * Filters registered block settings, extending attributes to include diff --git a/packages/block-editor/src/hooks/line-height.js b/packages/block-editor/src/hooks/line-height.js index b1390192608b79..d47e5eadf0788f 100644 --- a/packages/block-editor/src/hooks/line-height.js +++ b/packages/block-editor/src/hooks/line-height.js @@ -10,7 +10,7 @@ import LineHeightControl from '../components/line-height-control'; import { cleanEmptyObject } from './utils'; import useEditorFeature from '../components/use-editor-feature'; -export const LINE_HEIGHT_SUPPORT_KEY = '__experimentalLineHeight'; +export const LINE_HEIGHT_SUPPORT_KEY = 'lineHeight'; /** * Inspector control panel containing the line height related configuration diff --git a/packages/block-editor/src/hooks/padding.js b/packages/block-editor/src/hooks/padding.js index 7632943e5d075d..a83d6aff730f00 100644 --- a/packages/block-editor/src/hooks/padding.js +++ b/packages/block-editor/src/hooks/padding.js @@ -3,7 +3,7 @@ */ import { __ } from '@wordpress/i18n'; import { Platform } from '@wordpress/element'; -import { hasBlockSupport } from '@wordpress/blocks'; +import { getBlockSupport } from '@wordpress/blocks'; import { __experimentalBoxControl as BoxControl } from '@wordpress/components'; /** @@ -12,7 +12,12 @@ import { __experimentalBoxControl as BoxControl } from '@wordpress/components'; import { cleanEmptyObject } from './utils'; import { useCustomUnits } from '../components/unit-control'; -export const PADDING_SUPPORT_KEY = '__experimentalPadding'; +export const SPACING_SUPPORT_KEY = 'spacing'; + +const hasPaddingSupport = ( blockName ) => { + const spacingSupport = getBlockSupport( blockName, SPACING_SUPPORT_KEY ); + return spacingSupport && spacingSupport.padding !== false; +}; /** * Inspector control panel containing the line height related configuration @@ -30,7 +35,7 @@ export function PaddingEdit( props ) { const units = useCustomUnits(); - if ( ! hasBlockSupport( blockName, PADDING_SUPPORT_KEY ) ) { + if ( ! hasPaddingSupport( blockName ) ) { return null; } diff --git a/packages/block-editor/src/hooks/style.js b/packages/block-editor/src/hooks/style.js index fe2f66a9c141c7..adec7bb0d02df0 100644 --- a/packages/block-editor/src/hooks/style.js +++ b/packages/block-editor/src/hooks/style.js @@ -18,13 +18,13 @@ import { createHigherOrderComponent } from '@wordpress/compose'; */ import { COLOR_SUPPORT_KEY, ColorEdit } from './color'; import { TypographyPanel, TYPOGRAPHY_SUPPORT_KEYS } from './typography'; -import { PADDING_SUPPORT_KEY, PaddingEdit } from './padding'; +import { SPACING_SUPPORT_KEY, PaddingEdit } from './padding'; import SpacingPanelControl from '../components/spacing-panel-control'; const styleSupportKeys = [ ...TYPOGRAPHY_SUPPORT_KEYS, COLOR_SUPPORT_KEY, - PADDING_SUPPORT_KEY, + SPACING_SUPPORT_KEY, ]; const hasStyleSupport = ( blockType ) => @@ -148,16 +148,16 @@ export const withBlockControls = createHigherOrderComponent( ( BlockEdit ) => ( props ) => { const { name: blockName } = props; - const hasPaddingSupport = hasBlockSupport( + const hasSpacingSupport = hasBlockSupport( blockName, - PADDING_SUPPORT_KEY + SPACING_SUPPORT_KEY ); return [ , , , - hasPaddingSupport && ( + hasSpacingSupport && ( diff --git a/packages/block-editor/src/store/actions.js b/packages/block-editor/src/store/actions.js index cd1365f38fd0c5..e506e3271028e8 100644 --- a/packages/block-editor/src/store/actions.js +++ b/packages/block-editor/src/store/actions.js @@ -14,10 +14,7 @@ import { } from '@wordpress/blocks'; import { speak } from '@wordpress/a11y'; import { __ } from '@wordpress/i18n'; -/** - * Internal dependencies - */ -import { select } from './controls'; +import { controls } from '@wordpress/data'; /** * Generator which will yield a default block insert action if there @@ -26,7 +23,7 @@ import { select } from './controls'; * replacement, etc). */ function* ensureDefaultBlock() { - const count = yield select( 'core/block-editor', 'getBlockCount' ); + const count = yield controls.select( 'core/block-editor', 'getBlockCount' ); // To avoid a focus loss when removing the last block, assure there is // always a default block if the last of the blocks have been removed. @@ -156,7 +153,7 @@ export function selectBlock( clientId, initialPosition = null ) { * @param {string} clientId Block client ID. */ export function* selectPreviousBlock( clientId ) { - const previousBlockClientId = yield select( + const previousBlockClientId = yield controls.select( 'core/block-editor', 'getPreviousBlockClientId', clientId @@ -175,7 +172,7 @@ export function* selectPreviousBlock( clientId ) { * @param {string} clientId Block client ID. */ export function* selectNextBlock( clientId ) { - const nextBlockClientId = yield select( + const nextBlockClientId = yield controls.select( 'core/block-editor', 'getNextBlockClientId', clientId @@ -303,9 +300,9 @@ export function* replaceBlocks( clientIds = castArray( clientIds ); blocks = getBlocksWithDefaultStylesApplied( castArray( blocks ), - yield select( 'core/block-editor', 'getSettings' ) + yield controls.select( 'core/block-editor', 'getSettings' ) ); - const rootClientId = yield select( + const rootClientId = yield controls.select( 'core/block-editor', 'getBlockRootClientId', first( clientIds ) @@ -313,7 +310,7 @@ export function* replaceBlocks( // Replace is valid if the new blocks can be inserted in the root block. for ( let index = 0; index < blocks.length; index++ ) { const block = blocks[ index ]; - const canInsertBlock = yield select( + const canInsertBlock = yield controls.select( 'core/block-editor', 'canInsertBlockType', block.name, @@ -386,7 +383,7 @@ export function* moveBlocksToPosition( toRootClientId = '', index ) { - const templateLock = yield select( + const templateLock = yield controls.select( 'core/block-editor', 'getTemplateLock', fromRootClientId @@ -419,7 +416,7 @@ export function* moveBlocksToPosition( return; } - const canInsertBlocks = yield select( + const canInsertBlocks = yield controls.select( 'core/block-editor', 'canInsertBlocks', clientIds, @@ -498,11 +495,11 @@ export function* insertBlocks( ) { blocks = getBlocksWithDefaultStylesApplied( castArray( blocks ), - yield select( 'core/block-editor', 'getSettings' ) + yield controls.select( 'core/block-editor', 'getSettings' ) ); const allowedBlocks = []; for ( const block of blocks ) { - const isValid = yield select( + const isValid = yield controls.select( 'core/block-editor', 'canInsertBlockType', block.name, @@ -608,12 +605,12 @@ export function* removeBlocks( clientIds, selectPrevious = true ) { } clientIds = castArray( clientIds ); - const rootClientId = yield select( + const rootClientId = yield controls.select( 'core/block-editor', 'getBlockRootClientId', clientIds[ 0 ] ); - const isLocked = yield select( + const isLocked = yield controls.select( 'core/block-editor', 'getTemplateLock', rootClientId @@ -626,7 +623,7 @@ export function* removeBlocks( clientIds, selectPrevious = true ) { if ( selectPrevious ) { previousBlockId = yield selectPreviousBlock( clientIds[ 0 ] ); } else { - previousBlockId = yield select( + previousBlockId = yield controls.select( 'core/block-editor', 'getPreviousBlockClientId', clientIds[ 0 ] @@ -951,12 +948,12 @@ export function* duplicateBlocks( clientIds, updateSelection = true ) { if ( ! clientIds && ! clientIds.length ) { return; } - const blocks = yield select( + const blocks = yield controls.select( 'core/block-editor', 'getBlocksByClientId', clientIds ); - const rootClientId = yield select( + const rootClientId = yield controls.select( 'core/block-editor', 'getBlockRootClientId', clientIds[ 0 ] @@ -976,7 +973,7 @@ export function* duplicateBlocks( clientIds, updateSelection = true ) { return; } - const lastSelectedIndex = yield select( + const lastSelectedIndex = yield controls.select( 'core/block-editor', 'getBlockIndex', last( castArray( clientIds ) ), @@ -1007,12 +1004,12 @@ export function* insertBeforeBlock( clientId ) { if ( ! clientId ) { return; } - const rootClientId = yield select( + const rootClientId = yield controls.select( 'core/block-editor', 'getBlockRootClientId', clientId ); - const isLocked = yield select( + const isLocked = yield controls.select( 'core/block-editor', 'getTemplateLock', rootClientId @@ -1021,7 +1018,7 @@ export function* insertBeforeBlock( clientId ) { return; } - const firstSelectedIndex = yield select( + const firstSelectedIndex = yield controls.select( 'core/block-editor', 'getBlockIndex', clientId, @@ -1039,12 +1036,12 @@ export function* insertAfterBlock( clientId ) { if ( ! clientId ) { return; } - const rootClientId = yield select( + const rootClientId = yield controls.select( 'core/block-editor', 'getBlockRootClientId', clientId ); - const isLocked = yield select( + const isLocked = yield controls.select( 'core/block-editor', 'getTemplateLock', rootClientId @@ -1053,7 +1050,7 @@ export function* insertAfterBlock( clientId ) { return; } - const firstSelectedIndex = yield select( + const firstSelectedIndex = yield controls.select( 'core/block-editor', 'getBlockIndex', clientId, diff --git a/packages/block-editor/src/store/controls.js b/packages/block-editor/src/store/controls.js index f0cbed509f3131..83b4f453425462 100644 --- a/packages/block-editor/src/store/controls.js +++ b/packages/block-editor/src/store/controls.js @@ -1,32 +1,4 @@ -/** - * WordPress dependencies - */ -import { createRegistryControl } from '@wordpress/data'; - -/** - * Calls a selector using the current state. - * - * @param {string} storeName Store name. - * @param {string} selectorName Selector name. - * @param {Array} args Selector arguments. - * - * @return {Object} control descriptor. - */ -export function select( storeName, selectorName, ...args ) { - return { - type: 'SELECT', - storeName, - selectorName, - args, - }; -} - const controls = { - SELECT: createRegistryControl( - ( registry ) => ( { storeName, selectorName, args } ) => { - return registry.select( storeName )[ selectorName ]( ...args ); - } - ), SLEEP( { duration } ) { return new Promise( ( resolve ) => { setTimeout( resolve, duration ); diff --git a/packages/block-editor/src/store/test/actions.js b/packages/block-editor/src/store/test/actions.js index 772afcefda5081..dc7ad96e3261a7 100644 --- a/packages/block-editor/src/store/test/actions.js +++ b/packages/block-editor/src/store/test/actions.js @@ -1,3 +1,8 @@ +/** + * WordPress dependencies + */ +import { controls } from '@wordpress/data'; + /** * Internal dependencies */ @@ -32,7 +37,6 @@ import { updateBlockAttributes, updateBlockListSettings, } from '../actions'; -import { select } from '../controls'; describe( 'actions', () => { describe( 'resetBlocks', () => { @@ -142,19 +146,22 @@ describe( 'actions', () => { // Skip getSettings select. replaceBlockGenerator.next(); - expect( replaceBlockGenerator.next().value ).toEqual( { - args: [ 'chicken' ], - selectorName: 'getBlockRootClientId', - storeName: 'core/block-editor', - type: 'SELECT', - } ); + expect( replaceBlockGenerator.next().value ).toEqual( + controls.select( + 'core/block-editor', + 'getBlockRootClientId', + 'chicken' + ) + ); - expect( replaceBlockGenerator.next().value ).toEqual( { - args: [ 'core/test-block', undefined ], - selectorName: 'canInsertBlockType', - storeName: 'core/block-editor', - type: 'SELECT', - } ); + expect( replaceBlockGenerator.next().value ).toEqual( + controls.select( + 'core/block-editor', + 'canInsertBlockType', + 'core/test-block', + undefined + ) + ); expect( replaceBlockGenerator.next( true ).value ).toEqual( { type: 'REPLACE_BLOCKS', @@ -163,12 +170,9 @@ describe( 'actions', () => { time: expect.any( Number ), } ); - expect( replaceBlockGenerator.next().value ).toEqual( { - args: [], - selectorName: 'getBlockCount', - storeName: 'core/block-editor', - type: 'SELECT', - } ); + expect( replaceBlockGenerator.next().value ).toEqual( + controls.select( 'core/block-editor', 'getBlockCount' ) + ); expect( replaceBlockGenerator.next( 1 ) ).toEqual( { value: undefined, @@ -195,33 +199,35 @@ describe( 'actions', () => { blocks ); - expect( replaceBlockGenerator.next().value ).toEqual( { - args: [], - selectorName: 'getSettings', - storeName: 'core/block-editor', - type: 'SELECT', - } ); + expect( replaceBlockGenerator.next().value ).toEqual( + controls.select( 'core/block-editor', 'getSettings' ) + ); - expect( replaceBlockGenerator.next().value ).toEqual( { - args: [ 'chicken' ], - selectorName: 'getBlockRootClientId', - storeName: 'core/block-editor', - type: 'SELECT', - } ); + expect( replaceBlockGenerator.next().value ).toEqual( + controls.select( + 'core/block-editor', + 'getBlockRootClientId', + 'chicken' + ) + ); - expect( replaceBlockGenerator.next().value ).toEqual( { - args: [ 'core/test-ribs', undefined ], - selectorName: 'canInsertBlockType', - storeName: 'core/block-editor', - type: 'SELECT', - } ); + expect( replaceBlockGenerator.next().value ).toEqual( + controls.select( + 'core/block-editor', + 'canInsertBlockType', + 'core/test-ribs', + undefined + ) + ); - expect( replaceBlockGenerator.next( true ).value ).toEqual( { - args: [ 'core/test-chicken', undefined ], - selectorName: 'canInsertBlockType', - storeName: 'core/block-editor', - type: 'SELECT', - } ); + expect( replaceBlockGenerator.next( true ).value ).toEqual( + controls.select( + 'core/block-editor', + 'canInsertBlockType', + 'core/test-chicken', + undefined + ) + ); expect( replaceBlockGenerator.next( false ) ).toEqual( { value: undefined, @@ -249,26 +255,31 @@ describe( 'actions', () => { // Skip getSettings select. replaceBlockGenerator.next(); - expect( replaceBlockGenerator.next().value ).toEqual( { - args: [ 'chicken' ], - selectorName: 'getBlockRootClientId', - storeName: 'core/block-editor', - type: 'SELECT', - } ); + expect( replaceBlockGenerator.next().value ).toEqual( + controls.select( + 'core/block-editor', + 'getBlockRootClientId', + 'chicken' + ) + ); - expect( replaceBlockGenerator.next().value ).toEqual( { - args: [ 'core/test-ribs', undefined ], - selectorName: 'canInsertBlockType', - storeName: 'core/block-editor', - type: 'SELECT', - } ); + expect( replaceBlockGenerator.next().value ).toEqual( + controls.select( + 'core/block-editor', + 'canInsertBlockType', + 'core/test-ribs', + undefined + ) + ); - expect( replaceBlockGenerator.next( true ).value ).toEqual( { - args: [ 'core/test-chicken', undefined ], - selectorName: 'canInsertBlockType', - storeName: 'core/block-editor', - type: 'SELECT', - } ); + expect( replaceBlockGenerator.next( true ).value ).toEqual( + controls.select( + 'core/block-editor', + 'canInsertBlockType', + 'core/test-chicken', + undefined + ) + ); expect( replaceBlockGenerator.next( true ).value ).toEqual( { type: 'REPLACE_BLOCKS', @@ -277,12 +288,9 @@ describe( 'actions', () => { time: expect.any( Number ), } ); - expect( replaceBlockGenerator.next().value ).toEqual( { - args: [], - selectorName: 'getBlockCount', - storeName: 'core/block-editor', - type: 'SELECT', - } ); + expect( replaceBlockGenerator.next().value ).toEqual( + controls.select( 'core/block-editor', 'getBlockCount' ) + ); expect( replaceBlockGenerator.next( 1 ) ).toEqual( { value: undefined, @@ -348,12 +356,14 @@ describe( 'actions', () => { // Skip getSettings select. insertBlockGenerator.next(); - expect( insertBlockGenerator.next().value ).toEqual( { - args: [ 'core/test-block', 'testclientid' ], - selectorName: 'canInsertBlockType', - storeName: 'core/block-editor', - type: 'SELECT', - } ); + expect( insertBlockGenerator.next().value ).toEqual( + controls.select( + 'core/block-editor', + 'canInsertBlockType', + 'core/test-block', + 'testclientid' + ) + ); expect( insertBlockGenerator.next( true ) ).toEqual( { done: true, @@ -392,12 +402,9 @@ describe( 'actions', () => { false ); - expect( insertBlocksGenerator.next().value ).toEqual( { - args: [], - selectorName: 'getSettings', - storeName: 'core/block-editor', - type: 'SELECT', - } ); + expect( insertBlocksGenerator.next().value ).toEqual( + controls.select( 'core/block-editor', 'getSettings' ) + ); expect( insertBlocksGenerator.next( { @@ -408,26 +415,32 @@ describe( 'actions', () => { }, }, } ).value - ).toEqual( { - args: [ 'core/test-ribs', 'testrootid' ], - selectorName: 'canInsertBlockType', - storeName: 'core/block-editor', - type: 'SELECT', - } ); + ).toEqual( + controls.select( + 'core/block-editor', + 'canInsertBlockType', + 'core/test-ribs', + 'testrootid' + ) + ); - expect( insertBlocksGenerator.next( true ).value ).toEqual( { - args: [ 'core/test-chicken', 'testrootid' ], - selectorName: 'canInsertBlockType', - storeName: 'core/block-editor', - type: 'SELECT', - } ); + expect( insertBlocksGenerator.next( true ).value ).toEqual( + controls.select( + 'core/block-editor', + 'canInsertBlockType', + 'core/test-chicken', + 'testrootid' + ) + ); - expect( insertBlocksGenerator.next( true ).value ).toEqual( { - args: [ 'core/test-chicken-ribs', 'testrootid' ], - selectorName: 'canInsertBlockType', - storeName: 'core/block-editor', - type: 'SELECT', - } ); + expect( insertBlocksGenerator.next( true ).value ).toEqual( + controls.select( + 'core/block-editor', + 'canInsertBlockType', + 'core/test-chicken-ribs', + 'testrootid' + ) + ); expect( insertBlocksGenerator.next( true ) ).toEqual( { done: true, @@ -469,12 +482,9 @@ describe( 'actions', () => { false ); - expect( insertBlocksGenerator.next().value ).toEqual( { - args: [], - selectorName: 'getSettings', - storeName: 'core/block-editor', - type: 'SELECT', - } ); + expect( insertBlocksGenerator.next().value ).toEqual( + controls.select( 'core/block-editor', 'getSettings' ) + ); expect( insertBlocksGenerator.next( { @@ -484,12 +494,14 @@ describe( 'actions', () => { }, }, } ).value - ).toEqual( { - args: [ 'core/test-ribs', 'testrootid' ], - selectorName: 'canInsertBlockType', - storeName: 'core/block-editor', - type: 'SELECT', - } ); + ).toEqual( + controls.select( + 'core/block-editor', + 'canInsertBlockType', + 'core/test-ribs', + 'testrootid' + ) + ); expect( insertBlocksGenerator.next( true ) ).toEqual( { done: true, @@ -533,26 +545,32 @@ describe( 'actions', () => { // Skip getSettings select. insertBlocksGenerator.next(); - expect( insertBlocksGenerator.next().value ).toEqual( { - args: [ 'core/test-ribs', 'testrootid' ], - selectorName: 'canInsertBlockType', - storeName: 'core/block-editor', - type: 'SELECT', - } ); + expect( insertBlocksGenerator.next().value ).toEqual( + controls.select( + 'core/block-editor', + 'canInsertBlockType', + 'core/test-ribs', + 'testrootid' + ) + ); - expect( insertBlocksGenerator.next( true ).value ).toEqual( { - args: [ 'core/test-chicken', 'testrootid' ], - selectorName: 'canInsertBlockType', - storeName: 'core/block-editor', - type: 'SELECT', - } ); + expect( insertBlocksGenerator.next( true ).value ).toEqual( + controls.select( + 'core/block-editor', + 'canInsertBlockType', + 'core/test-chicken', + 'testrootid' + ) + ); - expect( insertBlocksGenerator.next( false ).value ).toEqual( { - args: [ 'core/test-chicken-ribs', 'testrootid' ], - selectorName: 'canInsertBlockType', - storeName: 'core/block-editor', - type: 'SELECT', - } ); + expect( insertBlocksGenerator.next( false ).value ).toEqual( + controls.select( + 'core/block-editor', + 'canInsertBlockType', + 'core/test-chicken-ribs', + 'testrootid' + ) + ); expect( insertBlocksGenerator.next( true ) ).toEqual( { done: true, @@ -588,19 +606,23 @@ describe( 'actions', () => { // Skip getSettings select. insertBlocksGenerator.next(); - expect( insertBlocksGenerator.next().value ).toEqual( { - args: [ 'core/test-ribs', 'testrootid' ], - selectorName: 'canInsertBlockType', - storeName: 'core/block-editor', - type: 'SELECT', - } ); + expect( insertBlocksGenerator.next().value ).toEqual( + controls.select( + 'core/block-editor', + 'canInsertBlockType', + 'core/test-ribs', + 'testrootid' + ) + ); - expect( insertBlocksGenerator.next( false ).value ).toEqual( { - args: [ 'core/test-chicken', 'testrootid' ], - selectorName: 'canInsertBlockType', - storeName: 'core/block-editor', - type: 'SELECT', - } ); + expect( insertBlocksGenerator.next( false ).value ).toEqual( + controls.select( + 'core/block-editor', + 'canInsertBlockType', + 'core/test-chicken', + 'testrootid' + ) + ); expect( insertBlocksGenerator.next( false ) ).toEqual( { done: true, @@ -635,26 +657,32 @@ describe( 'actions', () => { // Skip getSettings select. insertBlocksGenerator.next(); - expect( insertBlocksGenerator.next().value ).toEqual( { - args: [ 'core/test-ribs', 'testrootid' ], - selectorName: 'canInsertBlockType', - storeName: 'core/block-editor', - type: 'SELECT', - } ); + expect( insertBlocksGenerator.next().value ).toEqual( + controls.select( + 'core/block-editor', + 'canInsertBlockType', + 'core/test-ribs', + 'testrootid' + ) + ); - expect( insertBlocksGenerator.next( true ).value ).toEqual( { - args: [ 'core/test-chicken', 'testrootid' ], - selectorName: 'canInsertBlockType', - storeName: 'core/block-editor', - type: 'SELECT', - } ); + expect( insertBlocksGenerator.next( true ).value ).toEqual( + controls.select( + 'core/block-editor', + 'canInsertBlockType', + 'core/test-chicken', + 'testrootid' + ) + ); - expect( insertBlocksGenerator.next( false ).value ).toEqual( { - args: [ 'core/test-chicken-ribs', 'testrootid' ], - selectorName: 'canInsertBlockType', - storeName: 'core/block-editor', - type: 'SELECT', - } ); + expect( insertBlocksGenerator.next( false ).value ).toEqual( + controls.select( + 'core/block-editor', + 'canInsertBlockType', + 'core/test-chicken-ribs', + 'testrootid' + ) + ); expect( insertBlocksGenerator.next( true ) ).toEqual( { done: true, @@ -708,14 +736,22 @@ describe( 'actions', () => { const actions = Array.from( removeBlocks( clientIds ) ); expect( actions ).toEqual( [ - select( 'core/block-editor', 'getBlockRootClientId', clientId ), - select( 'core/block-editor', 'getTemplateLock', undefined ), + controls.select( + 'core/block-editor', + 'getBlockRootClientId', + clientId + ), + controls.select( + 'core/block-editor', + 'getTemplateLock', + undefined + ), selectPreviousBlock( clientId ), { type: 'REMOVE_BLOCKS', clientIds, }, - select( 'core/block-editor', 'getBlockCount' ), + controls.select( 'core/block-editor', 'getBlockCount' ), ] ); } ); } ); @@ -729,12 +765,13 @@ describe( 'actions', () => { 5 ); - expect( moveBlockToPositionGenerator.next().value ).toEqual( { - args: [ 'ribs' ], - selectorName: 'getTemplateLock', - storeName: 'core/block-editor', - type: 'SELECT', - } ); + expect( moveBlockToPositionGenerator.next().value ).toEqual( + controls.select( + 'core/block-editor', + 'getTemplateLock', + 'ribs' + ) + ); expect( moveBlockToPositionGenerator.next( 'insert' ).value @@ -757,12 +794,13 @@ describe( 'actions', () => { 5 ); - expect( moveBlockToPositionGenerator.next().value ).toEqual( { - args: [ 'ribs' ], - selectorName: 'getTemplateLock', - storeName: 'core/block-editor', - type: 'SELECT', - } ); + expect( moveBlockToPositionGenerator.next().value ).toEqual( + controls.select( + 'core/block-editor', + 'getTemplateLock', + 'ribs' + ) + ); expect( moveBlockToPositionGenerator.next( 'all' ) ).toEqual( { done: true, @@ -778,12 +816,13 @@ describe( 'actions', () => { 5 ); - expect( moveBlockToPositionGenerator.next().value ).toEqual( { - args: [ 'ribs' ], - selectorName: 'getTemplateLock', - storeName: 'core/block-editor', - type: 'SELECT', - } ); + expect( moveBlockToPositionGenerator.next().value ).toEqual( + controls.select( + 'core/block-editor', + 'getTemplateLock', + 'ribs' + ) + ); expect( moveBlockToPositionGenerator.next( 'insert' ) ).toEqual( { done: true, @@ -799,19 +838,22 @@ describe( 'actions', () => { 5 ); - expect( moveBlockToPositionGenerator.next().value ).toEqual( { - args: [ 'ribs' ], - selectorName: 'getTemplateLock', - storeName: 'core/block-editor', - type: 'SELECT', - } ); + expect( moveBlockToPositionGenerator.next().value ).toEqual( + controls.select( + 'core/block-editor', + 'getTemplateLock', + 'ribs' + ) + ); - expect( moveBlockToPositionGenerator.next().value ).toEqual( { - args: [ [ 'chicken' ], 'chicken-ribs' ], - selectorName: 'canInsertBlocks', - storeName: 'core/block-editor', - type: 'SELECT', - } ); + expect( moveBlockToPositionGenerator.next().value ).toEqual( + controls.select( + 'core/block-editor', + 'canInsertBlocks', + [ 'chicken' ], + 'chicken-ribs' + ) + ); expect( moveBlockToPositionGenerator.next( true ).value ).toEqual( { type: 'MOVE_BLOCKS_TO_POSITION', @@ -835,19 +877,22 @@ describe( 'actions', () => { 5 ); - expect( moveBlockToPositionGenerator.next().value ).toEqual( { - args: [ 'ribs' ], - selectorName: 'getTemplateLock', - storeName: 'core/block-editor', - type: 'SELECT', - } ); + expect( moveBlockToPositionGenerator.next().value ).toEqual( + controls.select( + 'core/block-editor', + 'getTemplateLock', + 'ribs' + ) + ); - expect( moveBlockToPositionGenerator.next().value ).toEqual( { - args: [ [ 'chicken' ], 'chicken-ribs' ], - selectorName: 'canInsertBlocks', - storeName: 'core/block-editor', - type: 'SELECT', - } ); + expect( moveBlockToPositionGenerator.next().value ).toEqual( + controls.select( + 'core/block-editor', + 'canInsertBlocks', + [ 'chicken' ], + 'chicken-ribs' + ) + ); expect( moveBlockToPositionGenerator.next( false ) ).toEqual( { done: true, @@ -865,12 +910,13 @@ describe( 'actions', () => { 5 ); - expect( moveBlockToPositionGenerator.next().value ).toEqual( { - args: [ 'ribs' ], - selectorName: 'getTemplateLock', - storeName: 'core/block-editor', - type: 'SELECT', - } ); + expect( moveBlockToPositionGenerator.next().value ).toEqual( + controls.select( + 'core/block-editor', + 'getTemplateLock', + 'ribs' + ) + ); expect( moveBlockToPositionGenerator.next().value ).toEqual( { type: 'MOVE_BLOCKS_TO_POSITION', @@ -891,14 +937,22 @@ describe( 'actions', () => { const actions = Array.from( removeBlock( clientId ) ); expect( actions ).toEqual( [ - select( 'core/block-editor', 'getBlockRootClientId', clientId ), - select( 'core/block-editor', 'getTemplateLock', undefined ), + controls.select( + 'core/block-editor', + 'getBlockRootClientId', + clientId + ), + controls.select( + 'core/block-editor', + 'getTemplateLock', + undefined + ), selectPreviousBlock( clientId ), { type: 'REMOVE_BLOCKS', clientIds: [ clientId ], }, - select( 'core/block-editor', 'getBlockCount' ), + controls.select( 'core/block-editor', 'getBlockCount' ), ] ); } ); @@ -908,9 +962,17 @@ describe( 'actions', () => { const actions = Array.from( removeBlock( clientId, false ) ); expect( actions ).toEqual( [ - select( 'core/block-editor', 'getBlockRootClientId', clientId ), - select( 'core/block-editor', 'getTemplateLock', undefined ), - select( + controls.select( + 'core/block-editor', + 'getBlockRootClientId', + clientId + ), + controls.select( + 'core/block-editor', + 'getTemplateLock', + undefined + ), + controls.select( 'core/block-editor', 'getPreviousBlockClientId', 'myclientid' @@ -919,7 +981,7 @@ describe( 'actions', () => { type: 'REMOVE_BLOCKS', clientIds: [ clientId ], }, - select( 'core/block-editor', 'getBlockCount' ), + controls.select( 'core/block-editor', 'getBlockCount' ), ] ); } ); } ); diff --git a/packages/block-library/package.json b/packages/block-library/package.json index 6c13a5ac73efcc..2fdfe218e1eaa9 100644 --- a/packages/block-library/package.json +++ b/packages/block-library/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/block-library", - "version": "2.24.0", + "version": "2.25.0", "description": "Block library for the WordPress editor.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/block-library/src/audio/block.json b/packages/block-library/src/audio/block.json index 30b165e51cfa0c..a077767932e73c 100644 --- a/packages/block-library/src/audio/block.json +++ b/packages/block-library/src/audio/block.json @@ -1,4 +1,5 @@ { + "apiVersion": 2, "name": "core/audio", "category": "media", "attributes": { @@ -37,7 +38,6 @@ }, "supports": { "anchor": true, - "align": true, - "lightBlockWrapper": true + "align": true } } diff --git a/packages/block-library/src/audio/edit.js b/packages/block-library/src/audio/edit.js index 0c9bfd882abcf6..96a52d3f9d4a28 100644 --- a/packages/block-library/src/audio/edit.js +++ b/packages/block-library/src/audio/edit.js @@ -16,7 +16,7 @@ import { MediaPlaceholder, MediaReplaceFlow, RichText, - __experimentalUseBlockWrapperProps as useBlockWrapperProps, + useBlockProps, } from '@wordpress/block-editor'; import { useEffect } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; @@ -41,7 +41,7 @@ function AudioEdit( { insertBlocksAfter, } ) { const { id, autoplay, caption, loop, preload, src } = attributes; - const blockWrapperProps = useBlockWrapperProps(); + const blockProps = useBlockProps(); const mediaUpload = useSelect( ( select ) => { const { getSettings } = select( 'core/block-editor' ); return getSettings().mediaUpload; @@ -116,7 +116,7 @@ function AudioEdit( { } if ( ! src ) { return ( -
+
} onSelect={ onSelectAudio } @@ -175,7 +175,7 @@ function AudioEdit( { /> -
+
{ /* Disable the audio tag so the user clicking on it won't play the file or change the position slider when the controls are enabled. diff --git a/packages/block-library/src/audio/save.js b/packages/block-library/src/audio/save.js index f88eb0bba52e0c..14dc6d57047f53 100644 --- a/packages/block-library/src/audio/save.js +++ b/packages/block-library/src/audio/save.js @@ -1,14 +1,14 @@ /** * WordPress dependencies */ -import { RichText } from '@wordpress/block-editor'; +import { RichText, useBlockProps } from '@wordpress/block-editor'; export default function save( { attributes } ) { const { autoplay, caption, loop, preload, src } = attributes; return ( src && ( -
+
+ ); + }, + }, { attributes: { images: { diff --git a/packages/block-library/src/gallery/save.js b/packages/block-library/src/gallery/save.js index 87478c82fbf625..335f5884167fa3 100644 --- a/packages/block-library/src/gallery/save.js +++ b/packages/block-library/src/gallery/save.js @@ -39,6 +39,11 @@ export default function save( { attributes } ) { href = image.link; break; } + // The image should only have an aria-label if it's within a link and has no alt text. + const imageLabel = + ! image.alt && image.caption && href + ? image.caption + : null; const img = ( ); diff --git a/packages/block-library/src/gallery/style.scss b/packages/block-library/src/gallery/style.scss index b7da214c990d85..e9fc504be1fd54 100644 --- a/packages/block-library/src/gallery/style.scss +++ b/packages/block-library/src/gallery/style.scss @@ -57,6 +57,7 @@ font-size: 0.8em; background: linear-gradient(0deg, rgba($color: $black, $alpha: 0.7) 0, rgba($color: $black, $alpha: 0.3) 70%, transparent); box-sizing: border-box; + margin: 0; img { display: inline; @@ -137,4 +138,3 @@ } } } - diff --git a/packages/block-library/src/group/block.json b/packages/block-library/src/group/block.json index a2d0cc083a9f6d..f554f5ca01b559 100644 --- a/packages/block-library/src/group/block.json +++ b/packages/block-library/src/group/block.json @@ -1,4 +1,5 @@ { + "apiVersion": 2, "name": "core/group", "category": "design", "attributes": { @@ -14,11 +15,12 @@ ], "anchor": true, "html": false, - "lightBlockWrapper": true, - "__experimentalColor": { + "color": { "gradients": true, - "linkColor": true + "link": true }, - "__experimentalPadding": true + "spacing": { + "padding": true + } } } diff --git a/packages/block-library/src/group/edit.js b/packages/block-library/src/group/edit.js index 975421e7d5ac67..fd8f6e0466c03e 100644 --- a/packages/block-library/src/group/edit.js +++ b/packages/block-library/src/group/edit.js @@ -2,10 +2,7 @@ * WordPress dependencies */ import { useSelect } from '@wordpress/data'; -import { - InnerBlocks, - __experimentalUseBlockWrapperProps as useBlockWrapperProps, -} from '@wordpress/block-editor'; +import { InnerBlocks, useBlockProps } from '@wordpress/block-editor'; import { __experimentalBoxControl as BoxControl } from '@wordpress/components'; const { __Visualizer: BoxControlVisualizer } = BoxControl; @@ -18,11 +15,11 @@ function GroupEdit( { attributes, clientId } ) { }, [ clientId ] ); - const blockWrapperProps = useBlockWrapperProps(); + const blockProps = useBlockProps(); const { tagName: TagName = 'div' } = attributes; return ( - + +
diff --git a/packages/block-library/src/heading/block.json b/packages/block-library/src/heading/block.json index fd03a4487ee5aa..7780c4ed5f2484 100644 --- a/packages/block-library/src/heading/block.json +++ b/packages/block-library/src/heading/block.json @@ -1,4 +1,5 @@ { + "apiVersion": 2, "name": "core/heading", "category": "text", "attributes": { @@ -22,12 +23,11 @@ "supports": { "anchor": true, "className": false, - "lightBlockWrapper": true, - "__experimentalColor": { - "linkColor": true + "color": { + "link": true }, - "__experimentalFontSize": true, - "__experimentalLineHeight": true, + "fontSize": true, + "lineHeight": true, "__experimentalSelector": { "core/heading/h1": "h1", "core/heading/h2": "h2", diff --git a/packages/block-library/src/heading/edit.js b/packages/block-library/src/heading/edit.js index 9c8adc25f3fbae..b40f5333da87c3 100644 --- a/packages/block-library/src/heading/edit.js +++ b/packages/block-library/src/heading/edit.js @@ -12,7 +12,7 @@ import { AlignmentToolbar, BlockControls, RichText, - __experimentalUseBlockWrapperProps as useBlockWrapperProps, + useBlockProps, } from '@wordpress/block-editor'; import { ToolbarGroup } from '@wordpress/components'; @@ -30,7 +30,7 @@ function HeadingEdit( { } ) { const { align, content, level, placeholder } = attributes; const tagName = 'h' + level; - const blockWrapperProps = useBlockWrapperProps( { + const blockProps = useBlockProps( { className: classnames( { [ `has-text-align-${ align }` ]: align, } ), @@ -75,7 +75,7 @@ function HeadingEdit( { onRemove={ () => onReplace( [] ) } placeholder={ placeholder || __( 'Write heading…' ) } textAlign={ align } - { ...blockWrapperProps } + { ...blockProps } /> ); diff --git a/packages/block-library/src/heading/save.js b/packages/block-library/src/heading/save.js index 00ecf40e1c27ce..e2eae91f823eb1 100644 --- a/packages/block-library/src/heading/save.js +++ b/packages/block-library/src/heading/save.js @@ -6,21 +6,19 @@ import classnames from 'classnames'; /** * WordPress dependencies */ -import { RichText } from '@wordpress/block-editor'; +import { RichText, useBlockProps } from '@wordpress/block-editor'; export default function save( { attributes } ) { const { align, content, level } = attributes; - const tagName = 'h' + level; + const TagName = 'h' + level; const className = classnames( { [ `has-text-align-${ align }` ]: align, } ); return ( - + + + ); } diff --git a/packages/block-library/src/image/block.json b/packages/block-library/src/image/block.json index 798210cbd5c2f8..ec80dc4c9ed250 100644 --- a/packages/block-library/src/image/block.json +++ b/packages/block-library/src/image/block.json @@ -1,4 +1,5 @@ { + "apiVersion": 2, "name": "core/image", "category": "media", "attributes": { @@ -70,7 +71,6 @@ } }, "supports": { - "anchor": true, - "lightBlockWrapper": true + "anchor": true } } diff --git a/packages/block-library/src/image/edit.js b/packages/block-library/src/image/edit.js index 5d5478b4db3394..17109a02f4a3b2 100644 --- a/packages/block-library/src/image/edit.js +++ b/packages/block-library/src/image/edit.js @@ -15,7 +15,7 @@ import { BlockControls, BlockIcon, MediaPlaceholder, - __experimentalUseBlockWrapperProps as useBlockWrapperProps, + useBlockProps, } from '@wordpress/block-editor'; import { useEffect, useRef } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; @@ -303,7 +303,7 @@ export function ImageEdit( { [ `size-${ sizeSlug }` ]: sizeSlug, } ); - const blockWrapperProps = useBlockWrapperProps( { + const blockProps = useBlockProps( { ref, className: classes, } ); @@ -311,7 +311,7 @@ export function ImageEdit( { return ( <> { controls } -
+
{ url && ( +
{ figure }
); } - return
{ figure }
; + return ( +
+ { figure } +
+ ); } diff --git a/packages/block-library/src/list/block.json b/packages/block-library/src/list/block.json index 3fa10c51a1f859..848c017842d392 100644 --- a/packages/block-library/src/list/block.json +++ b/packages/block-library/src/list/block.json @@ -1,4 +1,5 @@ { + "apiVersion": 2, "name": "core/list", "category": "text", "attributes": { @@ -27,10 +28,9 @@ "supports": { "anchor": true, "className": false, - "__experimentalColor": { + "color": { "gradients": true }, - "__unstablePasteTextInline": true, - "lightBlockWrapper": true + "__unstablePasteTextInline": true } } diff --git a/packages/block-library/src/list/edit.js b/packages/block-library/src/list/edit.js index 9a8e6659566ab9..5ca9052dbf6ecb 100644 --- a/packages/block-library/src/list/edit.js +++ b/packages/block-library/src/list/edit.js @@ -7,7 +7,7 @@ import { RichText, BlockControls, RichTextShortcut, - __experimentalUseBlockWrapperProps as useBlockWrapperProps, + useBlockProps, } from '@wordpress/block-editor'; import { ToolbarGroup } from '@wordpress/components'; import { @@ -154,7 +154,7 @@ export default function ListEdit( { ); - const blockWrapperProps = useBlockWrapperProps(); + const blockProps = useBlockProps(); return ( <> @@ -180,7 +180,7 @@ export default function ListEdit( { start={ start } reversed={ reversed } type={ type } - { ...blockWrapperProps } + { ...blockProps } > { controls } diff --git a/packages/block-library/src/list/save.js b/packages/block-library/src/list/save.js index 8cd1d3870148ba..7d4f8a37fc86a5 100644 --- a/packages/block-library/src/list/save.js +++ b/packages/block-library/src/list/save.js @@ -1,20 +1,15 @@ /** * WordPress dependencies */ -import { RichText } from '@wordpress/block-editor'; +import { RichText, useBlockProps } from '@wordpress/block-editor'; export default function save( { attributes } ) { const { ordered, values, type, reversed, start } = attributes; - const tagName = ordered ? 'ol' : 'ul'; + const TagName = ordered ? 'ol' : 'ul'; return ( - + + + ); } diff --git a/packages/block-library/src/media-text/block.json b/packages/block-library/src/media-text/block.json index 9911c4d35edc1b..e88b1b1d1b8182 100644 --- a/packages/block-library/src/media-text/block.json +++ b/packages/block-library/src/media-text/block.json @@ -1,4 +1,5 @@ { + "apiVersion": 2, "name": "core/media-text", "category": "media", "attributes": { @@ -84,10 +85,9 @@ "anchor": true, "align": [ "wide", "full" ], "html": false, - "lightBlockWrapper": true, - "__experimentalColor": { + "color": { "gradients": true, - "linkColor": true + "link": true } } } diff --git a/packages/block-library/src/media-text/edit.js b/packages/block-library/src/media-text/edit.js index 52914136a42b2f..fd83c4d830e7eb 100644 --- a/packages/block-library/src/media-text/edit.js +++ b/packages/block-library/src/media-text/edit.js @@ -15,7 +15,7 @@ import { BlockVerticalAlignmentToolbar, InnerBlocks, InspectorControls, - __experimentalUseBlockWrapperProps as useBlockWrapperProps, + useBlockProps, __experimentalImageURLInputUI as ImageURLInputUI, __experimentalImageSizeControl as ImageSizeControl, } from '@wordpress/block-editor'; @@ -280,7 +280,7 @@ function MediaTextEdit( { attributes, isSelected, setAttributes } ) { ); - const blockWrapperProps = useBlockWrapperProps( { + const blockProps = useBlockProps( { className: classNames, style, } ); @@ -310,7 +310,7 @@ function MediaTextEdit( { attributes, isSelected, setAttributes } ) { ) } -
+
+
- { this.props.uiStrings[ 'missing-block-detail' ] ?? - __( - 'We are working hard to add more blocks with each release.' - ) } + { missingBlockDetail } { ( isUnsupportedBlockEditorSupported || canEnableUnsupportedBlockEditor ) && ( <> -
  • +
  • setAttributes( { content: newContent } ) diff --git a/packages/block-library/src/paragraph/save.js b/packages/block-library/src/paragraph/save.js index 434cc022295588..9bc9921e31334a 100644 --- a/packages/block-library/src/paragraph/save.js +++ b/packages/block-library/src/paragraph/save.js @@ -6,22 +6,18 @@ import classnames from 'classnames'; /** * WordPress dependencies */ -import { RichText } from '@wordpress/block-editor'; +import { RichText, useBlockProps } from '@wordpress/block-editor'; export default function save( { attributes } ) { const { align, content, dropCap, direction } = attributes; - const className = classnames( { 'has-drop-cap': dropCap, [ `has-text-align-${ align }` ]: align, } ); return ( - +

    + +

    ); } diff --git a/packages/block-library/src/post-author/block.json b/packages/block-library/src/post-author/block.json index 3e788777dec81d..99f1cd2c8a8163 100644 --- a/packages/block-library/src/post-author/block.json +++ b/packages/block-library/src/post-author/block.json @@ -1,4 +1,5 @@ { + "apiVersion": 2, "name": "core/post-author", "category": "design", "attributes": { @@ -26,12 +27,11 @@ ], "supports": { "html": false, - "lightBlockWrapper": true, - "__experimentalFontSize": true, - "__experimentalColor": { + "fontSize": true, + "color": { "gradients": true, - "linkColor": true + "link": true }, - "__experimentalLineHeight": true + "lineHeight": true } } diff --git a/packages/block-library/src/post-author/edit.js b/packages/block-library/src/post-author/edit.js index cedbede9f5de64..120fb0da34616a 100644 --- a/packages/block-library/src/post-author/edit.js +++ b/packages/block-library/src/post-author/edit.js @@ -12,7 +12,7 @@ import { BlockControls, InspectorControls, RichText, - __experimentalUseBlockWrapperProps as useBlockWrapperProps, + useBlockProps, } from '@wordpress/block-editor'; import { PanelBody, SelectControl, ToggleControl } from '@wordpress/components'; import { useSelect, useDispatch } from '@wordpress/data'; @@ -55,7 +55,7 @@ function PostAuthorEdit( { isSelected, context, attributes, setAttributes } ) { } ); } - const blockWrapperProps = useBlockWrapperProps( { + const blockProps = useBlockProps( { className: classnames( { [ `has-text-align-${ textAlign }` ]: textAlign, } ), @@ -118,7 +118,7 @@ function PostAuthorEdit( { isSelected, context, attributes, setAttributes } ) { /> -
    +
    { showAvatar && authorDetails && (
    @@ -47,7 +44,7 @@ export default function Edit( { attributes, context, setAttributes } ) { -
    +
    diff --git a/packages/block-library/src/post-comments-count/block.json b/packages/block-library/src/post-comments-count/block.json index 5908f13b721c76..85d4005651da6e 100644 --- a/packages/block-library/src/post-comments-count/block.json +++ b/packages/block-library/src/post-comments-count/block.json @@ -1,4 +1,5 @@ { + "apiVersion": 2, "name": "core/post-comments-count", "category": "design", "attributes": { @@ -11,11 +12,10 @@ ], "supports": { "html": false, - "lightBlockWrapper": true, - "__experimentalColor": { + "color": { "gradients": true }, - "__experimentalFontSize": true, - "__experimentalLineHeight": true + "fontSize": true, + "lineHeight": true } } diff --git a/packages/block-library/src/post-comments-count/edit.js b/packages/block-library/src/post-comments-count/edit.js index ddc33fe26192f0..9f9f87939bfa70 100644 --- a/packages/block-library/src/post-comments-count/edit.js +++ b/packages/block-library/src/post-comments-count/edit.js @@ -10,7 +10,7 @@ import { AlignmentToolbar, BlockControls, Warning, - __experimentalUseBlockWrapperProps as useBlockWrapperProps, + useBlockProps, } from '@wordpress/block-editor'; import { useState, useEffect } from '@wordpress/element'; import apiFetch from '@wordpress/api-fetch'; @@ -25,7 +25,7 @@ export default function PostCommentsCountEdit( { const { textAlign } = attributes; const { postId } = context; const [ commentsCount, setCommentsCount ] = useState(); - const blockWrapperProps = useBlockWrapperProps( { + const blockProps = useBlockProps( { className: classnames( { [ `has-text-align-${ textAlign }` ]: textAlign, } ), @@ -59,7 +59,7 @@ export default function PostCommentsCountEdit( { } } /> -
    +
    { postId && commentsCount !== undefined ? ( commentsCount ) : ( diff --git a/packages/block-library/src/post-comments-form/block.json b/packages/block-library/src/post-comments-form/block.json index c0e131b83b231b..64cdcbba8f95fd 100644 --- a/packages/block-library/src/post-comments-form/block.json +++ b/packages/block-library/src/post-comments-form/block.json @@ -1,4 +1,5 @@ { + "apiVersion": 2, "name": "core/post-comments-form", "category": "design", "attributes": { @@ -12,12 +13,11 @@ ], "supports": { "html": false, - "lightBlockWrapper": true, - "__experimentalColor": { + "color": { "gradients": true, - "linkColor": true + "link": true }, - "__experimentalFontSize": true, - "__experimentalLineHeight": true + "fontSize": true, + "lineHeight": true } } diff --git a/packages/block-library/src/post-comments-form/edit.js b/packages/block-library/src/post-comments-form/edit.js index 49d5362360ea18..da6751e0e30dbe 100644 --- a/packages/block-library/src/post-comments-form/edit.js +++ b/packages/block-library/src/post-comments-form/edit.js @@ -10,7 +10,7 @@ import { AlignmentToolbar, BlockControls, Warning, - __experimentalUseBlockWrapperProps as useBlockWrapperProps, + useBlockProps, } from '@wordpress/block-editor'; import { useEntityProp } from '@wordpress/core-data'; import { __ } from '@wordpress/i18n'; @@ -28,7 +28,7 @@ export default function PostCommentsFormEdit( { 'comment_status', postId ); - const blockWrapperProps = useBlockWrapperProps( { + const blockProps = useBlockProps( { className: classnames( { [ `has-text-align-${ textAlign }` ]: textAlign, } ), @@ -44,7 +44,7 @@ export default function PostCommentsFormEdit( { } } /> -
    +
    { ! commentStatus && ( { __( diff --git a/packages/block-library/src/post-comments/block.json b/packages/block-library/src/post-comments/block.json index 51dbb5c22dcbcc..ee1e3d4c03f717 100644 --- a/packages/block-library/src/post-comments/block.json +++ b/packages/block-library/src/post-comments/block.json @@ -1,4 +1,5 @@ { + "apiVersion": 2, "name": "core/post-comments", "category": "design", "attributes": { @@ -12,16 +13,15 @@ ], "supports": { "html": false, - "lightBlockWrapper": true, "align": [ "wide", "full" ], - "__experimentalFontSize": true, - "__experimentalColor": { + "fontSize": true, + "color": { "gradients": true, - "linkColor": true + "link": true }, - "__experimentalLineHeight": true + "lineHeight": true } } diff --git a/packages/block-library/src/post-comments/edit.js b/packages/block-library/src/post-comments/edit.js index 79109cb2629f9b..e79a8b8760c03d 100644 --- a/packages/block-library/src/post-comments/edit.js +++ b/packages/block-library/src/post-comments/edit.js @@ -11,7 +11,7 @@ import { AlignmentToolbar, BlockControls, Warning, - __experimentalUseBlockWrapperProps as useBlockWrapperProps, + useBlockProps, } from '@wordpress/block-editor'; import { __ } from '@wordpress/i18n'; import { RawHTML } from '@wordpress/element'; @@ -49,7 +49,7 @@ export default function PostCommentsEdit( { } ) { const { postType, postId } = context; const { textAlign } = attributes; - const blockWrapperProps = useBlockWrapperProps( { + const blockProps = useBlockProps( { className: classnames( { [ `has-text-align-${ textAlign }` ]: textAlign, } ), @@ -72,7 +72,7 @@ export default function PostCommentsEdit( { /> -
    +
    diff --git a/packages/block-library/src/post-date/block.json b/packages/block-library/src/post-date/block.json index 872bf705c01162..94fc7dd67d9f98 100644 --- a/packages/block-library/src/post-date/block.json +++ b/packages/block-library/src/post-date/block.json @@ -1,4 +1,5 @@ { + "apiVersion": 2, "name": "core/post-date", "category": "design", "attributes": { @@ -15,11 +16,10 @@ ], "supports": { "html": false, - "lightBlockWrapper": true, - "__experimentalColor": { + "color": { "gradients": true }, - "__experimentalFontSize": true, - "__experimentalLineHeight": true + "fontSize": true, + "lineHeight": true } } diff --git a/packages/block-library/src/post-date/edit.js b/packages/block-library/src/post-date/edit.js index 664e59a6899027..4b75b93a648d31 100644 --- a/packages/block-library/src/post-date/edit.js +++ b/packages/block-library/src/post-date/edit.js @@ -13,7 +13,7 @@ import { AlignmentToolbar, BlockControls, InspectorControls, - __experimentalUseBlockWrapperProps as useBlockWrapperProps, + useBlockProps, } from '@wordpress/block-editor'; import { ToolbarGroup, @@ -56,7 +56,7 @@ export default function PostDateEdit( { attributes, context, setAttributes } ) { } ) ); const resolvedFormat = format || siteFormat || settings.formats.date; - const blockWrapperProps = useBlockWrapperProps( { + const blockProps = useBlockProps( { className: classnames( { [ `has-text-align-${ textAlign }` ]: textAlign, } ), @@ -105,7 +105,7 @@ export default function PostDateEdit( { attributes, context, setAttributes } ) { -
    +
    { date && (