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 Bindings: Update label for bound paragraphs and headings #65114

Closed
wants to merge 7 commits into from

Conversation

artemiomorales
Copy link
Contributor

@artemiomorales artemiomorales commented Sep 6, 2024

What?

This PR fixes the label for bound paragraphs and headings, using their bindings value rather than fallback content.

Why?

Addresses #62933
The label is currently read out loud by screen readers. Unless we update the label for bound blocks, screen readers will simply announce the value in the markup, which is misleading, as the actual content will be rendered by the block bindings API.

How?

It replicates some logic from use-bindings-attributes.js inside of block-selection-button.js in order to retrieve the bindings value, and also extracts key logic into a new getBindingsValues function so that it can be reused.

Testing Instructions

1. Register post meta by adding this snippet to your theme's functions.php
add_action( 'init', 'test_block_bindings' );

function test_block_bindings() {
	register_meta(
		'post',
		'text_field',
		array(
			'show_in_rest'      => true,
			'single'            => true,
			'type'              => 'string',
			'default'           => 'default text value',
		)
	);
}
2. Add heading and paragraph blocks bound to a custom field using the Code Editor
<!-- wp:heading {"metadata":{"bindings":{"content":{"source":"core/post-meta","args":{"key":"text_field"}}}}} -->
<h2 class="wp-block-heading">Bound heading</h2>
<!-- /wp:heading -->
<!-- wp:paragraph {"metadata":{"bindings":{"content":{"source":"core/post-meta","args":{"key":"text_field"}}}}} -->
<p>Bound paragraph</p>
<!-- /wp:paragraph -->
  1. Using the NVDA screen reader, navigate to the bound blocks in Navigation Mode, and see that the their modified content is announced.

Copy link

github-actions bot commented Sep 6, 2024

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Co-authored-by: artemiomorales <artemiosans@git.wordpress.org>
Co-authored-by: afercia <afercia@git.wordpress.org>
Co-authored-by: SantosGuillamot <santosguillamot@git.wordpress.org>
Co-authored-by: gziolo <gziolo@git.wordpress.org>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@SantosGuillamot
Copy link
Contributor

I assume this is going to be the case for other blocks and attributes. For example, does this happen with the heading content or the button text?

If that's the case, I believe we probably need to think about it more broadly and solve it for any block attribute, potentially using the bound value instead of a default message.

@gziolo
Copy link
Member

gziolo commented Sep 6, 2024

If accepted, it should be replicated with other blocks that can be connected. The challenge is that the attribute connected isn'tand always the most important one, connections for attributes editable in the sidebar shouldn't become too prominent.

@artemiomorales
Copy link
Contributor Author

To start, I just hardcoded a new label for bound paragraphs to get the conversation started.

Ideally, we would retrieve the actual binding value, but I'm not sure what would be the best way to go about that. The logic for reading the bindings value is currently in use-binding-attributes.js, and I'm not sure it's necessary to get so involved.

In addition to some text indicating that the content is dynamic, perhaps even just using the binding source and key could suffice? That information is already easily available in the block attributes.

Copy link

github-actions bot commented Sep 6, 2024

Size Change: -9.94 kB (-0.56%)

Total Size: 1.77 MB

