diff --git a/bin/build-plugin-zip.sh b/bin/build-plugin-zip.sh index d68c58f0c9edb7..4aea6ac016c1e8 100755 --- a/bin/build-plugin-zip.sh +++ b/bin/build-plugin-zip.sh @@ -115,8 +115,7 @@ build_files=$(ls build/*/*.{js,css,asset.php} build/block-library/blocks/*.php b status "Creating archive... 🎁" zip -r gutenberg.zip \ gutenberg.php \ - lib/*.php \ - lib/demo-block-templates/*.html \ + lib \ packages/block-serialization-default-parser/*.php \ post-content.php \ $vendor_scripts \ diff --git a/changelog.txt b/changelog.txt index 9552802795a92a..a7f8ab103087ce 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,120 @@ == Changelog == += 7.7.0-rc.1 = + +### Features + +- Add the initial version of the Patterns UI as a sidebar plugin (This is not the final interface and work is in progress to integrate with the main block inserter). [20354](https://github.com/WordPress/gutenberg/pull/20354), [20715](https://github.com/WordPress/gutenberg/pull/20715). + - Add an initial set of patterns [20724](https://github.com/WordPress/gutenberg/pull/20724). + +### Enhancements + +- Update the Block and editor UI. [19344](https://github.com/WordPress/gutenberg/pull/19344) + - New icons. [20464](https://github.com/WordPress/gutenberg/pull/20464) + - Avoid empty menu groups. [20495](https://github.com/WordPress/gutenberg/pull/20495) + - Block Placeholders. [20441](https://github.com/WordPress/gutenberg/pull/20441), [20676](https://github.com/WordPress/gutenberg/pull/20676). + - Various tweaks [20679](https://github.com/WordPress/gutenberg/pull/20679), [20578](https://github.com/WordPress/gutenberg/pull/20578). +- Improve the Back to WP Admin button in Fullscreen Mode. [20603](https://github.com/WordPress/gutenberg/pull/20603) +- Make the editor Fullscreen by default. [20611](https://github.com/WordPress/gutenberg/pull/20611) +- Remove template locking from the columns block [20465](https://github.com/WordPress/gutenberg/pull/20465) +- Make the inserter full height. [20526](https://github.com/WordPress/gutenberg/pull/20526) + +### Bug Fixes + +- A11y: + - Deselect first/last gallery images on blur. [14930](https://github.com/WordPress/gutenberg/pull/14930) + - Revert top toolbar tab order [20571](https://github.com/WordPress/gutenberg/pull/20571) +- Add an overlay to the html block preview to fix block selection in Firefox. [20425](https://github.com/WordPress/gutenberg/pull/20425) +- Add missing accessibility attributes in the SVG icons. [20538](https://github.com/WordPress/gutenberg/pull/20538) +- Fix invalid syntax error on Safari 12. [20507](https://github.com/WordPress/gutenberg/pull/20507) +- Use a consistent width for the link suggetions. [20448](https://github.com/WordPress/gutenberg/pull/20448) +- Use full labels for directional block movers. [20664](https://github.com/WordPress/gutenberg/pull/20664) +- Columns block: Force 50% column width at mid-range viewport. [20597](https://github.com/WordPress/gutenberg/pull/20597) +- Media & Text block: Fix frontend styles when "Crop image to fill" is selected [20539](https://github.com/WordPress/gutenberg/pull/20539) +- Latest Post block: + - Fix the excerpt length. [20313](https://github.com/WordPress/gutenberg/pull/20313) + - Don't trim manual exerptts [20432](https://github.com/WordPress/gutenberg/pull/20432) +- Fix sidebar scroll issue on small viewports. [20491](https://github.com/WordPress/gutenberg/pull/20491) +- Social Link block: + - Escape generated class name. [20479](https://github.com/WordPress/gutenberg/pull/20479) + - Fix label attribute type as string. [20468](https://github.com/WordPress/gutenberg/pull/20468) + - i18n: Use placeholder for the default label [20475](https://github.com/WordPress/gutenberg/pull/20475) +- Simulated Queries (Device previews): + - Check for match in stylesheet host and protocol to prevent Chrome breakage. [20673](https://github.com/WordPress/gutenberg/pull/20673) + - Fix IE11 editor breakage. [20226](https://github.com/WordPress/gutenberg/pull/20226) + - Fix incorrectly displayed preview option for private post types. [20604](https://github.com/WordPress/gutenberg/pull/20604) + - Focus preview button after opening preview. [20570](https://github.com/WordPress/gutenberg/pull/20570) +- Fix isURL regex to take account file urls. [20435](https://github.com/WordPress/gutenberg/pull/20435) +- Fix error when deleting empty paragraphs in IE11. [20594](https://github.com/WordPress/gutenberg/pull/20594) +- Fix hidden inserter toggle behind the popover. [20663](https://github.com/WordPress/gutenberg/pull/20663) +- Fix block registration shared defaults reuse across blocks. [20565](https://github.com/WordPress/gutenberg/pull/20565) +- Shim meta attributes for early block registrations. [20544](https://github.com/WordPress/gutenberg/pull/20544) +- Fix bouncing Custom color formatter. [20612](https://github.com/WordPress/gutenberg/pull/20612) +- Fix Gallery block styles in Edge causing editor breakage. [20690](https://github.com/WordPress/gutenberg/pull/20690) + +### New APIs: + +- @wordpress/env: Add support for ZIP URL sources. [20426](https://github.com/WordPress/gutenberg/pull/20426) + +### Experiments + +- Lighter Block DOM: allow block types to render their own wrapper [19701](https://github.com/WordPress/gutenberg/pull/19701) + - Lighter InnerBlocks. [19910](https://github.com/WordPress/gutenberg/pull/19910) + - Automatically add block class. [20658](https://github.com/WordPress/gutenberg/pull/20658) +- BlockPreview: Add __experimentalOnReady prop. [17242](https://github.com/WordPress/gutenberg/pull/17242) +- Edit Site: + - Update template navigation to use new link control. [20366](https://github.com/WordPress/gutenberg/pull/20366) + - Update the edit site save modal UI. [20608](https://github.com/WordPress/gutenberg/pull/20608) +- Fix the block toolbar in the Widgets and Site Edit screens. [20458](https://github.com/WordPress/gutenberg/pull/20458) +- Fix widgets screen inserter [20680](https://github.com/WordPress/gutenberg/pull/20680) + +### Documentation + +- Add tutorial for creating a custom block editor instance. [20410](https://github.com/WordPress/gutenberg/pull/20410) +- Create a new "Gutenberg as a Platform" page. [20666](https://github.com/WordPress/gutenberg/pull/20666) +- Typos and tweaks: [20382](https://github.com/WordPress/gutenberg/pull/20382), [20386](https://github.com/WordPress/gutenberg/pull/20386), [20517](https://github.com/WordPress/gutenberg/pull/20517), [20662](https://github.com/WordPress/gutenberg/pull/20662), [20454](https://github.com/WordPress/gutenberg/pull/20454), [20659](https://github.com/WordPress/gutenberg/pull/20659). + +### Code Quality + +- Refactoring to existing blocks to use a lighter DOM: + - List block. [20498](https://github.com/WordPress/gutenberg/pull/20498) + - Image block. [20576](https://github.com/WordPress/gutenberg/pull/20576) + - Heading. [20493](https://github.com/WordPress/gutenberg/pull/20493) +- Consistent block focus behaviour on mount. [20577](https://github.com/WordPress/gutenberg/pull/20577) +- Cleanup CSS variables. [20529](https://github.com/WordPress/gutenberg/pull/20529) +- Use the EditorSkeleton component in the widgets and Edit Site pages. [20440](https://github.com/WordPress/gutenberg/pull/20440), [20431](https://github.com/WordPress/gutenberg/pull/20431). +- Refactor SlotFill components. [19242](https://github.com/WordPress/gutenberg/pull/19242) +- Remove useless style override for floats. [20501](https://github.com/WordPress/gutenberg/pull/20501) +- Block popover: remove data-type. [20531](https://github.com/WordPress/gutenberg/pull/20531) +- Resizable editor improvements. [20259](https://github.com/WordPress/gutenberg/pull/20259) + +### Various + +- @wordpress/env: + - Save the database as a volume. [20648](https://github.com/WordPress/gutenberg/pull/20648) + - Fix accidental quotes in Site Title. [20520](https://github.com/WordPress/gutenberg/pull/20520) + - Set owner of wp-content to www-data. [20406](https://github.com/WordPress/gutenberg/pull/20406) +- @wordpress/create-block: + - Fix system requirements checks. [20461](https://github.com/WordPress/gutenberg/pull/20461) [20456](https://github.com/WordPress/gutenberg/pull/20456) +- Fix React warning triggered by the BlockToolbar component. [20546](https://github.com/WordPress/gutenberg/pull/20546) +- Skip the Type Writer effect component in IE 11. [20485](https://github.com/WordPress/gutenberg/pull/20485) +- Update browserslist to fix out-of-date caniuse-lite messages [20709](https://github.com/WordPress/gutenberg/pull/20709) +- Add storybook stories: + - TextControl [20467](https://github.com/WordPress/gutenberg/pull/20467) + - TextAreaControl [20472](https://github.com/WordPress/gutenberg/pull/20472) + - SelectControl [20482](https://github.com/WordPress/gutenberg/pull/20482) + - Tooltip [20322](https://github.com/WordPress/gutenberg/pull/20322) +- E2E Tests: + - Add test for the Image block. [20622](https://github.com/WordPress/gutenberg/pull/20622) + - More stable embed test. [20668](https://github.com/WordPress/gutenberg/pull/20668) + - Fix intermittent RichText e2e test failure. [20457](https://github.com/WordPress/gutenberg/pull/20457) +- Travis: Avoid skipping Puppeteer download. [20547](https://github.com/WordPress/gutenberg/pull/20547) +- Plugin: Bump minimum WordPress version to 5.3 [20628](https://github.com/WordPress/gutenberg/pull/20628) +- @wordrpess/priority-queue: Fix for environments that don't have `window` defined. [20486](https://github.com/WordPress/gutenberg/pull/20486) +- Update jest configuration to only ignore tests from /wordpress/ as a subdirectory [20420](https://github.com/WordPress/gutenberg/pull/20420) + + + = 7.6.0 = ## Features diff --git a/docs/designers-developers/developers/slotfills/README.md b/docs/designers-developers/developers/slotfills/README.md index 1fde71f171f99b..9df1769c19ba09 100644 --- a/docs/designers-developers/developers/slotfills/README.md +++ b/docs/designers-developers/developers/slotfills/README.md @@ -17,18 +17,16 @@ In order to access the SlotFills, we need to do four things: Here is an example using the `PluginPostStatusInfo` slotFill: + ```js const { registerPlugin } = wp.plugins; const { PluginPostStatusInfo } = wp.editPost; - -const PluginPostStatusInfoTest = () => { - return( - -

Post Status Info SlotFill

-
- ) -} +const PluginPostStatusInfoTest = () => ( + +

Post Status Info SlotFill

+
+); registerPlugin( 'post-status-info-test', { render: PluginPostStatusInfoTest } ); ``` @@ -62,7 +60,6 @@ const PluginPostStatusInfo = ( { children, className } ) => ( PluginPostStatusInfo.Slot = Slot; export default PluginPostStatusInfo; - ``` This new Slot is then exposed in the editor. The example below is from core and represents the Status & visibility panel. @@ -73,31 +70,34 @@ Any items that have been added via the SlotFill ( see the example above ), will See [core code](https://github.com/WordPress/gutenberg/tree/master/packages/edit-post/src/components/sidebar/post-status/index.js#L26). ```js -function PostStatus( { isOpened, onTogglePanel } ) { - return ( - - - { ( fills ) => ( - - - - - - - - { fills } - - - ) } - - - ); -} +const PostStatus = ( { isOpened, onTogglePanel } ) => ( + + + { ( fills ) => ( + + + + + + + + { fills } + + + ) } + + +); ``` ## Currently available SlotFills and examples -There are currently seven available SlotFills in the `edit-post` package. Please refer to the individual items below for usage and example details: +There are currently eight available SlotFills in the `edit-post` package. Please refer to the individual items below for usage and example details: * [PluginBlockSettingsMenuItem](/docs/designers-developers/developers/slotfills/plugin-block-settings-menu-item.md) * [PluginDocumentSettingPanel](/docs/designers-developers/developers/slotfills/plugin-document-setting-panel.md) @@ -107,7 +107,3 @@ There are currently seven available SlotFills in the `edit-post` package. Please * [PluginPrePublishPanel](/docs/designers-developers/developers/slotfills/plugin-pre-publish-panel.md) * [PluginSidebar](/docs/designers-developers/developers/slotfills/plugin-sidebar.md) * [PluginSidebarMoreMenuItem](/docs/designers-developers/developers/slotfills/plugin-sidebar-more-menu-item.md) - - - - diff --git a/docs/designers-developers/developers/slotfills/plugin-block-settings-menu-item.md b/docs/designers-developers/developers/slotfills/plugin-block-settings-menu-item.md index ce81b96f3e1824..666384c53af35d 100644 --- a/docs/designers-developers/developers/slotfills/plugin-block-settings-menu-item.md +++ b/docs/designers-developers/developers/slotfills/plugin-block-settings-menu-item.md @@ -1,9 +1,8 @@ # PluginBlockSettingsMenuItem -This slot allows for adding a new item into the More Options area. +This slot allows for adding a new item into the More Options area. This will either appear in the controls for each block or at the Top Toolbar depending on the users setting. - ## Example ```js @@ -12,13 +11,18 @@ const { PluginBlockSettingsMenuItem } = wp.editPost; const PluginBlockSettingsMenuGroupTest = () => ( { alert( 'clicked' )} } /> -) - -registerPlugin( 'block-settings-menu-group-test', { render: PluginBlockSettingsMenuGroupTest } ); + allowedBlocks={ [ 'core/paragraph' ] } + icon="smiley" + label="Menu item text" + onClick={ () => { + alert( 'clicked' ); + } } + /> +); + +registerPlugin( 'block-settings-menu-group-test', { + render: PluginBlockSettingsMenuGroupTest, +} ); ``` ## Location diff --git a/docs/designers-developers/developers/slotfills/plugin-document-setting-panel.md b/docs/designers-developers/developers/slotfills/plugin-document-setting-panel.md index 75f0a3638f1b4c..25a5ab915cb54b 100644 --- a/docs/designers-developers/developers/slotfills/plugin-document-setting-panel.md +++ b/docs/designers-developers/developers/slotfills/plugin-document-setting-panel.md @@ -3,15 +3,17 @@ This SlotFill allows registering a UI to edit Document settings. ## Available Props + * __name__ `string`: A string identifying the panel. * __className__ `string`: An optional class name added to the sidebar body. * __title__ `string`: Title displayed at the top of the sidebar. * __icon__ `(string|Element)`: The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element. ## Example + ```js -const { registerPlugin } = wp.plugins; -const { PluginDocumentSettingPanel } = wp.editPost; +import { registerPlugin } from '@wordpress/plugins'; +import { PluginDocumentSettingPanel } from '@wordpress/edit-post'; const PluginDocumentSettingPanelDemo = () => ( ( Custom Panel Contents ); -registerPlugin( 'plugin-document-setting-panel-demo', { render: PluginDocumentSettingPanelDemo, icon: 'palmtree' } ); -``` \ No newline at end of file + +registerPlugin( 'plugin-document-setting-panel-demo', { + render: PluginDocumentSettingPanelDemo, + icon: 'palmtree', +} ); +``` diff --git a/docs/designers-developers/developers/slotfills/plugin-post-publish-panel.md b/docs/designers-developers/developers/slotfills/plugin-post-publish-panel.md index 50c38098c19496..bbf146b4a8e050 100644 --- a/docs/designers-developers/developers/slotfills/plugin-post-publish-panel.md +++ b/docs/designers-developers/developers/slotfills/plugin-post-publish-panel.md @@ -5,19 +5,18 @@ This slot allows for injecting items into the bottom of the post-publish panel t ## Example ```js -const { registerPlugin } = wp.plugins; -const { PluginPostPublishPanel } = wp.editPost; - -const PluginPostPublishPanelTest = () => { - return ( - -

Post Publish Panel

-
- ) -} - -registerPlugin( 'post-publish-panel-test', { render: PluginPostPublishPanelTest } ); - +import { registerPlugin } from '@wordpress/plugins'; +import { PluginPostPublishPanel } from '@wordpress/edit-post'; + +const PluginPostPublishPanelTest = () => ( + +

Post Publish Panel

+
+); + +registerPlugin( 'post-publish-panel-test', { + render: PluginPostPublishPanelTest, +} ); ``` ## Location diff --git a/docs/designers-developers/developers/slotfills/plugin-post-status-info.md b/docs/designers-developers/developers/slotfills/plugin-post-status-info.md index 745fe64c62b9ee..3a8201e5506e98 100644 --- a/docs/designers-developers/developers/slotfills/plugin-post-status-info.md +++ b/docs/designers-developers/developers/slotfills/plugin-post-status-info.md @@ -5,17 +5,14 @@ This slots allows for the insertion of items in the Status & visibility panel of ## Example ```js -const { registerPlugin } = wp.plugins; -const { PluginPostStatusInfo } = wp.editPost; - - -const PluginPostStatusInfoTest = () => { - return( - -

Post Status Info SlotFill

-
- ) -} +import { registerPlugin } from '@wordpress/plugins'; +import { PluginPostStatusInfo } from '@wordpress/edit-post'; + +const PluginPostStatusInfoTest = () => ( + +

Post Status Info SlotFill

+
+); registerPlugin( 'post-status-info-test', { render: PluginPostStatusInfoTest } ); ``` diff --git a/docs/designers-developers/developers/slotfills/plugin-pre-publish-panel.md b/docs/designers-developers/developers/slotfills/plugin-pre-publish-panel.md index 622a945dd08d87..abaa1cc4d6ae8d 100644 --- a/docs/designers-developers/developers/slotfills/plugin-pre-publish-panel.md +++ b/docs/designers-developers/developers/slotfills/plugin-pre-publish-panel.md @@ -1,23 +1,22 @@ # PluginPrePublishPanel -This slot allows for injecting items into the bottom of the pre-publish panel that appears to confirm publishing after the user clicks "Publish'. +This slot allows for injecting items into the bottom of the pre-publish panel that appears to confirm publishing after the user clicks "Publish". ## Example ```js -const { registerPlugin } = wp.plugins; -const { PluginPrePublishPanel }= wp.editPost; - -const PluginPrePublishPanelTest = () => { - return ( - -

Pre Publish Panel

-
- ) -} - -registerPlugin( 'pre-publish-panel-test', { render: PluginPrePublishPanelTest } ); - +import { registerPlugin } from '@wordpress/plugins'; +import { PluginPrePublishPanel } from '@wordpress/edit-post'; + +const PluginPrePublishPanelTest = () => ( + +

Pre Publish Panel

+
+); + +registerPlugin( 'pre-publish-panel-test', { + render: PluginPrePublishPanelTest, +} ); ``` ## Location diff --git a/docs/designers-developers/developers/slotfills/plugin-sidebar-more-menu-item.md b/docs/designers-developers/developers/slotfills/plugin-sidebar-more-menu-item.md index 40d1e0e22bab54..687a898c53047a 100644 --- a/docs/designers-developers/developers/slotfills/plugin-sidebar-more-menu-item.md +++ b/docs/designers-developers/developers/slotfills/plugin-sidebar-more-menu-item.md @@ -7,33 +7,24 @@ This is done by setting the `target` on `` to match t ```js import { registerPlugin } from '@wordpress/plugins'; -import { - PluginSidebar, - PluginSidebarMoreMenuItem -} from '@wordpress/edit-post'; +import { PluginSidebar, PluginSidebarMoreMenuItem } from '@wordpress/edit-post'; import { image } from '@wordpress/icons'; - -const { Fragment } = wp.element; -const myIcon = +import { Fragment } from '@wordpress/element'; const PluginSidebarMoreMenuItemTest = () => ( - + Expanded Sidebar - More item - + Content of the sidebar -) +); -registerPlugin( 'plugin-sidebar-expanded-test', { render: PluginSidebarMoreMenuItemTest } ); +registerPlugin( 'plugin-sidebar-expanded-test', { + render: PluginSidebarMoreMenuItemTest, +} ); ``` ## Location diff --git a/docs/designers-developers/developers/slotfills/plugin-sidebar.md b/docs/designers-developers/developers/slotfills/plugin-sidebar.md index 8af1641f6ea1fd..b5467f04c4bebd 100644 --- a/docs/designers-developers/developers/slotfills/plugin-sidebar.md +++ b/docs/designers-developers/developers/slotfills/plugin-sidebar.md @@ -10,17 +10,12 @@ import { registerPlugin } from '@wordpress/plugins'; import { PluginSidebar } from '@wordpress/edit-post'; import { image } from '@wordpress/icons'; -const PluginSidebarTest = () => { - return ( - -

Plugin Sidebar

-
- ); -}; +const PluginSidebarTest = () => ( + +

Plugin Sidebar

+
+); + registerPlugin( 'plugin-sidebar-test', { render: PluginSidebarTest } ); ``` diff --git a/docs/designers-developers/developers/tutorials/readme.md b/docs/designers-developers/developers/tutorials/readme.md index 1a533bb595e16c..791048722f3bc9 100644 --- a/docs/designers-developers/developers/tutorials/readme.md +++ b/docs/designers-developers/developers/tutorials/readme.md @@ -12,4 +12,4 @@ * Learn how to add customized buttons to the toolbar with the [Format API tutorial](/docs/designers-developers/developers/tutorials/format-api/). -* Build your own [custom block editor instance](/docs/designers-developers/developers/tutorials/custom-block-editor/) - this will walk you through building a standalone instance of the block editor within WP Admin. \ No newline at end of file +* Build your own [custom block editor instance](/docs/designers-developers/developers/platform/custom-block-editor/) - this will walk you through building a standalone instance of the block editor within WP Admin. \ No newline at end of file diff --git a/gutenberg.php b/gutenberg.php index bdd7d4ebce6c2d..c151804694118a 100644 --- a/gutenberg.php +++ b/gutenberg.php @@ -3,7 +3,7 @@ * Plugin Name: Gutenberg * Plugin URI: https://github.com/WordPress/gutenberg * Description: Printing since 1440. This is the development plugin for the new block editor in core. - * Version: 7.6.0 + * Version: 7.7.0-rc.1 * Author: Gutenberg Team * Text Domain: gutenberg * diff --git a/lib/client-assets.php b/lib/client-assets.php index 10f36ce3a1d8d1..be7eeb19a83bb0 100644 --- a/lib/client-assets.php +++ b/lib/client-assets.php @@ -650,10 +650,10 @@ function gutenberg_load_block_pattern( $name ) { */ function gutenberg_extend_settings_block_patterns( $settings ) { $block_patterns = [ - gutenberg_load_block_pattern( 'teams' ), - gutenberg_load_block_pattern( 'testimonial' ), - gutenberg_load_block_pattern( 'columns4-footer' ), - gutenberg_load_block_pattern( 'natural-columns' ), + gutenberg_load_block_pattern( 'text-two-columns' ), + gutenberg_load_block_pattern( 'two-buttons' ), + gutenberg_load_block_pattern( 'cover-abc' ), + gutenberg_load_block_pattern( 'two-images' ), ]; $settings['__experimentalBlockPatterns'] = $block_patterns; return $settings; diff --git a/lib/patterns/columns4-footer.json b/lib/patterns/columns4-footer.json deleted file mode 100644 index f968a91b106131..00000000000000 --- a/lib/patterns/columns4-footer.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "__file": "wp_block", - "title": "4 columns footer", - "content": "\n
\n
\n\n\n\n\n\n\n\n\n\n\n\n\n
\n\n
\n
\n
\n" -} diff --git a/lib/patterns/cover-abc.json b/lib/patterns/cover-abc.json new file mode 100644 index 00000000000000..c1ff0314f8b56b --- /dev/null +++ b/lib/patterns/cover-abc.json @@ -0,0 +1,5 @@ +{ + "__file": "wp_block", + "title": "Cover", + "content": "\n
\n

abc!

\n
\n" + } diff --git a/lib/patterns/natural-columns.json b/lib/patterns/natural-columns.json deleted file mode 100644 index a352928a4bbf8d..00000000000000 --- a/lib/patterns/natural-columns.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "__file": "wp_block", - "title": "Natural Columns", - "content": "\n
\n
\n
\"\"/
\n\n\n\n
\"\"/
\n
\n\n\n\n
\n
\"\"/
\n\n\n\n

\n
\n\n\n\n
\n
\"\"/
\n\n\n\n
\"\"/
\n
\n
\n\n\n\n

Breath

\n\n\n\n

Here's a short paragraph about nature and how being outside is a breath of fresh air. A little air is good for the mind and body.

\n" -} \ No newline at end of file diff --git a/lib/patterns/teams.json b/lib/patterns/teams.json deleted file mode 100644 index c7cc28785ca15d..00000000000000 --- a/lib/patterns/teams.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "__file": "wp_block", - "title": "Teams", - "content": "\n
\n
\n
\n
\n
\"CC0
\n\n\n\n

Eliza Jason

\n\n\n\n

SEO & SMM

\n\n\n\n\n
\n\n\n\n
\n
\"CC0
\n\n\n\n

Bryant Van

\n\n\n\n

Web-Developer

\n\n\n\n\n
\n\n\n\n
\n
\"CC0
\n\n\n\n

Anna Caris

\n\n\n\n

Web-Designer

\n\n\n\n\n
\n
\n
\n
\n" -} diff --git a/lib/patterns/testimonial.json b/lib/patterns/testimonial.json deleted file mode 100644 index a42b13ae5b8a21..00000000000000 --- a/lib/patterns/testimonial.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "__file": "wp_block", - "title": "Testimonial", - "content": "\n
\"CC0
\n\n\n\n

“These guys are amazing! A very professional team that delivers excellent results every time we come for help. I highly recommend this company for your projects!”

\n\n\n\n

ANNA JANISON
director at CYKO

\n" -} \ No newline at end of file diff --git a/lib/patterns/text-two-columns.json b/lib/patterns/text-two-columns.json new file mode 100644 index 00000000000000..1f6f33a865d51b --- /dev/null +++ b/lib/patterns/text-two-columns.json @@ -0,0 +1,5 @@ +{ + "__file": "wp_block", + "title": "Two Columns of Text", + "content": "\n
\n
\n

CHAPTER 1. Loomings

\n\n\n\n

Call me Ishmael. Some years ago—never mind how long precisely—having little or no money in my purse, and nothing particular to interest me on shore, I thought I would sail about a little and see the watery part of the world. It is a way I have of driving off the spleen and regulating the circulation.

\n
\n\n\n\n
\n

Whenever I find myself growing grim about the mouth; whenever it is a damp, drizzly November in my soul; whenever I find myself involuntarily pausing before coffin warehouses, and bringing up the rear of every funeral I meet; and especially whenever my hypos get such an upper hand of me, that it requires a strong moral principle to prevent me from deliberately stepping into the street, and methodically knocking people’s hats off—then, I account it high time tozz get to sea as soon as I can.

\n
\n
\n" + } diff --git a/lib/patterns/two-buttons.json b/lib/patterns/two-buttons.json new file mode 100644 index 00000000000000..74bc530e77dedd --- /dev/null +++ b/lib/patterns/two-buttons.json @@ -0,0 +1,5 @@ +{ + "__file": "wp_block", + "title": "Two Buttons", + "content": "\n\n" + } diff --git a/lib/patterns/two-images.json b/lib/patterns/two-images.json new file mode 100644 index 00000000000000..d3303be5d5c6c1 --- /dev/null +++ b/lib/patterns/two-images.json @@ -0,0 +1,5 @@ +{ + "__file": "wp_block", + "title": "Two images side by side", + "content": "\n\n" +} diff --git a/package-lock.json b/package-lock.json index e6cb17be3c22c4..2b72c285bff0ba 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "gutenberg", - "version": "7.6.0", + "version": "7.7.0-rc.1", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -10093,6 +10093,7 @@ "lodash": "^4.17.15", "memize": "^1.0.5", "react-autosize-textarea": "^3.0.2", + "react-resize-aware": "^3.0.0", "react-spring": "^8.0.19", "redux-multi": "^0.1.12", "refx": "^3.0.0", @@ -19770,7 +19771,7 @@ }, "node-pre-gyp": { "version": "0.12.0", - "resolved": false, + "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.12.0.tgz", "integrity": "sha512-4KghwV8vH5k+g2ylT+sLTjy5wmUOb9vPhnM8NHvRf9dHmnW/CndrFXy2aRPaPST6dugXSdHXfeaHQm77PIz/1A==", "dev": true, "optional": true, @@ -19789,7 +19790,7 @@ }, "nopt": { "version": "4.0.1", - "resolved": false, + "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz", "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", "dev": true, "optional": true, diff --git a/package.json b/package.json index d8ed5f7f4aa86f..f426ebd53a6a95 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gutenberg", - "version": "7.6.0", + "version": "7.7.0-rc.1", "private": true, "description": "A new WordPress editor experience.", "author": "The WordPress Contributors", diff --git a/packages/block-editor/package.json b/packages/block-editor/package.json index 026071f18f5d8e..dfe9bf03d86a3e 100644 --- a/packages/block-editor/package.json +++ b/packages/block-editor/package.json @@ -52,6 +52,7 @@ "lodash": "^4.17.15", "memize": "^1.0.5", "react-autosize-textarea": "^3.0.2", + "react-resize-aware": "^3.0.0", "react-spring": "^8.0.19", "redux-multi": "^0.1.12", "refx": "^3.0.0", diff --git a/packages/block-editor/src/components/block-patterns/index.js b/packages/block-editor/src/components/block-patterns/index.js index c265548cf6e82d..caac37ef7cfc35 100644 --- a/packages/block-editor/src/components/block-patterns/index.js +++ b/packages/block-editor/src/components/block-patterns/index.js @@ -34,7 +34,7 @@ function BlockPattern( { pattern, onClick } ) { tabIndex={ 0 } >
- +
{ title }
diff --git a/packages/block-editor/src/components/block-patterns/style.scss b/packages/block-editor/src/components/block-patterns/style.scss index 97a428d818505f..f40f46b04001cb 100644 --- a/packages/block-editor/src/components/block-patterns/style.scss +++ b/packages/block-editor/src/components/block-patterns/style.scss @@ -21,17 +21,7 @@ } .block-editor-patterns__item-preview { - overflow: hidden; - height: 200px; - - .block-editor-block-preview__container { - height: 100%; - } - - .block-editor-block-preview__content { - display: flex; - justify-content: center; - } + padding: $grid-unit-20; } .block-editor-patterns__item-title { diff --git a/packages/block-editor/src/components/block-preview/auto.js b/packages/block-editor/src/components/block-preview/auto.js new file mode 100644 index 00000000000000..6b7c5857169c0c --- /dev/null +++ b/packages/block-editor/src/components/block-preview/auto.js @@ -0,0 +1,49 @@ +/** + * External dependencies + */ +import useResizeAware from 'react-resize-aware'; + +/** + * WordPress dependencies + */ +import { Disabled } from '@wordpress/components'; + +/** + * Internal dependencies + */ +import BlockList from '../block-list'; + +function AutoBlockPreview( { viewportWidth } ) { + const [ + containerResizeListener, + { width: containerWidth }, + ] = useResizeAware(); + const [ + containtResizeListener, + { height: contentHeight }, + ] = useResizeAware(); + + return ( +
+ { containerResizeListener } + + { containtResizeListener } + + +
+ ); +} + +export default AutoBlockPreview; diff --git a/packages/block-editor/src/components/block-preview/index.js b/packages/block-editor/src/components/block-preview/index.js index 5be781cc917d78..522bd6014282bc 100644 --- a/packages/block-editor/src/components/block-preview/index.js +++ b/packages/block-editor/src/components/block-preview/index.js @@ -2,179 +2,49 @@ * External dependencies */ import { castArray, noop } from 'lodash'; -import classnames from 'classnames'; /** * WordPress dependencies */ -import { Disabled } from '@wordpress/components'; -import { withSelect } from '@wordpress/data'; -import { - useLayoutEffect, - useState, - useRef, - useReducer, - useMemo, -} from '@wordpress/element'; +import { useSelect } from '@wordpress/data'; +import { useLayoutEffect, useReducer, useMemo } from '@wordpress/element'; /** * Internal dependencies */ import BlockEditorProvider from '../provider'; -import BlockList from '../block-list'; -import { getBlockPreviewContainerDOMNode } from '../../utils/dom'; - -const getInlineStyles = ( scale, x, y, isReady, width ) => ( { - transform: `scale(${ scale })`, - visibility: isReady ? 'visible' : 'hidden', - left: x, - top: y, - width, -} ); - -function ScaledBlockPreview( { - blocks, - viewportWidth, - padding = 0, - onReady, - scalingDelay, -} ) { - const previewRef = useRef( null ); - - const [ isReady, setIsReady ] = useState( false ); - const [ previewScale, setPreviewScale ] = useState( 1 ); - const [ { x, y }, setPosition ] = useState( { x: 0, y: 0 } ); - - // Dynamically calculate the scale factor - useLayoutEffect( () => { - // Timer - required to account for async render of `BlockEditorProvider` - const timerId = setTimeout( () => { - const containerElement = previewRef.current; - if ( ! containerElement ) { - return; - } - - // Auxiliary vars used for onReady() callback. - let scale, - offsetX = 0, - offsetY = 0; - - // If we're previewing a single block, scale the preview to fit it. - if ( blocks.length === 1 ) { - const block = blocks[ 0 ]; - const previewElement = getBlockPreviewContainerDOMNode( - block.clientId - ); - if ( ! previewElement ) { - return; - } - - let containerElementRect = containerElement.getBoundingClientRect(); - containerElementRect = { - width: containerElementRect.width - padding * 2, - height: containerElementRect.height - padding * 2, - left: containerElementRect.left, - top: containerElementRect.top, - }; - const scaledElementRect = previewElement.getBoundingClientRect(); - - scale = - containerElementRect.width / scaledElementRect.width || 1; - offsetX = - -( scaledElementRect.left - containerElementRect.left ) * - scale + - padding; - offsetY = - containerElementRect.height > - scaledElementRect.height * scale - ? ( containerElementRect.height - - scaledElementRect.height * scale ) / - 2 + - padding - : 0; - - setPreviewScale( scale ); - setPosition( { x: offsetX, y: offsetY } ); - - // Hack: we need to reset the scaled elements margins - previewElement.style.marginTop = '0'; - } else { - const containerElementRect = containerElement.getBoundingClientRect(); - scale = containerElementRect.width / viewportWidth; - setPreviewScale( scale ); - } - - setIsReady( true ); - onReady( { - scale, - position: { x: offsetX, y: offsetY }, - previewContainerRef: previewRef, - - inlineStyles: getInlineStyles( - scale, - offsetX, - offsetY, - true, - viewportWidth - ), - } ); - }, scalingDelay ); - - // Cleanup - return () => { - if ( timerId ) { - window.clearTimeout( timerId ); - } - }; - }, [] ); - - if ( ! blocks || blocks.length === 0 ) { - return null; - } - - const previewStyles = getInlineStyles( - previewScale, - x, - y, - isReady, - viewportWidth - ); - - return ( -
- - - -
- ); -} +import ScaledBlockPreview from './scaled'; +import AutoHeightBlockPreview from './auto'; +/** + * BlockPreview renders a preview of a block or array of blocks. + * + * @see https://github.com/WordPress/gutenberg/blob/master/packages/block-editor/src/components/block-preview/README.md + * + * @param {Array|Object} blocks A block instance (object) or an array of blocks to be previewed. + * @param {number} viewportWidth Width of the preview container in pixels. Controls at what size the blocks will be rendered inside the preview. Default: 700. + * @return {WPComponent} The component to be rendered. + */ export function BlockPreview( { blocks, viewportWidth = 700, padding, - settings, + autoHeight = false, __experimentalOnReady = noop, __experimentalScalingDelay = 100, } ) { + const settings = useSelect( ( select ) => + select( 'core/block-editor' ).getSettings() + ); const renderedBlocks = useMemo( () => castArray( blocks ), [ blocks ] ); const [ recompute, triggerRecompute ] = useReducer( ( state ) => state + 1, 0 ); useLayoutEffect( triggerRecompute, [ blocks ] ); + if ( ! blocks || blocks.length === 0 ) { + return null; + } return ( { /* @@ -182,29 +52,23 @@ export function BlockPreview( { * by remounting the component, ScaledBlockPreview is not meant to * be rerendered. */ } - + { autoHeight ? ( + + ) : ( + + ) } ); } -/** - * BlockPreview renders a preview of a block or array of blocks. - * - * @see https://github.com/WordPress/gutenberg/blob/master/packages/block-editor/src/components/block-preview/README.md - * - * @param {Array|Object} blocks A block instance (object) or an array of blocks to be previewed. - * @param {number} viewportWidth Width of the preview container in pixels. Controls at what size the blocks will be rendered inside the preview. Default: 700. - * @return {WPComponent} The component to be rendered. - */ -export default withSelect( ( select ) => { - return { - settings: select( 'core/block-editor' ).getSettings(), - }; -} )( BlockPreview ); +export default BlockPreview; diff --git a/packages/block-editor/src/components/block-preview/scaled.js b/packages/block-editor/src/components/block-preview/scaled.js new file mode 100644 index 00000000000000..69496241fdb5ac --- /dev/null +++ b/packages/block-editor/src/components/block-preview/scaled.js @@ -0,0 +1,155 @@ +/** + * External dependencies + */ +import classnames from 'classnames'; + +/** + * WordPress dependencies + */ +import { Disabled } from '@wordpress/components'; +import { useLayoutEffect, useState, useRef } from '@wordpress/element'; + +/** + * Internal dependencies + */ +import BlockList from '../block-list'; +import { getBlockPreviewContainerDOMNode } from '../../utils/dom'; + +const getInlineStyles = ( scale, x, y, isReady, width ) => ( { + transform: `scale(${ scale })`, + visibility: isReady ? 'visible' : 'hidden', + left: x, + top: y, + width, +} ); + +function ScaledBlockPreview( { + blocks, + viewportWidth, + padding = 0, + onReady, + scalingDelay, +} ) { + const previewRef = useRef( null ); + + const [ isReady, setIsReady ] = useState( false ); + const [ previewScale, setPreviewScale ] = useState( 1 ); + const [ { x, y }, setPosition ] = useState( { x: 0, y: 0 } ); + + // Dynamically calculate the scale factor + useLayoutEffect( () => { + // Timer - required to account for async render of `BlockEditorProvider` + const timerId = setTimeout( () => { + const containerElement = previewRef.current; + if ( ! containerElement ) { + return; + } + + // Auxiliary vars used for onReady() callback. + let scale, + offsetX = 0, + offsetY = 0; + + // If we're previewing a single block, scale the preview to fit it. + if ( blocks.length === 1 ) { + const block = blocks[ 0 ]; + const previewElement = getBlockPreviewContainerDOMNode( + block.clientId + ); + if ( ! previewElement ) { + return; + } + + let containerElementRect = containerElement.getBoundingClientRect(); + containerElementRect = { + width: containerElementRect.width - padding * 2, + height: containerElementRect.height - padding * 2, + left: containerElementRect.left, + top: containerElementRect.top, + }; + const scaledElementRect = previewElement.getBoundingClientRect(); + + scale = + containerElementRect.width / scaledElementRect.width || 1; + offsetX = + -( scaledElementRect.left - containerElementRect.left ) * + scale + + padding; + offsetY = + containerElementRect.height > + scaledElementRect.height * scale + ? ( containerElementRect.height - + scaledElementRect.height * scale ) / + 2 + + padding + : 0; + + setPreviewScale( scale ); + setPosition( { x: offsetX, y: offsetY } ); + + // Hack: we need to reset the scaled elements margins + previewElement.style.marginTop = '0'; + } else { + const containerElementRect = containerElement.getBoundingClientRect(); + scale = containerElementRect.width / viewportWidth; + setPreviewScale( scale ); + } + + setIsReady( true ); + onReady( { + scale, + position: { x: offsetX, y: offsetY }, + previewContainerRef: previewRef, + + inlineStyles: getInlineStyles( + scale, + offsetX, + offsetY, + true, + viewportWidth + ), + } ); + }, scalingDelay ); + + // Cleanup + return () => { + if ( timerId ) { + window.clearTimeout( timerId ); + } + }; + }, [] ); + + if ( ! blocks || blocks.length === 0 ) { + return null; + } + + const previewStyles = getInlineStyles( + previewScale, + x, + y, + isReady, + viewportWidth + ); + + return ( +
+ + + +
+ ); +} + +export default ScaledBlockPreview; diff --git a/packages/block-editor/src/components/block-preview/style.scss b/packages/block-editor/src/components/block-preview/style.scss index 99c0a4006ada29..1628c178dbd059 100644 --- a/packages/block-editor/src/components/block-preview/style.scss +++ b/packages/block-editor/src/components/block-preview/style.scss @@ -29,18 +29,17 @@ transform-origin: top left; // Resetting paddings, margins, and other. + text-align: initial; margin: 0; overflow: visible; min-height: auto; - .block-editor-block-list__layout, - .block-editor-block-list__block { - padding: 0; - } - - > div section { - height: auto; + .block-editor-block-preview__container &.is-centered { + .block-editor-block-list__layout, + .block-editor-block-list__block { + padding: 0; + } } .block-editor-block-list__insertion-point, diff --git a/packages/block-library/src/gallery/style.scss b/packages/block-library/src/gallery/style.scss index 94e2780f128815..fc1a7c7c8b76b2 100644 --- a/packages/block-library/src/gallery/style.scss +++ b/packages/block-library/src/gallery/style.scss @@ -84,7 +84,7 @@ // On mobile and responsive viewports, we allow only 1 or 2 columns at the most. & .blocks-gallery-image, & .blocks-gallery-item { - width: calc((100% - #{ $grid-unit-20 }) / 2); + width: calc(50% - #{ $grid-unit-20 }); &:nth-of-type(even) { margin-right: 0; @@ -102,15 +102,8 @@ @for $i from 3 through 8 { &.columns-#{ $i } .blocks-gallery-image, &.columns-#{ $i } .blocks-gallery-item { - width: calc((100% - #{ $grid-unit-20 } * #{ $i - 1 }) / #{ $i }); - margin-right: 16px; - - // Rules inside this query are only run by Microsoft Edge. - // Edge miscalculates `calc`, so we have to add some buffer. - // See also https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/15637241/ - @supports (-ms-ime-align:auto) { - width: calc((100% - #{ $grid-unit-20 } * #{ $i - 1 }) / #{ $i } - 1px); - } + width: calc(#{ 100% / $i } - #{ $grid-unit-20 * ( $i - 1 ) / $i }); + margin-right: $grid-unit-20; } } diff --git a/packages/block-library/src/latest-posts/edit.js b/packages/block-library/src/latest-posts/edit.js index 98e43940a9c8ba..8fa27ca78686cc 100644 --- a/packages/block-library/src/latest-posts/edit.js +++ b/packages/block-library/src/latest-posts/edit.js @@ -325,6 +325,21 @@ class LatestPostsEdit extends Component { [ `align${ featuredImageAlign }` ]: !! featuredImageAlign, } ); + const postExcerpt = + excerptLength < + excerpt.trim().split( ' ' ).length && + post.excerpt.raw === '' + ? excerpt + .trim() + .split( ' ', excerptLength ) + .join( ' ' ) + + ' ... ' + + __( 'Read more' ) + + '' + : excerpt; + return (
  • { displayFeaturedImage && ( @@ -370,28 +385,7 @@ class LatestPostsEdit extends Component { displayPostContentRadio === 'excerpt' && (
    - { excerptLength < - excerpt.trim().split( ' ' ) - .length - ? excerpt - .trim() - .split( - ' ', - excerptLength - ) - .join( ' ' ) + - ' ... ' + - __( 'Read more' ) + - '' - : excerpt - .trim() - .split( - ' ', - excerptLength - ) - .join( ' ' ) } + { postExcerpt }
    ) } diff --git a/packages/components/src/angle-picker-control/index.js b/packages/components/src/angle-picker-control/index.js index 517f67a3966364..9350c61f74f15c 100644 --- a/packages/components/src/angle-picker-control/index.js +++ b/packages/components/src/angle-picker-control/index.js @@ -39,6 +39,10 @@ const AngleCircle = ( { value, onChange, ...props } ) => { const changeAngleToPosition = ( event ) => { const { x: centerX, y: centerY } = angleCircleCenter.current; + // Prevent (drag) mouse events from selecting and accidentally + // triggering actions from other elements. + event.preventDefault(); + onChange( getAngle( centerX, centerY, event.clientX, event.clientY ) ); }; diff --git a/packages/components/src/custom-gradient-picker/style.scss b/packages/components/src/custom-gradient-picker/style.scss index ed0f6febd6b349..bf8c473a5179df 100644 --- a/packages/components/src/custom-gradient-picker/style.scss +++ b/packages/components/src/custom-gradient-picker/style.scss @@ -24,15 +24,22 @@ $components-custom-gradient-picker__padding: 3px; // 24px container, 18px handle border-radius: 50%; background: $white; padding: 2px; + min-width: $button-size-small; width: $button-size-small; height: $button-size-small; position: relative; + + svg { + height: 100%; + width: 100%; + } } .components-custom-gradient-picker__control-point-button { border: 2px solid $white; border-radius: 50%; height: 18px; + padding: 0; position: absolute; width: 18px; top: $components-custom-gradient-picker__padding; @@ -42,7 +49,6 @@ $components-custom-gradient-picker__padding: 3px; // 24px container, 18px handle color: #23282d; border-color: #999; box-shadow: - inset 0 -1px 0 #999, 0 0 0 1px $white, 0 0 0 3px $blue-medium-focus; } diff --git a/packages/components/src/range-control/index.js b/packages/components/src/range-control/index.js index 52706623ef7454..cee2659ed04e85 100644 --- a/packages/components/src/range-control/index.js +++ b/packages/components/src/range-control/index.js @@ -2,7 +2,7 @@ * External dependencies */ import classnames from 'classnames'; -import { clamp, noop } from 'lodash'; +import { clamp, isFinite, noop } from 'lodash'; /** * WordPress dependencies @@ -18,7 +18,11 @@ import BaseControl from '../base-control'; import Button from '../button'; import Icon from '../icon'; import { color } from '../utils/colors'; -import { useControlledRangeValue, useDebouncedHoverInteraction } from './utils'; +import { + floatClamp, + useControlledRangeValue, + useDebouncedHoverInteraction, +} from './utils'; import RangeRail from './rail'; import SimpleTooltip from './tooltip'; import { @@ -42,6 +46,7 @@ const BaseRangeControl = forwardRef( allowReset = false, beforeIcon, className, + currentInput, color: colorProp = color( 'blue.wordpress.700' ), disabled = false, help, @@ -54,7 +59,7 @@ const BaseRangeControl = forwardRef( onBlur = noop, onChange = noop, onFocus = noop, - onMouseEnter = noop, + onMouseMove = noop, onMouseLeave = noop, renderTooltipContent = ( v ) => v, showTooltip: showTooltipProp, @@ -67,7 +72,7 @@ const BaseRangeControl = forwardRef( ) => { const isRTL = useRtl(); - const sliderValue = initialPosition || valueProp; + const sliderValue = valueProp || initialPosition; const [ value, setValue ] = useControlledRangeValue( { min, max, @@ -75,7 +80,6 @@ const BaseRangeControl = forwardRef( } ); const [ showTooltip, setShowTooltip ] = useState( showTooltipProp ); const [ isFocused, setIsFocused ] = useState( false ); - const originalValueRef = useRef( value ); const inputRef = useRef(); @@ -90,7 +94,16 @@ const BaseRangeControl = forwardRef( const isCurrentlyFocused = inputRef.current?.matches( ':focus' ); const isThumbFocused = ! disabled && isFocused; - const fillValue = ( ( value - min ) / ( max - min ) ) * 100; + const isValueReset = value === null; + const inputSliderValue = isValueReset ? '' : value; + const currentInputValue = isValueReset ? '' : value || currentInput; + + const rangeFillValue = isValueReset + ? floatClamp( max / 2, min, max ) + : value; + + const calculatedFillValue = ( ( value - min ) / ( max - min ) ) * 100; + const fillValue = isValueReset ? 50 : calculatedFillValue; const fillValueOffset = `${ clamp( fillValue, 0, 100 ) }%`; const classes = classnames( 'components-range-control', className ); @@ -103,7 +116,7 @@ const BaseRangeControl = forwardRef( const id = `inspector-range-control-${ instanceId }`; const describedBy = !! help ? `${ id }__help` : undefined; - const enableTooltip = showTooltipProp !== false; + const enableTooltip = showTooltipProp !== false && isFinite( value ); const handleOnChange = ( event ) => { if ( ! event.target.checkValidity() ) { @@ -117,10 +130,8 @@ const BaseRangeControl = forwardRef( }; const handleOnReset = () => { - const nextValue = originalValueRef.current; - - setValue( nextValue ); - onChange( nextValue ); + setValue( null ); + onChange( undefined ); }; const handleShowTooltip = () => setShowTooltip( true ); @@ -141,7 +152,7 @@ const BaseRangeControl = forwardRef( const hoverInteractions = useDebouncedHoverInteraction( { onShow: handleShowTooltip, onHide: handleHideTooltip, - onMouseEnter, + onMouseMove, onMouseLeave, } ); @@ -188,7 +199,7 @@ const BaseRangeControl = forwardRef( step={ step } tabIndex={ 0 } type="range" - value={ value } + value={ inputSliderValue } /> { enableTooltip && ( ) } { allowReset && ( diff --git a/packages/components/src/range-control/styles/range-control-styles.js b/packages/components/src/range-control/styles/range-control-styles.js index 8b55777467414f..d20af0055c917f 100644 --- a/packages/components/src/range-control/styles/range-control-styles.js +++ b/packages/components/src/range-control/styles/range-control-styles.js @@ -248,6 +248,7 @@ export const Tooltip = styled.span` min-width: 32px; opacity: 0; padding: 8px; + pointer-events: none; position: absolute; text-align: center; transition: opacity 120ms ease; diff --git a/packages/components/src/range-control/test/index.js b/packages/components/src/range-control/test/index.js index 5f333b2a40676f..4c67a4f9c1a8f6 100644 --- a/packages/components/src/range-control/test/index.js +++ b/packages/components/src/range-control/test/index.js @@ -1,7 +1,7 @@ /** * External dependencies */ -import TestUtils from 'react-dom/test-utils'; +import TestUtils, { act } from 'react-dom/test-utils'; /** * Internal dependencies @@ -293,4 +293,119 @@ describe( 'RangeControl', () => { expect( onChange ).toHaveBeenCalledWith( 0.225 ); } ); } ); + + describe( 'initialPosition / value', () => { + const getInputElement = ( wrapper ) => + TestUtils.findRenderedDOMComponentWithClass( + wrapper, + 'components-range-control__slider' + ); + + it( 'renders initial rendered value of 50% of min/max, if no initialPosition or value is defined', () => { + const wrapper = getWrapper( { min: 0, max: 10 } ); + const inputElement = getInputElement( wrapper ); + + expect( inputElement.value ).toBe( '5' ); + } ); + + it( 'renders initialPosition if no value is provided', () => { + const wrapper = getWrapper( { + initialPosition: 50, + value: undefined, + } ); + const inputElement = getInputElement( wrapper ); + + expect( inputElement.value ).toBe( '50' ); + } ); + + it( 'renders value instead of initialPosition is provided', () => { + const wrapper = getWrapper( { initialPosition: 50, value: 10 } ); + const inputElement = getInputElement( wrapper ); + + expect( inputElement.value ).toBe( '10' ); + } ); + } ); + + describe( 'reset', () => { + class StatefulTestWrapper extends Component { + constructor( props ) { + super( props ); + this.state = { + value: undefined, + }; + this.handleOnChange = this.handleOnChange.bind( this ); + } + + handleOnChange( nextValue = this.props.resetFallbackValue ) { + this.setState( { value: nextValue } ); + } + + render() { + return ( + + ); + } + } + + const getStatefulWrapper = ( props = {} ) => + TestUtils.renderIntoDocument( + + ); + + const getInputElement = ( wrapper ) => + TestUtils.findRenderedDOMComponentWithClass( + wrapper, + 'components-range-control__slider' + ); + + it( 'resets to a custom fallback value, defined by a parent component', () => { + const wrapper = getStatefulWrapper( { + initialPosition: 50, + value: 10, + allowReset: true, + resetFallbackValue: 33, + } ); + + const resetButton = TestUtils.findRenderedDOMComponentWithClass( + wrapper, + 'components-range-control__reset' + ); + + act( () => { + TestUtils.Simulate.click( resetButton ); + } ); + + const inputElement = getInputElement( wrapper ); + + expect( inputElement.value ).toBe( '33' ); + } ); + + it( 'resets to a 50% of min/max value, of no initialPosition or value is defined', () => { + const wrapper = getStatefulWrapper( { + initialPosition: undefined, + value: 10, + min: 0, + max: 100, + allowReset: true, + resetFallbackValue: undefined, + } ); + + const resetButton = TestUtils.findRenderedDOMComponentWithClass( + wrapper, + 'components-range-control__reset' + ); + + act( () => { + TestUtils.Simulate.click( resetButton ); + } ); + + const inputElement = getInputElement( wrapper ); + + expect( inputElement.value ).toBe( '50' ); + } ); + } ); } ); diff --git a/packages/components/src/range-control/utils.js b/packages/components/src/range-control/utils.js index 4c39afebe99109..d1fd148ec2a3fb 100644 --- a/packages/components/src/range-control/utils.js +++ b/packages/components/src/range-control/utils.js @@ -1,7 +1,7 @@ /** * External dependencies */ -import { clamp, noop } from 'lodash'; +import { clamp, isFinite, noop } from 'lodash'; /** * WordPress dependencies @@ -11,35 +11,42 @@ import { useCallback, useRef, useEffect, useState } from '@wordpress/element'; /** * A float supported clamp function for a specific value. * - * @param {number} value The value to clamp + * @param {number|null} value The value to clamp * @param {number} min The minimum value * @param {number} max The maxinum value * * @return {number} A (float) number */ -function floatClamp( value, min, max ) { +export function floatClamp( value, min, max ) { + if ( ! isFinite( value ) ) { + return null; + } + return parseFloat( clamp( value, min, max ) ); } /** * Hook to store a clamped value, derived from props. */ -export function useControlledRangeValue( { min, max, value: valueProp = 0 } ) { +export function useControlledRangeValue( { min, max, value: valueProp } ) { const [ value, setValue ] = useState( floatClamp( valueProp, min, max ) ); const valueRef = useRef( value ); - const setClampValue = ( nextValue ) => { - setValue( floatClamp( nextValue, min, max ) ); - }; + const setClampValue = useCallback( + ( nextValue ) => { + setValue( floatClamp( nextValue, min, max ) ); + }, + [ setValue, min, max ] + ); useEffect( () => { if ( valueRef.current !== valueProp ) { setClampValue( valueProp ); valueRef.current = valueProp; } - }, [ valueProp, setClampValue ] ); + }, [ valueProp, setValue ] ); - return [ value, setClampValue ]; + return [ value, setValue ]; } /** @@ -49,7 +56,7 @@ export function useControlledRangeValue( { min, max, value: valueProp = 0 } ) { export function useDebouncedHoverInteraction( { onShow = noop, onHide = noop, - onMouseEnter = noop, + onMouseMove = noop, onMouseLeave = noop, timeout = 300, } ) { @@ -65,8 +72,8 @@ export function useDebouncedHoverInteraction( { [ timeout ] ); - const handleOnMouseEnter = useCallback( ( event ) => { - onMouseEnter( event ); + const handleOnMouseMove = useCallback( ( event ) => { + onMouseMove( event ); setDebouncedTimeout( () => { if ( ! show ) { @@ -92,7 +99,7 @@ export function useDebouncedHoverInteraction( { } ); return { - onMouseEnter: handleOnMouseEnter, + onMouseMove: handleOnMouseMove, onMouseLeave: handleOnMouseLeave, }; } diff --git a/packages/edit-post/src/components/header/header-toolbar/index.js b/packages/edit-post/src/components/header/header-toolbar/index.js index 7de48dc7abffac..080f9e2c258257 100644 --- a/packages/edit-post/src/components/header/header-toolbar/index.js +++ b/packages/edit-post/src/components/header/header-toolbar/index.js @@ -11,7 +11,11 @@ import { BlockNavigationDropdown, ToolSelector, } from '@wordpress/block-editor'; -import { EditorHistoryRedo, EditorHistoryUndo } from '@wordpress/editor'; +import { + TableOfContents, + EditorHistoryRedo, + EditorHistoryUndo, +} from '@wordpress/editor'; const inserterToggleProps = { isPrimary: true }; @@ -63,6 +67,7 @@ function HeaderToolbar() { + { displayBlockToolbar && (
    diff --git a/packages/edit-post/src/components/header/style.scss b/packages/edit-post/src/components/header/style.scss index d4e8fe8a3e4b3f..a476cb050d73f5 100644 --- a/packages/edit-post/src/components/header/style.scss +++ b/packages/edit-post/src/components/header/style.scss @@ -34,7 +34,7 @@ .edit-post-header__toolbar { display: flex; flex-grow: 1; - padding-left: $grid-unit-20; + padding-left: $grid-unit-30; } .edit-post-header__settings { @@ -54,6 +54,7 @@ // Special dimensions for this button. min-width: 32px; height: 32px; + margin-right: $grid-unit-10; } } diff --git a/packages/edit-post/src/components/layout/index.js b/packages/edit-post/src/components/layout/index.js index 73956e54b89cc0..99bdd87a457b62 100644 --- a/packages/edit-post/src/components/layout/index.js +++ b/packages/edit-post/src/components/layout/index.js @@ -13,7 +13,6 @@ import { EditorNotices, PostPublishPanel, EditorKeyboardShortcutsRegister, - TableOfContents, } from '@wordpress/editor'; import { useSelect, useDispatch } from '@wordpress/data'; import { @@ -68,7 +67,6 @@ function Layout() { previousShortcut, nextShortcut, hasBlockSelected, - isTextModeEnabled, } = useSelect( ( select ) => { return { hasFixedToolbar: select( 'core/edit-post' ).isFeatureActive( @@ -96,8 +94,6 @@ function Layout() { nextShortcut: select( 'core/keyboard-shortcuts' ).getAllShortcutRawKeyCombinations( 'core/edit-post/next-region' ), - isTextModeEnabled: - select( 'core/edit-post' ).getEditorMode() === 'text', }; }, [] ); const sidebarIsOpened = @@ -173,12 +169,6 @@ function Layout() { mode === 'visual' && (
    - -
    ) } diff --git a/packages/icons/src/library/info.js b/packages/icons/src/library/info.js index 7dc1ab2d2de89b..7499b180738b3b 100644 --- a/packages/icons/src/library/info.js +++ b/packages/icons/src/library/info.js @@ -4,8 +4,8 @@ import { SVG, Path } from '@wordpress/primitives'; const info = ( - - + + ); diff --git a/readme.txt b/readme.txt index f740b842fa4e21..9b8309f709240d 100644 --- a/readme.txt +++ b/readme.txt @@ -52,4 +52,4 @@ The four phases of the project are Editing, Customization, Collaboration, and Mu == Changelog == -To read the changelog for Gutenberg 7.6.0, please navigate to the release page. +To read the changelog for Gutenberg 7.7.0-rc.1, please navigate to the release page. diff --git a/storybook/test/__snapshots__/index.js.snap b/storybook/test/__snapshots__/index.js.snap index e680602147a219..a5605ba6c4db59 100644 --- a/storybook/test/__snapshots__/index.js.snap +++ b/storybook/test/__snapshots__/index.js.snap @@ -3275,6 +3275,7 @@ exports[`Storyshots Components/FontSizePicker With Slider 1`] = ` min-width: 32px; opacity: 0; padding: 8px; + pointer-events: none; position: absolute; text-align: center; -webkit-transition: opacity 120ms ease; @@ -3452,8 +3453,8 @@ input[type='number'].emotion-18 { onBlur={[Function]} onChange={[Function]} onFocus={[Function]} - onMouseEnter={[Function]} onMouseLeave={[Function]} + onMouseMove={[Function]} step={1} tabIndex={0} type="range" @@ -3490,8 +3491,6 @@ input[type='number'].emotion-18 {
    @@ -5349,12 +5279,12 @@ input[type='number'].emotion-12 { onBlur={[Function]} onChange={[Function]} onFocus={[Function]} - onMouseEnter={[Function]} onMouseLeave={[Function]} + onMouseMove={[Function]} step={1} tabIndex={0} type="range" - value={0} + value="" /> @@ -5375,7 +5305,7 @@ input[type='number'].emotion-12 { className="emotion-8 emotion-9" style={ Object { - "left": "0%", + "left": "50%", } } > @@ -5396,7 +5326,7 @@ input[type='number'].emotion-12 { onChange={[Function]} step={1} type="number" - value={0} + value="" />
    @@ -5539,6 +5469,7 @@ exports[`Storyshots Components/RangeControl Initial Value Zero 1`] = ` min-width: 32px; opacity: 0; padding: 8px; + pointer-events: none; position: absolute; text-align: center; -webkit-transition: opacity 120ms ease; @@ -5627,8 +5558,8 @@ input[type='number'].emotion-14 { onBlur={[Function]} onChange={[Function]} onFocus={[Function]} - onMouseEnter={[Function]} onMouseLeave={[Function]} + onMouseMove={[Function]} step={1} tabIndex={0} type="range" @@ -5665,8 +5596,6 @@ input[type='number'].emotion-14 { @@ -5830,6 +5758,7 @@ exports[`Storyshots Components/RangeControl Multiple 1`] = ` min-width: 32px; opacity: 0; padding: 8px; + pointer-events: none; position: absolute; text-align: center; -webkit-transition: opacity 120ms ease; @@ -5918,8 +5847,8 @@ input[type='number'].emotion-14 { onBlur={[Function]} onChange={[Function]} onFocus={[Function]} - onMouseEnter={[Function]} onMouseLeave={[Function]} + onMouseMove={[Function]} step={1} tabIndex={0} type="range" @@ -5956,8 +5885,6 @@ input[type='number'].emotion-14 {