From ec1c85acca586f4c8c1c80e864de3f8e1a3fa3fc Mon Sep 17 00:00:00 2001 From: Giordano Ricci Date: Fri, 23 Apr 2021 15:03:48 +0100 Subject: [PATCH] Grafana-UI: replace react-color with react-colorful (#33267) * Grafana-UI: replace react-color with react-colorful * Throttle onChange from SpectrumPalette --- packages/grafana-ui/package.json | 2 +- .../src/components/ColorPicker/ColorInput.tsx | 62 ++++---- .../ColorPicker/ColorPickerPopover.tsx | 2 +- .../ColorPicker/SpectrumPalette.tsx | 136 +++++++----------- .../ColorPicker/SpectrumPalettePointer.tsx | 77 ---------- yarn.lock | 36 +---- 6 files changed, 97 insertions(+), 218 deletions(-) delete mode 100644 packages/grafana-ui/src/components/ColorPicker/SpectrumPalettePointer.tsx diff --git a/packages/grafana-ui/package.json b/packages/grafana-ui/package.json index dc83349a442..cc7dc1b3977 100644 --- a/packages/grafana-ui/package.json +++ b/packages/grafana-ui/package.json @@ -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", diff --git a/packages/grafana-ui/src/components/ColorPicker/ColorInput.tsx b/packages/grafana-ui/src/components/ColorPicker/ColorInput.tsx index fc1dee2f15e..7ad1c84574f 100644 --- a/packages/grafana-ui/src/components/ColorPicker/ColorInput.tsx +++ b/packages/grafana-ui/src/components/ColorPicker/ColorInput.tsx @@ -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 { @@ -66,31 +70,41 @@ class ColorInput extends React.PureComponent { render() { const { value } = this.state; return ( -
-
-
- -
-
+ } + /> ); } } export default ColorInput; + +interface ColorPreviewProps { + color: string; +} + +const ColorPreview = ({ color }: ColorPreviewProps) => { + const styles = useStyles(getColorPreviewStyles); + + return ( +
+ ); +}; + +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}; +`; diff --git a/packages/grafana-ui/src/components/ColorPicker/ColorPickerPopover.tsx b/packages/grafana-ui/src/components/ColorPicker/ColorPickerPopover.tsx index 6cfc81fb810..9577bcfd2e0 100644 --- a/packages/grafana-ui/src/components/ColorPicker/ColorPickerPopover.tsx +++ b/packages/grafana-ui/src/components/ColorPicker/ColorPickerPopover.tsx @@ -72,7 +72,7 @@ class UnThemedColorPickerPopover extends Reac switch (activePicker) { case 'spectrum': - return ; + return ; case 'palette': return ; default: diff --git a/packages/grafana-ui/src/components/ColorPicker/SpectrumPalette.tsx b/packages/grafana-ui/src/components/ColorPicker/SpectrumPalette.tsx index cc76477cd66..09bb33e218b 100644 --- a/packages/grafana-ui/src/components/ColorPicker/SpectrumPalette.tsx +++ b/packages/grafana-ui/src/components/ColorPicker/SpectrumPalette.tsx @@ -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) => ( - -); +const SpectrumPalette: React.FunctionComponent = ({ 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(({ rgb, hsl, onChange, theme }) => { return ( -
-
-
-
- {/* - // @ts-ignore */} - -
-
- {/* - // @ts-ignore */} - -
-
+ <> + -
- {/* - // @ts-ignore */} - -
-
-
- ); -}); - -const SpectrumPalette: React.FunctionComponent = ({ color, onChange, theme }) => { - return ( -
- { - onChange(tinycolor(a.rgb).toString()); - }} - theme={theme} - /> - -
+ + ); }; +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; diff --git a/packages/grafana-ui/src/components/ColorPicker/SpectrumPalettePointer.tsx b/packages/grafana-ui/src/components/ColorPicker/SpectrumPalettePointer.tsx deleted file mode 100644 index 99b76a69bd2..00000000000 --- a/packages/grafana-ui/src/components/ColorPicker/SpectrumPalettePointer.tsx +++ /dev/null @@ -1,77 +0,0 @@ -import React from 'react'; -import { Themeable } from '../../types'; - -export interface SpectrumPalettePointerProps extends Themeable { - direction?: string; -} - -const SpectrumPalettePointer: React.FunctionComponent = ({ 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 ( -
-
-
-
- ); -}; - -export default SpectrumPalettePointer; diff --git a/yarn.lock b/yarn.lock index db8697eee5d..262b936a534 100644 --- a/yarn.lock +++ b/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=