mirror of
https://github.com/grafana/grafana.git
synced 2024-11-26 02:40:26 -06:00
Grafana-UI: replace react-color with react-colorful (#33267)
* Grafana-UI: replace react-color with react-colorful * Throttle onChange from SpectrumPalette
This commit is contained in:
parent
d76c056656
commit
ec1c85acca
@ -66,7 +66,7 @@
|
||||
"react": "17.0.1",
|
||||
"react-beautiful-dnd": "13.0.0",
|
||||
"react-calendar": "2.19.2",
|
||||
"react-color": "2.18.0",
|
||||
"react-colorful": "5.1.2",
|
||||
"react-custom-scrollbars": "4.2.1",
|
||||
"react-dom": "17.0.1",
|
||||
"react-highlight-words": "0.16.0",
|
||||
|
@ -3,7 +3,10 @@ import tinycolor from 'tinycolor2';
|
||||
import { debounce } from 'lodash';
|
||||
|
||||
import { ColorPickerProps } from './ColorPickerPopover';
|
||||
import { Input } from '../Forms/Legacy/Input/Input';
|
||||
import { Input } from '../Input/Input';
|
||||
import { useStyles } from '../../themes';
|
||||
import { GrafanaTheme } from '@grafana/data';
|
||||
import { cx, css } from '@emotion/css';
|
||||
|
||||
interface ColorInputState {
|
||||
previousColor: string;
|
||||
@ -12,6 +15,7 @@ interface ColorInputState {
|
||||
|
||||
interface ColorInputProps extends ColorPickerProps {
|
||||
style?: React.CSSProperties;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
class ColorInput extends React.PureComponent<ColorInputProps, ColorInputState> {
|
||||
@ -66,31 +70,41 @@ class ColorInput extends React.PureComponent<ColorInputProps, ColorInputState> {
|
||||
render() {
|
||||
const { value } = this.state;
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
...this.props.style,
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
background: this.props.color,
|
||||
width: '35px',
|
||||
height: '35px',
|
||||
flexGrow: 0,
|
||||
borderRadius: '3px 0 0 3px',
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
flexGrow: 1,
|
||||
}}
|
||||
>
|
||||
<Input className="gf-form-input" value={value} onChange={this.onChange} onBlur={this.onBlur} />
|
||||
</div>
|
||||
</div>
|
||||
<Input
|
||||
className={this.props.className}
|
||||
value={value}
|
||||
onChange={this.onChange}
|
||||
onBlur={this.onBlur}
|
||||
addonBefore={<ColorPreview color={this.props.color} />}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default ColorInput;
|
||||
|
||||
interface ColorPreviewProps {
|
||||
color: string;
|
||||
}
|
||||
|
||||
const ColorPreview = ({ color }: ColorPreviewProps) => {
|
||||
const styles = useStyles(getColorPreviewStyles);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cx(
|
||||
styles,
|
||||
css`
|
||||
background-color: ${color};
|
||||
`
|
||||
)}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const getColorPreviewStyles = (theme: GrafanaTheme) => css`
|
||||
height: 100%;
|
||||
width: ${theme.spacing.formInputHeight}px;
|
||||
border-radius: ${theme.border.radius.sm} 0 0 ${theme.border.radius.sm};
|
||||
border: 1px solid ${theme.colors.formInputBorder};
|
||||
`;
|
||||
|
@ -72,7 +72,7 @@ class UnThemedColorPickerPopover<T extends CustomPickersDescriptor> extends Reac
|
||||
|
||||
switch (activePicker) {
|
||||
case 'spectrum':
|
||||
return <SpectrumPalette color={color} onChange={this.handleChange} theme={theme} />;
|
||||
return <SpectrumPalette color={color} onChange={this.handleChange} />;
|
||||
case 'palette':
|
||||
return <NamedColorsPalette color={color} onChange={this.handleChange} theme={theme} />;
|
||||
default:
|
||||
|
@ -1,101 +1,67 @@
|
||||
import React from 'react';
|
||||
import { CustomPicker, ColorResult } from 'react-color';
|
||||
import React, { useMemo, useState } from 'react';
|
||||
|
||||
import { Saturation, Hue, Alpha } from 'react-color/lib/components/common';
|
||||
import { RgbaStringColorPicker } from 'react-colorful';
|
||||
import tinycolor from 'tinycolor2';
|
||||
import ColorInput from './ColorInput';
|
||||
import { Themeable } from '../../types';
|
||||
import SpectrumPalettePointer, { SpectrumPalettePointerProps } from './SpectrumPalettePointer';
|
||||
import { GrafanaTheme, getColorForTheme } from '@grafana/data';
|
||||
import { css, cx } from '@emotion/css';
|
||||
import { useStyles, useTheme } from '../../themes';
|
||||
import { useThrottleFn } from 'react-use';
|
||||
|
||||
export interface SpectrumPaletteProps extends Themeable {
|
||||
export interface SpectrumPaletteProps {
|
||||
color: string;
|
||||
onChange: (color: string) => void;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line react/display-name
|
||||
const renderPointer = (theme: GrafanaTheme) => (props: SpectrumPalettePointerProps) => (
|
||||
<SpectrumPalettePointer {...props} theme={theme} />
|
||||
);
|
||||
const SpectrumPalette: React.FunctionComponent<SpectrumPaletteProps> = ({ color, onChange }) => {
|
||||
const [currentColor, setColor] = useState(color);
|
||||
useThrottleFn(onChange, 500, [currentColor]);
|
||||
|
||||
const theme = useTheme();
|
||||
const styles = useStyles(getStyles);
|
||||
|
||||
const rgbaString = useMemo(() => {
|
||||
return currentColor.startsWith('rgba')
|
||||
? currentColor
|
||||
: tinycolor(getColorForTheme(currentColor, theme)).toRgbString();
|
||||
}, [currentColor, theme]);
|
||||
|
||||
// @ts-ignore
|
||||
const SpectrumPicker = CustomPicker<Themeable>(({ rgb, hsl, onChange, theme }) => {
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
width: '100%',
|
||||
flexDirection: 'column',
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
flexGrow: 1,
|
||||
flexDirection: 'column',
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
position: 'relative',
|
||||
height: '100px',
|
||||
width: '100%',
|
||||
}}
|
||||
>
|
||||
{/*
|
||||
// @ts-ignore */}
|
||||
<Saturation onChange={onChange} hsl={hsl} hsv={tinycolor(hsl).toHsv()} />
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
width: '100%',
|
||||
height: '16px',
|
||||
marginTop: '16px',
|
||||
position: 'relative',
|
||||
background: 'white',
|
||||
}}
|
||||
>
|
||||
{/*
|
||||
// @ts-ignore */}
|
||||
<Alpha rgb={rgb} hsl={hsl} a={rgb.a} onChange={onChange} pointer={renderPointer(theme)} />
|
||||
</div>
|
||||
</div>
|
||||
<>
|
||||
<RgbaStringColorPicker className={cx(styles.root)} color={rgbaString} onChange={setColor} />
|
||||
|
||||
<div
|
||||
style={{
|
||||
position: 'relative',
|
||||
width: '16px',
|
||||
height: '100px',
|
||||
marginLeft: '16px',
|
||||
}}
|
||||
>
|
||||
{/*
|
||||
// @ts-ignore */}
|
||||
<Hue onChange={onChange} hsl={hsl} direction="vertical" pointer={renderPointer(theme)} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
const SpectrumPalette: React.FunctionComponent<SpectrumPaletteProps> = ({ color, onChange, theme }) => {
|
||||
return (
|
||||
<div>
|
||||
<SpectrumPicker
|
||||
color={tinycolor(getColorForTheme(color, theme)).toRgb()}
|
||||
onChange={(a: ColorResult) => {
|
||||
onChange(tinycolor(a.rgb).toString());
|
||||
}}
|
||||
theme={theme}
|
||||
/>
|
||||
<ColorInput theme={theme} color={color} onChange={onChange} style={{ marginTop: '16px' }} />
|
||||
</div>
|
||||
<ColorInput theme={theme} color={currentColor} onChange={setColor} className={styles.colorInput} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const getStyles = (theme: GrafanaTheme) => ({
|
||||
root: css`
|
||||
&.react-colorful {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.react-colorful {
|
||||
&__saturation {
|
||||
border-radius: ${theme.border.radius.sm} ${theme.border.radius.sm} 0 0;
|
||||
}
|
||||
&__alpha {
|
||||
border-radius: 0 0 ${theme.border.radius.sm} ${theme.border.radius.sm};
|
||||
}
|
||||
&__alpha,
|
||||
&__hue {
|
||||
height: ${theme.spacing.md};
|
||||
position: relative;
|
||||
}
|
||||
&__pointer {
|
||||
height: ${theme.spacing.md};
|
||||
width: ${theme.spacing.md};
|
||||
}
|
||||
}
|
||||
`,
|
||||
colorInput: css`
|
||||
margin-top: ${theme.spacing.md};
|
||||
`,
|
||||
});
|
||||
|
||||
export default SpectrumPalette;
|
||||
|
@ -1,77 +0,0 @@
|
||||
import React from 'react';
|
||||
import { Themeable } from '../../types';
|
||||
|
||||
export interface SpectrumPalettePointerProps extends Themeable {
|
||||
direction?: string;
|
||||
}
|
||||
|
||||
const SpectrumPalettePointer: React.FunctionComponent<SpectrumPalettePointerProps> = ({ theme, direction }) => {
|
||||
const styles = {
|
||||
picker: {
|
||||
width: '16px',
|
||||
height: '16px',
|
||||
transform: direction === 'vertical' ? 'translate(0, -8px)' : 'translate(-8px, 0)',
|
||||
},
|
||||
};
|
||||
|
||||
const pointerColor = theme.colors.text;
|
||||
|
||||
let pointerStyles: React.CSSProperties = {
|
||||
position: 'absolute',
|
||||
left: '6px',
|
||||
width: '0',
|
||||
height: '0',
|
||||
borderStyle: 'solid',
|
||||
background: 'none',
|
||||
};
|
||||
|
||||
let topArrowStyles: React.CSSProperties = {
|
||||
top: '-7px',
|
||||
borderWidth: '6px 3px 0px 3px',
|
||||
borderColor: `${pointerColor} transparent transparent transparent`,
|
||||
};
|
||||
|
||||
let bottomArrowStyles: React.CSSProperties = {
|
||||
bottom: '-7px',
|
||||
borderWidth: '0px 3px 6px 3px',
|
||||
borderColor: ` transparent transparent ${pointerColor} transparent`,
|
||||
};
|
||||
|
||||
if (direction === 'vertical') {
|
||||
pointerStyles = {
|
||||
...pointerStyles,
|
||||
left: 'auto',
|
||||
};
|
||||
topArrowStyles = {
|
||||
borderWidth: '3px 0px 3px 6px',
|
||||
borderColor: `transparent transparent transparent ${pointerColor}`,
|
||||
left: '-7px',
|
||||
top: '7px',
|
||||
};
|
||||
bottomArrowStyles = {
|
||||
borderWidth: '3px 6px 3px 0px',
|
||||
borderColor: `transparent ${pointerColor} transparent transparent`,
|
||||
right: '-7px',
|
||||
top: '7px',
|
||||
};
|
||||
}
|
||||
|
||||
return (
|
||||
<div style={styles.picker}>
|
||||
<div
|
||||
style={{
|
||||
...pointerStyles,
|
||||
...topArrowStyles,
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
...pointerStyles,
|
||||
...bottomArrowStyles,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default SpectrumPalettePointer;
|
36
yarn.lock
36
yarn.lock
@ -2609,11 +2609,6 @@
|
||||
resolved "https://registry.yarnpkg.com/@grafana/tsconfig/-/tsconfig-1.0.0-rc1.tgz#d07ea16755a50cae21000113f30546b61647a200"
|
||||
integrity sha512-nucKPGyzlSKYSiJk5RA8GzMdVWhdYNdF+Hh65AXxjD9PlY69JKr5wANj8bVdQboag6dgg0BFKqgKPyY+YtV4Iw==
|
||||
|
||||
"@icons/material@^0.2.4":
|
||||
version "0.2.4"
|
||||
resolved "https://registry.yarnpkg.com/@icons/material/-/material-0.2.4.tgz#e90c9f71768b3736e76d7dd6783fc6c2afa88bc8"
|
||||
integrity sha512-QPcGmICAPbGLGb6F/yNf/KzKqvFx8z5qx3D1yFqVAjoFmXK35EgyW+cJ57Te3CNsmzblwtzakLGFqHPqrfb4Tw==
|
||||
|
||||
"@istanbuljs/load-nyc-config@^1.0.0":
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced"
|
||||
@ -16557,7 +16552,7 @@ lodash.uniq@4.5.0, lodash.uniq@^4.5.0:
|
||||
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
|
||||
integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=
|
||||
|
||||
lodash@4.17.21, lodash@>=4, lodash@^4, lodash@^4.0.0, lodash@^4.0.1, lodash@^4.1.1, lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.3, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.1, lodash@^4.3.0, lodash@~4.17.10, lodash@~4.17.15:
|
||||
lodash@4.17.21, lodash@>=4, lodash@^4, lodash@^4.0.0, lodash@^4.1.1, lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.3, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.1, lodash@^4.3.0, lodash@~4.17.10, lodash@~4.17.15:
|
||||
version "4.17.21"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
||||
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
|
||||
@ -16842,11 +16837,6 @@ marked@2.0.1:
|
||||
resolved "https://registry.yarnpkg.com/marked/-/marked-2.0.1.tgz#5e7ed7009bfa5c95182e4eb696f85e948cefcee3"
|
||||
integrity sha512-5+/fKgMv2hARmMW7DOpykr2iLhl0NgjyELk5yn92iE7z8Se1IS9n3UsFm86hFXIkvMBmVxki8+ckcpjBeyo/hw==
|
||||
|
||||
material-colors@^1.2.1:
|
||||
version "1.2.6"
|
||||
resolved "https://registry.yarnpkg.com/material-colors/-/material-colors-1.2.6.tgz#6d1958871126992ceecc72f4bcc4d8f010865f46"
|
||||
integrity sha512-6qE4B9deFBIa9YSpOc9O0Sgc43zTeVYbgDT5veRKSlB2+ZuHNoVVxA1L/ckMUayV9Ay9y7Z/SZCLcGteW9i7bg==
|
||||
|
||||
md5-file@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/md5-file/-/md5-file-4.0.0.tgz#f3f7ba1e2dd1144d5bf1de698d0e5f44a4409584"
|
||||
@ -20536,17 +20526,10 @@ react-calendar@2.19.2:
|
||||
prop-types "^15.6.0"
|
||||
react-lifecycles-compat "^3.0.4"
|
||||
|
||||
react-color@2.18.0:
|
||||
version "2.18.0"
|
||||
resolved "https://registry.yarnpkg.com/react-color/-/react-color-2.18.0.tgz#34956f0bac394f6c3bc01692fd695644cc775ffd"
|
||||
integrity sha512-FyVeU1kQiSokWc8NPz22azl1ezLpJdUyTbWL0LPUpcuuYDrZ/Y1veOk9rRK5B3pMlyDGvTk4f4KJhlkIQNRjEA==
|
||||
dependencies:
|
||||
"@icons/material" "^0.2.4"
|
||||
lodash "^4.17.11"
|
||||
material-colors "^1.2.1"
|
||||
prop-types "^15.5.10"
|
||||
reactcss "^1.2.0"
|
||||
tinycolor2 "^1.4.1"
|
||||
react-colorful@5.1.2:
|
||||
version "5.1.2"
|
||||
resolved "https://registry.yarnpkg.com/react-colorful/-/react-colorful-5.1.2.tgz#5cb1506b8f9104b88d02d34984a36c2d1e477e9e"
|
||||
integrity sha512-FRt9jz6xjiPqQ6bIAQ26kd0oJhHbGBwsA4BDz/F8FDCFuQJDiEl0wVUARNiqRyvQjwfKuhM42P/bMYI0l92hRw==
|
||||
|
||||
react-colorful@^5.0.1:
|
||||
version "5.1.0"
|
||||
@ -21135,13 +21118,6 @@ react@17.0.1:
|
||||
loose-envify "^1.1.0"
|
||||
object-assign "^4.1.1"
|
||||
|
||||
reactcss@^1.2.0:
|
||||
version "1.2.3"
|
||||
resolved "https://registry.yarnpkg.com/reactcss/-/reactcss-1.2.3.tgz#c00013875e557b1cf0dfd9a368a1c3dab3b548dd"
|
||||
integrity sha512-KiwVUcFu1RErkI97ywr8nvx8dNOpT03rbnma0SSalTYjkrPYaEajR4a/MRt6DZ46K6arDRbWMNHF+xH7G7n/8A==
|
||||
dependencies:
|
||||
lodash "^4.0.1"
|
||||
|
||||
read-cmd-shim@^1.0.1:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/read-cmd-shim/-/read-cmd-shim-1.0.5.tgz#87e43eba50098ba5a32d0ceb583ab8e43b961c16"
|
||||
@ -24042,7 +24018,7 @@ tiny-warning@^1.0.0, tiny-warning@^1.0.3:
|
||||
resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754"
|
||||
integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==
|
||||
|
||||
tinycolor2@1.4.1, tinycolor2@^1.4.1:
|
||||
tinycolor2@1.4.1:
|
||||
version "1.4.1"
|
||||
resolved "https://registry.yarnpkg.com/tinycolor2/-/tinycolor2-1.4.1.tgz#f4fad333447bc0b07d4dc8e9209d8f39a8ac77e8"
|
||||
integrity sha1-9PrTM0R7wLB9TcjpIJ2POaisd+g=
|
||||
|
Loading…
Reference in New Issue
Block a user