@grafana/ui
Version:
Grafana Components Library
83 lines (80 loc) • 2.53 kB
JavaScript
import { jsx } from 'react/jsx-runtime';
import { cx, css } from '@emotion/css';
import { debounce } from 'lodash';
import { forwardRef, useState, useMemo, useEffect } from 'react';
import tinycolor from 'tinycolor2';
import { useStyles2 } from '../../themes/ThemeContext.mjs';
import { Input } from '../Input/Input.mjs';
const ColorInput = forwardRef(
({ color, onChange, isClearable = false, onClick, onBlur, disabled, buttonAriaLabel, ...inputProps }, ref) => {
const [value, setValue] = useState(color);
const [previousColor, setPreviousColor] = useState(color);
const updateColor = useMemo(() => debounce(onChange, 100), []);
useEffect(() => {
const newColor = tinycolor(color);
if (newColor.isValid() && color !== previousColor) {
setValue(newColor.toString());
setPreviousColor(color);
}
}, [color, previousColor]);
const onChangeColor = (event) => {
const { value: colorValue } = event.currentTarget;
setValue(colorValue);
if (colorValue === "" && isClearable) {
updateColor(colorValue);
return;
}
const newColor = tinycolor(colorValue);
if (newColor.isValid()) {
updateColor(newColor.toString());
}
};
const onBlurInput = (event) => {
const newColor = tinycolor(value);
if (!newColor.isValid()) {
setValue(color);
}
onBlur == null ? void 0 : onBlur(event);
};
return /* @__PURE__ */ jsx(
Input,
{
...inputProps,
value,
onChange: onChangeColor,
disabled,
onClick,
onBlur: onBlurInput,
addonBefore: /* @__PURE__ */ jsx(ColorPreview, { onClick, ariaLabel: buttonAriaLabel, disabled, color }),
ref
}
);
}
);
ColorInput.displayName = "ColorInput";
const ColorPreview = ({ color, onClick, disabled, ariaLabel }) => {
const styles = useStyles2(getColorPreviewStyles);
return /* @__PURE__ */ jsx(
"button",
{
type: "button",
onClick,
"aria-label": ariaLabel,
disabled: disabled || !onClick,
className: cx(
styles,
css({
backgroundColor: color
})
)
}
);
};
const getColorPreviewStyles = (theme) => css({
height: "100%",
width: `${theme.spacing.gridSize * 4}px`,
borderRadius: `${theme.shape.radius.default} 0 0 ${theme.shape.radius.default}`,
border: `1px solid ${theme.colors.border.medium}`
});
export { ColorInput as default };
//# sourceMappingURL=ColorInput.mjs.map