Skip to content

Commit

Permalink
Make user able to change all color palette origins
Browse files Browse the repository at this point in the history
  • Loading branch information
jorgefilipecosta committed Nov 19, 2021
1 parent 914c9c9 commit fb6d2fa
Show file tree
Hide file tree
Showing 5 changed files with 311 additions and 236 deletions.
68 changes: 37 additions & 31 deletions lib/class-wp-theme-json-gutenberg.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 ) );
}
}
}
}
Expand Down Expand Up @@ -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;
}

Expand Down
109 changes: 69 additions & 40 deletions packages/components/src/color-edit/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,14 @@ function ColorNameInput( { value, onChange } ) {
}

function ColorOption( {
canOnlyChangeValues,
color,
onChange,
isEditing,
onStartEditing,
onRemove,
onStopEditing,
slugPrefix,
} ) {
const focusOutsideProps = useFocusOutside( onStopEditing );
return (
Expand All @@ -68,22 +70,22 @@ function ColorOption( {
<ColorIndicatorStyled colorValue={ color.color } />
</FlexItem>
<FlexItem>
{ isEditing ? (
{ isEditing && ! canOnlyChangeValues ? (
<ColorNameInput
value={ color.name }
onChange={ ( nextName ) =>
onChange( {
...color,
name: nextName,
slug: kebabCase( nextName ),
slug: slugPrefix + kebabCase( nextName ),
} )
}
/>
) : (
<ColorNameContainer>{ color.name }</ColorNameContainer>
) }
</FlexItem>
{ isEditing && (
{ isEditing && ! canOnlyChangeValues && (
<FlexItem>
<RemoveButton
isSmall
Expand Down Expand Up @@ -119,6 +121,8 @@ function ColorPaletteEditListView( {
onChange,
editingColor,
setEditingColor,
canOnlyChangeValues,
slugPrefix,
} ) {
// When unmounting the component if there are empty colors (the user did not complete the insertion) clean them.
const colorReference = useRef();
Expand All @@ -140,6 +144,7 @@ function ColorPaletteEditListView( {
<ItemGroup isBordered isSeparated>
{ colors.map( ( color, index ) => (
<ColorOption
canOnlyChangeValues={ canOnlyChangeValues }
key={ index }
color={ color }
onStartEditing={ () => {
Expand Down Expand Up @@ -177,6 +182,7 @@ function ColorPaletteEditListView( {
setEditingColor( null );
}
} }
slugPrefix={ slugPrefix }
/>
) ) }
</ItemGroup>
Expand All @@ -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 =
Expand All @@ -200,7 +214,7 @@ export default function ColorEdit( { colors = EMPTY_ARRAY, onChange } ) {
return (
<ColorEditStyles>
<ColorHStackHeader>
<ColorHeading>{ __( 'Custom' ) }</ColorHeading>
<ColorHeading>{ paletteLabel }</ColorHeading>
<ColorActionsContainer>
{ isEditing && (
<DoneButton
Expand All @@ -213,24 +227,26 @@ export default function ColorEdit( { colors = EMPTY_ARRAY, onChange } ) {
{ __( 'Done' ) }
</DoneButton>
) }
<Button
isSmall
isPressed={ isAdding }
icon={ plus }
label={ __( 'Add custom color' ) }
onClick={ () => {
onChange( [
...colors,
{
color: '#000',
name: '',
slug: '',
},
] );
setIsEditing( true );
setEditingColor( colors.length );
} }
/>
{ ! canOnlyChangeValues && (
<Button
isSmall
isPressed={ isAdding }
icon={ plus }
label={ __( 'Add custom color' ) }
onClick={ () => {
onChange( [
...colors,
{
color: '#000',
name: '',
slug: '',
},
] );
setIsEditing( true );
setEditingColor( colors.length );
} }
/>
) }
{ ! isEditing && (
<Button
disabled={ ! hasColors }
Expand All @@ -242,28 +258,42 @@ export default function ColorEdit( { colors = EMPTY_ARRAY, onChange } ) {
} }
/>
) }
{ isEditing && (
{ isEditing && ( canReset || ! canOnlyChangeValues ) && (
<DropdownMenu
icon={ moreVertical }
label={ __( 'Custom color options' ) }
label={ __( 'Color options' ) }
toggleProps={ {
isSmall: true,
} }
>
{ ( { onClose } ) => (
<>
<NavigableMenu role="menu">
<Button
variant="tertiary"
onClick={ () => {
setEditingColor( null );
setIsEditing( false );
onChange();
onClose();
} }
>
{ __( 'Remove all custom colors' ) }
</Button>
{ ! canOnlyChangeValues && (
<Button
variant="tertiary"
onClick={ () => {
setEditingColor( null );
setIsEditing( false );
onChange();
onClose();
} }
>
{ __( 'Remove all colors' ) }
</Button>
) }
{ canReset && (
<Button
variant="tertiary"
onClick={ () => {
setEditingColor( null );
onChange();
onClose();
} }
>
{ __( 'Reset colors' ) }
</Button>
) }
</NavigableMenu>
</>
) }
Expand All @@ -275,10 +305,12 @@ export default function ColorEdit( { colors = EMPTY_ARRAY, onChange } ) {
<>
{ isEditing && (
<ColorPaletteEditListView
canOnlyChangeValues={ canOnlyChangeValues }
colors={ colors }
onChange={ onChange }
editingColor={ editingColor }
setEditingColor={ setEditingColor }
slugPrefix={ slugPrefix }
/>
) }
{ ! isEditing && (
Expand All @@ -291,10 +323,7 @@ export default function ColorEdit( { colors = EMPTY_ARRAY, onChange } ) {
) }
</>
) }
{ ! hasColors &&
__(
'Custom colors are empty! Add some colors to create your own color palette.'
) }
{ ! hasColors && emptyMessage }
</ColorEditStyles>
);
}
Original file line number Diff line number Diff line change
@@ -1,22 +1,72 @@
/**
* 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
*/
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 (
<div className="edit-site-global-styles-color-palette-panel">
<ColorEdit colors={ userColors } onChange={ setColors } />
</div>
<VStack
className="edit-site-global-styles-color-palette-panel"
spacing={ 10 }
>
{ !! themeColors && !! themeColors.length && (
<ColorEdit
canReset={ themeColors !== baseThemeColors }
canOnlyChangeValues
colors={ themeColors }
onChange={ setThemeColors }
paletteLabel={ __( 'Theme' ) }
/>
) }
{ !! defaultColors && !! defaultColors.length && (
<ColorEdit
canReset={ defaultColors !== baseDefaultColors }
canOnlyChangeValues
colors={ defaultColors }
onChange={ setDefaultColors }
paletteLabel={ __( 'Default' ) }
/>
) }
<ColorEdit
colors={ customColors }
onChange={ setCustomColors }
paletteLabel={ __( 'Custom' ) }
emptyMessage={ __(
'Custom colors are empty! Add some colors to create your own color palette.'
) }
slugPrefix="custom-"
/>
</VStack>
);
}
Loading

0 comments on commit fb6d2fa

Please sign in to comment.