mirror of
https://github.com/urbit/shrub.git
synced 2024-12-25 04:52:06 +03:00
parent
ea9cef905a
commit
0e1f365bf5
@ -241,11 +241,13 @@ export function uxToHex(ux: string) {
|
|||||||
|
|
||||||
export const hexToUx = (hex) => {
|
export const hexToUx = (hex) => {
|
||||||
const ux = f.flow(
|
const ux = f.flow(
|
||||||
|
f.reverse,
|
||||||
f.chunk(4),
|
f.chunk(4),
|
||||||
// eslint-disable-next-line prefer-arrow-callback
|
// eslint-disable-next-line prefer-arrow-callback
|
||||||
f.map(x => _.dropWhile(x, function(y: unknown) {
|
f.map(x => _.dropWhile(x, function(y: unknown) {
|
||||||
return y === 0;
|
return y === '0';
|
||||||
}).join('')),
|
}).reverse().join('')),
|
||||||
|
f.reverse,
|
||||||
f.join('.')
|
f.join('.')
|
||||||
)(hex.split(''));
|
)(hex.split(''));
|
||||||
return `0x${ux}`;
|
return `0x${ux}`;
|
||||||
|
@ -7,8 +7,9 @@ import {
|
|||||||
StatelessTextInput as Input
|
StatelessTextInput as Input
|
||||||
} from '@tlon/indigo-react';
|
} from '@tlon/indigo-react';
|
||||||
import { useField } from 'formik';
|
import { useField } from 'formik';
|
||||||
import React, { FormEvent } from 'react';
|
import React, { FormEvent, useState, useEffect } from 'react';
|
||||||
import { hexToUx } from '~/logic/lib/util';
|
import { hexToUx } from '~/logic/lib/util';
|
||||||
|
import { uxToHex } from '@urbit/api/dist';
|
||||||
|
|
||||||
export type ColorInputProps = Parameters<typeof Col>[0] & {
|
export type ColorInputProps = Parameters<typeof Col>[0] & {
|
||||||
id: string;
|
id: string;
|
||||||
@ -17,24 +18,40 @@ export type ColorInputProps = Parameters<typeof Col>[0] & {
|
|||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const COLOR_REGEX = /^(\d|[a-f]|[A-F]){6}$/;
|
||||||
|
|
||||||
|
function padHex(hex: string) {
|
||||||
|
if(hex.length === 0) {
|
||||||
|
return '000000';
|
||||||
|
}
|
||||||
|
const repeat = 6 / hex.length;
|
||||||
|
if(Math.floor(repeat) === repeat) {
|
||||||
|
return hex.repeat(repeat);
|
||||||
|
}
|
||||||
|
if(hex.length < 6) {
|
||||||
|
return hex.slice(0,3).repeat(2);
|
||||||
|
}
|
||||||
|
return hex.slice(0,6);
|
||||||
|
}
|
||||||
|
|
||||||
export function ColorInput(props: ColorInputProps) {
|
export function ColorInput(props: ColorInputProps) {
|
||||||
const { id, placeholder, label, caption, disabled, ...rest } = props;
|
const { id, placeholder, label, caption, disabled, ...rest } = props;
|
||||||
const [{ value, onBlur }, meta, { setValue }] = useField(id);
|
const [{ value, onBlur }, meta, { setValue, setTouched }] = useField(id);
|
||||||
|
const [field, setField] = useState('');
|
||||||
|
// const [error, setError] = useState<string | undefined>();
|
||||||
|
|
||||||
const hex = value.replace('#', '').replace('0x', '').replace('.', '');
|
useEffect(() => {
|
||||||
const padded = hex.padStart(6, '0');
|
const newValue = hexToUx(padHex(field));
|
||||||
|
setValue(newValue);
|
||||||
|
setTouched(true);
|
||||||
|
}, [field]);
|
||||||
|
|
||||||
const onChange = (e: FormEvent<HTMLInputElement>) => {
|
const onChange = (e: FormEvent<HTMLInputElement>) => {
|
||||||
let { value: newValue } = e.target as HTMLInputElement;
|
const { value: newValue } = e.target as HTMLInputElement;
|
||||||
newValue = newValue.replace('#', '');
|
setField(newValue);
|
||||||
const valid = newValue.match(/^(\d|[a-f]|[A-F]){0,6}$/);
|
|
||||||
|
|
||||||
if (!valid) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const result = hexToUx(newValue);
|
|
||||||
setValue(result);
|
|
||||||
};
|
};
|
||||||
|
const isValid = value.match(COLOR_REGEX);
|
||||||
|
const hex = uxToHex(value);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box display='flex' flexDirection='column' {...rest}>
|
<Box display='flex' flexDirection='column' {...rest}>
|
||||||
@ -51,7 +68,7 @@ export function ColorInput(props: ColorInputProps) {
|
|||||||
borderBottomRightRadius={0}
|
borderBottomRightRadius={0}
|
||||||
onBlur={onBlur}
|
onBlur={onBlur}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
value={hex}
|
value={field}
|
||||||
disabled={disabled || false}
|
disabled={disabled || false}
|
||||||
borderRight={0}
|
borderRight={0}
|
||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
@ -64,14 +81,12 @@ export function ColorInput(props: ColorInputProps) {
|
|||||||
borderColor='lightGray'
|
borderColor='lightGray'
|
||||||
width='32px'
|
width='32px'
|
||||||
alignSelf='stretch'
|
alignSelf='stretch'
|
||||||
bg={`#${padded}`}
|
bg={isValid ? `#${hex}` : 'transparent'}
|
||||||
>
|
>
|
||||||
<Input
|
<Input
|
||||||
width='100%'
|
width='100%'
|
||||||
height='100%'
|
height='100%'
|
||||||
alignSelf='stretch'
|
alignSelf='stretch'
|
||||||
onChange={onChange}
|
|
||||||
value={padded}
|
|
||||||
disabled={disabled || false}
|
disabled={disabled || false}
|
||||||
type='color'
|
type='color'
|
||||||
opacity={0}
|
opacity={0}
|
||||||
|
Loading…
Reference in New Issue
Block a user