diff --git a/package-lock.json b/package-lock.json index 9038a1037..64cac44b3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,7 +17,6 @@ "@material/card": "5.1.0", "@material/checkbox": "5.1.0", "@material/circular-progress": "7.0.0", - "@material/data-table": "5.1.0", "@material/dialog": "10.0.0", "@material/drawer": "5.1.0", "@material/floating-label": "5.1.0", @@ -4191,26 +4190,6 @@ "@material/feature-targeting": "^7.0.0" } }, - "node_modules/@material/data-table": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@material/data-table/-/data-table-5.1.0.tgz", - "integrity": "sha512-vjijTvCHM7sfyPzQ05026nSWT1Bn/3lfj1u0oeYRnym6Ke6Os36x+IF/jFhjsraXKb2we6cof7OdoMFHCU8cqQ==", - "dev": true, - "dependencies": { - "@material/animation": "^5.1.0", - "@material/base": "^5.1.0", - "@material/checkbox": "^5.1.0", - "@material/density": "^5.1.0", - "@material/dom": "^5.1.0", - "@material/elevation": "^5.1.0", - "@material/feature-targeting": "^5.1.0", - "@material/rtl": "^5.1.0", - "@material/shape": "^5.1.0", - "@material/theme": "^5.1.0", - "@material/typography": "^5.1.0", - "tslib": "^1.10.0" - } - }, "node_modules/@material/density": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/@material/density/-/density-5.1.0.tgz", @@ -48298,26 +48277,6 @@ } } }, - "@material/data-table": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@material/data-table/-/data-table-5.1.0.tgz", - "integrity": "sha512-vjijTvCHM7sfyPzQ05026nSWT1Bn/3lfj1u0oeYRnym6Ke6Os36x+IF/jFhjsraXKb2we6cof7OdoMFHCU8cqQ==", - "dev": true, - "requires": { - "@material/animation": "^5.1.0", - "@material/base": "^5.1.0", - "@material/checkbox": "^5.1.0", - "@material/density": "^5.1.0", - "@material/dom": "^5.1.0", - "@material/elevation": "^5.1.0", - "@material/feature-targeting": "^5.1.0", - "@material/rtl": "^5.1.0", - "@material/shape": "^5.1.0", - "@material/theme": "^5.1.0", - "@material/typography": "^5.1.0", - "tslib": "^1.10.0" - } - }, "@material/density": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/@material/density/-/density-5.1.0.tgz", diff --git a/package.json b/package.json index d270f83d2..1ce722576 100755 --- a/package.json +++ b/package.json @@ -32,7 +32,6 @@ "@material/card": "5.1.0", "@material/checkbox": "5.1.0", "@material/circular-progress": "7.0.0", - "@material/data-table": "5.1.0", "@material/dialog": "10.0.0", "@material/drawer": "5.1.0", "@material/floating-label": "5.1.0", diff --git a/plugin/assets/css/src/block-editor.css b/plugin/assets/css/src/block-editor.css index 5be0949be..4f435c4a0 100644 --- a/plugin/assets/css/src/block-editor.css +++ b/plugin/assets/css/src/block-editor.css @@ -25,6 +25,7 @@ @import "./overrides.css"; @import "./material-components.css"; @import "./tokens/index.css"; +@import "./components/datatable-editor.css"; @media (min-width: 600px) { diff --git a/plugin/assets/css/src/components/datatable-editor.css b/plugin/assets/css/src/components/datatable-editor.css new file mode 100644 index 000000000..804df168d --- /dev/null +++ b/plugin/assets/css/src/components/datatable-editor.css @@ -0,0 +1,31 @@ +/* + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +/* Table editor style. */ +.wp-block-table td, +.wp-block-table th { + border: none; + border-top: 1px solid var(--md-sys-color-surface-variant); + border-left: 1px solid var(--md-sys-color-surface-variant); +} + +.mdc-data-table { + + table { + border: none !important; + } +} diff --git a/plugin/assets/css/src/components/datatable.css b/plugin/assets/css/src/components/datatable.css new file mode 100644 index 000000000..d467eea80 --- /dev/null +++ b/plugin/assets/css/src/components/datatable.css @@ -0,0 +1,78 @@ +/* + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +/* Data Table */ +.mdc-data-table { + max-width: calc(100vw - 2 * 40px); + border: 1px solid var(--md-sys-color-surface-variant); + border-radius: var(--mdc-data-table-radius, 24px); + overflow-x: auto; + + @media screen and (max-width: 480px) { + max-width: calc(100vw - 2 * 24px); + } + + & table { + width: 100%; + border: 0; + } + + table p { + -webkit-margin-before: 0; + margin-block-start: 0; + -webkit-margin-after: 0; + margin-block-end: 0; + } + + td:empty, + th:empty { + border-top: 0; + } + + thead:first-child tr:first-child th, + tbody:first-child tr:first-child td { + border-top: 0; + } +} + +.mdc-data-table__row, +.mdc-data-table__header-row { + border: none; +} + +.mdc-data-table__header-cell { + background: var(--md-sys-color-surface-variant); + color: var(--md-sys-color-on-surface-variant); + font-weight: bold; + text-align: center; +} + +.mdc-data-table__header-cell, +.mdc-data-table__cell { + padding: 16px 24px; + border-top: 1px solid var(--md-sys-color-surface-variant); + border-left: 1px solid var(--md-sys-color-surface-variant); + vertical-align: middle; + + &:first-child { + border-left: 0; + } +} + +.mdc-data-table__caption figcaption { + text-align: center; +} diff --git a/plugin/assets/css/src/components/material.css b/plugin/assets/css/src/components/material.css index ad60062fd..78325ac33 100644 --- a/plugin/assets/css/src/components/material.css +++ b/plugin/assets/css/src/components/material.css @@ -160,17 +160,6 @@ width: 860px; } -/* Data Table */ -.mdc-data-table { - border-radius: var(--mdc-data-table-radius, 4px); -} - -.mdc-data-table__header-cell { - font-weight: bold; -} - -.mdc-data-table__header-cell, -.mdc-data-table__cell, .mdc-menu .mdc-list { color: var(--md-sys-color-on-surface, #000); } diff --git a/plugin/assets/css/src/material-components.css b/plugin/assets/css/src/material-components.css index 271510f28..9d6aa8e4f 100644 --- a/plugin/assets/css/src/material-components.css +++ b/plugin/assets/css/src/material-components.css @@ -20,7 +20,6 @@ @import "@material/button/dist/mdc.button.css"; @import "@material/card/dist/mdc.card.css"; -@import "@material/data-table/dist/mdc.data-table.css"; @import "@material/icon-button/dist/mdc.icon-button.css"; @import "@material/image-list/dist/mdc.image-list.css"; @import "@material/layout-grid/dist/mdc.layout-grid.css"; @@ -32,3 +31,4 @@ @import "@material/textfield/dist/mdc.textfield.css"; @import "@material/tooltip/dist/mdc.tooltip.css"; @import "./components/material.css"; +@import "./components/datatable.css"; diff --git a/plugin/assets/css/src/overrides.css b/plugin/assets/css/src/overrides.css index b9c0bd9ee..18faa4789 100644 --- a/plugin/assets/css/src/overrides.css +++ b/plugin/assets/css/src/overrides.css @@ -77,40 +77,6 @@ } } -/* Data Table */ -.mdc-data-table { - background-color: var(--md-sys-color-surface, #fff) !important; - border-color: rgba(0, 0, 0, 0.12) !important; - border-color: var(--md-sys-color-on-surface, #000) !important; - - & thead { - border: none !important; - } -} - - -.mdc-data-table__table { - margin: 0 !important; -} - -.mdc-data-table__row { - border-top-color: rgba(0, 0, 0, 0.12) !important; - border-top-color: var(--md-sys-color-on-surface, #000) !important; - border-top-width: 1px !important; - border-top-style: solid !important; -} - -.mdc-data-table__header-cell { - border: none !important; - vertical-align: middle !important; -} - -.mdc-data-table__header-cell, -.mdc-data-table__cell { - border: none !important; - padding-left: 16px !important; - padding-right: 16px !important; -} /* List */ ul.mdc-list { diff --git a/plugin/assets/src/block-editor/blocks/data-table/core-deprecated.js b/plugin/assets/src/block-editor/blocks/data-table/core-deprecated.js new file mode 100644 index 000000000..bfb8e4b14 --- /dev/null +++ b/plugin/assets/src/block-editor/blocks/data-table/core-deprecated.js @@ -0,0 +1,142 @@ +/** + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import SaveV1 from './deprecated/dataTableV1'; + +const coreDeprecatedV1 = { + attributes: { + hasFixedLayout: { + type: 'boolean', + default: false, + }, + backgroundColor: { + type: 'string', + }, + caption: { + type: 'string', + source: 'html', + selector: 'figcaption', + default: '', + }, + 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', + }, + align: { + type: 'string', + source: 'attribute', + attribute: 'data-align', + }, + }, + }, + }, + }, + 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', + }, + align: { + type: 'string', + source: 'attribute', + attribute: 'data-align', + }, + }, + }, + }, + }, + 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', + }, + align: { + type: 'string', + source: 'attribute', + attribute: 'data-align', + }, + }, + }, + }, + }, + }, + save: SaveV1, +}; +export default coreDeprecatedV1; diff --git a/plugin/assets/src/block-editor/blocks/data-table/deprecated.js b/plugin/assets/src/block-editor/blocks/data-table/deprecated.js new file mode 100644 index 000000000..4cffa63d3 --- /dev/null +++ b/plugin/assets/src/block-editor/blocks/data-table/deprecated.js @@ -0,0 +1,139 @@ +/** + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import SaveV1 from './deprecated/dataTableV1'; + +const deprecatedV1 = { + attributes: { + hasFixedLayout: { + type: 'boolean', + default: false, + }, + caption: { + type: 'string', + source: 'html', + selector: 'figcaption', + default: '', + }, + 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', + }, + align: { + type: 'string', + source: 'attribute', + attribute: 'data-align', + }, + }, + }, + }, + }, + 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', + }, + align: { + type: 'string', + source: 'attribute', + attribute: 'data-align', + }, + }, + }, + }, + }, + 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', + }, + align: { + type: 'string', + source: 'attribute', + attribute: 'data-align', + }, + }, + }, + }, + }, + }, + save: SaveV1, +}; +export default deprecatedV1; diff --git a/plugin/assets/src/block-editor/blocks/data-table/deprecated/dataTableV1.js b/plugin/assets/src/block-editor/blocks/data-table/deprecated/dataTableV1.js new file mode 100644 index 000000000..8622fd519 --- /dev/null +++ b/plugin/assets/src/block-editor/blocks/data-table/deprecated/dataTableV1.js @@ -0,0 +1,109 @@ +/* + * + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * + */ + +import { RichText, useBlockProps } from '@wordpress/block-editor'; +import classnames from 'classnames'; +const SaveV1 = ( { attributes } ) => { + const { hasFixedLayout, head, body, foot, caption, className } = attributes; + + const isEmpty = ! head.length && ! body.length && ! foot.length; + + // eslint-disable-next-line @wordpress/no-unused-vars-before-return + const blockProps = useBlockProps.save( { + className: classnames( + 'wp-block-table', + ( className || '' ).replace( 'wp-block-table', '' ) + ), + } ); + + if ( isEmpty ) { + return null; + } + + const classes = classnames( 'mdc-data-table__table', { + 'has-fixed-layout': hasFixedLayout, + } ); + + const hasCaption = ! RichText.isEmpty( caption ); + + const Section = ( { type, rows } ) => { + if ( ! rows.length ) { + return null; + } + + const Tag = `t${ type }`; + const tagClass = 'body' === type ? 'mdc-data-table__content' : ''; + const trClass = classnames( { + 'mdc-data-table__header-row': 'head' === type, + 'mdc-data-table__row': 'head' !== type, + } ); + + return ( + + { rows.map( ( { cells }, rowIndex ) => ( + + { cells.map( + ( { content, tag, scope, align }, cellIndex ) => { + const cellClasses = classnames( { + [ `has-text-align-${ align }` ]: align, + 'mdc-data-table__cell': 'head' !== type, + 'mdc-data-table__header-cell': + 'head' === type, + } ); + + return ( + + ); + } + ) } + + ) ) } + + ); + }; + + return ( +
+
+ +
+
+
+
+
+ + { hasCaption && ( +
+ +
+ ) } +
+ ); +}; + +export default SaveV1; diff --git a/plugin/assets/src/block-editor/blocks/data-table/edit.js b/plugin/assets/src/block-editor/blocks/data-table/edit.js index 82e59611a..d0d33c5ed 100644 --- a/plugin/assets/src/block-editor/blocks/data-table/edit.js +++ b/plugin/assets/src/block-editor/blocks/data-table/edit.js @@ -36,8 +36,6 @@ import { TextControl, ToggleControl, } from '@wordpress/components'; -import { compose } from '@wordpress/compose'; -import { withSelect } from '@wordpress/data'; import { useState } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; @@ -84,8 +82,8 @@ const Section = ( { name, rows, onChange, createOnFocus, selectedCell } ) => { const Tag = `t${ name }`; const tagClass = 'body' === name ? 'mdc-data-table__content' : ''; const trClass = classnames( { - 'mdc-data-table__header-row': 'head' === name, - 'mdc-data-table__row': 'head' !== name, + 'mdc-data-table__header-row': [ 'head', 'foot' ].includes( name ), + 'mdc-data-table__row': 'body' === name, } ); return ( @@ -111,8 +109,11 @@ const Section = ( { name, rows, onChange, createOnFocus, selectedCell } ) => { ); const tdClasses = classnames( { - 'mdc-data-table__cell': 'head' !== name, - 'mdc-data-table__header-cell': 'head' === name, + 'mdc-data-table__cell': 'body' === name, + 'mdc-data-table__header-cell': [ + 'head', + 'foot', + ].includes( name ), 'is-selected': selectedCell && selectedCell.sectionName === @@ -164,7 +165,7 @@ const Section = ( { name, rows, onChange, createOnFocus, selectedCell } ) => { ); }; -const DataTableEdit = ( { attributes, setAttributes, hasCaption } ) => { +const DataTableEdit = ( { attributes, setAttributes } ) => { const { className, hasFixedLayout, caption, head, body, foot } = attributes; const [ selectedCell, setSelectedCell ] = useState( null ); const [ initialColumnCount, setinitialColumnCount ] = useState( 2 ); @@ -537,41 +538,28 @@ const DataTableEdit = ( { attributes, setAttributes, hasCaption } ) => { - { hasCaption && ( -
- setAttributes( { caption: value } ) - } - // Deselect the selected table cell when the caption is focused. - unstableOnFocus={ - /* istanbul ignore next */ - () => setSelectedCell( null ) - } - /> -
- ) } +
+ setAttributes( { caption: value } ) + } + // Deselect the selected table cell when the caption is focused. + unstableOnFocus={ + /* istanbul ignore next */ + () => setSelectedCell( null ) + } + /> +
); }; -export default compose( [ - withSelect( select => { - const tableBlock = select( 'core/blocks' ).getBlockType( 'core/table' ); - - return { - hasCaption: - tableBlock && - tableBlock.attributes && - 'caption' in tableBlock.attributes, - }; - } ), -] )( DataTableEdit ); +export default DataTableEdit; diff --git a/plugin/assets/src/block-editor/blocks/data-table/hooks.js b/plugin/assets/src/block-editor/blocks/data-table/hooks.js index f1a5a2300..45041efab 100644 --- a/plugin/assets/src/block-editor/blocks/data-table/hooks.js +++ b/plugin/assets/src/block-editor/blocks/data-table/hooks.js @@ -1,132 +1,47 @@ -/** - * Copyright 2020 Google LLC +/* + * + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. * - * http://www.apache.org/licenses/LICENSE-2.0 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. */ /** - * WordPress dependencies + * WordPress dependencies. */ -import { createHigherOrderComponent } from '@wordpress/compose'; -import { select, dispatch } from '@wordpress/data'; -import domReady from '@wordpress/dom-ready'; import { addFilter } from '@wordpress/hooks'; -import { __ } from '@wordpress/i18n'; +import coreDeprecatedV1 from './deprecated'; -/** - * Internal dependencies - */ -import DataTableSave from './save'; -import DataTableEdit from './edit'; - -export const isMaterialTableBlock = ( name, attributes ) => { - return ( - 'core/table' === name && - attributes && - attributes.className && - -1 !== attributes.className.indexOf( 'material' ) - ); -}; +const blockName = 'core/table'; -/** - * Maybe use material data table edit component. - * - * @param {WPElement} element Block save result. - * @param {WPBlock} blockType Block type definition. - * @param {Object} attributes Block attributes. - */ -export const withDataTableEdit = createHigherOrderComponent( BlockEdit => { - return props => { - if ( isMaterialTableBlock( props.name, props.attributes ) ) { - return ( - <> - - - ); - } - - return ; - }; -}, 'withMaterialDataTableEdit' ); - -/** - * Maybe use material data table save component. - * - * @param {WPElement} element Block save result. - * @param {WPBlock} blockType Block type definition. - * @param {Object} attributes Block attributes. - */ -export const save = ( element, blockType, attributes ) => { - if ( isMaterialTableBlock( blockType.name, attributes ) ) { - return ; +const addMigrationHook = ( settings, name ) => { + if ( name !== blockName ) { + return settings; } - - return element; -}; - -/** - * Add `Material` style. - * - * @param {Object} settings Block settings. - * @param {string} name Block name. - */ -export const addMaterialStyle = ( settings, name ) => { - if ( 'core/table' === name ) { - settings.styles = [ - { - name: 'material', - label: __( 'Material', 'material-design' ), - isDefault: true, - }, - { - name: 'regular', - label: __( 'Regular', 'material-design' ), - }, - settings.styles[ 1 ], - ]; + const copyDeprecated = settings.deprecated.slice( 0 ); + if ( settings.deprecated.length === 2 ) { + copyDeprecated.unshift( coreDeprecatedV1 ); + } else { + copyDeprecated.splice( 2, 0, coreDeprecatedV1 ); } + settings.deprecated = copyDeprecated; return settings; }; addFilter( 'blocks.registerBlockType', - 'material/data-table-style', - addMaterialStyle + `namespace/${ blockName }/addMigration/addAttributesToBlock`, + addMigrationHook ); - -addFilter( - 'editor.BlockEdit', - 'material/data-table-edit', - withDataTableEdit, - 1 -); - -addFilter( 'blocks.getSaveElement', 'material/data-table-save', save ); - -domReady( () => { - const stylePreferences = select( 'core/edit-post' ).getPreference( - 'preferredStyleVariations' - ); - - if ( - stylePreferences && - ( ! stylePreferences[ 'core/table' ] || - 'material' !== stylePreferences[ 'core/table' ] ) - ) { - dispatch( 'core/edit-post' ).updatePreferredStyleVariations( - 'core/table', - 'material' - ); - } -} ); diff --git a/plugin/assets/src/block-editor/blocks/data-table/index.js b/plugin/assets/src/block-editor/blocks/data-table/index.js index a44328674..48ca3b836 100644 --- a/plugin/assets/src/block-editor/blocks/data-table/index.js +++ b/plugin/assets/src/block-editor/blocks/data-table/index.js @@ -26,6 +26,7 @@ import edit from './edit'; import save from './save'; import metadata from './block.json'; import { example } from './example'; +import deprecatedV1 from './deprecated'; const { name } = metadata; @@ -45,4 +46,5 @@ export const settings = { edit, save, example, + deprecated: [ deprecatedV1 ], }; diff --git a/plugin/assets/src/block-editor/blocks/data-table/save.js b/plugin/assets/src/block-editor/blocks/data-table/save.js index 96102443a..7536d2a25 100644 --- a/plugin/assets/src/block-editor/blocks/data-table/save.js +++ b/plugin/assets/src/block-editor/blocks/data-table/save.js @@ -24,7 +24,7 @@ import classnames from 'classnames'; */ import { RichText, useBlockProps } from '@wordpress/block-editor'; -const Save = ( { attributes, hasCaption } ) => { +const Save = ( { attributes } ) => { const { hasFixedLayout, head, body, foot, caption, className } = attributes; const isEmpty = ! head.length && ! body.length && ! foot.length; @@ -45,7 +45,7 @@ const Save = ( { attributes, hasCaption } ) => { 'has-fixed-layout': hasFixedLayout, } ); - hasCaption = hasCaption && ! RichText.isEmpty( caption ); + const hasCaption = ! RichText.isEmpty( caption ); const Section = ( { type, rows } ) => { if ( ! rows.length ) { @@ -55,7 +55,7 @@ const Save = ( { attributes, hasCaption } ) => { const Tag = `t${ type }`; const tagClass = 'body' === type ? 'mdc-data-table__content' : ''; const trClass = classnames( { - 'mdc-data-table__header-row': 'head' === type, + 'mdc-data-table__header-row': [ 'head', 'foot' ].includes( type ), 'mdc-data-table__row': 'head' !== type, } ); @@ -67,9 +67,11 @@ const Save = ( { attributes, hasCaption } ) => { ( { content, tag, scope, align }, cellIndex ) => { const cellClasses = classnames( { [ `has-text-align-${ align }` ]: align, - 'mdc-data-table__cell': 'head' !== type, - 'mdc-data-table__header-cell': - 'head' === type, + 'mdc-data-table__cell': 'body' === type, + 'mdc-data-table__header-cell': [ + 'head', + 'foot', + ].includes( type ), } ); return ( diff --git a/plugin/assets/src/block-editor/blocks/data-table/state.js b/plugin/assets/src/block-editor/blocks/data-table/state.js index 420680839..ab3b4eb15 100644 --- a/plugin/assets/src/block-editor/blocks/data-table/state.js +++ b/plugin/assets/src/block-editor/blocks/data-table/state.js @@ -156,23 +156,27 @@ export function isCellSelected( cellLocation, selection ) { cellLocation.rowIndex === selection.rowIndex ); } + return false; } /** * Inserts a row in the table state. * - * @param {Object} state Current table state. - * @param {Object} options - * @param {string} options.sectionName Section in which to insert the row. - * @param {number} options.rowIndex Row index at which to insert the row. - * @param {number} options.columnCount + * @param {Object} state Current table state. + * @param {Object} options + * @param {string} options.sectionName Section in which to insert the row. + * @param {number} options.rowIndex Row index at which to insert the row. + * @param {?number} options.columnCount * * @return {Object} New table state. */ -export function insertRow( state, { sectionName, rowIndex, columnCount } ) { +export function insertRow( + state, + { sectionName, rowIndex, columnCount = null } +) { const firstRow = getFirstRow( state ); const cellCount = - columnCount === undefined + columnCount === null ? get( firstRow, [ 'cells', 'length' ] ) : columnCount; diff --git a/plugin/assets/src/block-editor/blocks/data-table/styles.css b/plugin/assets/src/block-editor/blocks/data-table/styles.css index d89ea5eb0..19660efb5 100644 --- a/plugin/assets/src/block-editor/blocks/data-table/styles.css +++ b/plugin/assets/src/block-editor/blocks/data-table/styles.css @@ -19,7 +19,6 @@ } .mdc-data-table { - width: 100%; tfoot { border: none; diff --git a/plugin/assets/src/block-editor/index.js b/plugin/assets/src/block-editor/index.js index 0068335fd..956350e8a 100755 --- a/plugin/assets/src/block-editor/index.js +++ b/plugin/assets/src/block-editor/index.js @@ -25,9 +25,9 @@ import { updateCategory } from '@wordpress/blocks'; * Internal dependencies */ import { registerBlocks, MaterialLogo } from './helpers'; -import './blocks/data-table/hooks'; import './formats'; import './style/core-template'; +import './blocks/data-table/hooks'; /** * Register the blocks. diff --git a/plugin/php/customizer/class-controls.php b/plugin/php/customizer/class-controls.php index 10c12c161..2fb534da4 100644 --- a/plugin/php/customizer/class-controls.php +++ b/plugin/php/customizer/class-controls.php @@ -1307,7 +1307,7 @@ public function get_corner_styles_controls() { 'label' => __( 'Data table', 'material-design' ), 'min' => 0, 'max' => 36, - 'initial_value' => 0, + 'initial_value' => 24, 'css_var' => '--mdc-data-table-radius', 'blocks' => [ 'material/data-table', diff --git a/plugin/tests/e2e/specs/block-editor/blocks/data-table/__snapshots__/data-table.spec.js.snap b/plugin/tests/e2e/specs/block-editor/blocks/data-table/__snapshots__/data-table.spec.js.snap deleted file mode 100644 index e218aedf0..000000000 --- a/plugin/tests/e2e/specs/block-editor/blocks/data-table/__snapshots__/data-table.spec.js.snap +++ /dev/null @@ -1,7 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`blocks: material/data-table core/table style should update table cell content 1`] = ` -" -
Column 1
-" -`; diff --git a/plugin/tests/e2e/specs/block-editor/blocks/data-table/data-table.spec.js b/plugin/tests/e2e/specs/block-editor/blocks/data-table/data-table.spec.js deleted file mode 100644 index dc59dc36f..000000000 --- a/plugin/tests/e2e/specs/block-editor/blocks/data-table/data-table.spec.js +++ /dev/null @@ -1,71 +0,0 @@ -/** - * Copyright 2020 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * WordPress dependencies - */ -import { - clickButton, - createNewPost, - getEditedPostContent, -} from '@wordpress/e2e-test-utils'; - -/** - * Internal dependencies - */ -import { insertBlockByKeyword, selectBlockByName } from '../../../../utils'; - -const createButtonLabel = 'Create Table'; -const buttonSelector = '.blocks-table__placeholder-form button'; - -describe( 'blocks: material/data-table core/table style', () => { - beforeEach( async () => { - await createNewPost( {} ); - await insertBlockByKeyword( 'Table' ); - await page.waitForSelector( buttonSelector ); - // Create the table. - await clickButton( createButtonLabel ); - } ); - - it( 'should have a "Styles" selection with Material style added', async () => { - await selectBlockByName( 'core/table' ); - const panels = await page.$$( '.components-panel__body-toggle' ); - - if ( - 'true' !== - ( await page.evaluate( - el => el.getAttribute( 'aria-expanded' ), - panels[ 0 ] - ) ) - ) { - await panels[ 0 ].click(); - } - - const styles = await page.$$( - '.block-editor-block-styles__item-label' - ); - expect( styles ).toHaveLength( 3 ); - } ); - - // eslint-disable-next-line jest/no-disabled-tests - it.skip( 'should update table cell content', async () => { - await page.waitForSelector( 'td' ); - await page.click( 'td' ); - await page.keyboard.type( 'Column 1' ); - - expect( await getEditedPostContent() ).toMatchSnapshot(); - } ); -} ); diff --git a/plugin/tests/js/block-editor/blocks/data-table/__snapshots__/edit.test.js.snap b/plugin/tests/js/block-editor/blocks/data-table/__snapshots__/edit.test.js.snap index b8d69932d..dfb57cf35 100644 --- a/plugin/tests/js/block-editor/blocks/data-table/__snapshots__/edit.test.js.snap +++ b/plugin/tests/js/block-editor/blocks/data-table/__snapshots__/edit.test.js.snap @@ -335,10 +335,10 @@ Object { class="" >
-`; - -exports[`Data Table Filters save should invoke DataTableSave 2`] = ``; - -exports[`Data Table Filters withDataTableEdit should include DataTableEdit 1`] = ` -Object { - "asFragment": [Function], - "baseElement": -
-
- Material Data Table Edit Component -
-
- , - "container":
-
- Material Data Table Edit Component -
-
, - "debug": [Function], - "findAllByAltText": [Function], - "findAllByDisplayValue": [Function], - "findAllByLabelText": [Function], - "findAllByPlaceholderText": [Function], - "findAllByRole": [Function], - "findAllByTestId": [Function], - "findAllByText": [Function], - "findAllByTitle": [Function], - "findByAltText": [Function], - "findByDisplayValue": [Function], - "findByLabelText": [Function], - "findByPlaceholderText": [Function], - "findByRole": [Function], - "findByTestId": [Function], - "findByText": [Function], - "findByTitle": [Function], - "getAllByAltText": [Function], - "getAllByDisplayValue": [Function], - "getAllByLabelText": [Function], - "getAllByPlaceholderText": [Function], - "getAllByRole": [Function], - "getAllByTestId": [Function], - "getAllByText": [Function], - "getAllByTitle": [Function], - "getByAltText": [Function], - "getByDisplayValue": [Function], - "getByLabelText": [Function], - "getByPlaceholderText": [Function], - "getByRole": [Function], - "getByTestId": [Function], - "getByText": [Function], - "getByTitle": [Function], - "queryAllByAltText": [Function], - "queryAllByDisplayValue": [Function], - "queryAllByLabelText": [Function], - "queryAllByPlaceholderText": [Function], - "queryAllByRole": [Function], - "queryAllByTestId": [Function], - "queryAllByText": [Function], - "queryAllByTitle": [Function], - "queryByAltText": [Function], - "queryByDisplayValue": [Function], - "queryByLabelText": [Function], - "queryByPlaceholderText": [Function], - "queryByRole": [Function], - "queryByTestId": [Function], - "queryByText": [Function], - "queryByTitle": [Function], - "rerender": [Function], - "unmount": [Function], -} -`; - -exports[`Data Table Filters withDataTableEdit should include DataTableEdit 2`] = ` -Object { - "asFragment": [Function], - "baseElement": -
-
- Material Data Table Edit Component -
-
-
-
- Original Edit component -
-
- , - "container":
-
- Original Edit component -
-
, - "debug": [Function], - "findAllByAltText": [Function], - "findAllByDisplayValue": [Function], - "findAllByLabelText": [Function], - "findAllByPlaceholderText": [Function], - "findAllByRole": [Function], - "findAllByTestId": [Function], - "findAllByText": [Function], - "findAllByTitle": [Function], - "findByAltText": [Function], - "findByDisplayValue": [Function], - "findByLabelText": [Function], - "findByPlaceholderText": [Function], - "findByRole": [Function], - "findByTestId": [Function], - "findByText": [Function], - "findByTitle": [Function], - "getAllByAltText": [Function], - "getAllByDisplayValue": [Function], - "getAllByLabelText": [Function], - "getAllByPlaceholderText": [Function], - "getAllByRole": [Function], - "getAllByTestId": [Function], - "getAllByText": [Function], - "getAllByTitle": [Function], - "getByAltText": [Function], - "getByDisplayValue": [Function], - "getByLabelText": [Function], - "getByPlaceholderText": [Function], - "getByRole": [Function], - "getByTestId": [Function], - "getByText": [Function], - "getByTitle": [Function], - "queryAllByAltText": [Function], - "queryAllByDisplayValue": [Function], - "queryAllByLabelText": [Function], - "queryAllByPlaceholderText": [Function], - "queryAllByRole": [Function], - "queryAllByTestId": [Function], - "queryAllByText": [Function], - "queryAllByTitle": [Function], - "queryByAltText": [Function], - "queryByDisplayValue": [Function], - "queryByLabelText": [Function], - "queryByPlaceholderText": [Function], - "queryByRole": [Function], - "queryByTestId": [Function], - "queryByText": [Function], - "queryByTitle": [Function], - "rerender": [Function], - "unmount": [Function], -} -`; diff --git a/plugin/tests/js/block-editor/blocks/data-table/__snapshots__/save.test.js.snap b/plugin/tests/js/block-editor/blocks/data-table/__snapshots__/save.test.js.snap index 4440b8db2..7542eaf34 100644 --- a/plugin/tests/js/block-editor/blocks/data-table/__snapshots__/save.test.js.snap +++ b/plugin/tests/js/block-editor/blocks/data-table/__snapshots__/save.test.js.snap @@ -126,24 +126,24 @@ Object { class="" >
Footer Col 1
Footer Col 2
Footer Col 3 @@ -153,6 +153,17 @@ Object {
+
+
+
+ Material Data Table +
+
+
, @@ -278,24 +289,24 @@ Object { class="" >
Footer Col 1
Footer Col 2
Footer Col 3 @@ -305,6 +316,17 @@ Object {
+
+
+
+ Material Data Table +
+
+
, "debug": [Function], @@ -517,6 +539,17 @@ Object {
+
+
+
+ Material Data Table +
+
+
, @@ -611,6 +644,17 @@ Object {
+
+
+
+ Material Data Table +
+
+
, "debug": [Function], diff --git a/plugin/tests/js/block-editor/blocks/data-table/hooks.test.js b/plugin/tests/js/block-editor/blocks/data-table/hooks.test.js deleted file mode 100644 index 109c07ed4..000000000 --- a/plugin/tests/js/block-editor/blocks/data-table/hooks.test.js +++ /dev/null @@ -1,291 +0,0 @@ -/** - * Copyright 2020 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * External dependencies - */ -import '@testing-library/jest-dom/extend-expect'; -import { render } from '@testing-library/react'; - -/** - * WordPress dependencies - */ -import { addFilter } from '@wordpress/hooks'; - -/** - * Internal dependencies - */ -import { - isMaterialTableBlock, - withDataTableEdit, - addMaterialStyle, - save, -} from '../../../../../assets/src/block-editor/blocks/data-table/hooks'; - -jest.mock( - '../../../../../assets/src/block-editor/blocks/data-table/edit', - () => ( { - __esModule: true, - default: () =>
Material Data Table Edit Component
, - } ) -); - -// Mock wp.hooks.addFilter. -jest.mock( '@wordpress/hooks', () => { - return { - addFilter: jest.fn(), - }; -} ); - -// Mock wp.blocks.registerBlockStyle. -jest.mock( '@wordpress/blocks', () => { - return { - registerBlockStyle: jest.fn(), - }; -} ); - -// Mock wp.data. -jest.mock( '@wordpress/block-editor', () => ( { - RichText: jest.fn(), - getColorClassName: jest.fn(), - createCustomColorsHOC: Comp => () => () => Comp, -} ) ); - -// Mock wp.data. -jest.mock( '@wordpress/data', () => ( { - combineReducers: jest.fn(), - registerStore: jest.fn(), - select: store => { - switch ( store ) { - case 'core/edit-post': - return { - getPreference: () => { - return { - 'core/table': 'regular', - }; - }, - }; - - default: - return {}; - } - }, - withSelect: () => () => { - return {}; - }, - dispatch: store => { - switch ( store ) { - case 'core/edit-post': - return { - updatePreferredStyleVariations: jest.fn(), - }; - - default: - return {}; - } - }, -} ) ); - -const attributes = { - hasFixedLayout: true, - head: [ - { - cells: [ - { - content: 'Version', - tag: 'th', - }, - { - content: 'Jazz Musician', - tag: 'th', - }, - { - content: 'Release Date', - tag: 'th', - }, - ], - }, - ], - body: [ - { - cells: [ - { - content: '5.2', - tag: 'td', - }, - { - content: 'Jaco Pastorius', - tag: 'td', - }, - { - content: 'May 7, 2019', - tag: 'td', - }, - ], - }, - { - cells: [ - { - content: '5.1', - tag: 'td', - }, - { - content: 'Betty Carter', - tag: 'td', - }, - { - content: 'February 21, 2019', - tag: 'td', - }, - ], - }, - { - cells: [ - { - content: '5.0', - tag: 'td', - }, - { - content: 'Bebo Valdés', - tag: 'td', - }, - { - content: 'December 6, 2018', - tag: 'td', - }, - ], - }, - ], - foot: [ - { - cells: [ - { - content: 'Footer Col 1', - tag: 'td', - }, - { - content: 'Footer Col 2', - tag: 'td', - }, - { - content: 'Footer Col 3', - tag: 'td', - }, - ], - }, - ], - caption: 'Material Data Table', - className: 'is-style-material', -}; - -describe( 'Data Table Filters', () => { - it( 'filters should be added', () => { - expect( addFilter ).toHaveBeenCalledTimes( 3 ); - - // eslint-disable-next-line jest/prefer-strict-equal - expect( addFilter.mock.calls[ 0 ] ).toEqual( [ - 'blocks.registerBlockType', - 'material/data-table-style', - addMaterialStyle, - ] ); - - // eslint-disable-next-line jest/prefer-strict-equal - expect( addFilter.mock.calls[ 1 ] ).toEqual( [ - 'editor.BlockEdit', - 'material/data-table-edit', - withDataTableEdit, - 1, - ] ); - - // eslint-disable-next-line jest/prefer-strict-equal - expect( addFilter.mock.calls[ 2 ] ).toEqual( [ - 'blocks.getSaveElement', - 'material/data-table-save', - save, - ] ); - } ); - - it( 'addMaterialStyle should add material style', () => { - let settings = addMaterialStyle( { styles: [] }, 'core/paragraph' ); - expect( settings.styles ).toHaveLength( 0 ); - - settings = addMaterialStyle( - { - styles: [ - { - name: 'regular', - label: 'Default', - isDefault: true, - }, - { name: 'stripes', label: 'Stripes' }, - ], - }, - 'core/table' - ); - expect( settings.styles ).toHaveLength( 3 ); - } ); - - it( 'isMaterialTableBlock should return correct value', () => { - expect( - isMaterialTableBlock( 'core/table', { - className: 'is-style-material', - } ) - ).toStrictEqual( true ); - - expect( - isMaterialTableBlock( 'core/table', { - className: 'is-style-regular', - } ) - ).toStrictEqual( false ); - - expect( - isMaterialTableBlock( 'core/paragraph', { - className: 'is-style-material', - } ) - ).toStrictEqual( false ); - } ); - - it( 'withDataTableEdit should include DataTableEdit', () => { - const Component = withDataTableEdit( () => { - return
Original Edit component
; - } ); - let wrapper = render( - - ); - - expect( wrapper ).toMatchSnapshot(); - - wrapper = render( - - ); - - expect( wrapper ).toMatchSnapshot(); - } ); - - it( 'save should invoke DataTableSave', () => { - const Component = () => { - return
Original Save component
; - }; - const element = ; - let saveElement = save( element, { name: 'core/table' }, attributes ); - - expect( saveElement ).toMatchSnapshot(); - - saveElement = save( element, { name: 'core/paragraph' }, attributes ); - - expect( saveElement ).toMatchSnapshot(); - } ); -} ); diff --git a/plugin/tests/phpunit/php/customizer/class-test-controls.php b/plugin/tests/phpunit/php/customizer/class-test-controls.php index b23b2e461..e828b0ff0 100644 --- a/plugin/tests/phpunit/php/customizer/class-test-controls.php +++ b/plugin/tests/phpunit/php/customizer/class-test-controls.php @@ -711,7 +711,7 @@ public function test_get_corner_styles_controls() { 'label' => __( 'Data table', 'material-design' ), 'min' => 0, 'max' => 36, - 'initial_value' => 0, + 'initial_value' => 24, 'css_var' => '--mdc-data-table-radius', 'blocks' => [ 'material/data-table', diff --git a/theme/assets/css/src/components/tables.css b/theme/assets/css/src/components/tables.css index 419d0f17f..682bb0f65 100644 --- a/theme/assets/css/src/components/tables.css +++ b/theme/assets/css/src/components/tables.css @@ -14,17 +14,50 @@ * limitations under the License. */ +/* Setup default table style with m3 without radius */ table { - border-collapse: collapse; - border: 1px solid var(--md-sys-color-on-surface, #000); + max-width: calc(100vw - 2 * 40px); + border: 1px solid var(--md-sys-color-surface-variant); + width: 100%; + + @media screen and (max-width: 480px) { + max-width: calc(100vw - 2 * 24px); + } +} + +thead tr, +tbody th { + border: none; } -tr { - border-top: 1px solid var(--md-sys-color-on-surface, #000); +th { + background: var(--md-sys-color-surface-variant); + color: var(--md-sys-color-on-surface-variant); + font-weight: bold; } th, td { - padding: 0.5em 1em; - text-align: inherit; + padding: 16px 24px; + border-top: 1px solid var(--md-sys-color-surface-variant); + border-left: 1px solid var(--md-sys-color-surface-variant); + vertical-align: middle; + + &:first-child { + border-left: 0; + } +} + +td:empty, +th:empty { + border-top: 0; +} + +thead:first-child tr:first-child th, +tbody:first-child tr:first-child td { + border-top: 0; +} + +.wp-block-table figcaption { + text-align: center; } diff --git a/theme/assets/css/src/editor.css b/theme/assets/css/src/editor.css index ec42a51c7..b7c3ea299 100644 --- a/theme/assets/css/src/editor.css +++ b/theme/assets/css/src/editor.css @@ -16,6 +16,7 @@ @import "./conf/variables.css"; @import "./base/typography.css"; +@import "./components/tables.css"; @mixin selector-typography .wp-block div, body-large; @mixin selector-typography p, body-large; @mixin selector-typography .editor-post-title__input, headline-large, 6, 6, 300;