自动完成
自动完成是一个文本输入框,当用户开始输入时,会弹出一个包含建议选项的面板,从而增强了文本输入体验。
简介
Autocomplete
是文本输入框的增强版本,它会在用户输入时显示建议选项,并允许用户从列表中选择一个选项。
- 完成字符串在文本框中的输入光标后内联显示。内联完成字符串在视觉上突出显示,并具有选定状态。
- 第一个选项会自动高亮显示。
- 当 Autocomplete 失去焦点时,选定的选项将成为输入框的值,除非用户选择不同的选项或更改输入框中的字符串。
- 输入框始终失去焦点。
- 如果没有选择任何值,输入框的文本在失去焦点时会被清除。
- 当用户按下 escape 键且弹出框关闭时,清除所有值。
- 该组件被禁用。
- 输入框无法被清除
- 当选择一个值时,弹出框不会关闭。
- 弹出框中的列表框不会循环焦点。
- 从列表框中隐藏已选选项。
- 用户输入不受提供的选项的约束。
- 高亮可以移动到输入框。
- 弹出框将在输入框获得焦点时打开。
- 弹出框将位于父组件的 DOM 结构下。
- 该组件变为只读。在多标签模式下也支持,此时标签无法删除。
- 输入框的文本在获得焦点时被选中。这有助于用户清除选定的值。
用法
安装完成后,您可以开始使用以下基本元素构建此组件
import Autocomplete from '@mui/joy/Autocomplete';
import Input from '@mui/joy/Input';
export default function App() {
return <Autocomplete options={['Option 1', 'Option 2']} />;
}
基础
Autocomplete 组件需要一个 options
列表,在文本框获得焦点后显示。该值必须从预定义的允许值集合中选择。
自定义
选项结构
默认情况下,options
接受 string
数组或 { label: string }
const options = [
{ label: 'The Godfather', id: 1 },
{ label: 'Pulp Fiction', id: 2 },
];
// or
const options = ['The Godfather', 'Pulp Fiction'];
但是,您可以通过提供 getOptionLabel
属性来使用不同的结构
const options = [
{ title: 'Pulp Fiction', id: 2 },
// ...
];
<Autocomplete getOptionLabel={option => option.title}>
选项外观
要自定义选项的外观,请将 renderOption
属性与 AutocompleteOption
组件结合使用作为选项容器。
要自定义特定插槽的变体和颜色,请使用 slotProps
<Autocomplete
variant="plain"
slotProps={{
listbox: {
variant: 'outlined',
},
}}
/>
标签
将 Autocomplete、FormLabel 和 FormHelperText(可选)放在 FormControl 组件下,以创建一个可访问的自动完成组件。
装饰器
使用 startDecorator
或 endDecorator
将装饰器插入到自动完成组件。
受控状态
该组件有两种可以控制的状态
- “value” 状态,使用
value
/onChange
属性组合。此状态表示用户选择的值,例如按下 Enter 键时。 - “input value” 状态,使用
inputValue
/onInputChange
属性组合。此状态表示文本框中显示的值。
这两个状态是隔离的,应该独立控制。
value:
'Option 1'
inputValue:
''
禁用选项
使用 getOptionDisabled
属性读取选项并返回 true
以禁用它们。
分组选项
您可以使用 groupBy
属性对选项进行分组。如果这样做,请确保选项也按照分组的维度进行排序,否则,您会注意到重复的标题。
加载中
只要网络请求处于挂起状态,它就会显示进度状态。
搜索输入框
使用 freeSolo
创建一个带有建议体验的搜索输入框,例如 Google 搜索或 react-autowhatever。
用户创建的选项
如果您打算将 freeSolo
模式用于类似组合框的体验(select 元素的增强版本),我们建议设置
selectOnFocus
以帮助用户清除选定的值。clearOnBlur
以帮助用户输入新值。handleHomeEndKeys
以使用 Home 和 End 键在弹出框内移动焦点。- 最后一个选项,例如:添加“您的搜索”。
当用户想要添加新值时,您还可以显示一个对话框。
验证
要显示无效状态,请在 FormControl
上设置 error
属性。
选定选项外观
使用 renderTag
属性自定义外观。
限制要显示的选定选项数量
您可以使用 limitTags
属性来限制在未聚焦时显示的选项数量。
尺寸
自动完成组件开箱即用地提供三种尺寸:sm
、md
(默认)和 lg
。尺寸会传递到内部组件,包括 Input
、Chip
和 List
。
尺寸也可以在 FormControl
上控制。
自定义过滤器
该组件公开了一个工厂,用于创建可以提供给 filterOptions
属性的过滤器方法。您可以使用它来更改默认的选项过滤行为。
import { createFilterOptions } from '@mui/material/Autocomplete';
参数
config
(object [可选])
config.ignoreAccents
(bool [可选]):默认为true
。删除变音符号。config.ignoreCase
(bool [可选]):默认为true
。将所有内容转换为小写。config.limit
(number [可选]):默认为 null。限制要显示的建议选项的数量。例如,如果config.limit
为100
,则仅显示前100
个匹配的选项。如果有很多选项匹配且未设置虚拟化,则此功能很有用。config.matchFrom
('any' | 'start' [可选]):默认为'any'
。config.stringify
(func [可选]):控制如何将选项转换为字符串,以便可以将其与输入文本片段进行匹配。config.trim
(bool [可选]):默认为false
。删除尾随空格。
返回值
filterOptions
:返回的过滤器方法可以直接提供给 Autocomplete 组件的 filterOptions
属性,或者提供给 hook 的同名参数。
在以下演示中,选项需要以查询前缀开头
const filterOptions = createFilterOptions({
matchFrom: 'start',
stringify: (option) => option.title,
});
<Autocomplete filterOptions={filterOptions} />;
高级过滤器
对于更丰富的过滤机制,例如模糊匹配,建议查看 match-sorter。例如
import { matchSorter } from 'match-sorter';
const filterOptions = (options, { inputValue }) => matchSorter(options, inputValue);
<Autocomplete filterOptions={filterOptions} />;
CSS 变量 Playground
Autocomplete 组件重用 Input 组件的 CSS 变量,为您提供一致的自定义体验。
<Autocomplete />
CSS 变量
高亮选项
以下演示依赖于 autosuggest-highlight,这是一个小巧 (1 kB) 的实用程序,用于在 autosuggest 和 autocomplete 组件中高亮文本。
GitHub 的选择器
要重现 GitHub 的标签选择器,Autocomplete 在 MUI Base Popper
中渲染。要从自动完成组件中移除弹出行为,请将 listbox 插槽替换为 AutocompleteListbox
组件。
- help wanted
- type: bug
虚拟化
在 10,000 个随机生成的选项中搜索。列表通过 react-window 实现虚拟化。
事件
如果您想阻止默认的按键处理程序行为,可以将事件的 defaultMuiPrevented
属性设置为 true
<Autocomplete
onKeyDown={(event) => {
if (event.key === 'Enter') {
// Prevent's default 'Enter' behavior.
event.defaultMuiPrevented = true;
// your handler code
}
}}
/>
限制
autocomplete/autofill
默认情况下,该组件使用 autoComplete="off"
属性禁用输入框的 autocomplete 功能(记住用户在之前的会话中为给定字段输入的内容)。Google Chrome 目前不支持此属性设置 (Issue 41239842)。一种可能的解决方法是删除 id
以使组件生成一个随机的 id。
除了记住过去输入的值之外,浏览器还可能提出 autofill 建议(保存的登录名、地址或付款详细信息)。如果您想避免 autofill,可以尝试以下操作
命名输入框时不要泄露浏览器可以使用的任何信息。例如,使用
id="field1"
而不是id="country"
。如果您将 id 留空,组件将使用随机 id。设置
autoComplete="new-password"
(某些浏览器会为此属性设置的输入框建议使用强密码)<Autocomplete slotProps={{ input: { autoComplete: 'new-password', }, }} />
阅读 MDN 上的指南 了解更多详情。
iOS VoiceOver
iOS Safari 上的 VoiceOver 对 aria-owns
属性的支持不是很好。您可以使用 disablePortal
属性来解决此问题。
<Autocomplete
slotProps={{
listbox: {
disablePortal: true,
},
}}
/>
可访问性
(WAI-ARIA: https://www.w3.org/WAI/ARIA/apg/patterns/combobox/)
我们鼓励为文本框使用标签。该组件实现了 WAI-ARIA 创作实践。