From 777ebc15d3ae63c3a06c50b57535dffb150c91aa Mon Sep 17 00:00:00 2001 From: Marco Ciampini Date: Thu, 18 Jul 2024 10:31:33 +0200 Subject: [PATCH 01/17] FontSizePicker: tidy up internal logic (#63553) * Add unit tests * Refactor code and extract logic * Sync JS docs * CHANGELOG * Further simplify logic * Inline `getPickerType` utility * Inline `getHeaderHint` and `shouldUseSelectOverToggle` utilities, refactor to switch statement. * toBeInTheDocument() => toBeVisible() * Move units back at the start of the render function for a smaller diff --- Co-authored-by: ciampo Co-authored-by: mirka <0mirka00@git.wordpress.org> Co-authored-by: tyxla --- packages/components/CHANGELOG.md | 1 + .../components/src/font-size-picker/index.tsx | 132 +++++++++--------- .../src/font-size-picker/test/index.tsx | 98 +++++++++++-- .../components/src/font-size-picker/types.ts | 7 +- 4 files changed, 156 insertions(+), 82 deletions(-) diff --git a/packages/components/CHANGELOG.md b/packages/components/CHANGELOG.md index 392d11fdd6673..326d2876e65c6 100644 --- a/packages/components/CHANGELOG.md +++ b/packages/components/CHANGELOG.md @@ -17,6 +17,7 @@ - `ToggleGroupControl`: support disabled options ([#63450](https://github.com/WordPress/gutenberg/pull/63450)). - `CustomSelectControl`: Stabilize `__experimentalShowSelectedHint` and `options[]. __experimentalHint` props ([#63248](https://github.com/WordPress/gutenberg/pull/63248)). - `SelectControl`: Add `"minimal"` variant ([#63265](https://github.com/WordPress/gutenberg/pull/63265)). +- `FontSizePicker`: tidy up internal logic ([#63553](https://github.com/WordPress/gutenberg/pull/63553)). ### Internal diff --git a/packages/components/src/font-size-picker/index.tsx b/packages/components/src/font-size-picker/index.tsx index e4de2f6f6f5cf..f93a09440a068 100644 --- a/packages/components/src/font-size-picker/index.tsx +++ b/packages/components/src/font-size-picker/index.tsx @@ -38,6 +38,8 @@ import { T_SHIRT_NAMES } from './constants'; const DEFAULT_UNITS = [ 'px', 'em', 'rem', 'vw', 'vh' ]; +const MAX_TOGGLE_GROUP_SIZES = 5; + const UnforwardedFontSizePicker = ( props: FontSizePickerProps, ref: ForwardedRef< any > @@ -59,43 +61,49 @@ const UnforwardedFontSizePicker = ( availableUnits: unitsProp, } ); - const shouldUseSelectControl = fontSizes.length > 5; const selectedFontSize = fontSizes.find( ( fontSize ) => fontSize.size === value ); const isCustomValue = !! value && ! selectedFontSize; - const [ showCustomValueControl, setShowCustomValueControl ] = useState( - ! disableCustomFontSizes && isCustomValue - ); - - const headerHint = useMemo( () => { - if ( showCustomValueControl ) { - return __( 'Custom' ); - } + // Initially request a custom picker if the value is not from the predef list. + const [ userRequestedCustom, setUserRequestedCustom ] = + useState( isCustomValue ); - if ( ! shouldUseSelectControl ) { - if ( selectedFontSize ) { - return ( - selectedFontSize.name || - T_SHIRT_NAMES[ fontSizes.indexOf( selectedFontSize ) ] - ); - } - return ''; - } + let currentPickerType; + if ( ! disableCustomFontSizes && userRequestedCustom ) { + // While showing the custom value picker, switch back to predef only if + // `disableCustomFontSizes` is set to `true`. + currentPickerType = 'custom' as const; + } else { + currentPickerType = + fontSizes.length > MAX_TOGGLE_GROUP_SIZES + ? ( 'select' as const ) + : ( 'togglegroup' as const ); + } - const commonUnit = getCommonSizeUnit( fontSizes ); - if ( commonUnit ) { - return `(${ commonUnit })`; + const headerHint = useMemo( () => { + switch ( currentPickerType ) { + case 'custom': + return __( 'Custom' ); + case 'togglegroup': + if ( selectedFontSize ) { + return ( + selectedFontSize.name || + T_SHIRT_NAMES[ fontSizes.indexOf( selectedFontSize ) ] + ); + } + break; + case 'select': + const commonUnit = getCommonSizeUnit( fontSizes ); + if ( commonUnit ) { + return `(${ commonUnit })`; + } + break; } return ''; - }, [ - showCustomValueControl, - shouldUseSelectControl, - selectedFontSize, - fontSizes, - ] ); + }, [ currentPickerType, selectedFontSize, fontSizes ] ); if ( fontSizes.length === 0 && disableCustomFontSizes ) { return null; @@ -133,53 +141,45 @@ const UnforwardedFontSizePicker = ( { ! disableCustomFontSizes && ( { - setShowCustomValueControl( - ! showCustomValueControl - ); - } } - isPressed={ showCustomValueControl } + onClick={ () => + setUserRequestedCustom( ! userRequestedCustom ) + } + isPressed={ currentPickerType === 'custom' } size="small" /> ) }
- { !! fontSizes.length && - shouldUseSelectControl && - ! showCustomValueControl && ( - { - if ( newValue === undefined ) { - onChange?.( undefined ); - } else { - onChange?.( - hasUnits - ? newValue - : Number( newValue ), - fontSizes.find( - ( fontSize ) => - fontSize.size === newValue - ) - ); - } - } } - onSelectCustom={ () => - setShowCustomValueControl( true ) + { currentPickerType === 'select' && ( + { + if ( newValue === undefined ) { + onChange?.( undefined ); + } else { + onChange?.( + hasUnits ? newValue : Number( newValue ), + fontSizes.find( + ( fontSize ) => + fontSize.size === newValue + ) + ); } - /> - ) } - { ! shouldUseSelectControl && ! showCustomValueControl && ( + } } + onSelectCustom={ () => setUserRequestedCustom( true ) } + /> + ) } + { currentPickerType === 'togglegroup' && ( ) } - { ! disableCustomFontSizes && showCustomValueControl && ( + { currentPickerType === 'custom' && ( { + setUserRequestedCustom( true ); + if ( newValue === undefined ) { onChange?.( undefined ); } else { @@ -240,6 +242,8 @@ const UnforwardedFontSizePicker = ( initialPosition={ fallbackFontSize } withInputField={ false } onChange={ ( newValue ) => { + setUserRequestedCustom( true ); + if ( newValue === undefined ) { onChange?.( undefined ); } else if ( hasUnits ) { diff --git a/packages/components/src/font-size-picker/test/index.tsx b/packages/components/src/font-size-picker/test/index.tsx index 620d782e3abce..f91c12e352bf8 100644 --- a/packages/components/src/font-size-picker/test/index.tsx +++ b/packages/components/src/font-size-picker/test/index.tsx @@ -9,6 +9,29 @@ import userEvent from '@testing-library/user-event'; */ import FontSizePicker from '../'; import type { FontSize } from '../types'; +/** + * WordPress dependencies + */ +import { useState } from '@wordpress/element'; + +const ControlledFontSizePicker = ( { + onChange, + ...props +}: React.ComponentProps< typeof FontSizePicker > ) => { + const [ fontSize, setFontSize ] = + useState< typeof props.value >( undefined ); + + return ( + { + setFontSize( newFontSize ); + onChange?.( newFontSize ); + } } + /> + ); +}; describe( 'FontSizePicker', () => { test.each( [ @@ -118,9 +141,7 @@ describe( 'FontSizePicker', () => { render( ); - expect( - screen.getByLabelText( expectedLabel ) - ).toBeInTheDocument(); + expect( screen.getByLabelText( expectedLabel ) ).toBeVisible(); } ); @@ -243,9 +264,7 @@ describe( 'FontSizePicker', () => { render( ); - expect( - screen.getByLabelText( expectedLabel ) - ).toBeInTheDocument(); + expect( screen.getByLabelText( expectedLabel ) ).toBeVisible(); } ); @@ -360,9 +379,7 @@ describe( 'FontSizePicker', () => { render( ); - expect( - screen.getByLabelText( expectedLabel ) - ).toBeInTheDocument(); + expect( screen.getByLabelText( expectedLabel ) ).toBeVisible(); } ); @@ -434,9 +451,7 @@ describe( 'FontSizePicker', () => { render( ); - expect( - screen.getByLabelText( expectedLabel ) - ).toBeInTheDocument(); + expect( screen.getByLabelText( expectedLabel ) ).toBeVisible(); } ); @@ -493,7 +508,7 @@ describe( 'FontSizePicker', () => { render( ); - expect( screen.getByRole( 'radiogroup' ) ).toBeInTheDocument(); + expect( screen.getByRole( 'radiogroup' ) ).toBeVisible(); expect( screen.queryByRole( 'radio', { checked: true } ) ).not.toBeInTheDocument(); @@ -514,7 +529,7 @@ describe( 'FontSizePicker', () => { await user.click( screen.getByRole( 'option', { name: 'Custom' } ) ); - expect( screen.getByLabelText( 'Custom' ) ).toBeInTheDocument(); + expect( screen.getByLabelText( 'Custom' ) ).toBeVisible(); expect( onChange ).not.toHaveBeenCalled(); } ); } @@ -522,7 +537,40 @@ describe( 'FontSizePicker', () => { function commonTests( fontSizes: FontSize[] ) { it( 'shows custom input when value is unknown', () => { render( ); - expect( screen.getByLabelText( 'Custom' ) ).toBeInTheDocument(); + expect( screen.getByLabelText( 'Custom' ) ).toBeVisible(); + } ); + + it( 'hides custom input when disableCustomFontSizes is set to `true` with a custom font size', () => { + const { rerender } = render( + + ); + expect( screen.getByLabelText( 'Custom' ) ).toBeVisible(); + + rerender( + + ); + expect( + screen.queryByLabelText( 'Custom' ) + ).not.toBeInTheDocument(); + } ); + + it( "doesn't hide custom input when the selected font size is a predef", () => { + const { rerender } = render( + + ); + expect( screen.getByLabelText( 'Custom' ) ).toBeVisible(); + + rerender( + + ); + expect( screen.getByLabelText( 'Custom' ) ).toBeVisible(); } ); it( 'allows custom values by default', async () => { @@ -539,6 +587,26 @@ describe( 'FontSizePicker', () => { expect( onChange ).toHaveBeenCalledWith( '80px' ); } ); + it( 'allows switching between custom and predef inputs when pressing the dedicated toggle', async () => { + const user = userEvent.setup(); + + render( ); + + await user.click( + screen.getByRole( 'button', { name: 'Set custom size' } ) + ); + + await user.type( screen.getByLabelText( 'Custom' ), '80' ); + + await user.click( + screen.getByRole( 'button', { name: 'Use size preset' } ) + ); + + expect( + screen.queryByLabelText( 'Custom' ) + ).not.toBeInTheDocument(); + } ); + it( 'does not allow custom values when disableCustomFontSizes is set', () => { render( Date: Thu, 18 Jul 2024 14:05:21 +0530 Subject: [PATCH 02/17] Term Description: Add border block support (#63630) * Add border support to term description block * Add box sizing style to term description block Co-authored-by: akasunil Co-authored-by: aaronrobertshaw --- .../block-library/src/term-description/block.json | 12 ++++++++++++ .../block-library/src/term-description/style.scss | 2 ++ 2 files changed, 14 insertions(+) diff --git a/packages/block-library/src/term-description/block.json b/packages/block-library/src/term-description/block.json index 7a3f27c8063ab..dc27fc17df789 100644 --- a/packages/block-library/src/term-description/block.json +++ b/packages/block-library/src/term-description/block.json @@ -40,6 +40,18 @@ }, "interactivity": { "clientNavigation": true + }, + "__experimentalBorder": { + "radius": true, + "color": true, + "width": true, + "style": true, + "__experimentalDefaultControls": { + "radius": true, + "color": true, + "width": true, + "style": true + } } } } diff --git a/packages/block-library/src/term-description/style.scss b/packages/block-library/src/term-description/style.scss index bd455f7a68d3d..1649a8d80c8f1 100644 --- a/packages/block-library/src/term-description/style.scss +++ b/packages/block-library/src/term-description/style.scss @@ -1,5 +1,7 @@ // Lowest specificity on wrapper margins to avoid overriding layout styles. :where(.wp-block-term-description) { + // This block has customizable padding, border-box makes that more predictable. + box-sizing: border-box; margin-top: var(--wp--style--block-gap); margin-bottom: var(--wp--style--block-gap); } From c380af558d215f5a6b5c2400a66c0a29c35960c4 Mon Sep 17 00:00:00 2001 From: Lena Morita Date: Thu, 18 Jul 2024 18:28:07 +0900 Subject: [PATCH 03/17] ColorPicker: Use `minimal` variant for SelectControl (#63676) * ColorPicker: Use `minimal` variant for SelectControl * Add changelog Co-authored-by: mirka <0mirka00@git.wordpress.org> Co-authored-by: ciampo Co-authored-by: tyxla --- packages/components/CHANGELOG.md | 1 + .../components/src/color-picker/component.tsx | 34 +++++++------------ 2 files changed, 13 insertions(+), 22 deletions(-) diff --git a/packages/components/CHANGELOG.md b/packages/components/CHANGELOG.md index 326d2876e65c6..46e357a008b3f 100644 --- a/packages/components/CHANGELOG.md +++ b/packages/components/CHANGELOG.md @@ -26,6 +26,7 @@ - `CustomSelectControlV2`: do not flip popover if legacy adapter. ([#63357](https://github.com/WordPress/gutenberg/pull/63357)). - `DropdownMenuV2`: invert animation direction. ([#63443](https://github.com/WordPress/gutenberg/pull/63443)). - `Tabs`: Vertical Tabs should be 40px min height. ([#63446](https://github.com/WordPress/gutenberg/pull/63446)). +- `ColorPicker`: Use `minimal` variant for `SelectControl` ([#63676](https://github.com/WordPress/gutenberg/pull/63676)). ## 28.3.0 (2024-07-10) diff --git a/packages/components/src/color-picker/component.tsx b/packages/components/src/color-picker/component.tsx index 8154a0a41331a..a1112d2e1ecd2 100644 --- a/packages/components/src/color-picker/component.tsx +++ b/packages/components/src/color-picker/component.tsx @@ -16,11 +16,7 @@ import { __ } from '@wordpress/i18n'; /** * Internal dependencies */ -import { - useContextSystem, - contextConnect, - ContextSystemProvider, -} from '../context'; +import { useContextSystem, contextConnect } from '../context'; import { ColorfulWrapper, SelectControl, @@ -43,9 +39,6 @@ const options = [ { label: 'Hex', value: 'hex' as const }, ]; -// `isBorderless` is still experimental and not a public prop for InputControl yet. -const BORDERLESS_SELECT_CONTROL_CONTEXT = { InputBase: { isBorderless: true } }; - const UnconnectedColorPicker = ( props: ColorPickerProps, forwardedRef: ForwardedRef< any > @@ -92,20 +85,17 @@ const UnconnectedColorPicker = ( /> - - - setColorType( nextColorType as ColorType ) - } - label={ __( 'Color format' ) } - hideLabelFromVision - /> - + + setColorType( nextColorType as ColorType ) + } + label={ __( 'Color format' ) } + hideLabelFromVision + variant="minimal" + /> Date: Thu, 18 Jul 2024 18:31:29 +0900 Subject: [PATCH 04/17] Add margin-bottom lint rules for CheckboxControl, ComboboxControl, SearchControl (#63679) Co-authored-by: mirka <0mirka00@git.wordpress.org> Co-authored-by: ciampo --- .eslintrc.js | 3 +++ .../src/components/inserter/media-tab/media-panel.js | 1 + packages/block-editor/src/components/inserter/style.scss | 4 ++-- packages/block-library/src/form-input/edit.js | 2 ++ packages/block-library/src/page-list/edit.js | 1 + packages/components/src/checkbox-control/README.md | 8 ++++++++ packages/components/src/checkbox-control/index.tsx | 1 + packages/components/src/combobox-control/README.md | 9 +++++++++ packages/components/src/combobox-control/index.tsx | 1 + 9 files changed, 28 insertions(+), 2 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index c15afbcf02aa9..4385f528f44db 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -290,7 +290,10 @@ module.exports = { ...restrictedSyntax, ...restrictedSyntaxComponents, ...[ + 'CheckboxControl', + 'ComboboxControl', 'FocalPointPicker', + 'SearchControl', 'TextareaControl', 'TreeSelect', ].map( ( componentName ) => ( { diff --git a/packages/block-editor/src/components/inserter/media-tab/media-panel.js b/packages/block-editor/src/components/inserter/media-tab/media-panel.js index 9a55bd5ef99ce..cc19403f9d947 100644 --- a/packages/block-editor/src/components/inserter/media-tab/media-panel.js +++ b/packages/block-editor/src/components/inserter/media-tab/media-panel.js @@ -25,6 +25,7 @@ export function MediaCategoryPanel( { rootClientId, onInsert, category } ) { return (
{ 'checkbox' !== type && ( { @@ -48,6 +49,7 @@ function InputFieldBlock( { attributes, setAttributes, className } ) { /> ) } { diff --git a/packages/block-library/src/page-list/edit.js b/packages/block-library/src/page-list/edit.js index fca8096ac05d4..2b7f31c3c7c5e 100644 --- a/packages/block-library/src/page-list/edit.js +++ b/packages/block-library/src/page-list/edit.js @@ -319,6 +319,7 @@ export default function PageListEdit( { { pagesTree.length > 0 && ( { const [ isChecked, setChecked ] = useState( true ); return ( ReactNode` - Required: No +#### __nextHasNoMarginBottom + +Start opting into the new margin-free styles that will become the default in a future version. + +- Type: `Boolean` +- Required: No +- Default: `false` + ## Related components - Like this component, but without a search input, the [`CustomSelectControl`](https://developer.wordpress.org/block-editor/reference-guides/components/custom-select-control/) component. diff --git a/packages/components/src/combobox-control/index.tsx b/packages/components/src/combobox-control/index.tsx index a39a5dc1fc541..e3b1434be8c7c 100644 --- a/packages/components/src/combobox-control/index.tsx +++ b/packages/components/src/combobox-control/index.tsx @@ -92,6 +92,7 @@ const getIndexOfMatchingSuggestion = ( * const [ filteredOptions, setFilteredOptions ] = useState( options ); * return ( * Date: Thu, 18 Jul 2024 21:05:03 +0900 Subject: [PATCH 05/17] Fix: Add Template Modal layout in mobile view (#63627) Co-authored-by: t-hamano Co-authored-by: jameskoster --- .../edit-site/src/components/add-new-template/index.js | 5 ++++- .../src/components/add-new-template/style.scss | 10 ++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/packages/edit-site/src/components/add-new-template/index.js b/packages/edit-site/src/components/add-new-template/index.js index 3705010be4853..e8f68905e34cc 100644 --- a/packages/edit-site/src/components/add-new-template/index.js +++ b/packages/edit-site/src/components/add-new-template/index.js @@ -19,6 +19,7 @@ import { decodeEntities } from '@wordpress/html-entities'; import { useState, memo } from '@wordpress/element'; import { useSelect, useDispatch } from '@wordpress/data'; import { store as coreStore } from '@wordpress/core-data'; +import { useViewportMatch } from '@wordpress/compose'; import { archive, blockMeta, @@ -161,6 +162,8 @@ function NewTemplateModal( { onClose } ) { const { createErrorNotice, createSuccessNotice } = useDispatch( noticesStore ); + const isMobile = useViewportMatch( 'medium', '<' ); + const { homeUrl } = useSelect( ( select ) => { const { getUnstableBase, // Site index. @@ -266,7 +269,7 @@ function NewTemplateModal( { onClose } ) { > { modalContent === modalContentMap.templatesList && ( Date: Thu, 18 Jul 2024 21:05:44 +0900 Subject: [PATCH 06/17] Quality: Remove "reusable block name hint" code (#63514) Co-authored-by: t-hamano Co-authored-by: Mamaduka --- packages/block-editor/README.md | 4 -- packages/block-editor/src/components/index.js | 5 -- .../inserter/reusable-block-rename-hint.js | 69 ------------------- .../src/components/inserter/style.scss | 24 ------- packages/block-editor/src/private-apis.js | 6 -- .../components/init-pattern-modal/index.js | 10 --- .../reusable-block-convert-button.js | 16 +---- 7 files changed, 2 insertions(+), 132 deletions(-) delete mode 100644 packages/block-editor/src/components/inserter/reusable-block-rename-hint.js diff --git a/packages/block-editor/README.md b/packages/block-editor/README.md index 6b9af74d03a3a..00951fb94c4a7 100644 --- a/packages/block-editor/README.md +++ b/packages/block-editor/README.md @@ -730,10 +730,6 @@ _Returns_ - `JSX.Element`: A React element. -### ReusableBlocksRenameHint - -Undocumented declaration. - ### RichText _Related_ diff --git a/packages/block-editor/src/components/index.js b/packages/block-editor/src/components/index.js index 2a127feb3df1c..29bb71b682e97 100644 --- a/packages/block-editor/src/components/index.js +++ b/packages/block-editor/src/components/index.js @@ -170,8 +170,3 @@ export { useBlockEditingMode } from './block-editing-mode'; export { default as BlockEditorProvider } from './provider'; export { useSettings, useSetting } from './use-settings'; export { useBlockCommands } from './use-block-commands'; - -/* - * The following rename hint component can be removed in 6.4. - */ -export { default as ReusableBlocksRenameHint } from './inserter/reusable-block-rename-hint'; diff --git a/packages/block-editor/src/components/inserter/reusable-block-rename-hint.js b/packages/block-editor/src/components/inserter/reusable-block-rename-hint.js deleted file mode 100644 index 6a3a3d1eec260..0000000000000 --- a/packages/block-editor/src/components/inserter/reusable-block-rename-hint.js +++ /dev/null @@ -1,69 +0,0 @@ -/** - * WordPress dependencies - */ -import { Button } from '@wordpress/components'; -import { useDispatch, useSelect } from '@wordpress/data'; -import { focus } from '@wordpress/dom'; -import { useRef } from '@wordpress/element'; -import { __ } from '@wordpress/i18n'; -import { close } from '@wordpress/icons'; -import { store as preferencesStore } from '@wordpress/preferences'; - -const PREFERENCE_NAME = 'isResuableBlocksrRenameHintVisible'; -/* - * This hook was added in 6.3 to help users with the transition from Reusable blocks to Patterns. - * It is only exported for use in the reusable-blocks package as well as block-editor. - * It will be removed in 6.4. and should not be used in any new code. - */ -export function useReusableBlocksRenameHint() { - return useSelect( - ( select ) => - select( preferencesStore ).get( 'core', PREFERENCE_NAME ) ?? true, - [] - ); -} - -/* - * This component was added in 6.3 to help users with the transition from Reusable blocks to Patterns. - * It is only exported for use in the reusable-blocks package as well as block-editor. - * It will be removed in 6.4. and should not be used in any new code. - */ -export default function ReusableBlocksRenameHint() { - const isReusableBlocksRenameHint = useSelect( - ( select ) => - select( preferencesStore ).get( 'core', PREFERENCE_NAME ) ?? true, - [] - ); - - const ref = useRef(); - - const { set: setPreference } = useDispatch( preferencesStore ); - if ( ! isReusableBlocksRenameHint ) { - return null; - } - - return ( -
-
- { __( - 'Reusable blocks are now synced patterns. A synced pattern will behave in exactly the same way as a reusable block.' - ) } -
-
- ); -} diff --git a/packages/block-editor/src/components/inserter/style.scss b/packages/block-editor/src/components/inserter/style.scss index 35801c0e65e54..d446340939c30 100644 --- a/packages/block-editor/src/components/inserter/style.scss +++ b/packages/block-editor/src/components/inserter/style.scss @@ -655,30 +655,6 @@ $block-inserter-tabs-height: 44px; margin: $grid-unit-20 $grid-unit-20 0; } -.reusable-blocks-menu-items__rename-hint { - align-items: top; - background: $gray-100; - border-radius: $radius-block-ui; - color: $gray-900; - display: flex; - flex-direction: row; - max-width: 380px; -} - -.reusable-blocks-menu-items__rename-hint-content { - margin: $grid-unit-15 0 $grid-unit-15 $grid-unit-15; -} - -.reusable-blocks-menu-items__rename-hint-dismiss { - // The dismiss button has a lot of empty space through its padding. - // Apply margin to visually align the icon with the top of the text to its left. - margin: $grid-unit-05 $grid-unit-05 $grid-unit-05 0; -} - -.components-menu-group .reusable-blocks-menu-items__rename-hint { - margin: 0; -} - .block-editor-patterns__sync-status-filter { .components-input-control__container { select.components-select-control__input { diff --git a/packages/block-editor/src/private-apis.js b/packages/block-editor/src/private-apis.js index c01d40d9d743b..eaf699d5e6939 100644 --- a/packages/block-editor/src/private-apis.js +++ b/packages/block-editor/src/private-apis.js @@ -29,10 +29,6 @@ import { import DimensionsTool from './components/dimensions-tool'; import ResolutionTool from './components/resolution-tool'; import TextAlignmentControl from './components/text-alignment-control'; -import { - default as ReusableBlocksRenameHint, - useReusableBlocksRenameHint, -} from './components/inserter/reusable-block-rename-hint'; import { usesContextKey } from './components/rich-text/format-edit'; import { ExperimentalBlockCanvas } from './components/block-canvas'; import { getDuotoneFilter } from './components/duotone/utils'; @@ -82,8 +78,6 @@ lock( privateApis, { ResolutionTool, TabbedSidebar, TextAlignmentControl, - ReusableBlocksRenameHint, - useReusableBlocksRenameHint, usesContextKey, useFlashEditableBlocks, globalStylesDataKey, diff --git a/packages/edit-post/src/components/init-pattern-modal/index.js b/packages/edit-post/src/components/init-pattern-modal/index.js index e2aef9994fa0f..a40ffc5dc5856 100644 --- a/packages/edit-post/src/components/init-pattern-modal/index.js +++ b/packages/edit-post/src/components/init-pattern-modal/index.js @@ -13,15 +13,6 @@ import { } from '@wordpress/components'; import { useEffect, useState } from '@wordpress/element'; import { store as editorStore } from '@wordpress/editor'; -import { privateApis as blockEditorPrivateApis } from '@wordpress/block-editor'; - -/** - * Internal dependencies - */ - -import { unlock } from '../../lock-unlock'; - -const { ReusableBlocksRenameHint } = unlock( blockEditorPrivateApis ); export default function InitPatternModal() { const { editPost } = useDispatch( editorStore ); @@ -82,7 +73,6 @@ export default function InitPatternModal() { __nextHasNoMarginBottom __next40pxDefaultSize /> - setIsModalOpen( true ) }> - { showRenameHint - ? __( 'Create pattern/reusable block' ) - : __( 'Create pattern' ) } + { __( 'Create pattern' ) } { isModalOpen && ( - Date: Thu, 18 Jul 2024 09:19:02 -0400 Subject: [PATCH 07/17] Image lightbox: Remove duplicate image when lightbox is opened (#63381) * Hide content image when lightbox is opened * Handle duplicate image when closing lightbox as well * Remove styling for prefers reduced motion * Rename state getters * Hide captions in galleries when opening lightbox * Revert "Hide captions in galleries when opening lightbox" This reverts commit 40c28b9eead72a44eb4bf4706b38e026fe77607f. --- packages/block-library/src/image/index.php | 2 ++ packages/block-library/src/image/style.scss | 22 +++++++++++++++++++++ packages/block-library/src/image/view.js | 15 +++++++++++++- 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/packages/block-library/src/image/index.php b/packages/block-library/src/image/index.php index ce9c958c19b6c..75f0d404e4820 100644 --- a/packages/block-library/src/image/index.php +++ b/packages/block-library/src/image/index.php @@ -230,6 +230,8 @@ function block_core_image_render_lightbox( $block_content, $block ) { // contain a caption, and we don't want to trigger the lightbox when the // caption is clicked. $p->set_attribute( 'data-wp-on-async--click', 'actions.showLightbox' ); + $p->set_attribute( 'data-wp-class--hide', 'state.isContentHidden' ); + $p->set_attribute( 'data-wp-class--show', 'state.isContentVisible' ); $body_content = $p->get_updated_html(); diff --git a/packages/block-library/src/image/style.scss b/packages/block-library/src/image/style.scss index 84c5a1f42de15..1bb19bf29da69 100644 --- a/packages/block-library/src/image/style.scss +++ b/packages/block-library/src/image/style.scss @@ -9,6 +9,16 @@ max-width: 100%; vertical-align: bottom; box-sizing: border-box; + + @media (prefers-reduced-motion: no-preference) { + &.hide { + visibility: hidden; + } + + &.show { + animation: show-content-image 0.4s; + } + } } // The following style maintains border radius application for deprecated @@ -319,6 +329,18 @@ } } +@keyframes show-content-image { + 0% { + visibility: hidden; + } + 99% { + visibility: hidden; + } + 100% { + visibility: visible; + } +} + @keyframes turn-on-visibility { 0% { opacity: 0; diff --git a/packages/block-library/src/image/view.js b/packages/block-library/src/image/view.js index 5ff97cccf1834..7010e9b7b2219 100644 --- a/packages/block-library/src/image/view.js +++ b/packages/block-library/src/image/view.js @@ -68,6 +68,19 @@ const { state, actions, callbacks } = store( const { imageId } = getContext(); return state.metadata[ imageId ].imageButtonTop; }, + get isContentHidden() { + const ctx = getContext(); + return ( + state.overlayEnabled && state.currentImageId === ctx.imageId + ); + }, + get isContentVisible() { + const ctx = getContext(); + return ( + ! state.overlayEnabled && + state.currentImageId === ctx.imageId + ); + }, }, actions: { showLightbox() { @@ -84,8 +97,8 @@ const { state, actions, callbacks } = store( state.scrollLeftReset = document.documentElement.scrollLeft; // Sets the current expanded image in the state and enables the overlay. - state.currentImageId = imageId; state.overlayEnabled = true; + state.currentImageId = imageId; // Computes the styles of the overlay for the animation. callbacks.setOverlayStyles(); From 32b4b2ec8acf8dc5e5eca4efbf6ed0ad6be3c3de Mon Sep 17 00:00:00 2001 From: Daniel Richards Date: Fri, 19 Jul 2024 12:28:27 +0800 Subject: [PATCH 08/17] Downgrade node 22(.5) unit tests to 22.4 (#63728) * Downgrade node 22 unit tests to 22.4 until https://github.com/npm/cli/issues/7657 is fixed * try again * Try using a stable name for the tests so that required jobs do not require an update --- .github/workflows/create-block.yml | 10 +++++++--- .github/workflows/unit-test.yml | 20 ++++++++++++++------ 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/.github/workflows/create-block.yml b/.github/workflows/create-block.yml index 0de1b9ee6566a..245b136ee22c1 100644 --- a/.github/workflows/create-block.yml +++ b/.github/workflows/create-block.yml @@ -14,13 +14,17 @@ concurrency: jobs: checks: - name: Checks w/Node.js ${{ matrix.node }} on ${{ matrix.os }} + name: Checks w/Node.js ${{ matrix.node.name }} on ${{ matrix.os }} runs-on: ${{ matrix.os }} if: ${{ github.repository == 'WordPress/gutenberg' || github.event_name == 'pull_request' }} strategy: fail-fast: false matrix: - node: ['20', '22'] + node: + - name: 20 + version: 20 + - name: 22 + version: 22.4 os: ['macos-latest', 'ubuntu-latest', 'windows-latest'] steps: @@ -31,7 +35,7 @@ jobs: - name: Setup Node.js and install dependencies uses: ./.github/setup-node with: - node-version: ${{ matrix.node }} + node-version: ${{ matrix.node.version }} - name: Create block shell: bash diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml index 488f41c217e7c..75a0d34ddc8d8 100644 --- a/.github/workflows/unit-test.yml +++ b/.github/workflows/unit-test.yml @@ -21,13 +21,17 @@ concurrency: jobs: unit-js: - name: JavaScript (Node.js ${{ matrix.node }}) ${{ matrix.shard }} + name: JavaScript (Node.js ${{ matrix.node.name }}) ${{ matrix.shard }} runs-on: ubuntu-latest if: ${{ github.repository == 'WordPress/gutenberg' || github.event_name == 'pull_request' }} strategy: fail-fast: false matrix: - node: ['20', '22'] + node: + - name: 20 + version: 20 + - name: 22 + version: 22.4 shard: ['1/4', '2/4', '3/4', '4/4'] steps: @@ -39,7 +43,7 @@ jobs: - name: Setup Node.js and install dependencies uses: ./.github/setup-node with: - node-version: ${{ matrix.node }} + node-version: ${{ matrix.node.version }} - name: Determine the number of CPU cores uses: SimenB/github-actions-cpu-cores@97ba232459a8e02ff6121db9362b09661c875ab8 # v2.0.0 @@ -60,13 +64,17 @@ jobs: --cacheDirectory="$HOME/.jest-cache" unit-js-date: - name: JavaScript Date Tests (Node.js ${{ matrix.node }}) + name: JavaScript Date Tests (Node.js ${{ matrix.node.name }}) runs-on: ubuntu-latest if: ${{ github.repository == 'WordPress/gutenberg' || github.event_name == 'pull_request' }} strategy: fail-fast: false matrix: - node: ['20', '22'] + node: + - name: 20 + version: 20 + - name: 22 + version: 22.4 steps: - name: Checkout repository @@ -77,7 +85,7 @@ jobs: - name: Setup Node.js and install dependencies uses: ./.github/setup-node with: - node-version: ${{ matrix.node }} + node-version: ${{ matrix.node.version }} - name: Determine the number of CPU cores uses: SimenB/github-actions-cpu-cores@97ba232459a8e02ff6121db9362b09661c875ab8 # v2.0.0 From 3053d39cc62a859e2320d9d7dcc3b0acb53f1ac2 Mon Sep 17 00:00:00 2001 From: Jorge Costa Date: Fri, 19 Jul 2024 07:19:21 +0200 Subject: [PATCH 09/17] Fix: DataViews: Layout resets for patterns each time a new pattern category is selected. (#63711) * Fix: DataViews: Layout resets for patterns each time a new pattern category is selected. * Use the state updater function Co-authored-by: jorgefilipecosta Co-authored-by: Mamaduka Co-authored-by: jameskoster Co-authored-by: aaronrobertshaw Co-authored-by: mrfoxtalbot Co-authored-by: talldan --- packages/edit-site/src/components/page-patterns/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/edit-site/src/components/page-patterns/index.js b/packages/edit-site/src/components/page-patterns/index.js index 6304c89d711fc..a1b4f2a0912de 100644 --- a/packages/edit-site/src/components/page-patterns/index.js +++ b/packages/edit-site/src/components/page-patterns/index.js @@ -351,7 +351,7 @@ export default function DataviewsPatterns() { // Reset the page number when the category changes. useEffect( () => { if ( previousCategoryId !== categoryId ) { - setView( DEFAULT_VIEW ); + setView( ( prevView ) => ( { ...prevView, page: 1 } ) ); } }, [ categoryId, previousCategoryId ] ); const { data, paginationInfo } = useMemo( () => { From ef198f9d3416dca97ebee84584652d8be0e87f4b Mon Sep 17 00:00:00 2001 From: Daniel Richards Date: Fri, 19 Jul 2024 13:41:15 +0800 Subject: [PATCH 10/17] Ensure root selector (body) is not wrapped in :root :where() (#63726) * Ensure root selector (body) is not wrapped in :root :where() to keep specificity at 0,0,1 * Fix PHP unit tests * Update editor root selector specificity * Update node structure unit test * Add backport changelog ---- Unlinked contributors: mleathem. Co-authored-by: talldan Co-authored-by: aaronrobertshaw Co-authored-by: andrewserong --- backport-changelog/6.6/7061.md | 3 +++ lib/class-wp-theme-json-gutenberg.php | 15 +++++++++----- .../test/use-global-styles-output.js | 3 ++- .../global-styles/use-global-styles-output.js | 3 +++ phpunit/class-wp-theme-json-test.php | 20 +++++++++---------- 5 files changed, 28 insertions(+), 16 deletions(-) create mode 100644 backport-changelog/6.6/7061.md diff --git a/backport-changelog/6.6/7061.md b/backport-changelog/6.6/7061.md new file mode 100644 index 0000000000000..307e6575cf38d --- /dev/null +++ b/backport-changelog/6.6/7061.md @@ -0,0 +1,3 @@ +https://github.com/WordPress/wordpress-develop/pull/7061 + +* https://github.com/WordPress/gutenberg/pull/63726 diff --git a/lib/class-wp-theme-json-gutenberg.php b/lib/class-wp-theme-json-gutenberg.php index df46c3399a2a7..65a5e5fe4b957 100644 --- a/lib/class-wp-theme-json-gutenberg.php +++ b/lib/class-wp-theme-json-gutenberg.php @@ -2921,6 +2921,9 @@ static function ( $pseudo_selector ) use ( $selector ) { } /* + * Root selector (body) styles should not be wrapped in `:root where()` to keep + * specificity at (0,0,1) and maintain backwards compatibility. + * * Top-level element styles using element-only specificity selectors should * not get wrapped in `:root :where()` to maintain backwards compatibility. * @@ -2928,11 +2931,13 @@ static function ( $pseudo_selector ) use ( $selector ) { * still need to be wrapped in `:root :where` to cap specificity for nested * variations etc. Pseudo selectors won't match the ELEMENTS selector exactly. */ - $element_only_selector = $current_element && - isset( static::ELEMENTS[ $current_element ] ) && - // buttons, captions etc. still need `:root :where()` as they are class based selectors. - ! isset( static::__EXPERIMENTAL_ELEMENT_CLASS_NAMES[ $current_element ] ) && - static::ELEMENTS[ $current_element ] === $selector; + $element_only_selector = $is_root_selector || ( + $current_element && + isset( static::ELEMENTS[ $current_element ] ) && + // buttons, captions etc. still need `:root :where()` as they are class based selectors. + ! isset( static::__EXPERIMENTAL_ELEMENT_CLASS_NAMES[ $current_element ] ) && + static::ELEMENTS[ $current_element ] === $selector + ); // 2. Generate and append the rules that use the general selector. $general_selector = $element_only_selector ? $selector : ":root :where($selector)"; diff --git a/packages/block-editor/src/components/global-styles/test/use-global-styles-output.js b/packages/block-editor/src/components/global-styles/test/use-global-styles-output.js index 066f7e3a28019..525a8a1d53d07 100644 --- a/packages/block-editor/src/components/global-styles/test/use-global-styles-output.js +++ b/packages/block-editor/src/components/global-styles/test/use-global-styles-output.js @@ -107,6 +107,7 @@ describe( 'global styles renderer', () => { }, }, selector: ROOT_BLOCK_SELECTOR, + skipSelectorWrapper: true, }, { styles: { @@ -481,7 +482,7 @@ describe( 'global styles renderer', () => { }; expect( toStyles( tree, blockSelectors ) ).toEqual( - ':where(body) {margin: 0;}.is-layout-flow > .alignleft { float: left; margin-inline-start: 0; margin-inline-end: 2em; }.is-layout-flow > .alignright { float: right; margin-inline-start: 2em; margin-inline-end: 0; }.is-layout-flow > .aligncenter { margin-left: auto !important; margin-right: auto !important; }.is-layout-constrained > .alignleft { float: left; margin-inline-start: 0; margin-inline-end: 2em; }.is-layout-constrained > .alignright { float: right; margin-inline-start: 2em; margin-inline-end: 0; }.is-layout-constrained > .aligncenter { margin-left: auto !important; margin-right: auto !important; }.is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)) { max-width: var(--wp--style--global--content-size); margin-left: auto !important; margin-right: auto !important; }.is-layout-constrained > .alignwide { max-width: var(--wp--style--global--wide-size); }body .is-layout-flex { display:flex; }.is-layout-flex { flex-wrap: wrap; align-items: center; }.is-layout-flex > :is(*, div) { margin: 0; }body .is-layout-grid { display:grid; }.is-layout-grid > :is(*, div) { margin: 0; }:root :where(body){background-color: red;margin: 10px;padding: 10px;}a:where(:not(.wp-element-button)){color: blue;}:root :where(a:where(:not(.wp-element-button)):hover){color: orange;}:root :where(a:where(:not(.wp-element-button)):focus){color: orange;}h1{font-size: 42px;}:root :where(.wp-block-group){margin-top: 10px;margin-right: 20px;margin-bottom: 30px;margin-left: 40px;padding-top: 11px;padding-right: 22px;padding-bottom: 33px;padding-left: 44px;}:root :where(h1,h2,h3,h4,h5,h6){color: orange;}:root :where(h1 a:where(:not(.wp-element-button)),h2 a:where(:not(.wp-element-button)),h3 a:where(:not(.wp-element-button)),h4 a:where(:not(.wp-element-button)),h5 a:where(:not(.wp-element-button)),h6 a:where(:not(.wp-element-button))){color: hotpink;}:root :where(h1 a:where(:not(.wp-element-button)):hover,h2 a:where(:not(.wp-element-button)):hover,h3 a:where(:not(.wp-element-button)):hover,h4 a:where(:not(.wp-element-button)):hover,h5 a:where(:not(.wp-element-button)):hover,h6 a:where(:not(.wp-element-button)):hover){color: red;}:root :where(h1 a:where(:not(.wp-element-button)):focus,h2 a:where(:not(.wp-element-button)):focus,h3 a:where(:not(.wp-element-button)):focus,h4 a:where(:not(.wp-element-button)):focus,h5 a:where(:not(.wp-element-button)):focus,h6 a:where(:not(.wp-element-button)):focus){color: red;}:root :where(.wp-block-image img, .wp-block-image .wp-crop-area){border-radius: 9999px;}:root :where(.wp-block-image){color: red;}.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }.has-white-color{color: var(--wp--preset--color--white) !important;}.has-white-background-color{background-color: var(--wp--preset--color--white) !important;}.has-white-border-color{border-color: var(--wp--preset--color--white) !important;}.has-black-color{color: var(--wp--preset--color--black) !important;}.has-black-background-color{background-color: var(--wp--preset--color--black) !important;}.has-black-border-color{border-color: var(--wp--preset--color--black) !important;}h1.has-blue-color,h2.has-blue-color,h3.has-blue-color,h4.has-blue-color,h5.has-blue-color,h6.has-blue-color{color: var(--wp--preset--color--blue) !important;}h1.has-blue-background-color,h2.has-blue-background-color,h3.has-blue-background-color,h4.has-blue-background-color,h5.has-blue-background-color,h6.has-blue-background-color{background-color: var(--wp--preset--color--blue) !important;}h1.has-blue-border-color,h2.has-blue-border-color,h3.has-blue-border-color,h4.has-blue-border-color,h5.has-blue-border-color,h6.has-blue-border-color{border-color: var(--wp--preset--color--blue) !important;}' + ':where(body) {margin: 0;}.is-layout-flow > .alignleft { float: left; margin-inline-start: 0; margin-inline-end: 2em; }.is-layout-flow > .alignright { float: right; margin-inline-start: 2em; margin-inline-end: 0; }.is-layout-flow > .aligncenter { margin-left: auto !important; margin-right: auto !important; }.is-layout-constrained > .alignleft { float: left; margin-inline-start: 0; margin-inline-end: 2em; }.is-layout-constrained > .alignright { float: right; margin-inline-start: 2em; margin-inline-end: 0; }.is-layout-constrained > .aligncenter { margin-left: auto !important; margin-right: auto !important; }.is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)) { max-width: var(--wp--style--global--content-size); margin-left: auto !important; margin-right: auto !important; }.is-layout-constrained > .alignwide { max-width: var(--wp--style--global--wide-size); }body .is-layout-flex { display:flex; }.is-layout-flex { flex-wrap: wrap; align-items: center; }.is-layout-flex > :is(*, div) { margin: 0; }body .is-layout-grid { display:grid; }.is-layout-grid > :is(*, div) { margin: 0; }body{background-color: red;margin: 10px;padding: 10px;}a:where(:not(.wp-element-button)){color: blue;}:root :where(a:where(:not(.wp-element-button)):hover){color: orange;}:root :where(a:where(:not(.wp-element-button)):focus){color: orange;}h1{font-size: 42px;}:root :where(.wp-block-group){margin-top: 10px;margin-right: 20px;margin-bottom: 30px;margin-left: 40px;padding-top: 11px;padding-right: 22px;padding-bottom: 33px;padding-left: 44px;}:root :where(h1,h2,h3,h4,h5,h6){color: orange;}:root :where(h1 a:where(:not(.wp-element-button)),h2 a:where(:not(.wp-element-button)),h3 a:where(:not(.wp-element-button)),h4 a:where(:not(.wp-element-button)),h5 a:where(:not(.wp-element-button)),h6 a:where(:not(.wp-element-button))){color: hotpink;}:root :where(h1 a:where(:not(.wp-element-button)):hover,h2 a:where(:not(.wp-element-button)):hover,h3 a:where(:not(.wp-element-button)):hover,h4 a:where(:not(.wp-element-button)):hover,h5 a:where(:not(.wp-element-button)):hover,h6 a:where(:not(.wp-element-button)):hover){color: red;}:root :where(h1 a:where(:not(.wp-element-button)):focus,h2 a:where(:not(.wp-element-button)):focus,h3 a:where(:not(.wp-element-button)):focus,h4 a:where(:not(.wp-element-button)):focus,h5 a:where(:not(.wp-element-button)):focus,h6 a:where(:not(.wp-element-button)):focus){color: red;}:root :where(.wp-block-image img, .wp-block-image .wp-crop-area){border-radius: 9999px;}:root :where(.wp-block-image){color: red;}.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }.has-white-color{color: var(--wp--preset--color--white) !important;}.has-white-background-color{background-color: var(--wp--preset--color--white) !important;}.has-white-border-color{border-color: var(--wp--preset--color--white) !important;}.has-black-color{color: var(--wp--preset--color--black) !important;}.has-black-background-color{background-color: var(--wp--preset--color--black) !important;}.has-black-border-color{border-color: var(--wp--preset--color--black) !important;}h1.has-blue-color,h2.has-blue-color,h3.has-blue-color,h4.has-blue-color,h5.has-blue-color,h6.has-blue-color{color: var(--wp--preset--color--blue) !important;}h1.has-blue-background-color,h2.has-blue-background-color,h3.has-blue-background-color,h4.has-blue-background-color,h5.has-blue-background-color,h6.has-blue-background-color{background-color: var(--wp--preset--color--blue) !important;}h1.has-blue-border-color,h2.has-blue-border-color,h3.has-blue-border-color,h4.has-blue-border-color,h5.has-blue-border-color,h6.has-blue-border-color{border-color: var(--wp--preset--color--blue) !important;}' ); } ); diff --git a/packages/block-editor/src/components/global-styles/use-global-styles-output.js b/packages/block-editor/src/components/global-styles/use-global-styles-output.js index 58c1fa35b600a..63d6a2fb22dd7 100644 --- a/packages/block-editor/src/components/global-styles/use-global-styles-output.js +++ b/packages/block-editor/src/components/global-styles/use-global-styles-output.js @@ -649,6 +649,9 @@ export const getNodesWithStyles = ( tree, blockSelectors ) => { nodes.push( { styles, selector: ROOT_BLOCK_SELECTOR, + // Root selector (body) styles should not be wrapped in `:root where()` to keep + // specificity at (0,0,1) and maintain backwards compatibility. + skipSelectorWrapper: true, } ); } diff --git a/phpunit/class-wp-theme-json-test.php b/phpunit/class-wp-theme-json-test.php index d76517091f44f..2f76ec7a5d473 100644 --- a/phpunit/class-wp-theme-json-test.php +++ b/phpunit/class-wp-theme-json-test.php @@ -552,7 +552,7 @@ public function test_get_stylesheet() { ); $variables = ':root{--wp--preset--color--grey: grey;--wp--preset--gradient--custom-gradient: linear-gradient(135deg,rgba(0,0,0) 0%,rgb(0,0,0) 100%);--wp--preset--font-size--small: 14px;--wp--preset--font-size--big: 41px;--wp--preset--font-family--arial: Arial, serif;}.wp-block-group{--wp--custom--base-font: 16;--wp--custom--line-height--small: 1.2;--wp--custom--line-height--medium: 1.4;--wp--custom--line-height--large: 1.8;}'; - $styles = static::$base_styles . ':root :where(body){color: var(--wp--preset--color--grey);}a:where(:not(.wp-element-button)){background-color: #333;color: #111;}:root :where(.wp-element-button, .wp-block-button__link){box-shadow: 10px 10px 5px 0px rgba(0,0,0,0.66);}:root :where(.wp-block-cover){min-height: unset;aspect-ratio: 16/9;}:root :where(.wp-block-group){background: var(--wp--preset--gradient--custom-gradient);border-radius: 10px;min-height: 50vh;padding: 24px;}:root :where(.wp-block-group a:where(:not(.wp-element-button))){color: #111;}:root :where(.wp-block-heading){color: #123456;}:root :where(.wp-block-heading a:where(:not(.wp-element-button))){background-color: #333;color: #111;font-size: 60px;}:root :where(.wp-block-media-text){text-align: center;}:root :where(.wp-block-post-date){color: #123456;}:root :where(.wp-block-post-date a:where(:not(.wp-element-button))){background-color: #777;color: #555;}:root :where(.wp-block-post-excerpt){column-count: 2;}:root :where(.wp-block-image){margin-bottom: 30px;}:root :where(.wp-block-image img, .wp-block-image .wp-block-image__crop-area, .wp-block-image .components-placeholder){border-top-left-radius: 10px;border-bottom-right-radius: 1em;}:root :where(.wp-block-image img, .wp-block-image .components-placeholder){filter: var(--wp--preset--duotone--custom-duotone);}'; + $styles = static::$base_styles . 'body{color: var(--wp--preset--color--grey);}a:where(:not(.wp-element-button)){background-color: #333;color: #111;}:root :where(.wp-element-button, .wp-block-button__link){box-shadow: 10px 10px 5px 0px rgba(0,0,0,0.66);}:root :where(.wp-block-cover){min-height: unset;aspect-ratio: 16/9;}:root :where(.wp-block-group){background: var(--wp--preset--gradient--custom-gradient);border-radius: 10px;min-height: 50vh;padding: 24px;}:root :where(.wp-block-group a:where(:not(.wp-element-button))){color: #111;}:root :where(.wp-block-heading){color: #123456;}:root :where(.wp-block-heading a:where(:not(.wp-element-button))){background-color: #333;color: #111;font-size: 60px;}:root :where(.wp-block-media-text){text-align: center;}:root :where(.wp-block-post-date){color: #123456;}:root :where(.wp-block-post-date a:where(:not(.wp-element-button))){background-color: #777;color: #555;}:root :where(.wp-block-post-excerpt){column-count: 2;}:root :where(.wp-block-image){margin-bottom: 30px;}:root :where(.wp-block-image img, .wp-block-image .wp-block-image__crop-area, .wp-block-image .components-placeholder){border-top-left-radius: 10px;border-bottom-right-radius: 1em;}:root :where(.wp-block-image img, .wp-block-image .components-placeholder){filter: var(--wp--preset--duotone--custom-duotone);}'; $presets = '.has-grey-color{color: var(--wp--preset--color--grey) !important;}.has-grey-background-color{background-color: var(--wp--preset--color--grey) !important;}.has-grey-border-color{border-color: var(--wp--preset--color--grey) !important;}.has-custom-gradient-gradient-background{background: var(--wp--preset--gradient--custom-gradient) !important;}.has-small-font-size{font-size: var(--wp--preset--font-size--small) !important;}.has-big-font-size{font-size: var(--wp--preset--font-size--big) !important;}.has-arial-font-family{font-family: var(--wp--preset--font-family--arial) !important;}'; $all = $variables . $styles . $presets; @@ -1361,7 +1361,7 @@ public function test_get_stylesheet_generates_fluid_typography_values() { unregister_block_type( 'test/clamp-me' ); $this->assertSame( - ':root{--wp--preset--font-size--pickles: clamp(14px, 0.875rem + ((1vw - 3.2px) * 0.156), 16px);--wp--preset--font-size--toast: clamp(14.642px, 0.915rem + ((1vw - 3.2px) * 0.575), 22px);}:root :where(body){font-size: clamp(0.875em, 0.875rem + ((1vw - 0.2em) * 0.156), 1em);}h1{font-size: clamp(50.171px, 3.136rem + ((1vw - 3.2px) * 3.893), 100px);}:root :where(.wp-block-test-clamp-me){font-size: clamp(27.894px, 1.743rem + ((1vw - 3.2px) * 1.571), 48px);}.has-pickles-font-size{font-size: var(--wp--preset--font-size--pickles) !important;}.has-toast-font-size{font-size: var(--wp--preset--font-size--toast) !important;}', + ':root{--wp--preset--font-size--pickles: clamp(14px, 0.875rem + ((1vw - 3.2px) * 0.156), 16px);--wp--preset--font-size--toast: clamp(14.642px, 0.915rem + ((1vw - 3.2px) * 0.575), 22px);}body{font-size: clamp(0.875em, 0.875rem + ((1vw - 0.2em) * 0.156), 1em);}h1{font-size: clamp(50.171px, 3.136rem + ((1vw - 3.2px) * 3.893), 100px);}:root :where(.wp-block-test-clamp-me){font-size: clamp(27.894px, 1.743rem + ((1vw - 3.2px) * 1.571), 48px);}.has-pickles-font-size{font-size: var(--wp--preset--font-size--pickles) !important;}.has-toast-font-size{font-size: var(--wp--preset--font-size--toast) !important;}', $theme_json->get_stylesheet( array( 'styles', 'variables', 'presets' ), null, array( 'skip_root_layout_styles' => true ) ) ); } @@ -3418,7 +3418,7 @@ public function test_get_property_value_valid() { ) ); - $expected = ':root :where(body){background-color: #ffffff;color: #000000;}:root :where(.wp-element-button, .wp-block-button__link){background-color: #000000;color: #ffffff;}'; + $expected = 'body{background-color: #ffffff;color: #000000;}:root :where(.wp-element-button, .wp-block-button__link){background-color: #000000;color: #ffffff;}'; $this->assertSame( $expected, $theme_json->get_stylesheet( array( 'styles' ), null, array( 'skip_root_layout_styles' => true ) ) ); } @@ -3495,7 +3495,7 @@ public function test_get_property_value_loop() { ) ); - $expected = ':root :where(body){background-color: #ffffff;}:root :where(.wp-element-button, .wp-block-button__link){color: #ffffff;}'; + $expected = 'body{background-color: #ffffff;}:root :where(.wp-element-button, .wp-block-button__link){color: #ffffff;}'; $this->assertSame( $expected, $theme_json->get_stylesheet( array( 'styles' ), null, array( 'skip_root_layout_styles' => true ) ) ); } @@ -3527,7 +3527,7 @@ public function test_get_property_value_recursion() { ) ); - $expected = ':root :where(body){background-color: #ffffff;color: #ffffff;}:root :where(.wp-element-button, .wp-block-button__link){color: #ffffff;}'; + $expected = 'body{background-color: #ffffff;color: #ffffff;}:root :where(.wp-element-button, .wp-block-button__link){color: #ffffff;}'; $this->assertSame( $expected, $theme_json->get_stylesheet( array( 'styles' ), null, array( 'skip_root_layout_styles' => true ) ) ); } @@ -3550,7 +3550,7 @@ public function test_get_property_value_self() { ) ); - $expected = ':root :where(body){background-color: #ffffff;}'; + $expected = 'body{background-color: #ffffff;}'; $this->assertSame( $expected, $theme_json->get_stylesheet( array( 'styles' ), null, array( 'skip_root_layout_styles' => true ) ) ); } @@ -3579,7 +3579,7 @@ public function test_get_styles_for_block_with_padding_aware_alignments() { 'selector' => 'body', ); - $expected = ':where(body) { margin: 0; }.wp-site-blocks { padding-top: var(--wp--style--root--padding-top); padding-bottom: var(--wp--style--root--padding-bottom); }.has-global-padding { padding-right: var(--wp--style--root--padding-right); padding-left: var(--wp--style--root--padding-left); }.has-global-padding > .alignfull { margin-right: calc(var(--wp--style--root--padding-right) * -1); margin-left: calc(var(--wp--style--root--padding-left) * -1); }.has-global-padding :where(:not(.alignfull.is-layout-flow) > .has-global-padding:not(.wp-block-block, .alignfull)) { padding-right: 0; padding-left: 0; }.has-global-padding :where(:not(.alignfull.is-layout-flow) > .has-global-padding:not(.wp-block-block, .alignfull)) > .alignfull { margin-left: 0; margin-right: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }:where(.is-layout-flex){gap: 0.5em;}:where(.is-layout-grid){gap: 0.5em;}.is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}.is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}.is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}.is-layout-constrained > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}.is-layout-constrained > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}.is-layout-constrained > .aligncenter{margin-left: auto !important;margin-right: auto !important;}.is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)){margin-left: auto !important;margin-right: auto !important;}body .is-layout-flex{display: flex;}.is-layout-flex{flex-wrap: wrap;align-items: center;}.is-layout-flex > :is(*, div){margin: 0;}body .is-layout-grid{display: grid;}.is-layout-grid > :is(*, div){margin: 0;}:root :where(body){--wp--style--root--padding-top: 10px;--wp--style--root--padding-right: 12px;--wp--style--root--padding-bottom: 10px;--wp--style--root--padding-left: 12px;}'; + $expected = ':where(body) { margin: 0; }.wp-site-blocks { padding-top: var(--wp--style--root--padding-top); padding-bottom: var(--wp--style--root--padding-bottom); }.has-global-padding { padding-right: var(--wp--style--root--padding-right); padding-left: var(--wp--style--root--padding-left); }.has-global-padding > .alignfull { margin-right: calc(var(--wp--style--root--padding-right) * -1); margin-left: calc(var(--wp--style--root--padding-left) * -1); }.has-global-padding :where(:not(.alignfull.is-layout-flow) > .has-global-padding:not(.wp-block-block, .alignfull)) { padding-right: 0; padding-left: 0; }.has-global-padding :where(:not(.alignfull.is-layout-flow) > .has-global-padding:not(.wp-block-block, .alignfull)) > .alignfull { margin-left: 0; margin-right: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }:where(.is-layout-flex){gap: 0.5em;}:where(.is-layout-grid){gap: 0.5em;}.is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}.is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}.is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}.is-layout-constrained > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}.is-layout-constrained > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}.is-layout-constrained > .aligncenter{margin-left: auto !important;margin-right: auto !important;}.is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)){margin-left: auto !important;margin-right: auto !important;}body .is-layout-flex{display: flex;}.is-layout-flex{flex-wrap: wrap;align-items: center;}.is-layout-flex > :is(*, div){margin: 0;}body .is-layout-grid{display: grid;}.is-layout-grid > :is(*, div){margin: 0;}body{--wp--style--root--padding-top: 10px;--wp--style--root--padding-right: 12px;--wp--style--root--padding-bottom: 10px;--wp--style--root--padding-left: 12px;}'; $root_rules = $theme_json->get_root_layout_rules( WP_Theme_JSON_Gutenberg::ROOT_BLOCK_SELECTOR, $metadata ); $style_rules = $theme_json->get_styles_for_block( $metadata ); $this->assertSame( $expected, $root_rules . $style_rules ); @@ -3607,7 +3607,7 @@ public function test_get_styles_for_block_without_padding_aware_alignments() { 'selector' => 'body', ); - $expected = static::$base_styles . ':root :where(body){padding-top: 10px;padding-right: 12px;padding-bottom: 10px;padding-left: 12px;}'; + $expected = static::$base_styles . 'body{padding-top: 10px;padding-right: 12px;padding-bottom: 10px;padding-left: 12px;}'; $root_rules = $theme_json->get_root_layout_rules( WP_Theme_JSON_Gutenberg::ROOT_BLOCK_SELECTOR, $metadata ); $style_rules = $theme_json->get_styles_for_block( $metadata ); $this->assertSame( $expected, $root_rules . $style_rules ); @@ -4782,7 +4782,7 @@ public function test_get_top_level_background_image_styles() { 'selector' => 'body', ); - $expected_styles = "html{min-height: calc(100% - var(--wp-admin--admin-bar--height, 0px));}:root :where(body){background-image: url('http://example.org/image.png');background-position: center center;background-repeat: no-repeat;background-size: contain;background-attachment: fixed;}"; + $expected_styles = "html{min-height: calc(100% - var(--wp-admin--admin-bar--height, 0px));}body{background-image: url('http://example.org/image.png');background-position: center center;background-repeat: no-repeat;background-size: contain;background-attachment: fixed;}"; $this->assertSame( $expected_styles, $theme_json->get_styles_for_block( $body_node ), 'Styles returned from "::get_styles_for_block()" with top-level background styles do not match expectations' ); $theme_json = new WP_Theme_JSON_Gutenberg( @@ -4800,7 +4800,7 @@ public function test_get_top_level_background_image_styles() { ) ); - $expected_styles = "html{min-height: calc(100% - var(--wp-admin--admin-bar--height, 0px));}:root :where(body){background-image: url('http://example.org/image.png');background-position: center center;background-repeat: no-repeat;background-size: contain;background-attachment: fixed;}"; + $expected_styles = "html{min-height: calc(100% - var(--wp-admin--admin-bar--height, 0px));}body{background-image: url('http://example.org/image.png');background-position: center center;background-repeat: no-repeat;background-size: contain;background-attachment: fixed;}"; $this->assertSame( $expected_styles, $theme_json->get_styles_for_block( $body_node ), 'Styles returned from "::get_styles_for_block()" with top-level background image as string type do not match expectations' ); } From dc41a6ee3e58fd9890a690a4514c2a1d415259ab Mon Sep 17 00:00:00 2001 From: George Mamadashvili Date: Fri, 19 Jul 2024 09:56:10 +0400 Subject: [PATCH 11/17] Navigation Submenu: Remove user permission checks (#63720) Co-authored-by: Mamaduka Co-authored-by: tyxla --- .../block-library/src/navigation-submenu/edit.js | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/packages/block-library/src/navigation-submenu/edit.js b/packages/block-library/src/navigation-submenu/edit.js index 4decc2e68ffbb..acc9510d0d3d3 100644 --- a/packages/block-library/src/navigation-submenu/edit.js +++ b/packages/block-library/src/navigation-submenu/edit.js @@ -29,7 +29,6 @@ import { import { isURL, prependHTTP } from '@wordpress/url'; import { useState, useEffect, useRef } from '@wordpress/element'; import { link as linkIcon, removeSubmenu } from '@wordpress/icons'; -import { useResourcePermissions } from '@wordpress/core-data'; import { speak } from '@wordpress/a11y'; import { createBlock } from '@wordpress/blocks'; import { useMergeRefs, usePrevious } from '@wordpress/compose'; @@ -134,7 +133,7 @@ export default function NavigationSubmenuEdit( { context, clientId, } ) { - const { label, type, url, description, rel, title } = attributes; + const { label, url, description, rel, title } = attributes; const { showSubmenuIcon, maxNestingLevel, openSubmenusOnClick } = context; @@ -154,9 +153,6 @@ export default function NavigationSubmenuEdit( { const itemLabelPlaceholder = __( 'Add text…' ); const ref = useRef(); - const pagesPermissions = useResourcePermissions( 'pages' ); - const postsPermissions = useResourcePermissions( 'posts' ); - const { parentCount, isParentOfSelectedBlock, @@ -264,13 +260,6 @@ export default function NavigationSubmenuEdit( { selection.addRange( range ); } - let userCanCreate = false; - if ( ! type || type === 'page' ) { - userCanCreate = pagesPermissions.canCreate; - } else if ( type === 'post' ) { - userCanCreate = postsPermissions.canCreate; - } - const { textColor, customTextColor, @@ -499,7 +488,6 @@ export default function NavigationSubmenuEdit( { } } } anchor={ popoverAnchor } - hasCreateSuggestion={ userCanCreate } onRemove={ () => { setAttributes( { url: '' } ); speak( __( 'Link removed.' ), 'assertive' ); From ed11e6fe975f335039362abc0c8bd2013f918be0 Mon Sep 17 00:00:00 2001 From: Marin Atanasov <8436925+tyxla@users.noreply.github.com> Date: Fri, 19 Jul 2024 09:12:36 +0300 Subject: [PATCH 12/17] Patterns: Render draggable only when enabled (#63715) Co-authored-by: tyxla Co-authored-by: Mamaduka --- .../components/inserter-draggable-blocks/index.js | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/packages/block-editor/src/components/inserter-draggable-blocks/index.js b/packages/block-editor/src/components/inserter-draggable-blocks/index.js index 7d20b5e53650b..5a63535be3d3c 100644 --- a/packages/block-editor/src/components/inserter-draggable-blocks/index.js +++ b/packages/block-editor/src/components/inserter-draggable-blocks/index.js @@ -43,6 +43,14 @@ const InserterDraggableBlocks = ( { useDispatch( blockEditorStore ) ); + if ( ! isEnabled ) { + return children( { + draggable: false, + onDragStart: undefined, + onDragEnd: undefined, + } ); + } + return ( { ( { onDraggableStart, onDraggableEnd } ) => { return children( { - draggable: isEnabled, - onDragStart: isEnabled ? onDraggableStart : undefined, - onDragEnd: isEnabled ? onDraggableEnd : undefined, + draggable: true, + onDragStart: onDraggableStart, + onDragEnd: onDraggableEnd, } ); } } From a2fb0fbf40b5556e23b5465ed4b8a859121fb376 Mon Sep 17 00:00:00 2001 From: Nik Tsekouras Date: Fri, 19 Jul 2024 09:13:50 +0300 Subject: [PATCH 13/17] Fix patterns sorting by `title` (#63710) Co-authored-by: ntsekouras Co-authored-by: youknowriad --- packages/edit-site/src/components/page-patterns/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/edit-site/src/components/page-patterns/index.js b/packages/edit-site/src/components/page-patterns/index.js index a1b4f2a0912de..27b75424e5f3b 100644 --- a/packages/edit-site/src/components/page-patterns/index.js +++ b/packages/edit-site/src/components/page-patterns/index.js @@ -294,6 +294,7 @@ export default function DataviewsPatterns() { { header: __( 'Title' ), id: 'title', + getValue: ( { item } ) => item.title?.raw || item.title, render: ( { item } ) => , enableHiding: false, }, From 5d4bf270bf0abf21bb0eee8f92ddd4f2b35ef299 Mon Sep 17 00:00:00 2001 From: Nik Tsekouras <ntsekouras@outlook.com> Date: Fri, 19 Jul 2024 09:14:10 +0300 Subject: [PATCH 14/17] Add post status icon in post summary (#63658) Co-authored-by: ntsekouras <ntsekouras@git.wordpress.org> Co-authored-by: jameskoster <jameskoster@git.wordpress.org> --- .../components/post-last-revision/index.js | 1 + .../src/components/post-panel-row/style.scss | 1 - .../src/components/post-status/index.js | 28 ++++++++++++------- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/packages/editor/src/components/post-last-revision/index.js b/packages/editor/src/components/post-last-revision/index.js index 73bcb7c0e026f..d0f94e26048d7 100644 --- a/packages/editor/src/components/post-last-revision/index.js +++ b/packages/editor/src/components/post-last-revision/index.js @@ -64,6 +64,7 @@ export function PrivatePostLastRevision() { className="editor-private-post-last-revision__button" text={ revisionsCount } variant="tertiary" + size="compact" /> </PostPanelRow> </PostLastRevisionCheck> diff --git a/packages/editor/src/components/post-panel-row/style.scss b/packages/editor/src/components/post-panel-row/style.scss index 53e0c645f6f06..f76c586850500 100644 --- a/packages/editor/src/components/post-panel-row/style.scss +++ b/packages/editor/src/components/post-panel-row/style.scss @@ -28,7 +28,6 @@ white-space: normal; text-wrap: balance; // Fallback for Safari. text-wrap: pretty; - height: auto; min-height: $button-size-compact; } diff --git a/packages/editor/src/components/post-status/index.js b/packages/editor/src/components/post-status/index.js index aacb933e1864e..11b51bca80aa7 100644 --- a/packages/editor/src/components/post-status/index.js +++ b/packages/editor/src/components/post-status/index.js @@ -16,6 +16,13 @@ import { useState, useMemo } from '@wordpress/element'; import { store as coreStore } from '@wordpress/core-data'; import { __experimentalInspectorPopoverHeader as InspectorPopoverHeader } from '@wordpress/block-editor'; import { useInstanceId } from '@wordpress/compose'; +import { + drafts, + published, + scheduled, + pending, + notAllowed, +} from '@wordpress/icons'; /** * Internal dependencies @@ -31,13 +38,13 @@ import PostSticky from '../post-sticky'; import { PrivatePostSchedule } from '../post-schedule'; import { store as editorStore } from '../../store'; -const labels = { - 'auto-draft': __( 'Draft' ), - draft: __( 'Draft' ), - pending: __( 'Pending' ), - private: __( 'Private' ), - future: __( 'Scheduled' ), - publish: __( 'Published' ), +const postStatusesInfo = { + 'auto-draft': { label: __( 'Draft' ), icon: drafts }, + draft: { label: __( 'Draft' ), icon: drafts }, + pending: { label: __( 'Pending' ), icon: pending }, + private: { label: __( 'Private' ), icon: notAllowed }, + future: { label: __( 'Scheduled' ), icon: scheduled }, + publish: { label: __( 'Published' ), icon: published }, }; export const STATUS_OPTIONS = [ @@ -200,13 +207,14 @@ export default function PostStatus() { variant="tertiary" size="compact" onClick={ onToggle } + icon={ postStatusesInfo[ status ]?.icon } aria-label={ sprintf( // translators: %s: Current post status. __( 'Change post status: %s' ), - labels[ status ] + postStatusesInfo[ status ]?.label ) } > - { labels[ status ] } + { postStatusesInfo[ status ]?.label } </Button> ) } renderContent={ ( { onClose } ) => ( @@ -290,7 +298,7 @@ export default function PostStatus() { /> ) : ( <div className="editor-post-status is-read-only"> - { labels[ status ] } + { postStatusesInfo[ status ]?.label } </div> ) } </PostPanelRow> From 6b0b4e4d6e660f208bb73c92570e7b8bb7898145 Mon Sep 17 00:00:00 2001 From: Nik Tsekouras <ntsekouras@outlook.com> Date: Fri, 19 Jul 2024 11:30:22 +0300 Subject: [PATCH 15/17] DataViews: Fix pattens list selection (#63733) Co-authored-by: ntsekouras <ntsekouras@git.wordpress.org> Co-authored-by: talldan <talldanwp@git.wordpress.org> --- packages/edit-site/src/components/page-patterns/index.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/edit-site/src/components/page-patterns/index.js b/packages/edit-site/src/components/page-patterns/index.js index 27b75424e5f3b..65e79b406cf55 100644 --- a/packages/edit-site/src/components/page-patterns/index.js +++ b/packages/edit-site/src/components/page-patterns/index.js @@ -252,6 +252,7 @@ export default function DataviewsPatterns() { const { params: { postType, categoryId: categoryIdFromURL }, } = useLocation(); + const [ selection, setSelection ] = useState( [] ); const type = postType || PATTERN_TYPES.user; const categoryId = categoryIdFromURL || PATTERN_DEFAULT_CATEGORY; const [ view, setView ] = useState( DEFAULT_VIEW ); @@ -409,6 +410,8 @@ export default function DataviewsPatterns() { isLoading={ isResolving } view={ view } onChangeView={ setView } + selection={ selection } + onChangeSelection={ setSelection } defaultLayouts={ defaultLayouts } /> </Page> From 6a466a098650bb46154d0a293ae4bf0b88a1d3ef Mon Sep 17 00:00:00 2001 From: Ben Dwyer <ben@scruffian.com> Date: Fri, 19 Jul 2024 10:01:38 +0100 Subject: [PATCH 16/17] Zoom Out: Only show the inserters when a block is selected or hovered (#63668) * Zoom Out: Only show the inserters when a block is selected or hovered * Correct logic for rendering the zoom out inserters We want to show the inserters on hover, even if there is no selection. * Update shouldRenderInsertionPoint condition * Make the inserters always present and just toggle visibility * Update docs/reference-guides/data/data-core-block-editor.md * Update packages/block-editor/src/components/block-tools/zoom-out-mode-inserter-button.js * Update packages/block-editor/src/components/block-tools/zoom-out-mode-inserter-button.js * Update packages/block-editor/src/components/block-tools/zoom-out-mode-inserter-button.js * Update packages/block-editor/src/components/block-tools/zoom-out-mode-inserter-button.js * Update packages/block-editor/src/store/reducer.js * Update packages/block-editor/src/store/reducer.js * Update packages/block-editor/src/store/selectors.js * fix the property name * Reduce number of select calls by lifting useSelect calls to ZoomOutModeInserters --------- Co-authored-by: Jerry Jones <jones.jeremydavid@gmail.com> Co-authored-by: scruffian <scruffian@git.wordpress.org> Co-authored-by: jeryj <jeryj@git.wordpress.org> --- .../data/data-core-block-editor.md | 24 +++++++ .../block-list/use-block-props/index.js | 2 +- .../use-block-props/use-is-hovered.js | 37 +++++++---- .../src/components/block-tools/style.scss | 8 +++ .../zoom-out-mode-inserter-button.js | 47 ++++++++++++++ .../block-tools/zoom-out-mode-inserters.js | 63 ++++++++++++------- packages/block-editor/src/store/actions.js | 15 +++++ packages/block-editor/src/store/reducer.js | 18 ++++++ packages/block-editor/src/store/selectors.js | 10 +++ 9 files changed, 191 insertions(+), 33 deletions(-) create mode 100644 packages/block-editor/src/components/block-tools/zoom-out-mode-inserter-button.js diff --git a/docs/reference-guides/data/data-core-block-editor.md b/docs/reference-guides/data/data-core-block-editor.md index 4b66ad9eb6cb4..7eed5c8741288 100644 --- a/docs/reference-guides/data/data-core-block-editor.md +++ b/docs/reference-guides/data/data-core-block-editor.md @@ -562,6 +562,18 @@ _Returns_ - `number`: Number of blocks in the post, or number of blocks with name equal to blockName. +### getHoveredBlockClientId + +Returns the currently hovered block. + +_Parameters_ + +- _state_ `Object`: Global application state. + +_Returns_ + +- `Object`: Client Id of the hovered block. + ### getInserterItems Determines the items that appear in the inserter. Includes both static items (e.g. a regular block type) and dynamic items (e.g. a reusable block). @@ -1257,6 +1269,18 @@ _Parameters_ Action that hides the insertion point. +### hoverBlock + +Returns an action object used in signalling that the block with the specified client ID has been hovered. + +_Parameters_ + +- _clientId_ `string`: Block client ID. + +_Returns_ + +- `Object`: Action object. + ### insertAfterBlock Action that inserts a default block after a given block. diff --git a/packages/block-editor/src/components/block-list/use-block-props/index.js b/packages/block-editor/src/components/block-list/use-block-props/index.js index 64e40559bb473..6c44aa5c5d970 100644 --- a/packages/block-editor/src/components/block-list/use-block-props/index.js +++ b/packages/block-editor/src/components/block-list/use-block-props/index.js @@ -115,7 +115,7 @@ export function useBlockProps( props = {}, { __unstableIsHtml } = {} ) { useFocusHandler( clientId ), useEventHandlers( { clientId, isSelected } ), useNavModeExit( clientId ), - useIsHovered(), + useIsHovered( { clientId } ), useIntersectionObserver(), useMovingAnimation( { triggerAnimationOnChange: index, clientId } ), useDisabled( { isDisabled: ! hasOverlay } ), diff --git a/packages/block-editor/src/components/block-list/use-block-props/use-is-hovered.js b/packages/block-editor/src/components/block-list/use-block-props/use-is-hovered.js index 518ed583933ac..7c4b4aae8a70a 100644 --- a/packages/block-editor/src/components/block-list/use-block-props/use-is-hovered.js +++ b/packages/block-editor/src/components/block-list/use-block-props/use-is-hovered.js @@ -2,23 +2,37 @@ * WordPress dependencies */ import { useRefEffect } from '@wordpress/compose'; +import { useDispatch } from '@wordpress/data'; -function listener( event ) { - if ( event.defaultPrevented ) { - return; - } - - const action = event.type === 'mouseover' ? 'add' : 'remove'; - - event.preventDefault(); - event.currentTarget.classList[ action ]( 'is-hovered' ); -} +/** + * Internal dependencies + */ +import { store as blockEditorStore } from '../../../store'; /* * Adds `is-hovered` class when the block is hovered and in navigation or * outline mode. */ -export function useIsHovered() { +export function useIsHovered( { clientId } ) { + const { hoverBlock } = useDispatch( blockEditorStore ); + + function listener( event ) { + if ( event.defaultPrevented ) { + return; + } + + const action = event.type === 'mouseover' ? 'add' : 'remove'; + + event.preventDefault(); + event.currentTarget.classList[ action ]( 'is-hovered' ); + + if ( action === 'add' ) { + hoverBlock( clientId ); + } else { + hoverBlock( null ); + } + } + return useRefEffect( ( node ) => { node.addEventListener( 'mouseout', listener ); node.addEventListener( 'mouseover', listener ); @@ -29,6 +43,7 @@ export function useIsHovered() { // Remove class in case it lingers. node.classList.remove( 'is-hovered' ); + hoverBlock( null ); }; }, [] ); } diff --git a/packages/block-editor/src/components/block-tools/style.scss b/packages/block-editor/src/components/block-tools/style.scss index 20c0ab4104204..6bf1f91cb0868 100644 --- a/packages/block-editor/src/components/block-tools/style.scss +++ b/packages/block-editor/src/components/block-tools/style.scss @@ -285,3 +285,11 @@ border: none; } } + +.block-editor-block-tools__zoom-out-mode-inserter-button { + visibility: hidden; + + &.is-visible { + visibility: visible; + } +} diff --git a/packages/block-editor/src/components/block-tools/zoom-out-mode-inserter-button.js b/packages/block-editor/src/components/block-tools/zoom-out-mode-inserter-button.js new file mode 100644 index 0000000000000..8ea80a5383013 --- /dev/null +++ b/packages/block-editor/src/components/block-tools/zoom-out-mode-inserter-button.js @@ -0,0 +1,47 @@ +/** + * External dependencies + */ +import clsx from 'clsx'; + +/** + * WordPress dependencies + */ +import { useState } from '@wordpress/element'; +import { Button } from '@wordpress/components'; +import { plus } from '@wordpress/icons'; +import { _x } from '@wordpress/i18n'; + +function ZoomOutModeInserterButton( { isVisible, onClick } ) { + const [ + zoomOutModeInserterButtonHovered, + setZoomOutModeInserterButtonHovered, + ] = useState( false ); + + return ( + <Button + variant="primary" + icon={ plus } + size="compact" + className={ clsx( + 'block-editor-button-pattern-inserter__button', + 'block-editor-block-tools__zoom-out-mode-inserter-button', + { + 'is-visible': isVisible || zoomOutModeInserterButtonHovered, + } + ) } + onClick={ onClick } + onMouseOver={ () => { + setZoomOutModeInserterButtonHovered( true ); + } } + onMouseOut={ () => { + setZoomOutModeInserterButtonHovered( false ); + } } + label={ _x( + 'Add pattern', + 'Generic label for pattern inserter button' + ) } + /> + ); +} + +export default ZoomOutModeInserterButton; diff --git a/packages/block-editor/src/components/block-tools/zoom-out-mode-inserters.js b/packages/block-editor/src/components/block-tools/zoom-out-mode-inserters.js index b64992cec4466..5f5b0401b512e 100644 --- a/packages/block-editor/src/components/block-tools/zoom-out-mode-inserters.js +++ b/packages/block-editor/src/components/block-tools/zoom-out-mode-inserters.js @@ -3,28 +3,33 @@ */ import { useSelect } from '@wordpress/data'; import { useEffect, useRef, useState } from '@wordpress/element'; -import { Button } from '@wordpress/components'; -import { plus } from '@wordpress/icons'; -import { _x } from '@wordpress/i18n'; /** * Internal dependencies */ import BlockPopoverInbetween from '../block-popover/inbetween'; +import ZoomOutModeInserterButton from './zoom-out-mode-inserter-button'; import { store as blockEditorStore } from '../../store'; import { unlock } from '../../lock-unlock'; function ZoomOutModeInserters() { const [ isReady, setIsReady ] = useState( false ); const { + hasSelection, blockOrder, - sectionRootClientId, insertionPoint, setInserterIsOpened, - hasSelection, + sectionRootClientId, + selectedBlockClientId, + hoveredBlockClientId, } = useSelect( ( select ) => { - const { getSettings, getBlockOrder, getSelectionStart } = - select( blockEditorStore ); + const { + getSettings, + getBlockOrder, + getSelectionStart, + getSelectedBlockClientId, + getHoveredBlockClientId, + } = select( blockEditorStore ); const { sectionRootClientId: root } = unlock( getSettings() ); // To do: move ZoomOutModeInserters to core/editor. // Or we perhaps we should move the insertion point state to the @@ -40,6 +45,8 @@ function ZoomOutModeInserters() { sectionRootClientId: root, setInserterIsOpened: getSettings().__experimentalSetIsInserterOpened, + selectedBlockClientId: getSelectedBlockClientId(), + hoveredBlockClientId: getHoveredBlockClientId(), }; }, [] ); @@ -64,18 +71,39 @@ function ZoomOutModeInserters() { }; }, [] ); - if ( ! isReady || ! hasSelection ) { + if ( ! isReady ) { return null; } return [ undefined, ...blockOrder ].map( ( clientId, index ) => { + const shouldRenderInserter = insertionPoint.insertionIndex !== index; + + const shouldRenderInsertionPoint = + insertionPoint.insertionIndex === index; + + if ( ! shouldRenderInserter && ! shouldRenderInsertionPoint ) { + return null; + } + + const previousClientId = clientId; + const nextClientId = blockOrder[ index ]; + + const isSelected = + hasSelection && + ( selectedBlockClientId === previousClientId || + selectedBlockClientId === nextClientId ); + + const isHovered = + hoveredBlockClientId === previousClientId || + hoveredBlockClientId === nextClientId; + return ( <BlockPopoverInbetween key={ index } - previousClientId={ clientId } - nextClientId={ blockOrder[ index ] } + previousClientId={ previousClientId } + nextClientId={ nextClientId } > - { insertionPoint.insertionIndex === index && ( + { shouldRenderInsertionPoint && ( <div style={ { borderRadius: '0', @@ -87,12 +115,9 @@ function ZoomOutModeInserters() { className="block-editor-block-list__insertion-point-indicator" /> ) } - { insertionPoint.insertionIndex !== index && ( - <Button - variant="primary" - icon={ plus } - size="compact" - className="block-editor-button-pattern-inserter__button" + { shouldRenderInserter && ( + <ZoomOutModeInserterButton + isVisible={ isSelected || isHovered } onClick={ () => { setInserterIsOpened( { rootClientId: sectionRootClientId, @@ -101,10 +126,6 @@ function ZoomOutModeInserters() { category: 'all', } ); } } - label={ _x( - 'Add pattern', - 'Generic label for pattern inserter button' - ) } /> ) } </BlockPopoverInbetween> diff --git a/packages/block-editor/src/store/actions.js b/packages/block-editor/src/store/actions.js index 170c5192f3bee..f7da8fa14b382 100644 --- a/packages/block-editor/src/store/actions.js +++ b/packages/block-editor/src/store/actions.js @@ -213,6 +213,21 @@ export function selectBlock( clientId, initialPosition = 0 ) { }; } +/** + * Returns an action object used in signalling that the block with the + * specified client ID has been hovered. + * + * @param {string} clientId Block client ID. + * + * @return {Object} Action object. + */ +export function hoverBlock( clientId ) { + return { + type: 'HOVER_BLOCK', + clientId, + }; +} + /** * Yields action objects used in signalling that the block preceding the given * clientId (or optionally, its first parent from bottom to top) diff --git a/packages/block-editor/src/store/reducer.js b/packages/block-editor/src/store/reducer.js index 7c83887876919..cd4569c45e580 100644 --- a/packages/block-editor/src/store/reducer.js +++ b/packages/block-editor/src/store/reducer.js @@ -2068,6 +2068,23 @@ export function lastFocus( state = false, action ) { return state; } +/** + * Reducer setting currently hovered block. + * + * @param {boolean} state Current state. + * @param {Object} action Dispatched action. + * + * @return {boolean} Updated state. + */ +export function hoveredBlockClientId( state = false, action ) { + switch ( action.type ) { + case 'HOVER_BLOCK': + return action.clientId; + } + + return state; +} + const combinedReducers = combineReducers( { blocks, isDragging, @@ -2100,6 +2117,7 @@ const combinedReducers = combineReducers( { blockRemovalRules, openedBlockSettingsMenu, registeredInserterMediaCategories, + hoveredBlockClientId, } ); function withAutomaticChangeReset( reducer ) { diff --git a/packages/block-editor/src/store/selectors.js b/packages/block-editor/src/store/selectors.js index d78d75e4210c8..d6d09b5910611 100644 --- a/packages/block-editor/src/store/selectors.js +++ b/packages/block-editor/src/store/selectors.js @@ -2809,6 +2809,16 @@ export function isBlockVisible( state, clientId ) { return state.blockVisibility?.[ clientId ] ?? true; } +/** + * Returns the currently hovered block. + * + * @param {Object} state Global application state. + * @return {Object} Client Id of the hovered block. + */ +export function getHoveredBlockClientId( state ) { + return state.hoveredBlockClientId; +} + /** * Returns the list of all hidden blocks. * From e685f6871a2f2103fd7bdf0b376c7c1557b11cd4 Mon Sep 17 00:00:00 2001 From: Jeremy Herve <jeremy@jeremy.hu> Date: Fri, 19 Jul 2024 11:18:49 +0200 Subject: [PATCH 17/17] Social Links: update Facebook's color to match brand guidelines (#60424) See the guidelines defined here: https://about.meta.com/brand/resources/facebook/logo/ ---- Co-authored-by: jeherve <jeherve@git.wordpress.org> Co-authored-by: ankitguptaindia <ankit-k-gupta@git.wordpress.org> Co-authored-by: talldan <talldanwp@git.wordpress.org> --- packages/block-library/src/social-link/socials-with-bg.scss | 2 +- packages/block-library/src/social-link/socials-without-bg.scss | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/block-library/src/social-link/socials-with-bg.scss b/packages/block-library/src/social-link/socials-with-bg.scss index 907e6bb98023d..35420fc624c0e 100644 --- a/packages/block-library/src/social-link/socials-with-bg.scss +++ b/packages/block-library/src/social-link/socials-with-bg.scss @@ -49,7 +49,7 @@ } .wp-social-link-facebook { - background-color: #1778f2; + background-color: #0866ff; color: #fff; } diff --git a/packages/block-library/src/social-link/socials-without-bg.scss b/packages/block-library/src/social-link/socials-without-bg.scss index 371310628c9b2..24538b29824b1 100644 --- a/packages/block-library/src/social-link/socials-without-bg.scss +++ b/packages/block-library/src/social-link/socials-without-bg.scss @@ -35,7 +35,7 @@ } .wp-social-link-facebook { - color: #1778f2; + color: #0866ff; } .wp-social-link-fivehundredpx {