diff --git a/packages/block-editor/CHANGELOG.md b/packages/block-editor/CHANGELOG.md index 7dabc36971ff68..2f36590f52fec4 100644 --- a/packages/block-editor/CHANGELOG.md +++ b/packages/block-editor/CHANGELOG.md @@ -12,6 +12,7 @@ - State control badges: migrate from the private `@wordpress/components` `Badge` to `@wordpress/ui` `Badge` ([#82608](https://github.com/WordPress/gutenberg/pull/82608)). - Use the `inertValue` helper to set `inert` attributes, for better React 18/19 compatibility ([#83871](https://github.com/WordPress/gutenberg/pull/83871)). - `LinkControl`: Add a `transformSuggestions` prop, so a consumer can filter, order or add to the search suggestions before they are shown ([#83652](https://github.com/WordPress/gutenberg/pull/83652)). +- Block inspector: Move the Additional CSS and Additional CSS class(es) controls from the Advanced panel in the Settings tab to a new "Additional styles" panel in the Styles tab, through a new `additional-styles` group for `InspectorControls`. Additional styles controls count toward Styles tab availability. When tabs are disabled or only one tab is available, the Additional styles and Advanced panels appear in the combined inspector ([#83753](https://github.com/WordPress/gutenberg/pull/83753)). ### Bug Fixes diff --git a/packages/block-editor/src/components/block-inspector/index.jsx b/packages/block-editor/src/components/block-inspector/index.jsx index faf41677e5bda0..19c236c1d20981 100644 --- a/packages/block-editor/src/components/block-inspector/index.jsx +++ b/packages/block-editor/src/components/block-inspector/index.jsx @@ -29,6 +29,7 @@ import { SectionStyleControls } from '../inspector-controls-tabs/styles-tab'; import useInspectorControlsTabs from '../inspector-controls-tabs/use-inspector-controls-tabs'; import InspectorControlsLastItem from '../inspector-controls/last-item'; import AdvancedControls from '../inspector-controls-tabs/advanced-controls-panel'; +import AdditionalStyles from '../inspector-controls-tabs/additional-styles-panel'; import PositionControls from '../inspector-controls-tabs/position-controls-panel'; import useBlockInspectorAnimationSettings from './useBlockInspectorAnimationSettings'; import { BlockStateBadges, BlockStatesControl } from '../../hooks/states'; @@ -82,6 +83,9 @@ function StyleInspectorSlots( { ) } { showAdvancedControls && (
+ { /* There are no tabs to divide the advanced tools + between, so each appears as its own panel. */ } +
) } diff --git a/packages/block-editor/src/components/block-inspector/style.scss b/packages/block-editor/src/components/block-inspector/style.scss index 109a10cb312e8d..cd0a2bccd37d1c 100644 --- a/packages/block-editor/src/components/block-inspector/style.scss +++ b/packages/block-editor/src/components/block-inspector/style.scss @@ -40,6 +40,14 @@ // Ensures this PanelBody is treated like the ToolsPanel, removing double borders. margin-top: -$border-width; } + + // The Advanced panel can hold two slot groups at once, the settings tools + // and the styling tools. Each slot renders its own container, so the + // margin between controls above stops at the last control of a container. + // Restore the gap where two containers meet. + .block-editor-block-inspector__advanced > div + div { + margin-top: $grid-unit-20; + } } .block-editor-block-inspector__no-blocks, diff --git a/packages/block-editor/src/components/global-styles/advanced-panel.jsx b/packages/block-editor/src/components/global-styles/advanced-panel.jsx index 6c55d26e715d13..e67e0050aa4e07 100644 --- a/packages/block-editor/src/components/global-styles/advanced-panel.jsx +++ b/packages/block-editor/src/components/global-styles/advanced-panel.jsx @@ -92,7 +92,7 @@ export default function AdvancedPanel( { ) } handleOnChange( newValue ) } onBlur={ handleOnBlur } diff --git a/packages/block-editor/src/components/inspector-controls-tabs/additional-styles-panel.jsx b/packages/block-editor/src/components/inspector-controls-tabs/additional-styles-panel.jsx new file mode 100644 index 00000000000000..6a441f8433ea32 --- /dev/null +++ b/packages/block-editor/src/components/inspector-controls-tabs/additional-styles-panel.jsx @@ -0,0 +1,37 @@ +import { + PanelBody, + __experimentalUseSlotFills as useSlotFills, +} from '@wordpress/components'; +import { __ } from '@wordpress/i18n'; +import { default as InspectorControls } from '../inspector-controls'; +import groups from '../inspector-controls/groups'; + +/** + * Renders the "Additional styles" panel for the block inspector. + * + * The panel holds advanced styling controls such as Additional CSS, which live + * in the `additional-styles` group. It renders nothing when the group has no + * fills. + * + * @param {Object} props Component props. + * @param {boolean} [props.initialOpen] Whether the panel starts expanded. + */ +const AdditionalStyles = ( { initialOpen = false } ) => { + const fills = useSlotFills( groups[ 'additional-styles' ].name ); + + if ( ! fills?.length ) { + return null; + } + + return ( + + + + ); +}; + +export default AdditionalStyles; diff --git a/packages/block-editor/src/components/inspector-controls-tabs/advanced-controls-panel.jsx b/packages/block-editor/src/components/inspector-controls-tabs/advanced-controls-panel.jsx index 7dfd6930e8c24a..f192f4130bb748 100644 --- a/packages/block-editor/src/components/inspector-controls-tabs/advanced-controls-panel.jsx +++ b/packages/block-editor/src/components/inspector-controls-tabs/advanced-controls-panel.jsx @@ -9,6 +9,16 @@ import { } from '../inspector-controls'; import { PrivateInspectorControlsAllowedBlocks } from '../inspector-controls/groups'; +/** + * Renders the "Advanced" panel for the block inspector. + * + * The panel holds advanced settings tools such as the HTML anchor, from the + * `advanced` group, alongside the private allowed-blocks control. It renders + * nothing when neither has fills. + * + * @param {Object} props Component props. + * @param {boolean} [props.initialOpen] Whether the panel starts expanded. + */ const AdvancedControls = ( { initialOpen = false } ) => { const fills = useSlotFills( InspectorAdvancedControls.slotName ); const privateFills = useSlotFills( diff --git a/packages/block-editor/src/components/inspector-controls-tabs/index.jsx b/packages/block-editor/src/components/inspector-controls-tabs/index.jsx index c0d15b7d3cfd0d..ac6868756290ec 100644 --- a/packages/block-editor/src/components/inspector-controls-tabs/index.jsx +++ b/packages/block-editor/src/components/inspector-controls-tabs/index.jsx @@ -203,6 +203,7 @@ export default function InspectorControlsTabs( { hasBlockStyles={ hasBlockStyles } isSectionBlock={ isSectionBlock } contentClientIds={ contentClientIds } + showAdditionalStyles={ !! blockName } /> diff --git a/packages/block-editor/src/components/inspector-controls-tabs/styles-tab.jsx b/packages/block-editor/src/components/inspector-controls-tabs/styles-tab.jsx index ccd99f6837de60..e9e239d911c21e 100644 --- a/packages/block-editor/src/components/inspector-controls-tabs/styles-tab.jsx +++ b/packages/block-editor/src/components/inspector-controls-tabs/styles-tab.jsx @@ -1,6 +1,7 @@ import { __ } from '@wordpress/i18n'; import { useDispatch, useSelect } from '@wordpress/data'; import { useMemo } from '@wordpress/element'; +import AdditionalStyles from './additional-styles-panel'; import BlockStyles from '../block-styles'; import InspectorControls from '../inspector-controls'; import PositionControls from './position-controls-panel'; @@ -101,6 +102,7 @@ const StylesTab = ( { hasBlockStyles, isSectionBlock, contentClientIds, + showAdditionalStyles = false, } ) => { return ( <> @@ -156,6 +158,13 @@ const StylesTab = ( { ) } + { /* Section blocks are excluded from the panels above but still + expose additional styling tools such as Additional CSS. */ } + { showAdditionalStyles && ( +
+ +
+ ) } ); }; diff --git a/packages/block-editor/src/components/inspector-controls-tabs/test/advanced-panels.jsdom.test.tsx b/packages/block-editor/src/components/inspector-controls-tabs/test/advanced-panels.jsdom.test.tsx new file mode 100644 index 00000000000000..4d29c4a8eb50e5 --- /dev/null +++ b/packages/block-editor/src/components/inspector-controls-tabs/test/advanced-panels.jsdom.test.tsx @@ -0,0 +1,113 @@ +import { describe, expect, it } from 'vitest'; +import { render, screen } from '@testing-library/react'; +import { SlotFillProvider } from '@wordpress/components'; +import AdvancedControls from '../advanced-controls-panel'; +import AdditionalStyles from '../additional-styles-panel'; +import groups from '../../inspector-controls/groups'; + +// The `InspectorControls` fill component is bypassed in favour of the +// underlying group fills, so that the panels can be exercised without a +// selected block and its editing mode. +const AdvancedFill = groups.advanced.Fill; +const AdditionalStylesFill = groups[ 'additional-styles' ].Fill; + +describe( 'AdvancedControls', () => { + it( 'renders nothing when the advanced group has no fills', () => { + render( + + + + ); + + expect( + screen.queryByRole( 'button', { name: 'Advanced' } ) + ).not.toBeInTheDocument(); + } ); + + it( 'renders the advanced group fills', () => { + render( + + + HTML anchor + + + + ); + + expect( + screen.getByRole( 'button', { name: 'Advanced' } ) + ).toBeVisible(); + expect( screen.getByText( 'HTML anchor' ) ).toBeVisible(); + } ); + + it( 'renders nothing when only the additional-styles group has fills', () => { + render( + + + Additional CSS + + + + ); + + expect( + screen.queryByRole( 'button', { name: 'Advanced' } ) + ).not.toBeInTheDocument(); + } ); +} ); + +describe( 'AdditionalStyles', () => { + it( 'renders nothing when the additional-styles group has no fills', () => { + render( + + + + ); + + expect( + screen.queryByRole( 'button', { name: 'Additional styles' } ) + ).not.toBeInTheDocument(); + } ); + + it( 'renders the additional-styles group fills', () => { + render( + + + Additional CSS + + + + ); + + expect( + screen.getByRole( 'button', { name: 'Additional styles' } ) + ).toBeVisible(); + expect( screen.getByText( 'Additional CSS' ) ).toBeVisible(); + } ); +} ); + +describe( 'Advanced and Additional styles together', () => { + it( 'renders as two separate panels', () => { + render( + + + HTML anchor + + + Additional CSS + + + + + ); + + expect( + screen.getByRole( 'button', { name: 'Additional styles' } ) + ).toBeVisible(); + expect( + screen.getByRole( 'button', { name: 'Advanced' } ) + ).toBeVisible(); + expect( screen.getByText( 'Additional CSS' ) ).toBeVisible(); + expect( screen.getByText( 'HTML anchor' ) ).toBeVisible(); + } ); +} ); diff --git a/packages/block-editor/src/components/inspector-controls-tabs/test/use-inspector-controls-tabs.jsdom.test.tsx b/packages/block-editor/src/components/inspector-controls-tabs/test/use-inspector-controls-tabs.jsdom.test.tsx index 2daf9805201ff0..2f16bd85f1de9d 100644 --- a/packages/block-editor/src/components/inspector-controls-tabs/test/use-inspector-controls-tabs.jsdom.test.tsx +++ b/packages/block-editor/src/components/inspector-controls-tabs/test/use-inspector-controls-tabs.jsdom.test.tsx @@ -19,6 +19,41 @@ vi.mock( import( '@wordpress/data' ), async ( importOriginal ) => { } ); describe( 'useInspectorControlsTabs', () => { + it( 'includes Styles when Additional styles is the only group with controls', () => { + const AdditionalStylesFill = groups[ 'additional-styles' ].Fill; + const { result } = renderHook( + () => useInspectorControlsTabs( 'test/block', [], false, false ), + { + wrapper: ( { children }: { children: ReactNode } ) => ( + + CSS + { children } + + ), + } + ); + + expect( result.current ).toEqual( [ TAB_STYLES ] ); + } ); + + it( 'keeps Additional styles in Styles without adding Settings alongside List View', () => { + const AdditionalStylesFill = groups[ 'additional-styles' ].Fill; + const { result } = renderHook( + () => useInspectorControlsTabs( 'test/block', [], false, false ), + { + wrapper: ( { children }: { children: ReactNode } ) => ( + + List View + CSS + { children } + + ), + } + ); + + expect( result.current ).toEqual( [ TAB_LIST_VIEW, TAB_STYLES ] ); + } ); + it( 'includes Settings when Allowed blocks is the only settings control', () => { const { result } = renderHook( () => diff --git a/packages/block-editor/src/components/inspector-controls-tabs/use-inspector-controls-tabs.js b/packages/block-editor/src/components/inspector-controls-tabs/use-inspector-controls-tabs.js index 8ee421f14ecf04..7607ea113cc4f6 100644 --- a/packages/block-editor/src/components/inspector-controls-tabs/use-inspector-controls-tabs.js +++ b/packages/block-editor/src/components/inspector-controls-tabs/use-inspector-controls-tabs.js @@ -31,6 +31,7 @@ export default function useInspectorControlsTabs( ) { const tabs = []; const { + 'additional-styles': additionalStylesGroup, bindings: bindingsGroup, border: borderGroup, color: colorGroup, @@ -56,6 +57,7 @@ export default function useInspectorControlsTabs( // Styles Tab: Add this tab if there are any fills for block supports // e.g. border, color, spacing, typography, etc. const styleFills = [ + ...( useSlotFills( additionalStylesGroup.name ) || [] ), ...( useSlotFills( borderGroup.name ) || [] ), ...( useSlotFills( colorGroup.name ) || [] ), ...( useSlotFills( layoutGroup.name ) || [] ), @@ -67,6 +69,16 @@ export default function useInspectorControlsTabs( ]; const hasStyleFills = styleFills.length; + const { tabSettings, isPreviewMode } = useSelect( ( select ) => { + const settings = select( blockEditorStore ).getSettings(); + return { + tabSettings: settings.blockInspectorTabs, + isPreviewMode: settings.isPreviewMode, + }; + }, [] ); + + const hasStylesTab = ! isPreviewMode && ( hasBlockStyles || hasStyleFills ); + // Settings Tab: If we don't have multiple tabs to display // (i.e. both list view and styles), check only the default // InspectorControls slots. If we have multiple tabs, we'll need to check @@ -106,15 +118,7 @@ export default function useInspectorControlsTabs( tabs.push( TAB_SETTINGS ); } - const { tabSettings, isPreviewMode } = useSelect( ( select ) => { - const settings = select( blockEditorStore ).getSettings(); - return { - tabSettings: settings.blockInspectorTabs, - isPreviewMode: settings.isPreviewMode, - }; - }, [] ); - - if ( ! isPreviewMode && ( hasBlockStyles || hasStyleFills ) ) { + if ( hasStylesTab ) { tabs.push( TAB_STYLES ); } diff --git a/packages/block-editor/src/components/inspector-controls/groups.js b/packages/block-editor/src/components/inspector-controls/groups.js index 9dbdc41607a460..4d893924993728 100644 --- a/packages/block-editor/src/components/inspector-controls/groups.js +++ b/packages/block-editor/src/components/inspector-controls/groups.js @@ -2,6 +2,9 @@ import { createSlotFill } from '@wordpress/components'; const InspectorControlsDefault = createSlotFill( 'InspectorControls' ); const InspectorControlsAdvanced = createSlotFill( 'InspectorAdvancedControls' ); +const InspectorControlsAdditionalStyles = createSlotFill( + 'InspectorControlsAdditionalStyles' +); const InspectorControlsBindings = createSlotFill( 'InspectorControlsBindings' ); const InspectorControlsBackground = createSlotFill( 'InspectorControlsBackground' @@ -27,6 +30,7 @@ const InspectorControlsContent = createSlotFill( 'InspectorControlsContent' ); const groups = { default: InspectorControlsDefault, advanced: InspectorControlsAdvanced, + 'additional-styles': InspectorControlsAdditionalStyles, background: InspectorControlsBackground, bindings: InspectorControlsBindings, border: InspectorControlsBorder, diff --git a/packages/block-editor/src/hooks/custom-class-name.jsx b/packages/block-editor/src/hooks/custom-class-name.jsx index db636379ec87f8..b016bccabd9ce0 100644 --- a/packages/block-editor/src/hooks/custom-class-name.jsx +++ b/packages/block-editor/src/hooks/custom-class-name.jsx @@ -34,10 +34,10 @@ function CustomClassNameControlsPure( { className, setAttributes } ) { } return ( - + { setAttributes( { diff --git a/packages/block-editor/src/hooks/custom-css.jsx b/packages/block-editor/src/hooks/custom-css.jsx index 0cebf5bdc5654e..6aea23f4e73531 100644 --- a/packages/block-editor/src/hooks/custom-css.jsx +++ b/packages/block-editor/src/hooks/custom-css.jsx @@ -52,7 +52,7 @@ function CustomCSSControl( { blockName, setAttributes, style } ) { ); return ( - + { - it( 'should remove nested keys', () => { - expect( cleanEmptyObject( { color: { text: undefined } } ) ).toEqual( - undefined - ); - } ); - - it( 'should remove partial nested keys', () => { - expect( - cleanEmptyObject( { - color: { text: undefined }, - typography: { fontSize: '10px' }, - } ) - ).toEqual( { - typography: { fontSize: '10px' }, - } ); - } ); - - it( 'should not remove falsy nested keys', () => { - expect( cleanEmptyObject( { color: { text: false } } ) ).not.toEqual( - undefined - ); - expect( cleanEmptyObject( { color: { text: '' } } ) ).not.toEqual( - undefined - ); - } ); -} ); diff --git a/packages/block-editor/src/hooks/test/utils.jsdom.test.tsx b/packages/block-editor/src/hooks/test/utils.jsdom.test.tsx index 9b92ee293f3cf4..3e223f2ab06445 100644 --- a/packages/block-editor/src/hooks/test/utils.jsdom.test.tsx +++ b/packages/block-editor/src/hooks/test/utils.jsdom.test.tsx @@ -2,13 +2,41 @@ import { afterEach, describe, expect, it } from 'vitest'; import { render, screen } from '@testing-library/react'; import { applyFilters, removeFilter } from '@wordpress/hooks'; import type { ComponentType } from 'react'; -import { createBlockEditFilter } from '../utils'; +import { cleanEmptyObject, createBlockEditFilter } from '../utils'; import { BlockEditContextProvider, mayDisplayControlsKey, mayDisplayPatternEditingControlsKey, } from '../../components/block-edit/context'; +describe( 'cleanEmptyObject', () => { + it( 'removes nested keys', () => { + expect( cleanEmptyObject( { color: { text: undefined } } ) ).toEqual( + undefined + ); + } ); + + it( 'removes partial nested keys', () => { + expect( + cleanEmptyObject( { + color: { text: undefined }, + typography: { fontSize: '10px' }, + } ) + ).toEqual( { + typography: { fontSize: '10px' }, + } ); + } ); + + it( 'preserves falsy nested keys', () => { + expect( cleanEmptyObject( { color: { text: false } } ) ).not.toEqual( + undefined + ); + expect( cleanEmptyObject( { color: { text: '' } } ) ).not.toEqual( + undefined + ); + } ); +} ); + describe( 'createBlockEditFilter', () => { afterEach( () => { removeFilter( 'editor.BlockEdit', 'core/editor/hooks' ); diff --git a/packages/block-editor/tsconfig.json b/packages/block-editor/tsconfig.json index 82b202cbf76b14..d93e45e623779c 100644 --- a/packages/block-editor/tsconfig.json +++ b/packages/block-editor/tsconfig.json @@ -5,51 +5,128 @@ "types": [] }, "references": [ - { "path": "./tsconfig.build.json" }, - { "path": "../a11y/tsconfig.build.json" }, - { "path": "../block-serialization-default-parser" }, - { "path": "../blob/tsconfig.build.json" }, - { "path": "../blocks" }, - { "path": "../components/tsconfig.build.json" }, - { "path": "../compose/tsconfig.build.json" }, - { "path": "../data" }, - { "path": "../dataviews/tsconfig.build.json" }, - { "path": "../date" }, - { "path": "../deprecated/tsconfig.build.json" }, - { "path": "../dom" }, - { "path": "../element/tsconfig.build.json" }, - { "path": "../preferences/tsconfig.build.json" }, - { "path": "../global-styles-engine/tsconfig.build.json" }, - { "path": "../priority-queue/tsconfig.build.json" }, - { "path": "../private-apis" }, - { "path": "../hooks" }, - { "path": "../html-entities/tsconfig.build.json" }, - { "path": "../i18n/tsconfig.build.json" }, - { "path": "../icons/tsconfig.build.json" }, - { "path": "../image-cropper/tsconfig.build.json" }, - { "path": "../interactivity/tsconfig.build.json" }, - { "path": "../is-shallow-equal/tsconfig.build.json" }, - { "path": "../kebab-case" }, - { "path": "../keycodes/tsconfig.build.json" }, - { "path": "../keyboard-shortcuts" }, - { "path": "../notices/tsconfig.build.json" }, - { "path": "../rich-text" }, - { "path": "../style-engine" }, - { "path": "../token-list/tsconfig.build.json" }, - { "path": "../ui/tsconfig.build.json" }, - { "path": "../url" }, - { "path": "../upload-media/tsconfig.build.json" }, - { "path": "../warning" } + { + "path": "./tsconfig.build.json" + }, + { + "path": "../a11y/tsconfig.build.json" + }, + { + "path": "../block-serialization-default-parser" + }, + { + "path": "../blob/tsconfig.build.json" + }, + { + "path": "../blocks" + }, + { + "path": "../components/tsconfig.build.json" + }, + { + "path": "../compose/tsconfig.build.json" + }, + { + "path": "../data" + }, + { + "path": "../dataviews/tsconfig.build.json" + }, + { + "path": "../date" + }, + { + "path": "../deprecated/tsconfig.build.json" + }, + { + "path": "../dom" + }, + { + "path": "../element/tsconfig.build.json" + }, + { + "path": "../preferences/tsconfig.build.json" + }, + { + "path": "../global-styles-engine/tsconfig.build.json" + }, + { + "path": "../priority-queue/tsconfig.build.json" + }, + { + "path": "../private-apis" + }, + { + "path": "../hooks" + }, + { + "path": "../html-entities/tsconfig.build.json" + }, + { + "path": "../i18n/tsconfig.build.json" + }, + { + "path": "../icons/tsconfig.build.json" + }, + { + "path": "../image-cropper/tsconfig.build.json" + }, + { + "path": "../interactivity/tsconfig.build.json" + }, + { + "path": "../is-shallow-equal/tsconfig.build.json" + }, + { + "path": "../kebab-case" + }, + { + "path": "../keycodes/tsconfig.build.json" + }, + { + "path": "../keyboard-shortcuts" + }, + { + "path": "../notices/tsconfig.build.json" + }, + { + "path": "../rich-text" + }, + { + "path": "../style-engine" + }, + { + "path": "../token-list/tsconfig.build.json" + }, + { + "path": "../ui/tsconfig.build.json" + }, + { + "path": "../url" + }, + { + "path": "../upload-media/tsconfig.build.json" + }, + { + "path": "../warning" + } ], /* * These dev files import sources outside the build's TypeScript allowlist. * TypeScript unit tests are checked separately by test:unit:conventions. + * + * Each excluded file imports a component the build allowlist does not + * type yet. A composite project has to resolve every relative import + * within its own program, so including one of these would mean adding + * the whole subgraph behind it. Drop an entry once the allowlist in + * `tsconfig.build.json` covers what it imports. */ "exclude": [ "**/benchmark", "src/components/block-icon/stories/index.story.ts", "src/components/contrast-checker/stories/index.story.ts", "src/components/inspector-controls-tabs/test/use-inspector-controls-tabs.jsdom.test.tsx", - "src/hooks/test/utils.jsdom.test.tsx" + "src/hooks/test/utils.jsdom.test.tsx", + "src/components/inspector-controls-tabs/test/advanced-panels.jsdom.test.tsx" ] } diff --git a/packages/editor/CHANGELOG.md b/packages/editor/CHANGELOG.md index 4c50ef714dd885..53522b189ad726 100644 --- a/packages/editor/CHANGELOG.md +++ b/packages/editor/CHANGELOG.md @@ -7,6 +7,7 @@ - `PostAuthor`: The field renders with the `SearchableSelect` component of `@wordpress/ui` instead of `ComboboxControl` and `SelectControl` ([#83323](https://github.com/WordPress/gutenberg/pull/83323)). - `DocumentOutline`: Show the outline items' focus ring with the design system's outline instead of a legacy box-shadow ([#83755](https://github.com/WordPress/gutenberg/pull/83755)). - Notes: Add a "Notes" submenu to the View group of the Options menu ([#83768](https://github.com/WordPress/gutenberg/pull/83768)). +- Block inspector: Move the "Apply globally" control from the Advanced panel in the Settings tab to the new "Additional styles" panel in the Styles tab, by filling the `additional-styles` group ([#83753](https://github.com/WordPress/gutenberg/pull/83753)). ### Bug Fixes diff --git a/packages/editor/src/hooks/push-changes-to-global-styles/index.jsx b/packages/editor/src/hooks/push-changes-to-global-styles/index.jsx index 9a15c415984656..6a289d9212898c 100644 --- a/packages/editor/src/hooks/push-changes-to-global-styles/index.jsx +++ b/packages/editor/src/hooks/push-changes-to-global-styles/index.jsx @@ -1,7 +1,7 @@ import { addFilter } from '@wordpress/hooks'; import { createHigherOrderComponent } from '@wordpress/compose'; import { - InspectorAdvancedControls, + InspectorControls, store as blockEditorStore, privateApis as blockEditorPrivateApis, useBlockEditingMode, @@ -556,9 +556,9 @@ function PushChangesToGlobalStyles( props ) { } return ( - + - + ); } diff --git a/packages/format-library/src/link/inline.tsx b/packages/format-library/src/link/inline.tsx index 17e348b691e120..4542cdf62df526 100644 --- a/packages/format-library/src/link/inline.tsx +++ b/packages/format-library/src/link/inline.tsx @@ -57,7 +57,7 @@ const LINK_SETTINGS = [ }, { id: 'cssClasses', - title: __( 'Additional CSS class(es)' ), + title: __( 'CSS class(es)' ), render: ( setting: CSSClassesSettingProps[ 'setting' ], value: CSSClassesSettingProps[ 'value' ], diff --git a/packages/format-library/src/link/test/css-classes-setting.jsdom.test.jsx b/packages/format-library/src/link/test/css-classes-setting.jsdom.test.jsx index b0230a2cb23705..7e78ea322b70a2 100644 --- a/packages/format-library/src/link/test/css-classes-setting.jsdom.test.jsx +++ b/packages/format-library/src/link/test/css-classes-setting.jsdom.test.jsx @@ -11,7 +11,7 @@ describe( 'CSSClassesSettingComponent', () => { {} } @@ -20,7 +20,7 @@ describe( 'CSSClassesSettingComponent', () => { // Checkbox should be visible const checkbox = screen.getByRole( 'checkbox', { - name: 'Additional CSS class(es)', + name: 'CSS class(es)', } ); expect( checkbox ).toBeVisible(); @@ -46,7 +46,7 @@ describe( 'CSSClassesSettingComponent', () => { { // Toggle on const checkbox = screen.getByRole( 'checkbox', { - name: 'Additional CSS class(es)', + name: 'CSS class(es)', } ); // starts collapsed expect( checkbox ).toHaveAttribute( 'aria-expanded', 'false' ); @@ -92,7 +92,7 @@ describe( 'CSSClassesSettingComponent', () => { { ); const checkbox = screen.getByRole( 'checkbox', { - name: 'Additional CSS class(es)', + name: 'CSS class(es)', } ); // Initially expanded and has aria-controls diff --git a/packages/global-styles-ui/src/screen-block.tsx b/packages/global-styles-ui/src/screen-block.tsx index a79df252b5d417..41fc407a196cf7 100644 --- a/packages/global-styles-ui/src/screen-block.tsx +++ b/packages/global-styles-ui/src/screen-block.tsx @@ -461,7 +461,10 @@ function ScreenBlock( { ) } { canEditCSS && ( - + { await pageUtils.pressKeys( 'primary+k' ); await page.keyboard.type( 'custom CSS' ); await page.getByRole( 'option', { name: 'Open custom CSS' } ).click(); - await expect( page.getByLabel( 'Additional CSS' ) ).toBeVisible(); + // Expect the CSS input to be present. + await expect( page.getByLabel( 'CSS' ) ).toBeVisible(); } ); test( 'Suggestions section shows contextual commands on open', async ( { diff --git a/test/e2e/specs/site-editor/push-to-global-styles.spec.js b/test/e2e/specs/site-editor/push-to-global-styles.spec.js index b9aa363bc00182..0950a8fad3fd7d 100644 --- a/test/e2e/specs/site-editor/push-to-global-styles.spec.js +++ b/test/e2e/specs/site-editor/push-to-global-styles.spec.js @@ -31,8 +31,8 @@ test.describe( 'Push to Global Styles button', () => { } /** - * Adds a Heading block, opens its Advanced panel and turns on Letter case - * so there's a change to push. + * Adds a Heading block, opens its Additional styles panel and turns on + * Letter case so there's a change to push. * * @param {Object} options Playwright fixtures. * @param {Object} options.page Playwright page. @@ -43,9 +43,9 @@ test.describe( 'Push to Global Styles button', () => { await editor.insertBlock( { name: 'core/heading' } ); await page.keyboard.type( 'A heading' ); - // Go to block settings and open the Advanced panel. + // Go to block settings and open the Additional styles panel. await editor.openDocumentSettingsSidebar(); - await page.getByRole( 'button', { name: 'Advanced' } ).click(); + await page.getByRole( 'button', { name: 'Additional styles' } ).click(); // Push button should be disabled with no changes. await expect( diff --git a/tools/eslint/suppressions.json b/tools/eslint/suppressions.json index de235b68813fbf..ef1ba312d35c4f 100644 --- a/tools/eslint/suppressions.json +++ b/tools/eslint/suppressions.json @@ -1514,6 +1514,11 @@ "count": 1 } }, + "packages/block-editor/src/components/inspector-controls-tabs/additional-styles-panel.jsx": { + "react/jsx-filename-extension": { + "count": 1 + } + }, "packages/block-editor/src/components/inspector-controls-tabs/advanced-controls-panel.jsx": { "react/jsx-filename-extension": { "count": 1