// Copyright 2024, Command Line Inc. // SPDX-License-Identifier: Apache-2.0 import clsx from "clsx"; import React, { forwardRef, memo, useImperativeHandle, useRef, useState } from "react"; import "./input.less"; interface InputGroupProps { children: React.ReactNode; className?: string; } const InputGroup = memo( forwardRef(({ children, className }: InputGroupProps, ref) => { const [isFocused, setIsFocused] = useState(false); const manageFocus = (focused: boolean) => { setIsFocused(focused); }; return (
{React.Children.map(children, (child) => { if (React.isValidElement(child)) { return React.cloneElement(child as any, { manageFocus }); } return child; })}
); }) ); interface InputLeftElementProps { children: React.ReactNode; className?: string; } const InputLeftElement = memo(({ children, className }: InputLeftElementProps) => { return
{children}
; }); interface InputRightElementProps { children: React.ReactNode; className?: string; } const InputRightElement = memo(({ children, className }: InputRightElementProps) => { return
{children}
; }); interface InputProps { value?: string; className?: string; onChange?: (value: string) => void; onKeyDown?: (event: React.KeyboardEvent) => void; onFocus?: () => void; onBlur?: () => void; placeholder?: string; defaultValue?: string; required?: boolean; maxLength?: number; autoFocus?: boolean; disabled?: boolean; isNumber?: boolean; inputRef?: React.MutableRefObject; manageFocus?: (isFocused: boolean) => void; } const Input = memo( forwardRef( ( { value, className, onChange, onKeyDown, onFocus, onBlur, placeholder, defaultValue = "", required, maxLength, autoFocus, disabled, isNumber, manageFocus, }: InputProps, ref ) => { const [internalValue, setInternalValue] = useState(defaultValue); const inputRef = useRef(null); useImperativeHandle(ref, () => inputRef.current as HTMLInputElement); const handleInputChange = (e: React.ChangeEvent) => { const inputValue = e.target.value; if (isNumber && inputValue !== "" && !/^\d*$/.test(inputValue)) { return; } if (value === undefined) { setInternalValue(inputValue); } onChange && onChange(inputValue); }; const handleFocus = () => { manageFocus?.(true); onFocus?.(); }; const handleBlur = () => { manageFocus?.(false); onBlur?.(); }; const inputValue = value ?? internalValue; return ( ); } ) ); export { Input, InputGroup, InputLeftElement, InputRightElement }; export type { InputGroupProps, InputLeftElementProps, InputProps, InputRightElementProps };