Unified color picker API, allowed for color specified for theme selection, updated code to changes in PopperController API

This commit is contained in:
Dominik Prokop
2019-01-18 12:24:44 +01:00
parent 977d53c8c9
commit e33614ade3
8 changed files with 68 additions and 62 deletions

View File

@@ -2,29 +2,19 @@ import React, { Component, createRef } from 'react';
import PopperController from '../Tooltip/PopperController';
import Popper from '../Tooltip/Popper';
import { ColorPickerPopover } from './ColorPickerPopover';
import { ColorDefinition } from '../../utils/colorsPalette';
import { Themeable } from '../../types';
interface Props {
export interface ColorPickerProps {
color: string;
onChange: (c: string) => void;
onChange: (color: string) => void;
}
export class ColorPicker extends Component<Props, any> {
export class ColorPicker extends Component<ColorPickerProps & Themeable, any> {
private pickerTriggerRef = createRef<HTMLDivElement>();
pickerElem: HTMLElement | null;
colorPickerDrop: any;
onColorSelect = (color: ColorDefinition) => {
this.props.onChange(color.name);
};
renderPickerTabs = () => {
return <ColorPickerPopover color="" onColorSelect={() => {}} />;
};
render() {
return (
<PopperController content={this.renderPickerTabs}>
<PopperController content={<ColorPickerPopover {...this.props} />}>
{(showPopper, hidePopper, popperProps) => {
return (
<>

View File

@@ -1,17 +1,13 @@
import React from 'react';
import NamedColorsPicker from './NamedColorsPicker';
import { Color } from 'csstype';
import { ColorDefinition, getColorName } from '../..//utils/colorsPalette';
import { getColorName } from '../..//utils/colorsPalette';
import { SpectrumPicker } from './SpectrumPicker';
import { GrafanaTheme } from '../../types';
import { ColorPickerProps } from './ColorPicker';
import { GrafanaTheme, Themeable } from '../../types';
// const DEFAULT_COLOR = '#000000';
export interface Props {
color: Color | string;
theme?: GrafanaTheme;
onColorSelect: (color: string | ColorDefinition) => void;
}
export interface Props extends ColorPickerProps, Themeable {}
type PickerType = 'palette' | 'spectrum';
@@ -23,22 +19,22 @@ export class ColorPickerPopover extends React.Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = {
activePicker: 'spectrum',
activePicker: 'palette',
};
}
handleSpectrumColorSelect = (color: any) => {
this.props.onColorSelect(color.toRgbString());
this.props.onChange(color.toRgbString());
};
renderPicker = () => {
const { activePicker } = this.state;
const { color } = this.props;
const { color, onChange, theme } = this.props;
return activePicker === 'spectrum' ? (
<SpectrumPicker color={color} onColorSelect={this.handleSpectrumColorSelect} options={{}} />
) : (
<NamedColorsPicker selectedColor={getColorName(color)} onChange={this.props.onColorSelect} />
<NamedColorsPicker color={getColorName(color)} onChange={onChange} theme={theme} />
);
};

View File

@@ -3,16 +3,14 @@ import * as PopperJS from 'popper.js';
import { SeriesColorPickerPopover } from './SeriesColorPickerPopover';
import PopperController from '../Tooltip/PopperController';
import Popper from '../Tooltip/Popper';
import { GrafanaTheme } from '../../types';
import { Themeable } from '../../types';
import { ColorPickerProps } from './ColorPicker';
export interface SeriesColorPickerProps {
color: string;
export interface SeriesColorPickerProps extends ColorPickerProps, Themeable {
yaxis?: number;
optionalClass?: string;
onColorChange: (newColor: string) => void;
onToggleAxis?: () => void;
children: JSX.Element;
theme?: GrafanaTheme;
}
export class SeriesColorPicker extends React.Component<SeriesColorPickerProps> {
@@ -26,13 +24,13 @@ export class SeriesColorPicker extends React.Component<SeriesColorPickerProps> {
};
renderPickerTabs = () => {
const { color, yaxis, onColorChange, onToggleAxis, theme } = this.props;
const { color, yaxis, onChange, onToggleAxis, theme } = this.props;
return (
<SeriesColorPickerPopover
theme={theme}
color={color}
yaxis={yaxis}
onColorChange={onColorChange}
onChange={onChange}
onToggleAxis={onToggleAxis}
/>
);
@@ -40,9 +38,8 @@ export class SeriesColorPicker extends React.Component<SeriesColorPickerProps> {
render() {
const { children } = this.props;
return (
<PopperController placement="bottom-start" content={this.renderPickerTabs}>
<PopperController placement="bottom-start" content={this.renderPickerTabs()}>
{(showPopper, hidePopper, popperProps) => {
return (
<>

View File

@@ -1,28 +1,26 @@
import React from 'react';
import React, { FunctionComponent } from 'react';
import { ColorPickerPopover } from './ColorPickerPopover';
import { GrafanaTheme } from '../../types';
import { Themeable } from '../../types';
import { ColorPickerProps } from './ColorPicker';
export interface SeriesColorPickerPopoverProps {
color: string;
export interface SeriesColorPickerPopoverProps extends ColorPickerProps, Themeable {
yaxis?: number;
onColorChange: (color: string) => void;
onToggleAxis?: () => void;
theme?: GrafanaTheme;
}
export class SeriesColorPickerPopover extends React.PureComponent<SeriesColorPickerPopoverProps, any> {
render() {
return (
<div>
<ColorPickerPopover theme={this.props.theme} color={this.props.color} onColorSelect={this.props.onColorChange}>
<div style={{ marginTop: '32px' }}>
{this.props.yaxis && <AxisSelector yaxis={this.props.yaxis} onToggleAxis={this.props.onToggleAxis} />}
</div>
</ColorPickerPopover>
</div>
);
}
}
export const SeriesColorPickerPopover: FunctionComponent<SeriesColorPickerPopoverProps> = ({
onChange,
color,
theme,
yaxis,
onToggleAxis,
}) => {
return (
<ColorPickerPopover theme={theme} color={color} onChange={onChange}>
<div style={{ marginTop: '32px' }}>{yaxis && <AxisSelector yaxis={yaxis} onToggleAxis={onToggleAxis} />}</div>
</ColorPickerPopover>
);
};
interface AxisSelectorProps {
yaxis: number;

View File

@@ -4,6 +4,9 @@
}
}
.ColorPicker__arrow {
}
.ColorPickerPopover {
border-radius: 3px;
}
@@ -22,6 +25,7 @@
.ColorPickerPopover__tab {
background: #303133;
color: white;
cursor: pointer;
}
.ColorPickerPopover__tab--active {
background: none;

View File

@@ -8,3 +8,7 @@ export enum GrafanaTheme {
Light = 'light',
Dark = 'dark',
}
export interface Themeable {
theme?: GrafanaTheme;
}

View File

@@ -1,4 +1,5 @@
import { flatten, some, values } from 'lodash';
import { GrafanaTheme } from '../types';
type Hue = 'green' | 'yellow' | 'red' | 'blue' | 'orange' | 'purple';
@@ -38,6 +39,7 @@ type ThemeVariants = {
dark: string;
light: string;
};
export type ColorDefinition = {
hue: Hue;
isPrimary?: boolean;
@@ -118,8 +120,23 @@ export const getColorDefinition = (hex: string): ColorDefinition | undefined =>
)[0];
};
export const getColorName = (hex: string): Color | undefined => {
const definition = getColorDefinition(hex);
return definition ? definition.name : undefined;
const isHex = (color: string) => {
const hexRegex = /^((0x){0,1}|#{0,1})([0-9A-F]{8}|[0-9A-F]{6})$/gi;
return hexRegex.test(color);
};
export const getColorName = (color: string): Color | undefined => {
if (color.indexOf('rgb') > -1) {
return undefined;
}
if (isHex(color)) {
const definition = getColorDefinition(color);
return definition ? definition.name : undefined;
}
return color as Color;
};
export const getColorForTheme = (color: ColorDefinition, theme?: GrafanaTheme) => {
return theme ? color.variants[theme] : color.variants.dark;
};

View File

@@ -1734,7 +1734,7 @@
resolved "https://registry.yarnpkg.com/@types/jquery/-/jquery-1.10.35.tgz#4e5c2b1e5b3bf0b863efb8c5e70081f52e6c9518"
integrity sha512-SVtqEcudm7yjkTwoRA1gC6CNMhGDdMx4Pg8BPdiqI7bXXdCn1BPmtxgeWYQOgDxrq53/5YTlhq5ULxBEAlWIBg==
"@types/lodash@4.14.119", "@types/lodash@^4.14.119":
"@types/lodash@^4.14.119":
version "4.14.119"
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.119.tgz#be847e5f4bc3e35e46d041c394ead8b603ad8b39"
integrity sha512-Z3TNyBL8Vd/M9D9Ms2S3LmFq2sSMzahodD6rCS9V2N44HUMINb75jNkSuwAx7eo2ufqTdfOdtGQpNbieUjPQmw==
@@ -1803,7 +1803,7 @@
dependencies:
"@types/react" "*"
"@types/react@*", "@types/react@^16.7.6":
"@types/react@*", "@types/react@16.7.6", "@types/react@^16.7.6":
version "16.7.6"
resolved "https://registry.yarnpkg.com/@types/react/-/react-16.7.6.tgz#80e4bab0d0731ad3ae51f320c4b08bdca5f03040"
integrity sha512-QBUfzftr/8eg/q3ZRgf/GaDP6rTYc7ZNem+g4oZM38C9vXyV8AWRWaTQuW5yCoZTsfHrN7b3DeEiUnqH9SrnpA==
@@ -4505,7 +4505,7 @@ caniuse-api@^1.5.2:
lodash.memoize "^4.1.2"
lodash.uniq "^4.5.0"
caniuse-db@^1.0.30000529, caniuse-db@^1.0.30000634, caniuse-db@^1.0.30000639:
caniuse-db@1.0.30000772, caniuse-db@^1.0.30000529, caniuse-db@^1.0.30000634, caniuse-db@^1.0.30000639:
version "1.0.30000772"
resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000772.tgz#51aae891768286eade4a3d8319ea76d6a01b512b"
integrity sha1-UarokXaChureSj2DGep21qAbUSs=