Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 | 3x 3x 1x 15x 15x 15x 15x 13x 4x 1x 3x 3x 1x 3x 3x 3x 3x 1x 1x 1x 15x 15x 12x 15x 1x 15x 1x 15x 15x 15x 4x 1x | import React from 'react';
import { useRef, useEffect, useState } from 'react';
const validHex = (hex: string): boolean => /^#?([A-Fa-f0-9]{3,4}){1,2}$/.test(hex);
const getNumberValue = (value: string) => Number(String(value).replace(/%/g, ''));
export interface EditableInputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'onChange'> {
prefixCls?: string;
value?: string | number;
label?: React.ReactNode;
labelStyle?: React.CSSProperties;
placement?: 'top' | 'left' | 'bottom' | 'right';
inputStyle?: React.CSSProperties;
onChange?: (evn: React.ChangeEvent<HTMLInputElement>, value: string | number) => void;
}
const EditableInput = React.forwardRef<HTMLInputElement, EditableInputProps>((props, ref) => {
const {
prefixCls = 'w-color-editable-input',
placement = 'bottom',
label,
value: initValue,
className,
style,
labelStyle,
inputStyle,
onChange,
onBlur,
...other
} = props;
const [value, setValue] = useState<string | number | undefined>(initValue);
const isFocus = useRef(false);
useEffect(() => {
if (props.value !== value) {
if (!isFocus.current) {
setValue(props.value);
}
}
}, [props.value]);
function handleChange(evn: React.FocusEvent<HTMLInputElement>, valInit?: string) {
const value = (valInit || evn.target.value).trim().replace(/^#/, '');
if (validHex(value)) {
onChange && onChange(evn, value);
}
const val = getNumberValue(value);
Eif (!isNaN(val)) {
onChange && onChange(evn, val);
}
setValue(value);
}
function handleBlur(evn: React.FocusEvent<HTMLInputElement>) {
isFocus.current = false;
setValue(props.value);
onBlur && onBlur(evn);
}
const placementStyle: React.CSSProperties = {};
if (placement === 'bottom') {
placementStyle['flexDirection'] = 'column';
}
if (placement === 'top') {
placementStyle['flexDirection'] = 'column-reverse';
}
if (placement === 'left') {
placementStyle['flexDirection'] = 'row-reverse';
}
const wrapperStyle = {
'--editable-input-label-color': 'rgb(153, 153, 153)',
'--editable-input-box-shadow': 'rgb(204 204 204) 0px 0px 0px 1px inset',
'--editable-input-color': '#666',
position: 'relative',
alignItems: 'center',
display: 'flex',
fontSize: 11,
...placementStyle,
...style,
} as React.CSSProperties;
const editableStyle = {
width: '100%',
paddingTop: 2,
paddingBottom: 2,
paddingLeft: 3,
paddingRight: 3,
fontSize: 11,
background: 'transparent',
boxSizing: 'border-box',
border: 'none',
color: 'var(--editable-input-color)',
boxShadow: 'var(--editable-input-box-shadow)',
...inputStyle,
} as React.CSSProperties;
return (
<div className={[prefixCls, className || ''].filter(Boolean).join(' ')} style={wrapperStyle}>
<input
ref={ref}
value={value}
onChange={handleChange}
onBlur={handleBlur}
autoComplete="off"
onFocus={() => (isFocus.current = true)}
{...other}
style={editableStyle}
/>
{label && (
<span
style={{
color: 'var(--editable-input-label-color)',
textTransform: 'capitalize',
...labelStyle,
}}
children={label}
/>
)}
</div>
);
});
EditableInput.displayName = 'EditableInput';
export default EditableInput;
|