Input
A basic widget for getting the user input is a text field. Keyboard and mouse can be used for providing or changing data.
When To Use#
A user input in a form field is needed.
A search input is required.
Examples
import { Input } from 'infrad';
import React from 'react';
const App: React.FC = () => <Input placeholder="Basic usage" />;
export default App;
import { SettingOutlined } from 'infra-design-icons';
import { Cascader, Input, Select, Space } from 'infrad';
import React from 'react';
const { Option } = Select;
const selectBefore = (
<Select defaultValue="http://" className="select-before">
<Option value="http://">http://</Option>
<Option value="https://">https://</Option>
</Select>
);
const selectAfter = (
<Select defaultValue=".com" className="select-after">
<Option value=".com">.com</Option>
<Option value=".jp">.jp</Option>
<Option value=".cn">.cn</Option>
<Option value=".org">.org</Option>
</Select>
);
const App: React.FC = () => (
<Space direction="vertical">
<Input addonBefore="http://" addonAfter=".com" defaultValue="mysite" />
<Input addonBefore={selectBefore} addonAfter={selectAfter} defaultValue="mysite" />
<Input addonAfter={<SettingOutlined style={{ color: '#999999' }} />} defaultValue="mysite" />
<Input addonBefore="http://" suffix=".com" defaultValue="mysite" />
<Input
addonBefore={<Cascader placeholder="cascader" style={{ width: 150 }} />}
defaultValue="mysite"
/>
</Space>
);
export default App;
.select-before {
width: 90px;
}
.select-after {
width: 80px;
}
[data-theme='compact'] .select-before {
width: 71px;
}
[data-theme='compact'] .select-after {
width: 65px;
}
import { AudioOutlined } from 'infra-design-icons';
import { Input, Space } from 'infrad';
import React from 'react';
const { Search } = Input;
const suffix = (
<AudioOutlined
style={{
fontSize: 16,
color: '#2673dd',
}}
/>
);
const onSearch = (value: string) => console.log(value);
const App: React.FC = () => (
<Space direction="vertical">
<Search placeholder="input search text" onSearch={onSearch} style={{ width: 200 }} />
<Search placeholder="input search text" allowClear onSearch={onSearch} style={{ width: 200 }} />
<Search
addonBefore="https://"
placeholder="input search text"
allowClear
onSearch={onSearch}
style={{ width: 304 }}
/>
<Search placeholder="input search text" onSearch={onSearch} enterButton />
<Search
placeholder="input search text"
allowClear
enterButton="Search"
size="large"
onSearch={onSearch}
/>
<Search
placeholder="input search text"
enterButton="Search"
size="large"
suffix={suffix}
onSearch={onSearch}
/>
</Space>
);
export default App;
import { Input } from 'infrad';
import React from 'react';
const { TextArea } = Input;
const App: React.FC = () => (
<>
<TextArea rows={4} />
<br />
<br />
<TextArea rows={4} placeholder="maxLength is 6" maxLength={6} />
</>
);
export default App;
import { Input, Tooltip } from 'infrad';
import React, { useState } from 'react';
interface NumericInputProps {
style: React.CSSProperties;
value: string;
onChange: (value: string) => void;
}
const formatNumber = (value: number) => new Intl.NumberFormat().format(value);
const NumericInput = (props: NumericInputProps) => {
const { value, onChange } = props;
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const { value: inputValue } = e.target;
const reg = /^-?\d*(\.\d*)?$/;
if (reg.test(inputValue) || inputValue === '' || inputValue === '-') {
onChange(inputValue);
}
};
// '.' at the end or only '-' in the input box.
const handleBlur = () => {
let valueTemp = value;
if (value.charAt(value.length - 1) === '.' || value === '-') {
valueTemp = value.slice(0, -1);
}
onChange(valueTemp.replace(/0*(\d+)/, '$1'));
};
const title = value ? (
<span className="numeric-input-title">{value !== '-' ? formatNumber(Number(value)) : '-'}</span>
) : (
'Input a number'
);
return (
<Tooltip trigger={['focus']} title={title} placement="topLeft" overlayClassName="numeric-input">
<Input
{...props}
onChange={handleChange}
onBlur={handleBlur}
placeholder="Input a number"
maxLength={25}
/>
</Tooltip>
);
};
const App: React.FC = () => {
const [value, setValue] = useState('');
return <NumericInput style={{ width: 120 }} value={value} onChange={setValue} />;
};
export default App;
/* to prevent the arrow overflow the popup container,
or the height is not enough when content is empty */
.numeric-input .ant-tooltip-inner {
min-width: 32px;
min-height: 37px;
}
.numeric-input .numeric-input-title {
font-size: 14px;
}
import { IInvisible, IView } from 'infra-design-icons';
import { Input, Space } from 'infrad';
import React from 'react';
const App: React.FC = () => (
<Space direction="vertical">
<Input.Password
placeholder="input password"
iconRender={visible => (visible ? <IView /> : <IInvisible />)}
/>
</Space>
);
export default App;
import { Input } from 'infrad';
import React from 'react';
const { TextArea } = Input;
const onChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
console.log('Change:', e.target.value);
};
const App: React.FC = () => (
<>
<Input showCount maxLength={20} onChange={onChange} />
<br />
<br />
<TextArea showCount maxLength={100} onChange={onChange} />
</>
);
export default App;
import { ClockCircleOutlined } from 'infra-design-icons';
import { Input, Space } from 'infrad';
import React from 'react';
const App: React.FC = () => (
<Space direction="vertical" style={{ width: '100%' }}>
<Input status="error" placeholder="Error" />
<Input status="warning" placeholder="Warning" />
<Input status="error" prefix={<ClockCircleOutlined />} placeholder="Error with prefix" />
<Input status="warning" prefix={<ClockCircleOutlined />} placeholder="Warning with prefix" />
</Space>
);
export default App;
import type { InputRef } from 'infrad';
import { Button, Input, Space, Switch } from 'infrad';
import React, { useRef, useState } from 'react';
const App: React.FC = () => {
const inputRef = useRef<InputRef>(null);
const [input, setInput] = useState(true);
const sharedProps = {
style: { width: '100%' },
defaultValue: 'Infra Design love you!',
ref: inputRef,
};
return (
<Space direction="vertical" style={{ width: '100%' }}>
<Space wrap>
<Button
onClick={() => {
inputRef.current!.focus({
cursor: 'start',
});
}}
>
Focus at first
</Button>
<Button
onClick={() => {
inputRef.current!.focus({
cursor: 'end',
});
}}
>
Focus at last
</Button>
<Button
onClick={() => {
inputRef.current!.focus({
cursor: 'all',
});
}}
>
Focus to select all
</Button>
<Button
onClick={() => {
inputRef.current!.focus({
preventScroll: true,
});
}}
>
Focus prevent scroll
</Button>
<Switch
checked={input}
checkedChildren="Input"
unCheckedChildren="TextArea"
onChange={() => {
setInput(!input);
}}
/>
</Space>
<br />
{input ? <Input {...sharedProps} /> : <Input.TextArea {...sharedProps} />}
</Space>
);
};
export default App;
import { IUser } from 'infra-design-icons';
import { Input } from 'infrad';
import React from 'react';
const App: React.FC = () => (
<>
<Input size="large" placeholder="large size" prefix={<IUser />} />
<br />
<br />
<Input placeholder="default size" prefix={<IUser />} />
<br />
<br />
<Input size="small" placeholder="small size" prefix={<IUser />} />
</>
);
export default App;
import { CopyOutlined } from 'infra-design-icons';
import {
AutoComplete,
Button,
Cascader,
Col,
DatePicker,
Input,
InputNumber,
Row,
Select,
Tooltip,
} from 'infrad';
import React from 'react';
const { Option } = Select;
const options = [
{
value: 'zhejiang',
label: 'Zhejiang',
children: [
{
value: 'hangzhou',
label: 'Hangzhou',
children: [
{
value: 'xihu',
label: 'West Lake',
},
],
},
],
},
{
value: 'jiangsu',
label: 'Jiangsu',
children: [
{
value: 'nanjing',
label: 'Nanjing',
children: [
{
value: 'zhonghuamen',
label: 'Zhong Hua Men',
},
],
},
],
},
];
const App: React.FC = () => (
<div className="site-input-group-wrapper">
<Input.Group size="large">
<Row gutter={8}>
<Col span={5}>
<Input defaultValue="0571" />
</Col>
<Col span={8}>
<Input defaultValue="26888888" />
</Col>
</Row>
</Input.Group>
<br />
<Input.Group compact>
<Input style={{ width: '20%' }} defaultValue="0571" />
<Input style={{ width: '30%' }} defaultValue="26888888" />
</Input.Group>
<br />
<Input.Group compact>
<Input style={{ width: 'calc(100% - 200px)' }} defaultValue="https://ant.design" />
<Button type="primary">Submit</Button>
</Input.Group>
<br />
<Input.Group compact>
<Input
style={{ width: 'calc(100% - 200px)' }}
defaultValue="git@github.com:ant-design/ant-design.git"
/>
<Tooltip title="copy git url">
<Button icon={<CopyOutlined />} />
</Tooltip>
</Input.Group>
<br />
<Input.Group compact>
<Select defaultValue="Zhejiang">
<Option value="Zhejiang">Zhejiang</Option>
<Option value="Jiangsu">Jiangsu</Option>
</Select>
<Input style={{ width: '50%' }} defaultValue="Xihu District, Hangzhou" />
</Input.Group>
<br />
<Input.Group compact>
<Input.Search allowClear style={{ width: '40%' }} defaultValue="0571" />
<Input.Search allowClear style={{ width: '40%' }} defaultValue="26888888" />
</Input.Group>
<br />
<Input.Group compact>
<Select defaultValue="Option1">
<Option value="Option1">Option1</Option>
<Option value="Option2">Option2</Option>
</Select>
<Input style={{ width: '50%' }} defaultValue="input content" />
<InputNumber />
</Input.Group>
<br />
<Input.Group compact>
<Input style={{ width: '50%' }} defaultValue="input content" />
<DatePicker style={{ width: '50%' }} />
</Input.Group>
<br />
<Input.Group compact>
<Input style={{ width: '30%' }} defaultValue="input content" />
<DatePicker.RangePicker style={{ width: '70%' }} />
</Input.Group>
<br />
<Input.Group compact>
<Select defaultValue="Option1-1">
<Option value="Option1-1">Option1-1</Option>
<Option value="Option1-2">Option1-2</Option>
</Select>
<Select defaultValue="Option2-2">
<Option value="Option2-1">Option2-1</Option>
<Option value="Option2-2">Option2-2</Option>
</Select>
</Input.Group>
<br />
<Input.Group compact>
<Select defaultValue="1">
<Option value="1">Between</Option>
<Option value="2">Except</Option>
</Select>
<Input style={{ width: 100, textAlign: 'center' }} placeholder="Minimum" />
<Input
className="site-input-split"
style={{
width: 30,
borderLeft: 0,
borderRight: 0,
pointerEvents: 'none',
}}
placeholder="~"
disabled
/>
<Input
className="site-input-right"
style={{
width: 100,
textAlign: 'center',
}}
placeholder="Maximum"
/>
</Input.Group>
<br />
<Input.Group compact>
<Select defaultValue="Sign Up" style={{ width: '30%' }}>
<Option value="Sign Up">Sign Up</Option>
<Option value="Sign In">Sign In</Option>
</Select>
<AutoComplete
style={{ width: '70%' }}
placeholder="Email"
options={[{ value: 'text 1' }, { value: 'text 2' }]}
/>
</Input.Group>
<br />
<Input.Group compact>
<Select style={{ width: '30%' }} defaultValue="Home">
<Option value="Home">Home</Option>
<Option value="Company">Company</Option>
</Select>
<Cascader style={{ width: '70%' }} options={options} placeholder="Select Address" />
</Input.Group>
</div>
);
export default App;
.site-input-group-wrapper .site-input-split {
background-color: #fff;
}
.site-input-group-wrapper .site-input-right {
border-left-width: 0;
}
.site-input-group-wrapper .site-input-right:hover,
.site-input-group-wrapper .site-input-right:focus {
border-left-width: 1px;
}
.site-input-group-wrapper .ant-input-rtl.site-input-right {
border-right-width: 0;
}
.site-input-group-wrapper .ant-input-rtl.site-input-right:hover,
.site-input-group-wrapper .ant-input-rtl.site-input-right:focus {
border-right-width: 1px;
}
import { Input } from 'infrad';
import React from 'react';
const { Search } = Input;
const App: React.FC = () => (
<>
<Search placeholder="input search loading default" loading />
<br />
<br />
<Search placeholder="input search loading with enterButton" loading enterButton />
<br />
<br />
<Search placeholder="input search text" enterButton="Search" size="large" loading />
</>
);
export default App;
import { Input } from 'infrad';
import React, { useState } from 'react';
const { TextArea } = Input;
const App: React.FC = () => {
const [value, setValue] = useState('');
return (
<>
<TextArea placeholder="Autosize height based on content lines" autoSize />
<div style={{ margin: '24px 0' }} />
<TextArea
placeholder="Autosize height with minimum and maximum number of lines"
autoSize={{ minRows: 2, maxRows: 6 }}
/>
<div style={{ margin: '24px 0' }} />
<TextArea
value={value}
onChange={e => setValue(e.target.value)}
placeholder="Controlled autosize"
autoSize={{ minRows: 3, maxRows: 5 }}
/>
</>
);
};
export default App;
¥RMB
¥RMB
import { InfoCircleOutlined, IUser } from 'infra-design-icons';
import { Input, Tooltip } from 'infrad';
import React from 'react';
const App: React.FC = () => (
<>
<Input
placeholder="Enter your username"
prefix={<IUser className="site-form-item-icon" />}
suffix={
<Tooltip title="Extra information">
<InfoCircleOutlined style={{ color: 'rgba(0,0,0,.45)' }} />
</Tooltip>
}
/>
<br />
<br />
<Input prefix="¥" suffix="RMB" />
<br />
<br />
<Input prefix="¥" suffix="RMB" disabled />
</>
);
export default App;
import { Input } from 'infrad';
import React from 'react';
const { TextArea } = Input;
const onChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
console.log(e);
};
const App: React.FC = () => (
<>
<Input placeholder="input with clear icon" allowClear onChange={onChange} />
<br />
<br />
<TextArea placeholder="textarea with clear icon" allowClear onChange={onChange} />
</>
);
export default App;
import { Input } from 'infrad';
import React from 'react';
const { TextArea } = Input;
const onChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
console.log('Change:', e.target.value);
};
const App: React.FC = () => (
<TextArea showCount maxLength={100} style={{ height: 120 }} onChange={onChange} />
);
export default App;
import { Input } from 'infrad';
import React from 'react';
const App: React.FC = () => <Input placeholder="Borderless" bordered={false} />;
export default App;
API#
Input#
Property | Description | Type | Default | Version |
---|---|---|---|---|
addonAfter | The label text displayed after (on the right side of) the input field | ReactNode | - | |
addonBefore | The label text displayed before (on the left side of) the input field | ReactNode | - | |
allowClear | If allow to remove input content with clear icon | boolean | { clearIcon: ReactNode } | false | |
bordered | Whether has border style | boolean | true | 4.5.0 |
defaultValue | The initial input content | string | - | |
disabled | Whether the input is disabled | boolean | false | |
id | The ID for input | string | - | |
maxLength | The max length | number | - | |
showCount | Whether show text count | boolean | { formatter: ({ count: number, maxLength?: number }) => ReactNode } | false | 4.18.0 |
status | Set validation status | 'error' | 'warning' | - | 4.19.0 |
prefix | The prefix icon for the Input | ReactNode | - | |
size | The size of the input box. Note: in the context of a form, the middle size is used | large | middle | small | - | |
suffix | The suffix icon for the Input | ReactNode | - | |
type | The type of input, see: MDN( use Input.TextArea instead of type="textarea" ) | string | text | |
value | The input content value | string | - | |
onChange | Callback when user input | function(e) | - | |
onPressEnter | The callback function that is triggered when Enter key is pressed | function(e) | - |
When
Input
is used in aForm.Item
context, if theForm.Item
has theid
andoptions
props defined thenvalue
,defaultValue
, andid
props ofInput
are automatically set.
The rest of the props of Input are exactly the same as the original input.
Input.TextArea#
Property | Description | Type | Default | Version |
---|---|---|---|---|
allowClear | If allow to remove input content with clear icon | boolean | false | |
autoSize | Height autosize feature, can be set to true | false or an object { minRows: 2, maxRows: 6 } | boolean | object | false | |
bordered | Whether has border style | boolean | true | 4.5.0 |
defaultValue | The initial input content | string | - | |
maxLength | The max length | number | - | 4.7.0 |
showCount | Whether show text count | boolean | { formatter: ({ count: number, maxLength?: number }) => string } | false | 4.7.0 (formatter: 4.10.0) |
value | The input content value | string | - | |
onPressEnter | The callback function that is triggered when Enter key is pressed | function(e) | - | |
onResize | The callback function that is triggered when resize | function({ width, height }) | - |
The rest of the props of Input.TextArea
are the same as the original textarea.
Input.Search#
Property | Description | Type | Default |
---|---|---|---|
enterButton | Whether to show an enter button after input. This property conflicts with the addonAfter property | boolean | ReactNode | false |
loading | Search box with loading | boolean | false |
onSearch | The callback function triggered when you click on the search-icon, the clear-icon or press the Enter key | function(value, event) | - |
Supports all props of Input
.
Input.Group#
Property | Description | Type | Default |
---|---|---|---|
compact | Whether use compact style | boolean | false |
size | The size of Input.Group specifies the size of the included Input fields. Available: large default small | string | default |
<Input.Group>
<input />
<input />
</Input.Group>
Input.Password#
Property | Description | Type | Default | Version |
---|---|---|---|---|
iconRender | Custom toggle button | (visible) => ReactNode | (visible) => (visible ? <EyeOutlined /> : <EyeInvisibleOutlined />) | 4.3.0 |
visibilityToggle | Whether show toggle button | boolean | true |
Input Methods#
Name | Description | Parameters | Version |
---|---|---|---|
blur | Remove focus | - | |
focus | Get focus | (option?: { preventScroll?: boolean, cursor?: 'start' | 'end' | 'all' }) | option - 4.10.0 |
FAQ#
Why Input lose focus when change prefix/suffix/showCount
#
When Input dynamic add or remove prefix/suffix/showCount
will make React recreate the dom structure and new input will be not focused. You can set an empty <span />
element to keep the dom structure:
const suffix = condition ? <Icon type="smile" /> : <span />;
<Input suffix={suffix} />;
Why TextArea in control can make value
exceed maxLength
?#
When in control, component should show as what it set to avoid submit value not align with store value in Form.