自動完成
自動完成是一個普通的文字輸入框,透過建議選項面板來增強功能。
此小工具在以下兩種情境中,對於設定單行文字框的值非常有用
- 文字框的值必須從預先定義的允許值集合中選擇,例如,位置欄位必須包含有效的位置名稱:下拉式方塊。
- 文字框可以包含任何任意值,但建議使用者可能的數值會很有幫助,例如,搜尋欄位可能會建議相似或先前的搜尋,以節省使用者時間:自由輸入。
它旨在成為 "react-select" 和 "downshift" 套件的改良版本。
下拉式方塊
數值必須從預先定義的允許值集合中選擇。
選項結構
預設情況下,元件接受以下選項結構
interface AutocompleteOption {
label: string;
}
// or
type AutocompleteOption = string;
例如
const options = [
{ label: 'The Godfather', id: 1 },
{ label: 'Pulp Fiction', id: 2 },
];
// or
const options = ['The Godfather', 'Pulp Fiction'];
但是,您可以透過提供 getOptionLabel
屬性來使用不同的結構。
如果您的選項是物件,則必須提供 isOptionEqualToValue
屬性,以確保正確的選擇和醒目提示。 預設情況下,它使用嚴格相等性來比較選項與目前的值。
Playground
以下每個範例都示範了自動完成元件的一項功能。
國家/地區選擇
選擇 248 個國家/地區之一。
受控狀態
元件有兩種可以控制的狀態
- 「value」狀態,搭配
value
/onChange
屬性組合。 此狀態表示使用者選擇的值,例如按下 Enter 時。 - 「input value」狀態,搭配
inputValue
/onInputChange
屬性組合。 此狀態表示文字框中顯示的值。
這兩個狀態是隔離的,應獨立控制。
自由輸入
將 freeSolo
設定為 true,讓文字框可以包含任何任意值。
搜尋輸入框
此屬性旨在涵蓋搜尋輸入框搭配建議的主要使用案例,例如 Google 搜尋或 react-autowhatever。
可建立
如果您打算將此模式用於像 下拉式方塊 般的體驗(select 元素的增強版本),我們建議設定
selectOnFocus
以協助使用者清除選取的值。clearOnBlur
以協助使用者輸入新值。handleHomeEndKeys
以使用 Home 和 End 鍵將焦點移至彈出視窗內。- 最後一個選項,例如:
新增「您的搜尋」
。
您也可以在使用者想要新增新值時顯示對話框。
群組
您可以使用 groupBy
屬性將選項分組。 如果您這樣做,請確保選項也以與分組相同的維度排序,否則,您會注意到重複的標題。
若要控制群組的呈現方式,請提供自訂的 renderGroup
屬性。 這是一個接受具有兩個欄位的物件的函式
group
—表示群組名稱的字串children
—屬於該群組的清單項目集合
以下示範展示如何使用此屬性來定義自訂標記並覆寫預設群組的樣式
useAutocomplete
對於進階客製化使用案例,公開了一個無頭 useAutocomplete()
Hook。 它接受與自動完成元件幾乎相同的選項,減去所有與 JSX 渲染相關的屬性。 自動完成元件建立在此 Hook 之上。
import { useAutocomplete } from '@mui/base/useAutocomplete';
useAutocomplete
Hook 也從 @mui/material 重新匯出,以方便使用和向後相容性。
import useAutocomplete from '@mui/material/useAutocomplete';
隨打字搜尋
如果您的邏輯是在每次按鍵時擷取新選項,並使用文字框的目前值在伺服器上篩選,您可能需要考慮節流請求。
此外,您需要透過覆寫 filterOptions
屬性來停用自動完成元件的內建篩選功能
<Autocomplete filterOptions={(x) => x} />
Google 地圖地點
Google 地圖地點自動完成功能的自訂 UI。 在此示範中,我們需要載入 Google Maps JavaScript 和 Google Places API。
固定選項
如果您需要鎖定某些標籤使其無法移除,您可以將晶片設定為停用。
限制標籤數量
您可以使用 limitTags
屬性來限制未聚焦時顯示的選項數量。
尺寸
想要更小的輸入框嗎? 使用 size
屬性。
全域客製化選項
若要全域客製化應用程式中所有元件的自動完成選項,您可以使用 主題預設屬性,並在 defaultProps
鍵中設定 renderOption
屬性。 renderOption
屬性會將 ownerState
作為第四個參數,其中包含屬性和內部元件狀態。 若要顯示標籤,您可以使用 ownerState
中的 getOptionLabel
屬性。 這種方法可以為每個自動完成元件啟用不同的選項,同時保持選項樣式的一致性。
GitHub 的選擇器
此示範重現 GitHub 的標籤選擇器
醒目提示
以下示範依賴 autosuggest-highlight,這是一個小型的 (1 kB) 公用程式,用於醒目提示自動建議和自動完成元件中的文字。
自訂篩選器
元件公開了一個工廠,用於建立可以提供給 filterOptions
屬性的篩選方法。 您可以使用它來變更預設選項篩選行為。
import { createFilterOptions } from '@mui/material/Autocomplete';
createFilterOptions(config) => filterOptions
引數
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
:傳回的篩選方法可以直接提供給自動完成元件的 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} />;
虛擬化
在 10,000 個隨機產生的選項中搜尋。 由於 react-window,清單已虛擬化。
事件
如果您想要防止預設的按鍵處理常式行為,您可以將事件的 defaultMuiPrevented
屬性設定為 true
<Autocomplete
onKeyDown={(event) => {
if (event.key === 'Enter') {
// Prevent's default 'Enter' behavior.
event.defaultMuiPrevented = true;
// your handler code
}
}}
/>
限制
自動完成/自動填入
瀏覽器具有啟發法,可協助使用者填寫表單輸入。 但是,這可能會損害元件的 UX。
預設情況下,元件會使用 autoComplete="off"
屬性停用輸入框的自動完成功能(記住使用者在先前工作階段中針對給定欄位輸入的內容)。 Google Chrome 目前不支援此屬性設定(Issue 41239842)。 一種可能的解決方法是移除 id
以讓元件產生隨機 ID。
除了記住過去輸入的值之外,瀏覽器也可能會建議自動填入建議(已儲存的登入、地址或付款詳細資訊)。 如果您想要避免自動填入,您可以嘗試以下操作
命名輸入框時,不要洩漏任何瀏覽器可以使用的資訊。 例如,
id="field1"
而不是id="country"
。 如果您將 ID 留空,元件會使用隨機 ID。設定
autoComplete="new-password"
(某些瀏覽器會針對具有此屬性設定的輸入框建議強式密碼)<TextField {...params} inputProps={{ ...params.inputProps, autoComplete: 'new-password', }} />
如需更多詳細資訊,請閱讀 MDN 上的指南。
iOS VoiceOver
iOS Safari 上的 VoiceOver 不太支援 aria-owns
屬性。 您可以使用 disablePortal
屬性來解決此問題。
ListboxComponent
如果您提供自訂的 ListboxComponent
屬性,則需要確保預期的捲動容器已將 role
屬性設定為 listbox
。 這可確保捲軸的正確行為,例如使用鍵盤導覽時。
無障礙功能
(WAI-ARIA:https://www.w3.org/WAI/ARIA/apg/patterns/combobox/)
我們鼓勵對文字框使用標籤。 此元件實作了 WAI-ARIA 撰寫實務。