mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
ColorPicker: migrated styles from sass to emotion (#30909)
* ColorPicker: migrated styles from sass to emotion * fixes frontend test * updated some changes * updated some changes * fixed small import nits
This commit is contained in:
parent
ef8a5b760f
commit
b4d51c9f68
@ -3,10 +3,11 @@ import omit from 'lodash/omit';
|
||||
import { PopoverController } from '../Tooltip/PopoverController';
|
||||
import { Popover } from '../Tooltip/Popover';
|
||||
import { ColorPickerPopover, ColorPickerProps, ColorPickerChangeHandler } from './ColorPickerPopover';
|
||||
import { getColorForTheme } from '@grafana/data';
|
||||
import { getColorForTheme, GrafanaTheme } from '@grafana/data';
|
||||
import { SeriesColorPickerPopover } from './SeriesColorPickerPopover';
|
||||
|
||||
import { withTheme } from '../../themes/ThemeContext';
|
||||
import { css } from 'emotion';
|
||||
import { withTheme, stylesFactory } from '../../themes';
|
||||
import { ColorPickerTrigger } from './ColorPickerTrigger';
|
||||
|
||||
/**
|
||||
@ -40,6 +41,7 @@ export const colorPickerFactory = <T extends ColorPickerProps>(
|
||||
|
||||
render() {
|
||||
const { theme, children } = this.props;
|
||||
const styles = getStyles(theme);
|
||||
const popoverElement = React.createElement(popover, {
|
||||
...omit(this.props, 'children'),
|
||||
onChange: this.onColorChange,
|
||||
@ -54,7 +56,7 @@ export const colorPickerFactory = <T extends ColorPickerProps>(
|
||||
<Popover
|
||||
{...popperProps}
|
||||
referenceElement={this.pickerTriggerRef.current}
|
||||
wrapperClassName="ColorPicker"
|
||||
wrapperClassName={styles.colorPicker}
|
||||
onMouseLeave={hidePopper}
|
||||
onMouseEnter={showPopper}
|
||||
/>
|
||||
@ -88,3 +90,32 @@ export const colorPickerFactory = <T extends ColorPickerProps>(
|
||||
|
||||
export const ColorPicker = withTheme(colorPickerFactory(ColorPickerPopover, 'ColorPicker'));
|
||||
export const SeriesColorPicker = withTheme(colorPickerFactory(SeriesColorPickerPopover, 'SeriesColorPicker'));
|
||||
|
||||
const getStyles = stylesFactory((theme: GrafanaTheme) => {
|
||||
return {
|
||||
colorPicker: css`
|
||||
position: absolute;
|
||||
z-index: ${theme.zIndex.tooltip};
|
||||
color: ${theme.colors.text};
|
||||
max-width: 400px;
|
||||
font-size: ${theme.typography.size.sm};
|
||||
// !important because these styles are also provided to popper via .popper classes from Tooltip component
|
||||
// hope to get rid of those soon
|
||||
padding: 15px !important;
|
||||
& [data-placement^='top'] {
|
||||
padding-left: 0 !important;
|
||||
padding-right: 0 !important;
|
||||
}
|
||||
& [data-placement^='bottom'] {
|
||||
padding-left: 0 !important;
|
||||
padding-right: 0 !important;
|
||||
}
|
||||
& [data-placement^='left'] {
|
||||
padding-top: 0 !important;
|
||||
}
|
||||
& [data-placement^='right'] {
|
||||
padding-top: 0 !important;
|
||||
}
|
||||
`,
|
||||
};
|
||||
});
|
||||
|
@ -3,16 +3,14 @@ import { mount, ReactWrapper } from 'enzyme';
|
||||
import { ColorPickerPopover } from './ColorPickerPopover';
|
||||
import { ColorSwatch } from './NamedColorsGroup';
|
||||
import flatten from 'lodash/flatten';
|
||||
import { getTheme } from '../../themes';
|
||||
import { GrafanaThemeType, getNamedColorPalette, getColorFromHexRgbOrName } from '@grafana/data';
|
||||
import { getNamedColorPalette, getColorFromHexRgbOrName } from '@grafana/data';
|
||||
|
||||
const allColors = flatten(Array.from(getNamedColorPalette().values()));
|
||||
|
||||
describe('ColorPickerPopover', () => {
|
||||
describe('rendering', () => {
|
||||
it('should render provided color as selected if color provided by name', () => {
|
||||
const theme = getTheme();
|
||||
const wrapper = mount(<ColorPickerPopover color={'green'} onChange={() => {}} theme={theme} />);
|
||||
const wrapper = mount(<ColorPickerPopover color={'green'} onChange={() => {}} />);
|
||||
const selectedSwatch = wrapper.find(ColorSwatch).findWhere((node) => node.key() === 'green');
|
||||
const notSelectedSwatches = wrapper.find(ColorSwatch).filterWhere((node) => node.prop('isSelected') === false);
|
||||
|
||||
@ -22,8 +20,7 @@ describe('ColorPickerPopover', () => {
|
||||
});
|
||||
|
||||
it('should render provided color as selected if color provided by hex', () => {
|
||||
const theme = getTheme();
|
||||
const wrapper = mount(<ColorPickerPopover color={'green'} onChange={() => {}} theme={theme} />);
|
||||
const wrapper = mount(<ColorPickerPopover color={'green'} onChange={() => {}} />);
|
||||
|
||||
const selectedSwatch = wrapper.find(ColorSwatch).findWhere((node) => node.key() === 'green');
|
||||
const notSelectedSwatches = wrapper.find(ColorSwatch).filterWhere((node) => node.prop('isSelected') === false);
|
||||
@ -44,26 +41,17 @@ describe('ColorPickerPopover', () => {
|
||||
});
|
||||
|
||||
it('should pass hex color value to onChange prop by default', () => {
|
||||
wrapper = mount(
|
||||
<ColorPickerPopover color={'green'} onChange={onChangeSpy} theme={getTheme(GrafanaThemeType.Light)} />
|
||||
);
|
||||
wrapper = mount(<ColorPickerPopover color={'green'} onChange={onChangeSpy} />);
|
||||
|
||||
const basicBlueSwatch = wrapper.find(ColorSwatch).findWhere((node) => node.key() === 'green');
|
||||
basicBlueSwatch.simulate('click');
|
||||
|
||||
expect(onChangeSpy).toBeCalledTimes(1);
|
||||
expect(onChangeSpy).toBeCalledWith(getColorFromHexRgbOrName('green', GrafanaThemeType.Light));
|
||||
expect(onChangeSpy).toBeCalledWith(getColorFromHexRgbOrName('green'));
|
||||
});
|
||||
|
||||
it('should pass color name to onChange prop when named colors enabled', () => {
|
||||
wrapper = mount(
|
||||
<ColorPickerPopover
|
||||
enableNamedColors
|
||||
color={'green'}
|
||||
onChange={onChangeSpy}
|
||||
theme={getTheme(GrafanaThemeType.Light)}
|
||||
/>
|
||||
);
|
||||
wrapper = mount(<ColorPickerPopover enableNamedColors color={'green'} onChange={onChangeSpy} />);
|
||||
|
||||
const basicBlueSwatch = wrapper.find(ColorSwatch).findWhere((node) => node.key() === 'green');
|
||||
basicBlueSwatch.simulate('click');
|
||||
|
@ -4,7 +4,9 @@ import { PopoverContentProps } from '../Tooltip/Tooltip';
|
||||
import SpectrumPalette from './SpectrumPalette';
|
||||
import { Themeable } from '../../types/theme';
|
||||
import { warnAboutColorPickerPropsDeprecation } from './warnAboutColorPickerPropsDeprecation';
|
||||
import { GrafanaThemeType, getColorForTheme } from '@grafana/data';
|
||||
import { css, cx } from 'emotion';
|
||||
import { GrafanaTheme, GrafanaThemeType, getColorForTheme } from '@grafana/data';
|
||||
import { stylesFactory, withTheme } from '../../themes';
|
||||
|
||||
export type ColorPickerChangeHandler = (color: string) => void;
|
||||
|
||||
@ -36,7 +38,7 @@ interface State<T> {
|
||||
activePicker: PickerType | keyof T;
|
||||
}
|
||||
|
||||
export class ColorPickerPopover<T extends CustomPickersDescriptor> extends React.Component<Props<T>, State<T>> {
|
||||
class UnThemedColorPickerPopover<T extends CustomPickersDescriptor> extends React.Component<Props<T>, State<T>> {
|
||||
constructor(props: Props<T>) {
|
||||
super(props);
|
||||
this.state = {
|
||||
@ -113,10 +115,15 @@ export class ColorPickerPopover<T extends CustomPickersDescriptor> extends React
|
||||
|
||||
render() {
|
||||
const { theme } = this.props;
|
||||
const colorPickerTheme = theme.type || GrafanaThemeType.Dark;
|
||||
const styles = getStyles(theme);
|
||||
return (
|
||||
<div className={`ColorPickerPopover ColorPickerPopover--${colorPickerTheme}`}>
|
||||
<div className="ColorPickerPopover__tabs">
|
||||
<div
|
||||
className={cx(
|
||||
styles.colorPickerPopover,
|
||||
theme.type === GrafanaThemeType.Light ? styles.colorPickerPopoverLight : styles.colorPickerPopoverDark
|
||||
)}
|
||||
>
|
||||
<div className={styles.colorPickerPopoverTabs}>
|
||||
<div className={this.getTabClassName('palette')} onClick={this.onTabChange('palette')}>
|
||||
Colors
|
||||
</div>
|
||||
@ -126,8 +133,62 @@ export class ColorPickerPopover<T extends CustomPickersDescriptor> extends React
|
||||
{this.renderCustomPickerTabs()}
|
||||
</div>
|
||||
|
||||
<div className="ColorPickerPopover__content">{this.renderPicker()}</div>
|
||||
<div className={styles.colorPickerPopoverContent}>{this.renderPicker()}</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export const ColorPickerPopover = withTheme(UnThemedColorPickerPopover);
|
||||
ColorPickerPopover.displayName = 'ColorPickerPopover';
|
||||
|
||||
const getStyles = stylesFactory((theme: GrafanaTheme) => {
|
||||
return {
|
||||
colorPickerPopover: css`
|
||||
border-radius: ${theme.border.radius.md};
|
||||
`,
|
||||
colorPickerPopoverLight: css`
|
||||
color: ${theme.palette.black};
|
||||
background: linear-gradient(180deg, ${theme.palette.white} 0%, #f7f8fa 104.25%);
|
||||
box-shadow: 0px 2px 4px #dde4ed, 0px 0px 2px #dde4ed;
|
||||
|
||||
.ColorPickerPopover__tab {
|
||||
width: 50%;
|
||||
text-align: center;
|
||||
padding: ${theme.spacing.sm} 0;
|
||||
background: #dde4ed;
|
||||
}
|
||||
.ColorPickerPopover__tab--active {
|
||||
background: ${theme.palette.white};
|
||||
}
|
||||
`,
|
||||
colorPickerPopoverDark: css`
|
||||
color: #d8d9da;
|
||||
background: linear-gradient(180deg, #1e2028 0%, #161719 104.25%);
|
||||
box-shadow: 0px 2px 4px ${theme.palette.black}, 0px 0px 2px ${theme.palette.black};
|
||||
|
||||
.ColorPickerPopover__tab {
|
||||
width: 50%;
|
||||
text-align: center;
|
||||
padding: ${theme.spacing.sm} 0;
|
||||
background: #303133;
|
||||
color: ${theme.palette.white};
|
||||
cursor: pointer;
|
||||
}
|
||||
.ColorPickerPopover__tab--active {
|
||||
background: none;
|
||||
}
|
||||
`,
|
||||
colorPickerPopoverContent: css`
|
||||
width: 336px;
|
||||
min-height: 184px;
|
||||
padding: ${theme.spacing.lg};
|
||||
`,
|
||||
colorPickerPopoverTabs: css`
|
||||
display: flex;
|
||||
width: 100%;
|
||||
border-radius: ${theme.border.radius.md} ${theme.border.radius.md} 0 0;
|
||||
overflow: hidden;
|
||||
`,
|
||||
};
|
||||
});
|
||||
|
@ -3,7 +3,8 @@ import React, { FunctionComponent } from 'react';
|
||||
import { ColorPickerPopover, ColorPickerProps } from './ColorPickerPopover';
|
||||
import { PopoverContentProps } from '../Tooltip/Tooltip';
|
||||
import { Switch } from '../Forms/Legacy/Switch/Switch';
|
||||
import { withTheme } from '../../themes/ThemeContext';
|
||||
import { css } from 'emotion';
|
||||
import { withTheme, useStyles } from '../../themes';
|
||||
|
||||
export interface SeriesColorPickerPopoverProps extends ColorPickerProps, PopoverContentProps {
|
||||
yaxis?: number;
|
||||
@ -11,6 +12,7 @@ export interface SeriesColorPickerPopoverProps extends ColorPickerProps, Popover
|
||||
}
|
||||
|
||||
export const SeriesColorPickerPopover: FunctionComponent<SeriesColorPickerPopoverProps> = (props) => {
|
||||
const styles = useStyles(getStyles);
|
||||
const { yaxis, onToggleAxis, color, ...colorPickerProps } = props;
|
||||
|
||||
const customPickers = onToggleAxis
|
||||
@ -22,8 +24,8 @@ export const SeriesColorPickerPopover: FunctionComponent<SeriesColorPickerPopove
|
||||
<Switch
|
||||
key="yaxisSwitch"
|
||||
label="Use right y-axis"
|
||||
className="ColorPicker__axisSwitch"
|
||||
labelClass="ColorPicker__axisSwitchLabel"
|
||||
className={styles.colorPickerAxisSwitch}
|
||||
labelClass={styles.colorPickerAxisSwitchLabel}
|
||||
checked={yaxis === 2}
|
||||
onChange={() => {
|
||||
if (onToggleAxis) {
|
||||
@ -87,3 +89,15 @@ export class AxisSelector extends React.PureComponent<AxisSelectorProps, AxisSel
|
||||
|
||||
// This component is to enable SeriesColorPickerPopover usage via series-color-picker-popover directive
|
||||
export const SeriesColorPickerPopoverWithTheme = withTheme(SeriesColorPickerPopover);
|
||||
|
||||
const getStyles = () => {
|
||||
return {
|
||||
colorPickerAxisSwitch: css`
|
||||
width: 100%;
|
||||
`,
|
||||
colorPickerAxisSwitchLabel: css`
|
||||
display: flex;
|
||||
flex-grow: 1;
|
||||
`,
|
||||
};
|
||||
};
|
||||
|
@ -1,178 +0,0 @@
|
||||
$arrowSize: 15px;
|
||||
.ColorPicker {
|
||||
@extend .popper;
|
||||
font-size: 12px;
|
||||
// !important because these styles are also provided to popper via .popper classes from Tooltip component
|
||||
// hope to get rid of those soon
|
||||
padding: $arrowSize !important;
|
||||
}
|
||||
|
||||
.ColorPicker__arrow {
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-style: solid;
|
||||
position: absolute;
|
||||
margin: 0px;
|
||||
|
||||
&[data-placement^='top'] {
|
||||
border-width: $arrowSize $arrowSize 0 $arrowSize;
|
||||
border-left-color: transparent;
|
||||
border-right-color: transparent;
|
||||
border-bottom-color: transparent;
|
||||
bottom: -$arrowSize;
|
||||
left: calc(50%-#{$arrowSize});
|
||||
padding-top: $arrowSize;
|
||||
}
|
||||
|
||||
&[data-placement^='bottom'] {
|
||||
border-width: 0 $arrowSize $arrowSize $arrowSize;
|
||||
border-left-color: transparent;
|
||||
border-right-color: transparent;
|
||||
border-top-color: transparent;
|
||||
top: 0;
|
||||
left: calc(50%-#{$arrowSize});
|
||||
}
|
||||
|
||||
&[data-placement^='bottom-start'] {
|
||||
border-width: 0 $arrowSize $arrowSize $arrowSize;
|
||||
border-left-color: transparent;
|
||||
border-right-color: transparent;
|
||||
border-top-color: transparent;
|
||||
top: 0;
|
||||
left: $arrowSize;
|
||||
}
|
||||
|
||||
&[data-placement^='bottom-end'] & {
|
||||
border-width: 0 $arrowSize $arrowSize $arrowSize;
|
||||
border-left-color: transparent;
|
||||
border-right-color: transparent;
|
||||
border-top-color: transparent;
|
||||
top: 0;
|
||||
left: calc(100%-#{$arrowSize});
|
||||
}
|
||||
|
||||
&[data-placement^='right'] {
|
||||
border-width: $arrowSize $arrowSize $arrowSize 0;
|
||||
border-left-color: transparent;
|
||||
border-top-color: transparent;
|
||||
border-bottom-color: transparent;
|
||||
left: 0;
|
||||
top: calc(50%-#{$arrowSize});
|
||||
}
|
||||
|
||||
&[data-placement^='left'] {
|
||||
border-width: $arrowSize 0 $arrowSize $arrowSize;
|
||||
border-top-color: transparent;
|
||||
border-right-color: transparent;
|
||||
border-bottom-color: transparent;
|
||||
right: -$arrowSize;
|
||||
top: calc(50%-#{$arrowSize});
|
||||
}
|
||||
}
|
||||
|
||||
.ColorPicker__arrow--light {
|
||||
border-color: #ffffff;
|
||||
}
|
||||
|
||||
.ColorPicker__arrow--dark {
|
||||
border-color: #1e2028;
|
||||
}
|
||||
|
||||
// !important because these styles are also provided to popper via .popper classes from Tooltip component
|
||||
// hope to get rid of those soon
|
||||
.ColorPicker[data-placement^='top'],
|
||||
.ColorPicker[data-placement^='bottom'] {
|
||||
padding-left: 0 !important;
|
||||
padding-right: 0 !important;
|
||||
}
|
||||
|
||||
// !important because these styles are also provided to popper via .popper classes from Tooltip component
|
||||
// hope to get rid of those soon
|
||||
.ColorPicker[data-placement^='left'],
|
||||
.ColorPicker[data-placement^='right'] {
|
||||
padding-top: 0 !important;
|
||||
}
|
||||
|
||||
.ColorPickerPopover {
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.ColorPickerPopover--light {
|
||||
color: black;
|
||||
background: linear-gradient(180deg, #ffffff 0%, #f7f8fa 104.25%);
|
||||
box-shadow: 0px 2px 4px #dde4ed, 0px 0px 2px #dde4ed;
|
||||
}
|
||||
|
||||
.ColorPickerPopover--dark {
|
||||
color: #d8d9da;
|
||||
background: linear-gradient(180deg, #1e2028 0%, #161719 104.25%);
|
||||
box-shadow: 0px 2px 4px #000000, 0px 0px 2px #000000;
|
||||
|
||||
.ColorPickerPopover__tab {
|
||||
background: #303133;
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
}
|
||||
.ColorPickerPopover__tab--active {
|
||||
background: none;
|
||||
}
|
||||
}
|
||||
|
||||
.ColorPickerPopover__content {
|
||||
width: 336px;
|
||||
min-height: 184px;
|
||||
padding: 24px;
|
||||
}
|
||||
|
||||
.ColorPickerPopover__tabs {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
border-radius: 3px 3px 0 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.ColorPickerPopover__tab {
|
||||
width: 50%;
|
||||
text-align: center;
|
||||
padding: 8px 0;
|
||||
background: #dde4ed;
|
||||
}
|
||||
|
||||
.ColorPickerPopover__tab--active {
|
||||
background: white;
|
||||
}
|
||||
|
||||
.ColorPicker__axisSwitch {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.ColorPicker__axisSwitchLabel {
|
||||
display: flex;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.gf-color-picker__body {
|
||||
padding-bottom: $arrowSize;
|
||||
padding-left: 6px;
|
||||
}
|
||||
|
||||
.drop-popover.gf-color-picker {
|
||||
.drop-content {
|
||||
width: 210px;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Remove. This is a temporary solution until color picker popovers are used
|
||||
// with Drop.js.
|
||||
.drop-popover.drop-popover--transparent {
|
||||
.drop-content {
|
||||
border: none;
|
||||
background: none;
|
||||
padding: 0;
|
||||
max-width: none;
|
||||
|
||||
&:before {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,4 @@
|
||||
@import 'ButtonCascader/ButtonCascader';
|
||||
@import 'ColorPicker/ColorPicker';
|
||||
@import 'Drawer/Drawer';
|
||||
@import 'RefreshPicker/RefreshPicker';
|
||||
@import 'Forms/Legacy/Select/Select';
|
||||
|
@ -71,3 +71,24 @@ $easing: cubic-bezier(0, 0, 0.265, 1);
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.drop-popover.gf-color-picker {
|
||||
.drop-content {
|
||||
width: 210px;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Remove. This is a temporary solution until color picker popovers are used
|
||||
// with Drop.js.
|
||||
.drop-popover.drop-popover--transparent {
|
||||
.drop-content {
|
||||
border: none;
|
||||
background: none;
|
||||
padding: 0;
|
||||
max-width: none;
|
||||
|
||||
&:before {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user