diff --git a/.eslintrc.js b/.eslintrc.js index 01f6967e8fe947..0fc37713dce4d1 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -296,6 +296,7 @@ module.exports = { 'RangeControl', 'SearchControl', 'TextareaControl', + 'ToggleGroupControl', 'TreeSelect', ].map( ( componentName ) => ( { selector: `JSXOpeningElement[name.name="${ componentName }"]:not(:has(JSXAttribute[name.name="__nextHasNoMarginBottom"]))`, diff --git a/.github/workflows/check-backport-changelog.yml b/.github/workflows/check-backport-changelog.yml index 606ca4c91683ce..366bad9fdbc247 100644 --- a/.github/workflows/check-backport-changelog.yml +++ b/.github/workflows/check-backport-changelog.yml @@ -1,4 +1,4 @@ -name: Verify Core Backport Changlog +name: Verify Core Backport Changelog on: pull_request: diff --git a/.stylelintrc.json b/.stylelintrc.json index df01978222e632..663befa2e4ce06 100644 --- a/.stylelintrc.json +++ b/.stylelintrc.json @@ -4,6 +4,14 @@ "at-rule-empty-line-before": null, "at-rule-no-unknown": null, "comment-empty-line-before": null, + "declaration-property-value-allowed-list": [ + { + "flex-direction": "/^(?!(row|column)-reverse).*$/" + }, + { + "message": "Avoid the flex-direction reverse values. For accessibility reasons, visual, reading, and DOM order must match. Only use the reverse values when they do not affect reading order, meaning, and interaction." + } + ], "declaration-property-value-disallowed-list": [ { "/.*/": [ "/--wp-components-color-/" ] @@ -18,7 +26,7 @@ "property-disallowed-list": [ [ "order" ], { - "message": "Avoid the order property. For accessibility reasons, visual, reading, and DOM order must match. Only use the order property when it does not affect reading order, meaning, and interaction" + "message": "Avoid the order property. For accessibility reasons, visual, reading, and DOM order must match. Only use the order property when it does not affect reading order, meaning, and interaction." } ], "rule-empty-line-before": null, diff --git a/docs/contributors/code/getting-started-with-code-contribution.md b/docs/contributors/code/getting-started-with-code-contribution.md index 921c8ad6ddc3e7..df6b305f35983e 100644 --- a/docs/contributors/code/getting-started-with-code-contribution.md +++ b/docs/contributors/code/getting-started-with-code-contribution.md @@ -16,7 +16,7 @@ We recommend using the [Node Version Manager](https://github.com/nvm-sh/nvm) (nv We recommend using the [wp-env package](/packages/env/README.md) for setting WordPress environment locally. You'll need to install Docker to use `wp-env`. See the [Development Environment tutorial for additional details](/docs/getting-started/devenv/README.md). > Note: To install Docker on Windows 10 Home Edition, follow the [install instructions from Docker for Windows with WSL2](https://docs.docker.com/docker-for-windows/wsl/). -As an alternative to Docker setup, you can use [Local](https://localwp.com/), [WampServer](http://www.wampserver.com/en/), or [MAMP](https://www.mamp.info/), or even use a remote server. +As an alternative to Docker setup, you can use [Local](https://localwp.com/), [WampServer](https://wampserver.aviatechno.net/), or [MAMP](https://www.mamp.info/), or even use a remote server. - GitHub CLI Although not a requirement, the [GitHub CLI](https://cli.github.com/) can be very useful in helping you checkout pull requests locally. Both from the Gutenberg repo and forked repos. This can be a major time saver while code reviewing and testing pull requests. @@ -134,7 +134,7 @@ If you run into an issue, check the [troubleshooting section in `wp-env` documen ### Using Local or MAMP -As an alternative to Docker and `wp-env`, you can also use [Local](https://localwp.com/), [WampServer](http://www.wampserver.com/en/), or [MAMP](https://www.mamp.info/) to run a local WordPress environment. To do so clone and install Gutenberg as a regular plugin in your installation by creating a symlink or copying the directory to the proper `wp-content/plugins` directory. +As an alternative to Docker and `wp-env`, you can also use [Local](https://localwp.com/), [WampServer](https://wampserver.aviatechno.net/), or [MAMP](https://www.mamp.info/) to run a local WordPress environment. To do so clone and install Gutenberg as a regular plugin in your installation by creating a symlink or copying the directory to the proper `wp-content/plugins` directory. You will also need some extra configuration to be able to run the e2e tests. diff --git a/docs/reference-guides/core-blocks.md b/docs/reference-guides/core-blocks.md index 3309a676dfc84a..e9818724b37271 100644 --- a/docs/reference-guides/core-blocks.md +++ b/docs/reference-guides/core-blocks.md @@ -360,7 +360,7 @@ Introduce new sections and organize content to help visitors (and search engines - **Name:** core/heading - **Category:** text - **Supports:** __unstablePasteTextInline, align (full, wide), anchor, className, color (background, gradients, link, text), interactivity (clientNavigation), spacing (margin, padding), splitting, typography (fontSize, lineHeight) -- **Attributes:** content, level, placeholder, textAlign +- **Attributes:** content, level, levelOptions, placeholder, textAlign ## Home Link diff --git a/docs/reference-guides/interactivity-api/README.md b/docs/reference-guides/interactivity-api/README.md index 9648b0118a5aa1..f5d410a8439f45 100644 --- a/docs/reference-guides/interactivity-api/README.md +++ b/docs/reference-guides/interactivity-api/README.md @@ -119,7 +119,7 @@ Here you have some more resources to learn/read more about the Interactivity API - [Interactivity API Discussions](https://github.com/WordPress/gutenberg/discussions/52882), especially the [showcase](https://github.com/WordPress/gutenberg/discussions/55642#discussioncomment-9667164) discussions. - [wpmovies.dev](http://wpmovies.dev/) demo and its [wp-movies-demo](https://github.com/WordPress/wp-movies-demo) repo - Examples using the Interactivity API at [block-development-examples](https://github.com/WordPress/block-development-examples): - - [`interactivity-api-block-833d15`](https://github.com/WordPress/block-development-examples/tree/trunk/plugins/833d15) + - [`interactivity-api-block-833d15`](https://github.com/WordPress/block-development-examples/tree/trunk/plugins/interactivity-api-block-833d15) - [`interactivity-api-countdown-3cd73e`](https://github.com/WordPress/block-development-examples/tree/trunk/plugins/interactivity-api-countdown-3cd73e) - [`interactivity-api-quiz-1835fa`](https://github.com/WordPress/block-development-examples/tree/trunk/plugins/interactivity-api-quiz-1835fa) diff --git a/docs/reference-guides/interactivity-api/iapi-faq.md b/docs/reference-guides/interactivity-api/iapi-faq.md index 5e5036779baaeb..dea7bc1d4367be 100644 --- a/docs/reference-guides/interactivity-api/iapi-faq.md +++ b/docs/reference-guides/interactivity-api/iapi-faq.md @@ -66,7 +66,7 @@ To summarize, using the Interactivity API rather than just using React comes wit - If you use React, your interactive blocks must generate the same markup on the client as they do on the server in PHP. Using the Interactivity API, there is no such requirement as directives are added to server-rendered HTML. - The Interactivity API is PHP-friendlier. It works out of the box with WordPress hooks or other server functionalities such as internationalization. For example, with React, you can’t know which hooks are applied on the server, and their modifications would be overwritten after hydration. -- All the benefits of [using a standard](https://developer.wordpress.org/block-editor/reference-guides/interactivity-api/what-is-interactivity-api#why-a-standard). +- All the benefits of [using a standard](/docs/reference-guides/interactivity-api/iapi-about.md#why-a-standard). ## What are the benefits of Interactivity API over just using jQuery or vanilla JavaScript? diff --git a/packages/base-styles/_variables.scss b/packages/base-styles/_variables.scss index b10eeeb167dadf..f5a9ec38824ff3 100644 --- a/packages/base-styles/_variables.scss +++ b/packages/base-styles/_variables.scss @@ -22,7 +22,6 @@ $text-editor-font-size: 15px; $editor-line-height: 1.8; $mobile-text-min-font-size: 16px; // Any font size below 16px will cause Mobile Safari to "zoom in". - /** * Grid System. * https://make.wordpress.org/design/2019/10/31/proposal-a-consistent-spacing-system-for-wordpress/ diff --git a/packages/block-editor/src/components/block-breadcrumb/index.js b/packages/block-editor/src/components/block-breadcrumb/index.js index b3f2d3dee12013..8bd790c5c8fb21 100644 --- a/packages/block-editor/src/components/block-breadcrumb/index.js +++ b/packages/block-editor/src/components/block-breadcrumb/index.js @@ -5,6 +5,7 @@ import { Button } from '@wordpress/components'; import { useSelect, useDispatch } from '@wordpress/data'; import { __ } from '@wordpress/i18n'; import { chevronRightSmall, Icon } from '@wordpress/icons'; +import { useRef } from '@wordpress/element'; /** * Internal dependencies @@ -12,7 +13,7 @@ import { chevronRightSmall, Icon } from '@wordpress/icons'; import BlockTitle from '../block-title'; import { store as blockEditorStore } from '../../store'; import { unlock } from '../../lock-unlock'; -import { __unstableUseBlockRef as useBlockRef } from '../block-list/use-block-props/use-block-refs'; +import { useBlockElementRef } from '../block-list/use-block-props/use-block-refs'; import getEditorRegion from '../../utils/get-editor-region'; /** @@ -41,7 +42,8 @@ function BlockBreadcrumb( { rootLabelText } ) { // We don't care about this specific ref, but this is a way // to get a ref within the editor canvas so we can focus it later. - const blockRef = useBlockRef( clientId ); + const blockRef = useRef(); + useBlockElementRef( clientId, blockRef ); /* * Disable reason: The `list` ARIA role is redundant but diff --git a/packages/block-editor/src/components/block-draggable/index.js b/packages/block-editor/src/components/block-draggable/index.js index 0ba2b857bc693e..e1afc1f2513841 100644 --- a/packages/block-editor/src/components/block-draggable/index.js +++ b/packages/block-editor/src/components/block-draggable/index.js @@ -13,7 +13,7 @@ import { throttle } from '@wordpress/compose'; import BlockDraggableChip from './draggable-chip'; import useScrollWhenDragging from './use-scroll-when-dragging'; import { store as blockEditorStore } from '../../store'; -import { __unstableUseBlockRef as useBlockRef } from '../block-list/use-block-props/use-block-refs'; +import { useBlockElement } from '../block-list/use-block-props/use-block-refs'; import { isDropTargetValid } from '../use-block-drop-zone'; const BlockDraggable = ( { @@ -82,8 +82,8 @@ const BlockDraggable = ( { }, [] ); // Find the root of the editor iframe. - const blockRef = useBlockRef( clientIds[ 0 ] ); - const editorRoot = blockRef.current?.closest( 'body' ); + const blockEl = useBlockElement( clientIds[ 0 ] ); + const editorRoot = blockEl?.closest( 'body' ); /* * Add a dragover event listener to the editor root to track the blocks being dragged over. diff --git a/packages/block-editor/src/components/block-list/use-block-props/use-block-refs.js b/packages/block-editor/src/components/block-list/use-block-props/use-block-refs.js index 056ade045d1654..16fd3ff1ca81dd 100644 --- a/packages/block-editor/src/components/block-list/use-block-props/use-block-refs.js +++ b/packages/block-editor/src/components/block-list/use-block-props/use-block-refs.js @@ -1,13 +1,7 @@ /** * WordPress dependencies */ -import { - useContext, - useMemo, - useRef, - useState, - useLayoutEffect, -} from '@wordpress/element'; +import { useContext, useState, useLayoutEffect } from '@wordpress/element'; import { useRefEffect } from '@wordpress/compose'; /** @@ -16,7 +10,7 @@ import { useRefEffect } from '@wordpress/compose'; import { BlockRefs } from '../../provider/block-refs-provider'; /** @typedef {import('@wordpress/element').RefCallback} RefCallback */ -/** @typedef {import('@wordpress/element').RefObject} RefObject */ +/** @typedef {import('@wordpress/element').Ref} Ref */ /** * Provides a ref to the BlockRefs context. @@ -36,31 +30,33 @@ export function useBlockRefProvider( clientId ) { ); } +function assignRef( ref, value ) { + if ( typeof ref === 'function' ) { + ref( value ); + } else if ( ref ) { + ref.current = value; + } +} + /** - * Gets a ref pointing to the current block element. Continues to return the same - * stable ref object even if the `clientId` argument changes. This hook is not - * reactive, i.e., it won't trigger a rerender of the calling component if the - * ref value changes. For reactive use cases there is the `useBlockElement` hook. - * - * @param {string} clientId The client ID to get a ref for. + * Tracks the DOM element for the block identified by `clientId` and assigns it to the `ref` + * whenever it changes. * - * @return {RefObject} A ref containing the element. + * @param {string} clientId The client ID to track. + * @param {Ref} ref The ref object/callback to assign to. */ -function useBlockRef( clientId ) { +export function useBlockElementRef( clientId, ref ) { const { refsMap } = useContext( BlockRefs ); - const latestClientId = useRef(); - latestClientId.current = clientId; - - // Always return an object, even if no ref exists for a given client ID, so - // that `current` works at a later point. - return useMemo( - () => ( { - get current() { - return refsMap.get( latestClientId.current ) ?? null; - }, - } ), - [ refsMap ] - ); + useLayoutEffect( () => { + assignRef( ref, refsMap.get( clientId ) ); + const unsubscribe = refsMap.subscribe( clientId, () => + assignRef( ref, refsMap.get( clientId ) ) + ); + return () => { + unsubscribe(); + assignRef( ref, null ); + }; + }, [ refsMap, clientId, ref ] ); } /** @@ -71,20 +67,8 @@ function useBlockRef( clientId ) { * * @return {Element|null} The block's wrapper element. */ -function useBlockElement( clientId ) { - const { refsMap } = useContext( BlockRefs ); +export function useBlockElement( clientId ) { const [ blockElement, setBlockElement ] = useState( null ); - // Delay setting the resulting `blockElement` until an effect. If the block element - // changes (i.e., the block is unmounted and re-mounted), this allows enough time - // for the ref callbacks to clean up the old element and set the new one. - useLayoutEffect( () => { - setBlockElement( refsMap.get( clientId ) ); - return refsMap.subscribe( clientId, () => - setBlockElement( refsMap.get( clientId ) ) - ); - }, [ refsMap, clientId ] ); + useBlockElementRef( clientId, setBlockElement ); return blockElement; } - -export { useBlockRef as __unstableUseBlockRef }; -export { useBlockElement as __unstableUseBlockElement }; diff --git a/packages/block-editor/src/components/block-mover/index.js b/packages/block-editor/src/components/block-mover/index.js index aaaf6c64b55953..3b7f25800095a5 100644 --- a/packages/block-editor/src/components/block-mover/index.js +++ b/packages/block-editor/src/components/block-mover/index.js @@ -69,7 +69,11 @@ function BlockMover( { [ clientIds ] ); - if ( ! canMove || ( isFirst && isLast && ! rootClientId ) ) { + if ( + ! canMove || + ( isFirst && isLast && ! rootClientId ) || + ( hideDragHandle && isManualGrid ) + ) { return null; } diff --git a/packages/block-editor/src/components/block-popover/cover.js b/packages/block-editor/src/components/block-popover/cover.js index caad2ddbb7ec56..401431defe4fd5 100644 --- a/packages/block-editor/src/components/block-popover/cover.js +++ b/packages/block-editor/src/components/block-popover/cover.js @@ -6,7 +6,7 @@ import { useEffect, useState, useMemo, forwardRef } from '@wordpress/element'; /** * Internal dependencies */ -import { __unstableUseBlockElement as useBlockElement } from '../block-list/use-block-props/use-block-refs'; +import { useBlockElement } from '../block-list/use-block-props/use-block-refs'; import { PrivateBlockPopover } from '.'; function BlockPopoverCover( diff --git a/packages/block-editor/src/components/block-popover/inbetween.js b/packages/block-editor/src/components/block-popover/inbetween.js index bc2eaeae0be603..2ed9ee0bcb284f 100644 --- a/packages/block-editor/src/components/block-popover/inbetween.js +++ b/packages/block-editor/src/components/block-popover/inbetween.js @@ -20,7 +20,7 @@ import { isRTL } from '@wordpress/i18n'; * Internal dependencies */ import { store as blockEditorStore } from '../../store'; -import { __unstableUseBlockElement as useBlockElement } from '../block-list/use-block-props/use-block-refs'; +import { useBlockElement } from '../block-list/use-block-props/use-block-refs'; import usePopoverScroll from './use-popover-scroll'; const MAX_POPOVER_RECOMPUTE_COUNTER = Number.MAX_SAFE_INTEGER; diff --git a/packages/block-editor/src/components/block-popover/index.js b/packages/block-editor/src/components/block-popover/index.js index cc8d832c31bc70..2413601a590e2e 100644 --- a/packages/block-editor/src/components/block-popover/index.js +++ b/packages/block-editor/src/components/block-popover/index.js @@ -18,7 +18,7 @@ import { /** * Internal dependencies */ -import { __unstableUseBlockElement as useBlockElement } from '../block-list/use-block-props/use-block-refs'; +import { useBlockElement } from '../block-list/use-block-props/use-block-refs'; import usePopoverScroll from './use-popover-scroll'; const MAX_POPOVER_RECOMPUTE_COUNTER = Number.MAX_SAFE_INTEGER; diff --git a/packages/block-editor/src/components/block-tools/block-selection-button.js b/packages/block-editor/src/components/block-tools/block-selection-button.js index 036aef4f135d3c..8d99b829a84bf4 100644 --- a/packages/block-editor/src/components/block-tools/block-selection-button.js +++ b/packages/block-editor/src/components/block-tools/block-selection-button.js @@ -37,7 +37,7 @@ import BlockTitle from '../block-title'; import BlockIcon from '../block-icon'; import { store as blockEditorStore } from '../../store'; import BlockDraggable from '../block-draggable'; -import { __unstableUseBlockElement as useBlockElement } from '../block-list/use-block-props/use-block-refs'; +import { useBlockElement } from '../block-list/use-block-props/use-block-refs'; /** * Block selection button component, displaying the label of the block. If the block diff --git a/packages/block-editor/src/components/block-tools/use-block-toolbar-popover-props.js b/packages/block-editor/src/components/block-tools/use-block-toolbar-popover-props.js index f99323dd5c80a7..0ca0f6e5a43dda 100644 --- a/packages/block-editor/src/components/block-tools/use-block-toolbar-popover-props.js +++ b/packages/block-editor/src/components/block-tools/use-block-toolbar-popover-props.js @@ -15,7 +15,7 @@ import { * Internal dependencies */ import { store as blockEditorStore } from '../../store'; -import { __unstableUseBlockElement as useBlockElement } from '../block-list/use-block-props/use-block-refs'; +import { useBlockElement } from '../block-list/use-block-props/use-block-refs'; import { hasStickyOrFixedPositionValue } from '../../hooks/position'; const COMMON_PROPS = { diff --git a/packages/block-editor/src/components/color-palette/test/__snapshots__/control.js.snap b/packages/block-editor/src/components/color-palette/test/__snapshots__/control.js.snap index 7a04f41a29b050..bd9175782a224a 100644 --- a/packages/block-editor/src/components/color-palette/test/__snapshots__/control.js.snap +++ b/packages/block-editor/src/components/color-palette/test/__snapshots__/control.js.snap @@ -45,7 +45,7 @@ exports[`ColorPaletteControl matches the snapshot 1`] = ` font-weight: 500; line-height: 1.4; text-transform: uppercase; - display: inline-block; + display: block; margin-bottom: calc(4px * 2); padding: 0; } diff --git a/packages/block-editor/src/components/dimensions-tool/scale-tool.js b/packages/block-editor/src/components/dimensions-tool/scale-tool.js index 05a7d2f4d251a7..a23fad586d4705 100644 --- a/packages/block-editor/src/components/dimensions-tool/scale-tool.js +++ b/packages/block-editor/src/components/dimensions-tool/scale-tool.js @@ -105,6 +105,7 @@ export default function ScaleTool( { panelId={ panelId } > - { - onChange( { - columnStart: columnStart - 1, - } ); - __unstableMarkNextChangeAsNotPersistent(); - moveBlocksToPosition( - [ blockClientId ], - gridClientId, - gridClientId, - getNumberOfBlocksBeforeCell( - columnStart - 1, - rowStart - ) - ); - } } - /> +
+ { + onChange( { + columnStart: columnStart - 1, + } ); + __unstableMarkNextChangeAsNotPersistent(); + moveBlocksToPosition( + [ blockClientId ], + gridClientId, + gridClientId, + getNumberOfBlocksBeforeCell( + columnStart - 1, + rowStart + ) + ); + } } + /> +
- = columnCount } - onClick={ () => { - onChange( { - columnStart: columnStart + 1, - } ); - __unstableMarkNextChangeAsNotPersistent(); - moveBlocksToPosition( - [ blockClientId ], - gridClientId, - gridClientId, - getNumberOfBlocksBeforeCell( - columnStart + 1, - rowStart - ) - ); - } } - /> +
+ = columnCount } + onClick={ () => { + onChange( { + columnStart: columnStart + 1, + } ); + __unstableMarkNextChangeAsNotPersistent(); + moveBlocksToPosition( + [ blockClientId ], + gridClientId, + gridClientId, + getNumberOfBlocksBeforeCell( + columnStart + 1, + rowStart + ) + ); + } } + /> +
); diff --git a/packages/block-editor/src/components/grid/grid-item-resizer.js b/packages/block-editor/src/components/grid/grid-item-resizer.js index 34bc1db6048067..28d9678772f76c 100644 --- a/packages/block-editor/src/components/grid/grid-item-resizer.js +++ b/packages/block-editor/src/components/grid/grid-item-resizer.js @@ -7,7 +7,7 @@ import { useState, useEffect } from '@wordpress/element'; /** * Internal dependencies */ -import { __unstableUseBlockElement as useBlockElement } from '../block-list/use-block-props/use-block-refs'; +import { useBlockElement } from '../block-list/use-block-props/use-block-refs'; import BlockPopoverCover from '../block-popover/cover'; import { getComputedCSS, getGridTracks, getClosestTrack } from './utils'; diff --git a/packages/block-editor/src/components/grid/grid-visualizer.js b/packages/block-editor/src/components/grid/grid-visualizer.js index 5e5e1e3bfa2f77..e1d35f012b4d81 100644 --- a/packages/block-editor/src/components/grid/grid-visualizer.js +++ b/packages/block-editor/src/components/grid/grid-visualizer.js @@ -13,7 +13,7 @@ import { __experimentalUseDropZone as useDropZone } from '@wordpress/compose'; /** * Internal dependencies */ -import { __unstableUseBlockElement as useBlockElement } from '../block-list/use-block-props/use-block-refs'; +import { useBlockElement } from '../block-list/use-block-props/use-block-refs'; import BlockPopoverCover from '../block-popover/cover'; import { range, GridRect, getGridInfo } from './utils'; import { store as blockEditorStore } from '../../store'; diff --git a/packages/block-editor/src/components/grid/style.scss b/packages/block-editor/src/components/grid/style.scss index 32f0cfc0c62dc2..6790d683ca7d03 100644 --- a/packages/block-editor/src/components/grid/style.scss +++ b/packages/block-editor/src/components/grid/style.scss @@ -105,7 +105,6 @@ .block-editor-grid-item-mover-button { width: $block-toolbar-height * 0.5; min-width: 0 !important; // overrides default button width. - overflow: hidden; padding-left: 0; padding-right: 0; @@ -155,7 +154,7 @@ justify-content: space-around; > .block-editor-grid-item-mover-button.block-editor-grid-item-mover-button { - height: $block-toolbar-height * 0.5 - $grid-unit-05; + height: $block-toolbar-height * 0.5 - $grid-unit-05 !important; // overrides toolbar button height. width: 100%; min-width: 0 !important; // overrides default button width. @@ -173,18 +172,53 @@ } } +.editor-collapsible-block-toolbar { + .block-editor-grid-item-mover__move-vertical-button-container { + // Move up a little to prevent the toolbar shift when focus is on the vertical movers. + @include break-small() { + height: $grid-unit-50; + position: relative; + top: -5px; // Should be -4px, but that causes scrolling when focus lands on the movers, in a 60px header. + } + } +} + .show-icon-labels { - .block-editor-grid-item-mover-button.block-editor-grid-item-mover-button.is-left-button { - border-right: 1px solid $gray-700; - padding-right: 12px; - } + .block-editor-grid-item-mover__move-horizontal-button-container { + position: relative; - .block-editor-grid-item-mover-button.block-editor-grid-item-mover-button.is-right-button { - border-left: 1px solid $gray-700; - padding-left: 12px; - } + &::before { + @include break-small() { + content: ""; + height: 100%; + width: $border-width; + background: $gray-200; + position: absolute; + top: 0; + } + + @include break-medium() { + background: $gray-900; + } + } + + &.is-left { + padding-right: 6px; + &::before { + right: 0; + } + } + + &.is-right { + padding-left: 6px; + + &::before { + left: 0; + } + } + } .block-editor-grid-item-mover__move-vertical-button-container { &::before { @@ -208,5 +242,21 @@ } } + .block-editor-grid-item-mover-button { + white-space: nowrap; + } + + .editor-collapsible-block-toolbar { + .block-editor-grid-item-mover__move-horizontal-button-container::before { + height: $grid-unit-30; + background: $gray-300; + top: $grid-unit-05; + } + + .block-editor-grid-item-mover__move-vertical-button-container::before { + background: $gray-300; + width: calc(100% - #{$grid-unit-30}); + } + } } diff --git a/packages/block-editor/src/components/skip-to-selected-block/index.js b/packages/block-editor/src/components/skip-to-selected-block/index.js index 51062e32934f0b..2f78f706112c38 100644 --- a/packages/block-editor/src/components/skip-to-selected-block/index.js +++ b/packages/block-editor/src/components/skip-to-selected-block/index.js @@ -4,12 +4,13 @@ import { useSelect } from '@wordpress/data'; import { __ } from '@wordpress/i18n'; import { Button } from '@wordpress/components'; +import { useRef } from '@wordpress/element'; /** * Internal dependencies */ import { store as blockEditorStore } from '../../store'; -import { __unstableUseBlockRef as useBlockRef } from '../block-list/use-block-props/use-block-refs'; +import { useBlockElementRef } from '../block-list/use-block-props/use-block-refs'; /** * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/skip-to-selected-block/README.md @@ -19,9 +20,10 @@ export default function SkipToSelectedBlock() { ( select ) => select( blockEditorStore ).getBlockSelectionStart(), [] ); - const ref = useBlockRef( selectedBlockClientId ); + const ref = useRef(); + useBlockElementRef( selectedBlockClientId, ref ); const onClick = () => { - ref.current.focus(); + ref.current?.focus(); }; return selectedBlockClientId ? ( diff --git a/packages/block-editor/src/hooks/block-hooks.scss b/packages/block-editor/src/hooks/block-hooks.scss index 4d871233de482b..c8f2027483ccf3 100644 --- a/packages/block-editor/src/hooks/block-hooks.scss +++ b/packages/block-editor/src/hooks/block-hooks.scss @@ -4,6 +4,7 @@ * we need to right-align the toggle. */ .components-toggle-control .components-h-stack { + /* stylelint-disable-next-line declaration-property-value-allowed-list -- This should be refactored to not use the row-reverse value. */ flex-direction: row-reverse; } diff --git a/packages/block-editor/src/hooks/contrast-checker.js b/packages/block-editor/src/hooks/contrast-checker.js index ef04da63e4946b..6e503ae8f3319d 100644 --- a/packages/block-editor/src/hooks/contrast-checker.js +++ b/packages/block-editor/src/hooks/contrast-checker.js @@ -7,7 +7,7 @@ import { useState, useEffect } from '@wordpress/element'; * Internal dependencies */ import ContrastChecker from '../components/contrast-checker'; -import { __unstableUseBlockRef as useBlockRef } from '../components/block-list/use-block-props/use-block-refs'; +import { useBlockElement } from '../components/block-list/use-block-props/use-block-refs'; function getComputedStyle( node ) { return node.ownerDocument.defaultView.getComputedStyle( node ); @@ -17,23 +17,23 @@ export default function BlockColorContrastChecker( { clientId } ) { const [ detectedBackgroundColor, setDetectedBackgroundColor ] = useState(); const [ detectedColor, setDetectedColor ] = useState(); const [ detectedLinkColor, setDetectedLinkColor ] = useState(); - const ref = useBlockRef( clientId ); + const blockEl = useBlockElement( clientId ); // There are so many things that can change the color of a block // So we perform this check on every render. // eslint-disable-next-line react-hooks/exhaustive-deps useEffect( () => { - if ( ! ref.current ) { + if ( ! blockEl ) { return; } - setDetectedColor( getComputedStyle( ref.current ).color ); + setDetectedColor( getComputedStyle( blockEl ).color ); - const firstLinkElement = ref.current?.querySelector( 'a' ); + const firstLinkElement = blockEl.querySelector( 'a' ); if ( firstLinkElement && !! firstLinkElement.innerText ) { setDetectedLinkColor( getComputedStyle( firstLinkElement ).color ); } - let backgroundColorNode = ref.current; + let backgroundColorNode = blockEl; let backgroundColor = getComputedStyle( backgroundColorNode ).backgroundColor; while ( @@ -48,7 +48,7 @@ export default function BlockColorContrastChecker( { clientId } ) { } setDetectedBackgroundColor( backgroundColor ); - } ); + }, [ blockEl ] ); return ( ) } - + { Platform.isNative ? ( + + ) : null } + { Platform.isWeb ? ( + + + { ( { onClose } ) => ( + + { linkOptions.map( ( linkItem ) => { + const isOptionSelected = + linkTo === linkItem.value; + return ( + { + setLinkTo( linkItem.value ); + onClose(); + } } + role="menuitemradio" + > + { linkItem.label } + + ); + } ) } + + ) } + + + ) : null } { Platform.isWeb && ( <> { ! multiGallerySelection && ( diff --git a/packages/block-library/src/gallery/editor.scss b/packages/block-library/src/gallery/editor.scss index 9efaf88e5acc71..025e86277f7edc 100644 --- a/packages/block-library/src/gallery/editor.scss +++ b/packages/block-library/src/gallery/editor.scss @@ -70,7 +70,6 @@ .gallery-image-sizes { .components-base-control__label { - display: block; margin-bottom: 4px; } diff --git a/packages/block-library/src/gallery/test/__snapshots__/index.native.js.snap b/packages/block-library/src/gallery/test/__snapshots__/index.native.js.snap index b79bd7c3877c7e..088a7d25282451 100644 --- a/packages/block-library/src/gallery/test/__snapshots__/index.native.js.snap +++ b/packages/block-library/src/gallery/test/__snapshots__/index.native.js.snap @@ -82,7 +82,7 @@ exports[`Gallery block inserts block 1`] = ` " `; -exports[`Gallery block overrides "Link to" setting of gallery items 1`] = ` +exports[`Gallery block overrides "Link" setting of gallery items 1`] = ` "