mirror of
https://github.com/AtomUI/AtomUI.git
synced 2026-10-28 23:08:36 +08:00
308 lines
18 KiB
Markdown
308 lines
18 KiB
Markdown
# Input 输入框控件族
|
||
|
||
## 概述
|
||
|
||
输入框是图形界面中最基础的表单域控件,用于通过键盘输入内容。AtomUI 的 Input 控件族完整复刻了 [Ant Design 5.0 Input](https://ant.design/components/input-cn) 的设计规范,在 .NET / Avalonia 平台上提供与 Ant Design React 版一致的视觉体验和交互行为。
|
||
|
||
AtomUI 的 Input 控件族包含以下控件:
|
||
|
||
| 控件 | 对应 Ant Design | 说明 |
|
||
|---|---|---|
|
||
| `TextBox` | — | 底层基础文本输入控件(内部基类) |
|
||
| `LineEdit` | `Input` | 单行输入框,支持前缀/后缀装饰、左右附加组件(AddOn) |
|
||
| `SearchEdit` | `Input.Search` | 搜索输入框,带有搜索按钮 |
|
||
| `TextArea` | `Input.TextArea` | 多行文本域,支持自适应高度、字符计数、可拖拽调整大小 |
|
||
|
||
> 注意:Ant Design 的 `Input.Password` 在 AtomUI 中并非独立控件,而是通过 `LineEdit` 的 `PasswordChar` + `IsEnableRevealButton` 属性组合实现。
|
||
|
||
---
|
||
|
||
## 设计原理
|
||
|
||
### Ant Design 的输入框设计哲学
|
||
|
||
Ant Design 对输入框的定位是:**「通过鼠标或键盘输入内容,是最基础的表单域的包装」**。为了适配不同的使用场景,Ant Design 建立了一套完整的输入框变体体系:
|
||
|
||
**四种输入框变体**:
|
||
|
||
| 变体 | 设计意图 | 典型用途 |
|
||
|---|---|---|
|
||
| 📝 **基础输入框(Input)** | 最常用的单行文本输入 | 用户名、邮箱、地址等 |
|
||
| 🔍 **搜索框(Input.Search)** | 带搜索操作的输入框,右侧附带搜索按钮或图标 | 全局搜索、列表过滤 |
|
||
| 🔒 **密码框(Input.Password)** | 遮蔽输入内容,带可选的明文切换按钮 | 登录密码、安全验证 |
|
||
| 📄 **文本域(Input.TextArea)** | 多行文本输入,可自适应高度 | 评论、备注、描述 |
|
||
|
||
**四种样式变体**(所有输入框类型均支持):
|
||
|
||
| 变体 | 设计意图 |
|
||
|---|---|
|
||
| 📦 **Outline(默认)** | 标准边框样式,最通用的输入框外观 |
|
||
| 🎨 **Filled** | 填充背景样式,在复杂表单中降低视觉噪音 |
|
||
| ➖ **Borderless** | 无边框样式,用于特定场景下的极简风格 |
|
||
| 📏 **Underlined** | 下划线样式,Material Design 风格 |
|
||
|
||
**两种验证状态**:
|
||
|
||
| 状态 | 设计意图 |
|
||
|---|---|
|
||
| ⚠️ **Warning** | 橙色边框,提示用户输入可能存在问题 |
|
||
| ❌ **Error** | 红色边框,明确告知用户输入不合法 |
|
||
|
||
### Avalonia TextBox 基础能力
|
||
|
||
AtomUI 的输入框控件族构建在 Avalonia 框架的 `Avalonia.Controls.TextBox` 之上。Avalonia TextBox 的继承链为:
|
||
|
||
```
|
||
Control → TemplatedControl → InputElement → TextBox
|
||
```
|
||
|
||
**Avalonia TextBox 提供的核心能力:**
|
||
|
||
| 能力 | 说明 |
|
||
|---|---|
|
||
| 文本编辑 | `Text` 双向绑定、光标管理(`CaretIndex`)、选区(`SelectionStart` / `SelectionEnd`) |
|
||
| 密码模式 | `PasswordChar` 掩码字符、`RevealPassword` 明文切换 |
|
||
| 多行支持 | `AcceptsReturn`、`AcceptsTab`、`MaxLines` / `MinLines` |
|
||
| 输入限制 | `MaxLength`、`IsReadOnly` |
|
||
| 占位文本 | `Watermark`(AtomUI 使用 `PlaceholderText` 替代) |
|
||
| 滚动支持 | 内置 `ScrollViewer` 支持文本超出可视区域时滚动 |
|
||
| 键盘导航 | 支持 Tab 导航、焦点管理 |
|
||
|
||
**Avalonia TextBox 提供的基础伪类:**
|
||
|
||
| 伪类 | 说明 |
|
||
|---|---|
|
||
| `:pointerover` | 鼠标悬浮 |
|
||
| `:focus` | 获得焦点 |
|
||
| `:focus-visible` | 通过键盘获得焦点 |
|
||
| `:disabled` | `IsEnabled == false` |
|
||
| `:empty` | 文本为空 |
|
||
|
||
### AtomUI 的扩展设计
|
||
|
||
AtomUI 在 Avalonia TextBox 的基础上,遵循 Ant Design 5.0 规范做了以下扩展:
|
||
|
||
| 扩展能力 | 实现方式 | 设计动机 |
|
||
|---|---|---|
|
||
| **四种样式变体** | `StyleVariant` 枚举 + 伪类驱动样式 | 对齐 Ant Design 的 `variant` 属性 |
|
||
| **验证状态反馈** | `Status` 枚举 + `IInputControlStatusAware` 接口 | 对齐 Ant Design 的 `status`,与 Form 表单验证无缝集成 |
|
||
| **三种尺寸** | `ISizeTypeAware` 接口 + `SizeType` 共享属性 | 全局统一的 Large / Middle / Small 尺寸系统 |
|
||
| **AddOn 装饰机制** | `AddOnDecoratedBox` 容器 | 支持左右附加组件(LeftAddOn / RightAddOn)和内部前后缀装饰 |
|
||
| **清除按钮** | `IsAllowClear` 属性 + `InputClearIconButton` | 内置清除图标,点击清空输入内容 |
|
||
| **密码显示切换** | `IsEnableRevealButton` + `RevealButton` | 复刻 Ant Design Input.Password 的密码可见性切换 |
|
||
| **字符计数** | `IsShowCount` + `MaxLength` | 实时显示已输入字符数 / 最大字符数 |
|
||
| **搜索按钮** | `SearchEdit` + `SearchButton` | 复刻 Ant Design Input.Search 的搜索按钮交互 |
|
||
| **自适应高度** | `TextArea.IsAutoSize` + `MinLines` / `MaxLines` | 文本域根据内容自动调整高度 |
|
||
| **可拖拽调整** | `TextArea.IsResizable` + `ResizeHandle` | 文本域支持拖拽调整大小 |
|
||
| **紧凑空间** | `ICompactSpaceAware` 接口 | 在 `Space.Compact` 中自动调整圆角和边框 |
|
||
| **表单集成** | `IFormItemAware` + `IFormItemFeedbackAware` | 可参与 FormItem 验证流程 |
|
||
| **Design Token** | `LineEditToken` / `TextAreaToken` | 所有视觉值从全局 Token 派生,支持主题切换 |
|
||
|
||
---
|
||
|
||
## 控件层级关系
|
||
|
||
Input 控件族的所有控件均定义在桌面端控件层(`AtomUI.Desktop.Controls`),没有对应的设备无关基类(`AtomUI.Controls` 层),因为这些控件直接继承自 Avalonia 的 `TextBox`。
|
||
|
||
```
|
||
Avalonia.Controls.TextBox
|
||
└── AtomUI.Desktop.Controls.TextBox (ISizeTypeAware, IMotionAwareControl, ICompactSpaceAware, IFormItemAware)
|
||
├── AtomUI.Desktop.Controls.LineEdit (+ IInputControlStatusAware, IInputControlStyleVariantAware)
|
||
│ └── AtomUI.Desktop.Controls.SearchEdit (+ SearchButtonClick 事件)
|
||
└── [独立继承]
|
||
AtomUI.Desktop.Controls.TextArea (ISizeTypeAware, IMotionAwareControl, IInputControlStatusAware, IInputControlStyleVariantAware, IFormItemAware)
|
||
```
|
||
|
||
### 各层级职责划分
|
||
|
||
| 层级 | 提供的能力 |
|
||
|---|---|
|
||
| `Avalonia.Controls.TextBox` | 文本编辑(输入/删除/选区/光标)、密码模式、多行支持、输入限制、滚动、键盘导航 |
|
||
| `AtomUI.Desktop.Controls.TextBox` | 尺寸系统(`SizeType`)、清除按钮(`IsAllowClear`)、密码可见性切换(`IsEnableRevealButton`)、字符计数(`IsShowCount`)、占位文本(`PlaceholderText`)、紧凑空间适配、表单集成、过渡动画 |
|
||
| `AtomUI.Desktop.Controls.LineEdit` | 样式变体(`StyleVariant`)、验证状态(`Status`)、AddOn 装饰(LeftAddOn / RightAddOn + InnerLeftContentTemplate / InnerRightContentTemplate)、与 `AddOnDecoratedBox` 集成 |
|
||
| `AtomUI.Desktop.Controls.SearchEdit` | 搜索按钮样式(`SearchButtonStyle`)、搜索按钮文本(`SearchButtonText`)、加载状态(`IsOperating`)、搜索按钮点击事件(`SearchButtonClick`) |
|
||
| `AtomUI.Desktop.Controls.TextArea` | 多行输入(`Lines`)、自适应高度(`IsAutoSize`)、可拖拽调整大小(`IsResizable`)、样式变体、验证状态、内部前后缀装饰 |
|
||
|
||
### 实现的共享接口
|
||
|
||
| 接口 | 定义位置 | 控件 | 作用 |
|
||
|---|---|---|---|
|
||
| `ISizeTypeAware` | `AtomUI.Controls.Shared` | TextBox, TextArea | 支持 `SizeType`(Small / Middle / Large)尺寸切换 |
|
||
| `IMotionAwareControl` | `AtomUI.Controls.Shared` | TextBox, TextArea | 支持动画开关 |
|
||
| `ICompactSpaceAware` | `AtomUI.Controls.Shared` | TextBox | 在 `Space.Compact` 中使用时自动调整圆角和边框 |
|
||
| `IFormItemAware` | `AtomUI.Controls.Shared` | TextBox, TextArea | 参与 FormItem 表单验证 |
|
||
| `IFormItemFeedbackAware` | `AtomUI.Controls.Shared` | TextBox, TextArea | 接收表单验证反馈控件 |
|
||
| `IInputControlStatusAware` | `AtomUI.Controls.Shared` | LineEdit, TextArea | 支持验证状态反馈(Error / Warning) |
|
||
| `IInputControlStyleVariantAware` | `AtomUI.Controls.Shared` | LineEdit, TextArea | 支持样式变体切换(Outline / Filled / Borderless) |
|
||
|
||
---
|
||
|
||
## 功能详解
|
||
|
||
### 装饰机制(AddOnDecoratedBox)
|
||
|
||
LineEdit 使用 `AddOnDecoratedBox` 作为装饰容器,提供了灵活的布局扩展能力:
|
||
|
||
```
|
||
┌──────────────────────────────────────────────────────────────────────┐
|
||
│ LeftAddOn │ InnerLeft │ [Text Input] │ InnerRight │ RightAddOn │
|
||
│ (http://)│ (🔍 icon)│ │ (clear/eye)│ (.com) │
|
||
└──────────────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
- **LeftAddOn / RightAddOn**:输入框外侧的附加组件,通过 `AddOnDecoratedBox` 的外部附加区域实现,常用于固定的前缀/后缀标签(如 `http://`、`.com`)。
|
||
- **InnerLeftContentTemplate / InnerRightContentTemplate**:输入框内侧的装饰元素,位于 `AddOnDecoratedBox` 的内容区域内,常用于图标(搜索图标、用户图标)。
|
||
- **ContentRightAddOn**(模板内部):清除按钮、密码切换按钮、表单反馈图标等功能性元素。
|
||
|
||
### 搜索框特性(SearchEdit)
|
||
|
||
SearchEdit 继承自 LineEdit,额外提供:
|
||
|
||
- **SearchButtonStyle**:搜索按钮样式,支持 `Default`(仅图标)和 `Primary`(主色调按钮)两种。
|
||
- **SearchButtonText**:搜索按钮文字,设置后按钮显示文字而非图标。
|
||
- **IsOperating**:加载状态,设为 `true` 时搜索按钮显示加载动画。
|
||
- **SearchButtonClick**:搜索按钮点击事件,路由事件(Bubble 策略)。
|
||
|
||
搜索框内部使用 `SearchEditDecoratedBox`(继承自 `AddOnDecoratedBox`)和 `SearchEditPanel`(自定义 Panel)实现独特的搜索按钮布局。
|
||
|
||
### 多行文本域特性(TextArea)
|
||
|
||
TextArea 独立继承自 Avalonia TextBox(不通过 AtomUI TextBox),提供:
|
||
|
||
- **Lines**:指定显示行数(默认 2),自动计算高度。
|
||
- **IsAutoSize**:开启后根据输入内容自动调整高度。
|
||
- **MinLines / MaxLines**:配合 `IsAutoSize` 限制自适应高度范围。
|
||
- **IsResizable**:开启后右下角显示拖拽手柄,可手动调整高度。
|
||
- **字符计数**:通过 `IsShowCount` + `MaxLength` 显示 `已输入 / 最大` 格式的计数。
|
||
|
||
TextArea 内部使用 `TextAreaDecoratedBox`(继承自 `AddOnDecoratedBox`)和 `ResizeHandle`(拖拽手柄控件)。
|
||
|
||
### 清除与密码切换
|
||
|
||
- **清除按钮**:由 `InputClearIconButton`(继承自 `IconButton`)实现,默认使用 `CloseCircleFilled` 图标。仅当 `IsAllowClear == true` 且文本不为空且非只读时显示。
|
||
- **密码切换按钮**:由 `RevealButton`(继承自 `ToggleIconButton`)实现,默认使用 `EyeOutlined`(已选中/可见)和 `EyeInvisibleOutlined`(未选中/隐藏)图标,通过 `IsEnableRevealButton` 启用。
|
||
|
||
### 表单集成
|
||
|
||
TextBox 和 TextArea 均实现了 `IFormItemAware` 和 `IFormItemFeedbackAware` 接口:
|
||
|
||
- **SetFormValue / GetFormValue / ClearFormValue**:表单系统可通过统一接口读写输入值。
|
||
- **NotifyValidateStatus**:表单验证失败时自动设置 `Status`(仅 LineEdit 和 TextArea 支持,因为它们实现了 `IInputControlStatusAware`)。
|
||
- **SetFeedbackControl**:接收并显示表单验证反馈控件(如错误/成功图标)。
|
||
|
||
### CompactSpace 支持
|
||
|
||
TextBox 实现了 `ICompactSpaceAware` 接口,在 `Space.Compact` 容器中:
|
||
- 根据位置(First / Middle / Last / OnlyOne)自动裁剪圆角。
|
||
- LineEdit 会根据内部 `AddOnDecoratedBox` 的边框厚度提供紧凑边框值。
|
||
|
||
---
|
||
|
||
## 与 Ant Design 规范的对齐程度
|
||
|
||
| 特性 | Ant Design (React) | AtomUI (Avalonia) | 对齐情况 |
|
||
|---|---|---|---|
|
||
| 基础输入 `Input` | ✅ | ✅ `LineEdit` | ✅ 完全对齐 |
|
||
| 搜索框 `Input.Search` | ✅ | ✅ `SearchEdit` | ✅ 完全对齐 |
|
||
| 密码框 `Input.Password` | ✅ 独立组件 | ✅ `LineEdit` + `PasswordChar` + `IsEnableRevealButton` | ✅ 功能对齐(非独立组件) |
|
||
| 文本域 `Input.TextArea` | ✅ | ✅ `TextArea` | ✅ 完全对齐 |
|
||
| 前缀/后缀 `prefix`/`suffix` | ✅ | ✅ `InnerLeftContentTemplate` / `InnerRightContentTemplate` | ✅ 完全对齐 |
|
||
| 前置/后置标签 `addonBefore`/`addonAfter` | ✅ | ✅ `LeftAddOn` / `RightAddOn` | ✅ 完全对齐 |
|
||
| 样式变体 `variant` | ✅ `outlined/filled/borderless` | ✅ `StyleVariant` + `Underlined` | ✅ 完全对齐(多一个 Underlined) |
|
||
| 验证状态 `status` | ✅ `error/warning` | ✅ `Status` | ✅ 完全对齐 |
|
||
| 允许清除 `allowClear` | ✅ | ✅ `IsAllowClear` | ✅ 完全对齐 |
|
||
| 字符计数 `showCount` | ✅ | ✅ `IsShowCount` | ✅ 完全对齐 |
|
||
| 自适应高度 `autoSize` | ✅ | ✅ `IsAutoSize` + `MinLines` / `MaxLines` | ✅ 完全对齐 |
|
||
| 搜索按钮 `enterButton` | ✅ | ✅ `SearchButtonStyle` + `SearchButtonText` | ✅ 完全对齐 |
|
||
| 搜索加载 `loading` | ✅ | ✅ `IsOperating` | ✅ 完全对齐 |
|
||
| 禁用 `disabled` | ✅ | ✅ `IsEnabled` | ✅ 完全对齐 |
|
||
| 可拖拽调整大小 | ✅ CSS resize | ✅ `IsResizable` + `ResizeHandle` | ✅ 完全对齐 |
|
||
| `onChange` 回调 | ✅ | ✅ `TextChangedEvent` + `IFormItemAware.ValueChanged` | ✅ 完全对齐 |
|
||
| `onSearch` 回调 | ✅ | ✅ `SearchButtonClick` 事件 | ✅ 完全对齐 |
|
||
|
||
---
|
||
|
||
## 源码位置
|
||
|
||
| 层级 | 文件路径 | 说明 |
|
||
|---|---|---|
|
||
| TextBox 基类 | `src/AtomUI.Desktop.Controls/Input/TextBox.cs` | 底层文本输入控件(内部基类) |
|
||
| LineEdit 控件 | `src/AtomUI.Desktop.Controls/Input/LineEdit.cs` | 单行输入框实现 |
|
||
| SearchEdit 控件 | `src/AtomUI.Desktop.Controls/Input/SearchEdit.cs` | 搜索输入框实现 |
|
||
| TextArea 控件 | `src/AtomUI.Desktop.Controls/Input/TextArea.cs` | 多行文本域实现 |
|
||
| LineEdit Token | `src/AtomUI.Desktop.Controls/Input/LineEditToken.cs` | LineEdit / TextBox 组件 Token |
|
||
| TextArea Token | `src/AtomUI.Desktop.Controls/Input/TextAreaToken.cs` | TextArea 组件 Token |
|
||
| TextBox 主题 | `src/AtomUI.Desktop.Controls/Input/Themes/TextBoxTheme.axaml` | TextBox ControlTheme |
|
||
| LineEdit 主题 | `src/AtomUI.Desktop.Controls/Input/Themes/LineEditTheme.axaml` | LineEdit ControlTheme |
|
||
| SearchEdit 主题 | `src/AtomUI.Desktop.Controls/Input/Themes/SearchEditTheme.axaml` | SearchEdit ControlTheme |
|
||
| TextArea 主题 | `src/AtomUI.Desktop.Controls/Input/Themes/TextAreaTheme.axaml` | TextArea ControlTheme |
|
||
| 主题常量 | `src/AtomUI.Desktop.Controls/Input/Themes/InputThemeConstants.cs` | 模板部件名称常量 |
|
||
| 搜索按钮 | `src/AtomUI.Desktop.Controls/Input/SearchButton.cs` | 搜索按钮内部控件 |
|
||
| 搜索装饰盒 | `src/AtomUI.Desktop.Controls/Input/SearchEditDecoratedBox.cs` | 搜索编辑框装饰容器 |
|
||
| 搜索布局面板 | `src/AtomUI.Desktop.Controls/Input/SearchEditPanel.cs` | 搜索编辑框布局面板 |
|
||
| 清除按钮 | `src/AtomUI.Desktop.Controls/Input/InputClearIconButton.cs` | 清除图标按钮 |
|
||
| 密码切换按钮 | `src/AtomUI.Desktop.Controls/Input/RevealButton.cs` | 密码显示/隐藏切换按钮 |
|
||
| 文本域装饰盒 | `src/AtomUI.Desktop.Controls/Input/TextAreaDecoratedBox.cs` | 文本域装饰容器 |
|
||
| 拖拽手柄 | `src/AtomUI.Desktop.Controls/Input/ResizeHandle.cs` | 文本域拖拽调整大小手柄 |
|
||
| Gallery 示例 | `controlgallery/AtomUIGallery/ShowCases/Views/DataEntry/LineEditShowCase.axaml` | 使用范例 |
|
||
|
||
---
|
||
|
||
## 模板结构
|
||
|
||
### LineEdit 模板结构
|
||
|
||
LineEdit 使用 `AddOnDecoratedBox` 作为根容器,提供完整的装饰能力:
|
||
|
||
```
|
||
AddOnDecoratedBox (PART_AddOnDecoratedBox)
|
||
├── [LeftAddOn 区域] ← 左侧附加组件(如 "http://")
|
||
├── [ContentLeftAddOn 区域] ← 内侧左装饰(如用户图标)
|
||
├── [主内容区域]
|
||
│ └── ScrollViewer (PART_ScrollViewer)
|
||
│ └── Panel
|
||
│ ├── TextBlock#Placeholder ← 占位文本(Text 为空时显示)
|
||
│ └── TextPresenter ← 文本展示器(PART_TextPresenter)
|
||
├── [ContentRightAddOn 区域] ← 内侧右装饰
|
||
│ └── StackPanel (Horizontal)
|
||
│ ├── InputClearIconButton ← 清除按钮(PART_ClearButton)
|
||
│ ├── RevealButton ← 密码显示切换(PART_RevealButton)
|
||
│ ├── ContentPresenter#FormFeedBack ← 表单验证反馈图标
|
||
│ ├── ContentPresenter ← InnerRightContent 展示
|
||
│ └── TextBlock#TextCountIndicator ← 字符计数显示
|
||
└── [RightAddOn 区域] ← 右侧附加组件(如 ".com")
|
||
```
|
||
|
||
### SearchEdit 模板结构
|
||
|
||
SearchEdit 的模板基于 LineEdit,但使用 `SearchEditDecoratedBox` 替代标准 `AddOnDecoratedBox`,搜索按钮通过 `SearchEditPanel` 进行特殊布局。
|
||
|
||
### TextArea 模板结构
|
||
|
||
```
|
||
DockPanel
|
||
├── TextBlock#TextCountIndicator (Dock=Bottom) ← 字符计数(底部对齐)
|
||
└── Panel
|
||
├── TextAreaDecoratedBox (PART_AddOnDecoratedBox)
|
||
│ ├── [ContentRightAddOn 区域]
|
||
│ │ └── StackPanel (Vertical)
|
||
│ │ ├── InputClearIconButton ← 清除按钮(PART_ClearButton)
|
||
│ │ ├── ContentPresenter#FormFeedBack ← 表单反馈
|
||
│ │ └── ContentPresenter ← InnerRightContent
|
||
│ └── Panel#ContentLayout
|
||
│ ├── TextBlock#Placeholder ← 占位文本
|
||
│ └── TextPresenter ← 文本展示器(PART_TextPresenter)
|
||
└── ResizeHandle (PART_ResizeHandle) ← 拖拽调整大小手柄(右下角)
|
||
```
|
||
|
||
### 模板部件常量
|
||
|
||
| 常量名 | 值 | 说明 |
|
||
|---|---|---|
|
||
| `TextBoxThemeConstants.ClearButtonPart` | `"PART_ClearButton"` | 清除按钮 |
|
||
| `TextBoxThemeConstants.RevealButtonPart` | `"PART_RevealButton"` | 密码显示切换按钮 |
|
||
| `TextAreaThemeConstants.ResizeHandle` | `"PART_ResizeHandle"` | 拖拽调整大小手柄 |
|
||
| `TextAreaThemeConstants.ScrollViewerPart` | `"PART_ScrollViewer"` | 文本域滚动容器 |
|
||
| `TextAreaThemeConstants.ClearButtonPart` | `"PART_ClearButton"` | 文本域清除按钮 |
|
||
| `TextAreaThemeConstants.TextPresenterPart` | `"PART_TextPresenter"` | 文本展示器 |
|