自動完成
自動完成元件是一個文字輸入框,透過建議選項面板來增強功能。
簡介
自動完成元件是一個增強型的文字輸入框,會在使用者輸入時顯示建議選項列表,並讓使用者從列表中選取選項。
MUI Base 提供了 useAutocomplete
Hook,用於建構自訂的自動完成功能。 它實作了 WAI-ARIA Combobox 模式,通常用於協助使用者更快地完成表單輸入或搜尋查詢。
Hook
import { useAutocomplete } from '@mui/base/useAutocomplete';
useAutocomplete
Hook 需要一個 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
Hook 有兩種可以控制的狀態
- 使用
value
/onChange
屬性組合的「value」狀態。 此狀態表示使用者選取的值,例如按下 Enter 鍵時。 - 使用
inputValue
/onInputChange
屬性組合的「input value」狀態。 此狀態表示文字框中顯示的值。
這兩個狀態是隔離的,應獨立控制。
value: Firefox
inputValue:
使用 Portal
React Portal 可用於在 DOM 階層之外渲染列表框,使其更容易「浮動」在相鄰元素之上。
MUI Base 提供了圍繞 React 的 createPortal()
建構的 Popper 元件,正是為了這個目的,並且還可以協助您管理鍵盤焦點,因為它會在 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 內渲染列表框