Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Block.json: Refactor and stabilize selectors API #46496

Merged
merged 26 commits into from
Mar 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
0239107
Allow selectors when registering blocks
aaronrobertshaw Dec 9, 2022
8d22173
Add tests for updated selectors API
aaronrobertshaw Dec 13, 2022
13e743e
Add selectors to block.json schema
aaronrobertshaw Dec 13, 2022
974f188
Update image block to use selectors API
aaronrobertshaw Dec 13, 2022
3858633
Add global function to get block CSS selectors
aaronrobertshaw Jan 15, 2023
b19da22
Update theme.json class to support selectors API
aaronrobertshaw Dec 16, 2022
bb99093
Add filter ensuring selectors metadata is available
aaronrobertshaw Jan 27, 2023
4776e71
Draft block selectors API documentation
aaronrobertshaw Jan 30, 2023
a7d49bb
Test root block selector generation for core block
aaronrobertshaw Jan 31, 2023
e354e2e
Fix typo in null duotone selector test
aaronrobertshaw Jan 31, 2023
e35ca22
Make duotone use color.duotone path
aaronrobertshaw Jan 31, 2023
045e256
Remove unnecessary selectors properties for fallback tests
aaronrobertshaw Jan 31, 2023
fd51b64
Add extra test to cover feature fallback to generated default selector
aaronrobertshaw Jan 31, 2023
b0c53a8
Fix typos and improve wording for docs
aaronrobertshaw Feb 13, 2023
a67f109
Fix up checks for whether selectors API in use
aaronrobertshaw Feb 14, 2023
5561ed7
Add selectors default value in block type api
aaronrobertshaw Feb 14, 2023
e133f6a
Improve block metadata selectors docs
aaronrobertshaw Feb 14, 2023
9edfa55
Note when selectors polyfill can be removed
aaronrobertshaw Feb 14, 2023
a42484d
Add note on selectors API purpose to block.json schema
aaronrobertshaw Feb 14, 2023
f11ccd7
Relocate new global function to 6.3 compat file
aaronrobertshaw Feb 14, 2023
efaef5e
Remove unnecessary space
aaronrobertshaw Feb 28, 2023
75a1f6a
Move duotone under the filters feature
aaronrobertshaw Mar 13, 2023
08b2604
Fix duotone fallback and selector function tests
aaronrobertshaw Mar 13, 2023
991dae9
Add editorSelectors API
aaronrobertshaw Mar 14, 2023
28d39fa
Switch to ternary for editor duotone selector check
aaronrobertshaw Mar 15, 2023
8aa8f24
Fix typo
aaronrobertshaw Mar 17, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions docs/reference-guides/block-api/block-metadata.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ Starting in WordPress 5.8 release, we encourage using the `block.json` metadata
"my-plugin/message": "message"
},
"usesContext": [ "groupId" ],
"editorSelectors": {
"root": ".editor-styles-wrapper .wp-block-my-plugin-notice"
},
"selectors": {
"root": ".wp-block-my-plugin-notice"
},
"supports": {
"align": true
},
Expand Down Expand Up @@ -379,6 +385,71 @@ See [the block context documentation](/docs/reference-guides/block-api/block-con
}
```

### Editor Selectors

- Type: `object`
- Optional
- Localized: No
- Property: `editorSelectors`
- Default: `{}`
- Since: `WordPress 6.3.0`

Any editor specific custom CSS selectors, keyed by `root`, feature, or
sub-feature, to be used when generating block styles for theme.json
(global styles) stylesheets in the editor.

Editor only selectors override those defined within the `selectors` property.

See the [the selectors documentation](/docs/reference-guides/block-api/block-selectors.md) for more details.

```json
{
"editorSelectors": {
"root": ".my-custom-block-selector",
"color": {
"text": ".my-custom-block-selector p"
},
"typography": {
"root": ".my-custom-block-selector > h2",
"text-decoration": ".my-custom-block-selector > h2 span"
}
}
}
```

### Selectors

- Type: `object`
- Optional
- Localized: No
- Property: `selectors`
- Default: `{}`
aaronrobertshaw marked this conversation as resolved.
Show resolved Hide resolved
- Since: `WordPress 6.3.0`

Any custom CSS selectors, keyed by `root`, feature, or sub-feature, to be used
aaronrobertshaw marked this conversation as resolved.
Show resolved Hide resolved
when generating block styles for theme.json (global styles) stylesheets.
Providing custom selectors allows more fine grained control over which styles
apply to what block elements, e.g. applying typography styles only to an inner
heading while colors are still applied on the outer block wrapper etc.


See the [the selectors documentation](/docs/reference-guides/block-api/block-selectors.md) for more details.

```json
{
"selectors": {
"root": ".my-custom-block-selector",
"color": {
"text": ".my-custom-block-selector p"
},
"typography": {
"root": ".my-custom-block-selector > h2",
"text-decoration": ".my-custom-block-selector > h2 span"
}
}
}
```

### Supports

- Type: `object`
Expand Down
145 changes: 145 additions & 0 deletions docs/reference-guides/block-api/block-selectors.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
# Selectors

Block Selectors is the API that allows blocks to customize the CSS selector used
when their styles are generated.
aaronrobertshaw marked this conversation as resolved.
Show resolved Hide resolved

A block may customize its CSS selectors at three levels: root, feature, and
subfeature. Each may also be overridden with editor-only selectors.

## Root Selector

The root selector is the block's primary CSS selector.

All blocks require a primary CSS selector for their style declarations to be
included under. If one is not provided through the Block Selectors API, a
default is generated in the form of `.wp-block-<name>`.

### Example
```json
{
...
"selectors": {
"root": ".my-custom-block-selector"
}
}
```

## Feature Selectors

Feature selectors relate to styles for a block support, e.g. border, color,
typography, etc.

A block may wish to apply the styles for specific features to different
elements within a block. An example might be using colors on the block's wrapper
but applying the typography styles to an inner heading only.

### Example
```json
{
...
"selectors": {
"root": ".my-custom-block-selector",
"color": ".my-custom-block-selector",
"typography": ".my-custom-block-selector > h2"
}
}
```

## Subfeature Selectors

These selectors relate to individual styles provided by a block support e.g.
`background-color`

A subfeature can have styles generated under its own unique selector. This is
especially useful where one block support subfeature can't be applied to the
same element as the support's other subfeatures.

A great example of this is `text-decoration`. Web browsers render this style
differently, making it difficult to override if added to a wrapper element. By
assigning `text-decoration` a custom selector, its style can target only the
elements to which it should be applied.

### Example
```json
{
...
"selectors": {
"root": ".my-custom-block-selector",
"color": ".my-custom-block-selector",
"typography": {
"root": ".my-custom-block-selector > h2",
"text-decoration": ".my-custom-block-selector > h2 span"
}
}
}
```

## Shorthand

Rather than specify a CSS selector for every subfeature, you can set a single
selector as a string value for the relevant feature. This is the approach
demonstrated for the `color` feature in the earlier examples above.

## Fallbacks

A selector that hasn't been configured for a specific feature will fall back to
the block's root selector. Similarly, if a subfeature hasn't had a custom
selector set, it will fall back to its parent feature's selector and, if unavailable, fall back further to the block's root selector.

Rather than repeating selectors for multiple subfeatures, you can set the
common selector as the parent feature's `root` selector and only define the
unique selectors for the subfeatures that differ.

### Example
```json
{
...
"selectors": {
"root": ".my-custom-block-selector",
"color": {
"text": ".my-custom-block-selector p"
},
"typography": {
"root": ".my-custom-block-selector > h2",
"text-decoration": ".my-custom-block-selector > h2 span"
}
}
}
```

The `color.background-color` subfeature isn't explicitly set in the above
example. As the `color` feature also doesn't define a `root` selector,
`color.background-color` would be included under the block's primary root
selector, `.my-custom-block-selector`.

For a subfeature such as `typography.font-size`, it would fallback to its parent
feature's selector given that is present, i.e. `.my-custom-block-selector > h2`.

## Editor-only Selectors

There are scenarios in which a block might need different markup within the
editor compared to the frontend e.g. inline cropping of the Image block. Some
generated styles may then need to be applied to different, or multiple,
elements.

Continuing with the Image cropping example, the image border styles need to also
be applied to the cropping area. If the selector for the cropping area is added
to the normal `selectors` config for the block, it would be output unnecessarily
on the frontend.

To avoid this, and include the selector for the editor only, the selectors for the border feature can be
overridden via the `editorSelectors` config.

### Example
```json
{
...
"selectors": {
"root": ".wp-block-image",
"border": ".wp-block-image img"
},
"editorSelectors": {
"border": ".wp-block-image img, .wp-block-image .wp-block-image__crop-area"
aaronrobertshaw marked this conversation as resolved.
Show resolved Hide resolved
},
}
```
Loading