Skip to content

Commit

Permalink
feat(react-color-picker): added alpha input field
Browse files Browse the repository at this point in the history
  • Loading branch information
ValentinaKozlova committed Jan 3, 2025
1 parent ab40fea commit ec5cfac
Showing 1 changed file with 48 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ const useStyles = makeStyles({
width: '80px',
},
spinButton: {
width: '50px',
minWidth: '60px',
},
});

Expand All @@ -62,16 +62,19 @@ type RgbKey = 'r' | 'g' | 'b';

export const Default = () => {
const hexId = useId('hex-input');
const alphaId = useId('alpha-input');

const styles = useStyles();
const [color, setColor] = React.useState(DEFAULT_COLOR_HSV);
const [hex, setHex] = React.useState(tinycolor(color).toHexString());
const [rgb, setRgb] = React.useState(tinycolor(color).toRgb());
const [alpha, setAlpha] = React.useState(color.a);

const handleChange: ColorPickerProps['onColorChange'] = (_, data) => {
setColor({ ...data.color, a: data.color.a ?? 1 });
setHex(tinycolor(data.color).toHexString());
setRgb(tinycolor(data.color).toRgb());
setAlpha(data.color.a ?? 1);
};

const onRgbChange = (event: SpinButtonChangeEvent, data: SpinButtonOnChangeData) => {
Expand All @@ -91,6 +94,26 @@ export const Default = () => {
}
};

const onAlphaChange: SpinButtonProps['onChange'] = React.useCallback(
(_ev, data) => {
const value = data.value ?? (data.displayValue !== undefined ? parseFloat(data.displayValue) : null);

if (value === null || Number.isNaN(value) || !/^(0|1|0?\.\d+|1\.0?)$/.test(value.toString())) {
return;
}

const newColor = tinycolor({ ...color, a: value });

if (newColor.isValid) {
setColor(newColor.toHsv());
setHex(newColor.toHex());
setRgb(newColor.toRgb());
}
setAlpha(newColor.a);
},
[setAlpha, setRgb, setHex, setColor, color],
);

return (
<div className={styles.example}>
<ColorPicker color={color} onColorChange={handleChange}>
Expand All @@ -99,7 +122,6 @@ export const Default = () => {
<AlphaSlider />
</ColorPicker>
<div className={styles.inputFields}>
<div className={styles.previewColor} style={{ backgroundColor: tinycolor(color).toRgbString() }} />
<InputHexField
id={hexId}
value={hex}
Expand All @@ -108,15 +130,17 @@ export const Default = () => {
const newColor = tinycolor(value);
if (newColor.isValid) {
setColor(newColor.toHsv());
setRgb(newColor.toRgb());
}
setHex(oldValue => (HEX_COLOR_REGEX.test(value) ? value : oldValue));
}}
/>
<InputRgbField label="Red" value={rgb.r} name="r" onChange={onRgbChange} />
<InputRgbField label="Green" value={rgb.g} name="g" onChange={onRgbChange} />
<InputRgbField label="Blue" value={rgb.b} name="b" onChange={onRgbChange} />
<InputAlphaField id={alphaId} value={alpha} onChange={onAlphaChange} />
</div>
<div className={styles.previewColor} style={{ backgroundColor: tinycolor(color).toHexString() }} />
<div className={styles.previewColor} style={{ backgroundColor: tinycolor(color).toRgbString() }} />
</div>
);
};
Expand Down Expand Up @@ -171,6 +195,27 @@ const InputRgbField = ({
);
};

const InputAlphaField = ({
label = 'Alpha',
value,
onChange,
id,
}: {
value: number;
label?: string;
onChange?: SpinButtonProps['onChange'];
id: string;
}) => {
const styles = useStyles();

return (
<div className={styles.colorFieldWrapper}>
<Label htmlFor={id}>{label}</Label>
<SpinButton min={0} max={1} className={styles.spinButton} value={value} step={0.01} onChange={onChange} id={id} />
</div>
);
};

const handleOnBlur = (e: React.FocusEvent<HTMLInputElement>) => {
const value = tinycolor(e.target.value);
if (!value.isValid) {
Expand Down

0 comments on commit ec5cfac

Please sign in to comment.