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 | import React, { FC, useCallback, useEffect, useRef, useState } from "react"; import styled from "styled-components"; import { StyledInput as StyledInputDefault } from "./style"; export interface CoordinateInputProps { coordinate: "x" | "y" | "w" | "h"; name: string; value?: number; min?: number; max?: number; step?: number; placeholder?: string; disabled?: boolean; onChange?: (e: React.ChangeEvent<HTMLInputElement>) => void; } const Wrapper = styled.div` position: relative; width: 100%; `; const StyledInput = styled(StyledInputDefault)` padding-left: 32px; `; const Label = styled.label` position: absolute; top: 1px; left: 0px; bottom: 1px; width: 27px; display: flex; align-items: center; justify-content: center; text-align: center; font-weight: bold; font-size: 11px; color: #999; text-transform: uppercase; border-right: 1px solid ${(props) => props.theme.colors.input.border}; `; const valueToString = (value: unknown) => value !== undefined && value !== null ? String(value) : ""; export const CoordinateInput: FC<CoordinateInputProps> = ({ name, coordinate = "x", value, min, max, step, placeholder, disabled, onChange, }) => { const inputRef = useRef<HTMLInputElement>(null); const [stringValue, setStringValue] = useState(valueToString(value)); const onChangeInternal = useCallback( (e: React.ChangeEvent<HTMLInputElement>) => { const newStringValue = e.currentTarget.value; setStringValue(newStringValue); onChange?.(e); }, [onChange] ); const onBlurInternal = useCallback(() => { setStringValue(valueToString(value)); }, [value]); useEffect(() => { Iif (document.activeElement !== inputRef.current) { setStringValue(valueToString(value)); } }, [value]); return ( <Wrapper> <StyledInput ref={inputRef} id={name} name={name} type="number" value={stringValue} min={min} max={max} step={step} placeholder={placeholder} disabled={disabled} onChange={onChangeInternal} onBlur={onBlurInternal} /> <Label htmlFor={name}>{coordinate}</Label> </Wrapper> ); }; |