Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update: Refactor panel color gradient settings to use a tools panel. Unify color UI. #41091

Merged
merged 5 commits into from
May 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 35 additions & 61 deletions packages/block-editor/src/components/colors-gradients/dropdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ import {
Dropdown,
FlexItem,
__experimentalHStack as HStack,
__experimentalItem as Item,
__experimentalItemGroup as ItemGroup,
__experimentalToolsPanelItem as ToolsPanelItem,
} from '@wordpress/components';

Expand All @@ -22,46 +20,34 @@ import {
*/
import ColorGradientControl from './control';

// Conditionally wraps the `ColorGradientSettingsDropdown` color controls in an
// `ItemGroup` allowing for a standalone group of controls to be
// rendered semantically.
const WithItemGroup = ( { __experimentalIsItemGroup, children } ) => {
if ( ! __experimentalIsItemGroup ) {
return children;
}

return (
<ItemGroup
isBordered
isSeparated
className="block-editor-panel-color-gradient-settings__item-group"
>
{ children }
</ItemGroup>
);
};

// When the `ColorGradientSettingsDropdown` controls are being rendered to a
// `ToolsPanel` they must be wrapped in a `ToolsPanelItem`.
const WithToolsPanelItem = ( {
__experimentalIsItemGroup,
settings,
children,
...props
} ) => {
if ( __experimentalIsItemGroup ) {
return children;
}

const WithToolsPanelItem = ( { setting, children, panelId, ...props } ) => {
const clearValue = () => {
if ( setting.colorValue ) {
setting.onColorChange();
} else if ( setting.gradientValue ) {
setting.onGradientChange();
}
};
return (
<ToolsPanelItem
hasValue={ settings.hasValue }
label={ settings.label }
onDeselect={ settings.onDeselect }
isShownByDefault={ settings.isShownByDefault }
resetAllFilter={ settings.resetAllFilter }
hasValue={ () => {
return !! setting.colorValue || !! setting.gradientValue;
} }
label={ setting.label }
onDeselect={ clearValue }
isShownByDefault={
setting.isShownByDefault !== undefined
? setting.isShownByDefault
: true
}
{ ...props }
className="block-editor-tools-panel-color-gradient-settings__item"
panelId={ panelId }
// Pass resetAllFilter if supplied due to rendering via SlotFill
// into parent ToolsPanel.
resetAllFilter={ setting.resetAllFilter }
>
{ children }
</ToolsPanelItem>
Expand All @@ -82,23 +68,21 @@ const LabeledColorIndicator = ( { colorValue, label } ) => (
// or as a `Button` if it isn't e.g. the controls are being rendered in
// a `ToolsPanel`.
const renderToggle = ( settings ) => ( { onToggle, isOpen } ) => {
const { __experimentalIsItemGroup, colorValue, label } = settings;
const { colorValue, label } = settings;

// Determine component, `Item` or `Button`, to wrap color indicator with.
const ToggleComponent = __experimentalIsItemGroup ? Item : Button;
const toggleClassName = __experimentalIsItemGroup
? 'block-editor-panel-color-gradient-settings__item'
: 'block-editor-panel-color-gradient-settings__dropdown';
const toggleProps = {
onClick: onToggle,
className: classnames( toggleClassName, { 'is-open': isOpen } ),
'aria-expanded': __experimentalIsItemGroup ? undefined : isOpen,
className: classnames(
'block-editor-panel-color-gradient-settings__dropdown',
{ 'is-open': isOpen }
),
'aria-expanded': isOpen,
};

return (
<ToggleComponent { ...toggleProps }>
<Button { ...toggleProps }>
<LabeledColorIndicator colorValue={ colorValue } label={ label } />
</ToggleComponent>
</Button>
);
};

Expand All @@ -115,15 +99,11 @@ export default function ColorGradientSettingsDropdown( {
disableCustomGradients,
enableAlpha,
gradients,
__experimentalIsItemGroup = true,
settings,
__experimentalHasMultipleOrigins,
__experimentalIsRenderedInSidebar,
...props
} ) {
const dropdownClassName = __experimentalIsItemGroup
? 'block-editor-panel-color-gradient-settings__dropdown'
: 'block-editor-tools-panel-color-gradient-settings__dropdown';
let popoverProps;
if ( __experimentalIsRenderedInSidebar ) {
popoverProps = {
Expand All @@ -133,12 +113,10 @@ export default function ColorGradientSettingsDropdown( {
}

return (
// Only wrap with `ItemGroup` if these controls are being rendered
// semantically.
<WithItemGroup __experimentalIsItemGroup={ __experimentalIsItemGroup }>
<>
{ settings.map( ( setting, index ) => {
const controlProps = {
clearable: __experimentalIsItemGroup ? undefined : false,
clearable: false,
colorValue: setting.colorValue,
colors,
disableCustomColors,
Expand All @@ -156,7 +134,6 @@ export default function ColorGradientSettingsDropdown( {
};
const toggleSettings = {
colorValue: setting.gradientValue ?? setting.colorValue,
__experimentalIsItemGroup,
label: setting.label,
};

Expand All @@ -166,15 +143,12 @@ export default function ColorGradientSettingsDropdown( {
// `ToolsPanelItem`
<WithToolsPanelItem
key={ index }
__experimentalIsItemGroup={
__experimentalIsItemGroup
}
settings={ setting }
setting={ setting }
{ ...props }
>
<Dropdown
popoverProps={ popoverProps }
className={ dropdownClassName }
className="block-editor-tools-panel-color-gradient-settings__dropdown"
contentClassName="block-editor-panel-color-gradient-settings__dropdown-content"
renderToggle={ renderToggle( toggleSettings ) }
renderContent={ () => (
Expand All @@ -185,6 +159,6 @@ export default function ColorGradientSettingsDropdown( {
)
);
} ) }
</WithItemGroup>
</>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,83 +9,26 @@ import { every, isEmpty } from 'lodash';
*/
import {
__experimentalSpacer as Spacer,
ColorIndicator,
PanelBody,
__experimentalToolsPanel as ToolsPanel,
} from '@wordpress/components';
import { sprintf, __ } from '@wordpress/i18n';
import { useRegistry } from '@wordpress/data';
import { useInstanceId } from '@wordpress/compose';

/**
* Internal dependencies
*/
import ColorGradientSettingsDropdown from './dropdown';
import { getColorObjectByColorValue } from '../colors';
import { __experimentalGetGradientObjectByGradientValue } from '../gradients';
import useSetting from '../use-setting';
import useCommonSingleMultipleSelects from './use-common-single-multiple-selects';
import useMultipleOriginColorsAndGradients from './use-multiple-origin-colors-and-gradients';

// translators: first %s: The type of color or gradient (e.g. background, overlay...), second %s: the color name or value (e.g. red or #ff0000)
const colorIndicatorAriaLabel = __( '(%s: color %s)' );

// translators: first %s: The type of color or gradient (e.g. background, overlay...), second %s: the color name or value (e.g. red or #ff0000)
const gradientIndicatorAriaLabel = __( '(%s: gradient %s)' );

const colorsAndGradientKeys = [
'colors',
'disableCustomColors',
'gradients',
'disableCustomGradients',
];

const Indicators = ( { colors, gradients, settings } ) => {
return settings.map(
(
{
colorValue,
gradientValue,
label,
colors: availableColors,
gradients: availableGradients,
},
index
) => {
if ( ! colorValue && ! gradientValue ) {
return null;
}
let ariaLabel;
if ( colorValue ) {
const colorObject = getColorObjectByColorValue(
availableColors || colors,
colorValue
);
ariaLabel = sprintf(
colorIndicatorAriaLabel,
label.toLowerCase(),
( colorObject && colorObject.name ) || colorValue
);
} else {
const gradientObject = __experimentalGetGradientObjectByGradientValue(
availableGradients || gradients,
colorValue
);
ariaLabel = sprintf(
gradientIndicatorAriaLabel,
label.toLowerCase(),
( gradientObject && gradientObject.name ) || gradientValue
);
}

return (
<ColorIndicator
key={ index }
colorValue={ colorValue || gradientValue }
aria-label={ ariaLabel }
/>
);
}
);
};

export const PanelColorGradientSettingsInner = ( {
className,
colors,
Expand All @@ -99,8 +42,9 @@ export const PanelColorGradientSettingsInner = ( {
__experimentalHasMultipleOrigins,
__experimentalIsRenderedInSidebar,
enableAlpha,
...props
} ) => {
const panelId = useInstanceId( PanelColorGradientSettingsInner );
const { batch } = useRegistry();
if (
isEmpty( colors ) &&
isEmpty( gradients ) &&
Expand All @@ -120,28 +64,38 @@ export const PanelColorGradientSettingsInner = ( {
return null;
}

const titleElement = (
<span className="block-editor-panel-color-gradient-settings__panel-title">
{ title }
<Indicators
colors={ colors }
gradients={ gradients }
settings={ settings }
/>
</span>
);

return (
<PanelBody
<ToolsPanel
className={ classnames(
'block-editor-panel-color-gradient-settings',
className
) }
title={ showTitle ? titleElement : undefined }
{ ...props }
label={ showTitle ? title : undefined }
resetAll={ () => {
batch( () => {
settings.forEach(
( {
colorValue,
gradientValue,
onColorChange,
onGradientChange,
} ) => {
if ( colorValue ) {
onColorChange();
} else if ( gradientValue ) {
onGradientChange();
}
}
);
} );
} }
panelId={ panelId }
__experimentalFirstVisibleItemClass="first"
__experimentalLastVisibleItemClass="last"
>
<ColorGradientSettingsDropdown
settings={ settings }
panelId={ panelId }
{ ...{
colors,
gradients,
Expand All @@ -157,7 +111,7 @@ export const PanelColorGradientSettingsInner = ( {
<Spacer marginY={ 4 } /> { children }
</>
) }
</PanelBody>
</ToolsPanel>
);
};

Expand Down
Loading