import React from 'react' ; import { HsvaColor , hsvaToHslaString } from '@uiw/color-convert' ; import Interactive , { Interaction } from '@uiw/react-drag-event-interactive' ; import { Pointer , PointerProps } from './Pointer' ; export interface SaturationProps extends Omit < React . HTMLAttributes < HTMLDivElement > , 'onChange' > { prefixCls ? : string ; /** hsva => `{ h: 0, s: 75, v: 82, a: 1 }` */ hsva : HsvaColor ; radius ? : React . CSSProperties [ 'borderRadius' ] ; /** React Component, Custom pointer component */ pointer ? : ( { prefixCls , left , top , color } : PointerProps ) => JSX . Element ; onChange ? : ( newColor : HsvaColor ) => void ; } const Saturation = React . forwardRef < HTMLDivElement , SaturationProps > ( ( props , ref ) => { const { prefixCls = 'w-color-saturation' , radius = 0 , pointer , className , style , hsva , onChange , ... other } = props ; const containerStyle = { width : 200 , height : 200 , borderRadius : radius , ... style , position : 'relative' , } ; const handleChange = ( interaction , event ) => { onChange && onChange ( { h : hsva . h , s : interaction . left * 100 , v : ( 1 - interaction . top ) * 100 , a : hsva . a , } ) ; } ; const comProps = { top : `${ 100 - hsva . v }%` , left : `${ hsva . s }%` , color : hsvaToHslaString ( hsva ) , } ; return ( < Interactive className = { [ prefixCls , className || '' ] . filter ( Boolean ) . join ( ' ' ) } { ... other } style = { { position : 'absolute' , inset : 0 , cursor : 'crosshair' , backgroundImage : `linear-gradient(0deg, #000, transparent), linear-gradient(90deg, #fff, hsl(${ hsva . h }, 100%, 50%))` , ... containerStyle , } } ref = { ref } onMove = { handleChange } onDown = { handleChange } > { React . createElement ( pointer || Pointer , { prefixCls , ... comProps , } ) } < /Interactive>); } ) ; Saturation . displayName = 'Saturation' ; export default Saturation ;