Filename Size Change
build/a11y/index.min.js 949 B -2 B (-0.21%)
build/block-editor/content-rtl.css 4.65 kB +114 B (+2.51%)
build/block-editor/content.css 4.64 kB +112 B (+2.47%)
build/block-editor/index.min.js 258 kB +560 B (+0.22%)
build/block-editor/style-rtl.css 16 kB -207 B (-1.27%)
build/block-editor/style.css 16 kB -207 B (-1.27%)
build/block-library/blocks/form-input/style-rtl.css 357 B +15 B (+4.39%)
build/block-library/blocks/form-input/style.css 357 B +15 B (+4.39%)
build/block-library/blocks/image/editor-rtl.css 785 B -106 B (-11.9%) 👏
build/block-library/blocks/image/editor.css 787 B -103 B (-11.57%) 👏
build/block-library/blocks/navigation/editor-rtl.css 2.19 kB +4 B (+0.18%)
build/block-library/blocks/navigation/editor.css 2.2 kB +3 B (+0.14%)
build/block-library/editor-rtl.css 11.7 kB -71 B (-0.6%)
build/block-library/editor.css 11.7 kB -71 B (-0.6%)
build/block-library/index.min.js 218 kB +321 B (+0.15%)
build/block-library/style-rtl.css 15 kB +17 B (+0.11%)
build/block-library/style.css 15 kB +17 B (+0.11%)
build/commands/index.min.js 16.1 kB -3 B (-0.02%)
build/components/index.min.js 224 kB -91 B (-0.04%)
build/components/style-rtl.css 12.1 kB -4 B (-0.03%)
build/components/style.css 12.1 kB -4 B (-0.03%)
build/compose/index.min.js 12.7 kB +135 B (+1.07%)
build/core-data/index.min.js 73.2 kB -3 B (0%)
build/customize-widgets/index.min.js 11 kB -2 B (-0.02%)
build/data/index.min.js 8.98 kB -2 B (-0.02%)
build/edit-post/index.min.js 12.7 kB -46 B (-0.36%)
build/edit-site/index.min.js 217 kB +5 B (0%)
build/edit-site/posts-rtl.css 7.3 kB -7 B (-0.1%)
build/edit-site/posts.css 7.3 kB -8 B (-0.11%)
build/edit-site/style-rtl.css 12.6 kB -7 B (-0.06%)
build/edit-site/style.css 12.6 kB -7 B (-0.06%)
build/edit-widgets/index.min.js 17.7 kB +1 B (+0.01%)
build/editor/index.min.js 102 kB +846 B (+0.83%)
build/editor/style-rtl.css 9.28 kB -6 B (-0.06%)
build/editor/style.css 9.28 kB -4 B (-0.04%)
build/interactivity/debug.min.js 0 B -16.4 kB (removed) 🏆
build/interactivity/file.min.js 0 B -447 B (removed) 🏆
build/interactivity/image.min.js 0 B -1.78 kB (removed) 🏆
build/interactivity/index.min.js 0 B -13.2 kB (removed) 🏆
build/interactivity/navigation.min.js 0 B -1.16 kB (removed) 🏆
build/interactivity/query.min.js 0 B -742 B (removed) 🏆
build/interactivity/router.min.js 0 B -2.8 kB (removed) 🏆
build/interactivity/search.min.js 0 B -615 B (removed) 🏆
build/modules/importmap-polyfill.min.js 0 B -12.3 kB (removed) 🏆
build/preferences/index.min.js 2.9 kB +6 B (+0.21%)
build/private-apis/index.min.js 1.01 kB +5 B (+0.5%)
build/vendors/react-dom.min.js 41.7 kB +2 B (0%)
build/widgets/index.min.js 7.19 kB -9 B (-0.13%)
build-module/a11y/index.min.js 898 B +898 B (new file) 🆕
build-module/block-library/file/view.min.js 447 B +447 B (new file) 🆕
build-module/block-library/image/view.min.js 1.78 kB +1.78 kB (new file) 🆕
build-module/block-library/navigation/view.min.js 1.16 kB +1.16 kB (new file) 🆕
build-module/block-library/query/view.min.js 743 B +743 B (new file) 🆕
build-module/block-library/search/view.min.js 616 B +616 B (new file) 🆕
build-module/interactivity-router/index.min.js 2.8 kB +2.8 kB (new file) 🆕
build-module/interactivity/debug.min.js 16.6 kB +16.6 kB (new file) 🆕
build-module/interactivity/index.min.js 13.3 kB +13.3 kB (new file) 🆕
ℹ️ View Unchanged
Filename Size
build/annotations/index.min.js 2.26 kB
build/api-fetch/index.min.js 2.32 kB
build/autop/index.min.js 2.12 kB
build/blob/index.min.js 579 B
build/block-directory/index.min.js 7.11 kB
build/block-directory/style-rtl.css 1.01 kB
build/block-directory/style.css 1.01 kB
build/block-editor/default-editor-styles-rtl.css 394 B
build/block-editor/default-editor-styles.css 394 B
build/block-library/blocks/archives/editor-rtl.css 61 B
build/block-library/blocks/archives/editor.css 60 B
build/block-library/blocks/archives/style-rtl.css 90 B
build/block-library/blocks/archives/style.css 90 B
build/block-library/blocks/audio/editor-rtl.css 149 B
build/block-library/blocks/audio/editor.css 151 B
build/block-library/blocks/audio/style-rtl.css 132 B
build/block-library/blocks/audio/style.css 132 B
build/block-library/blocks/audio/theme-rtl.css 134 B
build/block-library/blocks/audio/theme.css 134 B
build/block-library/blocks/avatar/editor-rtl.css 115 B
build/block-library/blocks/avatar/editor.css 115 B
build/block-library/blocks/avatar/style-rtl.css 104 B
build/block-library/blocks/avatar/style.css 104 B
build/block-library/blocks/button/editor-rtl.css 265 B
build/block-library/blocks/button/editor.css 265 B
build/block-library/blocks/button/style-rtl.css 538 B
build/block-library/blocks/button/style.css 538 B
build/block-library/blocks/buttons/editor-rtl.css 291 B
build/block-library/blocks/buttons/editor.css 291 B
build/block-library/blocks/buttons/style-rtl.css 328 B
build/block-library/blocks/buttons/style.css 328 B
build/block-library/blocks/calendar/style-rtl.css 240 B
build/block-library/blocks/calendar/style.css 240 B
build/block-library/blocks/categories/editor-rtl.css 132 B
build/block-library/blocks/categories/editor.css 131 B
build/block-library/blocks/categories/style-rtl.css 152 B
build/block-library/blocks/categories/style.css 152 B
build/block-library/blocks/code/editor-rtl.css 53 B
build/block-library/blocks/code/editor.css 53 B
build/block-library/blocks/code/style-rtl.css 121 B
build/block-library/blocks/code/style.css 121 B
build/block-library/blocks/code/theme-rtl.css 122 B
build/block-library/blocks/code/theme.css 122 B
build/block-library/blocks/columns/editor-rtl.css 108 B
build/block-library/blocks/columns/editor.css 108 B
build/block-library/blocks/columns/style-rtl.css 420 B
build/block-library/blocks/columns/style.css 420 B
build/block-library/blocks/comment-author-avatar/editor-rtl.css 124 B
build/block-library/blocks/comment-author-avatar/editor.css 124 B
build/block-library/blocks/comment-author-name/style-rtl.css 72 B
build/block-library/blocks/comment-author-name/style.css 72 B
build/block-library/blocks/comment-content/style-rtl.css 120 B
build/block-library/blocks/comment-content/style.css 120 B
build/block-library/blocks/comment-date/style-rtl.css 65 B
build/block-library/blocks/comment-date/style.css 65 B
build/block-library/blocks/comment-edit-link/style-rtl.css 70 B
build/block-library/blocks/comment-edit-link/style.css 70 B
build/block-library/blocks/comment-reply-link/style-rtl.css 71 B
build/block-library/blocks/comment-reply-link/style.css 71 B
build/block-library/blocks/comment-template/style-rtl.css 200 B
build/block-library/blocks/comment-template/style.css 199 B
build/block-library/blocks/comments-pagination-numbers/editor-rtl.css 122 B
build/block-library/blocks/comments-pagination-numbers/editor.css 121 B
build/block-library/blocks/comments-pagination/editor-rtl.css 228 B
build/block-library/blocks/comments-pagination/editor.css 217 B
build/block-library/blocks/comments-pagination/style-rtl.css 234 B
build/block-library/blocks/comments-pagination/style.css 231 B
build/block-library/blocks/comments-title/editor-rtl.css 75 B
build/block-library/blocks/comments-title/editor.css 75 B
build/block-library/blocks/comments/editor-rtl.css 832 B
build/block-library/blocks/comments/editor.css 832 B
build/block-library/blocks/comments/style-rtl.css 632 B
build/block-library/blocks/comments/style.css 631 B
build/block-library/blocks/cover/editor-rtl.css 641 B
build/block-library/blocks/cover/editor.css 642 B
build/block-library/blocks/cover/style-rtl.css 1.62 kB
build/block-library/blocks/cover/style.css 1.6 kB
build/block-library/blocks/details/editor-rtl.css 65 B
build/block-library/blocks/details/editor.css 65 B
build/block-library/blocks/details/style-rtl.css 86 B
build/block-library/blocks/details/style.css 86 B
build/block-library/blocks/embed/editor-rtl.css 331 B
build/block-library/blocks/embed/editor.css 331 B
build/block-library/blocks/embed/style-rtl.css 419 B
build/block-library/blocks/embed/style.css 419 B
build/block-library/blocks/embed/theme-rtl.css 133 B
build/block-library/blocks/embed/theme.css 133 B
build/block-library/blocks/file/editor-rtl.css 326 B
build/block-library/blocks/file/editor.css 326 B
build/block-library/blocks/file/style-rtl.css 278 B
build/block-library/blocks/file/style.css 279 B
build/block-library/blocks/file/view.min.js 324 B
build/block-library/blocks/footnotes/style-rtl.css 198 B
build/block-library/blocks/footnotes/style.css 197 B
build/block-library/blocks/form-input/editor-rtl.css 229 B
build/block-library/blocks/form-input/editor.css 229 B
build/block-library/blocks/form-submission-notification/editor-rtl.css 344 B
build/block-library/blocks/form-submission-notification/editor.css 341 B
build/block-library/blocks/form-submit-button/style-rtl.css 69 B
build/block-library/blocks/form-submit-button/style.css 69 B
build/block-library/blocks/form/view.min.js 470 B
build/block-library/blocks/freeform/editor-rtl.css 2.6 kB
build/block-library/blocks/freeform/editor.css 2.6 kB
build/block-library/blocks/gallery/editor-rtl.css 955 B
build/block-library/blocks/gallery/editor.css 958 B
build/block-library/blocks/gallery/style-rtl.css 1.83 kB
build/block-library/blocks/gallery/style.css 1.82 kB
build/block-library/blocks/gallery/theme-rtl.css 108 B
build/block-library/blocks/gallery/theme.css 108 B
build/block-library/blocks/group/editor-rtl.css 333 B
build/block-library/blocks/group/editor.css 333 B
build/block-library/blocks/group/style-rtl.css 103 B
build/block-library/blocks/group/style.css 103 B
build/block-library/blocks/group/theme-rtl.css 79 B
build/block-library/blocks/group/theme.css 79 B
build/block-library/blocks/heading/style-rtl.css 188 B
build/block-library/blocks/heading/style.css 188 B
build/block-library/blocks/html/editor-rtl.css 346 B
build/block-library/blocks/html/editor.css 347 B
build/block-library/blocks/image/style-rtl.css 1.59 kB
build/block-library/blocks/image/style.css 1.59 kB
build/block-library/blocks/image/theme-rtl.css 137 B
build/block-library/blocks/image/theme.css 137 B
build/block-library/blocks/image/view.min.js 1.65 kB
build/block-library/blocks/latest-comments/style-rtl.css 355 B
build/block-library/blocks/latest-comments/style.css 354 B
build/block-library/blocks/latest-posts/editor-rtl.css 179 B
build/block-library/blocks/latest-posts/editor.css 179 B
build/block-library/blocks/latest-posts/style-rtl.css 509 B
build/block-library/blocks/latest-posts/style.css 510 B
build/block-library/blocks/list/style-rtl.css 107 B
build/block-library/blocks/list/style.css 107 B
build/block-library/blocks/loginout/style-rtl.css 61 B
build/block-library/blocks/loginout/style.css 61 B
build/block-library/blocks/media-text/editor-rtl.css 321 B
build/block-library/blocks/media-text/editor.css 320 B
build/block-library/blocks/media-text/style-rtl.css 558 B
build/block-library/blocks/media-text/style.css 556 B
build/block-library/blocks/more/editor-rtl.css 427 B
build/block-library/blocks/more/editor.css 427 B
build/block-library/blocks/navigation-link/editor-rtl.css 644 B
build/block-library/blocks/navigation-link/editor.css 645 B
build/block-library/blocks/navigation-link/style-rtl.css 192 B
build/block-library/blocks/navigation-link/style.css 191 B
build/block-library/blocks/navigation-submenu/editor-rtl.css 295 B
build/block-library/blocks/navigation-submenu/editor.css 294 B
build/block-library/blocks/navigation/style-rtl.css 2.25 kB
build/block-library/blocks/navigation/style.css 2.23 kB
build/block-library/blocks/navigation/view.min.js 1.03 kB
build/block-library/blocks/nextpage/editor-rtl.css 392 B
build/block-library/blocks/nextpage/editor.css 392 B
build/block-library/blocks/page-list/editor-rtl.css 378 B
build/block-library/blocks/page-list/editor.css 378 B
build/block-library/blocks/page-list/style-rtl.css 175 B
build/block-library/blocks/page-list/style.css 175 B
build/block-library/blocks/paragraph/editor-rtl.css 236 B
build/block-library/blocks/paragraph/editor.css 236 B
build/block-library/blocks/paragraph/style-rtl.css 341 B
build/block-library/blocks/paragraph/style.css 340 B
build/block-library/blocks/post-author-biography/style-rtl.css 74 B
build/block-library/blocks/post-author-biography/style.css 74 B
build/block-library/blocks/post-author-name/style-rtl.css 69 B
build/block-library/blocks/post-author-name/style.css 69 B
build/block-library/blocks/post-author/editor-rtl.css 107 B
build/block-library/blocks/post-author/editor.css 107 B
build/block-library/blocks/post-author/style-rtl.css 188 B
build/block-library/blocks/post-author/style.css 189 B
build/block-library/blocks/post-comments-form/editor-rtl.css 96 B
build/block-library/blocks/post-comments-form/editor.css 96 B
build/block-library/blocks/post-comments-form/style-rtl.css 527 B
build/block-library/blocks/post-comments-form/style.css 528 B
build/block-library/blocks/post-content/editor-rtl.css 74 B
build/block-library/blocks/post-content/editor.css 74 B
build/block-library/blocks/post-content/style-rtl.css 79 B
build/block-library/blocks/post-content/style.css 79 B
build/block-library/blocks/post-date/style-rtl.css 62 B
build/block-library/blocks/post-date/style.css 62 B
build/block-library/blocks/post-excerpt/editor-rtl.css 71 B
build/block-library/blocks/post-excerpt/editor.css 71 B
build/block-library/blocks/post-excerpt/style-rtl.css 155 B
build/block-library/blocks/post-excerpt/style.css 155 B
build/block-library/blocks/post-featured-image/editor-rtl.css 729 B
build/block-library/blocks/post-featured-image/editor.css 726 B
build/block-library/blocks/post-featured-image/style-rtl.css 347 B
build/block-library/blocks/post-featured-image/style.css 347 B
build/block-library/blocks/post-navigation-link/style-rtl.css 215 B
build/block-library/blocks/post-navigation-link/style.css 214 B
build/block-library/blocks/post-template/editor-rtl.css 99 B
build/block-library/blocks/post-template/editor.css 98 B
build/block-library/blocks/post-template/style-rtl.css 399 B
build/block-library/blocks/post-template/style.css 398 B
build/block-library/blocks/post-terms/style-rtl.css 96 B
build/block-library/blocks/post-terms/style.css 96 B
build/block-library/blocks/post-time-to-read/style-rtl.css 70 B
build/block-library/blocks/post-time-to-read/style.css 70 B
build/block-library/blocks/post-title/style-rtl.css 226 B
build/block-library/blocks/post-title/style.css 226 B
build/block-library/blocks/preformatted/style-rtl.css 125 B
build/block-library/blocks/preformatted/style.css 125 B
build/block-library/blocks/pullquote/editor-rtl.css 134 B
build/block-library/blocks/pullquote/editor.css 134 B
build/block-library/blocks/pullquote/style-rtl.css 342 B
build/block-library/blocks/pullquote/style.css 342 B
build/block-library/blocks/pullquote/theme-rtl.css 167 B
build/block-library/blocks/pullquote/theme.css 167 B
build/block-library/blocks/query-pagination-numbers/editor-rtl.css 121 B
build/block-library/blocks/query-pagination-numbers/editor.css 118 B
build/block-library/blocks/query-pagination/editor-rtl.css 154 B
build/block-library/blocks/query-pagination/editor.css 154 B
build/block-library/blocks/query-pagination/style-rtl.css 237 B
build/block-library/blocks/query-pagination/style.css 237 B
build/block-library/blocks/query-title/style-rtl.css 64 B
build/block-library/blocks/query-title/style.css 64 B
build/block-library/blocks/query/editor-rtl.css 452 B
build/block-library/blocks/query/editor.css 451 B
build/block-library/blocks/query/view.min.js 958 B
build/block-library/blocks/quote/style-rtl.css 238 B
build/block-library/blocks/quote/style.css 238 B
build/block-library/blocks/quote/theme-rtl.css 233 B
build/block-library/blocks/quote/theme.css 236 B
build/block-library/blocks/read-more/style-rtl.css 138 B
build/block-library/blocks/read-more/style.css 138 B
build/block-library/blocks/rss/editor-rtl.css 101 B
build/block-library/blocks/rss/editor.css 101 B
build/block-library/blocks/rss/style-rtl.css 288 B
build/block-library/blocks/rss/style.css 287 B
build/block-library/blocks/search/editor-rtl.css 199 B
build/block-library/blocks/search/editor.css 199 B
build/block-library/blocks/search/style-rtl.css 672 B
build/block-library/blocks/search/style.css 671 B
build/block-library/blocks/search/theme-rtl.css 113 B
build/block-library/blocks/search/theme.css 113 B
build/block-library/blocks/search/view.min.js 475 B
build/block-library/blocks/separator/editor-rtl.css 100 B
build/block-library/blocks/separator/editor.css 100 B
build/block-library/blocks/separator/style-rtl.css 248 B
build/block-library/blocks/separator/style.css 248 B
build/block-library/blocks/separator/theme-rtl.css 195 B
build/block-library/blocks/separator/theme.css 195 B
build/block-library/blocks/shortcode/editor-rtl.css 286 B
build/block-library/blocks/shortcode/editor.css 286 B
build/block-library/blocks/site-logo/editor-rtl.css 806 B
build/block-library/blocks/site-logo/editor.css 803 B
build/block-library/blocks/site-logo/style-rtl.css 218 B
build/block-library/blocks/site-logo/style.css 218 B
build/block-library/blocks/site-tagline/editor-rtl.css 87 B
build/block-library/blocks/site-tagline/editor.css 87 B
build/block-library/blocks/site-tagline/style-rtl.css 65 B
build/block-library/blocks/site-tagline/style.css 65 B
build/block-library/blocks/site-title/editor-rtl.css 85 B
build/block-library/blocks/site-title/editor.css 85 B
build/block-library/blocks/site-title/style-rtl.css 206 B
build/block-library/blocks/site-title/style.css 206 B
build/block-library/blocks/social-link/editor-rtl.css 338 B
build/block-library/blocks/social-link/editor.css 338 B
build/block-library/blocks/social-links/editor-rtl.css 757 B
build/block-library/blocks/social-links/editor.css 756 B
build/block-library/blocks/social-links/style-rtl.css 1.51 kB
build/block-library/blocks/social-links/style.css 1.5 kB
build/block-library/blocks/spacer/editor-rtl.css 346 B
build/block-library/blocks/spacer/editor.css 346 B
build/block-library/blocks/spacer/style-rtl.css 48 B
build/block-library/blocks/spacer/style.css 48 B
build/block-library/blocks/table-of-contents/style-rtl.css 83 B
build/block-library/blocks/table-of-contents/style.css 83 B
build/block-library/blocks/table/editor-rtl.css 394 B
build/block-library/blocks/table/editor.css 394 B
build/block-library/blocks/table/style-rtl.css 640 B
build/block-library/blocks/table/style.css 639 B
build/block-library/blocks/table/theme-rtl.css 152 B
build/block-library/blocks/table/theme.css 152 B
build/block-library/blocks/tag-cloud/editor-rtl.css 144 B
build/block-library/blocks/tag-cloud/editor.css 144 B
build/block-library/blocks/tag-cloud/style-rtl.css 266 B
build/block-library/blocks/tag-cloud/style.css 265 B
build/block-library/blocks/template-part/editor-rtl.css 368 B
build/block-library/blocks/template-part/editor.css 368 B
build/block-library/blocks/template-part/theme-rtl.css 113 B
build/block-library/blocks/template-part/theme.css 113 B
build/block-library/blocks/term-description/style-rtl.css 126 B
build/block-library/blocks/term-description/style.css 126 B
build/block-library/blocks/text-columns/editor-rtl.css 95 B
build/block-library/blocks/text-columns/editor.css 95 B
build/block-library/blocks/text-columns/style-rtl.css 165 B
build/block-library/blocks/text-columns/style.css 165 B
build/block-library/blocks/verse/style-rtl.css 98 B
build/block-library/blocks/verse/style.css 98 B
build/block-library/blocks/video/editor-rtl.css 396 B
build/block-library/blocks/video/editor.css 397 B
build/block-library/blocks/video/style-rtl.css 192 B
build/block-library/blocks/video/style.css 192 B
build/block-library/blocks/video/theme-rtl.css 134 B
build/block-library/blocks/video/theme.css 134 B
build/block-library/classic-rtl.css 179 B
build/block-library/classic.css 179 B
build/block-library/common-rtl.css 1.1 kB
build/block-library/common.css 1.1 kB
build/block-library/editor-elements-rtl.css 75 B
build/block-library/editor-elements.css 75 B
build/block-library/elements-rtl.css 54 B
build/block-library/elements.css 54 B
build/block-library/reset-rtl.css 472 B
build/block-library/reset.css 472 B
build/block-library/theme-rtl.css 708 B
build/block-library/theme.css 712 B
build/block-serialization-default-parser/index.min.js 1.12 kB
build/block-serialization-spec-parser/index.min.js 2.87 kB
build/blocks/index.min.js 52.3 kB
build/commands/style-rtl.css 955 B
build/commands/style.css 952 B
build/core-commands/index.min.js 2.82 kB
build/customize-widgets/style-rtl.css 1.35 kB
build/customize-widgets/style.css 1.35 kB
build/data-controls/index.min.js 641 B
build/date/index.min.js 18 kB
build/deprecated/index.min.js 458 B
build/dom-ready/index.min.js 325 B
build/dom/index.min.js 4.66 kB
build/edit-post/classic-rtl.css 578 B
build/edit-post/classic.css 580 B
build/edit-post/style-rtl.css 2.31 kB
build/edit-post/style.css 2.31 kB
build/edit-widgets/style-rtl.css 4.2 kB
build/edit-widgets/style.css 4.2 kB
build/element/index.min.js 4.83 kB
build/escape-html/index.min.js 537 B
build/format-library/index.min.js 8.11 kB
build/format-library/style-rtl.css 476 B
build/format-library/style.css 476 B
build/hooks/index.min.js 1.54 kB
build/html-entities/index.min.js 445 B
build/i18n/index.min.js 3.58 kB
build/is-shallow-equal/index.min.js 526 B
build/keyboard-shortcuts/index.min.js 1.31 kB
build/keycodes/index.min.js 1.46 kB
build/list-reusable-blocks/index.min.js 2.18 kB
build/list-reusable-blocks/style-rtl.css 846 B
build/list-reusable-blocks/style.css 846 B
build/media-utils/index.min.js 3.2 kB
build/notices/index.min.js 946 B
build/nux/index.min.js 1.61 kB
build/nux/style-rtl.css 749 B
build/nux/style.css 745 B
build/patterns/index.min.js 7.34 kB
build/patterns/style-rtl.css 687 B
build/patterns/style.css 685 B
build/plugins/index.min.js 1.81 kB
build/preferences-persistence/index.min.js 2.06 kB
build/preferences/style-rtl.css 554 B
build/preferences/style.css 554 B
build/primitives/index.min.js 829 B
build/priority-queue/index.min.js 1.54 kB
build/react-i18n/index.min.js 630 B
build/react-refresh-entry/index.min.js 9.47 kB
build/react-refresh-runtime/index.min.js 6.76 kB
build/redux-routine/index.min.js 2.69 kB
build/reusable-blocks/index.min.js 2.55 kB
build/reusable-blocks/style-rtl.css 256 B
build/reusable-blocks/style.css 256 B
build/rich-text/index.min.js 10.1 kB
build/router/index.min.js 1.96 kB
build/server-side-render/index.min.js 1.94 kB
build/shortcode/index.min.js 1.4 kB
build/style-engine/index.min.js 2.04 kB
build/token-list/index.min.js 581 B
build/url/index.min.js 3.9 kB
build/vendors/react-jsx-runtime.min.js 560 B
build/vendors/react.min.js 4.02 kB
build/viewport/index.min.js 965 B
build/warning/index.min.js 250 B
build/widgets/style-rtl.css 1.16 kB
build/widgets/style.css 1.16 kB
build/wordcount/index.min.js 1.03 kB

