import { Accessor, Context, createContext, createEffect, createMemo, createSignal, JSX, mergeProps, useContext, } from 'solid-js' import { ChangeColor, Color, ColorResult } from '../../types' import * as color from '../../helpers/color' import { debounce } from 'lodash-es' export interface ColorPickerContextType { colors: Accessor changeColor: (color: ChangeColor, event?: Event) => void onSwatchHover?: (color: ChangeColor, event: Event) => void } export const ColorPickerContext = createContext(undefined) export interface ColorPickerProps { children?: JSX.Element defaultColor?: Color color?: Color onChange?: (color: ColorResult, event?: Event) => void onChangeComplete?: (color: ColorResult) => void onSwatchHover?: (color: ColorResult, event: Event) => void } export function ColorPickerProvider(_props: ColorPickerProps) { const props = mergeProps({ defaultColor: { h: 250, s: 0.5, l: 0.2, a: 1 } }, _props) const [colors, setColors] = createSignal({ ...color.toState(props.color ?? props.defaultColor, 0), }) createEffect(() => { if (props.color) { setColors({ ...color.toState(props.color, 0) }) } }) const handler = (fn: any, data: any, event: any) => fn(data, event) const debouncedChangeHandler = createMemo(() => debounce(handler, 100), []) const changeColor = (newColor: ChangeColor, event?: Event) => { const isValidColor = color.simpleCheckForValidColor(newColor) if (isValidColor) { const newColors = color.toState( newColor, (typeof newColor !== 'string' && 'h' in newColor ? newColor.h : undefined) || colors().oldHue, ) setColors(newColors) props.onChangeComplete && debouncedChangeHandler()(props.onChangeComplete, newColors, event) props.onChange && props.onChange(newColors, event) } } const handleSwatchHover = (data: ChangeColor, event: Event) => { const isValidColor = color.simpleCheckForValidColor(data) if (isValidColor) { const newColors = color.toState( data, (typeof data !== 'string' && 'h' in data ? data.h : undefined) || colors().oldHue, ) props.onSwatchHover && props.onSwatchHover(newColors, event) } } const store = { colors, changeColor, onSwatchHover: props.onSwatchHover ? handleSwatchHover : undefined, } return {props.children} } export function useColorPicker() { return useContext(ColorPickerContext as Context) } export function withColorPicker(Component: (props: T) => JSX.Element) { return (props: T & Omit) => ( ) }