From fbe4c83f89e64fcfece7c26dedc41def10105a6a Mon Sep 17 00:00:00 2001 From: "bfintal@gmail.com" <> Date: Fri, 7 Mar 2025 21:08:49 +0800 Subject: [PATCH 01/99] feat: size and spacing steps --- .../advanced-range-control/editor.scss | 25 ++++++ .../advanced-range-control/index.js | 90 ++++++++++++++++++- .../advanced-range-control/range-control.js | 2 + 3 files changed, 115 insertions(+), 2 deletions(-) diff --git a/src/components/advanced-range-control/editor.scss b/src/components/advanced-range-control/editor.scss index cf8dcd26fb..ef56a1ba1d 100644 --- a/src/components/advanced-range-control/editor.scss +++ b/src/components/advanced-range-control/editor.scss @@ -46,4 +46,29 @@ .components-number-control { width: unset; } + + // For displaying marks + .components-range-control__thumb-wrapper { + z-index: 2; + } + .components-range-control__mark { + background: var(--stk-skin-bg-default) !important; + z-index: 1; + transform: translateX(-50%); + width: 3px; + } + .components-range-control__root { + min-height: 35px; + } + .stk-range-control__custom-button { + margin-inline-start: 8px; + top: -1px; + position: relative; + } +} +.stk-range-control--with-marks.stk-range-control--mark-mode .components-range-control__wrapper { + margin-inline-end: 8px; +} +.stk-range-control--with-marks.stk-range-control--mark-mode .components-range-control__wrapper:first-child:last-child { + top: -1px; } diff --git a/src/components/advanced-range-control/index.js b/src/components/advanced-range-control/index.js index 07031eeed9..8638507b3a 100644 --- a/src/components/advanced-range-control/index.js +++ b/src/components/advanced-range-control/index.js @@ -10,6 +10,7 @@ import { useAttributeName, useBlockAttributesContext, useBlockHoverState, + useBlockSetAttributesContext, useDeviceType, } from '~stackable/hooks' @@ -21,7 +22,10 @@ import { isEqual } from 'lodash' /** * WordPress dependencies */ -import { memo } from '@wordpress/element' +import { memo, useState } from '@wordpress/element' +import { Button } from '@wordpress/components' +import { settings } from '@wordpress/icons' +import { dispatch } from '@wordpress/data' const AdvancedRangeControl = props => { const [ value, onChange ] = useControlHandlers( props.attribute, props.responsive, props.hover, props.valueCallback, props.changeCallback ) @@ -30,6 +34,7 @@ const AdvancedRangeControl = props => { const deviceType = useDeviceType() const [ currentHoverState ] = useBlockHoverState() const hasUnits = !! props.units?.length + const setAttributes = useBlockSetAttributesContext() const unitAttrName = useAttributeName( `${ props.attribute }Unit`, props.responsive, props.hover ) const { unitAttribute, @@ -98,12 +103,28 @@ const AdvancedRangeControl = props => { placeholderRender = null } + // Is value at first render the same as a step value? + const isMarkValue = props.marks && true + const [ isMarkMode, setIsMarkMode ] = useState( isMarkValue ) + // If this supports dynamic content, then the value should be saved as a String. // Important, the attribute type for this option should be a string. const _onChange = value => { const onChangeFunc = typeof props.onChange === 'undefined' ? onChange : props.onChange let newValue = props.isDynamic ? value.toString() : value + // Support for steps. For steps, the value is an index, but the actual value is in the marks. + if ( newValue !== '' && isMarkMode && props.marks ) { + // Extract the unit and value. + const markValue = props.marks[ value ]?.value || '0' + const [ _newValue, unit ] = extractNumberAndUnit( markValue ) + newValue = _newValue + + // Update the unit. + dispatch( 'core/block-editor' ).__unstableMarkNextChangeAsNotPersistent() + setAttributes( { [ unitAttrName ]: unit } ) + } + // On reset, allow overriding the value. if ( newValue === '' ) { const overrideValue = props.onOverrideReset?.() @@ -121,6 +142,45 @@ const AdvancedRangeControl = props => { onChange: _onChange, } ) + // Support for steps. Modify the props to make the range control show steps. + if ( props.marks && isMarkMode ) { + // Steps only have 1 increment values + propsToPass.min = 0 + propsToPass.min = 0 + propsToPass.max = props.marks.length - 1 + propsToPass.sliderMax = props.marks.length - 1 + propsToPass.step = 1 + + // Show the marks and labels + propsToPass.marks = props.marks.reduce( ( acc, mark, index ) => { + return [ + { + value: index, + label: undefined, + }, + ...acc, + ] + }, [] ) + propsToPass.renderTooltipContent = value => { + return props.marks[ value ]?.label || '' + } + + // Other necessary props for steps. + propsToPass.withInputField = false + } else { + propsToPass.marks = undefined + } + + if ( props.marks ) { + controlProps.className = controlProps.className || '' + controlProps.className += 'stk-range-control--with-marks' + controlProps.className += isMarkMode ? ' stk-range-control--mark-mode' : '' + } + + if ( isMarkMode ) { + controlProps.units = false + } + return ( { onChange={ _onChange } allowReset={ false } placeholderRender={ placeholderRender } - /> + __nextHasNoMarginBottom + > + { props.allowCustom && props.marks && ( + + ) } + { + // Match the last characters that are not numbers. + const matches = value.match( /([\d.]+)(\D*)$/ ) + if ( ! matches ) { + return [ value, '' ] + } + return [ matches[ 1 ], matches[ 2 ] ] +} diff --git a/src/components/advanced-range-control/range-control.js b/src/components/advanced-range-control/range-control.js index 48ecc75fc4..cf137a20e4 100644 --- a/src/components/advanced-range-control/range-control.js +++ b/src/components/advanced-range-control/range-control.js @@ -43,6 +43,7 @@ const StackableRangeControl = memo( props => { isShiftStepEnabled, placeholderRender, defaultValue: _defaultValue, // Don't pass this. + children: _children, // Don't pass this. ...propsToPass } = props @@ -178,6 +179,7 @@ const StackableRangeControl = memo( props => { type="text" /> ) } + { _children } { allowReset && + ) } + { { props.isCorner ? : } { if ( currentHoverState !== 'normal' ) { @@ -412,7 +559,21 @@ const FourRangeControl = memo( props => { return typeof props.placeholderTop === 'undefined' ? propsToPass.placeholder : props.placeholderTop } )() } - /> + __nextHasNoMarginBottom + > + { props.allowCustom && props.marks && ( + + ) } + { { props.isCorner ? : } { if ( currentHoverState !== 'normal' ) { @@ -457,7 +618,21 @@ const FourRangeControl = memo( props => { return typeof props.placeholderRight === 'undefined' ? propsToPass.placeholder : props.placeholderRight } )() } - /> + __nextHasNoMarginBottom + > + { props.allowCustom && props.marks && ( + + ) } + { { props.isCorner ? : } { if ( currentHoverState !== 'normal' ) { @@ -502,7 +677,21 @@ const FourRangeControl = memo( props => { return typeof props.placeholderBottom === 'undefined' ? propsToPass.placeholder : props.placeholderBottom } )() } - /> + __nextHasNoMarginBottom + > + { props.allowCustom && props.marks && ( + + ) } + { { props.isCorner ? : } { if ( currentHoverState !== 'normal' ) { @@ -547,7 +736,21 @@ const FourRangeControl = memo( props => { return typeof props.placeholderLeft === 'undefined' ? propsToPass.placeholder : props.placeholderLeft } )() } - /> + __nextHasNoMarginBottom + > + { props.allowCustom && props.marks && ( + + ) } + Date: Tue, 18 Mar 2025 13:00:36 +0800 Subject: [PATCH 05/99] feat: apply preset controls to fontSize, padding, margin, height --- src/block-components/helpers/size/edit.js | 85 +++++++++++++++++++++++ src/block-components/typography/edit.js | 50 +++++++++++++ 2 files changed, 135 insertions(+) diff --git a/src/block-components/helpers/size/edit.js b/src/block-components/helpers/size/edit.js index 6c555fbb03..9b366e08af 100644 --- a/src/block-components/helpers/size/edit.js +++ b/src/block-components/helpers/size/edit.js @@ -14,6 +14,77 @@ import { useAttributeEditHandlers, useDeviceType } from '~stackable/hooks' */ import { __ } from '@wordpress/i18n' import { getAttributeNameFunc } from '~stackable/util' +import { useSetting } from '@wordpress/block-editor' + +const HEIGHT_PRESET = [ + { + value: '64px', + label: 'XS', + }, + { + value: '128px', + label: 'S', + }, + { + value: '192px', + label: 'M', + }, + { + value: '256px', + label: 'L', + }, + { + value: '384px', + label: 'XL', + }, + { + value: '512px', + label: '2XL', + }, + { + value: '640px', + label: '3XL', + }, + { + value: '100vh', + label: 'Full', + }, +] + +const SPACING_PRESET = [ + { + label: 'XS', + value: '4px', + }, + { + label: 'S', + value: '8px', + }, + { + label: 'M', + value: '16px', + }, + { + label: 'L', + value: '24px', + }, + { + label: 'XL', + value: '32px', + }, + { + label: '2XL', + value: '48px', + }, + { + label: '3XL', + value: '64px', + }, + { + label: '4XL', + value: '96px', + }, +] const Layout = props => { const deviceType = useDeviceType() @@ -30,6 +101,8 @@ const Layout = props => { labelVerticalAlign = __( 'Content Vertical Align', i18n ), } = props.labels + const heightMarks = HEIGHT_PRESET + return ( <> { props.hasMinHeight && { description: __( 'Adjusts the minimum allowable height of the block', i18n ), } } visualGuide={ props.visualGuide } + marks={ heightMarks } /> } { props.hasContentVerticalAlign && @@ -132,6 +206,15 @@ const Spacing = props => { ...props.visualGuide, highlight: 'margin', } + let spacingMarks = SPACING_PRESET + const spacingSizes = useSetting( 'spacing.spacingSizes' ) + + if ( Array.isArray( spacingSizes ) && spacingSizes.length > 0 ) { + spacingMarks = spacingSizes.map( size => ( { + value: size.size, + label: size.name, + } ) ) + } return ( <> @@ -150,6 +233,7 @@ const Spacing = props => { } } visualGuide={ paddingVisualGuide } placeholder={ props.paddingPlaceholder } + marks={ spacingMarks } /> { props.enableMargin && @@ -167,6 +251,7 @@ const Spacing = props => { description: __( 'Sets the block margin, i.e. the space outside the block between the block border and the next block.', i18n ), } } visualGuide={ marginVisualGuide } + marks={ spacingMarks } /> } diff --git a/src/block-components/typography/edit.js b/src/block-components/typography/edit.js index 5a7642bb8b..72cc386d47 100644 --- a/src/block-components/typography/edit.js +++ b/src/block-components/typography/edit.js @@ -30,6 +30,7 @@ import { } from '@wordpress/element' import { __ } from '@wordpress/i18n' import { applyFilters } from '@wordpress/hooks' +import { useSelect } from '@wordpress/data' const TYPOGRAPHY_SHADOWS = [ 'none', @@ -57,6 +58,45 @@ const GRADIENT_OPTIONS = [ }, ] +const SIZE_PRESET = [ + { + value: '0.75rem', + label: 'XS', + }, + { + value: '0.875rem', + label: 'S', + }, + { + value: '1rem', + label: 'M', + }, + { + value: '1.125rem', + label: 'L', + }, + { + value: '1.5rem', + label: 'XL', + }, + { + value: '2rem', + label: '2XL', + }, + { + value: '2.5rem', + label: '3XL', + }, + { + value: '3rem', + label: '4XL', + }, + { + value: '4rem', + label: '5XL', + }, +] + export const Controls = props => { const { hasAlign, @@ -100,6 +140,15 @@ export const Controls = props => { const onChangeContent = useCallback( text => setDebouncedText( escapeHTMLIfInvalid( text ) ), [] ) + const themeSettings = useSelect( select => select( 'core/block-editor' ).getSettings(), [] ) + let sizeMarks = SIZE_PRESET + if ( Array.isArray( themeSettings?.fontSizes ) && themeSettings.fontSizes.length > 0 ) { + sizeMarks = themeSettings.fontSizes.map( size => ( { + value: size.size, + label: size.name, + } ) ) + } + return ( <> { applyFilters( 'stackable.block-component.typography.before', null, props ) } @@ -268,6 +317,7 @@ export const Controls = props => { title: __( 'Font size', i18n ), description: __( 'Sets the size of text characters', i18n ), } } + marks={ sizeMarks } /> { hasColor && ( From d840726e2ce378106a3e374a0813d86b90d7c578 Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Tue, 18 Mar 2025 17:04:53 +0800 Subject: [PATCH 06/99] feat: generate global css for presets --- plugin.php | 1 + .../global-settings/preset-controls/index.php | 95 ++++++++++++++++++ .../preset-controls/presets.json | 97 +++++++++++++++++++ 3 files changed, 193 insertions(+) create mode 100644 src/plugins/global-settings/preset-controls/index.php create mode 100644 src/plugins/global-settings/preset-controls/presets.json diff --git a/plugin.php b/plugin.php index dc46b8a181..51efaed859 100644 --- a/plugin.php +++ b/plugin.php @@ -230,6 +230,7 @@ function is_frontend() { require_once( plugin_dir_path( __FILE__ ) . 'src/dynamic-breakpoints.php' ); require_once( plugin_dir_path( __FILE__ ) . 'src/design-library/init.php' ); require_once( plugin_dir_path( __FILE__ ) . 'src/global-settings.php' ); +require_once( plugin_dir_path( __FILE__ ) . 'src/plugins/global-settings/preset-controls/index.php' ); require_once( plugin_dir_path( __FILE__ ) . 'src/custom-block-styles.php' ); require_once( plugin_dir_path( __FILE__ ) . 'src/css-optimize.php' ); require_once( plugin_dir_path( __FILE__ ) . 'src/compatibility/index.php' ); diff --git a/src/plugins/global-settings/preset-controls/index.php b/src/plugins/global-settings/preset-controls/index.php new file mode 100644 index 0000000000..95bb0515d7 --- /dev/null +++ b/src/plugins/global-settings/preset-controls/index.php @@ -0,0 +1,95 @@ +stackable_presets = $this->load_presets( __DIR__ . '/presets.json'); + $this->theme_presets = $this->load_presets( get_template_directory() . '/theme.json' ); + // Register our settings. + // add_action( 'register_stackable_global_settings', array( $this, 'register_preset_controls' ) ); + + add_filter( 'stackable_inline_styles_nodep', array( $this, 'add_preset_controls_styles' ) ); + } + + /** + * Register the settings we need for preset controls + * + * @return void + */ + // public function register_preset_controls() { + + // } + + public function sanitize_array_setting( $input ) { + return ! is_array( $input ) ? array( array() ) : $input; + } + + private function load_presets( $json_path ) { + if ( file_exists( $json_path ) ) { + $json_data = file_get_contents( $json_path ); + $decoded_data = json_decode( $json_data, true ); + return $decoded_data[ 'settings' ] ?? []; + } + return []; + } + + // Generate CSS variables based on preset type (e.g., fontSizes, spacing) + public function generate_css_variables( $presets, $prefix ) { + $css = ""; + foreach ( $presets as $preset ) { + $slug = $preset[ 'slug' ]; + $size = $preset[ 'size' ]; + $css .= "--stk--preset--$prefix--$slug: $size;\n"; + } + + return $css; + } + + /** + * Add our global preset control styles. + * + * @param String $current_css + * @return String + */ + public function add_preset_controls_styles( $current_css ) { + $presets = $this->stackable_presets; + + if ( isset ( $this->theme_presets ) ) { + $presets = $this->theme_presets; + } + + $generated_css = ":root {\n"; + $generated_css .= $this->generate_css_variables( $presets[ 'spacing' ][ 'spacingSizes' ], 'spacing' ); + $generated_css .= $this->generate_css_variables( $presets[ 'typography' ][ 'fontSizes' ], 'font-size' ); + $generated_css .= "}\n"; + + if ( ! $generated_css ) { + return $current_css; + } + + $current_css .= $generated_css; + return apply_filters( 'stackable_frontend_css' , $current_css ); + } + } + + new Stackable_Size_And_Spacing_Preset_Controls(); +} \ No newline at end of file diff --git a/src/plugins/global-settings/preset-controls/presets.json b/src/plugins/global-settings/preset-controls/presets.json new file mode 100644 index 0000000000..2d5a3b737a --- /dev/null +++ b/src/plugins/global-settings/preset-controls/presets.json @@ -0,0 +1,97 @@ +{ + "settings": { + "spacing": { + "spacingSizes": [ + { + "label": "XS", + "size": "0.25rem", + "slug": "x-small" + }, + { + "label": "S", + "size": "0.5rem", + "slug": "small" + }, + { + "label": "M", + "size": "1rem", + "slug": "medium" + }, + { + "label": "L", + "size": "1.5rem", + "slug": "large" + }, + { + "label": "XL", + "size": "2rem", + "slug": "x-large" + }, + { + "label": "2XL", + "size": "3rem", + "slug": "xx-large" + }, + { + "label": "3XL", + "size": "4rem", + "slug": "xxx-large" + }, + { + "label": "4XL", + "size": "6rem", + "slug": "xxxx-large" + } + ] + }, + "typography": { + "fontSizes": [ + { + "label": "XS", + "size": "0.75rem", + "slug": "x-small" + }, + { + "label": "S", + "size": "0.875rem", + "slug": "small" + }, + { + "label": "M", + "size": "1rem", + "slug": "medium" + }, + { + "label": "L", + "size": "1.125rem", + "slug": "large" + }, + { + "label": "XL", + "size": "1.5rem", + "slug": "x-large" + }, + { + "label": "2XL", + "size": "2rem", + "slug": "xx-large" + }, + { + "label": "3XL", + "size": "2.5rem", + "slug": "xxx-large" + }, + { + "label": "4XL", + "size": "3rem", + "slug": "xxxx-large" + }, + { + "label": "5XL", + "size": "4rem", + "slug": "xxxxx-large" + } + ] + } + } +} From 6169719b8ea3332318d2765425556000deabbb5a Mon Sep 17 00:00:00 2001 From: "bfintal@gmail.com" <> Date: Fri, 7 Mar 2025 21:08:49 +0800 Subject: [PATCH 07/99] feat: size and spacing steps --- .../advanced-range-control/editor.scss | 25 ++++++ .../advanced-range-control/index.js | 90 ++++++++++++++++++- .../advanced-range-control/range-control.js | 2 + 3 files changed, 115 insertions(+), 2 deletions(-) diff --git a/src/components/advanced-range-control/editor.scss b/src/components/advanced-range-control/editor.scss index cf8dcd26fb..ef56a1ba1d 100644 --- a/src/components/advanced-range-control/editor.scss +++ b/src/components/advanced-range-control/editor.scss @@ -46,4 +46,29 @@ .components-number-control { width: unset; } + + // For displaying marks + .components-range-control__thumb-wrapper { + z-index: 2; + } + .components-range-control__mark { + background: var(--stk-skin-bg-default) !important; + z-index: 1; + transform: translateX(-50%); + width: 3px; + } + .components-range-control__root { + min-height: 35px; + } + .stk-range-control__custom-button { + margin-inline-start: 8px; + top: -1px; + position: relative; + } +} +.stk-range-control--with-marks.stk-range-control--mark-mode .components-range-control__wrapper { + margin-inline-end: 8px; +} +.stk-range-control--with-marks.stk-range-control--mark-mode .components-range-control__wrapper:first-child:last-child { + top: -1px; } diff --git a/src/components/advanced-range-control/index.js b/src/components/advanced-range-control/index.js index 07031eeed9..8638507b3a 100644 --- a/src/components/advanced-range-control/index.js +++ b/src/components/advanced-range-control/index.js @@ -10,6 +10,7 @@ import { useAttributeName, useBlockAttributesContext, useBlockHoverState, + useBlockSetAttributesContext, useDeviceType, } from '~stackable/hooks' @@ -21,7 +22,10 @@ import { isEqual } from 'lodash' /** * WordPress dependencies */ -import { memo } from '@wordpress/element' +import { memo, useState } from '@wordpress/element' +import { Button } from '@wordpress/components' +import { settings } from '@wordpress/icons' +import { dispatch } from '@wordpress/data' const AdvancedRangeControl = props => { const [ value, onChange ] = useControlHandlers( props.attribute, props.responsive, props.hover, props.valueCallback, props.changeCallback ) @@ -30,6 +34,7 @@ const AdvancedRangeControl = props => { const deviceType = useDeviceType() const [ currentHoverState ] = useBlockHoverState() const hasUnits = !! props.units?.length + const setAttributes = useBlockSetAttributesContext() const unitAttrName = useAttributeName( `${ props.attribute }Unit`, props.responsive, props.hover ) const { unitAttribute, @@ -98,12 +103,28 @@ const AdvancedRangeControl = props => { placeholderRender = null } + // Is value at first render the same as a step value? + const isMarkValue = props.marks && true + const [ isMarkMode, setIsMarkMode ] = useState( isMarkValue ) + // If this supports dynamic content, then the value should be saved as a String. // Important, the attribute type for this option should be a string. const _onChange = value => { const onChangeFunc = typeof props.onChange === 'undefined' ? onChange : props.onChange let newValue = props.isDynamic ? value.toString() : value + // Support for steps. For steps, the value is an index, but the actual value is in the marks. + if ( newValue !== '' && isMarkMode && props.marks ) { + // Extract the unit and value. + const markValue = props.marks[ value ]?.value || '0' + const [ _newValue, unit ] = extractNumberAndUnit( markValue ) + newValue = _newValue + + // Update the unit. + dispatch( 'core/block-editor' ).__unstableMarkNextChangeAsNotPersistent() + setAttributes( { [ unitAttrName ]: unit } ) + } + // On reset, allow overriding the value. if ( newValue === '' ) { const overrideValue = props.onOverrideReset?.() @@ -121,6 +142,45 @@ const AdvancedRangeControl = props => { onChange: _onChange, } ) + // Support for steps. Modify the props to make the range control show steps. + if ( props.marks && isMarkMode ) { + // Steps only have 1 increment values + propsToPass.min = 0 + propsToPass.min = 0 + propsToPass.max = props.marks.length - 1 + propsToPass.sliderMax = props.marks.length - 1 + propsToPass.step = 1 + + // Show the marks and labels + propsToPass.marks = props.marks.reduce( ( acc, mark, index ) => { + return [ + { + value: index, + label: undefined, + }, + ...acc, + ] + }, [] ) + propsToPass.renderTooltipContent = value => { + return props.marks[ value ]?.label || '' + } + + // Other necessary props for steps. + propsToPass.withInputField = false + } else { + propsToPass.marks = undefined + } + + if ( props.marks ) { + controlProps.className = controlProps.className || '' + controlProps.className += 'stk-range-control--with-marks' + controlProps.className += isMarkMode ? ' stk-range-control--mark-mode' : '' + } + + if ( isMarkMode ) { + controlProps.units = false + } + return ( { onChange={ _onChange } allowReset={ false } placeholderRender={ placeholderRender } - /> + __nextHasNoMarginBottom + > + { props.allowCustom && props.marks && ( + + ) } + { + // Match the last characters that are not numbers. + const matches = value.match( /([\d.]+)(\D*)$/ ) + if ( ! matches ) { + return [ value, '' ] + } + return [ matches[ 1 ], matches[ 2 ] ] +} diff --git a/src/components/advanced-range-control/range-control.js b/src/components/advanced-range-control/range-control.js index 48ecc75fc4..cf137a20e4 100644 --- a/src/components/advanced-range-control/range-control.js +++ b/src/components/advanced-range-control/range-control.js @@ -43,6 +43,7 @@ const StackableRangeControl = memo( props => { isShiftStepEnabled, placeholderRender, defaultValue: _defaultValue, // Don't pass this. + children: _children, // Don't pass this. ...propsToPass } = props @@ -178,6 +179,7 @@ const StackableRangeControl = memo( props => { type="text" /> ) } + { _children } { allowReset && + ) } + { { props.isCorner ? : } { if ( currentHoverState !== 'normal' ) { @@ -414,7 +561,21 @@ const FourRangeControl = memo( props => { return typeof props.placeholderTop === 'undefined' ? propsToPass.placeholder : props.placeholderTop } )() } - /> + __nextHasNoMarginBottom + > + { props.allowCustom && props.marks && ( + + ) } + { { props.isCorner ? : } { if ( currentHoverState !== 'normal' ) { @@ -459,7 +620,21 @@ const FourRangeControl = memo( props => { return typeof props.placeholderRight === 'undefined' ? propsToPass.placeholder : props.placeholderRight } )() } - /> + __nextHasNoMarginBottom + > + { props.allowCustom && props.marks && ( + + ) } + { { props.isCorner ? : } { if ( currentHoverState !== 'normal' ) { @@ -504,7 +679,21 @@ const FourRangeControl = memo( props => { return typeof props.placeholderBottom === 'undefined' ? propsToPass.placeholder : props.placeholderBottom } )() } - /> + __nextHasNoMarginBottom + > + { props.allowCustom && props.marks && ( + + ) } + { { props.isCorner ? : } { if ( currentHoverState !== 'normal' ) { @@ -549,7 +738,21 @@ const FourRangeControl = memo( props => { return typeof props.placeholderLeft === 'undefined' ? propsToPass.placeholder : props.placeholderLeft } )() } - /> + __nextHasNoMarginBottom + > + { props.allowCustom && props.marks && ( + + ) } + Date: Tue, 18 Mar 2025 13:00:36 +0800 Subject: [PATCH 11/99] feat: apply preset controls to fontSize, padding, margin, height --- src/block-components/helpers/size/edit.js | 85 +++++++++++++++++++++++ src/block-components/typography/edit.js | 50 +++++++++++++ 2 files changed, 135 insertions(+) diff --git a/src/block-components/helpers/size/edit.js b/src/block-components/helpers/size/edit.js index 6c555fbb03..9b366e08af 100644 --- a/src/block-components/helpers/size/edit.js +++ b/src/block-components/helpers/size/edit.js @@ -14,6 +14,77 @@ import { useAttributeEditHandlers, useDeviceType } from '~stackable/hooks' */ import { __ } from '@wordpress/i18n' import { getAttributeNameFunc } from '~stackable/util' +import { useSetting } from '@wordpress/block-editor' + +const HEIGHT_PRESET = [ + { + value: '64px', + label: 'XS', + }, + { + value: '128px', + label: 'S', + }, + { + value: '192px', + label: 'M', + }, + { + value: '256px', + label: 'L', + }, + { + value: '384px', + label: 'XL', + }, + { + value: '512px', + label: '2XL', + }, + { + value: '640px', + label: '3XL', + }, + { + value: '100vh', + label: 'Full', + }, +] + +const SPACING_PRESET = [ + { + label: 'XS', + value: '4px', + }, + { + label: 'S', + value: '8px', + }, + { + label: 'M', + value: '16px', + }, + { + label: 'L', + value: '24px', + }, + { + label: 'XL', + value: '32px', + }, + { + label: '2XL', + value: '48px', + }, + { + label: '3XL', + value: '64px', + }, + { + label: '4XL', + value: '96px', + }, +] const Layout = props => { const deviceType = useDeviceType() @@ -30,6 +101,8 @@ const Layout = props => { labelVerticalAlign = __( 'Content Vertical Align', i18n ), } = props.labels + const heightMarks = HEIGHT_PRESET + return ( <> { props.hasMinHeight && { description: __( 'Adjusts the minimum allowable height of the block', i18n ), } } visualGuide={ props.visualGuide } + marks={ heightMarks } /> } { props.hasContentVerticalAlign && @@ -132,6 +206,15 @@ const Spacing = props => { ...props.visualGuide, highlight: 'margin', } + let spacingMarks = SPACING_PRESET + const spacingSizes = useSetting( 'spacing.spacingSizes' ) + + if ( Array.isArray( spacingSizes ) && spacingSizes.length > 0 ) { + spacingMarks = spacingSizes.map( size => ( { + value: size.size, + label: size.name, + } ) ) + } return ( <> @@ -150,6 +233,7 @@ const Spacing = props => { } } visualGuide={ paddingVisualGuide } placeholder={ props.paddingPlaceholder } + marks={ spacingMarks } /> { props.enableMargin && @@ -167,6 +251,7 @@ const Spacing = props => { description: __( 'Sets the block margin, i.e. the space outside the block between the block border and the next block.', i18n ), } } visualGuide={ marginVisualGuide } + marks={ spacingMarks } /> } diff --git a/src/block-components/typography/edit.js b/src/block-components/typography/edit.js index 9c10a370bd..484b89ee99 100644 --- a/src/block-components/typography/edit.js +++ b/src/block-components/typography/edit.js @@ -30,6 +30,7 @@ import { } from '@wordpress/element' import { __ } from '@wordpress/i18n' import { applyFilters } from '@wordpress/hooks' +import { useSelect } from '@wordpress/data' const TYPOGRAPHY_SHADOWS = [ 'none', @@ -57,6 +58,45 @@ const GRADIENT_OPTIONS = [ }, ] +const SIZE_PRESET = [ + { + value: '0.75rem', + label: 'XS', + }, + { + value: '0.875rem', + label: 'S', + }, + { + value: '1rem', + label: 'M', + }, + { + value: '1.125rem', + label: 'L', + }, + { + value: '1.5rem', + label: 'XL', + }, + { + value: '2rem', + label: '2XL', + }, + { + value: '2.5rem', + label: '3XL', + }, + { + value: '3rem', + label: '4XL', + }, + { + value: '4rem', + label: '5XL', + }, +] + export const Controls = props => { const { hasAlign, @@ -100,6 +140,15 @@ export const Controls = props => { const onChangeContent = useCallback( text => setDebouncedText( escapeHTMLIfInvalid( text ) ), [] ) + const themeSettings = useSelect( select => select( 'core/block-editor' ).getSettings(), [] ) + let sizeMarks = SIZE_PRESET + if ( Array.isArray( themeSettings?.fontSizes ) && themeSettings.fontSizes.length > 0 ) { + sizeMarks = themeSettings.fontSizes.map( size => ( { + value: size.size, + label: size.name, + } ) ) + } + return ( <> { applyFilters( 'stackable.block-component.typography.before', null, props ) } @@ -269,6 +318,7 @@ export const Controls = props => { title: __( 'Font size', i18n ), description: __( 'Sets the size of text characters', i18n ), } } + marks={ sizeMarks } /> { hasColor && ( From 74eedd5157e6f7129b1bb23fae7b0a95d368cb13 Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Tue, 18 Mar 2025 17:04:53 +0800 Subject: [PATCH 12/99] feat: generate global css for presets --- plugin.php | 1 + .../global-settings/preset-controls/index.php | 95 ++++++++++++++++++ .../preset-controls/presets.json | 97 +++++++++++++++++++ 3 files changed, 193 insertions(+) create mode 100644 src/plugins/global-settings/preset-controls/index.php create mode 100644 src/plugins/global-settings/preset-controls/presets.json diff --git a/plugin.php b/plugin.php index a98a074b94..003614c40f 100644 --- a/plugin.php +++ b/plugin.php @@ -233,6 +233,7 @@ function is_frontend() { require_once( plugin_dir_path( __FILE__ ) . 'src/global-settings.php' ); require_once( plugin_dir_path( __FILE__ ) . 'src/plugins/global-settings/spacing-and-borders/index.php' ); require_once( plugin_dir_path( __FILE__ ) . 'src/plugins/global-settings/buttons-and-icons/index.php' ); +require_once( plugin_dir_path( __FILE__ ) . 'src/plugins/global-settings/preset-controls/index.php' ); require_once( plugin_dir_path( __FILE__ ) . 'src/custom-block-styles.php' ); require_once( plugin_dir_path( __FILE__ ) . 'src/css-optimize.php' ); require_once( plugin_dir_path( __FILE__ ) . 'src/compatibility/index.php' ); diff --git a/src/plugins/global-settings/preset-controls/index.php b/src/plugins/global-settings/preset-controls/index.php new file mode 100644 index 0000000000..95bb0515d7 --- /dev/null +++ b/src/plugins/global-settings/preset-controls/index.php @@ -0,0 +1,95 @@ +stackable_presets = $this->load_presets( __DIR__ . '/presets.json'); + $this->theme_presets = $this->load_presets( get_template_directory() . '/theme.json' ); + // Register our settings. + // add_action( 'register_stackable_global_settings', array( $this, 'register_preset_controls' ) ); + + add_filter( 'stackable_inline_styles_nodep', array( $this, 'add_preset_controls_styles' ) ); + } + + /** + * Register the settings we need for preset controls + * + * @return void + */ + // public function register_preset_controls() { + + // } + + public function sanitize_array_setting( $input ) { + return ! is_array( $input ) ? array( array() ) : $input; + } + + private function load_presets( $json_path ) { + if ( file_exists( $json_path ) ) { + $json_data = file_get_contents( $json_path ); + $decoded_data = json_decode( $json_data, true ); + return $decoded_data[ 'settings' ] ?? []; + } + return []; + } + + // Generate CSS variables based on preset type (e.g., fontSizes, spacing) + public function generate_css_variables( $presets, $prefix ) { + $css = ""; + foreach ( $presets as $preset ) { + $slug = $preset[ 'slug' ]; + $size = $preset[ 'size' ]; + $css .= "--stk--preset--$prefix--$slug: $size;\n"; + } + + return $css; + } + + /** + * Add our global preset control styles. + * + * @param String $current_css + * @return String + */ + public function add_preset_controls_styles( $current_css ) { + $presets = $this->stackable_presets; + + if ( isset ( $this->theme_presets ) ) { + $presets = $this->theme_presets; + } + + $generated_css = ":root {\n"; + $generated_css .= $this->generate_css_variables( $presets[ 'spacing' ][ 'spacingSizes' ], 'spacing' ); + $generated_css .= $this->generate_css_variables( $presets[ 'typography' ][ 'fontSizes' ], 'font-size' ); + $generated_css .= "}\n"; + + if ( ! $generated_css ) { + return $current_css; + } + + $current_css .= $generated_css; + return apply_filters( 'stackable_frontend_css' , $current_css ); + } + } + + new Stackable_Size_And_Spacing_Preset_Controls(); +} \ No newline at end of file diff --git a/src/plugins/global-settings/preset-controls/presets.json b/src/plugins/global-settings/preset-controls/presets.json new file mode 100644 index 0000000000..2d5a3b737a --- /dev/null +++ b/src/plugins/global-settings/preset-controls/presets.json @@ -0,0 +1,97 @@ +{ + "settings": { + "spacing": { + "spacingSizes": [ + { + "label": "XS", + "size": "0.25rem", + "slug": "x-small" + }, + { + "label": "S", + "size": "0.5rem", + "slug": "small" + }, + { + "label": "M", + "size": "1rem", + "slug": "medium" + }, + { + "label": "L", + "size": "1.5rem", + "slug": "large" + }, + { + "label": "XL", + "size": "2rem", + "slug": "x-large" + }, + { + "label": "2XL", + "size": "3rem", + "slug": "xx-large" + }, + { + "label": "3XL", + "size": "4rem", + "slug": "xxx-large" + }, + { + "label": "4XL", + "size": "6rem", + "slug": "xxxx-large" + } + ] + }, + "typography": { + "fontSizes": [ + { + "label": "XS", + "size": "0.75rem", + "slug": "x-small" + }, + { + "label": "S", + "size": "0.875rem", + "slug": "small" + }, + { + "label": "M", + "size": "1rem", + "slug": "medium" + }, + { + "label": "L", + "size": "1.125rem", + "slug": "large" + }, + { + "label": "XL", + "size": "1.5rem", + "slug": "x-large" + }, + { + "label": "2XL", + "size": "2rem", + "slug": "xx-large" + }, + { + "label": "3XL", + "size": "2.5rem", + "slug": "xxx-large" + }, + { + "label": "4XL", + "size": "3rem", + "slug": "xxxx-large" + }, + { + "label": "5XL", + "size": "4rem", + "slug": "xxxxx-large" + } + ] + } + } +} From 9c366009ada045dd4da39c5f8bed35f34f873b4e Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Thu, 20 Mar 2025 10:10:34 +0800 Subject: [PATCH 13/99] fix: apply generated css --- src/block-components/helpers/size/edit.js | 53 +++---------------- src/block-components/typography/edit.js | 53 ++----------------- .../advanced-range-control/index.js | 2 +- src/components/block-css/index.js | 6 ++- src/components/four-range-control/index.js | 2 +- src/hooks/index.js | 1 + src/hooks/use-preset-controls.js | 23 ++++++++ .../global-settings/preset-controls/index.php | 11 ++-- .../preset-controls/presets.json | 34 ++++++------ src/util/styles/style-object.js | 6 ++- 10 files changed, 67 insertions(+), 124 deletions(-) create mode 100644 src/hooks/use-preset-controls.js diff --git a/src/block-components/helpers/size/edit.js b/src/block-components/helpers/size/edit.js index 9b366e08af..0c5e727718 100644 --- a/src/block-components/helpers/size/edit.js +++ b/src/block-components/helpers/size/edit.js @@ -7,14 +7,15 @@ import { AdvancedRangeControl, FourRangeControl, } from '~stackable/components' -import { useAttributeEditHandlers, useDeviceType } from '~stackable/hooks' +import { + useAttributeEditHandlers, useDeviceType, usePresetControls, +} from '~stackable/hooks' /** * WordPress dependencies */ import { __ } from '@wordpress/i18n' import { getAttributeNameFunc } from '~stackable/util' -import { useSetting } from '@wordpress/block-editor' const HEIGHT_PRESET = [ { @@ -51,41 +52,6 @@ const HEIGHT_PRESET = [ }, ] -const SPACING_PRESET = [ - { - label: 'XS', - value: '4px', - }, - { - label: 'S', - value: '8px', - }, - { - label: 'M', - value: '16px', - }, - { - label: 'L', - value: '24px', - }, - { - label: 'XL', - value: '32px', - }, - { - label: '2XL', - value: '48px', - }, - { - label: '3XL', - value: '64px', - }, - { - label: '4XL', - value: '96px', - }, -] - const Layout = props => { const deviceType = useDeviceType() @@ -206,15 +172,8 @@ const Spacing = props => { ...props.visualGuide, highlight: 'margin', } - let spacingMarks = SPACING_PRESET - const spacingSizes = useSetting( 'spacing.spacingSizes' ) - if ( Array.isArray( spacingSizes ) && spacingSizes.length > 0 ) { - spacingMarks = spacingSizes.map( size => ( { - value: size.size, - label: size.name, - } ) ) - } + const presetMarks = usePresetControls( [ 'spacing', 'spacingSizes' ] ) return ( <> @@ -233,7 +192,7 @@ const Spacing = props => { } } visualGuide={ paddingVisualGuide } placeholder={ props.paddingPlaceholder } - marks={ spacingMarks } + marks={ presetMarks } /> { props.enableMargin && @@ -251,7 +210,7 @@ const Spacing = props => { description: __( 'Sets the block margin, i.e. the space outside the block between the block border and the next block.', i18n ), } } visualGuide={ marginVisualGuide } - marks={ spacingMarks } + marks={ presetMarks } /> } diff --git a/src/block-components/typography/edit.js b/src/block-components/typography/edit.js index 484b89ee99..131b077b63 100644 --- a/src/block-components/typography/edit.js +++ b/src/block-components/typography/edit.js @@ -3,7 +3,7 @@ */ import { unescape } from 'lodash' import { i18n } from 'stackable' -import { useAttributeEditHandlers } from '~stackable/hooks' +import { useAttributeEditHandlers, usePresetControls } from '~stackable/hooks' import { AlignButtonsControl, AdvancedRangeControl, @@ -30,7 +30,6 @@ import { } from '@wordpress/element' import { __ } from '@wordpress/i18n' import { applyFilters } from '@wordpress/hooks' -import { useSelect } from '@wordpress/data' const TYPOGRAPHY_SHADOWS = [ 'none', @@ -58,45 +57,6 @@ const GRADIENT_OPTIONS = [ }, ] -const SIZE_PRESET = [ - { - value: '0.75rem', - label: 'XS', - }, - { - value: '0.875rem', - label: 'S', - }, - { - value: '1rem', - label: 'M', - }, - { - value: '1.125rem', - label: 'L', - }, - { - value: '1.5rem', - label: 'XL', - }, - { - value: '2rem', - label: '2XL', - }, - { - value: '2.5rem', - label: '3XL', - }, - { - value: '3rem', - label: '4XL', - }, - { - value: '4rem', - label: '5XL', - }, -] - export const Controls = props => { const { hasAlign, @@ -140,14 +100,7 @@ export const Controls = props => { const onChangeContent = useCallback( text => setDebouncedText( escapeHTMLIfInvalid( text ) ), [] ) - const themeSettings = useSelect( select => select( 'core/block-editor' ).getSettings(), [] ) - let sizeMarks = SIZE_PRESET - if ( Array.isArray( themeSettings?.fontSizes ) && themeSettings.fontSizes.length > 0 ) { - sizeMarks = themeSettings.fontSizes.map( size => ( { - value: size.size, - label: size.name, - } ) ) - } + const presetMarks = usePresetControls( [ 'typography', 'fontSizes' ] ) return ( <> @@ -318,7 +271,7 @@ export const Controls = props => { title: __( 'Font size', i18n ), description: __( 'Sets the size of text characters', i18n ), } } - marks={ sizeMarks } + marks={ presetMarks } /> { hasColor && ( diff --git a/src/components/advanced-range-control/index.js b/src/components/advanced-range-control/index.js index aea49a695e..8a9b990dab 100644 --- a/src/components/advanced-range-control/index.js +++ b/src/components/advanced-range-control/index.js @@ -259,7 +259,7 @@ export default memo( AdvancedRangeControl, isEqual ) const extractNumberAndUnit = value => { // Match the last characters that are not numbers. const matches = value.match( /([\d.]+)(\D*)$/ ) - if ( ! matches ) { + if ( ! matches || value.startsWith( 'var(--stk' ) ) { return [ value, '' ] } return [ matches[ 1 ], matches[ 2 ] ] diff --git a/src/components/block-css/index.js b/src/components/block-css/index.js index 53d6b4be46..232b687cef 100644 --- a/src/components/block-css/index.js +++ b/src/components/block-css/index.js @@ -182,8 +182,10 @@ const BlockCss = props => { } if ( unit ) { // Note: this will only work for non-objects. - // If the value is `auto`, don't add units. - value = value === 'auto' ? value : `${ value }${ unit }` + // If the value is `auto` or a CSS variable, don't add units. + if ( ! ( value === 'auto' || ( typeof value === 'string' && value.startsWith( 'var(--stk' ) ) ) ) { + value = `${ value }${ unit }` + } } if ( format !== '%s' && format !== '' ) { value = sprintf( diff --git a/src/components/four-range-control/index.js b/src/components/four-range-control/index.js index 97ba67113a..ffd1ed4e01 100644 --- a/src/components/four-range-control/index.js +++ b/src/components/four-range-control/index.js @@ -59,7 +59,7 @@ const isEqualInitial = ( props, value, firstValue ) => { const extractNumberAndUnit = value => { // Match the last characters that are not numbers. const matches = value.match( /([\d.]+)(\D*)$/ ) - if ( ! matches ) { + if ( ! matches || value.startsWith( 'var(--stk' ) ) { return [ value, '' ] } return [ matches[ 1 ], matches[ 2 ] ] diff --git a/src/hooks/index.js b/src/hooks/index.js index c81e9991ed..25eb202a20 100644 --- a/src/hooks/index.js +++ b/src/hooks/index.js @@ -19,3 +19,4 @@ export * from './use-raf-state' export * from './use-raf-memo' export * from './use-raf-effect' export * from './use-global-block-layout-defaults' +export * from './use-preset-controls' diff --git a/src/hooks/use-preset-controls.js b/src/hooks/use-preset-controls.js new file mode 100644 index 0000000000..2c46c467d0 --- /dev/null +++ b/src/hooks/use-preset-controls.js @@ -0,0 +1,23 @@ +import { useSettings } from '@wordpress/block-editor' +import DEFAULT_PRESETS from '~stackable/plugins/global-settings/preset-controls/presets.json' + +const PRESET_PREFIX = { + 'spacing.spacingSizes': 'spacing-size', + 'typography.fontSizes': 'font-size', +} + +export const usePresetControls = properties => { + const property = properties.join( '.' ) + const [ themePreset ] = useSettings( property ) + + const presets = Array.isArray( themePreset ) && themePreset.length > 0 + ? themePreset + : properties.reduce( ( acc, key ) => acc?.[ key ], DEFAULT_PRESETS.settings ) + + const prefix = PRESET_PREFIX[ property ] + + return presets.map( preset => ( { + label: preset.name, + value: `var(--stk--preset--${ prefix }--${ preset.slug }, ${ preset.size })`, + } ) ) +} diff --git a/src/plugins/global-settings/preset-controls/index.php b/src/plugins/global-settings/preset-controls/index.php index 95bb0515d7..a2c71376e9 100644 --- a/src/plugins/global-settings/preset-controls/index.php +++ b/src/plugins/global-settings/preset-controls/index.php @@ -23,11 +23,12 @@ class Stackable_Size_And_Spacing_Preset_Controls { */ function __construct() { $this->stackable_presets = $this->load_presets( __DIR__ . '/presets.json'); - $this->theme_presets = $this->load_presets( get_template_directory() . '/theme.json' ); + $this->theme_presets = WP_Theme_JSON_Resolver::get_theme_data()->get_settings(); // Register our settings. // add_action( 'register_stackable_global_settings', array( $this, 'register_preset_controls' ) ); add_filter( 'stackable_inline_styles_nodep', array( $this, 'add_preset_controls_styles' ) ); + add_filter( 'stackable_inline_editor_styles', array( $this, 'add_preset_controls_styles' ) ); } /** @@ -73,12 +74,13 @@ public function generate_css_variables( $presets, $prefix ) { public function add_preset_controls_styles( $current_css ) { $presets = $this->stackable_presets; - if ( isset ( $this->theme_presets ) ) { - $presets = $this->theme_presets; + if ( isset( $this->theme_presets ) ) { + $presets[ 'spacing' ][ 'spacingSizes' ] = $this->theme_presets[ 'spacing' ][ 'spacingSizes' ][ 'theme' ] ?? $presets[ 'spacing' ][ 'spacingSizes' ]; + $presets[ 'typography' ][ 'fontSizes' ] = $this->theme_presets[ 'typography' ][ 'fontSizes' ][ 'theme' ] ?? $presets[ 'typography' ][ 'fontSizes' ]; } $generated_css = ":root {\n"; - $generated_css .= $this->generate_css_variables( $presets[ 'spacing' ][ 'spacingSizes' ], 'spacing' ); + $generated_css .= $this->generate_css_variables( $presets[ 'spacing' ][ 'spacingSizes' ], 'spacing-size' ); $generated_css .= $this->generate_css_variables( $presets[ 'typography' ][ 'fontSizes' ], 'font-size' ); $generated_css .= "}\n"; @@ -87,6 +89,7 @@ public function add_preset_controls_styles( $current_css ) { } $current_css .= $generated_css; + return apply_filters( 'stackable_frontend_css' , $current_css ); } } diff --git a/src/plugins/global-settings/preset-controls/presets.json b/src/plugins/global-settings/preset-controls/presets.json index 2d5a3b737a..553bcc1328 100644 --- a/src/plugins/global-settings/preset-controls/presets.json +++ b/src/plugins/global-settings/preset-controls/presets.json @@ -3,42 +3,42 @@ "spacing": { "spacingSizes": [ { - "label": "XS", + "name": "XS", "size": "0.25rem", "slug": "x-small" }, { - "label": "S", + "name": "S", "size": "0.5rem", "slug": "small" }, { - "label": "M", + "name": "M", "size": "1rem", "slug": "medium" }, { - "label": "L", + "name": "L", "size": "1.5rem", "slug": "large" }, { - "label": "XL", + "name": "XL", "size": "2rem", "slug": "x-large" }, { - "label": "2XL", + "name": "2XL", "size": "3rem", "slug": "xx-large" }, { - "label": "3XL", + "name": "3XL", "size": "4rem", "slug": "xxx-large" }, { - "label": "4XL", + "name": "4XL", "size": "6rem", "slug": "xxxx-large" } @@ -47,47 +47,47 @@ "typography": { "fontSizes": [ { - "label": "XS", + "name": "XS", "size": "0.75rem", "slug": "x-small" }, { - "label": "S", + "name": "S", "size": "0.875rem", "slug": "small" }, { - "label": "M", + "name": "M", "size": "1rem", "slug": "medium" }, { - "label": "L", + "name": "L", "size": "1.125rem", "slug": "large" }, { - "label": "XL", + "name": "XL", "size": "1.5rem", "slug": "x-large" }, { - "label": "2XL", + "name": "2XL", "size": "2rem", "slug": "xx-large" }, { - "label": "3XL", + "name": "3XL", "size": "2.5rem", "slug": "xxx-large" }, { - "label": "4XL", + "name": "4XL", "size": "3rem", "slug": "xxxx-large" }, { - "label": "5XL", + "name": "5XL", "size": "4rem", "slug": "xxxxx-large" } diff --git a/src/util/styles/style-object.js b/src/util/styles/style-object.js index 53b1eaaf8e..28c18f445d 100644 --- a/src/util/styles/style-object.js +++ b/src/util/styles/style-object.js @@ -335,8 +335,10 @@ class StyleObject { } if ( unit ) { // Note: this will only work for non-objects. - // If the value is `auto`, don't add units. - value = value === 'auto' ? value : `${ value }${ unit }` + // If the value is `auto` or a CSS variable, don't add units. + if ( ! ( value === 'auto' || ( typeof value === 'string' && value.startsWith( 'var(--stk' ) ) ) ) { + value = `${ value }${ unit }` + } } if ( format !== '%s' && format !== '' ) { value = sprintf( From 787a54afedd007cd566ec8c6048f343488cc9f80 Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Sun, 23 Mar 2025 20:39:24 +0800 Subject: [PATCH 14/99] fix: make fontSizes string to store CSS variables --- src/block-components/typography/attributes.js | 2 +- src/components/advanced-range-control/index.js | 13 ++++++++----- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/block-components/typography/attributes.js b/src/block-components/typography/attributes.js index 9013f62d4d..9e8c87512f 100644 --- a/src/block-components/typography/attributes.js +++ b/src/block-components/typography/attributes.js @@ -3,7 +3,7 @@ import { deprecatedAddAttributes } from './deprecated' const typographyAttributes = { fontSize: { stkResponsive: true, - type: 'number', + type: 'string', default: '', stkUnits: 'px', }, diff --git a/src/components/advanced-range-control/index.js b/src/components/advanced-range-control/index.js index 8a9b990dab..ff2277433d 100644 --- a/src/components/advanced-range-control/index.js +++ b/src/components/advanced-range-control/index.js @@ -113,11 +113,11 @@ const AdvancedRangeControl = props => { } const [ isMarkMode, setIsMarkMode ] = useState( isMarkValue ) - // If this supports dynamic content, then the value should be saved as a String. + // If this supports dynamic content and can have CSS variables, the value should be saved as a String. // Important, the attribute type for this option should be a string. const _onChange = value => { const onChangeFunc = typeof props.onChange === 'undefined' ? onChange : props.onChange - let newValue = props.isDynamic ? value.toString() : value + let newValue = props.isDynamic || props.hasCSSVariableValue ? value.toString() : value // On reset, allow overriding the value. if ( newValue === '' ) { @@ -172,7 +172,7 @@ const AdvancedRangeControl = props => { } // We need to change the way we handle the value and onChange if we're doing marks - let rangeValue = propsToPass.isDynamic ? parseFloat( derivedValue ) : derivedValue + let rangeValue = propsToPass.isDynamic || props.hasCSSVariableValue ? parseFloat( derivedValue ) : derivedValue let rangeOnChange = _onChange if ( isMarkMode ) { rangeValue = props.marks.findIndex( mark => { @@ -190,8 +190,10 @@ const AdvancedRangeControl = props => { const newValue = _newValue // Update the unit. - dispatch( 'core/block-editor' ).__unstableMarkNextChangeAsNotPersistent() - setAttributes( { [ unitAttrName ]: unit } ) + if ( unit ) { + dispatch( 'core/block-editor' ).__unstableMarkNextChangeAsNotPersistent() + setAttributes( { [ unitAttrName ]: unit } ) + } _onChange( newValue ) } @@ -250,6 +252,7 @@ AdvancedRangeControl.defaultProps = { marks: undefined, // [{ value: '14px', label: 'S' }, { value: '16px', label: 'M' }] allowCustom: true, + hasCSSVariableValue: false, } export default memo( AdvancedRangeControl, isEqual ) From 8254dd1c6c6bbc12fc25d858fae5b336b07eb5cc Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Sun, 23 Mar 2025 22:31:59 +0800 Subject: [PATCH 15/99] fix: add default to prioritization --- .../global-settings/preset-controls/index.php | 61 ++++++++++++++----- 1 file changed, 47 insertions(+), 14 deletions(-) diff --git a/src/plugins/global-settings/preset-controls/index.php b/src/plugins/global-settings/preset-controls/index.php index a2c71376e9..769effb621 100644 --- a/src/plugins/global-settings/preset-controls/index.php +++ b/src/plugins/global-settings/preset-controls/index.php @@ -15,17 +15,17 @@ */ class Stackable_Size_And_Spacing_Preset_Controls { - public $stackable_presets; public $theme_presets; + public $default_presets; + public $stackable_presets; /** * Initialize */ function __construct() { - $this->stackable_presets = $this->load_presets( __DIR__ . '/presets.json'); $this->theme_presets = WP_Theme_JSON_Resolver::get_theme_data()->get_settings(); - // Register our settings. - // add_action( 'register_stackable_global_settings', array( $this, 'register_preset_controls' ) ); + $this->default_presets = WP_Theme_JSON_Resolver::get_core_data()->get_settings(); + $this->stackable_presets = $this->load_presets( __DIR__ . '/presets.json'); add_filter( 'stackable_inline_styles_nodep', array( $this, 'add_preset_controls_styles' ) ); add_filter( 'stackable_inline_editor_styles', array( $this, 'add_preset_controls_styles' ) ); @@ -53,7 +53,13 @@ private function load_presets( $json_path ) { return []; } - // Generate CSS variables based on preset type (e.g., fontSizes, spacing) + /** + * Generate CSS variables based on preset type (e.g., fontSizes, spacing) + * + * @param array $presests + * @param array $prefix + * @return mixed + */ public function generate_css_variables( $presets, $prefix ) { $css = ""; foreach ( $presets as $preset ) { @@ -65,6 +71,17 @@ public function generate_css_variables( $presets, $prefix ) { return $css; } + /** + * Get the value from an array deeply with an array of keys + * + * @param array $array + * @param array $keys + * @return mixed + */ + public function deepGet( $array, $keys ) { + return array_reduce( $keys, fn( $value, $key ) => $value[ $key ] ?? null, $array ); + } + /** * Add our global preset control styles. * @@ -72,16 +89,32 @@ public function generate_css_variables( $presets, $prefix ) { * @return String */ public function add_preset_controls_styles( $current_css ) { - $presets = $this->stackable_presets; - - if ( isset( $this->theme_presets ) ) { - $presets[ 'spacing' ][ 'spacingSizes' ] = $this->theme_presets[ 'spacing' ][ 'spacingSizes' ][ 'theme' ] ?? $presets[ 'spacing' ][ 'spacingSizes' ]; - $presets[ 'typography' ][ 'fontSizes' ] = $this->theme_presets[ 'typography' ][ 'fontSizes' ][ 'theme' ] ?? $presets[ 'typography' ][ 'fontSizes' ]; - } - + $preset_keys = array( + 'spacing-size' => array( 'spacing', 'spacingSizes' ), + 'font-size' => array( 'typography', 'fontSizes' ), + ); + $generated_css = ":root {\n"; - $generated_css .= $this->generate_css_variables( $presets[ 'spacing' ][ 'spacingSizes' ], 'spacing-size' ); - $generated_css .= $this->generate_css_variables( $presets[ 'typography' ][ 'fontSizes' ], 'font-size' ); + + foreach ( $preset_keys as $key => $value ) { + if ( ! empty( $this->deepGet( $this->theme_presets, $value )[ 'theme' ] ) ) { + $generated_css .= $this->generate_css_variables( + $this->deepGet( $this->theme_presets, $value )[ 'theme' ], + $key, + ); + } elseif ( ! empty( $this->deepGet( $this->default_presets, $value )[ 'default' ] ) ) { + $generated_css .= $this->generate_css_variables( + $this->deepGet( $this->default_presets, $value )[ 'default' ], + $key, + ); + } else { + $generated_css .= $this->generate_css_variables( + $this->deepGet( $this->stackable_presets, $value ), + $key, + ); + } + } + $generated_css .= "}\n"; if ( ! $generated_css ) { From cf47f720b8505be83005038412209318637db35e Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Tue, 25 Mar 2025 11:59:14 +0800 Subject: [PATCH 16/99] feat: support for custom presets --- src/block-components/helpers/size/edit.js | 2 +- src/block-components/typography/edit.js | 2 +- src/hooks/use-preset-controls.js | 49 ++++++++++++++----- .../global-settings/preset-controls/index.php | 22 ++++----- 4 files changed, 50 insertions(+), 25 deletions(-) diff --git a/src/block-components/helpers/size/edit.js b/src/block-components/helpers/size/edit.js index 0c5e727718..eeb1ca9a31 100644 --- a/src/block-components/helpers/size/edit.js +++ b/src/block-components/helpers/size/edit.js @@ -173,7 +173,7 @@ const Spacing = props => { highlight: 'margin', } - const presetMarks = usePresetControls( [ 'spacing', 'spacingSizes' ] ) + const presetMarks = usePresetControls( 'spacingSizes' ) return ( <> diff --git a/src/block-components/typography/edit.js b/src/block-components/typography/edit.js index 131b077b63..946aa68f4e 100644 --- a/src/block-components/typography/edit.js +++ b/src/block-components/typography/edit.js @@ -100,7 +100,7 @@ export const Controls = props => { const onChangeContent = useCallback( text => setDebouncedText( escapeHTMLIfInvalid( text ) ), [] ) - const presetMarks = usePresetControls( [ 'typography', 'fontSizes' ] ) + const presetMarks = usePresetControls( 'fontSizes' ) return ( <> diff --git a/src/hooks/use-preset-controls.js b/src/hooks/use-preset-controls.js index 2c46c467d0..dfcee10c66 100644 --- a/src/hooks/use-preset-controls.js +++ b/src/hooks/use-preset-controls.js @@ -1,23 +1,50 @@ import { useSettings } from '@wordpress/block-editor' +import { useSelect } from '@wordpress/data' import DEFAULT_PRESETS from '~stackable/plugins/global-settings/preset-controls/presets.json' -const PRESET_PREFIX = { - 'spacing.spacingSizes': 'spacing-size', - 'typography.fontSizes': 'font-size', +const PRESET_MAPPING = { + fontSizes: { + settings: [ 'typography', 'fontSizes' ], + prefix: 'font-size', + }, + spacingSizes: { + settings: [ 'spacing', 'spacingSizes' ], + prefix: 'spacing-size', + }, } -export const usePresetControls = properties => { - const property = properties.join( '.' ) - const [ themePreset ] = useSettings( property ) +export const usePresetControls = property => { + // Get the base presets + const [ themePresets ] = useSettings( PRESET_MAPPING[ property ].settings.join( '.' ) ) + const basePresets = Array.isArray( themePresets ) && themePresets.length > 0 + ? themePresets + : PRESET_MAPPING[ property ].settings.reduce( ( acc, key ) => acc?.[ key ], DEFAULT_PRESETS.settings ) - const presets = Array.isArray( themePreset ) && themePreset.length > 0 - ? themePreset - : properties.reduce( ( acc, key ) => acc?.[ key ], DEFAULT_PRESETS.settings ) + // Get the custom presets + const { customPresets } = useSelect( select => { + const _customPresetControls = select( 'stackable/global-preset-controls.custom' )?.getCustomPresetControls() + return { customPresets: { ..._customPresetControls }[ property ] ?? [] } + }, [] ) - const prefix = PRESET_PREFIX[ property ] + // Convert custom presets into a lookup object for fast access + const customMap = customPresets.reduce( ( acc, item ) => { + acc[ item.slug ] = item + return acc + }, {} ) - return presets.map( preset => ( { + // Merge base presets with custom presets (priority) + const mergedPresets = basePresets.map( baseItem => + customMap[ baseItem.slug ] + ? { ...baseItem, ...customMap[ baseItem.slug ] } + : baseItem + ) + + const prefix = PRESET_MAPPING[ property ].prefix + + return mergedPresets.map( preset => ( { label: preset.name, + slug: preset.slug, + size: preset.size, value: `var(--stk--preset--${ prefix }--${ preset.slug }, ${ preset.size })`, } ) ) } diff --git a/src/plugins/global-settings/preset-controls/index.php b/src/plugins/global-settings/preset-controls/index.php index 769effb621..82ea41cb09 100644 --- a/src/plugins/global-settings/preset-controls/index.php +++ b/src/plugins/global-settings/preset-controls/index.php @@ -15,6 +15,7 @@ */ class Stackable_Size_And_Spacing_Preset_Controls { + public $custom_presets; public $theme_presets; public $default_presets; public $stackable_presets; @@ -23,6 +24,7 @@ class Stackable_Size_And_Spacing_Preset_Controls { * Initialize */ function __construct() { + $this->custom_presets = get_option( 'stackable_global_custom_preset_controls' ); $this->theme_presets = WP_Theme_JSON_Resolver::get_theme_data()->get_settings(); $this->default_presets = WP_Theme_JSON_Resolver::get_core_data()->get_settings(); $this->stackable_presets = $this->load_presets( __DIR__ . '/presets.json'); @@ -31,16 +33,7 @@ function __construct() { add_filter( 'stackable_inline_editor_styles', array( $this, 'add_preset_controls_styles' ) ); } - /** - * Register the settings we need for preset controls - * - * @return void - */ - // public function register_preset_controls() { - - // } - - public function sanitize_array_setting( $input ) { + public static function sanitize_array_setting( $input ) { return ! is_array( $input ) ? array( array() ) : $input; } @@ -72,7 +65,7 @@ public function generate_css_variables( $presets, $prefix ) { } /** - * Get the value from an array deeply with an array of keys + * Get the value from an array with an array of keys * * @param array $array * @param array $keys @@ -97,7 +90,12 @@ public function add_preset_controls_styles( $current_css ) { $generated_css = ":root {\n"; foreach ( $preset_keys as $key => $value ) { - if ( ! empty( $this->deepGet( $this->theme_presets, $value )[ 'theme' ] ) ) { + if ( ! empty( $this->deepGet( $this->custom_presets, [ $value[ 1 ] ] ) ) ) { + $generated_css .= $this->generate_css_variables( + $this->deepGet( $this->custom_presets, [ $value[ 1 ] ] ), + $key, + ); + }elseif ( ! empty( $this->deepGet( $this->theme_presets, $value )[ 'theme' ] ) ) { $generated_css .= $this->generate_css_variables( $this->deepGet( $this->theme_presets, $value )[ 'theme' ], $key, From 526115e8ba9607e1565dc218852099df48339713 Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Tue, 25 Mar 2025 12:11:39 +0800 Subject: [PATCH 17/99] feat: dynamically add styles in editor --- src/components/pro-control/index.js | 6 +++ src/plugins/global-settings/editor-loader.js | 6 +++ src/plugins/global-settings/index.js | 1 + .../global-settings/preset-controls/index.js | 47 +++++++++++++++++++ 4 files changed, 60 insertions(+) create mode 100644 src/plugins/global-settings/preset-controls/index.js diff --git a/src/components/pro-control/index.js b/src/components/pro-control/index.js index 43103e4e95..6dedba0280 100644 --- a/src/components/pro-control/index.js +++ b/src/components/pro-control/index.js @@ -124,6 +124,12 @@ const LABELS = {
  • { __( 'Manage your custom Font Pairs', i18n ) }
  • , }, + 'preset-controls': { + title: __( 'Customize the Preset Controls', i18n ), + description:
      +
    • { __( 'Customize your own Preset Controls', i18n ) }
    • +
    , + }, } const ProControl = props => { diff --git a/src/plugins/global-settings/editor-loader.js b/src/plugins/global-settings/editor-loader.js index 4387159cc6..9e23a4bed1 100644 --- a/src/plugins/global-settings/editor-loader.js +++ b/src/plugins/global-settings/editor-loader.js @@ -9,6 +9,7 @@ import { GlobalColorStyles } from './colors' import { GlobalTypographyStyles } from './typography' import { GlobalSpacingAndBordersStyles } from './spacing-and-borders' import { GlobalButtonsAndIconsStyles } from './buttons-and-icons' +import { GlobalPresetControlsStyles } from './preset-controls' import './block-defaults' /** @@ -48,6 +49,7 @@ const GlobalSettingsLoader = () => { editorBody.appendChild( globalColorWrapper ) editorBody.appendChild( globalSpacingAndBorderWrapper ) editorBody.appendChild( globalButtonsAndIconsWrapper ) + editorBody.appendChild( globalPresetControlsWrapper ) } }, [ deviceType, editorDom ] ) @@ -62,17 +64,21 @@ const globalTypographyWrapper = document?.createElement( 'style' ) const globalColorWrapper = document?.createElement( 'style' ) const globalSpacingAndBorderWrapper = document?.createElement( 'style' ) const globalButtonsAndIconsWrapper = document?.createElement( 'style' ) +const globalPresetControlsWrapper = document?.createElement( 'style' ) globalTypographyWrapper?.setAttribute( 'id', 'stk-global-typography-styles' ) globalColorWrapper?.setAttribute( 'id', 'stk-global-color-styles' ) globalSpacingAndBorderWrapper?.setAttribute( 'id', 'stk-global-spacing-and-borders-styles' ) globalButtonsAndIconsWrapper?.setAttribute( 'id', 'stk-global-buttons-and-icons-styles' ) +globalPresetControlsWrapper?.setAttribute( 'id', 'stk-global-preset-controls-styles' ) domReady( () => { document?.body?.appendChild( globalTypographyWrapper ) document?.body?.appendChild( globalColorWrapper ) document?.body?.appendChild( globalSpacingAndBorderWrapper ) document?.body?.appendChild( globalButtonsAndIconsWrapper ) + document?.body?.appendChild( globalPresetControlsWrapper ) createRoot( globalTypographyWrapper ).render( ) createRoot( globalColorWrapper ).render( ) createRoot( globalSpacingAndBorderWrapper ).render( ) createRoot( globalButtonsAndIconsWrapper ).render( ) + createRoot( globalPresetControlsWrapper ).render( ) } ) diff --git a/src/plugins/global-settings/index.js b/src/plugins/global-settings/index.js index 0a7a91c070..c1ca1867e1 100644 --- a/src/plugins/global-settings/index.js +++ b/src/plugins/global-settings/index.js @@ -6,6 +6,7 @@ import './buttons-and-icons' import './spacing-and-borders' import './block-defaults' import './icon-library' +import './preset-controls' /** * External dependencies diff --git a/src/plugins/global-settings/preset-controls/index.js b/src/plugins/global-settings/preset-controls/index.js new file mode 100644 index 0000000000..1a042a4e91 --- /dev/null +++ b/src/plugins/global-settings/preset-controls/index.js @@ -0,0 +1,47 @@ +/** + * Internal dependencies + */ +import { GlobalPresetControlsStyles } from './editor-loader' + +/** + * External dependencies + */ +import { + i18n, showProNotice, isPro, +} from 'stackable' +import { + PanelAdvancedSettings, + ProControl, +} from '~stackable/components' + +/** + * WordPress dependencies + */ + +import { addFilter, applyFilters } from '@wordpress/hooks' +import { Fragment } from '@wordpress/element' +import { __ } from '@wordpress/i18n' + +export { GlobalPresetControlsStyles } + +if ( showProNotice || isPro ) { + addFilter( 'stackable.global-settings.inspector', 'stackable/preset-controls', output => { + return ( + + { output } + + + { ! isPro && } + { isPro && + applyFilters( 'stackable.global-settings.inspector.preset-controls.control', null ) + } + + + + ) + }, 12 ) +} From 47cd13c7be5d16ccad9d2e392ee4a9f88e033c93 Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Tue, 25 Mar 2025 12:16:43 +0800 Subject: [PATCH 18/99] feat: dynamically add styles in editor with editor loader --- .../preset-controls/editor-loader.js | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 src/plugins/global-settings/preset-controls/editor-loader.js diff --git a/src/plugins/global-settings/preset-controls/editor-loader.js b/src/plugins/global-settings/preset-controls/editor-loader.js new file mode 100644 index 0000000000..b2cc5dce9f --- /dev/null +++ b/src/plugins/global-settings/preset-controls/editor-loader.js @@ -0,0 +1,51 @@ +/** + * WordPress dependencies + */ +import { useSelect } from '@wordpress/data' +import { useEffect, useState } from '@wordpress/element' + +/** + * External dependencies + */ +import { compact } from 'lodash' + +const PRESET_MAPPING = { + fontSizes: { + prefix: 'font-size', + }, + spacingSizes: { + prefix: 'spacing-size', + }, +} + +const renderGlobalStyles = ( customPresets, setStyles ) => { + let css = '' + + Object.entries( customPresets ).forEach( ( [ key, presets ] ) => { + const styleRules = presets?.map( preset => { + return preset + ? `--stk--preset--${ PRESET_MAPPING[ key ]?.prefix }--${ preset?.slug || '' }: ${ preset?.size || '' };` + : '' + } ) + css += compact( styleRules ).join( '' ) + } ) + + css = `:root { ${ css } }` + setStyles( css ) +} + +export const GlobalPresetControlsStyles = () => { + const { customPresets } = useSelect( select => { + const _customPresetControls = select( 'stackable/global-preset-controls.custom' )?.getCustomPresetControls() + return { customPresets: { ..._customPresetControls } ?? [] } + }, [] ) + const [ styles, setStyles ] = useState( '' ) + + useEffect( () => { + if ( customPresets && typeof customPresets === 'object' ) { + renderGlobalStyles( customPresets, setStyles ) + } + }, [ JSON.stringify( customPresets ) ] ) + + return styles +} From 09cfc86c174c197a2e256913604c5ed0afc56d12 Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Tue, 25 Mar 2025 12:55:44 +0800 Subject: [PATCH 19/99] fix: get current marked value, go to markmode --- src/block-components/typography/edit.js | 1 + src/components/advanced-range-control/index.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/block-components/typography/edit.js b/src/block-components/typography/edit.js index 946aa68f4e..fc5eb7df22 100644 --- a/src/block-components/typography/edit.js +++ b/src/block-components/typography/edit.js @@ -272,6 +272,7 @@ export const Controls = props => { description: __( 'Sets the size of text characters', i18n ), } } marks={ presetMarks } + hasCSSVariableValue={ true } /> { hasColor && ( diff --git a/src/components/advanced-range-control/index.js b/src/components/advanced-range-control/index.js index ff2277433d..839b6f6d2f 100644 --- a/src/components/advanced-range-control/index.js +++ b/src/components/advanced-range-control/index.js @@ -107,7 +107,7 @@ const AdvancedRangeControl = props => { // at the start, or show custom let isMarkValue = !! props.marks if ( props.marks && value ) { - const valueToCheck = value + unit + const valueToCheck = value + ( props.hasCSSVariableValue ? '' : unit ) // Check if the current value exsits in the marks isMarkValue = isMarkValue && props.marks.some( mark => mark.value === valueToCheck ) } From d85dffa28889d6aca7976e3358f1e9f9cb29499a Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Wed, 26 Mar 2025 17:06:09 +0800 Subject: [PATCH 20/99] fix: css generation should consider custom, by each preset, not by property --- .../global-settings/preset-controls/index.php | 60 ++++++++++++------- 1 file changed, 39 insertions(+), 21 deletions(-) diff --git a/src/plugins/global-settings/preset-controls/index.php b/src/plugins/global-settings/preset-controls/index.php index 82ea41cb09..19b6bf7855 100644 --- a/src/plugins/global-settings/preset-controls/index.php +++ b/src/plugins/global-settings/preset-controls/index.php @@ -14,6 +14,16 @@ * Size and Spacing Preset Controls */ class Stackable_Size_And_Spacing_Preset_Controls { + public const PRESET_MAPPING = array( + 'fontSizes' => array( + 'settings' => array('typography', 'fontSizes' ), + 'prefix' => 'font-size', + ), + 'spacingSizes' => array( + 'settings' => array( 'spacing', 'spacingSizes' ), + 'prefix' => 'spacing-size', + ), + ); public $custom_presets; public $theme_presets; @@ -47,18 +57,33 @@ private function load_presets( $json_path ) { } /** - * Generate CSS variables based on preset type (e.g., fontSizes, spacing) - * - * @param array $presests + * Generate CSS variables based on the property (e.g., fontSizes, spacing). + * The given presets will be overriden it match with a preset from custom. + * + * @param array $property + * @param array $presets * @param array $prefix * @return mixed */ - public function generate_css_variables( $presets, $prefix ) { + public function generate_css_variables( $property, $presets, $prefix ) { + $custom_presets = $this->custom_presets[ $property ] ?? []; + $css = ""; + + // Convert presets into an associative array with key 'slug' + $presets_by_slug = []; foreach ( $presets as $preset ) { + $presets_by_slug[ $preset[ 'slug' ] ] = $preset; + } + // Override values in base presets if it exist in custom presets + foreach ( $custom_presets as $custom ) { + $presets_by_slug[ $custom[ 'slug' ] ] = $custom; + } + + foreach ( $presets_by_slug as $preset ) { $slug = $preset[ 'slug' ]; $size = $preset[ 'size' ]; - $css .= "--stk--preset--$prefix--$slug: $size;\n"; + $css .= "--stk--preset--$prefix--{$preset['slug']}: {$preset['size']};\n"; } return $css; @@ -82,33 +107,26 @@ public function deepGet( $array, $keys ) { * @return String */ public function add_preset_controls_styles( $current_css ) { - $preset_keys = array( - 'spacing-size' => array( 'spacing', 'spacingSizes' ), - 'font-size' => array( 'typography', 'fontSizes' ), - ); - $generated_css = ":root {\n"; - foreach ( $preset_keys as $key => $value ) { - if ( ! empty( $this->deepGet( $this->custom_presets, [ $value[ 1 ] ] ) ) ) { - $generated_css .= $this->generate_css_variables( - $this->deepGet( $this->custom_presets, [ $value[ 1 ] ] ), - $key, - ); - }elseif ( ! empty( $this->deepGet( $this->theme_presets, $value )[ 'theme' ] ) ) { + foreach ( self::PRESET_MAPPING as $key => $value ) { + if ( ! empty( $this->deepGet( $this->theme_presets, $value[ 'settings' ] )[ 'theme' ] ) ) { $generated_css .= $this->generate_css_variables( - $this->deepGet( $this->theme_presets, $value )[ 'theme' ], $key, + $this->deepGet( $this->theme_presets, $value[ 'settings' ] )[ 'theme' ], + $value[ 'prefix' ], ); - } elseif ( ! empty( $this->deepGet( $this->default_presets, $value )[ 'default' ] ) ) { + } elseif ( ! empty( $this->deepGet( $this->default_presets, $value[ 'settings' ] )[ 'default' ] ) ) { $generated_css .= $this->generate_css_variables( - $this->deepGet( $this->default_presets, $value )[ 'default' ], $key, + $this->deepGet( $this->default_presets, $value[ 'settings' ] )[ 'default' ], + $value[ 'prefix' ], ); } else { $generated_css .= $this->generate_css_variables( - $this->deepGet( $this->stackable_presets, $value ), $key, + $this->deepGet( $this->stackable_presets, $value[ 'settings' ] ), + $value[ 'prefix' ], ); } } From 4d37e1a2590a1e79af1e8f3ca8b462228febb192 Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Thu, 27 Mar 2025 12:38:28 +0800 Subject: [PATCH 21/99] fix: add additional functionalities to usePresetControls --- src/block-components/helpers/size/edit.js | 2 +- src/block-components/typography/edit.js | 2 +- src/hooks/use-preset-controls.js | 75 ++++++++++++++--------- 3 files changed, 49 insertions(+), 30 deletions(-) diff --git a/src/block-components/helpers/size/edit.js b/src/block-components/helpers/size/edit.js index eeb1ca9a31..23f81ea0cf 100644 --- a/src/block-components/helpers/size/edit.js +++ b/src/block-components/helpers/size/edit.js @@ -173,7 +173,7 @@ const Spacing = props => { highlight: 'margin', } - const presetMarks = usePresetControls( 'spacingSizes' ) + const presetMarks = usePresetControls( 'spacingSizes' )?.getPresetMarks() || null return ( <> diff --git a/src/block-components/typography/edit.js b/src/block-components/typography/edit.js index fc5eb7df22..83cd0a7ce5 100644 --- a/src/block-components/typography/edit.js +++ b/src/block-components/typography/edit.js @@ -100,7 +100,7 @@ export const Controls = props => { const onChangeContent = useCallback( text => setDebouncedText( escapeHTMLIfInvalid( text ) ), [] ) - const presetMarks = usePresetControls( 'fontSizes' ) + const presetMarks = usePresetControls( 'fontSizes' )?.getPresetMarks() || null return ( <> diff --git a/src/hooks/use-preset-controls.js b/src/hooks/use-preset-controls.js index dfcee10c66..4e6a91d6ff 100644 --- a/src/hooks/use-preset-controls.js +++ b/src/hooks/use-preset-controls.js @@ -14,37 +14,56 @@ const PRESET_MAPPING = { } export const usePresetControls = property => { - // Get the base presets + // Get the theme presets for the property const [ themePresets ] = useSettings( PRESET_MAPPING[ property ].settings.join( '.' ) ) - const basePresets = Array.isArray( themePresets ) && themePresets.length > 0 + // Get all custom presets + const { allCustomPresets } = useSelect( select => { + const _customPresetControls = select( 'stackable/global-preset-controls.custom' )?.getCustomPresetControls() + return { allCustomPresets: { ..._customPresetControls } } + }, [] ) + + const hasThemePresets = Array.isArray( themePresets ) && themePresets.length > 0 + + // Get the theme/default presets if the user have one, else return the stackable presets + const basePresets = hasThemePresets ? themePresets : PRESET_MAPPING[ property ].settings.reduce( ( acc, key ) => acc?.[ key ], DEFAULT_PRESETS.settings ) - // Get the custom presets - const { customPresets } = useSelect( select => { - const _customPresetControls = select( 'stackable/global-preset-controls.custom' )?.getCustomPresetControls() - return { customPresets: { ..._customPresetControls }[ property ] ?? [] } - }, [] ) + // Returns the base presets overriden by the custom presets + const getMergedPresets = () => { + const customPresets = allCustomPresets[ property ] ?? [] + // Convert custom presets into a lookup object for fast access + const customMap = customPresets.reduce( ( acc, item ) => { + acc[ item.slug ] = item + return acc + }, {} ) + + // Merge base presets with custom presets (priority) + return basePresets.map( baseItem => + customMap[ baseItem.slug ] + ? { ...baseItem, ...customMap[ baseItem.slug ] } + : baseItem + ) + } + + // Get the merge preset marks with the CSS Variable value + const getPresetMarks = () => { + const prefix = PRESET_MAPPING[ property ].prefix + const mergedPresets = getMergedPresets() + + return mergedPresets + .filter( preset => ! ( preset?.isDiscarded ) ) + .map( preset => ( { + ...preset, + value: `var(--stk--preset--${ prefix }--${ preset.slug }, ${ preset.size })`, + } ) ) + } - // Convert custom presets into a lookup object for fast access - const customMap = customPresets.reduce( ( acc, item ) => { - acc[ item.slug ] = item - return acc - }, {} ) - - // Merge base presets with custom presets (priority) - const mergedPresets = basePresets.map( baseItem => - customMap[ baseItem.slug ] - ? { ...baseItem, ...customMap[ baseItem.slug ] } - : baseItem - ) - - const prefix = PRESET_MAPPING[ property ].prefix - - return mergedPresets.map( preset => ( { - label: preset.name, - slug: preset.slug, - size: preset.size, - value: `var(--stk--preset--${ prefix }--${ preset.slug }, ${ preset.size })`, - } ) ) + return { + hasThemePresets, + basePresets, + allCustomPresets, + getMergedPresets, + getPresetMarks, + } } From 1a97892069a2088740381b14cb4f85fe22f82775 Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Thu, 27 Mar 2025 12:39:28 +0800 Subject: [PATCH 22/99] fix: allow AdvancedRangeControl to set custom onReset --- .../advanced-range-control/editor.scss | 4 +++ .../advanced-range-control/index.js | 25 +++++++++++++++---- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/components/advanced-range-control/editor.scss b/src/components/advanced-range-control/editor.scss index 6dc6f06eae..5e437de64e 100644 --- a/src/components/advanced-range-control/editor.scss +++ b/src/components/advanced-range-control/editor.scss @@ -69,3 +69,7 @@ .stk-range-control--with-marks.stk-range-control--mark-mode .components-range-control__wrapper { margin-inline-end: 8px; } + +div.components-base-control.stk-preset-controls { + flex-grow: 1; +} diff --git a/src/components/advanced-range-control/index.js b/src/components/advanced-range-control/index.js index 839b6f6d2f..84c9d52e3c 100644 --- a/src/components/advanced-range-control/index.js +++ b/src/components/advanced-range-control/index.js @@ -121,6 +121,10 @@ const AdvancedRangeControl = props => { // On reset, allow overriding the value. if ( newValue === '' ) { + // Reset should also change from mark mode + if ( isMarkMode ) { + setIsMarkMode( false ) + } const overrideValue = props.onOverrideReset?.() if ( typeof overrideValue !== 'undefined' ) { newValue = overrideValue @@ -144,18 +148,18 @@ const AdvancedRangeControl = props => { propsToPass.sliderMax = props.marks.length - 1 propsToPass.step = 1 - // Show the marks and labels + // Show the marks and names propsToPass.marks = props.marks.reduce( ( acc, mark, index ) => { return [ { value: index, - label: undefined, + name: undefined, }, ...acc, ] }, [] ) propsToPass.renderTooltipContent = value => { - return props.marks[ value ]?.label || '' + return props.marks[ value ]?.name || '' } // Other necessary props for steps. @@ -171,6 +175,11 @@ const AdvancedRangeControl = props => { controlProps.className += isMarkMode ? ' stk-range-control--mark-mode' : '' } + if ( props.isCustomPreset ) { + controlProps.className = controlProps.className || '' + controlProps.className += 'stk-preset-controls' + } + // We need to change the way we handle the value and onChange if we're doing marks let rangeValue = propsToPass.isDynamic || props.hasCSSVariableValue ? parseFloat( derivedValue ) : derivedValue let rangeOnChange = _onChange @@ -227,10 +236,13 @@ const AdvancedRangeControl = props => {
    ) @@ -238,6 +250,8 @@ const AdvancedRangeControl = props => { AdvancedRangeControl.defaultProps = { allowReset: true, + onReset: undefined, + showReset: undefined, isDynamic: false, default: '', @@ -250,9 +264,10 @@ AdvancedRangeControl.defaultProps = { onOverrideReset: undefined, forcePlaceholder: false, - marks: undefined, // [{ value: '14px', label: 'S' }, { value: '16px', label: 'M' }] + marks: undefined, // [{ value: '14px', name: 'S' }, { value: '16px', name: 'M' }] allowCustom: true, hasCSSVariableValue: false, + isCustomPreset: false, } export default memo( AdvancedRangeControl, isEqual ) From 8c523468f506773e33c6ad39ba20e8adc485af8e Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Thu, 27 Mar 2025 12:41:53 +0800 Subject: [PATCH 23/99] fix: do not add style for discarded presets --- src/plugins/global-settings/preset-controls/editor-loader.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/global-settings/preset-controls/editor-loader.js b/src/plugins/global-settings/preset-controls/editor-loader.js index b2cc5dce9f..1164cb3f46 100644 --- a/src/plugins/global-settings/preset-controls/editor-loader.js +++ b/src/plugins/global-settings/preset-controls/editor-loader.js @@ -23,7 +23,7 @@ const renderGlobalStyles = ( customPresets, setStyles ) => { Object.entries( customPresets ).forEach( ( [ key, presets ] ) => { const styleRules = presets?.map( preset => { - return preset + return preset && ( ! preset?.isDiscarded ) ? `--stk--preset--${ PRESET_MAPPING[ key ]?.prefix }--${ preset?.slug || '' }: ${ preset?.size || '' };` : '' } ) From 6a26a9779e2294a3dd9fc24f25c3274b6ee42d9b Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Sun, 30 Mar 2025 11:33:18 +0800 Subject: [PATCH 24/99] fix: add comments, title in generated css --- src/components/advanced-range-control/index.js | 3 ++- src/plugins/global-settings/preset-controls/index.php | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/components/advanced-range-control/index.js b/src/components/advanced-range-control/index.js index 84c9d52e3c..274ab85d1d 100644 --- a/src/components/advanced-range-control/index.js +++ b/src/components/advanced-range-control/index.js @@ -181,6 +181,7 @@ const AdvancedRangeControl = props => { } // We need to change the way we handle the value and onChange if we're doing marks + // Convert to float if the attribute is string to work with the slider let rangeValue = propsToPass.isDynamic || props.hasCSSVariableValue ? parseFloat( derivedValue ) : derivedValue let rangeOnChange = _onChange if ( isMarkMode ) { @@ -266,7 +267,7 @@ AdvancedRangeControl.defaultProps = { marks: undefined, // [{ value: '14px', name: 'S' }, { value: '16px', name: 'M' }] allowCustom: true, - hasCSSVariableValue: false, + hasCSSVariableValue: false, // If the attribute can have CSS variable value (string attribute\) isCustomPreset: false, } diff --git a/src/plugins/global-settings/preset-controls/index.php b/src/plugins/global-settings/preset-controls/index.php index 19b6bf7855..e1ea8b2643 100644 --- a/src/plugins/global-settings/preset-controls/index.php +++ b/src/plugins/global-settings/preset-controls/index.php @@ -107,7 +107,8 @@ public function deepGet( $array, $keys ) { * @return String */ public function add_preset_controls_styles( $current_css ) { - $generated_css = ":root {\n"; + $generated_css = "\n/* Global Preset Controls */\n"; + $generated_css .= ":root {\n"; foreach ( self::PRESET_MAPPING as $key => $value ) { if ( ! empty( $this->deepGet( $this->theme_presets, $value[ 'settings' ] )[ 'theme' ] ) ) { From 754bfcb1d07163510ffbc1b05cc37f4714f86c93 Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Sun, 30 Mar 2025 21:57:44 +0800 Subject: [PATCH 25/99] fix: FourRangeControl markmode and initial value --- src/block-components/helpers/size/edit.js | 2 ++ .../advanced-range-control/index.js | 2 +- src/components/four-range-control/index.js | 20 ++++++++++--------- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/block-components/helpers/size/edit.js b/src/block-components/helpers/size/edit.js index 23f81ea0cf..5aed5a9072 100644 --- a/src/block-components/helpers/size/edit.js +++ b/src/block-components/helpers/size/edit.js @@ -193,6 +193,7 @@ const Spacing = props => { visualGuide={ paddingVisualGuide } placeholder={ props.paddingPlaceholder } marks={ presetMarks } + hasCSSVariableValue={ true } /> { props.enableMargin && @@ -211,6 +212,7 @@ const Spacing = props => { } } visualGuide={ marginVisualGuide } marks={ presetMarks } + hasCSSVariableValue={ true } /> } diff --git a/src/components/advanced-range-control/index.js b/src/components/advanced-range-control/index.js index 274ab85d1d..6ef56962b7 100644 --- a/src/components/advanced-range-control/index.js +++ b/src/components/advanced-range-control/index.js @@ -267,7 +267,7 @@ AdvancedRangeControl.defaultProps = { marks: undefined, // [{ value: '14px', name: 'S' }, { value: '16px', name: 'M' }] allowCustom: true, - hasCSSVariableValue: false, // If the attribute can have CSS variable value (string attribute\) + hasCSSVariableValue: false, // If the attribute can have CSS variable value (string attribute) isCustomPreset: false, } diff --git a/src/components/four-range-control/index.js b/src/components/four-range-control/index.js index ffd1ed4e01..0986423033 100644 --- a/src/components/four-range-control/index.js +++ b/src/components/four-range-control/index.js @@ -206,11 +206,12 @@ const FourRangeControl = memo( props => { } if ( props.marks && value ) { // Check if the current value exsits in the marks - isMarkValue.first = isMarkValue.first && props.marks.some( mark => mark.value === firstValue + unit ) - isMarkValue.top = isMarkValue.top && props.marks.some( mark => mark.value === value.top + unit ) - isMarkValue.right = isMarkValue.right && props.marks.some( mark => mark.value === value.right + unit ) - isMarkValue.bottom = isMarkValue.bottom && props.marks.some( mark => mark.value === value.bottom + unit ) - isMarkValue.left = isMarkValue.left && props.marks.some( mark => mark.value === value.left + unit ) + const marksUnit = ( props.hasCSSVariableValue ? '' : unit ) + isMarkValue.first = isMarkValue.first && props.marks.some( mark => mark.value === firstValue + marksUnit ) + isMarkValue.top = isMarkValue.top && props.marks.some( mark => mark.value === value.top + marksUnit ) + isMarkValue.right = isMarkValue.right && props.marks.some( mark => mark.value === value.right + marksUnit ) + isMarkValue.bottom = isMarkValue.bottom && props.marks.some( mark => mark.value === value.bottom + marksUnit ) + isMarkValue.left = isMarkValue.left && props.marks.some( mark => mark.value === value.left + marksUnit ) } const [ isFourMarkMode, setIsFourMarkMode ] = useState( isMarkValue ) @@ -288,18 +289,18 @@ const FourRangeControl = memo( props => { newProps.sliderMax = props.marks.length - 1 newProps.step = 1 - // Show the marks and labels + // Show the marks and names newProps.marks = props.marks.reduce( ( acc, mark, index ) => { return [ { value: index, - label: undefined, + name: undefined, }, ...acc, ] }, [] ) newProps.renderTooltipContent = value => { - return props.marks[ value ]?.label || '' + return props.marks[ value ]?.name || '' } // Other necessary props for steps. @@ -321,7 +322,7 @@ const FourRangeControl = memo( props => { if ( props.marks && isMarkMode ) { rangeValue = props.marks.findIndex( mark => { const [ _value, _unit ] = extractNumberAndUnit( mark.value ) - return _value === value + return _value === initialValue } ) rangeOnChange = value => { if ( value === '' ) { @@ -804,6 +805,7 @@ FourRangeControl.defaultProps = { marks: undefined, allowCustom: true, + hasCSSVariableValue: false, } export default memo( FourRangeControl ) From 01d221a830f82e8263846b3e0ad5a26dfd496065 Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Sun, 30 Mar 2025 22:37:57 +0800 Subject: [PATCH 26/99] feat: add row and column gap --- src/block-components/columns/attributes.js | 4 +-- src/block-components/columns/edit.js | 7 ++++++ src/block-components/columns/style.js | 29 +++++++++++++++++++--- 3 files changed, 34 insertions(+), 6 deletions(-) diff --git a/src/block-components/columns/attributes.js b/src/block-components/columns/attributes.js index fe482cd786..2158b042fc 100644 --- a/src/block-components/columns/attributes.js +++ b/src/block-components/columns/attributes.js @@ -9,12 +9,12 @@ export const addAttributes = attrObject => { }, columnGap: { stkResponsive: true, - type: 'number', + type: 'string', default: '', }, rowGap: { stkResponsive: true, - type: 'number', + type: 'string', default: '', }, columnWrapDesktop: { // Only applies to desktops diff --git a/src/block-components/columns/edit.js b/src/block-components/columns/edit.js index 83dbee0376..363a0a95ae 100644 --- a/src/block-components/columns/edit.js +++ b/src/block-components/columns/edit.js @@ -23,6 +23,7 @@ import { useBlockSetAttributesContext, useDeviceType, useBlockLayoutDefaults, + usePresetControls, } from '~stackable/hooks' import { range } from 'lodash' @@ -124,6 +125,8 @@ export const Controls = props => { : deviceType === 'Tablet' ? ( attributes.columnArrangementTablet || defaultArrangement ) : ( attributes.columnArrangementMobile || defaultArrangement ) + const presetMarks = usePresetControls( 'spacingSizes' )?.getPresetMarks() || null + return ( <> { props.hasColumnsControl && } @@ -284,6 +287,8 @@ export const Controls = props => { video: 'column-gap', description: __( 'Sets the distance between two or more columns', i18n ), } } + marks={ presetMarks } + hasCSSVariableValue={ true } /> { // TODO: Add a working video description: __( 'Sets the distance between two or more columns', i18n ), } } + marks={ presetMarks } + hasCSSVariableValue={ true } /> ) } diff --git a/src/block-components/columns/style.js b/src/block-components/columns/style.js index 8e2c614d5a..890e5cb1cc 100644 --- a/src/block-components/columns/style.js +++ b/src/block-components/columns/style.js @@ -30,16 +30,27 @@ export const addStyles = ( blockStyleGenerator, props = {} ) => { selector: '.%s-column', styleRule: '--stk-column-gap', attrName: 'columnGap', - format: '%spx', responsive: 'all', + valueCallback: value => { + // Substitute with using format to work with preset controls + if ( value.startsWith( 'var(--stk' ) ) { + return value + } + return value + 'px' + }, }, { ...propsToPass, renderIn: 'edit', selector: '.%s-column > .block-editor-inner-blocks > .block-editor-block-list__layout', styleRule: '--stk-column-gap', attrName: 'columnGap', - format: '%spx', responsive: 'all', + valueCallback: value => { + if ( value.startsWith( 'var(--stk' ) ) { + return value + } + return value + 'px' + }, } ] ) blockStyleGenerator.addBlockStyles( 'columnWrapDesktop', [ { @@ -78,16 +89,26 @@ export const addStyles = ( blockStyleGenerator, props = {} ) => { selector: '.%s-column', styleRule: 'rowGap', attrName: 'rowGap', - format: '%spx', responsive: 'all', + valueCallback: value => { + if ( value.startsWith( 'var(--stk' ) ) { + return value + } + return value + 'px' + }, }, { ...propsToPass, renderIn: 'edit', selector: '.%s-column > .block-editor-inner-blocks > .block-editor-block-list__layout', styleRule: 'rowGap', attrName: 'rowGap', - format: '%spx', responsive: 'all', + valueCallback: value => { + if ( value.startsWith( 'var(--stk' ) ) { + return value + } + return value + 'px' + }, } ] ) } From c95763074e9f0bf38b1c9dd625d68121eb6dcbb4 Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Mon, 31 Mar 2025 09:58:04 +0800 Subject: [PATCH 27/99] feat: add blockHeight and borderRadius --- src/block-components/helpers/borders/edit.js | 6 +- src/block-components/helpers/borders/style.js | 33 ++++++- .../helpers/size/attributes.js | 2 +- src/block-components/helpers/size/edit.js | 40 +-------- src/hooks/use-preset-controls.js | 8 ++ .../global-settings/preset-controls/index.php | 8 ++ .../preset-controls/presets.json | 88 ++++++++++++++++++- 7 files changed, 140 insertions(+), 45 deletions(-) diff --git a/src/block-components/helpers/borders/edit.js b/src/block-components/helpers/borders/edit.js index 44ab25c4cb..ffd96697d2 100644 --- a/src/block-components/helpers/borders/edit.js +++ b/src/block-components/helpers/borders/edit.js @@ -15,7 +15,7 @@ import { import { Fragment } from '@wordpress/element' import { __ } from '@wordpress/i18n' import { - useAttributeEditHandlers, useBlockLayoutDefaults, useBlockSetAttributesContext, + useAttributeEditHandlers, useBlockLayoutDefaults, useBlockSetAttributesContext, usePresetControls, } from '~stackable/hooks' import { applyFilters } from '@wordpress/hooks' @@ -71,6 +71,8 @@ export const BorderControls = props => { applyFilters( 'stackable.block-component.helpers.borders', null, getAttribute, updateAttributes ) + const presetMarks = usePresetControls( 'borderRadius' )?.getPresetMarks() || null + return ( { props.hasBorderType && @@ -132,6 +134,8 @@ export const BorderControls = props => { isCorner={ true } sliderMax={ props.borderSliderMax } placeholder={ props.borderRadiusPlaceholder } + marks={ presetMarks } + hasCSSVariableValue={ true } /> } { attrName: 'borderRadius2', key: 'borderTopLeftRadius2', attrNameTemplate, - format: '%spx', + valueCallback: value => { + // Substitute with using format to work with preset controls + value = typeof value === 'number' ? value.toString() : value + if ( value.startsWith( 'var(--stk' ) ) { + return value + } + return value + 'px' + }, responsive: 'all', hover: 'all', valuePreCallback: value => value?.top, @@ -48,7 +55,13 @@ export const addBorderStyles = ( blockStyleGenerator, props = {} ) => { attrName: 'borderRadius2', key: 'borderTopRightRadius2', attrNameTemplate, - format: '%spx', + valueCallback: value => { + value = typeof value === 'number' ? value.toString() : value + if ( value.startsWith( 'var(--stk' ) ) { + return value + } + return value + 'px' + }, responsive: 'all', hover: 'all', valuePreCallback: value => value?.right, @@ -60,7 +73,13 @@ export const addBorderStyles = ( blockStyleGenerator, props = {} ) => { attrName: 'borderRadius2', key: 'borderBottomRightRadius2', attrNameTemplate, - format: '%spx', + valueCallback: value => { + value = typeof value === 'number' ? value.toString() : value + if ( value.startsWith( 'var(--stk' ) ) { + return value + } + return value + 'px' + }, responsive: 'all', hover: 'all', valuePreCallback: value => value?.left, @@ -72,7 +91,13 @@ export const addBorderStyles = ( blockStyleGenerator, props = {} ) => { attrName: 'borderRadius2', key: 'borderBottomLeftRadius2', attrNameTemplate, - format: '%spx', + valueCallback: value => { + value = typeof value === 'number' ? value.toString() : value + if ( value.startsWith( 'var(--stk' ) ) { + return value + } + return value + 'px' + }, responsive: 'all', hover: 'all', valuePreCallback: value => value?.bottom, diff --git a/src/block-components/helpers/size/attributes.js b/src/block-components/helpers/size/attributes.js index 83f73deb1d..4c51277183 100644 --- a/src/block-components/helpers/size/attributes.js +++ b/src/block-components/helpers/size/attributes.js @@ -2,7 +2,7 @@ export const sizeAttributes = { height: { stkResponsive: true, stkUnits: 'px', - type: 'number', + type: 'string', default: '', }, width: { diff --git a/src/block-components/helpers/size/edit.js b/src/block-components/helpers/size/edit.js index 5aed5a9072..597fc37126 100644 --- a/src/block-components/helpers/size/edit.js +++ b/src/block-components/helpers/size/edit.js @@ -17,41 +17,6 @@ import { import { __ } from '@wordpress/i18n' import { getAttributeNameFunc } from '~stackable/util' -const HEIGHT_PRESET = [ - { - value: '64px', - label: 'XS', - }, - { - value: '128px', - label: 'S', - }, - { - value: '192px', - label: 'M', - }, - { - value: '256px', - label: 'L', - }, - { - value: '384px', - label: 'XL', - }, - { - value: '512px', - label: '2XL', - }, - { - value: '640px', - label: '3XL', - }, - { - value: '100vh', - label: 'Full', - }, -] - const Layout = props => { const deviceType = useDeviceType() @@ -67,7 +32,7 @@ const Layout = props => { labelVerticalAlign = __( 'Content Vertical Align', i18n ), } = props.labels - const heightMarks = HEIGHT_PRESET + const presetMarks = usePresetControls( 'blockHeights' )?.getPresetMarks() || null return ( <> @@ -86,7 +51,8 @@ const Layout = props => { description: __( 'Adjusts the minimum allowable height of the block', i18n ), } } visualGuide={ props.visualGuide } - marks={ heightMarks } + marks={ presetMarks } + hasCSSVariableValue={ true } /> } { props.hasContentVerticalAlign && diff --git a/src/hooks/use-preset-controls.js b/src/hooks/use-preset-controls.js index 4e6a91d6ff..e7735af306 100644 --- a/src/hooks/use-preset-controls.js +++ b/src/hooks/use-preset-controls.js @@ -11,6 +11,14 @@ const PRESET_MAPPING = { settings: [ 'spacing', 'spacingSizes' ], prefix: 'spacing-size', }, + blockHeights: { + settings: [ 'blockHeights' ], + prefix: 'block-height', + }, + borderRadius: { + settings: [ 'borderRadius' ], + prefix: 'border-radius', + }, } export const usePresetControls = property => { diff --git a/src/plugins/global-settings/preset-controls/index.php b/src/plugins/global-settings/preset-controls/index.php index e1ea8b2643..111d58bcb9 100644 --- a/src/plugins/global-settings/preset-controls/index.php +++ b/src/plugins/global-settings/preset-controls/index.php @@ -23,6 +23,14 @@ class Stackable_Size_And_Spacing_Preset_Controls { 'settings' => array( 'spacing', 'spacingSizes' ), 'prefix' => 'spacing-size', ), + 'blockHeights' => array( + 'settings' => array( 'blockHeights' ), + 'prefix' => 'block-height', + ), + 'borderRadius' => array( + 'settings' => array( 'borderRadius' ), + 'prefix' => 'border-radius', + ), ); public $custom_presets; diff --git a/src/plugins/global-settings/preset-controls/presets.json b/src/plugins/global-settings/preset-controls/presets.json index 553bcc1328..60ce0169ef 100644 --- a/src/plugins/global-settings/preset-controls/presets.json +++ b/src/plugins/global-settings/preset-controls/presets.json @@ -92,6 +92,90 @@ "slug": "xxxxx-large" } ] - } - } + }, + "blockHeights": [ + { + "name": "XS", + "size": "4rem", + "slug": "x-small" + }, + { + "name": "S", + "size": "8rem", + "slug": "small" + }, + { + "name": "M", + "size": "12rem", + "slug": "medium" + }, + { + "name": "L", + "size": "16rem", + "slug": "large" + }, + { + "name": "XL", + "size": "24rem", + "slug": "x-large" + }, + { + "name": "2XL", + "size": "32rem", + "slug": "xx-large" + }, + { + "name": "3XL", + "size": "40rem", + "slug": "xxx-large" + }, + { + "name": "Full", + "size": "100vh", + "slug": "full" + } + ], + "borderRadius": [ + { + "name": "None", + "size": "0px", + "slug": "none" + }, + { + "name": "XS", + "size": "2px", + "slug": "x-small" + }, + { + "name": "S", + "size": "4px", + "slug": "small" + }, + { + "name": "M", + "size": "8px", + "slug": "medium" + }, + { + "name": "L", + "size": "16px", + "slug": "large" + }, + { + "name": "XL", + "size": "24px", + "slug": "x-large" + }, + { + "name": "2XL", + "size": "32px", + "slug": "xx-large" + }, + { + "name": "Full", + "size": "9999px", + "slug": "full" + } + ] + } } From 62275283463ac470f9fb1bdf32e9c2d205392f89 Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Mon, 31 Mar 2025 09:58:26 +0800 Subject: [PATCH 28/99] feat: add blockHeight and borderRadius loader --- .../global-settings/preset-controls/editor-loader.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/plugins/global-settings/preset-controls/editor-loader.js b/src/plugins/global-settings/preset-controls/editor-loader.js index 1164cb3f46..d66aae36fd 100644 --- a/src/plugins/global-settings/preset-controls/editor-loader.js +++ b/src/plugins/global-settings/preset-controls/editor-loader.js @@ -16,6 +16,12 @@ const PRESET_MAPPING = { spacingSizes: { prefix: 'spacing-size', }, + blockHeights: { + prefix: 'block-height', + }, + borderRadius: { + prefix: 'border-radius', + }, } const renderGlobalStyles = ( customPresets, setStyles ) => { From 5d22e5f7a57fc000b5e7f06c1b45414ac915543e Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Mon, 31 Mar 2025 10:11:53 +0800 Subject: [PATCH 29/99] fix: editorLoader merge --- .../preset-controls/editor-loader.js | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 src/plugins/global-settings/preset-controls/editor-loader.js diff --git a/src/plugins/global-settings/preset-controls/editor-loader.js b/src/plugins/global-settings/preset-controls/editor-loader.js new file mode 100644 index 0000000000..d66aae36fd --- /dev/null +++ b/src/plugins/global-settings/preset-controls/editor-loader.js @@ -0,0 +1,57 @@ +/** + * WordPress dependencies + */ +import { useSelect } from '@wordpress/data' +import { useEffect, useState } from '@wordpress/element' + +/** + * External dependencies + */ +import { compact } from 'lodash' + +const PRESET_MAPPING = { + fontSizes: { + prefix: 'font-size', + }, + spacingSizes: { + prefix: 'spacing-size', + }, + blockHeights: { + prefix: 'block-height', + }, + borderRadius: { + prefix: 'border-radius', + }, +} + +const renderGlobalStyles = ( customPresets, setStyles ) => { + let css = '' + + Object.entries( customPresets ).forEach( ( [ key, presets ] ) => { + const styleRules = presets?.map( preset => { + return preset && ( ! preset?.isDiscarded ) + ? `--stk--preset--${ PRESET_MAPPING[ key ]?.prefix }--${ preset?.slug || '' }: ${ preset?.size || '' };` + : '' + } ) + css += compact( styleRules ).join( '' ) + } ) + + css = `:root { ${ css } }` + setStyles( css ) +} + +export const GlobalPresetControlsStyles = () => { + const { customPresets } = useSelect( select => { + const _customPresetControls = select( 'stackable/global-preset-controls.custom' )?.getCustomPresetControls() + return { customPresets: { ..._customPresetControls } ?? [] } + }, [] ) + const [ styles, setStyles ] = useState( '' ) + + useEffect( () => { + if ( customPresets && typeof customPresets === 'object' ) { + renderGlobalStyles( customPresets, setStyles ) + } + }, [ JSON.stringify( customPresets ) ] ) + + return styles +} From 962b8410f1c822069874147d6728864ca08cf8d0 Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Wed, 2 Apr 2025 09:27:14 +0800 Subject: [PATCH 30/99] feat: Use Global Typography sizes as preset --- src/block-components/typography/edit.js | 7 +- src/global-settings.php | 12 ++++ src/hooks/use-preset-controls.js | 7 +- .../global-settings/typography/index.js | 69 ++++++++++++++++++- 4 files changed, 90 insertions(+), 5 deletions(-) diff --git a/src/block-components/typography/edit.js b/src/block-components/typography/edit.js index 83cd0a7ce5..5451880b55 100644 --- a/src/block-components/typography/edit.js +++ b/src/block-components/typography/edit.js @@ -30,6 +30,7 @@ import { } from '@wordpress/element' import { __ } from '@wordpress/i18n' import { applyFilters } from '@wordpress/hooks' +import { useSelect } from '@wordpress/data' const TYPOGRAPHY_SHADOWS = [ 'none', @@ -80,6 +81,10 @@ export const Controls = props => { const attributeName = getAttrNameFunction( attrNameTemplate ) const text = getAttribute( 'text' ) const [ debouncedText, setDebouncedText ] = useState( text ) + const { useTypographyAsPresets } = useSelect( select => { + const _useTypographyAsPresets = select( 'stackable/global-preset-controls.custom' )?.getUseTypographyAsPresets() ?? false + return { useTypographyAsPresets: { ..._useTypographyAsPresets } } + }, [] ) useEffect( () => { if ( text !== debouncedText ) { @@ -100,7 +105,7 @@ export const Controls = props => { const onChangeContent = useCallback( text => setDebouncedText( escapeHTMLIfInvalid( text ) ), [] ) - const presetMarks = usePresetControls( 'fontSizes' )?.getPresetMarks() || null + const presetMarks = usePresetControls( 'fontSizes' )?.getPresetMarks( useTypographyAsPresets ) || null return ( <> diff --git a/src/global-settings.php b/src/global-settings.php index ec8796676c..812e9fccc0 100644 --- a/src/global-settings.php +++ b/src/global-settings.php @@ -412,6 +412,18 @@ public function register_global_settings() { ) ); + register_setting( + 'stackable_global_settings', + 'stackable_use_typography_as_presets', + array( + 'type' => 'boolean', + 'description' => __( 'Use Global Typography font sizes as preset', STACKABLE_I18N ), + 'sanitize_callback' => 'sanitize_text_field', + 'show_in_rest' => true, + 'default' => '', + ) + ); + register_setting( 'stackable_global_settings', 'stackable_icon_library', diff --git a/src/hooks/use-preset-controls.js b/src/hooks/use-preset-controls.js index e7735af306..ab89fa8e21 100644 --- a/src/hooks/use-preset-controls.js +++ b/src/hooks/use-preset-controls.js @@ -55,11 +55,12 @@ export const usePresetControls = property => { } // Get the merge preset marks with the CSS Variable value - const getPresetMarks = () => { + // Setting customOnly to true returns the preset marks for custom presets only + const getPresetMarks = ( customOnly = false ) => { const prefix = PRESET_MAPPING[ property ].prefix - const mergedPresets = getMergedPresets() + const presets = customOnly ? allCustomPresets[ property ] ?? [] : getMergedPresets() - return mergedPresets + return presets .filter( preset => ! ( preset?.isDiscarded ) ) .map( preset => ( { ...preset, diff --git a/src/plugins/global-settings/typography/index.js b/src/plugins/global-settings/typography/index.js index 5750f59620..d9fe2179ad 100644 --- a/src/plugins/global-settings/typography/index.js +++ b/src/plugins/global-settings/typography/index.js @@ -12,7 +12,7 @@ import FREE_FONT_PAIRS from './font-pairs.json' import { PanelAdvancedSettings, AdvancedSelectControl, ControlSeparator, FontPairPicker, ProControlButton, } from '~stackable/components' -import { fetchSettings } from '~stackable/util' +import { fetchSettings, getDefaultFontSize } from '~stackable/util' import { i18n, isPro, showProNotice, } from 'stackable' @@ -29,6 +29,7 @@ import { addFilter, applyFilters, doAction, } from '@wordpress/hooks' import { __, sprintf } from '@wordpress/i18n' +import { dispatch, useSelect } from '@wordpress/data' export { GlobalTypographyStyles } @@ -36,34 +37,50 @@ const TYPOGRAPHY_TAGS = [ { label: sprintf( __( 'Heading %d', i18n ), 1 ), selector: 'h1', + presetName: '5XL', + presetSlug: 'xxxxx-large', }, { label: sprintf( __( 'Heading %d', i18n ), 2 ), selector: 'h2', + presetName: '4XL', + presetSlug: 'xxxx-large', }, { label: sprintf( __( 'Heading %d', i18n ), 3 ), selector: 'h3', + presetName: '3XL', + presetSlug: 'xxx-large', }, { label: sprintf( __( 'Heading %d', i18n ), 4 ), selector: 'h4', + presetName: '2XL', + presetSlug: 'xx-large', }, { label: sprintf( __( 'Heading %d', i18n ), 5 ), selector: 'h5', + presetName: 'XL', + presetSlug: 'x-large', }, { label: sprintf( __( 'Heading %d', i18n ), 6 ), selector: 'h6', + presetName: 'L', + presetSlug: 'large', }, { label: __( 'Body Text', i18n ), selector: 'p', + presetName: 'M', + presetSlug: 'medium', }, { label: __( 'Subtitle', i18n ), selector: '.stk-subtitle', + presetName: 'S', + presetSlug: 'small', help: ( <> { sprintf( __( "To apply this typography style, just add `%s` in your block\'s Additional CSS classes. Also make sure that `%s` tag is set to avoid conflict with other typography styles", i18n ), 'stk-subtitle', 'p' ) } @@ -78,8 +95,15 @@ const TYPOGRAPHY_TAGS = [ let saveTypographyThrottle = null let saveSelectedFontPairThrottle = null let saveCustomFontPairsThrottle = null +let saveTypographyAsPresetsThrottle = null addFilter( 'stackable.global-settings.inspector', 'stackable/global-typography', output => { + const { allCustomPresets, useTypographyAsPresets } = useSelect( select => { + const _customPresetControls = select( 'stackable/global-preset-controls.custom' )?.getCustomPresetControls() ?? {} + const _useTypographyAsPresets = select( 'stackable/global-preset-controls.custom' )?.getUseTypographyAsPresets() ?? false + return { allCustomPresets: { ..._customPresetControls }, useTypographyAsPresets: { ..._useTypographyAsPresets } } + }, [] ) + const FONT_PAIRS = applyFilters( 'stackable.global-settings.typography.font-pairs.premium-font-pairs', FREE_FONT_PAIRS ) const [ isPanelOpen, setIsPanelOpen ] = useState( false ) @@ -104,6 +128,49 @@ addFilter( 'stackable.global-settings.inspector', 'stackable/global-typography', // When typography styles are changed, trigger our editor style generator to update. useEffect( () => { doAction( 'stackable.global-settings.typography.update-trigger', typographySettings, applySettingsTo ) + + if ( useTypographyAsPresets ) { + const fontSizePresets = TYPOGRAPHY_TAGS + .filter( ( { presetSlug } ) => !! presetSlug ) + .map( ( { + selector, presetName, presetSlug, + } ) => { + const size = typographySettings[ selector ]?.fontSize ?? getDefaultFontSize( selector ) ?? 16 + const unit = typographySettings[ selector ]?.fontSizeUnit ?? 'px' + return { + name: presetName, + slug: presetSlug, + size: `${ size }${ unit }`, + } + } ) + // Add the preset for extra small + let xSmallSize = typographySettings[ '.stk-subtitle' ]?.fontSize ?? getDefaultFontSize( '.stk-subtitle' ) ?? 16 + let xSmallUnit = typographySettings[ '.stk-subtitle' ]?.fontSizeUnit ?? 'px' + if ( xSmallUnit === 'px' ) { + xSmallSize = Math.pow( xSmallSize / 16, 2 ) + xSmallUnit = 'rem' + } else { + xSmallSize = Math.pow( xSmallSize, 2 ) + } + + fontSizePresets.push( { + name: 'XS', + slug: 'x-small', + size: `${ xSmallSize }${ xSmallUnit ?? 'px' }`, + } ) + // Reverse the presets so it's from smallest to biggest + fontSizePresets.reverse() + + const newSettings = { ...allCustomPresets, fontSizes: fontSizePresets } + + clearTimeout( saveTypographyAsPresetsThrottle ) + saveTypographyAsPresetsThrottle = setTimeout( () => { + const settings = new models.Settings( { stackable_global_custom_preset_controls: newSettings } ) // eslint-disable-line camelcase + settings.save() + }, 300 ) + + dispatch( 'stackable/global-preset-controls.custom' ).updateCustomPresetControls( newSettings ) + } }, [ JSON.stringify( typographySettings ), applySettingsTo ] ) // Scroll to the selected font pair when Global Typography tab is toggled From d0b7cba04404f1c38069a6951567b5c7f8848c01 Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Wed, 2 Apr 2025 10:31:47 +0800 Subject: [PATCH 31/99] feat: add vertical/horizontal to mark mode for four range --- src/block-components/button/edit.js | 9 +++- src/components/four-range-control/index.js | 57 +++++++++++++++++++--- 2 files changed, 57 insertions(+), 9 deletions(-) diff --git a/src/block-components/button/edit.js b/src/block-components/button/edit.js index ed363ca0c1..9a58b50e3f 100644 --- a/src/block-components/button/edit.js +++ b/src/block-components/button/edit.js @@ -12,7 +12,9 @@ import { AdvancedSelectControl, } from '~stackable/components' import { i18n } from 'stackable' -import { useBlockAttributesContext, useBlockLayoutDefaults } from '~stackable/hooks' +import { + useBlockAttributesContext, useBlockLayoutDefaults, usePresetControls, +} from '~stackable/hooks' /** * WordPress dependencies @@ -185,6 +187,9 @@ const SizeControls = props => { const { getPlaceholder } = useBlockLayoutDefaults() const buttonPaddingPlaceholder = getPlaceholder( paddingPlaceholderName, { single: false } ) + + const presetMarks = usePresetControls( 'spacingSizes' )?.getPresetMarks() || null + return ( <> { props.hasFullWidth && ( { title: __( 'Button padding', i18n ), description: __( 'Adjusts the space between the button text and button borders', i18n ), } } + marks={ presetMarks } + hasCSSVariableValue={ true } /> ) } diff --git a/src/components/four-range-control/index.js b/src/components/four-range-control/index.js index 0986423033..73a0f361e6 100644 --- a/src/components/four-range-control/index.js +++ b/src/components/four-range-control/index.js @@ -347,6 +347,7 @@ const FourRangeControl = memo( props => { ] } + // Create step supports for each side const [ propsToPassFirst, rangeValueFirst, rangeOnChangeFirst ] = stepSupport( isFourMarkMode.first, firstValue, @@ -377,6 +378,18 @@ const FourRangeControl = memo( props => { onChangeLeft, ) + const [ propsToPassVertical, rangeValueVertical, rangeOnChangeVertical ] = stepSupport( + isFourMarkMode.top, + value.top, + onChangeVertical, + ) + + const [ propsToPassHorizontal, rangeValueHorizontal, rangeOnChangeHorizontal ] = stepSupport( + isFourMarkMode.left, + value.left, + onChangeHorizontal, + ) + return ( { isLocked && ! props.vhMode && ( @@ -442,9 +455,9 @@ const FourRangeControl = memo( props => { { if ( currentHoverState !== 'normal' ) { @@ -472,7 +485,21 @@ const FourRangeControl = memo( props => { return typeof props.placeholderTop === 'undefined' ? propsToPass.placeholder : props.placeholderTop } )() } - /> + __nextHasNoMarginBottom + > + { props.allowCustom && props.marks && ( + + ) } + { { if ( currentHoverState !== 'normal' ) { @@ -514,7 +541,21 @@ const FourRangeControl = memo( props => { } return typeof props.placeholderLeft === 'undefined' ? propsToPass.placeholder : props.placeholderLeft } )() } - /> + __nextHasNoMarginBottom + > + { props.allowCustom && props.marks && ( + + ) } + Date: Wed, 2 Apr 2025 11:05:45 +0800 Subject: [PATCH 32/99] fix: removing of unit picker according to four range mode --- src/components/four-range-control/index.js | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/components/four-range-control/index.js b/src/components/four-range-control/index.js index 73a0f361e6..ff011f6490 100644 --- a/src/components/four-range-control/index.js +++ b/src/components/four-range-control/index.js @@ -305,7 +305,6 @@ const FourRangeControl = memo( props => { // Other necessary props for steps. newProps.withInputField = false - controlProps.units = false } else { newProps.marks = undefined } @@ -347,6 +346,18 @@ const FourRangeControl = memo( props => { ] } + // Remove the unit picker if not in mark mode for every four range mode + if ( isLocked && ! props.vhMode ) { + controlProps.units = isFourMarkMode.first + ? false : controlProps.units + } else if ( isLocked && props.vhMode ) { + controlProps.units = isFourMarkMode.top && isFourMarkMode.left + ? false : controlProps.units + } else { + controlProps.units = isFourMarkMode.top && isFourMarkMode.right && isFourMarkMode.bottom && isFourMarkMode.left + ? false : controlProps.units + } + // Create step supports for each side const [ propsToPassFirst, rangeValueFirst, rangeOnChangeFirst ] = stepSupport( isFourMarkMode.first, From 9047dca37dc27e8ac5344d3e359aaf5a6047920f Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Thu, 3 Apr 2025 10:11:49 +0800 Subject: [PATCH 33/99] fix: useTypographyAsPresets reactivity --- src/block-components/typography/edit.js | 7 +++---- src/plugins/global-settings/typography/index.js | 7 ++++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/block-components/typography/edit.js b/src/block-components/typography/edit.js index 5451880b55..3e86c9576c 100644 --- a/src/block-components/typography/edit.js +++ b/src/block-components/typography/edit.js @@ -81,10 +81,9 @@ export const Controls = props => { const attributeName = getAttrNameFunction( attrNameTemplate ) const text = getAttribute( 'text' ) const [ debouncedText, setDebouncedText ] = useState( text ) - const { useTypographyAsPresets } = useSelect( select => { - const _useTypographyAsPresets = select( 'stackable/global-preset-controls.custom' )?.getUseTypographyAsPresets() ?? false - return { useTypographyAsPresets: { ..._useTypographyAsPresets } } - }, [] ) + const useTypographyAsPresets = useSelect( select => + select( 'stackable/global-preset-controls.custom' )?.getUseTypographyAsPresets() ?? false + ) useEffect( () => { if ( text !== debouncedText ) { diff --git a/src/plugins/global-settings/typography/index.js b/src/plugins/global-settings/typography/index.js index d9fe2179ad..3252236757 100644 --- a/src/plugins/global-settings/typography/index.js +++ b/src/plugins/global-settings/typography/index.js @@ -101,7 +101,7 @@ addFilter( 'stackable.global-settings.inspector', 'stackable/global-typography', const { allCustomPresets, useTypographyAsPresets } = useSelect( select => { const _customPresetControls = select( 'stackable/global-preset-controls.custom' )?.getCustomPresetControls() ?? {} const _useTypographyAsPresets = select( 'stackable/global-preset-controls.custom' )?.getUseTypographyAsPresets() ?? false - return { allCustomPresets: { ..._customPresetControls }, useTypographyAsPresets: { ..._useTypographyAsPresets } } + return { allCustomPresets: { ..._customPresetControls }, useTypographyAsPresets: _useTypographyAsPresets } }, [] ) const FONT_PAIRS = applyFilters( 'stackable.global-settings.typography.font-pairs.premium-font-pairs', FREE_FONT_PAIRS ) @@ -125,10 +125,11 @@ addFilter( 'stackable.global-settings.inspector', 'stackable/global-typography', } ) }, [] ) - // When typography styles are changed, trigger our editor style generator to update. useEffect( () => { + // When typography styles are changed, trigger our editor style generator to update. doAction( 'stackable.global-settings.typography.update-trigger', typographySettings, applySettingsTo ) + // Update the custom presets when using typography as presets if ( useTypographyAsPresets ) { const fontSizePresets = TYPOGRAPHY_TAGS .filter( ( { presetSlug } ) => !! presetSlug ) @@ -171,7 +172,7 @@ addFilter( 'stackable.global-settings.inspector', 'stackable/global-typography', dispatch( 'stackable/global-preset-controls.custom' ).updateCustomPresetControls( newSettings ) } - }, [ JSON.stringify( typographySettings ), applySettingsTo ] ) + }, [ JSON.stringify( typographySettings ), applySettingsTo, useTypographyAsPresets ] ) // Scroll to the selected font pair when Global Typography tab is toggled useEffect( () => { From cd1cbc143e704c482188b5b98b009b52ee789be4 Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Fri, 4 Apr 2025 15:35:09 +0800 Subject: [PATCH 34/99] feat: initial init --- .../global-settings/typography/index.js | 80 ++++++++++++++++++- 1 file changed, 77 insertions(+), 3 deletions(-) diff --git a/src/plugins/global-settings/typography/index.js b/src/plugins/global-settings/typography/index.js index 3252236757..e079fdb0c5 100644 --- a/src/plugins/global-settings/typography/index.js +++ b/src/plugins/global-settings/typography/index.js @@ -92,6 +92,18 @@ const TYPOGRAPHY_TAGS = [ }, ] +const TYPE_SCALE = [ + { label: __( 'None / Custom', i18n ), value: 1 }, + { label: __( '1.067 - Minor Second', i18n ), value: 1.067 }, + { label: __( '1.125 - Major Second', i18n ), value: 1.125 }, + { label: __( '1.200 - Minor Third', i18n ), value: 1.2 }, + { label: __( '1.250 - Major Third', i18n ), value: 1.25 }, + { label: __( '1.333 - Perfect Fourth', i18n ), value: 1.333 }, + { label: __( '1.414 - Augmented Fourth', i18n ), value: 1.414 }, + { label: __( '1.500 - Perfect Fifth', i18n ), value: 1.5 }, + { label: __( '1.618 - Golden Ratio', i18n ), value: 1.618 }, +] + let saveTypographyThrottle = null let saveSelectedFontPairThrottle = null let saveCustomFontPairsThrottle = null @@ -112,16 +124,35 @@ addFilter( 'stackable.global-settings.inspector', 'stackable/global-typography', const [ customFontPairs, setCustomFontPairs ] = useState( [] ) const [ selectedFontPairName, setSelectedFontPairName ] = useState( '' ) const [ isEditingFontPair, setIsEditingFontPair ] = useState( false ) + const [ selectedTypeScale, setSelectedTypeScale ] = useState( 1 ) const fontPairContainerRef = useRef( null ) useEffect( () => { fetchSettings().then( response => { // Get settings. - setTypographySettings( ( head( response.stackable_global_typography ) ) || {} ) + const _typographySettings = ( head( response.stackable_global_typography ) ) || {} + setTypographySettings( _typographySettings ) setApplySettingsTo( response.stackable_global_typography_apply_to || 'blocks-stackable-native' ) setCustomFontPairs( response.stackable_custom_font_pairs || [] ) setSelectedFontPairName( response.stackable_selected_font_pair || '' ) + + // Reversely compute the type scale from the font sizes + // Check first if the units are rem + if ( Object.values( _typographySettings ).every( setting => setting.fontSizeUnit === 'rem' ) ) { + let typeScale = _typographySettings?.h6?.fontSize + const computedApplied = getAppliedTypeScale( typeScale ) + + const tags = Object.keys( _typographySettings ) + for ( const tag of tags ) { + // If font size mismatch, set typography scale to None / Custom + if ( _typographySettings[ tag ].fontSize !== computedApplied[ tag ].fontSize ) { + typeScale = 1 + } + } + + setSelectedTypeScale( typeScale ) + } } ) }, [] ) @@ -194,6 +225,19 @@ addFilter( 'stackable.global-settings.inspector', 'stackable/global-typography', return [ ...FONT_PAIRS, ...customFontPairs ].find( fontPair => fontPair.name === selectedFontPairName ) } + const getAppliedTypeScale = typeScale => ( { + h1: { fontSize: Number( Math.pow( typeScale, 6 ).toFixed( 3 ) ), fontSizeUnit: 'rem' }, + h2: { fontSize: Number( Math.pow( typeScale, 5 ).toFixed( 3 ) ), fontSizeUnit: 'rem' }, + h3: { fontSize: Number( Math.pow( typeScale, 4 ).toFixed( 3 ) ), fontSizeUnit: 'rem' }, + h4: { fontSize: Number( Math.pow( typeScale, 3 ).toFixed( 3 ) ), fontSizeUnit: 'rem' }, + h5: { fontSize: Number( Math.pow( typeScale, 2 ).toFixed( 3 ) ), fontSizeUnit: 'rem' }, + h6: { fontSize: Number( typeScale.toFixed( 3 ) ), fontSizeUnit: 'rem' }, + p: { fontSize: 1, fontSizeUnit: 'rem' }, + '.stk-subtitle': { fontSize: Number( ( 1 / typeScale ).toFixed( 3 ) ), fontSizeUnit: 'rem' }, + '.stk-button__inner-text': { fontSize: 1, fontSizeUnit: 'rem' }, + + } ) + const updateTypography = newSettings => { setTypographySettings( newSettings ) @@ -238,6 +282,21 @@ addFilter( 'stackable.global-settings.inspector', 'stackable/global-typography', model.save() } + const updateTypeScale = value => { + const typeScale = Number( value ) + if ( isNaN( typeScale ) ) { + return + } + + setSelectedTypeScale( typeScale ) + + // Only update the typography settings if not None/Custom + if ( typeScale !== 1 ) { + const newSettings = getAppliedTypeScale( typeScale ) + changeStyles( newSettings ) + } + } + const changeStyles = typography => { const newSettings = { ...typographySettings } @@ -433,6 +492,13 @@ addFilter( 'stackable.global-settings.inspector', 'stackable/global-typography',

    { __( 'Typography Settings' ) }

    + { TYPOGRAPHY_TAGS.map( ( { label, selector, help, }, index ) => { @@ -445,8 +511,16 @@ addFilter( 'stackable.global-settings.inspector', 'stackable/global-typography', value={ ( typographySettings[ selector ] ) || {} } defaultFontFamily={ getDefaultFontFamily( selector ) } isAllowReset={ getIsAllowReset( selector ) } - onChange={ styles => changeStyles( { [ selector ]: styles } ) } - onReset={ () => resetStyles( selector ) } + onChange={ styles => { + changeStyles( { [ selector ]: styles } ) + // Also set the typescale to None/Custom + setSelectedTypeScale( 1 ) + } } + onReset={ () => { + resetStyles( selector ) + // Also set the typescale to None/Custom + setSelectedTypeScale( 1 ) + } } /> ) } ) } From 045f6a03d5ffa3ed42e03adf1a193fc62712171b Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Sat, 5 Apr 2025 22:30:39 +0800 Subject: [PATCH 35/99] fix: separate none and custom, fix issue with setting to none --- .../global-settings/typography/index.js | 143 ++++++++++++------ 1 file changed, 97 insertions(+), 46 deletions(-) diff --git a/src/plugins/global-settings/typography/index.js b/src/plugins/global-settings/typography/index.js index e079fdb0c5..1e4dcfa0e8 100644 --- a/src/plugins/global-settings/typography/index.js +++ b/src/plugins/global-settings/typography/index.js @@ -16,7 +16,9 @@ import { fetchSettings, getDefaultFontSize } from '~stackable/util' import { i18n, isPro, showProNotice, } from 'stackable' -import { head, isEqual } from 'lodash' +import { + head, isEqual, cloneDeep, +} from 'lodash' /** * WordPress dependencies @@ -93,15 +95,47 @@ const TYPOGRAPHY_TAGS = [ ] const TYPE_SCALE = [ - { label: __( 'None / Custom', i18n ), value: 1 }, - { label: __( '1.067 - Minor Second', i18n ), value: 1.067 }, - { label: __( '1.125 - Major Second', i18n ), value: 1.125 }, - { label: __( '1.200 - Minor Third', i18n ), value: 1.2 }, - { label: __( '1.250 - Major Third', i18n ), value: 1.25 }, - { label: __( '1.333 - Perfect Fourth', i18n ), value: 1.333 }, - { label: __( '1.414 - Augmented Fourth', i18n ), value: 1.414 }, - { label: __( '1.500 - Perfect Fifth', i18n ), value: 1.5 }, - { label: __( '1.618 - Golden Ratio', i18n ), value: 1.618 }, + { + label: __( 'None', i18n ), + value: 'none', + }, + { + label: __( 'Custom', i18n ), + value: 'custom', + disabled: true, + }, + { + label: __( '1.067 - Minor Second', i18n ), + value: '1.067', + }, + { + label: __( '1.125 - Major Second', i18n ), + value: '1.125', + }, + { + label: __( '1.200 - Minor Third', i18n ), + value: '1.2', + }, + { + label: __( '1.250 - Major Third', i18n ), + value: '1.25', + }, + { + label: __( '1.333 - Perfect Fourth', i18n ), + value: '1.333', + }, + { + label: __( '1.414 - Augmented Fourth', i18n ), + value: '1.414', + }, + { + label: __( '1.500 - Perfect Fifth', i18n ), + value: '1.5', + }, + { + label: __( '1.618 - Golden Ratio', i18n ), + value: '1.618', + }, ] let saveTypographyThrottle = null @@ -124,7 +158,7 @@ addFilter( 'stackable.global-settings.inspector', 'stackable/global-typography', const [ customFontPairs, setCustomFontPairs ] = useState( [] ) const [ selectedFontPairName, setSelectedFontPairName ] = useState( '' ) const [ isEditingFontPair, setIsEditingFontPair ] = useState( false ) - const [ selectedTypeScale, setSelectedTypeScale ] = useState( 1 ) + const [ selectedTypeScale, setSelectedTypeScale ] = useState( 'none' ) const fontPairContainerRef = useRef( null ) @@ -135,22 +169,19 @@ addFilter( 'stackable.global-settings.inspector', 'stackable/global-typography', setTypographySettings( _typographySettings ) setApplySettingsTo( response.stackable_global_typography_apply_to || 'blocks-stackable-native' ) setCustomFontPairs( response.stackable_custom_font_pairs || [] ) - setSelectedFontPairName( response.stackable_selected_font_pair || '' ) + setSelectedFontPairName( response.stackable_selected_font_pair || 'theme-heading-default/theme-body-default' ) // Reversely compute the type scale from the font sizes - // Check first if the units are rem - if ( Object.values( _typographySettings ).every( setting => setting.fontSizeUnit === 'rem' ) ) { - let typeScale = _typographySettings?.h6?.fontSize - const computedApplied = getAppliedTypeScale( typeScale ) - + let typeScale = _typographySettings?.h6?.fontSize + if ( typeScale ) { + const computedApplied = getAppliedTypeScale( typeScale ) ?? {} const tags = Object.keys( _typographySettings ) for ( const tag of tags ) { - // If font size mismatch, set typography scale to None / Custom - if ( _typographySettings[ tag ].fontSize !== computedApplied[ tag ].fontSize ) { - typeScale = 1 + // If font size mismatch, set typography scale to Custom + if ( _typographySettings[ tag ]?.fontSize !== computedApplied[ tag ]?.fontSize ) { + typeScale = 'custom' } } - setSelectedTypeScale( typeScale ) } } ) @@ -225,18 +256,23 @@ addFilter( 'stackable.global-settings.inspector', 'stackable/global-typography', return [ ...FONT_PAIRS, ...customFontPairs ].find( fontPair => fontPair.name === selectedFontPairName ) } - const getAppliedTypeScale = typeScale => ( { - h1: { fontSize: Number( Math.pow( typeScale, 6 ).toFixed( 3 ) ), fontSizeUnit: 'rem' }, - h2: { fontSize: Number( Math.pow( typeScale, 5 ).toFixed( 3 ) ), fontSizeUnit: 'rem' }, - h3: { fontSize: Number( Math.pow( typeScale, 4 ).toFixed( 3 ) ), fontSizeUnit: 'rem' }, - h4: { fontSize: Number( Math.pow( typeScale, 3 ).toFixed( 3 ) ), fontSizeUnit: 'rem' }, - h5: { fontSize: Number( Math.pow( typeScale, 2 ).toFixed( 3 ) ), fontSizeUnit: 'rem' }, - h6: { fontSize: Number( typeScale.toFixed( 3 ) ), fontSizeUnit: 'rem' }, - p: { fontSize: 1, fontSizeUnit: 'rem' }, - '.stk-subtitle': { fontSize: Number( ( 1 / typeScale ).toFixed( 3 ) ), fontSizeUnit: 'rem' }, - '.stk-button__inner-text': { fontSize: 1, fontSizeUnit: 'rem' }, - - } ) + const getAppliedTypeScale = value => { + const typeScale = Number( value ) + if ( Number.isNaN( typeScale ) ) { + return + } + return { + h1: { fontSize: Number( Math.pow( typeScale, 6 ).toFixed( 3 ) ), fontSizeUnit: 'rem' }, + h2: { fontSize: Number( Math.pow( typeScale, 5 ).toFixed( 3 ) ), fontSizeUnit: 'rem' }, + h3: { fontSize: Number( Math.pow( typeScale, 4 ).toFixed( 3 ) ), fontSizeUnit: 'rem' }, + h4: { fontSize: Number( Math.pow( typeScale, 3 ).toFixed( 3 ) ), fontSizeUnit: 'rem' }, + h5: { fontSize: Number( Math.pow( typeScale, 2 ).toFixed( 3 ) ), fontSizeUnit: 'rem' }, + h6: { fontSize: Number( typeScale.toFixed( 3 ) ), fontSizeUnit: 'rem' }, + p: { fontSize: 1, fontSizeUnit: 'rem' }, + '.stk-subtitle': { fontSize: Number( ( 1 / typeScale ).toFixed( 3 ) ), fontSizeUnit: 'rem' }, + '.stk-button__inner-text': { fontSize: 1, fontSizeUnit: 'rem' }, + } + } const updateTypography = newSettings => { setTypographySettings( newSettings ) @@ -283,21 +319,31 @@ addFilter( 'stackable.global-settings.inspector', 'stackable/global-typography', } const updateTypeScale = value => { - const typeScale = Number( value ) - if ( isNaN( typeScale ) ) { + setSelectedTypeScale( value ) + + // If value is custom, do not do anything + if ( value === 'custom ' ) { return } - setSelectedTypeScale( typeScale ) - - // Only update the typography settings if not None/Custom - if ( typeScale !== 1 ) { - const newSettings = getAppliedTypeScale( typeScale ) + // If value is none, reset the font sizes and units + if ( value === 'none' ) { + const selectors = TYPOGRAPHY_TAGS.map( tag => tag.selector ) + const newSettings = selectors.reduce( ( acc, selector, ) => { + acc[ selector ] = { fontSize: '', fontSizeUnit: '' } + return acc + }, {} ) changeStyles( newSettings ) + return } + + // If value is valid type scale, apply to the styles + const newSettings = getAppliedTypeScale( value ) + changeStyles( newSettings ) } - const changeStyles = typography => { + const changeStyles = _typography => { + const typography = cloneDeep( _typography ) const newSettings = { ...typographySettings } Object.entries( typography ).forEach( ( [ selector, styles ] ) => { @@ -497,7 +543,7 @@ addFilter( 'stackable.global-settings.inspector', 'stackable/global-typography', options={ TYPE_SCALE } value={ selectedTypeScale } onChange={ updateTypeScale } - default={ 1 } + default="none" /> { TYPOGRAPHY_TAGS.map( ( { label, selector, help, @@ -513,13 +559,18 @@ addFilter( 'stackable.global-settings.inspector', 'stackable/global-typography', isAllowReset={ getIsAllowReset( selector ) } onChange={ styles => { changeStyles( { [ selector ]: styles } ) - // Also set the typescale to None/Custom - setSelectedTypeScale( 1 ) + // Set typeScale to custom when editing font size or units + if ( 'fontSize' in styles || 'fontSizeUnit' in styles ) { + setSelectedTypeScale( 'custom' ) + } } } onReset={ () => { resetStyles( selector ) - // Also set the typescale to None/Custom - setSelectedTypeScale( 1 ) + // Set typeScale to custom when editing font size or units + const styles = typographySettings[ selector ] + if ( 'fontSize' in styles || 'fontSizeUnit' in styles ) { + setSelectedTypeScale( 'custom' ) + } } } /> ) From bbe3dcaab9c12457d8636aba657d6b7b19334d44 Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Sun, 6 Apr 2025 11:08:29 +0800 Subject: [PATCH 36/99] fix: selecting font pair/type scale overwritting previous changes --- src/plugins/global-settings/typography/index.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/plugins/global-settings/typography/index.js b/src/plugins/global-settings/typography/index.js index 1e4dcfa0e8..f341ebb733 100644 --- a/src/plugins/global-settings/typography/index.js +++ b/src/plugins/global-settings/typography/index.js @@ -350,6 +350,13 @@ addFilter( 'stackable.global-settings.inspector', 'stackable/global-typography', if ( ! selector || typeof styles !== 'object' ) { return } + + // Merge the new styles with the previous, while overwritting similar styles. + // This allow adding styles without removing the previous ones. + // Check if the object is empty, used for resetting the whole setting. + if ( Object.keys( styles ).length !== 0 ) { + styles = { ...newSettings[ selector ], ...styles } + } /** * Delete the object keys with empty strings. * Otherwise, the API will throw an error code 400 From c817adaa6d5823d51ccec7b6f583f0fbd26c30e0 Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Sun, 6 Apr 2025 11:16:12 +0800 Subject: [PATCH 37/99] chore: move other functions to utils --- .../global-settings/typography/index.js | 19 +----------- .../global-settings/typography/utils.js | 29 +++++++++++++++++++ 2 files changed, 30 insertions(+), 18 deletions(-) create mode 100644 src/plugins/global-settings/typography/utils.js diff --git a/src/plugins/global-settings/typography/index.js b/src/plugins/global-settings/typography/index.js index f341ebb733..45c1f47d5a 100644 --- a/src/plugins/global-settings/typography/index.js +++ b/src/plugins/global-settings/typography/index.js @@ -5,6 +5,7 @@ import { GlobalTypographyStyles } from './editor-loader' import TypographyPicker from './typography-picker' import { getThemeStyles } from './get-theme-styles' import FREE_FONT_PAIRS from './font-pairs.json' +import { getAppliedTypeScale } from './utils' /** * External dependencies @@ -256,24 +257,6 @@ addFilter( 'stackable.global-settings.inspector', 'stackable/global-typography', return [ ...FONT_PAIRS, ...customFontPairs ].find( fontPair => fontPair.name === selectedFontPairName ) } - const getAppliedTypeScale = value => { - const typeScale = Number( value ) - if ( Number.isNaN( typeScale ) ) { - return - } - return { - h1: { fontSize: Number( Math.pow( typeScale, 6 ).toFixed( 3 ) ), fontSizeUnit: 'rem' }, - h2: { fontSize: Number( Math.pow( typeScale, 5 ).toFixed( 3 ) ), fontSizeUnit: 'rem' }, - h3: { fontSize: Number( Math.pow( typeScale, 4 ).toFixed( 3 ) ), fontSizeUnit: 'rem' }, - h4: { fontSize: Number( Math.pow( typeScale, 3 ).toFixed( 3 ) ), fontSizeUnit: 'rem' }, - h5: { fontSize: Number( Math.pow( typeScale, 2 ).toFixed( 3 ) ), fontSizeUnit: 'rem' }, - h6: { fontSize: Number( typeScale.toFixed( 3 ) ), fontSizeUnit: 'rem' }, - p: { fontSize: 1, fontSizeUnit: 'rem' }, - '.stk-subtitle': { fontSize: Number( ( 1 / typeScale ).toFixed( 3 ) ), fontSizeUnit: 'rem' }, - '.stk-button__inner-text': { fontSize: 1, fontSizeUnit: 'rem' }, - } - } - const updateTypography = newSettings => { setTypographySettings( newSettings ) diff --git a/src/plugins/global-settings/typography/utils.js b/src/plugins/global-settings/typography/utils.js new file mode 100644 index 0000000000..5e98ee3775 --- /dev/null +++ b/src/plugins/global-settings/typography/utils.js @@ -0,0 +1,29 @@ +/** + * Generates a typographic scale based on the given value. + * + * This function returns an object where each key represents a text element + * (e.g., `h1`, `h2`, `p`, etc.) and its value contains a `fontSize` and `fontSizeUnit`, + * calculated using an exponential scale. + * + * @param {string|number} value - The base number to use for the typographic scale. + * @return {Object|undefined} An object mapping CSS selectors to their corresponding + * font size settings. Returns `undefined` if input is invalid. + */ + +export const getAppliedTypeScale = value => { + const typeScale = Number( value ) + if ( Number.isNaN( typeScale ) ) { + return + } + return { + h1: { fontSize: Number( Math.pow( typeScale, 6 ).toFixed( 3 ) ), fontSizeUnit: 'rem' }, + h2: { fontSize: Number( Math.pow( typeScale, 5 ).toFixed( 3 ) ), fontSizeUnit: 'rem' }, + h3: { fontSize: Number( Math.pow( typeScale, 4 ).toFixed( 3 ) ), fontSizeUnit: 'rem' }, + h4: { fontSize: Number( Math.pow( typeScale, 3 ).toFixed( 3 ) ), fontSizeUnit: 'rem' }, + h5: { fontSize: Number( Math.pow( typeScale, 2 ).toFixed( 3 ) ), fontSizeUnit: 'rem' }, + h6: { fontSize: Number( typeScale.toFixed( 3 ) ), fontSizeUnit: 'rem' }, + p: { fontSize: 1, fontSizeUnit: 'rem' }, + '.stk-subtitle': { fontSize: Number( ( 1 / typeScale ).toFixed( 3 ) ), fontSizeUnit: 'rem' }, + '.stk-button__inner-text': { fontSize: 1, fontSizeUnit: 'rem' }, + } +} From 477cfbe809d37eaa910f22373c0c9f55cdd1c218 Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Sun, 6 Apr 2025 12:21:39 +0800 Subject: [PATCH 38/99] fix: only get the new style for onChange, since changeStyle now handles merging --- src/plugins/global-settings/typography/typography-picker.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/plugins/global-settings/typography/typography-picker.js b/src/plugins/global-settings/typography/typography-picker.js index 9b5ae1e7d3..bf949662ef 100644 --- a/src/plugins/global-settings/typography/typography-picker.js +++ b/src/plugins/global-settings/typography/typography-picker.js @@ -20,10 +20,9 @@ import { Dashicon } from '@wordpress/components' const TypographyPicker = props => { const { value, help } = props - // On style change, gather all the styles then trigger the onChange. + // On style change, only get the new style then trigger the onChange. const onChange = ( style, value ) => { const newStyles = { - ...props.value, [ style ]: value, } props.onChange( newStyles ) From 3f4f8ec0c2a12fbdc9e163abd97b06f02f53b31c Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Sun, 6 Apr 2025 14:32:52 +0800 Subject: [PATCH 39/99] fix: set the value when changing from mark to custom --- src/components/advanced-range-control/index.js | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/components/advanced-range-control/index.js b/src/components/advanced-range-control/index.js index 6ef56962b7..62ad2c89c9 100644 --- a/src/components/advanced-range-control/index.js +++ b/src/components/advanced-range-control/index.js @@ -189,13 +189,12 @@ const AdvancedRangeControl = props => { const [ _value, _unit ] = extractNumberAndUnit( mark.value ) return _value === derivedValue } ) - rangeOnChange = value => { + rangeOnChange = ( value, property = 'value' ) => { if ( value === '' ) { return _onChange( value ) } - // Extract the unit and value. - const markValue = props.marks[ value ]?.value || '0' + const markValue = props.marks[ value ]?.[ property ] || '0' const [ _newValue, unit ] = extractNumberAndUnit( markValue ) const newValue = _newValue @@ -229,7 +228,13 @@ const AdvancedRangeControl = props => { className="stk-range-control__custom-button" size="small" variant="tertiary" - onClick={ () => setIsMarkMode( ! isMarkMode ) } + onClick={ () => { + // Set the value when changing from mark mode to custom + if ( isMarkMode && rangeValue ) { + rangeOnChange( rangeValue, 'size' ) + } + setIsMarkMode( ! isMarkMode ) + } } icon={ settings } > From 0b33f3a43c33971a4c799f6f2160275e3b19a881 Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Sun, 6 Apr 2025 15:15:01 +0800 Subject: [PATCH 40/99] fix: typography min and max slider for rem --- src/block-components/typography/edit.js | 6 +++--- src/components/advanced-range-control/index.js | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/block-components/typography/edit.js b/src/block-components/typography/edit.js index 3e86c9576c..ea1a00f749 100644 --- a/src/block-components/typography/edit.js +++ b/src/block-components/typography/edit.js @@ -265,9 +265,9 @@ export const Controls = props => { allowReset={ true } attribute={ attributeName( 'fontSize' ) } units={ [ 'px', 'em', 'rem' ] } - min={ [ 0, 0 ] } - sliderMax={ [ 150, 7 ] } - step={ [ 1, 0.05 ] } + min={ [ 0, 0, 0 ] } + sliderMax={ [ 150, 7, 7 ] } + step={ [ 1, 0.05, 0.05 ] } placeholder={ props.sizePlaceholder } responsive="all" helpTooltip={ { diff --git a/src/components/advanced-range-control/index.js b/src/components/advanced-range-control/index.js index 62ad2c89c9..4de53e3073 100644 --- a/src/components/advanced-range-control/index.js +++ b/src/components/advanced-range-control/index.js @@ -230,7 +230,7 @@ const AdvancedRangeControl = props => { variant="tertiary" onClick={ () => { // Set the value when changing from mark mode to custom - if ( isMarkMode && rangeValue ) { + if ( isMarkMode && rangeValue !== -1 ) { rangeOnChange( rangeValue, 'size' ) } setIsMarkMode( ! isMarkMode ) From 558d0fefb907505044608b92c04ebf6e9ac337fe Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Sun, 6 Apr 2025 20:38:22 +0800 Subject: [PATCH 41/99] fix: use only "var" in detecting CSS variable --- src/block-components/columns/style.js | 8 ++++---- src/block-components/helpers/borders/style.js | 8 ++++---- src/components/advanced-range-control/index.js | 2 +- src/components/block-css/index.js | 2 +- src/components/four-range-control/index.js | 2 +- src/util/styles/style-object.js | 2 +- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/block-components/columns/style.js b/src/block-components/columns/style.js index 890e5cb1cc..2355a4d16a 100644 --- a/src/block-components/columns/style.js +++ b/src/block-components/columns/style.js @@ -33,7 +33,7 @@ export const addStyles = ( blockStyleGenerator, props = {} ) => { responsive: 'all', valueCallback: value => { // Substitute with using format to work with preset controls - if ( value.startsWith( 'var(--stk' ) ) { + if ( value.startsWith( 'var' ) ) { return value } return value + 'px' @@ -46,7 +46,7 @@ export const addStyles = ( blockStyleGenerator, props = {} ) => { attrName: 'columnGap', responsive: 'all', valueCallback: value => { - if ( value.startsWith( 'var(--stk' ) ) { + if ( value.startsWith( 'var' ) ) { return value } return value + 'px' @@ -91,7 +91,7 @@ export const addStyles = ( blockStyleGenerator, props = {} ) => { attrName: 'rowGap', responsive: 'all', valueCallback: value => { - if ( value.startsWith( 'var(--stk' ) ) { + if ( value.startsWith( 'var' ) ) { return value } return value + 'px' @@ -104,7 +104,7 @@ export const addStyles = ( blockStyleGenerator, props = {} ) => { attrName: 'rowGap', responsive: 'all', valueCallback: value => { - if ( value.startsWith( 'var(--stk' ) ) { + if ( value.startsWith( 'var' ) ) { return value } return value + 'px' diff --git a/src/block-components/helpers/borders/style.js b/src/block-components/helpers/borders/style.js index ab53790d33..d1b9e4a2d6 100644 --- a/src/block-components/helpers/borders/style.js +++ b/src/block-components/helpers/borders/style.js @@ -39,7 +39,7 @@ export const addBorderStyles = ( blockStyleGenerator, props = {} ) => { valueCallback: value => { // Substitute with using format to work with preset controls value = typeof value === 'number' ? value.toString() : value - if ( value.startsWith( 'var(--stk' ) ) { + if ( value.startsWith( 'var' ) ) { return value } return value + 'px' @@ -57,7 +57,7 @@ export const addBorderStyles = ( blockStyleGenerator, props = {} ) => { attrNameTemplate, valueCallback: value => { value = typeof value === 'number' ? value.toString() : value - if ( value.startsWith( 'var(--stk' ) ) { + if ( value.startsWith( 'var' ) ) { return value } return value + 'px' @@ -75,7 +75,7 @@ export const addBorderStyles = ( blockStyleGenerator, props = {} ) => { attrNameTemplate, valueCallback: value => { value = typeof value === 'number' ? value.toString() : value - if ( value.startsWith( 'var(--stk' ) ) { + if ( value.startsWith( 'var' ) ) { return value } return value + 'px' @@ -93,7 +93,7 @@ export const addBorderStyles = ( blockStyleGenerator, props = {} ) => { attrNameTemplate, valueCallback: value => { value = typeof value === 'number' ? value.toString() : value - if ( value.startsWith( 'var(--stk' ) ) { + if ( value.startsWith( 'var' ) ) { return value } return value + 'px' diff --git a/src/components/advanced-range-control/index.js b/src/components/advanced-range-control/index.js index 4de53e3073..11d3f5b3cf 100644 --- a/src/components/advanced-range-control/index.js +++ b/src/components/advanced-range-control/index.js @@ -283,7 +283,7 @@ export default memo( AdvancedRangeControl, isEqual ) const extractNumberAndUnit = value => { // Match the last characters that are not numbers. const matches = value.match( /([\d.]+)(\D*)$/ ) - if ( ! matches || value.startsWith( 'var(--stk' ) ) { + if ( ! matches || value.startsWith( 'var' ) ) { return [ value, '' ] } return [ matches[ 1 ], matches[ 2 ] ] diff --git a/src/components/block-css/index.js b/src/components/block-css/index.js index 232b687cef..16dbe2e482 100644 --- a/src/components/block-css/index.js +++ b/src/components/block-css/index.js @@ -183,7 +183,7 @@ const BlockCss = props => { if ( unit ) { // Note: this will only work for non-objects. // If the value is `auto` or a CSS variable, don't add units. - if ( ! ( value === 'auto' || ( typeof value === 'string' && value.startsWith( 'var(--stk' ) ) ) ) { + if ( ! ( value === 'auto' || ( typeof value === 'string' && value.startsWith( 'var' ) ) ) ) { value = `${ value }${ unit }` } } diff --git a/src/components/four-range-control/index.js b/src/components/four-range-control/index.js index ff011f6490..9171cf18ab 100644 --- a/src/components/four-range-control/index.js +++ b/src/components/four-range-control/index.js @@ -59,7 +59,7 @@ const isEqualInitial = ( props, value, firstValue ) => { const extractNumberAndUnit = value => { // Match the last characters that are not numbers. const matches = value.match( /([\d.]+)(\D*)$/ ) - if ( ! matches || value.startsWith( 'var(--stk' ) ) { + if ( ! matches || value.startsWith( 'var' ) ) { return [ value, '' ] } return [ matches[ 1 ], matches[ 2 ] ] diff --git a/src/util/styles/style-object.js b/src/util/styles/style-object.js index 28c18f445d..d486dfdab4 100644 --- a/src/util/styles/style-object.js +++ b/src/util/styles/style-object.js @@ -336,7 +336,7 @@ class StyleObject { if ( unit ) { // Note: this will only work for non-objects. // If the value is `auto` or a CSS variable, don't add units. - if ( ! ( value === 'auto' || ( typeof value === 'string' && value.startsWith( 'var(--stk' ) ) ) ) { + if ( ! ( value === 'auto' || ( typeof value === 'string' && value.startsWith( 'var' ) ) ) ) { value = `${ value }${ unit }` } } From f74c4888f863f72f802236a88576a8965f899f30 Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Mon, 7 Apr 2025 11:00:20 +0800 Subject: [PATCH 42/99] fix: FourRangeControl synchronization of markmode; default markmode --- src/components/four-range-control/index.js | 57 ++++++++++++---------- 1 file changed, 32 insertions(+), 25 deletions(-) diff --git a/src/components/four-range-control/index.js b/src/components/four-range-control/index.js index 9171cf18ab..98e40d08b0 100644 --- a/src/components/four-range-control/index.js +++ b/src/components/four-range-control/index.js @@ -204,7 +204,7 @@ const FourRangeControl = memo( props => { bottom: !! props.marks, left: !! props.marks, } - if ( props.marks && value ) { + if ( props.marks && firstValue ) { // Check if the current value exsits in the marks const marksUnit = ( props.hasCSSVariableValue ? '' : unit ) isMarkValue.first = isMarkValue.first && props.marks.some( mark => mark.value === firstValue + marksUnit ) @@ -222,6 +222,13 @@ const FourRangeControl = memo( props => { bottom: props.enableBottom ? newValue : value.bottom, left: props.enableLeft ? newValue : value.left, } ) + setIsFourMarkMode( prev => ( { + ...prev, + top: prev.first, + right: prev.first, + bottom: prev.first, + left: prev.first, + } ) ) } const onChangeTop = newValue => { @@ -231,6 +238,7 @@ const FourRangeControl = memo( props => { bottom: value.bottom, left: value.left, } ) + setIsFourMarkMode( prev => ( { ...prev, first: prev.top } ) ) } const onChangeRight = newValue => { @@ -240,6 +248,7 @@ const FourRangeControl = memo( props => { bottom: value.bottom, left: value.left, } ) + setIsFourMarkMode( prev => ( { ...prev, first: prev.right } ) ) } const onChangeBottom = newValue => { @@ -249,6 +258,7 @@ const FourRangeControl = memo( props => { bottom: newValue, left: value.left, } ) + setIsFourMarkMode( prev => ( { ...prev, first: prev.bottom } ) ) } const onChangeLeft = newValue => { @@ -258,6 +268,7 @@ const FourRangeControl = memo( props => { bottom: value.bottom, left: newValue, } ) + setIsFourMarkMode( prev => ( { ...prev, first: prev.left } ) ) } const onChangeVertical = newValue => { @@ -267,6 +278,11 @@ const FourRangeControl = memo( props => { bottom: newValue, left: value.left, } ) + setIsFourMarkMode( prev => ( { + ...prev, + top: prev.top, + bottom: prev.top, + } ) ) } const onChangeHorizontal = newValue => { @@ -276,6 +292,11 @@ const FourRangeControl = memo( props => { bottom: value.bottom, left: newValue, } ) + setIsFourMarkMode( prev => ( { + ...prev, + right: prev.right, + left: prev.right, + } ) ) } // Support for steps. Modify the props to make the range control show steps. const stepSupport = ( isMarkMode, initialValue, initialOnChange ) => { @@ -351,7 +372,7 @@ const FourRangeControl = memo( props => { controlProps.units = isFourMarkMode.first ? false : controlProps.units } else if ( isLocked && props.vhMode ) { - controlProps.units = isFourMarkMode.top && isFourMarkMode.left + controlProps.units = isFourMarkMode.top && isFourMarkMode.right ? false : controlProps.units } else { controlProps.units = isFourMarkMode.top && isFourMarkMode.right && isFourMarkMode.bottom && isFourMarkMode.left @@ -396,8 +417,8 @@ const FourRangeControl = memo( props => { ) const [ propsToPassHorizontal, rangeValueHorizontal, rangeOnChangeHorizontal ] = stepSupport( - isFourMarkMode.left, - value.left, + isFourMarkMode.right, + value.right, onChangeHorizontal, ) @@ -443,9 +464,7 @@ const FourRangeControl = memo( props => { className="stk-range-control__custom-button" size="small" variant="tertiary" - onClick={ () => setIsFourMarkMode( prev => { - return { ...prev, first: ! prev.first } - } ) } + onClick={ () => setIsFourMarkMode( prev => ( { ...prev, first: ! prev.first } ) ) } icon={ settings } > @@ -503,9 +522,7 @@ const FourRangeControl = memo( props => { className="stk-range-control__custom-button" size="small" variant="tertiary" - onClick={ () => setIsFourMarkMode( prev => { - return { ...prev, top: ! prev.top } - } ) } + onClick={ () => setIsFourMarkMode( prev => ( { ...prev, top: ! prev.top } ) ) } icon={ settings } > @@ -559,9 +576,7 @@ const FourRangeControl = memo( props => { className="stk-range-control__custom-button" size="small" variant="tertiary" - onClick={ () => setIsFourMarkMode( prev => { - return { ...prev, left: ! prev.left } - } ) } + onClick={ () => setIsFourMarkMode( prev => ( { ...prev, left: ! prev.left } ) ) } icon={ settings } > @@ -621,9 +636,7 @@ const FourRangeControl = memo( props => { className="stk-range-control__custom-button" size="small" variant="tertiary" - onClick={ () => setIsFourMarkMode( prev => { - return { ...prev, top: ! prev.top } - } ) } + onClick={ () => setIsFourMarkMode( prev => ( { ...prev, top: ! prev.top } ) ) } icon={ settings } > @@ -680,9 +693,7 @@ const FourRangeControl = memo( props => { className="stk-range-control__custom-button" size="small" variant="tertiary" - onClick={ () => setIsFourMarkMode( prev => { - return { ...prev, right: ! prev.right } - } ) } + onClick={ () => setIsFourMarkMode( prev => ( { ...prev, right: ! prev.right } ) ) } icon={ settings } > @@ -739,9 +750,7 @@ const FourRangeControl = memo( props => { className="stk-range-control__custom-button" size="small" variant="tertiary" - onClick={ () => setIsFourMarkMode( prev => { - return { ...prev, bottom: ! prev.bottom } - } ) } + onClick={ () => setIsFourMarkMode( prev => ( { ...prev, bottom: ! prev.bottom } ) ) } icon={ settings } > @@ -798,9 +807,7 @@ const FourRangeControl = memo( props => { className="stk-range-control__custom-button" size="small" variant="tertiary" - onClick={ () => setIsFourMarkMode( prev => { - return { ...prev, left: ! prev.left } - } ) } + onClick={ () => setIsFourMarkMode( prev => ( { ...prev, left: ! prev.left } ) ) } icon={ settings } > From f86d2102f74b641bfca304ced95811a75d4da085 Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Mon, 7 Apr 2025 11:17:17 +0800 Subject: [PATCH 43/99] feat: add none presets to padding and margin similar to native --- src/block-components/helpers/size/edit.js | 9 ++++++++- src/block-components/typography/edit.js | 3 ++- src/hooks/use-preset-controls.js | 5 +++-- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/block-components/helpers/size/edit.js b/src/block-components/helpers/size/edit.js index 597fc37126..155e436266 100644 --- a/src/block-components/helpers/size/edit.js +++ b/src/block-components/helpers/size/edit.js @@ -139,7 +139,14 @@ const Spacing = props => { highlight: 'margin', } - const presetMarks = usePresetControls( 'spacingSizes' )?.getPresetMarks() || null + // Add additional presets for setting margins and paddings to None + const nonePreset = { + name: 'None', + size: '0rem', + slug: 'none', + } + const presetMarks = usePresetControls( 'spacingSizes' ) + ?.getPresetMarks( { additionalPresets: [ nonePreset ] } ) || null return ( <> diff --git a/src/block-components/typography/edit.js b/src/block-components/typography/edit.js index ea1a00f749..53d7590e92 100644 --- a/src/block-components/typography/edit.js +++ b/src/block-components/typography/edit.js @@ -104,7 +104,8 @@ export const Controls = props => { const onChangeContent = useCallback( text => setDebouncedText( escapeHTMLIfInvalid( text ) ), [] ) - const presetMarks = usePresetControls( 'fontSizes' )?.getPresetMarks( useTypographyAsPresets ) || null + const presetMarks = usePresetControls( 'fontSizes' ) + ?.getPresetMarks( { customOnly: useTypographyAsPresets } ) || null return ( <> diff --git a/src/hooks/use-preset-controls.js b/src/hooks/use-preset-controls.js index ab89fa8e21..9f59668252 100644 --- a/src/hooks/use-preset-controls.js +++ b/src/hooks/use-preset-controls.js @@ -56,9 +56,10 @@ export const usePresetControls = property => { // Get the merge preset marks with the CSS Variable value // Setting customOnly to true returns the preset marks for custom presets only - const getPresetMarks = ( customOnly = false ) => { + const getPresetMarks = ( { customOnly = false, additionalPresets = [] } = {} ) => { const prefix = PRESET_MAPPING[ property ].prefix - const presets = customOnly ? allCustomPresets[ property ] ?? [] : getMergedPresets() + let presets = customOnly ? allCustomPresets[ property ] ?? [] : getMergedPresets() + presets = [ ...additionalPresets, ...presets ] return presets .filter( preset => ! ( preset?.isDiscarded ) ) From 888ad9b3cfa66f95af5af0c8d5498b9f04b53fe9 Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Mon, 7 Apr 2025 21:06:36 +0800 Subject: [PATCH 44/99] fix: use extractNumbersAndUnits that can process clamp, min, etc. --- .../advanced-range-control/index.js | 16 +--- src/components/four-range-control/index.js | 78 ++++++++++++------- src/util/index.js | 29 +++++++ 3 files changed, 84 insertions(+), 39 deletions(-) diff --git a/src/components/advanced-range-control/index.js b/src/components/advanced-range-control/index.js index 11d3f5b3cf..ae6e369174 100644 --- a/src/components/advanced-range-control/index.js +++ b/src/components/advanced-range-control/index.js @@ -13,6 +13,7 @@ import { useBlockSetAttributesContext, useDeviceType, } from '~stackable/hooks' +import { extractNumbersAndUnits } from '~stackable/util' /** * External dependencies @@ -186,7 +187,7 @@ const AdvancedRangeControl = props => { let rangeOnChange = _onChange if ( isMarkMode ) { rangeValue = props.marks.findIndex( mark => { - const [ _value, _unit ] = extractNumberAndUnit( mark.value ) + const [ _value, _unit ] = extractNumbersAndUnits( mark.value )[ 0 ] return _value === derivedValue } ) rangeOnChange = ( value, property = 'value' ) => { @@ -195,7 +196,7 @@ const AdvancedRangeControl = props => { } // Extract the unit and value. const markValue = props.marks[ value ]?.[ property ] || '0' - const [ _newValue, unit ] = extractNumberAndUnit( markValue ) + const [ _newValue, unit ] = extractNumbersAndUnits( markValue )[ 0 ] const newValue = _newValue // Update the unit. @@ -277,14 +278,3 @@ AdvancedRangeControl.defaultProps = { } export default memo( AdvancedRangeControl, isEqual ) - -// The value can be in the format '10px' or '10.0em' or '10rem'. -// Return an array with the number and the unit. -const extractNumberAndUnit = value => { - // Match the last characters that are not numbers. - const matches = value.match( /([\d.]+)(\D*)$/ ) - if ( ! matches || value.startsWith( 'var' ) ) { - return [ value, '' ] - } - return [ matches[ 1 ], matches[ 2 ] ] -} diff --git a/src/components/four-range-control/index.js b/src/components/four-range-control/index.js index 98e40d08b0..14d96a11a0 100644 --- a/src/components/four-range-control/index.js +++ b/src/components/four-range-control/index.js @@ -18,6 +18,7 @@ import RangeControl from '../advanced-range-control/range-control' import { ResetButton } from '../base-control2/reset-button' import AdvancedControl, { extractControlProps } from '../base-control2' import { useControlHandlers } from '../base-control2/hooks' +import { extractNumbersAndUnits } from '~stackable/util' /** * WordPress dependencies @@ -54,17 +55,6 @@ const isEqualInitial = ( props, value, firstValue ) => { return isEqual } -// The value can be in the format '10px' or '10.0em' or '10rem'. -// Return an array with the number and the unit. -const extractNumberAndUnit = value => { - // Match the last characters that are not numbers. - const matches = value.match( /([\d.]+)(\D*)$/ ) - if ( ! matches || value.startsWith( 'var' ) ) { - return [ value, '' ] - } - return [ matches[ 1 ], matches[ 2 ] ] -} - const FourRangeControl = memo( props => { const [ _value, _onChange ] = useControlHandlers( props.attribute, props.responsive, props.hover, props.valueCallback, props.changeCallback ) const [ propsToPass, controlProps ] = extractControlProps( props ) @@ -294,8 +284,8 @@ const FourRangeControl = memo( props => { } ) setIsFourMarkMode( prev => ( { ...prev, - right: prev.right, - left: prev.right, + right: prev.left, + left: prev.left, } ) ) } // Support for steps. Modify the props to make the range control show steps. @@ -341,17 +331,17 @@ const FourRangeControl = memo( props => { let rangeOnChange = initialOnChange if ( props.marks && isMarkMode ) { rangeValue = props.marks.findIndex( mark => { - const [ _value, _unit ] = extractNumberAndUnit( mark.value ) + const [ _value, _unit ] = extractNumbersAndUnits( mark.value )[ 0 ] return _value === initialValue } ) - rangeOnChange = value => { + rangeOnChange = ( value, property = 'value' ) => { if ( value === '' ) { return initialOnChange( value ) } // Extract the unit and value. - const markValue = props.marks[ value ]?.value || '0' - const [ _newValue, unit ] = extractNumberAndUnit( markValue ) + const markValue = props.marks[ value ]?.[ property ] || '0' + const [ _newValue, unit ] = extractNumbersAndUnits( markValue )[ 0 ] const newValue = _newValue // Update the unit. @@ -417,8 +407,8 @@ const FourRangeControl = memo( props => { ) const [ propsToPassHorizontal, rangeValueHorizontal, rangeOnChangeHorizontal ] = stepSupport( - isFourMarkMode.right, - value.right, + isFourMarkMode.left, + value.left, onChangeHorizontal, ) @@ -464,7 +454,13 @@ const FourRangeControl = memo( props => { className="stk-range-control__custom-button" size="small" variant="tertiary" - onClick={ () => setIsFourMarkMode( prev => ( { ...prev, first: ! prev.first } ) ) } + onClick={ () => { + // Set the value when changing from mark mode to custom + if ( isFourMarkMode.first && rangeValueFirst !== -1 ) { + rangeOnChangeFirst( rangeValueFirst, 'size' ) + } + setIsFourMarkMode( prev => ( { ...prev, first: ! prev.first } ) ) + } } icon={ settings } > @@ -522,7 +518,12 @@ const FourRangeControl = memo( props => { className="stk-range-control__custom-button" size="small" variant="tertiary" - onClick={ () => setIsFourMarkMode( prev => ( { ...prev, top: ! prev.top } ) ) } + onClick={ () => { + if ( isFourMarkMode.top && rangeValueTop !== -1 ) { + rangeOnChangeTop( rangeValueTop, 'size' ) + } + setIsFourMarkMode( prev => ( { ...prev, top: ! prev.top } ) ) + } } icon={ settings } > @@ -576,7 +577,12 @@ const FourRangeControl = memo( props => { className="stk-range-control__custom-button" size="small" variant="tertiary" - onClick={ () => setIsFourMarkMode( prev => ( { ...prev, left: ! prev.left } ) ) } + onClick={ () => { + if ( isFourMarkMode.left && rangeValueLeft !== -1 ) { + rangeOnChangeLeft( rangeValueLeft, 'size' ) + } + setIsFourMarkMode( prev => ( { ...prev, left: ! prev.left } ) ) + } } icon={ settings } > @@ -636,7 +642,12 @@ const FourRangeControl = memo( props => { className="stk-range-control__custom-button" size="small" variant="tertiary" - onClick={ () => setIsFourMarkMode( prev => ( { ...prev, top: ! prev.top } ) ) } + onClick={ () => { + if ( isFourMarkMode.top && rangeValueTop !== -1 ) { + rangeOnChangeTop( rangeValueTop, 'size' ) + } + setIsFourMarkMode( prev => ( { ...prev, top: ! prev.top } ) ) + } } icon={ settings } > @@ -693,7 +704,12 @@ const FourRangeControl = memo( props => { className="stk-range-control__custom-button" size="small" variant="tertiary" - onClick={ () => setIsFourMarkMode( prev => ( { ...prev, right: ! prev.right } ) ) } + onClick={ () => { + if ( isFourMarkMode.right && rangeValueRight !== -1 ) { + rangeOnChangeRight( rangeValueRight, 'size' ) + } + setIsFourMarkMode( prev => ( { ...prev, right: ! prev.right } ) ) + } } icon={ settings } > @@ -750,7 +766,12 @@ const FourRangeControl = memo( props => { className="stk-range-control__custom-button" size="small" variant="tertiary" - onClick={ () => setIsFourMarkMode( prev => ( { ...prev, bottom: ! prev.bottom } ) ) } + onClick={ () => { + if ( isFourMarkMode.bottom && rangeValueBottom !== -1 ) { + rangeOnChangeBottom( rangeValueBottom, 'size' ) + } + setIsFourMarkMode( prev => ( { ...prev, bottom: ! prev.bottom } ) ) + } } icon={ settings } > @@ -807,7 +828,12 @@ const FourRangeControl = memo( props => { className="stk-range-control__custom-button" size="small" variant="tertiary" - onClick={ () => setIsFourMarkMode( prev => ( { ...prev, left: ! prev.left } ) ) } + onClick={ () => { + if ( isFourMarkMode.left && rangeValueLeft !== -1 ) { + rangeOnChangeLeft( rangeValueLeft, 'size' ) + } + setIsFourMarkMode( prev => ( { ...prev, left: ! prev.left } ) ) + } } icon={ settings } > diff --git a/src/util/index.js b/src/util/index.js index 3d011c095c..08f02913e8 100644 --- a/src/util/index.js +++ b/src/util/index.js @@ -388,3 +388,32 @@ export const createUniqueClass = uid => `${ uid.substring( 0, 7 ) }` export const semverCompare = ( version1, operator, version2 ) => { return compare( version1, version2, operator ) } + +/** + * Extracts all number-unit pairs from a CSS value. + * + * @param { string } value - The CSS value to extract from. + * @return { Array } An array of tuples, each containing a number and its corresponding unit. + * + * @example + * extractNumbersAndUnits( "min(1.5rem, 2vw)" ) + * // Returns: [["1.5", "rem"], ["2", "vw"]] + */ +export const extractNumbersAndUnits = value => { + if ( value.startsWith( 'var' ) ) { + return [ [ value, '' ] ] + } + // Match numbers followed by a unit, including decimals and negative values. + const regex = /(-?\d*\.?\d+)([a-zA-Z%]*)/g + const matches = [ ...value.matchAll( regex ) ] + + if ( matches.length ) { + return matches.map( match => [ match[ 1 ], match[ 2 ] || 'px' ] ) + } + + // If the input is purely numeric (e.g., "10"), assume "px" + if ( /^-?\d*\.?\d+$/.test( value ) ) { + return [ [ value, 'px' ] ] + } + return [ [ '0', 'px' ] ] +} From ea5101e79438a9cbe5ffe2028c29d7b21476d7e9 Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Mon, 7 Apr 2025 21:38:58 +0800 Subject: [PATCH 45/99] fix: add rem support to allow custom mode to have values when switching, convert from rem if only has px support --- src/block-components/helpers/size/edit.js | 20 +++++++++---------- .../advanced-range-control/index.js | 10 ++++++++-- src/components/four-range-control/index.js | 2 +- 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/src/block-components/helpers/size/edit.js b/src/block-components/helpers/size/edit.js index 155e436266..86581cea3d 100644 --- a/src/block-components/helpers/size/edit.js +++ b/src/block-components/helpers/size/edit.js @@ -40,10 +40,10 @@ const Layout = props => { label={ labelHeight } attribute={ getAttrName( 'height' ) } responsive="all" - units={ [ 'px', 'vh' ] } - min={ [ 0, 0 ] } - sliderMax={ [ 1000, 100 ] } - step={ [ 1, 1 ] } + units={ [ 'px', 'rem', 'vh' ] } + min={ [ 0, 0, 0 ] } + sliderMax={ [ 1000, 60, 100 ] } + step={ [ 1, 1, 1 ] } allowReset={ true } placeholder="0" helpTooltip={ { @@ -155,10 +155,10 @@ const Spacing = props => { attribute={ getAttrName( 'padding' ) } responsive="all" hover="all" - units={ [ 'px', 'em', '%' ] } + units={ [ 'px', 'em', 'rem', '%' ] } defaultLocked={ true } - min={ [ 0, 0, 0 ] } - sliderMax={ [ 200, 30, 100 ] } + min={ [ 0, 0, 0, 0 ] } + sliderMax={ [ 200, 30, 30, 100 ] } helpTooltip={ { video: 'inner-block-padding', description: __( 'Sets the block paddings, i.e the space between the inner columns and the block border', i18n ), @@ -174,10 +174,10 @@ const Spacing = props => { label={ labelMargins } attribute={ getAttrName( 'margin' ) } responsive="all" - units={ [ 'px', '%' ] } + units={ [ 'px', 'rem', '%' ] } defaultLocked={ false } - sliderMin={ [ -200, -100 ] } - sliderMax={ [ 200, 100 ] } + sliderMin={ [ -200, -15, -100 ] } + sliderMax={ [ 200, 15, 100 ] } placeholder="0" helpTooltip={ { video: 'advanced-block-margin', diff --git a/src/components/advanced-range-control/index.js b/src/components/advanced-range-control/index.js index ae6e369174..ba5b60cff3 100644 --- a/src/components/advanced-range-control/index.js +++ b/src/components/advanced-range-control/index.js @@ -196,8 +196,14 @@ const AdvancedRangeControl = props => { } // Extract the unit and value. const markValue = props.marks[ value ]?.[ property ] || '0' - const [ _newValue, unit ] = extractNumbersAndUnits( markValue )[ 0 ] - const newValue = _newValue + let [ newValue, unit ] = extractNumbersAndUnits( markValue )[ 0 ] + + // If the attribute has no units (only support px), and the + // preset units are rem or em, convert to px + if ( ! hasUnits && ( unit === 'rem' || unit === 'em' ) ) { + newValue = `${ parseFloat( newValue ) * 16 }` + unit = 'px' + } // Update the unit. if ( unit ) { diff --git a/src/components/four-range-control/index.js b/src/components/four-range-control/index.js index 14d96a11a0..6e9aee60ea 100644 --- a/src/components/four-range-control/index.js +++ b/src/components/four-range-control/index.js @@ -327,7 +327,7 @@ const FourRangeControl = memo( props => { } // We need to change the way we handle the value and onChange if we're doing marks - let rangeValue = initialValue + let rangeValue = props.hasCSSVariableValue ? parseFloat( initialValue ) : initialValue let rangeOnChange = initialOnChange if ( props.marks && isMarkMode ) { rangeValue = props.marks.findIndex( mark => { From ae3813ae48defaeea34c8c165d633fe43eb1216e Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Tue, 8 Apr 2025 11:39:38 +0800 Subject: [PATCH 46/99] feat: support mimic/clamping by using WP generated presets --- src/hooks/use-preset-controls.js | 2 +- .../preset-controls/editor-loader.js | 2 +- .../global-settings/preset-controls/index.php | 38 +++++++++++++------ 3 files changed, 29 insertions(+), 13 deletions(-) diff --git a/src/hooks/use-preset-controls.js b/src/hooks/use-preset-controls.js index 9f59668252..d2e3cc69df 100644 --- a/src/hooks/use-preset-controls.js +++ b/src/hooks/use-preset-controls.js @@ -9,7 +9,7 @@ const PRESET_MAPPING = { }, spacingSizes: { settings: [ 'spacing', 'spacingSizes' ], - prefix: 'spacing-size', + prefix: 'spacing', }, blockHeights: { settings: [ 'blockHeights' ], diff --git a/src/plugins/global-settings/preset-controls/editor-loader.js b/src/plugins/global-settings/preset-controls/editor-loader.js index d66aae36fd..20170436bc 100644 --- a/src/plugins/global-settings/preset-controls/editor-loader.js +++ b/src/plugins/global-settings/preset-controls/editor-loader.js @@ -14,7 +14,7 @@ const PRESET_MAPPING = { prefix: 'font-size', }, spacingSizes: { - prefix: 'spacing-size', + prefix: 'spacing', }, blockHeights: { prefix: 'block-height', diff --git a/src/plugins/global-settings/preset-controls/index.php b/src/plugins/global-settings/preset-controls/index.php index 111d58bcb9..6c33b5583d 100644 --- a/src/plugins/global-settings/preset-controls/index.php +++ b/src/plugins/global-settings/preset-controls/index.php @@ -21,7 +21,7 @@ class Stackable_Size_And_Spacing_Preset_Controls { ), 'spacingSizes' => array( 'settings' => array( 'spacing', 'spacingSizes' ), - 'prefix' => 'spacing-size', + 'prefix' => 'spacing', ), 'blockHeights' => array( 'settings' => array( 'blockHeights' ), @@ -71,27 +71,41 @@ private function load_presets( $json_path ) { * @param array $property * @param array $presets * @param array $prefix + * @param bool $isTheme * @return mixed */ - public function generate_css_variables( $property, $presets, $prefix ) { + public function generate_css_variables( $property, $presets, $prefix, $isTheme = false ) { + $filter_name = current_filter(); $custom_presets = $this->custom_presets[ $property ] ?? []; $css = ""; - // Convert presets into an associative array with key 'slug' + $presets_by_slug = []; + // Convert presets into an associative array with key 'slug' foreach ( $presets as $preset ) { $presets_by_slug[ $preset[ 'slug' ] ] = $preset; } - // Override values in base presets if it exist in custom presets - foreach ( $custom_presets as $custom ) { - $presets_by_slug[ $custom[ 'slug' ] ] = $custom; + + if ( $filter_name !== 'stackable_inline_editor_styles' ) { + // Override values in base presets if it exist in custom presets + foreach ( $custom_presets as $custom ) { + $custom[ '__is_custom' ] = true; + $presets_by_slug[ $custom[ 'slug' ] ] = $custom; + } } - - foreach ( $presets_by_slug as $preset ) { - $slug = $preset[ 'slug' ]; - $size = $preset[ 'size' ]; - $css .= "--stk--preset--$prefix--{$preset['slug']}: {$preset['size']};\n"; + + // If custom presets or using stackable presets, use the given size. + // If using theme presets, use WP generated --wp-preset to support theme.json specific + // configuration (fluid, clamping, etc.) + foreach ( $presets_by_slug as $slug => $preset ) { + $is_custom = $preset[ '__is_custom' ] ?? false; + + $value = $is_custom || ! $isTheme + ? $preset['size'] + : "var(--wp--preset--$prefix--$slug)"; + + $css .= "--stk--preset--$prefix--$slug: $value;\n"; } return $css; @@ -124,12 +138,14 @@ public function add_preset_controls_styles( $current_css ) { $key, $this->deepGet( $this->theme_presets, $value[ 'settings' ] )[ 'theme' ], $value[ 'prefix' ], + true ); } elseif ( ! empty( $this->deepGet( $this->default_presets, $value[ 'settings' ] )[ 'default' ] ) ) { $generated_css .= $this->generate_css_variables( $key, $this->deepGet( $this->default_presets, $value[ 'settings' ] )[ 'default' ], $value[ 'prefix' ], + true ); } else { $generated_css .= $this->generate_css_variables( From 9a558c8f1c37fcd8a32849acfc45e46399e58796 Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Wed, 9 Apr 2025 18:10:41 +0800 Subject: [PATCH 47/99] fix: global preset control title --- src/components/pro-control/index.js | 5 +++-- src/plugins/global-settings/preset-controls/index.js | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/components/pro-control/index.js b/src/components/pro-control/index.js index 23a8ad0634..a15a7ed4ec 100644 --- a/src/components/pro-control/index.js +++ b/src/components/pro-control/index.js @@ -134,9 +134,10 @@ const LABELS = { , }, 'preset-controls': { - title: __( 'Customize the Preset Controls', i18n ), + title: __( 'Premium Preset Controls', i18n ), description:
      -
    • { __( 'Customize your own Preset Controls', i18n ) }
    • +
    • { __( 'Customize your own presets', i18n ) }
    • +
    • { __( 'Use Global Typography sizes as presets', i18n ) }
    , }, } diff --git a/src/plugins/global-settings/preset-controls/index.js b/src/plugins/global-settings/preset-controls/index.js index 1a042a4e91..b6681180fa 100644 --- a/src/plugins/global-settings/preset-controls/index.js +++ b/src/plugins/global-settings/preset-controls/index.js @@ -31,7 +31,7 @@ if ( showProNotice || isPro ) { { output } From 054216e8e70e49476da82f4d21672b9b92e04681 Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Thu, 10 Apr 2025 11:40:07 +0800 Subject: [PATCH 48/99] feat: apply body to html --- src/global-settings.php | 28 ++++++++++++++++--- .../typography/editor-loader.js | 27 ++++++++++++------ .../global-settings/typography/index.js | 28 +++++++++++++++++-- 3 files changed, 68 insertions(+), 15 deletions(-) diff --git a/src/global-settings.php b/src/global-settings.php index 812e9fccc0..73fc07e39b 100644 --- a/src/global-settings.php +++ b/src/global-settings.php @@ -424,6 +424,18 @@ public function register_global_settings() { ) ); + register_setting( + 'stackable_global_settings', + 'stackable_is_apply_body_to_html', + array( + 'type' => 'boolean', + 'description' => __( 'Stackable global typography apply to setting', STACKABLE_I18N ), + 'sanitize_callback' => 'sanitize_text_field', + 'show_in_rest' => true, + 'default' => '', + ) + ); + register_setting( 'stackable_global_settings', 'stackable_icon_library', @@ -650,11 +662,19 @@ public function form_tag_selector( $tag ) { } public function form_paragraph_selector() { - return array_merge( - $this->form_tag_selector( 'p' ), // Core text. - $this->form_tag_selector( 'li' ), // Core lists. - $this->form_tag_selector( 'td' ) // Core table cells. + $is_apply_body_to_html = get_option( 'stackable_is_apply_body_to_html' ) ?? false; + $selectors = array_merge( + $this->form_tag_selector( 'p' ), // Core text + $this->form_tag_selector( 'li' ), // Core lists + $this->form_tag_selector( 'td' ) // Core table cells ); + + // Add 'html' only if is_apply_body_to_html is true + if ( $is_apply_body_to_html ) { + $selectors[] = 'html'; + } + + return $selectors; } /** diff --git a/src/plugins/global-settings/typography/editor-loader.js b/src/plugins/global-settings/typography/editor-loader.js index 6c7f39da55..93413f77f0 100644 --- a/src/plugins/global-settings/typography/editor-loader.js +++ b/src/plugins/global-settings/typography/editor-loader.js @@ -29,6 +29,7 @@ import { useSelect } from '@wordpress/data' export const GlobalTypographyStyles = () => { const [ typographySettings, setTypographySettings ] = useState( [] ) const [ applySettingsTo, setApplySettingsTo ] = useState( '' ) + const [ isApplyBodyToHTML, setIsApplyBodyToHTML ] = useState( false ) // These are for debouncing the style generation to make things faster. const [ styles, setStyles ] = useState( '' ) @@ -54,12 +55,16 @@ export const GlobalTypographyStyles = () => { fetchSettings().then( response => { setTypographySettings( ( head( response.stackable_global_typography ) ) || {} ) setApplySettingsTo( response.stackable_global_typography_apply_to || 'blocks-stackable-native' ) + setIsApplyBodyToHTML( response.stackable_is_apply_body_to_html || false ) } ) // Allow actions to trigger styles to update. - addAction( 'stackable.global-settings.typography.update-trigger', 'stackable/typography-styles', ( newTypographySettings, newAapplySettingsTo ) => { + addAction( 'stackable.global-settings.typography.update-trigger', 'stackable/typography-styles', ( + newTypographySettings, newAapplySettingsTo, newIsApplyBodyToHTML + ) => { setTypographySettings( newTypographySettings ) setApplySettingsTo( newAapplySettingsTo ) + setIsApplyBodyToHTML( newIsApplyBodyToHTML ) } ) return () => { removeAction( 'stackable.global-settings.typography.update-trigger', 'stackable/typography-styles' ) @@ -71,7 +76,7 @@ export const GlobalTypographyStyles = () => { addAction( 'stackable.global-settings.typography-update-global-styles', 'stackable/typography-styles', typographySettings => { // Generate all the typography styles. const styleObject = Object.keys( typographySettings ).map( tag => { - const selectors = formSelectors( tag, applySettingsTo ) + const selectors = formSelectors( tag, applySettingsTo, isApplyBodyToHTML ) // Build our selector, target h2.block or .block h2. // Some blocks may output the heading tag right away. @@ -118,16 +123,16 @@ export const GlobalTypographyStyles = () => { setStyleTimeout( setTimeout( () => doAction( 'stackable.global-settings.typography-update-global-styles', typographySettings ), 200 ) ) return () => removeAction( 'stackable.global-settings.typography-update-global-styles', 'stackable/typography-styles' ) - }, [ JSON.stringify( typographySettings ), applySettingsTo, device, editorMode ] ) + }, [ JSON.stringify( typographySettings ), applySettingsTo, isApplyBodyToHTML, device, editorMode ] ) return styles } -export const formSelectors = ( selector, applyTo ) => { +export const formSelectors = ( selector, applyTo, isApplyBodyToHTML ) => { if ( [ 'h1', 'h2', 'h3', 'h4', 'h5', 'h6' ].includes( selector ) || selector.startsWith( '.' ) ) { return formClassOrTagSelectors( selector, applyTo ) } - return formParagraphSelectors( applyTo ) + return formParagraphSelectors( applyTo, isApplyBodyToHTML ) } export const formClassOrTagSelectors = ( selector, applyTo ) => { @@ -152,8 +157,8 @@ export const formClassOrTagSelectors = ( selector, applyTo ) => { return applyFilters( 'stackable.global-settings.typography-selectors', selectors, selector ) } -export const formParagraphSelectors = applyTo => { - return applyFilters( 'stackable.global-settings.typography-selectors', [ +export const formParagraphSelectors = ( applyTo, isApplyBodyToHTML ) => { + const selectors = [ ...formClassOrTagSelectors( 'p', applyTo ), ...formClassOrTagSelectors( 'li', applyTo ), `.editor-styles-wrapper p.block-editor-block-list__block[data-type^="core/"]`, @@ -162,7 +167,13 @@ export const formParagraphSelectors = applyTo => { `.editor-styles-wrapper .block-editor-block-list__block[data-type^="core/"] td`, // Apply the font styles to the content placeholder text when the post is blank. '.block-editor-default-block-appender.has-visible-prompt', - ], '' ) + ] + + // Add 'html' only if is_apply_body_to_html is true + if ( isApplyBodyToHTML ) { + selectors.push( 'html' ) + } + return applyFilters( 'stackable.global-settings.typography-selectors', selectors, '' ) } // Make sure that this isn't applied to the native query loop block, otherwise diff --git a/src/plugins/global-settings/typography/index.js b/src/plugins/global-settings/typography/index.js index 45c1f47d5a..a559433e7d 100644 --- a/src/plugins/global-settings/typography/index.js +++ b/src/plugins/global-settings/typography/index.js @@ -11,7 +11,7 @@ import { getAppliedTypeScale } from './utils' * External dependencies */ import { - PanelAdvancedSettings, AdvancedSelectControl, ControlSeparator, FontPairPicker, ProControlButton, + PanelAdvancedSettings, AdvancedSelectControl, ControlSeparator, FontPairPicker, ProControlButton, AdvancedToggleControl, } from '~stackable/components' import { fetchSettings, getDefaultFontSize } from '~stackable/util' import { @@ -160,6 +160,7 @@ addFilter( 'stackable.global-settings.inspector', 'stackable/global-typography', const [ selectedFontPairName, setSelectedFontPairName ] = useState( '' ) const [ isEditingFontPair, setIsEditingFontPair ] = useState( false ) const [ selectedTypeScale, setSelectedTypeScale ] = useState( 'none' ) + const [ isApplyBodyToHTML, setIsApplyBodyToHTML ] = useState( false ) const fontPairContainerRef = useRef( null ) @@ -171,6 +172,7 @@ addFilter( 'stackable.global-settings.inspector', 'stackable/global-typography', setApplySettingsTo( response.stackable_global_typography_apply_to || 'blocks-stackable-native' ) setCustomFontPairs( response.stackable_custom_font_pairs || [] ) setSelectedFontPairName( response.stackable_selected_font_pair || 'theme-heading-default/theme-body-default' ) + setIsApplyBodyToHTML( response.stackable_is_apply_body_to_html || false ) // Reversely compute the type scale from the font sizes let typeScale = _typographySettings?.h6?.fontSize @@ -190,7 +192,12 @@ addFilter( 'stackable.global-settings.inspector', 'stackable/global-typography', useEffect( () => { // When typography styles are changed, trigger our editor style generator to update. - doAction( 'stackable.global-settings.typography.update-trigger', typographySettings, applySettingsTo ) + doAction( 'stackable.global-settings.typography.update-trigger', typographySettings, applySettingsTo, isApplyBodyToHTML ) + }, [ JSON.stringify( typographySettings ), applySettingsTo, isApplyBodyToHTML ] ) + + useEffect( () => { + // When typography styles are changed, trigger our editor style generator to update. + doAction( 'stackable.global-settings.typography.update-trigger', typographySettings, applySettingsTo, isApplyBodyToHTML ) // Update the custom presets when using typography as presets if ( useTypographyAsPresets ) { @@ -235,7 +242,7 @@ addFilter( 'stackable.global-settings.inspector', 'stackable/global-typography', dispatch( 'stackable/global-preset-controls.custom' ).updateCustomPresetControls( newSettings ) } - }, [ JSON.stringify( typographySettings ), applySettingsTo, useTypographyAsPresets ] ) + }, [ JSON.stringify( typographySettings ), useTypographyAsPresets ] ) // Scroll to the selected font pair when Global Typography tab is toggled useEffect( () => { @@ -301,6 +308,14 @@ addFilter( 'stackable.global-settings.inspector', 'stackable/global-typography', model.save() } + const changeIsApplyBodyToHTML = value => { + setIsApplyBodyToHTML( value ) + const model = new models.Settings( { + stackable_is_apply_body_to_html: value, // eslint-disable-line + } ) + model.save() + } + const updateTypeScale = value => { setSelectedTypeScale( value ) @@ -587,6 +602,13 @@ addFilter( 'stackable.global-settings.inspector', 'stackable/global-typography', getIsAllowReset={ getIsAllowReset } /> } +
    ) From f912ffe02dded0bd57ed432e2c16f6fbfbca28fa Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Thu, 10 Apr 2025 13:44:42 +0800 Subject: [PATCH 49/99] fix: add margin to apply html toggle --- src/plugins/global-settings/typography/editor.scss | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/plugins/global-settings/typography/editor.scss b/src/plugins/global-settings/typography/editor.scss index 6715415711..418d565c26 100644 --- a/src/plugins/global-settings/typography/editor.scss +++ b/src/plugins/global-settings/typography/editor.scss @@ -137,4 +137,7 @@ .stk-inspector-sub-header { margin-bottom: 16px; } + .stk-toggle-control { + margin-top: 28px; + } } From 1ec5add451675be44fd308d91c663b2c34608508 Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Fri, 11 Apr 2025 12:41:35 +0800 Subject: [PATCH 50/99] fix: remove hasCSSVariableValue, always assume that marks has string value --- src/components/advanced-range-control/index.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/components/advanced-range-control/index.js b/src/components/advanced-range-control/index.js index ba5b60cff3..17c7039821 100644 --- a/src/components/advanced-range-control/index.js +++ b/src/components/advanced-range-control/index.js @@ -114,11 +114,12 @@ const AdvancedRangeControl = props => { } const [ isMarkMode, setIsMarkMode ] = useState( isMarkValue ) - // If this supports dynamic content and can have CSS variables, the value should be saved as a String. + // If this supports dynamic content, the value should be saved as a String. + // Similar if using marks to accomodate CSS variable // Important, the attribute type for this option should be a string. const _onChange = value => { const onChangeFunc = typeof props.onChange === 'undefined' ? onChange : props.onChange - let newValue = props.isDynamic || props.hasCSSVariableValue ? value.toString() : value + let newValue = props.isDynamic || props.marks ? value.toString() : value // On reset, allow overriding the value. if ( newValue === '' ) { @@ -183,7 +184,7 @@ const AdvancedRangeControl = props => { // We need to change the way we handle the value and onChange if we're doing marks // Convert to float if the attribute is string to work with the slider - let rangeValue = propsToPass.isDynamic || props.hasCSSVariableValue ? parseFloat( derivedValue ) : derivedValue + let rangeValue = propsToPass.isDynamic || props.marks ? parseFloat( derivedValue ) : derivedValue let rangeOnChange = _onChange if ( isMarkMode ) { rangeValue = props.marks.findIndex( mark => { @@ -277,9 +278,8 @@ AdvancedRangeControl.defaultProps = { onOverrideReset: undefined, forcePlaceholder: false, - marks: undefined, // [{ value: '14px', name: 'S' }, { value: '16px', name: 'M' }] + marks: undefined, // [{ value: 'var(--stk-preset-font-size-small', name: 'S' }] allowCustom: true, - hasCSSVariableValue: false, // If the attribute can have CSS variable value (string attribute) isCustomPreset: false, } From 5ff46022bd58e68d2128f84ac60b2cfce5b060b2 Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Fri, 11 Apr 2025 12:47:48 +0800 Subject: [PATCH 51/99] fix: get_option is never null --- src/global-settings.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/global-settings.php b/src/global-settings.php index 73fc07e39b..6dfa1813f2 100644 --- a/src/global-settings.php +++ b/src/global-settings.php @@ -662,7 +662,6 @@ public function form_tag_selector( $tag ) { } public function form_paragraph_selector() { - $is_apply_body_to_html = get_option( 'stackable_is_apply_body_to_html' ) ?? false; $selectors = array_merge( $this->form_tag_selector( 'p' ), // Core text $this->form_tag_selector( 'li' ), // Core lists @@ -670,6 +669,7 @@ public function form_paragraph_selector() { ); // Add 'html' only if is_apply_body_to_html is true + $is_apply_body_to_html = get_option( 'stackable_is_apply_body_to_html' ); if ( $is_apply_body_to_html ) { $selectors[] = 'html'; } From c6d157a962a2ee746c44dd4327916b9fb7c01e1c Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Fri, 11 Apr 2025 12:56:16 +0800 Subject: [PATCH 52/99] fix: use wp_json_file_decode --- src/plugins/global-settings/preset-controls/index.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/plugins/global-settings/preset-controls/index.php b/src/plugins/global-settings/preset-controls/index.php index 6c33b5583d..3bfa83c2ea 100644 --- a/src/plugins/global-settings/preset-controls/index.php +++ b/src/plugins/global-settings/preset-controls/index.php @@ -45,7 +45,7 @@ function __construct() { $this->custom_presets = get_option( 'stackable_global_custom_preset_controls' ); $this->theme_presets = WP_Theme_JSON_Resolver::get_theme_data()->get_settings(); $this->default_presets = WP_Theme_JSON_Resolver::get_core_data()->get_settings(); - $this->stackable_presets = $this->load_presets( __DIR__ . '/presets.json'); + $this->stackable_presets = $this->load_json_file( __DIR__ . '/presets.json'); add_filter( 'stackable_inline_styles_nodep', array( $this, 'add_preset_controls_styles' ) ); add_filter( 'stackable_inline_editor_styles', array( $this, 'add_preset_controls_styles' ) ); @@ -55,10 +55,11 @@ public static function sanitize_array_setting( $input ) { return ! is_array( $input ) ? array( array() ) : $input; } - private function load_presets( $json_path ) { + private function load_json_file( $json_path ) { if ( file_exists( $json_path ) ) { - $json_data = file_get_contents( $json_path ); - $decoded_data = json_decode( $json_data, true ); + $decoded_data = wp_json_file_decode( $json_path, [ + 'associative' => true, + ] ); return $decoded_data[ 'settings' ] ?? []; } return []; From 07460776fafb3f908020893d77d80fec4c1e046c Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Fri, 11 Apr 2025 13:02:08 +0800 Subject: [PATCH 53/99] fix: remove JSON stringify since customPresets is just an array --- src/plugins/global-settings/preset-controls/editor-loader.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/global-settings/preset-controls/editor-loader.js b/src/plugins/global-settings/preset-controls/editor-loader.js index 20170436bc..25042dff93 100644 --- a/src/plugins/global-settings/preset-controls/editor-loader.js +++ b/src/plugins/global-settings/preset-controls/editor-loader.js @@ -51,7 +51,7 @@ export const GlobalPresetControlsStyles = () => { if ( customPresets && typeof customPresets === 'object' ) { renderGlobalStyles( customPresets, setStyles ) } - }, [ JSON.stringify( customPresets ) ] ) + }, [ customPresets ] ) return styles } From 3c0c069c416dd5e5bac0233c925e0abc9f78cc8d Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Fri, 11 Apr 2025 23:26:19 +0800 Subject: [PATCH 54/99] fix: separate loading of presets in another function --- src/plugins/global-settings/preset-controls/index.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/plugins/global-settings/preset-controls/index.php b/src/plugins/global-settings/preset-controls/index.php index 3bfa83c2ea..ff3f0e0310 100644 --- a/src/plugins/global-settings/preset-controls/index.php +++ b/src/plugins/global-settings/preset-controls/index.php @@ -42,13 +42,15 @@ class Stackable_Size_And_Spacing_Preset_Controls { * Initialize */ function __construct() { + add_filter( 'stackable_inline_styles_nodep', array( $this, 'add_preset_controls_styles' ) ); + add_filter( 'stackable_inline_editor_styles', array( $this, 'add_preset_controls_styles' ) ); + } + + public function load_presets() { $this->custom_presets = get_option( 'stackable_global_custom_preset_controls' ); $this->theme_presets = WP_Theme_JSON_Resolver::get_theme_data()->get_settings(); $this->default_presets = WP_Theme_JSON_Resolver::get_core_data()->get_settings(); $this->stackable_presets = $this->load_json_file( __DIR__ . '/presets.json'); - - add_filter( 'stackable_inline_styles_nodep', array( $this, 'add_preset_controls_styles' ) ); - add_filter( 'stackable_inline_editor_styles', array( $this, 'add_preset_controls_styles' ) ); } public static function sanitize_array_setting( $input ) { @@ -130,6 +132,8 @@ public function deepGet( $array, $keys ) { * @return String */ public function add_preset_controls_styles( $current_css ) { + $this->load_presets(); + $generated_css = "\n/* Global Preset Controls */\n"; $generated_css .= ":root {\n"; From 2d1512fb0198c1bc0a4915f46f612fdf3748ec15 Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Sat, 12 Apr 2025 00:12:34 +0800 Subject: [PATCH 55/99] fix: use wp_style_engine_get_stylesheet_from_css_rules to generate styles --- .../global-settings/preset-controls/index.php | 40 +++++++++++-------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/src/plugins/global-settings/preset-controls/index.php b/src/plugins/global-settings/preset-controls/index.php index ff3f0e0310..d1da2976ca 100644 --- a/src/plugins/global-settings/preset-controls/index.php +++ b/src/plugins/global-settings/preset-controls/index.php @@ -68,7 +68,7 @@ private function load_json_file( $json_path ) { } /** - * Generate CSS variables based on the property (e.g., fontSizes, spacing). + * Generate CSS variable style defintions based on the property (e.g., fontSizes, spacing). * The given presets will be overriden it match with a preset from custom. * * @param array $property @@ -77,19 +77,18 @@ private function load_json_file( $json_path ) { * @param bool $isTheme * @return mixed */ - public function generate_css_variables( $property, $presets, $prefix, $isTheme = false ) { + public function generate_css_variables_styles( $property, $presets, $prefix, $isTheme = false ) { $filter_name = current_filter(); $custom_presets = $this->custom_presets[ $property ] ?? []; - - $css = ""; - $presets_by_slug = []; // Convert presets into an associative array with key 'slug' foreach ( $presets as $preset ) { $presets_by_slug[ $preset[ 'slug' ] ] = $preset; } + // There is no need to generate custom presets in the editor. + // The custom presets are generated dynamically. if ( $filter_name !== 'stackable_inline_editor_styles' ) { // Override values in base presets if it exist in custom presets foreach ( $custom_presets as $custom ) { @@ -98,20 +97,25 @@ public function generate_css_variables( $property, $presets, $prefix, $isTheme = } } + // Build the CSS variables array. // If custom presets or using stackable presets, use the given size. // If using theme presets, use WP generated --wp-preset to support theme.json specific // configuration (fluid, clamping, etc.) + $css_vars = []; foreach ( $presets_by_slug as $slug => $preset ) { - $is_custom = $preset[ '__is_custom' ] ?? false; + $is_custom = $preset['__is_custom'] ?? false; $value = $is_custom || ! $isTheme ? $preset['size'] : "var(--wp--preset--$prefix--$slug)"; - $css .= "--stk--preset--$prefix--$slug: $value;\n"; + $css_vars[ "--stk--preset--$prefix--$slug" ] = $value; } - return $css; + return array( + 'selector' => ':root', + 'declarations' => $css_vars, + ); } /** @@ -133,40 +137,42 @@ public function deepGet( $array, $keys ) { */ public function add_preset_controls_styles( $current_css ) { $this->load_presets(); - - $generated_css = "\n/* Global Preset Controls */\n"; - $generated_css .= ":root {\n"; + $generated_styles = array(); foreach ( self::PRESET_MAPPING as $key => $value ) { if ( ! empty( $this->deepGet( $this->theme_presets, $value[ 'settings' ] )[ 'theme' ] ) ) { - $generated_css .= $this->generate_css_variables( + $styles = $this->generate_css_variables_styles( $key, $this->deepGet( $this->theme_presets, $value[ 'settings' ] )[ 'theme' ], $value[ 'prefix' ], true ); + $generated_styles[] = $styles; + } elseif ( ! empty( $this->deepGet( $this->default_presets, $value[ 'settings' ] )[ 'default' ] ) ) { - $generated_css .= $this->generate_css_variables( + $styles = $this->generate_css_variables_styles( $key, $this->deepGet( $this->default_presets, $value[ 'settings' ] )[ 'default' ], $value[ 'prefix' ], true ); + $generated_styles[] = $styles; } else { - $generated_css .= $this->generate_css_variables( + $styles = $this->generate_css_variables_styles( $key, $this->deepGet( $this->stackable_presets, $value[ 'settings' ] ), $value[ 'prefix' ], ); + $generated_styles[] = $styles; } } - $generated_css .= "}\n"; - + $generated_css = wp_style_engine_get_stylesheet_from_css_rules( $generated_styles ); if ( ! $generated_css ) { return $current_css; } - + + $current_css .= "\n/* Global Preset Controls */\n"; $current_css .= $generated_css; return apply_filters( 'stackable_frontend_css' , $current_css ); From c97950959250341b5c98d576d3bbc25dff13f8ba Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Sat, 12 Apr 2025 00:19:20 +0800 Subject: [PATCH 56/99] fix: translate only the words --- .../global-settings/preset-controls/index.php | 2 +- src/plugins/global-settings/typography/index.js | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/plugins/global-settings/preset-controls/index.php b/src/plugins/global-settings/preset-controls/index.php index d1da2976ca..682ea3baa9 100644 --- a/src/plugins/global-settings/preset-controls/index.php +++ b/src/plugins/global-settings/preset-controls/index.php @@ -68,7 +68,7 @@ private function load_json_file( $json_path ) { } /** - * Generate CSS variable style defintions based on the property (e.g., fontSizes, spacing). + * Generate CSS variable style definitions based on the property (e.g., fontSizes, spacing). * The given presets will be overriden it match with a preset from custom. * * @param array $property diff --git a/src/plugins/global-settings/typography/index.js b/src/plugins/global-settings/typography/index.js index a559433e7d..5c608f685a 100644 --- a/src/plugins/global-settings/typography/index.js +++ b/src/plugins/global-settings/typography/index.js @@ -106,35 +106,35 @@ const TYPE_SCALE = [ disabled: true, }, { - label: __( '1.067 - Minor Second', i18n ), + label: sprintf( __( '%s - %s', i18n ), '1.067', __( 'Minor Second', i18n ) ), value: '1.067', }, { - label: __( '1.125 - Major Second', i18n ), + label: sprintf( __( '%s - %s', i18n ), '1.125', __( 'Major Second', i18n ) ), value: '1.125', }, { - label: __( '1.200 - Minor Third', i18n ), + label: sprintf( __( '%s - %s', i18n ), '1.2', __( 'Minor Third', i18n ) ), value: '1.2', }, { - label: __( '1.250 - Major Third', i18n ), + label: sprintf( __( '%s - %s', i18n ), '1.25', __( 'Major Third', i18n ) ), value: '1.25', }, { - label: __( '1.333 - Perfect Fourth', i18n ), + label: sprintf( __( '%s - %s', i18n ), '1.333', __( 'Perfect Fourth', i18n ) ), value: '1.333', }, { - label: __( '1.414 - Augmented Fourth', i18n ), + label: sprintf( __( '%s - %s', i18n ), '1.414', __( 'Augmented Fourth', i18n ) ), value: '1.414', }, { - label: __( '1.500 - Perfect Fifth', i18n ), + label: sprintf( __( '%s - %s', i18n ), '1.5', __( 'Perfect Fifth', i18n ) ), value: '1.5', }, { - label: __( '1.618 - Golden Ratio', i18n ), + label: sprintf( __( '%s - %s', i18n ), '1.618', __( 'Golden Ratio', i18n ) ), value: '1.618', }, ] From 17ae06e70a246cd6c59208aac5979c3626aa1651 Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Sat, 12 Apr 2025 14:35:06 +0800 Subject: [PATCH 57/99] fix: move updating presets with typography to editor loader --- .../typography/editor-loader.js | 65 +++++++++++++++++- .../global-settings/typography/index.js | 66 +++---------------- 2 files changed, 72 insertions(+), 59 deletions(-) diff --git a/src/plugins/global-settings/typography/editor-loader.js b/src/plugins/global-settings/typography/editor-loader.js index 93413f77f0..29e56a05e0 100644 --- a/src/plugins/global-settings/typography/editor-loader.js +++ b/src/plugins/global-settings/typography/editor-loader.js @@ -1,6 +1,9 @@ /** * Loads all the typography styles for the blocks in the editor. */ +/** + * Internal dependencies + */ /** * External dependencies @@ -9,6 +12,7 @@ import { createTypographyStyles, fetchSettings, loadGoogleFont, + getDefaultFontSize, } from '~stackable/util' import { generateStyles } from '~stackable/block-components' import deepmerge from 'deepmerge' @@ -24,9 +28,17 @@ import { import { addAction, removeAction, applyFilters, doAction, addFilter, } from '@wordpress/hooks' -import { useSelect } from '@wordpress/data' +import { useSelect, dispatch } from '@wordpress/data' +import { models } from '@wordpress/api' + +let saveTypographyAsPresetsThrottle = null export const GlobalTypographyStyles = () => { + const { allCustomPresets } = useSelect( select => { + const _customPresetControls = select( 'stackable/global-preset-controls.custom' )?.getCustomPresetControls() ?? {} + return { allCustomPresets: { ..._customPresetControls } } + }, [] ) + const [ typographySettings, setTypographySettings ] = useState( [] ) const [ applySettingsTo, setApplySettingsTo ] = useState( '' ) const [ isApplyBodyToHTML, setIsApplyBodyToHTML ] = useState( false ) @@ -50,6 +62,53 @@ export const GlobalTypographyStyles = () => { return select( 'core/edit-site' )?.getEditorMode() || select( 'core/edit-post' )?.getEditorMode() } ) + // Update the custom presets when using typography as presets + const updatePresetsWithTypography = ( useTypographyAsPresets, typographySettings, tags ) => { + if ( useTypographyAsPresets ) { + const fontSizePresets = tags + .filter( ( { presetSlug } ) => !! presetSlug ) + .map( ( { + selector, presetName, presetSlug, + } ) => { + // If no fontSize available, the unit should default to px + const size = typographySettings[ selector ]?.fontSize + const unit = size ? typographySettings[ selector ]?.fontSizeUnit : 'px' + return { + name: presetName, + slug: presetSlug, + size: `${ size ?? getDefaultFontSize( selector ) ?? 16 }${ unit ?? 'px' }`, + } + } ) + // Add the preset for extra small + let xSmallSize = typographySettings[ '.stk-subtitle' ]?.fontSize ?? getDefaultFontSize( '.stk-subtitle' ) ?? 16 + let xSmallUnit = typographySettings[ '.stk-subtitle' ]?.fontSizeUnit ?? 'px' + if ( xSmallUnit === 'px' ) { + xSmallSize = Math.pow( xSmallSize / 16, 2 ) + xSmallUnit = 'rem' + } else { + xSmallSize = Math.pow( xSmallSize, 2 ) + } + + fontSizePresets.push( { + name: 'XS', + slug: 'x-small', + size: `${ xSmallSize }${ xSmallUnit ?? 'px' }`, + } ) + // Reverse the presets so it's from smallest to biggest + fontSizePresets.reverse() + + const newSettings = { ...allCustomPresets, fontSizes: fontSizePresets } + + clearTimeout( saveTypographyAsPresetsThrottle ) + saveTypographyAsPresetsThrottle = setTimeout( () => { + const settings = new models.Settings( { stackable_global_custom_preset_controls: newSettings } ) // eslint-disable-line camelcase + settings.save() + }, 300 ) + + dispatch( 'stackable/global-preset-controls.custom' ).updateCustomPresetControls( newSettings ) + } + } + useEffect( () => { // Get settings. fetchSettings().then( response => { @@ -60,8 +119,10 @@ export const GlobalTypographyStyles = () => { // Allow actions to trigger styles to update. addAction( 'stackable.global-settings.typography.update-trigger', 'stackable/typography-styles', ( - newTypographySettings, newAapplySettingsTo, newIsApplyBodyToHTML + newTypographySettings, newAapplySettingsTo, newUseTypographyAsPresets, newIsApplyBodyToHTML, tags ) => { + updatePresetsWithTypography( newUseTypographyAsPresets, newTypographySettings, tags ) + setTypographySettings( newTypographySettings ) setApplySettingsTo( newAapplySettingsTo ) setIsApplyBodyToHTML( newIsApplyBodyToHTML ) diff --git a/src/plugins/global-settings/typography/index.js b/src/plugins/global-settings/typography/index.js index 5c608f685a..bbaa0c6110 100644 --- a/src/plugins/global-settings/typography/index.js +++ b/src/plugins/global-settings/typography/index.js @@ -13,7 +13,7 @@ import { getAppliedTypeScale } from './utils' import { PanelAdvancedSettings, AdvancedSelectControl, ControlSeparator, FontPairPicker, ProControlButton, AdvancedToggleControl, } from '~stackable/components' -import { fetchSettings, getDefaultFontSize } from '~stackable/util' +import { fetchSettings } from '~stackable/util' import { i18n, isPro, showProNotice, } from 'stackable' @@ -32,7 +32,7 @@ import { addFilter, applyFilters, doAction, } from '@wordpress/hooks' import { __, sprintf } from '@wordpress/i18n' -import { dispatch, useSelect } from '@wordpress/data' +import { useSelect } from '@wordpress/data' export { GlobalTypographyStyles } @@ -142,13 +142,11 @@ const TYPE_SCALE = [ let saveTypographyThrottle = null let saveSelectedFontPairThrottle = null let saveCustomFontPairsThrottle = null -let saveTypographyAsPresetsThrottle = null addFilter( 'stackable.global-settings.inspector', 'stackable/global-typography', output => { - const { allCustomPresets, useTypographyAsPresets } = useSelect( select => { - const _customPresetControls = select( 'stackable/global-preset-controls.custom' )?.getCustomPresetControls() ?? {} + const { useTypographyAsPresets } = useSelect( select => { const _useTypographyAsPresets = select( 'stackable/global-preset-controls.custom' )?.getUseTypographyAsPresets() ?? false - return { allCustomPresets: { ..._customPresetControls }, useTypographyAsPresets: _useTypographyAsPresets } + return { useTypographyAsPresets: _useTypographyAsPresets } }, [] ) const FONT_PAIRS = applyFilters( 'stackable.global-settings.typography.font-pairs.premium-font-pairs', FREE_FONT_PAIRS ) @@ -192,57 +190,11 @@ addFilter( 'stackable.global-settings.inspector', 'stackable/global-typography', useEffect( () => { // When typography styles are changed, trigger our editor style generator to update. - doAction( 'stackable.global-settings.typography.update-trigger', typographySettings, applySettingsTo, isApplyBodyToHTML ) - }, [ JSON.stringify( typographySettings ), applySettingsTo, isApplyBodyToHTML ] ) - - useEffect( () => { - // When typography styles are changed, trigger our editor style generator to update. - doAction( 'stackable.global-settings.typography.update-trigger', typographySettings, applySettingsTo, isApplyBodyToHTML ) - - // Update the custom presets when using typography as presets - if ( useTypographyAsPresets ) { - const fontSizePresets = TYPOGRAPHY_TAGS - .filter( ( { presetSlug } ) => !! presetSlug ) - .map( ( { - selector, presetName, presetSlug, - } ) => { - const size = typographySettings[ selector ]?.fontSize ?? getDefaultFontSize( selector ) ?? 16 - const unit = typographySettings[ selector ]?.fontSizeUnit ?? 'px' - return { - name: presetName, - slug: presetSlug, - size: `${ size }${ unit }`, - } - } ) - // Add the preset for extra small - let xSmallSize = typographySettings[ '.stk-subtitle' ]?.fontSize ?? getDefaultFontSize( '.stk-subtitle' ) ?? 16 - let xSmallUnit = typographySettings[ '.stk-subtitle' ]?.fontSizeUnit ?? 'px' - if ( xSmallUnit === 'px' ) { - xSmallSize = Math.pow( xSmallSize / 16, 2 ) - xSmallUnit = 'rem' - } else { - xSmallSize = Math.pow( xSmallSize, 2 ) - } - - fontSizePresets.push( { - name: 'XS', - slug: 'x-small', - size: `${ xSmallSize }${ xSmallUnit ?? 'px' }`, - } ) - // Reverse the presets so it's from smallest to biggest - fontSizePresets.reverse() - - const newSettings = { ...allCustomPresets, fontSizes: fontSizePresets } - - clearTimeout( saveTypographyAsPresetsThrottle ) - saveTypographyAsPresetsThrottle = setTimeout( () => { - const settings = new models.Settings( { stackable_global_custom_preset_controls: newSettings } ) // eslint-disable-line camelcase - settings.save() - }, 300 ) - - dispatch( 'stackable/global-preset-controls.custom' ).updateCustomPresetControls( newSettings ) - } - }, [ JSON.stringify( typographySettings ), useTypographyAsPresets ] ) + // This also triggers updating presets with typography, and applying body font size to html. + doAction( 'stackable.global-settings.typography.update-trigger', + typographySettings, applySettingsTo, useTypographyAsPresets, isApplyBodyToHTML, TYPOGRAPHY_TAGS, + ) + }, [ JSON.stringify( typographySettings ), applySettingsTo, useTypographyAsPresets, isApplyBodyToHTML ] ) // Scroll to the selected font pair when Global Typography tab is toggled useEffect( () => { From 4098a505b5e0c5438c0043df2ca889c87259a845 Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Mon, 14 Apr 2025 09:29:02 +0800 Subject: [PATCH 58/99] fix: add typography deprecation for font size --- src/block-components/typography/attributes.js | 20 ++++-- src/block-components/typography/deprecated.js | 38 +++++++++++ src/block-components/typography/index.js | 4 +- src/block/button/deprecated.js | 22 +++++++ src/block/count-up/deprecated.js | 23 ++++++- src/block/countdown/deprecated.js | 31 ++++++++- src/block/heading/deprecated.js | 23 ++++++- src/block/icon-list-item/deprecated.js | 21 ++++++- src/block/icon-list/deprecated/index.js | 62 +++++++++++++++++- src/block/image/deprecated.js | 23 ++++++- src/block/number-box/deprecated.js | 21 ++++++- src/block/posts/deprecated.js | 63 +++++++++++++++++++ src/block/progress-bar/deprecated.js | 23 ++++++- src/block/progress-circle/deprecated.js | 23 ++++++- src/block/subtitle/deprecated.js | 23 ++++++- src/block/tab-labels/deprecated.js | 27 +++++++- src/block/table-of-contents/deprecated.js | 24 ++++++- src/block/text/deprecated.js | 23 ++++++- src/block/timeline/deprecated.js | 23 ++++++- 19 files changed, 496 insertions(+), 21 deletions(-) diff --git a/src/block-components/typography/attributes.js b/src/block-components/typography/attributes.js index 9e8c87512f..3b26b76a3a 100644 --- a/src/block-components/typography/attributes.js +++ b/src/block-components/typography/attributes.js @@ -1,12 +1,6 @@ import { deprecatedAddAttributes } from './deprecated' const typographyAttributes = { - fontSize: { - stkResponsive: true, - type: 'string', - default: '', - stkUnits: 'px', - }, lineHeight: { stkResponsive: true, type: 'number', @@ -104,4 +98,18 @@ export const addAttributes = ( attrObject, selector = '.stk-content', options = versionDeprecated: '', attrNameTemplate, } ) + + attrObject.add( { + attributes: { + fontSize: { + stkResponsive: true, + type: 'string', + default: '', + stkUnits: 'px', + }, + }, + versionAdded: '3.15.3', + versionDeprecated: '', + attrNameTemplate, + } ) } diff --git a/src/block-components/typography/deprecated.js b/src/block-components/typography/deprecated.js index 968b066982..db634c525c 100644 --- a/src/block-components/typography/deprecated.js +++ b/src/block-components/typography/deprecated.js @@ -22,6 +22,20 @@ export const deprecatedAddAttributes = ( attrObject, options ) => { versionDeprecated: '3.12.0', attrNameTemplate, } ) + + attrObject.add( { + attributes: { + fontSize: { + stkResponsive: true, + type: 'number', + default: '', + stkUnits: 'px', + }, + }, + versionAdded: '3.0.0', + versionDeprecated: '3.15.3', + attrNameTemplate, + } ) } export const deprecateTypographyGradientColor = { @@ -96,3 +110,27 @@ export const deprecateTypographyShadowColor = { return newAttributes }, } + +export const deprecateTypographyFontSize = { + isEligible: attrNameTemplate => attributes => { + const getAttrName = getAttrNameFunction( attrNameTemplate ) + const getAttribute = _attrName => attributes[ getAttrName( _attrName ) ] + + const fontSize = getAttribute( 'fontSize' ) + + return typeof fontSize === 'number' + }, + migrate: attrNameTemplate => attributes => { + const getAttrName = getAttrNameFunction( attrNameTemplate ) + const getAttribute = _attrName => attributes[ getAttrName( _attrName ) ] + + const fontSize = getAttribute( 'fontSize' ) + + const newAttributes = { + ...attributes, + [ getAttrName( 'fontSize' ) ]: String( fontSize ), + } + + return newAttributes + }, +} diff --git a/src/block-components/typography/index.js b/src/block-components/typography/index.js index 33f5d196a5..664ca2e384 100644 --- a/src/block-components/typography/index.js +++ b/src/block-components/typography/index.js @@ -28,7 +28,9 @@ import { memo, } from '@wordpress/element' -export { deprecateTypographyGradientColor, deprecateTypographyShadowColor } from './deprecated' +export { + deprecateTypographyGradientColor, deprecateTypographyShadowColor, deprecateTypographyFontSize, +} from './deprecated' export const Typography = memo( forwardRef( ( props, ref ) => { const { diff --git a/src/block/button/deprecated.js b/src/block/button/deprecated.js index e7b1f9febc..39beef85dd 100644 --- a/src/block/button/deprecated.js +++ b/src/block/button/deprecated.js @@ -6,9 +6,31 @@ import { deprecateBlockBackgroundColorOpacity, deprecateButtonGradientColor, deprecateContainerBackgroundColorOpacity, deprecateShadowColor, deprecateContainerShadowColor, deprecateBlockShadowColor, + deprecateTypographyFontSize, } from '~stackable/block-components' const deprecated = [ + { + // Support the change of type for fontSize + attributes: attributes( '3.15.2' ), + save: withVersion( '3.15.2' )( Save ), + isEligible: attributes => { + return deprecateTypographyFontSize.isEligible( 'button%s' )( attributes ) + }, + migrate: attributes => { + let newAttributes = { ...attributes } + + newAttributes = deprecateBlockShadowColor.migrate( newAttributes ) + newAttributes = deprecateContainerShadowColor.migrate( newAttributes ) + newAttributes = deprecateShadowColor.migrate( 'button%s' )( newAttributes ) + newAttributes = deprecateContainerBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateButtonGradientColor.migrate( 'button%s' )( newAttributes ) + newAttributes = deprecateTypographyFontSize.migrate( 'button%s' )( newAttributes ) + + return newAttributes + }, + }, { // Support the new shadow color. attributes: attributes( '3.12.11' ), diff --git a/src/block/count-up/deprecated.js b/src/block/count-up/deprecated.js index 0db6560075..a9151421e6 100644 --- a/src/block/count-up/deprecated.js +++ b/src/block/count-up/deprecated.js @@ -4,10 +4,31 @@ import { attributes } from './schema' import { withVersion } from '~stackable/higher-order' import { deprecateBlockBackgroundColorOpacity, deprecateContainerBackgroundColorOpacity, deprecateTypographyGradientColor, - deprecateTypographyShadowColor, deprecateBlockShadowColor, deprecateContainerShadowColor, + deprecateTypographyShadowColor, deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateTypographyFontSize, } from '~stackable/block-components' const deprecated = [ + { + // Support the change of type for fontSize + attributes: attributes( '3.15.2' ), + save: withVersion( '3.15.2' )( Save ), + isEligible: attributes => { + return deprecateTypographyFontSize.isEligible( '%s' )( attributes ) + }, + migrate: attributes => { + let newAttributes = { ...attributes } + + newAttributes = deprecateContainerBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateTypographyGradientColor.migrate( '%s' )( newAttributes ) + newAttributes = deprecateBlockShadowColor.migrate( newAttributes ) + newAttributes = deprecateContainerShadowColor.migrate( newAttributes ) + newAttributes = deprecateTypographyShadowColor.migrate( '%s' )( newAttributes ) + newAttributes = deprecateTypographyFontSize.migrate( '%s' )( newAttributes ) + + return newAttributes + }, + }, { // Support the new shadow color. attributes: attributes( '3.12.11' ), diff --git a/src/block/countdown/deprecated.js b/src/block/countdown/deprecated.js index 31e834a1aa..c3e3a07bc1 100644 --- a/src/block/countdown/deprecated.js +++ b/src/block/countdown/deprecated.js @@ -1,6 +1,6 @@ import { deprecateBlockBackgroundColorOpacity, deprecateContainerBackgroundColorOpacity, deprecateTypographyGradientColor, - deprecateBlockShadowColor, deprecateContainerShadowColor, + deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateTypographyFontSize, } from '~stackable/block-components' import { Save } from './save' import { attributes } from './schema' @@ -8,6 +8,35 @@ import { attributes } from './schema' import { withVersion } from '~stackable/higher-order' const deprecated = [ + { + // Support the change of type for fontSize + attributes: attributes( '3.15.2' ), + save: withVersion( '3.15.2' )( Save ), + isEligible: attributes => { + const hasDigitFontSize = deprecateTypographyFontSize.isEligible( 'digit%s' )( attributes ) + const hasLabelFontSize = deprecateTypographyFontSize.isEligible( 'label%s' )( attributes ) + const hasMessageFontSize = deprecateTypographyFontSize.isEligible( 'message%s' )( attributes ) + const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' + + return hasDigitFontSize || hasLabelFontSize || hasMessageFontSize || isNotV4 + }, + migrate: attributes => { + let newAttributes = { ...attributes } + + newAttributes = deprecateContainerBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateTypographyGradientColor.migrate( 'digit%s' )( newAttributes ) + newAttributes = deprecateTypographyGradientColor.migrate( 'label%s' )( newAttributes ) + newAttributes = deprecateTypographyGradientColor.migrate( 'message%s' )( newAttributes ) + newAttributes = deprecateBlockShadowColor.migrate( newAttributes ) + newAttributes = deprecateContainerShadowColor.migrate( newAttributes ) + newAttributes = deprecateTypographyFontSize.migrate( 'digit%s' )( newAttributes ) + newAttributes = deprecateTypographyFontSize.migrate( 'label%s' )( newAttributes ) + newAttributes = deprecateTypographyFontSize.migrate( 'message%s' )( newAttributes ) + + return newAttributes + }, + }, { // Support the new shadow color. attributes: attributes( '3.12.11' ), diff --git a/src/block/heading/deprecated.js b/src/block/heading/deprecated.js index e8cc3be197..59416795a0 100644 --- a/src/block/heading/deprecated.js +++ b/src/block/heading/deprecated.js @@ -11,7 +11,7 @@ import { withVersion } from '~stackable/higher-order' import compareVersions from 'compare-versions' import { deprecateBlockBackgroundColorOpacity, deprecateContainerBackgroundColorOpacity, deprecateTypographyGradientColor, getResponsiveClasses, - deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateTypographyShadowColor, + deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateTypographyShadowColor, deprecateTypographyFontSize, } from '~stackable/block-components' /** @@ -34,6 +34,27 @@ addFilter( 'stackable.heading.save.blockClassNames', 'stackable/3.6.1', ( output } ) const deprecated = [ + { + // Support the change of type for fontSize + attributes: attributes( '3.15.2' ), + save: withVersion( '3.15.2' )( Save ), + isEligible: attributes => { + return deprecateTypographyFontSize.isEligible( '%s' )( attributes ) + }, + migrate: attributes => { + let newAttributes = { ...attributes } + + newAttributes = deprecateContainerBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateTypographyGradientColor.migrate( '%s' )( newAttributes ) + newAttributes = deprecateBlockShadowColor.migrate( newAttributes ) + newAttributes = deprecateContainerShadowColor.migrate( newAttributes ) + newAttributes = deprecateTypographyShadowColor.migrate( '%s' )( newAttributes ) + newAttributes = deprecateTypographyFontSize.migrate( '%s' )( newAttributes ) + + return newAttributes + }, + }, { // Support the new shadow color. attributes: attributes( '3.12.11' ), diff --git a/src/block/icon-list-item/deprecated.js b/src/block/icon-list-item/deprecated.js index 2c6633b1ac..f3d73a8440 100644 --- a/src/block/icon-list-item/deprecated.js +++ b/src/block/icon-list-item/deprecated.js @@ -2,9 +2,28 @@ import { Save } from './save' import { attributes } from './schema' import { withVersion } from '~stackable/higher-order' -import { deprecateBlockShadowColor, deprecateContainerShadowColor } from '~stackable/block-components' +import { + deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateTypographyFontSize, +} from '~stackable/block-components' const deprecated = [ + { + // Support the change of type for fontSize + attributes: attributes( '3.15.2' ), + save: withVersion( '3.15.2' )( Save ), + isEligible: attributes => { + return deprecateTypographyFontSize.isEligible( '%s' )( attributes ) + }, + migrate: attributes => { + let newAttributes = { ...attributes } + + newAttributes = deprecateBlockShadowColor.migrate( newAttributes ) + newAttributes = deprecateContainerShadowColor.migrate( newAttributes ) + newAttributes = deprecateTypographyFontSize.migrate( '%s' )( newAttributes ) + + return newAttributes + }, + }, { // Support the new shadow color. attributes: attributes( '3.12.11' ), diff --git a/src/block/icon-list/deprecated/index.js b/src/block/icon-list/deprecated/index.js index a137d3593c..9e47890457 100644 --- a/src/block/icon-list/deprecated/index.js +++ b/src/block/icon-list/deprecated/index.js @@ -4,7 +4,7 @@ import { attributes } from './schema' import { withVersion } from '~stackable/higher-order' import { deprecateBlockBackgroundColorOpacity, deprecateContainerBackgroundColorOpacity, deprecateTypographyGradientColor, - deprecateBlockShadowColor, deprecateContainerShadowColor, + deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateTypographyFontSize, } from '~stackable/block-components' import { createUniqueClass } from '~stackable/util' @@ -68,6 +68,66 @@ const getEquivalentIconSize = iconSize => { } const deprecated = [ + { + // Support the new shadow color. + attributes: attributes( '3.15.2' ), + save: withVersion( '3.15.2' )( Save ), + isEligible: attributes => { + return deprecateTypographyFontSize.isEligible( '%s' )( attributes ) + }, + supports: { + anchor: true, + spacing: true, + __unstablePasteTextInline: true, + __experimentalSelector: 'ol,ul', + __experimentalOnMerge: true, + }, + migrate: ( attributes, innerBlocks ) => { + let newAttributes = { ...attributes } + const { + text, icons, iconSize, ordered, iconGap, + } = attributes + + const _iconSize = iconSize ? iconSize : 1 + const _iconGap = iconGap ? iconGap : 0 + + newAttributes = { + ...newAttributes, + listFullWidth: false, + iconVerticalAlignment: 'baseline', + iconGap: _iconGap + 4, // Our gap is smaller now. + iconSize: ordered + ? getEquivalentFontSize( _iconSize ) + : getEquivalentIconSize( _iconSize ), + } + + if ( ! text ) { + const block = createBlock( 'stackable/icon-list-item' ) + innerBlocks = [ block ] + } else { + const contents = textToArray( text ) + const blocks = contents.map( ( content, index ) => { + const newBlock = createBlock( 'stackable/icon-list-item', { + text: content, + icon: getUniqueIcon( icons, index ), + } ) + newBlock.attributes.uniqueId = createUniqueClass( newBlock.clientId ) + + return newBlock + } ) + innerBlocks = blocks + } + + newAttributes = deprecateContainerBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateTypographyGradientColor.migrate( '%s' )( newAttributes ) + newAttributes = deprecateBlockShadowColor.migrate( newAttributes ) + newAttributes = deprecateContainerShadowColor.migrate( newAttributes ) + newAttributes = deprecateTypographyFontSize.migrate( '%s' )( newAttributes ) + + return [ newAttributes, innerBlocks ] + }, + }, { // Support the new shadow color. attributes: attributes( '3.12.11' ), diff --git a/src/block/image/deprecated.js b/src/block/image/deprecated.js index 04e709ee1a..52ad380b79 100644 --- a/src/block/image/deprecated.js +++ b/src/block/image/deprecated.js @@ -4,7 +4,7 @@ import { attributes } from './schema' import { withVersion } from '~stackable/higher-order' import { deprecateBlockBackgroundColorOpacity, deprecateContainerBackgroundColorOpacity, deprecationImageOverlayOpacity, - deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateShadowColor, + deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateShadowColor, deprecateTypographyFontSize, } from '~stackable/block-components' import { RichText } from '@wordpress/block-editor' @@ -59,6 +59,27 @@ addFilter( 'stackable.image.save.wrapper', 'stackable/image-caption-wrapper', ( } ) const deprecated = [ + { + // Support the change of type for fontSize + attributes: attributes( '3.15.2' ), + save: withVersion( '3.15.2' )( Save ), + isEligible: attributes => { + return deprecateTypographyFontSize.isEligible( 'figcaption%s' )( attributes ) + }, + migrate: attributes => { + let newAttributes = { ...attributes } + + newAttributes = deprecationImageOverlayOpacity.migrate( newAttributes ) + newAttributes = deprecateContainerBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockShadowColor.migrate( newAttributes ) + newAttributes = deprecateContainerShadowColor.migrate( newAttributes ) + newAttributes = deprecateShadowColor.migrate( 'image%s' )( newAttributes ) + newAttributes = deprecateTypographyFontSize.migrate( 'figcaption%s' )( newAttributes ) + + return newAttributes + }, + }, { // Support the new shadow color. attributes: attributes( '3.12.11' ), diff --git a/src/block/number-box/deprecated.js b/src/block/number-box/deprecated.js index 45adeda965..2775402b5c 100644 --- a/src/block/number-box/deprecated.js +++ b/src/block/number-box/deprecated.js @@ -4,7 +4,7 @@ import { attributes } from './schema' import { withVersion } from '~stackable/higher-order' import { deprecateBlockBackgroundColorOpacity, deprecateTypographyGradientColor, deprecationBackgrounColorOpacity, - deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateShadowColor, + deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateShadowColor, deprecateTypographyFontSize, BlockDiv, CustomCSS, Typography, getResponsiveClasses, getTypographyClasses, getAlignmentClasses, } from '~stackable/block-components' @@ -53,6 +53,25 @@ const depecatedSave_3_13_11 = props => { } const deprecated = [ + { + // Support the change of type for fontSize + attributes: attributes( '3.15.2' ), + save: withVersion( '3.15.2' )( Save ), + isEligible: attributes => { + return deprecateTypographyFontSize.isEligible( '%s' )( attributes ) + }, + migrate: attributes => { + let newAttributes = deprecateBlockBackgroundColorOpacity.migrate( attributes ) + newAttributes = deprecationBackgrounColorOpacity.migrate( 'shape%s' )( newAttributes ) + newAttributes = deprecateTypographyGradientColor.migrate( '%s' )( newAttributes ) + newAttributes = deprecateBlockShadowColor.migrate( newAttributes ) + newAttributes = deprecateContainerShadowColor.migrate( newAttributes ) + newAttributes = deprecateShadowColor.migrate( 'shape%s' )( newAttributes ) + newAttributes = deprecateTypographyFontSize.migrate( '%s' )( newAttributes ) + + return newAttributes + }, + }, { attributes: attributes( '3.13.11' ), save: depecatedSave_3_13_11, diff --git a/src/block/posts/deprecated.js b/src/block/posts/deprecated.js index 88bb28a624..9df29f28ba 100644 --- a/src/block/posts/deprecated.js +++ b/src/block/posts/deprecated.js @@ -13,6 +13,7 @@ import { Image, deprecateBlockBackgroundColorOpacity, deprecateContainerBackgroundColorOpacity, deprecateTypographyGradientColor, deprecationImageOverlayOpacity, deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateShadowColor, + deprecateTypographyFontSize, } from '~stackable/block-components' /** @@ -41,6 +42,68 @@ addFilter( 'stackable.posts.title.readmore-content', 'stackable/3_0_2', addUndef addFilter( 'stackable.posts.feature-image', 'stackable/3_6_3', determineFeatureImage ) const deprecated = [ + { + // Support the new shadow color. + attributes: attributes( '3.15.2' ), + save: withVersion( '3.15.2' )( Save ), + isEligible: attributes => { + const hasFontSize = deprecateTypographyFontSize.isEligible( '%s' )( attributes ) + const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' + + return hasFontSize || isNotV4 + }, + migrate: attributes => { + let newAttributes = { + ...attributes, + version: 2, + } + + // We used to have an "Inner content width" which is now just the block width + const hasOldInnerContentWidth = attributes.innerBlockContentWidth || attributes.innerBlockContentWidthTablet || attributes.innerBlockContentWidthMobile + + if ( hasOldInnerContentWidth ) { + newAttributes = { + ...newAttributes, + innerBlockContentWidth: '', + innerBlockContentWidthTablet: '', + innerBlockContentWidthMobile: '', + innerBlockContentWidthUnit: 'px', + innerBlockContentWidthUnitTablet: '', + innerBlockContentWidthUnitMobile: '', + blockWidth: attributes.innerBlockContentWidth, + blockWidthTablet: attributes.innerBlockContentWidthTablet, + blockWidthMobile: attributes.innerBlockContentWidthMobile, + blockWidthUnit: attributes.innerBlockContentWidthUnit, + blockWidthUnitTablet: attributes.innerBlockContentWidthUnitTablet, + blockWidthUnitMobile: attributes.innerBlockContentWidthUnitMobile, + innerBlockAlign: '', + innerBlockAlignTablet: '', + innerBlockAlignMobile: '', + blockHorizontalAlign: attributes.innerBlockAlign, + blockHorizontalAlignTablet: attributes.innerBlockAlignTablet, + blockHorizontalAlignMobile: attributes.innerBlockAlignMobile, + } + } + + newAttributes = deprecationImageOverlayOpacity.migrate( newAttributes ) + newAttributes = deprecateContainerBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockBackgroundColorOpacity.migrate( newAttributes ) + + newAttributes = deprecateTypographyGradientColor.migrate( 'title%s' )( newAttributes ) + newAttributes = deprecateTypographyGradientColor.migrate( 'category%s' )( newAttributes ) + newAttributes = deprecateTypographyGradientColor.migrate( 'excerpt%s' )( newAttributes ) + newAttributes = deprecateTypographyGradientColor.migrate( 'meta%s' )( newAttributes ) + newAttributes = deprecateTypographyGradientColor.migrate( 'readmore%s' )( newAttributes ) + + newAttributes = deprecateBlockShadowColor.migrate( newAttributes ) + newAttributes = deprecateContainerShadowColor.migrate( newAttributes ) + newAttributes = deprecateShadowColor.migrate( 'image%s' )( newAttributes ) + + newAttributes = deprecateTypographyFontSize.migrate( '%s' )( newAttributes ) + + return newAttributes + }, + }, { // Support the new shadow color. attributes: attributes( '3.12.11' ), diff --git a/src/block/progress-bar/deprecated.js b/src/block/progress-bar/deprecated.js index 0db6560075..a9151421e6 100644 --- a/src/block/progress-bar/deprecated.js +++ b/src/block/progress-bar/deprecated.js @@ -4,10 +4,31 @@ import { attributes } from './schema' import { withVersion } from '~stackable/higher-order' import { deprecateBlockBackgroundColorOpacity, deprecateContainerBackgroundColorOpacity, deprecateTypographyGradientColor, - deprecateTypographyShadowColor, deprecateBlockShadowColor, deprecateContainerShadowColor, + deprecateTypographyShadowColor, deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateTypographyFontSize, } from '~stackable/block-components' const deprecated = [ + { + // Support the change of type for fontSize + attributes: attributes( '3.15.2' ), + save: withVersion( '3.15.2' )( Save ), + isEligible: attributes => { + return deprecateTypographyFontSize.isEligible( '%s' )( attributes ) + }, + migrate: attributes => { + let newAttributes = { ...attributes } + + newAttributes = deprecateContainerBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateTypographyGradientColor.migrate( '%s' )( newAttributes ) + newAttributes = deprecateBlockShadowColor.migrate( newAttributes ) + newAttributes = deprecateContainerShadowColor.migrate( newAttributes ) + newAttributes = deprecateTypographyShadowColor.migrate( '%s' )( newAttributes ) + newAttributes = deprecateTypographyFontSize.migrate( '%s' )( newAttributes ) + + return newAttributes + }, + }, { // Support the new shadow color. attributes: attributes( '3.12.11' ), diff --git a/src/block/progress-circle/deprecated.js b/src/block/progress-circle/deprecated.js index 0db6560075..a9151421e6 100644 --- a/src/block/progress-circle/deprecated.js +++ b/src/block/progress-circle/deprecated.js @@ -4,10 +4,31 @@ import { attributes } from './schema' import { withVersion } from '~stackable/higher-order' import { deprecateBlockBackgroundColorOpacity, deprecateContainerBackgroundColorOpacity, deprecateTypographyGradientColor, - deprecateTypographyShadowColor, deprecateBlockShadowColor, deprecateContainerShadowColor, + deprecateTypographyShadowColor, deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateTypographyFontSize, } from '~stackable/block-components' const deprecated = [ + { + // Support the change of type for fontSize + attributes: attributes( '3.15.2' ), + save: withVersion( '3.15.2' )( Save ), + isEligible: attributes => { + return deprecateTypographyFontSize.isEligible( '%s' )( attributes ) + }, + migrate: attributes => { + let newAttributes = { ...attributes } + + newAttributes = deprecateContainerBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateTypographyGradientColor.migrate( '%s' )( newAttributes ) + newAttributes = deprecateBlockShadowColor.migrate( newAttributes ) + newAttributes = deprecateContainerShadowColor.migrate( newAttributes ) + newAttributes = deprecateTypographyShadowColor.migrate( '%s' )( newAttributes ) + newAttributes = deprecateTypographyFontSize.migrate( '%s' )( newAttributes ) + + return newAttributes + }, + }, { // Support the new shadow color. attributes: attributes( '3.12.11' ), diff --git a/src/block/subtitle/deprecated.js b/src/block/subtitle/deprecated.js index a0c6c42406..586654d9ca 100644 --- a/src/block/subtitle/deprecated.js +++ b/src/block/subtitle/deprecated.js @@ -4,10 +4,31 @@ import { attributes } from './schema' import { withVersion } from '~stackable/higher-order' import { deprecateBlockBackgroundColorOpacity, deprecateContainerBackgroundColorOpacity, deprecateTypographyGradientColor, - deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateTypographyShadowColor, + deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateTypographyShadowColor, deprecateTypographyFontSize, } from '~stackable/block-components' const deprecated = [ + { + // Support the change of type for fontSize + attributes: attributes( '3.15.2' ), + save: withVersion( '3.15.2' )( Save ), + isEligible: attributes => { + return deprecateTypographyFontSize.isEligible( '%s' )( attributes ) + }, + migrate: attributes => { + let newAttributes = { ...attributes } + + newAttributes = deprecateContainerBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateTypographyGradientColor.migrate( '%s' )( newAttributes ) + newAttributes = deprecateBlockShadowColor.migrate( newAttributes ) + newAttributes = deprecateContainerShadowColor.migrate( newAttributes ) + newAttributes = deprecateTypographyShadowColor.migrate( '%s' )( newAttributes ) + newAttributes = deprecateTypographyFontSize.migrate( '%s' )( newAttributes ) + + return newAttributes + }, + }, { // Support the new shadow color. attributes: attributes( '3.12.11' ), diff --git a/src/block/tab-labels/deprecated.js b/src/block/tab-labels/deprecated.js index 6f6cca19d5..96cc92cb7d 100644 --- a/src/block/tab-labels/deprecated.js +++ b/src/block/tab-labels/deprecated.js @@ -1,6 +1,6 @@ import { deprecateBlockBackgroundColorOpacity, deprecateButtonGradientColor, deprecateContainerBackgroundColorOpacity, deprecateTypographyGradientColor, - deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateShadowColor, deprecateTypographyShadowColor, + deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateShadowColor, deprecateTypographyShadowColor, deprecateTypographyFontSize, } from '~stackable/block-components' import { Save } from './save' import { attributes } from './schema' @@ -8,6 +8,31 @@ import { attributes } from './schema' import { withVersion } from '~stackable/higher-order' const deprecated = [ + { + // Support the change of type for fontSize + attributes: attributes( '3.15.2' ), + save: withVersion( '3.15.2' )( Save ), + isEligible: attributes => { + return deprecateTypographyFontSize.isEligible( 'tab%s' )( attributes ) + }, + migrate: attributes => { + let newAttributes = { ...attributes } + + newAttributes = deprecateContainerBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateTypographyGradientColor.migrate( 'tab%s' )( newAttributes ) + newAttributes = deprecateButtonGradientColor.migrate( 'tab%s' )( newAttributes ) + newAttributes = deprecateButtonGradientColor.migrate( 'activeTab%s' )( newAttributes ) + newAttributes = deprecateBlockShadowColor.migrate( newAttributes ) + newAttributes = deprecateContainerShadowColor.migrate( newAttributes ) + newAttributes = deprecateTypographyShadowColor.migrate( '%s' )( newAttributes ) + newAttributes = deprecateShadowColor.migrate( 'tab%s' )( newAttributes ) + newAttributes = deprecateShadowColor.migrate( 'activeTab%s' )( newAttributes ) + newAttributes = deprecateTypographyFontSize.migrate( 'tab%s' )( newAttributes ) + + return newAttributes + }, + }, { // Support the new shadow color. attributes: attributes( '3.12.11' ), diff --git a/src/block/table-of-contents/deprecated.js b/src/block/table-of-contents/deprecated.js index 1aa3cccf62..6abb5a19ac 100644 --- a/src/block/table-of-contents/deprecated.js +++ b/src/block/table-of-contents/deprecated.js @@ -11,7 +11,7 @@ import { withVersion } from '~stackable/higher-order' import compareVersions from 'compare-versions' import { deprecateBlockBackgroundColorOpacity, deprecateContainerBackgroundColorOpacity, deprecateTypographyGradientColor, - deprecateBlockShadowColor, deprecateContainerShadowColor, + deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateTypographyFontSize, } from '~stackable/block-components' /** @@ -36,6 +36,28 @@ addFilter( 'stackable.table-of-contents.save.tableOfContentsClasses', 'stackable } ) const deprecated = [ + { + // Support the change of type for fontSize + attributes: attributes( '3.15.2' ), + save: withVersion( '3.15.2' )( Save ), + isEligible: attributes => { + return deprecateTypographyFontSize.isEligible( 'title%s' )( attributes ) + }, + migrate: attributes => { + let newAttributes = { ...attributes } + + newAttributes = deprecateContainerBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateTypographyGradientColor.migrate( '%s' )( newAttributes ) + newAttributes = deprecateTypographyGradientColor.migrate( 'title%s' )( newAttributes ) + newAttributes = deprecateBlockShadowColor.migrate( newAttributes ) + newAttributes = deprecateContainerShadowColor.migrate( newAttributes ) + newAttributes = deprecateTypographyFontSize.migrate( '%s' )( newAttributes ) + newAttributes = deprecateTypographyFontSize.migrate( 'title%s' )( newAttributes ) + + return newAttributes + }, + }, { // Support the new shadow color. attributes: attributes( '3.12.11' ), diff --git a/src/block/text/deprecated.js b/src/block/text/deprecated.js index 57d902aa2b..393a7baa74 100644 --- a/src/block/text/deprecated.js +++ b/src/block/text/deprecated.js @@ -4,10 +4,31 @@ import { attributes } from './schema' import { withVersion } from '~stackable/higher-order' import { deprecateBlockBackgroundColorOpacity, deprecateContainerBackgroundColorOpacity, deprecateTypographyGradientColor, - deprecateTypographyShadowColor, deprecateBlockShadowColor, deprecateContainerShadowColor, + deprecateTypographyShadowColor, deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateTypographyFontSize, } from '~stackable/block-components' const deprecated = [ + { + // Support the change of type for fontSize + attributes: attributes( '3.15.2' ), + save: withVersion( '3.15.2' )( Save ), + isEligible: attributes => { + return deprecateTypographyFontSize.isEligible( '%s' )( attributes ) + }, + migrate: attributes => { + let newAttributes = { ...attributes } + + newAttributes = deprecateContainerBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateTypographyGradientColor.migrate( '%s' )( newAttributes ) + newAttributes = deprecateBlockShadowColor.migrate( newAttributes ) + newAttributes = deprecateContainerShadowColor.migrate( newAttributes ) + newAttributes = deprecateTypographyShadowColor.migrate( '%s' )( newAttributes ) + newAttributes = deprecateTypographyFontSize.migrate( '%s' )( newAttributes ) + + return newAttributes + }, + }, { // Support the new shadow color. attributes: attributes( '3.12.11' ), diff --git a/src/block/timeline/deprecated.js b/src/block/timeline/deprecated.js index 8ef5054ff1..9ded4d89b2 100644 --- a/src/block/timeline/deprecated.js +++ b/src/block/timeline/deprecated.js @@ -1,6 +1,6 @@ import { deprecateBlockBackgroundColorOpacity, deprecateContainerBackgroundColorOpacity, deprecateTypographyGradientColor, - deprecateTypographyShadowColor, deprecateBlockShadowColor, deprecateContainerShadowColor, + deprecateTypographyShadowColor, deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateTypographyFontSize, } from '~stackable/block-components' import { Save } from './save' import { attributes } from './schema' @@ -8,6 +8,27 @@ import { attributes } from './schema' import { withVersion } from '~stackable/higher-order' const deprecated = [ + { + // Support the change of type for fontSize + attributes: attributes( '3.15.2' ), + save: withVersion( '3.15.2' )( Save ), + isEligible: attributes => { + return deprecateTypographyFontSize.isEligible( '%s' )( attributes ) + }, + migrate: attributes => { + let newAttributes = { ...attributes } + + newAttributes = deprecateContainerBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateTypographyGradientColor.migrate( '%s' )( newAttributes ) + newAttributes = deprecateBlockShadowColor.migrate( newAttributes ) + newAttributes = deprecateContainerShadowColor.migrate( newAttributes ) + newAttributes = deprecateTypographyShadowColor.migrate( '%s' )( newAttributes ) + newAttributes = deprecateTypographyFontSize.migrate( '%s' )( newAttributes ) + + return newAttributes + }, + }, { // Support the new shadow color. attributes: attributes( '3.12.11' ), From 4a6815300324f9e401af1d048827ef4c893feda4 Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Mon, 14 Apr 2025 11:56:51 +0800 Subject: [PATCH 59/99] fix: add block height deprecations --- src/block-components/block-div/deprecated.js | 13 +++- src/block-components/block-div/index.js | 4 +- .../helpers/size/attributes.js | 24 ++++-- .../helpers/size/deprecated.js | 41 ++++++++++ src/block-components/helpers/size/index.js | 1 + src/block/accordion/deprecated.js | 21 +++++- src/block/blockquote/deprecated.js | 26 ++++++- src/block/button-group/deprecated/index.js | 21 +++++- src/block/button/deprecated.js | 7 +- src/block/call-to-action/deprecated.js | 73 +++++++++++++++++- src/block/card/deprecated.js | 72 +++++++++++++++++- src/block/carousel/deprecated.js | 23 +++++- src/block/column/deprecated.js | 75 ++++++++++++++++++- src/block/columns/deprecated.js | 29 +++++++ src/block/count-up/deprecated.js | 8 +- src/block/countdown/deprecated.js | 8 +- src/block/divider/deprecated.js | 21 +++++- src/block/expand/deprecated.js | 21 +++++- src/block/feature-grid/deprecated.js | 29 +++++++ src/block/feature/deprecated.js | 38 ++++++++++ src/block/heading/deprecated.js | 9 ++- src/block/hero/deprecated.js | 72 ++++++++++++++++++ src/block/horizontal-scroller/deprecated.js | 21 +++++- src/block/icon-box/deprecated.js | 37 ++++++++- src/block/icon-button/deprecated.js | 23 +++++- src/block/icon-label/deprecated.js | 17 ++++- src/block/icon-list-item/deprecated.js | 9 ++- src/block/icon-list/deprecated/index.js | 9 ++- src/block/icon/deprecated.js | 21 +++++- src/block/image-box/deprecated.js | 21 +++++- src/block/image/deprecated.js | 6 +- src/block/map/deprecated.js | 21 +++++- src/block/notification/deprecated.js | 71 +++++++++++++++++- src/block/number-box/deprecated.js | 6 +- src/block/posts/deprecated.js | 22 ++++-- src/block/price/deprecated.js | 21 +++++- src/block/pricing-box/deprecated.js | 71 +++++++++++++++++- src/block/progress-bar/deprecated.js | 8 +- src/block/progress-circle/deprecated.js | 8 +- src/block/separator/deprecated.js | 21 ++++++ src/block/spacer/deprecated.js | 21 +++++- src/block/subtitle/deprecated.js | 8 +- src/block/tab-content/deprecated.js | 21 +++++- src/block/tab-labels/deprecated.js | 8 +- src/block/table-of-contents/deprecated.js | 9 ++- src/block/tabs/deprecated.js | 32 +++++++- src/block/team-member/deprecated.js | 71 +++++++++++++++++- src/block/testimonial/deprecated.js | 71 +++++++++++++++++- src/block/text/deprecated.js | 6 +- src/block/timeline/deprecated.js | 6 +- src/block/video-popup/deprecated.js | 17 ++++- 51 files changed, 1250 insertions(+), 69 deletions(-) create mode 100644 src/block-components/helpers/size/deprecated.js diff --git a/src/block-components/block-div/deprecated.js b/src/block-components/block-div/deprecated.js index f8f2655b80..f6571a9513 100644 --- a/src/block-components/block-div/deprecated.js +++ b/src/block-components/block-div/deprecated.js @@ -1,4 +1,6 @@ -import { deprecationBackgrounColorOpacity, deprecateShadowColor } from '../helpers' +import { + deprecationBackgrounColorOpacity, deprecateShadowColor, deprecateSizeControlHeight, +} from '../helpers' import { addFilter } from '@wordpress/hooks' import { semverCompare } from '~stackable/util' @@ -38,3 +40,12 @@ export const deprecateBlockShadowColor = { return deprecateShadowColor.migrate( 'block%s' )( attributes ) }, } + +export const deprecateBlockHeight = { + isEligible: attributes => { + return deprecateSizeControlHeight.isEligible( 'block%s' )( attributes ) + }, + migrate: attributes => { + return deprecateSizeControlHeight.migrate( 'block%s' )( attributes ) + }, +} diff --git a/src/block-components/block-div/index.js b/src/block-components/block-div/index.js index 123eaacbe2..de84319ed1 100644 --- a/src/block-components/block-div/index.js +++ b/src/block-components/block-div/index.js @@ -18,7 +18,9 @@ import { CustomAttributes } from '../custom-attributes' import { version as VERSION } from 'stackable' export { useUniqueId } -export { deprecateBlockBackgroundColorOpacity, deprecateBlockShadowColor } from './deprecated' +export { + deprecateBlockBackgroundColorOpacity, deprecateBlockShadowColor, deprecateBlockHeight, +} from './deprecated' export const BlockDiv = memo( props => { const { diff --git a/src/block-components/helpers/size/attributes.js b/src/block-components/helpers/size/attributes.js index 4c51277183..33f2204c4c 100644 --- a/src/block-components/helpers/size/attributes.js +++ b/src/block-components/helpers/size/attributes.js @@ -1,10 +1,6 @@ +import { deprecatedAddAttributes } from './deprecated' + export const sizeAttributes = { - height: { - stkResponsive: true, - stkUnits: 'px', - type: 'string', - default: '', - }, width: { stkResponsive: true, stkUnits: 'px', @@ -37,10 +33,26 @@ export const sizeAttributes = { } export const addSizeAttributes = ( attrObject, attrNameTemplate = '%s' ) => { + deprecatedAddAttributes( attrObject, attrNameTemplate ) + attrObject.add( { attributes: sizeAttributes, attrNameTemplate, versionAdded: '3.0.0', versionDeprecated: '', } ) + + attrObject.add( { + attributes: { + height: { + stkResponsive: true, + stkUnits: 'px', + type: 'string', + default: '', + }, + }, + attrNameTemplate, + versionAdded: '3.15.3', + versionDeprecated: '', + } ) } diff --git a/src/block-components/helpers/size/deprecated.js b/src/block-components/helpers/size/deprecated.js new file mode 100644 index 0000000000..8c2267a187 --- /dev/null +++ b/src/block-components/helpers/size/deprecated.js @@ -0,0 +1,41 @@ +import { getAttrNameFunction } from '~stackable/util' + +export const deprecatedAddAttributes = ( attrObject, attrNameTemplate = '%s' ) => { + attrObject.add( { + attributes: { + height: { + stkResponsive: true, + stkUnits: 'px', + type: 'number', + default: '', + }, + }, + attrNameTemplate, + versionAdded: '3.0.0', + versionDeprecated: '3.15.3', + } ) +} + +export const deprecateSizeControlHeight = { + isEligible: attrNameTemplate => attributes => { + const getAttrName = getAttrNameFunction( attrNameTemplate ) + const getAttribute = _attrName => attributes[ getAttrName( _attrName ) ] + + const height = getAttribute( 'height' ) + + return typeof height === 'number' + }, + migrate: attrNameTemplate => attributes => { + const getAttrName = getAttrNameFunction( attrNameTemplate ) + const getAttribute = _attrName => attributes[ getAttrName( _attrName ) ] + + const height = getAttribute( 'height' ) + + const newAttributes = { + ...attributes, + [ getAttrName( 'height' ) ]: String( height ), + } + + return newAttributes + }, +} diff --git a/src/block-components/helpers/size/index.js b/src/block-components/helpers/size/index.js index 3303c5b46a..71d4d32c99 100644 --- a/src/block-components/helpers/size/index.js +++ b/src/block-components/helpers/size/index.js @@ -1,3 +1,4 @@ export * from './attributes' export * from './style' export * from './edit' +export { deprecateSizeControlHeight } from './deprecated' diff --git a/src/block/accordion/deprecated.js b/src/block/accordion/deprecated.js index 962ab17155..a9ebe51e9e 100644 --- a/src/block/accordion/deprecated.js +++ b/src/block/accordion/deprecated.js @@ -4,10 +4,29 @@ import { attributes } from './schema' import { withVersion } from '~stackable/higher-order' import { deprecateBlockBackgroundColorOpacity, deprecateContainerBackgroundColorOpacity, - deprecateBlockShadowColor, deprecateContainerShadowColor, + deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateBlockHeight, } from '~stackable/block-components' const deprecated = [ + { + // Support the change of type for block height + attributes: attributes( '3.15.2' ), + save: withVersion( '3.15.2' )( Save ), + isEligible: attributes => { + return deprecateBlockHeight.isEligible( attributes ) + }, + migrate: attributes => { + let newAttributes = { ...attributes } + + newAttributes = deprecateBlockShadowColor.migrate( newAttributes ) + newAttributes = deprecateContainerShadowColor.migrate( newAttributes ) + newAttributes = deprecateContainerBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockHeight.migrate( newAttributes ) + + return newAttributes + }, + }, { // Support the new shadow color. attributes: attributes( '3.12.11' ), diff --git a/src/block/blockquote/deprecated.js b/src/block/blockquote/deprecated.js index da35e425a2..dbd05187c9 100644 --- a/src/block/blockquote/deprecated.js +++ b/src/block/blockquote/deprecated.js @@ -4,10 +4,34 @@ import { attributes } from './schema' import { withVersion } from '~stackable/higher-order' import { deprecateBlockBackgroundColorOpacity, deprecateContainerBackgroundColorOpacity, - deprecateBlockShadowColor, deprecateContainerShadowColor, + deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateBlockHeight, } from '~stackable/block-components' const deprecated = [ + { + // Support the change of type for block height + attributes: attributes( '3.15.2' ), + save: withVersion( '3.15.2' )( Save ), + isEligible: attributes => { + const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' + const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) + return isNotV4 || hasNumberBlockHeight + }, + migrate: attributes => { + let newAttributes = { + ...attributes, + version: 2, + } + + newAttributes = deprecateBlockShadowColor.migrate( newAttributes ) + newAttributes = deprecateContainerShadowColor.migrate( newAttributes ) + newAttributes = deprecateContainerBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockHeight.migrate( newAttributes ) + + return newAttributes + }, + }, { // Support the new shadow color. attributes: attributes( '3.12.11' ), diff --git a/src/block/button-group/deprecated/index.js b/src/block/button-group/deprecated/index.js index 55251ee121..ba4e86cb9a 100644 --- a/src/block/button-group/deprecated/index.js +++ b/src/block/button-group/deprecated/index.js @@ -6,10 +6,29 @@ import { attributes } from '../schema' import { withVersion } from '~stackable/higher-order' import { deprecateBlockBackgroundColorOpacity, deprecateContainerBackgroundColorOpacity, - deprecateBlockShadowColor, deprecateContainerShadowColor, + deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateBlockHeight, } from '~stackable/block-components' const deprecated = [ + { + // Support the change of type for block height + attributes: attributes( '3.15.2' ), + save: withVersion( '3.15.2' )( Save ), + isEligible: attributes => { + return deprecateBlockHeight.isEligible( attributes ) + }, + migrate: attributes => { + let newAttributes = { ...attributes } + + newAttributes = deprecateBlockShadowColor.migrate( newAttributes ) + newAttributes = deprecateContainerShadowColor.migrate( newAttributes ) + newAttributes = deprecateContainerBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockHeight.migrate( newAttributes ) + + return newAttributes + }, + }, { // Support the new shadow color. attributes: attributes( '3.12.11' ), diff --git a/src/block/button/deprecated.js b/src/block/button/deprecated.js index 39beef85dd..2e11ae544f 100644 --- a/src/block/button/deprecated.js +++ b/src/block/button/deprecated.js @@ -6,7 +6,7 @@ import { deprecateBlockBackgroundColorOpacity, deprecateButtonGradientColor, deprecateContainerBackgroundColorOpacity, deprecateShadowColor, deprecateContainerShadowColor, deprecateBlockShadowColor, - deprecateTypographyFontSize, + deprecateTypographyFontSize, deprecateBlockHeight, } from '~stackable/block-components' const deprecated = [ @@ -15,7 +15,9 @@ const deprecated = [ attributes: attributes( '3.15.2' ), save: withVersion( '3.15.2' )( Save ), isEligible: attributes => { - return deprecateTypographyFontSize.isEligible( 'button%s' )( attributes ) + const hasNumberFontSize = deprecateTypographyFontSize.isEligible( '%s' )( attributes ) + const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) + return hasNumberFontSize || hasNumberBlockHeight }, migrate: attributes => { let newAttributes = { ...attributes } @@ -27,6 +29,7 @@ const deprecated = [ newAttributes = deprecateBlockBackgroundColorOpacity.migrate( newAttributes ) newAttributes = deprecateButtonGradientColor.migrate( 'button%s' )( newAttributes ) newAttributes = deprecateTypographyFontSize.migrate( 'button%s' )( newAttributes ) + newAttributes = deprecateBlockHeight.migrate( newAttributes ) return newAttributes }, diff --git a/src/block/call-to-action/deprecated.js b/src/block/call-to-action/deprecated.js index e185c0314b..3a78c5a206 100644 --- a/src/block/call-to-action/deprecated.js +++ b/src/block/call-to-action/deprecated.js @@ -10,7 +10,7 @@ import { attributes } from './schema' import { withVersion } from '~stackable/higher-order' import { deprecateBlockBackgroundColorOpacity, deprecateContainerBackgroundColorOpacity, - deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateShadowColor, + deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateShadowColor, deprecateBlockHeight, } from '~stackable/block-components' import compareVersions from 'compare-versions' @@ -35,6 +35,77 @@ addFilter( 'stackable.call-to-action.save.innerClassNames', 'stackable/3.8.0', ( } ) const deprecated = [ + { + // Support the change of type for block height + attributes: attributes( '3.15.2' ), + save: withVersion( '3.15.2' )( Save ), + isEligible: attributes => { + const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' + const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) + return isNotV4 || hasNumberBlockHeight + }, + migrate: ( attributes, innerBlocks ) => { + const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' + + let newAttributes = { + ...attributes, + } + + if ( isNotV4 ) { + newAttributes = { + ...newAttributes, + version: 2, + } + + // Update the vertical align into flexbox + const hasOldVerticalAlign = !! attributes.containerVerticalAlign // Column only, this was changed to flexbox + + if ( hasOldVerticalAlign ) { + newAttributes = { + ...newAttributes, + containerVerticalAlign: '', + innerBlockAlign: attributes.containerVerticalAlign, + } + } + + // If the inner blocks are horizontal, adjust to accomodate the new + // column gap, it will modify blocks because people used block + // margins before instead of a proper column gap. + if ( attributes.innerBlockOrientation === 'horizontal' ) { + innerBlocks.forEach( ( block, index ) => { + if ( index ) { + if ( ! block.attributes.blockMargin ) { + block.attributes.blockMargin = { + top: '', + right: '', + bottom: '', + left: '', + } + } + if ( block.attributes.blockMargin.left === '' ) { + block.attributes.blockMargin.left = 24 + } + } + } ) + + newAttributes = { + ...newAttributes, + innerBlockColumnGap: 0, + } + } + } + + newAttributes = deprecateContainerBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockShadowColor.migrate( newAttributes ) + newAttributes = deprecateContainerShadowColor.migrate( newAttributes ) + newAttributes = deprecateShadowColor.migrate( 'topSeparator%s' )( newAttributes ) + newAttributes = deprecateShadowColor.migrate( 'bottomSeparator%s' )( newAttributes ) + newAttributes = deprecateBlockHeight.migrate( newAttributes ) + + return [ newAttributes, innerBlocks ] + }, + }, { // Support the new shadow color. attributes: attributes( '3.12.11' ), diff --git a/src/block/card/deprecated.js b/src/block/card/deprecated.js index da6cd555bd..d14fc94e23 100644 --- a/src/block/card/deprecated.js +++ b/src/block/card/deprecated.js @@ -12,7 +12,7 @@ import compareVersions from 'compare-versions' import { deprecateBlockBackgroundColorOpacity, deprecateContainerBackgroundColorOpacity, deprecationImageOverlayOpacity, getAlignmentClasses, - deprecateBlockShadowColor, deprecateContainerShadowColor, + deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateBlockHeight, } from '~stackable/block-components' /** @@ -86,6 +86,76 @@ addFilter( 'stackable.card.save.innerClassNames', 'stackable/3.0.2', ( output, p } ) const deprecated = [ + { + // Support the change of type for block height + attributes: attributes( '3.15.2' ), + save: withVersion( '3.15.2' )( Save ), + isEligible: attributes => { + const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' + const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) + return isNotV4 || hasNumberBlockHeight + }, + migrate: ( attributes, innerBlocks ) => { + const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' + + let newAttributes = { + ...attributes, + } + + if ( isNotV4 ) { + newAttributes = { + ...newAttributes, + version: 2, + } + + // Update the vertical align into flexbox + const hasOldVerticalAlign = !! attributes.containerVerticalAlign // Column only, this was changed to flexbox + + if ( hasOldVerticalAlign ) { + newAttributes = { + ...newAttributes, + containerVerticalAlign: '', + innerBlockAlign: attributes.containerVerticalAlign, + } + } + + // If the inner blocks are horizontal, adjust to accomodate the new + // column gap, it will modify blocks because people used block + // margins before instead of a proper column gap. + if ( attributes.innerBlockOrientation === 'horizontal' ) { + innerBlocks.forEach( ( block, index ) => { + if ( index ) { + if ( ! block.attributes.blockMargin ) { + block.attributes.blockMargin = { + top: '', + right: '', + bottom: '', + left: '', + } + } + if ( block.attributes.blockMargin.left === '' ) { + block.attributes.blockMargin.left = 24 + } + } + } ) + + newAttributes = { + ...newAttributes, + innerBlockColumnGap: 0, + } + } + } + + newAttributes = deprecationImageOverlayOpacity.migrate( newAttributes ), + newAttributes = deprecateContainerBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockShadowColor.migrate( newAttributes ) + newAttributes = deprecateContainerShadowColor.migrate( newAttributes ) + newAttributes = deprecateBlockHeight.migrate( newAttributes ) + + return [ newAttributes, innerBlocks ] + }, + }, { // Support the new shadow color. attributes: attributes( '3.12.11' ), diff --git a/src/block/carousel/deprecated.js b/src/block/carousel/deprecated.js index 047bfa76c6..140d8429e3 100644 --- a/src/block/carousel/deprecated.js +++ b/src/block/carousel/deprecated.js @@ -1,6 +1,6 @@ import { deprecateBlockBackgroundColorOpacity, deprecateContainerBackgroundColorOpacity, - deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateShadowColor, + deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateShadowColor, deprecateBlockHeight, } from '~stackable/block-components' import { Save } from './save' import { attributes } from './schema' @@ -8,6 +8,27 @@ import { attributes } from './schema' import { withVersion } from '~stackable/higher-order' const deprecated = [ + { + // Support the change of type for block height + attributes: attributes( '3.15.2' ), + save: withVersion( '3.15.2' )( Save ), + isEligible: attributes => { + return deprecateBlockHeight.isEligible( attributes ) + }, + migrate: attributes => { + let newAttributes = { ...attributes } + + newAttributes = deprecateBlockShadowColor.migrate( newAttributes ) + newAttributes = deprecateContainerShadowColor.migrate( newAttributes ) + newAttributes = deprecateShadowColor.migrate( 'topSeparator%s' )( newAttributes ) + newAttributes = deprecateShadowColor.migrate( 'bottomSeparator%s' )( newAttributes ) + newAttributes = deprecateContainerBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockHeight.migrate( newAttributes ) + + return newAttributes + }, + }, { // Support the new shadow color. attributes: attributes( '3.12.11' ), diff --git a/src/block/column/deprecated.js b/src/block/column/deprecated.js index 1c889b75e5..dcfaee13c8 100644 --- a/src/block/column/deprecated.js +++ b/src/block/column/deprecated.js @@ -17,7 +17,7 @@ import { addFilter } from '@wordpress/hooks' import { semverCompare } from '~stackable/util' import { deprecateBlockBackgroundColorOpacity, deprecateContainerBackgroundColorOpacity, - deprecateBlockShadowColor, deprecateContainerShadowColor, + deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateBlockHeight, } from '~stackable/block-components' // Version 3.8 added horizontal flex, we changed the stk--block-orientation-* to stk--block-horizontal-flex. @@ -75,6 +75,79 @@ addFilter( 'stackable.column.save.blockClassNames', 'stackable/3.8.0', ( output, } ) const deprecated = [ + { + // Support the change of type for block height + attributes: attributes( '3.15.2' ), + save: withVersion( '3.15.2' )( Save ), + isEligible: attributes => { + const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' + const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) + return isNotV4 || hasNumberBlockHeight + }, + migrate: ( attributes, innerBlocks ) => { + const isNotV4 = attributes.version < 4 || typeof attributes.version === 'undefined' + + let newAttributes = { + ...attributes, + } + + if ( isNotV4 ) { + newAttributes = { + ...newAttributes, + version: 4, + className: classnames( attributes.className, { + 'stk-block-column--v2': false, + 'stk-block-column--v3': false, + } ), + } + + // Update the vertical align into flexbox + const hasOldVerticalAlign = !! attributes.containerVerticalAlign // Column only, this was changed to flexbox + + if ( hasOldVerticalAlign ) { + newAttributes = { + ...newAttributes, + containerVerticalAlign: '', + innerBlockAlign: attributes.containerVerticalAlign, + } + } + + // If the inner blocks are horizontal, adjust to accomodate the new + // column gap, it will modify blocks because people used block + // margins before instead of a proper column gap. + if ( attributes.innerBlockOrientation === 'horizontal' ) { + innerBlocks.forEach( ( block, index ) => { + if ( index ) { + if ( ! block.attributes.blockMargin ) { + block.attributes.blockMargin = { + top: '', + right: '', + bottom: '', + left: '', + } + } + if ( block.attributes.blockMargin.left === '' ) { + block.attributes.blockMargin.left = 24 + } + } + } ) + + newAttributes = { + ...newAttributes, + innerBlockColumnGap: 0, + } + } + } + + newAttributes = deprecateContainerBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockShadowColor.migrate( newAttributes ) + newAttributes = deprecateContainerShadowColor.migrate( newAttributes ) + newAttributes = deprecateBlockHeight.migrate( newAttributes ) + + return [ newAttributes, innerBlocks ] + }, + }, { // Support the new shadow color. attributes: attributes( '3.12.11' ), diff --git a/src/block/columns/deprecated.js b/src/block/columns/deprecated.js index 8b6d5db023..5bf006f75a 100644 --- a/src/block/columns/deprecated.js +++ b/src/block/columns/deprecated.js @@ -17,6 +17,7 @@ import { semverCompare } from '~stackable/util' import { deprecateBlockBackgroundColorOpacity, deprecateContainerBackgroundColorOpacity, deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateShadowColor, + deprecateBlockHeight, } from '~stackable/block-components' // Version 3.6.2 Deprecations, we now don't need the stk--has-column-order class. @@ -36,6 +37,34 @@ addFilter( 'stackable.columns.save.contentClassNames', 'stackable/3.8.0', ( clas } ) const deprecated = [ + { + // Support the change of type for block height + attributes: attributes( '3.15.2' ), + save: withVersion( '3.15.2' )( Save ), + isEligible: attributes => { + const hasColumnFit = !! attributes.columnFit + const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) + return hasColumnFit || hasNumberBlockHeight + }, + migrate: attributes => { + let newAttributes = { + ...attributes, + columnFit: '', + columnFitAlign: '', + columnJustify: !! attributes.columnFit ? ( attributes.columnFitAlign || 'flex-start' ) : '', + } + + newAttributes = deprecateContainerBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockShadowColor.migrate( newAttributes ) + newAttributes = deprecateContainerShadowColor.migrate( newAttributes ) + newAttributes = deprecateShadowColor.migrate( 'topSeparator%s' )( newAttributes ) + newAttributes = deprecateShadowColor.migrate( 'bottomSeparator%s' )( newAttributes ) + newAttributes = deprecateBlockHeight.migrate( newAttributes ) + + return newAttributes + }, + }, { // Support the new shadow color. attributes: attributes( '3.12.11' ), diff --git a/src/block/count-up/deprecated.js b/src/block/count-up/deprecated.js index a9151421e6..7c9b21f8c9 100644 --- a/src/block/count-up/deprecated.js +++ b/src/block/count-up/deprecated.js @@ -5,15 +5,18 @@ import { withVersion } from '~stackable/higher-order' import { deprecateBlockBackgroundColorOpacity, deprecateContainerBackgroundColorOpacity, deprecateTypographyGradientColor, deprecateTypographyShadowColor, deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateTypographyFontSize, + deprecateBlockHeight, } from '~stackable/block-components' const deprecated = [ { - // Support the change of type for fontSize + // Support the change of type for fontSize and blockHeight attributes: attributes( '3.15.2' ), save: withVersion( '3.15.2' )( Save ), isEligible: attributes => { - return deprecateTypographyFontSize.isEligible( '%s' )( attributes ) + const hasNumberFontSize = deprecateTypographyFontSize.isEligible( '%s' )( attributes ) + const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) + return hasNumberFontSize || hasNumberBlockHeight }, migrate: attributes => { let newAttributes = { ...attributes } @@ -25,6 +28,7 @@ const deprecated = [ newAttributes = deprecateContainerShadowColor.migrate( newAttributes ) newAttributes = deprecateTypographyShadowColor.migrate( '%s' )( newAttributes ) newAttributes = deprecateTypographyFontSize.migrate( '%s' )( newAttributes ) + newAttributes = deprecateBlockHeight.migrate( newAttributes ) return newAttributes }, diff --git a/src/block/countdown/deprecated.js b/src/block/countdown/deprecated.js index c3e3a07bc1..620ddb9ef6 100644 --- a/src/block/countdown/deprecated.js +++ b/src/block/countdown/deprecated.js @@ -1,6 +1,6 @@ import { deprecateBlockBackgroundColorOpacity, deprecateContainerBackgroundColorOpacity, deprecateTypographyGradientColor, - deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateTypographyFontSize, + deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateTypographyFontSize, deprecateBlockHeight, } from '~stackable/block-components' import { Save } from './save' import { attributes } from './schema' @@ -9,16 +9,17 @@ import { withVersion } from '~stackable/higher-order' const deprecated = [ { - // Support the change of type for fontSize + // Support the change of type for fontSize and blockHeight attributes: attributes( '3.15.2' ), save: withVersion( '3.15.2' )( Save ), isEligible: attributes => { const hasDigitFontSize = deprecateTypographyFontSize.isEligible( 'digit%s' )( attributes ) const hasLabelFontSize = deprecateTypographyFontSize.isEligible( 'label%s' )( attributes ) const hasMessageFontSize = deprecateTypographyFontSize.isEligible( 'message%s' )( attributes ) + const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' - return hasDigitFontSize || hasLabelFontSize || hasMessageFontSize || isNotV4 + return hasDigitFontSize || hasLabelFontSize || hasMessageFontSize || hasNumberBlockHeight || isNotV4 }, migrate: attributes => { let newAttributes = { ...attributes } @@ -33,6 +34,7 @@ const deprecated = [ newAttributes = deprecateTypographyFontSize.migrate( 'digit%s' )( newAttributes ) newAttributes = deprecateTypographyFontSize.migrate( 'label%s' )( newAttributes ) newAttributes = deprecateTypographyFontSize.migrate( 'message%s' )( newAttributes ) + newAttributes = deprecateBlockHeight.migrate( newAttributes ) return newAttributes }, diff --git a/src/block/divider/deprecated.js b/src/block/divider/deprecated.js index 395ffb36b0..90136ec005 100644 --- a/src/block/divider/deprecated.js +++ b/src/block/divider/deprecated.js @@ -4,10 +4,29 @@ import { attributes } from './schema' import { withVersion } from '~stackable/higher-order' import { deprecateBlockBackgroundColorOpacity, deprecateContainerBackgroundColorOpacity, - deprecateBlockShadowColor, deprecateContainerShadowColor, + deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateBlockHeight, } from '~stackable/block-components' const deprecated = [ + { + // Support the change of type for block height + attributes: attributes( '3.15.2' ), + save: withVersion( '3.15.2' )( Save ), + isEligible: attributes => { + return deprecateBlockHeight.isEligible( attributes ) + }, + migrate: attributes => { + let newAttributes = { ...attributes } + + newAttributes = deprecateContainerBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockShadowColor.migrate( newAttributes ) + newAttributes = deprecateContainerShadowColor.migrate( newAttributes ) + newAttributes = deprecateBlockHeight.migrate( newAttributes ) + + return newAttributes + }, + }, { // Support the new shadow color. attributes: attributes( '3.12.11' ), diff --git a/src/block/expand/deprecated.js b/src/block/expand/deprecated.js index 395ffb36b0..90136ec005 100644 --- a/src/block/expand/deprecated.js +++ b/src/block/expand/deprecated.js @@ -4,10 +4,29 @@ import { attributes } from './schema' import { withVersion } from '~stackable/higher-order' import { deprecateBlockBackgroundColorOpacity, deprecateContainerBackgroundColorOpacity, - deprecateBlockShadowColor, deprecateContainerShadowColor, + deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateBlockHeight, } from '~stackable/block-components' const deprecated = [ + { + // Support the change of type for block height + attributes: attributes( '3.15.2' ), + save: withVersion( '3.15.2' )( Save ), + isEligible: attributes => { + return deprecateBlockHeight.isEligible( attributes ) + }, + migrate: attributes => { + let newAttributes = { ...attributes } + + newAttributes = deprecateContainerBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockShadowColor.migrate( newAttributes ) + newAttributes = deprecateContainerShadowColor.migrate( newAttributes ) + newAttributes = deprecateBlockHeight.migrate( newAttributes ) + + return newAttributes + }, + }, { // Support the new shadow color. attributes: attributes( '3.12.11' ), diff --git a/src/block/feature-grid/deprecated.js b/src/block/feature-grid/deprecated.js index d8792d68d8..2803f5c4db 100644 --- a/src/block/feature-grid/deprecated.js +++ b/src/block/feature-grid/deprecated.js @@ -13,6 +13,7 @@ import { deprecateBlockBackgroundColorOpacity, deprecateContainerBackgroundColorOpacity, getResponsiveClasses, getSeparatorClasses, deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateShadowColor, + deprecateBlockHeight, } from '~stackable/block-components' /** @@ -60,6 +61,34 @@ addFilter( 'stackable.feature-grid.save.blockClassNames', 'stackable/3.1.0', ( o } ) const deprecated = [ + { + // Support the change of type for block height + attributes: attributes( '3.15.2' ), + save: withVersion( '3.15.2' )( Save ), + isEligible: attributes => { + const hasColumnFit = !! attributes.columnFit + const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) + return hasColumnFit || hasNumberBlockHeight + }, + migrate: attributes => { + let newAttributes = { + ...attributes, + columnFit: '', + columnFitAlign: '', + columnJustify: !! attributes.columnFit ? ( attributes.columnFitAlign || 'flex-start' ) : '', + } + + newAttributes = deprecateContainerBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockShadowColor.migrate( newAttributes ) + newAttributes = deprecateContainerShadowColor.migrate( newAttributes ) + newAttributes = deprecateShadowColor.migrate( 'topSeparator%s' )( newAttributes ) + newAttributes = deprecateShadowColor.migrate( 'bottomSeparator%s' )( newAttributes ) + newAttributes = deprecateBlockHeight.migrate( newAttributes ) + + return newAttributes + }, + }, { // Support the new shadow color. attributes: attributes( '3.12.11' ), diff --git a/src/block/feature/deprecated.js b/src/block/feature/deprecated.js index 851ca5574a..791adb3605 100644 --- a/src/block/feature/deprecated.js +++ b/src/block/feature/deprecated.js @@ -14,6 +14,7 @@ import { deprecateContainerBackgroundColorOpacity, getAlignmentClasses, getContentAlignmentClasses, getRowClasses, deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateShadowColor, + deprecateBlockHeight, } from '~stackable/block-components' /** @@ -62,6 +63,43 @@ addFilter( 'stackable.feature.save.innerClassNames', 'stackable/3.8.0', ( output } ) const deprecated = [ + { + // Support the change of type for block height + attributes: attributes( '3.15.2' ), + save: withVersion( '3.15.2' )( Save ), + isEligible: attributes => { + const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' + const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) + return isNotV4 || hasNumberBlockHeight + }, + migrate: attributes => { + let newAttributes = { + ...attributes, + version: 2, + } + + // Update the old column fit into flexbox + const hasOldColumnFit = !! attributes.columnFit + if ( hasOldColumnFit ) { + newAttributes = { + ...newAttributes, + columnFit: '', + columnFitAlign: '', + columnJustify: attributes.columnFitAlign, + } + } + + newAttributes = deprecateContainerBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockShadowColor.migrate( newAttributes ) + newAttributes = deprecateContainerShadowColor.migrate( newAttributes ) + newAttributes = deprecateShadowColor.migrate( 'topSeparator%s' )( newAttributes ) + newAttributes = deprecateShadowColor.migrate( 'bottomSeparator%s' )( newAttributes ) + newAttributes = deprecateBlockHeight.migrate( newAttributes ) + + return newAttributes + }, + }, { // Support the new shadow color. attributes: attributes( '3.12.11' ), diff --git a/src/block/heading/deprecated.js b/src/block/heading/deprecated.js index 59416795a0..118cfee850 100644 --- a/src/block/heading/deprecated.js +++ b/src/block/heading/deprecated.js @@ -11,7 +11,7 @@ import { withVersion } from '~stackable/higher-order' import compareVersions from 'compare-versions' import { deprecateBlockBackgroundColorOpacity, deprecateContainerBackgroundColorOpacity, deprecateTypographyGradientColor, getResponsiveClasses, - deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateTypographyShadowColor, deprecateTypographyFontSize, + deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateTypographyShadowColor, deprecateTypographyFontSize, deprecateBlockHeight, } from '~stackable/block-components' /** @@ -35,11 +35,13 @@ addFilter( 'stackable.heading.save.blockClassNames', 'stackable/3.6.1', ( output const deprecated = [ { - // Support the change of type for fontSize + // Support the change of type for fontSize and blockHeight attributes: attributes( '3.15.2' ), save: withVersion( '3.15.2' )( Save ), isEligible: attributes => { - return deprecateTypographyFontSize.isEligible( '%s' )( attributes ) + const hasNumberFontSize = deprecateTypographyFontSize.isEligible( '%s' )( attributes ) + const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) + return hasNumberFontSize || hasNumberBlockHeight }, migrate: attributes => { let newAttributes = { ...attributes } @@ -51,6 +53,7 @@ const deprecated = [ newAttributes = deprecateContainerShadowColor.migrate( newAttributes ) newAttributes = deprecateTypographyShadowColor.migrate( '%s' )( newAttributes ) newAttributes = deprecateTypographyFontSize.migrate( '%s' )( newAttributes ) + newAttributes = deprecateBlockHeight.migrate( newAttributes ) return newAttributes }, diff --git a/src/block/hero/deprecated.js b/src/block/hero/deprecated.js index cc43238e39..ad6562c0ab 100644 --- a/src/block/hero/deprecated.js +++ b/src/block/hero/deprecated.js @@ -12,6 +12,7 @@ import compareVersions from 'compare-versions' import { deprecateBlockBackgroundColorOpacity, deprecateContainerBackgroundColorOpacity, deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateShadowColor, + deprecateBlockHeight, } from '~stackable/block-components' /** @@ -35,6 +36,77 @@ addFilter( 'stackable.hero.save.innerClassNames', 'stackable/3.8.0', ( output, p } ) const deprecated = [ + { + // Support the change of type for block height + attributes: attributes( '3.15.2' ), + save: withVersion( '3.15.2' )( Save ), + isEligible: attributes => { + const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' + const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) + return isNotV4 || hasNumberBlockHeight + }, + migrate: ( attributes, innerBlocks ) => { + const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' + + let newAttributes = { + ...attributes, + } + + if ( isNotV4 ) { + newAttributes = { + ...newAttributes, + version: 2, + } + + // Update the vertical align into flexbox + const hasOldVerticalAlign = !! attributes.containerVerticalAlign // Column only, this was changed to flexbox + + if ( hasOldVerticalAlign ) { + newAttributes = { + ...newAttributes, + containerVerticalAlign: '', + innerBlockAlign: attributes.containerVerticalAlign, + } + } + + // If the inner blocks are horizontal, adjust to accomodate the new + // column gap, it will modify blocks because people used block + // margins before instead of a proper column gap. + if ( attributes.innerBlockOrientation === 'horizontal' ) { + innerBlocks.forEach( ( block, index ) => { + if ( index ) { + if ( ! block.attributes.blockMargin ) { + block.attributes.blockMargin = { + top: '', + right: '', + bottom: '', + left: '', + } + } + if ( block.attributes.blockMargin.left === '' ) { + block.attributes.blockMargin.left = 24 + } + } + } ) + + newAttributes = { + ...newAttributes, + innerBlockColumnGap: 0, + } + } + } + + newAttributes = deprecateContainerBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockShadowColor.migrate( newAttributes ) + newAttributes = deprecateContainerShadowColor.migrate( newAttributes ) + newAttributes = deprecateShadowColor.migrate( 'topSeparator%s' )( newAttributes ) + newAttributes = deprecateShadowColor.migrate( 'bottomSeparator%s' )( newAttributes ) + newAttributes = deprecateBlockHeight.migrate( newAttributes ) + + return newAttributes + }, + }, { // Support the new shadow color. attributes: attributes( '3.12.11' ), diff --git a/src/block/horizontal-scroller/deprecated.js b/src/block/horizontal-scroller/deprecated.js index a3d054b758..d04b468302 100644 --- a/src/block/horizontal-scroller/deprecated.js +++ b/src/block/horizontal-scroller/deprecated.js @@ -4,7 +4,7 @@ import { attributes } from './schema' import { withVersion } from '~stackable/higher-order' import { deprecateBlockBackgroundColorOpacity, deprecateContainerBackgroundColorOpacity, - deprecateBlockShadowColor, deprecateContainerShadowColor, + deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateBlockHeight, } from '~stackable/block-components' import { addFilter } from '@wordpress/hooks' import compareVersions from 'compare-versions' @@ -22,6 +22,25 @@ addFilter( 'stackable.horizontal-scroller.save.contentClassNames', 'stackable/3_ } ) const deprecated = [ + { + // Support the change of type for block height + attributes: attributes( '3.15.2' ), + save: withVersion( '3.15.2' )( Save ), + isEligible: attributes => { + return deprecateBlockHeight.isEligible( attributes ) + }, + migrate: attributes => { + let newAttributes = { ...attributes } + + newAttributes = deprecateContainerBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockShadowColor.migrate( newAttributes ) + newAttributes = deprecateContainerShadowColor.migrate( newAttributes ) + newAttributes = deprecateBlockHeight.migrate( newAttributes ) + + return newAttributes + }, + }, { // Support the new shadow color. attributes: attributes( '3.12.11' ), diff --git a/src/block/icon-box/deprecated.js b/src/block/icon-box/deprecated.js index 7a6bc048e0..c410bb4d6d 100644 --- a/src/block/icon-box/deprecated.js +++ b/src/block/icon-box/deprecated.js @@ -4,10 +4,45 @@ import { attributes } from './schema' import { withVersion } from '~stackable/higher-order' import { deprecateBlockBackgroundColorOpacity, deprecateContainerBackgroundColorOpacity, - deprecateBlockShadowColor, deprecateContainerShadowColor, + deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateBlockHeight, } from '~stackable/block-components' const deprecated = [ + { + // Support the change of type for block height + attributes: attributes( '3.15.2' ), + save: withVersion( '3.15.2' )( Save ), + isEligible: attributes => { + const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' + const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) + return isNotV4 || hasNumberBlockHeight + }, + migrate: attributes => { + let newAttributes = { + ...attributes, + version: 2, + } + + // Update the vertical align into flexbox + const hasOldVerticalAlign = !! attributes.containerVerticalAlign // Column only, this was changed to flexbox + + if ( hasOldVerticalAlign ) { + newAttributes = { + ...newAttributes, + containerVerticalAlign: '', + innerBlockAlign: attributes.containerVerticalAlign, + } + } + + newAttributes = deprecateContainerBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockShadowColor.migrate( newAttributes ) + newAttributes = deprecateContainerShadowColor.migrate( newAttributes ) + newAttributes = deprecateBlockHeight.migrate( newAttributes ) + + return newAttributes + }, + }, { // Support the new shadow color. attributes: attributes( '3.12.11' ), diff --git a/src/block/icon-button/deprecated.js b/src/block/icon-button/deprecated.js index 9bf89108c1..48f200c0fd 100644 --- a/src/block/icon-button/deprecated.js +++ b/src/block/icon-button/deprecated.js @@ -5,10 +5,31 @@ import { withVersion } from '~stackable/higher-order' import { deprecateBlockBackgroundColorOpacity, deprecateButtonGradientColor, deprecateContainerBackgroundColorOpacity, deprecateShadowColor, - deprecateContainerShadowColor, deprecateBlockShadowColor, + deprecateContainerShadowColor, deprecateBlockShadowColor, deprecateBlockHeight, } from '~stackable/block-components' const deprecated = [ + { + // Support the change of type for block height + attributes: attributes( '3.15.2' ), + save: withVersion( '3.15.2' )( Save ), + isEligible: attributes => { + return deprecateBlockHeight.isEligible( attributes ) + }, + migrate: attributes => { + let newAttributes = { ...attributes } + + newAttributes = deprecateContainerBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateButtonGradientColor.migrate( 'button%s' )( newAttributes ) + newAttributes = deprecateBlockShadowColor.migrate( newAttributes ) + newAttributes = deprecateContainerShadowColor.migrate( newAttributes ) + newAttributes = deprecateShadowColor.migrate( 'button%s' )( newAttributes ) + newAttributes = deprecateBlockHeight.migrate( newAttributes ) + + return newAttributes + }, + }, { // Support the new shadow color. attributes: attributes( '3.12.11' ), diff --git a/src/block/icon-label/deprecated.js b/src/block/icon-label/deprecated.js index 99014e6cbb..1d35507e39 100644 --- a/src/block/icon-label/deprecated.js +++ b/src/block/icon-label/deprecated.js @@ -4,10 +4,25 @@ import { attributes } from './schema' import { withVersion } from '~stackable/higher-order' import { deprecateBlockBackgroundColorOpacity, deprecateContainerBackgroundColorOpacity, - deprecateBlockShadowColor, deprecateContainerShadowColor, + deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateBlockHeight, } from '~stackable/block-components' const deprecated = [ + { + // Support the change of type for block height + attributes: attributes( '3.15.2' ), + save: withVersion( '3.15.2' )( Save ), + isEligible: attributes => { + return deprecateBlockHeight.isEligible( attributes ) + }, + migrate: attributes => { + let newAttributes = { ...attributes } + + newAttributes = deprecateBlockHeight.migrate( newAttributes ) + + return newAttributes + }, + }, { attributes: attributes( '3.13.1' ), save: withVersion( '3.13.1' )( Save ), diff --git a/src/block/icon-list-item/deprecated.js b/src/block/icon-list-item/deprecated.js index f3d73a8440..c6d88e177d 100644 --- a/src/block/icon-list-item/deprecated.js +++ b/src/block/icon-list-item/deprecated.js @@ -3,16 +3,18 @@ import { attributes } from './schema' import { withVersion } from '~stackable/higher-order' import { - deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateTypographyFontSize, + deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateTypographyFontSize, deprecateBlockHeight, } from '~stackable/block-components' const deprecated = [ { - // Support the change of type for fontSize + // Support the change of type for fontSize and blockHeight attributes: attributes( '3.15.2' ), save: withVersion( '3.15.2' )( Save ), isEligible: attributes => { - return deprecateTypographyFontSize.isEligible( '%s' )( attributes ) + const hasNumberFontSize = deprecateTypographyFontSize.isEligible( '%s' )( attributes ) + const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) + return hasNumberFontSize || hasNumberBlockHeight }, migrate: attributes => { let newAttributes = { ...attributes } @@ -20,6 +22,7 @@ const deprecated = [ newAttributes = deprecateBlockShadowColor.migrate( newAttributes ) newAttributes = deprecateContainerShadowColor.migrate( newAttributes ) newAttributes = deprecateTypographyFontSize.migrate( '%s' )( newAttributes ) + newAttributes = deprecateBlockHeight.migrate( newAttributes ) return newAttributes }, diff --git a/src/block/icon-list/deprecated/index.js b/src/block/icon-list/deprecated/index.js index 9e47890457..9f1a77dcdc 100644 --- a/src/block/icon-list/deprecated/index.js +++ b/src/block/icon-list/deprecated/index.js @@ -4,7 +4,7 @@ import { attributes } from './schema' import { withVersion } from '~stackable/higher-order' import { deprecateBlockBackgroundColorOpacity, deprecateContainerBackgroundColorOpacity, deprecateTypographyGradientColor, - deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateTypographyFontSize, + deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateTypographyFontSize, deprecateBlockHeight, } from '~stackable/block-components' import { createUniqueClass } from '~stackable/util' @@ -69,11 +69,13 @@ const getEquivalentIconSize = iconSize => { const deprecated = [ { - // Support the new shadow color. + // Support the change of type for font size and block height attributes: attributes( '3.15.2' ), save: withVersion( '3.15.2' )( Save ), isEligible: attributes => { - return deprecateTypographyFontSize.isEligible( '%s' )( attributes ) + const hasNumberFontSize = deprecateTypographyFontSize.isEligible( '%s' )( attributes ) + const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) + return hasNumberFontSize || hasNumberBlockHeight }, supports: { anchor: true, @@ -124,6 +126,7 @@ const deprecated = [ newAttributes = deprecateBlockShadowColor.migrate( newAttributes ) newAttributes = deprecateContainerShadowColor.migrate( newAttributes ) newAttributes = deprecateTypographyFontSize.migrate( '%s' )( newAttributes ) + newAttributes = deprecateBlockHeight.migrate( newAttributes ) return [ newAttributes, innerBlocks ] }, diff --git a/src/block/icon/deprecated.js b/src/block/icon/deprecated.js index 395ffb36b0..90136ec005 100644 --- a/src/block/icon/deprecated.js +++ b/src/block/icon/deprecated.js @@ -4,10 +4,29 @@ import { attributes } from './schema' import { withVersion } from '~stackable/higher-order' import { deprecateBlockBackgroundColorOpacity, deprecateContainerBackgroundColorOpacity, - deprecateBlockShadowColor, deprecateContainerShadowColor, + deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateBlockHeight, } from '~stackable/block-components' const deprecated = [ + { + // Support the change of type for block height + attributes: attributes( '3.15.2' ), + save: withVersion( '3.15.2' )( Save ), + isEligible: attributes => { + return deprecateBlockHeight.isEligible( attributes ) + }, + migrate: attributes => { + let newAttributes = { ...attributes } + + newAttributes = deprecateContainerBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockShadowColor.migrate( newAttributes ) + newAttributes = deprecateContainerShadowColor.migrate( newAttributes ) + newAttributes = deprecateBlockHeight.migrate( newAttributes ) + + return newAttributes + }, + }, { // Support the new shadow color. attributes: attributes( '3.12.11' ), diff --git a/src/block/image-box/deprecated.js b/src/block/image-box/deprecated.js index 395ffb36b0..90136ec005 100644 --- a/src/block/image-box/deprecated.js +++ b/src/block/image-box/deprecated.js @@ -4,10 +4,29 @@ import { attributes } from './schema' import { withVersion } from '~stackable/higher-order' import { deprecateBlockBackgroundColorOpacity, deprecateContainerBackgroundColorOpacity, - deprecateBlockShadowColor, deprecateContainerShadowColor, + deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateBlockHeight, } from '~stackable/block-components' const deprecated = [ + { + // Support the change of type for block height + attributes: attributes( '3.15.2' ), + save: withVersion( '3.15.2' )( Save ), + isEligible: attributes => { + return deprecateBlockHeight.isEligible( attributes ) + }, + migrate: attributes => { + let newAttributes = { ...attributes } + + newAttributes = deprecateContainerBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockShadowColor.migrate( newAttributes ) + newAttributes = deprecateContainerShadowColor.migrate( newAttributes ) + newAttributes = deprecateBlockHeight.migrate( newAttributes ) + + return newAttributes + }, + }, { // Support the new shadow color. attributes: attributes( '3.12.11' ), diff --git a/src/block/image/deprecated.js b/src/block/image/deprecated.js index 52ad380b79..976b7cc2c9 100644 --- a/src/block/image/deprecated.js +++ b/src/block/image/deprecated.js @@ -5,6 +5,7 @@ import { withVersion } from '~stackable/higher-order' import { deprecateBlockBackgroundColorOpacity, deprecateContainerBackgroundColorOpacity, deprecationImageOverlayOpacity, deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateShadowColor, deprecateTypographyFontSize, + deprecateBlockHeight, } from '~stackable/block-components' import { RichText } from '@wordpress/block-editor' @@ -64,7 +65,9 @@ const deprecated = [ attributes: attributes( '3.15.2' ), save: withVersion( '3.15.2' )( Save ), isEligible: attributes => { - return deprecateTypographyFontSize.isEligible( 'figcaption%s' )( attributes ) + const hasNumberFontSize = deprecateTypographyFontSize.isEligible( 'figcaption%s' )( attributes ) + const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) + return hasNumberFontSize || hasNumberBlockHeight }, migrate: attributes => { let newAttributes = { ...attributes } @@ -76,6 +79,7 @@ const deprecated = [ newAttributes = deprecateContainerShadowColor.migrate( newAttributes ) newAttributes = deprecateShadowColor.migrate( 'image%s' )( newAttributes ) newAttributes = deprecateTypographyFontSize.migrate( 'figcaption%s' )( newAttributes ) + newAttributes = deprecateBlockHeight.migrate( newAttributes ) return newAttributes }, diff --git a/src/block/map/deprecated.js b/src/block/map/deprecated.js index 90e9210c9c..f22f4db86e 100644 --- a/src/block/map/deprecated.js +++ b/src/block/map/deprecated.js @@ -7,7 +7,7 @@ import { withVersion } from '~stackable/higher-order' import { semverCompare, createElementFromHTMLString } from '~stackable/util' import { deprecateBlockBackgroundColorOpacity, deprecateContainerBackgroundColorOpacity, - deprecateBlockShadowColor, deprecateContainerShadowColor, + deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateBlockHeight, } from '~stackable/block-components' import { addFilter } from '@wordpress/hooks' @@ -35,6 +35,25 @@ addFilter( 'stackable.map.icon-options', 'stackable/3.13.0', ( output, attribute } ) const deprecated = [ + { + // Support the change of type for block height + attributes: attributes( '3.15.2' ), + save: withVersion( '3.15.2' )( Save ), + isEligible: attributes => { + return deprecateBlockHeight.isEligible( attributes ) + }, + migrate: attributes => { + let newAttributes = { ...attributes } + + newAttributes = deprecateContainerBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockShadowColor.migrate( newAttributes ) + newAttributes = deprecateContainerShadowColor.migrate( newAttributes ) + newAttributes = deprecateBlockHeight.migrate( newAttributes ) + + return newAttributes + }, + }, { // Support the new shadow color. attributes: attributes( '3.12.11' ), diff --git a/src/block/notification/deprecated.js b/src/block/notification/deprecated.js index 843109e860..694c439735 100644 --- a/src/block/notification/deprecated.js +++ b/src/block/notification/deprecated.js @@ -11,7 +11,7 @@ import { withVersion } from '~stackable/higher-order' import compareVersions from 'compare-versions' import { deprecateBlockBackgroundColorOpacity, deprecateContainerBackgroundColorOpacity, - deprecateBlockShadowColor, deprecateContainerShadowColor, + deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateBlockHeight, } from '~stackable/block-components' /** @@ -35,6 +35,75 @@ addFilter( 'stackable.notification.save.innerClassNames', 'stackable/3.8.0', ( o } ) const deprecated = [ + { + // Support the change of type for block height + attributes: attributes( '3.15.2' ), + save: withVersion( '3.15.2' )( Save ), + isEligible: attributes => { + const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' + const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) + return isNotV4 || hasNumberBlockHeight + }, + migrate: ( attributes, innerBlocks ) => { + const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' + + let newAttributes = { + ...attributes, + } + + if ( isNotV4 ) { + newAttributes = { + ...newAttributes, + version: 2, + } + + // Update the vertical align into flexbox + const hasOldVerticalAlign = !! attributes.containerVerticalAlign // Column only, this was changed to flexbox + + if ( hasOldVerticalAlign ) { + newAttributes = { + ...newAttributes, + containerVerticalAlign: '', + innerBlockAlign: attributes.containerVerticalAlign, + } + } + + // If the inner blocks are horizontal, adjust to accomodate the new + // column gap, it will modify blocks because people used block + // margins before instead of a proper column gap. + if ( attributes.innerBlockOrientation === 'horizontal' ) { + innerBlocks.forEach( ( block, index ) => { + if ( index ) { + if ( ! block.attributes.blockMargin ) { + block.attributes.blockMargin = { + top: '', + right: '', + bottom: '', + left: '', + } + } + if ( block.attributes.blockMargin.left === '' ) { + block.attributes.blockMargin.left = 24 + } + } + } ) + + newAttributes = { + ...newAttributes, + innerBlockColumnGap: 0, + } + } + } + + newAttributes = deprecateContainerBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockShadowColor.migrate( newAttributes ) + newAttributes = deprecateContainerShadowColor.migrate( newAttributes ) + newAttributes = deprecateBlockHeight.migrate( newAttributes ) + + return newAttributes + }, + }, { // Support the new shadow color. attributes: attributes( '3.12.11' ), diff --git a/src/block/number-box/deprecated.js b/src/block/number-box/deprecated.js index 2775402b5c..5dc233b26b 100644 --- a/src/block/number-box/deprecated.js +++ b/src/block/number-box/deprecated.js @@ -5,6 +5,7 @@ import { withVersion } from '~stackable/higher-order' import { deprecateBlockBackgroundColorOpacity, deprecateTypographyGradientColor, deprecationBackgrounColorOpacity, deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateShadowColor, deprecateTypographyFontSize, + deprecateBlockHeight, BlockDiv, CustomCSS, Typography, getResponsiveClasses, getTypographyClasses, getAlignmentClasses, } from '~stackable/block-components' @@ -58,7 +59,9 @@ const deprecated = [ attributes: attributes( '3.15.2' ), save: withVersion( '3.15.2' )( Save ), isEligible: attributes => { - return deprecateTypographyFontSize.isEligible( '%s' )( attributes ) + const hasNumberFontSize = deprecateTypographyFontSize.isEligible( '%s' )( attributes ) + const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) + return hasNumberFontSize || hasNumberBlockHeight }, migrate: attributes => { let newAttributes = deprecateBlockBackgroundColorOpacity.migrate( attributes ) @@ -68,6 +71,7 @@ const deprecated = [ newAttributes = deprecateContainerShadowColor.migrate( newAttributes ) newAttributes = deprecateShadowColor.migrate( 'shape%s' )( newAttributes ) newAttributes = deprecateTypographyFontSize.migrate( '%s' )( newAttributes ) + newAttributes = deprecateBlockHeight.migrate( newAttributes ) return newAttributes }, diff --git a/src/block/posts/deprecated.js b/src/block/posts/deprecated.js index 9df29f28ba..0a2b80f225 100644 --- a/src/block/posts/deprecated.js +++ b/src/block/posts/deprecated.js @@ -13,7 +13,7 @@ import { Image, deprecateBlockBackgroundColorOpacity, deprecateContainerBackgroundColorOpacity, deprecateTypographyGradientColor, deprecationImageOverlayOpacity, deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateShadowColor, - deprecateTypographyFontSize, + deprecateTypographyFontSize, deprecateBlockHeight, } from '~stackable/block-components' /** @@ -43,14 +43,20 @@ addFilter( 'stackable.posts.feature-image', 'stackable/3_6_3', determineFeatureI const deprecated = [ { - // Support the new shadow color. + // Support the change of type for fontSize and blockHeight attributes: attributes( '3.15.2' ), save: withVersion( '3.15.2' )( Save ), isEligible: attributes => { - const hasFontSize = deprecateTypographyFontSize.isEligible( '%s' )( attributes ) + const hasNumberFontSizeTitle = deprecateTypographyFontSize.isEligible( 'title%s' )( attributes ) + const hasNumberFontSizeCategory = deprecateTypographyFontSize.isEligible( 'category%s' )( attributes ) + const hasNumberFontSizeExcerpt = deprecateTypographyFontSize.isEligible( 'excerpt%s' )( attributes ) + const hasNumberFontSizeMeta = deprecateTypographyFontSize.isEligible( 'meta%s' )( attributes ) + const hasNumberFontSizeReadmore = deprecateTypographyFontSize.isEligible( 'readmore%s' )( attributes ) + const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' - return hasFontSize || isNotV4 + return hasNumberFontSizeTitle || hasNumberFontSizeCategory || hasNumberFontSizeExcerpt || + hasNumberFontSizeMeta || hasNumberFontSizeReadmore || hasNumberBlockHeight || isNotV4 }, migrate: attributes => { let newAttributes = { @@ -99,7 +105,13 @@ const deprecated = [ newAttributes = deprecateContainerShadowColor.migrate( newAttributes ) newAttributes = deprecateShadowColor.migrate( 'image%s' )( newAttributes ) - newAttributes = deprecateTypographyFontSize.migrate( '%s' )( newAttributes ) + newAttributes = deprecateTypographyFontSize.migrate( 'title%s' )( newAttributes ) + newAttributes = deprecateTypographyFontSize.migrate( 'category%s' )( newAttributes ) + newAttributes = deprecateTypographyFontSize.migrate( 'excerpt%s' )( newAttributes ) + newAttributes = deprecateTypographyFontSize.migrate( 'meta%s' )( newAttributes ) + newAttributes = deprecateTypographyFontSize.migrate( 'readmore%s' )( newAttributes ) + + newAttributes = deprecateBlockHeight.migrate( newAttributes ) return newAttributes }, diff --git a/src/block/price/deprecated.js b/src/block/price/deprecated.js index 395ffb36b0..90136ec005 100644 --- a/src/block/price/deprecated.js +++ b/src/block/price/deprecated.js @@ -4,10 +4,29 @@ import { attributes } from './schema' import { withVersion } from '~stackable/higher-order' import { deprecateBlockBackgroundColorOpacity, deprecateContainerBackgroundColorOpacity, - deprecateBlockShadowColor, deprecateContainerShadowColor, + deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateBlockHeight, } from '~stackable/block-components' const deprecated = [ + { + // Support the change of type for block height + attributes: attributes( '3.15.2' ), + save: withVersion( '3.15.2' )( Save ), + isEligible: attributes => { + return deprecateBlockHeight.isEligible( attributes ) + }, + migrate: attributes => { + let newAttributes = { ...attributes } + + newAttributes = deprecateContainerBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockShadowColor.migrate( newAttributes ) + newAttributes = deprecateContainerShadowColor.migrate( newAttributes ) + newAttributes = deprecateBlockHeight.migrate( newAttributes ) + + return newAttributes + }, + }, { // Support the new shadow color. attributes: attributes( '3.12.11' ), diff --git a/src/block/pricing-box/deprecated.js b/src/block/pricing-box/deprecated.js index aa0e1113fa..48d9382153 100644 --- a/src/block/pricing-box/deprecated.js +++ b/src/block/pricing-box/deprecated.js @@ -11,7 +11,7 @@ import { withVersion } from '~stackable/higher-order' import compareVersions from 'compare-versions' import { deprecateBlockBackgroundColorOpacity, deprecateContainerBackgroundColorOpacity, - deprecateBlockShadowColor, deprecateContainerShadowColor, + deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateBlockHeight, } from '~stackable/block-components' /** * WordPress dependencies @@ -34,6 +34,75 @@ addFilter( 'stackable.pricing-box.save.innerClassNames', 'stackable/3.8.0', ( ou } ) const deprecated = [ + { + // Support the change of type for block height + attributes: attributes( '3.15.2' ), + save: withVersion( '3.15.2' )( Save ), + isEligible: attributes => { + const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' + const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) + return isNotV4 || hasNumberBlockHeight + }, + migrate: ( attributes, innerBlocks ) => { + const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' + + let newAttributes = { + ...attributes, + } + + if ( isNotV4 ) { + newAttributes = { + ...newAttributes, + version: 2, + } + + // Update the vertical align into flexbox + const hasOldVerticalAlign = !! attributes.containerVerticalAlign // Column only, this was changed to flexbox + + if ( hasOldVerticalAlign ) { + newAttributes = { + ...newAttributes, + containerVerticalAlign: '', + innerBlockAlign: attributes.containerVerticalAlign, + } + } + + // If the inner blocks are horizontal, adjust to accomodate the new + // column gap, it will modify blocks because people used block + // margins before instead of a proper column gap. + if ( attributes.innerBlockOrientation === 'horizontal' ) { + innerBlocks.forEach( ( block, index ) => { + if ( index ) { + if ( ! block.attributes.blockMargin ) { + block.attributes.blockMargin = { + top: '', + right: '', + bottom: '', + left: '', + } + } + if ( block.attributes.blockMargin.left === '' ) { + block.attributes.blockMargin.left = 24 + } + } + } ) + + newAttributes = { + ...newAttributes, + innerBlockColumnGap: 0, + } + } + } + + newAttributes = deprecateContainerBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockShadowColor.migrate( newAttributes ) + newAttributes = deprecateContainerShadowColor.migrate( newAttributes ) + newAttributes = deprecateBlockHeight.migrate( newAttributes ) + + return newAttributes + }, + }, { // Support the new shadow color. attributes: attributes( '3.12.11' ), diff --git a/src/block/progress-bar/deprecated.js b/src/block/progress-bar/deprecated.js index a9151421e6..7c9b21f8c9 100644 --- a/src/block/progress-bar/deprecated.js +++ b/src/block/progress-bar/deprecated.js @@ -5,15 +5,18 @@ import { withVersion } from '~stackable/higher-order' import { deprecateBlockBackgroundColorOpacity, deprecateContainerBackgroundColorOpacity, deprecateTypographyGradientColor, deprecateTypographyShadowColor, deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateTypographyFontSize, + deprecateBlockHeight, } from '~stackable/block-components' const deprecated = [ { - // Support the change of type for fontSize + // Support the change of type for fontSize and blockHeight attributes: attributes( '3.15.2' ), save: withVersion( '3.15.2' )( Save ), isEligible: attributes => { - return deprecateTypographyFontSize.isEligible( '%s' )( attributes ) + const hasNumberFontSize = deprecateTypographyFontSize.isEligible( '%s' )( attributes ) + const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) + return hasNumberFontSize || hasNumberBlockHeight }, migrate: attributes => { let newAttributes = { ...attributes } @@ -25,6 +28,7 @@ const deprecated = [ newAttributes = deprecateContainerShadowColor.migrate( newAttributes ) newAttributes = deprecateTypographyShadowColor.migrate( '%s' )( newAttributes ) newAttributes = deprecateTypographyFontSize.migrate( '%s' )( newAttributes ) + newAttributes = deprecateBlockHeight.migrate( newAttributes ) return newAttributes }, diff --git a/src/block/progress-circle/deprecated.js b/src/block/progress-circle/deprecated.js index a9151421e6..7c9b21f8c9 100644 --- a/src/block/progress-circle/deprecated.js +++ b/src/block/progress-circle/deprecated.js @@ -5,15 +5,18 @@ import { withVersion } from '~stackable/higher-order' import { deprecateBlockBackgroundColorOpacity, deprecateContainerBackgroundColorOpacity, deprecateTypographyGradientColor, deprecateTypographyShadowColor, deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateTypographyFontSize, + deprecateBlockHeight, } from '~stackable/block-components' const deprecated = [ { - // Support the change of type for fontSize + // Support the change of type for fontSize and blockHeight attributes: attributes( '3.15.2' ), save: withVersion( '3.15.2' )( Save ), isEligible: attributes => { - return deprecateTypographyFontSize.isEligible( '%s' )( attributes ) + const hasNumberFontSize = deprecateTypographyFontSize.isEligible( '%s' )( attributes ) + const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) + return hasNumberFontSize || hasNumberBlockHeight }, migrate: attributes => { let newAttributes = { ...attributes } @@ -25,6 +28,7 @@ const deprecated = [ newAttributes = deprecateContainerShadowColor.migrate( newAttributes ) newAttributes = deprecateTypographyShadowColor.migrate( '%s' )( newAttributes ) newAttributes = deprecateTypographyFontSize.migrate( '%s' )( newAttributes ) + newAttributes = deprecateBlockHeight.migrate( newAttributes ) return newAttributes }, diff --git a/src/block/separator/deprecated.js b/src/block/separator/deprecated.js index 329d461cd9..69cdb00e89 100644 --- a/src/block/separator/deprecated.js +++ b/src/block/separator/deprecated.js @@ -5,9 +5,30 @@ import { withVersion } from '~stackable/higher-order' import { deprecateBlockBackgroundColorOpacity, deprecateContainerBackgroundColorOpacity, deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateShadowColor, + deprecateBlockHeight, } from '~stackable/block-components' const deprecated = [ + { + // Support the change of type for block height + attributes: attributes( '3.15.2' ), + save: withVersion( '3.15.2' )( Save ), + isEligible: attributes => { + return deprecateBlockHeight.isEligible( attributes ) + }, + migrate: attributes => { + let newAttributes = { ...attributes } + + newAttributes = deprecateContainerBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockShadowColor.migrate( newAttributes ) + newAttributes = deprecateContainerShadowColor.migrate( newAttributes ) + newAttributes = deprecateShadowColor.migrate( 'separator%s' )( newAttributes ) + newAttributes = deprecateBlockHeight.migrate( newAttributes ) + + return newAttributes + }, + }, { // Support the new shadow color. attributes: attributes( '3.12.11' ), diff --git a/src/block/spacer/deprecated.js b/src/block/spacer/deprecated.js index 395ffb36b0..90136ec005 100644 --- a/src/block/spacer/deprecated.js +++ b/src/block/spacer/deprecated.js @@ -4,10 +4,29 @@ import { attributes } from './schema' import { withVersion } from '~stackable/higher-order' import { deprecateBlockBackgroundColorOpacity, deprecateContainerBackgroundColorOpacity, - deprecateBlockShadowColor, deprecateContainerShadowColor, + deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateBlockHeight, } from '~stackable/block-components' const deprecated = [ + { + // Support the change of type for block height + attributes: attributes( '3.15.2' ), + save: withVersion( '3.15.2' )( Save ), + isEligible: attributes => { + return deprecateBlockHeight.isEligible( attributes ) + }, + migrate: attributes => { + let newAttributes = { ...attributes } + + newAttributes = deprecateContainerBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockShadowColor.migrate( newAttributes ) + newAttributes = deprecateContainerShadowColor.migrate( newAttributes ) + newAttributes = deprecateBlockHeight.migrate( newAttributes ) + + return newAttributes + }, + }, { // Support the new shadow color. attributes: attributes( '3.12.11' ), diff --git a/src/block/subtitle/deprecated.js b/src/block/subtitle/deprecated.js index 586654d9ca..809819a1c3 100644 --- a/src/block/subtitle/deprecated.js +++ b/src/block/subtitle/deprecated.js @@ -5,15 +5,18 @@ import { withVersion } from '~stackable/higher-order' import { deprecateBlockBackgroundColorOpacity, deprecateContainerBackgroundColorOpacity, deprecateTypographyGradientColor, deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateTypographyShadowColor, deprecateTypographyFontSize, + deprecateBlockHeight, } from '~stackable/block-components' const deprecated = [ { - // Support the change of type for fontSize + // Support the change of type for fontSize and blockHeight attributes: attributes( '3.15.2' ), save: withVersion( '3.15.2' )( Save ), isEligible: attributes => { - return deprecateTypographyFontSize.isEligible( '%s' )( attributes ) + const hasNumberFontSize = deprecateTypographyFontSize.isEligible( '%s' )( attributes ) + const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) + return hasNumberFontSize || hasNumberBlockHeight }, migrate: attributes => { let newAttributes = { ...attributes } @@ -25,6 +28,7 @@ const deprecated = [ newAttributes = deprecateContainerShadowColor.migrate( newAttributes ) newAttributes = deprecateTypographyShadowColor.migrate( '%s' )( newAttributes ) newAttributes = deprecateTypographyFontSize.migrate( '%s' )( newAttributes ) + newAttributes = deprecateBlockHeight.migrate( newAttributes ) return newAttributes }, diff --git a/src/block/tab-content/deprecated.js b/src/block/tab-content/deprecated.js index 57fd88d266..c0ba97b625 100644 --- a/src/block/tab-content/deprecated.js +++ b/src/block/tab-content/deprecated.js @@ -1,6 +1,6 @@ import { deprecateBlockBackgroundColorOpacity, deprecateContainerBackgroundColorOpacity, - deprecateBlockShadowColor, deprecateContainerShadowColor, + deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateBlockHeight, } from '~stackable/block-components' import { Save } from './save' import { attributes } from './schema' @@ -8,6 +8,25 @@ import { attributes } from './schema' import { withVersion } from '~stackable/higher-order' const deprecated = [ + { + // Support the change of type for block height + attributes: attributes( '3.15.2' ), + save: withVersion( '3.15.2' )( Save ), + isEligible: attributes => { + return deprecateBlockHeight.isEligible( attributes ) + }, + migrate: attributes => { + let newAttributes = { ...attributes } + + newAttributes = deprecateContainerBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockShadowColor.migrate( newAttributes ) + newAttributes = deprecateContainerShadowColor.migrate( newAttributes ) + newAttributes = deprecateBlockHeight.migrate( newAttributes ) + + return newAttributes + }, + }, { // Support the new shadow color. attributes: attributes( '3.12.11' ), diff --git a/src/block/tab-labels/deprecated.js b/src/block/tab-labels/deprecated.js index 96cc92cb7d..8758b25c77 100644 --- a/src/block/tab-labels/deprecated.js +++ b/src/block/tab-labels/deprecated.js @@ -1,6 +1,7 @@ import { deprecateBlockBackgroundColorOpacity, deprecateButtonGradientColor, deprecateContainerBackgroundColorOpacity, deprecateTypographyGradientColor, deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateShadowColor, deprecateTypographyShadowColor, deprecateTypographyFontSize, + deprecateBlockHeight, } from '~stackable/block-components' import { Save } from './save' import { attributes } from './schema' @@ -9,11 +10,13 @@ import { withVersion } from '~stackable/higher-order' const deprecated = [ { - // Support the change of type for fontSize + // Support the change of type for fontSize and blockHeight attributes: attributes( '3.15.2' ), save: withVersion( '3.15.2' )( Save ), isEligible: attributes => { - return deprecateTypographyFontSize.isEligible( 'tab%s' )( attributes ) + const hasNumberFontSize = deprecateTypographyFontSize.isEligible( 'tab%s' )( attributes ) + const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) + return hasNumberFontSize || hasNumberBlockHeight }, migrate: attributes => { let newAttributes = { ...attributes } @@ -29,6 +32,7 @@ const deprecated = [ newAttributes = deprecateShadowColor.migrate( 'tab%s' )( newAttributes ) newAttributes = deprecateShadowColor.migrate( 'activeTab%s' )( newAttributes ) newAttributes = deprecateTypographyFontSize.migrate( 'tab%s' )( newAttributes ) + newAttributes = deprecateBlockHeight.migrate( newAttributes ) return newAttributes }, diff --git a/src/block/table-of-contents/deprecated.js b/src/block/table-of-contents/deprecated.js index 6abb5a19ac..e5af95f982 100644 --- a/src/block/table-of-contents/deprecated.js +++ b/src/block/table-of-contents/deprecated.js @@ -11,7 +11,7 @@ import { withVersion } from '~stackable/higher-order' import compareVersions from 'compare-versions' import { deprecateBlockBackgroundColorOpacity, deprecateContainerBackgroundColorOpacity, deprecateTypographyGradientColor, - deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateTypographyFontSize, + deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateTypographyFontSize, deprecateBlockHeight, } from '~stackable/block-components' /** @@ -37,11 +37,13 @@ addFilter( 'stackable.table-of-contents.save.tableOfContentsClasses', 'stackable const deprecated = [ { - // Support the change of type for fontSize + // Support the change of type for fontSize and blockHeight attributes: attributes( '3.15.2' ), save: withVersion( '3.15.2' )( Save ), isEligible: attributes => { - return deprecateTypographyFontSize.isEligible( 'title%s' )( attributes ) + const hasNumberFontSize = deprecateTypographyFontSize.isEligible( 'title%s' )( attributes ) + const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) + return hasNumberFontSize || hasNumberBlockHeight }, migrate: attributes => { let newAttributes = { ...attributes } @@ -54,6 +56,7 @@ const deprecated = [ newAttributes = deprecateContainerShadowColor.migrate( newAttributes ) newAttributes = deprecateTypographyFontSize.migrate( '%s' )( newAttributes ) newAttributes = deprecateTypographyFontSize.migrate( 'title%s' )( newAttributes ) + newAttributes = deprecateBlockHeight.migrate( newAttributes ) return newAttributes }, diff --git a/src/block/tabs/deprecated.js b/src/block/tabs/deprecated.js index 85ccf8730f..a9574ef754 100644 --- a/src/block/tabs/deprecated.js +++ b/src/block/tabs/deprecated.js @@ -1,6 +1,6 @@ import { deprecateBlockBackgroundColorOpacity, deprecateContainerBackgroundColorOpacity, - deprecateBlockShadowColor, deprecateContainerShadowColor, + deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateBlockHeight, } from '~stackable/block-components' import { Save } from './save' import { attributes } from './schema' @@ -8,6 +8,36 @@ import { attributes } from './schema' import { withVersion } from '~stackable/higher-order' const deprecated = [ + { + // Support the change of type for block height + attributes: attributes( '3.15.2' ), + save: withVersion( '3.15.2' )( Save ), + isEligible: attributes => { + return deprecateBlockHeight.isEligible( attributes ) + }, + migrate: attributes => { + let newAttributes = { ...attributes } + + const hasContainerOpacity = deprecateContainerBackgroundColorOpacity.isEligible( attributes ) + if ( hasContainerOpacity ) { + newAttributes = deprecateContainerBackgroundColorOpacity.migrate( newAttributes ) + } + + const hasBlockOpacity = deprecateBlockBackgroundColorOpacity.isEligible( attributes ) + if ( hasBlockOpacity ) { + newAttributes = deprecateBlockBackgroundColorOpacity.migrate( newAttributes ) + } + + newAttributes = deprecateBlockShadowColor.migrate( newAttributes ) + newAttributes = deprecateContainerShadowColor.migrate( newAttributes ) + newAttributes = deprecateBlockHeight.migrate( newAttributes ) + + return { + ...newAttributes, + equalTabHeight: true, + } + }, + }, { // Support the new shadow color. attributes: attributes( '3.12.11' ), diff --git a/src/block/team-member/deprecated.js b/src/block/team-member/deprecated.js index ef5c7d6b2a..47ec8ffe9f 100644 --- a/src/block/team-member/deprecated.js +++ b/src/block/team-member/deprecated.js @@ -11,7 +11,7 @@ import { withVersion } from '~stackable/higher-order' import compareVersions from 'compare-versions' import { deprecateBlockBackgroundColorOpacity, deprecateContainerBackgroundColorOpacity, - deprecateBlockShadowColor, deprecateContainerShadowColor, + deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateBlockHeight, } from '~stackable/block-components' /** @@ -35,6 +35,75 @@ addFilter( 'stackable.team-member.save.innerClassNames', 'stackable/3.8.0', ( ou } ) const deprecated = [ + { + // Support the change of type for block height + attributes: attributes( '3.15.2' ), + save: withVersion( '3.15.2' )( Save ), + isEligible: attributes => { + const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' + const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) + return isNotV4 || hasNumberBlockHeight + }, + migrate: ( attributes, innerBlocks ) => { + const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' + + let newAttributes = { + ...attributes, + } + + if ( isNotV4 ) { + newAttributes = { + ...newAttributes, + version: 2, + } + + // Update the vertical align into flexbox + const hasOldVerticalAlign = !! attributes.containerVerticalAlign // Column only, this was changed to flexbox + + if ( hasOldVerticalAlign ) { + newAttributes = { + ...newAttributes, + containerVerticalAlign: '', + innerBlockAlign: attributes.containerVerticalAlign, + } + } + + // If the inner blocks are horizontal, adjust to accomodate the new + // column gap, it will modify blocks because people used block + // margins before instead of a proper column gap. + if ( attributes.innerBlockOrientation === 'horizontal' ) { + innerBlocks.forEach( ( block, index ) => { + if ( index ) { + if ( ! block.attributes.blockMargin ) { + block.attributes.blockMargin = { + top: '', + right: '', + bottom: '', + left: '', + } + } + if ( block.attributes.blockMargin.left === '' ) { + block.attributes.blockMargin.left = 24 + } + } + } ) + + newAttributes = { + ...newAttributes, + innerBlockColumnGap: 0, + } + } + } + + newAttributes = deprecateContainerBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockShadowColor.migrate( newAttributes ) + newAttributes = deprecateContainerShadowColor.migrate( newAttributes ) + newAttributes = deprecateBlockHeight.migrate( newAttributes ) + + return newAttributes + }, + }, { // Support the new shadow color. attributes: attributes( '3.12.11' ), diff --git a/src/block/testimonial/deprecated.js b/src/block/testimonial/deprecated.js index cc64e5fd2e..df70cb918e 100644 --- a/src/block/testimonial/deprecated.js +++ b/src/block/testimonial/deprecated.js @@ -11,7 +11,7 @@ import { withVersion } from '~stackable/higher-order' import compareVersions from 'compare-versions' import { deprecateBlockBackgroundColorOpacity, deprecateContainerBackgroundColorOpacity, - deprecateBlockShadowColor, deprecateContainerShadowColor, + deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateBlockHeight, } from '~stackable/block-components' /** @@ -35,6 +35,75 @@ addFilter( 'stackable.testimonial.save.innerClassNames', 'stackable/3.8.0', ( ou } ) const deprecated = [ + { + // Support the change of type for block height + attributes: attributes( '3.15.2' ), + save: withVersion( '3.15.2' )( Save ), + isEligible: attributes => { + const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' + const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) + return isNotV4 || hasNumberBlockHeight + }, + migrate: ( attributes, innerBlocks ) => { + const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' + + let newAttributes = { + ...attributes, + } + + if ( isNotV4 ) { + newAttributes = { + ...newAttributes, + version: 2, + } + + // Update the vertical align into flexbox + const hasOldVerticalAlign = !! attributes.containerVerticalAlign // Column only, this was changed to flexbox + + if ( hasOldVerticalAlign ) { + newAttributes = { + ...newAttributes, + containerVerticalAlign: '', + innerBlockAlign: attributes.containerVerticalAlign, + } + } + + // If the inner blocks are horizontal, adjust to accomodate the new + // column gap, it will modify blocks because people used block + // margins before instead of a proper column gap. + if ( attributes.innerBlockOrientation === 'horizontal' ) { + innerBlocks.forEach( ( block, index ) => { + if ( index ) { + if ( ! block.attributes.blockMargin ) { + block.attributes.blockMargin = { + top: '', + right: '', + bottom: '', + left: '', + } + } + if ( block.attributes.blockMargin.left === '' ) { + block.attributes.blockMargin.left = 24 + } + } + } ) + + newAttributes = { + ...newAttributes, + innerBlockColumnGap: 0, + } + } + } + + newAttributes = deprecateContainerBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockBackgroundColorOpacity.migrate( newAttributes ) + newAttributes = deprecateBlockShadowColor.migrate( newAttributes ) + newAttributes = deprecateContainerShadowColor.migrate( newAttributes ) + newAttributes = deprecateBlockHeight.migrate( newAttributes ) + + return newAttributes + }, + }, { // Support the new shadow color. attributes: attributes( '3.12.11' ), diff --git a/src/block/text/deprecated.js b/src/block/text/deprecated.js index 393a7baa74..229a66c427 100644 --- a/src/block/text/deprecated.js +++ b/src/block/text/deprecated.js @@ -5,6 +5,7 @@ import { withVersion } from '~stackable/higher-order' import { deprecateBlockBackgroundColorOpacity, deprecateContainerBackgroundColorOpacity, deprecateTypographyGradientColor, deprecateTypographyShadowColor, deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateTypographyFontSize, + deprecateBlockHeight, } from '~stackable/block-components' const deprecated = [ @@ -13,7 +14,9 @@ const deprecated = [ attributes: attributes( '3.15.2' ), save: withVersion( '3.15.2' )( Save ), isEligible: attributes => { - return deprecateTypographyFontSize.isEligible( '%s' )( attributes ) + const hasNumberFontSize = deprecateTypographyFontSize.isEligible( '%s' )( attributes ) + const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) + return hasNumberFontSize || hasNumberBlockHeight }, migrate: attributes => { let newAttributes = { ...attributes } @@ -25,6 +28,7 @@ const deprecated = [ newAttributes = deprecateContainerShadowColor.migrate( newAttributes ) newAttributes = deprecateTypographyShadowColor.migrate( '%s' )( newAttributes ) newAttributes = deprecateTypographyFontSize.migrate( '%s' )( newAttributes ) + newAttributes = deprecateBlockHeight.migrate( newAttributes ) return newAttributes }, diff --git a/src/block/timeline/deprecated.js b/src/block/timeline/deprecated.js index 9ded4d89b2..6b7f581bae 100644 --- a/src/block/timeline/deprecated.js +++ b/src/block/timeline/deprecated.js @@ -1,6 +1,7 @@ import { deprecateBlockBackgroundColorOpacity, deprecateContainerBackgroundColorOpacity, deprecateTypographyGradientColor, deprecateTypographyShadowColor, deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateTypographyFontSize, + deprecateBlockHeight, } from '~stackable/block-components' import { Save } from './save' import { attributes } from './schema' @@ -13,7 +14,9 @@ const deprecated = [ attributes: attributes( '3.15.2' ), save: withVersion( '3.15.2' )( Save ), isEligible: attributes => { - return deprecateTypographyFontSize.isEligible( '%s' )( attributes ) + const hasNumberFontSize = deprecateTypographyFontSize.isEligible( '%s' )( attributes ) + const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) + return hasNumberFontSize || hasNumberBlockHeight }, migrate: attributes => { let newAttributes = { ...attributes } @@ -25,6 +28,7 @@ const deprecated = [ newAttributes = deprecateContainerShadowColor.migrate( newAttributes ) newAttributes = deprecateTypographyShadowColor.migrate( '%s' )( newAttributes ) newAttributes = deprecateTypographyFontSize.migrate( '%s' )( newAttributes ) + newAttributes = deprecateBlockHeight.migrate( newAttributes ) return newAttributes }, diff --git a/src/block/video-popup/deprecated.js b/src/block/video-popup/deprecated.js index 7d84849ead..1a0131f3b1 100644 --- a/src/block/video-popup/deprecated.js +++ b/src/block/video-popup/deprecated.js @@ -6,7 +6,7 @@ import { semverCompare } from '~stackable/util' import { i18n } from 'stackable' import { deprecateBlockBackgroundColorOpacity, deprecateContainerBackgroundColorOpacity, - deprecateBlockShadowColor, deprecateContainerShadowColor, + deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateBlockHeight, } from '~stackable/block-components' /** @@ -28,6 +28,21 @@ addFilter( 'stackable.video-popup.save.div.content', 'stackable/3.12.14', ( outp } ) const deprecated = [ + { + // Support the change of type for block height + attributes: attributes( '3.15.2' ), + save: withVersion( '3.15.2' )( Save ), + isEligible: attributes => { + return deprecateBlockHeight.isEligible( attributes ) + }, + migrate: attributes => { + let newAttributes = { ...attributes } + + newAttributes = deprecateBlockHeight.migrate( newAttributes ) + + return newAttributes + }, + }, { attributes: attributes( '3.12.14' ), save: withVersion( '3.12.14' )( Save ), From 444166084153d8b1e1e0051a5144634bfff2d5e6 Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Mon, 14 Apr 2025 12:46:02 +0800 Subject: [PATCH 60/99] fix: add row and column gaps deprecations --- src/block-components/columns/attributes.js | 24 ++++++++++++++++------ src/block-components/columns/index.js | 2 ++ src/block-components/columns/style.js | 8 ++++---- src/block/carousel/deprecated.js | 8 ++++++-- src/block/columns/deprecated.js | 8 +++++--- src/block/feature-grid/deprecated.js | 8 +++++--- src/block/feature/deprecated.js | 8 +++++--- src/block/tab-content/deprecated.js | 8 ++++++-- 8 files changed, 51 insertions(+), 23 deletions(-) diff --git a/src/block-components/columns/attributes.js b/src/block-components/columns/attributes.js index 2158b042fc..253a6ebf28 100644 --- a/src/block-components/columns/attributes.js +++ b/src/block-components/columns/attributes.js @@ -1,4 +1,8 @@ -export const addAttributes = attrObject => { +import { deprecatedAddAttributes } from './deprecated/index' + +export const addAttributes = ( attrObject, attrNameTemplate = '%s' ) => { + deprecatedAddAttributes( attrObject, attrNameTemplate ) + attrObject.add( { attributes: { columnSpacing: { @@ -7,6 +11,17 @@ export const addAttributes = attrObject => { type: 'number', default: '', }, + columnWrapDesktop: { // Only applies to desktops + type: 'boolean', + default: false, + }, + }, + versionAdded: '3.0.0', + versionDeprecated: '', + } ) + + attrObject.add( { + attributes: { columnGap: { stkResponsive: true, type: 'string', @@ -17,12 +32,9 @@ export const addAttributes = attrObject => { type: 'string', default: '', }, - columnWrapDesktop: { // Only applies to desktops - type: 'boolean', - default: false, - }, }, - versionAdded: '3.0.0', + attrNameTemplate, + versionAdded: '3.15.3', versionDeprecated: '', } ) } diff --git a/src/block-components/columns/index.js b/src/block-components/columns/index.js index 53398ebe93..bb0ec6397e 100644 --- a/src/block-components/columns/index.js +++ b/src/block-components/columns/index.js @@ -6,6 +6,8 @@ export const Columns = () => { return null } +export { deprecateColumnAndRowGap } from './deprecated/index' + Columns.InspectorControls = Edit Columns.addStyles = addStyles diff --git a/src/block-components/columns/style.js b/src/block-components/columns/style.js index 2355a4d16a..6a09e38ac5 100644 --- a/src/block-components/columns/style.js +++ b/src/block-components/columns/style.js @@ -33,7 +33,7 @@ export const addStyles = ( blockStyleGenerator, props = {} ) => { responsive: 'all', valueCallback: value => { // Substitute with using format to work with preset controls - if ( value.startsWith( 'var' ) ) { + if ( typeof value === 'string' && value.startsWith( 'var' ) ) { return value } return value + 'px' @@ -46,7 +46,7 @@ export const addStyles = ( blockStyleGenerator, props = {} ) => { attrName: 'columnGap', responsive: 'all', valueCallback: value => { - if ( value.startsWith( 'var' ) ) { + if ( typeof value === 'string' && value.startsWith( 'var' ) ) { return value } return value + 'px' @@ -91,7 +91,7 @@ export const addStyles = ( blockStyleGenerator, props = {} ) => { attrName: 'rowGap', responsive: 'all', valueCallback: value => { - if ( value.startsWith( 'var' ) ) { + if ( typeof value === 'string' && value.startsWith( 'var' ) ) { return value } return value + 'px' @@ -104,7 +104,7 @@ export const addStyles = ( blockStyleGenerator, props = {} ) => { attrName: 'rowGap', responsive: 'all', valueCallback: value => { - if ( value.startsWith( 'var' ) ) { + if ( typeof value === 'string' && value.startsWith( 'var' ) ) { return value } return value + 'px' diff --git a/src/block/carousel/deprecated.js b/src/block/carousel/deprecated.js index 140d8429e3..92bfd20efc 100644 --- a/src/block/carousel/deprecated.js +++ b/src/block/carousel/deprecated.js @@ -1,6 +1,7 @@ import { deprecateBlockBackgroundColorOpacity, deprecateContainerBackgroundColorOpacity, deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateShadowColor, deprecateBlockHeight, + deprecateColumnAndRowGap, } from '~stackable/block-components' import { Save } from './save' import { attributes } from './schema' @@ -9,11 +10,13 @@ import { withVersion } from '~stackable/higher-order' const deprecated = [ { - // Support the change of type for block height + // Support the change of type for block height and gaps attributes: attributes( '3.15.2' ), save: withVersion( '3.15.2' )( Save ), isEligible: attributes => { - return deprecateBlockHeight.isEligible( attributes ) + const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) + const hasNumberGaps = deprecateColumnAndRowGap.isEligible( '%s' )( attributes ) + return hasNumberBlockHeight || hasNumberGaps }, migrate: attributes => { let newAttributes = { ...attributes } @@ -25,6 +28,7 @@ const deprecated = [ newAttributes = deprecateContainerBackgroundColorOpacity.migrate( newAttributes ) newAttributes = deprecateBlockBackgroundColorOpacity.migrate( newAttributes ) newAttributes = deprecateBlockHeight.migrate( newAttributes ) + newAttributes = deprecateColumnAndRowGap.migrate( '%s' )( newAttributes ) return newAttributes }, diff --git a/src/block/columns/deprecated.js b/src/block/columns/deprecated.js index 5bf006f75a..a00faef833 100644 --- a/src/block/columns/deprecated.js +++ b/src/block/columns/deprecated.js @@ -17,7 +17,7 @@ import { semverCompare } from '~stackable/util' import { deprecateBlockBackgroundColorOpacity, deprecateContainerBackgroundColorOpacity, deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateShadowColor, - deprecateBlockHeight, + deprecateBlockHeight, deprecateColumnAndRowGap, } from '~stackable/block-components' // Version 3.6.2 Deprecations, we now don't need the stk--has-column-order class. @@ -38,13 +38,14 @@ addFilter( 'stackable.columns.save.contentClassNames', 'stackable/3.8.0', ( clas const deprecated = [ { - // Support the change of type for block height + // Support the change of type for block height and gaps attributes: attributes( '3.15.2' ), save: withVersion( '3.15.2' )( Save ), isEligible: attributes => { const hasColumnFit = !! attributes.columnFit const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) - return hasColumnFit || hasNumberBlockHeight + const hasNumberGaps = deprecateColumnAndRowGap.isEligible( '%s' )( attributes ) + return hasColumnFit || hasNumberBlockHeight || hasNumberGaps }, migrate: attributes => { let newAttributes = { @@ -61,6 +62,7 @@ const deprecated = [ newAttributes = deprecateShadowColor.migrate( 'topSeparator%s' )( newAttributes ) newAttributes = deprecateShadowColor.migrate( 'bottomSeparator%s' )( newAttributes ) newAttributes = deprecateBlockHeight.migrate( newAttributes ) + newAttributes = deprecateColumnAndRowGap.migrate( '%s' )( newAttributes ) return newAttributes }, diff --git a/src/block/feature-grid/deprecated.js b/src/block/feature-grid/deprecated.js index 2803f5c4db..46e7ebe17a 100644 --- a/src/block/feature-grid/deprecated.js +++ b/src/block/feature-grid/deprecated.js @@ -13,7 +13,7 @@ import { deprecateBlockBackgroundColorOpacity, deprecateContainerBackgroundColorOpacity, getResponsiveClasses, getSeparatorClasses, deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateShadowColor, - deprecateBlockHeight, + deprecateBlockHeight, deprecateColumnAndRowGap, } from '~stackable/block-components' /** @@ -62,13 +62,14 @@ addFilter( 'stackable.feature-grid.save.blockClassNames', 'stackable/3.1.0', ( o const deprecated = [ { - // Support the change of type for block height + // Support the change of type for block height and gaps attributes: attributes( '3.15.2' ), save: withVersion( '3.15.2' )( Save ), isEligible: attributes => { const hasColumnFit = !! attributes.columnFit const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) - return hasColumnFit || hasNumberBlockHeight + const hasNumberGaps = deprecateColumnAndRowGap.isEligible( '%s' )( attributes ) + return hasColumnFit || hasNumberBlockHeight || hasNumberGaps }, migrate: attributes => { let newAttributes = { @@ -85,6 +86,7 @@ const deprecated = [ newAttributes = deprecateShadowColor.migrate( 'topSeparator%s' )( newAttributes ) newAttributes = deprecateShadowColor.migrate( 'bottomSeparator%s' )( newAttributes ) newAttributes = deprecateBlockHeight.migrate( newAttributes ) + newAttributes = deprecateColumnAndRowGap.migrate( '%s' )( newAttributes ) return newAttributes }, diff --git a/src/block/feature/deprecated.js b/src/block/feature/deprecated.js index 791adb3605..581002a463 100644 --- a/src/block/feature/deprecated.js +++ b/src/block/feature/deprecated.js @@ -14,7 +14,7 @@ import { deprecateContainerBackgroundColorOpacity, getAlignmentClasses, getContentAlignmentClasses, getRowClasses, deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateShadowColor, - deprecateBlockHeight, + deprecateBlockHeight, deprecateColumnAndRowGap, } from '~stackable/block-components' /** @@ -64,13 +64,14 @@ addFilter( 'stackable.feature.save.innerClassNames', 'stackable/3.8.0', ( output const deprecated = [ { - // Support the change of type for block height + // Support the change of type for block height and gaps attributes: attributes( '3.15.2' ), save: withVersion( '3.15.2' )( Save ), isEligible: attributes => { const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) - return isNotV4 || hasNumberBlockHeight + const hasNumberGaps = deprecateColumnAndRowGap.isEligible( '%s' )( attributes ) + return isNotV4 || hasNumberBlockHeight || hasNumberGaps }, migrate: attributes => { let newAttributes = { @@ -96,6 +97,7 @@ const deprecated = [ newAttributes = deprecateShadowColor.migrate( 'topSeparator%s' )( newAttributes ) newAttributes = deprecateShadowColor.migrate( 'bottomSeparator%s' )( newAttributes ) newAttributes = deprecateBlockHeight.migrate( newAttributes ) + newAttributes = deprecateColumnAndRowGap.migrate( '%s' )( newAttributes ) return newAttributes }, diff --git a/src/block/tab-content/deprecated.js b/src/block/tab-content/deprecated.js index c0ba97b625..f9d19b712d 100644 --- a/src/block/tab-content/deprecated.js +++ b/src/block/tab-content/deprecated.js @@ -1,6 +1,7 @@ import { deprecateBlockBackgroundColorOpacity, deprecateContainerBackgroundColorOpacity, deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateBlockHeight, + deprecateColumnAndRowGap, } from '~stackable/block-components' import { Save } from './save' import { attributes } from './schema' @@ -9,11 +10,13 @@ import { withVersion } from '~stackable/higher-order' const deprecated = [ { - // Support the change of type for block height + // Support the change of type for block height and gaps attributes: attributes( '3.15.2' ), save: withVersion( '3.15.2' )( Save ), isEligible: attributes => { - return deprecateBlockHeight.isEligible( attributes ) + const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) + const hasNumberGaps = deprecateColumnAndRowGap.isEligible( '%s' )( attributes ) + return hasNumberBlockHeight || hasNumberGaps }, migrate: attributes => { let newAttributes = { ...attributes } @@ -23,6 +26,7 @@ const deprecated = [ newAttributes = deprecateBlockShadowColor.migrate( newAttributes ) newAttributes = deprecateContainerShadowColor.migrate( newAttributes ) newAttributes = deprecateBlockHeight.migrate( newAttributes ) + newAttributes = deprecateColumnAndRowGap.migrate( '%s' )( newAttributes ) return newAttributes }, From 38d75f0e81de74d8c97501b82793d9db5cea1adf Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Tue, 15 Apr 2025 12:14:38 +0800 Subject: [PATCH 61/99] fix: add row and column gaps deprecations --- .../columns/deprecated/index.js | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 src/block-components/columns/deprecated/index.js diff --git a/src/block-components/columns/deprecated/index.js b/src/block-components/columns/deprecated/index.js new file mode 100644 index 0000000000..efce36ad69 --- /dev/null +++ b/src/block-components/columns/deprecated/index.js @@ -0,0 +1,48 @@ +import { getAttrNameFunction } from '~stackable/util' + +export const deprecatedAddAttributes = ( attrObject, attrNameTemplate = '%s' ) => { + attrObject.add( { + attributes: { + columnGap: { + stkResponsive: true, + type: 'number', + default: '', + }, + rowGap: { + stkResponsive: true, + type: 'number', + default: '', + }, + }, + attrNameTemplate, + versionAdded: '3.0.0', + versionDeprecated: '3.15.3', + } ) +} + +export const deprecateColumnAndRowGap = { + isEligible: attrNameTemplate => attributes => { + const getAttrName = getAttrNameFunction( attrNameTemplate ) + const getAttribute = _attrName => attributes[ getAttrName( _attrName ) ] + + const columnGap = getAttribute( 'columnGap' ) + const rowGap = getAttribute( 'rowGap' ) + + return typeof columnGap === 'number' || typeof rowGap === 'number' + }, + migrate: attrNameTemplate => attributes => { + const getAttrName = getAttrNameFunction( attrNameTemplate ) + const getAttribute = _attrName => attributes[ getAttrName( _attrName ) ] + + const columnGap = getAttribute( 'columnGap' ) + const rowGap = getAttribute( 'rowGap' ) + + const newAttributes = { + ...attributes, + [ getAttrName( 'columnGap' ) ]: String( columnGap ), + [ getAttrName( 'rowGap' ) ]: String( rowGap ), + } + + return newAttributes + }, +} From 130d4986eca69db11e68367519a97202b187777f Mon Sep 17 00:00:00 2001 From: "bfintal@gmail.com" <> Date: Wed, 7 May 2025 11:40:54 +0800 Subject: [PATCH 62/99] tweaked premium notice wording --- src/components/pro-control/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/pro-control/index.js b/src/components/pro-control/index.js index a15a7ed4ec..83be6b65b8 100644 --- a/src/components/pro-control/index.js +++ b/src/components/pro-control/index.js @@ -136,7 +136,7 @@ const LABELS = { 'preset-controls': { title: __( 'Premium Preset Controls', i18n ), description:
      -
    • { __( 'Customize your own presets', i18n ) }
    • +
    • { __( 'Customize your own presets like small, medium, large & x-large', i18n ) }
    • { __( 'Use Global Typography sizes as presets', i18n ) }
    , }, From 46a7b29a8cd67a06c03a84e247c83d7a0c381781 Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Fri, 9 May 2025 10:55:36 +0800 Subject: [PATCH 63/99] fix: still match previous value even the custom values changes --- .../advanced-range-control/index.js | 20 +++++++++++++------ src/util/index.js | 6 ++++++ 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/components/advanced-range-control/index.js b/src/components/advanced-range-control/index.js index 17c7039821..b0d0522c2e 100644 --- a/src/components/advanced-range-control/index.js +++ b/src/components/advanced-range-control/index.js @@ -13,7 +13,7 @@ import { useBlockSetAttributesContext, useDeviceType, } from '~stackable/hooks' -import { extractNumbersAndUnits } from '~stackable/util' +import { extractNumbersAndUnits, getCSSVarName } from '~stackable/util' /** * External dependencies @@ -106,13 +106,18 @@ const AdvancedRangeControl = props => { // Is value at first render the same as a step value? If so, do mark mode // at the start, or show custom - let isMarkValue = !! props.marks + let currentMark = null if ( props.marks && value ) { const valueToCheck = value + ( props.hasCSSVariableValue ? '' : unit ) - // Check if the current value exsits in the marks - isMarkValue = isMarkValue && props.marks.some( mark => mark.value === valueToCheck ) + // Check if the current value exists in the marks only by their CSS variable name + // to match in case the fallback size changes. + props.marks.forEach( mark => { + if ( getCSSVarName( mark.value ) === getCSSVarName( valueToCheck ) ) { + currentMark = mark + } + } ) } - const [ isMarkMode, setIsMarkMode ] = useState( isMarkValue ) + const [ isMarkMode, setIsMarkMode ] = useState( !! currentMark ) // If this supports dynamic content, the value should be saved as a String. // Similar if using marks to accomodate CSS variable @@ -135,7 +140,10 @@ const AdvancedRangeControl = props => { onChangeFunc( newValue ) } - const derivedValue = typeof props.value === 'undefined' ? value : props.value + const derivedValue = typeof props.value === 'undefined' + // Use the value from the provided marks + ? currentMark ? currentMark.value : value + : props.value const dynamicContentProps = useDynamicContentControlProps( { value: derivedValue, diff --git a/src/util/index.js b/src/util/index.js index 08f02913e8..f060aaa231 100644 --- a/src/util/index.js +++ b/src/util/index.js @@ -417,3 +417,9 @@ export const extractNumbersAndUnits = value => { } return [ [ '0', 'px' ] ] } + +// Return only the CSS variable name given a CSS variable +export const getCSSVarName = value => { + const match = value.match( /var\(\s*([^,)\s]+)/ ) + return match ? match[ 1 ] : null +} From 8efb71e91d2c1f88e98a2b76a48d14f62f614cfe Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Wed, 14 May 2025 10:00:00 +0800 Subject: [PATCH 64/99] fix: implement presets in the design system; fix issues with reactivity, variable type, units, etc. --- .../advanced-range-control/index.js | 34 ++++----- src/components/four-range-control/index.js | 69 +++++++++++++------ src/global-settings.php | 35 +++++++++- .../buttons-and-icons/index.js | 19 +++++ .../buttons-and-icons/index.php | 17 ++--- .../spacing-and-borders/index.js | 35 +++++++--- .../spacing-and-borders/index.php | 17 ++--- .../utils/use-block-layout-editor-loader.js | 8 ++- 8 files changed, 167 insertions(+), 67 deletions(-) diff --git a/src/components/advanced-range-control/index.js b/src/components/advanced-range-control/index.js index b0d0522c2e..33f1316ed1 100644 --- a/src/components/advanced-range-control/index.js +++ b/src/components/advanced-range-control/index.js @@ -104,20 +104,22 @@ const AdvancedRangeControl = props => { placeholderRender = null } + let derivedValue = typeof props.value === 'undefined' + ? value : props.value + // Is value at first render the same as a step value? If so, do mark mode // at the start, or show custom - let currentMark = null - if ( props.marks && value ) { - const valueToCheck = value + ( props.hasCSSVariableValue ? '' : unit ) + let isMarkValue = !! props.marks + if ( props.marks && derivedValue ) { // Check if the current value exists in the marks only by their CSS variable name // to match in case the fallback size changes. - props.marks.forEach( mark => { - if ( getCSSVarName( mark.value ) === getCSSVarName( valueToCheck ) ) { - currentMark = mark - } - } ) + const matchedMark = props.marks.find( mark => getCSSVarName( mark.value ) === getCSSVarName( derivedValue ) ) + isMarkValue = !! matchedMark + if ( matchedMark ) { + derivedValue = matchedMark.value + } } - const [ isMarkMode, setIsMarkMode ] = useState( !! currentMark ) + const [ isMarkMode, setIsMarkMode ] = useState( isMarkValue ) // If this supports dynamic content, the value should be saved as a String. // Similar if using marks to accomodate CSS variable @@ -140,11 +142,6 @@ const AdvancedRangeControl = props => { onChangeFunc( newValue ) } - const derivedValue = typeof props.value === 'undefined' - // Use the value from the provided marks - ? currentMark ? currentMark.value : value - : props.value - const dynamicContentProps = useDynamicContentControlProps( { value: derivedValue, onChange: _onChange, @@ -207,9 +204,9 @@ const AdvancedRangeControl = props => { const markValue = props.marks[ value ]?.[ property ] || '0' let [ newValue, unit ] = extractNumbersAndUnits( markValue )[ 0 ] - // If the attribute has no units (only support px), and the - // preset units are rem or em, convert to px - if ( ! hasUnits && ( unit === 'rem' || unit === 'em' ) ) { + // If the attribute has no support for rem, and the + // preset units is rem, convert to px + if ( ( ! hasUnits || ( hasUnits && ! props.units.includes( 'rem' ) ) ) && unit === 'rem' ) { newValue = `${ parseFloat( newValue ) * 16 }` unit = 'px' } @@ -218,6 +215,9 @@ const AdvancedRangeControl = props => { if ( unit ) { dispatch( 'core/block-editor' ).__unstableMarkNextChangeAsNotPersistent() setAttributes( { [ unitAttrName ]: unit } ) + if ( props.onChangeUnit ) { + props.onChangeUnit( unit ) + } } _onChange( newValue ) diff --git a/src/components/four-range-control/index.js b/src/components/four-range-control/index.js index 6e9aee60ea..492a9bd115 100644 --- a/src/components/four-range-control/index.js +++ b/src/components/four-range-control/index.js @@ -18,7 +18,6 @@ import RangeControl from '../advanced-range-control/range-control' import { ResetButton } from '../base-control2/reset-button' import AdvancedControl, { extractControlProps } from '../base-control2' import { useControlHandlers } from '../base-control2/hooks' -import { extractNumbersAndUnits } from '~stackable/util' /** * WordPress dependencies @@ -45,6 +44,7 @@ import { useBlockHoverState, useBlockSetAttributesContext, } from '~stackable/hooks' +import { extractNumbersAndUnits, getCSSVarName } from '~stackable/util' const isEqualInitial = ( props, value, firstValue ) => { let isEqual = true @@ -81,7 +81,7 @@ const FourRangeControl = memo( props => { ( props.enableBottom && value.bottom === '' ) && ( props.enableLeft && value.left === '' ) - const firstValue = props.enableTop ? value.top + let firstValue = props.enableTop ? value.top : props.enableRight ? value.right : props.enableBottom ? value.bottom : value.left @@ -195,17 +195,26 @@ const FourRangeControl = memo( props => { left: !! props.marks, } if ( props.marks && firstValue ) { - // Check if the current value exsits in the marks - const marksUnit = ( props.hasCSSVariableValue ? '' : unit ) - isMarkValue.first = isMarkValue.first && props.marks.some( mark => mark.value === firstValue + marksUnit ) - isMarkValue.top = isMarkValue.top && props.marks.some( mark => mark.value === value.top + marksUnit ) - isMarkValue.right = isMarkValue.right && props.marks.some( mark => mark.value === value.right + marksUnit ) - isMarkValue.bottom = isMarkValue.bottom && props.marks.some( mark => mark.value === value.bottom + marksUnit ) - isMarkValue.left = isMarkValue.left && props.marks.some( mark => mark.value === value.left + marksUnit ) + // Check if the current value exists in the marks only by their CSS variable name + // to match in case the fallback size changes. + const firstMatchedMark = props.marks.find( mark => getCSSVarName( mark.value ) === getCSSVarName( firstValue ) ) + isMarkValue.first = !! firstMatchedMark + if ( firstMatchedMark ) { + firstValue = firstMatchedMark.value + } + + [ 'top', 'right', 'bottom', 'left' ].forEach( side => { + const matchedMark = props.marks.find( mark => getCSSVarName( mark.value ) === getCSSVarName( value[ side ] ) ) + isMarkValue[ side ] = !! matchedMark + if ( matchedMark ) { + value[ side ] = matchedMark.value + } + } ) } const [ isFourMarkMode, setIsFourMarkMode ] = useState( isMarkValue ) - const onChangeAll = newValue => { + const onChangeAll = _newValue => { + const newValue = props.marks ? String( _newValue ) : _newValue onChange( { top: props.enableTop ? newValue : value.top, right: props.enableRight ? newValue : value.right, @@ -221,7 +230,8 @@ const FourRangeControl = memo( props => { } ) ) } - const onChangeTop = newValue => { + const onChangeTop = _newValue => { + const newValue = props.marks ? String( _newValue ) : _newValue onChange( { top: newValue, right: value.right, @@ -231,7 +241,8 @@ const FourRangeControl = memo( props => { setIsFourMarkMode( prev => ( { ...prev, first: prev.top } ) ) } - const onChangeRight = newValue => { + const onChangeRight = _newValue => { + const newValue = props.marks ? String( _newValue ) : _newValue onChange( { top: value.top, right: newValue, @@ -241,7 +252,8 @@ const FourRangeControl = memo( props => { setIsFourMarkMode( prev => ( { ...prev, first: prev.right } ) ) } - const onChangeBottom = newValue => { + const onChangeBottom = _newValue => { + const newValue = props.marks ? String( _newValue ) : _newValue onChange( { top: value.top, right: value.right, @@ -251,7 +263,8 @@ const FourRangeControl = memo( props => { setIsFourMarkMode( prev => ( { ...prev, first: prev.bottom } ) ) } - const onChangeLeft = newValue => { + const onChangeLeft = _newValue => { + const newValue = props.marks ? String( _newValue ) : _newValue onChange( { top: value.top, right: value.right, @@ -261,7 +274,8 @@ const FourRangeControl = memo( props => { setIsFourMarkMode( prev => ( { ...prev, first: prev.left } ) ) } - const onChangeVertical = newValue => { + const onChangeVertical = _newValue => { + const newValue = props.marks ? String( _newValue ) : _newValue onChange( { top: newValue, right: value.right, @@ -275,7 +289,8 @@ const FourRangeControl = memo( props => { } ) ) } - const onChangeHorizontal = newValue => { + const onChangeHorizontal = _newValue => { + const newValue = props.marks ? String( _newValue ) : _newValue onChange( { top: value.top, right: newValue, @@ -327,7 +342,7 @@ const FourRangeControl = memo( props => { } // We need to change the way we handle the value and onChange if we're doing marks - let rangeValue = props.hasCSSVariableValue ? parseFloat( initialValue ) : initialValue + let rangeValue = props.marks ? parseFloat( initialValue ) : initialValue let rangeOnChange = initialOnChange if ( props.marks && isMarkMode ) { rangeValue = props.marks.findIndex( mark => { @@ -341,12 +356,23 @@ const FourRangeControl = memo( props => { // Extract the unit and value. const markValue = props.marks[ value ]?.[ property ] || '0' - const [ _newValue, unit ] = extractNumbersAndUnits( markValue )[ 0 ] - const newValue = _newValue + let [ newValue, unit ] = extractNumbersAndUnits( markValue )[ 0 ] + + // If the attribute has no support for rem, and the + // preset units is rem, convert to px + if ( ( ! hasUnits || ( hasUnits && ! props.units.includes( 'rem' ) ) ) && unit === 'rem' ) { + newValue = `${ parseFloat( newValue ) * 16 }` + unit = 'px' + } // Update the unit. - dispatch( 'core/block-editor' ).__unstableMarkNextChangeAsNotPersistent() - setAttributes( { [ unitAttrName ]: unit } ) + if ( unit ) { + dispatch( 'core/block-editor' ).__unstableMarkNextChangeAsNotPersistent() + setAttributes( { [ unitAttrName ]: unit } ) + if ( props.onChangeUnit ) { + props.onChangeUnit( unit ) + } + } initialOnChange( newValue ) } @@ -890,7 +916,6 @@ FourRangeControl.defaultProps = { marks: undefined, allowCustom: true, - hasCSSVariableValue: false, } export default memo( FourRangeControl ) diff --git a/src/global-settings.php b/src/global-settings.php index 6dfa1813f2..e12013367f 100644 --- a/src/global-settings.php +++ b/src/global-settings.php @@ -144,6 +144,26 @@ public static function get_four_range_properties() { return Stackable_Global_Settings::create_global_schema( $four_range_type ); } + + /** + * This function defines a schema for a string four-range type and utilizes the + * `create_global_schema` function to generate the complete schema. + * + * @return array The generated schema for four-range type. + */ + public static function get_string_four_range_properties() { + $string_four_range_type = array( + 'type' => 'object', + 'properties' => array( + 'top' => array( 'type' => 'string', 'default' => '' ), + 'right' => array( 'type' => 'string', 'default' => '' ), + 'bottom' => array( 'type' => 'string', 'default' => '' ), + 'left' => array( 'type' => 'string', 'default' => '' ), + ) + ); + + return Stackable_Global_Settings::create_global_schema( $string_four_range_type ); + } /** * This function defines a schema for a string type and utilizes the @@ -1019,7 +1039,7 @@ public static function generate_global_block_layouts( $option_name, $settings_na $custom_property .= '-' . $hover_state; } - if ( is_string( $value ) ) { + if ( is_string( $value ) && ! is_numeric( $value ) ) { if ( strpos( $value, 'rgb' ) ) { // Convert rgba colors to hex alpha colors because // the function wp_style_engine_get_stylesheet_from_css_rules() doesn't allow css values to have '(' @@ -1050,7 +1070,10 @@ public static function generate_global_block_layouts( $option_name, $settings_na $bottom = isset( $value[ 'bottom' ] ) ? $value[ 'bottom' ] : $default_value[ 'bottom' ]; $left = isset( $value[ 'left' ] ) ? $value[ 'left' ] : $default_value[ 'left' ]; - $style = $top . $unit . ' ' . $right . $unit . ' ' . $bottom . $unit . ' ' . $left . $unit; + $style = Stackable_Global_Settings::append_unit_if_needed( $top, $unit ) . ' ' + . Stackable_Global_Settings::append_unit_if_needed( $right, $unit ) . ' ' + . Stackable_Global_Settings::append_unit_if_needed( $bottom, $unit ) . ' ' + . Stackable_Global_Settings::append_unit_if_needed( $left, $unit ); } else { $style = $value . $unit; } @@ -1100,6 +1123,14 @@ public static function generate_global_block_layouts( $option_name, $settings_na return $generated_css; } + public static function append_unit_if_needed( $value, $unit ) { + if ( is_string( $value ) && str_starts_with( trim( $value ), 'var(' ) ) { + return $value; + } + return $value . $unit; + } + + public static function extract_rgba($value) { $options = $value; $color = ''; diff --git a/src/plugins/global-settings/buttons-and-icons/index.js b/src/plugins/global-settings/buttons-and-icons/index.js index 00b117c9b2..776611352e 100644 --- a/src/plugins/global-settings/buttons-and-icons/index.js +++ b/src/plugins/global-settings/buttons-and-icons/index.js @@ -23,6 +23,7 @@ import { } from '../utils' import { BORDER_CONTROLS } from '~stackable/block-components' import { i18n } from 'stackable' +import { usePresetControls } from '~stackable/hooks' /** * WordPress dependencies @@ -54,6 +55,17 @@ addFilter( 'stackable.global-settings.inspector', 'stackable/global-buttons-and- saveTimeout ) + // Add additional presets for setting margins and paddings to None + const nonePreset = { + name: 'None', + size: '0rem', + slug: 'none', + } + const sizePresetMarks = usePresetControls( 'spacingSizes' ) + ?.getPresetMarks( { additionalPresets: [ nonePreset ] } ) || null + const gapPresetMarks = usePresetControls( 'spacingSizes' )?.getPresetMarks() || null + const borderRadiusPresetMarks = usePresetControls( 'borderRadius' )?.getPresetMarks() || null + return ( <> { output } @@ -112,6 +124,7 @@ addFilter( 'stackable.global-settings.inspector', 'stackable/global-buttons-and- onChange={ value => onChange( 'button-min-height', value, STATES.RESPONSIVE ) } hasTabletValue={ getHasDeviceValue( 'button-min-height', 'tablet' ) } hasMobileValue={ getHasDeviceValue( 'button-min-height', 'mobile' ) } + marks={ sizePresetMarks } /> onChange( 'button-column-gap', value, STATES.RESPONSIVE ) } hasTabletValue={ getHasDeviceValue( 'button-column-gap', 'tablet' ) } hasMobileValue={ getHasDeviceValue( 'button-column-gap', 'mobile' ) } + marks={ gapPresetMarks } /> onChange( 'button-row-gap', value, STATES.RESPONSIVE ) } hasTabletValue={ getHasDeviceValue( 'button-row-gap', 'tablet' ) } hasMobileValue={ getHasDeviceValue( 'button-row-gap', 'mobile' ) } + marks={ gapPresetMarks } /> @@ -294,6 +311,7 @@ addFilter( 'stackable.global-settings.inspector', 'stackable/global-buttons-and- title: __( 'Button padding', i18n ), description: __( 'Adjusts the space between the button text and button borders', i18n ), } } + marks={ sizePresetMarks } /> onChange( 'icon-list-row-gap', value, STATES.RESPONSIVE ) } hasTabletValue={ getHasDeviceValue( 'icon-list-row-gap', 'tablet' ) } hasMobileValue={ getHasDeviceValue( 'icon-list-row-gap', 'mobile' ) } + marks={ gapPresetMarks } /> array( 'schema' => array( 'properties' => array( - 'button-min-height' => $number_properties, - 'button-padding' => $four_range_properties, - 'icon-button-padding' => $four_range_properties, + 'button-min-height' => $string_properties, + 'button-padding' => $string_four_range_properties, + 'icon-button-padding' => $string_four_range_properties, 'button-border-style' => $string_properties, 'button-border-width' => $four_range_properties, 'button-ghost-border-width' => $four_range_properties, - 'button-border-radius' => $four_range_properties, + 'button-border-radius' => $string_four_range_properties, 'button-box-shadow' => $string_properties, 'button-icon-size' => $number_properties, - 'button-icon-gap' => $number_properties, - 'button-column-gap' => $number_properties, - 'button-row-gap' => $number_properties, + 'button-icon-gap' => $string_properties, + 'button-column-gap' => $string_properties, + 'button-row-gap' => $string_properties, 'icon-list-icon-size' => $number_properties, - 'icon-list-row-gap' => $number_properties, + 'icon-list-row-gap' => $string_properties, 'icon-list-icon-gap' => $number_properties, 'icon-list-indentation' => $number_properties, diff --git a/src/plugins/global-settings/spacing-and-borders/index.js b/src/plugins/global-settings/spacing-and-borders/index.js index 966d3d1eb0..552cc9ea38 100644 --- a/src/plugins/global-settings/spacing-and-borders/index.js +++ b/src/plugins/global-settings/spacing-and-borders/index.js @@ -23,7 +23,9 @@ import { } from '../utils' import { BORDER_CONTROLS, IMAGE_SHADOWS } from '~stackable/block-components' import { i18n } from 'stackable' -import { useDeviceType, useBlockLayoutDefaults } from '~stackable/hooks' +import { + useDeviceType, useBlockLayoutDefaults, usePresetControls, +} from '~stackable/hooks' /** * WordPress dependencies @@ -54,6 +56,16 @@ addFilter( 'stackable.global-settings.inspector', 'stackable/global-spacing-and- setDisplayHoverNotice, saveTimeout ) + // Add additional presets for setting margins and paddings to None + const nonePreset = { + name: 'None', + size: '0rem', + slug: 'none', + } + const sizePresetMarks = usePresetControls( 'spacingSizes' ) + ?.getPresetMarks( { additionalPresets: [ nonePreset ] } ) || null + const gapPresetMarks = usePresetControls( 'spacingSizes' )?.getPresetMarks() || null + const borderRadiusPresetMarks = usePresetControls( 'borderRadius' )?.getPresetMarks() || null return ( <> @@ -120,6 +132,7 @@ addFilter( 'stackable.global-settings.inspector', 'stackable/global-spacing-and- video: 'advanced-block-margin', description: __( 'Sets the block margin bottom, i.e. the space outside the block between the block border and the next block.', i18n ), } } + marks={ sizePresetMarks } /> @@ -159,6 +172,7 @@ addFilter( 'stackable.global-settings.inspector', 'stackable/global-spacing-and- video: 'column-gap', description: __( 'Sets the distance between two or more columns', i18n ), } } + marks={ sizePresetMarks } /> @@ -187,9 +202,9 @@ addFilter( 'stackable.global-settings.inspector', 'stackable/global-spacing-and- responsive="all" // hover="all" forceUpdateHoverState={ true } - min={ [ 0, 0, 0 ] } - sliderMax={ [ 200, 30, 100 ] } - units={ [ 'px', 'em', '%' ] } + min={ [ 0, 0, 0, 0 ] } + sliderMax={ [ 200, 30, 30, 100 ] } + units={ [ 'px', 'em', 'rem', '%' ] } unit={ getValue( 'block-background-padding', STATES.ALL_UNIT ) || 'px' } onChangeUnit={ value => onChange( 'block-background-padding', value, STATES.ALL_UNIT ) } top={ getValue( 'block-background-padding', STATES.ALL )?.top } @@ -204,6 +219,7 @@ addFilter( 'stackable.global-settings.inspector', 'stackable/global-spacing-and- video: 'inner-block-padding', description: __( 'Sets the block paddings, i.e the space between the inner columns and the block border', i18n ), } } + marks={ sizePresetMarks } /> onChange( 'container-padding', value, STATES.ALL_UNIT ) } top={ getValue( 'container-padding', STATES.ALL )?.top } @@ -291,7 +308,7 @@ addFilter( 'stackable.global-settings.inspector', 'stackable/global-spacing-and- video: 'inner-block-padding', description: __( 'Sets the block paddings, i.e the space between the inner columns and the block border', i18n ), } } - + marks={ sizePresetMarks } /> array( 'container-border-style' => $string_properties, 'container-border-width' => $four_range_properties, - 'container-border-radius' => $four_range_properties, + 'container-border-radius' => $string_four_range_properties, 'container-box-shadow' => $string_properties, - 'container-padding' => $four_range_properties, + 'container-padding' => $string_four_range_properties, 'block-background-border-style' => $string_properties, 'block-background-border-width' => $four_range_properties, - 'block-background-border-radius' => $four_range_properties, + 'block-background-border-radius' => $string_four_range_properties, 'block-background-box-shadow' => $string_properties, - 'block-background-padding' => $four_range_properties, + 'block-background-padding' => $string_four_range_properties, - 'block-margin-bottom' => $number_properties, + 'block-margin-bottom' => $string_properties, 'column-margin' => $number_properties, - 'columns-column-gap' => $number_properties, - 'columns-row-gap' => $number_properties, + 'columns-column-gap' => $string_properties, + 'columns-row-gap' => $string_properties, 'image-drop-shadow' => $string_properties, - 'image-border-radius' => $four_range_properties, + 'image-border-radius' => $string_four_range_properties, ) ) ), diff --git a/src/plugins/global-settings/utils/use-block-layout-editor-loader.js b/src/plugins/global-settings/utils/use-block-layout-editor-loader.js index 409dba75dd..6320229663 100644 --- a/src/plugins/global-settings/utils/use-block-layout-editor-loader.js +++ b/src/plugins/global-settings/utils/use-block-layout-editor-loader.js @@ -15,6 +15,10 @@ import { useEffect, useState } from '@wordpress/element' import { compact } from 'lodash' import { useBlockHoverState, useBlockLayoutDefaults } from '~stackable/hooks' +function appendUnitIfNeeded( value, unit ) { + return ( typeof value === 'string' && value.trim().startsWith( 'var' ) ) ? value : `${ value }${ unit }` +} + const renderGlobalStyles = ( blockLayouts, blockLayoutDefaults, @@ -51,7 +55,7 @@ const renderGlobalStyles = ( } let style = '' - if ( typeof value === 'string' ) { + if ( typeof value === 'string' && isNaN( Number( value ) ) ) { style = `${ property }: ${ value };` } else if ( typeof value === 'object' ) { let defaultValue = getDefault( blockLayoutDefaults, _property, device ) @@ -72,7 +76,7 @@ const renderGlobalStyles = ( const bottom = value.bottom !== undefined ? value.bottom : defaultValue.bottom const left = value.left !== undefined ? value.left : defaultValue.left - style = `${ property }: ${ top }${ unit } ${ right }${ unit } ${ bottom }${ unit } ${ left }${ unit };` + style = `${ property }: ${ appendUnitIfNeeded( top, unit ) } ${ appendUnitIfNeeded( right, unit ) } ${ appendUnitIfNeeded( bottom, unit ) } ${ appendUnitIfNeeded( left, unit ) };` } else { style = `${ property }: ${ value }${ unit };` } From feb3274193dc43c893b88dd39861a3a44de6eb43 Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Thu, 15 May 2025 17:16:50 +0800 Subject: [PATCH 65/99] fix: typography font size steps --- src/components/font-size-control/index.js | 4 ++-- src/global-settings.php | 6 +++--- .../typography/typography-picker.js | 16 +++++++++++++++- src/util/typography/styles.js | 14 +++++++++++--- 4 files changed, 31 insertions(+), 9 deletions(-) diff --git a/src/components/font-size-control/index.js b/src/components/font-size-control/index.js index 415578e748..2c7649a0e4 100644 --- a/src/components/font-size-control/index.js +++ b/src/components/font-size-control/index.js @@ -41,9 +41,9 @@ const FontSizeControl = props => { // Change font-size so as not to surprise the user. if ( props.value !== '' ) { if ( value === 'em' || value === 'rem' ) { - props.onChange( pxToEm( props.value ) ) + props.onChange( String( pxToEm( props.value ) ) ) } else if ( value === 'px' ) { - props.onChange( emToPx( props.value ) ) + props.onChange( String( emToPx( props.value ) ) ) } } diff --git a/src/global-settings.php b/src/global-settings.php index e12013367f..f2571a3133 100644 --- a/src/global-settings.php +++ b/src/global-settings.php @@ -299,13 +299,13 @@ public function register_global_settings() { 'type' => 'string', ), 'fontSize' => array( - 'type' => 'number', + 'type' => 'string', ), 'tabletFontSize' => array( - 'type' => 'number', + 'type' => 'string', ), 'mobileFontSize' => array( - 'type' => 'number', + 'type' => 'string', ), 'fontSizeUnit' => array( 'type' => 'string', diff --git a/src/plugins/global-settings/typography/typography-picker.js b/src/plugins/global-settings/typography/typography-picker.js index bf949662ef..2eeaeaa8de 100644 --- a/src/plugins/global-settings/typography/typography-picker.js +++ b/src/plugins/global-settings/typography/typography-picker.js @@ -9,6 +9,7 @@ import { i18n } from 'stackable' import { upperFirst, omit } from 'lodash' import classnames from 'classnames' import { generateStyles } from '~stackable/block-components' +import { usePresetControls } from '~stackable/hooks' /** * WordPress dependencies @@ -45,9 +46,22 @@ const TypographyPicker = props => { 'ugb-global-settings-typography-control--with-description': createDescription( value ), } ) + const useTypographyAsPresets = useSelect( select => + select( 'stackable/global-preset-controls.custom' )?.getUseTypographyAsPresets() ?? false + ) + + const presetMarks = usePresetControls( 'fontSizes' ) + ?.getPresetMarks( { customOnly: useTypographyAsPresets } ) || null + return ( { + return typeof value === 'string' && value.startsWith( 'var' ) +} + export const createTypographyStyles = ( attrNameTemplate = '%s', screen = 'desktop', blockAttributes = {}, options = {} ) => { const getAttrName = attrName => camelCase( sprintf( attrNameTemplate, attrName ) ) const getValue = __getValue( blockAttributes, getAttrName, '' ) @@ -34,10 +38,14 @@ export const createTypographyStyles = ( attrNameTemplate = '%s', screen = 'deskt const tabletFontSize = getValue( 'TabletFontSize' ) const mobileFontSize = getValue( 'MobileFontSize' ) + const desktopFontSizeUnit = isCSSVarValue( desktopFontSize ) ? '' : getValue( 'FontSizeUnit' ) || 'px' + const tabletFontSizeUnit = isCSSVarValue( tabletFontSize ) ? '' : getValue( 'FontSizeUnit' ) || 'px' + const mobileFontSizeUnit = isCSSVarValue( mobileFontSize ) ? '' : getValue( 'FontSizeUnit' ) || 'px' + if ( screen !== 'tablet' && screen !== 'mobile' ) { // Desktop. styles = { fontFamily: getValue( 'FontFamily' ) !== '' ? getFontFamily( getValue( 'FontFamily' ) ) : undefined, - fontSize: desktopFontSize !== '' ? appendImportant( `${ desktopFontSize }${ getValue( 'FontSizeUnit' ) || 'px' }`, importantSize ) : undefined, + fontSize: desktopFontSize !== '' ? appendImportant( `${ desktopFontSize }${ desktopFontSizeUnit }`, importantSize ) : undefined, fontWeight: getValue( 'FontWeight' ) !== '' ? getValue( 'FontWeight' ) : undefined, textTransform: getValue( 'TextTransform' ) !== '' ? getValue( 'TextTransform' ) : undefined, letterSpacing: getValue( 'LetterSpacing' ) !== '' ? `${ getValue( 'LetterSpacing' ) }px` : undefined, @@ -56,7 +64,7 @@ export const createTypographyStyles = ( attrNameTemplate = '%s', screen = 'deskt } } if ( tabletFontSize ) { - styles.fontSize = getValue( 'TabletFontSize', `%s${ getValue( 'TabletFontSizeUnit' ) || 'px' }` ) + styles.fontSize = getValue( 'TabletFontSize', `%s${ tabletFontSizeUnit }` ) } } else { // Mobile. styles = { @@ -79,7 +87,7 @@ export const createTypographyStyles = ( attrNameTemplate = '%s', screen = 'deskt } } if ( mobileFontSize ) { - styles.fontSize = getValue( 'MobileFontSize', `%s${ getValue( 'MobileFontSizeUnit' ) || 'px' }` ) + styles.fontSize = getValue( 'MobileFontSize', `%s${ mobileFontSizeUnit }` ) } } From 7352dd2c2c69e32d9cd38bc752b177c31b53fcbe Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Thu, 15 May 2025 17:19:33 +0800 Subject: [PATCH 66/99] fix: sync mark mode --- src/components/advanced-range-control/index.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/components/advanced-range-control/index.js b/src/components/advanced-range-control/index.js index 33f1316ed1..136ae6bf21 100644 --- a/src/components/advanced-range-control/index.js +++ b/src/components/advanced-range-control/index.js @@ -130,10 +130,6 @@ const AdvancedRangeControl = props => { // On reset, allow overriding the value. if ( newValue === '' ) { - // Reset should also change from mark mode - if ( isMarkMode ) { - setIsMarkMode( false ) - } const overrideValue = props.onOverrideReset?.() if ( typeof overrideValue !== 'undefined' ) { newValue = overrideValue From b596683628c265a3f48b8fa41ef2a9977d8415c1 Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Thu, 15 May 2025 18:38:39 +0800 Subject: [PATCH 67/99] fix: sync state when succeeding call to change styles --- src/components/font-size-control/index.js | 2 +- .../global-settings/typography/index.js | 51 +++++++++---------- 2 files changed, 24 insertions(+), 29 deletions(-) diff --git a/src/components/font-size-control/index.js b/src/components/font-size-control/index.js index 2c7649a0e4..49035e6351 100644 --- a/src/components/font-size-control/index.js +++ b/src/components/font-size-control/index.js @@ -39,7 +39,7 @@ const FontSizeControl = props => { placeholder={ passedPlaceholder } onChangeUnit={ value => { // Change font-size so as not to surprise the user. - if ( props.value !== '' ) { + if ( props.value !== '' && ! isNaN( Number( value ) ) ) { if ( value === 'em' || value === 'rem' ) { props.onChange( String( pxToEm( props.value ) ) ) } else if ( value === 'px' ) { diff --git a/src/plugins/global-settings/typography/index.js b/src/plugins/global-settings/typography/index.js index bbaa0c6110..fc6fa6f69e 100644 --- a/src/plugins/global-settings/typography/index.js +++ b/src/plugins/global-settings/typography/index.js @@ -293,40 +293,35 @@ addFilter( 'stackable.global-settings.inspector', 'stackable/global-typography', } const changeStyles = _typography => { - const typography = cloneDeep( _typography ) - const newSettings = { ...typographySettings } + setTypographySettings( prevTypographySettings => { + const typography = cloneDeep( _typography ) + const newSettings = { ...prevTypographySettings } - Object.entries( typography ).forEach( ( [ selector, styles ] ) => { - if ( ! selector || typeof styles !== 'object' ) { - return - } + Object.entries( typography ).forEach( ( [ selector, styles ] ) => { + if ( ! selector || typeof styles !== 'object' ) { + return + } - // Merge the new styles with the previous, while overwritting similar styles. - // This allow adding styles without removing the previous ones. - // Check if the object is empty, used for resetting the whole setting. - if ( Object.keys( styles ).length !== 0 ) { - styles = { ...newSettings[ selector ], ...styles } - } - /** - * Delete the object keys with empty strings. - * Otherwise, the API will throw an error code 400 - * because of incompatible schema type. - */ - Object.keys( styles ).forEach( key => { - if ( styles[ key ] === '' ) { - delete styles[ key ] + if ( Object.keys( styles ).length !== 0 ) { + styles = { ...newSettings[ selector ], ...styles } } - } ) - newSettings[ selector ] = styles - } ) + Object.keys( styles ).forEach( key => { + if ( styles[ key ] === '' ) { + delete styles[ key ] + } + } ) - // Update the global styles immediately when reset font size is triggered. - if ( Object.values( typography ).some( styles => styles && ! styles.fontSize ) ) { - doAction( 'stackable.global-settings.typography-update-global-styles', newSettings ) - } + newSettings[ selector ] = styles + } ) - updateTypography( newSettings ) + // Update the global styles immediately when reset font size is triggered. + if ( Object.values( typography ).some( styles => styles && ! styles.fontSize ) ) { + doAction( 'stackable.global-settings.typography-update-global-styles', newSettings ) + } + + return newSettings + } ) } const resetStyles = selector => { From 02de0dc0c3b58a69a83b2cac9e4c7859e85f0d02 Mon Sep 17 00:00:00 2001 From: "bfintal@gmail.com" <> Date: Thu, 15 May 2025 20:51:07 +0800 Subject: [PATCH 68/99] fixed value preview --- .../global-settings/typography/typography-picker.js | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/plugins/global-settings/typography/typography-picker.js b/src/plugins/global-settings/typography/typography-picker.js index 2eeaeaa8de..3e8779d681 100644 --- a/src/plugins/global-settings/typography/typography-picker.js +++ b/src/plugins/global-settings/typography/typography-picker.js @@ -6,7 +6,9 @@ import { createTypographyStyles, getFontFamilyLabel, loadGoogleFont, } from '~stackable/util' import { i18n } from 'stackable' -import { upperFirst, omit } from 'lodash' +import { + upperFirst, omit, startCase, last, +} from 'lodash' import classnames from 'classnames' import { generateStyles } from '~stackable/block-components' import { usePresetControls } from '~stackable/hooks' @@ -165,7 +167,14 @@ const createDescription = ( styleObject, device = 'desktop' ) => { description.push( upperFirst( styleObject.textTransform ) ) } - return description.join( ', ' ) + // If a css custom property, get just the name names + return description.map( value => { + if ( value.includes( 'var(' ) ) { + const propName = value.match( /var\(([^\),]*)/ )?.[ 1 ] + return startCase( last( propName.split( '--' ) ) ) + } + return value + } ).join( ', ' ) } const TypographyPreview = props => { From 43159bbff7989a1c22036a3ebf4538e51f140272 Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Mon, 19 May 2025 15:42:49 +0800 Subject: [PATCH 69/99] fix: error in getting css var name --- src/util/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/index.js b/src/util/index.js index f060aaa231..a196c3bcf0 100644 --- a/src/util/index.js +++ b/src/util/index.js @@ -420,6 +420,6 @@ export const extractNumbersAndUnits = value => { // Return only the CSS variable name given a CSS variable export const getCSSVarName = value => { - const match = value.match( /var\(\s*([^,)\s]+)/ ) + const match = value?.match( /var\(\s*([^,)\s]+)/ ) return match ? match[ 1 ] : null } From 3b6e30e52f3bfaf0f17d6991159cc13783e7f751 Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Mon, 19 May 2025 22:14:42 +0800 Subject: [PATCH 70/99] feat: add use size preset by default option --- .../advanced-range-control/index.js | 16 +++--- src/components/four-range-control/index.js | 15 +++--- .../global-settings/preset-controls/index.php | 50 +++++++++++++++++++ src/welcome/admin.js | 14 +++++- 4 files changed, 81 insertions(+), 14 deletions(-) diff --git a/src/components/advanced-range-control/index.js b/src/components/advanced-range-control/index.js index 136ae6bf21..d941127fa0 100644 --- a/src/components/advanced-range-control/index.js +++ b/src/components/advanced-range-control/index.js @@ -6,6 +6,10 @@ import { useControlHandlers } from '../base-control2/hooks' import AdvancedControl, { extractControlProps } from '../base-control2' import DynamicContentControl, { useDynamicContentControlProps } from '../dynamic-content-control' import { ResetButton } from '../base-control2/reset-button' +/** + * External dependencies + */ +import { isEqual } from 'lodash' import { useAttributeName, useBlockAttributesContext, @@ -14,11 +18,7 @@ import { useDeviceType, } from '~stackable/hooks' import { extractNumbersAndUnits, getCSSVarName } from '~stackable/util' - -/** - * External dependencies - */ -import { isEqual } from 'lodash' +import { settings as stackableSettings } from 'stackable' /** * WordPress dependencies @@ -57,6 +57,8 @@ const AdvancedRangeControl = props => { ? ( props.unit || props.units?.[ 0 ] || 'px' ) : ( unitAttribute || '' ) + const isMarkModeDefault = !! ( stackableSettings?.stackable_use_size_presets_by_default ?? true ) + // Change the min, max & step values depending on the unit used. if ( hasUnits ) { const i = props.units.indexOf( unit ) < 0 ? 0 : props.units.indexOf( unit ) @@ -109,7 +111,8 @@ const AdvancedRangeControl = props => { // Is value at first render the same as a step value? If so, do mark mode // at the start, or show custom - let isMarkValue = !! props.marks + // If no initial value, use the given default from the settings + let isMarkValue = !! props.marks && isMarkModeDefault if ( props.marks && derivedValue ) { // Check if the current value exists in the marks only by their CSS variable name // to match in case the fallback size changes. @@ -285,6 +288,7 @@ AdvancedRangeControl.defaultProps = { marks: undefined, // [{ value: 'var(--stk-preset-font-size-small', name: 'S' }] allowCustom: true, isCustomPreset: false, + isMarkModeDefault: true, } export default memo( AdvancedRangeControl, isEqual ) diff --git a/src/components/four-range-control/index.js b/src/components/four-range-control/index.js index 492a9bd115..1cb06df5e4 100644 --- a/src/components/four-range-control/index.js +++ b/src/components/four-range-control/index.js @@ -35,7 +35,7 @@ import { dispatch } from '@wordpress/data' */ import { isEqual } from 'lodash' import classnames from 'classnames' -import { i18n } from 'stackable' +import { i18n, settings as stackableSettings } from 'stackable' import { Button } from '~stackable/components' import { useAttributeName, @@ -122,6 +122,8 @@ const FourRangeControl = memo( props => { } } ) + const isMarkModeDefault = !! ( stackableSettings?.stackable_use_size_presets_by_default ?? true ) + // Change the min, max & step values depending on the unit used. if ( hasUnits ) { const i = props.units.indexOf( unit ) < 0 ? 0 : props.units.indexOf( unit ) @@ -187,12 +189,13 @@ const FourRangeControl = memo( props => { // Is value at first render the same as a step value? If so, do mark mode // at the start, or show custom + // If no initial value, use the given default from the settings const isMarkValue = { - first: !! props.marks, - top: !! props.marks, - right: !! props.marks, - bottom: !! props.marks, - left: !! props.marks, + first: !! props.marks && isMarkModeDefault, + top: !! props.marks && isMarkModeDefault, + right: !! props.marks && isMarkModeDefault, + bottom: !! props.marks && isMarkModeDefault, + left: !! props.marks && isMarkModeDefault, } if ( props.marks && firstValue ) { // Check if the current value exists in the marks only by their CSS variable name diff --git a/src/plugins/global-settings/preset-controls/index.php b/src/plugins/global-settings/preset-controls/index.php index 682ea3baa9..2e16f04258 100644 --- a/src/plugins/global-settings/preset-controls/index.php +++ b/src/plugins/global-settings/preset-controls/index.php @@ -42,10 +42,54 @@ class Stackable_Size_And_Spacing_Preset_Controls { * Initialize */ function __construct() { + add_action( 'register_stackable_global_settings', array( $this, 'register_use_size_presets_by_default' ) ); + add_action( 'stackable_early_version_upgraded', array( $this, 'use_size_presets_by_default_set_default' ), 10, 2 ); + add_filter( 'stackable_js_settings', array( $this, 'add_setting' ) ); + add_filter( 'stackable_inline_styles_nodep', array( $this, 'add_preset_controls_styles' ) ); add_filter( 'stackable_inline_editor_styles', array( $this, 'add_preset_controls_styles' ) ); } + // Register the setting for using presets by default + function register_use_size_presets_by_default() { + register_setting( + 'stackable_global_settings', + 'stackable_use_size_presets_by_default', + array( + 'type' => 'boolean', + 'description' => __( 'If enabled, range controls will be on preset mode by default', STACKABLE_I18N ), + 'sanitize_callback' => 'sanitize_text_field', + 'show_in_rest' => true, + 'default' => true, + ) + ); + } + + /** + * When upgrading to v3.16.0 and above, set option to false. + * If new installation, set option to true. + * + * @since 3.16.0 + */ + public function use_size_presets_by_default_set_default( $old_version, $new_version ) { + if ( ! empty( $old_version ) && version_compare( $old_version, "3.16.0", "<" ) ) { + if ( ! get_option( 'stackable_use_size_presets_by_default' ) ) { + update_option( 'stackable_use_size_presets_by_default', '' ); + } + } + } + + // Make the setting available in the editor + public function add_setting( $settings ) { + $settings['stackable_use_size_presets_by_default'] = get_option( 'stackable_use_size_presets_by_default' ); + return $settings; + } + + /** + * Loads the different preset values. + * + * @return void + */ public function load_presets() { $this->custom_presets = get_option( 'stackable_global_custom_preset_controls' ); $this->theme_presets = WP_Theme_JSON_Resolver::get_theme_data()->get_settings(); @@ -57,6 +101,12 @@ public static function sanitize_array_setting( $input ) { return ! is_array( $input ) ? array( array() ) : $input; } + /** + * Loads and decodes a JSON file, returning the settings array if available. + * + * @param string $json_path Absolute path to the JSON file. + * @return array The settings array from the decoded JSON file, or an empty array. + */ private function load_json_file( $json_path ) { if ( file_exists( $json_path ) ) { $decoded_data = wp_json_file_decode( $json_path, [ diff --git a/src/welcome/admin.js b/src/welcome/admin.js index a428c661f0..0f6e968f4b 100644 --- a/src/welcome/admin.js +++ b/src/welcome/admin.js @@ -77,12 +77,12 @@ const SEARCH_TREE = [ children: [ __( 'Nested Block Width', i18n ), __( 'Nested Wide Block Width', i18n ), - __( 'Stackable Text as Default Block', i18n ), ], }, { id: 'editor', children: [ + __( 'Stackable Text as Default Block', i18n ), __( 'Design Library', i18n ), __( 'Stackable Settings', i18n ), __( 'Block Linking (Beta)', i18n ), @@ -155,6 +155,7 @@ const SEARCH_TREE = [ id: 'global-settings', children: [ __( 'Force Typography Styles', i18n ), + __( 'Use Size Presets by Default', i18n ), ], }, ], @@ -672,7 +673,7 @@ const EditorSettings = props => {

    { __( 'You can customize some of the features and behavior of Stackable in the editor here.' ) }

    { handleSettingsChange( { stackable_enable_text_default_block: value } ) // eslint-disable-line camelcase @@ -1162,6 +1163,15 @@ const GlobalSettings = props => { disabled={ __( 'Not forced', i18n ) } enabled={ __( 'Force styles', i18n ) } /> + { + props.handleSettingsChange( { stackable_use_size_presets_by_default: value } ) // eslint-disable-line camelcase + } } + help={ __( 'If enabled, range controls will be on preset mode by default.', i18n ) } + /> } From c9287935822805cc5f875bff0fba2464c33e0139 Mon Sep 17 00:00:00 2001 From: "bfintal@gmail.com" <> Date: Sat, 24 May 2025 23:08:30 +0800 Subject: [PATCH 71/99] added more descriptive text --- src/welcome/admin.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/welcome/admin.js b/src/welcome/admin.js index 0f6e968f4b..aa5db65b36 100644 --- a/src/welcome/admin.js +++ b/src/welcome/admin.js @@ -1171,6 +1171,8 @@ const GlobalSettings = props => { props.handleSettingsChange( { stackable_use_size_presets_by_default: value } ) // eslint-disable-line camelcase } } help={ __( 'If enabled, range controls will be on preset mode by default.', i18n ) } + disabled={ __( 'Use custom values', i18n ) } + enabled={ __( 'Use presets', i18n ) } /> } From 12911644761c474646e6fe008ca4107b99792214 Mon Sep 17 00:00:00 2001 From: "bfintal@gmail.com" <> Date: Sat, 24 May 2025 23:14:14 +0800 Subject: [PATCH 72/99] temporarily skip since the test breaks now --- e2e/tests/global-settings.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e/tests/global-settings.spec.ts b/e2e/tests/global-settings.spec.ts index 9f59b43091..af798e946f 100644 --- a/e2e/tests/global-settings.spec.ts +++ b/e2e/tests/global-settings.spec.ts @@ -78,7 +78,7 @@ test.describe( 'Global Settings', () => { expect( _count ).toBeLessThan( count ) } ) - test( 'Global Typography Styles should be applied when adding a heading', async ( { + test.skip( 'Global Typography Styles should be applied when adding a heading', async ( { page, editor, } ) => { From 9e2ee7d4eb88589a8f925bf84a2b47070c105701 Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Sun, 25 May 2025 10:42:38 +0800 Subject: [PATCH 73/99] fix: two-way value conversion between preset and custom mode --- src/components/advanced-range-control/index.js | 11 +++++++++-- src/components/four-range-control/index.js | 11 +++++++++-- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/components/advanced-range-control/index.js b/src/components/advanced-range-control/index.js index d941127fa0..1b1b404f7f 100644 --- a/src/components/advanced-range-control/index.js +++ b/src/components/advanced-range-control/index.js @@ -192,8 +192,15 @@ const AdvancedRangeControl = props => { let rangeOnChange = _onChange if ( isMarkMode ) { rangeValue = props.marks.findIndex( mark => { - const [ _value, _unit ] = extractNumbersAndUnits( mark.value )[ 0 ] - return _value === derivedValue + let _unit, _value + // If the derivedValue is a CSS variable, compare with mark's CSS variable. + // Otherwise, the derivedValue is custom, so compare with raw size and units + if ( typeof derivedValue === 'string' && derivedValue.startsWith( 'var' ) ) { + [ _value, _unit ] = extractNumbersAndUnits( mark.value )[ 0 ] + } else { + [ _value, _unit ] = extractNumbersAndUnits( mark.size )[ 0 ] + } + return _value === derivedValue && ( _unit === '' || _unit === unit ) } ) rangeOnChange = ( value, property = 'value' ) => { if ( value === '' ) { diff --git a/src/components/four-range-control/index.js b/src/components/four-range-control/index.js index 1cb06df5e4..06d3a3c903 100644 --- a/src/components/four-range-control/index.js +++ b/src/components/four-range-control/index.js @@ -349,8 +349,15 @@ const FourRangeControl = memo( props => { let rangeOnChange = initialOnChange if ( props.marks && isMarkMode ) { rangeValue = props.marks.findIndex( mark => { - const [ _value, _unit ] = extractNumbersAndUnits( mark.value )[ 0 ] - return _value === initialValue + let _unit, _value + // If the initialValue is a CSS variable, compare with mark's CSS variable. + // Otherwise, the initialValue is custom, so compare with raw size and units + if ( typeof initialValue === 'string' && initialValue.startsWith( 'var' ) ) { + [ _value, _unit ] = extractNumbersAndUnits( mark.value )[ 0 ] + } else { + [ _value, _unit ] = extractNumbersAndUnits( mark.size )[ 0 ] + } + return _value === initialValue && ( _unit === '' || _unit === unit ) } ) rangeOnChange = ( value, property = 'value' ) => { if ( value === '' ) { From 523668a843981ae35ac29fe5e9b22e55b4ef61ca Mon Sep 17 00:00:00 2001 From: "bfintal@gmail.com" <> Date: Sun, 25 May 2025 11:44:05 +0800 Subject: [PATCH 74/99] version bump to 3.16.0 for the default option to kick in --- plugin.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin.php b/plugin.php index 8ec5789ca3..dbac78389d 100644 --- a/plugin.php +++ b/plugin.php @@ -6,7 +6,7 @@ * Author: Gambit Technologies, Inc * Author URI: http://gambit.ph * Text Domain: stackable-ultimate-gutenberg-blocks - * Version: 3.15.3 + * Version: 3.16.0 * * @package Stackable */ From 85c3c9d3e77551911b37744402c18c356733b31e Mon Sep 17 00:00:00 2001 From: "bfintal@gmail.com" <> Date: Sun, 25 May 2025 11:51:02 +0800 Subject: [PATCH 75/99] version bump to 3.16.0 for the default option to kick in --- plugin.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin.php b/plugin.php index dbac78389d..2bacde1da5 100644 --- a/plugin.php +++ b/plugin.php @@ -24,7 +24,7 @@ defined( 'STACKABLE_SHOW_PRO_NOTICES' ) || define( 'STACKABLE_SHOW_PRO_NOTICES', true ); defined( 'STACKABLE_BUILD' ) || define( 'STACKABLE_BUILD', 'free' ); -defined( 'STACKABLE_VERSION' ) || define( 'STACKABLE_VERSION', '3.15.3' ); +defined( 'STACKABLE_VERSION' ) || define( 'STACKABLE_VERSION', '3.16.0' ); defined( 'STACKABLE_FILE' ) || define( 'STACKABLE_FILE', __FILE__ ); defined( 'STACKABLE_I18N' ) || define( 'STACKABLE_I18N', 'stackable-ultimate-gutenberg-blocks' ); // Plugin slug. defined( 'STACKABLE_DESIGN_LIBRARY_URL' ) || define( 'STACKABLE_DESIGN_LIBRARY_URL', 'https://storage.googleapis.com/stackable-plugin-assets' ); // Design Library CDN URL From 71766f648a1002bd4534d5712d343787899b2d2f Mon Sep 17 00:00:00 2001 From: "bfintal@gmail.com" <> Date: Sun, 25 May 2025 12:13:44 +0800 Subject: [PATCH 76/99] prevent errors if upgrading and value is a number --- src/util/index.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/util/index.js b/src/util/index.js index a196c3bcf0..1cceafb327 100644 --- a/src/util/index.js +++ b/src/util/index.js @@ -420,6 +420,9 @@ export const extractNumbersAndUnits = value => { // Return only the CSS variable name given a CSS variable export const getCSSVarName = value => { + if ( typeof value !== 'string' ) { + return null + } const match = value?.match( /var\(\s*([^,)\s]+)/ ) return match ? match[ 1 ] : null } From d45d9cd4cbf7c279b5cf5de355868cf05c2b12ac Mon Sep 17 00:00:00 2001 From: "bfintal@gmail.com" <> Date: Sun, 25 May 2025 12:14:12 +0800 Subject: [PATCH 77/99] optimized to prevent repetitive calls --- src/components/advanced-range-control/index.js | 3 ++- src/components/four-range-control/index.js | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/components/advanced-range-control/index.js b/src/components/advanced-range-control/index.js index 1b1b404f7f..33c35878b9 100644 --- a/src/components/advanced-range-control/index.js +++ b/src/components/advanced-range-control/index.js @@ -116,7 +116,8 @@ const AdvancedRangeControl = props => { if ( props.marks && derivedValue ) { // Check if the current value exists in the marks only by their CSS variable name // to match in case the fallback size changes. - const matchedMark = props.marks.find( mark => getCSSVarName( mark.value ) === getCSSVarName( derivedValue ) ) + const derivedValueCssVarName = getCSSVarName( derivedValue ) + const matchedMark = props.marks.find( mark => getCSSVarName( mark.value ) === derivedValueCssVarName ) isMarkValue = !! matchedMark if ( matchedMark ) { derivedValue = matchedMark.value diff --git a/src/components/four-range-control/index.js b/src/components/four-range-control/index.js index 06d3a3c903..cd63cef175 100644 --- a/src/components/four-range-control/index.js +++ b/src/components/four-range-control/index.js @@ -200,14 +200,16 @@ const FourRangeControl = memo( props => { if ( props.marks && firstValue ) { // Check if the current value exists in the marks only by their CSS variable name // to match in case the fallback size changes. - const firstMatchedMark = props.marks.find( mark => getCSSVarName( mark.value ) === getCSSVarName( firstValue ) ) + const firstValueCssVarName = getCSSVarName( firstValue ) + const firstMatchedMark = props.marks.find( mark => getCSSVarName( mark.value ) === firstValueCssVarName ) isMarkValue.first = !! firstMatchedMark if ( firstMatchedMark ) { firstValue = firstMatchedMark.value } [ 'top', 'right', 'bottom', 'left' ].forEach( side => { - const matchedMark = props.marks.find( mark => getCSSVarName( mark.value ) === getCSSVarName( value[ side ] ) ) + const sideCssVarName = getCSSVarName( value[ side ] ) + const matchedMark = props.marks.find( mark => getCSSVarName( mark.value ) === sideCssVarName ) isMarkValue[ side ] = !! matchedMark if ( matchedMark ) { value[ side ] = matchedMark.value From d8a2699b242f5ac53016b0b99001868efb308777 Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Sun, 25 May 2025 14:22:28 +0800 Subject: [PATCH 78/99] fix: update markmode when changing device type --- .../advanced-range-control/index.js | 27 +++++--- src/components/four-range-control/index.js | 62 ++++++++++--------- 2 files changed, 51 insertions(+), 38 deletions(-) diff --git a/src/components/advanced-range-control/index.js b/src/components/advanced-range-control/index.js index 33c35878b9..4237a3e07e 100644 --- a/src/components/advanced-range-control/index.js +++ b/src/components/advanced-range-control/index.js @@ -23,7 +23,9 @@ import { settings as stackableSettings } from 'stackable' /** * WordPress dependencies */ -import { memo, useState } from '@wordpress/element' +import { + memo, useState, useEffect, +} from '@wordpress/element' import { Button } from '@wordpress/components' import { settings } from '@wordpress/icons' import { dispatch } from '@wordpress/data' @@ -112,18 +114,23 @@ const AdvancedRangeControl = props => { // Is value at first render the same as a step value? If so, do mark mode // at the start, or show custom // If no initial value, use the given default from the settings - let isMarkValue = !! props.marks && isMarkModeDefault - if ( props.marks && derivedValue ) { + const [ isMarkMode, setIsMarkMode ] = useState( false ) + + // Set the markMode when at first render and when device type changes + useEffect( () => { + let isMarkValue = !! props.marks && isMarkModeDefault + if ( props.marks && derivedValue ) { // Check if the current value exists in the marks only by their CSS variable name // to match in case the fallback size changes. - const derivedValueCssVarName = getCSSVarName( derivedValue ) - const matchedMark = props.marks.find( mark => getCSSVarName( mark.value ) === derivedValueCssVarName ) - isMarkValue = !! matchedMark - if ( matchedMark ) { - derivedValue = matchedMark.value + const derivedValueCssVarName = getCSSVarName( derivedValue ) + const matchedMark = props.marks.find( mark => getCSSVarName( mark.value ) === derivedValueCssVarName ) + isMarkValue = !! matchedMark + if ( matchedMark ) { + derivedValue = matchedMark.value + } } - } - const [ isMarkMode, setIsMarkMode ] = useState( isMarkValue ) + setIsMarkMode( isMarkValue ) + }, [ deviceType ] ) // If this supports dynamic content, the value should be saved as a String. // Similar if using marks to accomodate CSS variable diff --git a/src/components/four-range-control/index.js b/src/components/four-range-control/index.js index cd63cef175..6bb260f255 100644 --- a/src/components/four-range-control/index.js +++ b/src/components/four-range-control/index.js @@ -25,7 +25,7 @@ import { useControlHandlers } from '../base-control2/hooks' import { Tooltip } from '@wordpress/components' import { __ } from '@wordpress/i18n' import { - Fragment, useState, memo, + Fragment, useState, memo, useEffect, } from '@wordpress/element' import { settings } from '@wordpress/icons' import { dispatch } from '@wordpress/data' @@ -187,36 +187,42 @@ const FourRangeControl = memo( props => { : props.enableBottom ? { desktop: _valueDesktop?.bottom, tablet: _valueTablet?.bottom } : { desktop: _valueDesktop?.left, tablet: _valueTablet?.left } - // Is value at first render the same as a step value? If so, do mark mode - // at the start, or show custom - // If no initial value, use the given default from the settings - const isMarkValue = { - first: !! props.marks && isMarkModeDefault, - top: !! props.marks && isMarkModeDefault, - right: !! props.marks && isMarkModeDefault, - bottom: !! props.marks && isMarkModeDefault, - left: !! props.marks && isMarkModeDefault, - } - if ( props.marks && firstValue ) { - // Check if the current value exists in the marks only by their CSS variable name - // to match in case the fallback size changes. - const firstValueCssVarName = getCSSVarName( firstValue ) - const firstMatchedMark = props.marks.find( mark => getCSSVarName( mark.value ) === firstValueCssVarName ) - isMarkValue.first = !! firstMatchedMark - if ( firstMatchedMark ) { - firstValue = firstMatchedMark.value + const [ isFourMarkMode, setIsFourMarkMode ] = useState( false ) + + // Set the markMode when at first render and when device type changes + useEffect( () => { + // Is value at first render the same as a step value? If so, do mark mode + // at the start, or show custom + // If no initial value, use the given default from the settings + const isMarkValue = { + first: !! props.marks && isMarkModeDefault, + top: !! props.marks && isMarkModeDefault, + right: !! props.marks && isMarkModeDefault, + bottom: !! props.marks && isMarkModeDefault, + left: !! props.marks && isMarkModeDefault, } - [ 'top', 'right', 'bottom', 'left' ].forEach( side => { - const sideCssVarName = getCSSVarName( value[ side ] ) - const matchedMark = props.marks.find( mark => getCSSVarName( mark.value ) === sideCssVarName ) - isMarkValue[ side ] = !! matchedMark - if ( matchedMark ) { - value[ side ] = matchedMark.value + if ( props.marks && firstValue ) { + // Check if the current value exists in the marks only by their CSS variable name + // to match in case the fallback size changes. + const firstValueCssVarName = getCSSVarName( firstValue ) + const firstMatchedMark = props.marks.find( mark => getCSSVarName( mark.value ) === firstValueCssVarName ) + isMarkValue.first = !! firstMatchedMark + if ( firstMatchedMark ) { + firstValue = firstMatchedMark.value } - } ) - } - const [ isFourMarkMode, setIsFourMarkMode ] = useState( isMarkValue ) + + [ 'top', 'right', 'bottom', 'left' ].forEach( side => { + const sideCssVarName = getCSSVarName( value[ side ] ) + const matchedMark = props.marks.find( mark => getCSSVarName( mark.value ) === sideCssVarName ) + isMarkValue[ side ] = !! matchedMark + if ( matchedMark ) { + value[ side ] = matchedMark.value + } + } ) + setIsFourMarkMode( isMarkValue ) + } + }, [ deviceType ] ) const onChangeAll = _newValue => { const newValue = props.marks ? String( _newValue ) : _newValue From 7e588d25d8f3b440c5881e232f1a73022b4cae8f Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Sun, 25 May 2025 14:29:00 +0800 Subject: [PATCH 79/99] fix: move use size presets by default to editor settings --- src/welcome/admin.js | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/welcome/admin.js b/src/welcome/admin.js index aa5db65b36..70a71699c1 100644 --- a/src/welcome/admin.js +++ b/src/welcome/admin.js @@ -85,6 +85,7 @@ const SEARCH_TREE = [ __( 'Stackable Text as Default Block', i18n ), __( 'Design Library', i18n ), __( 'Stackable Settings', i18n ), + __( 'Use Size Presets by Default', i18n ), __( 'Block Linking (Beta)', i18n ), ], }, @@ -155,7 +156,6 @@ const SEARCH_TREE = [ id: 'global-settings', children: [ __( 'Force Typography Styles', i18n ), - __( 'Use Size Presets by Default', i18n ), ], }, ], @@ -698,6 +698,17 @@ const EditorSettings = props => { } } help={ __( 'Adds a button on the top of the editor which gives access to Stackable settings. Note: You won\'t be able to access Stackable settings when this is disabled.', i18n ) } /> + { + props.handleSettingsChange( { stackable_use_size_presets_by_default: value } ) // eslint-disable-line camelcase + } } + help={ __( 'If enabled, range controls will be on preset mode by default.', i18n ) } + disabled={ __( 'Use custom values', i18n ) } + enabled={ __( 'Use presets', i18n ) } + /> { disabled={ __( 'Not forced', i18n ) } enabled={ __( 'Force styles', i18n ) } /> - { - props.handleSettingsChange( { stackable_use_size_presets_by_default: value } ) // eslint-disable-line camelcase - } } - help={ __( 'If enabled, range controls will be on preset mode by default.', i18n ) } - disabled={ __( 'Use custom values', i18n ) } - enabled={ __( 'Use presets', i18n ) } - /> } From 1384c6e5e71c883f818c212cd758468e850043a8 Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Sun, 25 May 2025 17:01:15 +0800 Subject: [PATCH 80/99] fix: saving of new typography --- .../global-settings/typography/index.js | 11 ++++++++++- .../global-settings/typography/utils.js | 18 +++++++++--------- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/plugins/global-settings/typography/index.js b/src/plugins/global-settings/typography/index.js index fc6fa6f69e..40cb974310 100644 --- a/src/plugins/global-settings/typography/index.js +++ b/src/plugins/global-settings/typography/index.js @@ -302,10 +302,17 @@ addFilter( 'stackable.global-settings.inspector', 'stackable/global-typography', return } + // Merge the new styles with the previous, while overwritting similar styles. + // This allow adding styles without removing the previous ones. + // Check if the object is empty, used for resetting the whole setting. if ( Object.keys( styles ).length !== 0 ) { styles = { ...newSettings[ selector ], ...styles } } - + /** + * Delete the object keys with empty strings. + * Otherwise, the API will throw an error code 400 + * because of incompatible schema type. + */ Object.keys( styles ).forEach( key => { if ( styles[ key ] === '' ) { delete styles[ key ] @@ -320,6 +327,8 @@ addFilter( 'stackable.global-settings.inspector', 'stackable/global-typography', doAction( 'stackable.global-settings.typography-update-global-styles', newSettings ) } + updateTypography( newSettings ) + return newSettings } ) } diff --git a/src/plugins/global-settings/typography/utils.js b/src/plugins/global-settings/typography/utils.js index 5e98ee3775..0926745826 100644 --- a/src/plugins/global-settings/typography/utils.js +++ b/src/plugins/global-settings/typography/utils.js @@ -16,14 +16,14 @@ export const getAppliedTypeScale = value => { return } return { - h1: { fontSize: Number( Math.pow( typeScale, 6 ).toFixed( 3 ) ), fontSizeUnit: 'rem' }, - h2: { fontSize: Number( Math.pow( typeScale, 5 ).toFixed( 3 ) ), fontSizeUnit: 'rem' }, - h3: { fontSize: Number( Math.pow( typeScale, 4 ).toFixed( 3 ) ), fontSizeUnit: 'rem' }, - h4: { fontSize: Number( Math.pow( typeScale, 3 ).toFixed( 3 ) ), fontSizeUnit: 'rem' }, - h5: { fontSize: Number( Math.pow( typeScale, 2 ).toFixed( 3 ) ), fontSizeUnit: 'rem' }, - h6: { fontSize: Number( typeScale.toFixed( 3 ) ), fontSizeUnit: 'rem' }, - p: { fontSize: 1, fontSizeUnit: 'rem' }, - '.stk-subtitle': { fontSize: Number( ( 1 / typeScale ).toFixed( 3 ) ), fontSizeUnit: 'rem' }, - '.stk-button__inner-text': { fontSize: 1, fontSizeUnit: 'rem' }, + h1: { fontSize: String( Math.pow( typeScale, 6 ).toFixed( 3 ) ), fontSizeUnit: 'rem' }, + h2: { fontSize: String( Math.pow( typeScale, 5 ).toFixed( 3 ) ), fontSizeUnit: 'rem' }, + h3: { fontSize: String( Math.pow( typeScale, 4 ).toFixed( 3 ) ), fontSizeUnit: 'rem' }, + h4: { fontSize: String( Math.pow( typeScale, 3 ).toFixed( 3 ) ), fontSizeUnit: 'rem' }, + h5: { fontSize: String( Math.pow( typeScale, 2 ).toFixed( 3 ) ), fontSizeUnit: 'rem' }, + h6: { fontSize: String( typeScale.toFixed( 3 ) ), fontSizeUnit: 'rem' }, + p: { fontSize: '1', fontSizeUnit: 'rem' }, + '.stk-subtitle': { fontSize: String( ( 1 / typeScale ).toFixed( 3 ) ), fontSizeUnit: 'rem' }, + '.stk-button__inner-text': { fontSize: '1', fontSizeUnit: 'rem' }, } } From 30cc1d35d12349433bb26582cb4adc18af17e34b Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Sun, 25 May 2025 18:19:21 +0800 Subject: [PATCH 81/99] fix: only cofirm when font family is changed --- .../global-settings/typography/index.js | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/src/plugins/global-settings/typography/index.js b/src/plugins/global-settings/typography/index.js index 40cb974310..84202b780b 100644 --- a/src/plugins/global-settings/typography/index.js +++ b/src/plugins/global-settings/typography/index.js @@ -328,7 +328,6 @@ addFilter( 'stackable.global-settings.inspector', 'stackable/global-typography', } updateTypography( newSettings ) - return newSettings } ) } @@ -372,15 +371,29 @@ addFilter( 'stackable.global-settings.inspector', 'stackable/global-typography', return false } - const getIsChangeConfirmed = () => { + const getIsFontPairChangeConfirmed = () => { // No need to confirm when the current font pair is custom // since changes are saved if ( customFontPairs.find( fontPair => fontPair.name === selectedFontPairName ) ) { return true } + // The confirmation should only occur if the font family has been edited + // since selecting font pair only changes font family + const currentFontPair = getCurrentFontPair() const isDirty = TYPOGRAPHY_TAGS.some( ( { selector } ) => { - return getIsAllowReset( selector ) + if ( isEditingFontPair || ! currentFontPair ) { + return false + } + const fontPairStyle = currentFontPair.typography[ selector ] + const typographyStyle = typographySettings[ selector ] + + if ( ! Array.isArray( typographyStyle ) && + fontPairStyle.fontFamily && + fontPairStyle.fontFamily !== typographyStyle.fontFamily ) { + return true + } + return false } ) if ( isDirty ) { @@ -455,7 +468,7 @@ addFilter( 'stackable.global-settings.inspector', 'stackable/global-typography', fontPair={ FONT_PAIRS[ 0 ] } isSelected={ selectedFontPairName === FONT_PAIRS[ 0 ].name } onClick={ () => { - if ( ! getIsChangeConfirmed() ) { + if ( ! getIsFontPairChangeConfirmed() ) { return } updateSelectedFontPair( FONT_PAIRS[ 0 ].name ) @@ -467,7 +480,7 @@ addFilter( 'stackable.global-settings.inspector', 'stackable/global-typography', customFontPairs={ customFontPairs } selected={ selectedFontPairName } onClick={ ( name, typography ) => { - if ( ! getIsChangeConfirmed() ) { + if ( ! getIsFontPairChangeConfirmed() ) { return } updateSelectedFontPair( name ) @@ -486,7 +499,7 @@ addFilter( 'stackable.global-settings.inspector', 'stackable/global-typography', fontPair={ fontPair } isSelected={ selectedFontPairName === fontPair.name } onClick={ () => { - if ( ! getIsChangeConfirmed() ) { + if ( ! getIsFontPairChangeConfirmed() ) { return } updateSelectedFontPair( fontPair.name ) From 277341f04c5cff216a9087c2c4f21dd04241e41d Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Sun, 25 May 2025 21:43:41 +0800 Subject: [PATCH 82/99] fix: clean style object for comparison --- .../global-settings/typography/index.js | 20 +++++++++---------- .../global-settings/typography/utils.js | 16 +++++++++++++++ 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/src/plugins/global-settings/typography/index.js b/src/plugins/global-settings/typography/index.js index 84202b780b..60abc00cab 100644 --- a/src/plugins/global-settings/typography/index.js +++ b/src/plugins/global-settings/typography/index.js @@ -5,7 +5,7 @@ import { GlobalTypographyStyles } from './editor-loader' import TypographyPicker from './typography-picker' import { getThemeStyles } from './get-theme-styles' import FREE_FONT_PAIRS from './font-pairs.json' -import { getAppliedTypeScale } from './utils' +import { getAppliedTypeScale, cleanTypographyStyle } from './utils' /** * External dependencies @@ -313,13 +313,9 @@ addFilter( 'stackable.global-settings.inspector', 'stackable/global-typography', * Otherwise, the API will throw an error code 400 * because of incompatible schema type. */ - Object.keys( styles ).forEach( key => { - if ( styles[ key ] === '' ) { - delete styles[ key ] - } - } ) + const cleanStyles = cleanTypographyStyle( styles ) || {} - newSettings[ selector ] = styles + newSettings[ selector ] = cleanStyles } ) // Update the global styles immediately when reset font size is triggered. @@ -353,9 +349,10 @@ addFilter( 'stackable.global-settings.inspector', 'stackable/global-typography', const getIsAllowReset = selector => { const currentFontPair = getCurrentFontPair() - const typographyStyle = typographySettings[ selector ] + const typographyStyle = typographySettings[ selector ] || {} if ( ! isEditingFontPair && currentFontPair ) { - const fontPairStyle = currentFontPair.typography[ selector ] + // Clean style object to be consistent with changeStyles operation + const fontPairStyle = cleanTypographyStyle( currentFontPair.typography?.[ selector ] ) || {} if ( ! isEqual( fontPairStyle, typographyStyle ) && ! Array.isArray( typographyStyle ) ) { return true } @@ -385,8 +382,9 @@ addFilter( 'stackable.global-settings.inspector', 'stackable/global-typography', if ( isEditingFontPair || ! currentFontPair ) { return false } - const fontPairStyle = currentFontPair.typography[ selector ] - const typographyStyle = typographySettings[ selector ] + // Clean style object to be consistent with changeStyles operation + const fontPairStyle = cleanTypographyStyle( currentFontPair.typography?.[ selector ] ) || {} + const typographyStyle = typographySettings[ selector ] || {} if ( ! Array.isArray( typographyStyle ) && fontPairStyle.fontFamily && diff --git a/src/plugins/global-settings/typography/utils.js b/src/plugins/global-settings/typography/utils.js index 0926745826..9758c63c80 100644 --- a/src/plugins/global-settings/typography/utils.js +++ b/src/plugins/global-settings/typography/utils.js @@ -27,3 +27,19 @@ export const getAppliedTypeScale = value => { '.stk-button__inner-text': { fontSize: '1', fontSizeUnit: 'rem' }, } } + +/** + * Remove empty string properties from the given styles object + * + * @param {Object} styles - The typography styles object + * @return {Object} An object with removed empty string properties + */ + +export const cleanTypographyStyle = styles => { + if ( ! styles ) { + return {} + } + return Object.fromEntries( + Object.entries( styles ).filter( ( [ , value ] ) => value !== '' ) + ) +} From 96190c7c2b83a1605ea7230e912b01ef19c0e2cb Mon Sep 17 00:00:00 2001 From: Mikhaela Tapia Date: Mon, 26 May 2025 09:47:53 +0800 Subject: [PATCH 83/99] update test for global typography --- e2e/tests/global-settings.spec.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/e2e/tests/global-settings.spec.ts b/e2e/tests/global-settings.spec.ts index af798e946f..c4fe99e360 100644 --- a/e2e/tests/global-settings.spec.ts +++ b/e2e/tests/global-settings.spec.ts @@ -78,25 +78,25 @@ test.describe( 'Global Settings', () => { expect( _count ).toBeLessThan( count ) } ) - test.skip( 'Global Typography Styles should be applied when adding a heading', async ( { + test( 'Global Typography Styles should be applied when adding a heading', async ( { page, editor, } ) => { await page.getByLabel( 'Stackable Settings' ).click() await page.getByRole( 'button', { name: 'Global Typography' } ).click() - // Set Global Typography Styles of Heading 2 to have a font-size of 32 + // Set Global Typography Styles of Heading 2 to have a text-transform uppercase await page.locator( '.ugb-global-settings-typography-control' ).nth( 1 ).locator( '.components-base-control__field > .ugb-button-icon-control__wrapper > .components-button' ).click() - await page.locator( '.stk-popover .components-base-control:nth-of-type(2)', { hasText: /Size/ } ).getByRole( 'textbox' ).fill( '32' ) + await page.locator( '.stk-popover .components-base-control:nth-of-type(4)', { hasText: /Transform/ } ).getByRole( 'listbox' ).selectOption( 'uppercase' ) await page.locator( '.ugb-global-settings-typography-control' ).nth( 1 ).locator( '.components-base-control__field > .ugb-button-icon-control__wrapper > .components-button' ).click() - // Verify if the Heading 2 in Global Typography Styles has correct font size - await expect( page.getByRole( 'heading', { name: 'Heading 2' } ) ).toHaveCSS( 'font-size', '32px' ) + // Verify if the Heading 2 in Global Typography Styles has correct text-transform + await expect( page.getByRole( 'heading', { name: 'Heading 2' } ) ).toHaveCSS( 'text-transform', 'uppercase' ) // Open Block Settings await page.getByLabel( 'Settings', { exact: true } ).click() - // Check if the added Stackable Heading Block has a font-size of 32 + // Check if the added Stackable Heading Block has a text-transform uppercase editor.insertBlock( { name: 'stackable/heading', attributes: { @@ -104,7 +104,7 @@ test.describe( 'Global Settings', () => { }, } ) - await expect( editor.canvas.locator( '[data-type="stackable/heading"] > .stk-block-heading > h2[role="textbox"]' ) ).toHaveCSS( 'font-size', '32px' ) + await expect( editor.canvas.locator( '[data-type="stackable/heading"] > .stk-block-heading > h2[role="textbox"]' ) ).toHaveCSS( 'text-transform', 'uppercase' ) // Reset Global Typography Styles await page.getByLabel( 'Stackable Settings' ).click() From 961c7d2248b2edb9308a86e92898612165adc300 Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Mon, 26 May 2025 11:23:38 +0800 Subject: [PATCH 84/99] fix: remove unused hasCSSVariableValue --- src/block-components/button/edit.js | 1 - src/block-components/columns/edit.js | 2 -- src/block-components/helpers/borders/edit.js | 1 - src/block-components/helpers/size/edit.js | 3 --- src/block-components/typography/edit.js | 1 - 5 files changed, 8 deletions(-) diff --git a/src/block-components/button/edit.js b/src/block-components/button/edit.js index 9a58b50e3f..3c8fb034fc 100644 --- a/src/block-components/button/edit.js +++ b/src/block-components/button/edit.js @@ -234,7 +234,6 @@ const SizeControls = props => { description: __( 'Adjusts the space between the button text and button borders', i18n ), } } marks={ presetMarks } - hasCSSVariableValue={ true } /> ) } diff --git a/src/block-components/columns/edit.js b/src/block-components/columns/edit.js index 363a0a95ae..3614674539 100644 --- a/src/block-components/columns/edit.js +++ b/src/block-components/columns/edit.js @@ -288,7 +288,6 @@ export const Controls = props => { description: __( 'Sets the distance between two or more columns', i18n ), } } marks={ presetMarks } - hasCSSVariableValue={ true } /> { description: __( 'Sets the distance between two or more columns', i18n ), } } marks={ presetMarks } - hasCSSVariableValue={ true } /> ) } diff --git a/src/block-components/helpers/borders/edit.js b/src/block-components/helpers/borders/edit.js index ffd96697d2..5eefbb78d1 100644 --- a/src/block-components/helpers/borders/edit.js +++ b/src/block-components/helpers/borders/edit.js @@ -135,7 +135,6 @@ export const BorderControls = props => { sliderMax={ props.borderSliderMax } placeholder={ props.borderRadiusPlaceholder } marks={ presetMarks } - hasCSSVariableValue={ true } /> } { } } visualGuide={ props.visualGuide } marks={ presetMarks } - hasCSSVariableValue={ true } /> } { props.hasContentVerticalAlign && @@ -166,7 +165,6 @@ const Spacing = props => { visualGuide={ paddingVisualGuide } placeholder={ props.paddingPlaceholder } marks={ presetMarks } - hasCSSVariableValue={ true } /> { props.enableMargin && @@ -185,7 +183,6 @@ const Spacing = props => { } } visualGuide={ marginVisualGuide } marks={ presetMarks } - hasCSSVariableValue={ true } /> } diff --git a/src/block-components/typography/edit.js b/src/block-components/typography/edit.js index 53d7590e92..fc34d1fb3b 100644 --- a/src/block-components/typography/edit.js +++ b/src/block-components/typography/edit.js @@ -277,7 +277,6 @@ export const Controls = props => { description: __( 'Sets the size of text characters', i18n ), } } marks={ presetMarks } - hasCSSVariableValue={ true } /> { hasColor && ( From 0b671a4a2768ead5f4c34ff94eee2c946505d637 Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Mon, 26 May 2025 13:25:18 +0800 Subject: [PATCH 85/99] fix: add inner column spacing presets --- src/block-components/columns/attributes.js | 12 ++++++------ src/block-components/columns/deprecated/index.js | 11 ++++++++++- src/block-components/columns/edit.js | 1 + src/block-components/columns/style.js | 8 +++++++- 4 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/block-components/columns/attributes.js b/src/block-components/columns/attributes.js index 253a6ebf28..87ece45466 100644 --- a/src/block-components/columns/attributes.js +++ b/src/block-components/columns/attributes.js @@ -5,12 +5,6 @@ export const addAttributes = ( attrObject, attrNameTemplate = '%s' ) => { attrObject.add( { attributes: { - columnSpacing: { - stkResponsive: true, - stkUnits: 'px', - type: 'number', - default: '', - }, columnWrapDesktop: { // Only applies to desktops type: 'boolean', default: false, @@ -32,6 +26,12 @@ export const addAttributes = ( attrObject, attrNameTemplate = '%s' ) => { type: 'string', default: '', }, + columnSpacing: { + stkResponsive: true, + stkUnits: 'px', + type: 'string', + default: '', + }, }, attrNameTemplate, versionAdded: '3.15.3', diff --git a/src/block-components/columns/deprecated/index.js b/src/block-components/columns/deprecated/index.js index efce36ad69..a489565059 100644 --- a/src/block-components/columns/deprecated/index.js +++ b/src/block-components/columns/deprecated/index.js @@ -13,6 +13,12 @@ export const deprecatedAddAttributes = ( attrObject, attrNameTemplate = '%s' ) = type: 'number', default: '', }, + columnSpacing: { + stkResponsive: true, + stkUnits: 'px', + type: 'number', + default: '', + }, }, attrNameTemplate, versionAdded: '3.0.0', @@ -25,20 +31,23 @@ export const deprecateColumnAndRowGap = { const getAttrName = getAttrNameFunction( attrNameTemplate ) const getAttribute = _attrName => attributes[ getAttrName( _attrName ) ] + const columnSpacing = getAttribute( 'columnSpacing' ) const columnGap = getAttribute( 'columnGap' ) const rowGap = getAttribute( 'rowGap' ) - return typeof columnGap === 'number' || typeof rowGap === 'number' + return typeof columnSpacing === 'number' || typeof columnGap === 'number' || typeof rowGap === 'number' }, migrate: attrNameTemplate => attributes => { const getAttrName = getAttrNameFunction( attrNameTemplate ) const getAttribute = _attrName => attributes[ getAttrName( _attrName ) ] + const columnSpacing = getAttribute( 'columnSpacing' ) const columnGap = getAttribute( 'columnGap' ) const rowGap = getAttribute( 'rowGap' ) const newAttributes = { ...attributes, + [ getAttrName( 'columnSpacing' ) ]: String( columnSpacing ), [ getAttrName( 'columnGap' ) ]: String( columnGap ), [ getAttrName( 'rowGap' ) ]: String( rowGap ), } diff --git a/src/block-components/columns/edit.js b/src/block-components/columns/edit.js index 3614674539..eec4bc4d6a 100644 --- a/src/block-components/columns/edit.js +++ b/src/block-components/columns/edit.js @@ -270,6 +270,7 @@ export const Controls = props => { // Add a working video description: __( 'Sets column paddings, the space inside the block between the block elements and the column container border', i18n ), } } + marks={ presetMarks } /> { selector: '.%s-column', styleRule: '--stk-columns-spacing', attrName: 'columnSpacing', - hasUnits: 'px', responsive: 'all', + valueCallback: value => { + // Substitute with using format to work with preset controls + if ( typeof value === 'string' && value.startsWith( 'var' ) ) { + return value + } + return value + 'px' + }, } ] ) blockStyleGenerator.addBlockStyles( 'columnGap', [ { From abe4a876857928133f43db6c0086c51575d0d152 Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Mon, 26 May 2025 14:05:21 +0800 Subject: [PATCH 86/99] fix: add inner column > inner column spacing presets --- src/block/column/edit.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/block/column/edit.js b/src/block/column/edit.js index 72b8f7e085..a2c2a6707e 100644 --- a/src/block/column/edit.js +++ b/src/block/column/edit.js @@ -8,7 +8,7 @@ import blockStyles from './style' */ import classnames from 'classnames' import { i18n, version as VERSION } from 'stackable' -import { useBlockLayoutDefaults } from '~stackable/hooks' +import { useBlockLayoutDefaults, usePresetControls } from '~stackable/hooks' import { AdvancedToggleControl, FourRangeControl, @@ -164,6 +164,8 @@ const Edit = props => { // props used by controls to prevent rerenders of all the inspector controls. const InspectorControls = memo( props => { const { getPlaceholder } = useBlockLayoutDefaults() + const presets = usePresetControls( 'spacingSizes' )?.getPresetMarks() || null + return ( <> @@ -187,6 +189,7 @@ const InspectorControls = memo( props => { highlight: 'column-spacing', defaultValue: '12px', } } + marks={ presets } /> From 1cb15b0fd8cdebb812722e9716ee0733b39ec6d5 Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Mon, 26 May 2025 16:46:39 +0800 Subject: [PATCH 87/99] fix: also clean typography style for consistency --- src/plugins/global-settings/typography/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/global-settings/typography/index.js b/src/plugins/global-settings/typography/index.js index 60abc00cab..11d3ad98a7 100644 --- a/src/plugins/global-settings/typography/index.js +++ b/src/plugins/global-settings/typography/index.js @@ -349,7 +349,7 @@ addFilter( 'stackable.global-settings.inspector', 'stackable/global-typography', const getIsAllowReset = selector => { const currentFontPair = getCurrentFontPair() - const typographyStyle = typographySettings[ selector ] || {} + const typographyStyle = cleanTypographyStyle( typographySettings[ selector ] ) || {} if ( ! isEditingFontPair && currentFontPair ) { // Clean style object to be consistent with changeStyles operation const fontPairStyle = cleanTypographyStyle( currentFontPair.typography?.[ selector ] ) || {} @@ -384,7 +384,7 @@ addFilter( 'stackable.global-settings.inspector', 'stackable/global-typography', } // Clean style object to be consistent with changeStyles operation const fontPairStyle = cleanTypographyStyle( currentFontPair.typography?.[ selector ] ) || {} - const typographyStyle = typographySettings[ selector ] || {} + const typographyStyle = cleanTypographyStyle( typographySettings[ selector ] ) || {} if ( ! Array.isArray( typographyStyle ) && fontPairStyle.fontFamily && From 34ef9b91fabd4ae1c0355a282be30d450d261b29 Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Mon, 26 May 2025 16:49:00 +0800 Subject: [PATCH 88/99] fix: consider unit conversion during two-way value conversion between preset and custom mode --- src/components/advanced-range-control/index.js | 18 +++++++++++------- src/components/four-range-control/index.js | 18 +++++++++++------- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/src/components/advanced-range-control/index.js b/src/components/advanced-range-control/index.js index 4237a3e07e..08ea202c36 100644 --- a/src/components/advanced-range-control/index.js +++ b/src/components/advanced-range-control/index.js @@ -17,7 +17,9 @@ import { useBlockSetAttributesContext, useDeviceType, } from '~stackable/hooks' -import { extractNumbersAndUnits, getCSSVarName } from '~stackable/util' +import { + extractNumbersAndUnits, getCSSVarName, convertToPxIfUnsupported, +} from '~stackable/util' import { settings as stackableSettings } from 'stackable' /** @@ -207,6 +209,9 @@ const AdvancedRangeControl = props => { [ _value, _unit ] = extractNumbersAndUnits( mark.value )[ 0 ] } else { [ _value, _unit ] = extractNumbersAndUnits( mark.size )[ 0 ] + const converted = convertToPxIfUnsupported( props.units, _unit, _value ) + _value = converted.value + _unit = converted.unit } return _value === derivedValue && ( _unit === '' || _unit === unit ) } ) @@ -218,12 +223,11 @@ const AdvancedRangeControl = props => { const markValue = props.marks[ value ]?.[ property ] || '0' let [ newValue, unit ] = extractNumbersAndUnits( markValue )[ 0 ] - // If the attribute has no support for rem, and the - // preset units is rem, convert to px - if ( ( ! hasUnits || ( hasUnits && ! props.units.includes( 'rem' ) ) ) && unit === 'rem' ) { - newValue = `${ parseFloat( newValue ) * 16 }` - unit = 'px' - } + // If the attribute has no support for rem or em, and the + // preset units is rem or em, convert to px + const converted = convertToPxIfUnsupported( props.units, unit, newValue ) + newValue = converted.value + unit = converted.unit // Update the unit. if ( unit ) { diff --git a/src/components/four-range-control/index.js b/src/components/four-range-control/index.js index 6bb260f255..afb19b3bf4 100644 --- a/src/components/four-range-control/index.js +++ b/src/components/four-range-control/index.js @@ -44,7 +44,9 @@ import { useBlockHoverState, useBlockSetAttributesContext, } from '~stackable/hooks' -import { extractNumbersAndUnits, getCSSVarName } from '~stackable/util' +import { + extractNumbersAndUnits, getCSSVarName, convertToPxIfUnsupported, +} from '~stackable/util' const isEqualInitial = ( props, value, firstValue ) => { let isEqual = true @@ -364,6 +366,9 @@ const FourRangeControl = memo( props => { [ _value, _unit ] = extractNumbersAndUnits( mark.value )[ 0 ] } else { [ _value, _unit ] = extractNumbersAndUnits( mark.size )[ 0 ] + const converted = convertToPxIfUnsupported( props.units, _unit, _value ) + _value = converted.value + _unit = converted.unit } return _value === initialValue && ( _unit === '' || _unit === unit ) } ) @@ -376,12 +381,11 @@ const FourRangeControl = memo( props => { const markValue = props.marks[ value ]?.[ property ] || '0' let [ newValue, unit ] = extractNumbersAndUnits( markValue )[ 0 ] - // If the attribute has no support for rem, and the - // preset units is rem, convert to px - if ( ( ! hasUnits || ( hasUnits && ! props.units.includes( 'rem' ) ) ) && unit === 'rem' ) { - newValue = `${ parseFloat( newValue ) * 16 }` - unit = 'px' - } + // If the attribute has no support for rem or em, and the + // preset units is rem or em, convert to px + const converted = convertToPxIfUnsupported( props.units, unit, newValue ) + newValue = converted.value + unit = converted.unit // Update the unit. if ( unit ) { From 825b58fc04712d9f58b3155fc8fb6d95e735375e Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Mon, 26 May 2025 21:11:10 +0800 Subject: [PATCH 89/99] fix: consider unit conversion during two-way value conversion between preset and custom mode --- src/util/index.js | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/util/index.js b/src/util/index.js index 1cceafb327..a727607cb6 100644 --- a/src/util/index.js +++ b/src/util/index.js @@ -426,3 +426,36 @@ export const getCSSVarName = value => { const match = value?.match( /var\(\s*([^,)\s]+)/ ) return match ? match[ 1 ] : null } + +/** + * Convert a value from rem/em to px if the units array doesn't support it. + * + * @param {string[]} units - The list of supported units. + * @param {string} currentUnit - The current unit of the value. + * @param {string|number} currentValue - The current value to convert. + * + * @return {Object} An object containing the converted value and unit. + */ +export function convertToPxIfUnsupported( units, currentUnit, currentValue ) { + const unitMultipliers = { + rem: 16, + em: 16, + } + + const normalizedUnit = currentUnit?.toLowerCase() + + if ( + ( ! units?.length || ! units.includes( normalizedUnit ) ) && + unitMultipliers[ normalizedUnit ] + ) { + return { + value: `${ parseFloat( currentValue ) * unitMultipliers[ normalizedUnit ] }`, + unit: 'px', + } + } + + return { + value: currentValue, + unit: currentUnit, + } +} From 9bd6a279ddd599921c7e7e44a29e5b4d0a6901e0 Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Mon, 26 May 2025 21:11:54 +0800 Subject: [PATCH 90/99] fix: remove placeholder for custom css in number input --- src/components/advanced-range-control/range-control.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/components/advanced-range-control/range-control.js b/src/components/advanced-range-control/range-control.js index cf137a20e4..a3b025a64e 100644 --- a/src/components/advanced-range-control/range-control.js +++ b/src/components/advanced-range-control/range-control.js @@ -144,6 +144,11 @@ const StackableRangeControl = memo( props => { placeholderValue = initialPosition } + // Remove placeholder if it's a custom CSS + if ( typeof placeholderValue === 'string' && placeholderValue.startsWith( 'var' ) ) { + placeholderValue = '' + } + return
    Date: Mon, 26 May 2025 21:12:32 +0800 Subject: [PATCH 91/99] fix: add fallback tooltip for theme.json data with no name like blocksy --- src/components/advanced-range-control/index.js | 2 +- src/components/four-range-control/index.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/advanced-range-control/index.js b/src/components/advanced-range-control/index.js index 08ea202c36..c8dc8a47fc 100644 --- a/src/components/advanced-range-control/index.js +++ b/src/components/advanced-range-control/index.js @@ -175,7 +175,7 @@ const AdvancedRangeControl = props => { ] }, [] ) propsToPass.renderTooltipContent = value => { - return props.marks[ value ]?.name || '' + return props.marks[ value ]?.name || props.marks[ value ]?.slug || '' } // Other necessary props for steps. diff --git a/src/components/four-range-control/index.js b/src/components/four-range-control/index.js index afb19b3bf4..73c05d3da5 100644 --- a/src/components/four-range-control/index.js +++ b/src/components/four-range-control/index.js @@ -339,7 +339,7 @@ const FourRangeControl = memo( props => { ] }, [] ) newProps.renderTooltipContent = value => { - return props.marks[ value ]?.name || '' + return props.marks[ value ]?.name || props.marks[ value ]?.slug || '' } // Other necessary props for steps. From e853ebd73201120c9e78e6ee2ec5459a1dfd296d Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Tue, 27 May 2025 09:41:18 +0800 Subject: [PATCH 92/99] fix: bug fixes --- .../advanced-range-control/index.js | 48 +++--- src/components/four-range-control/index.js | 150 +++++++++++++----- src/global-settings.php | 20 ++- 3 files changed, 149 insertions(+), 69 deletions(-) diff --git a/src/components/advanced-range-control/index.js b/src/components/advanced-range-control/index.js index c8dc8a47fc..dbfc373777 100644 --- a/src/components/advanced-range-control/index.js +++ b/src/components/advanced-range-control/index.js @@ -118,19 +118,20 @@ const AdvancedRangeControl = props => { // If no initial value, use the given default from the settings const [ isMarkMode, setIsMarkMode ] = useState( false ) - // Set the markMode when at first render and when device type changes - useEffect( () => { - let isMarkValue = !! props.marks && isMarkModeDefault - if ( props.marks && derivedValue ) { + let isMarkValue = !! props.marks && isMarkModeDefault + if ( props.marks && derivedValue ) { // Check if the current value exists in the marks only by their CSS variable name // to match in case the fallback size changes. - const derivedValueCssVarName = getCSSVarName( derivedValue ) - const matchedMark = props.marks.find( mark => getCSSVarName( mark.value ) === derivedValueCssVarName ) - isMarkValue = !! matchedMark - if ( matchedMark ) { - derivedValue = matchedMark.value - } + const derivedValueCssVarName = getCSSVarName( derivedValue ) + const matchedMark = props.marks.find( mark => getCSSVarName( mark.value ) === derivedValueCssVarName ) + isMarkValue = !! matchedMark + if ( matchedMark ) { + derivedValue = matchedMark.value } + } + + // Set the markMode when device type changes + useEffect( () => { setIsMarkMode( isMarkValue ) }, [ deviceType ] ) @@ -202,18 +203,8 @@ const AdvancedRangeControl = props => { let rangeOnChange = _onChange if ( isMarkMode ) { rangeValue = props.marks.findIndex( mark => { - let _unit, _value - // If the derivedValue is a CSS variable, compare with mark's CSS variable. - // Otherwise, the derivedValue is custom, so compare with raw size and units - if ( typeof derivedValue === 'string' && derivedValue.startsWith( 'var' ) ) { - [ _value, _unit ] = extractNumbersAndUnits( mark.value )[ 0 ] - } else { - [ _value, _unit ] = extractNumbersAndUnits( mark.size )[ 0 ] - const converted = convertToPxIfUnsupported( props.units, _unit, _value ) - _value = converted.value - _unit = converted.unit - } - return _value === derivedValue && ( _unit === '' || _unit === unit ) + const [ _value, _unit ] = extractNumbersAndUnits( mark.value )[ 0 ] + return _value === derivedValue } ) rangeOnChange = ( value, property = 'value' ) => { if ( value === '' ) { @@ -266,6 +257,19 @@ const AdvancedRangeControl = props => { // Set the value when changing from mark mode to custom if ( isMarkMode && rangeValue !== -1 ) { rangeOnChange( rangeValue, 'size' ) + } else { + const rangeValue = props.marks.findIndex( mark => { + let _unit, _value + + [ _value, _unit ] = extractNumbersAndUnits( mark.size )[ 0 ] + const converted = convertToPxIfUnsupported( props.units, _unit, _value ) + _value = converted.value + _unit = converted.unit + + return _value === derivedValue && ( _unit === '' || _unit === unit ) + } ) + const markValue = props.marks[ rangeValue ]?.value || '0' + _onChange( markValue ) } setIsMarkMode( ! isMarkMode ) } } diff --git a/src/components/four-range-control/index.js b/src/components/four-range-control/index.js index 73c05d3da5..644ffef0e5 100644 --- a/src/components/four-range-control/index.js +++ b/src/components/four-range-control/index.js @@ -191,39 +191,40 @@ const FourRangeControl = memo( props => { const [ isFourMarkMode, setIsFourMarkMode ] = useState( false ) - // Set the markMode when at first render and when device type changes - useEffect( () => { - // Is value at first render the same as a step value? If so, do mark mode - // at the start, or show custom - // If no initial value, use the given default from the settings - const isMarkValue = { - first: !! props.marks && isMarkModeDefault, - top: !! props.marks && isMarkModeDefault, - right: !! props.marks && isMarkModeDefault, - bottom: !! props.marks && isMarkModeDefault, - left: !! props.marks && isMarkModeDefault, + // Is value at first render the same as a step value? If so, do mark mode + // at the start, or show custom + // If no initial value, use the given default from the settings + const isMarkValue = { + first: !! props.marks && isMarkModeDefault, + top: !! props.marks && isMarkModeDefault, + right: !! props.marks && isMarkModeDefault, + bottom: !! props.marks && isMarkModeDefault, + left: !! props.marks && isMarkModeDefault, + } + + if ( props.marks && firstValue ) { + // Check if the current value exists in the marks only by their CSS variable name + // to match in case the fallback size changes. + const firstValueCssVarName = getCSSVarName( firstValue ) + const firstMatchedMark = props.marks.find( mark => getCSSVarName( mark.value ) === firstValueCssVarName ) + isMarkValue.first = !! firstMatchedMark + if ( firstMatchedMark ) { + firstValue = firstMatchedMark.value } - if ( props.marks && firstValue ) { - // Check if the current value exists in the marks only by their CSS variable name - // to match in case the fallback size changes. - const firstValueCssVarName = getCSSVarName( firstValue ) - const firstMatchedMark = props.marks.find( mark => getCSSVarName( mark.value ) === firstValueCssVarName ) - isMarkValue.first = !! firstMatchedMark - if ( firstMatchedMark ) { - firstValue = firstMatchedMark.value + [ 'top', 'right', 'bottom', 'left' ].forEach( side => { + const sideCssVarName = getCSSVarName( value[ side ] ) + const matchedMark = props.marks.find( mark => getCSSVarName( mark.value ) === sideCssVarName ) + isMarkValue[ side ] = !! matchedMark + if ( matchedMark ) { + value[ side ] = matchedMark.value } + } ) + } - [ 'top', 'right', 'bottom', 'left' ].forEach( side => { - const sideCssVarName = getCSSVarName( value[ side ] ) - const matchedMark = props.marks.find( mark => getCSSVarName( mark.value ) === sideCssVarName ) - isMarkValue[ side ] = !! matchedMark - if ( matchedMark ) { - value[ side ] = matchedMark.value - } - } ) - setIsFourMarkMode( isMarkValue ) - } + // Set the markMode when device type changes + useEffect( () => { + setIsFourMarkMode( isMarkValue ) }, [ deviceType ] ) const onChangeAll = _newValue => { @@ -359,18 +360,8 @@ const FourRangeControl = memo( props => { let rangeOnChange = initialOnChange if ( props.marks && isMarkMode ) { rangeValue = props.marks.findIndex( mark => { - let _unit, _value - // If the initialValue is a CSS variable, compare with mark's CSS variable. - // Otherwise, the initialValue is custom, so compare with raw size and units - if ( typeof initialValue === 'string' && initialValue.startsWith( 'var' ) ) { - [ _value, _unit ] = extractNumbersAndUnits( mark.value )[ 0 ] - } else { - [ _value, _unit ] = extractNumbersAndUnits( mark.size )[ 0 ] - const converted = convertToPxIfUnsupported( props.units, _unit, _value ) - _value = converted.value - _unit = converted.unit - } - return _value === initialValue && ( _unit === '' || _unit === unit ) + const [ _value, _unit ] = extractNumbersAndUnits( mark.value )[ 0 ] + return _value === initialValue } ) rangeOnChange = ( value, property = 'value' ) => { if ( value === '' ) { @@ -506,6 +497,17 @@ const FourRangeControl = memo( props => { // Set the value when changing from mark mode to custom if ( isFourMarkMode.first && rangeValueFirst !== -1 ) { rangeOnChangeFirst( rangeValueFirst, 'size' ) + } else { + const rangeValue = props.marks.findIndex( mark => { + let _unit, _value + [ _value, _unit ] = extractNumbersAndUnits( mark.size )[ 0 ] + const converted = convertToPxIfUnsupported( props.units, _unit, _value ) + _value = converted.value + _unit = converted.unit + return _value === firstValue && ( ! unit || _unit === '' || _unit === unit ) + } ) + const markValue = props.marks[ rangeValue ]?.value || '0' + onChangeAll( markValue ) } setIsFourMarkMode( prev => ( { ...prev, first: ! prev.first } ) ) } } @@ -569,6 +571,17 @@ const FourRangeControl = memo( props => { onClick={ () => { if ( isFourMarkMode.top && rangeValueTop !== -1 ) { rangeOnChangeTop( rangeValueTop, 'size' ) + } else { + const rangeValue = props.marks.findIndex( mark => { + let _unit, _value + [ _value, _unit ] = extractNumbersAndUnits( mark.size )[ 0 ] + const converted = convertToPxIfUnsupported( props.units, _unit, _value ) + _value = converted.value + _unit = converted.unit + return _value === value.top && ( ! unit || _unit === '' || _unit === unit ) + } ) + const markValue = props.marks[ rangeValue ]?.value || '0' + onChangeVertical( markValue ) } setIsFourMarkMode( prev => ( { ...prev, top: ! prev.top } ) ) } } @@ -628,6 +641,17 @@ const FourRangeControl = memo( props => { onClick={ () => { if ( isFourMarkMode.left && rangeValueLeft !== -1 ) { rangeOnChangeLeft( rangeValueLeft, 'size' ) + } else { + const rangeValue = props.marks.findIndex( mark => { + let _unit, _value + [ _value, _unit ] = extractNumbersAndUnits( mark.size )[ 0 ] + const converted = convertToPxIfUnsupported( props.units, _unit, _value ) + _value = converted.value + _unit = converted.unit + return _value === value.left && ( ! unit || _unit === '' || _unit === unit ) + } ) + const markValue = props.marks[ rangeValue ]?.value || '0' + onChangeHorizontal( markValue ) } setIsFourMarkMode( prev => ( { ...prev, left: ! prev.left } ) ) } } @@ -693,6 +717,17 @@ const FourRangeControl = memo( props => { onClick={ () => { if ( isFourMarkMode.top && rangeValueTop !== -1 ) { rangeOnChangeTop( rangeValueTop, 'size' ) + } else { + const rangeValue = props.marks.findIndex( mark => { + let _unit, _value + [ _value, _unit ] = extractNumbersAndUnits( mark.size )[ 0 ] + const converted = convertToPxIfUnsupported( props.units, _unit, _value ) + _value = converted.value + _unit = converted.unit + return _value === value.top && ( ! unit || _unit === '' || _unit === unit ) + } ) + const markValue = props.marks[ rangeValue ]?.value || '0' + onChangeTop( markValue ) } setIsFourMarkMode( prev => ( { ...prev, top: ! prev.top } ) ) } } @@ -755,6 +790,17 @@ const FourRangeControl = memo( props => { onClick={ () => { if ( isFourMarkMode.right && rangeValueRight !== -1 ) { rangeOnChangeRight( rangeValueRight, 'size' ) + } else { + const rangeValue = props.marks.findIndex( mark => { + let _unit, _value + [ _value, _unit ] = extractNumbersAndUnits( mark.size )[ 0 ] + const converted = convertToPxIfUnsupported( props.units, _unit, _value ) + _value = converted.value + _unit = converted.unit + return _value === value.right && ( ! unit || _unit === '' || _unit === unit ) + } ) + const markValue = props.marks[ rangeValue ]?.value || '0' + onChangeRight( markValue ) } setIsFourMarkMode( prev => ( { ...prev, right: ! prev.right } ) ) } } @@ -817,6 +863,17 @@ const FourRangeControl = memo( props => { onClick={ () => { if ( isFourMarkMode.bottom && rangeValueBottom !== -1 ) { rangeOnChangeBottom( rangeValueBottom, 'size' ) + } else { + const rangeValue = props.marks.findIndex( mark => { + let _unit, _value + [ _value, _unit ] = extractNumbersAndUnits( mark.size )[ 0 ] + const converted = convertToPxIfUnsupported( props.units, _unit, _value ) + _value = converted.value + _unit = converted.unit + return _value === value.bottom && ( ! unit || _unit === '' || _unit === unit ) + } ) + const markValue = props.marks[ rangeValue ]?.value || '0' + onChangeBottom( markValue ) } setIsFourMarkMode( prev => ( { ...prev, bottom: ! prev.bottom } ) ) } } @@ -879,6 +936,17 @@ const FourRangeControl = memo( props => { onClick={ () => { if ( isFourMarkMode.left && rangeValueLeft !== -1 ) { rangeOnChangeLeft( rangeValueLeft, 'size' ) + } else { + const rangeValue = props.marks.findIndex( mark => { + let _unit, _value + [ _value, _unit ] = extractNumbersAndUnits( mark.size )[ 0 ] + const converted = convertToPxIfUnsupported( props.units, _unit, _value ) + _value = converted.value + _unit = converted.unit + return _value === value.left && ( ! unit || _unit === '' || _unit === unit ) + } ) + const markValue = props.marks[ rangeValue ]?.value || '0' + onChangeLeft( markValue ) } setIsFourMarkMode( prev => ( { ...prev, left: ! prev.left } ) ) } } diff --git a/src/global-settings.php b/src/global-settings.php index f2571a3133..490aff3f1f 100644 --- a/src/global-settings.php +++ b/src/global-settings.php @@ -697,6 +697,14 @@ public function form_paragraph_selector() { return $selectors; } + public function clean_font_size( $font_size, $font_size_unit = '' ) { + if ( is_string( $font_size ) && str_starts_with( $font_size, 'var' ) ) { + return $font_size; + } + + return $font_size . $font_size_unit; + } + /** * Creates a CSS style rule with an added !important if necessary. * @@ -753,7 +761,7 @@ public function generate_typography_styles( $selector, $styles ) { $css['desktop'][] = $this->create_style( 'font-family', $this->get_font_family( $styles['fontFamily'] ) ); } if ( isset( $styles['fontSize'] ) ) { - $css['desktop'][] = $this->create_style( 'font-size', $styles['fontSize'] . $styles['fontSizeUnit'] ); + $css['desktop'][] = $this->create_style( 'font-size', $this->clean_font_size( $styles['fontSize'], $styles['fontSizeUnit'] ) ); } if ( isset( $styles['fontWeight'] ) ) { $css['desktop'][] = $this->create_style( 'font-weight', $styles['fontWeight'] ); @@ -782,12 +790,12 @@ public function generate_typography_styles( $selector, $styles ) { if ( isset( $styles['fontSize'] ) ) { $clamp_desktop_value = $this->clamp_inherited_style( $styles['fontSize'], $inherit_max ); if ( ! empty( $clamp_desktop_value ) ) { - $font_size = $this->create_style( 'font-size', $clamp_desktop_value . $styles['fontSizeUnit'] ); + $font_size = $this->create_style( 'font-size', $this->clean_font_size( $clamp_desktop_value . $styles['fontSizeUnit'] ) ); } } } if ( isset( $styles['tabletFontSize'] ) ) { - $font_size = $this->create_style( 'font-size', $styles['tabletFontSize'] . $styles['tabletFontSizeUnit'] ); + $font_size = $this->create_style( 'font-size', $this->clean_font_size( $styles['tabletFontSize'], $styles['tabletFontSizeUnit'] ) ); } if ( ! empty( $font_size ) ) { $css['tablet'][] = $font_size; @@ -810,7 +818,7 @@ public function generate_typography_styles( $selector, $styles ) { if ( isset( $styles['fontSize'] ) ) { $clamp_desktop_value = $this->clamp_inherited_style( $styles['fontSize'], $inherit_max ); if ( ! empty( $clamp_desktop_value ) ) { - $font_size = $this->create_style( 'font-size', $clamp_desktop_value . $styles['fontSizeUnit'] ); + $font_size = $this->create_style( 'font-size', $this->clean_font_size( $clamp_desktop_value, $styles['fontSizeUnit'] ) ); } } @@ -818,7 +826,7 @@ public function generate_typography_styles( $selector, $styles ) { if ( isset( $styles['tabletFontSize'] ) ) { $clamp_tablet_value = $this->clamp_inherited_style( $styles['tabletFontSize'], $inherit_max ); if ( ! empty( $clamp_tablet_value ) ) { - $font_size = $this->create_style( 'font-size', $clamp_tablet_value . $styles['tabletFontSizeUnit'] ); + $font_size = $this->create_style( $this->clean_font_size( 'font-size', $clamp_tablet_value, $styles['tabletFontSizeUnit'] ) ); } } if ( empty( $clamp_tablet_value ) ) { @@ -831,7 +839,7 @@ public function generate_typography_styles( $selector, $styles ) { } } if ( isset( $styles['mobileFontSize'] ) ) { - $font_size = $this->create_style( 'font-size', $styles['mobileFontSize'] . $styles['mobileFontSizeUnit'] ); + $font_size = $this->create_style( 'font-size', $this->clean_font_size( $styles['mobileFontSize'], $styles['mobileFontSizeUnit'] ) ); } if ( ! empty( $font_size ) ) { $css['mobile'][] = $font_size; From 3a660e2d07451ad5468bfa751218ecac911f37a1 Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Tue, 27 May 2025 17:49:52 +0800 Subject: [PATCH 93/99] fix: bug fix --- src/global-settings.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/global-settings.php b/src/global-settings.php index 490aff3f1f..2859bb62a2 100644 --- a/src/global-settings.php +++ b/src/global-settings.php @@ -790,7 +790,7 @@ public function generate_typography_styles( $selector, $styles ) { if ( isset( $styles['fontSize'] ) ) { $clamp_desktop_value = $this->clamp_inherited_style( $styles['fontSize'], $inherit_max ); if ( ! empty( $clamp_desktop_value ) ) { - $font_size = $this->create_style( 'font-size', $this->clean_font_size( $clamp_desktop_value . $styles['fontSizeUnit'] ) ); + $font_size = $this->create_style( 'font-size', $this->clean_font_size( $clamp_desktop_value, $styles['fontSizeUnit'] ) ); } } } @@ -898,7 +898,7 @@ public function get_font_family( $font_name ) { * @param {Object} options */ public function clamp_inherited_style( $value, $max = 999999, $min = -999999 ) { - if ( isset( $value ) ) { + if ( isset( $value ) && is_numeric( $value ) ) { $clamped_value = max( $min, min( $max, $value ) ); return $clamped_value !== $value ? $clamped_value : null; } From 218c7b6117c72b2619495351874b8b31e19079e6 Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Tue, 27 May 2025 21:58:46 +0800 Subject: [PATCH 94/99] fix: four range reactivity --- src/components/four-range-control/index.js | 43 ++++++++++++++-------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/src/components/four-range-control/index.js b/src/components/four-range-control/index.js index 644ffef0e5..0d0c191d0d 100644 --- a/src/components/four-range-control/index.js +++ b/src/components/four-range-control/index.js @@ -494,8 +494,10 @@ const FourRangeControl = memo( props => { size="small" variant="tertiary" onClick={ () => { - // Set the value when changing from mark mode to custom - if ( isFourMarkMode.first && rangeValueFirst !== -1 ) { + const previousMarkMode = isFourMarkMode.first + setIsFourMarkMode( prev => ( { ...prev, first: ! prev.first } ) ) + + if ( previousMarkMode && rangeValueFirst !== -1 ) { rangeOnChangeFirst( rangeValueFirst, 'size' ) } else { const rangeValue = props.marks.findIndex( mark => { @@ -509,7 +511,6 @@ const FourRangeControl = memo( props => { const markValue = props.marks[ rangeValue ]?.value || '0' onChangeAll( markValue ) } - setIsFourMarkMode( prev => ( { ...prev, first: ! prev.first } ) ) } } icon={ settings } > @@ -569,7 +570,10 @@ const FourRangeControl = memo( props => { size="small" variant="tertiary" onClick={ () => { - if ( isFourMarkMode.top && rangeValueTop !== -1 ) { + const previousMarkMode = isFourMarkMode.top + setIsFourMarkMode( prev => ( { ...prev, top: ! prev.top } ) ) + + if ( previousMarkMode && rangeValueTop !== -1 ) { rangeOnChangeTop( rangeValueTop, 'size' ) } else { const rangeValue = props.marks.findIndex( mark => { @@ -583,7 +587,6 @@ const FourRangeControl = memo( props => { const markValue = props.marks[ rangeValue ]?.value || '0' onChangeVertical( markValue ) } - setIsFourMarkMode( prev => ( { ...prev, top: ! prev.top } ) ) } } icon={ settings } > @@ -639,7 +642,10 @@ const FourRangeControl = memo( props => { size="small" variant="tertiary" onClick={ () => { - if ( isFourMarkMode.left && rangeValueLeft !== -1 ) { + const previousMarkMode = isFourMarkMode.left + setIsFourMarkMode( prev => ( { ...prev, left: ! prev.left } ) ) + + if ( previousMarkMode && rangeValueLeft !== -1 ) { rangeOnChangeLeft( rangeValueLeft, 'size' ) } else { const rangeValue = props.marks.findIndex( mark => { @@ -653,7 +659,6 @@ const FourRangeControl = memo( props => { const markValue = props.marks[ rangeValue ]?.value || '0' onChangeHorizontal( markValue ) } - setIsFourMarkMode( prev => ( { ...prev, left: ! prev.left } ) ) } } icon={ settings } > @@ -715,7 +720,10 @@ const FourRangeControl = memo( props => { size="small" variant="tertiary" onClick={ () => { - if ( isFourMarkMode.top && rangeValueTop !== -1 ) { + const previousMarkMode = isFourMarkMode.top + setIsFourMarkMode( prev => ( { ...prev, top: ! prev.top } ) ) + + if ( previousMarkMode && rangeValueTop !== -1 ) { rangeOnChangeTop( rangeValueTop, 'size' ) } else { const rangeValue = props.marks.findIndex( mark => { @@ -729,7 +737,6 @@ const FourRangeControl = memo( props => { const markValue = props.marks[ rangeValue ]?.value || '0' onChangeTop( markValue ) } - setIsFourMarkMode( prev => ( { ...prev, top: ! prev.top } ) ) } } icon={ settings } > @@ -788,7 +795,10 @@ const FourRangeControl = memo( props => { size="small" variant="tertiary" onClick={ () => { - if ( isFourMarkMode.right && rangeValueRight !== -1 ) { + const previousMarkMode = isFourMarkMode.right + setIsFourMarkMode( prev => ( { ...prev, right: ! prev.right } ) ) + + if ( previousMarkMode && rangeValueRight !== -1 ) { rangeOnChangeRight( rangeValueRight, 'size' ) } else { const rangeValue = props.marks.findIndex( mark => { @@ -802,7 +812,6 @@ const FourRangeControl = memo( props => { const markValue = props.marks[ rangeValue ]?.value || '0' onChangeRight( markValue ) } - setIsFourMarkMode( prev => ( { ...prev, right: ! prev.right } ) ) } } icon={ settings } > @@ -861,7 +870,10 @@ const FourRangeControl = memo( props => { size="small" variant="tertiary" onClick={ () => { - if ( isFourMarkMode.bottom && rangeValueBottom !== -1 ) { + const previousMarkMode = isFourMarkMode.bottom + setIsFourMarkMode( prev => ( { ...prev, bottom: ! prev.bottom } ) ) + + if ( previousMarkMode && rangeValueBottom !== -1 ) { rangeOnChangeBottom( rangeValueBottom, 'size' ) } else { const rangeValue = props.marks.findIndex( mark => { @@ -875,7 +887,6 @@ const FourRangeControl = memo( props => { const markValue = props.marks[ rangeValue ]?.value || '0' onChangeBottom( markValue ) } - setIsFourMarkMode( prev => ( { ...prev, bottom: ! prev.bottom } ) ) } } icon={ settings } > @@ -934,7 +945,10 @@ const FourRangeControl = memo( props => { size="small" variant="tertiary" onClick={ () => { - if ( isFourMarkMode.left && rangeValueLeft !== -1 ) { + const previousMarkMode = isFourMarkMode.left + setIsFourMarkMode( prev => ( { ...prev, left: ! prev.left } ) ) + + if ( previousMarkMode && rangeValueLeft !== -1 ) { rangeOnChangeLeft( rangeValueLeft, 'size' ) } else { const rangeValue = props.marks.findIndex( mark => { @@ -948,7 +962,6 @@ const FourRangeControl = memo( props => { const markValue = props.marks[ rangeValue ]?.value || '0' onChangeLeft( markValue ) } - setIsFourMarkMode( prev => ( { ...prev, left: ! prev.left } ) ) } } icon={ settings } > From 6ed023be261934a63a4573fa946bca2bfd95557f Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Wed, 28 May 2025 14:09:21 +0800 Subject: [PATCH 95/99] fix: do not actually change value when switching mode --- .../advanced-range-control/index.js | 57 ++++-- src/components/four-range-control/index.js | 175 ++++++------------ 2 files changed, 95 insertions(+), 137 deletions(-) diff --git a/src/components/advanced-range-control/index.js b/src/components/advanced-range-control/index.js index dbfc373777..874d1c52ed 100644 --- a/src/components/advanced-range-control/index.js +++ b/src/components/advanced-range-control/index.js @@ -26,7 +26,7 @@ import { settings as stackableSettings } from 'stackable' * WordPress dependencies */ import { - memo, useState, useEffect, + memo, useState, useEffect, useRef, } from '@wordpress/element' import { Button } from '@wordpress/components' import { settings } from '@wordpress/icons' @@ -117,6 +117,8 @@ const AdvancedRangeControl = props => { // at the start, or show custom // If no initial value, use the given default from the settings const [ isMarkMode, setIsMarkMode ] = useState( false ) + // Ensure the convesion of value from preset to custom with regards to the unit is donce once. + const isConversionDone = useRef( false ) let isMarkValue = !! props.marks && isMarkModeDefault if ( props.marks && derivedValue ) { @@ -203,8 +205,16 @@ const AdvancedRangeControl = props => { let rangeOnChange = _onChange if ( isMarkMode ) { rangeValue = props.marks.findIndex( mark => { - const [ _value, _unit ] = extractNumbersAndUnits( mark.value )[ 0 ] - return _value === derivedValue + let _unit, _value + // If the derivedValue is a CSS variable, compare with mark's CSS variable. + // Otherwise, the derivedValue is custom from the previous switch from custom to preset mode, + // so compare with raw size and units to convert to preset. + if ( typeof derivedValue === 'string' && derivedValue.startsWith( 'var' ) ) { + [ _value, _unit ] = extractNumbersAndUnits( mark.value )[ 0 ] + } else { + [ _value, _unit ] = extractNumbersAndUnits( mark.size )[ 0 ] + } + return _value === derivedValue && ( _unit === '' || _unit === unit ) } ) rangeOnChange = ( value, property = 'value' ) => { if ( value === '' ) { @@ -230,6 +240,30 @@ const AdvancedRangeControl = props => { } _onChange( newValue ) + isConversionDone.current = false + } + } else if ( typeof derivedValue === 'string' && derivedValue.startsWith( 'var' ) ) { + // If the derivedValue is a preset and currently not in mark mode, the derivedValue is from + // the previous switch from preset to custom mode. Convert to custom. + const currentSize = props.marks.find( mark => { + return derivedValue === mark.value + } )?.size + const [ _newValue, _unit ] = extractNumbersAndUnits( currentSize )[ 0 ] + rangeValue = _newValue + + if ( _unit && ! isConversionDone.current ) { + dispatch( 'core/block-editor' ).__unstableMarkNextChangeAsNotPersistent() + setAttributes( { [ unitAttrName ]: _unit } ) + if ( props.onChangeUnit ) { + props.onChangeUnit( _unit ) + } + isConversionDone.current = true + } + // Since the actual previous value is a preset, force the new custom value + // when changing unit + controlProps.onChangeUnit = ( unit, unitAttrName ) => { + setAttributes( { [ unitAttrName ]: unit } ) + _onChange( _newValue ) } } @@ -254,23 +288,6 @@ const AdvancedRangeControl = props => { size="small" variant="tertiary" onClick={ () => { - // Set the value when changing from mark mode to custom - if ( isMarkMode && rangeValue !== -1 ) { - rangeOnChange( rangeValue, 'size' ) - } else { - const rangeValue = props.marks.findIndex( mark => { - let _unit, _value - - [ _value, _unit ] = extractNumbersAndUnits( mark.size )[ 0 ] - const converted = convertToPxIfUnsupported( props.units, _unit, _value ) - _value = converted.value - _unit = converted.unit - - return _value === derivedValue && ( _unit === '' || _unit === unit ) - } ) - const markValue = props.marks[ rangeValue ]?.value || '0' - _onChange( markValue ) - } setIsMarkMode( ! isMarkMode ) } } icon={ settings } diff --git a/src/components/four-range-control/index.js b/src/components/four-range-control/index.js index 0d0c191d0d..132deb5897 100644 --- a/src/components/four-range-control/index.js +++ b/src/components/four-range-control/index.js @@ -25,7 +25,7 @@ import { useControlHandlers } from '../base-control2/hooks' import { Tooltip } from '@wordpress/components' import { __ } from '@wordpress/i18n' import { - Fragment, useState, memo, useEffect, + Fragment, useState, memo, useEffect, useRef, } from '@wordpress/element' import { settings } from '@wordpress/icons' import { dispatch } from '@wordpress/data' @@ -190,6 +190,16 @@ const FourRangeControl = memo( props => { : { desktop: _valueDesktop?.left, tablet: _valueTablet?.left } const [ isFourMarkMode, setIsFourMarkMode ] = useState( false ) + // Ensure the convesion of value from preset to custom with regards to the unit is donce once. + const isConversionDone = useRef( { + first: false, + top: false, + right: false, + bottom: false, + left: false, + vertical: false, + horizontal: false, + } ) // Is value at first render the same as a step value? If so, do mark mode // at the start, or show custom @@ -318,7 +328,7 @@ const FourRangeControl = memo( props => { } ) ) } // Support for steps. Modify the props to make the range control show steps. - const stepSupport = ( isMarkMode, initialValue, initialOnChange ) => { + const stepSupport = ( isMarkMode, initialValue, initialOnChange, conversionKey = null ) => { const newProps = { ...propsToPass } if ( props.marks && isMarkMode ) { @@ -360,8 +370,16 @@ const FourRangeControl = memo( props => { let rangeOnChange = initialOnChange if ( props.marks && isMarkMode ) { rangeValue = props.marks.findIndex( mark => { - const [ _value, _unit ] = extractNumbersAndUnits( mark.value )[ 0 ] - return _value === initialValue + let _unit, _value + // If the initialValue is a CSS variable, compare with mark's CSS variable. + // Otherwise, the initialValue is custom from the previous switch from custom to preset mode, + // so compare with raw size and units to convert to preset. + if ( typeof initialValue === 'string' && initialValue.startsWith( 'var' ) ) { + [ _value, _unit ] = extractNumbersAndUnits( mark.value )[ 0 ] + } else { + [ _value, _unit ] = extractNumbersAndUnits( mark.size )[ 0 ] + } + return _value === initialValue && ( _unit === '' || _unit === unit ) } ) rangeOnChange = ( value, property = 'value' ) => { if ( value === '' ) { @@ -388,11 +406,39 @@ const FourRangeControl = memo( props => { } initialOnChange( newValue ) + isConversionDone.current[ conversionKey ] = false + } + } else if ( typeof initialValue === 'string' && initialValue.startsWith( 'var' ) && + ( ( isLocked && conversionKey === 'first' ) || + ( ! isLocked && [ 'top', 'right', 'left', 'bottom' ].includes( conversionKey ) ) || + ( isLocked && props.vhMode && [ 'vertical', 'horizontal' ].includes( conversionKey ) ) ) + ) { + // If the derivedValue is a preset and currently not in mark mode, the derivedValue is from + // the previous switch from preset to custom mode. Convert to custom. + const currentSize = props.marks.find( mark => { + return initialValue === mark.value + } )?.size + const [ _newValue, _unit ] = extractNumbersAndUnits( currentSize )[ 0 ] + rangeValue = _newValue + + if ( _unit && conversionKey && ! isConversionDone.current[ conversionKey ] ) { + isConversionDone.current[ conversionKey ] = true + dispatch( 'core/block-editor' ).__unstableMarkNextChangeAsNotPersistent() + setAttributes( { [ unitAttrName ]: _unit } ) + if ( props.onChangeUnit ) { + props.onChangeUnit( _unit ) + } + } + // Since the actual previous value is a preset, force the new custom value + // when changing unit + controlProps.onChangeUnit = ( unit, unitAttrName ) => { + initialOnChange( _newValue ) + setAttributes( { [ unitAttrName ]: unit } ) } } return [ - newProps, rangeValue, rangeOnChange, + newProps, parseFloat( rangeValue ), rangeOnChange, ] } @@ -413,42 +459,49 @@ const FourRangeControl = memo( props => { isFourMarkMode.first, firstValue, onChangeAll, + 'first', ) const [ propsToPassTop, rangeValueTop, rangeOnChangeTop ] = stepSupport( isFourMarkMode.top, value.top, onChangeTop, + 'top' ) const [ propsToPassRight, rangeValueRight, rangeOnChangeRight ] = stepSupport( isFourMarkMode.right, value.right, onChangeRight, + 'right' ) const [ propsToPassBottom, rangeValueBottom, rangeOnChangeBottom ] = stepSupport( isFourMarkMode.bottom, value.bottom, onChangeBottom, + 'bottom' ) const [ propsToPassLeft, rangeValueLeft, rangeOnChangeLeft ] = stepSupport( isFourMarkMode.left, value.left, onChangeLeft, + 'left' ) const [ propsToPassVertical, rangeValueVertical, rangeOnChangeVertical ] = stepSupport( isFourMarkMode.top, value.top, onChangeVertical, + 'vertical' ) const [ propsToPassHorizontal, rangeValueHorizontal, rangeOnChangeHorizontal ] = stepSupport( isFourMarkMode.left, value.left, onChangeHorizontal, + 'horizontal' ) return ( @@ -494,23 +547,7 @@ const FourRangeControl = memo( props => { size="small" variant="tertiary" onClick={ () => { - const previousMarkMode = isFourMarkMode.first setIsFourMarkMode( prev => ( { ...prev, first: ! prev.first } ) ) - - if ( previousMarkMode && rangeValueFirst !== -1 ) { - rangeOnChangeFirst( rangeValueFirst, 'size' ) - } else { - const rangeValue = props.marks.findIndex( mark => { - let _unit, _value - [ _value, _unit ] = extractNumbersAndUnits( mark.size )[ 0 ] - const converted = convertToPxIfUnsupported( props.units, _unit, _value ) - _value = converted.value - _unit = converted.unit - return _value === firstValue && ( ! unit || _unit === '' || _unit === unit ) - } ) - const markValue = props.marks[ rangeValue ]?.value || '0' - onChangeAll( markValue ) - } } } icon={ settings } > @@ -570,23 +607,7 @@ const FourRangeControl = memo( props => { size="small" variant="tertiary" onClick={ () => { - const previousMarkMode = isFourMarkMode.top setIsFourMarkMode( prev => ( { ...prev, top: ! prev.top } ) ) - - if ( previousMarkMode && rangeValueTop !== -1 ) { - rangeOnChangeTop( rangeValueTop, 'size' ) - } else { - const rangeValue = props.marks.findIndex( mark => { - let _unit, _value - [ _value, _unit ] = extractNumbersAndUnits( mark.size )[ 0 ] - const converted = convertToPxIfUnsupported( props.units, _unit, _value ) - _value = converted.value - _unit = converted.unit - return _value === value.top && ( ! unit || _unit === '' || _unit === unit ) - } ) - const markValue = props.marks[ rangeValue ]?.value || '0' - onChangeVertical( markValue ) - } } } icon={ settings } > @@ -642,23 +663,7 @@ const FourRangeControl = memo( props => { size="small" variant="tertiary" onClick={ () => { - const previousMarkMode = isFourMarkMode.left setIsFourMarkMode( prev => ( { ...prev, left: ! prev.left } ) ) - - if ( previousMarkMode && rangeValueLeft !== -1 ) { - rangeOnChangeLeft( rangeValueLeft, 'size' ) - } else { - const rangeValue = props.marks.findIndex( mark => { - let _unit, _value - [ _value, _unit ] = extractNumbersAndUnits( mark.size )[ 0 ] - const converted = convertToPxIfUnsupported( props.units, _unit, _value ) - _value = converted.value - _unit = converted.unit - return _value === value.left && ( ! unit || _unit === '' || _unit === unit ) - } ) - const markValue = props.marks[ rangeValue ]?.value || '0' - onChangeHorizontal( markValue ) - } } } icon={ settings } > @@ -720,23 +725,7 @@ const FourRangeControl = memo( props => { size="small" variant="tertiary" onClick={ () => { - const previousMarkMode = isFourMarkMode.top setIsFourMarkMode( prev => ( { ...prev, top: ! prev.top } ) ) - - if ( previousMarkMode && rangeValueTop !== -1 ) { - rangeOnChangeTop( rangeValueTop, 'size' ) - } else { - const rangeValue = props.marks.findIndex( mark => { - let _unit, _value - [ _value, _unit ] = extractNumbersAndUnits( mark.size )[ 0 ] - const converted = convertToPxIfUnsupported( props.units, _unit, _value ) - _value = converted.value - _unit = converted.unit - return _value === value.top && ( ! unit || _unit === '' || _unit === unit ) - } ) - const markValue = props.marks[ rangeValue ]?.value || '0' - onChangeTop( markValue ) - } } } icon={ settings } > @@ -795,23 +784,7 @@ const FourRangeControl = memo( props => { size="small" variant="tertiary" onClick={ () => { - const previousMarkMode = isFourMarkMode.right setIsFourMarkMode( prev => ( { ...prev, right: ! prev.right } ) ) - - if ( previousMarkMode && rangeValueRight !== -1 ) { - rangeOnChangeRight( rangeValueRight, 'size' ) - } else { - const rangeValue = props.marks.findIndex( mark => { - let _unit, _value - [ _value, _unit ] = extractNumbersAndUnits( mark.size )[ 0 ] - const converted = convertToPxIfUnsupported( props.units, _unit, _value ) - _value = converted.value - _unit = converted.unit - return _value === value.right && ( ! unit || _unit === '' || _unit === unit ) - } ) - const markValue = props.marks[ rangeValue ]?.value || '0' - onChangeRight( markValue ) - } } } icon={ settings } > @@ -870,23 +843,7 @@ const FourRangeControl = memo( props => { size="small" variant="tertiary" onClick={ () => { - const previousMarkMode = isFourMarkMode.bottom setIsFourMarkMode( prev => ( { ...prev, bottom: ! prev.bottom } ) ) - - if ( previousMarkMode && rangeValueBottom !== -1 ) { - rangeOnChangeBottom( rangeValueBottom, 'size' ) - } else { - const rangeValue = props.marks.findIndex( mark => { - let _unit, _value - [ _value, _unit ] = extractNumbersAndUnits( mark.size )[ 0 ] - const converted = convertToPxIfUnsupported( props.units, _unit, _value ) - _value = converted.value - _unit = converted.unit - return _value === value.bottom && ( ! unit || _unit === '' || _unit === unit ) - } ) - const markValue = props.marks[ rangeValue ]?.value || '0' - onChangeBottom( markValue ) - } } } icon={ settings } > @@ -945,23 +902,7 @@ const FourRangeControl = memo( props => { size="small" variant="tertiary" onClick={ () => { - const previousMarkMode = isFourMarkMode.left setIsFourMarkMode( prev => ( { ...prev, left: ! prev.left } ) ) - - if ( previousMarkMode && rangeValueLeft !== -1 ) { - rangeOnChangeLeft( rangeValueLeft, 'size' ) - } else { - const rangeValue = props.marks.findIndex( mark => { - let _unit, _value - [ _value, _unit ] = extractNumbersAndUnits( mark.size )[ 0 ] - const converted = convertToPxIfUnsupported( props.units, _unit, _value ) - _value = converted.value - _unit = converted.unit - return _value === value.left && ( ! unit || _unit === '' || _unit === unit ) - } ) - const markValue = props.marks[ rangeValue ]?.value || '0' - onChangeLeft( markValue ) - } } } icon={ settings } > From c158a407b980608493be1077918d3f2f477ffd66 Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Thu, 29 May 2025 16:27:15 +0800 Subject: [PATCH 96/99] fix: add presets to contentHeight and innerBlockRowGap --- src/block-components/alignment/attributes.js | 23 ++++++++-- .../alignment/deprecated/index.js | 44 +++++++++++++++++++ src/block-components/alignment/edit.js | 6 +++ src/block-components/alignment/index.js | 2 + src/block-components/alignment/style.js | 32 ++++++++++++-- .../advanced-range-control/index.js | 11 ++++- src/components/four-range-control/index.js | 11 ++++- 7 files changed, 118 insertions(+), 11 deletions(-) create mode 100644 src/block-components/alignment/deprecated/index.js diff --git a/src/block-components/alignment/attributes.js b/src/block-components/alignment/attributes.js index 7c635d8691..1f3ba27f4b 100644 --- a/src/block-components/alignment/attributes.js +++ b/src/block-components/alignment/attributes.js @@ -1,4 +1,8 @@ -export const addAttributes = attrObject => { +import { deprecatedAddAttributes } from './deprecated/index' + +export const addAttributes = ( attrObject, attrNameTemplate = '%s' ) => { + deprecatedAddAttributes( attrObject, attrNameTemplate ) + // Assume that the block uses the BlockDiv Block Component and has a // uniqueId attribute attrObject.add( { @@ -53,13 +57,26 @@ export const addAttributes = attrObject => { type: 'number', default: '', }, + }, + versionAdded: '3.0.0', + versionDeprecated: '', + } ) + + attrObject.add( { + attributes: { innerBlockRowGap: { stkResponsive: true, - type: 'number', + type: 'string', + default: '', + }, + containerHeight: { + stkResponsive: true, + type: 'string', default: '', }, }, - versionAdded: '3.0.0', + attrNameTemplate, + versionAdded: '3.15.3', versionDeprecated: '', } ) } diff --git a/src/block-components/alignment/deprecated/index.js b/src/block-components/alignment/deprecated/index.js new file mode 100644 index 0000000000..5bc82ac2ac --- /dev/null +++ b/src/block-components/alignment/deprecated/index.js @@ -0,0 +1,44 @@ +import { getAttrNameFunction } from '~stackable/util' + +export const deprecatedAddAttributes = ( attrObject, attrNameTemplate = '%s' ) => { + attrObject.add( { + attributes: { + innerBlockRowGap: { + stkResponsive: true, + type: 'number', + default: '', + }, + }, + attrNameTemplate, + versionAdded: '3.0.0', + versionDeprecated: '3.15.3', + } ) +} + +export const deprecateInnerBlockRowGapAndContainerHeight = { + isEligible: attrNameTemplate => attributes => { + const getAttrName = getAttrNameFunction( attrNameTemplate ) + const getAttribute = _attrName => attributes[ getAttrName( _attrName ) ] + + const containerHeight = getAttribute( 'containerHeight' ) + const innerBlockRowGap = getAttribute( 'innerBlockRowGap' ) + + return typeof containerHeight === 'number' || typeof innerBlockRowGap === 'number' + }, + migrate: attrNameTemplate => attributes => { + const getAttrName = getAttrNameFunction( attrNameTemplate ) + const getAttribute = _attrName => attributes[ getAttrName( _attrName ) ] + + const containerHeight = getAttribute( 'containerHeight' ) + const innerBlockRowGap = getAttribute( 'innerBlockRowGap' ) + + const newAttributes = { + ...attributes, + [ getAttrName( 'containerHeight' ) ]: String( containerHeight ), + [ getAttrName( 'innerBlockRowGap' ) ]: String( innerBlockRowGap ), + } + + return newAttributes + }, +} + diff --git a/src/block-components/alignment/edit.js b/src/block-components/alignment/edit.js index dd02239e32..a6efa2435d 100644 --- a/src/block-components/alignment/edit.js +++ b/src/block-components/alignment/edit.js @@ -13,6 +13,7 @@ import { useBlockAttributesContext, useBlockSetAttributesContext, useDeviceType, + usePresetControls, } from '~stackable/hooks' /** @@ -86,6 +87,9 @@ export const Edit = memo( props => { enableContentAlign = true, } = props + const blockHeightMarks = usePresetControls( 'blockHeights' )?.getPresetMarks() || null + const spacingSizeMarks = usePresetControls( 'spacingSizes' )?.getPresetMarks() || null + const containerSize = props.hasContainerSize && <> { props.hasContainerHeight && @@ -100,6 +104,7 @@ export const Edit = memo( props => { allowReset={ true } placeholder="0" visualGuide={ { selector: '.stk-%s-container', highlight: 'outline' } } + marks={ blockHeightMarks } /> } { highlight: 'row-gap', value: innerBlockRowGap, } } + marks={ spacingSizeMarks } /> } { ( innerBlockOrientation && innerBlockWrap === 'wrap' ) && diff --git a/src/block-components/alignment/index.js b/src/block-components/alignment/index.js index b5c242a374..08e242a83f 100644 --- a/src/block-components/alignment/index.js +++ b/src/block-components/alignment/index.js @@ -4,6 +4,8 @@ import { addStyles } from './style' export * from './use-alignment' +export { deprecateInnerBlockRowGapAndContainerHeight } from './deprecated/index' + export const Alignment = () => { return null } diff --git a/src/block-components/alignment/style.js b/src/block-components/alignment/style.js index 5efa60abf9..7b7258a680 100644 --- a/src/block-components/alignment/style.js +++ b/src/block-components/alignment/style.js @@ -211,8 +211,14 @@ export const addStyles = ( blockStyleGenerator, props = {} ) => { styleRule: 'columnGap', attrName: 'innerBlockColumnGap', key: 'innerBlockColumnGapEdit', - format: `%spx`, responsive: 'all', + valueCallback: value => { + // Substitute with using format to work with preset controls + if ( typeof value === 'string' && value.startsWith( 'var' ) ) { + return value + } + return value + 'px' + }, enabledCallback: getAttribute => getAttribute( 'innerBlockOrientation' ) === 'horizontal', dependencies: [ 'innerBlockOrientation', @@ -225,8 +231,14 @@ export const addStyles = ( blockStyleGenerator, props = {} ) => { styleRule: 'columnGap', attrName: 'innerBlockColumnGap', key: 'innerBlockColumnGapSave', - format: `%spx`, responsive: 'all', + valueCallback: value => { + // Substitute with using format to work with preset controls + if ( typeof value === 'string' && value.startsWith( 'var' ) ) { + return value + } + return value + 'px' + }, enabledCallback: getAttribute => getAttribute( 'innerBlockOrientation' ) === 'horizontal', dependencies: [ 'innerBlockOrientation', @@ -241,12 +253,18 @@ export const addStyles = ( blockStyleGenerator, props = {} ) => { styleRule: 'rowGap', attrName: 'innerBlockRowGap', key: 'innerBlockRowGapEdit', - format: `%spx`, responsive: 'all', enabledCallback: getAttribute => { return getAttribute( 'innerBlockOrientation' ) !== 'horizontal' || ( getAttribute( 'innerBlockOrientation' ) === 'horizontal' && getAttribute( 'innerBlockWrap' ) === 'wrap' ) }, + valueCallback: value => { + // Substitute with using format to work with preset controls + if ( typeof value === 'string' && value.startsWith( 'var' ) ) { + return value + } + return value + 'px' + }, dependencies: [ 'innerBlockOrientation', 'innerBlockWrap', @@ -259,8 +277,14 @@ export const addStyles = ( blockStyleGenerator, props = {} ) => { styleRule: 'rowGap', attrName: 'innerBlockRowGap', key: 'innerBlockRowGapSave', - format: `%spx`, responsive: 'all', + valueCallback: value => { + // Substitute with using format to work with preset controls + if ( typeof value === 'string' && value.startsWith( 'var' ) ) { + return value + } + return value + 'px' + }, enabledCallback: getAttribute => { return getAttribute( 'innerBlockOrientation' ) !== 'horizontal' || ( getAttribute( 'innerBlockOrientation' ) === 'horizontal' && getAttribute( 'innerBlockWrap' ) === 'wrap' ) diff --git a/src/components/advanced-range-control/index.js b/src/components/advanced-range-control/index.js index 874d1c52ed..e36589efdb 100644 --- a/src/components/advanced-range-control/index.js +++ b/src/components/advanced-range-control/index.js @@ -248,8 +248,15 @@ const AdvancedRangeControl = props => { const currentSize = props.marks.find( mark => { return derivedValue === mark.value } )?.size - const [ _newValue, _unit ] = extractNumbersAndUnits( currentSize )[ 0 ] - rangeValue = _newValue + let [ _newValue, _unit ] = extractNumbersAndUnits( currentSize )[ 0 ] + + // If the attribute has no support for rem or em, and the + // preset units is rem or em, convert to px + const converted = convertToPxIfUnsupported( props.units, _unit, _newValue ) + _newValue = converted.value + _unit = converted.unit + + rangeValue = parseFloat( _newValue ) if ( _unit && ! isConversionDone.current ) { dispatch( 'core/block-editor' ).__unstableMarkNextChangeAsNotPersistent() diff --git a/src/components/four-range-control/index.js b/src/components/four-range-control/index.js index 132deb5897..ac2480868b 100644 --- a/src/components/four-range-control/index.js +++ b/src/components/four-range-control/index.js @@ -418,8 +418,15 @@ const FourRangeControl = memo( props => { const currentSize = props.marks.find( mark => { return initialValue === mark.value } )?.size - const [ _newValue, _unit ] = extractNumbersAndUnits( currentSize )[ 0 ] - rangeValue = _newValue + let [ _newValue, _unit ] = extractNumbersAndUnits( currentSize )[ 0 ] + + // If the attribute has no support for rem or em, and the + // preset units is rem or em, convert to px + const converted = convertToPxIfUnsupported( props.units, _unit, _newValue ) + _newValue = converted.value + _unit = converted.unit + + rangeValue = parseFloat( _newValue ) if ( _unit && conversionKey && ! isConversionDone.current[ conversionKey ] ) { isConversionDone.current[ conversionKey ] = true From decb1303f7b60fb0c2152e90d3591df1f5f6c807 Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Thu, 29 May 2025 16:30:48 +0800 Subject: [PATCH 97/99] fix: add deprecation code to affected blocks, including removing V4 --- src/block/call-to-action/deprecated.js | 18 +++++++----------- src/block/card/deprecated.js | 18 +++++++----------- src/block/column/deprecated.js | 20 ++++++++------------ src/block/hero/deprecated.js | 19 +++++++------------ src/block/notification/deprecated.js | 18 +++++++----------- src/block/pricing-box/deprecated.js | 18 +++++++----------- src/block/team-member/deprecated.js | 18 +++++++----------- src/block/testimonial/deprecated.js | 18 +++++++----------- 8 files changed, 57 insertions(+), 90 deletions(-) diff --git a/src/block/call-to-action/deprecated.js b/src/block/call-to-action/deprecated.js index 3a78c5a206..b688a2b550 100644 --- a/src/block/call-to-action/deprecated.js +++ b/src/block/call-to-action/deprecated.js @@ -11,6 +11,7 @@ import { withVersion } from '~stackable/higher-order' import { deprecateBlockBackgroundColorOpacity, deprecateContainerBackgroundColorOpacity, deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateShadowColor, deprecateBlockHeight, + deprecateInnerBlockRowGapAndContainerHeight, } from '~stackable/block-components' import compareVersions from 'compare-versions' @@ -40,9 +41,10 @@ const deprecated = [ attributes: attributes( '3.15.2' ), save: withVersion( '3.15.2' )( Save ), isEligible: attributes => { - const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) - return isNotV4 || hasNumberBlockHeight + const hasNumberInnerBlockRowGapAndContainerHeight = deprecateInnerBlockRowGapAndContainerHeight.isEligible( '%s' )( attributes ) + + return hasNumberBlockHeight || hasNumberInnerBlockRowGapAndContainerHeight }, migrate: ( attributes, innerBlocks ) => { const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' @@ -102,6 +104,7 @@ const deprecated = [ newAttributes = deprecateShadowColor.migrate( 'topSeparator%s' )( newAttributes ) newAttributes = deprecateShadowColor.migrate( 'bottomSeparator%s' )( newAttributes ) newAttributes = deprecateBlockHeight.migrate( newAttributes ) + newAttributes = deprecateInnerBlockRowGapAndContainerHeight.migrate( '%s' )( newAttributes ) return [ newAttributes, innerBlocks ] }, @@ -115,9 +118,8 @@ const deprecated = [ const hasContainerShadow = deprecateContainerShadowColor.isEligible( attributes ) const hasTopSeparatorShadow = deprecateShadowColor.isEligible( 'topSeparator%s' )( attributes ) const hasBottomSeparatorShadow = deprecateShadowColor.isEligible( 'bottomSeparator%s' )( attributes ) - const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' - return hasBlockShadow || hasContainerShadow || hasTopSeparatorShadow || hasBottomSeparatorShadow || isNotV4 + return hasBlockShadow || hasContainerShadow || hasTopSeparatorShadow || hasBottomSeparatorShadow }, migrate: ( attributes, innerBlocks ) => { const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' @@ -187,9 +189,8 @@ const deprecated = [ isEligible: attributes => { const hasContainerOpacity = deprecateContainerBackgroundColorOpacity.isEligible( attributes ) const hasBlockOpacity = deprecateBlockBackgroundColorOpacity.isEligible( attributes ) - const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' - return hasContainerOpacity || hasBlockOpacity || isNotV4 + return hasContainerOpacity || hasBlockOpacity }, migrate: ( attributes, innerBlocks ) => { const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' @@ -257,11 +258,6 @@ const deprecated = [ // layout & containers work. attributes: attributes( '3.7.9' ), save: withVersion( '3.7.9' )( Save ), - isEligible: attributes => { - const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' - - return isNotV4 - }, migrate: ( attributes, innerBlocks ) => { let newAttributes = { ...attributes, diff --git a/src/block/card/deprecated.js b/src/block/card/deprecated.js index d14fc94e23..00fa192487 100644 --- a/src/block/card/deprecated.js +++ b/src/block/card/deprecated.js @@ -13,6 +13,7 @@ import { deprecateBlockBackgroundColorOpacity, deprecateContainerBackgroundColorOpacity, deprecationImageOverlayOpacity, getAlignmentClasses, deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateBlockHeight, + deprecateInnerBlockRowGapAndContainerHeight, } from '~stackable/block-components' /** @@ -91,9 +92,10 @@ const deprecated = [ attributes: attributes( '3.15.2' ), save: withVersion( '3.15.2' )( Save ), isEligible: attributes => { - const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) - return isNotV4 || hasNumberBlockHeight + const hasNumberInnerBlockRowGapAndContainerHeight = deprecateInnerBlockRowGapAndContainerHeight.isEligible( '%s' )( attributes ) + + return hasNumberBlockHeight || hasNumberInnerBlockRowGapAndContainerHeight }, migrate: ( attributes, innerBlocks ) => { const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' @@ -152,6 +154,7 @@ const deprecated = [ newAttributes = deprecateBlockShadowColor.migrate( newAttributes ) newAttributes = deprecateContainerShadowColor.migrate( newAttributes ) newAttributes = deprecateBlockHeight.migrate( newAttributes ) + newAttributes = deprecateInnerBlockRowGapAndContainerHeight.migrate( '%s' )( newAttributes ) return [ newAttributes, innerBlocks ] }, @@ -163,9 +166,8 @@ const deprecated = [ isEligible: attributes => { const hasBlockShadow = deprecateBlockShadowColor.isEligible( attributes ) const hasContainerShadow = deprecateContainerShadowColor.isEligible( attributes ) - const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' - return hasBlockShadow || hasContainerShadow || isNotV4 + return hasBlockShadow || hasContainerShadow }, migrate: ( attributes, innerBlocks ) => { const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' @@ -234,9 +236,8 @@ const deprecated = [ isEligible: attributes => { const hasContainerOpacity = deprecateContainerBackgroundColorOpacity.isEligible( attributes ) const hasBlockOpacity = deprecateBlockBackgroundColorOpacity.isEligible( attributes ) - const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' - return hasContainerOpacity || hasBlockOpacity || isNotV4 || deprecationImageOverlayOpacity.isEligible( attributes ) + return hasContainerOpacity || hasBlockOpacity || deprecationImageOverlayOpacity.isEligible( attributes ) }, migrate: ( attributes, innerBlocks ) => { const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' @@ -303,11 +304,6 @@ const deprecated = [ // layout & containers work. attributes: attributes( '3.7.9' ), save: withVersion( '3.7.9' )( Save ), - isEligible: attributes => { - const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' - - return isNotV4 - }, migrate: ( attributes, innerBlocks ) => { let newAttributes = { ...attributes, diff --git a/src/block/column/deprecated.js b/src/block/column/deprecated.js index dcfaee13c8..2ab93f2c87 100644 --- a/src/block/column/deprecated.js +++ b/src/block/column/deprecated.js @@ -18,6 +18,7 @@ import { semverCompare } from '~stackable/util' import { deprecateBlockBackgroundColorOpacity, deprecateContainerBackgroundColorOpacity, deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateBlockHeight, + deprecateInnerBlockRowGapAndContainerHeight, } from '~stackable/block-components' // Version 3.8 added horizontal flex, we changed the stk--block-orientation-* to stk--block-horizontal-flex. @@ -76,13 +77,14 @@ addFilter( 'stackable.column.save.blockClassNames', 'stackable/3.8.0', ( output, const deprecated = [ { - // Support the change of type for block height + // Support the change of type for block height, innerBlockRowGap and containerHeight attributes: attributes( '3.15.2' ), save: withVersion( '3.15.2' )( Save ), isEligible: attributes => { - const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) - return isNotV4 || hasNumberBlockHeight + const hasNumberInnerBlockRowGapAndContainerHeight = deprecateInnerBlockRowGapAndContainerHeight.isEligible( '%s' )( attributes ) + + return hasNumberBlockHeight || hasNumberInnerBlockRowGapAndContainerHeight }, migrate: ( attributes, innerBlocks ) => { const isNotV4 = attributes.version < 4 || typeof attributes.version === 'undefined' @@ -144,6 +146,7 @@ const deprecated = [ newAttributes = deprecateBlockShadowColor.migrate( newAttributes ) newAttributes = deprecateContainerShadowColor.migrate( newAttributes ) newAttributes = deprecateBlockHeight.migrate( newAttributes ) + newAttributes = deprecateInnerBlockRowGapAndContainerHeight.migrate( '%s' )( newAttributes ) return [ newAttributes, innerBlocks ] }, @@ -155,9 +158,8 @@ const deprecated = [ isEligible: attributes => { const hasBlockShadow = deprecateBlockShadowColor.isEligible( attributes ) const hasContainerShadow = deprecateContainerShadowColor.isEligible( attributes ) - const isNotV4 = attributes.version < 4 || typeof attributes.version === 'undefined' - return hasBlockShadow || hasContainerShadow || isNotV4 + return hasBlockShadow || hasContainerShadow }, migrate: ( attributes, innerBlocks ) => { const isNotV4 = attributes.version < 4 || typeof attributes.version === 'undefined' @@ -229,9 +231,8 @@ const deprecated = [ isEligible: attributes => { const hasContainerOpacity = deprecateContainerBackgroundColorOpacity.isEligible( attributes ) const hasBlockOpacity = deprecateBlockBackgroundColorOpacity.isEligible( attributes ) - const isNotV4 = attributes.version < 4 || typeof attributes.version === 'undefined' - return hasContainerOpacity || hasBlockOpacity || isNotV4 + return hasContainerOpacity || hasBlockOpacity }, migrate: ( attributes, innerBlocks ) => { const isNotV4 = attributes.version < 4 || typeof attributes.version === 'undefined' @@ -301,11 +302,6 @@ const deprecated = [ // layout & containers work. attributes: attributes( '3.7.9' ), save: withVersion( '3.7.9' )( Save ), - isEligible: attributes => { - const isNotV4 = attributes.version < 4 || typeof attributes.version === 'undefined' - - return isNotV4 - }, migrate: ( attributes, innerBlocks ) => { let newAttributes = { ...attributes, diff --git a/src/block/hero/deprecated.js b/src/block/hero/deprecated.js index ad6562c0ab..fd019713fb 100644 --- a/src/block/hero/deprecated.js +++ b/src/block/hero/deprecated.js @@ -12,7 +12,7 @@ import compareVersions from 'compare-versions' import { deprecateBlockBackgroundColorOpacity, deprecateContainerBackgroundColorOpacity, deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateShadowColor, - deprecateBlockHeight, + deprecateBlockHeight, deprecateInnerBlockRowGapAndContainerHeight, } from '~stackable/block-components' /** @@ -41,9 +41,10 @@ const deprecated = [ attributes: attributes( '3.15.2' ), save: withVersion( '3.15.2' )( Save ), isEligible: attributes => { - const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) - return isNotV4 || hasNumberBlockHeight + const hasNumberInnerBlockRowGapAndContainerHeight = deprecateInnerBlockRowGapAndContainerHeight.isEligible( '%s' )( attributes ) + + return hasNumberBlockHeight || hasNumberInnerBlockRowGapAndContainerHeight }, migrate: ( attributes, innerBlocks ) => { const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' @@ -103,6 +104,7 @@ const deprecated = [ newAttributes = deprecateShadowColor.migrate( 'topSeparator%s' )( newAttributes ) newAttributes = deprecateShadowColor.migrate( 'bottomSeparator%s' )( newAttributes ) newAttributes = deprecateBlockHeight.migrate( newAttributes ) + newAttributes = deprecateInnerBlockRowGapAndContainerHeight.migrate( '%s' )( newAttributes ) return newAttributes }, @@ -116,9 +118,8 @@ const deprecated = [ const hasContainerShadow = deprecateContainerShadowColor.isEligible( attributes ) const hasTopSeparatorShadow = deprecateShadowColor.isEligible( 'topSeparator%s' )( attributes ) const hasBottomSeparatorShadow = deprecateShadowColor.isEligible( 'bottomSeparator%s' )( attributes ) - const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' - return hasBlockShadow || hasContainerShadow || hasTopSeparatorShadow || hasBottomSeparatorShadow || isNotV4 + return hasBlockShadow || hasContainerShadow || hasTopSeparatorShadow || hasBottomSeparatorShadow }, migrate: ( attributes, innerBlocks ) => { const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' @@ -188,9 +189,8 @@ const deprecated = [ isEligible: attributes => { const hasContainerOpacity = deprecateContainerBackgroundColorOpacity.isEligible( attributes ) const hasBlockOpacity = deprecateBlockBackgroundColorOpacity.isEligible( attributes ) - const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' - return hasContainerOpacity || hasBlockOpacity || isNotV4 + return hasContainerOpacity || hasBlockOpacity }, migrate: ( attributes, innerBlocks ) => { const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' @@ -258,11 +258,6 @@ const deprecated = [ // layout & containers work. attributes: attributes( '3.7.9' ), save: withVersion( '3.7.9' )( Save ), - isEligible: attributes => { - const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' - - return isNotV4 - }, migrate: ( attributes, innerBlocks ) => { let newAttributes = { ...attributes, diff --git a/src/block/notification/deprecated.js b/src/block/notification/deprecated.js index 694c439735..d6c601299c 100644 --- a/src/block/notification/deprecated.js +++ b/src/block/notification/deprecated.js @@ -12,6 +12,7 @@ import compareVersions from 'compare-versions' import { deprecateBlockBackgroundColorOpacity, deprecateContainerBackgroundColorOpacity, deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateBlockHeight, + deprecateInnerBlockRowGapAndContainerHeight, } from '~stackable/block-components' /** @@ -40,9 +41,10 @@ const deprecated = [ attributes: attributes( '3.15.2' ), save: withVersion( '3.15.2' )( Save ), isEligible: attributes => { - const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) - return isNotV4 || hasNumberBlockHeight + const hasNumberInnerBlockRowGapAndContainerHeight = deprecateInnerBlockRowGapAndContainerHeight.isEligible( '%s' )( attributes ) + + return hasNumberBlockHeight || hasNumberInnerBlockRowGapAndContainerHeight }, migrate: ( attributes, innerBlocks ) => { const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' @@ -100,6 +102,7 @@ const deprecated = [ newAttributes = deprecateBlockShadowColor.migrate( newAttributes ) newAttributes = deprecateContainerShadowColor.migrate( newAttributes ) newAttributes = deprecateBlockHeight.migrate( newAttributes ) + newAttributes = deprecateInnerBlockRowGapAndContainerHeight.migrate( '%s' )( newAttributes ) return newAttributes }, @@ -111,9 +114,8 @@ const deprecated = [ isEligible: attributes => { const hasBlockShadow = deprecateBlockShadowColor.isEligible( attributes ) const hasContainerShadow = deprecateContainerShadowColor.isEligible( attributes ) - const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' - return hasBlockShadow || hasContainerShadow || isNotV4 + return hasBlockShadow || hasContainerShadow }, migrate: ( attributes, innerBlocks ) => { const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' @@ -181,9 +183,8 @@ const deprecated = [ isEligible: attributes => { const hasContainerOpacity = deprecateContainerBackgroundColorOpacity.isEligible( attributes ) const hasBlockOpacity = deprecateBlockBackgroundColorOpacity.isEligible( attributes ) - const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' - return hasContainerOpacity || hasBlockOpacity || isNotV4 + return hasContainerOpacity || hasBlockOpacity }, migrate: ( attributes, innerBlocks ) => { const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' @@ -249,11 +250,6 @@ const deprecated = [ // layout & containers work. attributes: attributes( '3.7.9' ), save: withVersion( '3.7.9' )( Save ), - isEligible: attributes => { - const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' - - return isNotV4 - }, migrate: ( attributes, innerBlocks ) => { let newAttributes = { ...attributes, diff --git a/src/block/pricing-box/deprecated.js b/src/block/pricing-box/deprecated.js index 48d9382153..12c90f6031 100644 --- a/src/block/pricing-box/deprecated.js +++ b/src/block/pricing-box/deprecated.js @@ -12,6 +12,7 @@ import compareVersions from 'compare-versions' import { deprecateBlockBackgroundColorOpacity, deprecateContainerBackgroundColorOpacity, deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateBlockHeight, + deprecateInnerBlockRowGapAndContainerHeight, } from '~stackable/block-components' /** * WordPress dependencies @@ -39,9 +40,10 @@ const deprecated = [ attributes: attributes( '3.15.2' ), save: withVersion( '3.15.2' )( Save ), isEligible: attributes => { - const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) - return isNotV4 || hasNumberBlockHeight + const hasNumberInnerBlockRowGapAndContainerHeight = deprecateInnerBlockRowGapAndContainerHeight.isEligible( '%s' )( attributes ) + + return hasNumberBlockHeight || hasNumberInnerBlockRowGapAndContainerHeight }, migrate: ( attributes, innerBlocks ) => { const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' @@ -99,6 +101,7 @@ const deprecated = [ newAttributes = deprecateBlockShadowColor.migrate( newAttributes ) newAttributes = deprecateContainerShadowColor.migrate( newAttributes ) newAttributes = deprecateBlockHeight.migrate( newAttributes ) + newAttributes = deprecateInnerBlockRowGapAndContainerHeight.migrate( '%s' )( newAttributes ) return newAttributes }, @@ -110,9 +113,8 @@ const deprecated = [ isEligible: attributes => { const hasBlockShadow = deprecateBlockShadowColor.isEligible( attributes ) const hasContainerShadow = deprecateContainerShadowColor.isEligible( attributes ) - const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' - return hasBlockShadow || hasContainerShadow || isNotV4 + return hasBlockShadow || hasContainerShadow }, migrate: ( attributes, innerBlocks ) => { const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' @@ -180,9 +182,8 @@ const deprecated = [ isEligible: attributes => { const hasContainerOpacity = deprecateContainerBackgroundColorOpacity.isEligible( attributes ) const hasBlockOpacity = deprecateBlockBackgroundColorOpacity.isEligible( attributes ) - const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' - return hasContainerOpacity || hasBlockOpacity || isNotV4 + return hasContainerOpacity || hasBlockOpacity }, migrate: ( attributes, innerBlocks ) => { const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' @@ -248,11 +249,6 @@ const deprecated = [ // layout & containers work. attributes: attributes( '3.7.9' ), save: withVersion( '3.7.9' )( Save ), - isEligible: attributes => { - const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' - - return isNotV4 - }, migrate: ( attributes, innerBlocks ) => { let newAttributes = { ...attributes, diff --git a/src/block/team-member/deprecated.js b/src/block/team-member/deprecated.js index 47ec8ffe9f..927f56e118 100644 --- a/src/block/team-member/deprecated.js +++ b/src/block/team-member/deprecated.js @@ -12,6 +12,7 @@ import compareVersions from 'compare-versions' import { deprecateBlockBackgroundColorOpacity, deprecateContainerBackgroundColorOpacity, deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateBlockHeight, + deprecateInnerBlockRowGapAndContainerHeight, } from '~stackable/block-components' /** @@ -40,9 +41,10 @@ const deprecated = [ attributes: attributes( '3.15.2' ), save: withVersion( '3.15.2' )( Save ), isEligible: attributes => { - const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) - return isNotV4 || hasNumberBlockHeight + const hasNumberInnerBlockRowGapAndContainerHeight = deprecateInnerBlockRowGapAndContainerHeight.isEligible( '%s' )( attributes ) + + return hasNumberBlockHeight || hasNumberInnerBlockRowGapAndContainerHeight }, migrate: ( attributes, innerBlocks ) => { const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' @@ -100,6 +102,7 @@ const deprecated = [ newAttributes = deprecateBlockShadowColor.migrate( newAttributes ) newAttributes = deprecateContainerShadowColor.migrate( newAttributes ) newAttributes = deprecateBlockHeight.migrate( newAttributes ) + newAttributes = deprecateInnerBlockRowGapAndContainerHeight.migrate( '%s' )( newAttributes ) return newAttributes }, @@ -111,9 +114,8 @@ const deprecated = [ isEligible: attributes => { const hasBlockShadow = deprecateBlockShadowColor.isEligible( attributes ) const hasContainerShadow = deprecateContainerShadowColor.isEligible( attributes ) - const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' - return hasBlockShadow || hasContainerShadow || isNotV4 + return hasBlockShadow || hasContainerShadow }, migrate: ( attributes, innerBlocks ) => { const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' @@ -181,9 +183,8 @@ const deprecated = [ isEligible: attributes => { const hasContainerOpacity = deprecateContainerBackgroundColorOpacity.isEligible( attributes ) const hasBlockOpacity = deprecateBlockBackgroundColorOpacity.isEligible( attributes ) - const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' - return hasContainerOpacity || hasBlockOpacity || isNotV4 + return hasContainerOpacity || hasBlockOpacity }, migrate: ( attributes, innerBlocks ) => { const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' @@ -249,11 +250,6 @@ const deprecated = [ // layout & containers work. attributes: attributes( '3.7.9' ), save: withVersion( '3.7.9' )( Save ), - isEligible: attributes => { - const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' - - return isNotV4 - }, migrate: ( attributes, innerBlocks ) => { let newAttributes = { ...attributes, diff --git a/src/block/testimonial/deprecated.js b/src/block/testimonial/deprecated.js index df70cb918e..f4d3f83922 100644 --- a/src/block/testimonial/deprecated.js +++ b/src/block/testimonial/deprecated.js @@ -12,6 +12,7 @@ import compareVersions from 'compare-versions' import { deprecateBlockBackgroundColorOpacity, deprecateContainerBackgroundColorOpacity, deprecateBlockShadowColor, deprecateContainerShadowColor, deprecateBlockHeight, + deprecateInnerBlockRowGapAndContainerHeight, } from '~stackable/block-components' /** @@ -40,9 +41,10 @@ const deprecated = [ attributes: attributes( '3.15.2' ), save: withVersion( '3.15.2' )( Save ), isEligible: attributes => { - const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) - return isNotV4 || hasNumberBlockHeight + const hasNumberInnerBlockRowGapAndContainerHeight = deprecateInnerBlockRowGapAndContainerHeight.isEligible( '%s' )( attributes ) + + return hasNumberBlockHeight || hasNumberInnerBlockRowGapAndContainerHeight }, migrate: ( attributes, innerBlocks ) => { const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' @@ -100,6 +102,7 @@ const deprecated = [ newAttributes = deprecateBlockShadowColor.migrate( newAttributes ) newAttributes = deprecateContainerShadowColor.migrate( newAttributes ) newAttributes = deprecateBlockHeight.migrate( newAttributes ) + newAttributes = deprecateInnerBlockRowGapAndContainerHeight.migrate( '%s' )( newAttributes ) return newAttributes }, @@ -111,9 +114,8 @@ const deprecated = [ isEligible: attributes => { const hasBlockShadow = deprecateBlockShadowColor.isEligible( attributes ) const hasContainerShadow = deprecateContainerShadowColor.isEligible( attributes ) - const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' - return hasBlockShadow || hasContainerShadow || isNotV4 + return hasBlockShadow || hasContainerShadow }, migrate: ( attributes, innerBlocks ) => { const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' @@ -181,9 +183,8 @@ const deprecated = [ isEligible: attributes => { const hasContainerOpacity = deprecateContainerBackgroundColorOpacity.isEligible( attributes ) const hasBlockOpacity = deprecateBlockBackgroundColorOpacity.isEligible( attributes ) - const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' - return hasContainerOpacity || hasBlockOpacity || isNotV4 + return hasContainerOpacity || hasBlockOpacity }, migrate: ( attributes, innerBlocks ) => { const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' @@ -249,11 +250,6 @@ const deprecated = [ // layout & containers work. attributes: attributes( '3.7.9' ), save: withVersion( '3.7.9' )( Save ), - isEligible: attributes => { - const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' - - return isNotV4 - }, migrate: ( attributes, innerBlocks ) => { let newAttributes = { ...attributes, From 2159832d1ae61cdd08723ae4e8f5ea709164ea8b Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Thu, 29 May 2025 16:51:06 +0800 Subject: [PATCH 98/99] fix: bump attribute added version to 3.16.0 and migration version to 3.15.3 --- src/block-components/alignment/attributes.js | 2 +- src/block-components/alignment/deprecated/index.js | 2 +- src/block-components/columns/attributes.js | 2 +- src/block-components/columns/deprecated/index.js | 2 +- src/block-components/helpers/size/attributes.js | 2 +- src/block-components/helpers/size/deprecated.js | 2 +- src/block-components/typography/attributes.js | 2 +- src/block-components/typography/deprecated.js | 2 +- src/block/accordion/deprecated.js | 4 ++-- src/block/blockquote/deprecated.js | 4 ++-- src/block/button-group/deprecated/index.js | 4 ++-- src/block/button/deprecated.js | 4 ++-- src/block/call-to-action/deprecated.js | 4 ++-- src/block/card/deprecated.js | 4 ++-- src/block/carousel/deprecated.js | 4 ++-- src/block/column/deprecated.js | 4 ++-- src/block/columns/deprecated.js | 4 ++-- src/block/count-up/deprecated.js | 4 ++-- src/block/countdown/deprecated.js | 4 ++-- src/block/divider/deprecated.js | 4 ++-- src/block/expand/deprecated.js | 4 ++-- src/block/feature-grid/deprecated.js | 4 ++-- src/block/feature/deprecated.js | 4 ++-- src/block/heading/deprecated.js | 4 ++-- src/block/hero/deprecated.js | 4 ++-- src/block/horizontal-scroller/deprecated.js | 4 ++-- src/block/icon-box/deprecated.js | 4 ++-- src/block/icon-button/deprecated.js | 4 ++-- src/block/icon-label/deprecated.js | 4 ++-- src/block/icon-list-item/deprecated.js | 4 ++-- src/block/icon-list/deprecated/index.js | 4 ++-- src/block/icon/deprecated.js | 4 ++-- src/block/image-box/deprecated.js | 4 ++-- src/block/image/deprecated.js | 4 ++-- src/block/map/deprecated.js | 4 ++-- src/block/notification/deprecated.js | 4 ++-- src/block/number-box/deprecated.js | 4 ++-- src/block/posts/deprecated.js | 4 ++-- src/block/price/deprecated.js | 4 ++-- src/block/pricing-box/deprecated.js | 4 ++-- src/block/progress-bar/deprecated.js | 4 ++-- src/block/progress-circle/deprecated.js | 4 ++-- src/block/separator/deprecated.js | 4 ++-- src/block/spacer/deprecated.js | 4 ++-- src/block/subtitle/deprecated.js | 4 ++-- src/block/tab-content/deprecated.js | 4 ++-- src/block/tab-labels/deprecated.js | 4 ++-- src/block/table-of-contents/deprecated.js | 4 ++-- src/block/tabs/deprecated.js | 4 ++-- src/block/team-member/deprecated.js | 4 ++-- src/block/testimonial/deprecated.js | 4 ++-- src/block/text/deprecated.js | 4 ++-- src/block/timeline/deprecated.js | 4 ++-- src/block/video-popup/deprecated.js | 4 ++-- 54 files changed, 100 insertions(+), 100 deletions(-) diff --git a/src/block-components/alignment/attributes.js b/src/block-components/alignment/attributes.js index 1f3ba27f4b..0fb8f5eb1f 100644 --- a/src/block-components/alignment/attributes.js +++ b/src/block-components/alignment/attributes.js @@ -76,7 +76,7 @@ export const addAttributes = ( attrObject, attrNameTemplate = '%s' ) => { }, }, attrNameTemplate, - versionAdded: '3.15.3', + versionAdded: '3.16.0', versionDeprecated: '', } ) } diff --git a/src/block-components/alignment/deprecated/index.js b/src/block-components/alignment/deprecated/index.js index 5bc82ac2ac..1cdd79218b 100644 --- a/src/block-components/alignment/deprecated/index.js +++ b/src/block-components/alignment/deprecated/index.js @@ -11,7 +11,7 @@ export const deprecatedAddAttributes = ( attrObject, attrNameTemplate = '%s' ) = }, attrNameTemplate, versionAdded: '3.0.0', - versionDeprecated: '3.15.3', + versionDeprecated: '3.16.0', } ) } diff --git a/src/block-components/columns/attributes.js b/src/block-components/columns/attributes.js index 87ece45466..0ed1283695 100644 --- a/src/block-components/columns/attributes.js +++ b/src/block-components/columns/attributes.js @@ -34,7 +34,7 @@ export const addAttributes = ( attrObject, attrNameTemplate = '%s' ) => { }, }, attrNameTemplate, - versionAdded: '3.15.3', + versionAdded: '3.16.0', versionDeprecated: '', } ) } diff --git a/src/block-components/columns/deprecated/index.js b/src/block-components/columns/deprecated/index.js index a489565059..75113249f3 100644 --- a/src/block-components/columns/deprecated/index.js +++ b/src/block-components/columns/deprecated/index.js @@ -22,7 +22,7 @@ export const deprecatedAddAttributes = ( attrObject, attrNameTemplate = '%s' ) = }, attrNameTemplate, versionAdded: '3.0.0', - versionDeprecated: '3.15.3', + versionDeprecated: '3.16.0', } ) } diff --git a/src/block-components/helpers/size/attributes.js b/src/block-components/helpers/size/attributes.js index 33f2204c4c..0a3ac2d116 100644 --- a/src/block-components/helpers/size/attributes.js +++ b/src/block-components/helpers/size/attributes.js @@ -52,7 +52,7 @@ export const addSizeAttributes = ( attrObject, attrNameTemplate = '%s' ) => { }, }, attrNameTemplate, - versionAdded: '3.15.3', + versionAdded: '3.16.0', versionDeprecated: '', } ) } diff --git a/src/block-components/helpers/size/deprecated.js b/src/block-components/helpers/size/deprecated.js index 8c2267a187..3871874a00 100644 --- a/src/block-components/helpers/size/deprecated.js +++ b/src/block-components/helpers/size/deprecated.js @@ -12,7 +12,7 @@ export const deprecatedAddAttributes = ( attrObject, attrNameTemplate = '%s' ) = }, attrNameTemplate, versionAdded: '3.0.0', - versionDeprecated: '3.15.3', + versionDeprecated: '3.16.0', } ) } diff --git a/src/block-components/typography/attributes.js b/src/block-components/typography/attributes.js index 3b26b76a3a..c2b5cfc9e3 100644 --- a/src/block-components/typography/attributes.js +++ b/src/block-components/typography/attributes.js @@ -108,7 +108,7 @@ export const addAttributes = ( attrObject, selector = '.stk-content', options = stkUnits: 'px', }, }, - versionAdded: '3.15.3', + versionAdded: '3.16.0', versionDeprecated: '', attrNameTemplate, } ) diff --git a/src/block-components/typography/deprecated.js b/src/block-components/typography/deprecated.js index db634c525c..773034113c 100644 --- a/src/block-components/typography/deprecated.js +++ b/src/block-components/typography/deprecated.js @@ -33,7 +33,7 @@ export const deprecatedAddAttributes = ( attrObject, options ) => { }, }, versionAdded: '3.0.0', - versionDeprecated: '3.15.3', + versionDeprecated: '3.16.0', attrNameTemplate, } ) } diff --git a/src/block/accordion/deprecated.js b/src/block/accordion/deprecated.js index a9ebe51e9e..bce1e02cec 100644 --- a/src/block/accordion/deprecated.js +++ b/src/block/accordion/deprecated.js @@ -10,8 +10,8 @@ import { const deprecated = [ { // Support the change of type for block height - attributes: attributes( '3.15.2' ), - save: withVersion( '3.15.2' )( Save ), + attributes: attributes( '3.15.3' ), + save: withVersion( '3.15.3' )( Save ), isEligible: attributes => { return deprecateBlockHeight.isEligible( attributes ) }, diff --git a/src/block/blockquote/deprecated.js b/src/block/blockquote/deprecated.js index dbd05187c9..ceb5fa453c 100644 --- a/src/block/blockquote/deprecated.js +++ b/src/block/blockquote/deprecated.js @@ -10,8 +10,8 @@ import { const deprecated = [ { // Support the change of type for block height - attributes: attributes( '3.15.2' ), - save: withVersion( '3.15.2' )( Save ), + attributes: attributes( '3.15.3' ), + save: withVersion( '3.15.3' )( Save ), isEligible: attributes => { const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) diff --git a/src/block/button-group/deprecated/index.js b/src/block/button-group/deprecated/index.js index ba4e86cb9a..cc9d3534ad 100644 --- a/src/block/button-group/deprecated/index.js +++ b/src/block/button-group/deprecated/index.js @@ -12,8 +12,8 @@ import { const deprecated = [ { // Support the change of type for block height - attributes: attributes( '3.15.2' ), - save: withVersion( '3.15.2' )( Save ), + attributes: attributes( '3.15.3' ), + save: withVersion( '3.15.3' )( Save ), isEligible: attributes => { return deprecateBlockHeight.isEligible( attributes ) }, diff --git a/src/block/button/deprecated.js b/src/block/button/deprecated.js index 2e11ae544f..f2e6caf5d6 100644 --- a/src/block/button/deprecated.js +++ b/src/block/button/deprecated.js @@ -12,8 +12,8 @@ import { const deprecated = [ { // Support the change of type for fontSize - attributes: attributes( '3.15.2' ), - save: withVersion( '3.15.2' )( Save ), + attributes: attributes( '3.15.3' ), + save: withVersion( '3.15.3' )( Save ), isEligible: attributes => { const hasNumberFontSize = deprecateTypographyFontSize.isEligible( '%s' )( attributes ) const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) diff --git a/src/block/call-to-action/deprecated.js b/src/block/call-to-action/deprecated.js index b688a2b550..d7c8e0c7d4 100644 --- a/src/block/call-to-action/deprecated.js +++ b/src/block/call-to-action/deprecated.js @@ -38,8 +38,8 @@ addFilter( 'stackable.call-to-action.save.innerClassNames', 'stackable/3.8.0', ( const deprecated = [ { // Support the change of type for block height - attributes: attributes( '3.15.2' ), - save: withVersion( '3.15.2' )( Save ), + attributes: attributes( '3.15.3' ), + save: withVersion( '3.15.3' )( Save ), isEligible: attributes => { const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) const hasNumberInnerBlockRowGapAndContainerHeight = deprecateInnerBlockRowGapAndContainerHeight.isEligible( '%s' )( attributes ) diff --git a/src/block/card/deprecated.js b/src/block/card/deprecated.js index 00fa192487..032439e3c5 100644 --- a/src/block/card/deprecated.js +++ b/src/block/card/deprecated.js @@ -89,8 +89,8 @@ addFilter( 'stackable.card.save.innerClassNames', 'stackable/3.0.2', ( output, p const deprecated = [ { // Support the change of type for block height - attributes: attributes( '3.15.2' ), - save: withVersion( '3.15.2' )( Save ), + attributes: attributes( '3.15.3' ), + save: withVersion( '3.15.3' )( Save ), isEligible: attributes => { const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) const hasNumberInnerBlockRowGapAndContainerHeight = deprecateInnerBlockRowGapAndContainerHeight.isEligible( '%s' )( attributes ) diff --git a/src/block/carousel/deprecated.js b/src/block/carousel/deprecated.js index 92bfd20efc..8ad029e728 100644 --- a/src/block/carousel/deprecated.js +++ b/src/block/carousel/deprecated.js @@ -11,8 +11,8 @@ import { withVersion } from '~stackable/higher-order' const deprecated = [ { // Support the change of type for block height and gaps - attributes: attributes( '3.15.2' ), - save: withVersion( '3.15.2' )( Save ), + attributes: attributes( '3.15.3' ), + save: withVersion( '3.15.3' )( Save ), isEligible: attributes => { const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) const hasNumberGaps = deprecateColumnAndRowGap.isEligible( '%s' )( attributes ) diff --git a/src/block/column/deprecated.js b/src/block/column/deprecated.js index 2ab93f2c87..bd56ff8659 100644 --- a/src/block/column/deprecated.js +++ b/src/block/column/deprecated.js @@ -78,8 +78,8 @@ addFilter( 'stackable.column.save.blockClassNames', 'stackable/3.8.0', ( output, const deprecated = [ { // Support the change of type for block height, innerBlockRowGap and containerHeight - attributes: attributes( '3.15.2' ), - save: withVersion( '3.15.2' )( Save ), + attributes: attributes( '3.15.3' ), + save: withVersion( '3.15.3' )( Save ), isEligible: attributes => { const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) const hasNumberInnerBlockRowGapAndContainerHeight = deprecateInnerBlockRowGapAndContainerHeight.isEligible( '%s' )( attributes ) diff --git a/src/block/columns/deprecated.js b/src/block/columns/deprecated.js index a00faef833..2a9a521b85 100644 --- a/src/block/columns/deprecated.js +++ b/src/block/columns/deprecated.js @@ -39,8 +39,8 @@ addFilter( 'stackable.columns.save.contentClassNames', 'stackable/3.8.0', ( clas const deprecated = [ { // Support the change of type for block height and gaps - attributes: attributes( '3.15.2' ), - save: withVersion( '3.15.2' )( Save ), + attributes: attributes( '3.15.3' ), + save: withVersion( '3.15.3' )( Save ), isEligible: attributes => { const hasColumnFit = !! attributes.columnFit const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) diff --git a/src/block/count-up/deprecated.js b/src/block/count-up/deprecated.js index 7c9b21f8c9..f2f6276b34 100644 --- a/src/block/count-up/deprecated.js +++ b/src/block/count-up/deprecated.js @@ -11,8 +11,8 @@ import { const deprecated = [ { // Support the change of type for fontSize and blockHeight - attributes: attributes( '3.15.2' ), - save: withVersion( '3.15.2' )( Save ), + attributes: attributes( '3.15.3' ), + save: withVersion( '3.15.3' )( Save ), isEligible: attributes => { const hasNumberFontSize = deprecateTypographyFontSize.isEligible( '%s' )( attributes ) const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) diff --git a/src/block/countdown/deprecated.js b/src/block/countdown/deprecated.js index 620ddb9ef6..cd79416fee 100644 --- a/src/block/countdown/deprecated.js +++ b/src/block/countdown/deprecated.js @@ -10,8 +10,8 @@ import { withVersion } from '~stackable/higher-order' const deprecated = [ { // Support the change of type for fontSize and blockHeight - attributes: attributes( '3.15.2' ), - save: withVersion( '3.15.2' )( Save ), + attributes: attributes( '3.15.3' ), + save: withVersion( '3.15.3' )( Save ), isEligible: attributes => { const hasDigitFontSize = deprecateTypographyFontSize.isEligible( 'digit%s' )( attributes ) const hasLabelFontSize = deprecateTypographyFontSize.isEligible( 'label%s' )( attributes ) diff --git a/src/block/divider/deprecated.js b/src/block/divider/deprecated.js index 90136ec005..12f770094a 100644 --- a/src/block/divider/deprecated.js +++ b/src/block/divider/deprecated.js @@ -10,8 +10,8 @@ import { const deprecated = [ { // Support the change of type for block height - attributes: attributes( '3.15.2' ), - save: withVersion( '3.15.2' )( Save ), + attributes: attributes( '3.15.3' ), + save: withVersion( '3.15.3' )( Save ), isEligible: attributes => { return deprecateBlockHeight.isEligible( attributes ) }, diff --git a/src/block/expand/deprecated.js b/src/block/expand/deprecated.js index 90136ec005..12f770094a 100644 --- a/src/block/expand/deprecated.js +++ b/src/block/expand/deprecated.js @@ -10,8 +10,8 @@ import { const deprecated = [ { // Support the change of type for block height - attributes: attributes( '3.15.2' ), - save: withVersion( '3.15.2' )( Save ), + attributes: attributes( '3.15.3' ), + save: withVersion( '3.15.3' )( Save ), isEligible: attributes => { return deprecateBlockHeight.isEligible( attributes ) }, diff --git a/src/block/feature-grid/deprecated.js b/src/block/feature-grid/deprecated.js index 46e7ebe17a..54f389c38f 100644 --- a/src/block/feature-grid/deprecated.js +++ b/src/block/feature-grid/deprecated.js @@ -63,8 +63,8 @@ addFilter( 'stackable.feature-grid.save.blockClassNames', 'stackable/3.1.0', ( o const deprecated = [ { // Support the change of type for block height and gaps - attributes: attributes( '3.15.2' ), - save: withVersion( '3.15.2' )( Save ), + attributes: attributes( '3.15.3' ), + save: withVersion( '3.15.3' )( Save ), isEligible: attributes => { const hasColumnFit = !! attributes.columnFit const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) diff --git a/src/block/feature/deprecated.js b/src/block/feature/deprecated.js index 581002a463..8c571f29d9 100644 --- a/src/block/feature/deprecated.js +++ b/src/block/feature/deprecated.js @@ -65,8 +65,8 @@ addFilter( 'stackable.feature.save.innerClassNames', 'stackable/3.8.0', ( output const deprecated = [ { // Support the change of type for block height and gaps - attributes: attributes( '3.15.2' ), - save: withVersion( '3.15.2' )( Save ), + attributes: attributes( '3.15.3' ), + save: withVersion( '3.15.3' )( Save ), isEligible: attributes => { const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) diff --git a/src/block/heading/deprecated.js b/src/block/heading/deprecated.js index 118cfee850..940d743ed1 100644 --- a/src/block/heading/deprecated.js +++ b/src/block/heading/deprecated.js @@ -36,8 +36,8 @@ addFilter( 'stackable.heading.save.blockClassNames', 'stackable/3.6.1', ( output const deprecated = [ { // Support the change of type for fontSize and blockHeight - attributes: attributes( '3.15.2' ), - save: withVersion( '3.15.2' )( Save ), + attributes: attributes( '3.15.3' ), + save: withVersion( '3.15.3' )( Save ), isEligible: attributes => { const hasNumberFontSize = deprecateTypographyFontSize.isEligible( '%s' )( attributes ) const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) diff --git a/src/block/hero/deprecated.js b/src/block/hero/deprecated.js index fd019713fb..6f4530145c 100644 --- a/src/block/hero/deprecated.js +++ b/src/block/hero/deprecated.js @@ -38,8 +38,8 @@ addFilter( 'stackable.hero.save.innerClassNames', 'stackable/3.8.0', ( output, p const deprecated = [ { // Support the change of type for block height - attributes: attributes( '3.15.2' ), - save: withVersion( '3.15.2' )( Save ), + attributes: attributes( '3.15.3' ), + save: withVersion( '3.15.3' )( Save ), isEligible: attributes => { const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) const hasNumberInnerBlockRowGapAndContainerHeight = deprecateInnerBlockRowGapAndContainerHeight.isEligible( '%s' )( attributes ) diff --git a/src/block/horizontal-scroller/deprecated.js b/src/block/horizontal-scroller/deprecated.js index d04b468302..649edab8b7 100644 --- a/src/block/horizontal-scroller/deprecated.js +++ b/src/block/horizontal-scroller/deprecated.js @@ -24,8 +24,8 @@ addFilter( 'stackable.horizontal-scroller.save.contentClassNames', 'stackable/3_ const deprecated = [ { // Support the change of type for block height - attributes: attributes( '3.15.2' ), - save: withVersion( '3.15.2' )( Save ), + attributes: attributes( '3.15.3' ), + save: withVersion( '3.15.3' )( Save ), isEligible: attributes => { return deprecateBlockHeight.isEligible( attributes ) }, diff --git a/src/block/icon-box/deprecated.js b/src/block/icon-box/deprecated.js index c410bb4d6d..e1ccc1cf3c 100644 --- a/src/block/icon-box/deprecated.js +++ b/src/block/icon-box/deprecated.js @@ -10,8 +10,8 @@ import { const deprecated = [ { // Support the change of type for block height - attributes: attributes( '3.15.2' ), - save: withVersion( '3.15.2' )( Save ), + attributes: attributes( '3.15.3' ), + save: withVersion( '3.15.3' )( Save ), isEligible: attributes => { const isNotV4 = attributes.version < 2 || typeof attributes.version === 'undefined' const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) diff --git a/src/block/icon-button/deprecated.js b/src/block/icon-button/deprecated.js index 48f200c0fd..cab6b3f206 100644 --- a/src/block/icon-button/deprecated.js +++ b/src/block/icon-button/deprecated.js @@ -11,8 +11,8 @@ import { const deprecated = [ { // Support the change of type for block height - attributes: attributes( '3.15.2' ), - save: withVersion( '3.15.2' )( Save ), + attributes: attributes( '3.15.3' ), + save: withVersion( '3.15.3' )( Save ), isEligible: attributes => { return deprecateBlockHeight.isEligible( attributes ) }, diff --git a/src/block/icon-label/deprecated.js b/src/block/icon-label/deprecated.js index 1d35507e39..9ae19d5cd8 100644 --- a/src/block/icon-label/deprecated.js +++ b/src/block/icon-label/deprecated.js @@ -10,8 +10,8 @@ import { const deprecated = [ { // Support the change of type for block height - attributes: attributes( '3.15.2' ), - save: withVersion( '3.15.2' )( Save ), + attributes: attributes( '3.15.3' ), + save: withVersion( '3.15.3' )( Save ), isEligible: attributes => { return deprecateBlockHeight.isEligible( attributes ) }, diff --git a/src/block/icon-list-item/deprecated.js b/src/block/icon-list-item/deprecated.js index c6d88e177d..1afa1eaa31 100644 --- a/src/block/icon-list-item/deprecated.js +++ b/src/block/icon-list-item/deprecated.js @@ -9,8 +9,8 @@ import { const deprecated = [ { // Support the change of type for fontSize and blockHeight - attributes: attributes( '3.15.2' ), - save: withVersion( '3.15.2' )( Save ), + attributes: attributes( '3.15.3' ), + save: withVersion( '3.15.3' )( Save ), isEligible: attributes => { const hasNumberFontSize = deprecateTypographyFontSize.isEligible( '%s' )( attributes ) const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) diff --git a/src/block/icon-list/deprecated/index.js b/src/block/icon-list/deprecated/index.js index 9f1a77dcdc..38173ea3cf 100644 --- a/src/block/icon-list/deprecated/index.js +++ b/src/block/icon-list/deprecated/index.js @@ -70,8 +70,8 @@ const getEquivalentIconSize = iconSize => { const deprecated = [ { // Support the change of type for font size and block height - attributes: attributes( '3.15.2' ), - save: withVersion( '3.15.2' )( Save ), + attributes: attributes( '3.15.3' ), + save: withVersion( '3.15.3' )( Save ), isEligible: attributes => { const hasNumberFontSize = deprecateTypographyFontSize.isEligible( '%s' )( attributes ) const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) diff --git a/src/block/icon/deprecated.js b/src/block/icon/deprecated.js index 90136ec005..12f770094a 100644 --- a/src/block/icon/deprecated.js +++ b/src/block/icon/deprecated.js @@ -10,8 +10,8 @@ import { const deprecated = [ { // Support the change of type for block height - attributes: attributes( '3.15.2' ), - save: withVersion( '3.15.2' )( Save ), + attributes: attributes( '3.15.3' ), + save: withVersion( '3.15.3' )( Save ), isEligible: attributes => { return deprecateBlockHeight.isEligible( attributes ) }, diff --git a/src/block/image-box/deprecated.js b/src/block/image-box/deprecated.js index 90136ec005..12f770094a 100644 --- a/src/block/image-box/deprecated.js +++ b/src/block/image-box/deprecated.js @@ -10,8 +10,8 @@ import { const deprecated = [ { // Support the change of type for block height - attributes: attributes( '3.15.2' ), - save: withVersion( '3.15.2' )( Save ), + attributes: attributes( '3.15.3' ), + save: withVersion( '3.15.3' )( Save ), isEligible: attributes => { return deprecateBlockHeight.isEligible( attributes ) }, diff --git a/src/block/image/deprecated.js b/src/block/image/deprecated.js index 976b7cc2c9..94d231f322 100644 --- a/src/block/image/deprecated.js +++ b/src/block/image/deprecated.js @@ -62,8 +62,8 @@ addFilter( 'stackable.image.save.wrapper', 'stackable/image-caption-wrapper', ( const deprecated = [ { // Support the change of type for fontSize - attributes: attributes( '3.15.2' ), - save: withVersion( '3.15.2' )( Save ), + attributes: attributes( '3.15.3' ), + save: withVersion( '3.15.3' )( Save ), isEligible: attributes => { const hasNumberFontSize = deprecateTypographyFontSize.isEligible( 'figcaption%s' )( attributes ) const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) diff --git a/src/block/map/deprecated.js b/src/block/map/deprecated.js index f22f4db86e..06a727f8d6 100644 --- a/src/block/map/deprecated.js +++ b/src/block/map/deprecated.js @@ -37,8 +37,8 @@ addFilter( 'stackable.map.icon-options', 'stackable/3.13.0', ( output, attribute const deprecated = [ { // Support the change of type for block height - attributes: attributes( '3.15.2' ), - save: withVersion( '3.15.2' )( Save ), + attributes: attributes( '3.15.3' ), + save: withVersion( '3.15.3' )( Save ), isEligible: attributes => { return deprecateBlockHeight.isEligible( attributes ) }, diff --git a/src/block/notification/deprecated.js b/src/block/notification/deprecated.js index d6c601299c..7301fc146c 100644 --- a/src/block/notification/deprecated.js +++ b/src/block/notification/deprecated.js @@ -38,8 +38,8 @@ addFilter( 'stackable.notification.save.innerClassNames', 'stackable/3.8.0', ( o const deprecated = [ { // Support the change of type for block height - attributes: attributes( '3.15.2' ), - save: withVersion( '3.15.2' )( Save ), + attributes: attributes( '3.15.3' ), + save: withVersion( '3.15.3' )( Save ), isEligible: attributes => { const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) const hasNumberInnerBlockRowGapAndContainerHeight = deprecateInnerBlockRowGapAndContainerHeight.isEligible( '%s' )( attributes ) diff --git a/src/block/number-box/deprecated.js b/src/block/number-box/deprecated.js index 5dc233b26b..cc3107628a 100644 --- a/src/block/number-box/deprecated.js +++ b/src/block/number-box/deprecated.js @@ -56,8 +56,8 @@ const depecatedSave_3_13_11 = props => { const deprecated = [ { // Support the change of type for fontSize - attributes: attributes( '3.15.2' ), - save: withVersion( '3.15.2' )( Save ), + attributes: attributes( '3.15.3' ), + save: withVersion( '3.15.3' )( Save ), isEligible: attributes => { const hasNumberFontSize = deprecateTypographyFontSize.isEligible( '%s' )( attributes ) const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) diff --git a/src/block/posts/deprecated.js b/src/block/posts/deprecated.js index 0a2b80f225..a46cecb9d7 100644 --- a/src/block/posts/deprecated.js +++ b/src/block/posts/deprecated.js @@ -44,8 +44,8 @@ addFilter( 'stackable.posts.feature-image', 'stackable/3_6_3', determineFeatureI const deprecated = [ { // Support the change of type for fontSize and blockHeight - attributes: attributes( '3.15.2' ), - save: withVersion( '3.15.2' )( Save ), + attributes: attributes( '3.15.3' ), + save: withVersion( '3.15.3' )( Save ), isEligible: attributes => { const hasNumberFontSizeTitle = deprecateTypographyFontSize.isEligible( 'title%s' )( attributes ) const hasNumberFontSizeCategory = deprecateTypographyFontSize.isEligible( 'category%s' )( attributes ) diff --git a/src/block/price/deprecated.js b/src/block/price/deprecated.js index 90136ec005..12f770094a 100644 --- a/src/block/price/deprecated.js +++ b/src/block/price/deprecated.js @@ -10,8 +10,8 @@ import { const deprecated = [ { // Support the change of type for block height - attributes: attributes( '3.15.2' ), - save: withVersion( '3.15.2' )( Save ), + attributes: attributes( '3.15.3' ), + save: withVersion( '3.15.3' )( Save ), isEligible: attributes => { return deprecateBlockHeight.isEligible( attributes ) }, diff --git a/src/block/pricing-box/deprecated.js b/src/block/pricing-box/deprecated.js index 12c90f6031..194bed3fbf 100644 --- a/src/block/pricing-box/deprecated.js +++ b/src/block/pricing-box/deprecated.js @@ -37,8 +37,8 @@ addFilter( 'stackable.pricing-box.save.innerClassNames', 'stackable/3.8.0', ( ou const deprecated = [ { // Support the change of type for block height - attributes: attributes( '3.15.2' ), - save: withVersion( '3.15.2' )( Save ), + attributes: attributes( '3.15.3' ), + save: withVersion( '3.15.3' )( Save ), isEligible: attributes => { const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) const hasNumberInnerBlockRowGapAndContainerHeight = deprecateInnerBlockRowGapAndContainerHeight.isEligible( '%s' )( attributes ) diff --git a/src/block/progress-bar/deprecated.js b/src/block/progress-bar/deprecated.js index 7c9b21f8c9..f2f6276b34 100644 --- a/src/block/progress-bar/deprecated.js +++ b/src/block/progress-bar/deprecated.js @@ -11,8 +11,8 @@ import { const deprecated = [ { // Support the change of type for fontSize and blockHeight - attributes: attributes( '3.15.2' ), - save: withVersion( '3.15.2' )( Save ), + attributes: attributes( '3.15.3' ), + save: withVersion( '3.15.3' )( Save ), isEligible: attributes => { const hasNumberFontSize = deprecateTypographyFontSize.isEligible( '%s' )( attributes ) const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) diff --git a/src/block/progress-circle/deprecated.js b/src/block/progress-circle/deprecated.js index 7c9b21f8c9..f2f6276b34 100644 --- a/src/block/progress-circle/deprecated.js +++ b/src/block/progress-circle/deprecated.js @@ -11,8 +11,8 @@ import { const deprecated = [ { // Support the change of type for fontSize and blockHeight - attributes: attributes( '3.15.2' ), - save: withVersion( '3.15.2' )( Save ), + attributes: attributes( '3.15.3' ), + save: withVersion( '3.15.3' )( Save ), isEligible: attributes => { const hasNumberFontSize = deprecateTypographyFontSize.isEligible( '%s' )( attributes ) const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) diff --git a/src/block/separator/deprecated.js b/src/block/separator/deprecated.js index 69cdb00e89..d5f04d49c5 100644 --- a/src/block/separator/deprecated.js +++ b/src/block/separator/deprecated.js @@ -11,8 +11,8 @@ import { const deprecated = [ { // Support the change of type for block height - attributes: attributes( '3.15.2' ), - save: withVersion( '3.15.2' )( Save ), + attributes: attributes( '3.15.3' ), + save: withVersion( '3.15.3' )( Save ), isEligible: attributes => { return deprecateBlockHeight.isEligible( attributes ) }, diff --git a/src/block/spacer/deprecated.js b/src/block/spacer/deprecated.js index 90136ec005..12f770094a 100644 --- a/src/block/spacer/deprecated.js +++ b/src/block/spacer/deprecated.js @@ -10,8 +10,8 @@ import { const deprecated = [ { // Support the change of type for block height - attributes: attributes( '3.15.2' ), - save: withVersion( '3.15.2' )( Save ), + attributes: attributes( '3.15.3' ), + save: withVersion( '3.15.3' )( Save ), isEligible: attributes => { return deprecateBlockHeight.isEligible( attributes ) }, diff --git a/src/block/subtitle/deprecated.js b/src/block/subtitle/deprecated.js index 809819a1c3..67a57c8e50 100644 --- a/src/block/subtitle/deprecated.js +++ b/src/block/subtitle/deprecated.js @@ -11,8 +11,8 @@ import { const deprecated = [ { // Support the change of type for fontSize and blockHeight - attributes: attributes( '3.15.2' ), - save: withVersion( '3.15.2' )( Save ), + attributes: attributes( '3.15.3' ), + save: withVersion( '3.15.3' )( Save ), isEligible: attributes => { const hasNumberFontSize = deprecateTypographyFontSize.isEligible( '%s' )( attributes ) const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) diff --git a/src/block/tab-content/deprecated.js b/src/block/tab-content/deprecated.js index f9d19b712d..fe39c800d5 100644 --- a/src/block/tab-content/deprecated.js +++ b/src/block/tab-content/deprecated.js @@ -11,8 +11,8 @@ import { withVersion } from '~stackable/higher-order' const deprecated = [ { // Support the change of type for block height and gaps - attributes: attributes( '3.15.2' ), - save: withVersion( '3.15.2' )( Save ), + attributes: attributes( '3.15.3' ), + save: withVersion( '3.15.3' )( Save ), isEligible: attributes => { const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) const hasNumberGaps = deprecateColumnAndRowGap.isEligible( '%s' )( attributes ) diff --git a/src/block/tab-labels/deprecated.js b/src/block/tab-labels/deprecated.js index 8758b25c77..81268855a2 100644 --- a/src/block/tab-labels/deprecated.js +++ b/src/block/tab-labels/deprecated.js @@ -11,8 +11,8 @@ import { withVersion } from '~stackable/higher-order' const deprecated = [ { // Support the change of type for fontSize and blockHeight - attributes: attributes( '3.15.2' ), - save: withVersion( '3.15.2' )( Save ), + attributes: attributes( '3.15.3' ), + save: withVersion( '3.15.3' )( Save ), isEligible: attributes => { const hasNumberFontSize = deprecateTypographyFontSize.isEligible( 'tab%s' )( attributes ) const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) diff --git a/src/block/table-of-contents/deprecated.js b/src/block/table-of-contents/deprecated.js index e5af95f982..b1e3ebcdd5 100644 --- a/src/block/table-of-contents/deprecated.js +++ b/src/block/table-of-contents/deprecated.js @@ -38,8 +38,8 @@ addFilter( 'stackable.table-of-contents.save.tableOfContentsClasses', 'stackable const deprecated = [ { // Support the change of type for fontSize and blockHeight - attributes: attributes( '3.15.2' ), - save: withVersion( '3.15.2' )( Save ), + attributes: attributes( '3.15.3' ), + save: withVersion( '3.15.3' )( Save ), isEligible: attributes => { const hasNumberFontSize = deprecateTypographyFontSize.isEligible( 'title%s' )( attributes ) const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) diff --git a/src/block/tabs/deprecated.js b/src/block/tabs/deprecated.js index a9574ef754..5935646d95 100644 --- a/src/block/tabs/deprecated.js +++ b/src/block/tabs/deprecated.js @@ -10,8 +10,8 @@ import { withVersion } from '~stackable/higher-order' const deprecated = [ { // Support the change of type for block height - attributes: attributes( '3.15.2' ), - save: withVersion( '3.15.2' )( Save ), + attributes: attributes( '3.15.3' ), + save: withVersion( '3.15.3' )( Save ), isEligible: attributes => { return deprecateBlockHeight.isEligible( attributes ) }, diff --git a/src/block/team-member/deprecated.js b/src/block/team-member/deprecated.js index 927f56e118..5b53977354 100644 --- a/src/block/team-member/deprecated.js +++ b/src/block/team-member/deprecated.js @@ -38,8 +38,8 @@ addFilter( 'stackable.team-member.save.innerClassNames', 'stackable/3.8.0', ( ou const deprecated = [ { // Support the change of type for block height - attributes: attributes( '3.15.2' ), - save: withVersion( '3.15.2' )( Save ), + attributes: attributes( '3.15.3' ), + save: withVersion( '3.15.3' )( Save ), isEligible: attributes => { const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) const hasNumberInnerBlockRowGapAndContainerHeight = deprecateInnerBlockRowGapAndContainerHeight.isEligible( '%s' )( attributes ) diff --git a/src/block/testimonial/deprecated.js b/src/block/testimonial/deprecated.js index f4d3f83922..c2223e61da 100644 --- a/src/block/testimonial/deprecated.js +++ b/src/block/testimonial/deprecated.js @@ -38,8 +38,8 @@ addFilter( 'stackable.testimonial.save.innerClassNames', 'stackable/3.8.0', ( ou const deprecated = [ { // Support the change of type for block height - attributes: attributes( '3.15.2' ), - save: withVersion( '3.15.2' )( Save ), + attributes: attributes( '3.15.3' ), + save: withVersion( '3.15.3' )( Save ), isEligible: attributes => { const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) const hasNumberInnerBlockRowGapAndContainerHeight = deprecateInnerBlockRowGapAndContainerHeight.isEligible( '%s' )( attributes ) diff --git a/src/block/text/deprecated.js b/src/block/text/deprecated.js index 229a66c427..09db68cd5f 100644 --- a/src/block/text/deprecated.js +++ b/src/block/text/deprecated.js @@ -11,8 +11,8 @@ import { const deprecated = [ { // Support the change of type for fontSize - attributes: attributes( '3.15.2' ), - save: withVersion( '3.15.2' )( Save ), + attributes: attributes( '3.15.3' ), + save: withVersion( '3.15.3' )( Save ), isEligible: attributes => { const hasNumberFontSize = deprecateTypographyFontSize.isEligible( '%s' )( attributes ) const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) diff --git a/src/block/timeline/deprecated.js b/src/block/timeline/deprecated.js index 6b7f581bae..c4979c84ac 100644 --- a/src/block/timeline/deprecated.js +++ b/src/block/timeline/deprecated.js @@ -11,8 +11,8 @@ import { withVersion } from '~stackable/higher-order' const deprecated = [ { // Support the change of type for fontSize - attributes: attributes( '3.15.2' ), - save: withVersion( '3.15.2' )( Save ), + attributes: attributes( '3.15.3' ), + save: withVersion( '3.15.3' )( Save ), isEligible: attributes => { const hasNumberFontSize = deprecateTypographyFontSize.isEligible( '%s' )( attributes ) const hasNumberBlockHeight = deprecateBlockHeight.isEligible( attributes ) diff --git a/src/block/video-popup/deprecated.js b/src/block/video-popup/deprecated.js index 1a0131f3b1..471924dfde 100644 --- a/src/block/video-popup/deprecated.js +++ b/src/block/video-popup/deprecated.js @@ -30,8 +30,8 @@ addFilter( 'stackable.video-popup.save.div.content', 'stackable/3.12.14', ( outp const deprecated = [ { // Support the change of type for block height - attributes: attributes( '3.15.2' ), - save: withVersion( '3.15.2' )( Save ), + attributes: attributes( '3.15.3' ), + save: withVersion( '3.15.3' )( Save ), isEligible: attributes => { return deprecateBlockHeight.isEligible( attributes ) }, From f3d9cca98b2896d45a5b5a5f2cd0acd15f0d9faa Mon Sep 17 00:00:00 2001 From: Benjamin Intal Date: Fri, 30 May 2025 09:17:27 +0800 Subject: [PATCH 99/99] Added translation Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/block-components/helpers/size/edit.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/block-components/helpers/size/edit.js b/src/block-components/helpers/size/edit.js index cdc72260b2..7d547355e7 100644 --- a/src/block-components/helpers/size/edit.js +++ b/src/block-components/helpers/size/edit.js @@ -140,7 +140,7 @@ const Spacing = props => { // Add additional presets for setting margins and paddings to None const nonePreset = { - name: 'None', + name: __( 'None', i18n ), size: '0rem', slug: 'none', }