color picker clickable

This commit is contained in:
hamid zarghami
2026-05-02 12:32:41 +03:30
parent 42715e5990
commit c6d7f8e4c1
+48 -23
View File
@@ -1,7 +1,6 @@
import { type FC, type InputHTMLAttributes, useState, useRef, useEffect } from 'react'
import { clx } from '../helpers/utils'
import Error from './Error'
import ColorfilterIcon from '@/assets/icons/color.png'
type Props = {
label?: string
@@ -15,6 +14,7 @@ type Props = {
const ColorPicker: FC<Props> = (props: Props) => {
const [color, setColor] = useState<string>(props.value || '#000000')
const colorInputRef = useRef<HTMLInputElement>(null)
const pickerOpenGuardRef = useRef(false)
const inputClass = clx(
'w-full bg-white h-10 text-black block pl-10 pr-10 text-xs rounded-xl border border-border',
@@ -37,10 +37,14 @@ const ColorPicker: FC<Props> = (props: Props) => {
}
}
const handleColorIconClick = () => {
if (!props.readOnly) {
colorInputRef.current?.click()
}
const openNativeColorPicker = () => {
if (props.readOnly) return
if (pickerOpenGuardRef.current) return
pickerOpenGuardRef.current = true
colorInputRef.current?.click()
window.setTimeout(() => {
pickerOpenGuardRef.current = false
}, 400)
}
useEffect(() => {
@@ -55,32 +59,53 @@ const ColorPicker: FC<Props> = (props: Props) => {
{props.label}
</label>
<div className='w-full relative mt-1'>
<div
className={clx(
'w-full relative mt-1 rounded-xl',
!props.readOnly && 'cursor-pointer'
)}
onClick={!props.readOnly ? openNativeColorPicker : undefined}
>
<input
type='text'
value={color}
onChange={handleTextChange}
placeholder='#000000'
readOnly={props.readOnly}
className={inputClass}
title={
!props.readOnly
? 'کلیک: پالت رنگ — با Tab وارد فیلد شوید تا کد را تایپ کنید'
: undefined
}
className={`${inputClass} cursor-pointer`}
/>
<button
type='button'
onClick={handleColorIconClick}
disabled={props.readOnly}
<span
aria-hidden
className={clx(
'absolute top-0 bottom-0 my-auto left-3 cursor-pointer',
props.readOnly && 'cursor-not-allowed opacity-50'
'absolute top-0 bottom-0 my-auto left-1 flex items-center justify-center min-h-10 min-w-10 rounded-lg pointer-events-none',
props.readOnly && 'opacity-50'
)}
>
<img src={ColorfilterIcon} alt='color-filter' className='size-7' />
</button>
{/* <img
src={ColorfilterIcon}
alt=''
className='size-7 select-none'
/> */}
</span>
<div
className='absolute top-0 bottom-0 my-auto right-3 w-5 h-5 rounded-full'
style={{ backgroundColor: color }}
/>
<span
aria-hidden
className={clx(
'absolute top-0 bottom-0 my-auto right-1 flex items-center justify-center min-h-10 min-w-10 rounded-lg pointer-events-none',
props.readOnly && 'opacity-50'
)}
>
<span
className='block w-5 h-5 rounded-full border border-border shadow-sm'
style={{ backgroundColor: color }}
/>
</span>
<input
ref={colorInputRef}
@@ -89,11 +114,11 @@ const ColorPicker: FC<Props> = (props: Props) => {
onChange={handleColorChange}
className='absolute opacity-0 pointer-events-none w-0 h-0'
/>
{props.error_text && (
<Error errorText={props.error_text} />
)}
</div>
{props.error_text && (
<Error errorText={props.error_text} />
)}
</div>
)
}