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

[WIP] Table: Add header, footer and striped style colors #31696

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions packages/block-library/src/table/block.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,42 @@
"selector": "figcaption",
"default": ""
},
"secondaryBackgroundColor": {
"type": "string"
},
"customSecondaryBackgroundColor": {
"type": "string"
},
"secondaryTextColor": {
"type": "string"
},
"customSecondaryTextColor": {
"type": "string"
},
"headerBackgroundColor": {
"type": "string"
},
"customHeaderBackgroundColor": {
"type": "string"
},
"headerTextColor": {
"type": "string"
},
"customHeaderTextColor": {
"type": "string"
},
"footerBackgroundColor": {
"type": "string"
},
"customFooterBackgroundColor": {
"type": "string"
},
"footerTextColor": {
"type": "string"
},
"customFooterTextColor": {
"type": "string"
},
"head": {
"type": "array",
"default": [],
Expand Down
54 changes: 45 additions & 9 deletions packages/block-library/src/table/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
BlockIcon,
AlignmentToolbar,
useBlockProps,
withColors,
__experimentalUseColorProps as useColorProps,
__experimentalUseBorderProps as useBorderProps,
} from '@wordpress/block-editor';
Expand Down Expand Up @@ -57,6 +58,8 @@ import {
toggleSection,
isEmptyTableSection,
} from './state';
import { getColorPropsFromObjects } from './utils';
import SecondaryColorControls from './secondary-color-controls';

