Skip to content
Merged
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
Next Next commit
Color Picker: Re-instate debounce and controlled value to fix issue w…
…ith gradient picker
  • Loading branch information
andrewserong committed Nov 30, 2021
commit 9e0d22d90643db3d1437103d82be59f233617fdd
16 changes: 13 additions & 3 deletions packages/components/src/color-picker/component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import namesPlugin from 'colord/plugins/names';
*/
import { useState, useMemo } from '@wordpress/element';
import { settings } from '@wordpress/icons';
import { useDebounce } from '@wordpress/compose';
import { __ } from '@wordpress/i18n';

/**
Expand All @@ -32,6 +33,7 @@ import {
import { ColorDisplay } from './color-display';
import { ColorInput } from './color-input';
import { Picker } from './picker';
import { useControlledValue } from '../utils/hooks';

import type { ColorType } from './types';

Expand All @@ -57,23 +59,31 @@ const ColorPicker = (
) => {
const {
enableAlpha = false,
color,
color: colorProp,
onChange,
defaultValue = '#fff',
copyFormat,
...divProps
} = useContextSystem( props, 'ColorPicker' );

const [ color, setColor ] = useControlledValue( {
onChange,
value: colorProp,
defaultValue,
} );

// Use a safe default value for the color and remove the possibility of `undefined`.
const safeColordColor = useMemo( () => {
return color ? colord( color ) : colord( defaultValue );
Copy link
Member

Choose a reason for hiding this comment

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

Given that useControlledValue, is already taking into account defaultValue, I guess we can simplify this to return colord( color ).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good suggestion, thanks! I've simplified the return statement here and moved the inline comment to above useControlledValue as that's where the default value logic is now happening.

}, [ color, defaultValue ] );

const debouncedSetColor = useDebounce( setColor );

const handleChange = useCallback(
( nextValue: Colord ) => {
onChange( nextValue.toHex() );
debouncedSetColor( nextValue.toHex() );
},
[ onChange ]
[ debouncedSetColor ]
);

const [ showInputs, setShowInputs ] = useState< boolean >( false );
Expand Down
15 changes: 15 additions & 0 deletions packages/components/src/color-picker/test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@ function moveReactColorfulSlider( sliderElement, from, to ) {
fireEvent( sliderElement, new FakeMouseEvent( 'mousemove', to ) );
}

const sleep = ( ms ) => {
const promise = new Promise( ( resolve ) => setTimeout( resolve, ms ) );
jest.advanceTimersByTime( ms + 1 );
return promise;
};

const hslaMatcher = expect.objectContaining( {
h: expect.any( Number ),
s: expect.any( Number ),
Expand Down Expand Up @@ -87,6 +93,9 @@ describe( 'ColorPicker', () => {
{ pageX: 10, pageY: 10 }
);

// `onChange` is debounced so we need to sleep for at least 1ms before checking that onChange was called
await sleep( 1 );

expect( onChangeComplete ).toHaveBeenCalledWith(
legacyColorMatcher
);
Expand All @@ -108,6 +117,9 @@ describe( 'ColorPicker', () => {
{ pageX: 10, pageY: 10 }
);

// `onChange` is debounced so we need to sleep for at least 1ms before checking that onChange was called
await sleep( 1 );

expect( onChange ).toHaveBeenCalledWith(
expect.stringMatching( /^#([a-fA-F0-9]{8})$/ )
);
Expand Down Expand Up @@ -138,6 +150,9 @@ describe( 'ColorPicker', () => {
{ pageX: 10, pageY: 10 }
);

// `onChange` is debounced so we need to sleep for at least 1ms before checking that onChange was called
await sleep( 1 );

expect( onChange ).toHaveBeenCalledWith(
expect.stringMatching( /^#([a-fA-F0-9]{6})$/ )
);
Expand Down