From 2cef96393cd301b7a4a908a8156736e08aaf7f04 Mon Sep 17 00:00:00 2001 From: MaggieCabrera Date: Fri, 24 Feb 2023 11:49:35 +0100 Subject: [PATCH 1/4] create a filter slot --- .../inspector-controls-tabs/styles-tab.js | 1 + .../components/inspector-controls/groups.js | 2 + packages/block-editor/src/hooks/duotone.js | 78 +++++++++++++------ 3 files changed, 57 insertions(+), 24 deletions(-) diff --git a/packages/block-editor/src/components/inspector-controls-tabs/styles-tab.js b/packages/block-editor/src/components/inspector-controls-tabs/styles-tab.js index 3a7f625d10de26..c901e9cddbe147 100644 --- a/packages/block-editor/src/components/inspector-controls-tabs/styles-tab.js +++ b/packages/block-editor/src/components/inspector-controls-tabs/styles-tab.js @@ -32,6 +32,7 @@ const StylesTab = ( { blockName, clientId, hasBlockStyles } ) => { label={ __( 'Color' ) } className="color-block-support-panel__inner-wrapper" /> + - { - const maybePreset = getDuotonePresetFromColors( - newDuotone, - duotonePalette - ); - - const newStyle = { - ...style, - color: { - ...style?.color, - duotone: maybePreset ?? newDuotone, // use preset or fallback to custom colors. - }, - }; - setAttributes( { style: newStyle } ); - } } - /> - + <> + + { + const maybePreset = getDuotonePresetFromColors( + newDuotone, + duotonePalette + ); + + const newStyle = { + ...style, + color: { + ...style?.color, + duotone: maybePreset ?? newDuotone, // use preset or fallback to custom colors. + }, + }; + setAttributes( { style: newStyle } ); + } } + /> + + + { + const maybePreset = getDuotonePresetFromColors( + newDuotone, + duotonePalette + ); + + const newStyle = { + ...style, + color: { + ...style?.color, + duotone: maybePreset ?? newDuotone, // use preset or fallback to custom colors. + }, + }; + setAttributes( { style: newStyle } ); + } } + /> + + ); } From f5d14fee9ef24cad79b0c15f42a597edb422b58f Mon Sep 17 00:00:00 2001 From: MaggieCabrera Date: Fri, 24 Feb 2023 11:57:19 +0100 Subject: [PATCH 2/4] disable custom duotone for the toolbar --- packages/block-editor/src/hooks/duotone.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/block-editor/src/hooks/duotone.js b/packages/block-editor/src/hooks/duotone.js index ae5dd70b034105..a5da38ebd79872 100644 --- a/packages/block-editor/src/hooks/duotone.js +++ b/packages/block-editor/src/hooks/duotone.js @@ -165,8 +165,8 @@ function DuotonePanel( { attributes, setAttributes } ) { { const maybePreset = getDuotonePresetFromColors( From e85536fb5a424b259793d5a9d46be74b5a9b226e Mon Sep 17 00:00:00 2001 From: MaggieCabrera Date: Tue, 4 Apr 2023 11:20:48 +0200 Subject: [PATCH 3/4] add a prop to show duotone palettes grouped by origin --- .../src/components/duotone-control/index.js | 2 + packages/block-editor/src/hooks/duotone.js | 25 ++- .../src/duotone-picker/duotone-picker.tsx | 167 +++++++++++------- .../components/src/duotone-picker/types.ts | 16 ++ 4 files changed, 149 insertions(+), 61 deletions(-) diff --git a/packages/block-editor/src/components/duotone-control/index.js b/packages/block-editor/src/components/duotone-control/index.js index d27e6863fe0dfd..fdfbefc4723094 100644 --- a/packages/block-editor/src/components/duotone-control/index.js +++ b/packages/block-editor/src/components/duotone-control/index.js @@ -16,6 +16,7 @@ import { Icon, filter } from '@wordpress/icons'; function DuotoneControl( { colorPalette, duotonePalette, + duotonePaletteByOrigin, disableCustomColors, disableCustomDuotone, value, @@ -67,6 +68,7 @@ function DuotoneControl( { [ ...userPresets, @@ -82,6 +83,24 @@ function useMultiOriginPresets( { presetSetting, defaultSetting } ) { ); } +function useGroupedPresets( { presetSetting, defaultSetting } ) { + const disableDefault = ! useSetting( defaultSetting ); + const userPresets = + useSetting( `${ presetSetting }.custom` ) || EMPTY_ARRAY; + const themePresets = + useSetting( `${ presetSetting }.theme` ) || EMPTY_ARRAY; + const defaultPresets = + useSetting( `${ presetSetting }.default` ) || EMPTY_ARRAY; + + return useMemo( () => { + return { + user: userPresets, + theme: themePresets, + default: disableDefault ? EMPTY_ARRAY : defaultPresets, + }; + }, [ disableDefault, userPresets, themePresets, defaultPresets ] ); +} + export function getColorsFromDuotonePreset( duotone, duotonePalette ) { if ( ! duotone ) { return; @@ -115,6 +134,10 @@ function DuotonePanel( { attributes, setAttributes } ) { presetSetting: 'color.duotone', defaultSetting: 'color.defaultDuotone', } ); + const duotonePaletteByOrigin = useGroupedPresets( { + presetSetting: 'color.duotone', + defaultSetting: 'color.defaultDuotone', + } ); const colorPalette = useMultiOriginPresets( { presetSetting: 'color.palette', defaultSetting: 'color.defaultPalette', @@ -163,7 +186,7 @@ function DuotonePanel( { attributes, setAttributes } ) { { - * const [ duotone, setDuotone ] = useState( [ '#000000', '#ffffff' ] ); - * return ( - * <> - * - * - * - * ); - * }; - * ``` - */ -function DuotonePicker( { - clearable = true, - unsetable = true, +function SinglePalette( { + defaultDark, + defaultLight, + clearable, + unsetable, colorPalette, duotonePalette, disableCustomColors, disableCustomDuotone, value, + unsetOption, onChange, -}: DuotonePickerProps ) { - const [ defaultDark, defaultLight ] = useMemo( - () => getDefaultColors( colorPalette ), - [ colorPalette ] - ); - - const isUnset = value === 'unset'; - - const unsetOption = ( - { - onChange( isUnset ? undefined : 'unset' ); - } } - /> - ); - +}: SinglePaletteProps ) { + const colorValue = value && value !== 'unset' ? value : undefined; const options = duotonePalette.map( ( { colors, slug, name } ) => { const style = { background: getGradientFromCSSColors( colors, '135deg' ), @@ -137,7 +89,7 @@ function DuotonePicker( { { ! disableCustomColors && ! disableCustomDuotone && ( ) } @@ -145,7 +97,7 @@ function DuotonePicker( { { @@ -172,4 +124,99 @@ function DuotonePicker( { ); } +/** + * ```jsx + * import { DuotonePicker, DuotoneSwatch } from '@wordpress/components'; + * import { useState } from '@wordpress/element'; + * + * const DUOTONE_PALETTE = [ + * { colors: [ '#8c00b7', '#fcff41' ], name: 'Purple and yellow', slug: 'purple-yellow' }, + * { colors: [ '#000097', '#ff4747' ], name: 'Blue and red', slug: 'blue-red' }, + * ]; + * + * const COLOR_PALETTE = [ + * { color: '#ff4747', name: 'Red', slug: 'red' }, + * { color: '#fcff41', name: 'Yellow', slug: 'yellow' }, + * { color: '#000097', name: 'Blue', slug: 'blue' }, + * { color: '#8c00b7', name: 'Purple', slug: 'purple' }, + * ]; + * + * const Example = () => { + * const [ duotone, setDuotone ] = useState( [ '#000000', '#ffffff' ] ); + * return ( + * <> + * + * + * + * ); + * }; + * ``` + */ +function DuotonePicker( { + clearable = true, + unsetable = true, + colorPalette, + duotonePalette, + duotonePaletteByOrigin, + disableCustomColors, + disableCustomDuotone, + value, + onChange, +}: DuotonePickerProps ) { + const [ defaultDark, defaultLight ] = useMemo( + () => getDefaultColors( colorPalette ), + [ colorPalette ] + ); + + const isUnset = value === 'unset'; + + const unsetOption = ( + { + onChange( isUnset ? undefined : 'unset' ); + } } + /> + ); + + const paletteCommonProps = { + defaultDark, + defaultLight, + clearable, + unsetable, + colorPalette, + duotonePalette, + disableCustomColors, + disableCustomDuotone, + value, + unsetOption, + onChange, + }; + + return ( + <> + { duotonePaletteByOrigin ? ( + + ) : ( + + ) } + + ); +} + export default DuotonePicker; diff --git a/packages/components/src/duotone-picker/types.ts b/packages/components/src/duotone-picker/types.ts index 3d5927675f542f..57d2878b124ce8 100644 --- a/packages/components/src/duotone-picker/types.ts +++ b/packages/components/src/duotone-picker/types.ts @@ -19,6 +19,10 @@ export type DuotonePickerProps = { * Array of duotone presets of the form `{ colors: [ '#000000', '#ffffff' ], name: 'Grayscale', slug: 'grayscale' }`. */ duotonePalette: DuotoneColor[]; + /** + * Array of duotone presets of the form `{ colors: [ '#000000', '#ffffff' ], name: 'Grayscale', slug: 'grayscale' } grouped by origin`. + */ + duotonePaletteByOrigin?: duotonePaletteByOrigin; /** * Whether custom colors should be disabled. * @@ -47,6 +51,12 @@ type Color = { slug: string; }; +type duotonePaletteByOrigin = { + theme: DuotoneColor[]; + user: DuotoneColor[]; + default: DuotoneColor[]; +}; + type DuotoneColor = { colors: string[]; name: string; @@ -59,3 +69,9 @@ export type DuotoneSwatchProps = { */ values?: string[] | null; }; + +export type SinglePaletteProps = DuotonePickerProps & { + defaultDark: string; + defaultLight: string; + unsetOption: any; +}; From 8577539576e2e1430e049e26f6dcbe2998f87dfb Mon Sep 17 00:00:00 2001 From: MaggieCabrera Date: Wed, 5 Apr 2023 13:32:07 +0200 Subject: [PATCH 4/4] show palettes by group --- packages/block-editor/src/hooks/duotone.js | 23 ++-- .../src/duotone-picker/duotone-picker.tsx | 114 ++++++++++++++---- .../components/src/duotone-picker/types.ts | 40 ++++-- 3 files changed, 140 insertions(+), 37 deletions(-) diff --git a/packages/block-editor/src/hooks/duotone.js b/packages/block-editor/src/hooks/duotone.js index 934f1c9dfb7a59..22c0414b9ac61d 100644 --- a/packages/block-editor/src/hooks/duotone.js +++ b/packages/block-editor/src/hooks/duotone.js @@ -93,11 +93,20 @@ function useGroupedPresets( { presetSetting, defaultSetting } ) { useSetting( `${ presetSetting }.default` ) || EMPTY_ARRAY; return useMemo( () => { - return { - user: userPresets, - theme: themePresets, - default: disableDefault ? EMPTY_ARRAY : defaultPresets, - }; + return [ + { + name: 'User', + palettes: userPresets, + }, + { + name: 'Theme', + palettes: themePresets, + }, + { + name: 'Default', + palettes: disableDefault ? EMPTY_ARRAY : defaultPresets, + }, + ]; }, [ disableDefault, userPresets, themePresets, defaultPresets ] ); } @@ -162,7 +171,7 @@ function DuotonePanel( { attributes, setAttributes } ) { __experimentalShareWithChildBlocks > { +function paletteOptions( { palette, value, onChange }: paletteOptionsProps ) { + return palette.map( ( { colors, slug, name } ) => { const style = { background: getGradientFromCSSColors( colors, '135deg' ), color: 'transparent', @@ -71,6 +63,27 @@ function SinglePalette( { /> ); } ); +} + +function SinglePalette( { + defaultDark, + defaultLight, + clearable, + unsetable, + colorPalette, + duotonePalette, + disableCustomColors, + disableCustomDuotone, + value, + unsetOption, + onChange, +}: SinglePaletteProps ) { + const colorValue = value && value !== 'unset' ? value : undefined; + const options = paletteOptions( { + palette: duotonePalette, + value, + onChange, + } ); return ( + { duotonePaletteByOrigin + .filter( ( { palettes } ) => palettes.length > 0 ) + .map( ( { name, palettes }, index, array ) => { + if ( index > 0 ) { + paletteProps.unsetable = false; + } + if ( index === array.length - 1 ) { + paletteProps.clearable = true; + } + return ( + + { name } + + + ); + } ) } + + ); +} + /** * ```jsx * import { DuotonePicker, DuotoneSwatch } from '@wordpress/components'; @@ -191,10 +258,8 @@ function DuotonePicker( { const paletteCommonProps = { defaultDark, defaultLight, - clearable, unsetable, colorPalette, - duotonePalette, disableCustomColors, disableCustomDuotone, value, @@ -205,13 +270,16 @@ function DuotonePicker( { return ( <> { duotonePaletteByOrigin ? ( - + <> + + ) : ( ) } diff --git a/packages/components/src/duotone-picker/types.ts b/packages/components/src/duotone-picker/types.ts index 57d2878b124ce8..18bb5607a9bcf4 100644 --- a/packages/components/src/duotone-picker/types.ts +++ b/packages/components/src/duotone-picker/types.ts @@ -51,11 +51,10 @@ type Color = { slug: string; }; -type duotonePaletteByOrigin = { - theme: DuotoneColor[]; - user: DuotoneColor[]; - default: DuotoneColor[]; -}; +type duotonePaletteByOrigin = Array< { + name: string; + palettes: DuotoneColor[]; +} >; type DuotoneColor = { colors: string[]; @@ -70,8 +69,35 @@ export type DuotoneSwatchProps = { values?: string[] | null; }; -export type SinglePaletteProps = DuotonePickerProps & { +export type SinglePaletteProps = { + defaultDark: string; + defaultLight: string; + unsetable?: boolean; + colorPalette: Color[]; + disableCustomColors?: boolean; + disableCustomDuotone?: boolean; + value?: string[] | 'unset'; + unsetOption: React.ReactElement; + onChange: ( value: DuotonePickerProps[ 'value' ] | undefined ) => void; + clearable?: boolean; + duotonePalette: DuotoneColor[]; +}; + +export type MultiplePalettesProps = { defaultDark: string; defaultLight: string; - unsetOption: any; + unsetable?: boolean; + colorPalette: Color[]; + disableCustomColors?: boolean; + disableCustomDuotone?: boolean; + value?: string[] | 'unset'; + unsetOption: React.ReactElement; + onChange: ( value: DuotonePickerProps[ 'value' ] | undefined ) => void; + duotonePaletteByOrigin: duotonePaletteByOrigin; +}; + +export type paletteOptionsProps = { + palette: DuotoneColor[]; + value?: string[] | 'unset'; + onChange: ( value: DuotonePickerProps[ 'value' ] | undefined ) => void; };