Skip to content

Commit

Permalink
docs(react-color-picker): Added hex input field and validation (#33372)
Browse files Browse the repository at this point in the history
Co-authored-by: Dmytro Kirpa <kirpadv@gmail.com>
  • Loading branch information
ValentinaKozlova and dmytrokirpa authored Dec 6, 2024
1 parent e186b82 commit 0676543
Showing 1 changed file with 67 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as React from 'react';
import { tinycolor } from '@ctrl/tinycolor';
import { makeStyles } from '@fluentui/react-components';
import { makeStyles, useId, Input, type InputProps, Label } from '@fluentui/react-components';
import {
ColorPicker,
ColorSlider,
Expand All @@ -22,25 +22,88 @@ const useStyles = makeStyles({
borderRadius: '4px',
border: '1px solid #ccc',
},
inputFields: {
display: 'flex',
alignItems: 'flex-end',
flexDirection: 'row',
gap: '10px',
},
colorFieldWrapper: {
display: 'flex',
flexDirection: 'column',
gap: '6px',
},
input: {
width: '80px',
},
});

const HEX_COLOR_REGEX = /^#?([0-9A-Fa-f]{0,6})$/;
const DEFAULT_COLOR_HSV = tinycolor('#2be700').toHsv();

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

const styles = useStyles();
const [color, setColor] = React.useState(DEFAULT_COLOR_HSV);
const handleChange: ColorPickerProps['onColorChange'] = (_, data) =>
const [hex, setHex] = React.useState(tinycolor(color).toHexString());

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

return (
<div className={styles.example}>
<ColorPicker color={color} onColorChange={handleChange}>
<ColorArea />
<ColorSlider />
<AlphaSlider />
<ColorArea />
</ColorPicker>
<div className={styles.inputFields}>
<div className={styles.previewColor} style={{ backgroundColor: tinycolor(color).toRgbString() }} />
<InputHexField
id={hexId}
value={hex}
onChange={e => {
const value = e.target.value;
const newColor = tinycolor(value);
if (newColor.isValid) {
setColor(newColor.toHsv());
}
setHex(oldValue => (HEX_COLOR_REGEX.test(value) ? value : oldValue));
}}
/>
</div>
</div>
);
};

<div className={styles.previewColor} style={{ backgroundColor: tinycolor(color).toRgbString() }} />
const InputHexField = ({
label = 'Hex',
id,
value,
onChange,
}: {
label?: string;
id: string;
value: string;
onChange: InputProps['onChange'];
}) => {
const styles = useStyles();
return (
<div className={styles.colorFieldWrapper}>
<Label htmlFor={id}>{label}</Label>
<Input className={styles.input} value={value} id={id} onChange={onChange} onBlur={handleOnBlur} />
</div>
);
};

const handleOnBlur = (e: React.FocusEvent<HTMLInputElement>) => {
const value = tinycolor(e.target.value);
if (!value.isValid) {
e.target.setAttribute('aria-invalid', 'true');
} else {
e.target.removeAttribute('aria-invalid');
}
};

0 comments on commit 0676543

Please sign in to comment.