const ALIGNMENT_CONTROLS = [
{
Expand Down Expand Up @@ -92,20 +95,24 @@ function TSection( { name, ...props } ) {
return <TagName { ...props } />;
}

function TableEdit( {
attributes,
setAttributes,
insertBlocksAfter,
isSelected,
} ) {
function TableEdit( props ) {
const { attributes, setAttributes, insertBlocksAfter, isSelected } = props;
const { hasFixedLayout, caption, head, foot } = attributes;
const [ initialRowCount, setInitialRowCount ] = useState( 2 );
const [ initialColumnCount, setInitialColumnCount ] = useState( 2 );
const [ selectedCell, setSelectedCell ] = useState();

const blockProps = useBlockProps();
const colorProps = useColorProps( attributes );
const borderProps = useBorderProps( attributes );

const isStripedStyle = blockProps.className.includes( 'is-style-stripes' );

// Secondary color props to be applied conditionally to inner elements.
const headerProps = getColorPropsFromObjects( 'header', props );
const stripedProps = getColorPropsFromObjects( 'secondary', props );
const footerProps = getColorPropsFromObjects( 'footer', props );

/**
* Updates the initial column count used for table creation.
*
Expand Down Expand Up @@ -385,10 +392,27 @@ function TableEdit( {
},
];

const getRowProps = ( name, rowIndex ) => {
if ( name === 'head' ) {
return headerProps;
}

if ( name === 'foot' ) {
return footerProps;
}

// Striped styling only applies to table body.
if ( isStripedStyle && rowIndex % 2 === 0 ) {
return stripedProps;
}

return {};
};

const renderedSections = [ 'head', 'body', 'foot' ].map( ( name ) => (
<TSection name={ name } key={ name }>
{ attributes[ name ].map( ( { cells }, rowIndex ) => (
<tr key={ rowIndex }>
<tr key={ rowIndex } { ...getRowProps( name, rowIndex ) }>
{ cells.map(
(
{ content, tag: CellTag, scope, align },
Expand Down Expand Up @@ -427,7 +451,7 @@ function TableEdit( {
const isEmpty = ! sections.length;

return (
<figure { ...useBlockProps() }>
<figure { ...blockProps }>
{ ! isEmpty && (
<BlockControls>
<ToolbarGroup>
Expand Down Expand Up @@ -455,6 +479,11 @@ function TableEdit( {
) }
{ ! isEmpty && (
<InspectorControls>
<SecondaryColorControls
sections={ sections }
isStripedStyle={ isStripedStyle }
tableProps={ props }
/>
<PanelBody
title={ __( 'Table settings' ) }
className="blocks-table-settings"
Expand Down Expand Up @@ -545,4 +574,11 @@ function TableEdit( {
);
}

export default TableEdit;
export default withColors( {
secondaryBackgroundColor: 'background-color',
secondaryTextColor: 'color',
headerBackgroundColor: 'background-color',
headerTextColor: 'color',
footerBackgroundColor: 'background-color',
footerTextColor: 'color',
} )( TableEdit );
32 changes: 30 additions & 2 deletions packages/block-library/src/table/save.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ import {
__experimentalGetColorClassesAndStyles as getColorClassesAndStyles,
} from '@wordpress/block-editor';

/**
* Internal dependencies
*/
import { getColorProps } from './utils';

export default function save( { attributes } ) {
const { hasFixedLayout, head, body, foot, caption } = attributes;
const isEmpty = ! head.length && ! body.length && ! foot.length;
Expand All @@ -21,15 +26,38 @@ export default function save( { attributes } ) {
return null;
}

const blockProps = useBlockProps.save();
const isStripedStyle = blockProps.className.includes( 'is-style-stripes' );

const colorProps = getColorClassesAndStyles( attributes );
const borderProps = getBorderClassesAndStyles( attributes );
const headerProps = getColorProps( 'header', attributes );
const stripedProps = getColorProps( 'secondary', attributes );
const footerProps = getColorProps( 'footer', attributes );

const classes = classnames( colorProps.className, borderProps.className, {
'has-fixed-layout': hasFixedLayout,
} );

const hasCaption = ! RichText.isEmpty( caption );

const getRowProps = ( name, rowIndex ) => {
if ( name === 'head' ) {
return headerProps;
}

if ( name === 'foot' ) {
return footerProps;
}

// Striped styling only applies to table body.
if ( isStripedStyle && rowIndex % 2 === 0 ) {
return stripedProps;
}

return {};
};

const Section = ( { type, rows } ) => {
if ( ! rows.length ) {
return null;
Expand All @@ -40,7 +68,7 @@ export default function save( { attributes } ) {
return (
<Tag>
{ rows.map( ( { cells }, rowIndex ) => (
<tr key={ rowIndex }>
<tr key={ rowIndex } { ...getRowProps( type, rowIndex ) }>
{ cells.map(
( { content, tag, scope, align }, cellIndex ) => {
const cellClasses = classnames( {
Expand Down Expand Up @@ -72,7 +100,7 @@ export default function save( { attributes } ) {
};

return (
<figure { ...useBlockProps.save() }>
<figure { ...blockProps }>
<table
className={ classes === '' ? undefined : classes }
style={ { ...colorProps.style, ...borderProps.style } }
Expand Down
116 changes: 116 additions & 0 deletions packages/block-library/src/table/secondary-color-controls.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
/**
* WordPress dependencies
*/
import { ContrastChecker, PanelColorSettings } from '@wordpress/block-editor';
import { Platform } from '@wordpress/element';
import { __ } from '@wordpress/i18n';

const SecondaryColorControls = ( {
sections,
isStripedStyle,
tableProps: {
secondaryBackgroundColor,
setSecondaryBackgroundColor,
secondaryTextColor,
setSecondaryTextColor,
headerBackgroundColor,
setHeaderBackgroundColor,
headerTextColor,
setHeaderTextColor,
footerBackgroundColor,
setFooterBackgroundColor,
footerTextColor,
setFooterTextColor,
},
} ) => {
const activeColors = [];
const contrastCheckerConfigs = [];

// Color options are only included as required to reduce clutter in the
// inspector controls sidebar. Contrast checkers are setup for each
// background and text color pairing.

if ( sections.includes( 'head' ) ) {
activeColors.push(
{
value: headerTextColor.color,
onChange: setHeaderTextColor,
label: __( 'Header text color' ),
},
{
value: headerBackgroundColor.color,
onChange: setHeaderBackgroundColor,
label: __( 'Header background color' ),
}
);
contrastCheckerConfigs.push( {
textColor: headerTextColor?.color,
backgroundColor: headerBackgroundColor?.color,
isLargeText: false,
id: 'header-contrast-checker',
} );
}

if ( isStripedStyle ) {
activeColors.push(
{
value: secondaryTextColor.color,
onChange: setSecondaryTextColor,
label: __( 'Striped text color' ),
},
{
value: secondaryBackgroundColor.color,
onChange: setSecondaryBackgroundColor,
label: __( 'Striped background color' ),
}
);
contrastCheckerConfigs.push( {
textColor: secondaryTextColor?.color,
backgroundColor: secondaryBackgroundColor?.color,
isLargeText: false,
id: 'striped-contrast-checker',
} );
}

if ( sections.includes( 'foot' ) ) {
activeColors.push(
{
value: footerTextColor.color,
onChange: setFooterTextColor,
label: __( 'Footer text color' ),
},
{
value: footerBackgroundColor.color,
onChange: setFooterBackgroundColor,
label: __( 'Footer background color' ),
}
);
contrastCheckerConfigs.push( {
textColor: footerTextColor?.color,
backgroundColor: footerBackgroundColor?.color,
isLargeText: false,
id: 'footer-contrast-checker',
} );
}

// Don't display color controls for Native or if there aren't any needed.
if ( Platform.OS !== 'web' || ! activeColors.length ) {
return null;
}

const contrastCheckers = contrastCheckerConfigs.map( ( config ) => (
<ContrastChecker key={ config.id } { ...config } />
) );

return (
<PanelColorSettings
title={ __( 'Secondary Colors' ) }
colorSettings={ activeColors }
initialOpen={ false }
>
{ contrastCheckers }
</PanelColorSettings>
);
};

export default SecondaryColorControls;
12 changes: 11 additions & 1 deletion packages/block-library/src/table/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
border-spacing: 0;
border-collapse: inherit;
background-color: transparent;
border-bottom: 1px solid $gray-100;

tbody tr:nth-child(odd) {
background-color: $gray-100;
Expand Down Expand Up @@ -95,7 +96,16 @@
border-color: transparent;
}

border-bottom: 1px solid $gray-100;
// Force user selected colors while stripe style is active.
table.has-text-color {
thead,
tfoot,
tbody {
tr:not(.has-text-color) {
color: currentColor;
}
}
}
}

// Border Styles
Expand Down
Loading