Skip to content

Commit

Permalink
color picker hue slider fix
Browse files Browse the repository at this point in the history
  • Loading branch information
funwithtriangles committed Jan 3, 2025
1 parent 3a62eea commit 7e6eb6d
Showing 1 changed file with 31 additions and 10 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,21 @@
import { forwardRef, useCallback, useEffect, useImperativeHandle, useRef, useState } from 'react'
import { Colorful, ColorResult, rgbaToHex } from '@uiw/react-color'
import {
forwardRef,
useCallback,
useEffect,
useImperativeHandle,
useMemo,
useRef,
useState,
} from 'react'
import {
Colorful,
ColorResult,
hexToHsva,
HsvaColor,
hsvaToHex,
rgbaToHex,
rgbaToHsva,
} from '@uiw/react-color'
import { useFloating, shift, offset } from '@floating-ui/react-dom'
import css from './ColorPicker.module.css'

Expand All @@ -13,13 +29,15 @@ interface ColorPickerProps {
onValueChange: (value: RGBColor) => void
}

const defaultColor: HsvaColor = hexToHsva('#FFFFFF')

export const ColorPicker = forwardRef<ColorPickerHandle, ColorPickerProps>(function ColorPicker(
{ onValueChange },
ref,
) {
const colorBoxRef = useRef<HTMLDivElement>(null)
const [color, setColor] = useState('#ffffff')
const colorRef = useRef('#ffffff')
const [color, setColor] = useState<HsvaColor>(defaultColor)
const colorRef = useRef<HsvaColor>(defaultColor)
const [isOpen, setIsOpen] = useState(false)
const { refs, floatingStyles } = useFloating({
middleware: [shift({ padding: 10 }), offset({ mainAxis: 10 })],
Expand All @@ -35,8 +53,8 @@ export const ColorPicker = forwardRef<ColorPickerHandle, ColorPickerProps>(funct
}, [])

const onChange = useCallback(
({ rgb: { r, g, b }, hex }: ColorResult) => {
setColor(hex)
({ rgb: { r, g, b }, hsva }: ColorResult) => {
setColor(hsva)
onValueChange([r / 255, g / 255, b / 255])
},
[onValueChange],
Expand All @@ -56,18 +74,21 @@ export const ColorPicker = forwardRef<ColorPickerHandle, ColorPickerProps>(funct

// Avoiding using state to keep external frequent updates performant
const updateColor = useCallback(([r, g, b]: RGBColor) => {
const hex = rgbaToHex({ r: r * 255, g: g * 255, b: b * 255, a: 1 })
colorBoxRef.current?.style.setProperty('background-color', hex)
colorRef.current = hex
const rgba = { r: r * 255, g: g * 255, b: b * 255, a: 1 }
const hsva = rgbaToHsva(rgba)
colorBoxRef.current?.style.setProperty('background-color', rgbaToHex(rgba))
colorRef.current = hsva
}, [])

useImperativeHandle(ref, () => ({ updateColor }), [updateColor])

const backgroundColor = useMemo(() => hsvaToHex(color), [color])

return (
<div className={css.container} ref={refs.setReference}>
<div
className={css.colorBox}
style={{ backgroundColor: color }}
style={{ backgroundColor }}
onClick={onBoxClick}
ref={colorBoxRef}
/>
Expand Down

0 comments on commit 7e6eb6d

Please sign in to comment.