color-input: fixing performance and text input

This commit is contained in:
Hunter Miller 2021-11-24 19:05:01 -06:00
parent 28cc660998
commit 6a6d2200b6

View File

@ -1,15 +1,14 @@
import {
Box, Col,
ErrorLabel, Label,
Row,
StatelessTextInput as Input
} from '@tlon/indigo-react';
import { useField } from 'formik';
import React, { FormEvent, useState, useEffect } from 'react';
import React, { useState, useEffect, ChangeEvent, useMemo } from 'react';
import { hexToUx } from '~/logic/lib/util';
import { uxToHex } from '@urbit/api/dist';
import _ from 'lodash';
export type ColorInputProps = Parameters<typeof Col>[0] & {
id: string;
@ -36,19 +35,28 @@ function padHex(hex: string) {
export function ColorInput(props: ColorInputProps) {
const { id, placeholder, label, caption, disabled, ...rest } = props;
const [{ value, onBlur }, meta, { setValue, setTouched }] = useField(id);
const [{ value }, meta, { setValue, setTouched }] = useField(id);
const [field, setField] = useState(uxToHex(value));
useEffect(() => {
const update = (value: string) => {
const normalizedValue = value.trim().replace(/[^a-f\d]/gi, '').slice(0,6);
setField(normalizedValue);
};
const onText = (e: ChangeEvent<HTMLInputElement>) => update(e.target.value);
const pickerChange = useMemo(() => _.debounce(update, 100), []);
const updateField = useMemo(() => _.debounce((field: string) => {
const newValue = hexToUx(padHex(field));
setValue(newValue);
setTouched(true);
}, 150), []);
useEffect(() => {
updateField(field);
}, [field]);
const onChange = (e: FormEvent<HTMLInputElement>) => {
const { value: newValue } = e.target as HTMLInputElement;
setField(newValue.slice(1));
};
const hex = uxToHex(value);
const isValid = COLOR_REGEX.test(hex);
@ -65,8 +73,8 @@ export function ColorInput(props: ColorInputProps) {
id={id}
borderTopRightRadius={0}
borderBottomRightRadius={0}
onBlur={onBlur}
onChange={onChange}
onBlur={onText}
onChange={onText}
value={field}
disabled={disabled || false}
borderRight={0}
@ -90,7 +98,7 @@ export function ColorInput(props: ColorInputProps) {
type='color'
opacity={0}
overflow='hidden'
onChange={onChange}
onChange={(e: ChangeEvent<HTMLInputElement>) => pickerChange(e.target.value)}
/>
</Box>
</Row>