diff --git a/lib/class-wp-theme-json-gutenberg.php b/lib/class-wp-theme-json-gutenberg.php
index 1b5cba91fe811e..ecb9ade8ea2b3f 100644
--- a/lib/class-wp-theme-json-gutenberg.php
+++ b/lib/class-wp-theme-json-gutenberg.php
@@ -301,7 +301,9 @@ public function __construct( $theme_json = array(), $origin = 'theme' ) {
$path = array_merge( $node['path'], $preset_metadata['path'] );
$preset = _wp_array_get( $this->theme_json, $path, null );
if ( null !== $preset ) {
- _wp_array_set( $this->theme_json, $path, array( $origin => $preset ) );
+ if ( 'user' !== $origin || isset( $preset[0] ) ) {
+ _wp_array_set( $this->theme_json, $path, array( $origin => $preset ) );
+ }
}
}
}
@@ -1333,48 +1335,52 @@ public function merge( $incoming ) {
* @return array
*/
private static function remove_insecure_settings( $input ) {
+ $origins = array( 'default', 'theme', 'user' );
+
$output = array();
foreach ( self::PRESETS_METADATA as $preset_metadata ) {
- $presets = _wp_array_get( $input, $preset_metadata['path'], null );
- if ( null === $presets ) {
- continue;
- }
+ foreach ( $origins as $origin ) {
+ $path_with_origin = array_merge( $preset_metadata['path'], array( $origin ) );
+ $presets = _wp_array_get( $input, $path_with_origin, null );
+ if ( null === $presets ) {
+ continue;
+ }
- $escaped_preset = array();
- foreach ( $presets as $preset ) {
- if (
- esc_attr( esc_html( $preset['name'] ) ) === $preset['name'] &&
- sanitize_html_class( $preset['slug'] ) === $preset['slug']
- ) {
- $value = null;
- if ( isset( $preset_metadata['value_key'] ) ) {
- $value = $preset[ $preset_metadata['value_key'] ];
- } elseif (
- isset( $preset_metadata['value_func'] ) &&
- is_callable( $preset_metadata['value_func'] )
+ $escaped_preset = array();
+ foreach ( $presets as $preset ) {
+ if (
+ esc_attr( esc_html( $preset['name'] ) ) === $preset['name'] &&
+ sanitize_html_class( $preset['slug'] ) === $preset['slug']
) {
- $value = call_user_func( $preset_metadata['value_func'], $preset );
- }
+ $value = null;
+ if ( isset( $preset_metadata['value_key'] ) ) {
+ $value = $preset[ $preset_metadata['value_key'] ];
+ } elseif (
+ isset( $preset_metadata['value_func'] ) &&
+ is_callable( $preset_metadata['value_func'] )
+ ) {
+ $value = call_user_func( $preset_metadata['value_func'], $preset );
+ }
- $preset_is_valid = true;
- foreach ( $preset_metadata['properties'] as $property ) {
- if ( ! self::is_safe_css_declaration( $property, $value ) ) {
- $preset_is_valid = false;
- break;
+ $preset_is_valid = true;
+ foreach ( $preset_metadata['properties'] as $property ) {
+ if ( ! self::is_safe_css_declaration( $property, $value ) ) {
+ $preset_is_valid = false;
+ break;
+ }
}
- }
- if ( $preset_is_valid ) {
- $escaped_preset[] = $preset;
+ if ( $preset_is_valid ) {
+ $escaped_preset[] = $preset;
+ }
}
}
- }
- if ( ! empty( $escaped_preset ) ) {
- _wp_array_set( $output, $preset_metadata['path'], $escaped_preset );
+ if ( ! empty( $escaped_preset ) ) {
+ _wp_array_set( $output, $path_with_origin, $escaped_preset );
+ }
}
}
-
return $output;
}
diff --git a/packages/components/src/color-edit/index.js b/packages/components/src/color-edit/index.js
index c3f8c4a82129cf..a9dafeae2c8a69 100644
--- a/packages/components/src/color-edit/index.js
+++ b/packages/components/src/color-edit/index.js
@@ -49,12 +49,14 @@ function ColorNameInput( { value, onChange } ) {
}
function ColorOption( {
+ canOnlyChangeValues,
color,
onChange,
isEditing,
onStartEditing,
onRemove,
onStopEditing,
+ slugPrefix,
} ) {
const focusOutsideProps = useFocusOutside( onStopEditing );
return (
@@ -68,14 +70,14 @@ function ColorOption( {
- { isEditing ? (
+ { isEditing && ! canOnlyChangeValues ? (
onChange( {
...color,
name: nextName,
- slug: kebabCase( nextName ),
+ slug: slugPrefix + kebabCase( nextName ),
} )
}
/>
@@ -83,7 +85,7 @@ function ColorOption( {
{ color.name }
) }
- { isEditing && (
+ { isEditing && ! canOnlyChangeValues && (
{ colors.map( ( color, index ) => (
{
@@ -177,6 +182,7 @@ function ColorPaletteEditListView( {
setEditingColor( null );
}
} }
+ slugPrefix={ slugPrefix }
/>
) ) }
@@ -186,7 +192,15 @@ function ColorPaletteEditListView( {
const EMPTY_ARRAY = [];
-export default function ColorEdit( { colors = EMPTY_ARRAY, onChange } ) {
+export default function ColorEdit( {
+ colors = EMPTY_ARRAY,
+ onChange,
+ paletteLabel,
+ emptyMessage,
+ canOnlyChangeValues,
+ canReset,
+ slugPrefix = '',
+} ) {
const [ isEditing, setIsEditing ] = useState( false );
const [ editingColor, setEditingColor ] = useState( null );
const isAdding =
@@ -200,7 +214,7 @@ export default function ColorEdit( { colors = EMPTY_ARRAY, onChange } ) {
return (
- { __( 'Custom' ) }
+ { paletteLabel }
{ isEditing && (
) }
-
);
}
diff --git a/packages/edit-site/src/components/global-styles/color-palette-panel.js b/packages/edit-site/src/components/global-styles/color-palette-panel.js
index b069738de3fa07..281f3c5fe48721 100644
--- a/packages/edit-site/src/components/global-styles/color-palette-panel.js
+++ b/packages/edit-site/src/components/global-styles/color-palette-panel.js
@@ -1,7 +1,11 @@
/**
* WordPress dependencies
*/
-import { __experimentalColorEdit as ColorEdit } from '@wordpress/components';
+import {
+ __experimentalColorEdit as ColorEdit,
+ __experimentalVStack as VStack,
+} from '@wordpress/components';
+import { __ } from '@wordpress/i18n';
/**
* Internal dependencies
@@ -9,14 +13,60 @@ import { __experimentalColorEdit as ColorEdit } from '@wordpress/components';
import { useSetting } from './hooks';
export default function ColorPalettePanel( { name } ) {
- const [ userColors, setColors ] = useSetting(
- 'color.palette',
+ const [ themeColors, setThemeColors ] = useSetting(
+ 'color.palette.theme',
+ name
+ );
+ const [ baseThemeColors ] = useSetting(
+ 'color.palette.theme',
name,
- 'user'
+ 'base'
+ );
+ const [ defaultColors, setDefaultColors ] = useSetting(
+ 'color.palette.default',
+ name
+ );
+ const [ baseDefaultColors ] = useSetting(
+ 'color.palette.default',
+ name,
+ 'base'
+ );
+ const [ customColors, setCustomColors ] = useSetting(
+ 'color.palette.user',
+ name
);
return (
-
-
-
+
+ { !! themeColors && !! themeColors.length && (
+
+ ) }
+ { !! defaultColors && !! defaultColors.length && (
+
+ ) }
+
+
);
}
diff --git a/packages/edit-site/src/components/global-styles/global-styles-provider.js b/packages/edit-site/src/components/global-styles/global-styles-provider.js
index f18eff6c728be8..25dd5d04796780 100644
--- a/packages/edit-site/src/components/global-styles/global-styles-provider.js
+++ b/packages/edit-site/src/components/global-styles/global-styles-provider.js
@@ -2,9 +2,6 @@
* External dependencies
*/
import {
- get,
- cloneDeep,
- set,
mergeWith,
pickBy,
isEmpty,
@@ -23,7 +20,6 @@ import { store as coreStore } from '@wordpress/core-data';
/**
* Internal dependencies
*/
-import { PRESET_METADATA } from './utils';
import { GlobalStylesContext } from './context';
function mergeTreesCustomizer( _, srcValue ) {
@@ -39,29 +35,6 @@ function mergeBaseAndUserConfigs( base, user ) {
return mergeWith( {}, base, user, mergeTreesCustomizer );
}
-function addUserOriginToSettings( settingsToAdd ) {
- const newSettings = cloneDeep( settingsToAdd );
- PRESET_METADATA.forEach( ( { path } ) => {
- const presetData = get( newSettings, path );
- if ( presetData ) {
- set( newSettings, path, {
- user: presetData,
- } );
- }
- } );
- return newSettings;
-}
-
-function removeUserOriginFromSettings( settingsToRemove ) {
- const newSettings = cloneDeep( settingsToRemove );
- PRESET_METADATA.forEach( ( { path } ) => {
- const presetData = get( newSettings, path );
- if ( presetData ) {
- set( newSettings, path, ( presetData ?? {} ).user );
- }
- } );
- return newSettings;
-}
const cleanEmptyObject = ( object ) => {
if ( ! isObject( object ) || Array.isArray( object ) ) {
return object;
@@ -97,7 +70,7 @@ function useGlobalStylesUserConfig() {
const config = useMemo( () => {
return {
- settings: addUserOriginToSettings( settings ?? {} ),
+ settings: settings ?? {},
styles: styles ?? {},
};
}, [ settings, styles ] );
@@ -111,15 +84,12 @@ function useGlobalStylesUserConfig() {
);
const currentConfig = {
styles: record?.styles ?? {},
- settings: addUserOriginToSettings( record?.settings ?? {} ),
+ settings: record?.settings ?? {},
};
const updatedConfig = callback( currentConfig );
editEntityRecord( 'root', 'globalStyles', globalStylesId, {
styles: cleanEmptyObject( updatedConfig.styles ) || {},
- settings:
- cleanEmptyObject(
- removeUserOriginFromSettings( updatedConfig.settings )
- ) || {},
+ settings: cleanEmptyObject( updatedConfig.settings ) || {},
} );
},
[ globalStylesId ]
diff --git a/phpunit/class-wp-theme-json-test.php b/phpunit/class-wp-theme-json-test.php
index fb2388dda5444a..f772b4371a7269 100644
--- a/phpunit/class-wp-theme-json-test.php
+++ b/phpunit/class-wp-theme-json-test.php
@@ -1237,20 +1237,22 @@ function test_remove_insecure_properties_removes_non_preset_settings() {
'color' => array(
'custom' => true,
'palette' => array(
- array(
- 'name' => 'Red',
- 'slug' => 'red',
- 'color' => '#ff0000',
- ),
- array(
- 'name' => 'Green',
- 'slug' => 'green',
- 'color' => '#00ff00',
- ),
- array(
- 'name' => 'Blue',
- 'slug' => 'blue',
- 'color' => '#0000ff',
+ 'user' => array(
+ array(
+ 'name' => 'Red',
+ 'slug' => 'red',
+ 'color' => '#ff0000',
+ ),
+ array(
+ 'name' => 'Green',
+ 'slug' => 'green',
+ 'color' => '#00ff00',
+ ),
+ array(
+ 'name' => 'Blue',
+ 'slug' => 'blue',
+ 'color' => '#0000ff',
+ ),
),
),
),
@@ -1262,20 +1264,22 @@ function test_remove_insecure_properties_removes_non_preset_settings() {
'color' => array(
'custom' => true,
'palette' => array(
- array(
- 'name' => 'Yellow',
- 'slug' => 'yellow',
- 'color' => '#ff0000',
- ),
- array(
- 'name' => 'Pink',
- 'slug' => 'pink',
- 'color' => '#00ff00',
- ),
- array(
- 'name' => 'Orange',
- 'slug' => 'orange',
- 'color' => '#0000ff',
+ 'user' => array(
+ array(
+ 'name' => 'Yellow',
+ 'slug' => 'yellow',
+ 'color' => '#ff0000',
+ ),
+ array(
+ 'name' => 'Pink',
+ 'slug' => 'pink',
+ 'color' => '#00ff00',
+ ),
+ array(
+ 'name' => 'Orange',
+ 'slug' => 'orange',
+ 'color' => '#0000ff',
+ ),
),
),
),
@@ -1293,20 +1297,22 @@ function test_remove_insecure_properties_removes_non_preset_settings() {
'settings' => array(
'color' => array(
'palette' => array(
- array(
- 'name' => 'Red',
- 'slug' => 'red',
- 'color' => '#ff0000',
- ),
- array(
- 'name' => 'Green',
- 'slug' => 'green',
- 'color' => '#00ff00',
- ),
- array(
- 'name' => 'Blue',
- 'slug' => 'blue',
- 'color' => '#0000ff',
+ 'user' => array(
+ array(
+ 'name' => 'Red',
+ 'slug' => 'red',
+ 'color' => '#ff0000',
+ ),
+ array(
+ 'name' => 'Green',
+ 'slug' => 'green',
+ 'color' => '#00ff00',
+ ),
+ array(
+ 'name' => 'Blue',
+ 'slug' => 'blue',
+ 'color' => '#0000ff',
+ ),
),
),
),
@@ -1314,20 +1320,22 @@ function test_remove_insecure_properties_removes_non_preset_settings() {
'core/group' => array(
'color' => array(
'palette' => array(
- array(
- 'name' => 'Yellow',
- 'slug' => 'yellow',
- 'color' => '#ff0000',
- ),
- array(
- 'name' => 'Pink',
- 'slug' => 'pink',
- 'color' => '#00ff00',
- ),
- array(
- 'name' => 'Orange',
- 'slug' => 'orange',
- 'color' => '#0000ff',
+ 'user' => array(
+ array(
+ 'name' => 'Yellow',
+ 'slug' => 'yellow',
+ 'color' => '#ff0000',
+ ),
+ array(
+ 'name' => 'Pink',
+ 'slug' => 'pink',
+ 'color' => '#00ff00',
+ ),
+ array(
+ 'name' => 'Orange',
+ 'slug' => 'orange',
+ 'color' => '#0000ff',
+ ),
),
),
),
@@ -1345,49 +1353,53 @@ function test_remove_insecure_properties_removes_unsafe_preset_settings() {
'settings' => array(
'color' => array(
'palette' => array(
- array(
- 'name' => 'Red/>ok',
- 'slug' => 'red',
- 'color' => '#ff0000',
- ),
- array(
- 'name' => 'Green',
- 'slug' => 'a" attr',
- 'color' => '#00ff00',
- ),
- array(
- 'name' => 'Blue',
- 'slug' => 'blue',
- 'color' => 'var(--color, var(--unsafe-fallback))',
- ),
- array(
- 'name' => 'Pink',
- 'slug' => 'pink',
- 'color' => '#FFC0CB',
+ 'user' => array(
+ array(
+ 'name' => 'Red/>ok',
+ 'slug' => 'red',
+ 'color' => '#ff0000',
+ ),
+ array(
+ 'name' => 'Green',
+ 'slug' => 'a" attr',
+ 'color' => '#00ff00',
+ ),
+ array(
+ 'name' => 'Blue',
+ 'slug' => 'blue',
+ 'color' => 'var(--color, var(--unsafe-fallback))',
+ ),
+ array(
+ 'name' => 'Pink',
+ 'slug' => 'pink',
+ 'color' => '#FFC0CB',
+ ),
),
),
),
'typography' => array(
'fontFamilies' => array(
- array(
- 'name' => 'Helvetica Arial/>test',
- 'slug' => 'helvetica-arial',
- 'fontFamily' => 'Helvetica Neue, Helvetica, Arial, sans-serif',
- ),
- array(
- 'name' => 'Geneva',
- 'slug' => 'geneva#asa',
- 'fontFamily' => 'Geneva, Tahoma, Verdana, sans-serif',
- ),
- array(
- 'name' => 'Cambria',
- 'slug' => 'cambria',
- 'fontFamily' => 'Cambria, Georgia, serif',
- ),
- array(
- 'name' => 'Helvetica Arial',
- 'slug' => 'helvetica-arial',
- 'fontFamily' => 'var(--fontFamily, var(--unsafe-fallback))',
+ 'user' => array(
+ array(
+ 'name' => 'Helvetica Arial/>test',
+ 'slug' => 'helvetica-arial',
+ 'fontFamily' => 'Helvetica Neue, Helvetica, Arial, sans-serif',
+ ),
+ array(
+ 'name' => 'Geneva',
+ 'slug' => 'geneva#asa',
+ 'fontFamily' => 'Geneva, Tahoma, Verdana, sans-serif',
+ ),
+ array(
+ 'name' => 'Cambria',
+ 'slug' => 'cambria',
+ 'fontFamily' => 'Cambria, Georgia, serif',
+ ),
+ array(
+ 'name' => 'Helvetica Arial',
+ 'slug' => 'helvetica-arial',
+ 'fontFamily' => 'var(--fontFamily, var(--unsafe-fallback))',
+ ),
),
),
),
@@ -1395,25 +1407,27 @@ function test_remove_insecure_properties_removes_unsafe_preset_settings() {
'core/group' => array(
'color' => array(
'palette' => array(
- array(
- 'name' => 'Red/>ok',
- 'slug' => 'red',
- 'color' => '#ff0000',
- ),
- array(
- 'name' => 'Green',
- 'slug' => 'a" attr',
- 'color' => '#00ff00',
- ),
- array(
- 'name' => 'Blue',
- 'slug' => 'blue',
- 'color' => 'var(--color, var(--unsafe--fallback))',
- ),
- array(
- 'name' => 'Pink',
- 'slug' => 'pink',
- 'color' => '#FFC0CB',
+ 'user' => array(
+ array(
+ 'name' => 'Red/>ok',
+ 'slug' => 'red',
+ 'color' => '#ff0000',
+ ),
+ array(
+ 'name' => 'Green',
+ 'slug' => 'a" attr',
+ 'color' => '#00ff00',
+ ),
+ array(
+ 'name' => 'Blue',
+ 'slug' => 'blue',
+ 'color' => 'var(--color, var(--unsafe--fallback))',
+ ),
+ array(
+ 'name' => 'Pink',
+ 'slug' => 'pink',
+ 'color' => '#FFC0CB',
+ ),
),
),
),
@@ -1428,19 +1442,23 @@ function test_remove_insecure_properties_removes_unsafe_preset_settings() {
'settings' => array(
'color' => array(
'palette' => array(
- array(
- 'name' => 'Pink',
- 'slug' => 'pink',
- 'color' => '#FFC0CB',
+ 'user' => array(
+ array(
+ 'name' => 'Pink',
+ 'slug' => 'pink',
+ 'color' => '#FFC0CB',
+ ),
),
),
),
'typography' => array(
'fontFamilies' => array(
- array(
- 'name' => 'Cambria',
- 'slug' => 'cambria',
- 'fontFamily' => 'Cambria, Georgia, serif',
+ 'user' => array(
+ array(
+ 'name' => 'Cambria',
+ 'slug' => 'cambria',
+ 'fontFamily' => 'Cambria, Georgia, serif',
+ ),
),
),
),
@@ -1448,10 +1466,12 @@ function test_remove_insecure_properties_removes_unsafe_preset_settings() {
'core/group' => array(
'color' => array(
'palette' => array(
- array(
- 'name' => 'Pink',
- 'slug' => 'pink',
- 'color' => '#FFC0CB',
+ 'user' => array(
+ array(
+ 'name' => 'Pink',
+ 'slug' => 'pink',
+ 'color' => '#FFC0CB',
+ ),
),
),
),