Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Use dropdown menus for nested color controls
  • Loading branch information
youknowriad committed Dec 2, 2021
commit 8a0b5e21eee4d0f44d7cd299d7eb08dd9f272150
25 changes: 14 additions & 11 deletions packages/block-editor/src/hooks/color-panel.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,31 @@
* WordPress dependencies
*/
import { useState, useEffect } from '@wordpress/element';
import { __ } from '@wordpress/i18n';

/**
* Internal dependencies
*/
import PanelColorGradientSettings from '../components/colors-gradients/panel-color-gradient-settings';
import ContrastChecker from '../components/contrast-checker';
import { __unstableUseBlockRef as useBlockRef } from '../components/block-list/use-block-props/use-block-refs';
import ColorGradientControl from '../components/colors-gradients/control';
import useCommonSingleMultipleSelects from '../components/colors-gradients/use-common-single-multiple-selects';
import useSetting from '../components/use-setting';

function getComputedStyle( node ) {
return node.ownerDocument.defaultView.getComputedStyle( node );
}

export default function ColorPanel( {
settings,
setting,
clientId,
enableContrastChecking = true,
} ) {
const [ detectedBackgroundColor, setDetectedBackgroundColor ] = useState();
const [ detectedColor, setDetectedColor ] = useState();
const ref = useBlockRef( clientId );
const colorGradientSettings = useCommonSingleMultipleSelects();
colorGradientSettings.colors = useSetting( 'color.palette' );
Copy link
Member

@jorgefilipecosta jorgefilipecosta Dec 2, 2021

Choose a reason for hiding this comment

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

We were showing multiple color palettes default, theme, and user, and now we are just showing a single palette. I guess we can use the hook useMultipleOriginColorsAndGradients to get all the palettes.

colorGradientSettings.gradients = useSetting( 'color.gradients' );

useEffect( () => {
if ( ! enableContrastChecking ) {
Expand Down Expand Up @@ -52,19 +56,18 @@ export default function ColorPanel( {
} );

return (
<PanelColorGradientSettings
title={ __( 'Color' ) }
settings={ settings }
showTitle={ false }
__experimentalHasMultipleOrigins
__experimentalIsRenderedInSidebar
>
<div className="block-editor-panel-color-gradient-settings">
<ColorGradientControl
showTitle={ false }
{ ...colorGradientSettings }
{ ...setting }
/>
{ enableContrastChecking && (
<ContrastChecker
backgroundColor={ detectedBackgroundColor }
textColor={ detectedColor }
/>
) }
</PanelColorGradientSettings>
</div>
);
}
250 changes: 93 additions & 157 deletions packages/block-editor/src/hooks/color.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,18 @@ import { isObject, setWith, clone } from 'lodash';
*/
import { addFilter } from '@wordpress/hooks';
import { getBlockSupport } from '@wordpress/blocks';
import { __, isRTL } from '@wordpress/i18n';
import { __ } from '@wordpress/i18n';
import { useRef, useEffect, useMemo, Platform } from '@wordpress/element';
import { createHigherOrderComponent } from '@wordpress/compose';
import {
__experimentalNavigatorProvider as NavigatorProvider,
__experimentalNavigatorScreen as NavigatorScreen,
__experimentalUseNavigator as useNavigator,
__experimentalItemGroup as ItemGroup,
__experimentalItem as Item,
__experimentalView as View,
__experimentalHStack as HStack,
__experimentalVStack as VStack,
__experimentalSpacer as Spacer,
__experimentalHeading as Heading,
FlexItem,
ColorIndicator,
PanelBody,
Dropdown,
} from '@wordpress/components';
import { Icon, chevronLeft, chevronRight } from '@wordpress/icons';

/**
* Internal dependencies
Expand Down Expand Up @@ -224,55 +217,6 @@ function immutableSet( object, path, value ) {
return setWith( object ? clone( object ) : {}, path, value, clone );
}

function NavigationButton( {
path,
icon,
children,
isBack = false,
...props
} ) {
const navigator = useNavigator();
return (
<Item onClick={ () => navigator.push( path, { isBack } ) } { ...props }>
{ icon && (
<HStack justify="flex-start">
<FlexItem>
<Icon icon={ icon } size={ 24 } />
</FlexItem>
<FlexItem>{ children }</FlexItem>
</HStack>
) }
{ ! icon && children }
</Item>
);
}

function ScreenHeader( { back, title } ) {
return (
<VStack spacing={ 2 }>
<HStack spacing={ 2 }>
<View>
<NavigationButton
path={ back }
icon={
<Icon
icon={ isRTL() ? chevronRight : chevronLeft }
variant="muted"
/>
}
size="small"
isBack
aria-label={ __( 'Navigate to the previous view' ) }
/>
</View>
<Spacer>
<Heading level={ 5 }>{ title }</Heading>
</Spacer>
</HStack>
</VStack>
);
}

/**
* Inspector control panel containing the color related configuration
*
Expand Down Expand Up @@ -460,28 +404,58 @@ export function ColorEdit( props ) {
title={ __( 'Colors' ) }
className="block-editor__hooks-colors-panel"
>
<NavigatorProvider initialPath="/">
<NavigatorScreen path="/">
<ItemGroup isBordered isSeparated>
{ ( hasBackgroundColor || hasGradientColor ) && (
<NavigationButton path="/background">
<HStack justify="flex-start">
<FlexItem>
<ColorIndicator
colorValue={
gradientValue ??
backgroundValue
}
/>
</FlexItem>
<FlexItem>
{ __( 'Background' ) }
</FlexItem>
</HStack>
</NavigationButton>
<ItemGroup isBordered isSeparated>
{ ( hasBackgroundColor || hasGradientColor ) && (
<Dropdown
position="middle left"
renderToggle={ ( { onToggle } ) => {
return (
<Item onClick={ onToggle }>
<HStack justify="flex-start">
<FlexItem>
<ColorIndicator
colorValue={
gradientValue ??
backgroundValue
}
/>
</FlexItem>
<FlexItem>
{ __( 'Background' ) }
</FlexItem>
</HStack>
</Item>
);
} }
renderContent={ () => (
<ColorPanel
enableContrastChecking={
// Turn on contrast checker for web only since it's not supported on mobile yet.
Platform.OS === 'web' &&
! gradient &&
! style?.color?.gradient
}
clientId={ props.clientId }
setting={ {
label: __( 'Background color' ),
onColorChange: hasBackgroundColor
? onChangeColor( 'background' )
: undefined,
colorValue: backgroundValue,
gradientValue,
onGradientChange: hasGradientColor
? onChangeGradient
: undefined,
} }
/>
) }
{ hasTextColor && (
<NavigationButton path="/text">
/>
) }
{ hasTextColor && (
<Dropdown
position="middle left"
renderToggle={ ( { onToggle } ) => (
<Item onClick={ onToggle }>
<HStack justify="flex-start">
<FlexItem>
<ColorIndicator
Expand All @@ -490,10 +464,31 @@ export function ColorEdit( props ) {
</FlexItem>
<FlexItem>{ __( 'Text' ) }</FlexItem>
</HStack>
</NavigationButton>
</Item>
) }
{ hasLinkColor && (
<NavigationButton path="/link">
renderContent={ () => (
<ColorPanel
enableContrastChecking={
// Turn on contrast checker for web only since it's not supported on mobile yet.
Platform.OS === 'web' &&
! gradient &&
! style?.color?.gradient
}
clientId={ props.clientId }
setting={ {
label: __( 'Text color' ),
onColorChange: onChangeColor( 'text' ),
colorValue: textColorValue,
} }
/>
) }
/>
) }
{ hasLinkColor && (
<Dropdown
position="middle left"
renderToggle={ ( { onToggle } ) => (
<Item onClick={ onToggle }>
<HStack justify="flex-start">
<FlexItem>
<ColorIndicator
Expand All @@ -502,77 +497,18 @@ export function ColorEdit( props ) {
</FlexItem>
<FlexItem>{ __( 'Links' ) }</FlexItem>
</HStack>
</NavigationButton>
</Item>
) }
</ItemGroup>
</NavigatorScreen>

{ ( hasBackgroundColor || hasGradientColor ) && (
<NavigatorScreen path="/background">
<ScreenHeader
back="/"
title={ __( 'Background' ) }
/>
<ColorPanel
enableContrastChecking={
// Turn on contrast checker for web only since it's not supported on mobile yet.
Platform.OS === 'web' &&
! gradient &&
! style?.color?.gradient
}
clientId={ props.clientId }
settings={ [
{
label: __( 'Background color' ),
onColorChange: hasBackgroundColor
? onChangeColor( 'background' )
: undefined,
colorValue: backgroundValue,
gradientValue,
onGradientChange: hasGradientColor
? onChangeGradient
: undefined,
},
] }
/>
</NavigatorScreen>
) }

{ hasTextColor && (
<NavigatorScreen path="/text">
<ScreenHeader back="/" title={ __( 'Text' ) } />
<ColorPanel
enableContrastChecking={
// Turn on contrast checker for web only since it's not supported on mobile yet.
Platform.OS === 'web' &&
! gradient &&
! style?.color?.gradient
}
clientId={ props.clientId }
settings={ [
{
label: __( 'Text color' ),
onColorChange: onChangeColor( 'text' ),
colorValue: textColorValue,
},
] }
/>
</NavigatorScreen>
) }

{ hasLinkColor && (
<NavigatorScreen path="/link">
<ScreenHeader back="/" title={ __( 'Link' ) } />
<ColorPanel
enableContrastChecking={
// Turn on contrast checker for web only since it's not supported on mobile yet.
Platform.OS === 'web' &&
! gradient &&
! style?.color?.gradient
}
clientId={ props.clientId }
settings={ [
{
renderContent={ () => (
<ColorPanel
enableContrastChecking={
// Turn on contrast checker for web only since it's not supported on mobile yet.
Platform.OS === 'web' &&
! gradient &&
! style?.color?.gradient
}
clientId={ props.clientId }
setting={ {
label: __( 'Link Color' ),
onColorChange: onChangeLinkColor,
colorValue: getLinkColorFromAttributeValue(
Expand All @@ -581,12 +517,12 @@ export function ColorEdit( props ) {
),
clearable: !! style?.elements?.link
?.color?.text,
},
] }
/>
</NavigatorScreen>
} }
/>
) }
/>
) }
</NavigatorProvider>
</ItemGroup>
</PanelBody>
</InspectorControls>
);
Expand Down
4 changes: 4 additions & 0 deletions packages/block-editor/src/hooks/color.scss
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
.block-editor__hooks-colors-panel {

.components-dropdown {
display: block;
}

// Allow horizontal overflow so the size-increasing color indicators don't cause a scrollbar.
.components-navigator-screen {
overflow-x: visible;
Copy link
Contributor

Choose a reason for hiding this comment

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

NavigatorScreen already has a overflow-x: 'auto', why do we need to force it to visible ?

Copy link
Contributor

Choose a reason for hiding this comment

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

That rule can be removed. I suspect it's a remnant as this PR was forked from the one that included the navigator. I didn't feel very comfortable with targetting those classes either.

Expand Down