@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
JavaScript
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 })] }));
});