index.tsx 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. import React, {
  2. useCallback,
  3. RefForwardingComponent,
  4. PropsWithChildren,
  5. useMemo
  6. } from 'react'
  7. import classnames from 'classnames'
  8. import { SketchPicker, ColorResult } from 'react-color'
  9. import { Popover } from 'antd'
  10. const styles = require('./ColorPicker.less')
  11. const defaultTheme = require('assets/json/echartsThemes/default.project.json')
  12. const defaultThemeColors = defaultTheme.theme.color
  13. interface IColorPickerProps {
  14. value?: string | [number, number, number, number]
  15. size?: 'default' | 'small' | 'large'
  16. preset?: boolean
  17. disableAlpha?: boolean
  18. rawValue?: boolean
  19. className?: string
  20. onChange?: (value: string | [number, number, number, number]) => void
  21. }
  22. const ColorPicker: RefForwardingComponent<
  23. Popover,
  24. PropsWithChildren<IColorPickerProps>
  25. > = (props, ref) => {
  26. const { value, size, preset, disableAlpha, rawValue, className, onChange } = props
  27. const cls = classnames({
  28. [styles.picker]: true,
  29. [className]: !!className,
  30. [`${styles.picker}-sm`]: size && size === 'small',
  31. [`${styles.picker}-lg`]: size && size === 'large'
  32. })
  33. const colorChange = useCallback(
  34. (e: ColorResult) => {
  35. const { r, g, b, a } = e.rgb
  36. onChange?.(rawValue ? [r, g, b, a] : `rgba(${r}, ${g}, ${b}, ${a})`)
  37. },
  38. [onChange, rawValue]
  39. )
  40. const color = useMemo(
  41. (): string =>
  42. rawValue && value
  43. ? `rgba(${(value as [number, number, number, number]).join()})`
  44. : (value as string),
  45. [value, rawValue]
  46. )
  47. return (
  48. <Popover
  49. ref={ref}
  50. content={
  51. <div style={{ margin: '-8px -16px' }}>
  52. <SketchPicker
  53. color={color}
  54. presetColors={preset ? defaultThemeColors : []}
  55. onChangeComplete={colorChange}
  56. disableAlpha={disableAlpha}
  57. />
  58. </div>
  59. }
  60. trigger="click"
  61. placement="right"
  62. >
  63. {props.children || (
  64. <div className={cls}>
  65. <span
  66. className={styles.colorIndicator}
  67. style={{ background: color }}
  68. />
  69. </div>
  70. )}
  71. </Popover>
  72. )
  73. }
  74. export type ColorPickerProps = IColorPickerProps
  75. export default React.forwardRef(ColorPicker)