UNPKG

@syncfusion/react-inputs

Version:

Syncfusion React Input package is a feature-rich collection of UI components, including Textbox, Textarea, Numeric-textbox and Form, designed to capture user input in React applications.

107 lines (106 loc) 5.34 kB
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import { useState, useCallback, useEffect, forwardRef, useImperativeHandle, useRef, useId } from 'react'; import { preRender, useProviderContext, Variant, Size } from '@syncfusion/react-base'; import { CLASS_NAMES, InputBase, renderClearButton, renderFloatLabelElement } from '../common/inputbase'; export { Variant, Size }; /** * Specifies the available color schemes for the component. * * @enum {string} */ export var Color; (function (Color) { /** Success color scheme (typically green) for positive actions or status */ Color["Success"] = "Success"; /** Warning color scheme (typically yellow/amber) for cautionary actions or status */ Color["Warning"] = "Warning"; /** Error color scheme (typically red) for negative actions or status */ Color["Error"] = "Error"; })(Color || (Color = {})); /** * TextBox component that provides a standard text input with extended functionality. * Supports both controlled and uncontrolled modes based on presence of value or defaultValue prop. * * ```typescript * import { TextBox } from "@syncfusion/react-inputs"; * * <TextBox defaultValue="Initial text" placeholder="Enter text" /> * ``` */ export const TextBox = forwardRef((props, ref) => { const { disabled = false, onChange, onBlur, onFocus, clearButton = false, labelMode = 'Never', className = '', id, readOnly = false, value, defaultValue, width, placeholder = '', variant, size = Size.Medium, color, prefix, suffix, ...rest } = props; const stableIdRef = useRef(id || `default_${useId()}`); const stableId = stableIdRef.current; const isControlled = value !== undefined; const [inputValue, setValue] = useState(isControlled ? value : (defaultValue || '')); const [isFocused, setIsFocused] = useState(false); const inputRef = useRef(null); const { locale, dir } = useProviderContext(); const publicAPI = { clearButton, labelMode, disabled, readOnly, variant, size, color, value }; const getContainerClassNames = () => { return classNames(CLASS_NAMES.INPUTGROUP, CLASS_NAMES.WRAPPER, labelMode !== 'Never' ? CLASS_NAMES.FLOATINPUT : '', className, (dir === 'rtl') ? CLASS_NAMES.RTL : '', disabled ? CLASS_NAMES.DISABLE : '', isFocused ? CLASS_NAMES.TEXTBOX_FOCUS : '', ((inputValue) !== '') ? CLASS_NAMES.VALIDINPUT : '', variant && variant.toLowerCase() !== 'standard' ? variant.toLowerCase() === 'outlined' ? 'sf-outline' : `sf-${variant.toLowerCase()}` : '', size && size.toLowerCase() !== 'small' ? `sf-${size.toLowerCase()}` : '', color ? `sf-${color.toLowerCase()}` : '', prefix ? 'sf-has-prefix' : '', 'sf-control'); }; const classNames = (...classes) => { return classes.filter(Boolean).join(' '); }; const containerClassNames = getContainerClassNames(); useEffect(() => { preRender('textbox'); }, []); useEffect(() => { if (isControlled) { setValue(value || ''); } }, [value, isControlled]); useImperativeHandle(ref, () => ({ ...publicAPI, element: inputRef.current })); const updateValue = useCallback((newValue, event) => { if (!isControlled) { setValue(newValue); } if (onChange) { onChange({ event: event, value: newValue }); } }, [onChange, isControlled]); const changeHandler = useCallback((event) => { const newValue = event.target.value; updateValue(newValue, event); }, [updateValue]); const handleFocus = useCallback((event) => { setIsFocused(true); if (onFocus) { onFocus(event); } }, [onFocus]); const clearInput = useCallback(() => { const newValue = ''; if (!isControlled) { setValue(newValue); if (inputRef.current) { inputRef.current.value = newValue; } } if (onChange) { onChange({ value: newValue, event: undefined }); } }, [isControlled, onChange]); const handleBlur = useCallback((event) => { setIsFocused(false); if (onBlur) { onBlur(event); } }, [onBlur]); const displayValue = isControlled ? value : inputValue; return (_jsxs("div", { className: containerClassNames, style: { width: width || '100%' }, children: [prefix && _jsx("span", { className: 'sf-input-icon sf-no-hover', children: prefix }), _jsx(InputBase, { id: stableId, floatLabelType: labelMode, ref: inputRef, ...rest, readOnly: readOnly, value: isControlled ? (displayValue) : undefined, defaultValue: !isControlled ? (inputValue || '') : undefined, disabled: disabled, placeholder: labelMode === 'Never' ? placeholder : undefined, className: 'sf-textbox sf-lib sf-ellipsis', onChange: changeHandler, "aria-label": labelMode === 'Never' ? 'textbox' : undefined, onFocus: handleFocus, onBlur: handleBlur }), renderFloatLabelElement(labelMode || 'Never', isFocused || (displayValue) !== '', displayValue, placeholder, stableId), clearButton && renderClearButton((isFocused ? displayValue : ''), clearInput, clearButton, 'textbox', locale), suffix && _jsx("span", { className: 'sf-input-icon sf-no-hover', children: suffix })] })); });