From 4a4bd4a15f8e73d2591ccea39c9830f76b43501f Mon Sep 17 00:00:00 2001 From: Daniel Richards Date: Mon, 2 Dec 2019 16:11:23 +0800 Subject: [PATCH] Add table block caption (#15554) * Initial attempt at table block caption Try using a figcaption for the table caption Revert "Try using a figcaption for the table caption" Switch back to a standard table caption This reverts commit b5f00ddfb3bba0f4f2356bfe83e78e75932ded48. Add comment explaining location of RichText Ensure table cell is deselected when navigating from a table cell to the caption Styling tweaks Add an inline toolbar to the caption to match the image block implementation Adjust margin to match image block Add e2e test for the table block caption Refine caption accessibility. Use a div for the caption content Update caption to use a figcaption element with aria-labelledby Update table block deprecation so that it has its own attribute definition Update existing fixtures and add a new fixture for table captions Minor refinements Fix hasCaption logic Update snapshots Update comment with latest understanding of issue Use client id to generate non-clashing caption element id Update block-transforms fixture Update test to use a regular expression * Reuse the captionId when already set as an attribute * Change style rule to use figcaption selector * Explain use of aria-labelledby * Update deprecation * Use RichText for figcaption, strip out a11y hacks * Ensure empty classname is not output onto table element and update snapshots * Update raw handling test * Revert "Update raw handling test" This reverts commit f3ae75194873ba8e72aa8980194bbe054dc75719. * Revert "Ensure empty classname is not output onto table element and update snapshots" This reverts commit 0265104ecd3741f0a9ee98e6c337250a097e0011. * Update table caption fixtures and deprecations --- packages/block-library/src/table/block.json | 6 + .../block-library/src/table/deprecated.js | 105 ++++++++++++- packages/block-library/src/table/edit.js | 17 +- packages/block-library/src/table/editor.scss | 6 + packages/block-library/src/table/save.js | 9 ++ packages/block-library/src/table/theme.scss | 4 + .../e2e-tests/fixtures/block-transforms.js | 6 + .../fixtures/blocks/core__table.json | 1 + .../fixtures/blocks/core__table__caption.html | 3 + .../fixtures/blocks/core__table__caption.json | 146 ++++++++++++++++++ .../blocks/core__table__caption.parsed.json | 20 +++ .../core__table__caption.serialized.html | 3 + .../blocks/core__table__scope-attribute.json | 1 + .../blocks/__snapshots__/table.test.js.snap | 6 + .../specs/editor/blocks/table.test.js | 13 ++ 15 files changed, 339 insertions(+), 7 deletions(-) create mode 100644 packages/e2e-tests/fixtures/blocks/core__table__caption.html create mode 100644 packages/e2e-tests/fixtures/blocks/core__table__caption.json create mode 100644 packages/e2e-tests/fixtures/blocks/core__table__caption.parsed.json create mode 100644 packages/e2e-tests/fixtures/blocks/core__table__caption.serialized.html diff --git a/packages/block-library/src/table/block.json b/packages/block-library/src/table/block.json index 539c4df88ab7c..d5e52c7de813d 100644 --- a/packages/block-library/src/table/block.json +++ b/packages/block-library/src/table/block.json @@ -9,6 +9,12 @@ "backgroundColor": { "type": "string" }, + "caption": { + "type": "string", + "source": "html", + "selector": "figcaption", + "default": "" + }, "head": { "type": "array", "default": [], diff --git a/packages/block-library/src/table/deprecated.js b/packages/block-library/src/table/deprecated.js index 79fc5726ea23f..1dd641db9bc07 100644 --- a/packages/block-library/src/table/deprecated.js +++ b/packages/block-library/src/table/deprecated.js @@ -8,18 +8,111 @@ import classnames from 'classnames'; */ import { RichText, getColorClassName } from '@wordpress/block-editor'; -/** - * Internal dependencies - */ -import metadata from './block.json'; - const supports = { align: true, }; const deprecated = [ { - attributes: metadata.attributes, + attributes: { + hasFixedLayout: { + type: 'boolean', + default: false, + }, + backgroundColor: { + type: 'string', + }, + head: { + type: 'array', + default: [], + source: 'query', + selector: 'thead tr', + query: { + cells: { + type: 'array', + default: [], + source: 'query', + selector: 'td,th', + query: { + content: { + type: 'string', + source: 'html', + }, + tag: { + type: 'string', + default: 'td', + source: 'tag', + }, + scope: { + type: 'string', + source: 'attribute', + attribute: 'scope', + }, + }, + }, + }, + }, + body: { + type: 'array', + default: [], + source: 'query', + selector: 'tbody tr', + query: { + cells: { + type: 'array', + default: [], + source: 'query', + selector: 'td,th', + query: { + content: { + type: 'string', + source: 'html', + }, + tag: { + type: 'string', + default: 'td', + source: 'tag', + }, + scope: { + type: 'string', + source: 'attribute', + attribute: 'scope', + }, + }, + }, + }, + }, + foot: { + type: 'array', + default: [], + source: 'query', + selector: 'tfoot tr', + query: { + cells: { + type: 'array', + default: [], + source: 'query', + selector: 'td,th', + query: { + content: { + type: 'string', + source: 'html', + }, + tag: { + type: 'string', + default: 'td', + source: 'tag', + }, + scope: { + type: 'string', + source: 'attribute', + attribute: 'scope', + }, + }, + }, + }, + }, + }, supports, save( { attributes } ) { const { diff --git a/packages/block-library/src/table/edit.js b/packages/block-library/src/table/edit.js index 1599bb7e53f64..b2aa14dbfea7d 100644 --- a/packages/block-library/src/table/edit.js +++ b/packages/block-library/src/table/edit.js @@ -483,9 +483,16 @@ export class TableEdit extends Component { className, backgroundColor, setBackgroundColor, + setAttributes, } = this.props; const { initialRowCount, initialColumnCount } = this.state; - const { hasFixedLayout, head, body, foot } = attributes; + const { + hasFixedLayout, + caption, + head, + body, + foot, + } = attributes; const isEmpty = isEmptyTableSection( head ) && isEmptyTableSection( body ) && isEmptyTableSection( foot ); const Section = this.renderSection; @@ -582,6 +589,14 @@ export class TableEdit extends Component {
+ setAttributes( { caption: value } ) } + // Deselect the selected table cell when the caption is focused. + unstableOnFocus={ () => this.setState( { selectedCell: null } ) } + /> ); diff --git a/packages/block-library/src/table/editor.scss b/packages/block-library/src/table/editor.scss index 16002aa4dbaae..195144afe1be7 100644 --- a/packages/block-library/src/table/editor.scss +++ b/packages/block-library/src/table/editor.scss @@ -51,11 +51,17 @@ text-align: left; align-items: center; } + &__placeholder-input { width: 100px; } + &__placeholder-button { min-width: 100px; justify-content: center; } + + figcaption { + @include caption-style-theme(); + } } diff --git a/packages/block-library/src/table/save.js b/packages/block-library/src/table/save.js index 0911f20fe85bf..fc661fd614882 100644 --- a/packages/block-library/src/table/save.js +++ b/packages/block-library/src/table/save.js @@ -15,6 +15,7 @@ export default function save( { attributes } ) { body, foot, backgroundColor, + caption, } = attributes; const isEmpty = ! head.length && ! body.length && ! foot.length; @@ -29,6 +30,8 @@ export default function save( { attributes } ) { 'has-background': !! backgroundClass, } ); + const hasCaption = ! RichText.isEmpty( caption ); + const Section = ( { type, rows } ) => { if ( ! rows.length ) { return null; @@ -69,6 +72,12 @@ export default function save( { attributes } ) {
+ { hasCaption && ( + + ) } ); } diff --git a/packages/block-library/src/table/theme.scss b/packages/block-library/src/table/theme.scss index 664a4f57cf53d..9c0158c6b5c69 100644 --- a/packages/block-library/src/table/theme.scss +++ b/packages/block-library/src/table/theme.scss @@ -7,4 +7,8 @@ border: 1px solid; word-break: normal; } + + figcaption { + @include caption-style-theme(); + } } diff --git a/packages/e2e-tests/fixtures/block-transforms.js b/packages/e2e-tests/fixtures/block-transforms.js index 1b3aee829d156..380d8f86cdf4c 100644 --- a/packages/e2e-tests/fixtures/block-transforms.js +++ b/packages/e2e-tests/fixtures/block-transforms.js @@ -724,6 +724,12 @@ export const EXPECTED_TRANSFORMS = { 'Group', ], }, + core__table__caption: { + originalBlock: 'Table', + availableTransforms: [ + 'Group', + ], + }, 'core__table__scope-attribute': { originalBlock: 'Table', availableTransforms: [ diff --git a/packages/e2e-tests/fixtures/blocks/core__table.json b/packages/e2e-tests/fixtures/blocks/core__table.json index 3318420a516b3..e2a7660f63473 100644 --- a/packages/e2e-tests/fixtures/blocks/core__table.json +++ b/packages/e2e-tests/fixtures/blocks/core__table.json @@ -5,6 +5,7 @@ "isValid": true, "attributes": { "hasFixedLayout": false, + "caption": "", "head": [ { "cells": [ diff --git a/packages/e2e-tests/fixtures/blocks/core__table__caption.html b/packages/e2e-tests/fixtures/blocks/core__table__caption.html new file mode 100644 index 0000000000000..999504d7f2d6b --- /dev/null +++ b/packages/e2e-tests/fixtures/blocks/core__table__caption.html @@ -0,0 +1,3 @@ + +
VersionMusicianDate
.70No musician chosen.May 27, 2003
1.0Miles DavisJanuary 3, 2004
Lots of versions skipped, see the full list
4.4Clifford BrownDecember 8, 2015
4.5Coleman HawkinsApril 12, 2016
4.6Pepper AdamsAugust 16, 2016
4.7Sarah VaughanDecember 6, 2016
A table for testing
+ diff --git a/packages/e2e-tests/fixtures/blocks/core__table__caption.json b/packages/e2e-tests/fixtures/blocks/core__table__caption.json new file mode 100644 index 0000000000000..9c566a0cd15da --- /dev/null +++ b/packages/e2e-tests/fixtures/blocks/core__table__caption.json @@ -0,0 +1,146 @@ +[ + { + "clientId": "_clientId_0", + "name": "core/table", + "isValid": true, + "attributes": { + "hasFixedLayout": false, + "caption": "A table for testing", + "head": [ + { + "cells": [ + { + "content": "Version", + "tag": "th" + }, + { + "content": "Musician", + "tag": "th" + }, + { + "content": "Date", + "tag": "th" + } + ] + } + ], + "body": [ + { + "cells": [ + { + "content": ".70", + "tag": "td" + }, + { + "content": "No musician chosen.", + "tag": "td" + }, + { + "content": "May 27, 2003", + "tag": "td" + } + ] + }, + { + "cells": [ + { + "content": "1.0", + "tag": "td" + }, + { + "content": "Miles Davis", + "tag": "td" + }, + { + "content": "January 3, 2004", + "tag": "td" + } + ] + }, + { + "cells": [ + { + "content": "Lots of versions skipped, see the full list", + "tag": "td" + }, + { + "content": "…", + "tag": "td" + }, + { + "content": "…", + "tag": "td" + } + ] + }, + { + "cells": [ + { + "content": "4.4", + "tag": "td" + }, + { + "content": "Clifford Brown", + "tag": "td" + }, + { + "content": "December 8, 2015", + "tag": "td" + } + ] + }, + { + "cells": [ + { + "content": "4.5", + "tag": "td" + }, + { + "content": "Coleman Hawkins", + "tag": "td" + }, + { + "content": "April 12, 2016", + "tag": "td" + } + ] + }, + { + "cells": [ + { + "content": "4.6", + "tag": "td" + }, + { + "content": "Pepper Adams", + "tag": "td" + }, + { + "content": "August 16, 2016", + "tag": "td" + } + ] + }, + { + "cells": [ + { + "content": "4.7", + "tag": "td" + }, + { + "content": "Sarah Vaughan", + "tag": "td" + }, + { + "content": "December 6, 2016", + "tag": "td" + } + ] + } + ], + "foot": [] + }, + "innerBlocks": [], + "originalContent": "
VersionMusicianDate
.70No musician chosen.May 27, 2003
1.0Miles DavisJanuary 3, 2004
Lots of versions skipped, see the full list
4.4Clifford BrownDecember 8, 2015
4.5Coleman HawkinsApril 12, 2016
4.6Pepper AdamsAugust 16, 2016
4.7Sarah VaughanDecember 6, 2016
A table for testing
" + } +] diff --git a/packages/e2e-tests/fixtures/blocks/core__table__caption.parsed.json b/packages/e2e-tests/fixtures/blocks/core__table__caption.parsed.json new file mode 100644 index 0000000000000..5e537c8dbaa6d --- /dev/null +++ b/packages/e2e-tests/fixtures/blocks/core__table__caption.parsed.json @@ -0,0 +1,20 @@ +[ + { + "blockName": "core/table", + "attrs": {}, + "innerBlocks": [], + "innerHTML": "\n
VersionMusicianDate
.70No musician chosen.May 27, 2003
1.0Miles DavisJanuary 3, 2004
Lots of versions skipped, see the full list
4.4Clifford BrownDecember 8, 2015
4.5Coleman HawkinsApril 12, 2016
4.6Pepper AdamsAugust 16, 2016
4.7Sarah VaughanDecember 6, 2016
A table for testing
\n", + "innerContent": [ + "\n
VersionMusicianDate
.70No musician chosen.May 27, 2003
1.0Miles DavisJanuary 3, 2004
Lots of versions skipped, see the full list
4.4Clifford BrownDecember 8, 2015
4.5Coleman HawkinsApril 12, 2016
4.6Pepper AdamsAugust 16, 2016
4.7Sarah VaughanDecember 6, 2016
A table for testing
\n" + ] + }, + { + "blockName": null, + "attrs": {}, + "innerBlocks": [], + "innerHTML": "\n", + "innerContent": [ + "\n" + ] + } +] diff --git a/packages/e2e-tests/fixtures/blocks/core__table__caption.serialized.html b/packages/e2e-tests/fixtures/blocks/core__table__caption.serialized.html new file mode 100644 index 0000000000000..0de976c2ab37a --- /dev/null +++ b/packages/e2e-tests/fixtures/blocks/core__table__caption.serialized.html @@ -0,0 +1,3 @@ + +
VersionMusicianDate
.70No musician chosen.May 27, 2003
1.0Miles DavisJanuary 3, 2004
Lots of versions skipped, see the full list
4.4Clifford BrownDecember 8, 2015
4.5Coleman HawkinsApril 12, 2016
4.6Pepper AdamsAugust 16, 2016
4.7Sarah VaughanDecember 6, 2016
A table for testing
+ diff --git a/packages/e2e-tests/fixtures/blocks/core__table__scope-attribute.json b/packages/e2e-tests/fixtures/blocks/core__table__scope-attribute.json index 23bb732aebff2..994fd2936de7a 100644 --- a/packages/e2e-tests/fixtures/blocks/core__table__scope-attribute.json +++ b/packages/e2e-tests/fixtures/blocks/core__table__scope-attribute.json @@ -5,6 +5,7 @@ "isValid": true, "attributes": { "hasFixedLayout": false, + "caption": "", "head": [ { "cells": [ diff --git a/packages/e2e-tests/specs/editor/blocks/__snapshots__/table.test.js.snap b/packages/e2e-tests/specs/editor/blocks/__snapshots__/table.test.js.snap index 1a7d08c1ff86f..876b7f9ef0263 100644 --- a/packages/e2e-tests/specs/editor/blocks/__snapshots__/table.test.js.snap +++ b/packages/e2e-tests/specs/editor/blocks/__snapshots__/table.test.js.snap @@ -1,5 +1,11 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`Table allows a caption to be added 1`] = ` +" +
Caption!
+" +`; + exports[`Table allows adding and deleting columns across the table header, body and footer 1`] = ` "
diff --git a/packages/e2e-tests/specs/editor/blocks/table.test.js b/packages/e2e-tests/specs/editor/blocks/table.test.js index 790ba0cd1ad7d..99c4a195e458b 100644 --- a/packages/e2e-tests/specs/editor/blocks/table.test.js +++ b/packages/e2e-tests/specs/editor/blocks/table.test.js @@ -232,4 +232,17 @@ describe( 'Table', () => { // Expect that the snapshot shows the text in the second cell. expect( await getEditedPostContent() ).toMatchSnapshot(); } ); + + it( 'allows a caption to be added', async () => { + await insertBlock( 'Table' ); + + // Create the table. + await clickButton( createButtonLabel ); + + // Click the first cell and add some text. + await page.click( '.wp-block-table figcaption' ); + await page.keyboard.type( 'Caption!' ); + + expect( await getEditedPostContent() ).toMatchSnapshot(); + } ); } );