import { InputText } from 'exchange-elements/v2';
import { ChangeEvent, useEffect, useRef, useState } from 'react';
import styles from './index.module.scss';
interface ColorFieldProps {
label: string;
value: string;
onValueChange: (value: string) => void;
}
function normalizeHex(value: string): string {
const next = value.trim();
if (!next) {
return '#000000';
}
const withHash = next.startsWith('#') ? next : `#${next}`;
if (/^#[0-9A-Fa-f]{6}$/.test(withHash)) {
return withHash.toLowerCase();
}
return '#000000';
}
function isValidHex(value: string): boolean {
const withHash = value.startsWith('#') ? value : `#${value}`;
return /^#[0-9A-Fa-f]{6}$/.test(withHash);
}
export const ColorField = ({ label, value, onValueChange }: ColorFieldProps) => {
const colorInputRef = useRef<HTMLInputElement | null>(null);
const [draft, setDraft] = useState(normalizeHex(value));
useEffect(() => {
setDraft(normalizeHex(value));
}, [value]);
const handleBlur = () => {
if (!isValidHex(draft)) {
setDraft(normalizeHex(value));
return;
}
const next = normalizeHex(draft);
setDraft(next);
onValueChange(next);
};
return (
<div className={styles.inputWrapper}>
<InputText
value={draft}
label={label}
labelPos="top"
size="sm"
onChange={(event: ChangeEvent<HTMLInputElement>) => {
setDraft(event.target.value);
}}
onBlur={handleBlur}
/>
<button
type="button"
className={styles.button_color}
style={{ backgroundColor: normalizeHex(value) }}
onClick={() => colorInputRef.current?.click()}
/>
<input
ref={colorInputRef}
type="color"
className={styles.input_hidden}
value={normalizeHex(value)}
onChange={(event) => {
setDraft(event.target.value);
onValueChange(event.target.value);
}}
tabIndex={-1}
/>
</div>
);
};
[data-theme='mxt'],
[data-theme='mb'][data-mode='light'] {
--dd-item-text-selected: var(--neutral-2);
--dd-item-bg-selected: var(--neutral-12);
}
[data-theme='tr'],
[data-theme='mb'][data-mode='dark'] {
--dd-item-text-selected: var(--neutral-13);
--dd-item-bg-selected: var(--neutral-5);
}
.input {
color: var(--neutral-12);
input {
color: var(--neutral-12);
}
}
.dropdown {
li {
&[aria-selected='true'] {
background-color: var(--dd-item-bg-selected);
div[aria-label='Label'] {
color: var(--dd-item-text-selected);
}
}
svg {
color: transparent;
}
}
}
.inputWrapper {
position: relative;
&:focus-within {
background-color: transparent !important;
}
div {
background-color: transparent;
&:focus-within {
background-color: transparent !important;
}
.input {
background-color: transparent;
}
}
}
.button_color {
position: absolute;
bottom: var(--space-0375);
right: var(--space-0500);
width: var(--space-1250);
height: var(--space-1250);
border-radius: var(--space-0125);
cursor: pointer;
}
.input_hidden {
position: absolute;
bottom: 0;
right: var(--space-0500);
opacity: 0;
pointer-events: none;
}