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

Try tabs instead of segmented control for switching between solid/gradient in color panels #41937

Merged
merged 12 commits into from
Jul 11, 2022
142 changes: 77 additions & 65 deletions packages/block-editor/src/components/colors-gradients/control.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,13 @@ import { every, isEmpty } from 'lodash';
/**
* WordPress dependencies
*/
import { useState } from '@wordpress/element';
import {
BaseControl,
__experimentalVStack as VStack,
__experimentalToggleGroupControl as ToggleGroupControl,
__experimentalToggleGroupControlOption as ToggleGroupControlOption,
TabPanel,
ColorPalette,
GradientPicker,
} from '@wordpress/components';
import { __ } from '@wordpress/i18n';

/**
* Internal dependencies
Expand All @@ -30,6 +27,19 @@ const colorsAndGradientKeys = [
'disableCustomGradients',
];

const TAB_COLOR = {
name: 'color',
title: 'Solid color',
value: 'color',
};
const TAB_GRADIENT = {
name: 'gradient',
title: 'Gradient',
value: 'gradient',
};

const TABS_SETTINGS = [ TAB_COLOR, TAB_GRADIENT ];

function ColorGradientControlInner( {
colors,
gradients,
Expand All @@ -52,13 +62,57 @@ function ColorGradientControlInner( {
const canChooseAGradient =
onGradientChange &&
( ! isEmpty( gradients ) || ! disableCustomGradients );
const [ currentTab, setCurrentTab ] = useState(
gradientValue ? 'gradient' : !! canChooseAColor && 'color'
);

if ( ! canChooseAColor && ! canChooseAGradient ) {
return null;
}

const tabPanels = {
[ TAB_COLOR.value ]: (
<ColorPalette
value={ colorValue }
onChange={
canChooseAGradient
? ( newColor ) => {
onColorChange( newColor );
onGradientChange();
}
: onColorChange
}
{ ...{ colors, disableCustomColors } }
__experimentalHasMultipleOrigins={
__experimentalHasMultipleOrigins
}
__experimentalIsRenderedInSidebar={
__experimentalIsRenderedInSidebar
}
clearable={ clearable }
enableAlpha={ enableAlpha }
/>
),
[ TAB_GRADIENT.value ]: (
<GradientPicker
value={ gradientValue }
onChange={
canChooseAColor
? ( newGradient ) => {
onGradientChange( newGradient );
onColorChange();
}
: onGradientChange
}
{ ...{ gradients, disableCustomGradients } }
__experimentalHasMultipleOrigins={
__experimentalHasMultipleOrigins
}
__experimentalIsRenderedInSidebar={
__experimentalIsRenderedInSidebar
}
clearable={ clearable }
/>
),
};

return (
<BaseControl
className={ classnames(
Expand All @@ -78,66 +132,24 @@ function ColorGradientControlInner( {
</legend>
) }
{ canChooseAColor && canChooseAGradient && (
<ToggleGroupControl
value={ currentTab }
onChange={ setCurrentTab }
label={ __( 'Select color type' ) }
hideLabelFromVision
isBlock
>
<ToggleGroupControlOption
value="color"
label={ __( 'Solid' ) }
/>
<ToggleGroupControlOption
value="gradient"
label={ __( 'Gradient' ) }
/>
</ToggleGroupControl>
) }
{ ( currentTab === 'color' || ! canChooseAGradient ) && (
<ColorPalette
value={ colorValue }
onChange={
canChooseAGradient
? ( newColor ) => {
onColorChange( newColor );
onGradientChange();
}
: onColorChange
<TabPanel
className="block-editor-color-gradient-control__tabs"
tabs={ TABS_SETTINGS }
initialTabName={
gradientValue
? TAB_GRADIENT.value
: !! canChooseAColor && TAB_COLOR.value
}
{ ...{ colors, disableCustomColors } }
__experimentalHasMultipleOrigins={
__experimentalHasMultipleOrigins
}
__experimentalIsRenderedInSidebar={
__experimentalIsRenderedInSidebar
}
clearable={ clearable }
enableAlpha={ enableAlpha }
/>
) }
{ ( currentTab === 'gradient' || ! canChooseAColor ) && (
<GradientPicker
value={ gradientValue }
onChange={
canChooseAColor
? ( newGradient ) => {
onGradientChange( newGradient );
onColorChange();
}
: onGradientChange
}
{ ...{ gradients, disableCustomGradients } }
__experimentalHasMultipleOrigins={
__experimentalHasMultipleOrigins
}
__experimentalIsRenderedInSidebar={
__experimentalIsRenderedInSidebar
}
clearable={ clearable }
/>
>
{ ( tab ) => (
<div className="block-editor-color-gradient-control__tab-panel">
{ tabPanels[ tab.value ] }
</div>
) }
</TabPanel>
) }
{ ! canChooseAGradient && tabPanels[ TAB_COLOR.value ] }
{ ! canChooseAColor && tabPanels[ TAB_GRADIENT.value ] }
</VStack>
</fieldset>
</BaseControl>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,3 +100,7 @@
.block-editor-panel-color-gradient-settings__dropdown {
width: 100%;
}

.block-editor-color-gradient-control__tab-panel {
padding-top: $grid-unit-10;
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,6 @@ const getButtonWithAriaLabelStartPredicate =
);
};

const getTabWithTestPredicate = ( text ) => ( element ) => {
return (
element.type === 'button' &&
element.props[ 'aria-label' ] &&
element.props[ 'aria-label' ] === text
);
};

const colorTabButtonPredicate = getTabWithTestPredicate( 'Solid' );
const gradientTabButtonPredicate = getTabWithTestPredicate( 'Gradient' );

describe( 'ColorPaletteControl', () => {
it( 'renders tabs if it is possible to select a color and a gradient rendering a color picker at the start', async () => {
render(
Expand Down Expand Up @@ -63,8 +52,12 @@ describe( 'ColorPaletteControl', () => {
);

// Is showing the two tab buttons.
expect( screen.queryByLabelText( 'Solid' ) ).toBeInTheDocument();
expect( screen.queryByLabelText( 'Gradient' ) ).toBeInTheDocument();
expect(
screen.getByRole( 'tab', { name: 'Solid color' } )
).toBeInTheDocument();
expect(
screen.getByRole( 'tab', { name: 'Gradient' } )
).toBeInTheDocument();

// Is showing the two predefined Colors.
expect( screen.getAllByLabelText( /^Color:/ ) ).toHaveLength( 2 );
Expand Down Expand Up @@ -92,12 +85,12 @@ describe( 'ColorPaletteControl', () => {
} );

// Is not showing the two tab buttons.
expect( wrapper.root.findAll( colorTabButtonPredicate ) ).toHaveLength(
0
);
expect(
wrapper.root.findAll( gradientTabButtonPredicate )
).toHaveLength( 0 );
screen.queryByRole( 'tab', { name: 'Solid color' } )
).not.toBeInTheDocument();
expect(
screen.queryByRole( 'tab', { name: 'Gradient' } )
).not.toBeInTheDocument();

// Is showing the two predefined Colors.
expect(
Expand Down Expand Up @@ -139,12 +132,12 @@ describe( 'ColorPaletteControl', () => {
} );

// Is not showing the two tab buttons.
expect( wrapper.root.findAll( colorTabButtonPredicate ) ).toHaveLength(
0
);
expect(
wrapper.root.findAll( gradientTabButtonPredicate )
).toHaveLength( 0 );
screen.queryByRole( 'tab', { name: 'Solid color' } )
).not.toBeInTheDocument();
expect(
screen.queryByRole( 'tab', { name: 'Gradient' } )
).not.toBeInTheDocument();

// Is showing the two predefined Gradients.
expect(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,7 @@
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
import {
__experimentalToggleGroupControl as ToggleGroupControl,
__experimentalToggleGroupControlOption as ToggleGroupControlOption,
} from '@wordpress/components';
import { useState } from '@wordpress/element';
import { TabPanel } from '@wordpress/components';

/**
* Internal dependencies
Expand All @@ -16,8 +12,6 @@ import GradientPalettePanel from './gradients-palette-panel';
import ScreenHeader from './header';

function ScreenColorPalette( { name } ) {
const [ currentTab, setCurrentTab ] = useState( 'solid' );

return (
<>
<ScreenHeader
Expand All @@ -26,27 +20,31 @@ function ScreenColorPalette( { name } ) {
'Palettes are used to provide default color options for blocks and various design tools. Here you can edit the colors with their labels.'
) }
/>
<ToggleGroupControl
className="edit-site-screen-color-palette-toggle"
value={ currentTab }
onChange={ setCurrentTab }
label={ __( 'Select palette type' ) }
hideLabelFromVision
isBlock
<TabPanel
tabs={ [
{
name: 'solid',
title: 'Solid color',
value: 'solid',
},
{
name: 'gradient',
title: 'Gradient',
value: 'gradient',
},
] }
>
<ToggleGroupControlOption
value="solid"
label={ __( 'Solid' ) }
/>
<ToggleGroupControlOption
value="gradient"
label={ __( 'Gradient' ) }
/>
</ToggleGroupControl>
{ currentTab === 'solid' && <ColorPalettePanel name={ name } /> }
{ currentTab === 'gradient' && (
<GradientPalettePanel name={ name } />
) }
{ ( tab ) => (
<>
{ tab.value === 'solid' && (
<ColorPalettePanel name={ name } />
) }
{ tab.value === 'gradient' && (
<GradientPalettePanel name={ name } />
) }
</>
) }
</TabPanel>
</>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ function ScreenLinkColor( { name } ) {
) }
/>

<TabPanel className="my-tab-panel" tabs={ tabs }>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Removed some copypasta here

<TabPanel tabs={ tabs }>
{ ( tab ) => {
const pseudoSelectorConfig =
pseudoStates[ tab.name ] ?? null;
Expand Down
18 changes: 7 additions & 11 deletions packages/edit-site/src/components/global-styles/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -66,22 +66,18 @@
margin: 0;
}

.edit-site-screen-color-palette-toggle.edit-site-screen-color-palette-toggle {
margin-right: $grid-unit-20;
margin-left: $grid-unit-20;
width: unset;
.components-toggle-group-control {
min-height: $grid-unit-40;
}
}

.edit-site-screen-text-color__control,
.edit-site-screen-link-color__control,
.edit-site-screen-button-color__control,
.edit-site-screen-background-color__control {
.edit-site-screen-button-color__control {
padding: $grid-unit-20;
}

.edit-site-screen-background-color__control {
.block-editor-color-gradient-control__tab-panel {
padding: $grid-unit-20;
}
}

.edit-site-global-styles-variations_item {
box-sizing: border-box;

Expand Down