compressed-size-action

@SantosGuillamot
Copy link
Contributor

Personally, I don't feel comfortable hardcoding something that just works for the paragraph. If it is the __experimentalLabel setting what we need to change, maybe we can filter that with the existing hook or a new one. I haven't looked into that.

@artemiomorales
Copy link
Contributor Author

I assume this is going to be the case for other blocks and attributes. For example, does this happen with the heading content or the button text?

@SantosGuillamot This indeed happens with the heading block.
We don't currently announce the text content of button blocks in navigation mode, though.

If that's the case, I believe we probably need to think about it more broadly and solve it for any block attribute, potentially using the bound value instead of a default message.

If it's just the paragraph and heading, do you think that warrants a broader solution?

Potentially we could intervene at an earlier level. For example, this is where the __experimentalLabel gets read. Potentially we could check for bindings at this stage and modify the label accordingly:

/**
* Get the label for the block, usually this is either the block title,
* or the value of the block's `label` function when that's specified.
*
* @param {Object} blockType The block type.
* @param {Object} attributes The values of the block's attributes.
* @param {Object} context The intended use for the label.
*
* @return {string} The block label.
*/
export function getBlockLabel( blockType, attributes, context = 'visual' ) {
const { __experimentalLabel: getLabel, title } = blockType;
const label = getLabel && getLabel( attributes, { context } );
if ( ! label ) {
return title;
}
if ( label.toPlainText ) {
return label.toPlainText();
}
// Strip any HTML (i.e. RichText formatting) before returning.
return stripHTML( label );
}

