自动完成
自动完成组件是由建议选项面板增强的文本输入框。
简介
自动完成组件是一个增强的文本输入框,它在用户输入时显示建议选项列表,并允许用户从列表中选择一个选项。
MUI Base 提供了 useAutocomplete
钩子,用于构建自定义自动完成功能。它实现了 WAI-ARIA Combobox 模式,通常用于帮助用户更快地完成表单输入或搜索查询。
钩子
import { useAutocomplete } from '@mui/base/useAutocomplete';
useAutocomplete
钩子需要一个 options
列表,以便在文本框获得焦点时显示。该值必须从预定义的集合中选择。
以下演示展示了如何创建一个简单的组合框,应用样式,并使用 onChange
属性将选定的值写入状态变量
按 Enter 开始编辑
自定义
渲染选项
默认情况下,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 = [
{ issuer: 'Bank of America', brand: 'Visa', last4: '1234' },
{ issuer: 'Bank of America', brand: 'MasterCard', last4: '5678' },
{ issuer: 'Barclays', brand: 'Visa', last4: '4698' },
// ...
];
const {
getRootProps,
// etc
} = useAutocomplete({
getOptionLabel: (option) => option.last4,
});
受控状态
useAutocomplete
钩子有两个可以控制的状态
- “value”状态,使用
value
/onChange
属性组合。此状态表示用户选择的值,例如在按下 Enter 时。 - “input value”状态,使用
inputValue
/onInputChange
属性组合。此状态表示文本框中显示的值。
这两个状态是隔离的,应该独立控制。
value: Firefox
inputValue:
使用 portal
React Portal 可用于在 DOM 层次结构之外渲染列表框,使其更容易“浮动”在相邻元素之上。
MUI Base 提供了一个围绕 React 的 createPortal()
构建的 Popper 组件,正是为了这个目的,并且还可以帮助您管理键盘焦点,因为它在 portal 中和 portal 外移动。
要在 MUI Base 的 Popper 中渲染列表框,必须按如下方式合并 ref
import { useAutocomplete } from '@mui/base/useAutocomplete';
import { Popper } from '@mui/base/Popper';
import { unstable_useForkRef as useForkRef } from '@mui/utils';
export default function App(props) {
const {
getRootProps,
getInputProps,
getListboxProps,
getOptionProps,
popupOpen,
anchorEl,
setAnchorEl,
groupedOptions,
} = useAutocomplete(props);
const rootRef = useForkRef(ref, setAnchorEl);
return (
<React.Fragment>
<div {...getRootProps()} ref={rootRef}>
<input {...getInputProps()} />
</div>
{anchorEl && (
<Popper open={popupOpen} anchorEl={anchorEl}>
{groupedOptions.length > 0 && (
<ul {...getListboxProps()}>
{groupedOptions.map((option, index) => (
<li {...getOptionProps({ option, index })}>{option.label}</li>
))}
</ul>
)}
</Popper>
)}
</React.Fragment>
);
}
这是一个完整的演示,展示了如何在 Popper 内部渲染列表框