简体   繁体   English

在 React JS 中使用 `rgb-hex` 库作为输入时,将十六进制 3 位转换为 6 位?

[英]Making hex 3-digit converts it to 6-digits while using `rgb-hex` library as an input in React JS?

I am using react-colorful & using it's <HexColorInput /> component as:我正在使用react-colorful并使用它的<HexColorInput />组件作为:

<HexColorInput
    className="w-12 text-blue-gray-500"
    color={rgb2hex(selectedColor.rgba)}
    onChange={(hex: string) => {
        updateBackground({
            selectedColor: {
                ...selectedColor,
                rgba: hex2rgb(hex),
            },
        })
    }}
/>

The color prop acts similar to value prop on input . color道具的作用类似于input上的value道具。 And onChange handler changes as you type in an input.当您输入输入时, onChange处理程序会发生变化。

The problem right now is when I make the hex input to be 3-digits, it automatically converts it to 6-digits as I'm directly using rgb2hex function on the input.现在的问题是当我将十六进制输入设为 3 位时,它会自动将其转换为 6 位,因为我直接在输入上使用rgb2hex function。

How do I fix this?我该如何解决?

Codesandbox → https://codesandbox.io/s/react-colorful-sketch-picker-ouz5t Codesandbox → https://codesandbox.io/s/react-colorful-sketch-picker-ouz5t

The common way to declare a hex color is using 6 digits.声明十六进制颜色的常用方法是使用 6 位数字。 When using the 3 digits format, you are shortening the 6 digits format.使用 3 位格式时,您正在缩短 6 位格式。 This only works if the digits in the positions R (so 1,2), G (3,4) and B(5,6) are equals.这仅适用于 R(所以 1,2)、G(3,4)和 B(5,6)位置中的数字相等的情况。

Eg: You can write #00CCFF in 3 digits format as #0CF , but you cannot do the same on #425416例如:您可以将#00CCFF以 3 位格式写为#0CF ,但您不能在#425416上执行相同的操作

Maybe this thread can make my point more clear.也许这个线程可以让我的观点更清楚。

I just had to check if hex.length is equal to 4 & if it is, then I return :我只需要检查hex.length是否等于4 ,如果是,则return

<HexColorInput
  className="w-12 text-blue-gray-500"
  color={rgb2hex(selectedColor.rgba)}
  onChange={(hex: string) => {
    if (hex.length === 4) return
    updateBackground({
      selectedColor: {
        ...selectedColor,
        rgba: hex2rgb(hex),
      },
    })
  }}
/>

The source of HexColorInput specifically adds # to it so for any 3-digit hex, it makes it a 4-digit. HexColorInput的源特别添加了# ,因此对于任何 3 位十六进制,它使其成为 4 位。

Edit:编辑:

The above answer doesn't return to previous value if I blur when HexColorInput contains 3 digit value like #21b so I cloned HexColorInput & removed a validation from it that also supported 3 digit hex.如果当HexColorInput包含 3 位值(如#21b )时模糊,上述答案不会返回到以前的值,因此我克隆HexColorInput并从中删除了一个也支持 3 位十六进制的验证。

My new HexInput.tsx looks like:我的新HexInput.tsx看起来像:

import React from 'react'

import { useEventCallback } from '../hooks'

const hex6 = /^#?[0-9A-F]{6}$/i
const validHex = (color: string): boolean => hex6.test(color)

// Escapes all non-hexadecimal characters including "#"
const escapeNonHex = (hex: string) => hex.replace(/([^0-9A-F]+)/gi, '').substr(0, 6)

type ComponentProps = {
    hex: string
    onChange: (newColor: string) => void
}

type InputProps = Omit<React.InputHTMLAttributes<HTMLInputElement>, 'onChange' | 'value'>

export const HexInput = ({
    hex = '',
    onChange,
    onBlur,
    ...rest
}: Partial<InputProps & ComponentProps>) => {
    const [value, setValue] = React.useState(() => escapeNonHex(hex))
    const onChangeCallback = useEventCallback<string>(onChange)
    const onBlurCallback = useEventCallback<React.FocusEvent<HTMLInputElement>>(onBlur)

    // Trigger `onChange` handler only if the input value is a valid HEX-color
    const handleChange = React.useCallback(
        (e: React.ChangeEvent<HTMLInputElement>) => {
            const inputValue = escapeNonHex(e.target.value)
            setValue(inputValue)
            if (validHex(inputValue)) onChangeCallback('#' + inputValue)
        },
        [onChangeCallback]
    )

    // Take the color from props if the last typed color (in local state) is not valid
    const handleBlur = React.useCallback(
        (e: React.FocusEvent<HTMLInputElement>) => {
            if (!validHex(e.target.value)) setValue(escapeNonHex(hex))
            onBlurCallback(e)
        },
        [hex, onBlurCallback]
    )

    // Update the local state when `color` property value is changed
    React.useEffect(() => {
        setValue(escapeNonHex(hex))
    }, [hex])

    return (
        <input
            {...rest}
            value={value}
            spellCheck="false" // the element should not be checked for spelling errors
            onChange={handleChange}
            onBlur={handleBlur}
        />
    )
}

Here's the complete example with a demo → https://codesandbox.io/s/react-colorful-sketch-picker-ouz5t?file=/src/HexRgbaBox/HexInput.tsx这是带有演示的完整示例 → https://codesandbox.io/s/react-colorful-sketch-picker-ouz5t?file=/src/HexRgbaBox/HexInput.tsx

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM