diff --git a/inc/class-base-css.php b/inc/class-base-css.php index b9c046b8d..8d804cc3b 100644 --- a/inc/class-base-css.php +++ b/inc/class-base-css.php @@ -202,6 +202,54 @@ public static function hex2rgba( $color, $opacity = false ) { return $output; } + /** + * Convert a color slug to a CSS variable reference. + * WordPress generates CSS variables in the format: --wp--preset--color--{slug} + * + * @param string|null $slug The color slug. + * @return string|null The CSS variable reference. + * @since 3.1.5 + * @access public + */ + public static function get_color_css_variable( $slug ) { + if ( empty( $slug ) ) { + return $slug; + } + + // If it's already a color value or CSS variable, return as-is. + if ( + strpos( $slug, '#' ) === 0 || + strpos( $slug, 'rgb' ) === 0 || + strpos( $slug, 'hsl' ) === 0 || + strpos( $slug, 'var(' ) === 0 + ) { + return $slug; + } + + // Sanitize slug: WordPress slugs should only contain lowercase alphanumeric, hyphens, and underscores. + // This prevents potential CSS injection if slug comes from untrusted sources. + $sanitized_slug = strtolower( preg_replace( '/[^a-z0-9-_]/', '', $slug ) ); + + // Convert slug to CSS variable. + return 'var(--wp--preset--color--' . $sanitized_slug . ')'; + } + + /** + * Resolve a color value which may be a slug from the theme color palette. + * This function converts slugs to CSS variables to preserve the connection to theme.json. + * If the value is a slug, it returns a CSS variable reference. + * Otherwise, returns the value as-is (for hex, rgb, hsl values). + * + * @param string|null $value The color value or slug. + * @return string|null The CSS variable or color value. + * @since 3.1.5 + * @access public + */ + public static function resolve_color_value( $value ) { + // Use CSS variable conversion for slugs. + return self::get_color_css_variable( $value ); + } + /** * Get Blocks CSS * diff --git a/inc/css/blocks/class-advanced-column-css.php b/inc/css/blocks/class-advanced-column-css.php index 1cd53a63d..b152db00c 100644 --- a/inc/css/blocks/class-advanced-column-css.php +++ b/inc/css/blocks/class-advanced-column-css.php @@ -188,6 +188,9 @@ function ( $value ) use ( $block ) { array( 'property' => '--background-color-hover', 'value' => 'backgroundColorHover', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, ), array( 'property' => 'align-self', diff --git a/inc/css/blocks/class-advanced-heading-css.php b/inc/css/blocks/class-advanced-heading-css.php index 452c9ed4f..f7d25452f 100644 --- a/inc/css/blocks/class-advanced-heading-css.php +++ b/inc/css/blocks/class-advanced-heading-css.php @@ -44,10 +44,16 @@ public function render_css( $block ) { array( 'property' => 'color', 'value' => 'headingColor', + 'format' => function ( $value, $attrs ) { + return Base_CSS::resolve_color_value( $value ); + }, ), array( 'property' => 'background', 'value' => 'backgroundColor', + 'format' => function ( $value, $attrs ) { + return Base_CSS::resolve_color_value( $value ); + }, ), array( 'property' => 'font-family', @@ -225,10 +231,16 @@ public function render_css( $block ) { array( 'property' => 'color', 'value' => 'highlightColor', + 'format' => function ( $value, $attrs ) { + return Base_CSS::resolve_color_value( $value ); + }, ), array( 'property' => 'background', 'value' => 'highlightBackground', + 'format' => function ( $value, $attrs ) { + return Base_CSS::resolve_color_value( $value ); + }, ), ); @@ -537,6 +549,9 @@ public function render_css( $block ) { array( 'property' => 'color', 'value' => 'linkColor', + 'format' => function ( $value, $attrs ) { + return Base_CSS::resolve_color_value( $value ); + }, ), ), ) @@ -549,6 +564,9 @@ public function render_css( $block ) { array( 'property' => 'color', 'value' => 'linkHoverColor', + 'format' => function ( $value, $attrs ) { + return Base_CSS::resolve_color_value( $value ); + }, ), ), ) diff --git a/inc/css/blocks/class-button-css.php b/inc/css/blocks/class-button-css.php index 0b5fdb44e..ec8a67437 100644 --- a/inc/css/blocks/class-button-css.php +++ b/inc/css/blocks/class-button-css.php @@ -135,11 +135,17 @@ public function render_css( $block ) { 'property' => 'color', 'value' => 'color', 'hasSync' => 'gr-btn-color', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, ), array( 'property' => 'background', 'value' => 'background', 'hasSync' => 'gr-btn-background', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, ), array( 'property' => 'background', @@ -150,6 +156,9 @@ public function render_css( $block ) { 'property' => 'border-color', 'value' => 'border', 'hasSync' => 'gr-btn-border-color', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, ), array( 'property' => 'box-shadow', @@ -201,11 +210,17 @@ public function render_css( $block ) { 'property' => 'color', 'value' => 'hoverColor', 'hasSync' => 'gr-btn-color-hover', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, ), array( 'property' => 'background', 'value' => 'hoverBackground', 'hasSync' => 'gr-btn-background-hover', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, ), array( 'property' => 'background', @@ -216,6 +231,9 @@ public function render_css( $block ) { 'property' => 'border-color', 'value' => 'hoverBorder', 'hasSync' => 'gr-btn-border-color-hover', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, ), array( 'property' => 'box-shadow', @@ -298,10 +316,16 @@ public function render_global_css() { array( 'property' => '--gr-btn-color', 'value' => 'color', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, ), array( 'property' => '--gr-btn-background', 'value' => 'background', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, ), array( 'property' => '--gr-btn-background', @@ -336,6 +360,9 @@ public function render_global_css() { array( 'property' => '--gr-btn-border-color', 'value' => 'border', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, 'condition' => function ( $attrs ) { return isset( $attrs['border'] ) && ! empty( $attrs['border'] ); }, @@ -421,10 +448,16 @@ public function render_global_css() { array( 'property' => '--gr-btn-color-hover', 'value' => 'hoverColor', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, ), array( 'property' => '--gr-btn-background-hover', 'value' => 'hoverBackground', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, ), array( 'property' => '--gr-btn-background-hover', @@ -433,6 +466,9 @@ public function render_global_css() { array( 'property' => '--gr-btn-border-color-hover', 'value' => 'hoverBorder', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, ), array( 'property' => '--gr-btn-shadow-hover', diff --git a/inc/css/blocks/class-circle-counter-css.php b/inc/css/blocks/class-circle-counter-css.php index 0533f3a86..913a79baa 100644 --- a/inc/css/blocks/class-circle-counter-css.php +++ b/inc/css/blocks/class-circle-counter-css.php @@ -67,10 +67,10 @@ public function render_css( $block ) { $percentage = isset( $attrs['percentage'] ) ? $attrs['percentage'] : 50; if ( 50 > $percentage ) { - return isset( $attrs['progressColor'] ) ? $attrs['progressColor'] : '#3878ff'; + return isset( $attrs['progressColor'] ) ? Base_CSS::resolve_color_value( $attrs['progressColor'] ) : '#3878ff'; } - return $value; + return Base_CSS::resolve_color_value( $value ); }, ), array( @@ -80,10 +80,10 @@ public function render_css( $block ) { $percentage = isset( $attrs['percentage'] ) ? $attrs['percentage'] : 50; if ( 50 > $percentage ) { - return isset( $attrs['backgroundColor'] ) ? $attrs['backgroundColor'] : '#4682b426'; + return isset( $attrs['backgroundColor'] ) ? Base_CSS::resolve_color_value( $attrs['backgroundColor'] ) : '#4682b426'; } - return $value; + return Base_CSS::resolve_color_value( $value ); }, ), array( @@ -132,6 +132,9 @@ public function render_css( $block ) { array( 'property' => 'color', 'value' => 'titleColor', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, ), ), ) @@ -144,6 +147,9 @@ public function render_css( $block ) { array( 'property' => 'color', 'value' => 'progressColor', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, ), ), ) diff --git a/inc/css/blocks/class-countdown-css.php b/inc/css/blocks/class-countdown-css.php index d8a5d1373..178eb9b24 100644 --- a/inc/css/blocks/class-countdown-css.php +++ b/inc/css/blocks/class-countdown-css.php @@ -78,10 +78,16 @@ public function render_css( $block ) { array( 'property' => '--background-color', 'value' => 'backgroundColor', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, ), array( 'property' => '--border-color', 'value' => 'borderColor', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, ), array( 'property' => '--border-style', @@ -279,6 +285,9 @@ public function render_css( $block ) { array( 'property' => 'color', 'value' => 'valueColor', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, ), ), ) @@ -291,6 +300,9 @@ public function render_css( $block ) { array( 'property' => 'color', 'value' => 'labelColor', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, ), ), ) @@ -303,6 +315,9 @@ public function render_css( $block ) { array( 'property' => 'color', 'value' => 'separatorColor', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, ), ), ) diff --git a/inc/css/blocks/class-flip-css.php b/inc/css/blocks/class-flip-css.php index 0332c679b..a06fd8c3d 100644 --- a/inc/css/blocks/class-flip-css.php +++ b/inc/css/blocks/class-flip-css.php @@ -96,6 +96,9 @@ public function render_css( $block ) { array( 'property' => '--border-color', 'value' => 'borderColor', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, ), array( 'property' => '--border-width', @@ -136,6 +139,9 @@ public function render_css( $block ) { array( 'property' => '--front-background', 'value' => 'frontBackgroundColor', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, 'condition' => function ( $attrs ) { return ! isset( $attrs['frontBackgroundType'] ); }, @@ -198,6 +204,9 @@ public function render_css( $block ) { array( 'property' => '--back-background', 'value' => 'backBackgroundColor', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, 'condition' => function ( $attrs ) { return ! isset( $attrs['backBackgroundType'] ); }, @@ -373,6 +382,9 @@ public function render_css( $block ) { array( 'property' => 'color', 'value' => 'titleColor', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, ), array( 'property' => 'font-size', @@ -392,6 +404,9 @@ public function render_css( $block ) { array( 'property' => 'color', 'value' => 'descriptionColor', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, ), array( 'property' => 'font-size', diff --git a/inc/css/blocks/class-font-awesome-icons-css.php b/inc/css/blocks/class-font-awesome-icons-css.php index b9381d110..d3008897e 100644 --- a/inc/css/blocks/class-font-awesome-icons-css.php +++ b/inc/css/blocks/class-font-awesome-icons-css.php @@ -86,6 +86,9 @@ public function render_css( $block ) { array( 'property' => '--border-color', 'value' => 'borderColor', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, ), array( 'property' => '--border-size', @@ -156,11 +159,17 @@ public function render_css( $block ) { array( 'property' => 'color', 'value' => 'textColor', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, 'hasSync' => 'icon-text-color', ), array( 'property' => 'background', 'value' => 'backgroundColor', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, 'hasSync' => 'icon-background-color', ), ), @@ -174,6 +183,9 @@ public function render_css( $block ) { array( 'property' => 'color', 'value' => 'textColorHover', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, 'condition' => function ( $attrs ) { return ! ( isset( $attrs['library'] ) && 'themeisle-icons' === $this->get_attr_value( $attrs['library'], 'fontawesome' ) ); }, @@ -182,11 +194,17 @@ public function render_css( $block ) { array( 'property' => 'background', 'value' => 'backgroundColorHover', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, 'hasSync' => 'icon-background-color-hover', ), array( 'property' => 'border-color', 'value' => 'borderColorHover', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, 'hasSync' => 'iconBorderColorHover', ), ), @@ -200,6 +218,9 @@ public function render_css( $block ) { array( 'property' => 'color', 'value' => 'textColor', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, 'condition' => function ( $attrs ) { return ! ( isset( $attrs['library'] ) && 'themeisle-icons' === $this->get_attr_value( $attrs['library'], 'fontawesome' ) ); }, @@ -216,6 +237,9 @@ public function render_css( $block ) { array( 'property' => 'fill', 'value' => 'textColor', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, 'condition' => function ( $attrs ) { return isset( $attrs['library'] ) && 'themeisle-icons' === $this->get_attr_value( $attrs['library'], 'fontawesome' ); }, @@ -232,6 +256,9 @@ public function render_css( $block ) { array( 'property' => 'fill', 'value' => 'textColorHover', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, 'condition' => function ( $attrs ) { return isset( $attrs['library'] ) && 'themeisle-icons' === $this->get_attr_value( $attrs['library'], 'fontawesome' ); }, @@ -297,18 +324,30 @@ public function render_global_css() { array( 'property' => '--icon-text-color-hover', 'value' => 'textColorHover', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, ), array( 'property' => '--icon-background-color-hover', 'value' => 'backgroundColorHover', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, ), array( 'property' => '--icon-text-color', 'value' => 'textColor', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, ), array( 'property' => '--icon-background-color', 'value' => 'backgroundColor', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, ), ), ) diff --git a/inc/css/blocks/class-popup-css.php b/inc/css/blocks/class-popup-css.php index 75b33ee51..dc9880fc6 100644 --- a/inc/css/blocks/class-popup-css.php +++ b/inc/css/blocks/class-popup-css.php @@ -56,14 +56,23 @@ public function render_css( $block ) { array( 'property' => '--background-color', 'value' => 'backgroundColor', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, ), array( 'property' => '--close-color', 'value' => 'closeColor', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, ), array( 'property' => '--overlay-color', 'value' => 'overlayColor', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, ), array( 'property' => '--overlay-opacity', @@ -89,6 +98,9 @@ public function render_css( $block ) { array( 'property' => '--brd-color', 'value' => 'borderColor', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, ), array( 'property' => '--brd-style', diff --git a/inc/css/blocks/class-posts-css.php b/inc/css/blocks/class-posts-css.php index 377d08a78..19da67532 100644 --- a/inc/css/blocks/class-posts-css.php +++ b/inc/css/blocks/class-posts-css.php @@ -57,10 +57,16 @@ public function render_css( $block ) { array( 'property' => '--text-color', 'value' => 'textColor', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, ), array( 'property' => '--background-color', 'value' => 'backgroundColor', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, ), array( 'property' => '--background-overlay', @@ -69,6 +75,9 @@ public function render_css( $block ) { array( 'property' => '--border-color', 'value' => 'borderColor', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, ), array( 'property' => '--title-text-size', diff --git a/inc/css/blocks/class-progress-bar-css.php b/inc/css/blocks/class-progress-bar-css.php index 363c88fd8..d615a9df3 100644 --- a/inc/css/blocks/class-progress-bar-css.php +++ b/inc/css/blocks/class-progress-bar-css.php @@ -47,10 +47,16 @@ public function render_css( $block ) { array( 'property' => '--title-color', 'value' => 'titleColor', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, ), array( 'property' => '--percentage-color', 'value' => 'percentageColor', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, 'condition' => function ( $attrs ) { return ! isset( $attrs['percentagePosition'] ); }, @@ -58,6 +64,9 @@ public function render_css( $block ) { array( 'property' => '--percentage-color-outer', 'value' => 'percentageColor', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, 'condition' => function ( $attrs ) { return isset( $attrs['percentagePosition'] ) && 'outer' === $attrs['percentagePosition']; }, @@ -65,6 +74,9 @@ public function render_css( $block ) { array( 'property' => '--percentage-color-tooltip', 'value' => 'percentageColor', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, 'condition' => function ( $attrs ) { return isset( $attrs['percentagePosition'] ) && 'tooltip' === $attrs['percentagePosition']; }, @@ -72,6 +84,9 @@ public function render_css( $block ) { array( 'property' => '--percentage-color-append', 'value' => 'percentageColor', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, 'condition' => function ( $attrs ) { return isset( $attrs['percentagePosition'] ) && 'append' === $attrs['percentagePosition']; }, @@ -79,6 +94,9 @@ public function render_css( $block ) { array( 'property' => '--background-color', 'value' => 'backgroundColor', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, ), array( 'property' => '--border-radius', @@ -93,6 +111,9 @@ public function render_css( $block ) { array( 'property' => '--bar-background', 'value' => 'barBackgroundColor', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, ), array( 'property' => '--title-font-size', diff --git a/inc/css/blocks/class-review-css.php b/inc/css/blocks/class-review-css.php index 5340a5b73..888a21f70 100644 --- a/inc/css/blocks/class-review-css.php +++ b/inc/css/blocks/class-review-css.php @@ -79,41 +79,65 @@ public function render_css( $block ) { array( 'property' => '--background-color', 'value' => 'backgroundColor', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, 'hasSync' => 'review-background-color', ), array( 'property' => '--primary-color', 'value' => 'primaryColor', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, 'hasSync' => 'review-primary-color', ), array( 'property' => '--text-color', 'value' => 'textColor', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, 'hasSync' => 'review-text-color', ), array( 'property' => '--button-text-color', 'value' => 'buttonTextColor', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, 'hasSync' => 'review-button-text-color', ), array( 'property' => '--border-color', 'value' => 'borderColor', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, 'hasSync' => 'review-border-color', ), array( 'property' => '--stars-color', 'value' => 'starsColor', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, 'hasSync' => 'review-stars-color', ), array( 'property' => '--pros-color', 'value' => 'prosColor', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, 'hasSync' => 'review-pros-color', ), array( 'property' => '--cons-color', 'value' => 'consColor', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, 'hasSync' => 'review-cons-color', ), array( @@ -225,34 +249,58 @@ public function render_global_css() { array( 'property' => '--review-background-color', 'value' => 'backgroundColor', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, ), array( 'property' => '--review-primary-color', 'value' => 'primaryColor', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, ), array( 'property' => '--review-text-color', 'value' => 'textColor', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, ), array( 'property' => '--review-button-text-color', 'value' => 'buttonTextColor', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, ), array( 'property' => '--review-stars-color', 'value' => 'starsColor', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, ), array( 'property' => '--review-border-color', 'value' => 'borderColor', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, ), array( 'property' => '--review-pros-color', 'value' => 'prosColor', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, ), array( 'property' => '--review-cons-color', 'value' => 'consColor', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, ), ), ) diff --git a/inc/css/blocks/class-shared-css.php b/inc/css/blocks/class-shared-css.php index 75a40bcd4..25e7cc98d 100644 --- a/inc/css/blocks/class-shared-css.php +++ b/inc/css/blocks/class-shared-css.php @@ -22,18 +22,30 @@ public static function section_shared() { array( 'property' => '--text-color', 'value' => 'color', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, ), array( 'property' => '--link-color', 'value' => 'linkColor', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, ), array( 'property' => '--content-color-hover', 'value' => 'colorHover', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, ), array( 'property' => '--background', 'value' => 'backgroundColor', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, 'condition' => function ( $attrs ) { return ! ( isset( $attrs['backgroundType'] ) && 'color' !== $attrs['backgroundType'] ); }, @@ -209,6 +221,9 @@ public static function section_shared() { array( 'property' => 'border-color', 'value' => 'borderColor', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, 'condition' => function ( $attrs ) { return isset( $attrs['border'] ) && is_array( $attrs['border'] ); }, @@ -278,16 +293,18 @@ public static function section_shared() { 'value' => 'boxShadowColor', 'default' => '#000', 'format' => function ( $value, $attrs ) { + $resolved = Base_CSS::resolve_color_value( $value ); + if ( ! isset( $attrs['boxShadowColorOpacity'] ) ) { - return $value; + return $resolved; } if ( 100 === $attrs['boxShadowColorOpacity'] ) { - return $value; + return $resolved; } $opacity = ( isset( $attrs['boxShadowColorOpacity'] ) ? $attrs['boxShadowColorOpacity'] : 50 ) / 100; - return Base_CSS::hex2rgba( $value, $opacity ); + return Base_CSS::hex2rgba( $resolved, $opacity ); }, ), ), @@ -308,6 +325,9 @@ public static function section_overlay() { array( 'property' => 'background', 'value' => 'backgroundOverlayColor', + 'format' => function ( $value ) { + return Base_CSS::resolve_color_value( $value ); + }, 'condition' => function ( $attrs ) { return ! ( isset( $attrs['backgroundOverlayType'] ) && 'color' !== $attrs['backgroundOverlayType'] ); }, diff --git a/inc/css/blocks/class-sharing-icons-css.php b/inc/css/blocks/class-sharing-icons-css.php index 76931d1cc..560c50c2e 100644 --- a/inc/css/blocks/class-sharing-icons-css.php +++ b/inc/css/blocks/class-sharing-icons-css.php @@ -43,7 +43,7 @@ public function render_css( $block ) { 'property' => '--icon-bg-color', 'value' => $icon, 'format' => function ( $value, $attrs ) { - return $value['backgroundColor']; + return Base_CSS::resolve_color_value( $value['backgroundColor'] ); }, 'condition' => function ( $attrs ) use ( $icon ) { return isset( $attrs[ $icon ]['backgroundColor'] ); @@ -53,7 +53,7 @@ public function render_css( $block ) { 'property' => '--text-color', 'value' => $icon, 'format' => function ( $value, $attrs ) { - return $value['textColor']; + return Base_CSS::resolve_color_value( $value['textColor'] ); }, 'condition' => function ( $attrs ) use ( $icon ) { return isset( $attrs[ $icon ]['textColor'] ); diff --git a/package-lock.json b/package-lock.json index 9ec5060b1..0a52ec34b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -182,6 +182,7 @@ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.27.1.tgz", "integrity": "sha512-IaaGWsQqfsQWVLqMn9OB92MNN7zukfVA4s7KKAI0KfrrDsZ0yhi5uV4baBuLuN7n3vsZpwP8asPPcVwApxvjBQ==", "dev": true, + "peer": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.27.1", @@ -2043,6 +2044,7 @@ } ], "license": "MIT", + "peer": true, "engines": { "node": ">=18" }, @@ -2066,6 +2068,7 @@ } ], "license": "MIT", + "peer": true, "engines": { "node": ">=18" } @@ -2191,6 +2194,7 @@ "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.14.0.tgz", "integrity": "sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA==", "dev": true, + "peer": true, "dependencies": { "@babel/runtime": "^7.18.3", "@emotion/babel-plugin": "^11.13.5", @@ -3721,6 +3725,7 @@ "resolved": "https://registry.npmjs.org/@octokit/core/-/core-4.2.4.tgz", "integrity": "sha512-rYKilwgzQ7/imScn3M9/pFfUf4I1AZEH3KhyJmtPdE2zfaXAn2mFfUy4FbKewzc2We5y/LlKLj36fWJLKC2SIQ==", "dev": true, + "peer": true, "dependencies": { "@octokit/auth-token": "^3.0.0", "@octokit/graphql": "^5.0.0", @@ -4196,6 +4201,7 @@ "integrity": "sha512-IVAh/nOJaw6W9g+RJVlIQJ6gSiER+ae6mKQ5CX1bERzQgbC1VSeBlwdvczT7pxb0GWiyrxH4TGKbMfDb4Sq/ig==", "dev": true, "license": "Apache-2.0", + "peer": true, "dependencies": { "playwright": "1.55.1" }, @@ -5461,6 +5467,7 @@ "resolved": "https://registry.npmjs.org/@svgr/core/-/core-8.1.0.tgz", "integrity": "sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==", "dev": true, + "peer": true, "dependencies": { "@babel/core": "^7.21.3", "@svgr/babel-preset": "8.1.0", @@ -5826,8 +5833,7 @@ "version": "5.0.4", "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", - "dev": true, - "peer": true + "dev": true }, "node_modules/@types/babel__core": { "version": "7.20.5", @@ -5925,6 +5931,7 @@ "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", "dev": true, + "peer": true, "dependencies": { "@types/estree": "*", "@types/json-schema": "*" @@ -6164,6 +6171,7 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.21.tgz", "integrity": "sha512-EV/37Td6c+MgKAbkcLG6vqZ2zEYHD7bvSrzqqs2RIhbA6w3x+Dqz8MZM3sP6kGTeLrdoOgKZe+Xja7tUB2DNkQ==", "dev": true, + "peer": true, "dependencies": { "undici-types": "~6.21.0" } @@ -6216,6 +6224,7 @@ "version": "18.3.22", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.22.tgz", "integrity": "sha512-vUhG0YmQZ7kL/tmKLrD3g5zXbXXreZXB3pmROW8bg3CnLnpjkRVwUlLne7Ufa2r9yJ8+/6B73RzhAek5TBKh2Q==", + "peer": true, "dependencies": { "@types/prop-types": "*", "csstype": "^3.0.2" @@ -6225,6 +6234,7 @@ "version": "18.3.7", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz", "integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==", + "peer": true, "peerDependencies": { "@types/react": "^18.0.0" } @@ -6351,6 +6361,7 @@ "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.40.tgz", "integrity": "sha512-u6kMFSBM9HcoTpUXnL6mt2HSzftqb3JgYV6oxIgL2dl6sX6aCa5k6SOkzv5DuZjBTPUE/dJltKtwwuqrkZHpfw==", "dev": true, + "peer": true, "dependencies": { "@types/node": "*", "@types/tapable": "^1", @@ -6837,6 +6848,7 @@ "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz", "integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==", "dev": true, + "peer": true, "dependencies": { "@babel/runtime": "^7.9.2" } @@ -7287,6 +7299,7 @@ "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz", "integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==", "dev": true, + "peer": true, "dependencies": { "@babel/runtime": "^7.9.2" } @@ -7369,6 +7382,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.32.1.tgz", "integrity": "sha512-LKMrmwCPoLhM45Z00O1ulb6jwyVr2kr3XJp+G+tSEZcbauNnScewcQwtJqXDhXeYPDEjZ8C1SjXm015CirEmGg==", "dev": true, + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.32.1", "@typescript-eslint/types": "8.32.1", @@ -8847,6 +8861,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz", "integrity": "sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==", "dev": true, + "peer": true, "dependencies": { "@eslint-community/regexpp": "^4.5.1", "@typescript-eslint/scope-manager": "6.21.0", @@ -8882,6 +8897,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz", "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==", "dev": true, + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "6.21.0", "@typescript-eslint/types": "6.21.0", @@ -9999,6 +10015,7 @@ "integrity": "sha512-yJ474Zv3cwiSOO9nXJuqzvwEeM+chDuQ8GJirw+pZ91sCGCyOZ3dJkVE09fTV0VEVzXyLWhh3G/AolYTPX7Mow==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.25.7", @@ -10115,6 +10132,7 @@ "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==", "dev": true, "license": "BSD-2-Clause", + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "6.21.0", "@typescript-eslint/types": "6.21.0", @@ -10370,7 +10388,8 @@ "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1367902.tgz", "integrity": "sha512-XxtPuC3PGakY6PD7dG66/o8KwJ/LkH2/EKe19Dcw58w53dv4/vSQEkn/SzuyhHE2q4zPgCkxQBxus3VV4ql+Pg==", "dev": true, - "license": "BSD-3-Clause" + "license": "BSD-3-Clause", + "peer": true }, "node_modules/@wordpress/scripts/node_modules/eslint-plugin-jest": { "version": "27.9.0", @@ -10639,6 +10658,7 @@ "integrity": "sha512-X4UlrxDTH8oom9qXlcjnydsjAOD2BmB6yFmvS4Z2zdTzqqpRWb+fbqrH412+l+OUXmbzJlSXjlMFYPgYG12IAA==", "dev": true, "license": "MIT", + "peer": true, "bin": { "prettier": "bin/prettier.cjs" }, @@ -10991,6 +11011,7 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", "dev": true, + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -11068,6 +11089,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -12289,6 +12311,7 @@ "url": "https://github.com/sponsors/ai" } ], + "peer": true, "dependencies": { "caniuse-lite": "^1.0.30001716", "electron-to-chromium": "^1.5.149", @@ -12767,8 +12790,7 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true, - "peer": true + "dev": true }, "node_modules/chrome-launcher": { "version": "1.2.0", @@ -14102,7 +14124,6 @@ "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==", "dev": true, - "peer": true, "dependencies": { "node-fetch": "2.6.7" } @@ -14112,7 +14133,6 @@ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", "dev": true, - "peer": true, "dependencies": { "whatwg-url": "^5.0.0" }, @@ -14132,22 +14152,19 @@ "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "dev": true, - "peer": true + "dev": true }, "node_modules/cross-fetch/node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/cross-fetch/node_modules/whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", "dev": true, - "peer": true, "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" @@ -15018,7 +15035,8 @@ "version": "0.0.1445099", "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1445099.tgz", "integrity": "sha512-GEuIbCLU2Iu6Sg05GeWS7ksijhOUZIDJD2YBUNRanK7SLKjeci1uxUUomu2VNvygQRuoq/vtnTYrgPZBEiYNMA==", - "dev": true + "dev": true, + "peer": true }, "node_modules/diff": { "version": "4.0.2", @@ -15102,8 +15120,7 @@ "version": "0.5.16", "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", - "dev": true, - "peer": true + "dev": true }, "node_modules/dom-serializer": { "version": "2.0.0", @@ -15660,6 +15677,7 @@ "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "dev": true, + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -20286,6 +20304,7 @@ "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", "dev": true, + "peer": true, "dependencies": { "@jest/core": "^29.7.0", "@jest/types": "^29.6.3", @@ -22009,7 +22028,6 @@ "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", "dev": true, - "peer": true, "bin": { "lz-string": "bin/bin.js" } @@ -22247,6 +22265,7 @@ "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz", "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==", "dev": true, + "peer": true, "bin": { "marked": "bin/marked.js" }, @@ -22958,8 +22977,7 @@ "version": "0.5.3", "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", - "dev": true, - "peer": true + "dev": true }, "node_modules/modify-values": { "version": "1.0.1", @@ -23495,6 +23513,7 @@ "resolved": "https://registry.npmjs.org/npm-package-json-lint/-/npm-package-json-lint-6.4.0.tgz", "integrity": "sha512-cuXAJJB1Rdqz0UO6w524matlBqDBjcNt7Ru+RDIu4y6RI1gVqiWBnylrK8sPRk81gGBA0X8hJbDXolVOoTc+sA==", "dev": true, + "peer": true, "dependencies": { "ajv": "^6.12.6", "ajv-errors": "^1.0.1", @@ -27505,6 +27524,7 @@ "url": "https://github.com/sponsors/ai" } ], + "peer": true, "dependencies": { "nanoid": "^3.3.8", "picocolors": "^1.1.1", @@ -28155,6 +28175,7 @@ "integrity": "sha512-1nMfdFjucm5hKvq0IClqZwK4FJkGXhRrQstOQ3P4vp8HxKrJEMFcY6RdBRVTdfQS/UlnX6gfbPuTvaqx/bDoeQ==", "dev": true, "license": "MIT", + "peer": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/preact" @@ -28202,7 +28223,6 @@ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", "dev": true, - "peer": true, "dependencies": { "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", @@ -28217,7 +28237,6 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, - "peer": true, "engines": { "node": ">=10" }, @@ -28229,8 +28248,7 @@ "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true, - "peer": true + "dev": true }, "node_modules/process-nextick-args": { "version": "2.0.1", @@ -28426,6 +28444,7 @@ "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-24.9.0.tgz", "integrity": "sha512-HFdCeH/wx6QPz8EncafbCqJBqaCG1ENW75xg3cLFMRUoqZDgByT6HSueiumetT2uClZxwqj0qS4qMVZwLHRHHw==", "dev": true, + "peer": true, "dependencies": { "@puppeteer/browsers": "2.10.5", "chromium-bidi": "5.1.0", @@ -28485,7 +28504,6 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, - "peer": true, "dependencies": { "ms": "2.1.2" }, @@ -28502,15 +28520,13 @@ "version": "0.0.1045489", "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1045489.tgz", "integrity": "sha512-D+PTmWulkuQW4D1NTiCRCFxF7pQPn0hgp4YyX4wAQ6xYXKOadSWPR3ENGDQ47MW/Ewc9v2rpC/UEEGahgBYpSQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/puppeteer/node_modules/extract-zip": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", "dev": true, - "peer": true, "dependencies": { "debug": "^4.1.1", "get-stream": "^5.1.0", @@ -28531,7 +28547,6 @@ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "dev": true, - "peer": true, "dependencies": { "pump": "^3.0.0" }, @@ -28546,15 +28561,13 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true, - "peer": true + "dev": true }, "node_modules/puppeteer/node_modules/puppeteer-core": { "version": "19.0.0", "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-19.0.0.tgz", "integrity": "sha512-OljQ9W5M4cBX68vnOAGbcRkVENDHn6lfj6QYoGsnLQsxPAh6ExTQAhHauwdFdQkhYdDExZFWlKArnBONzeHY+g==", "dev": true, - "peer": true, "dependencies": { "cross-fetch": "3.1.5", "debug": "4.3.4", @@ -28576,7 +28589,6 @@ "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", "dev": true, - "peer": true, "dependencies": { "chownr": "^1.1.1", "mkdirp-classic": "^0.5.2", @@ -28589,7 +28601,6 @@ "resolved": "https://registry.npmjs.org/ws/-/ws-8.9.0.tgz", "integrity": "sha512-Ja7nszREasGaYUYCI2k4lCKIRTt+y7XuqVoHR44YpI49TtryyqbqvDMn5eqfW7e6HzTukDRIsXqzVHScqRcafg==", "dev": true, - "peer": true, "engines": { "node": ">=10.0.0" }, @@ -28761,6 +28772,7 @@ "version": "17.0.2", "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", + "peer": true, "dependencies": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1" @@ -28798,6 +28810,7 @@ "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", "integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==", + "peer": true, "dependencies": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", @@ -28846,6 +28859,7 @@ "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz", "integrity": "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==", "dev": true, + "peer": true, "engines": { "node": ">=0.10.0" } @@ -29182,7 +29196,8 @@ "resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz", "integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/reflect.getprototypeof": { "version": "1.0.10", @@ -29854,6 +29869,7 @@ "resolved": "https://registry.npmjs.org/sass/-/sass-1.89.0.tgz", "integrity": "sha512-ld+kQU8YTdGNjOLfRWBzewJpU5cwEv/h5yyqlSeJcj6Yh8U4TDA9UA5FPicqDz/xgRPWRSYIQNiFks21TbA9KQ==", "dev": true, + "peer": true, "dependencies": { "chokidar": "^4.0.0", "immutable": "^5.0.2", @@ -29955,6 +29971,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -30014,6 +30031,7 @@ "resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-19.0.5.tgz", "integrity": "sha512-NMPKdfpXTnPn49FDogMBi36SiBfXkSOJqCkk0E4iWOY1tusvvgBwqUmxTX1kmlT6kIYed9YwNKD1sfPpqa5yaA==", "dev": true, + "peer": true, "dependencies": { "@semantic-release/commit-analyzer": "^9.0.2", "@semantic-release/error": "^3.0.0", @@ -31903,6 +31921,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "@csstools/css-parser-algorithms": "^3.0.4", "@csstools/css-tokenizer": "^3.0.3", @@ -32304,6 +32323,7 @@ "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -33239,6 +33259,7 @@ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", "dev": true, + "peer": true, "engines": { "node": ">=10" }, @@ -33359,6 +33380,7 @@ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", "dev": true, + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -34140,6 +34162,7 @@ "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.99.9.tgz", "integrity": "sha512-brOPwM3JnmOa+7kd3NsmOUOwbDAj8FT9xDsG3IW0MgbN9yZV7Oi/s/+MNQ/EcSMqw7qfoRyXPoeEWT8zLVdVGg==", "dev": true, + "peer": true, "dependencies": { "@types/eslint-scope": "^3.7.7", "@types/estree": "^1.0.6", @@ -34243,6 +34266,7 @@ "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz", "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==", "dev": true, + "peer": true, "dependencies": { "@discoveryjs/json-ext": "^0.5.0", "@webpack-cli/configtest": "^2.1.1", @@ -34341,6 +34365,7 @@ "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.2.tgz", "integrity": "sha512-0XavAZbNJ5sDrCbkpWL8mia0o5WPOd2YGtxrEiZkBK9FjLppIUK2TgxK6qGD2P3hUXTJNNPVibrerKcx5WkR1g==", "dev": true, + "peer": true, "dependencies": { "@types/bonjour": "^3.5.9", "@types/connect-history-api-fallback": "^1.3.5", diff --git a/src/blocks/blocks/accordion/group/edit.js b/src/blocks/blocks/accordion/group/edit.js index 5399ca46a..63e3e186e 100644 --- a/src/blocks/blocks/accordion/group/edit.js +++ b/src/blocks/blocks/accordion/group/edit.js @@ -25,7 +25,7 @@ import { useCSSNode } from '../../../helpers/block-utility.js'; -import { useDarkBackground } from '../../../helpers/utility-hooks.js'; +import { useDarkBackground, useColorResolver } from '../../../helpers/utility-hooks.js'; // @ts-ignore import faIcons from '../../../../../assets/fontawesome/fa-icons.json'; @@ -70,12 +70,13 @@ const Edit = ({ }, []); const getValue = field => getDefaultValueByField({ name, field, defaultAttributes, attributes }); + const resolveColor = useColorResolver(); const inlineStyles = { - '--title-color': getValue( 'titleColor' ), - '--title-background': getValue( 'titleBackground' ), - '--content-background': getValue( 'contentBackground' ), - '--border-color': getValue( 'borderColor' ), + '--title-color': resolveColor( getValue( 'titleColor' ) ), + '--title-background': resolveColor( getValue( 'titleBackground' ) ), + '--content-background': resolveColor( getValue( 'contentBackground' ) ), + '--border-color': resolveColor( getValue( 'borderColor' ) ), '--border-width': getValue( 'borderWidth' ), '--box-shadow': attributes.boxShadow.active && `${attributes.boxShadow.horizontal}px ${attributes.boxShadow.vertical}px ${attributes.boxShadow.blur}px ${attributes.boxShadow.spread}px ${hex2rgba( attributes.boxShadow.color, attributes.boxShadow.colorOpacity )}`, '--padding': boxValues( attributes.padding, { top: '18px', right: '24px', bottom: '18px', left: '24px' }), @@ -119,8 +120,8 @@ const Edit = ({ const [ activeCSSNodeName, setActiveNodeCSS ] = useCSSNode(); useEffect( () => { - const activeTitleColor = getValue( 'activeTitleColor' ); - const activeTitleBackground = getValue( 'activeTitleBackground' ); + const activeTitleColor = resolveColor( getValue( 'activeTitleColor' ) ); + const activeTitleBackground = resolveColor( getValue( 'activeTitleBackground' ) ); setActiveNodeCSS([ ...( activeTitleColor ? [ `> * > * > .wp-block-themeisle-blocks-accordion-item.is-open > .wp-block-themeisle-blocks-accordion-item__title { diff --git a/src/blocks/blocks/advanced-heading/edit.js b/src/blocks/blocks/advanced-heading/edit.js index 2cfab5e84..d4df589c2 100644 --- a/src/blocks/blocks/advanced-heading/edit.js +++ b/src/blocks/blocks/advanced-heading/edit.js @@ -37,7 +37,8 @@ import { boxValues, _cssBlock, _px } from '../../helpers/helper-functions'; import { makeBox } from '../../plugins/copy-paste/utils'; import { useDarkBackground, - useResponsiveAttributes + useResponsiveAttributes, + useColorResolver } from '../../helpers/utility-hooks.js'; const { attributes: defaultAttributes } = metadata; @@ -63,6 +64,9 @@ const Edit = ({ useDarkBackground( attributes.backgroundColor, attributes, setAttributes ); + // Get color resolver to handle theme color slugs + const resolveColor = useColorResolver(); + const changeContent = value => { setAttributes({ content: value }); }; @@ -153,14 +157,14 @@ const Edit = ({ attributes.fontSizeTablet, attributes.fontSizeMobile ]), - color: attributes.headingColor, + color: resolveColor( attributes.headingColor ), fontFamily: attributes.fontFamily || undefined, fontWeight: 'regular' === attributes.fontVariant ? 'normal' : attributes.fontVariant, fontStyle: attributes.fontStyle || undefined, textTransform: attributes.textTransform || undefined, lineHeight: ( ( ! isString( attributes.lineHeight ) && 3 < attributes.lineHeight ) ? attributes.lineHeight + 'px' : attributes.lineHeight ) || undefined, letterSpacing: _px( attributes.letterSpacing ), - background: attributes.backgroundColor, + background: resolveColor( attributes.backgroundColor ), ...textShadowStyle, ...inlineStyle }, x => x?.includes?.( 'undefined' ) ); @@ -182,18 +186,18 @@ const Edit = ({ diff --git a/src/blocks/blocks/button-group/button/edit.js b/src/blocks/blocks/button-group/button/edit.js index 0361c8668..9f383fb42 100644 --- a/src/blocks/blocks/button-group/button/edit.js +++ b/src/blocks/blocks/button-group/button/edit.js @@ -33,6 +33,7 @@ import { buildGetSyncValue } from '../../../helpers/block-utility.js'; import { boxToCSS, objectOrNumberAsBox, _cssBlock, _px } from '../../../helpers/helper-functions'; +import { useColorResolver } from '../../../helpers/utility-hooks.js'; const { attributes: defaultAttributes } = metadata; @@ -52,6 +53,9 @@ const Edit = ( props ) => { const getSyncValue = buildGetSyncValue( name, attributes, defaultAttributes ); + // Get color resolver to handle theme color slugs + const resolveColor = useColorResolver(); + useEffect( () => { const unsubscribe = blockInit( clientId, defaultAttributes ); return () => unsubscribe( attributes.id ); @@ -80,40 +84,41 @@ const Edit = ( props ) => {
{ 'none' !== attributes.iconType ? ( diff --git a/src/blocks/blocks/circle-counter/components/circular-progress-bar.js b/src/blocks/blocks/circle-counter/components/circular-progress-bar.js index eb9fbab0e..cd5d6e534 100644 --- a/src/blocks/blocks/circle-counter/components/circular-progress-bar.js +++ b/src/blocks/blocks/circle-counter/components/circular-progress-bar.js @@ -1,7 +1,8 @@ const CircularProgressBar = ({ attributes, progressRef, - valueRef + valueRef, + resolveColor }) => { const size = attributes.height; const center = size / 2; @@ -32,7 +33,7 @@ const CircularProgressBar = ({ r={ radius } strokeWidth={ attributes.strokeWidth } style={ { - stroke: attributes.backgroundColor + stroke: resolveColor( attributes.backgroundColor ) } } /> diff --git a/src/blocks/blocks/circle-counter/edit.js b/src/blocks/blocks/circle-counter/edit.js index c2e263bb8..d2573227d 100644 --- a/src/blocks/blocks/circle-counter/edit.js +++ b/src/blocks/blocks/circle-counter/edit.js @@ -31,6 +31,7 @@ import Inspector from './inspector.js'; import CircularProgressBar from './components/circular-progress-bar.js'; import { blockInit } from '../../helpers/block-utility.js'; import { _px } from '../../helpers/helper-functions'; +import { useColorResolver } from '../../helpers/utility-hooks.js'; const { attributes: defaultAttributes } = metadata; @@ -52,6 +53,8 @@ const CircularProgressBarBlock = ({ return () => unsubscribe( attributes.id ); }, [ attributes.id ]); + const resolveColor = useColorResolver(); + const progressRef = useRef( null ); const valueRef = useRef( null ); const [ interval, changeInterval ] = useState({}); @@ -142,7 +145,7 @@ const CircularProgressBarBlock = ({ onChange={ title => setAttributes({ title }) } multiline={ false } style={ { - color: attributes.titleColor + color: resolveColor( attributes.titleColor ) } } />
@@ -174,6 +177,7 @@ const CircularProgressBarBlock = ({ attributes={ attributes } progressRef={ progressRef } valueRef={ valueRef } + resolveColor={ resolveColor } /> @@ -188,7 +192,7 @@ const CircularProgressBarBlock = ({ onChange={ title => setAttributes({ title }) } multiline={ false } style={ { - color: attributes.titleColor + color: resolveColor( attributes.titleColor ) } } /> diff --git a/src/blocks/blocks/font-awesome-icons/edit.js b/src/blocks/blocks/font-awesome-icons/edit.js index 5fe413a5e..25b35cdfc 100644 --- a/src/blocks/blocks/font-awesome-icons/edit.js +++ b/src/blocks/blocks/font-awesome-icons/edit.js @@ -22,6 +22,7 @@ import Inspector from './inspector.js'; import themeIsleIcons from './../../helpers/themeisle-icons'; import { blockInit, getDefaultValueByField } from '../../helpers/block-utility.js'; import { _cssBlock, boxValues } from '../../helpers/helper-functions'; +import { useColorResolver } from '../../helpers/utility-hooks.js'; const { attributes: defaultAttributes } = metadata; @@ -58,12 +59,15 @@ const Edit = ({ return () => unsubscribe( attributes.id ); }, [ attributes.id ]); + // Get color resolver to handle theme color slugs + const resolveColor = useColorResolver(); + const Icon = themeIsleIcons.icons[ attributes.icon ]; const getValue = field => getDefaultValueByField({ name, field, defaultAttributes, attributes }); const inlineStyles = { - '--border-color': attributes.borderColor, + '--border-color': resolveColor( attributes.borderColor ), '--border-size': attributes.borderSize !== undefined && `${attributes.borderSize }px`, '--border-radius': attributes.borderRadius !== undefined && `${ attributes.borderRadius }%`, '--margin': ! isObjectLike( getValue( 'margin' ) ) ? getValue( 'margin' ) + 'px' : boxValues( getValue( 'margin' ), { top: '5px', right: '5px', bottom: '5px', left: '5px' }), @@ -97,30 +101,30 @@ const Edit = ({ diff --git a/src/blocks/blocks/popup/edit.js b/src/blocks/blocks/popup/edit.js index 1a91ffef5..f61bea0dc 100644 --- a/src/blocks/blocks/popup/edit.js +++ b/src/blocks/blocks/popup/edit.js @@ -39,7 +39,7 @@ import metadata from './block.json'; import Inspector from './inspector.js'; import { blockInit, useCSSNode } from '../../helpers/block-utility'; import { boxValues, _cssBlock, stringToBox } from '../../helpers/helper-functions'; -import { useDarkBackground } from '../../helpers/utility-hooks.js'; +import { useDarkBackground, useColorResolver } from '../../helpers/utility-hooks.js'; import { useDispatch, useSelect } from '@wordpress/data'; const { attributes: defaultAttributes } = metadata; @@ -61,6 +61,8 @@ const Edit = ({ return () => unsubscribe( attributes.id ); }, []); + const resolveColor = useColorResolver(); + const [ isEditing, setEditing ] = useState( false ); const { @@ -100,13 +102,13 @@ const Edit = ({ const inlineStyles = { '--min-width': attributes.minWidth ? attributes.minWidth + 'px' : '400px', '--max-width': attributes.maxWidth ? attributes.maxWidth + 'px' : undefined, - '--background-color': attributes.backgroundColor, - '--close-color': attributes.closeColor, - '--overlay-color': attributes.overlayColor, + '--background-color': resolveColor( attributes.backgroundColor ), + '--close-color': resolveColor( attributes.closeColor ), + '--overlay-color': resolveColor( attributes.overlayColor ), '--overlay-opacity': attributes.overlayOpacity !== undefined ? attributes.overlayOpacity / 100 : 1, '--brd-width': boxValues( attributes.borderWidth ), '--brd-radius': boxValues( attributes.borderRadius ), - '--brd-color': attributes.borderColor, + '--brd-color': resolveColor( attributes.borderColor ), '--brd-style': attributes.borderStyle, // Responsive diff --git a/src/blocks/blocks/posts/edit.js b/src/blocks/blocks/posts/edit.js index 73c0d5c5b..12155b196 100644 --- a/src/blocks/blocks/posts/edit.js +++ b/src/blocks/blocks/posts/edit.js @@ -54,7 +54,8 @@ import { } from '../../helpers/helper-functions.js'; import { useDarkBackground, - useResponsiveAttributes + useResponsiveAttributes, + useColorResolver } from '../../helpers/utility-hooks.js'; import '../../components/store/index.js'; import FeaturedPost from './components/layout/featured.js'; @@ -240,6 +241,9 @@ const Edit = ({ useDarkBackground( attributes.backgroundColor, attributes, setAttributes ); + // Get color resolver to handle theme color slugs + const resolveColor = useColorResolver(); + const getValue = field => getDefaultValueByField({ name, field, defaultAttributes, attributes }); const imageBoxShadow = getValue( 'imageBoxShadow' ); @@ -258,10 +262,10 @@ const Edit = ({ '--box-shadow': boxShadow.active && `${ boxShadow.horizontal }px ${ boxShadow.vertical }px ${ boxShadow.blur }px ${ boxShadow.spread }px ${ hex2rgba( boxShadow.color, boxShadow.colorOpacity ) }`, '--vert-align': _align( attributes.verticalAlign ), '--text-align': attributes.textAlign, - '--text-color': attributes.textColor, - '--background-color': attributes.backgroundColor, + '--text-color': resolveColor( attributes.textColor ), + '--background-color': resolveColor( attributes.backgroundColor ), '--background-overlay': attributes.backgroundOverlay || '#0000005e', - '--border-color': attributes.borderColor, + '--border-color': resolveColor( attributes.borderColor ), '--content-gap': attributes.contentGap, '--img-width': responsiveGetAttributes([ _px( attributes.imageWidth ), attributes.imageWidthTablet, attributes.imageWidthMobile ]), '--img-width-tablet': attributes.imageWidthTablet, diff --git a/src/blocks/blocks/progress-bar/edit.js b/src/blocks/blocks/progress-bar/edit.js index 325bcedba..390ba6d5c 100644 --- a/src/blocks/blocks/progress-bar/edit.js +++ b/src/blocks/blocks/progress-bar/edit.js @@ -26,6 +26,7 @@ import { import metadata from './block.json'; import { blockInit } from '../../helpers/block-utility.js'; import Inspector from './inspector.js'; +import { useColorResolver } from '../../helpers/utility-hooks.js'; const { attributes: defaultAttributes } = metadata; @@ -46,6 +47,9 @@ const ProgressBar = ({ return () => unsubscribe( attributes.id ); }, [ attributes.id ]); + // Get color resolver to handle theme color slugs + const resolveColor = useColorResolver(); + const blockRef = useRef( null ); const [ showPercentage, setShowPercentage ] = useState( false ); @@ -86,15 +90,15 @@ const ProgressBar = ({ }, [ attributes.percentage, attributes.duration ]); const inlineStyles = { - '--title-color': attributes.titleColor, - '--percentage-color': attributes.percentageColor, - '--percentage-color-outer': attributes.percentageColor, - '--percentage-color-tooltip': attributes.percentageColor, - '--percentage-color-append': attributes.percentageColor, - '--background-color': attributes.backgroundColor, + '--title-color': resolveColor( attributes.titleColor ), + '--percentage-color': resolveColor( attributes.percentageColor ), + '--percentage-color-outer': resolveColor( attributes.percentageColor ), + '--percentage-color-tooltip': resolveColor( attributes.percentageColor ), + '--percentage-color-append': resolveColor( attributes.percentageColor ), + '--background-color': resolveColor( attributes.backgroundColor ), '--border-radius': attributes.borderRadius !== undefined && ( attributes.borderRadius + 'px' ), '--height': attributes.height !== undefined && ( attributes.height + 'px' ), - '--bar-background': attributes.barBackgroundColor, + '--bar-background': resolveColor( attributes.barBackgroundColor ), '--title-font-size': attributes.titleFontSize }; diff --git a/src/blocks/blocks/review/edit.js b/src/blocks/blocks/review/edit.js index c0cdca204..3ab458661 100644 --- a/src/blocks/blocks/review/edit.js +++ b/src/blocks/blocks/review/edit.js @@ -47,7 +47,7 @@ import { getDefaultValueByField } from '../../helpers/block-utility.js'; -import { useDarkBackground } from '../../helpers/utility-hooks.js'; +import { useDarkBackground, useColorResolver } from '../../helpers/utility-hooks.js'; import { _px } from '../../helpers/helper-functions'; const { attributes: defaultAttributes } = metadata; @@ -116,6 +116,9 @@ const Edit = ({ const getValue = field => getDefaultValueByField({ name, field, defaultAttributes, attributes }); + // Get color resolver to handle theme color slugs + const resolveColor = useColorResolver(); + useDarkBackground( getValue( 'backgroundColor' ), attributes, setAttributes ); const overallRatings = ( attributes.features.reduce( ( accumulator, feature ) => accumulator + feature.rating, 0 ) / attributes.features.length ).toFixed( 1 ); @@ -153,14 +156,14 @@ const Edit = ({ const boxShadow = getValue( 'boxShadow' ); const inlineStyles = { - '--background-color': getValue( 'backgroundColor' ), - '--primary-color': getValue( 'primaryColor' ), - '--text-color': getValue( 'textColor' ), - '--button-text-color': getValue( 'buttonTextColor' ), - '--border-color': getValue( 'borderColor' ), - '--stars-color': getValue( 'starsColor' ), - '--pros-color': getValue( 'prosColor' ), - '--cons-color': getValue( 'consColor' ), + '--background-color': resolveColor( getValue( 'backgroundColor' ) ), + '--primary-color': resolveColor( getValue( 'primaryColor' ) ), + '--text-color': resolveColor( getValue( 'textColor' ) ), + '--button-text-color': resolveColor( getValue( 'buttonTextColor' ) ), + '--border-color': resolveColor( getValue( 'borderColor' ) ), + '--stars-color': resolveColor( getValue( 'starsColor' ) ), + '--pros-color': resolveColor( getValue( 'prosColor' ) ), + '--cons-color': resolveColor( getValue( 'consColor' ) ), '--content-font-size': getValue( 'contentFontSize' ), ...( attributes?.padding?.top && { '--padding-desktop-top': attributes.padding.top }), ...( attributes?.padding?.bottom && { '--padding-desktop-bottom': attributes.padding.bottom }), diff --git a/src/blocks/blocks/section/column/edit.js b/src/blocks/blocks/section/column/edit.js index 295a705f5..03c62322e 100644 --- a/src/blocks/blocks/section/column/edit.js +++ b/src/blocks/blocks/section/column/edit.js @@ -38,7 +38,7 @@ import { getDefaultValueByField } from '../../../helpers/block-utility.js'; import { _cssBlock } from '../../../helpers/helper-functions'; -import { useDarkBackground } from '../../../helpers/utility-hooks.js'; +import { useDarkBackground, useColorResolver } from '../../../helpers/utility-hooks.js'; const { attributes: defaultAttributes } = metadata; @@ -104,6 +104,9 @@ const Edit = ({ return () => unsubscribe( attributes.id ); }, [ attributes.id ]); + // Get color resolver to handle theme color slugs + const resolveColor = useColorResolver(); + useEffect( () => { if ( 1 < parentBlock.innerBlocks.length ) { if ( ! adjacentBlockClientId ) { @@ -223,7 +226,7 @@ const Edit = ({ if ( 'color' === attributes.backgroundType ) { background = { - '--background': attributes.backgroundColor + '--background': resolveColor( attributes.backgroundColor ) }; } @@ -250,7 +253,7 @@ const Edit = ({ borderBottomWidth: attributes.border.bottom, borderLeftWidth: attributes.border.left, borderStyle: 'solid', - borderColor: attributes.borderColor + borderColor: resolveColor( attributes.borderColor ) }; } @@ -264,8 +267,9 @@ const Edit = ({ } if ( true === attributes.boxShadow ) { + const resolvedBoxShadowColor = resolveColor( attributes.boxShadowColor ); boxShadowStyle = { - boxShadow: `${ attributes.boxShadowHorizontal }px ${ attributes.boxShadowVertical }px ${ attributes.boxShadowBlur }px ${ attributes.boxShadowSpread }px ${ attributes.boxShadowColor.includes( 'var(' ) && ( attributes.boxShadowColorOpacity === undefined || 100 === attributes.boxShadowColorOpacity ) ? attributes.boxShadowColor : hexToRgba( ( attributes.boxShadowColor ? attributes.boxShadowColor : '#000000' ), attributes.boxShadowColorOpacity ) }` + boxShadow: `${ attributes.boxShadowHorizontal }px ${ attributes.boxShadowVertical }px ${ attributes.boxShadowBlur }px ${ attributes.boxShadowSpread }px ${ resolvedBoxShadowColor?.includes( 'var(' ) && ( attributes.boxShadowColorOpacity === undefined || 100 === attributes.boxShadowColorOpacity ) ? resolvedBoxShadowColor : hexToRgba( ( resolvedBoxShadowColor || '#000000' ), attributes.boxShadowColorOpacity ) }` }; } @@ -281,8 +285,8 @@ const Edit = ({ ...borderStyle, ...borderRadiusStyle, ...boxShadowStyle, - '--link-color': attributes.linkColor, - '--background-color-hover': attributes.backgroundColorHover + '--link-color': resolveColor( attributes.linkColor ), + '--background-color-hover': resolveColor( attributes.backgroundColorHover ) }; if ( attributes.verticalAlign ) { @@ -291,7 +295,7 @@ const Edit = ({ if ( 'color' === attributes.backgroundOverlayType ) { overlayBackground = { - background: attributes.backgroundOverlayColor, + background: resolveColor( attributes.backgroundOverlayColor ), opacity: attributes.backgroundOverlayOpacity / 100 }; } @@ -333,12 +337,12 @@ const Edit = ({ diff --git a/src/blocks/blocks/section/columns/edit.js b/src/blocks/blocks/section/columns/edit.js index 8c2aaeb2d..78e0a9dbd 100644 --- a/src/blocks/blocks/section/columns/edit.js +++ b/src/blocks/blocks/section/columns/edit.js @@ -54,7 +54,7 @@ import { } from '../../../helpers/block-utility.js'; import { columnsIcon as icon } from '../../../helpers/icons.js'; import { _cssBlock, _px } from '../../../helpers/helper-functions'; -import { useDarkBackground } from '../../../helpers/utility-hooks.js'; +import { useDarkBackground, useColorResolver } from '../../../helpers/utility-hooks.js'; const { attributes: defaultAttributes } = metadata; @@ -74,6 +74,9 @@ const Edit = ({ return () => unsubscribe( attributes.id ); }, [ attributes.id ]); + // Get color resolver to handle theme color slugs + const resolveColor = useColorResolver(); + const { updateBlockAttributes, replaceInnerBlocks } = useDispatch( 'core/block-editor' ); const { @@ -266,7 +269,7 @@ const Edit = ({ if ( 'color' === attributes.backgroundType ) { background = { - backgroundColor: attributes.backgroundColor + backgroundColor: resolveColor( attributes.backgroundColor ) }; } @@ -293,7 +296,7 @@ const Edit = ({ borderBottomWidth: attributes.border.bottom, borderLeftWidth: attributes.border.left, borderStyle: 'solid', - borderColor: attributes.borderColor + borderColor: resolveColor( attributes.borderColor ) }; } @@ -307,8 +310,9 @@ const Edit = ({ } if ( true === attributes.boxShadow ) { + const resolvedBoxShadowColor = resolveColor( attributes.boxShadowColor ); boxShadowStyle = { - boxShadow: `${ attributes.boxShadowHorizontal }px ${ attributes.boxShadowVertical }px ${ attributes.boxShadowBlur }px ${ attributes.boxShadowSpread }px ${ attributes.boxShadowColor.includes( 'var(' ) && ( attributes.boxShadowColorOpacity === undefined || 100 === attributes.boxShadowColorOpacity ) ? attributes.boxShadowColor : hexToRgba( ( attributes.boxShadowColor ? attributes.boxShadowColor : '#000000' ), attributes.boxShadowColorOpacity ) }` + boxShadow: `${ attributes.boxShadowHorizontal }px ${ attributes.boxShadowVertical }px ${ attributes.boxShadowBlur }px ${ attributes.boxShadowSpread }px ${ resolvedBoxShadowColor?.includes( 'var(' ) && ( attributes.boxShadowColorOpacity === undefined || 100 === attributes.boxShadowColorOpacity ) ? resolvedBoxShadowColor : hexToRgba( ( resolvedBoxShadowColor || '#000000' ), attributes.boxShadowColorOpacity ) }` }; } @@ -318,12 +322,12 @@ const Edit = ({ ...borderStyle, ...borderRadiusStyle, ...boxShadowStyle, - '--link-color': attributes.linkColor + '--link-color': resolveColor( attributes.linkColor ) }; if ( 'color' === attributes.backgroundOverlayType ) { overlayBackground = { - background: attributes.backgroundOverlayColor, + background: resolveColor( attributes.backgroundOverlayColor ), opacity: attributes.backgroundOverlayOpacity / 100 }; } @@ -420,12 +424,12 @@ const Edit = ({ diff --git a/src/blocks/blocks/tabs/group/edit.js b/src/blocks/blocks/tabs/group/edit.js index 7e942713a..2cd7fc5e2 100644 --- a/src/blocks/blocks/tabs/group/edit.js +++ b/src/blocks/blocks/tabs/group/edit.js @@ -38,7 +38,7 @@ import Controls from './controls.js'; import { blockInit, getDefaultValueByField } from '../../../helpers/block-utility.js'; import { boxToCSS, objectOrNumberAsBox, _px } from '../../../helpers/helper-functions'; import BlockAppender from '../../../components/block-appender-button'; -import { useDarkBackground } from '../../../helpers/utility-hooks.js'; +import { useDarkBackground, useColorResolver } from '../../../helpers/utility-hooks.js'; const { attributes: defaultAttributes } = metadata; @@ -168,6 +168,9 @@ const Edit = ({ useDarkBackground( attributes.tabColor, attributes, setAttributes ); + // Get color resolver to handle theme color slugs + const resolveColor = useColorResolver(); + /** * ------------ Tab Actions ------------ */ @@ -213,14 +216,14 @@ const Edit = ({ const inlineStyles = { '--title-border-width': boxToCSS( getSyncValue( 'titleBorderWidth' ) ), '--border-width': boxToCSS( _px( getSyncValue( 'borderWidth' ) ) ), - '--border-color': getSyncValue( 'borderColor' ), - '--title-color': getSyncValue( 'titleColor' ), - '--title-background': getSyncValue( 'titleBackgroundColor' ), - '--tab-color': getSyncValue( 'tabColor' ), - '--active-title-color': getSyncValue( 'activeTitleColor' ), - '--active-title-background': getSyncValue( 'activeTitleBackgroundColor' ), - '--active-title-border-color': getSyncValue( 'activeBorderColor' ), - '--content-text-color': getSyncValue( 'contentTextColor' ), + '--border-color': resolveColor( getSyncValue( 'borderColor' ) ), + '--title-color': resolveColor( getSyncValue( 'titleColor' ) ), + '--title-background': resolveColor( getSyncValue( 'titleBackgroundColor' ) ), + '--tab-color': resolveColor( getSyncValue( 'tabColor' ) ), + '--active-title-color': resolveColor( getSyncValue( 'activeTitleColor' ) ), + '--active-title-background': resolveColor( getSyncValue( 'activeTitleBackgroundColor' ) ), + '--active-title-border-color': resolveColor( getSyncValue( 'activeBorderColor' ) ), + '--content-text-color': resolveColor( getSyncValue( 'contentTextColor' ) ), '--title-padding': boxToCSS( getSyncValue( 'titlePadding' ) ), '--content-padding': boxToCSS( getSyncValue( 'contentPadding' ) ), '--border-side-width': 'left' === attributes.tabsPosition ? objectOrNumberAsBox( getSyncValue( 'borderWidth' ) )?.left : objectOrNumberAsBox( getSyncValue( 'borderWidth' ) )?.top, diff --git a/src/blocks/helpers/helper-functions.js b/src/blocks/helpers/helper-functions.js index 507019a40..871f88a9e 100644 --- a/src/blocks/helpers/helper-functions.js +++ b/src/blocks/helpers/helper-functions.js @@ -331,14 +331,22 @@ export const hex2rgba = ( color, alpha = 100 ) => { * @return {string|boolean} */ export const lightnessFromColor = color => { - if ( ! color ) { + // Handle falsy values and non-string types + if ( ! color || typeof color !== 'string' ) { return false; } let value = color; + // Handle CSS variables if ( color.startsWith( 'var(' ) ) { - value = getComputedStyle( document.documentElement ).getPropertyValue( color.slice( 4, -1 ) ).trim(); + // Check if we're in a browser environment + if ( typeof document !== 'undefined' && document.documentElement ) { + value = getComputedStyle( document.documentElement ).getPropertyValue( color.slice( 4, -1 ) ).trim(); + } else { + // In test/non-browser environment, can't resolve CSS variables + return false; + } } // Convert hex to RGB if necessary @@ -351,7 +359,13 @@ export const lightnessFromColor = color => { } // Extract the red, green, and blue values - const [ r, g, b ] = value.match( /\d+/g ).map( Number ); + const matches = value.match( /\d+/g ); + if ( ! matches || matches.length < 3 ) { + // Invalid color format + return false; + } + + const [ r, g, b ] = matches.map( Number ); // Calculate the brightness value const brightness = ( 0.299 * r ) + ( 0.587 * g ) + ( 0.114 * b ); @@ -360,6 +374,53 @@ export const lightnessFromColor = color => { return 128 > brightness ? 'dark' : 'light'; }; +/** + * Convert a color slug to a CSS variable reference. + * WordPress generates CSS variables in the format: --wp--preset--color--{slug} + * + * @param {string|undefined} slug The color slug + * @return {string|undefined} The CSS variable reference + */ +export const getColorCSSVariable = ( slug ) => { + // Handle all falsy values and non-string types + if ( ! slug || typeof slug !== 'string' ) { + return slug; + } + + // If it's already a color value or CSS variable, return as-is + if ( + slug.startsWith( '#' ) || + slug.startsWith( 'rgb' ) || + slug.startsWith( 'hsl' ) || + slug.startsWith( 'var(' ) + ) { + return slug; + } + + // Sanitize slug: WordPress slugs should only contain lowercase alphanumeric, hyphens, and underscores + // This prevents potential CSS injection if slug comes from untrusted sources + const sanitizedSlug = slug.toLowerCase().replace( /[^a-z0-9-_]/g, '' ); + + // Convert slug to CSS variable + return `var(--wp--preset--color--${ sanitizedSlug })`; +}; + +/** + * Resolve a color value which may be a slug from the color palette. + * This function converts slugs to CSS variables to preserve the connection to theme.json. + * If the value is a slug, it returns a CSS variable reference. + * Otherwise, returns the value as-is (for hex, rgb, hsl values). + * + * @deprecated The palette parameter is deprecated and no longer used. Use getColorCSSVariable() directly. + * @param {string|undefined} value The color value or slug + * @param {Array} palette Optional color palette array (deprecated, no longer used) + * @return {string|undefined} The CSS variable or color value + */ +export const resolveColorValue = ( value, palette = null ) => { + // Use CSS variable conversion for slugs + return getColorCSSVariable( value ); +}; + /** * Return the values from a box type. * diff --git a/src/blocks/helpers/utility-hooks.js b/src/blocks/helpers/utility-hooks.js index 86805b688..d09217571 100644 --- a/src/blocks/helpers/utility-hooks.js +++ b/src/blocks/helpers/utility-hooks.js @@ -8,7 +8,7 @@ import { useEffect } from '@wordpress/element'; /** * Internal dependencies */ -import { buildResponsiveGetAttributes, buildResponsiveSetAttributes, lightnessFromColor } from './helper-functions.js'; +import { buildResponsiveGetAttributes, buildResponsiveSetAttributes, lightnessFromColor, getColorCSSVariable } from './helper-functions.js'; /** * Utiliy hook to get/set responsive attributes. @@ -37,8 +37,10 @@ export const useResponsiveAttributes = ( setAttributes = () => {}) => useSelect( */ export const useDarkBackground = ( backgroundColor, attributes, setAttributes, darkClassName = 'has-dark-bg', lightClassName = 'has-light-bg' ) => { useEffect( () => { - const isDark = 'dark' === lightnessFromColor( backgroundColor ); - const isLight = 'light' === lightnessFromColor( backgroundColor ); + // Resolve color slugs to CSS variables before checking lightness + const resolvedColor = getColorCSSVariable( backgroundColor ); + const isDark = 'dark' === lightnessFromColor( resolvedColor ); + const isLight = 'light' === lightnessFromColor( resolvedColor ); let classes = attributes.className || ''; @@ -67,3 +69,16 @@ export const useDarkBackground = ( backgroundColor, attributes, setAttributes, d setAttributes({ className: classes }); }, [ backgroundColor ]); }; + +/** + * Utility hook to resolve color slugs from the theme palette. + * Returns a function that can resolve a color value (which may be a slug) to a CSS variable. + * This preserves the connection to theme.json colors. + * + * @return {Function} A function that resolves color values/slugs. + */ +export const useColorResolver = () => { + // Return the getColorCSSVariable function directly + // We don't need the palette since we use CSS variables + return getColorCSSVariable; +}; diff --git a/src/blocks/test/unit/helper-functions.test.ts b/src/blocks/test/unit/helper-functions.test.ts index c4db851be..c679a1b73 100644 --- a/src/blocks/test/unit/helper-functions.test.ts +++ b/src/blocks/test/unit/helper-functions.test.ts @@ -1,4 +1,4 @@ -import { boxToCSS, boxValues, buildResponsiveGetAttributes, buildResponsiveSetAttributes, compactObject, getChoice, mergeBoxDefaultValues, removeBoxDefaultValues, stringToBox } from '../../helpers/helper-functions.js'; +import { boxToCSS, boxValues, buildResponsiveGetAttributes, buildResponsiveSetAttributes, compactObject, getChoice, getColorCSSVariable, mergeBoxDefaultValues, removeBoxDefaultValues, resolveColorValue, stringToBox } from '../../helpers/helper-functions.js'; describe( 'Box Values Function', () => { @@ -239,3 +239,82 @@ describe( 'Compact Object Function', () => { expect( compactObject({ a: {}, b: {}}) ).toBeUndefined(); }); }); + +describe( 'Get Color CSS Variable Function', () => { + it( 'should convert a color slug to a CSS variable', () => { + expect( getColorCSSVariable( 'primary' ) ).toEqual( 'var(--wp--preset--color--primary)' ); + expect( getColorCSSVariable( 'base' ) ).toEqual( 'var(--wp--preset--color--base)' ); + expect( getColorCSSVariable( 'contrast' ) ).toEqual( 'var(--wp--preset--color--contrast)' ); + }); + + it( 'should pass through hex color values unchanged', () => { + expect( getColorCSSVariable( '#ff0000' ) ).toEqual( '#ff0000' ); + expect( getColorCSSVariable( '#0073aa' ) ).toEqual( '#0073aa' ); + expect( getColorCSSVariable( '#000' ) ).toEqual( '#000' ); + }); + + it( 'should pass through rgb color values unchanged', () => { + expect( getColorCSSVariable( 'rgb(255, 0, 0)' ) ).toEqual( 'rgb(255, 0, 0)' ); + expect( getColorCSSVariable( 'rgba(255, 0, 0, 0.5)' ) ).toEqual( 'rgba(255, 0, 0, 0.5)' ); + }); + + it( 'should pass through hsl color values unchanged', () => { + expect( getColorCSSVariable( 'hsl(0, 100%, 50%)' ) ).toEqual( 'hsl(0, 100%, 50%)' ); + expect( getColorCSSVariable( 'hsla(0, 100%, 50%, 0.5)' ) ).toEqual( 'hsla(0, 100%, 50%, 0.5)' ); + }); + + it( 'should pass through existing CSS variables unchanged', () => { + expect( getColorCSSVariable( 'var(--custom-color)' ) ).toEqual( 'var(--custom-color)' ); + expect( getColorCSSVariable( 'var(--my-brand-color)' ) ).toEqual( 'var(--my-brand-color)' ); + }); + + it( 'should sanitize color slugs to prevent CSS injection', () => { + expect( getColorCSSVariable( 'Primary-Color' ) ).toEqual( 'var(--wp--preset--color--primary-color)' ); + expect( getColorCSSVariable( 'test@color!' ) ).toEqual( 'var(--wp--preset--color--testcolor)' ); + expect( getColorCSSVariable( 'my_special_color' ) ).toEqual( 'var(--wp--preset--color--my_special_color)' ); + expect( getColorCSSVariable( 'Color123' ) ).toEqual( 'var(--wp--preset--color--color123)' ); + }); + + it( 'should handle undefined and empty values', () => { + expect( getColorCSSVariable( undefined ) ).toBeUndefined(); + expect( getColorCSSVariable( '' ) ).toEqual( '' ); + }); + + it( 'should preserve hyphens and underscores in slugs', () => { + expect( getColorCSSVariable( 'primary-blue' ) ).toEqual( 'var(--wp--preset--color--primary-blue)' ); + expect( getColorCSSVariable( 'dark-gray-100' ) ).toEqual( 'var(--wp--preset--color--dark-gray-100)' ); + expect( getColorCSSVariable( 'secondary_dark' ) ).toEqual( 'var(--wp--preset--color--secondary_dark)' ); + expect( getColorCSSVariable( 'accent_1' ) ).toEqual( 'var(--wp--preset--color--accent_1)' ); + }); +}); + +describe( 'Resolve Color Value Function', () => { + it( 'should convert color slugs to CSS variables', () => { + expect( resolveColorValue( 'primary' ) ).toEqual( 'var(--wp--preset--color--primary)' ); + expect( resolveColorValue( 'base' ) ).toEqual( 'var(--wp--preset--color--base)' ); + }); + + it( 'should pass through hex values unchanged', () => { + expect( resolveColorValue( '#ff0000' ) ).toEqual( '#ff0000' ); + expect( resolveColorValue( '#0073aa' ) ).toEqual( '#0073aa' ); + }); + + it( 'should pass through rgb values unchanged', () => { + expect( resolveColorValue( 'rgb(255, 0, 0)' ) ).toEqual( 'rgb(255, 0, 0)' ); + }); + + it( 'should work with deprecated palette parameter (ignored)', () => { + const palette = [ + { slug: 'primary', color: '#0073aa', name: 'Primary' }, + { slug: 'base', color: '#000000', name: 'Base' } + ]; + + // Palette parameter is now ignored, should still convert to CSS variable + expect( resolveColorValue( 'primary', palette ) ).toEqual( 'var(--wp--preset--color--primary)' ); + expect( resolveColorValue( 'base', palette ) ).toEqual( 'var(--wp--preset--color--base)' ); + }); + + it( 'should handle undefined values', () => { + expect( resolveColorValue( undefined ) ).toBeUndefined(); + }); +});