From fe9fb941ed6dc00419f6b3183aa0526af7ebc8ff Mon Sep 17 00:00:00 2001 From: gilbert-hernandez Date: Mon, 30 Sep 2024 10:27:23 -0600 Subject: [PATCH 01/98] KAD-3345 ShadowControl/ResponsiveShadowControl component created/added to adv text --- ...-kadence-blocks-advanced-heading-block.php | 8 + src/blocks/advancedheading/block.json | 24 +++ src/blocks/advancedheading/edit.js | 202 ++++++++++++------ src/packages/components/src/index.js | 2 + .../shadow/responsive-shadow-control/index.js | 178 +++++++++++++++ .../src/shadow/shadow-control/index.js | 111 ++++++++++ 6 files changed, 465 insertions(+), 60 deletions(-) create mode 100644 src/packages/components/src/shadow/responsive-shadow-control/index.js create mode 100644 src/packages/components/src/shadow/shadow-control/index.js diff --git a/includes/blocks/class-kadence-blocks-advanced-heading-block.php b/includes/blocks/class-kadence-blocks-advanced-heading-block.php index 33087a377..2345b61c7 100644 --- a/includes/blocks/class-kadence-blocks-advanced-heading-block.php +++ b/includes/blocks/class-kadence-blocks-advanced-heading-block.php @@ -172,6 +172,14 @@ public function build_css( $attributes, $css, $unique_id, $unique_style_id ) { if ( isset( $attributes['textShadow'] ) && is_array( $attributes['textShadow'] ) && isset( $attributes['textShadow'][0] ) && is_array( $attributes['textShadow'][0] ) && isset( $attributes['textShadow'][0]['enable'] ) && $attributes['textShadow'][0]['enable'] ) { $css->add_property( 'text-shadow', ( isset( $attributes['textShadow'][0]['hOffset'] ) ? $attributes['textShadow'][0]['hOffset'] : 1 ) . 'px ' . ( isset( $attributes['textShadow'][0]['vOffset'] ) ? $attributes['textShadow'][0]['vOffset'] : 1 ) . 'px ' . ( isset( $attributes['textShadow'][0]['blur'] ) ? $attributes['textShadow'][0]['blur'] : 1 ) . 'px ' . ( isset( $attributes['textShadow'][0]['color'] ) ? $css->render_color( $attributes['textShadow'][0]['color'] ) : 'rgba(0,0,0,0.2)' ) ); } + if ( isset( $attributes['textShadowTablet'] ) && is_array( $attributes['textShadowTablet'] ) && isset( $attributes['textShadowTablet'][0] ) && is_array( $attributes['textShadowTablet'][0] ) && isset( $attributes['textShadowTablet'][0]['enable'] ) && $attributes['textShadowTablet'][0]['enable'] ) { + $css->set_media_state('tablet'); + $css->add_property( 'text-shadow', ( isset( $attributes['textShadowTablet'][0]['hOffset'] ) ? $attributes['textShadowTablet'][0]['hOffset'] : 1 ) . 'px ' . ( isset( $attributes['textShadowTablet'][0]['vOffset'] ) ? $attributes['textShadowTablet'][0]['vOffset'] : 1 ) . 'px ' . ( isset( $attributes['textShadowTablet'][0]['blur'] ) ? $attributes['textShadowTablet'][0]['blur'] : 1 ) . 'px ' . ( isset( $attributes['textShadowTablet'][0]['color'] ) ? $css->render_color( $attributes['textShadowTablet'][0]['color'] ) : 'rgba(0,0,0,0.2)' ) ); + } + if ( isset( $attributes['textShadowMobile'] ) && is_array( $attributes['textShadowMobile'] ) && isset( $attributes['textShadowMobile'][0] ) && is_array( $attributes['textShadowMobile'][0] ) && isset( $attributes['textShadowMobile'][0]['enable'] ) && $attributes['textShadowMobile'][0]['enable'] ) { + $css->set_media_state('mobile'); + $css->add_property( 'text-shadow', ( isset( $attributes['textShadowMobile'][0]['hOffset'] ) ? $attributes['textShadowMobile'][0]['hOffset'] : 1 ) . 'px ' . ( isset( $attributes['textShadowMobile'][0]['vOffset'] ) ? $attributes['textShadowMobile'][0]['vOffset'] : 1 ) . 'px ' . ( isset( $attributes['textShadowMobile'][0]['blur'] ) ? $attributes['textShadowMobile'][0]['blur'] : 1 ) . 'px ' . ( isset( $attributes['textShadowMobile'][0]['color'] ) ? $css->render_color( $attributes['textShadowMobile'][0]['color'] ) : 'rgba(0,0,0,0.2)' ) ); + } $css->set_media_state( 'tablet' ); // Old size first. if ( ! empty( $attributes['tabSize'] ) ) { diff --git a/src/blocks/advancedheading/block.json b/src/blocks/advancedheading/block.json index 5d3374454..d4223b353 100644 --- a/src/blocks/advancedheading/block.json +++ b/src/blocks/advancedheading/block.json @@ -319,6 +319,30 @@ } ] }, + "textShadowTablet": { + "type": "array", + "default": [ + { + "enable": false, + "color": "rgba(0, 0, 0, 0.2)", + "blur": 1, + "hOffset": 1, + "vOffset": 1 + } + ] + }, + "textShadowMobile": { + "type": "array", + "default": [ + { + "enable": false, + "color": "rgba(0, 0, 0, 0.2)", + "blur": 1, + "hOffset": 1, + "vOffset": 1 + } + ] + }, "htmlTag": { "type": "string", "default": "heading" diff --git a/src/blocks/advancedheading/edit.js b/src/blocks/advancedheading/edit.js index 7b453f24d..5e3b90343 100644 --- a/src/blocks/advancedheading/edit.js +++ b/src/blocks/advancedheading/edit.js @@ -10,6 +10,7 @@ import classnames from 'classnames'; import { PopColorControl, TextShadowControl, + ResponsiveShadowControl, TypographyControls, InlineTypographyControls, ResponsiveMeasurementControls, @@ -119,6 +120,8 @@ function KadenceAdvancedHeading(props) { color, colorClass, textShadow, + textShadowTablet, + textShadowMobile, mobileAlign, tabletAlign, size, @@ -357,17 +360,66 @@ function KadenceAdvancedHeading(props) { } }, []); + let newItems; const saveShadow = (value) => { - const newItems = textShadow.map((item, thisIndex) => { - if (0 === thisIndex) { - item = { ...item, ...value }; + if (value.enable === 'reset') { + const resetItems = [ + { + type: 'array', + default: [ + { + enable: false, + color: 'rgba(0, 0, 0, 0.2)', + blur: 1, + hOffset: 1, + vOffset: 1, + }, + ], + enable: false, + }, + ]; + switch (previewDevice) { + case 'Desktop': + setAttributes({ textShadow: resetItems }); + break; + case 'Tablet': + setAttributes({ textShadowTablet: resetItems }); + break; + case 'Mobile': + setAttributes({ textShadowMobile: resetItems }); + break; } - - return item; - }); - setAttributes({ - textShadow: newItems, - }); + } else if (previewDevice === 'Desktop') { + newItems = textShadow.map((item, thisIndex) => { + if (0 === thisIndex) { + item = { ...item, ...value }; + } + return item; + }); + setAttributes({ + textShadow: newItems, + }); + } else if (previewDevice === 'Tablet') { + newItems = textShadowTablet.map((item, thisIndex) => { + if (0 === thisIndex) { + item = { ...item, ...value }; + } + return item; + }); + setAttributes({ + textShadowTablet: newItems, + }); + } else if (previewDevice === 'Mobile') { + newItems = textShadowMobile.map((item, thisIndex) => { + if (0 === thisIndex) { + item = { ...item, ...value }; + } + return item; + }); + setAttributes({ + textShadowMobile: newItems, + }); + } }; const isDynamicReplaced = @@ -475,6 +527,64 @@ function KadenceAdvancedHeading(props) { undefined !== tabletAlign ? tabletAlign : '', undefined !== mobileAlign ? mobileAlign : '' ); + const previewEnableTextShadow = getPreviewSize( + previewDevice, + undefined !== textShadow ? textShadow[0].enable : '', + undefined !== textShadowTablet ? textShadowTablet[0].enable : '', + undefined !== textShadowMobile ? textShadowMobile[0].enable : '' + ); + const previewColorTextShadow = getPreviewSize( + previewDevice, + undefined !== textShadow && undefined !== textShadow[0] && undefined !== textShadow[0].color + ? textShadow[0].color + : 'rgba(0, 0, 0, 0.2)', + undefined !== textShadowTablet && undefined !== textShadowTablet[0] && undefined !== textShadowTablet[0].color + ? textShadowTablet[0].color + : 'rgba(0, 0, 0, 0.2)', + undefined !== textShadowMobile && undefined !== textShadowMobile[0] && undefined !== textShadowMobile[0].color + ? textShadowMobile[0].color + : 'rgba(0, 0, 0, 0.2)' + ); + const previewHOffset = getPreviewSize( + previewDevice, + undefined !== textShadow && undefined !== textShadow[0] && undefined !== textShadow[0].hOffset + ? textShadow[0].hOffset + : 1, + undefined !== textShadowTablet && undefined !== textShadowTablet[0] && undefined !== textShadowTablet[0].hOffset + ? textShadowTablet[0].hOffset + : 1, + undefined !== textShadowMobile && undefined !== textShadowMobile[0] && undefined !== textShadowMobile[0].hOffset + ? textShadowMobile[0].hOffset + : 1 + ); + const previewVOffset = getPreviewSize( + previewDevice, + undefined !== textShadow && undefined !== textShadow[0] && undefined !== textShadow[0].vOffset + ? textShadow[0].vOffset + : 1, + + undefined !== textShadowTablet && undefined !== textShadowTablet[0] && undefined !== textShadowTablet[0].vOffset + ? textShadowTablet[0].vOffset + : 1, + + undefined !== textShadowMobile && undefined !== textShadowMobile[0] && undefined !== textShadowMobile[0].vOffset + ? textShadowMobile[0].vOffset + : 1 + ); + const previewBlur = getPreviewSize( + previewDevice, + undefined !== textShadow && undefined !== textShadow[0] && undefined !== textShadow[0].blur + ? textShadow[0].blur + : 1, + + undefined !== textShadowTablet && undefined !== textShadowTablet[0] && undefined !== textShadowTablet[0].blur + ? textShadowTablet[0].blur + : 1, + + undefined !== textShadowMobile && undefined !== textShadowMobile[0] && undefined !== textShadowMobile[0].blur + ? textShadowMobile[0].blur + : 1 + ); let previewJustifyAlign = previewAlign; switch (previewAlign) { case 'left': @@ -907,21 +1017,23 @@ function KadenceAdvancedHeading(props) { : undefined, textTransform: textTransform ? textTransform : undefined, fontFamily: typography ? renderTypography : '', - textShadow: - undefined !== textShadow && - undefined !== textShadow[0] && - undefined !== textShadow[0].enable && - textShadow[0].enable - ? (undefined !== textShadow[0].hOffset ? textShadow[0].hOffset : 1) + - 'px ' + - (undefined !== textShadow[0].vOffset ? textShadow[0].vOffset : 1) + - 'px ' + - (undefined !== textShadow[0].blur ? textShadow[0].blur : 1) + - 'px ' + - (undefined !== textShadow[0].color - ? KadenceColorOutput(textShadow[0].color) - : 'rgba(0,0,0,0.2)') - : undefined, + textShadow: previewEnableTextShadow + ? `${previewHOffset}px ${previewVOffset}px ${previewBlur}px ${KadenceColorOutput( + previewColorTextShadow + )}` + : textShadow[0].enable && previewDevice === 'Tablet' + ? `${textShadow[0].hOffset}px ${textShadow[0].vOffset}px ${ + textShadow[0].blur + }px ${KadenceColorOutput(textShadow[0].color)}` + : textShadowTablet[0].enable && previewDevice === 'Mobile' + ? `${textShadowTablet[0].hOffset}px ${textShadowTablet[0].vOffset}px ${ + textShadowTablet[0].blur + }px ${KadenceColorOutput(textShadowTablet[0].color)}` + : textShadow[0].enable && previewDevice === 'Mobile' + ? `${textShadow[0].hOffset}px ${textShadow[0].vOffset}px ${ + textShadow[0].blur + }px ${KadenceColorOutput(textShadow[0].color)}` + : undefined, }} placeholder={__('Write something…', 'kadence-blocks')} /> @@ -1607,44 +1719,14 @@ function KadenceAdvancedHeading(props) { initialOpen={false} panelName={'kb-adv-heading-text-shadow'} > - { saveShadow({ enable: value }); }} diff --git a/src/packages/components/src/index.js b/src/packages/components/src/index.js index d66a5fe40..2a2920572 100644 --- a/src/packages/components/src/index.js +++ b/src/packages/components/src/index.js @@ -97,6 +97,8 @@ export { default as MeasurementSingleControl } from './measurement/single-input- /* Color */ export { default as AdvancedColorControlPalette } from './color/advanced-color-control-palette'; export { default as BorderColorControls } from './color/border-color-control'; +export { default as ShadowControl } from './shadow/shadow-control'; +export { default as ResponsiveShadowControl } from './shadow/responsive-shadow-control'; /* Block Defaults */ export { default as KadenceBlockDefaults } from './block-defaults'; diff --git a/src/packages/components/src/shadow/responsive-shadow-control/index.js b/src/packages/components/src/shadow/responsive-shadow-control/index.js new file mode 100644 index 000000000..e6139d8db --- /dev/null +++ b/src/packages/components/src/shadow/responsive-shadow-control/index.js @@ -0,0 +1,178 @@ +/** + * Import Externals + */ +import PopColorControl from '../../pop-color-control'; + +/** + * Internal block libraries + */ +import { __ } from '@wordpress/i18n'; +import {Component, useState} from '@wordpress/element'; +import { ToggleControl } from '@wordpress/components'; +import { map, isEqual } from 'lodash'; +import { useSelect, useDispatch } from '@wordpress/data'; +import { default as ShadowControl } from '../shadow-control'; + +import { + Dashicon, + Button, + ButtonGroup, +} from '@wordpress/components'; +import {capitalizeFirstLetter} from '@kadence/helpers'; +import RangeControl from "../../range/range-control"; +import {undo} from "@wordpress/icons"; + +/** + * Build the BoxShadow controls + * @returns {object} BoxShadow settings. + */ +export default function ResponsiveShadowControl ( { + label, + enable = true, + color, + colorDefault, + blur, + hOffset, + vOffset, + onColorChange, + onBlurChange, + onHOffsetChange, + onVOffsetChange, + onEnableChange, + className = '', + reset = true, +} ) { + const [ deviceType, setDeviceType ] = useState( 'Desktop' ); + const previewDevice = useSelect( ( select ) => { + return select( 'kadenceblocks/data' ).getPreviewDeviceType(); + }, [] ); + if ( previewDevice !== deviceType ) { + setDeviceType( previewDevice ); + } + const { + setPreviewDeviceType, + } = useDispatch( 'kadenceblocks/data' ); + const customSetPreviewDeviceType = ( device ) => { + setPreviewDeviceType( capitalizeFirstLetter( device ) ); + setDeviceType( capitalizeFirstLetter( device ) ); + }; + + const onReset = () => { + onEnableChange('reset'); + } + const devices = [ + { + name: 'Desktop', + key: 'desktop', + title: , + itemClass: 'kb-desk-tab', + }, + { + name: 'Tablet', + key: 'tablet', + title: , + itemClass: 'kb-tablet-tab', + }, + { + name: 'Mobile', + key: 'mobile', + title: , + itemClass: 'kb-mobile-tab', + }, + ]; + const output = {}; + output.Mobile = ( + + ); + output.Tablet = ( + + ); + output.Desktop = ( + + ); + + return [ + onEnableChange && ( +
+
+ { label && ( + + { label } + { reset && ( + + ) } + + ) } + + { map( devices, ( { name, key, title, itemClass } ) => ( + + ) ) } + +
+ { ( output[ deviceType ] ? output[ deviceType ] : output.Desktop ) } +
+ ) + ]; +} diff --git a/src/packages/components/src/shadow/shadow-control/index.js b/src/packages/components/src/shadow/shadow-control/index.js new file mode 100644 index 000000000..92f13eae4 --- /dev/null +++ b/src/packages/components/src/shadow/shadow-control/index.js @@ -0,0 +1,111 @@ +/** + * BoxShadow Component + * + */ + +/** + * Import Externals + */ +import PopColorControl from '../../pop-color-control'; + +/** + * Internal block libraries + */ +import { __ } from '@wordpress/i18n'; +import { Component } from '@wordpress/element'; +import { ToggleControl } from '@wordpress/components'; +/** + * Build the Shadow controls + * @returns {object} Shadow settings. + */ +const ShadowControl = ( { + label, + enable = true, + color, + colorDefault, + blur, + hOffset, + vOffset, + onColorChange, + onBlurChange, + onHOffsetChange, + onVOffsetChange, + onEnableChange +} ) => ( +
+ { label && ( +
+

{ label }

+ { onEnableChange && ( + onEnableChange( value ) } + /> + ) } +
+ ) } + { enable && ( +
+
+
+

{ __( 'Color', 'kadence-blocks' ) }

+ onColorChange( value ) } + /> +
+
+

{ 'X' }

+
+
+ onHOffsetChange( Number( event.target.value ) ) } + min={ -200 } + max={ 200 } + step={ 1 } + type="number" + className="components-text-control__input" + /> +
+
+
+
+

{ 'Y' }

+
+
+ onVOffsetChange( Number( event.target.value ) ) } + min={ -200 } + max={ 200 } + step={ 1 } + type="number" + className="components-text-control__input" + /> +
+
+
+
+

{ 'Blur' }

