import { merge } from 'lodash-es' import { createEffect, JSX, mergeProps } from 'solid-js' import { calculateChange } from '../../helpers/saturation' import { ChangeColor, HslColor, HsvColor } from '../../types' export type SaturationProps = { hsl: HslColor hsv: HsvColor pointer?: JSX.Element onChange?: (color: ChangeColor, event?: Event) => void shadow?: JSX.CSSProperties['box-shadow'] radius?: JSX.CSSProperties['border-radius'] styles?: JSX.CSSProperties } export function Saturation(_props: SaturationProps) { const props = mergeProps({ styles: {} }, _props) let container: HTMLDivElement createEffect(() => { return () => { unbindEventListeners() } }, []) function handleChange(event: MouseEvent | TouchEvent) { if (props.onChange) { props.onChange(calculateChange(event, props.hsl, container!), event as any) } } function handleMouseDown(event: MouseEvent) { handleChange(event) if (container!) { container.addEventListener('mousemove', handleChange) container.addEventListener('mouseup', handleMouseUp) } } function handleMouseUp() { unbindEventListeners() } function unbindEventListeners() { if (container!) { container.removeEventListener('mousemove', handleChange) container.removeEventListener('mouseup', handleMouseUp) } } const styles = () => { const { hsv, hsl, shadow, radius, styles } = props return merge, Record>( { color: { position: 'absolute', inset: '0px', background: `hsl(${hsl.h},100%, 50%)`, 'border-radius': radius, }, white: { position: 'absolute', inset: '0px', 'border-radius': radius, }, black: { position: 'absolute', inset: '0px', "box-shadow": shadow, 'border-radius': radius, }, pointer: { position: 'absolute', top: `${-(hsv.v * 100) + 100}%`, left: `${hsv.s * 100}%`, cursor: 'default', }, circle: { width: '4px', height: '4px', 'box-shadow': `0 0 0 1.5px #fff, inset 0 0 1px 1px rgba(0,0,0,.3), 0 0 1px 2px rgba(0,0,0,.4)`, 'border-radius': '50%', cursor: 'hand', transform: 'translate(-2px, -2px)', }, }, { saturation: props.styles || {}, } ) } return (
{props.pointer ? props.pointer :
}
) }