Skip to content

Commit

Permalink
Merge branch 'trunk' into fix/notice-color-dark-mode
Browse files Browse the repository at this point in the history
  • Loading branch information
t-hamano committed Feb 19, 2025
2 parents cc8f523 + 3639ac4 commit 4bc1c56
Show file tree
Hide file tree
Showing 38 changed files with 373 additions and 165 deletions.
4 changes: 2 additions & 2 deletions changelog.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
== Changelog ==

= 20.3.0-rc.1 =

= 20.3.0 =

## Changelog

Expand Down Expand Up @@ -90,6 +89,7 @@

#### Interactivity API
- iAPI Router: Fix CSS rule order in some constructed style sheets. ([68923](https://github.com/WordPress/gutenberg/pull/68923))
- iAPI Router: Revert "Handle styles assets on region-based navigation" ([69222](https://github.com/WordPress/gutenberg/pull/69222))


### Accessibility
Expand Down
38 changes: 38 additions & 0 deletions docs/reference-guides/block-api/block-variations.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,44 @@ wp.blocks.registerBlockVariation( 'core/embed', {
} );
```

## Registering block variations in PHP

Block variations can also be registered from PHP using the `get_block_type_variations` filter hook. This approach is particularly useful when you need to dynamically generate variations based on registered post types, taxonomies, or other WordPress data.

Here's an example of how to register a custom variation for the `core/image` block:

```php
function my_custom_image_variation( $variations, $block_type ) {
// Only modify variations for the image block
if ( 'core/image' !== $block_type->name ) {
return $variations;
}

// Add a custom variation
$variations[] = array(
'name' => 'wide-image',
'title' => __( 'Wide image', 'textdomain' ),
'description' => __( 'A wide image', 'textdomain' ),
'scope' => array( 'inserter' ),
'isDefault' => false,
'attributes' => array(
'align' => 'wide', // Identifies the link type as custom
),
);

return $variations;
}
add_filter( 'get_block_type_variations', 'my_custom_image_variation', 10, 2 );
```

The `get_block_type_variations` filter is called when variations are requested for a block type. It receives two parameters:
- `$variations`: An array of currently registered variations for the block type
- `$block_type`: The full block type object

Note that variations registered through PHP will be merged with any variations registered through JavaScript using `registerBlockVariation()`.

<div class="callout callout-info">Check the <a href="https://developer.wordpress.org/news/2024/03/how-to-register-block-variations-with-php/">How to register block variations with PHP</a> blog post for more info about this</div>

## Removing a block variation

Block variations can also be easily removed. To do so, use `wp.blocks.unregisterBlockVariation()`. This function accepts the name of the block and the `name` of the variation that should be unregistered.
Expand Down
2 changes: 1 addition & 1 deletion gutenberg.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* Description: Printing since 1440. This is the development plugin for the block editor, site editor, and other future WordPress core functionality.
* Requires at least: 6.6
* Requires PHP: 7.2
* Version: 20.3.0-rc.1
* Version: 20.3.0
* Author: Gutenberg Team
* Text Domain: gutenberg
*
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "gutenberg",
"version": "20.3.0-rc.1",
"version": "20.3.0",
"private": true,
"description": "A new WordPress editor experience.",
"author": "The WordPress Contributors",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ exports[`ColorPaletteControl matches the snapshot 1`] = `
class="components-circular-option-picker"
>
<div
aria-label="Custom color picker."
aria-label="Custom color picker"
id="components-circular-option-picker-0"
role="listbox"
>
Expand Down
29 changes: 16 additions & 13 deletions packages/block-editor/src/components/iframe/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -131,27 +131,30 @@ function Iframe( {
function preventFileDropDefault( event ) {
event.preventDefault();
}

const { ownerDocument } = node;

// Ideally ALL classes that are added through get_body_class should
// be added in the editor too, which we'll somehow have to get from
// the server in the future (which will run the PHP filters).
setBodyClasses(
Array.from( ownerDocument.body.classList ).filter(
( name ) =>
name.startsWith( 'admin-color-' ) ||
name.startsWith( 'post-type-' ) ||
name === 'wp-embed-responsive'
)
);

function onLoad() {
const { contentDocument, ownerDocument } = node;
const { contentDocument } = node;
const { documentElement } = contentDocument;
iFrameDocument = contentDocument;

documentElement.classList.add( 'block-editor-iframe__html' );

clearerRef( documentElement );

// Ideally ALL classes that are added through get_body_class should
// be added in the editor too, which we'll somehow have to get from
// the server in the future (which will run the PHP filters).
setBodyClasses(
Array.from( ownerDocument.body.classList ).filter(
( name ) =>
name.startsWith( 'admin-color-' ) ||
name.startsWith( 'post-type-' ) ||
name === 'wp-embed-responsive'
)
);

contentDocument.dir = ownerDocument.dir;

for ( const compatStyle of getCompatibilityStyles() ) {
Expand Down
5 changes: 5 additions & 0 deletions packages/block-editor/src/components/inserter/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -644,5 +644,10 @@ $block-inserter-tabs-height: 44px;
}

.block-editor-tabbed-sidebar__tabpanel .block-editor-inserter__help-text {
display: none;
padding: 0 $grid-unit-30 $grid-unit-20;

@include break-mobile {
display: block;
}
}
2 changes: 2 additions & 0 deletions packages/block-library/src/cover/edit/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,8 @@ function CoverEdit( {
value={ overlayColor.color }
onChange={ onSetOverlayColor }
clearable={ false }
asButtons
aria-label={ __( 'Overlay color' ) }
/>
</div>
</CoverPlaceholder>
Expand Down
12 changes: 6 additions & 6 deletions packages/block-library/src/cover/test/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ async function setup( attributes, useCoreBlocks, customSettings ) {

async function createAndSelectBlock() {
await userEvent.click(
screen.getByRole( 'option', {
screen.getByRole( 'button', {
name: 'Black',
} )
);
Expand All @@ -72,7 +72,7 @@ describe( 'Cover block', () => {

test( 'can set overlay color using color picker on block placeholder', async () => {
const { container } = await setup();
const colorPicker = screen.getByRole( 'option', {
const colorPicker = screen.getByRole( 'button', {
name: 'Black',
} );
await userEvent.click( colorPicker );
Expand All @@ -96,7 +96,7 @@ describe( 'Cover block', () => {
await setup();

await userEvent.click(
screen.getByRole( 'option', {
screen.getByRole( 'button', {
name: 'Black',
} )
);
Expand Down Expand Up @@ -389,7 +389,7 @@ describe( 'Cover block', () => {
describe( 'isDark settings', () => {
test( 'should toggle is-light class if background changed from light to dark', async () => {
await setup();
const colorPicker = screen.getByRole( 'option', {
const colorPicker = screen.getByRole( 'button', {
name: 'White',
} );
await userEvent.click( colorPicker );
Expand All @@ -413,7 +413,7 @@ describe( 'Cover block', () => {
} );
test( 'should remove is-light class if overlay color is removed', async () => {
await setup();
const colorPicker = screen.getByRole( 'option', {
const colorPicker = screen.getByRole( 'button', {
name: 'White',
} );
await userEvent.click( colorPicker );
Expand All @@ -426,7 +426,7 @@ describe( 'Cover block', () => {
} )
);
await userEvent.click( screen.getByText( 'Overlay' ) );
// The default color is black, so clicking the black color option will remove the background color,
// The default color is black, so clicking the black color button will remove the background color,
// which should remove the isDark setting and assign the is-light class.
const popupColorPicker = screen.getByRole( 'option', {
name: 'White',
Expand Down
27 changes: 3 additions & 24 deletions packages/block-library/src/navigation-link/editor.scss
Original file line number Diff line number Diff line change
Expand Up @@ -82,30 +82,9 @@
// Draw a wavy underline.
.wp-block-navigation-link__placeholder-text {
span {
$blur: 10%;
$width: 6%;
$stop1: 30%;
$stop2: 64%;

--wp-underline-color: var(--wp-admin-theme-color);

background-image:
linear-gradient(45deg, transparent ($stop1 - $blur), var(--wp-underline-color) $stop1, var(--wp-underline-color) ($stop1 + $width), transparent ($stop1 + $width + $blur)),
linear-gradient(135deg, transparent ($stop2 - $blur), var(--wp-underline-color) $stop2, var(--wp-underline-color) ($stop2 + $width), transparent ($stop2 + $width + $blur));
background-position: 0 100%;
background-size: 6px 3px;
background-repeat: repeat-x;

// Since applied to a span, it doesn't change the footprint of the item,
// but it does vertically shift the underline to better align.
padding-bottom: 0.1em;
}

&.is-invalid,
&.is-draft {
span {
--wp-underline-color: #{$alert-red};
}
text-decoration: wavy underline;
text-decoration-skip-ink: none;
text-underline-offset: 0.25rem;
}
}

Expand Down
2 changes: 2 additions & 0 deletions packages/block-library/src/query-total/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
*
* @since 6.8.0
*
* @global WP_Query $wp_query WordPress Query object.
*
* @param array $attributes Block attributes.
* @param string $content Block default content.
* @param WP_Block $block Block instance.
Expand Down
2 changes: 1 addition & 1 deletion packages/components/src/border-box-control/test/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ describe( 'BorderBoxControl', () => {
await waitFor( () =>
expect(
screen.getByRole( 'button', {
name: 'Custom color picker.',
name: 'Custom color picker',
} )
).toBeVisible()
);
Expand Down
2 changes: 1 addition & 1 deletion packages/components/src/border-control/test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ describe( 'BorderControl', () => {

const customColorPicker = getButton( /Custom color picker/ );
const circularOptionPicker = screen.getByRole( 'listbox', {
name: 'Custom color picker.',
name: 'Custom color picker',
} );
const colorSwatchButtons =
within( circularOptionPicker ).getAllByRole( 'option' );
Expand Down
13 changes: 13 additions & 0 deletions packages/components/src/circular-option-picker/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,19 @@ Prevents keyboard interaction from wrapping around. Only used when `asButtons` i
- Required: No
- Default: `true`

### `aria-labelledby`: `string`

The ID reference list of one or more elements that label the wrapper element.

- Required: No

### `aria-label`: `string`

The label for the wrapper element. Not used if an 'aria-labelledby' is provided.

- Required: No
- Default: `Custom color picker`

## Subcomponents

### `CircularOptionPicker.ButtonAction`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ function ButtonsCircularOptionPicker(
);

return (
<div { ...additionalProps } id={ baseId }>
<div { ...additionalProps } role="group" id={ baseId }>
<CircularOptionPickerContext.Provider value={ contextValue }>
{ options }
{ children }
Expand Down
1 change: 1 addition & 0 deletions packages/components/src/circular-option-picker/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@ export {
ButtonAction,
DropdownLinkAction,
} from './circular-option-picker-actions';
export { getComputeCircularOptionPickerCommonProps } from './utils';

export default CircularOptionPicker;
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ WithLoopingDisabled.parameters = {
docs: {
source: {
code: `<CircularOptionPicker
aria-label="${ WithLoopingDisabled.args[ 'aria-label' ] }"
'aria-label': 'Circular Option Picker',
loop={false}
options={<DefaultOptions />}
/>`,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ describe( 'CircularOptionPicker', () => {

expect( screen.queryByRole( 'listbox' ) ).not.toBeInTheDocument();
expect( screen.queryByRole( 'option' ) ).not.toBeInTheDocument();
expect( screen.getByRole( 'group' ) ).toBeInTheDocument();
expect( screen.getByRole( 'button' ) ).toBeInTheDocument();
} );
} );
Expand Down
21 changes: 11 additions & 10 deletions packages/components/src/circular-option-picker/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,16 @@ type CommonCircularOptionPickerProps = {
* The child elements.
*/
children?: ReactNode;
/**
* The ID reference list of one or more elements that label the wrapper
* element.
*/
'aria-labelledby'?: string;
/**
* The label for the wrapper element. Defaults to 'Custom color picker'. Not
* used if an 'aria-labelledby' is provided.
*/
'aria-label'?: string;
};

type WithBaseId = {
Expand All @@ -59,16 +69,7 @@ type FullListboxCircularOptionPickerProps = CommonCircularOptionPickerProps & {
* @default true
*/
loop?: boolean;
} & (
| {
'aria-label': string;
'aria-labelledby'?: never;
}
| {
'aria-label'?: never;
'aria-labelledby': string;
}
);
};

export type ListboxCircularOptionPickerProps = WithBaseId &
Omit< FullListboxCircularOptionPickerProps, 'asButtons' >;
Expand Down
27 changes: 27 additions & 0 deletions packages/components/src/circular-option-picker/utils.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';

/**
* Computes the common props for the CircularOptionPicker.
*/
export function getComputeCircularOptionPickerCommonProps(
asButtons?: boolean,
loop?: boolean,
ariaLabel?: string,
ariaLabelledby?: string
) {
const metaProps = asButtons
? { asButtons: true }
: { asButtons: false, loop };

const labelProps = {
'aria-labelledby': ariaLabelledby,
'aria-label': ariaLabelledby
? undefined
: ariaLabel || __( 'Custom color picker' ),
};

return { metaProps, labelProps };
}
Loading

0 comments on commit 4bc1c56

Please sign in to comment.