Skip to content

Commit

Permalink
ColorPicker: store internal HSLA state for better slider UX
Browse files Browse the repository at this point in the history
  • Loading branch information
ciampo committed Jan 5, 2024
1 parent 2e39fb6 commit 7d57eb4
Showing 1 changed file with 56 additions and 30 deletions.
86 changes: 56 additions & 30 deletions packages/components/src/color-picker/hsl-input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,61 @@
*/
import { colord } from 'colord';

/**
* WordPress dependencies
*/
import { useState, useEffect } from '@wordpress/element';

/**
* Internal dependencies
*/
import { InputWithSlider } from './input-with-slider';
import type { HslInputProps } from './types';

export const HslInput = ( { color, onChange, enableAlpha }: HslInputProps ) => {
const { h, s, l, a } = color.toHsl();
const colorPropHSL = color.toHsl();

const [ internalHSLA, setInternalHSLA ] = useState( { ...colorPropHSL } );

const isInternalColorSameAsReceivedColor = color.isEqual(
colord( internalHSLA )
);

useEffect( () => {
if ( ! isInternalColorSameAsReceivedColor ) {
setInternalHSLA( colorPropHSL );
}
}, [ colorPropHSL, isInternalColorSameAsReceivedColor ] );

const colorValue = isInternalColorSameAsReceivedColor
? internalHSLA
: colorPropHSL;

const updateHSLAValue = (
partialNewValue: Partial< typeof colorPropHSL >
) => {
setInternalHSLA( ( prevValue ) => ( {
...prevValue,
...partialNewValue,
} ) );

const nextOnChangeValue = colord( {
...colorValue,
...partialNewValue,
} );

// Avoid firing `onChange` if the resulting didn't change.
if ( color.isEqual( nextOnChangeValue ) ) {
return;
}

onChange(
colord( {
...colorValue,
...partialNewValue,
} )
);
};

return (
<>
Expand All @@ -19,43 +66,29 @@ export const HslInput = ( { color, onChange, enableAlpha }: HslInputProps ) => {
max={ 359 }
label="Hue"
abbreviation="H"
value={ h }
value={ colorValue.h }
onChange={ ( nextH: number ) => {
onChange( colord( { h: nextH, s, l, a } ) );
updateHSLAValue( { h: nextH } );
} }
/>
<InputWithSlider
min={ 0 }
max={ 100 }
label="Saturation"
abbreviation="S"
value={ s }
value={ colorValue.s }
onChange={ ( nextS: number ) => {
onChange(
colord( {
h,
s: nextS,
l,
a,
} )
);
updateHSLAValue( { s: nextS } );
} }
/>
<InputWithSlider
min={ 0 }
max={ 100 }
label="Lightness"
abbreviation="L"
value={ l }
value={ colorValue.l }
onChange={ ( nextL: number ) => {
onChange(
colord( {
h,
s,
l: nextL,
a,
} )
);
updateHSLAValue( { l: nextL } );
} }
/>
{ enableAlpha && (
Expand All @@ -64,16 +97,9 @@ export const HslInput = ( { color, onChange, enableAlpha }: HslInputProps ) => {
max={ 100 }
label="Alpha"
abbreviation="A"
value={ Math.trunc( 100 * a ) }
value={ Math.trunc( 100 * colorValue.a ) }
onChange={ ( nextA: number ) => {
onChange(
colord( {
h,
s,
l,
a: nextA / 100,
} )
);
updateHSLAValue( { a: nextA / 100 } );
} }
/>
) }
Expand Down

0 comments on commit 7d57eb4

Please sign in to comment.