我正在 ReactJS 项目中使用 Material UI (v0.20.0) 组件库中的 Autocomplete 组件。我尝试过寻找此功能的实现,但没有遇到一个好的例子。我希望能够突出显示/格式化用户在搜索结果中输入的文本,类似于所附图像。
如果您使用的是 Material-ui v0.xx 那么请看下面的示例。
要将样式应用于用户输入的文本,您必须使用 inputStyle 属性,如下所示。
我还提到了浮动标签、下划线、提示文本等其他样式,这些样式可能会对社区有所帮助。
const styles = {
floatingSearchLabelStyle: {
color: '#fff',
fontFamily: 'Open Sans","Helvetica Neue",Helvetica,Arial,"Lucida Grande'
},
inputSearchStyleText: {
color: '#fff'
},
underlineSearchStyle : {
borderColor: '#fff'
},
hintSearchStyle: {
color: '#fff'
}
}
<AutoComplete
floatingLabelText="Search people"
hintText="Search with name"
dataSource = {dataSource}
style={{marginTop: '-20px'}}
maxSearchResults={10}
anchorOrigin={{vertical: 'bottom', horizontal: 'left'}}
animated={true}
onNewRequest= {this.handleNewRequest}
onUpdateInput={this.handleUpdateInput}
filter={AutoComplete.fuzzyFilter}
inputStyle={styles.inputSearchStyleText}
underlineStyle={styles.underlineSearchStyle}
underlineFocusStyle={styles.underlineSearchStyle}
hintStyle={styles.hintSearchStyle}
floatingLabelStyle={styles.floatingSearchLabelStyle}
/>
如果您使用的是material-ui v0.xx,希望这个答案对您有所帮助。
在 Material-UI 版本 5+ 中,我们可以使用 renderOption 属性根据用户输入的输入突出显示选项,方法如下
<Autocomplete
renderOption={React.useCallback((props, option, { inputValue }) => {
function boldString(str, substr) {
const strRegExp = new RegExp(substr, 'g')
return str.replace(strRegExp, '<b style=color:#1e99fa !important;>' + substr + '</b>')
}
return (
<Box component='li' {...props}>
<div style={{width: '50%'}} dangerouslySetInnerHTML={{ __html: boldString(option.label, inputValue) }}/>
</Box>
)
})}
/>
对于 Material-UI 版本 5+,这是替代的抽象函数 TypeScript 解决方案,利用
renderOption
组件上提供的 <Autocomplete>
属性。
该解决方案对完整选项标签字符串执行
split
,以根据输入查询字符串值进行拆分(通过区分大小写的 RegExp
),然后将每个字符串部分与包装的 <span>
元素重新映射回一起围绕每个文本部分,然后您可以轻松地在 matched和 unmatched 选项文本部分上扩展您自己的类型安全(即
CSSProperties
)自定义样式。
import React, { CSSProperties } from "react";
import Autocomplete, { AutocompleteRenderOptionState } from "@mui/material/Autocomplete";
const renderOption = (
props: React.HTMLAttributes<HTMLLIElement>,
option: string,
state: AutocompleteRenderOptionState
) => {
const { inputValue } = state;
const parts = option.split(new RegExp(`(${inputValue})`, "gi"));
return (
<li {...props}>
{parts.map((part, index) => {
const isOptionPartMatched =
part.toLowerCase() === inputValue.toLowerCase();
// apply and extend additional custom styles to the matched option label part(s) here
const matchedStyles: CSSProperties = {
fontWeight: 700,
};
// apply and extend additional custom styles to the unmatched option label part(s) here
const unmatchedStyles: CSSProperties = {
fontWeight: 375,
};
return (
<span
key={`${option}_${index}`}
style={{
...(isOptionPartMatched ? matchedStyles : unmatchedStyles),
}}
>
{part}
</span>
);
})}
</li>
);
};
<Autocomplete
renderOption={renderOption}
/>
MUI API 参考:https://mui.com/material-ui/api/autocomplete/#autocomplete-prop-renderOption