Files
bruno/packages/bruno-app/src/ui/TextInput/index.js
Abhishek S Lal 260c9e1f4c refactor: replace old Checkbox component and Added new TextInput, MaskedInput, and Select components (#7755)
* refactor: replace old Checkbox component and Added new TextInput, MaskedInput, and Select components

- Deleted the old Checkbox and StyledWrapper components from the components directory.
- Introduced a new Checkbox component with enhanced features including indeterminate state and customizable icons.
- Added a new StyledWrapper for the Checkbox to manage styles and layout.
- Created InputWrapper and StyledWrapper components for consistent form field handling.
- Added new TextInput, MaskedInput, and Select components with their respective styles for improved UI consistency.

* refactor: enhance Checkbox, InputWrapper, and Select components with accessibility improvements

- Added useId for unique ID generation in Checkbox and Select components, improving accessibility.
- Updated Checkbox to use generated IDs for aria attributes and labels.
- Refactored InputWrapper to accept and apply generated IDs for label, description, and error elements.
- Modified Select component to include aria attributes for better screen reader support.
- Adjusted StyledWrapper imports to reference constants for consistent styling across components.
2026-05-18 17:05:59 +05:30

109 lines
3.3 KiB
JavaScript

import React, { useState } from 'react';
import InputWrapper from 'ui/InputWrapper';
import StyledWrapper from './StyledWrapper';
/**
* TextInput - A form text input component
*
* @param {string} props.value - Controlled input value
* @param {function} props.onChange - Called with the input change event
* @param {string} props.id - Input id attribute
* @param {string} props.name - Input name attribute (defaults to id)
* @param {string} props.type - Input type: 'text' | 'number' | 'email' | 'url' (default: 'text')
* @param {string} props.placeholder - Placeholder text
* @param {boolean} props.disabled - Disables the input
* @param {string} props.error - Error message displayed below the input
* @param {string} props.label - Label text displayed above the input
* @param {string} props.description - Description text below the label
* @param {boolean} props.required - Shows asterisk on label
* @param {ReactNode} props.leftSection - Element rendered on the left side
* @param {ReactNode} props.rightSection - Element rendered on the right side
* @param {string} props.size - Input size: 'sm' | 'md' (default: 'md')
* @param {string} props.className - Additional CSS class for the wrapper
* @param {boolean} props.autoFocus - Auto-focus on mount
* @param {boolean} props.readOnly - Makes input read-only
* @param {string} props.autoComplete - HTML autoComplete attribute
* @param {number} props.maxLength - Max character length
* @param {number} props.min - Min value for type="number"
* @param {number} props.max - Max value for type="number"
* @param {number} props.step - Step value for type="number"
*/
const TextInput = ({
value,
onChange,
id,
name,
type = 'text',
placeholder,
disabled = false,
error,
label,
description,
required = false,
leftSection,
rightSection,
size = 'md',
className,
autoFocus,
readOnly,
autoComplete,
maxLength,
min,
max,
step,
'data-testid': testId
}) => {
const [isFocused, setIsFocused] = useState(false);
const wrapperClasses = [
'text-input-wrapper',
'textbox',
isFocused ? 'text-input-focused' : '',
error ? 'text-input-error' : '',
disabled ? 'text-input-disabled' : ''
]
.filter(Boolean)
.join(' ');
return (
<InputWrapper
label={label}
description={description}
error={error}
htmlFor={id}
required={required}
size={size}
className={className}
>
<StyledWrapper $size={size}>
<div className={wrapperClasses}>
{leftSection && <span className="text-input-left-section">{leftSection}</span>}
<input
id={id}
type={type}
name={name || id}
className="text-input-field"
value={value}
onChange={onChange}
placeholder={placeholder}
disabled={disabled}
data-testid={testId}
readOnly={readOnly}
autoFocus={autoFocus}
autoComplete={autoComplete}
maxLength={maxLength}
min={min}
max={max}
step={step}
onFocus={() => setIsFocused(true)}
onBlur={() => setIsFocused(false)}
/>
{rightSection && <span className="text-input-right-section">{rightSection}</span>}
</div>
</StyledWrapper>
</InputWrapper>
);
};
export default TextInput;