@artemiomorales artemiomorales added the Needs Accessibility Feedback Need input from accessibility label Sep 6, 2024
@SantosGuillamot
Copy link
Contributor

We don't currently announce the text content of button blocks in navigation mode, though.
If it's just the paragraph and heading, do you think that warrants a broader solution?

Is it expected or it is just because we aren't passing __experimentalLabel to the button block?

I'm not familiar with this part of the codebase, but I guess we will encounter this problem for any block using __experimentalLabel, so I'd try to fix the root of the problem, not adding a workaround for the use cases we have identified.

For example, it seems it is also used in the image block: link. I haven't tested it, but maybe there is the same problem there.

There are already a bunch of blocks relying on that, and it could even create more issues when we add support for more blocks.

Looking at the getBlockLabel and getBlockAccessibilityLabel seems like a good starting point.

@artemiomorales
Copy link
Contributor Author

artemiomorales commented Sep 9, 2024

Is it expected or it is just because we aren't passing __experimentalLabel to the button block?

I believe it's because __experimentalLabel hasn't been defined for the button block.

I'm not familiar with this part of the codebase, but I guess we will encounter this problem for any block using __experimentalLabel, so I'd try to fix the root of the problem, not adding a workaround for the use cases we have identified.

Ok I've started looking at devising a general solution for this.

