@xsolla/xui-input
v0.106.0
Published
A cross-platform React input component with label, error states, icons, clear button, and validation support. Works on both React (web) and React Native.
Downloads
11,006
Readme
Input
A cross-platform React input component with label, error states, icons, clear button, and validation support. Works on both React (web) and React Native.
Installation
npm install @xsolla/xui-input
# or
yarn add @xsolla/xui-inputPrerequisites
Important: Input requires XUIProvider from @xsolla/xui-core to be wrapped around your app for proper theming.
If your input appears white or washed out on a light background, you need to set the theme mode:
import { XUIProvider } from '@xsolla/xui-core';
// For light/white page backgrounds
<XUIProvider initialMode="light">
<YourApp />
</XUIProvider>
// For dark page backgrounds (default)
<XUIProvider initialMode="dark">
<YourApp />
</XUIProvider>See Quick Start for more details.
Demo
Basic Input
import * as React from 'react';
import { Input } from '@xsolla/xui-input';
export default function BasicInput() {
const [value, setValue] = React.useState('');
return (
<Input
value={value}
onChangeText={setValue}
placeholder="Enter text"
/>
);
}Input with Label
import * as React from 'react';
import { Input } from '@xsolla/xui-input';
export default function LabeledInput() {
const [email, setEmail] = React.useState('');
return (
<Input
label="Email Address"
value={email}
onChangeText={setEmail}
placeholder="[email protected]"
/>
);
}Input Sizes
import * as React from 'react';
import { Input } from '@xsolla/xui-input';
export default function InputSizes() {
return (
<div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
<Input size="xs" placeholder="Extra Small" />
<Input size="sm" placeholder="Small" />
<Input size="md" placeholder="Medium (default)" />
<Input size="lg" placeholder="Large" />
<Input size="xl" placeholder="Extra Large" />
</div>
);
}Input with Icons
import * as React from 'react';
import { Input } from '@xsolla/xui-input';
import { Search, Check } from '@xsolla/xui-icons';
import { Calendar, Mail } from '@xsolla/xui-icons-base';
export default function InputWithIcons() {
return (
<div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
<Input
iconLeft={<Search />}
placeholder="Search..."
/>
<Input
iconRight={<Calendar />}
placeholder="Select date"
/>
<Input
iconLeft={<Mail />}
iconRight={<Check />}
placeholder="Email"
/>
</div>
);
}Input with Clear Button
import * as React from 'react';
import { Input } from '@xsolla/xui-input';
export default function ClearableInput() {
const [value, setValue] = React.useState('Some text');
return (
<Input
value={value}
onChangeText={setValue}
extraClear
onRemove={() => setValue('')}
placeholder="Type something..."
/>
);
}Input with Validation
import * as React from 'react';
import { Input } from '@xsolla/xui-input';
export default function ValidatedInput() {
const [email, setEmail] = React.useState('');
const [error, setError] = React.useState('');
const validateEmail = (value: string) => {
setEmail(value);
if (value && !value.includes('@')) {
setError('Please enter a valid email address');
} else {
setError('');
}
};
return (
<Input
label="Email"
value={email}
onChangeText={validateEmail}
error={!!error}
errorMessage={error}
placeholder="[email protected]"
/>
);
}Anatomy
Import the component and use it directly:
import { Input } from '@xsolla/xui-input';
<Input
label="Field Label" // Optional label above input
value={value} // Controlled value
onChangeText={setValue} // Value change handler
placeholder="Placeholder" // Placeholder text
iconLeft={<Icon />} // Optional left icon
iconRight={<Icon />} // Optional right icon
extraClear // Shows clear button when has value
error // Error state boolean
errorMessage="Error text" // Error message below input
disabled // Disabled state
/>Examples
Disabled Input
import * as React from 'react';
import { Input } from '@xsolla/xui-input';
export default function DisabledInput() {
return (
<Input
label="Disabled Field"
value="Cannot edit this"
disabled
/>
);
}Input with Success State
import * as React from 'react';
import { Input } from '@xsolla/xui-input';
export default function SuccessInput() {
return (
<Input
label="Username"
value="johndoe"
checked
placeholder="Enter username"
/>
);
}Custom Border Radius
import * as React from 'react';
import { Input } from '@xsolla/xui-input';
export default function CustomRadiusInput() {
return (
<Input
placeholder="Rounded input"
borderTopLeftRadius={20}
borderTopRightRadius={20}
borderBottomLeftRadius={20}
borderBottomRightRadius={20}
/>
);
}Search Input
import * as React from 'react';
import { Input } from '@xsolla/xui-input';
import { Search } from '@xsolla/xui-icons';
export default function SearchInput() {
const [query, setQuery] = React.useState('');
return (
<Input
value={query}
onChangeText={setQuery}
iconLeft={<Search />}
extraClear
onRemove={() => setQuery('')}
placeholder="Search..."
size="md"
/>
);
}Form with Multiple Inputs
import * as React from 'react';
import { Input } from '@xsolla/xui-input';
import { Mail } from '@xsolla/xui-icons-base';
export default function FormInputs() {
const [form, setForm] = React.useState({
firstName: '',
lastName: '',
email: '',
});
const updateField = (field: string) => (value: string) => {
setForm(prev => ({ ...prev, [field]: value }));
};
return (
<div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
<Input
label="First Name"
value={form.firstName}
onChangeText={updateField('firstName')}
placeholder="John"
/>
<Input
label="Last Name"
value={form.lastName}
onChangeText={updateField('lastName')}
placeholder="Doe"
/>
<Input
label="Email"
value={form.email}
onChangeText={updateField('email')}
iconLeft={<Mail />}
placeholder="[email protected]"
/>
</div>
);
}API Reference
Input
The main input component. Renders a semantic <input> element with wrapper styling.
Input Props:
| Prop | Type | Default | Description |
| :--- | :--- | :------ | :---------- |
| value | string | - | The controlled value of the input. |
| placeholder | string | - | Placeholder text shown when input is empty. |
| onChange | (e: ChangeEvent<HTMLInputElement>) => void | - | Native change event handler. |
| onChangeText | (text: string) => void | - | Simplified change handler receiving text value. |
| size | "xl" \| "lg" \| "md" \| "sm" \| "xs" | "md" | The size of the input. |
| disabled | boolean | false | Whether the input is disabled. |
| label | string | - | Label text displayed above the input. |
| errorMessage | string | - | Error message displayed below the input. |
| error | boolean | false | Whether to show error styling. |
| iconLeft | ReactNode | - | Icon displayed on the left side. |
| iconRight | ReactNode | - | Icon displayed on the right side. |
| extraClear | boolean | false | Whether to show clear button when input has value. |
| onRemove | () => void | - | Callback when clear button is clicked. |
| checked | boolean | false | Whether to show success/check icon. |
| checkedIcon | ReactNode | <Check /> | Custom icon for checked state. |
| iconRightSize | number \| string | - | Custom size for right icon. |
| borderTopLeftRadius | number | - | Custom top-left border radius. |
| borderTopRightRadius | number | - | Custom top-right border radius. |
| borderBottomLeftRadius | number | - | Custom bottom-left border radius. |
| borderBottomRightRadius | number | - | Custom bottom-right border radius. |
| backgroundColor | string | - | Custom background color. |
| aria-label | string | - | Accessible label for the input. |
| id | string | - | HTML id attribute (also links label). |
| testID | string | - | Test identifier for testing frameworks. |
Size Configuration:
| Size | Height | Padding (V/H) | Font Size | Icon Size | | :--- | :----- | :------------ | :-------- | :-------- | | xl | 56px | 12px / 12px | 16px | 18px | | lg | 48px | 14px / 12px | 16px | 18px | | md | 40px | 11px / 12px | 14px | 18px | | sm | 32px | 7px / 10px | 14px | 16px | | xs | 28px | 7px / 10px | 12px | 16px |
Theming
Input components use the design system theme for colors and sizing:
// Colors accessed via theme
theme.colors.control.input.bg // Background color
theme.colors.control.input.bgHover // Hover background
theme.colors.control.input.bgFocus // Focus background
theme.colors.control.input.bgDisable // Disabled background
theme.colors.control.input.border // Border color
theme.colors.control.input.borderFocus // Focus border color
theme.colors.control.input.borderError // Error border color
theme.colors.control.input.text // Text color
theme.colors.control.input.placeholder // Placeholder color
// Sizing accessed via theme
theme.sizing.input(size).height
theme.sizing.input(size).paddingVertical
theme.sizing.input(size).paddingHorizontal
theme.sizing.input(size).fontSizeAccessibility
- Uses semantic
<input>element with proper<label>association - Label is linked via
htmlForattribute - Error messages use
aria-describedbyfor screen readers - Focus indicators follow WCAG guidelines
- Disabled state properly communicated to assistive technology
- Clear button includes accessible label
