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

Table: Add border block support #31265

Merged
merged 3 commits into from
Apr 29, 2021
Merged
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
1 change: 1 addition & 0 deletions packages/block-editor/src/hooks/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ import './font-size';
import './border-color';
import './layout';

export { getBorderClassesAndStyles, useBorderProps } from './use-border-props';
export { getColorClassesAndStyles, useColorProps } from './use-color-props';
1 change: 1 addition & 0 deletions packages/block-editor/src/hooks/index.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ import './style';
import './color';
import './font-size';

export { getBorderClassesAndStyles, useBorderProps } from './use-border-props';
export { getColorClassesAndStyles, useColorProps } from './use-color-props';
73 changes: 73 additions & 0 deletions packages/block-editor/src/hooks/use-border-props.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/**
* External dependencies
*/
import classnames from 'classnames';

/**
* Internal dependencies
*/
import { getInlineStyles } from './style';
import {
getColorClassName,
getColorObjectByAttributeValues,
} from '../components/colors';
import useEditorFeature from '../components/use-editor-feature';

// This utility is intended to assist where the serialization of the border
// block support is being skipped for a block but the border related CSS classes
// & styles still need to be generated so they can be applied to inner elements.

const EMPTY_ARRAY = [];

/**
* Provides the CSS class names and inline styles for a block's border support
* attributes.
*
* @param {Object} attributes Block attributes.
* @param {string} attributes.borderColor Selected named border color.
* @param {Object} attributes.style Block's styles attribute.
*
* @return {Object} Border block support derived CSS classes & styles.
*/
export function getBorderClassesAndStyles( { borderColor, style } ) {
const borderStyles = style?.border || {};
const borderClass = getColorClassName( 'border-color', borderColor );

const className = classnames( {
[ borderClass ]: !! borderClass,
'has-border-color': borderColor || style?.border?.color,
} );

return {
className: className || undefined,
style: getInlineStyles( { border: borderStyles } ),
};
}

/**
* Derives the border related props for a block from its border block support
* attributes.
*
* Inline styles are forced for named colors to ensure these selections are
* reflected when themes do not load their color stylesheets in the editor.
*
* @param {Object} attributes Block attributes.
* @return {Object} ClassName & style props from border block support.
*/
export function useBorderProps( attributes ) {
const colors = useEditorFeature( 'color.palette' ) || EMPTY_ARRAY;
const borderProps = getBorderClassesAndStyles( attributes );

// Force inline style to apply border color when themes do not load their
// color stylesheets in the editor.
if ( attributes.borderColor ) {
const borderColorObject = getColorObjectByAttributeValues(
colors,
attributes.borderColor
);

borderProps.style.borderColor = borderColorObject.color;
}

return borderProps;
}
2 changes: 2 additions & 0 deletions packages/block-editor/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import '@wordpress/rich-text';
*/
import './hooks';
export {
getBorderClassesAndStyles as __experimentalGetBorderClassesAndStyles,
useBorderProps as __experimentalUseBorderProps,
getColorClassesAndStyles as __experimentalGetColorClassesAndStyles,
useColorProps as __experimentalUseColorProps,
} from './hooks';
Expand Down
6 changes: 6 additions & 0 deletions packages/block-library/src/table/block.json
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,12 @@
"__experimentalSkipSerialization": true,
"gradients": true
},
"__experimentalBorder": {
"__experimentalSkipSerialization": true,
"color": true,
"style": true,
"width": true
},
"__experimentalSelector": ".wp-block-table > table"
},
"editorStyle": "wp-block-table-editor",
Expand Down
12 changes: 8 additions & 4 deletions packages/block-library/src/table/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
AlignmentToolbar,
useBlockProps,
__experimentalUseColorProps as useColorProps,
__experimentalUseBorderProps as useBorderProps,
} from '@wordpress/block-editor';
import { __ } from '@wordpress/i18n';
import {
Expand Down Expand Up @@ -103,6 +104,7 @@ function TableEdit( {
const [ selectedCell, setSelectedCell ] = useState();

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

/**
* Updates the initial column count used for table creation.
Expand Down Expand Up @@ -477,10 +479,12 @@ function TableEdit( {
) }
{ ! isEmpty && (
<table
className={ classnames( colorProps.className, {
'has-fixed-layout': hasFixedLayout,
} ) }
style={ colorProps.style }
className={ classnames(
colorProps.className,
borderProps.className,
{ 'has-fixed-layout': hasFixedLayout }
) }
style={ { ...colorProps.style, ...borderProps.style } }
>
{ renderedSections }
</table>
Expand Down
6 changes: 4 additions & 2 deletions packages/block-library/src/table/save.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import classnames from 'classnames';
import {
RichText,
useBlockProps,
__experimentalGetBorderClassesAndStyles as getBorderClassesAndStyles,
__experimentalGetColorClassesAndStyles as getColorClassesAndStyles,
} from '@wordpress/block-editor';

Expand All @@ -21,8 +22,9 @@ export default function save( { attributes } ) {
}

const colorProps = getColorClassesAndStyles( attributes );
const borderProps = getBorderClassesAndStyles( attributes );

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

Expand Down Expand Up @@ -73,7 +75,7 @@ export default function save( { attributes } ) {
<figure { ...useBlockProps.save() }>
<table
className={ classes === '' ? undefined : classes }
style={ colorProps.style }
style={ { ...colorProps.style, ...borderProps.style } }
>
<Section type="head" rows={ head } />
<Section type="body" rows={ body } />
Expand Down
32 changes: 32 additions & 0 deletions packages/block-library/src/table/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -97,4 +97,36 @@

border-bottom: 1px solid $gray-100;
}

// Border Styles
//
// Allow any custom border color, style or width selections to be inherited
// from the table element that receives the border support props.

.has-border-color {
> *,
tr,
th,
td {
border-color: inherit;
}
}

table[style*="border-style"] {
> *,
tr,
th,
td {
border-style: inherit;
}
}

table[style*="border-width"] {
> *,
tr,
th,
td {
border-width: inherit;
}
}
}