For example, it seems it is also used in the image block: link. I haven't tested it, but maybe there is the same problem there.

Yes, the same problem exists with the image block, except that the image uses the alt attribute rather than a content attribute to create the label.

Copy link

github-actions bot commented Sep 9, 2024

Flaky tests detected in 38eb29c.
Some tests passed with failed attempts. The failures may not be related to this commit but are still reported for visibility. See the documentation for more information.

🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/10786914084
📝 Reported issues:

function labelWithBlockBindings( settings ) {
return ( attributes, { context } ) => {
if ( attributes?.metadata?.bindings && context === 'accessibility' ) {
return 'Overriding label';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For now, I just check whether the paragraph is bound and, if so, return the label Paragraph with dynamic content.

Is Overriding label a leftover added for testing? In any case, it should be translatable.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the feedback! Rather than hardcoding this, I've now modified the PR so it reads the actual bindings values. I've updated the PR description accordingly.

afercia
afercia previously requested changes Sep 9, 2024
Copy link
Contributor

@afercia afercia left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please see my last comment.

@artemiomorales artemiomorales changed the title Block Bindings: Update label for bound paragraphs Block Bindings: Update label for bound paragraphs and headings Sep 13, 2024
@artemiomorales
Copy link
Contributor Author

artemiomorales commented Sep 13, 2024

Update: I've revised the PR so that it retrieves the actual bindings value and uses it for the label. The PR description has been updated accordingly.

Note that pattern overrides required some additional handling. I explore a solution in #65302, which is meant to accompany this PR or be merged shortly after.

@talldan talldan dismissed afercia’s stale review September 18, 2024 15:31

Feedback was addressed

@SantosGuillamot
Copy link
Contributor

I didn't find time to properly review this yet (it's on my to-do list). But there are a couple of things I wanted to ask:

  • Why do we need a different solution for pattern overrides? Is this going to be a problem for other registered sources? If that's the case, I wonder if we are solving the root of the problem.
  • Did we explore the possibility of using the bindings value in getBlockLabel and getBlockAccessibilityLabel?

@artemiomorales
Copy link
Contributor Author

artemiomorales commented Sep 27, 2024

@SantosGuillamot As far as I can tell, this is root of the problem: The block bindings hook in use-bindings-attributes.js overwrites the regular attributes with the bindings values in the BlockEdit component, and because the BlockSelectionButton exists at a different level of the hierarchy outside of the block edit context, the computed bindings information isn't easily available to it.

Here's where the attributes are overridden in the BlockEdit component:

return (
<>
<BlockEdit
{ ...props }
attributes={ { ...props.attributes, ...boundAttributes } }
setAttributes={ _setAttributes }
/>
</>
);

Worth noting is that BlockEdit is a context provider:

<BlockEditContextProvider
// It is important to return the same object if props haven't
// changed to avoid unnecessary rerenders.
// See https://reactjs.org/docs/context.html#caveats.
value={ useMemo(
() => ( {
name,
isSelected,
clientId,
layout: layoutSupport ? layout : null,
__unstableLayoutClassNames,
// We use symbols in favour of an __unstable prefix to avoid
// usage outside of the package (this context is exposed).
[ mayDisplayControlsKey ]: mayDisplayControls,
[ mayDisplayParentControlsKey ]: mayDisplayParentControls,
[ blockEditingModeKey ]: blockEditingMode,
[ blockBindingsKey ]: bindings,
[ isPreviewModeKey ]: isPreviewMode,
} ),
[
name,
isSelected,
clientId,
layoutSupport,
layout,
__unstableLayoutClassNames,
mayDisplayControls,
mayDisplayParentControls,
blockEditingMode,
bindings,
isPreviewMode,
]
) }
>
<Edit { ...props } />
{ originalBlockClientId && (
<MultipleUsageWarning
originalBlockClientId={ originalBlockClientId }
name={ name }
onReplace={ props.onReplace }
/>
) }
</BlockEditContextProvider>

Both attributes and setAttributes are passed to BlockEdit inside the BlockList component:

let blockEdit = (
<BlockEdit
name={ name }
isSelected={ isSelected }
attributes={ attributes }
setAttributes={ setAttributes }
insertBlocksAfter={ isLocked ? undefined : onInsertBlocksAfter }
onReplace={ canRemove ? onReplace : undefined }
onRemove={ canRemove ? onRemove : undefined }
mergeBlocks={ canRemove ? onMerge : undefined }
clientId={ clientId }
isSelectionEnabled={ isSelectionEnabled }
toggleSelection={ toggleSelection }
__unstableLayoutClassNames={ layoutClassNames }
__unstableParentLayout={
Object.keys( parentLayout ).length ? parentLayout : undefined
}
mayDisplayControls={ mayDisplayControls }
mayDisplayParentControls={ mayDisplayParentControls }
blockEditingMode={ context.blockEditingMode }
isPreviewMode={ context.isPreviewMode }
/>
);

And the BlockList component is rendered inside of BlockCanvas:

export function ExperimentalBlockCanvas( {
shouldIframe = true,
height = '300px',
children = <BlockList />,
styles,
contentRef: contentRefProp,
iframeProps,
} ) {
useBlockCommands();
const resetTypingRef = useMouseMoveTypingReset();
const clearerRef = useBlockSelectionClearer();
const localRef = useRef();
const contentRef = useMergeRefs( [ contentRefProp, clearerRef, localRef ] );
if ( ! shouldIframe ) {
return (
<BlockTools
__unstableContentRef={ localRef }
style={ { height, display: 'flex' } }
>
<EditorStyles
styles={ styles }
scope=":where(.editor-styles-wrapper)"
transformOptions={ EDITOR_STYLE_TRANSFORM_OPTIONS }
/>
<WritingFlow
ref={ contentRef }
className="editor-styles-wrapper"
tabIndex={ -1 }
style={ {
height: '100%',
width: '100%',
} }
>
{ children }
</WritingFlow>
</BlockTools>
);
}
return (
<BlockTools
__unstableContentRef={ localRef }
style={ { height, display: 'flex' } }
>
<Iframe
{ ...iframeProps }
ref={ resetTypingRef }
contentRef={ contentRef }
style={ {
...iframeProps?.style,
} }
name="editor-canvas"
>
<EditorStyles styles={ styles } />
{ children }
</Iframe>
</BlockTools>
);
}

The BlockSelectionButton is part of BlockTools, which, as you can see in the snippet above, exists at a higher level than the BlockList. What we need to do is make the bound attributes available at that level.

To solve this, we could potentially refactor to wrap the BlockTools in another context provider, and use that to store the computed bindings values. Either that or refactor the BlockEdit component. That was my first thought, though it seems like it could get involved.

Another option, like I've done here, is to replicate the logic to compute the bindings values in the BlockSelectionButton. (This approach comes via a quick suggestion from @ellatrix — no need to join the conversation Ella, just pinging for awareness and in case you're interested in taking a look).

Why do we need a different solution for pattern overrides? Is this going to be a problem for other registered sources? If that's the case, I wonder if we are solving the root of the problem.

It's not really a different solution — it's essentially replicating the logic that we normally use in use-bindings-attributes.js to retrieve the overrides. There is a small detail with priority in how we're reading the custom name versus the block content for the label, but overall I just handled the patterns in a separate PR to make everything easier to parse.

As far as other registered sources goes, this issue with the label is currently specific to sources that override the content attribute in paragraphs and headings. As long as we pass the updated attributes computed via the normal bindings logic to getBlockAccessibilityLabel, then it should work as intended.

Did we explore the possibility of using the bindings value in getBlockLabel and getBlockAccessibilityLabel?

getBlockLabel and getBlockAccessibilityLabel are utils that use the block attributes to create a label, so I don't think it's appropriate to extend them to read the bindings values. Instead, I think it makes sense to pass the right attributes to them so they work as intended.

So in summary, I see two solutions:

  1. Somehow share the computed value of the bindings in use-bindings-attributes.js with BlockTools (which may require refactoring of where and how we define block context)
  2. Just recompute the bindings values for the BlockSelectionButton

Perhaps there's an easy way to do the first approach, though I just wanted to get this working and keep iterating, and I didn't want to go down that potential rabbit hole unless we felt it was necessary. I could be off base here, though. Would be happy to hear any additional thoughts or insights 🙏

@SantosGuillamot
Copy link
Contributor

I've been trying to test the original issue and consequently the potential fix, but it seems the navigation mode was removed in this pull request. More context can be found in this other issue, where a new mechanism is being discussed.

Having said that, I think this raises again the discussion about when to use the original block attributes and when to use the binding values. You can find more information in this old pull request, where that possibility was explored. My gut says we need to provide a way to let developers decide if they want to use the binding values or the original attributes, but the use cases weren't clear at that moment. This could be done via a new selector or even accepting a new parameter in getBlockAttributes. Anyway, that need to be explored and done carefully.

@artemiomorales
Copy link
Contributor Author

I've been trying to test the original issue and consequently the potential fix, but it seems the navigation mode was removed in #65204. More context can be found in #65603, where a new mechanism is being discussed.

Ok, on one hand, we could try to land this in core then, but any effort invested into a solution likely won't be viable for more than one release. I think we should see what the new mechanism ends up being before investing more time into this.

My gut says we need to provide a way to let developers decide if they want to use the binding values or the original attributes, but the use cases weren't clear at that moment. This could be done via a new selector or even accepting a new parameter in getBlockAttributes. Anyway, that need to be explored and done carefully.

I think we could potentially offer the developers a way to customize what's used for the label, but what would the sensible default be? I think creating a label like, "{Name of attribute}: {Binding value}" could work well in the majority of cases. I can't say that for sure, though any approach we take would likely be better than the current one with post meta, where it just reads the original content.

@SantosGuillamot
Copy link
Contributor

I may be wrong here but, if I remember this particular issue was only a problem for the Navigation mode, right? I think it was working fine in my tests in other modes.

When I said "provide a way to let developers decide if they want to use the binding values or the original attributes" I wasn't referring to letting them decide the label discussed in this particular issue, I was referring to providing a method to let any developer, in any part of the code, decide if they want to use the original attributes or the values of the bindings.

@artemiomorales
Copy link
Contributor Author

I may be wrong here but, if I remember this particular issue was only a problem for the Navigation mode, right? I think it was working fine in my tests in other modes.

Right, since Navigation Move has been removed, then this PR is no longer relevant. Keyboard navigation no longer works well in the editor, but that's a bigger issue than just block bindings.

When I said "provide a way to let developers decide if they want to use the binding values or the original attributes" I wasn't referring to letting them decide the label discussed in this particular issue, I was referring to providing a method to let any developer, in any part of the code, decide if they want to use the original attributes or the values of the bindings.

I think we're both in agreement here; I was just thinking of what a good default would be.

In any case, I'm going to close this. We can continue the conversation at a later date if it becomes relevant.

@gziolo gziolo deleted the fix/bound-block-screenreader branch November 14, 2024 21:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Block bindings Needs Accessibility Feedback Need input from accessibility [Type] Bug An existing feature does not function as intended
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Block Bindings: Improve accessibility of bound paragraphs when using a screenreader in Navigation Mode
4 participants