+
+
+ onBlurChange( Number( event.target.value ) ) } + min={ 0 } + max={ 200 } + step={ 1 } + type="number" + className="components-text-control__input" + /> +
+
+
+
+
+ ) } +
+); +export default ShadowControl; From 45530f500672e9ad69e23d713786e27746e9ef6c Mon Sep 17 00:00:00 2001 From: Josh Oakes Date: Mon, 7 Oct 2024 12:07:36 -0500 Subject: [PATCH 02/98] KAD-3155 Work in progress --- .../class-kadence-blocks-table-block.php | 105 +++++++++ .../class-kadence-blocks-editor-assets.php | 1 + kadence-blocks.php | 1 + src/blocks/table/block.json | 24 ++ src/blocks/table/children/data/block.json | 17 ++ src/blocks/table/children/data/edit.js | 66 ++++++ src/blocks/table/children/data/editor.scss | 7 + src/blocks/table/children/data/index.js | 27 +++ src/blocks/table/children/data/style.scss | 6 + src/blocks/table/children/row/block.json | 21 ++ src/blocks/table/children/row/edit.js | 156 +++++++++++++ src/blocks/table/children/row/editor.scss | 7 + src/blocks/table/children/row/index.js | 27 +++ src/blocks/table/children/row/style.scss | 6 + src/blocks/table/edit.js | 217 ++++++++++++++++++ src/blocks/table/editor.scss | 18 ++ src/blocks/table/index.js | 30 +++ src/blocks/table/style.scss | 6 + webpack.config.js | 1 + 19 files changed, 743 insertions(+) create mode 100644 includes/blocks/class-kadence-blocks-table-block.php create mode 100644 src/blocks/table/block.json create mode 100644 src/blocks/table/children/data/block.json create mode 100644 src/blocks/table/children/data/edit.js create mode 100644 src/blocks/table/children/data/editor.scss create mode 100644 src/blocks/table/children/data/index.js create mode 100644 src/blocks/table/children/data/style.scss create mode 100644 src/blocks/table/children/row/block.json create mode 100644 src/blocks/table/children/row/edit.js create mode 100644 src/blocks/table/children/row/editor.scss create mode 100644 src/blocks/table/children/row/index.js create mode 100644 src/blocks/table/children/row/style.scss create mode 100644 src/blocks/table/edit.js create mode 100644 src/blocks/table/editor.scss create mode 100644 src/blocks/table/index.js create mode 100644 src/blocks/table/style.scss diff --git a/includes/blocks/class-kadence-blocks-table-block.php b/includes/blocks/class-kadence-blocks-table-block.php new file mode 100644 index 000000000..288abe04a --- /dev/null +++ b/includes/blocks/class-kadence-blocks-table-block.php @@ -0,0 +1,105 @@ +set_style_id( 'kb-' . $this->block_name . $unique_style_id ); + + + return $css->css_output(); + } + + /** + * Return dynamically generated HTML for block + * + * @param $attributes + * @param $unique_id + * @param $content + * @param WP_Block $block_instance The instance of the WP_Block class that represents the block being rendered. + * + * @return mixed + */ + public function build_html( $attributes, $unique_id, $content, $block_instance ) { + return sprintf( + '%2$s
', + esc_attr( $unique_id ), + $content + ); + } + + /** + * Registers scripts and styles. + */ + public function register_scripts() { + parent::register_scripts(); + // If in the backend, bail out. + if ( is_admin() ) { + return; + } + if ( apply_filters( 'kadence_blocks_check_if_rest', false ) && kadence_blocks_is_rest() ) { + return; + } + +// wp_register_script( 'kadence-blocks-' . $this->block_name, KADENCE_BLOCKS_URL . 'includes/assets/js/kt-tabs.min.js', array(), KADENCE_BLOCKS_VERSION, true ); + + } + +} + +Kadence_Blocks_Table_Block::get_instance(); diff --git a/includes/class-kadence-blocks-editor-assets.php b/includes/class-kadence-blocks-editor-assets.php index 227bd8241..5b59534c1 100644 --- a/includes/class-kadence-blocks-editor-assets.php +++ b/includes/class-kadence-blocks-editor-assets.php @@ -136,6 +136,7 @@ public function on_init_editor_assets() { 'search', 'show-more', 'spacer', + 'table', 'tableofcontents', 'tabs', 'testimonials', diff --git a/kadence-blocks.php b/kadence-blocks.php index f25fd14a4..4f80e4c5b 100644 --- a/kadence-blocks.php +++ b/kadence-blocks.php @@ -88,6 +88,7 @@ function kadence_blocks_init(): void { require_once KADENCE_BLOCKS_PATH . 'includes/blocks/class-kadence-blocks-search-block.php'; require_once KADENCE_BLOCKS_PATH . 'includes/blocks/class-kadence-blocks-show-more-block.php'; require_once KADENCE_BLOCKS_PATH . 'includes/blocks/class-kadence-blocks-spacer-block.php'; + require_once KADENCE_BLOCKS_PATH . 'includes/blocks/class-kadence-blocks-table-block.php'; require_once KADENCE_BLOCKS_PATH . 'includes/blocks/class-kadence-blocks-table-of-contents-block.php'; require_once KADENCE_BLOCKS_PATH . 'includes/blocks/class-kadence-blocks-tabs-block.php'; require_once KADENCE_BLOCKS_PATH . 'includes/blocks/class-kadence-blocks-testimonials-block.php'; diff --git a/src/blocks/table/block.json b/src/blocks/table/block.json new file mode 100644 index 000000000..74fa20c51 --- /dev/null +++ b/src/blocks/table/block.json @@ -0,0 +1,24 @@ +{ + "$schema": "https://schemas.wp.org/trunk/block.json", + "apiVersion": 3, + "name": "kadence/table", + "title": "Table (Adv)", + "category": "kadence-blocks", + "textdomain": "kadence-blocks", + "attributes": { + "uniqueID": { + "type": "string" + }, + "rows": { + "type": "number", + "default": 2 + }, + "columns": { + "type": "number", + "default": 2 + } + }, + "supports": { + "kbMetadata": true + } +} diff --git a/src/blocks/table/children/data/block.json b/src/blocks/table/children/data/block.json new file mode 100644 index 000000000..4426602c8 --- /dev/null +++ b/src/blocks/table/children/data/block.json @@ -0,0 +1,17 @@ +{ + "$schema": "https://schemas.wp.org/trunk/block.json", + "apiVersion": 3, + "name": "kadence/table-data", + "title": "Table Data", + "category": "kadence-blocks", + "textdomain": "kadence-blocks", + "parent": [ "kadence/row" ], + "attributes": { + "uniqueID": { + "type": "string" + } + }, + "supports": { + "kbMetadata": true + } +} diff --git a/src/blocks/table/children/data/edit.js b/src/blocks/table/children/data/edit.js new file mode 100644 index 000000000..50e14f858 --- /dev/null +++ b/src/blocks/table/children/data/edit.js @@ -0,0 +1,66 @@ +import { __ } from '@wordpress/i18n'; +import { useEffect } from '@wordpress/element'; +import { useSelect, useDispatch } from '@wordpress/data'; +import { useBlockProps, InnerBlocks } from '@wordpress/block-editor'; +import metadata from './block.json'; + +import { KadenceBlockDefaults, CopyPasteAttributes } from '@kadence/components'; +import { setBlockDefaults, getUniqueId, getPostOrFseId } from '@kadence/helpers'; + +import classnames from 'classnames'; + +const DEFAULT_BLOCK = [['core/paragraph', {}]]; +export function Edit(props) { + const { attributes, setAttributes, className, clientId } = props; + + const { uniqueID } = attributes; + + const { addUniqueID } = useDispatch('kadenceblocks/data'); + const { isUniqueID, isUniqueBlock, parentData } = useSelect( + (select) => { + return { + isUniqueID: (value) => select('kadenceblocks/data').isUniqueID(value), + isUniqueBlock: (value, clientId) => select('kadenceblocks/data').isUniqueBlock(value, clientId), + parentData: { + rootBlock: select('core/block-editor').getBlock( + select('core/block-editor').getBlockHierarchyRootClientId(clientId) + ), + postId: select('core/editor')?.getCurrentPostId() ? select('core/editor')?.getCurrentPostId() : '', + reusableParent: select('core/block-editor').getBlockAttributes( + select('core/block-editor').getBlockParentsByBlockName(clientId, 'core/block').slice(-1)[0] + ), + editedPostId: select('core/edit-site') ? select('core/edit-site').getEditedPostId() : false, + }, + }; + }, + [clientId] + ); + + const classes = classnames(className, 'kb-table-data'); + const blockProps = useBlockProps({ + className: classes, + }); + + useEffect(() => { + setBlockDefaults('kadence/table-data', attributes); + + const postOrFseId = getPostOrFseId(props, parentData); + const uniqueId = getUniqueId(uniqueID, clientId, isUniqueID, isUniqueBlock, postOrFseId); + if (uniqueId !== uniqueID) { + attributes.uniqueID = uniqueId; + setAttributes({ uniqueID: uniqueId }); + addUniqueID(uniqueId, clientId); + } else { + addUniqueID(uniqueID, clientId); + } + }, []); + + return ( + + {/*renderAppender={() => }*/} + + + ); +} + +export default Edit; diff --git a/src/blocks/table/children/data/editor.scss b/src/blocks/table/children/data/editor.scss new file mode 100644 index 000000000..4863db2a5 --- /dev/null +++ b/src/blocks/table/children/data/editor.scss @@ -0,0 +1,7 @@ +/** + * #.# Editor Styles + * + * CSS for just Backend enqueued after style.scss + * which makes it higher in priority. + */ +@import "style"; diff --git a/src/blocks/table/children/data/index.js b/src/blocks/table/children/data/index.js new file mode 100644 index 000000000..1e6bfb5a7 --- /dev/null +++ b/src/blocks/table/children/data/index.js @@ -0,0 +1,27 @@ +import { registerBlockType } from '@wordpress/blocks'; + +/** + * Internal dependencies + */ +import edit from './edit'; +import metadata from './block.json'; +import { spacerIcon } from '@kadence/icons'; +import { __, _x } from '@wordpress/i18n'; + +/** + * Import Css + */ +import './style.scss'; + +registerBlockType('kadence/table-data', { + ...metadata, + title: _x('Table Data', 'block title', 'kadence-blocks'), + description: _x('Display tables on your site', 'block description', 'kadence-blocks'), + keywords: [__('table', 'kadence-blocks'), __('structure', 'kadence-blocks'), 'KB'], + icon: { + src: spacerIcon, + }, + edit, + save: () => null, + example: {}, +}); diff --git a/src/blocks/table/children/data/style.scss b/src/blocks/table/children/data/style.scss new file mode 100644 index 000000000..b4d44bdb5 --- /dev/null +++ b/src/blocks/table/children/data/style.scss @@ -0,0 +1,6 @@ +/** + * #.# Editor Styles + * + * CSS for just Backend enqueued after style.scss + * which makes it higher in priority. + */ diff --git a/src/blocks/table/children/row/block.json b/src/blocks/table/children/row/block.json new file mode 100644 index 000000000..b76ade452 --- /dev/null +++ b/src/blocks/table/children/row/block.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://schemas.wp.org/trunk/block.json", + "apiVersion": 3, + "name": "kadence/table-row", + "title": "Table (Adv)", + "parent": [ "kadence/table" ], + "category": "kadence-blocks", + "textdomain": "kadence-blocks", + "attributes": { + "uniqueID": { + "type": "string" + }, + "columns": { + "type": "number", + "default": 2 + } + }, + "supports": { + "kbMetadata": true + } +} diff --git a/src/blocks/table/children/row/edit.js b/src/blocks/table/children/row/edit.js new file mode 100644 index 000000000..6ad5a83a7 --- /dev/null +++ b/src/blocks/table/children/row/edit.js @@ -0,0 +1,156 @@ +import { __ } from '@wordpress/i18n'; +import { useState, useEffect } from '@wordpress/element'; +import { useSelect, useDispatch } from '@wordpress/data'; +import { useBlockProps, BlockControls, InnerBlocks } from '@wordpress/block-editor'; +import metadata from './block.json'; + +import { + RangeControl, + ToggleControl, + TextControl, + Modal, + SelectControl, + FormFileUpload, + Button, + Notice, + __experimentalNumberControl as NumberControl, +} from '@wordpress/components'; + +import { + KadenceSelectPosts, + KadencePanelBody, + InspectorControlTabs, + KadenceInspectorControls, + KadenceBlockDefaults, + ResponsiveMeasureRangeControl, + SpacingVisualizer, + CopyPasteAttributes, +} from '@kadence/components'; + +import { + setBlockDefaults, + mouseOverVisualizer, + getSpacingOptionOutput, + getUniqueId, + getPostOrFseId, + getPreviewSize, +} from '@kadence/helpers'; + +import classnames from 'classnames'; + +export function Edit(props) { + const { attributes, setAttributes, className, clientId } = props; + + const { uniqueID, columns } = attributes; + + const { addUniqueID } = useDispatch('kadenceblocks/data'); + const { isUniqueID, isUniqueBlock, previewDevice, parentData } = useSelect( + (select) => { + return { + isUniqueID: (value) => select('kadenceblocks/data').isUniqueID(value), + isUniqueBlock: (value, clientId) => select('kadenceblocks/data').isUniqueBlock(value, clientId), + previewDevice: select('kadenceblocks/data').getPreviewDeviceType(), + parentData: { + rootBlock: select('core/block-editor').getBlock( + select('core/block-editor').getBlockHierarchyRootClientId(clientId) + ), + postId: select('core/editor')?.getCurrentPostId() ? select('core/editor')?.getCurrentPostId() : '', + reusableParent: select('core/block-editor').getBlockAttributes( + select('core/block-editor').getBlockParentsByBlockName(clientId, 'core/block').slice(-1)[0] + ), + editedPostId: select('core/edit-site') ? select('core/edit-site').getEditedPostId() : false, + }, + }; + }, + [clientId] + ); + + const [activeTab, setActiveTab] = useState('general'); + const { getBlocks } = useSelect((select) => select('core/block-editor')); + const { replaceInnerBlocks } = useDispatch('core/block-editor'); + + const nonTransAttrs = []; + + const classes = classnames(className, 'kb-table-row'); + const blockProps = useBlockProps({ + className: classes, + }); + + useEffect(() => { + setBlockDefaults('kadence/table-row', attributes); + + const postOrFseId = getPostOrFseId(props, parentData); + const uniqueId = getUniqueId(uniqueID, clientId, isUniqueID, isUniqueBlock, postOrFseId); + if (uniqueId !== uniqueID) { + attributes.uniqueID = uniqueId; + setAttributes({ uniqueID: uniqueId }); + addUniqueID(uniqueId, clientId); + } else { + addUniqueID(uniqueID, clientId); + } + }, []); + + useEffect(() => { + const innerBlocks = getBlocks(clientId); + + if (innerBlocks.length < columns) { + // Add new blocks + const newBlocks = [ + ...innerBlocks, + ...Array(Math.max(1, columns - innerBlocks.length)) + .fill(null) + .map(() => wp.blocks.createBlock('kadence/table-data', {})), + ]; + replaceInnerBlocks(clientId, newBlocks, false); + } else if (innerBlocks.length > columns) { + // Remove excess blocks + const updatedBlocks = innerBlocks.slice(0, columns); + replaceInnerBlocks(clientId, updatedBlocks, false); + } + }, [columns]); + + // const ALLOWED_BLOCKS = ['kadence/table-data']; + + return ( +
+ + setAttributes(attributesToPaste)} + /> + + + + + {activeTab === 'general' && ( + <> + + Settings + + + )} + + {activeTab === 'advanced' && <>KadenceBlockDefaults} + + + {/*allowedBlocks={ALLOWED_BLOCKS}*/} + + +
+ ); +} + +export default Edit; diff --git a/src/blocks/table/children/row/editor.scss b/src/blocks/table/children/row/editor.scss new file mode 100644 index 000000000..4863db2a5 --- /dev/null +++ b/src/blocks/table/children/row/editor.scss @@ -0,0 +1,7 @@ +/** + * #.# Editor Styles + * + * CSS for just Backend enqueued after style.scss + * which makes it higher in priority. + */ +@import "style"; diff --git a/src/blocks/table/children/row/index.js b/src/blocks/table/children/row/index.js new file mode 100644 index 000000000..c6295cc17 --- /dev/null +++ b/src/blocks/table/children/row/index.js @@ -0,0 +1,27 @@ +import { registerBlockType } from '@wordpress/blocks'; + +/** + * Internal dependencies + */ +import edit from './edit'; +import metadata from './block.json'; +import { spacerIcon } from '@kadence/icons'; +import { __, _x } from '@wordpress/i18n'; + +/** + * Import Css + */ +import './style.scss'; + +registerBlockType('kadence/table-row', { + ...metadata, + title: _x('Table Row', 'block title', 'kadence-blocks'), + description: _x('Display tables on your site', 'block description', 'kadence-blocks'), + keywords: [__('table', 'kadence-blocks'), __('structure', 'kadence-blocks'), 'KB'], + icon: { + src: spacerIcon, + }, + edit, + save: () => null, + example: {}, +}); diff --git a/src/blocks/table/children/row/style.scss b/src/blocks/table/children/row/style.scss new file mode 100644 index 000000000..b4d44bdb5 --- /dev/null +++ b/src/blocks/table/children/row/style.scss @@ -0,0 +1,6 @@ +/** + * #.# Editor Styles + * + * CSS for just Backend enqueued after style.scss + * which makes it higher in priority. + */ diff --git a/src/blocks/table/edit.js b/src/blocks/table/edit.js new file mode 100644 index 000000000..a31d0aeee --- /dev/null +++ b/src/blocks/table/edit.js @@ -0,0 +1,217 @@ +import { __ } from '@wordpress/i18n'; +import { useState, useEffect } from '@wordpress/element'; +import { useSelect, useDispatch } from '@wordpress/data'; +import { useBlockProps, BlockControls, InnerBlocks } from '@wordpress/block-editor'; +import classnames from 'classnames'; +import metadata from './block.json'; +import './editor.scss'; +import { createBlock } from '@wordpress/blocks'; + +import { + RangeControl, + ToggleControl, + TextControl, + Modal, + SelectControl, + FormFileUpload, + Button, + Notice, + __experimentalNumberControl as NumberControl, +} from '@wordpress/components'; + +import { + KadenceSelectPosts, + KadencePanelBody, + InspectorControlTabs, + KadenceInspectorControls, + KadenceBlockDefaults, + ResponsiveMeasureRangeControl, + SpacingVisualizer, + CopyPasteAttributes, +} from '@kadence/components'; + +import { + setBlockDefaults, + mouseOverVisualizer, + getSpacingOptionOutput, + getUniqueId, + getPostOrFseId, + getPreviewSize, +} from '@kadence/helpers'; + +export function Edit(props) { + const { attributes, setAttributes, className, clientId } = props; + + const { uniqueID, rows, columns } = attributes; + + const { addUniqueID } = useDispatch('kadenceblocks/data'); + const { isUniqueID, isUniqueBlock, previewDevice, parentData } = useSelect( + (select) => { + return { + isUniqueID: (value) => select('kadenceblocks/data').isUniqueID(value), + isUniqueBlock: (value, clientId) => select('kadenceblocks/data').isUniqueBlock(value, clientId), + previewDevice: select('kadenceblocks/data').getPreviewDeviceType(), + parentData: { + rootBlock: select('core/block-editor').getBlock( + select('core/block-editor').getBlockHierarchyRootClientId(clientId) + ), + postId: select('core/editor')?.getCurrentPostId() ? select('core/editor')?.getCurrentPostId() : '', + reusableParent: select('core/block-editor').getBlockAttributes( + select('core/block-editor').getBlockParentsByBlockName(clientId, 'core/block').slice(-1)[0] + ), + editedPostId: select('core/edit-site') ? select('core/edit-site').getEditedPostId() : false, + }, + }; + }, + [clientId] + ); + + const { replaceInnerBlocks } = useDispatch('core/block-editor'); + + const [activeTab, setActiveTab] = useState('general'); + + const nonTransAttrs = []; + + const classes = classnames( + { + 'wp-block-kadence-table': true, + [`wp-block-kadence-table${uniqueID}`]: uniqueID, + }, + className + ); + const blockProps = useBlockProps({ + className: classes, + }); + + useEffect(() => { + setBlockDefaults('kadence/table', attributes); + + if (uniqueID === undefined) { + updateRowsColumns(rows, columns); + } + + const postOrFseId = getPostOrFseId(props, parentData); + const uniqueId = getUniqueId(uniqueID, clientId, isUniqueID, isUniqueBlock, postOrFseId); + if (uniqueId !== uniqueID) { + attributes.uniqueID = uniqueId; + setAttributes({ uniqueID: uniqueId }); + addUniqueID(uniqueId, clientId); + } else { + addUniqueID(uniqueID, clientId); + } + }, []); + + const updateRowsColumns = (newRows, newColumns) => { + console.log(newRows, newColumns); + const currentBlocks = wp.data.select('core/block-editor').getBlocks(clientId); + + let newRowBlocks = [...currentBlocks]; + + if (newRows > rows && newRows !== 0) { + const additionalRows = Array(Math.max(1, newRows - currentBlocks.length)) + .fill() + .map(() => { + return createBlock( + 'kadence/table-row', + { columns: newColumns }, + Array(newColumns) + .fill() + .map(() => createBlock('kadence/table-data', {})) + ); + }); + newRowBlocks = [...newRowBlocks, ...additionalRows]; + } else if (newRows < rows && newRows !== 0) { + newRowBlocks = newRowBlocks.slice(0, newRows); + } + + if (newColumns !== columns) { + newRowBlocks = newRowBlocks.map((rowBlock) => { + if (rowBlock.attributes.columns === newColumns) { + return rowBlock; + } + return { + ...rowBlock, + attributes: { ...rowBlock.attributes, columns: newColumns }, + }; + }); + } + + replaceInnerBlocks(clientId, newRowBlocks, false); + setAttributes({ rows: newRows, columns: newColumns }); + }; + + return ( +
+ + setAttributes(attributesToPaste)} + /> + + + + + {activeTab === 'general' && ( + <> + + updateRowsColumns(newRows, columns)} + min={1} + max={50} + /> + updateRowsColumns(rows, newColumns)} + min={1} + max={20} + /> + + + + )} + + {activeTab === 'advanced' && ( + <> + + + )} + + + +
+
+ ); +} + +export default Edit; diff --git a/src/blocks/table/editor.scss b/src/blocks/table/editor.scss new file mode 100644 index 000000000..749c7bfd7 --- /dev/null +++ b/src/blocks/table/editor.scss @@ -0,0 +1,18 @@ +/** + * #.# Editor Styles + * + * CSS for just Backend enqueued after style.scss + * which makes it higher in priority. + */ +@import "style"; + +.wp-block-kadence-table { + table, th, td { + border: 1px solid; + border-collapse: collapse; + } + + .wp-block { + margin: 0 !important; + } +} diff --git a/src/blocks/table/index.js b/src/blocks/table/index.js new file mode 100644 index 000000000..691828a4e --- /dev/null +++ b/src/blocks/table/index.js @@ -0,0 +1,30 @@ +import { registerBlockType } from '@wordpress/blocks'; + +/** + * Internal dependencies + */ +import edit from './edit'; +import metadata from './block.json'; +import { spacerIcon } from '@kadence/icons'; +import { __, _x } from '@wordpress/i18n'; + +import './children/row/index'; +import './children/data/index'; + +/** + * Import Css + */ +import './style.scss'; + +registerBlockType('kadence/table', { + ...metadata, + title: _x('Table (Adv)', 'block title', 'kadence-blocks'), + description: _x('Display tables on your site', 'block description', 'kadence-blocks'), + keywords: [__('table', 'kadence-blocks'), __('structure', 'kadence-blocks'), 'KB'], + icon: { + src: spacerIcon, + }, + edit, + save: () => null, + example: {}, +}); diff --git a/src/blocks/table/style.scss b/src/blocks/table/style.scss new file mode 100644 index 000000000..b4d44bdb5 --- /dev/null +++ b/src/blocks/table/style.scss @@ -0,0 +1,6 @@ +/** + * #.# Editor Styles + * + * CSS for just Backend enqueued after style.scss + * which makes it higher in priority. + */ diff --git a/webpack.config.js b/webpack.config.js index cd78fc278..3f97bc616 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -46,6 +46,7 @@ module.exports = { 'blocks-testimonials': './src/blocks/testimonials/block.js', 'blocks-advanced-form': './src/blocks/advanced-form/index.js', 'blocks-progress-bar': './src/blocks/progress-bar/index.js', + 'blocks-table': './src/blocks/table/index.js', 'plugin-kadence-control': './src/plugin.js', 'early-filters': './src/early-filters.js', 'extension-kadence-base': './src/extension/kadence-base/index.js', From eae22b38833d69d9f8d12cdc83ef669edd565bf5 Mon Sep 17 00:00:00 2001 From: Josh Oakes Date: Tue, 29 Oct 2024 15:17:14 -0500 Subject: [PATCH 03/98] KAD-3689 Option to mark data as table header --- .../class-kadence-blocks-table-data-block.php | 104 ++++++++++++++++++ .../class-kadence-blocks-table-row-block.php | 101 +++++++++++++++++ kadence-blocks.php | 2 + src/blocks/table/children/data/block.json | 4 + src/blocks/table/children/data/edit.js | 60 ++++++++-- src/blocks/table/children/data/index.js | 5 +- src/blocks/table/children/row/edit.js | 33 ++++-- src/blocks/table/children/row/index.js | 5 +- src/blocks/table/edit.js | 28 +++-- src/blocks/table/index.js | 5 +- 10 files changed, 319 insertions(+), 28 deletions(-) create mode 100644 includes/blocks/class-kadence-blocks-table-data-block.php create mode 100644 includes/blocks/class-kadence-blocks-table-row-block.php diff --git a/includes/blocks/class-kadence-blocks-table-data-block.php b/includes/blocks/class-kadence-blocks-table-data-block.php new file mode 100644 index 000000000..95eaaee13 --- /dev/null +++ b/includes/blocks/class-kadence-blocks-table-data-block.php @@ -0,0 +1,104 @@ +block_name . '/block.json', + array( + 'render_callback' => array( $this, 'render_css' ), + ) + ); + } + + /** + * Builds CSS for block. + * + * @param array $attributes the blocks attributes. + * @param Kadence_Blocks_CSS $css the css class for blocks. + * @param string $unique_id the blocks attr ID. + * @param string $unique_style_id the blocks alternate ID for queries. + */ + public function build_css( $attributes, $css, $unique_id, $unique_style_id ) { + + $css->set_style_id( 'kb-' . $this->block_name . $unique_style_id ); + + + return $css->css_output(); + } + + /** + * Return dynamically generated HTML for block + * + * @param $attributes + * @param $unique_id + * @param $content + * @param WP_Block $block_instance The instance of the WP_Block class that represents the block being rendered. + * + * @return mixed + */ + public function build_html( $attributes, $unique_id, $content, $block_instance ) { + $tag = ! empty( $attributes['isHeader'] ) ? 'th' : 'td'; + + return sprintf( + '<%s class="kb-table-wrap kb-table-id-%2$s">%3$s', + $tag, + esc_attr( $unique_id ), + $content, + $tag + ); + } + +} + +Kadence_Blocks_Table_Data_Block::get_instance(); diff --git a/includes/blocks/class-kadence-blocks-table-row-block.php b/includes/blocks/class-kadence-blocks-table-row-block.php new file mode 100644 index 000000000..97206baa9 --- /dev/null +++ b/includes/blocks/class-kadence-blocks-table-row-block.php @@ -0,0 +1,101 @@ +block_name . '/block.json', + array( + 'render_callback' => array( $this, 'render_css' ), + ) + ); + } + + + /** + * Builds CSS for block. + * + * @param array $attributes the blocks attributes. + * @param Kadence_Blocks_CSS $css the css class for blocks. + * @param string $unique_id the blocks attr ID. + * @param string $unique_style_id the blocks alternate ID for queries. + */ + public function build_css( $attributes, $css, $unique_id, $unique_style_id ) { + + $css->set_style_id( 'kb-' . $this->block_name . $unique_style_id ); + + + return $css->css_output(); + } + + /** + * Return dynamically generated HTML for block + * + * @param $attributes + * @param $unique_id + * @param $content + * @param WP_Block $block_instance The instance of the WP_Block class that represents the block being rendered. + * + * @return mixed + */ + public function build_html( $attributes, $unique_id, $content, $block_instance ) { + return sprintf( + '%2$s', + esc_attr( $unique_id ), + $content + ); + } + +} + +Kadence_Blocks_Table_Row_Block::get_instance(); diff --git a/kadence-blocks.php b/kadence-blocks.php index e320bb6a7..eb397b9e7 100644 --- a/kadence-blocks.php +++ b/kadence-blocks.php @@ -89,6 +89,8 @@ function kadence_blocks_init(): void { require_once KADENCE_BLOCKS_PATH . 'includes/blocks/class-kadence-blocks-show-more-block.php'; require_once KADENCE_BLOCKS_PATH . 'includes/blocks/class-kadence-blocks-spacer-block.php'; require_once KADENCE_BLOCKS_PATH . 'includes/blocks/class-kadence-blocks-table-block.php'; + require_once KADENCE_BLOCKS_PATH . 'includes/blocks/class-kadence-blocks-table-data-block.php'; + require_once KADENCE_BLOCKS_PATH . 'includes/blocks/class-kadence-blocks-table-row-block.php'; require_once KADENCE_BLOCKS_PATH . 'includes/blocks/class-kadence-blocks-table-of-contents-block.php'; require_once KADENCE_BLOCKS_PATH . 'includes/blocks/class-kadence-blocks-tabs-block.php'; require_once KADENCE_BLOCKS_PATH . 'includes/blocks/class-kadence-blocks-testimonials-block.php'; diff --git a/src/blocks/table/children/data/block.json b/src/blocks/table/children/data/block.json index 4426602c8..ea03fb026 100644 --- a/src/blocks/table/children/data/block.json +++ b/src/blocks/table/children/data/block.json @@ -9,6 +9,10 @@ "attributes": { "uniqueID": { "type": "string" + }, + "isHeader": { + "type": "boolean", + "default": false } }, "supports": { diff --git a/src/blocks/table/children/data/edit.js b/src/blocks/table/children/data/edit.js index 50e14f858..d36a0a0bd 100644 --- a/src/blocks/table/children/data/edit.js +++ b/src/blocks/table/children/data/edit.js @@ -1,19 +1,29 @@ import { __ } from '@wordpress/i18n'; -import { useEffect } from '@wordpress/element'; +import React, { useEffect, useState } from '@wordpress/element'; import { useSelect, useDispatch } from '@wordpress/data'; -import { useBlockProps, InnerBlocks } from '@wordpress/block-editor'; +import { BlockControls, useBlockProps, InnerBlocks } from '@wordpress/block-editor'; import metadata from './block.json'; -import { KadenceBlockDefaults, CopyPasteAttributes } from '@kadence/components'; +import { + KadenceBlockDefaults, + CopyPasteAttributes, + KadenceInspectorControls, + KadencePanelBody, + InspectorControlTabs, + SelectParentBlock, +} from '@kadence/components'; import { setBlockDefaults, getUniqueId, getPostOrFseId } from '@kadence/helpers'; import classnames from 'classnames'; +import { ToggleControl } from '@wordpress/components'; const DEFAULT_BLOCK = [['core/paragraph', {}]]; export function Edit(props) { const { attributes, setAttributes, className, clientId } = props; - const { uniqueID } = attributes; + const { uniqueID, isHeader } = attributes; + + const [activeTab, setActiveTab] = useState('general'); const { addUniqueID } = useDispatch('kadenceblocks/data'); const { isUniqueID, isUniqueBlock, parentData } = useSelect( @@ -55,11 +65,47 @@ export function Edit(props) { } }, []); + const Tag = isHeader ? 'th' : 'td'; + return ( - - {/*renderAppender={() => }*/} + + + + + + + + setActiveTab(value)} + activeTab={activeTab} + /> + + {activeTab === 'general' && ( + + setAttributes({ isHeader: value })} + help={__('Switches to th tag and applies header typography styles.', 'kadence-blocks')} + /> + + )} + - + ); } diff --git a/src/blocks/table/children/data/index.js b/src/blocks/table/children/data/index.js index 1e6bfb5a7..8d333322d 100644 --- a/src/blocks/table/children/data/index.js +++ b/src/blocks/table/children/data/index.js @@ -1,4 +1,5 @@ import { registerBlockType } from '@wordpress/blocks'; +import { InnerBlocks } from '@wordpress/block-editor'; /** * Internal dependencies @@ -22,6 +23,8 @@ registerBlockType('kadence/table-data', { src: spacerIcon, }, edit, - save: () => null, + save: () => { + return ; + }, example: {}, }); diff --git a/src/blocks/table/children/row/edit.js b/src/blocks/table/children/row/edit.js index 6ad5a83a7..ca03e98f5 100644 --- a/src/blocks/table/children/row/edit.js +++ b/src/blocks/table/children/row/edit.js @@ -1,7 +1,7 @@ import { __ } from '@wordpress/i18n'; -import { useState, useEffect } from '@wordpress/element'; +import React, { useState, useEffect } from '@wordpress/element'; import { useSelect, useDispatch } from '@wordpress/data'; -import { useBlockProps, BlockControls, InnerBlocks } from '@wordpress/block-editor'; +import { useBlockProps, BlockControls, InnerBlocks, useInnerBlocksProps } from '@wordpress/block-editor'; import metadata from './block.json'; import { @@ -25,6 +25,7 @@ import { ResponsiveMeasureRangeControl, SpacingVisualizer, CopyPasteAttributes, + SelectParentBlock, } from '@kadence/components'; import { @@ -109,10 +110,22 @@ export function Edit(props) { } }, [columns]); - // const ALLOWED_BLOCKS = ['kadence/table-data']; + const innerBlocksProps = useInnerBlocksProps( + { + className: '', + style: {}, + }, + { + allowedBlocks: ['kadence/table-data'], + templateLock: true, + renderAppender: false, + templateInsertUpdatesSelection: true, + } + ); return ( -
+ <> + {/*
*/} + KadenceBlockDefaults} - - {/*allowedBlocks={ALLOWED_BLOCKS}*/} - - -
+ + ); } diff --git a/src/blocks/table/children/row/index.js b/src/blocks/table/children/row/index.js index c6295cc17..c899ed9d3 100644 --- a/src/blocks/table/children/row/index.js +++ b/src/blocks/table/children/row/index.js @@ -1,4 +1,5 @@ import { registerBlockType } from '@wordpress/blocks'; +import { InnerBlocks } from '@wordpress/block-editor'; /** * Internal dependencies @@ -22,6 +23,8 @@ registerBlockType('kadence/table-row', { src: spacerIcon, }, edit, - save: () => null, + save: () => { + return ; + }, example: {}, }); diff --git a/src/blocks/table/edit.js b/src/blocks/table/edit.js index a31d0aeee..d8d2e0427 100644 --- a/src/blocks/table/edit.js +++ b/src/blocks/table/edit.js @@ -1,7 +1,7 @@ import { __ } from '@wordpress/i18n'; import { useState, useEffect } from '@wordpress/element'; import { useSelect, useDispatch } from '@wordpress/data'; -import { useBlockProps, BlockControls, InnerBlocks } from '@wordpress/block-editor'; +import { useBlockProps, BlockControls, InnerBlocks, useInnerBlocksProps } from '@wordpress/block-editor'; import classnames from 'classnames'; import metadata from './block.json'; import './editor.scss'; @@ -140,6 +140,23 @@ export function Edit(props) { setAttributes({ rows: newRows, columns: newColumns }); }; + const innerBlocksProps = useInnerBlocksProps( + { + className: '', + style: {}, + }, + { + allowedBlocks: ['kadence/table-row'], + templateLock: false, + template: [ + ['kadence/table-row', { columns: 2 }], + ['kadence/table-row', { columns: 2 }], + ], + renderAppender: false, + templateInsertUpdatesSelection: true, + } + ); + return (
@@ -202,14 +219,7 @@ export function Edit(props) { )} - - -
+ ); } diff --git a/src/blocks/table/index.js b/src/blocks/table/index.js index 691828a4e..ee53dbe6b 100644 --- a/src/blocks/table/index.js +++ b/src/blocks/table/index.js @@ -1,4 +1,5 @@ import { registerBlockType } from '@wordpress/blocks'; +import { InnerBlocks } from '@wordpress/block-editor'; /** * Internal dependencies @@ -25,6 +26,8 @@ registerBlockType('kadence/table', { src: spacerIcon, }, edit, - save: () => null, + save: () => { + return ; + }, example: {}, }); From e527519b9c3718030d024b515efc26d892a13818 Mon Sep 17 00:00:00 2001 From: Josh Oakes Date: Tue, 29 Oct 2024 15:36:10 -0500 Subject: [PATCH 04/98] KAD-3684 Typography settings for cells KAD-3685 Typography settings for headers --- .../class-kadence-blocks-table-block.php | 7 +- src/blocks/table/block.json | 72 +++++++++++ .../table/components/backend-styles/index.js | 112 ++++++++++++++++++ src/blocks/table/edit.js | 105 ++++++++++++++-- 4 files changed, 288 insertions(+), 8 deletions(-) create mode 100644 src/blocks/table/components/backend-styles/index.js diff --git a/includes/blocks/class-kadence-blocks-table-block.php b/includes/blocks/class-kadence-blocks-table-block.php index 288abe04a..4fc6c4ece 100644 --- a/includes/blocks/class-kadence-blocks-table-block.php +++ b/includes/blocks/class-kadence-blocks-table-block.php @@ -61,6 +61,11 @@ public function build_css( $attributes, $css, $unique_id, $unique_style_id ) { $css->set_style_id( 'kb-' . $this->block_name . $unique_style_id ); + $css->set_selector( '.kb-table-block' . esc_attr( $unique_id ) ); + $css->render_typography( $attributes, 'dataTypography' ); + + $css->set_selector( '.kb-table-block' . esc_attr( $unique_id ) . ' th' ); + $css->render_typography( $attributes, 'headerTypography' ); return $css->css_output(); } @@ -77,7 +82,7 @@ public function build_css( $attributes, $css, $unique_id, $unique_style_id ) { */ public function build_html( $attributes, $unique_id, $content, $block_instance ) { return sprintf( - '
%2$s
', + '%2$s
', esc_attr( $unique_id ), $content ); diff --git a/src/blocks/table/block.json b/src/blocks/table/block.json index 74fa20c51..ab2c040e4 100644 --- a/src/blocks/table/block.json +++ b/src/blocks/table/block.json @@ -16,6 +16,78 @@ "columns": { "type": "number", "default": 2 + }, + "dataTypography": { + "type": "array", + "default": [ + { + "size": ["", "", ""], + "sizeType": "px", + "lineHeight": ["", "", ""], + "lineType": "", + "letterSpacing": "", + "family": "", + "google": "", + "style": "", + "weight": "", + "variant": "", + "subset": "", + "loadGoogle": true, + "padding": ["xxs", "xs", "xxs", "xs"], + "marginTop": 8, + "color": "", + "background": "", + "border": ["", "", "", ""], + "borderRadius": ["", "", "", ""], + "borderWidth": ["", "", "", ""], + "colorHover": "", + "backgroundHover": "", + "borderHover": ["", "", "", ""], + "colorActive": "", + "backgroundActive": "", + "borderActive": ["", "", "", ""], + "textTransform": "", + "paddingTablet": ["", "", "", ""], + "paddingMobile": ["", "", "", ""], + "paddingType": "px" + } + ] + }, + "headerTypography": { + "type": "array", + "default": [ + { + "size": ["", "", ""], + "sizeType": "px", + "lineHeight": ["", "", ""], + "lineType": "", + "letterSpacing": "", + "family": "", + "google": "", + "style": "", + "weight": "", + "variant": "", + "subset": "", + "loadGoogle": true, + "padding": ["xxs", "xs", "xxs", "xs"], + "marginTop": 8, + "color": "", + "background": "", + "border": ["", "", "", ""], + "borderRadius": ["", "", "", ""], + "borderWidth": ["", "", "", ""], + "colorHover": "", + "backgroundHover": "", + "borderHover": ["", "", "", ""], + "colorActive": "", + "backgroundActive": "", + "borderActive": ["", "", "", ""], + "textTransform": "", + "paddingTablet": ["", "", "", ""], + "paddingMobile": ["", "", "", ""], + "paddingType": "px" + } + ] } }, "supports": { diff --git a/src/blocks/table/components/backend-styles/index.js b/src/blocks/table/components/backend-styles/index.js new file mode 100644 index 000000000..a1a02fe94 --- /dev/null +++ b/src/blocks/table/components/backend-styles/index.js @@ -0,0 +1,112 @@ +import { + KadenceBlocksCSS, + getFontSizeOptionOutput, + getPreviewSize, + getSpacingOptionOutput, + KadenceColorOutput, + useElementHeight, +} from '@kadence/helpers'; + +export default function BackendStyles(props) { + const { attributes, previewDevice } = props; + + const { + uniqueID, + // padding, + // tabletPadding, + // mobilePadding, + // paddingUnit, + // margin, + // tabletMargin, + // mobileMargin, + // marginUnit, + dataTypography, + headerTypography, + } = attributes; + + const css = new KadenceBlocksCSS(); + + // const previewMarginTop = getPreviewSize( + // previewDevice, + // undefined !== margin ? margin[0] : '', + // undefined !== tabletMargin ? tabletMargin[0] : '', + // undefined !== mobileMargin ? mobileMargin[0] : '' + // ); + // const previewMarginRight = getPreviewSize( + // previewDevice, + // undefined !== margin ? margin[1] : '', + // undefined !== tabletMargin ? tabletMargin[1] : '', + // undefined !== mobileMargin ? mobileMargin[1] : '' + // ); + // const previewMarginBottom = getPreviewSize( + // previewDevice, + // undefined !== margin ? margin[2] : '', + // undefined !== tabletMargin ? tabletMargin[2] : '', + // undefined !== mobileMargin ? mobileMargin[2] : '' + // ); + // const previewMarginLeft = getPreviewSize( + // previewDevice, + // undefined !== margin ? margin[3] : '', + // undefined !== tabletMargin ? tabletMargin[3] : '', + // undefined !== mobileMargin ? mobileMargin[3] : '' + // ); + // + // const previewPaddingTop = getPreviewSize( + // previewDevice, + // undefined !== padding ? padding[0] : '', + // undefined !== tabletPadding ? tabletPadding[0] : '', + // undefined !== mobilePadding ? mobilePadding[0] : '' + // ); + // const previewPaddingRight = getPreviewSize( + // previewDevice, + // undefined !== padding ? padding[1] : '', + // undefined !== tabletPadding ? tabletPadding[1] : '', + // undefined !== mobilePadding ? mobilePadding[1] : '' + // ); + // const previewPaddingBottom = getPreviewSize( + // previewDevice, + // undefined !== padding ? padding[2] : '', + // undefined !== tabletPadding ? tabletPadding[2] : '', + // undefined !== mobilePadding ? mobilePadding[2] : '' + // ); + // const previewPaddingLeft = getPreviewSize( + // previewDevice, + // undefined !== padding ? padding[3] : '', + // undefined !== tabletPadding ? tabletPadding[3] : '', + // undefined !== mobilePadding ? mobilePadding[3] : '' + // ); + + // const previewWidth = getPreviewSize( + // previewDevice, + // undefined !== width?.[0] ? width[0] : '', + // undefined !== width?.[1] ? width[1] : '', + // undefined !== width?.[2] ? width[2] : '' + // ); + + css.set_selector(`.wp-block-kadence-table${uniqueID}`); + css.render_font(dataTypography ? dataTypography : [], previewDevice); + + css.set_selector(`.wp-block-kadence-table${uniqueID} th`); + css.render_font(headerTypography ? headerTypography : [], previewDevice); + + // css.add_property('color', KadenceColorOutput(dataTypography.color)); + // css.add_property('font-size', getFontSizeOptionOutput(previewFontSize, dataTypography.sizeType)); + // css.add_property('letter-spacing', getSpacingOptionOutput(previewLetterSpacing, dataTypography.letterType)); + // css.add_property('text-transform', dataTypography.textTransform); + // css.add_property('font-family', dataTypography.family); + // css.add_property('font-style', dataTypography.style); + // css.add_property('font-weight', dataTypography.weight); + // css.add_property('line-height', getSpacingOptionOutput(previewLineHeight, dataTypography.lineType)); + // css.add_property('margin-top', getSpacingOptionOutput(previewMarginTop, marginUnit)); + // css.add_property('margin-right', getSpacingOptionOutput(previewMarginRight, marginUnit)); + // css.add_property('margin-bottom', getSpacingOptionOutput(previewMarginBottom, marginUnit)); + // css.add_property('margin-left', getSpacingOptionOutput(previewMarginLeft, marginUnit)); + // css.add_property('padding-top', getSpacingOptionOutput(previewPaddingTop, paddingUnit)); + // css.add_property('padding-right', getSpacingOptionOutput(previewPaddingRight, paddingUnit)); + // css.add_property('padding-bottom', getSpacingOptionOutput(previewPaddingBottom, paddingUnit)); + // css.add_property('padding-left', getSpacingOptionOutput(previewPaddingLeft, paddingUnit)); + + const cssOutput = css.css_output(); + + return ; +} diff --git a/src/blocks/table/edit.js b/src/blocks/table/edit.js index d8d2e0427..98955342d 100644 --- a/src/blocks/table/edit.js +++ b/src/blocks/table/edit.js @@ -28,6 +28,7 @@ import { ResponsiveMeasureRangeControl, SpacingVisualizer, CopyPasteAttributes, + TypographyControls, } from '@kadence/components'; import { @@ -38,11 +39,12 @@ import { getPostOrFseId, getPreviewSize, } from '@kadence/helpers'; +import BackendStyles from './components/backend-styles'; export function Edit(props) { const { attributes, setAttributes, className, clientId } = props; - const { uniqueID, rows, columns } = attributes; + const { uniqueID, rows, columns, dataTypography, headerTypography } = attributes; const { addUniqueID } = useDispatch('kadenceblocks/data'); const { isUniqueID, isUniqueBlock, previewDevice, parentData } = useSelect( @@ -157,6 +159,18 @@ export function Edit(props) { } ); + const saveDataTypography = (value) => { + setAttributes({ + dataTypography: [{ ...dataTypography[0], ...value }, ...dataTypography.slice(1)], + }); + }; + + const saveHeaderTypography = (value) => { + setAttributes({ + headerTypography: [{ ...headerTypography[0], ...value }, ...headerTypography.slice(1)], + }); + }; + return (
@@ -169,12 +183,7 @@ export function Edit(props) { /> - + {activeTab === 'general' && ( <> @@ -208,6 +217,87 @@ export function Edit(props) { )} + {activeTab === 'style' && ( + <> + + saveDataTypography({ size: value })} + fontSizeType={dataTypography[0].sizeType} + onFontSizeType={(value) => saveDataTypography({ sizeType: value })} + lineHeight={dataTypography[0].lineHeight} + onLineHeight={(value) => saveDataTypography({ lineHeight: value })} + lineHeightType={dataTypography[0].lineType} + onLineHeightType={(value) => saveDataTypography({ lineType: value })} + letterSpacing={dataTypography[0].letterSpacing} + onLetterSpacing={(value) => saveDataTypography({ letterSpacing: value })} + textTransform={dataTypography[0].textTransform} + onTextTransform={(value) => saveDataTypography({ textTransform: value })} + fontFamily={dataTypography[0].family} + onFontFamily={(value) => saveDataTypography({ family: value })} + onFontChange={(select) => { + saveDataTypography({ + family: select.value, + google: select.google, + }); + }} + onFontArrayChange={(values) => saveDataTypography(values)} + googleFont={dataTypography[0].google} + onGoogleFont={(value) => saveDataTypography({ google: value })} + loadGoogleFont={dataTypography[0].loadGoogle} + onLoadGoogleFont={(value) => saveDataTypography({ loadGoogle: value })} + fontVariant={dataTypography[0].variant} + onFontVariant={(value) => saveDataTypography({ variant: value })} + fontWeight={dataTypography[0].weight} + onFontWeight={(value) => saveDataTypography({ weight: value })} + fontStyle={dataTypography[0].style} + onFontStyle={(value) => saveDataTypography({ style: value })} + fontSubset={dataTypography[0].subset} + onFontSubset={(value) => saveDataTypography({ subset: value })} + /> + + + saveHeaderTypography({ size: value })} + fontSizeType={headerTypography[0].sizeType} + onFontSizeType={(value) => saveHeaderTypography({ sizeType: value })} + lineHeight={headerTypography[0].lineHeight} + onLineHeight={(value) => saveHeaderTypography({ lineHeight: value })} + lineHeightType={headerTypography[0].lineType} + onLineHeightType={(value) => saveHeaderTypography({ lineType: value })} + letterSpacing={headerTypography[0].letterSpacing} + onLetterSpacing={(value) => saveHeaderTypography({ letterSpacing: value })} + textTransform={headerTypography[0].textTransform} + onTextTransform={(value) => saveHeaderTypography({ textTransform: value })} + fontFamily={headerTypography[0].family} + onFontFamily={(value) => saveHeaderTypography({ family: value })} + onFontChange={(select) => { + saveHeaderTypography({ + family: select.value, + google: select.google, + }); + }} + onFontArrayChange={(values) => saveHeaderTypography(values)} + googleFont={headerTypography[0].google} + onGoogleFont={(value) => saveHeaderTypography({ google: value })} + loadGoogleFont={headerTypography[0].loadGoogle} + onLoadGoogleFont={(value) => saveHeaderTypography({ loadGoogle: value })} + fontVariant={headerTypography[0].variant} + onFontVariant={(value) => saveHeaderTypography({ variant: value })} + fontWeight={headerTypography[0].weight} + onFontWeight={(value) => saveHeaderTypography({ weight: value })} + fontStyle={headerTypography[0].style} + onFontStyle={(value) => saveHeaderTypography({ style: value })} + fontSubset={headerTypography[0].subset} + onFontSubset={(value) => saveHeaderTypography({ subset: value })} + /> + + + )} + {activeTab === 'advanced' && ( <> )} + ); From 73a93d0dd00aea07b95233f867bb5babf886baa5 Mon Sep 17 00:00:00 2001 From: Josh Oakes Date: Tue, 29 Oct 2024 16:04:16 -0500 Subject: [PATCH 05/98] KAD-3688 Background settings for rows --- .../class-kadence-blocks-table-block.php | 26 +++++- src/blocks/table/block.json | 20 +++++ .../table/components/backend-styles/index.js | 25 ++++++ src/blocks/table/edit.js | 79 ++++++++++++++++++- src/blocks/table/editor.scss | 16 ++-- 5 files changed, 152 insertions(+), 14 deletions(-) diff --git a/includes/blocks/class-kadence-blocks-table-block.php b/includes/blocks/class-kadence-blocks-table-block.php index 4fc6c4ece..37ded6fd8 100644 --- a/includes/blocks/class-kadence-blocks-table-block.php +++ b/includes/blocks/class-kadence-blocks-table-block.php @@ -61,12 +61,32 @@ public function build_css( $attributes, $css, $unique_id, $unique_style_id ) { $css->set_style_id( 'kb-' . $this->block_name . $unique_style_id ); - $css->set_selector( '.kb-table-block' . esc_attr( $unique_id ) ); + $css->set_selector( '.wp-block-kadence-table' . esc_attr( $unique_id ) ); $css->render_typography( $attributes, 'dataTypography' ); - $css->set_selector( '.kb-table-block' . esc_attr( $unique_id ) . ' th' ); + $css->set_selector( '.wp-block-kadence-table' . esc_attr( $unique_id ) . ' th' ); $css->render_typography( $attributes, 'headerTypography' ); + if ( !empty( $attributes['evenOddBackground'] ) ) { + $css->set_selector( '.wp-block-kadence-table' . esc_attr( $unique_id ) . ' tr:nth-child(even)' ); + $css->add_property( 'background-color', $css->render_color( $attributes['backgroundColorEven'] ) ); + + $css->set_selector( '.wp-block-kadence-table' . esc_attr( $unique_id ) . ' tr:nth-child(odd)' ); + $css->add_property( 'background-color', $css->render_color( $attributes['backgroundColorOdd'] ) ); + + $css->set_selector( '.wp-block-kadence-table' . esc_attr( $unique_id ) . ' tr:nth-child(odd):hover' ); + $css->add_property( 'background-color', $css->render_color( $attributes['backgroundHoverColorOdd'] ) ); + + $css->set_selector( '.wp-block-kadence-table' . esc_attr( $unique_id ) . ' tr:nth-child(even):hover' ); + $css->add_property( 'background-color', $css->render_color( $attributes['backgroundHoverColorEven'] ) ); + } else { + $css->set_selector( '.wp-block-kadence-table' . esc_attr( $unique_id ) . ' tr' ); + $css->add_property( 'background-color', $css->render_color( $attributes['backgroundColorEven'] ) ); + + $css->set_selector( '.wp-block-kadence-table' . esc_attr( $unique_id ) . ' tr:hover' ); + $css->add_property( 'background-color', $css->render_color( $attributes['backgroundHoverColorEven'] ) ); + } + return $css->css_output(); } @@ -82,7 +102,7 @@ public function build_css( $attributes, $css, $unique_id, $unique_style_id ) { */ public function build_html( $attributes, $unique_id, $content, $block_instance ) { return sprintf( - '
%2$s
', + '%2$s
', esc_attr( $unique_id ), $content ); diff --git a/src/blocks/table/block.json b/src/blocks/table/block.json index ab2c040e4..ea3fac515 100644 --- a/src/blocks/table/block.json +++ b/src/blocks/table/block.json @@ -88,6 +88,26 @@ "paddingType": "px" } ] + }, + "evenOddBackground": { + "type": "boolean", + "default": false + }, + "backgroundColorEven": { + "type": "string", + "default": "" + }, + "backgroundColorOdd": { + "type": "string", + "default": "" + }, + "backgroundHoverColorEven": { + "type": "string", + "default": "" + }, + "backgroundHoverColorOdd": { + "type": "string", + "default": "" } }, "supports": { diff --git a/src/blocks/table/components/backend-styles/index.js b/src/blocks/table/components/backend-styles/index.js index a1a02fe94..83387ef53 100644 --- a/src/blocks/table/components/backend-styles/index.js +++ b/src/blocks/table/components/backend-styles/index.js @@ -22,6 +22,11 @@ export default function BackendStyles(props) { // marginUnit, dataTypography, headerTypography, + evenOddBackground, + backgroundColorEven, + backgroundColorOdd, + backgroundHoverColorEven, + backgroundHoverColorOdd, } = attributes; const css = new KadenceBlocksCSS(); @@ -89,6 +94,26 @@ export default function BackendStyles(props) { css.set_selector(`.wp-block-kadence-table${uniqueID} th`); css.render_font(headerTypography ? headerTypography : [], previewDevice); + if (evenOddBackground) { + css.set_selector(`.wp-block-kadence-table${uniqueID} tr:nth-child(even)`); + css.add_property('background-color', KadenceColorOutput(backgroundColorEven)); + + css.set_selector(`.wp-block-kadence-table${uniqueID} tr:nth-child(odd)`); + css.add_property('background-color', KadenceColorOutput(backgroundColorOdd)); + + css.set_selector(`.wp-block-kadence-table${uniqueID} tr:nth-child(odd):hover`); + css.add_property('background-color', KadenceColorOutput(backgroundHoverColorOdd)); + + css.set_selector(`.wp-block-kadence-table${uniqueID} tr:nth-child(even):hover`); + css.add_property('background-color', KadenceColorOutput(backgroundHoverColorEven)); + } else { + css.set_selector(`.wp-block-kadence-table${uniqueID} tr`); + css.add_property('background-color', KadenceColorOutput(backgroundColorEven)); + + css.set_selector(`.wp-block-kadence-table${uniqueID} tr:hover`); + css.add_property('background-color', KadenceColorOutput(backgroundHoverColorEven)); + } + // css.add_property('color', KadenceColorOutput(dataTypography.color)); // css.add_property('font-size', getFontSizeOptionOutput(previewFontSize, dataTypography.sizeType)); // css.add_property('letter-spacing', getSpacingOptionOutput(previewLetterSpacing, dataTypography.letterType)); diff --git a/src/blocks/table/edit.js b/src/blocks/table/edit.js index 98955342d..3a3176501 100644 --- a/src/blocks/table/edit.js +++ b/src/blocks/table/edit.js @@ -29,6 +29,8 @@ import { SpacingVisualizer, CopyPasteAttributes, TypographyControls, + HoverToggleControl, + PopColorControl, } from '@kadence/components'; import { @@ -44,7 +46,18 @@ import BackendStyles from './components/backend-styles'; export function Edit(props) { const { attributes, setAttributes, className, clientId } = props; - const { uniqueID, rows, columns, dataTypography, headerTypography } = attributes; + const { + uniqueID, + rows, + columns, + dataTypography, + headerTypography, + evenOddBackground, + backgroundColorEven, + backgroundColorOdd, + backgroundHoverColorEven, + backgroundHoverColorOdd, + } = attributes; const { addUniqueID } = useDispatch('kadenceblocks/data'); const { isUniqueID, isUniqueBlock, previewDevice, parentData } = useSelect( @@ -219,7 +232,11 @@ export function Edit(props) { {activeTab === 'style' && ( <> - + saveDataTypography({ subset: value })} /> - + saveHeaderTypography({ subset: value })} /> + + setAttributes({ evenOddBackground: value })} + /> + + + setAttributes({ backgroundHoverColorEven: value })} + /> + + {evenOddBackground && ( + setAttributes({ backgroundHoverColorOdd: value })} + /> + )} + + } + normal={ + <> + setAttributes({ backgroundColorEven: value })} + /> + + {evenOddBackground && ( + setAttributes({ backgroundColorOdd: value })} + /> + )} + + } + /> + )} diff --git a/src/blocks/table/editor.scss b/src/blocks/table/editor.scss index 749c7bfd7..ebd8c749b 100644 --- a/src/blocks/table/editor.scss +++ b/src/blocks/table/editor.scss @@ -7,12 +7,12 @@ @import "style"; .wp-block-kadence-table { - table, th, td { - border: 1px solid; - border-collapse: collapse; - } - - .wp-block { - margin: 0 !important; - } + //table, th, td { + // border: 1px solid; + // border-collapse: collapse; + //} + // + //.wp-block { + // margin: 0 !important; + //} } From d30766b583f9320de4b006066397e010e8a86bcc Mon Sep 17 00:00:00 2001 From: Josh Oakes Date: Wed, 30 Oct 2024 13:52:48 -0500 Subject: [PATCH 06/98] KAD-3687 Background settings for columns w/ tests --- .../class-kadence-blocks-abstract-block.php | 3 +- .../class-kadence-blocks-table-block.php | 54 +++-- .../class-kadence-blocks-table-row-block.php | 7 +- src/blocks/table/block.json | 8 + src/blocks/table/children/data/edit.js | 12 +- .../children/row/backend-styles/index.js | 25 ++ src/blocks/table/children/row/block.json | 8 + src/blocks/table/children/row/edit.js | 66 ++++-- .../table/components/backend-styles/index.js | 36 ++- src/blocks/table/edit.js | 63 ++++- src/blocks/table/editor.scss | 2 +- tests/wpunit/Blocks/TableTest.php | 222 ++++++++++++++++++ 12 files changed, 455 insertions(+), 51 deletions(-) create mode 100644 src/blocks/table/children/row/backend-styles/index.js create mode 100644 tests/wpunit/Blocks/TableTest.php diff --git a/includes/blocks/class-kadence-blocks-abstract-block.php b/includes/blocks/class-kadence-blocks-abstract-block.php index a1943fb5f..3e7b2222a 100644 --- a/includes/blocks/class-kadence-blocks-abstract-block.php +++ b/includes/blocks/class-kadence-blocks-abstract-block.php @@ -78,7 +78,8 @@ class Kadence_Blocks_Abstract_Block { 'off-canvas', 'header-column', 'search', - 'identity' + 'identity', + 'table', ]; /** * Allow us to enable merged defaults on blocks individually. diff --git a/includes/blocks/class-kadence-blocks-table-block.php b/includes/blocks/class-kadence-blocks-table-block.php index 37ded6fd8..b4e00ad5c 100644 --- a/includes/blocks/class-kadence-blocks-table-block.php +++ b/includes/blocks/class-kadence-blocks-table-block.php @@ -61,30 +61,54 @@ public function build_css( $attributes, $css, $unique_id, $unique_style_id ) { $css->set_style_id( 'kb-' . $this->block_name . $unique_style_id ); - $css->set_selector( '.wp-block-kadence-table' . esc_attr( $unique_id ) ); + $css->set_selector( '.kb-table' . esc_attr( $unique_id ) ); $css->render_typography( $attributes, 'dataTypography' ); - $css->set_selector( '.wp-block-kadence-table' . esc_attr( $unique_id ) . ' th' ); + $css->set_selector( '.kb-table' . esc_attr( $unique_id ) . ' th' ); $css->render_typography( $attributes, 'headerTypography' ); if ( !empty( $attributes['evenOddBackground'] ) ) { - $css->set_selector( '.wp-block-kadence-table' . esc_attr( $unique_id ) . ' tr:nth-child(even)' ); - $css->add_property( 'background-color', $css->render_color( $attributes['backgroundColorEven'] ) ); + $css->set_selector( '.kb-table' . esc_attr( $unique_id ) . ' tr:nth-child(even)' ); + $css->add_property( 'background-color', $css->render_color( $attributes['backgroundColorEven'] ?? 'undefined' ) ); - $css->set_selector( '.wp-block-kadence-table' . esc_attr( $unique_id ) . ' tr:nth-child(odd)' ); - $css->add_property( 'background-color', $css->render_color( $attributes['backgroundColorOdd'] ) ); + $css->set_selector( '.kb-table' . esc_attr( $unique_id ) . ' tr:nth-child(odd)' ); + $css->add_property( 'background-color', $css->render_color( $attributes['backgroundColorOdd'] ?? 'undefined' ) ); - $css->set_selector( '.wp-block-kadence-table' . esc_attr( $unique_id ) . ' tr:nth-child(odd):hover' ); - $css->add_property( 'background-color', $css->render_color( $attributes['backgroundHoverColorOdd'] ) ); + $css->set_selector( '.kb-table' . esc_attr( $unique_id ) . ' tr:nth-child(odd):hover' ); + $css->add_property( 'background-color', $css->render_color( $attributes['backgroundHoverColorOdd'] ?? 'undefined' ) ); - $css->set_selector( '.wp-block-kadence-table' . esc_attr( $unique_id ) . ' tr:nth-child(even):hover' ); - $css->add_property( 'background-color', $css->render_color( $attributes['backgroundHoverColorEven'] ) ); + $css->set_selector( '.kb-table' . esc_attr( $unique_id ) . ' tr:nth-child(even):hover' ); + $css->add_property( 'background-color', $css->render_color( $attributes['backgroundHoverColorEven'] ?? 'undefined' ) ); } else { - $css->set_selector( '.wp-block-kadence-table' . esc_attr( $unique_id ) . ' tr' ); - $css->add_property( 'background-color', $css->render_color( $attributes['backgroundColorEven'] ) ); - $css->set_selector( '.wp-block-kadence-table' . esc_attr( $unique_id ) . ' tr:hover' ); - $css->add_property( 'background-color', $css->render_color( $attributes['backgroundHoverColorEven'] ) ); + if( !empty( $attributes['backgroundColorEven'] ) ) { + $css->set_selector( '.kb-table' . esc_attr( $unique_id ) . ' tr' ); + $css->add_property( 'background-color', $css->render_color( $attributes['backgroundColorEven'] ) ); + } + + if( !empty( $attributes['backgroundHoverColorEven'] ) ) { + $css->set_selector( '.kb-table' . esc_attr( $unique_id ) . ' tr:hover' ); + $css->add_property( 'background-color', $css->render_color( $attributes['backgroundHoverColorEven'] ) ); + } + } + + if( !empty( $attributes['columnBackgrounds'] ) ) { + foreach( $attributes['columnBackgrounds'] as $index => $background ) { + if ( $background ) { + $css->set_selector( '.kb-table' . esc_attr( $unique_id ) . ' td:nth-child(' . ( $index + 1 ) . ')' ); + $css->add_property( 'background-color', $css->render_color( $background ) ); + } + } + + } + + if( !empty( $attributes['columnBackgroundsHover'] ) ) { + foreach( $attributes['columnBackgroundsHover'] as $index => $background ) { + if ( $background ) { + $css->set_selector( '.kb-table' . esc_attr( $unique_id ) . ' td:nth-child(' . ( $index + 1 ) . '):hover' ); + $css->add_property( 'background-color', $css->render_color( $background ) ); + } + } } return $css->css_output(); @@ -102,7 +126,7 @@ public function build_css( $attributes, $css, $unique_id, $unique_style_id ) { */ public function build_html( $attributes, $unique_id, $content, $block_instance ) { return sprintf( - '%2$s
', + '%2$s
', esc_attr( $unique_id ), $content ); diff --git a/includes/blocks/class-kadence-blocks-table-row-block.php b/includes/blocks/class-kadence-blocks-table-row-block.php index 97206baa9..8e007334f 100644 --- a/includes/blocks/class-kadence-blocks-table-row-block.php +++ b/includes/blocks/class-kadence-blocks-table-row-block.php @@ -74,6 +74,11 @@ public function build_css( $attributes, $css, $unique_id, $unique_style_id ) { $css->set_style_id( 'kb-' . $this->block_name . $unique_style_id ); + $css->set_selector( '.wp-block-kadence-table .kb-table-row' . $unique_id ); + $css->add_property( 'background-color', $css->render_color( $attributes['backgroundColor'] ) ); + + $css->set_selector( '.wp-block-kadence-table .kb-table-row' . $unique_id . ':hover' ); + $css->add_property( 'background-color', $css->render_color( $attributes['backgroundHoverColor'] ) ); return $css->css_output(); } @@ -90,7 +95,7 @@ public function build_css( $attributes, $css, $unique_id, $unique_style_id ) { */ public function build_html( $attributes, $unique_id, $content, $block_instance ) { return sprintf( - '%2$s', + '%2$s', esc_attr( $unique_id ), $content ); diff --git a/src/blocks/table/block.json b/src/blocks/table/block.json index ea3fac515..b8c6f58c5 100644 --- a/src/blocks/table/block.json +++ b/src/blocks/table/block.json @@ -108,6 +108,14 @@ "backgroundHoverColorOdd": { "type": "string", "default": "" + }, + "columnBackgrounds": { + "type": "array", + "default": [] + }, + "columnBackgroundsHover": { + "type": "array", + "default": [] } }, "supports": { diff --git a/src/blocks/table/children/data/edit.js b/src/blocks/table/children/data/edit.js index d36a0a0bd..83da04ef0 100644 --- a/src/blocks/table/children/data/edit.js +++ b/src/blocks/table/children/data/edit.js @@ -70,11 +70,6 @@ export function Edit(props) { return ( -
)} + {activeTab === 'advanced' && ( + + )} diff --git a/src/blocks/table/children/row/backend-styles/index.js b/src/blocks/table/children/row/backend-styles/index.js new file mode 100644 index 000000000..c27d43d75 --- /dev/null +++ b/src/blocks/table/children/row/backend-styles/index.js @@ -0,0 +1,25 @@ +import { + KadenceBlocksCSS, + getFontSizeOptionOutput, + getPreviewSize, + getSpacingOptionOutput, + KadenceColorOutput, + useElementHeight, +} from '@kadence/helpers'; + +export default function BackendStyles(props) { + const { attributes, previewDevice } = props; + + const { uniqueID, backgroundColor } = attributes; + + const css = new KadenceBlocksCSS(); + + css.set_selector(`.wp-block-kadence-table .kb-table-row${uniqueID}`); + if (backgroundColor !== '') { + css.add_property('background-color', KadenceColorOutput(backgroundColor)); + } + + const cssOutput = css.css_output(); + + return ; +} diff --git a/src/blocks/table/children/row/block.json b/src/blocks/table/children/row/block.json index b76ade452..264b1c97b 100644 --- a/src/blocks/table/children/row/block.json +++ b/src/blocks/table/children/row/block.json @@ -13,6 +13,14 @@ "columns": { "type": "number", "default": 2 + }, + "backgroundColor": { + "type": "string", + "default": "" + }, + "backgroundHoverColor": { + "type": "string", + "default": "" } }, "supports": { diff --git a/src/blocks/table/children/row/edit.js b/src/blocks/table/children/row/edit.js index ca03e98f5..b9f5e0292 100644 --- a/src/blocks/table/children/row/edit.js +++ b/src/blocks/table/children/row/edit.js @@ -25,6 +25,7 @@ import { ResponsiveMeasureRangeControl, SpacingVisualizer, CopyPasteAttributes, + PopColorControl, SelectParentBlock, } from '@kadence/components'; @@ -38,11 +39,12 @@ import { } from '@kadence/helpers'; import classnames from 'classnames'; +import BackendStyles from './backend-styles'; export function Edit(props) { const { attributes, setAttributes, className, clientId } = props; - const { uniqueID, columns } = attributes; + const { uniqueID, columns, backgroundColor, backgroundHoverColor } = attributes; const { addUniqueID } = useDispatch('kadenceblocks/data'); const { isUniqueID, isUniqueBlock, previewDevice, parentData } = useSelect( @@ -72,10 +74,16 @@ export function Edit(props) { const nonTransAttrs = []; - const classes = classnames(className, 'kb-table-row'); - const blockProps = useBlockProps({ - className: classes, - }); + // const classes = classnames( + // { + // 'kb-table-row': true, + // [`kb-table-row${uniqueID}`]: uniqueID, + // }, + // className + // ); + // const blockProps = useBlockProps({ + // className: classes, + // }); useEffect(() => { setBlockDefaults('kadence/table-row', attributes); @@ -110,9 +118,15 @@ export function Edit(props) { } }, [columns]); - const innerBlocksProps = useInnerBlocksProps( + const { children, ...innerBlocksProps } = useInnerBlocksProps( { - className: '', + className: classnames( + { + 'kb-table-row': true, + [`kb-table-row${uniqueID}`]: uniqueID, + }, + className + ), style: {}, }, { @@ -124,7 +138,7 @@ export function Edit(props) { ); return ( - <> + {/*
*/} - + {activeTab === 'general' && ( <> @@ -161,10 +170,35 @@ export function Edit(props) { )} + {activeTab === 'style' && ( + <> + + setAttributes({ backgroundColor: value })} + /> + + setAttributes({ backgroundHoverColor: value })} + /> + + + )} + {activeTab === 'advanced' && <>KadenceBlockDefaults} - - + {children} + + ); } diff --git a/src/blocks/table/components/backend-styles/index.js b/src/blocks/table/components/backend-styles/index.js index 83387ef53..dcb0a32c0 100644 --- a/src/blocks/table/components/backend-styles/index.js +++ b/src/blocks/table/components/backend-styles/index.js @@ -27,6 +27,8 @@ export default function BackendStyles(props) { backgroundColorOdd, backgroundHoverColorEven, backgroundHoverColorOdd, + columnBackgrounds, + columnBackgroundsHover, } = attributes; const css = new KadenceBlocksCSS(); @@ -88,32 +90,50 @@ export default function BackendStyles(props) { // undefined !== width?.[2] ? width[2] : '' // ); - css.set_selector(`.wp-block-kadence-table${uniqueID}`); + css.set_selector(`.kb-table${uniqueID}`); css.render_font(dataTypography ? dataTypography : [], previewDevice); - css.set_selector(`.wp-block-kadence-table${uniqueID} th`); + css.set_selector(`.kb-table${uniqueID} th`); css.render_font(headerTypography ? headerTypography : [], previewDevice); if (evenOddBackground) { - css.set_selector(`.wp-block-kadence-table${uniqueID} tr:nth-child(even)`); + css.set_selector(`.kb-table${uniqueID} tr:nth-child(even)`); css.add_property('background-color', KadenceColorOutput(backgroundColorEven)); - css.set_selector(`.wp-block-kadence-table${uniqueID} tr:nth-child(odd)`); + css.set_selector(`.kb-table${uniqueID} tr:nth-child(odd)`); css.add_property('background-color', KadenceColorOutput(backgroundColorOdd)); - css.set_selector(`.wp-block-kadence-table${uniqueID} tr:nth-child(odd):hover`); + css.set_selector(`.kb-table${uniqueID} tr:nth-child(odd):hover`); css.add_property('background-color', KadenceColorOutput(backgroundHoverColorOdd)); - css.set_selector(`.wp-block-kadence-table${uniqueID} tr:nth-child(even):hover`); + css.set_selector(`.kb-table${uniqueID} tr:nth-child(even):hover`); css.add_property('background-color', KadenceColorOutput(backgroundHoverColorEven)); } else { - css.set_selector(`.wp-block-kadence-table${uniqueID} tr`); + css.set_selector(`.kb-table${uniqueID} tr`); css.add_property('background-color', KadenceColorOutput(backgroundColorEven)); - css.set_selector(`.wp-block-kadence-table${uniqueID} tr:hover`); + css.set_selector(`.kb-table${uniqueID} tr:hover`); css.add_property('background-color', KadenceColorOutput(backgroundHoverColorEven)); } + if (columnBackgrounds) { + columnBackgrounds.forEach((background, index) => { + if (background) { + css.set_selector(`.kb-table${uniqueID} td:nth-child(${index + 1})`); + css.add_property('background-color', KadenceColorOutput(background)); + } + }); + } + + if (columnBackgroundsHover) { + columnBackgroundsHover.forEach((background, index) => { + if (background) { + css.set_selector(`.kb-table${uniqueID} td:nth-child(${index + 1}):hover`); + css.add_property('background-color', KadenceColorOutput(background)); + } + }); + } + // css.add_property('color', KadenceColorOutput(dataTypography.color)); // css.add_property('font-size', getFontSizeOptionOutput(previewFontSize, dataTypography.sizeType)); // css.add_property('letter-spacing', getSpacingOptionOutput(previewLetterSpacing, dataTypography.letterType)); diff --git a/src/blocks/table/edit.js b/src/blocks/table/edit.js index 3a3176501..cf8b486d1 100644 --- a/src/blocks/table/edit.js +++ b/src/blocks/table/edit.js @@ -57,6 +57,8 @@ export function Edit(props) { backgroundColorOdd, backgroundHoverColorEven, backgroundHoverColorOdd, + columnBackgrounds, + columnBackgroundsHover, } = attributes; const { addUniqueID } = useDispatch('kadenceblocks/data'); @@ -89,8 +91,8 @@ export function Edit(props) { const classes = classnames( { - 'wp-block-kadence-table': true, - [`wp-block-kadence-table${uniqueID}`]: uniqueID, + 'kb-table': true, + [`kb-table${uniqueID}`]: uniqueID, }, className ); @@ -116,8 +118,25 @@ export function Edit(props) { } }, []); + const updateColumnBackground = (index, color, isHover = false) => { + const arrayToUpdate = isHover ? [...columnBackgroundsHover] : [...columnBackgrounds]; + if (color === '') { + delete arrayToUpdate[index]; + arrayToUpdate.length = arrayToUpdate.length || index + 1; + } else { + arrayToUpdate[index] = color; + } + setAttributes({ + [isHover ? 'columnBackgroundsHover' : 'columnBackgrounds']: arrayToUpdate, + }); + }; + + const getColumnBackground = (index, isHover = false) => { + const array = isHover ? columnBackgroundsHover : columnBackgrounds; + return array && array[index] ? array[index] : ''; + }; + const updateRowsColumns = (newRows, newColumns) => { - console.log(newRows, newColumns); const currentBlocks = wp.data.select('core/block-editor').getBlocks(clientId); let newRowBlocks = [...currentBlocks]; @@ -162,7 +181,7 @@ export function Edit(props) { }, { allowedBlocks: ['kadence/table-row'], - templateLock: false, + templateLock: true, template: [ ['kadence/table-row', { columns: 2 }], ['kadence/table-row', { columns: 2 }], @@ -368,6 +387,42 @@ export function Edit(props) { } /> + + + {Array.from({ length: columns }).map((_, index) => ( + + updateColumnBackground(index, value, true)} + /> + } + normal={ + updateColumnBackground(index, value)} + /> + } + /> + + ))} + )} diff --git a/src/blocks/table/editor.scss b/src/blocks/table/editor.scss index ebd8c749b..b99f3d54c 100644 --- a/src/blocks/table/editor.scss +++ b/src/blocks/table/editor.scss @@ -6,7 +6,7 @@ */ @import "style"; -.wp-block-kadence-table { +.kb-table { //table, th, td { // border: 1px solid; // border-collapse: collapse; diff --git a/tests/wpunit/Blocks/TableTest.php b/tests/wpunit/Blocks/TableTest.php new file mode 100644 index 000000000..6f96485fc --- /dev/null +++ b/tests/wpunit/Blocks/TableTest.php @@ -0,0 +1,222 @@ +block = new Kadence_Blocks_Table_Block(); + $this->css = new \Kadence_Blocks_CSS(); + } + + public function testStandardBackgroundCss() { + $unique_id = '123'; + $attributes = [ + 'backgroundColorEven' => 'red', + 'backgroundHoverColorEven' => 'blue', + 'uniqueID' => $unique_id, + ]; + + $css_output = $this->block->build_css($attributes, $this->css, $unique_id, $unique_id); + $css_helper = new CSSTestHelper($css_output); + + $this->assertTrue( + $css_helper->assertCSSPropertiesEqual( + '.kb-table'.$unique_id.' tr', + [ + 'background-color' => 'red' + ] + ) + ); + + $this->assertTrue( + $css_helper->assertCSSPropertiesEqual( + '.kb-table'.$unique_id.' tr:hover', + [ + 'background-color' => 'blue' + ] + ) + ); + } + + public function testEvenOddBackgroundCss() { + $unique_id = '123'; + $attributes = [ + 'evenOddBackground' => true, + 'backgroundColorEven' => '#111', + 'backgroundHoverColorEven' => '#222', + 'backgroundColorOdd' => '#333', + 'backgroundHoverColorOdd' => '#444', + 'uniqueID' => $unique_id, + ]; + + $css_output = $this->block->build_css($attributes, $this->css, $unique_id, $unique_id); + $css_helper = new CSSTestHelper($css_output); + + $this->assertTrue( + $css_helper->assertCSSPropertiesEqual( + '.kb-table'.$unique_id.' tr:nth-child(even)', + [ + 'background-color' => '#111' + ] + ) + ); + + $this->assertTrue( + $css_helper->assertCSSPropertiesEqual( + '.kb-table'.$unique_id.' tr:nth-child(even):hover', + [ + 'background-color' => '#222' + ] + ) + ); + + $this->assertTrue( + $css_helper->assertCSSPropertiesEqual( + '.kb-table'.$unique_id.' tr:nth-child(odd)', + [ + 'background-color' => '#333' + ] + ) + ); + + $this->assertTrue( + $css_helper->assertCSSPropertiesEqual( + '.kb-table'.$unique_id.' tr:nth-child(odd):hover', + [ + 'background-color' => '#444' + ] + ) + ); + } + + public function testNoColumnBackgroundCss() { + $unique_id = '123'; + $attributes = [ + 'columnBackgrounds' => [], // No column backgrounds + 'uniqueID' => $unique_id, + ]; + + $css_output = $this->block->build_css($attributes, $this->css, $unique_id, $unique_id); + $css_helper = new CSSTestHelper($css_output); + + $this->assertEmpty($css_output); + + } + + public function testNoColumnHoverBackgroundCss() { + $unique_id = '123'; + $attributes = [ + 'columnBackgroundsHover' => [], // No column backgrounds + 'uniqueID' => $unique_id, + ]; + + $css_output = $this->block->build_css($attributes, $this->css, $unique_id, $unique_id); + $css_helper = new CSSTestHelper($css_output); + + $this->assertEmpty($css_output); + + } + + public function testColumndBackgroundCss() { + $unique_id = '123'; + $attributes = [ + 'columnBackgrounds' => [ null, '#fff', '#444', null, 'red'], // No column backgrounds + 'uniqueID' => $unique_id, + ]; + + $css_output = $this->block->build_css($attributes, $this->css, $unique_id, $unique_id); + $css_helper = new CSSTestHelper($css_output); + + + $this->assertStringNotContainsString( 'td:nth-child(1)', $css_output ); + $this->assertStringNotContainsString( 'td:nth-child(4)', $css_output ); + + $this->assertTrue( + $css_helper->assertCSSPropertiesEqual( + '.kb-table'.$unique_id.' td:nth-child(2)', + [ + 'background-color' => '#fff' + ] + ) + ); + + $this->assertTrue( + $css_helper->assertCSSPropertiesEqual( + '.kb-table'.$unique_id.' td:nth-child(3)', + [ + 'background-color' => '#444' + ] + ) + ); + + $this->assertTrue( + $css_helper->assertCSSPropertiesEqual( + '.kb-table'.$unique_id.' td:nth-child(5)', + [ + 'background-color' => 'red' + ] + ) + ); + } + + public function testColumndHoverBackgroundCss() { + $unique_id = '123'; + $attributes = [ + 'columnBackgroundsHover' => [ null, '#111', '#333', null, 'blue'], + 'uniqueID' => $unique_id, + ]; + + $css_output = $this->block->build_css($attributes, $this->css, $unique_id, $unique_id); + $css_helper = new CSSTestHelper($css_output); + + + $this->assertStringNotContainsString( 'td:nth-child(1):hover', $css_output ); + $this->assertStringNotContainsString( 'td:nth-child(4):hover', $css_output ); + + $this->assertTrue( + $css_helper->assertCSSPropertiesEqual( + '.kb-table'.$unique_id.' td:nth-child(2):hover', + [ + 'background-color' => '#111' + ] + ) + ); + + $this->assertTrue( + $css_helper->assertCSSPropertiesEqual( + '.kb-table'.$unique_id.' td:nth-child(3):hover', + [ + 'background-color' => '#333' + ] + ) + ); + + $this->assertTrue( + $css_helper->assertCSSPropertiesEqual( + '.kb-table'.$unique_id.' td:nth-child(5):hover', + [ + 'background-color' => 'blue' + ] + ) + ); + } +} From d201f02b371da35539e677614d9e41eb1ac3deea Mon Sep 17 00:00:00 2001 From: Josh Oakes Date: Wed, 30 Oct 2024 16:09:36 -0500 Subject: [PATCH 07/98] KAD-3683 WIP Border Styles --- .../class-kadence-blocks-table-block.php | 16 ++++ .../class-kadence-blocks-table-data-block.php | 3 + .../class-kadence-blocks-table-row-block.php | 7 +- src/blocks/table/block.json | 40 ++++++++++ src/blocks/table/children/data/edit.js | 2 +- .../children/row/backend-styles/index.js | 10 ++- src/blocks/table/children/row/block.json | 16 ++++ src/blocks/table/children/row/edit.js | 77 +++++++++++++++---- .../table/components/backend-styles/index.js | 28 ++++++- src/blocks/table/edit.js | 39 +++++++++- src/blocks/table/style.scss | 10 +++ tests/wpunit/Blocks/TableTest.php | 4 - 12 files changed, 224 insertions(+), 28 deletions(-) diff --git a/includes/blocks/class-kadence-blocks-table-block.php b/includes/blocks/class-kadence-blocks-table-block.php index b4e00ad5c..a35591406 100644 --- a/includes/blocks/class-kadence-blocks-table-block.php +++ b/includes/blocks/class-kadence-blocks-table-block.php @@ -38,6 +38,14 @@ class Kadence_Blocks_Table_Block extends Kadence_Blocks_Abstract_Block { */ protected $has_script = true; + /** + * Block determines in scripts need to be loaded for block. + * + * @var string + */ + protected $has_style = true; + + /** * Instance Control */ @@ -111,6 +119,14 @@ public function build_css( $attributes, $css, $unique_id, $unique_style_id ) { } } + // Render borders for the table + if( !empty( $attributes['borderOnRowOnly'])) { + $css->set_selector( '.kb-table' . esc_attr( $unique_id ) . ' tr' ); + } else { + $css->set_selector( '.kb-table' . esc_attr( $unique_id ) . ' td, .kb-table' . esc_attr( $unique_id ) . ' th' ); + } + $css->render_border_styles( $attributes, 'borderStyle' ); + return $css->css_output(); } diff --git a/includes/blocks/class-kadence-blocks-table-data-block.php b/includes/blocks/class-kadence-blocks-table-data-block.php index 95eaaee13..7a6d00da6 100644 --- a/includes/blocks/class-kadence-blocks-table-data-block.php +++ b/includes/blocks/class-kadence-blocks-table-data-block.php @@ -38,6 +38,9 @@ class Kadence_Blocks_Table_Data_Block extends Kadence_Blocks_Abstract_Block { */ protected $has_script = false; + protected $has_style = false; + + /** * Instance Control */ diff --git a/includes/blocks/class-kadence-blocks-table-row-block.php b/includes/blocks/class-kadence-blocks-table-row-block.php index 8e007334f..5dc66ee7a 100644 --- a/includes/blocks/class-kadence-blocks-table-row-block.php +++ b/includes/blocks/class-kadence-blocks-table-row-block.php @@ -38,6 +38,9 @@ class Kadence_Blocks_Table_Row_Block extends Kadence_Blocks_Abstract_Block { */ protected $has_script = false; + protected $has_style = false; + + /** * Instance Control */ @@ -74,10 +77,10 @@ public function build_css( $attributes, $css, $unique_id, $unique_style_id ) { $css->set_style_id( 'kb-' . $this->block_name . $unique_style_id ); - $css->set_selector( '.wp-block-kadence-table .kb-table-row' . $unique_id ); + $css->set_selector( '.kb-table .kb-table-row' . $unique_id ); $css->add_property( 'background-color', $css->render_color( $attributes['backgroundColor'] ) ); - $css->set_selector( '.wp-block-kadence-table .kb-table-row' . $unique_id . ':hover' ); + $css->set_selector( '.kb-table .kb-table-row' . $unique_id . ':hover' ); $css->add_property( 'background-color', $css->render_color( $attributes['backgroundHoverColor'] ) ); return $css->css_output(); diff --git a/src/blocks/table/block.json b/src/blocks/table/block.json index b8c6f58c5..49e044c9c 100644 --- a/src/blocks/table/block.json +++ b/src/blocks/table/block.json @@ -116,6 +116,46 @@ "columnBackgroundsHover": { "type": "array", "default": [] + }, + "borderStyle": { + "type": "array", + "default": [ + { + "top": ["", "", ""], + "right": ["", "", ""], + "bottom": ["", "", ""], + "left": ["", "", ""], + "unit": "px" + } + ] + }, + "tabletBorderStyle": { + "type": "array", + "default": [ + { + "top": ["", "", ""], + "right": ["", "", ""], + "bottom": ["", "", ""], + "left": ["", "", ""], + "unit": "px" + } + ] + }, + "mobileBorderStyle": { + "type": "array", + "default": [ + { + "top": ["", "", ""], + "right": ["", "", ""], + "bottom": ["", "", ""], + "left": ["", "", ""], + "unit": "px" + } + ] + }, + "borderOnRowOnly" : { + "type": "boolean", + "default": false } }, "supports": { diff --git a/src/blocks/table/children/data/edit.js b/src/blocks/table/children/data/edit.js index 83da04ef0..c42691d62 100644 --- a/src/blocks/table/children/data/edit.js +++ b/src/blocks/table/children/data/edit.js @@ -106,7 +106,7 @@ export function Edit(props) { /> )} - + ); } diff --git a/src/blocks/table/children/row/backend-styles/index.js b/src/blocks/table/children/row/backend-styles/index.js index c27d43d75..cc6ad810c 100644 --- a/src/blocks/table/children/row/backend-styles/index.js +++ b/src/blocks/table/children/row/backend-styles/index.js @@ -10,15 +10,21 @@ import { export default function BackendStyles(props) { const { attributes, previewDevice } = props; - const { uniqueID, backgroundColor } = attributes; + const { uniqueID, backgroundColor, minHeight, tabletMinHeight, mobileMinHeight, minHeightUnit } = attributes; + + const previewMinHeight = getPreviewSize(previewDevice, minHeight, tabletMinHeight, mobileMinHeight); const css = new KadenceBlocksCSS(); - css.set_selector(`.wp-block-kadence-table .kb-table-row${uniqueID}`); + css.set_selector(`.kb-table .kb-table-row${uniqueID}`); if (backgroundColor !== '') { css.add_property('background-color', KadenceColorOutput(backgroundColor)); } + if (previewMinHeight) { + css.add_property('height', previewMinHeight + minHeightUnit); + } + const cssOutput = css.css_output(); return ; diff --git a/src/blocks/table/children/row/block.json b/src/blocks/table/children/row/block.json index 264b1c97b..6bb3be772 100644 --- a/src/blocks/table/children/row/block.json +++ b/src/blocks/table/children/row/block.json @@ -21,6 +21,22 @@ "backgroundHoverColor": { "type": "string", "default": "" + }, + "minHeight": { + "type": "number", + "default": "" + }, + "minHeightTablet": { + "type": "number", + "default": "" + }, + "minHeightMobile": { + "type": "number", + "default": "" + }, + "minHeightUnit": { + "type": "string", + "default": "px" } }, "supports": { diff --git a/src/blocks/table/children/row/edit.js b/src/blocks/table/children/row/edit.js index b9f5e0292..48c39a3ba 100644 --- a/src/blocks/table/children/row/edit.js +++ b/src/blocks/table/children/row/edit.js @@ -27,6 +27,7 @@ import { CopyPasteAttributes, PopColorControl, SelectParentBlock, + ResponsiveRangeControls, } from '@kadence/components'; import { @@ -44,7 +45,16 @@ import BackendStyles from './backend-styles'; export function Edit(props) { const { attributes, setAttributes, className, clientId } = props; - const { uniqueID, columns, backgroundColor, backgroundHoverColor } = attributes; + const { + uniqueID, + columns, + backgroundColor, + backgroundHoverColor, + minHeight, + tabletMinHeight, + mobileMinHeight, + minHeightUnit, + } = attributes; const { addUniqueID } = useDispatch('kadenceblocks/data'); const { isUniqueID, isUniqueBlock, previewDevice, parentData } = useSelect( @@ -68,7 +78,7 @@ export function Edit(props) { [clientId] ); - const [activeTab, setActiveTab] = useState('general'); + const [activeTab, setActiveTab] = useState('style'); const { getBlocks } = useSelect((select) => select('core/block-editor')); const { replaceInnerBlocks } = useDispatch('core/block-editor'); @@ -155,20 +165,25 @@ export function Edit(props) { clientId={clientId} parentSlug={'kadence/table'} /> - + - {activeTab === 'general' && ( - <> - - Settings - - - )} + {/*{activeTab === 'general' && (*/} + {/* <>*/} + {/* */} + {/* Settings*/} + {/* */} + {/* */} + {/*)}*/} {activeTab === 'style' && ( <> @@ -191,6 +206,38 @@ export function Edit(props) { onChange={(value) => setAttributes({ backgroundHoverColor: value })} /> + + + setAttributes({ minHeight: value })} + tabletValue={tabletMinHeight} + onChangeTablet={(value) => setAttributes({ tabletMinHeight: value })} + mobileValue={mobileMinHeight} + onChangeMobile={(value) => setAttributes({ mobileMinHeight: value })} + min={0} + max={minHeightUnit === 'px' ? 600 : 100} + step={1} + unit={minHeightUnit} + onUnit={(value) => { + setAttributes({ minHeightUnit: value }); + }} + units={['px', 'em', 'vh']} + reset={() => + setAttributes({ + minHeight: null, + tabletMinHeight: null, + mobileMinHeight: null, + }) + } + showUnit={true} + /> + )} diff --git a/src/blocks/table/components/backend-styles/index.js b/src/blocks/table/components/backend-styles/index.js index dcb0a32c0..517bde2f0 100644 --- a/src/blocks/table/components/backend-styles/index.js +++ b/src/blocks/table/components/backend-styles/index.js @@ -4,7 +4,7 @@ import { getPreviewSize, getSpacingOptionOutput, KadenceColorOutput, - useElementHeight, + getBorderStyle, } from '@kadence/helpers'; export default function BackendStyles(props) { @@ -29,6 +29,10 @@ export default function BackendStyles(props) { backgroundHoverColorOdd, columnBackgrounds, columnBackgroundsHover, + borderStyle, + tabletBorderStyle, + mobileBorderStyle, + borderOnRowOnly, } = attributes; const css = new KadenceBlocksCSS(); @@ -134,6 +138,28 @@ export default function BackendStyles(props) { }); } + if (borderOnRowOnly) { + css.set_selector(`.kb-table${uniqueID} tr`); + } else { + css.set_selector(`.kb-table${uniqueID} th, .kb-table${uniqueID} td`); + } + css.add_property( + 'border-top', + getBorderStyle(previewDevice, 'top', borderStyle, tabletBorderStyle, mobileBorderStyle) + ); + css.add_property( + 'border-right', + getBorderStyle(previewDevice, 'right', borderStyle, tabletBorderStyle, mobileBorderStyle) + ); + css.add_property( + 'border-bottom', + getBorderStyle(previewDevice, 'bottom', borderStyle, tabletBorderStyle, mobileBorderStyle) + ); + css.add_property( + 'border-left', + getBorderStyle(previewDevice, 'left', borderStyle, tabletBorderStyle, mobileBorderStyle) + ); + // css.add_property('color', KadenceColorOutput(dataTypography.color)); // css.add_property('font-size', getFontSizeOptionOutput(previewFontSize, dataTypography.sizeType)); // css.add_property('letter-spacing', getSpacingOptionOutput(previewLetterSpacing, dataTypography.letterType)); diff --git a/src/blocks/table/edit.js b/src/blocks/table/edit.js index cf8b486d1..7720dcc7c 100644 --- a/src/blocks/table/edit.js +++ b/src/blocks/table/edit.js @@ -31,6 +31,8 @@ import { TypographyControls, HoverToggleControl, PopColorControl, + ResponsiveMeasurementControls, + ResponsiveBorderControl, } from '@kadence/components'; import { @@ -59,6 +61,10 @@ export function Edit(props) { backgroundHoverColorOdd, columnBackgrounds, columnBackgroundsHover, + borderStyle, + tabletBorderStyle, + mobileBorderStyle, + borderOnRowOnly, } = attributes; const { addUniqueID } = useDispatch('kadenceblocks/data'); @@ -91,8 +97,8 @@ export function Edit(props) { const classes = classnames( { - 'kb-table': true, - [`kb-table${uniqueID}`]: uniqueID, + 'kb-table-container': true, + [`kb-table-container${uniqueID}`]: uniqueID, }, className ); @@ -176,7 +182,13 @@ export function Edit(props) { const innerBlocksProps = useInnerBlocksProps( { - className: '', + className: classnames( + { + 'kb-table': true, + [`kb-table${uniqueID}`]: uniqueID, + }, + className + ), style: {}, }, { @@ -251,6 +263,27 @@ export function Edit(props) { {activeTab === 'style' && ( <> + + setAttributes({ borderStyle: value })} + onChangeTablet={(value) => setAttributes({ tabletBorderStyle: value })} + onChangeMobile={(value) => setAttributes({ mobileBorderStyle: value })} + /> + + setAttributes({ borderOnRowOnly: value })} + /> + block->build_css($attributes, $this->css, $unique_id, $unique_id); - $css_helper = new CSSTestHelper($css_output); $this->assertEmpty($css_output); - } public function testNoColumnHoverBackgroundCss() { @@ -130,10 +128,8 @@ public function testNoColumnHoverBackgroundCss() { ]; $css_output = $this->block->build_css($attributes, $this->css, $unique_id, $unique_id); - $css_helper = new CSSTestHelper($css_output); $this->assertEmpty($css_output); - } public function testColumndBackgroundCss() { From 0583c8bd960de7dfa4c2b9b763d60df75b2489ff Mon Sep 17 00:00:00 2001 From: Josh Oakes Date: Thu, 31 Oct 2024 11:04:14 -0500 Subject: [PATCH 08/98] Update edit.js --- src/blocks/table/children/row/edit.js | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/src/blocks/table/children/row/edit.js b/src/blocks/table/children/row/edit.js index 48c39a3ba..c581b6d3c 100644 --- a/src/blocks/table/children/row/edit.js +++ b/src/blocks/table/children/row/edit.js @@ -167,29 +167,16 @@ export function Edit(props) { /> - {/*{activeTab === 'general' && (*/} - {/* <>*/} - {/* */} - {/* Settings*/} - {/* */} - {/* */} - {/*)}*/} - - {activeTab === 'style' && ( + {activeTab === 'general' && ( <> Date: Fri, 1 Nov 2024 09:01:32 -0500 Subject: [PATCH 09/98] Block json updates --- src/blocks/table/children/data/block.json | 2 +- src/blocks/table/children/row/block.json | 1 + src/blocks/table/children/row/edit.js | 3 ++- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/blocks/table/children/data/block.json b/src/blocks/table/children/data/block.json index ea03fb026..54cd9abae 100644 --- a/src/blocks/table/children/data/block.json +++ b/src/blocks/table/children/data/block.json @@ -5,7 +5,7 @@ "title": "Table Data", "category": "kadence-blocks", "textdomain": "kadence-blocks", - "parent": [ "kadence/row" ], + "parent": [ "kadence/table-row" ], "attributes": { "uniqueID": { "type": "string" diff --git a/src/blocks/table/children/row/block.json b/src/blocks/table/children/row/block.json index 6bb3be772..6d67b0fd1 100644 --- a/src/blocks/table/children/row/block.json +++ b/src/blocks/table/children/row/block.json @@ -4,6 +4,7 @@ "name": "kadence/table-row", "title": "Table (Adv)", "parent": [ "kadence/table" ], + "allowedBlocks": [ "kadence/table-data" ], "category": "kadence-blocks", "textdomain": "kadence-blocks", "attributes": { diff --git a/src/blocks/table/children/row/edit.js b/src/blocks/table/children/row/edit.js index c581b6d3c..dcf523d75 100644 --- a/src/blocks/table/children/row/edit.js +++ b/src/blocks/table/children/row/edit.js @@ -141,7 +141,8 @@ export function Edit(props) { }, { allowedBlocks: ['kadence/table-data'], - templateLock: true, + orientation: 'vertical', + templateLock: 'all', renderAppender: false, templateInsertUpdatesSelection: true, } From bdd53905a3b1e028e3609349f4b8825a3cf530c7 Mon Sep 17 00:00:00 2001 From: Josh Oakes Date: Fri, 1 Nov 2024 09:22:40 -0500 Subject: [PATCH 10/98] Use context for columns --- src/blocks/table/block.json | 3 +++ src/blocks/table/children/row/block.json | 5 +---- src/blocks/table/children/row/edit.js | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/blocks/table/block.json b/src/blocks/table/block.json index 49e044c9c..cf8330ea5 100644 --- a/src/blocks/table/block.json +++ b/src/blocks/table/block.json @@ -158,6 +158,9 @@ "default": false } }, + "providesContext": { + "kadence/table-columns": "columns" + }, "supports": { "kbMetadata": true } diff --git a/src/blocks/table/children/row/block.json b/src/blocks/table/children/row/block.json index 6d67b0fd1..fdaf13404 100644 --- a/src/blocks/table/children/row/block.json +++ b/src/blocks/table/children/row/block.json @@ -11,10 +11,6 @@ "uniqueID": { "type": "string" }, - "columns": { - "type": "number", - "default": 2 - }, "backgroundColor": { "type": "string", "default": "" @@ -40,6 +36,7 @@ "default": "px" } }, + "usesContext": [ "kadence/table-columns" ], "supports": { "kbMetadata": true } diff --git a/src/blocks/table/children/row/edit.js b/src/blocks/table/children/row/edit.js index dcf523d75..b51a5a5d1 100644 --- a/src/blocks/table/children/row/edit.js +++ b/src/blocks/table/children/row/edit.js @@ -43,11 +43,10 @@ import classnames from 'classnames'; import BackendStyles from './backend-styles'; export function Edit(props) { - const { attributes, setAttributes, className, clientId } = props; + const { attributes, setAttributes, className, clientId, context } = props; const { uniqueID, - columns, backgroundColor, backgroundHoverColor, minHeight, @@ -56,6 +55,7 @@ export function Edit(props) { minHeightUnit, } = attributes; + const columns = context['kadence/table-columns']; const { addUniqueID } = useDispatch('kadenceblocks/data'); const { isUniqueID, isUniqueBlock, previewDevice, parentData } = useSelect( (select) => { From 63dc032e88520efe0e32cd855c1eaa96cba81f57 Mon Sep 17 00:00:00 2001 From: Josh Oakes Date: Mon, 4 Nov 2024 12:08:21 -0600 Subject: [PATCH 11/98] Update kb-search.min.js --- includes/assets/js/kb-search.min.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/assets/js/kb-search.min.js b/includes/assets/js/kb-search.min.js index 123422f1a..5e551d9aa 100644 --- a/includes/assets/js/kb-search.min.js +++ b/includes/assets/js/kb-search.min.js @@ -1 +1 @@ -(function(){"use strict";window.kadenceSearchBlock={cache:{},initSearch(){if(window.kadenceSearchBlock.cache=document.querySelectorAll(".kb-search-modal-container"),!window.kadenceSearchBlock.cache.length)return void console.log("No search block found");console.log(window.kadenceSearchBlock.cache);for(let a=0;a .wp-block-kadence-singlebtn:nth-of-type(1)"),d=b.querySelector(".kb-search-modal"),f=b.querySelector(".kb-search-modal .kb-search-close-btn"),g=b.querySelector(".kb-search-input");if(c){const a=function(a){return a.preventDefault(),console.log("hideModalButton"),d.classList.remove("active"),c.removeAttribute("aria-hidden"),f.setAttribute("aria-hidden","true"),f.setAttribute("aria-expanded","false"),!1};c.addEventListener("click",function(a){return a.preventDefault(),console.log("showModalButton"),d.classList.add("active"),c.setAttribute("aria-hidden","true"),f.removeAttribute("aria-hidden"),f.setAttribute("aria-expanded","true"),!1}),f.addEventListener("click",a),f.setAttribute("aria-hidden","true"),d.addEventListener("click",function(b){b.target===g||g.contains(b.target)||a(b)}),document.addEventListener("keydown",function(b){"Escape"===b.key&&d.classList.contains("active")&&a(b)})}}},init(){window.kadenceSearchBlock.initSearch()}},"loading"===document.readyState?document.addEventListener("DOMContentLoaded",window.kadenceSearchBlock.init):window.kadenceSearchBlock.init(),document.addEventListener("kadenceJSInitReload",function(){window.kadenceSearchBlock.init()}),document.addEventListener("kb-query-loaded",function(){window.kadenceSearchBlock.init()})})(); \ No newline at end of file +(function(){"use strict";window.kadenceSearchBlock={cache:{},initSearch(){if(window.kadenceSearchBlock.cache=document.querySelectorAll(".kb-search-modal-container"),!window.kadenceSearchBlock.cache.length)return void console.log("No search block found");for(let a=0;a .wp-block-kadence-singlebtn:nth-of-type(1)"),d=b.querySelector(".kb-search-modal"),f=b.querySelector(".kb-search-modal .kb-search-close-btn"),g=b.querySelector(".kb-search-input");if(c){const a=function(a){return a.preventDefault(),console.log("hideModalButton"),d.classList.remove("active"),c.removeAttribute("aria-hidden"),f.setAttribute("aria-hidden","true"),f.setAttribute("aria-expanded","false"),!1};c.addEventListener("click",function(a){return a.preventDefault(),console.log("showModalButton"),d.classList.add("active"),c.setAttribute("aria-hidden","true"),f.removeAttribute("aria-hidden"),f.setAttribute("aria-expanded","true"),!1}),f.addEventListener("click",a),f.setAttribute("aria-hidden","true"),d.addEventListener("click",function(b){b.target===g||g.contains(b.target)||a(b)}),document.addEventListener("keydown",function(b){"Escape"===b.key&&d.classList.contains("active")&&a(b)})}}},init(){window.kadenceSearchBlock.initSearch()}},"loading"===document.readyState?document.addEventListener("DOMContentLoaded",window.kadenceSearchBlock.init):window.kadenceSearchBlock.init(),document.addEventListener("kadenceJSInitReload",function(){window.kadenceSearchBlock.init()}),document.addEventListener("kb-query-loaded",function(){window.kadenceSearchBlock.init()})})(); \ No newline at end of file From 053e140707e8557785f73e5f3b21ff0a149ba670 Mon Sep 17 00:00:00 2001 From: Josh Oakes Date: Mon, 4 Nov 2024 12:53:39 -0600 Subject: [PATCH 12/98] Update class-kadence-blocks-table-block.php --- .../class-kadence-blocks-table-block.php | 42 +++++++++++++------ 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/includes/blocks/class-kadence-blocks-table-block.php b/includes/blocks/class-kadence-blocks-table-block.php index a35591406..c81b3069c 100644 --- a/includes/blocks/class-kadence-blocks-table-block.php +++ b/includes/blocks/class-kadence-blocks-table-block.php @@ -69,33 +69,33 @@ public function build_css( $attributes, $css, $unique_id, $unique_style_id ) { $css->set_style_id( 'kb-' . $this->block_name . $unique_style_id ); - $css->set_selector( '.kb-table' . esc_attr( $unique_id ) ); + $css->set_selector( '.kb-table-wrap .kb-table' . esc_attr( $unique_id ) ); $css->render_typography( $attributes, 'dataTypography' ); - $css->set_selector( '.kb-table' . esc_attr( $unique_id ) . ' th' ); + $css->set_selector( '.kb-table-wrap .kb-table' . esc_attr( $unique_id ) . ' th' ); $css->render_typography( $attributes, 'headerTypography' ); if ( !empty( $attributes['evenOddBackground'] ) ) { - $css->set_selector( '.kb-table' . esc_attr( $unique_id ) . ' tr:nth-child(even)' ); + $css->set_selector( '.kb-table-wrap .kb-table' . esc_attr( $unique_id ) . ' tr:nth-child(even)' ); $css->add_property( 'background-color', $css->render_color( $attributes['backgroundColorEven'] ?? 'undefined' ) ); - $css->set_selector( '.kb-table' . esc_attr( $unique_id ) . ' tr:nth-child(odd)' ); + $css->set_selector( '.kb-table-wrap .kb-table' . esc_attr( $unique_id ) . ' tr:nth-child(odd)' ); $css->add_property( 'background-color', $css->render_color( $attributes['backgroundColorOdd'] ?? 'undefined' ) ); - $css->set_selector( '.kb-table' . esc_attr( $unique_id ) . ' tr:nth-child(odd):hover' ); + $css->set_selector( '.kb-table-wrap .kb-table' . esc_attr( $unique_id ) . ' tr:nth-child(odd):hover' ); $css->add_property( 'background-color', $css->render_color( $attributes['backgroundHoverColorOdd'] ?? 'undefined' ) ); - $css->set_selector( '.kb-table' . esc_attr( $unique_id ) . ' tr:nth-child(even):hover' ); + $css->set_selector( '.kb-table-wrap .kb-table' . esc_attr( $unique_id ) . ' tr:nth-child(even):hover' ); $css->add_property( 'background-color', $css->render_color( $attributes['backgroundHoverColorEven'] ?? 'undefined' ) ); } else { if( !empty( $attributes['backgroundColorEven'] ) ) { - $css->set_selector( '.kb-table' . esc_attr( $unique_id ) . ' tr' ); + $css->set_selector( '.kb-table-wrap .kb-table' . esc_attr( $unique_id ) . ' tr' ); $css->add_property( 'background-color', $css->render_color( $attributes['backgroundColorEven'] ) ); } if( !empty( $attributes['backgroundHoverColorEven'] ) ) { - $css->set_selector( '.kb-table' . esc_attr( $unique_id ) . ' tr:hover' ); + $css->set_selector( '.kb-table-wrap .kb-table' . esc_attr( $unique_id ) . ' tr:hover' ); $css->add_property( 'background-color', $css->render_color( $attributes['backgroundHoverColorEven'] ) ); } } @@ -103,7 +103,7 @@ public function build_css( $attributes, $css, $unique_id, $unique_style_id ) { if( !empty( $attributes['columnBackgrounds'] ) ) { foreach( $attributes['columnBackgrounds'] as $index => $background ) { if ( $background ) { - $css->set_selector( '.kb-table' . esc_attr( $unique_id ) . ' td:nth-child(' . ( $index + 1 ) . ')' ); + $css->set_selector( '.kb-table-wrap .kb-table' . esc_attr( $unique_id ) . ' td:nth-child(' . ( $index + 1 ) . ')' ); $css->add_property( 'background-color', $css->render_color( $background ) ); } } @@ -113,7 +113,7 @@ public function build_css( $attributes, $css, $unique_id, $unique_style_id ) { if( !empty( $attributes['columnBackgroundsHover'] ) ) { foreach( $attributes['columnBackgroundsHover'] as $index => $background ) { if ( $background ) { - $css->set_selector( '.kb-table' . esc_attr( $unique_id ) . ' td:nth-child(' . ( $index + 1 ) . '):hover' ); + $css->set_selector( '.kb-table-wrap .kb-table' . esc_attr( $unique_id ) . ' td:nth-child(' . ( $index + 1 ) . '):hover' ); $css->add_property( 'background-color', $css->render_color( $background ) ); } } @@ -121,9 +121,9 @@ public function build_css( $attributes, $css, $unique_id, $unique_style_id ) { // Render borders for the table if( !empty( $attributes['borderOnRowOnly'])) { - $css->set_selector( '.kb-table' . esc_attr( $unique_id ) . ' tr' ); + $css->set_selector( '.kb-table-wrap .kb-table' . esc_attr( $unique_id ) . ' tr' ); } else { - $css->set_selector( '.kb-table' . esc_attr( $unique_id ) . ' td, .kb-table' . esc_attr( $unique_id ) . ' th' ); + $css->set_selector( '.kb-table-wrap .kb-table' . esc_attr( $unique_id ) . ' td, .kb-table' . esc_attr( $unique_id ) . ' th' ); } $css->render_border_styles( $attributes, 'borderStyle' ); @@ -141,8 +141,24 @@ public function build_css( $attributes, $css, $unique_id, $unique_style_id ) { * @return mixed */ public function build_html( $attributes, $unique_id, $content, $block_instance ) { + + + $wrapper_classes = [ + 'kb-table-wrap', + 'kb-table-wrap' . esc_attr( $unique_id ), + ]; + + if(! empty( $attributes['className'] )) { + $wrapper_classes[] = esc_attr( $attributes['className'] ); + } + + $wrapper_attributes = get_block_wrapper_attributes( [ + 'class' => implode( ' ', $wrapper_classes ), + ] ); + return sprintf( - '%2$s
', + '
%3$s
', + $wrapper_attributes, esc_attr( $unique_id ), $content ); From 0dfb9570a97297058b9185c28bf8126a935ed4d4 Mon Sep 17 00:00:00 2001 From: Josh Oakes Date: Wed, 6 Nov 2024 09:28:03 -0600 Subject: [PATCH 13/98] Block icons --- src/blocks/table/children/data/index.js | 4 ++-- src/blocks/table/children/row/index.js | 4 ++-- src/blocks/table/index.js | 4 ++-- .../icons/src/block-icons/table/table-data/index.js | 8 ++++++++ .../icons/src/block-icons/table/table-row/index.js | 8 ++++++++ src/packages/icons/src/block-icons/table/table/index.js | 8 ++++++++ src/packages/icons/src/index.js | 5 +++++ 7 files changed, 35 insertions(+), 6 deletions(-) create mode 100644 src/packages/icons/src/block-icons/table/table-data/index.js create mode 100644 src/packages/icons/src/block-icons/table/table-row/index.js create mode 100644 src/packages/icons/src/block-icons/table/table/index.js diff --git a/src/blocks/table/children/data/index.js b/src/blocks/table/children/data/index.js index 8d333322d..921f0d0e7 100644 --- a/src/blocks/table/children/data/index.js +++ b/src/blocks/table/children/data/index.js @@ -6,7 +6,7 @@ import { InnerBlocks } from '@wordpress/block-editor'; */ import edit from './edit'; import metadata from './block.json'; -import { spacerIcon } from '@kadence/icons'; +import { tableDataBlockIcon } from '@kadence/icons'; import { __, _x } from '@wordpress/i18n'; /** @@ -20,7 +20,7 @@ registerBlockType('kadence/table-data', { description: _x('Display tables on your site', 'block description', 'kadence-blocks'), keywords: [__('table', 'kadence-blocks'), __('structure', 'kadence-blocks'), 'KB'], icon: { - src: spacerIcon, + src: tableDataBlockIcon, }, edit, save: () => { diff --git a/src/blocks/table/children/row/index.js b/src/blocks/table/children/row/index.js index c899ed9d3..19a1e2e38 100644 --- a/src/blocks/table/children/row/index.js +++ b/src/blocks/table/children/row/index.js @@ -6,7 +6,7 @@ import { InnerBlocks } from '@wordpress/block-editor'; */ import edit from './edit'; import metadata from './block.json'; -import { spacerIcon } from '@kadence/icons'; +import { tableRowBlockIcon } from '@kadence/icons'; import { __, _x } from '@wordpress/i18n'; /** @@ -20,7 +20,7 @@ registerBlockType('kadence/table-row', { description: _x('Display tables on your site', 'block description', 'kadence-blocks'), keywords: [__('table', 'kadence-blocks'), __('structure', 'kadence-blocks'), 'KB'], icon: { - src: spacerIcon, + src: tableRowBlockIcon, }, edit, save: () => { diff --git a/src/blocks/table/index.js b/src/blocks/table/index.js index ee53dbe6b..bf183a1a3 100644 --- a/src/blocks/table/index.js +++ b/src/blocks/table/index.js @@ -6,7 +6,7 @@ import { InnerBlocks } from '@wordpress/block-editor'; */ import edit from './edit'; import metadata from './block.json'; -import { spacerIcon } from '@kadence/icons'; +import { tableBlockIcon } from '@kadence/icons'; import { __, _x } from '@wordpress/i18n'; import './children/row/index'; @@ -23,7 +23,7 @@ registerBlockType('kadence/table', { description: _x('Display tables on your site', 'block description', 'kadence-blocks'), keywords: [__('table', 'kadence-blocks'), __('structure', 'kadence-blocks'), 'KB'], icon: { - src: spacerIcon, + src: tableBlockIcon, }, edit, save: () => { diff --git a/src/packages/icons/src/block-icons/table/table-data/index.js b/src/packages/icons/src/block-icons/table/table-data/index.js new file mode 100644 index 000000000..6339b177f --- /dev/null +++ b/src/packages/icons/src/block-icons/table/table-data/index.js @@ -0,0 +1,8 @@ +export default + +; diff --git a/src/packages/icons/src/block-icons/table/table-row/index.js b/src/packages/icons/src/block-icons/table/table-row/index.js new file mode 100644 index 000000000..7fa8fb72a --- /dev/null +++ b/src/packages/icons/src/block-icons/table/table-row/index.js @@ -0,0 +1,8 @@ +export default + +; diff --git a/src/packages/icons/src/block-icons/table/table/index.js b/src/packages/icons/src/block-icons/table/table/index.js new file mode 100644 index 000000000..0be200e0b --- /dev/null +++ b/src/packages/icons/src/block-icons/table/table/index.js @@ -0,0 +1,8 @@ +export default + +; diff --git a/src/packages/icons/src/index.js b/src/packages/icons/src/index.js index a91d8062a..628f5cb3f 100644 --- a/src/packages/icons/src/index.js +++ b/src/packages/icons/src/index.js @@ -229,6 +229,11 @@ export { default as lineBar } from './block-icons/progress-bar/line-bar-layout'; export { default as semiCircleBar } from './block-icons/progress-bar/semi-circle-bar-layout'; export { default as lineMask } from './block-icons/progress-bar/line-mask-layout'; +// Table Block +export { default as tableBlockIcon } from './block-icons/table/table' +export { default as tableRowBlockIcon } from './block-icons/table/table-row' +export { default as tableDataBlockIcon } from './block-icons/table/table-data' + // Arrows export { default as ArrowUp } from './arrow-up'; export { default as ArrowDown } from './arrow-down'; From ad1be37285b8974971df59803483042b17e3215c Mon Sep 17 00:00:00 2001 From: Josh Oakes Date: Wed, 6 Nov 2024 13:29:06 -0600 Subject: [PATCH 14/98] Update class-kadence-blocks-table-block.php --- .../class-kadence-blocks-table-block.php | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/includes/blocks/class-kadence-blocks-table-block.php b/includes/blocks/class-kadence-blocks-table-block.php index c81b3069c..0cccc266e 100644 --- a/includes/blocks/class-kadence-blocks-table-block.php +++ b/includes/blocks/class-kadence-blocks-table-block.php @@ -69,33 +69,33 @@ public function build_css( $attributes, $css, $unique_id, $unique_style_id ) { $css->set_style_id( 'kb-' . $this->block_name . $unique_style_id ); - $css->set_selector( '.kb-table-wrap .kb-table' . esc_attr( $unique_id ) ); + $css->set_selector( '.kb-table-container .kb-table' . esc_attr( $unique_id ) ); $css->render_typography( $attributes, 'dataTypography' ); - $css->set_selector( '.kb-table-wrap .kb-table' . esc_attr( $unique_id ) . ' th' ); + $css->set_selector( '.kb-table-container .kb-table' . esc_attr( $unique_id ) . ' th' ); $css->render_typography( $attributes, 'headerTypography' ); if ( !empty( $attributes['evenOddBackground'] ) ) { - $css->set_selector( '.kb-table-wrap .kb-table' . esc_attr( $unique_id ) . ' tr:nth-child(even)' ); + $css->set_selector( '.kb-table-container .kb-table' . esc_attr( $unique_id ) . ' tr:nth-child(even)' ); $css->add_property( 'background-color', $css->render_color( $attributes['backgroundColorEven'] ?? 'undefined' ) ); - $css->set_selector( '.kb-table-wrap .kb-table' . esc_attr( $unique_id ) . ' tr:nth-child(odd)' ); + $css->set_selector( '.kb-table-container .kb-table' . esc_attr( $unique_id ) . ' tr:nth-child(odd)' ); $css->add_property( 'background-color', $css->render_color( $attributes['backgroundColorOdd'] ?? 'undefined' ) ); - $css->set_selector( '.kb-table-wrap .kb-table' . esc_attr( $unique_id ) . ' tr:nth-child(odd):hover' ); + $css->set_selector( '.kb-table-container .kb-table' . esc_attr( $unique_id ) . ' tr:nth-child(odd):hover' ); $css->add_property( 'background-color', $css->render_color( $attributes['backgroundHoverColorOdd'] ?? 'undefined' ) ); - $css->set_selector( '.kb-table-wrap .kb-table' . esc_attr( $unique_id ) . ' tr:nth-child(even):hover' ); + $css->set_selector( '.kb-table-container .kb-table' . esc_attr( $unique_id ) . ' tr:nth-child(even):hover' ); $css->add_property( 'background-color', $css->render_color( $attributes['backgroundHoverColorEven'] ?? 'undefined' ) ); } else { if( !empty( $attributes['backgroundColorEven'] ) ) { - $css->set_selector( '.kb-table-wrap .kb-table' . esc_attr( $unique_id ) . ' tr' ); + $css->set_selector( '.kb-table-container .kb-table' . esc_attr( $unique_id ) . ' tr' ); $css->add_property( 'background-color', $css->render_color( $attributes['backgroundColorEven'] ) ); } if( !empty( $attributes['backgroundHoverColorEven'] ) ) { - $css->set_selector( '.kb-table-wrap .kb-table' . esc_attr( $unique_id ) . ' tr:hover' ); + $css->set_selector( '.kb-table-container .kb-table' . esc_attr( $unique_id ) . ' tr:hover' ); $css->add_property( 'background-color', $css->render_color( $attributes['backgroundHoverColorEven'] ) ); } } @@ -103,7 +103,7 @@ public function build_css( $attributes, $css, $unique_id, $unique_style_id ) { if( !empty( $attributes['columnBackgrounds'] ) ) { foreach( $attributes['columnBackgrounds'] as $index => $background ) { if ( $background ) { - $css->set_selector( '.kb-table-wrap .kb-table' . esc_attr( $unique_id ) . ' td:nth-child(' . ( $index + 1 ) . ')' ); + $css->set_selector( '.kb-table-container .kb-table' . esc_attr( $unique_id ) . ' td:nth-child(' . ( $index + 1 ) . ')' ); $css->add_property( 'background-color', $css->render_color( $background ) ); } } @@ -113,7 +113,7 @@ public function build_css( $attributes, $css, $unique_id, $unique_style_id ) { if( !empty( $attributes['columnBackgroundsHover'] ) ) { foreach( $attributes['columnBackgroundsHover'] as $index => $background ) { if ( $background ) { - $css->set_selector( '.kb-table-wrap .kb-table' . esc_attr( $unique_id ) . ' td:nth-child(' . ( $index + 1 ) . '):hover' ); + $css->set_selector( '.kb-table-container .kb-table' . esc_attr( $unique_id ) . ' td:nth-child(' . ( $index + 1 ) . '):hover' ); $css->add_property( 'background-color', $css->render_color( $background ) ); } } @@ -121,9 +121,9 @@ public function build_css( $attributes, $css, $unique_id, $unique_style_id ) { // Render borders for the table if( !empty( $attributes['borderOnRowOnly'])) { - $css->set_selector( '.kb-table-wrap .kb-table' . esc_attr( $unique_id ) . ' tr' ); + $css->set_selector( '.kb-table-container .kb-table' . esc_attr( $unique_id ) . ' tr' ); } else { - $css->set_selector( '.kb-table-wrap .kb-table' . esc_attr( $unique_id ) . ' td, .kb-table' . esc_attr( $unique_id ) . ' th' ); + $css->set_selector( '.kb-table-container .kb-table' . esc_attr( $unique_id ) . ' td, .kb-table' . esc_attr( $unique_id ) . ' th' ); } $css->render_border_styles( $attributes, 'borderStyle' ); @@ -144,8 +144,8 @@ public function build_html( $attributes, $unique_id, $content, $block_instance ) $wrapper_classes = [ - 'kb-table-wrap', - 'kb-table-wrap' . esc_attr( $unique_id ), + 'kb-table-container', + 'kb-table-container' . esc_attr( $unique_id ), ]; if(! empty( $attributes['className'] )) { From 7ebcd257d492736b235f673308b10a3fe4d6fefc Mon Sep 17 00:00:00 2001 From: Josh Oakes Date: Wed, 6 Nov 2024 13:29:21 -0600 Subject: [PATCH 15/98] Sticky WIP --- src/blocks/table/block.json | 24 ++++ .../table/components/backend-styles/index.js | 33 +++-- src/blocks/table/edit.js | 119 +++++++++++++++++- 3 files changed, 162 insertions(+), 14 deletions(-) diff --git a/src/blocks/table/block.json b/src/blocks/table/block.json index cf8330ea5..9650f8030 100644 --- a/src/blocks/table/block.json +++ b/src/blocks/table/block.json @@ -156,6 +156,30 @@ "borderOnRowOnly" : { "type": "boolean", "default": false + }, + "stickyFirstRow": { + "type": "boolean", + "default": false + }, + "stickyFirstColumn": { + "type": "boolean", + "default": false + }, + "maxHeight": { + "type": "array", + "default": ["", "", ""] + }, + "maxHeightUnit": { + "type": "string", + "default": "%" + }, + "maxWidth": { + "type": "array", + "default": ["", "", ""] + }, + "maxWidthUnit": { + "type": "string", + "default": "%" } }, "providesContext": { diff --git a/src/blocks/table/components/backend-styles/index.js b/src/blocks/table/components/backend-styles/index.js index 517bde2f0..9941b4516 100644 --- a/src/blocks/table/components/backend-styles/index.js +++ b/src/blocks/table/components/backend-styles/index.js @@ -12,14 +12,8 @@ export default function BackendStyles(props) { const { uniqueID, - // padding, - // tabletPadding, - // mobilePadding, - // paddingUnit, - // margin, - // tabletMargin, - // mobileMargin, - // marginUnit, + rows, + columns, dataTypography, headerTypography, evenOddBackground, @@ -33,8 +27,13 @@ export default function BackendStyles(props) { tabletBorderStyle, mobileBorderStyle, borderOnRowOnly, + stickyFirstRow, + stickyFirstColumn, + maxWidth, + maxWidthUnit, + maxHeight, + maxHeightUnit, } = attributes; - const css = new KadenceBlocksCSS(); // const previewMarginTop = getPreviewSize( @@ -177,6 +176,22 @@ export default function BackendStyles(props) { // css.add_property('padding-bottom', getSpacingOptionOutput(previewPaddingBottom, paddingUnit)); // css.add_property('padding-left', getSpacingOptionOutput(previewPaddingLeft, paddingUnit)); + if (stickyFirstRow) { + css.set_selector(`.kb-table${uniqueID}:first-child`); + css.add_property('position', 'sticky'); + css.add_property('top', '0'); + css.add_property('z-index', '1'); + } + + if (stickyFirstColumn) { + css.set_selector(`.kb-table${uniqueID} td:first-child, .kb-table${uniqueID} th:first-child`); + css.add_property('position', 'sticky'); + css.add_property('left', '0'); + } + + css.set_selector(`.kb-table-container${uniqueID}`); + css.add_property('position', 'sticky'); + const cssOutput = css.css_output(); return ; diff --git a/src/blocks/table/edit.js b/src/blocks/table/edit.js index 7720dcc7c..52518cd45 100644 --- a/src/blocks/table/edit.js +++ b/src/blocks/table/edit.js @@ -33,6 +33,7 @@ import { PopColorControl, ResponsiveMeasurementControls, ResponsiveBorderControl, + ResponsiveRangeControls, } from '@kadence/components'; import { @@ -65,6 +66,12 @@ export function Edit(props) { tabletBorderStyle, mobileBorderStyle, borderOnRowOnly, + stickyFirstRow, + stickyFirstColumn, + maxWidth, + maxWidthUnit, + maxHeight, + maxHeightUnit, } = attributes; const { addUniqueID } = useDispatch('kadenceblocks/data'); @@ -253,11 +260,113 @@ export function Edit(props) { />
+ title={__('Sticky Settings', 'kadence-blocks')} + panelName={'sticky-settings'} + initialOpen={false} + > + setAttributes({ stickyFirstRow: value })} + help={__('Max height must be set for this to apply.', 'kadence-blocks')} + /> + + setAttributes({ stickyFirstColumn: value })} + help={__('Max width must be set for this to apply.', 'kadence-blocks')} + /> + + + { + setAttributes({ + maxWidth: [ + value, + undefined !== maxWidth && undefined !== maxWidth[1] ? maxWidth[1] : '', + undefined !== maxWidth && undefined !== maxWidth[2] ? maxWidth[2] : '', + ], + }); + }} + tabletValue={undefined !== maxWidth && undefined !== maxWidth[1] ? maxWidth[1] : ''} + onChangeTablet={(value) => { + setAttributes({ + maxWidth: [ + undefined !== maxWidth && undefined !== maxWidth[0] ? maxWidth[0] : '', + value, + undefined !== maxWidth && undefined !== maxWidth[2] ? maxWidth[2] : '', + ], + }); + }} + mobileValue={undefined !== maxWidth && undefined !== maxWidth[2] ? maxWidth[2] : ''} + onChangeMobile={(value) => { + setAttributes({ + maxWidth: [ + undefined !== maxWidth && undefined !== maxWidth[0] ? maxWidth[0] : '', + undefined !== maxWidth && undefined !== maxWidth[1] ? maxWidth[1] : '', + value, + ], + }); + }} + min={0} + max={maxWidthUnit === 'px' ? 2000 : 100} + step={1} + unit={maxWidthUnit ? maxWidthUnit : '%'} + onUnit={(value) => { + setAttributes({ maxWidthUnit: value }); + }} + units={['px', '%', 'vw']} + /> + + { + setAttributes({ + maxHeight: [ + value, + undefined !== maxHeight && undefined !== maxHeight[1] ? maxHeight[1] : '', + undefined !== maxHeight && undefined !== maxHeight[2] ? maxHeight[2] : '', + ], + }); + }} + tabletValue={undefined !== maxHeight && undefined !== maxHeight[1] ? maxHeight[1] : ''} + onChangeTablet={(value) => { + setAttributes({ + maxHeight: [ + undefined !== maxHeight && undefined !== maxHeight[0] ? maxHeight[0] : '', + value, + undefined !== maxHeight && undefined !== maxHeight[2] ? maxHeight[2] : '', + ], + }); + }} + mobileValue={undefined !== maxHeight && undefined !== maxHeight[2] ? maxHeight[2] : ''} + onChangeMobile={(value) => { + setAttributes({ + maxHeight: [ + undefined !== maxHeight && undefined !== maxHeight[0] ? maxHeight[0] : '', + undefined !== maxHeight && undefined !== maxHeight[1] ? maxHeight[1] : '', + value, + ], + }); + }} + min={0} + max={maxHeightUnit === 'px' ? 2000 : 100} + step={1} + unit={maxHeightUnit ? maxHeightUnit : '%'} + onUnit={(value) => { + setAttributes({ maxHeightUnit: value }); + }} + units={['px', '%', 'vw']} + /> + )} From 69eb425192e14e3df4bba09476581a3b2681aff9 Mon Sep 17 00:00:00 2001 From: Josh Oakes Date: Fri, 8 Nov 2024 10:49:32 -0600 Subject: [PATCH 16/98] KAD-3742 Create transform --- src/blocks/table/transforms.js | 84 ++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 src/blocks/table/transforms.js diff --git a/src/blocks/table/transforms.js b/src/blocks/table/transforms.js new file mode 100644 index 000000000..53e4c0f4a --- /dev/null +++ b/src/blocks/table/transforms.js @@ -0,0 +1,84 @@ +/** + * External dependencies + */ +import { every } from 'lodash'; + +/** + * WordPress dependencies + */ +import { createBlobURL } from '@wordpress/blob'; +import { createBlock, getBlockAttributes } from '@wordpress/blocks'; +import { dispatch } from '@wordpress/data'; +import { store as noticesStore } from '@wordpress/notices'; +import { __ } from '@wordpress/i18n'; + +const coreCellToKadenceCell = (cell) => { + return createBlock('kadence/table-data', {}, [ + createBlock('core/paragraph', { + content: cell.content, + }), + ]); +}; + +const createKadenceRow = (rowData) => { + const cells = rowData.cells.map((cell) => coreCellToKadenceCell(cell)); + return createBlock('kadence/table-row', {}, cells); +}; + +const getColumnCount = (attributes) => { + if (attributes.head && attributes.head[0]) { + return attributes.head[0].cells.length; + } + if (attributes.body && attributes.body[0]) { + return attributes.body[0].cells.length; + } + if (attributes.foot && attributes.foot[0]) { + return attributes.foot[0].cells.length; + } + return 0; +}; + +const transforms = { + from: [ + { + type: 'block', + isMultiBlock: true, + blocks: ['core/table'], + transform: (attributes) => { + const { head, body, foot } = attributes[0]; + const innerBlocks = []; + + console.log(attributes); + + if (head && head.length > 0) { + head.forEach((row) => { + innerBlocks.push(createKadenceRow(row)); + }); + } + + if (body && body.length > 0) { + body.forEach((row) => { + innerBlocks.push(createKadenceRow(row)); + }); + } + + if (foot && foot.length > 0) { + foot.forEach((row) => { + innerBlocks.push(createKadenceRow(row)); + }); + } + + return createBlock( + 'kadence/table', + { + isFirstRowHeader: head && head.length > 0, + columns: getColumnCount(attributes[0]), + }, + innerBlocks + ); + }, + }, + ], +}; + +export default transforms; From 806d9bf85fdee7a09b3f67383ffe23548fb0c452 Mon Sep 17 00:00:00 2001 From: Josh Oakes Date: Fri, 8 Nov 2024 12:45:40 -0600 Subject: [PATCH 17/98] Update index.js --- src/blocks/table/index.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/blocks/table/index.js b/src/blocks/table/index.js index bf183a1a3..ffedce5f5 100644 --- a/src/blocks/table/index.js +++ b/src/blocks/table/index.js @@ -5,6 +5,7 @@ import { InnerBlocks } from '@wordpress/block-editor'; * Internal dependencies */ import edit from './edit'; +import transforms from './transforms'; import metadata from './block.json'; import { tableBlockIcon } from '@kadence/icons'; import { __, _x } from '@wordpress/i18n'; @@ -26,6 +27,7 @@ registerBlockType('kadence/table', { src: tableBlockIcon, }, edit, + transforms, save: () => { return ; }, From 6832dba6471a549c06862683b1e8268c1e06e635 Mon Sep 17 00:00:00 2001 From: gilbert-hernandez Date: Fri, 8 Nov 2024 15:02:13 -0700 Subject: [PATCH 18/98] KAD-3345 requested updates --- ...-kadence-blocks-advanced-heading-block.php | 6 +- src/blocks/advancedheading/block.json | 4 + src/blocks/advancedheading/edit.js | 82 ++++++++++--------- .../src/shadow/shadow-control/index.js | 8 -- 4 files changed, 51 insertions(+), 49 deletions(-) diff --git a/includes/blocks/class-kadence-blocks-advanced-heading-block.php b/includes/blocks/class-kadence-blocks-advanced-heading-block.php index 2345b61c7..995cab797 100644 --- a/includes/blocks/class-kadence-blocks-advanced-heading-block.php +++ b/includes/blocks/class-kadence-blocks-advanced-heading-block.php @@ -169,14 +169,14 @@ public function build_css( $attributes, $css, $unique_id, $unique_style_id ) { $css->add_property( 'background-color', $css->render_color( $attributes['background'] ) ); } } - if ( isset( $attributes['textShadow'] ) && is_array( $attributes['textShadow'] ) && isset( $attributes['textShadow'][0] ) && is_array( $attributes['textShadow'][0] ) && isset( $attributes['textShadow'][0]['enable'] ) && $attributes['textShadow'][0]['enable'] ) { + if ( isset( $attributes['textShadow'] ) && is_array( $attributes['textShadow'] ) && isset( $attributes['textShadow'][0] ) && is_array( $attributes['textShadow'][0] ) && isset( $attributes['enableTextShadow'] ) && $attributes['enableTextShadow'] ) { $css->add_property( 'text-shadow', ( isset( $attributes['textShadow'][0]['hOffset'] ) ? $attributes['textShadow'][0]['hOffset'] : 1 ) . 'px ' . ( isset( $attributes['textShadow'][0]['vOffset'] ) ? $attributes['textShadow'][0]['vOffset'] : 1 ) . 'px ' . ( isset( $attributes['textShadow'][0]['blur'] ) ? $attributes['textShadow'][0]['blur'] : 1 ) . 'px ' . ( isset( $attributes['textShadow'][0]['color'] ) ? $css->render_color( $attributes['textShadow'][0]['color'] ) : 'rgba(0,0,0,0.2)' ) ); } - if ( isset( $attributes['textShadowTablet'] ) && is_array( $attributes['textShadowTablet'] ) && isset( $attributes['textShadowTablet'][0] ) && is_array( $attributes['textShadowTablet'][0] ) && isset( $attributes['textShadowTablet'][0]['enable'] ) && $attributes['textShadowTablet'][0]['enable'] ) { + if ( isset( $attributes['textShadowTablet'] ) && is_array( $attributes['textShadowTablet'] ) && isset( $attributes['textShadowTablet'][0] ) && is_array( $attributes['textShadowTablet'][0] ) && isset( $attributes['enableTextShadow'] ) && $attributes['enableTextShadow'] ) { $css->set_media_state('tablet'); $css->add_property( 'text-shadow', ( isset( $attributes['textShadowTablet'][0]['hOffset'] ) ? $attributes['textShadowTablet'][0]['hOffset'] : 1 ) . 'px ' . ( isset( $attributes['textShadowTablet'][0]['vOffset'] ) ? $attributes['textShadowTablet'][0]['vOffset'] : 1 ) . 'px ' . ( isset( $attributes['textShadowTablet'][0]['blur'] ) ? $attributes['textShadowTablet'][0]['blur'] : 1 ) . 'px ' . ( isset( $attributes['textShadowTablet'][0]['color'] ) ? $css->render_color( $attributes['textShadowTablet'][0]['color'] ) : 'rgba(0,0,0,0.2)' ) ); } - if ( isset( $attributes['textShadowMobile'] ) && is_array( $attributes['textShadowMobile'] ) && isset( $attributes['textShadowMobile'][0] ) && is_array( $attributes['textShadowMobile'][0] ) && isset( $attributes['textShadowMobile'][0]['enable'] ) && $attributes['textShadowMobile'][0]['enable'] ) { + if ( isset( $attributes['textShadowMobile'] ) && is_array( $attributes['textShadowMobile'] ) && isset( $attributes['textShadowMobile'][0] ) && is_array( $attributes['textShadowMobile'][0] ) && isset( $attributes['enableTextShadow'] ) && $attributes['enableTextShadow'] ) { $css->set_media_state('mobile'); $css->add_property( 'text-shadow', ( isset( $attributes['textShadowMobile'][0]['hOffset'] ) ? $attributes['textShadowMobile'][0]['hOffset'] : 1 ) . 'px ' . ( isset( $attributes['textShadowMobile'][0]['vOffset'] ) ? $attributes['textShadowMobile'][0]['vOffset'] : 1 ) . 'px ' . ( isset( $attributes['textShadowMobile'][0]['blur'] ) ? $attributes['textShadowMobile'][0]['blur'] : 1 ) . 'px ' . ( isset( $attributes['textShadowMobile'][0]['color'] ) ? $css->render_color( $attributes['textShadowMobile'][0]['color'] ) : 'rgba(0,0,0,0.2)' ) ); } diff --git a/src/blocks/advancedheading/block.json b/src/blocks/advancedheading/block.json index d4223b353..cf7342f2c 100644 --- a/src/blocks/advancedheading/block.json +++ b/src/blocks/advancedheading/block.json @@ -307,6 +307,10 @@ "mobileAlign": { "type": "string" }, + "enableTextShadow": { + "type": "boolean", + "default": false + }, "textShadow": { "type": "array", "default": [ diff --git a/src/blocks/advancedheading/edit.js b/src/blocks/advancedheading/edit.js index 5e3b90343..4081f7b24 100644 --- a/src/blocks/advancedheading/edit.js +++ b/src/blocks/advancedheading/edit.js @@ -119,6 +119,7 @@ function KadenceAdvancedHeading(props) { content, color, colorClass, + enableTextShadow, textShadow, textShadowTablet, textShadowMobile, @@ -527,12 +528,6 @@ function KadenceAdvancedHeading(props) { undefined !== tabletAlign ? tabletAlign : '', undefined !== mobileAlign ? mobileAlign : '' ); - const previewEnableTextShadow = getPreviewSize( - previewDevice, - undefined !== textShadow ? textShadow[0].enable : '', - undefined !== textShadowTablet ? textShadowTablet[0].enable : '', - undefined !== textShadowMobile ? textShadowMobile[0].enable : '' - ); const previewColorTextShadow = getPreviewSize( previewDevice, undefined !== textShadow && undefined !== textShadow[0] && undefined !== textShadow[0].color @@ -540,10 +535,10 @@ function KadenceAdvancedHeading(props) { : 'rgba(0, 0, 0, 0.2)', undefined !== textShadowTablet && undefined !== textShadowTablet[0] && undefined !== textShadowTablet[0].color ? textShadowTablet[0].color - : 'rgba(0, 0, 0, 0.2)', + : textShadow[0].color, undefined !== textShadowMobile && undefined !== textShadowMobile[0] && undefined !== textShadowMobile[0].color ? textShadowMobile[0].color - : 'rgba(0, 0, 0, 0.2)' + : textShadowTablet[0].color ? textShadowTablet[0].color : textShadow[0].color ); const previewHOffset = getPreviewSize( previewDevice, @@ -552,10 +547,10 @@ function KadenceAdvancedHeading(props) { : 1, undefined !== textShadowTablet && undefined !== textShadowTablet[0] && undefined !== textShadowTablet[0].hOffset ? textShadowTablet[0].hOffset - : 1, + : '', undefined !== textShadowMobile && undefined !== textShadowMobile[0] && undefined !== textShadowMobile[0].hOffset ? textShadowMobile[0].hOffset - : 1 + : '' ); const previewVOffset = getPreviewSize( previewDevice, @@ -565,11 +560,11 @@ function KadenceAdvancedHeading(props) { undefined !== textShadowTablet && undefined !== textShadowTablet[0] && undefined !== textShadowTablet[0].vOffset ? textShadowTablet[0].vOffset - : 1, + : '', undefined !== textShadowMobile && undefined !== textShadowMobile[0] && undefined !== textShadowMobile[0].vOffset ? textShadowMobile[0].vOffset - : 1 + : '' ); const previewBlur = getPreviewSize( previewDevice, @@ -579,11 +574,11 @@ function KadenceAdvancedHeading(props) { undefined !== textShadowTablet && undefined !== textShadowTablet[0] && undefined !== textShadowTablet[0].blur ? textShadowTablet[0].blur - : 1, + : '', undefined !== textShadowMobile && undefined !== textShadowMobile[0] && undefined !== textShadowMobile[0].blur ? textShadowMobile[0].blur - : 1 + : '' ); let previewJustifyAlign = previewAlign; switch (previewAlign) { @@ -1017,7 +1012,7 @@ function KadenceAdvancedHeading(props) { : undefined, textTransform: textTransform ? textTransform : undefined, fontFamily: typography ? renderTypography : '', - textShadow: previewEnableTextShadow + textShadow: enableTextShadow ? `${previewHOffset}px ${previewVOffset}px ${previewBlur}px ${KadenceColorOutput( previewColorTextShadow )}` @@ -1719,30 +1714,41 @@ function KadenceAdvancedHeading(props) { initialOpen={false} panelName={'kb-adv-heading-text-shadow'} > - { - saveShadow({ enable: value }); - }} - onColorChange={(value) => { - saveShadow({ color: value }); - }} - onHOffsetChange={(value) => { - saveShadow({ hOffset: value }); - }} - onVOffsetChange={(value) => { - saveShadow({ vOffset: value }); - }} - onBlurChange={(value) => { - saveShadow({ blur: value }); - }} + + { + setAttributes({enableTextShadow: value }); + } } /> + {enableTextShadow === true && ( + { + saveShadow({ enable: value }); + }} + onColorChange={(value) => { + saveShadow({ color: value }); + }} + onHOffsetChange={(value) => { + saveShadow({ hOffset: value }); + }} + onVOffsetChange={(value) => { + saveShadow({ vOffset: value }); + }} + onBlurChange={(value) => { + saveShadow({ blur: value }); + }} + /> + )} + {showSettings('iconSettings', 'kadence/advancedheading') && (

{ label }

- { onEnableChange && ( - onEnableChange( value ) } - /> - ) }
) } - { enable && (
@@ -105,7 +98,6 @@ const ShadowControl = ( {
- ) }
); export default ShadowControl; From bda7f5c31c2552bcc1f90a0251511ee06d0a8c18 Mon Sep 17 00:00:00 2001 From: Josh Oakes Date: Fri, 8 Nov 2024 16:40:45 -0600 Subject: [PATCH 19/98] KAD-3786 Insert before/after --- src/blocks/table/block.json | 59 +++- src/blocks/table/children/data/block.json | 10 +- src/blocks/table/children/data/edit.js | 166 +++++++++- src/blocks/table/children/row/block.json | 5 +- src/blocks/table/children/row/edit.js | 148 +++++---- .../table/components/backend-styles/index.js | 58 ++-- src/blocks/table/edit.js | 289 ++++++++++++++---- 7 files changed, 569 insertions(+), 166 deletions(-) diff --git a/src/blocks/table/block.json b/src/blocks/table/block.json index 9650f8030..7c2d54576 100644 --- a/src/blocks/table/block.json +++ b/src/blocks/table/block.json @@ -9,13 +9,8 @@ "uniqueID": { "type": "string" }, - "rows": { - "type": "number", - "default": 2 - }, "columns": { - "type": "number", - "default": 2 + "type": "number" }, "dataTypography": { "type": "array", @@ -180,10 +175,60 @@ "maxWidthUnit": { "type": "string", "default": "%" + }, + "cellPadding": { + "type": "array", + "default": ["xxs", "xs", "xxs", "xs"] + }, + "tabletCellPadding": { + "type": "array", + "default": ["", "", "", ""] + }, + "mobileCellPadding": { + "type": "array", + "default": ["", "", "", ""] + }, + "cellPaddingType": { + "type": "string", + "default": "px" + }, + "headerAlign": { + "type": "string", + "default": "center" + }, + "headerAlignTablet": { + "type": "string", + "default": "" + }, + "headerAlignMobile": { + "type": "string", + "default": "" + }, + "textAlign": { + "type": "string", + "default": "left" + }, + "textAlignTablet": { + "type": "string", + "default": "" + }, + "textAlignMobile": { + "type": "string", + "default": "" + }, + "isFirstRowHeader": { + "type": "boolean", + "default": false + }, + "isFirstColumnHeader": { + "type": "boolean", + "default": false } }, "providesContext": { - "kadence/table-columns": "columns" + "kadence/table/columns": "columns", + "kadence/table/isFirstRowHeader": "isFirstRowHeader", + "kadence/table/isFirstColumnHeader": "isFirstColumnHeader" }, "supports": { "kbMetadata": true diff --git a/src/blocks/table/children/data/block.json b/src/blocks/table/children/data/block.json index 54cd9abae..ebb469765 100644 --- a/src/blocks/table/children/data/block.json +++ b/src/blocks/table/children/data/block.json @@ -9,13 +9,13 @@ "attributes": { "uniqueID": { "type": "string" - }, - "isHeader": { - "type": "boolean", - "default": false } }, "supports": { "kbMetadata": true - } + }, + "usesContext": [ + "kadence/table/thisRowIsHeader", + "kadence/table/isFirstColumnHeader" + ] } diff --git a/src/blocks/table/children/data/edit.js b/src/blocks/table/children/data/edit.js index c42691d62..3ff2c292a 100644 --- a/src/blocks/table/children/data/edit.js +++ b/src/blocks/table/children/data/edit.js @@ -3,6 +3,7 @@ import React, { useEffect, useState } from '@wordpress/element'; import { useSelect, useDispatch } from '@wordpress/data'; import { BlockControls, useBlockProps, InnerBlocks } from '@wordpress/block-editor'; import metadata from './block.json'; +import { plus, columns } from '@wordpress/icons'; import { KadenceBlockDefaults, @@ -13,24 +14,47 @@ import { SelectParentBlock, } from '@kadence/components'; import { setBlockDefaults, getUniqueId, getPostOrFseId } from '@kadence/helpers'; - +import { createBlock } from '@wordpress/blocks'; +import { flow } from 'lodash'; import classnames from 'classnames'; -import { ToggleControl } from '@wordpress/components'; +import { ToolbarDropdownMenu, MenuGroup, MenuItem } from '@wordpress/components'; const DEFAULT_BLOCK = [['core/paragraph', {}]]; export function Edit(props) { - const { attributes, setAttributes, className, clientId } = props; + const { attributes, setAttributes, className, clientId, context } = props; - const { uniqueID, isHeader } = attributes; + const { uniqueID } = attributes; const [activeTab, setActiveTab] = useState('general'); const { addUniqueID } = useDispatch('kadenceblocks/data'); - const { isUniqueID, isUniqueBlock, parentData } = useSelect( + const { replaceInnerBlocks } = useDispatch('core/block-editor'); + const { insertBlock, updateBlockAttributes } = useDispatch('core/block-editor'); + + const { + isUniqueID, + isUniqueBlock, + parentData, + index, + parentTableClientId, + parentColumns, + columnPosition, + siblingRows, + } = useSelect( (select) => { + const blockParents = select('core/block-editor').getBlockParents(clientId); + const tableClientId = blockParents[0]; + const rowId = blockParents[1]; + const rowBlocks = select('core/block-editor').getBlockOrder(rowId); return { isUniqueID: (value) => select('kadenceblocks/data').isUniqueID(value), isUniqueBlock: (value, clientId) => select('kadenceblocks/data').isUniqueBlock(value, clientId), + index: select('core/block-editor').getBlockIndex(clientId), + parentTableClientId: tableClientId, + parentColumns: select('core/block-editor').getBlockAttributes(tableClientId).columns, + currentRowClientId: rowId, + columnPosition: rowBlocks.indexOf(clientId), + siblingRows: select('core/block-editor').getBlocks(tableClientId), parentData: { rootBlock: select('core/block-editor').getBlock( select('core/block-editor').getBlockHierarchyRootClientId(clientId) @@ -65,11 +89,134 @@ export function Edit(props) { } }, []); - const Tag = isHeader ? 'th' : 'td'; + const addRow = (position) => { + let insertIndex; + + switch (position) { + case 'before': + insertIndex = index; + break; + case 'after': + insertIndex = index + 1; + break; + case 'top': + insertIndex = 0; + break; + case 'bottom': + insertIndex = undefined; + break; + default: + return; + } + + const newRow = createBlock('kadence/table-row', {}); + insertBlock(newRow, insertIndex, parentTableClientId, false); + }; + + const addColumn = (position) => { + const newColumnCount = parentColumns + 1; + + let insertIndex; + switch (position) { + case 'before': + insertIndex = columnPosition; + break; + case 'after': + insertIndex = columnPosition + 1; + break; + case 'start': + insertIndex = 0; + break; + case 'end': + insertIndex = parentColumns; + break; + default: + return; + } + + siblingRows.forEach((row) => { + const newCells = [...row.innerBlocks]; + const newCell = createBlock('kadence/table-data', {}); + newCells.splice(insertIndex, 0, newCell); + + replaceInnerBlocks(row.clientId, newCells, false); + updateBlockAttributes(parentTableClientId, { columns: newColumnCount }); + }); + }; + + const rowControls = [ + { + title: __('Add Row Before', 'kadence-blocks'), + onClick: () => addRow('before'), + }, + { + title: __('Add Row After', 'kadence-blocks'), + onClick: () => addRow('after'), + }, + { + title: __('Add Row at Top', 'kadence-blocks'), + onClick: () => addRow('top'), + }, + { + title: __('Add Row at Bottom', 'kadence-blocks'), + onClick: () => addRow('bottom'), + }, + ]; + + const columnControls = [ + { + title: __('Add Column Before', 'kadence-blocks'), + onClick: () => addColumn('before'), + }, + { + title: __('Add Column After', 'kadence-blocks'), + onClick: () => addColumn('after'), + }, + { + title: __('Add Column at Start', 'kadence-blocks'), + onClick: () => addColumn('start'), + }, + { + title: __('Add Column at End', 'kadence-blocks'), + onClick: () => addColumn('end'), + }, + ]; + + const thisRowIsHeader = context['kadence/table/thisRowIsHeader']; + const firstColumnIsHeader = context['kadence/table/isFirstColumnHeader']; + const Tag = (index === 0 && firstColumnIsHeader) || thisRowIsHeader ? 'th' : 'td'; return ( + + {({ onClose }) => ( + <> + + {rowControls.map((control) => ( + + {control.title} + + ))} + + + )} + + + + {({ onClose }) => ( + <> + + {columnControls.map((control) => ( + + {control.title} + + ))} + + + )} + + - setAttributes({ isHeader: value })} - help={__('Switches to th tag and applies header typography styles.', 'kadence-blocks')} - /> + General settings )} {activeTab === 'advanced' && ( diff --git a/src/blocks/table/children/row/block.json b/src/blocks/table/children/row/block.json index fdaf13404..41c792d85 100644 --- a/src/blocks/table/children/row/block.json +++ b/src/blocks/table/children/row/block.json @@ -36,7 +36,10 @@ "default": "px" } }, - "usesContext": [ "kadence/table-columns" ], + "usesContext": [ + "kadence/table/columns", + "kadence/table/isFirstRowHeader" + ], "supports": { "kbMetadata": true } diff --git a/src/blocks/table/children/row/edit.js b/src/blocks/table/children/row/edit.js index b51a5a5d1..a8f10a946 100644 --- a/src/blocks/table/children/row/edit.js +++ b/src/blocks/table/children/row/edit.js @@ -1,43 +1,31 @@ import { __ } from '@wordpress/i18n'; -import React, { useState, useEffect } from '@wordpress/element'; +import React, { useState, useEffect, useMemo } from '@wordpress/element'; import { useSelect, useDispatch } from '@wordpress/data'; -import { useBlockProps, BlockControls, InnerBlocks, useInnerBlocksProps } from '@wordpress/block-editor'; +import { + useBlockProps, + BlockControls, + BlockContextProvider, + useInnerBlocksProps, + InnerBlocks, +} from '@wordpress/block-editor'; import metadata from './block.json'; +import { flow } from 'lodash'; +import { ToolbarDropdownMenu, MenuGroup, MenuItem } from '@wordpress/components'; +import { createBlock } from '@wordpress/blocks'; -import { - RangeControl, - ToggleControl, - TextControl, - Modal, - SelectControl, - FormFileUpload, - Button, - Notice, - __experimentalNumberControl as NumberControl, -} from '@wordpress/components'; +import { plus } from '@wordpress/icons'; import { - KadenceSelectPosts, KadencePanelBody, InspectorControlTabs, KadenceInspectorControls, - KadenceBlockDefaults, - ResponsiveMeasureRangeControl, - SpacingVisualizer, CopyPasteAttributes, PopColorControl, SelectParentBlock, ResponsiveRangeControls, } from '@kadence/components'; -import { - setBlockDefaults, - mouseOverVisualizer, - getSpacingOptionOutput, - getUniqueId, - getPostOrFseId, - getPreviewSize, -} from '@kadence/helpers'; +import { setBlockDefaults, getUniqueId, getPostOrFseId } from '@kadence/helpers'; import classnames from 'classnames'; import BackendStyles from './backend-styles'; @@ -55,14 +43,19 @@ export function Edit(props) { minHeightUnit, } = attributes; - const columns = context['kadence/table-columns']; + const columns = context['kadence/table/columns']; + const isFirstRowHeader = context['kadence/table/isFirstRowHeader']; + const { addUniqueID } = useDispatch('kadenceblocks/data'); - const { isUniqueID, isUniqueBlock, previewDevice, parentData } = useSelect( + const { insertBlock } = useDispatch('core/block-editor'); + const { isUniqueID, isUniqueBlock, previewDevice, parentData, index, parentClientId } = useSelect( (select) => { return { isUniqueID: (value) => select('kadenceblocks/data').isUniqueID(value), isUniqueBlock: (value, clientId) => select('kadenceblocks/data').isUniqueBlock(value, clientId), + parentClientId: select('core/block-editor').getBlockParents(clientId)[0], previewDevice: select('kadenceblocks/data').getPreviewDeviceType(), + index: select('core/block-editor').getBlockIndex(clientId), parentData: { rootBlock: select('core/block-editor').getBlock( select('core/block-editor').getBlockHierarchyRootClientId(clientId) @@ -78,23 +71,60 @@ export function Edit(props) { [clientId] ); + const addRow = (position) => { + let insertIndex; + + switch (position) { + case 'before': + insertIndex = index; + break; + case 'after': + insertIndex = index + 1; + break; + case 'top': + insertIndex = 0; + break; + case 'bottom': + insertIndex = undefined; + break; + default: + return; + } + + const newRow = createBlock('kadence/table-row', {}); + insertBlock(newRow, insertIndex, parentClientId, false); + }; + + const rowControls = [ + { + title: __('Add Row Before', 'kadence-blocks'), + onClick: () => addRow('before'), + }, + { + title: __('Add Row After', 'kadence-blocks'), + onClick: () => addRow('after'), + }, + { + title: __('Add Row at Top', 'kadence-blocks'), + onClick: () => addRow('top'), + }, + { + title: __('Add Row at Bottom', 'kadence-blocks'), + onClick: () => addRow('bottom'), + }, + ]; + const [activeTab, setActiveTab] = useState('style'); const { getBlocks } = useSelect((select) => select('core/block-editor')); const { replaceInnerBlocks } = useDispatch('core/block-editor'); + const thisRowIsHeader = useMemo(() => { + return index === 0 && isFirstRowHeader + ? { 'kadence/table/thisRowIsHeader': true } + : { 'kadence/table/thisRowIsHeader': false }; + }, [index, isFirstRowHeader]); const nonTransAttrs = []; - // const classes = classnames( - // { - // 'kb-table-row': true, - // [`kb-table-row${uniqueID}`]: uniqueID, - // }, - // className - // ); - // const blockProps = useBlockProps({ - // className: classes, - // }); - useEffect(() => { setBlockDefaults('kadence/table-row', attributes); @@ -113,12 +143,11 @@ export function Edit(props) { const innerBlocks = getBlocks(clientId); if (innerBlocks.length < columns) { - // Add new blocks const newBlocks = [ ...innerBlocks, ...Array(Math.max(1, columns - innerBlocks.length)) .fill(null) - .map(() => wp.blocks.createBlock('kadence/table-data', {})), + .map(() => createBlock('kadence/table-data', {})), ]; replaceInnerBlocks(clientId, newBlocks, false); } else if (innerBlocks.length > columns) { @@ -128,30 +157,43 @@ export function Edit(props) { } }, [columns]); + const blockProps = useBlockProps({ + className: classnames( + { + 'kb-table-row': true, + [`kb-table-row${uniqueID}`]: uniqueID, + }, + className + ), + }); + const { children, ...innerBlocksProps } = useInnerBlocksProps( { - className: classnames( - { - 'kb-table-row': true, - [`kb-table-row${uniqueID}`]: uniqueID, - }, - className - ), - style: {}, + className: '', }, { allowedBlocks: ['kadence/table-data'], - orientation: 'vertical', - templateLock: 'all', renderAppender: false, templateInsertUpdatesSelection: true, } ); return ( - - {/*
*/} + + + {({ onClose }) => ( + <> + + {rowControls.map((control) => ( + + {control.title} + + ))} + + + )} + KadenceBlockDefaults} - {children} + {children} ); diff --git a/src/blocks/table/components/backend-styles/index.js b/src/blocks/table/components/backend-styles/index.js index 9941b4516..ff5bc8658 100644 --- a/src/blocks/table/components/backend-styles/index.js +++ b/src/blocks/table/components/backend-styles/index.js @@ -33,6 +33,16 @@ export default function BackendStyles(props) { maxWidthUnit, maxHeight, maxHeightUnit, + cellPadding, + tabletCellPadding, + mobileCellPadding, + cellPaddingType, + textAlign, + textAlignTablet, + textAlignMobile, + headerAlign, + headerAlignTablet, + headerAlignMobile, } = attributes; const css = new KadenceBlocksCSS(); @@ -61,31 +71,6 @@ export default function BackendStyles(props) { // undefined !== mobileMargin ? mobileMargin[3] : '' // ); // - // const previewPaddingTop = getPreviewSize( - // previewDevice, - // undefined !== padding ? padding[0] : '', - // undefined !== tabletPadding ? tabletPadding[0] : '', - // undefined !== mobilePadding ? mobilePadding[0] : '' - // ); - // const previewPaddingRight = getPreviewSize( - // previewDevice, - // undefined !== padding ? padding[1] : '', - // undefined !== tabletPadding ? tabletPadding[1] : '', - // undefined !== mobilePadding ? mobilePadding[1] : '' - // ); - // const previewPaddingBottom = getPreviewSize( - // previewDevice, - // undefined !== padding ? padding[2] : '', - // undefined !== tabletPadding ? tabletPadding[2] : '', - // undefined !== mobilePadding ? mobilePadding[2] : '' - // ); - // const previewPaddingLeft = getPreviewSize( - // previewDevice, - // undefined !== padding ? padding[3] : '', - // undefined !== tabletPadding ? tabletPadding[3] : '', - // undefined !== mobilePadding ? mobilePadding[3] : '' - // ); - // const previewWidth = getPreviewSize( // previewDevice, // undefined !== width?.[0] ? width[0] : '', @@ -93,11 +78,34 @@ export default function BackendStyles(props) { // undefined !== width?.[2] ? width[2] : '' // ); + const previewHeaderAlign = getPreviewSize(previewDevice, headerAlign, headerAlignTablet, headerAlignMobile); + const previewTextAlign = getPreviewSize(previewDevice, textAlign, textAlignTablet, textAlignMobile); + css.set_selector(`.kb-table${uniqueID}`); css.render_font(dataTypography ? dataTypography : [], previewDevice); css.set_selector(`.kb-table${uniqueID} th`); css.render_font(headerTypography ? headerTypography : [], previewDevice); + css.add_property('text-align', previewHeaderAlign); + css.render_measure_output( + cellPadding, + tabletCellPadding, + mobileCellPadding, + previewDevice, + 'padding', + cellPaddingType + ); + + css.set_selector(`.kb-table${uniqueID} td`); + css.add_property('text-align', previewTextAlign); + css.render_measure_output( + cellPadding, + tabletCellPadding, + mobileCellPadding, + previewDevice, + 'padding', + cellPaddingType + ); if (evenOddBackground) { css.set_selector(`.kb-table${uniqueID} tr:nth-child(even)`); diff --git a/src/blocks/table/edit.js b/src/blocks/table/edit.js index 52518cd45..77ebf2dec 100644 --- a/src/blocks/table/edit.js +++ b/src/blocks/table/edit.js @@ -1,6 +1,6 @@ import { __ } from '@wordpress/i18n'; -import { useState, useEffect } from '@wordpress/element'; -import { useSelect, useDispatch } from '@wordpress/data'; +import React, { useState, useEffect } from '@wordpress/element'; +import { useSelect, useDispatch, dispatch, select } from '@wordpress/data'; import { useBlockProps, BlockControls, InnerBlocks, useInnerBlocksProps } from '@wordpress/block-editor'; import classnames from 'classnames'; import metadata from './block.json'; @@ -34,6 +34,7 @@ import { ResponsiveMeasurementControls, ResponsiveBorderControl, ResponsiveRangeControls, + ResponsiveAlignControls, } from '@kadence/components'; import { @@ -72,6 +73,18 @@ export function Edit(props) { maxWidthUnit, maxHeight, maxHeightUnit, + cellPadding, + mobileCellPadding, + tabletCelladding, + cellPaddingType, + textAlign, + textAlignTablet, + textAlignMobile, + headerAlign, + headerAlignTablet, + headerAlignMobile, + isFirstRowHeader, + isFirstColumnHeader, } = attributes; const { addUniqueID } = useDispatch('kadenceblocks/data'); @@ -99,6 +112,8 @@ export function Edit(props) { const { replaceInnerBlocks } = useDispatch('core/block-editor'); const [activeTab, setActiveTab] = useState('general'); + const [placeholderRows, setPlaceholderRows] = useState(2); + const [placeholderColumns, setPlaceholderColumns] = useState(2); const nonTransAttrs = []; @@ -116,9 +131,9 @@ export function Edit(props) { useEffect(() => { setBlockDefaults('kadence/table', attributes); - if (uniqueID === undefined) { - updateRowsColumns(rows, columns); - } + // if (uniqueID === undefined) { + // updateRowsColumns(rows); + // } const postOrFseId = getPostOrFseId(props, parentData); const uniqueId = getUniqueId(uniqueID, clientId, isUniqueID, isUniqueBlock, postOrFseId); @@ -149,44 +164,6 @@ export function Edit(props) { return array && array[index] ? array[index] : ''; }; - const updateRowsColumns = (newRows, newColumns) => { - const currentBlocks = wp.data.select('core/block-editor').getBlocks(clientId); - - let newRowBlocks = [...currentBlocks]; - - if (newRows > rows && newRows !== 0) { - const additionalRows = Array(Math.max(1, newRows - currentBlocks.length)) - .fill() - .map(() => { - return createBlock( - 'kadence/table-row', - { columns: newColumns }, - Array(newColumns) - .fill() - .map(() => createBlock('kadence/table-data', {})) - ); - }); - newRowBlocks = [...newRowBlocks, ...additionalRows]; - } else if (newRows < rows && newRows !== 0) { - newRowBlocks = newRowBlocks.slice(0, newRows); - } - - if (newColumns !== columns) { - newRowBlocks = newRowBlocks.map((rowBlock) => { - if (rowBlock.attributes.columns === newColumns) { - return rowBlock; - } - return { - ...rowBlock, - attributes: { ...rowBlock.attributes, columns: newColumns }, - }; - }); - } - - replaceInnerBlocks(clientId, newRowBlocks, false); - setAttributes({ rows: newRows, columns: newColumns }); - }; - const innerBlocksProps = useInnerBlocksProps( { className: classnames( @@ -200,16 +177,121 @@ export function Edit(props) { }, { allowedBlocks: ['kadence/table-row'], - templateLock: true, - template: [ - ['kadence/table-row', { columns: 2 }], - ['kadence/table-row', { columns: 2 }], - ], renderAppender: false, - templateInsertUpdatesSelection: true, + templateInsertUpdatesSelection: false, } ); + const createTableRow = () => { + return createBlock('kadence/table-row', {}); + }; + + const handleInsertRowAbove = (index) => { + const { insertBlock } = dispatch('core/block-editor'); + const newRow = createTableRow(); + const blocks = select('core/block-editor').getBlocks(clientId); + insertBlock(newRow, index, clientId, false); + setAttributes({ rows: rows + 1 }); + }; + + const handleInsertRowBelow = (index) => { + const { insertBlock } = dispatch('core/block-editor'); + const newRow = createTableRow(); + const blocks = select('core/block-editor').getBlocks(clientId); + insertBlock(newRow, index + 1, clientId, false); + setAttributes({ rows: rows + 1 }); + }; + + const handleDeleteRow = (index) => { + const { removeBlock } = dispatch('core/block-editor'); + const blocks = select('core/block-editor').getBlocks(clientId); + if (blocks.length > 1) { + // Prevent deleting last row + removeBlock(blocks[index].clientId); + setAttributes({ rows: rows - 1 }); + } + }; + + // Handle column manipulation + const handleInsertColumnLeft = (index) => { + const { replaceBlock } = dispatch('core/block-editor'); + const blocks = select('core/block-editor').getBlocks(clientId); + + blocks.forEach((row) => { + const newCells = [...row.innerBlocks]; + const newCell = createBlock('kadence/table-data', {}); + newCells.splice(index, 0, newCell); + + const newRow = createBlock('kadence/table-row', { ...row.attributes, columns: columns + 1 }, newCells); + + replaceBlock(row.clientId, newRow); + }); + + setAttributes({ columns: columns + 1 }); + }; + + const handleInsertColumnRight = (index) => { + handleInsertColumnLeft(index + 1); + }; + + const handleDeleteColumn = (index) => { + if (columns <= 1) return; // Prevent deleting last column + + const { replaceBlock } = dispatch('core/block-editor'); + const blocks = select('core/block-editor').getBlocks(clientId); + + blocks.forEach((row) => { + const newCells = [...row.innerBlocks]; + newCells.splice(index, 1); + + const newRow = createBlock('kadence/table-row', { ...row.attributes, columns: columns - 1 }, newCells); + + replaceBlock(row.clientId, newRow); + }); + + setAttributes({ columns: columns - 1 }); + }; + + // Initialize table structure + useEffect(() => { + if (uniqueID) { + const blocks = select('core/block-editor').getBlocks(clientId); + + if (blocks.length === 0) { + const initialBlocks = Array(rows) + .fill(null) + .map(() => createTableRow()); + + replaceInnerBlocks(clientId, initialBlocks, false); + } + } + }, [uniqueID]); + + const createTable = () => { + setAttributes({ + columns: placeholderColumns, + }); + updateRowsColumns(placeholderRows); + }; + + const updateRowsColumns = (newRows) => { + const blocks = select('core/block-editor').getBlocks(clientId); + let newBlocks = [...blocks]; + + // Handle rows + if (newRows > rows) { + const additionalRows = Array(newRows - rows) + .fill(null) + .map(() => createTableRow()); + newBlocks = [...newBlocks, ...additionalRows]; + } else if (newRows < rows) { + newBlocks = newBlocks.slice(0, newRows); + } + + replaceInnerBlocks(clientId, newBlocks, false); + setAttributes({ rows: newRows }); + }; + const saveDataTypography = (value) => { setAttributes({ dataTypography: [{ ...dataTypography[0], ...value }, ...dataTypography.slice(1)], @@ -222,6 +304,38 @@ export function Edit(props) { }); }; + if (undefined === columns) { + return ( +
+

{__('Table layout', 'kadence-blocks')}

+
+ setPlaceholderColumns(value)} + min={2} + max={100} + /> + + setPlaceholderRows(value)} + min={2} + max={100} + /> + + +
+
+ ); + } + return (
@@ -238,27 +352,37 @@ export function Edit(props) { {activeTab === 'general' && ( <> - - updateRowsColumns(newRows, columns)} - min={1} - max={50} - /> + + updateRowsColumns(rows, newColumns)} + onChange={(value) => setAttributes({ columns: value })} min={1} max={20} /> + + setAttributes({ isFirstRowHeader: value })} + help={__('Switches to th tag and applies header typography styles.', 'kadence-blocks')} + /> + + setAttributes({ isFirstColumnHeader: value })} + help={__('Switches to th tag and applies header typography styles.', 'kadence-blocks')} + /> + setAttributes({ borderOnRowOnly: value })} /> + + setAttributes({ cellPadding: value })} + onChangeTablet={(value) => setAttributes({ tabletCelladding: value })} + onChangeMobile={(value) => setAttributes({ mobileCellPadding: value })} + min={cellPaddingType === 'em' || cellPaddingType === 'rem' ? -25 : -999} + max={cellPaddingType === 'em' || cellPaddingType === 'rem' ? 25 : 999} + step={cellPaddingType === 'em' || cellPaddingType === 'rem' ? 0.1 : 1} + unit={cellPaddingType} + units={['px', 'em', 'rem', '%']} + onUnit={(value) => setAttributes({ cellPaddingType: value })} + /> + + setAttributes({ textAlign: nextAlign })} + onChangeTablet={(nextAlign) => setAttributes({ textAlignMobile: nextAlign })} + onChangeMobile={(nextAlign) => setAttributes({ textAlignTablet: nextAlign })} + /> + setAttributes({ headerAlign: nextAlign })} + onChangeTablet={(nextAlign) => setAttributes({ headerAlignMobile: nextAlign })} + onChangeMobile={(nextAlign) => setAttributes({ headerAlignTablet: nextAlign })} + /> Date: Mon, 11 Nov 2024 09:21:03 -0600 Subject: [PATCH 20/98] KAD-3686 Sticky header rows --- .../class-kadence-blocks-table-block.php | 35 +++++++++- .../class-kadence-blocks-table-data-block.php | 13 +++- src/blocks/table/block.json | 6 +- src/blocks/table/children/data/block.json | 11 +++- src/blocks/table/children/data/edit.js | 8 ++- src/blocks/table/children/row/block.json | 7 ++ src/blocks/table/children/row/edit.js | 7 ++ .../table/components/backend-styles/index.js | 40 +++++------ src/blocks/table/edit.js | 66 +++++-------------- src/blocks/table/editor.scss | 16 ++--- 10 files changed, 120 insertions(+), 89 deletions(-) diff --git a/includes/blocks/class-kadence-blocks-table-block.php b/includes/blocks/class-kadence-blocks-table-block.php index 0cccc266e..801a0fbe4 100644 --- a/includes/blocks/class-kadence-blocks-table-block.php +++ b/includes/blocks/class-kadence-blocks-table-block.php @@ -69,11 +69,44 @@ public function build_css( $attributes, $css, $unique_id, $unique_style_id ) { $css->set_style_id( 'kb-' . $this->block_name . $unique_style_id ); - $css->set_selector( '.kb-table-container .kb-table' . esc_attr( $unique_id ) ); + $css->set_selector( '.kb-table-container' . esc_attr( $unique_id ) ); $css->render_typography( $attributes, 'dataTypography' ); + $max_width_unit = !empty( $attributes['maxWidthUnit'] ) ? $attributes['maxWidthUnit'] : 'px'; + $css->render_responsive_range( $attributes, 'maxWidth', 'max-width', $max_width_unit ); + + $max_height_unit = !empty( $attributes['maxHeighUnit'] ) ? $attributes['maxHeighUnit'] : 'px'; + $css->render_responsive_range( $attributes, 'maxHeight', 'max-height', $max_height_unit ); + + if ( !empty( $attributes['maxHeighUnit'][0] ) ) { + $css->add_property('overflow-y', 'auto'); + } + + if ( !empty( $attributes['maxWidthUnit'][0] ) ) { + $css->add_property('overflow-x', 'auto'); + } + + if( !empty( $attributes['stickyFirstRow']) ) { + $css->set_selector( '.kb-table-container .kb-table' . esc_attr( $unique_id ) . ' tr:first-child'); + $css->add_property( 'position', 'sticky'); + $css->add_property( 'top', '0'); + $css->add_property( 'z-index', '1'); + } + + if( !empty( $attributes['stickyFirstColumn']) ) { + $css->set_selector( '.kb-table-container .kb-table' . esc_attr( $unique_id ) . ' td:first-child, .kb-table' . esc_attr( $unique_id ) . ' th:first-child'); + $css->add_property( 'position', 'sticky'); + $css->add_property( 'left', '0'); + } + + $css->set_selector( '.kb-table-container .kb-table' . esc_attr( $unique_id ) . ' th' ); $css->render_typography( $attributes, 'headerTypography' ); + $css->render_measure_output( $attributes, 'cellPadding', 'padding' ); + + $css->set_selector( '.kb-table-container .kb-table' . esc_attr( $unique_id ) . ' td' ); + $css->render_measure_output( $attributes, 'cellPadding', 'padding' ); + if ( !empty( $attributes['evenOddBackground'] ) ) { $css->set_selector( '.kb-table-container .kb-table' . esc_attr( $unique_id ) . ' tr:nth-child(even)' ); diff --git a/includes/blocks/class-kadence-blocks-table-data-block.php b/includes/blocks/class-kadence-blocks-table-data-block.php index 7a6d00da6..05fdcced4 100644 --- a/includes/blocks/class-kadence-blocks-table-data-block.php +++ b/includes/blocks/class-kadence-blocks-table-data-block.php @@ -91,7 +91,7 @@ public function build_css( $attributes, $css, $unique_id, $unique_style_id ) { * @return mixed */ public function build_html( $attributes, $unique_id, $content, $block_instance ) { - $tag = ! empty( $attributes['isHeader'] ) ? 'th' : 'td'; + $tag = $this->is_this_block_header( $attributes, $block_instance->context ) ? 'th' : 'td'; return sprintf( '<%s class="kb-table-wrap kb-table-id-%2$s">%3$s', @@ -102,6 +102,17 @@ public function build_html( $attributes, $unique_id, $content, $block_instance ) ); } + private function is_this_block_header( $attributes, $context ) { + $isFirstRowHeader = ! empty( $context['kadence/table/isFirstRowHeader'] ); + $isFirstColumnHeader = ! empty( $context['kadence/table/isFirstColumnHeader'] ); + + $column = $attributes['column'] ?? -1; + $row = $context['kadence/table/parentRow'] ?? -1; + + return ( $column === 0 && $isFirstColumnHeader ) || ( $row === 0 && $isFirstRowHeader ); + + } + } Kadence_Blocks_Table_Data_Block::get_instance(); diff --git a/src/blocks/table/block.json b/src/blocks/table/block.json index 7c2d54576..1e01f6bb3 100644 --- a/src/blocks/table/block.json +++ b/src/blocks/table/block.json @@ -10,7 +10,7 @@ "type": "string" }, "columns": { - "type": "number" + "type": "string" }, "dataTypography": { "type": "array", @@ -166,7 +166,7 @@ }, "maxHeightUnit": { "type": "string", - "default": "%" + "default": "px" }, "maxWidth": { "type": "array", @@ -178,7 +178,7 @@ }, "cellPadding": { "type": "array", - "default": ["xxs", "xs", "xxs", "xs"] + "default": ["xxs", "xxs", "xxs", "xxs"] }, "tabletCellPadding": { "type": "array", diff --git a/src/blocks/table/children/data/block.json b/src/blocks/table/children/data/block.json index ebb469765..7fa393150 100644 --- a/src/blocks/table/children/data/block.json +++ b/src/blocks/table/children/data/block.json @@ -5,10 +5,15 @@ "title": "Table Data", "category": "kadence-blocks", "textdomain": "kadence-blocks", - "parent": [ "kadence/table-row" ], + "parent": [ + "kadence/table-row" + ], "attributes": { "uniqueID": { "type": "string" + }, + "column": { + "type": "number" } }, "supports": { @@ -16,6 +21,8 @@ }, "usesContext": [ "kadence/table/thisRowIsHeader", - "kadence/table/isFirstColumnHeader" + "kadence/table/isFirstColumnHeader", + "kadence/table/parentRow", + "kadence/table/isFirstRowHeader" ] } diff --git a/src/blocks/table/children/data/edit.js b/src/blocks/table/children/data/edit.js index 3ff2c292a..e666f13e7 100644 --- a/src/blocks/table/children/data/edit.js +++ b/src/blocks/table/children/data/edit.js @@ -23,7 +23,7 @@ const DEFAULT_BLOCK = [['core/paragraph', {}]]; export function Edit(props) { const { attributes, setAttributes, className, clientId, context } = props; - const { uniqueID } = attributes; + const { uniqueID, column } = attributes; const [activeTab, setActiveTab] = useState('general'); @@ -70,6 +70,12 @@ export function Edit(props) { [clientId] ); + useEffect(() => { + if (columnPosition !== column) { + setAttributes({ column: columnPosition }); + } + }, [columnPosition]); + const classes = classnames(className, 'kb-table-data'); const blockProps = useBlockProps({ className: classes, diff --git a/src/blocks/table/children/row/block.json b/src/blocks/table/children/row/block.json index 41c792d85..7a402d7f8 100644 --- a/src/blocks/table/children/row/block.json +++ b/src/blocks/table/children/row/block.json @@ -11,6 +11,9 @@ "uniqueID": { "type": "string" }, + "row": { + "type": "number" + }, "backgroundColor": { "type": "string", "default": "" @@ -40,6 +43,10 @@ "kadence/table/columns", "kadence/table/isFirstRowHeader" ], + "providesContext": { + "kadence/table/parentRow": "row", + "kadence/table/isFirstRowHeader": "kadence/table/isFirstRowHeader" + }, "supports": { "kbMetadata": true } diff --git a/src/blocks/table/children/row/edit.js b/src/blocks/table/children/row/edit.js index a8f10a946..3dced4496 100644 --- a/src/blocks/table/children/row/edit.js +++ b/src/blocks/table/children/row/edit.js @@ -41,6 +41,7 @@ export function Edit(props) { tabletMinHeight, mobileMinHeight, minHeightUnit, + row, } = attributes; const columns = context['kadence/table/columns']; @@ -71,6 +72,12 @@ export function Edit(props) { [clientId] ); + useEffect(() => { + if (index !== row) { + setAttributes({ row: index }); + } + }, [index]); + const addRow = (position) => { let insertIndex; diff --git a/src/blocks/table/components/backend-styles/index.js b/src/blocks/table/components/backend-styles/index.js index ff5bc8658..525268458 100644 --- a/src/blocks/table/components/backend-styles/index.js +++ b/src/blocks/table/components/backend-styles/index.js @@ -80,10 +80,23 @@ export default function BackendStyles(props) { const previewHeaderAlign = getPreviewSize(previewDevice, headerAlign, headerAlignTablet, headerAlignMobile); const previewTextAlign = getPreviewSize(previewDevice, textAlign, textAlignTablet, textAlignMobile); + const previewMaxHeight = getPreviewSize(previewDevice, maxHeight?.[0], maxHeight?.[1], maxHeight?.[2]); + const previewMaxWidth = getPreviewSize(previewDevice, maxWidth?.[0], maxWidth?.[1], maxWidth?.[2]); css.set_selector(`.kb-table${uniqueID}`); css.render_font(dataTypography ? dataTypography : [], previewDevice); + css.set_selector(`.kb-table-container${uniqueID}`); + if (maxHeight) { + css.add_property('max-height', getSpacingOptionOutput(previewMaxHeight, maxHeightUnit) + ' !important'); + css.add_property('overflow-y', 'auto'); + } + + if (maxWidth) { + css.add_property('max-width', getSpacingOptionOutput(previewMaxWidth, maxWidthUnit) + ' !important'); + css.add_property('overflow-x', 'auto'); + } + css.set_selector(`.kb-table${uniqueID} th`); css.render_font(headerTypography ? headerTypography : [], previewDevice); css.add_property('text-align', previewHeaderAlign); @@ -167,38 +180,21 @@ export default function BackendStyles(props) { getBorderStyle(previewDevice, 'left', borderStyle, tabletBorderStyle, mobileBorderStyle) ); - // css.add_property('color', KadenceColorOutput(dataTypography.color)); - // css.add_property('font-size', getFontSizeOptionOutput(previewFontSize, dataTypography.sizeType)); - // css.add_property('letter-spacing', getSpacingOptionOutput(previewLetterSpacing, dataTypography.letterType)); - // css.add_property('text-transform', dataTypography.textTransform); - // css.add_property('font-family', dataTypography.family); - // css.add_property('font-style', dataTypography.style); - // css.add_property('font-weight', dataTypography.weight); - // css.add_property('line-height', getSpacingOptionOutput(previewLineHeight, dataTypography.lineType)); - // css.add_property('margin-top', getSpacingOptionOutput(previewMarginTop, marginUnit)); - // css.add_property('margin-right', getSpacingOptionOutput(previewMarginRight, marginUnit)); - // css.add_property('margin-bottom', getSpacingOptionOutput(previewMarginBottom, marginUnit)); - // css.add_property('margin-left', getSpacingOptionOutput(previewMarginLeft, marginUnit)); - // css.add_property('padding-top', getSpacingOptionOutput(previewPaddingTop, paddingUnit)); - // css.add_property('padding-right', getSpacingOptionOutput(previewPaddingRight, paddingUnit)); - // css.add_property('padding-bottom', getSpacingOptionOutput(previewPaddingBottom, paddingUnit)); - // css.add_property('padding-left', getSpacingOptionOutput(previewPaddingLeft, paddingUnit)); - if (stickyFirstRow) { - css.set_selector(`.kb-table${uniqueID}:first-child`); - css.add_property('position', 'sticky'); + css.set_selector(`.kb-table${uniqueID} tr:first-child`); + css.add_property('position', 'sticky !important'); css.add_property('top', '0'); css.add_property('z-index', '1'); } if (stickyFirstColumn) { css.set_selector(`.kb-table${uniqueID} td:first-child, .kb-table${uniqueID} th:first-child`); - css.add_property('position', 'sticky'); + css.add_property('position', 'sticky !important'); css.add_property('left', '0'); } - css.set_selector(`.kb-table-container${uniqueID}`); - css.add_property('position', 'sticky'); + // css.set_selector(`.kb-table-container${uniqueID}`); + // css.add_property('position', 'sticky'); const cssOutput = css.css_output(); diff --git a/src/blocks/table/edit.js b/src/blocks/table/edit.js index 77ebf2dec..501c182d4 100644 --- a/src/blocks/table/edit.js +++ b/src/blocks/table/edit.js @@ -15,6 +15,7 @@ import { SelectControl, FormFileUpload, Button, + ButtonGroup, Notice, __experimentalNumberControl as NumberControl, } from '@wordpress/components'; @@ -131,10 +132,6 @@ export function Edit(props) { useEffect(() => { setBlockDefaults('kadence/table', attributes); - // if (uniqueID === undefined) { - // updateRowsColumns(rows); - // } - const postOrFseId = getPostOrFseId(props, parentData); const uniqueId = getUniqueId(uniqueID, clientId, isUniqueID, isUniqueBlock, postOrFseId); if (uniqueId !== uniqueID) { @@ -202,17 +199,15 @@ export function Edit(props) { setAttributes({ rows: rows + 1 }); }; - const handleDeleteRow = (index) => { + const handleDeleteLastRow = () => { const { removeBlock } = dispatch('core/block-editor'); const blocks = select('core/block-editor').getBlocks(clientId); if (blocks.length > 1) { // Prevent deleting last row - removeBlock(blocks[index].clientId); - setAttributes({ rows: rows - 1 }); + removeBlock(blocks[blocks.length - 1].clientId, false); } }; - // Handle column manipulation const handleInsertColumnLeft = (index) => { const { replaceBlock } = dispatch('core/block-editor'); const blocks = select('core/block-editor').getBlocks(clientId); @@ -230,43 +225,6 @@ export function Edit(props) { setAttributes({ columns: columns + 1 }); }; - const handleInsertColumnRight = (index) => { - handleInsertColumnLeft(index + 1); - }; - - const handleDeleteColumn = (index) => { - if (columns <= 1) return; // Prevent deleting last column - - const { replaceBlock } = dispatch('core/block-editor'); - const blocks = select('core/block-editor').getBlocks(clientId); - - blocks.forEach((row) => { - const newCells = [...row.innerBlocks]; - newCells.splice(index, 1); - - const newRow = createBlock('kadence/table-row', { ...row.attributes, columns: columns - 1 }, newCells); - - replaceBlock(row.clientId, newRow); - }); - - setAttributes({ columns: columns - 1 }); - }; - - // Initialize table structure - useEffect(() => { - if (uniqueID) { - const blocks = select('core/block-editor').getBlocks(clientId); - - if (blocks.length === 0) { - const initialBlocks = Array(rows) - .fill(null) - .map(() => createTableRow()); - - replaceInnerBlocks(clientId, initialBlocks, false); - } - } - }, [uniqueID]); - const createTable = () => { setAttributes({ columns: placeholderColumns, @@ -317,7 +275,7 @@ export function Edit(props) { value={placeholderColumns} onChange={(value) => setPlaceholderColumns(value)} min={2} - max={100} + max={15} /> - + + + + setAttributes({ columns: value })} min={1} max={20} + style={{ marginTop: '15px' }} /> { setAttributes({ @@ -451,6 +416,7 @@ export function Edit(props) { { setAttributes({ @@ -484,7 +450,7 @@ export function Edit(props) { min={0} max={maxHeightUnit === 'px' ? 2000 : 100} step={1} - unit={maxHeightUnit ? maxHeightUnit : '%'} + unit={maxHeightUnit ? maxHeightUnit : 'px'} onUnit={(value) => { setAttributes({ maxHeightUnit: value }); }} diff --git a/src/blocks/table/editor.scss b/src/blocks/table/editor.scss index b99f3d54c..93b153166 100644 --- a/src/blocks/table/editor.scss +++ b/src/blocks/table/editor.scss @@ -6,13 +6,11 @@ */ @import "style"; -.kb-table { - //table, th, td { - // border: 1px solid; - // border-collapse: collapse; - //} - // - //.wp-block { - // margin: 0 !important; - //} +.kb-table-container { + + [data-type="core/paragraph"], + [data-type="core/paragraph"] > .wp-block { + margin-bottom: 0 !important; + margin-top: 0 !important; + } } From bcb1570954bdbc699c391181e62213fd4401996d Mon Sep 17 00:00:00 2001 From: Josh Oakes Date: Tue, 12 Nov 2024 10:42:49 -0600 Subject: [PATCH 21/98] KAD-3788 Options to set column widths --- .../class-kadence-blocks-table-block.php | 22 ++ src/blocks/table/block.json | 10 +- .../table/components/backend-styles/index.js | 58 ++-- src/blocks/table/edit.js | 268 +++++++++++++++--- 4 files changed, 284 insertions(+), 74 deletions(-) diff --git a/includes/blocks/class-kadence-blocks-table-block.php b/includes/blocks/class-kadence-blocks-table-block.php index 801a0fbe4..f663a7620 100644 --- a/includes/blocks/class-kadence-blocks-table-block.php +++ b/includes/blocks/class-kadence-blocks-table-block.php @@ -86,6 +86,28 @@ public function build_css( $attributes, $css, $unique_id, $unique_style_id ) { $css->add_property('overflow-x', 'auto'); } + if ( ! empty( $attributes['useFixedWidths'] ) && ! empty( $attributes['columnSettings'] ) && is_array( $attributes['columnSettings'] ) ) { + $has_fixed_columns = false; + + foreach ( $attributes['columnSettings'] as $index => $settings ) { + if ( ! empty( $settings['useFixed'] ) && isset( $settings['width'] ) && '' !== $settings['width'] ) { + $has_fixed_columns = true; + $width_unit = ! empty( $settings['unit'] ) ? $settings['unit'] : '%'; + + $css->set_selector( '.kb-table' . esc_attr( $unique_id ) . ' td:nth-child(' . ( $index + 1 ) . '), ' . + '.kb-table' . esc_attr( $unique_id ) . ' th:nth-child(' . ( $index + 1 ) . ')' ); + $css->add_property( 'width', $settings['width'] . $width_unit ); + } + } + + // Only set table-layout fixed if we have any fixed width columns. + if ( $has_fixed_columns ) { + $css->set_selector( '.kb-table' . esc_attr( $unique_id ) ); + $css->add_property( 'table-layout', 'fixed' ); + $css->add_property( 'width', '100%' ); + } + } + if( !empty( $attributes['stickyFirstRow']) ) { $css->set_selector( '.kb-table-container .kb-table' . esc_attr( $unique_id ) . ' tr:first-child'); $css->add_property( 'position', 'sticky'); diff --git a/src/blocks/table/block.json b/src/blocks/table/block.json index 1e01f6bb3..4b9e5a360 100644 --- a/src/blocks/table/block.json +++ b/src/blocks/table/block.json @@ -10,7 +10,7 @@ "type": "string" }, "columns": { - "type": "string" + "type": "number" }, "dataTypography": { "type": "array", @@ -223,6 +223,14 @@ "isFirstColumnHeader": { "type": "boolean", "default": false + }, + "columnSettings": { + "type": "array", + "default": [] + }, + "useFixedWidths": { + "type": "boolean", + "default": false } }, "providesContext": { diff --git a/src/blocks/table/components/backend-styles/index.js b/src/blocks/table/components/backend-styles/index.js index 525268458..5ce2a67b2 100644 --- a/src/blocks/table/components/backend-styles/index.js +++ b/src/blocks/table/components/backend-styles/index.js @@ -43,41 +43,12 @@ export default function BackendStyles(props) { headerAlign, headerAlignTablet, headerAlignMobile, + useFixedWidths, + columnSettings, } = attributes; const css = new KadenceBlocksCSS(); - // const previewMarginTop = getPreviewSize( - // previewDevice, - // undefined !== margin ? margin[0] : '', - // undefined !== tabletMargin ? tabletMargin[0] : '', - // undefined !== mobileMargin ? mobileMargin[0] : '' - // ); - // const previewMarginRight = getPreviewSize( - // previewDevice, - // undefined !== margin ? margin[1] : '', - // undefined !== tabletMargin ? tabletMargin[1] : '', - // undefined !== mobileMargin ? mobileMargin[1] : '' - // ); - // const previewMarginBottom = getPreviewSize( - // previewDevice, - // undefined !== margin ? margin[2] : '', - // undefined !== tabletMargin ? tabletMargin[2] : '', - // undefined !== mobileMargin ? mobileMargin[2] : '' - // ); - // const previewMarginLeft = getPreviewSize( - // previewDevice, - // undefined !== margin ? margin[3] : '', - // undefined !== tabletMargin ? tabletMargin[3] : '', - // undefined !== mobileMargin ? mobileMargin[3] : '' - // ); - // - // const previewWidth = getPreviewSize( - // previewDevice, - // undefined !== width?.[0] ? width[0] : '', - // undefined !== width?.[1] ? width[1] : '', - // undefined !== width?.[2] ? width[2] : '' - // ); - + // Get preview sizes const previewHeaderAlign = getPreviewSize(previewDevice, headerAlign, headerAlignTablet, headerAlignMobile); const previewTextAlign = getPreviewSize(previewDevice, textAlign, textAlignTablet, textAlignMobile); const previewMaxHeight = getPreviewSize(previewDevice, maxHeight?.[0], maxHeight?.[1], maxHeight?.[2]); @@ -97,6 +68,26 @@ export default function BackendStyles(props) { css.add_property('overflow-x', 'auto'); } + // Add column width styles + if (useFixedWidths && Array.isArray(columnSettings)) { + let hasFixedColumns = false; + + columnSettings.forEach((settings, index) => { + if (settings?.useFixed && settings?.width) { + hasFixedColumns = true; + css.set_selector(`.kb-table${uniqueID} td:nth-child(${index + 1}), .kb-table${uniqueID} th:nth-child(${index + 1})`); + css.add_property('width', `${settings.width}${settings.unit}`); + } + }); + + // Only apply fixed layout if we have any fixed columns + if (hasFixedColumns) { + css.set_selector(`.kb-table${uniqueID}`); + css.add_property('table-layout', 'fixed'); + css.add_property('width', '100%'); + } + } + css.set_selector(`.kb-table${uniqueID} th`); css.render_font(headerTypography ? headerTypography : [], previewDevice); css.add_property('text-align', previewHeaderAlign); @@ -193,9 +184,6 @@ export default function BackendStyles(props) { css.add_property('left', '0'); } - // css.set_selector(`.kb-table-container${uniqueID}`); - // css.add_property('position', 'sticky'); - const cssOutput = css.css_output(); return ; diff --git a/src/blocks/table/edit.js b/src/blocks/table/edit.js index 501c182d4..9f01a73c6 100644 --- a/src/blocks/table/edit.js +++ b/src/blocks/table/edit.js @@ -18,6 +18,7 @@ import { ButtonGroup, Notice, __experimentalNumberControl as NumberControl, + ResizableBox, } from '@wordpress/components'; import { @@ -48,6 +49,9 @@ import { } from '@kadence/helpers'; import BackendStyles from './components/backend-styles'; +const DEFAULT_PERCENT_WIDTH = 30; +const DEFAULT_PIXEL_WIDTH = 150; + export function Edit(props) { const { attributes, setAttributes, className, clientId } = props; @@ -113,8 +117,9 @@ export function Edit(props) { const { replaceInnerBlocks } = useDispatch('core/block-editor'); const [activeTab, setActiveTab] = useState('general'); - const [placeholderRows, setPlaceholderRows] = useState(2); + const [placeholderRows, setPlaceholderRows] = useState(4); const [placeholderColumns, setPlaceholderColumns] = useState(2); + const [isResizing, setIsResizing] = useState(false); const nonTransAttrs = []; @@ -183,20 +188,11 @@ export function Edit(props) { return createBlock('kadence/table-row', {}); }; - const handleInsertRowAbove = (index) => { - const { insertBlock } = dispatch('core/block-editor'); - const newRow = createTableRow(); - const blocks = select('core/block-editor').getBlocks(clientId); - insertBlock(newRow, index, clientId, false); - setAttributes({ rows: rows + 1 }); - }; - const handleInsertRowBelow = (index) => { const { insertBlock } = dispatch('core/block-editor'); const newRow = createTableRow(); const blocks = select('core/block-editor').getBlocks(clientId); insertBlock(newRow, index + 1, clientId, false); - setAttributes({ rows: rows + 1 }); }; const handleDeleteLastRow = () => { @@ -208,46 +204,57 @@ export function Edit(props) { } }; - const handleInsertColumnLeft = (index) => { - const { replaceBlock } = dispatch('core/block-editor'); - const blocks = select('core/block-editor').getBlocks(clientId); + const createTable = () => { + setAttributes({ + columns: parseInt(placeholderColumns), + }); + updateRowsColumns(placeholderRows); + }; - blocks.forEach((row) => { - const newCells = [...row.innerBlocks]; - const newCell = createBlock('kadence/table-data', {}); - newCells.splice(index, 0, newCell); + const getColumnDefaults = () => ({ + useFixed: false, + width: DEFAULT_PERCENT_WIDTH, + unit: '%', + }); - const newRow = createBlock('kadence/table-row', { ...row.attributes, columns: columns + 1 }, newCells); + const getColumnSetting = (index) => { + const settings = attributes.columnSettings || []; + return settings[index] || getColumnDefaults(); + }; - replaceBlock(row.clientId, newRow); - }); + const updateColumnSetting = (index, updates) => { + const newSettings = [...(attributes.columnSettings || [])]; + const currentSetting = getColumnSetting(index); + + // Handle unit changes with smart defaults + if (updates.unit && updates.unit !== currentSetting.unit) { + if (updates.unit === '%') { + // Converting from px to % + updates.width = DEFAULT_PERCENT_WIDTH; + } else { + // Converting from % to px + updates.width = DEFAULT_PIXEL_WIDTH; + } + } - setAttributes({ columns: columns + 1 }); - }; + newSettings[index] = { + ...currentSetting, + ...updates, + }; - const createTable = () => { - setAttributes({ - columns: placeholderColumns, - }); - updateRowsColumns(placeholderRows); + setAttributes({ columnSettings: newSettings }); }; const updateRowsColumns = (newRows) => { const blocks = select('core/block-editor').getBlocks(clientId); let newBlocks = [...blocks]; - // Handle rows - if (newRows > rows) { - const additionalRows = Array(newRows - rows) - .fill(null) - .map(() => createTableRow()); - newBlocks = [...newBlocks, ...additionalRows]; - } else if (newRows < rows) { - newBlocks = newBlocks.slice(0, newRows); - } + const additionalRows = Array(newRows) + .fill(null) + .map(() => createTableRow()); + newBlocks = [...newBlocks, ...additionalRows]; replaceInnerBlocks(clientId, newBlocks, false); - setAttributes({ rows: newRows }); }; const saveDataTypography = (value) => { @@ -310,6 +317,89 @@ export function Edit(props) { {activeTab === 'general' && ( <> + + setAttributes({ useFixedWidths: value })} + /> + + {attributes.useFixedWidths && ( +
+ {Array.from({ length: attributes.columns }).map((_, index) => { + const columnSetting = getColumnSetting(index); + return ( +
+

+ {sprintf(__('Column %d', 'kadence-blocks'), index + 1)} +

+ + + updateColumnSetting(index, { useFixed: value }) + } + /> + + {columnSetting.useFixed && ( + <> +
+
+ + updateColumnSetting(index, { width: value }) + } + min={columnSetting.unit === '%' ? 1 : 20} + max={columnSetting.unit === '%' ? 100 : 1000} + step={1} + /> +
+ + updateColumnSetting(index, { unit: value }) + } + style={{ minWidth: '70px' }} + /> +
+ + )} +
+ ); + })} +
+ )} +