Forráskód Böngészése

Use render props pattern in color picker

Andrej Ocenas 6 éve
szülő
commit
96285c4f56

+ 10 - 1
packages/grafana-ui/src/components/ColorPicker/ColorPicker.story.tsx

@@ -50,7 +50,16 @@ ColorPickerStories.add('Series color picker', () => {
             color={selectedColor}
             color={selectedColor}
             onChange={color => updateSelectedColor(color)}
             onChange={color => updateSelectedColor(color)}
           >
           >
-            <div style={{ color: selectedColor, cursor: 'pointer' }}>Open color picker</div>
+            {({ ref, showColorPicker, hideColorPicker }) => (
+              <div
+                ref={ref}
+                onMouseLeave={hideColorPicker}
+                onClick={showColorPicker}
+                style={{ color: selectedColor, cursor: 'pointer' }}
+              >
+                Open color picker
+              </div>
+            )}
           </SeriesColorPicker>
           </SeriesColorPicker>
         );
         );
       }}
       }}

+ 14 - 7
packages/grafana-ui/src/components/ColorPicker/ColorPicker.tsx

@@ -1,4 +1,5 @@
 import React, { Component, createRef } from 'react';
 import React, { Component, createRef } from 'react';
+import { omit } from 'lodash';
 import { PopperController } from '../Tooltip/PopperController';
 import { PopperController } from '../Tooltip/PopperController';
 import { Popper } from '../Tooltip/Popper';
 import { Popper } from '../Tooltip/Popper';
 import { ColorPickerPopover, ColorPickerProps, ColorPickerChangeHandler } from './ColorPickerPopover';
 import { ColorPickerPopover, ColorPickerProps, ColorPickerChangeHandler } from './ColorPickerPopover';
@@ -8,13 +9,19 @@ import { SeriesColorPickerPopover } from './SeriesColorPickerPopover';
 import { withTheme } from '../../themes/ThemeContext';
 import { withTheme } from '../../themes/ThemeContext';
 import { ColorPickerTrigger } from './ColorPickerTrigger';
 import { ColorPickerTrigger } from './ColorPickerTrigger';
 
 
+type ColorPickerTriggerRenderer = (props: {
+  ref: React.RefObject<any>;
+  showColorPicker: () => void;
+  hideColorPicker: () => void;
+}) => React.ReactNode;
+
 export const colorPickerFactory = <T extends ColorPickerProps>(
 export const colorPickerFactory = <T extends ColorPickerProps>(
   popover: React.ComponentType<T>,
   popover: React.ComponentType<T>,
   displayName = 'ColorPicker'
   displayName = 'ColorPicker'
 ) => {
 ) => {
-  return class ColorPicker extends Component<T, any> {
+  return class ColorPicker extends Component<T & { children?: ColorPickerTriggerRenderer }, any> {
     static displayName = displayName;
     static displayName = displayName;
-    pickerTriggerRef = createRef<HTMLDivElement>();
+    pickerTriggerRef = createRef<any>();
 
 
     onColorChange = (color: string) => {
     onColorChange = (color: string) => {
       const { onColorChange, onChange } = this.props;
       const { onColorChange, onChange } = this.props;
@@ -24,11 +31,11 @@ export const colorPickerFactory = <T extends ColorPickerProps>(
     };
     };
 
 
     render() {
     render() {
+      const { theme, children } = this.props;
       const popoverElement = React.createElement(popover, {
       const popoverElement = React.createElement(popover, {
-        ...this.props,
+        ...omit(this.props, 'children'),
         onChange: this.onColorChange,
         onChange: this.onColorChange,
       });
       });
-      const { theme, children } = this.props;
 
 
       return (
       return (
         <PopperController content={popoverElement} hideAfter={300}>
         <PopperController content={popoverElement} hideAfter={300}>
@@ -46,10 +53,10 @@ export const colorPickerFactory = <T extends ColorPickerProps>(
                 )}
                 )}
 
 
                 {children ? (
                 {children ? (
-                  React.cloneElement(children as JSX.Element, {
+                  (children as ColorPickerTriggerRenderer)({
                     ref: this.pickerTriggerRef,
                     ref: this.pickerTriggerRef,
-                    onClick: showPopper,
-                    onMouseLeave: hidePopper,
+                    showColorPicker: showPopper,
+                    hideColorPicker: hidePopper,
                   })
                   })
                 ) : (
                 ) : (
                   <ColorPickerTrigger
                   <ColorPickerTrigger

+ 1 - 1
packages/grafana-ui/src/components/ColorPicker/ColorPickerPopover.tsx

@@ -17,8 +17,8 @@ export interface ColorPickerProps extends Themeable {
    */
    */
   onColorChange?: ColorPickerChangeHandler;
   onColorChange?: ColorPickerChangeHandler;
   enableNamedColors?: boolean;
   enableNamedColors?: boolean;
-  children?: JSX.Element;
 }
 }
+
 export interface Props<T> extends ColorPickerProps, PopperContentProps {
 export interface Props<T> extends ColorPickerProps, PopperContentProps {
   customPickers?: T;
   customPickers?: T;
 }
 }

+ 2 - 2
packages/grafana-ui/src/components/ColorPicker/ColorPickerTrigger.tsx

@@ -1,4 +1,4 @@
-import React, { forwardRef, Ref } from 'react';
+import React, { forwardRef } from 'react';
 
 
 interface ColorPickerTriggerProps {
 interface ColorPickerTriggerProps {
   onClick: () => void;
   onClick: () => void;
@@ -8,7 +8,7 @@ interface ColorPickerTriggerProps {
 
 
 export const ColorPickerTrigger = forwardRef(function ColorPickerTrigger(
 export const ColorPickerTrigger = forwardRef(function ColorPickerTrigger(
   props: ColorPickerTriggerProps,
   props: ColorPickerTriggerProps,
-  ref: Ref<HTMLDivElement>
+  ref: React.Ref<HTMLDivElement>
 ) {
 ) {
   return (
   return (
     <div
     <div

+ 5 - 3
public/app/plugins/panel/graph/Legend/LegendSeriesItem.tsx

@@ -174,9 +174,11 @@ class LegendSeriesIcon extends PureComponent<LegendSeriesIconProps, LegendSeries
         onToggleAxis={this.props.onToggleAxis}
         onToggleAxis={this.props.onToggleAxis}
         enableNamedColors
         enableNamedColors
       >
       >
-        <span className="graph-legend-icon">
-          <SeriesIcon color={this.props.color} />
-        </span>
+        {({ ref, showColorPicker, hideColorPicker }) => (
+          <span ref={ref} onClick={showColorPicker} onMouseLeave={hideColorPicker} className="graph-legend-icon">
+            <SeriesIcon color={this.props.color} />
+          </span>
+        )}
       </SeriesColorPicker>
       </SeriesColorPicker>
     );
     );
   }
   }