ant-design AutoComplete 的 variant 形态解析:outlined、filled、borderless 与 underlined
【免费下载链接】ant-designAn enterprise-class UI design language and React UI library项目地址: https://gitcode.com/GitHub_Trending/an/ant-design
本篇围绕 AutoComplete 组件的variant属性展开,介绍outlined、filled、borderless、underlined四种输入形态的用法与差异,并结合 variant 示例、官方属性表 以及底层 Select 源码,说明 variant 的解析优先级链与样式生成机制。读完后你可以直接复制示例代码实现四种形态,并能按“组件属性 → Form 上下文 → ConfigProvider 全局配置”的正确优先级统一整站控件形态。
四种形态是什么
AutoComplete 自5.13.0版本起支持variant属性,可取四个值,官方文档(variant 示例说明)的原文即:
可选
outlinedfilledborderlessunderlined四种形态。
对应 属性 API 表 中的记录:
| 属性 | 说明 | 类型 | 默认值 | 版本 |
|---|---|---|---|---|
variant | 形态变体 | outlined|borderless|filled|underlined | outlined | 5.13.0 |
四种形态的视觉语义:
outlined(默认):完整描边输入框,最通用的表单形态;filled:无描边、带背景填充,适合浅色底卡片内弱化控件存在感;borderless:无边框无背景,视觉上“隐形”,适合内嵌在自定义容器(如搜索栏、标签栏)中;underlined:仅保留底部横线,常见于移动风格与轻量输入场景。
官方示例代码逐段解读
示例源码位于 variant.tsx,完整代码如下:
import React, { useState } from 'react'; import { AutoComplete, Flex } from 'antd'; import type { AutoCompleteProps } from 'antd'; const mockVal = (str: string, repeat = 1) => ({ value: str.repeat(repeat), }); const App: React.FC = () => { const [options, setOptions] = useState<AutoCompleteProps['options']>([]); const getPanelValue = (searchText: string) => !searchText ? [] : [mockVal(searchText), mockVal(searchText, 2), mockVal(searchText, 3)]; return ( <Flex vertical gap={12}> <AutoComplete options={options} style={{ width: 200 }} placeholder="Outlined" showSearch={{ onSearch: (text) => setOptions(getPanelValue(text)) }} onSelect={globalThis.console.log} /> <AutoComplete options={options} style={{ width: 200 }} placeholder="Filled" showSearch={{ onSearch: (text) => setOptions(getPanelValue(text))}} onSelect={globalThis.console.log} variant="filled" /> <AutoComplete options={options} style={{ width: 200 }} placeholder="Borderless" showSearch={{ onSearch: (text) => setOptions(getPanelValue(text))}} onSelect={globalThis.console.log} variant="borderless" /> <AutoComplete options={options} style={{ width: 200 }} placeholder="Underlined" onSearch={(text) => setOptions(getPanelValue(text))} onSelect={globalThis.console.log} variant="underlined" /> </Flex> ); }; export default App;几个值得注意的写法细节:
- 动态候选项:
mockVal(str, repeat)把搜索词重复 1~3 次生成{ value: string }形式的候选项;getPanelValue在搜索词为空时返回空数组,否则返回三条递增值。四个输入框共享同一个optionsstate,所以任意一个框输入,其余框的下拉候选也会同步更新——这正是演示四种形态“外观不同但行为一致”的意图。 showSearch的两种写法:前三个组件传showSearch={{ onSearch }}对象形式,最后一个直接传onSearch属性。这与 AutoCompleteProps 定义 一致:showSearch接受boolean或Pick<SearchConfig, 'filterOption' | 'onSearch' | 'searchIcon'>,即可以只携带搜索相关子配置。variant是唯一差异:四个<AutoComplete>除placeholder与variant外完全相同,outlined因是默认值而未显式写出。- 布局:使用
<Flex vertical gap={12}>纵向排列,style={{ width: 200 }}保证四个输入框宽度一致,便于对比形态差异。
该示例已被 demo 快照测试覆盖,可在 demo.test.tsx.snap 中找到renders components/auto-complete/demo/variant.tsx correctly 1条目,说明四种形态的渲染结果被纳入回归验证。
variant 为什么对 AutoComplete 生效:它本质是 Select 的组合
阅读 AutoComplete.tsx 可以看到,AutoCompleteProps继承自 Select 的InternalSelectProps(仅省略loading、mode、showSearch等少量属性),而组件主体就是把 props 原样转发给内部 Select,并以Select.SECRET_COMBOBOX_MODE_DO_NOT_USE进入 combobox 模式:
// components/auto-complete/AutoComplete.tsx return ( <Select ref={ref} suffixIcon={null} {...omit(props, ['dataSource', 'dropdownClassName', 'popupClassName', 'onDropdownVisibleChange', 'onOpenChange'])} prefixCls={prefixCls} mode={Select.SECRET_COMBOBOX_MODE_DO_NOT_USE as SelectProps['mode']} ... > {optionChildren} </Select> );因此variant并不是 AutoComplete 自己实现的样式逻辑,而是复用了 Select 输入框的 variant 能力。在 select/index.tsx 中,组件调用useVariants(仓库内实现为useVarianthook)合并 variant 后,将其作为类名开关挂到根节点:
// components/select/index.tsx const [variant, enableVariantCls] = useVariants('select', customizeVariant, bordered); ... [`${prefixCls}-${variant}`]: enableVariantCls,也就是说,当mergedVariant属于合法 variants 列表(Variants由 config-provider 模块导出,见 context.ts)时,根元素会追加ant-select-{variant}类,例如ant-select-filled、ant-select-underline的写法为ant-select-underlined。
解析优先级:谁的 variant 说了算
variant 的合并逻辑集中在 useVariants.ts,其解析链如下:
// form variant > component global variant > fallback component global variant > global variant mergedVariant = ctxVariant ?? configComponentVariant ?? configVariant ?? 'outlined';结合源码,优先级从高到低为:
- 组件自身
variant属性(最高优先级,直接覆盖一切); - 旧版
bordered={false}:若显式传入bordered={false},等价于borderless(兼容逻辑,源码注释为 "Compatible for legacyborderedprop"); - Form 的
VariantContext:把 AutoComplete 放在设置了variant的<Form>内时,会继承表单级形态; - ConfigProvider 的组件级配置:即
theme之外通过 ConfigProvider 配置的select.variant(AutoComplete 内部复用 Select 配置); - ConfigProvider 的全局
variant; - 兜底默认值
outlined。
hook 同时返回enableVariantCls,只有当合并结果属于已知 variants 时才挂出ant-select-{variant}类名,避免非法值产生样式副作用。
这套链路的实际含义是:整站统一形态时优先改 ConfigProvider,局部强调时再用组件属性覆盖,两者不冲突。
样式如何落地:按形态作用域生成 CSS 变量
类名只是开关,真正的视觉差异来自 Select 输入框的样式生成逻辑。在 select-input.ts 中,genSelectInputVariantStyle会为每个 variant 生成一段以&${componentCls}-${variant}为作用域的样式块:
// components/select/style/select-input.ts const genSelectInputVariantStyle = (token, variant, colors, errorColors, warningColors, patchStyle) => { const { componentCls } = token; return { [`&${componentCls}-${variant}`]: [ genSelectInputVariableStyle(token, colors), { [`&${componentCls}-status-error`]: genSelectInputVariableStyle(token, { ...colors, ...errorColors }), [`&${componentCls}-status-warning`]: genSelectInputVariableStyle(token, { ...colors, ...warningColors }), }, patchStyle, ], }; };可以看到两个关键设计:
- 形态通过 CSS 变量覆盖实现:每个 variant 传入各自的
colors(描边色、背景色、hover/active 背景等),覆盖基础变量,从而改变输入框外观,而不重复整套几何属性; - 与
status正交:error/warning状态在 variant 作用域内再次覆盖颜色变量。因此variant与 属性表 中的status('success' | 'warning' | 'error' | 'processing')可自由组合,例如variant="filled"的错误态输入框仍保留填充底并显示错误色描边。
实践建议与注意事项
- 选择形态:默认
outlined适用于绝大多数表单;在卡片/面板内需要弱化控件时选filled;嵌入自定义容器(无容器边框冲突)时用borderless;移动端风格或极简输入用underlined。 - 保持一致性:同屏多个 AutoComplete 建议统一
variant,并优先通过 ConfigProvider 或 Form 的variant下发,而不是逐个组件写死,避免优先级混乱。 - 旧代码迁移:如果项目还使用
bordered={false},从源码看其会被自动映射为borderless,但 select 源码中已把bordered标记为待废弃(建议改用variant),新代码应直接使用variant。 - 与语义化样式配合:
variant只决定输入框形态,若还需针对内部区域做定制,可结合 AutoComplete 的 classNames/styles 语义结构(root、input、placeholder、content、popup等键位)进一步微调。 - 版本前提:
variant需要 antd5.13.0 及以上;更低版本应使用bordered属性模拟borderless,或升级后再启用四形态能力。
快速参考
| 场景 | 推荐写法 |
|---|---|
| 单个输入框改形态 | <AutoComplete variant="filled" ... /> |
| 不写属性 | 默认outlined |
| Form 内统一形态 | <Form variant="underlined">内放 AutoComplete |
| 整站统一 | ConfigProvider 设置全局或select组件级variant |
旧bordered={false} | 自动视为borderless,建议迁移到variant |
| 组合状态 | variant+status正交组合,如variant="borderless" status="error" |
核心文件索引:示例说明 variant.md、示例源码 variant.tsx、组件实现 AutoComplete.tsx、variant 合并逻辑 useVariants.ts、Select 输入框样式生成 select-input.ts、属性表 index.zh-CN.md。
【免费下载链接】ant-designAn enterprise-class UI design language and React UI library项目地址: https://gitcode.com/GitHub_Trending/an/ant-design
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考