Inputs: components 021-030

This commit is contained in:
ZacharyZhang-NY committed 2026-10-05 12:17:01 -04:00
1 parent a61ac6168a
commit 1b025b5fad
64 files changed
+3090 -11

No files matched your search

+43
View File
@@ -0,0 +1,43 @@
# 021 Button 按钮
## 用途
触发一个操作。提供主按钮、次按钮、描边、无底色和危险五种变体,可带图标,可显示加载与禁用。基于 MyGo `ui.ButtonBase`。
## 最小示例
```go
if mujica.Button(c, "Save", mujica.ButtonOptions{Icon: icons.Must("check")}).Clicked() {
fmt.Println("saved")
}
```
签名:`func Button(c *ui.Context, label string, opts ButtonOptions) *ui.Element`
## 参数
| 字段 | 类型 | 默认值 | 含义 |
| --- | --- | --- | --- |
| `label` | `string` | 必填(仅图标时可为空) | 按钮文字。 |
| `Variant` | `ButtonVariant` | `Primary` | `Primary`、`Secondary`、`Outline`、`Ghost`、`Danger`。 |
| `Icon` | `*ui.SVG` | `nil` | 文字前的 16 DIP 图标。 |
| `Loading` | `bool` | `false` | 以菱形加载标记替换图标,保留尺寸与文字,阻止点击。 |
| `Disabled` | `bool` | `false` | 不可点击、不进入 Tab 序列。 |
| `Label` | `string` | `""` | 无文字按钮的无障碍名称。 |
## 状态
默认、悬停(底色加深或出现浅底)、按下、键盘聚焦(2 DIP 酒红焦点环,外留 2 DIP)、加载、禁用(MyGo 统一减淡)。高度不低于当前密度的控件高度(28/36/44 DIP)。
## 事件
`Clicked()`:鼠标在按钮内释放、Enter 或 Space 时为真,一次操作只报告一次。加载与禁用时始终为假。
## 键盘操作
Tab / Shift+Tab 聚焦;Enter 或 Space 触发。
## 限制
- 加载标记在减少动画模式下静止显示。
- 危险变体的悬停与按下色由 `DangerFill` 混合黑色得到,未单独定义变量。
+42
View File
@@ -0,0 +1,42 @@
# 022 IconButton 图标按钮
## 用途
只显示图标的方形按钮,用于工具栏与紧凑操作。操作名称必填,供辅助技术朗读,并作为默认提示文字。建立在 Button 之上。
## 最小示例
```go
if mujica.IconButton(c, icons.Must("settings"), "Settings", mujica.IconButtonOptions{Variant: mujica.Ghost}).Clicked() {
fmt.Println("open settings")
}
```
签名:`func IconButton(c *ui.Context, icon *ui.SVG, label string, opts IconButtonOptions) *ui.Element`
## 参数
| 字段 | 类型 | 默认值 | 含义 |
| --- | --- | --- | --- |
| `icon` | `*ui.SVG` | 必填 | 图标;为 nil 时 panic。 |
| `label` | `string` | 必填 | 操作名称;为空时 panic。 |
| `Variant` | `ButtonVariant` | `Primary` | 与 Button 相同的五种变体;工具栏通常用 `Ghost`。 |
| `Tooltip` | `string` | 操作名称 | 悬停约 600 毫秒后显示的提示。 |
| `Loading` | `bool` | `false` | 显示加载标记并阻止点击。 |
| `Disabled` | `bool` | `false` | 禁用。 |
## 状态
同 Button:悬停、按下、聚焦、加载、禁用。边长等于当前密度的控件高度,不小于 28 DIP。
## 事件
`Clicked()`,一次操作一次。
## 键盘操作
Tab 聚焦;Enter 或 Space 触发。
## 限制
- 禁用时不显示提示:MyGo 的 `Hovered` 对禁用元素返回 false,提示随之不出现;名称仍作为无障碍描述保留。
+53
View File
@@ -0,0 +1,53 @@
# 023 ButtonGroup 按钮组
## 用途
把若干按钮拼成一条,共用边框与尺寸,只有外侧圆角。整个组是一个 Tab 停靠点,组内用方向键移动。基于 `ui.ButtonBase` 与 MyGo 焦点组 `FocusGroup`。
## 最小示例
```go
items := []mujica.ButtonGroupItem{{Label: "Day"}, {Label: "Week"}, {Label: "Month"}}
if i := mujica.ButtonGroup(c, items, mujica.ButtonGroupOptions{Label: "Range"}).ClickedItem(); i >= 0 {
fmt.Println("chose", items[i].Label)
}
```
签名:`func ButtonGroup(c *ui.Context, items []ButtonGroupItem, opts ButtonGroupOptions) ButtonGroupResult`
## 参数
`ButtonGroupItem`
| 字段 | 类型 | 默认值 | 含义 |
| --- | --- | --- | --- |
| `Label` | `string` | `""` | 文字;与 `Icon` 至少给一个,否则 panic。 |
| `Icon` | `*ui.SVG` | `nil` | 图标。 |
| `Name` | `string` | `""` | 仅图标项的无障碍名称。 |
| `Disabled` | `bool` | `false` | 单项禁用;方向键跳过该项。 |
`ButtonGroupOptions`
| 字段 | 类型 | 默认值 | 含义 |
| --- | --- | --- | --- |
| `Vertical` | `bool` | `false` | 纵向排列,使用上下方向键。 |
| `Label` | `string` | `""` | 组的无障碍名称(工具栏角色)。 |
| `Disabled` | `bool` | `false` | 禁用整组。 |
`items` 为空时 panic。
## 状态
每项有悬停、按下、聚焦、禁用;相邻项共用一条 1 DIP 分隔边。
## 事件
`ClickedItem()` 返回本帧被点击项的下标,无点击时为 -1。
## 键盘操作
Tab 进入组(回到上次聚焦项);横向组 Left/Right、纵向组 Up/Down 移动并循环;Home、End 到首末项;Enter 或 Space 触发。
## 限制
- 组内没有选中概念;需要保持选中请使用 ToggleGroup(033)。
+49
View File
@@ -0,0 +1,49 @@
# 024 TextInput 文本输入框
## 用途
单行文本编辑。支持占位、前后插槽、清空、只读与错误。编辑核心是 MyGo `ui.TextInputBase`,因此保留选择、撤销重做、剪贴板、右键菜单与输入法组合。
## 最小示例
```go
r := mujica.TextInput(c, &name, mujica.TextInputOptions{Label: "Name", Placeholder: "Your name", Clearable: true})
if r.Submitted() {
fmt.Println("hello", name)
}
```
签名:`func TextInput(c *ui.Context, value *string, opts TextInputOptions) InputResult`
`InputResult` 内嵌外层 `*ui.Element`,`Input` 字段是内部编辑元素,`Changed()`、`Submitted()` 报告事件。
## 参数
| 字段 | 类型 | 默认值 | 含义 |
| --- | --- | --- | --- |
| `value` | `*string` | 必填 | 编辑的字符串;nil 时 panic。 |
| `Placeholder` | `string` | `""` | 空值时的占位文字(TextMuted 色)。 |
| `Label` | `string` | `""` | 无障碍名称,也供测试查找。 |
| `Leading` / `Trailing` | `func()` | `nil` | 在框内左侧、右侧构建内容,如图标或单位。 |
| `Clearable` | `bool` | `false` | 有内容时显示清空按钮;Escape 也会清空。 |
| `Disabled` | `bool` | `false` | 禁用,不可聚焦。 |
| `ReadOnly` | `bool` | `false` | 可聚焦、选择、复制,不可修改。 |
| `Error` | `string` | `""` | 非空时边框变为 Danger,并在下方显示该文字;辅助技术同时朗读。 |
## 状态
默认(Surface 底、ControlBorder 边)、悬停(边框加深)、聚焦(边框 Focus 色;键盘聚焦另加焦点环)、只读(Background 底、Border 边)、错误、禁用。颜色变化 120 毫秒过渡,减少动画时直接切换。
## 事件
- `Changed()`:输入、粘贴、撤销或清空改变了值。只读时不会报告。
- `Submitted()`:在框内按 Enter。
## 键盘操作
Tab 聚焦(全选内容);Enter 提交;Escape 清空(仅 `Clearable` 且有内容时,否则交给外层);Cmd/Ctrl+Z、Shift+Cmd+Z 撤销重做;Cmd/Ctrl+A/C/X/V;输入法组合期间不提交。
## 限制
- MyGo 没有公开的只读输入接口(只读模式仅用于 `Text.Selectable`,`editor.go:77`)。`ReadOnly` 通过让编辑器编辑一个副本并在同帧还原实现,撤销栈里可能出现被还原的步骤。
- 清空按钮不进入 Tab 序列(与 MyGo SearchField 相同),键盘用 Escape 清空。
+49
View File
@@ -0,0 +1,49 @@
# 025 TextArea 多行文本框
## 用途
多行文本编辑,可设最小与最大高度,超出最大高度后在框内滚动;可显示字数;提交快捷键可配置。编辑核心是 MyGo `ui.TextAreaBase`,只排版可见段落,适合长文本。
## 最小示例
```go
r := mujica.TextArea(c, &notes, mujica.TextAreaOptions{Label: "Notes", MaxHeight: 160, MaxLength: 200})
if r.Submitted() {
fmt.Println("send", notes)
}
```
签名:`func TextArea(c *ui.Context, value *string, opts TextAreaOptions) InputResult`
## 参数
| 字段 | 类型 | 默认值 | 含义 |
| --- | --- | --- | --- |
| `value` | `*string` | 必填 | 编辑的字符串。 |
| `Placeholder` | `string` | `""` | 占位文字。 |
| `Label` | `string` | `""` | 无障碍名称。 |
| `MinHeight` | `float32` | `0`(三行) | 编辑区最小高度,DIP。 |
| `MaxHeight` | `float32` | `0`(随内容增长) | 编辑区最大高度,超出后滚动;小于 `MinHeight` 时 panic。 |
| `MaxLength` | `int` | `0`(不显示) | 显示“当前 / 上限”字数(按 Unicode 字符计);超出时变红并提示超出数量。 |
| `SubmitKey` / `SubmitMods` | `ui.Key` / `ui.Modifiers` | Cmd+Enter(非 macOS 为 Ctrl+Enter) | 提交快捷键;`SubmitKey` 为零时使用默认值。 |
| `Disabled` | `bool` | `false` | 禁用。 |
| `ReadOnly` | `bool` | `false` | 只读,可选择复制。 |
| `Error` | `string` | `""` | 错误文字;为空且超出 `MaxLength` 时自动显示超出提示。 |
## 状态
默认、悬停、聚焦、只读、错误、禁用,表现同 TextInput。
## 事件
`Changed()`:内容被用户改变。`Submitted()`:按下提交快捷键。
## 键盘操作
Enter 与 Shift+Enter 换行;提交快捷键提交;方向键、PageUp/PageDown 移动光标并滚动;撤销、剪贴板与输入法同 TextInput。
## 限制
- `MaxLength` 只提示,不截断输入,以免打断输入法组合与粘贴。
- 提交快捷键不能是不带修饰键的 Enter:MyGo 编辑器先接收 Enter 并插入换行(`editor.go:161`)。
- 只读实现方式同 TextInput。
+49
View File
@@ -0,0 +1,49 @@
# 026 NumberInput 数字输入框
## 用途
输入与步进数值,支持范围、步长、精度与空值。合并 MyGo 的 Number input(输入模式)与 Stepper(`StepperOnly` 仅步进模式)。
## 最小示例
```go
if mujica.NumberInput(c, &copies, mujica.NumberInputOptions{Min: 1, Max: 99, Label: "Copies"}).Changed() {
fmt.Println("copies", copies)
}
```
签名:`func NumberInput(c *ui.Context, value *float64, opts NumberInputOptions) InputResult`
## 参数
| 字段 | 类型 | 默认值 | 含义 |
| --- | --- | --- | --- |
| `value` | `*float64` | 必填 | 数值;空值用 `math.NaN()` 表示,仅在 `AllowEmpty` 时允许。 |
| `Min` / `Max` | `float64` | 都为 0 | 范围;相等(含零值)表示不限范围;`Min > Max` 时 panic。 |
| `Step` | `float64` | `1` | 方向键与按钮的步长;负数 panic。 |
| `Precision` | `int` | 取 `Step` 的小数位 | 保留与显示的小数位。 |
| `AllowEmpty` | `bool` | `false` | 允许清空,值变为 NaN;从空值步进时从 0(夹在范围内)开始。 |
| `StepperOnly` | `bool` | `false` | 只显示数值与上下箭头,不可输入;必须给出 `Min < Max`,且不能与 `AllowEmpty` 同用。 |
| `Placeholder` | `string` | `""` | 空值时的占位。 |
| `Label` | `string` | `""` | 无障碍名称。 |
| `Disabled` | `bool` | `false` | 禁用。 |
| `Error` | `string` | `""` | 调用方给出的错误。 |
## 状态
输入模式同 TextInput;输入非数字或超出范围时显示内置错误(“请输入数字”“请输入 a 到 b 之间的数字”),值保持上一次有效值;失去焦点后文本恢复为当前值并清除该错误。到达边界时对应按钮禁用。
## 事件
`Changed()`:值因输入、方向键、按钮或步进器改变。
## 键盘操作
输入模式:Up/Down 按步长增减。仅步进模式:Up/Right 增加、Down/Left 减少、Home 到最小、End 到最大;按住箭头持续步进。
## 限制
- 输入模式下的加减按钮不进入 Tab 序列,键盘用 Up/Down。
- 仅步进模式复用 MyGo `ui.Stepper`,箭头高度来自主题间距,不随密度的控件高度变化。
- MyGo `ui.Stepper` 的箭头不检查禁用(`indicators.go:216`),禁用时组件向它传入副本,保证值不被修改。
- MyGo 的步进器吸附依赖有限边界(`widgets.go` 中 `snap`),所以仅步进模式要求有界。
+42
View File
@@ -0,0 +1,42 @@
# 027 PasswordInput 密码输入框
## 用途
遮蔽显示的密码输入,带显示/隐藏切换。允许粘贴;遮蔽时不允许复制与剪切。基于 `ui.TextInputBase(...).Password()`,辅助技术读不到遮蔽中的值。组件从不记录密码内容。
## 最小示例
```go
if mujica.PasswordInput(c, &password, mujica.PasswordInputOptions{Label: "Password"}).Submitted() {
fmt.Println("signing in")
}
```
签名:`func PasswordInput(c *ui.Context, value *string, opts PasswordInputOptions) InputResult`
## 参数
| 字段 | 类型 | 默认值 | 含义 |
| --- | --- | --- | --- |
| `value` | `*string` | 必填 | 密码。 |
| `Placeholder` | `string` | `""` | 占位文字。 |
| `Label` | `string` | `""` | 无障碍名称。 |
| `Disabled` | `bool` | `false` | 禁用(切换按钮同时禁用)。 |
| `Error` | `string` | `""` | 错误文字。 |
## 状态
默认、悬停、聚焦、错误、禁用;遮蔽 / 显示两种模式,切换按钮的图标与名称(“显示密码”“隐藏密码”)随之变化。
## 事件
`Changed()`:内容改变。`Submitted()`:Enter。日志只写切换事件(`mujica: password_input reveal`,含是否显示),不写内容。
## 键盘操作
Tab 依次到输入框、切换按钮;切换按钮上 Space 或 Enter 切换;输入框中 Enter 提交,Cmd/Ctrl+V 粘贴。
## 限制
- MyGo 的 `Password()` 一旦设置无法撤销(`editor.go:791`),因此遮蔽与显示两种模式各用一个编辑器,切换时撤销历史和光标位置不保留,焦点留在切换按钮上。
- 显示模式下内容是普通文本,可复制,辅助技术可朗读——这是用户主动选择的结果。
+51
View File
@@ -0,0 +1,51 @@
# 028 SearchInput 搜索框
## 用途
搜索模式:放大镜、输入、清空与提交。查找栏模式(`Find`):在此基础上显示匹配数量、上一项与下一项,对应 MyGo 的 Search field 与 Find bar。匹配由调用方计算。
## 最小示例
```go
matches := 0
if query != "" {
matches = strings.Count(text, query)
}
r := mujica.SearchInput(c, &query, mujica.SearchInputOptions{Find: true, Matches: matches, Current: &current})
if r.Moved() {
fmt.Println("show match", current)
}
```
签名:`func SearchInput(c *ui.Context, query *string, opts SearchInputOptions) SearchInputResult`
## 参数
| 字段 | 类型 | 默认值 | 含义 |
| --- | --- | --- | --- |
| `query` | `*string` | 必填 | 查询文字。 |
| `Placeholder` | `string` | “搜索”或“查找” | 占位文字。 |
| `Label` | `string` | 占位文字 | 无障碍名称。 |
| `Disabled` | `bool` | `false` | 禁用(查找快捷键也停用)。 |
| `Find` | `bool` | `false` | 开启查找栏模式。 |
| `Matches` | `int` | `0` | 匹配数量;负数 panic。 |
| `Current` | `*int` | `nil` | 当前匹配下标;`Find` 时必填,组件会把它夹在有效范围内。 |
## 状态
同 TextInput;查找栏模式下显示“第 n 项,共 m 项”或“无匹配”(状态角色,变化时可被朗读),无匹配时上一项/下一项禁用。
## 事件
- `Changed()`:查询改变(含清空)。
- `Submitted()`:搜索模式下 Enter。
- `Moved()`:查找栏模式下当前匹配改变。
## 键盘操作
搜索模式:Enter 提交,Escape 清空。查找栏模式:Enter 下一项,Shift+Enter 上一项,macOS 上 Cmd+G / Shift+Cmd+G、其他平台 F3 / Shift+F3(窗口级),循环到首尾;Escape 清空。
## 限制
- MyGo 单行编辑器把 Shift+Enter 当作普通提交且不公开修饰键(`editor.go:489`,`submitMods` 未导出),组件用 `HandleInput` 先截获 Shift+Enter。
- 没有“完成/关闭”按钮;是否显示查找栏由调用方决定。
+51
View File
@@ -0,0 +1,51 @@
# 029 Checkbox 复选框
## 用途
切换布尔值,支持选中、未选、半选;点击方框或标签都会切换。`CheckboxGroup` 提供组内全选(对应 MyGo CheckboxGroup)。基于 `ui.CheckboxBase`。
## 最小示例
```go
mujica.CheckboxGroup(c, "Notifications", []mujica.CheckboxItem{
{Label: "Mail", Value: &mail},
{Label: "Calendar", Value: &calendar},
}, mujica.CheckboxGroupOptions{})
```
签名:
```go
func Checkbox(c *ui.Context, value *bool, label string, opts CheckboxOptions) *ui.Element
func CheckboxGroup(c *ui.Context, label string, items []CheckboxItem, opts CheckboxGroupOptions) InputResult
```
## 参数
`CheckboxOptions`
| 字段 | 类型 | 默认值 | 含义 |
| --- | --- | --- | --- |
| `Indeterminate` | `bool` | `false` | 显示半选横线;此时点击总是变为选中。是否半选由调用方决定。 |
| `Disabled` | `bool` | `false` | 禁用。 |
`CheckboxItem`:`Label string`、`Value *bool`(必填)、`Disabled bool`。`CheckboxGroupOptions`:`Disabled bool`。`items` 为空时 panic。
## 状态
未选(Surface 底、ControlBorder 边)、悬停与按下(AccentText 边)、选中(酒红底、象牙白勾)、半选(酒红底、象牙白横线)、键盘聚焦(方框外焦点环)、禁用。行高不低于密度控件高度。
全选框:全部选中为选中,部分选中为半选,全不选为未选。点击时若可用项未全选则全部勾选,否则全部清除;禁用项保持不变。
## 事件
- `Checkbox(...).Changed()`:用户切换了值。
- `CheckboxGroup(...).Changed()`:全选或任一项被切换。
## 键盘操作
Tab 聚焦(每个复选框一个停靠点);Space 切换。
## 限制
- MyGo 只有内部字段能把复选框报告为“mixed”(`access.go:307`,`checked` 未导出)。半选时组件在无障碍描述中加入“部分选中”,但角色状态仍报告为未选中。
+52
View File
@@ -0,0 +1,52 @@
# 030 RadioGroup 单选组
## 用途
在一组选项中选一个,横向或纵向排列;选项值是任意可比较类型,作为稳定标识。基于 `ui.RadioGroup` 与 `ui.RadioBase`,整组是一个 Tab 停靠点。
## 最小示例
```go
items := []mujica.RadioItem[string]{{Value: "s", Label: "Small"}, {Value: "m", Label: "Medium"}, {Value: "l", Label: "Large"}}
if mujica.RadioGroup(c, &size, items, mujica.RadioGroupOptions{Label: "Size"}).Changed() {
fmt.Println("size", size)
}
```
签名:`func RadioGroup[T comparable](c *ui.Context, value *T, items []RadioItem[T], opts RadioGroupOptions) InputResult`
## 参数
`RadioItem[T]`
| 字段 | 类型 | 默认值 | 含义 |
| --- | --- | --- | --- |
| `Value` | `T` | 必填 | 稳定选项值;重复时 panic。 |
| `Label` | `string` | `""` | 标签,点击标签也会选择。 |
| `Disabled` | `bool` | `false` | 单项禁用,方向键跳过。 |
`RadioGroupOptions`
| 字段 | 类型 | 默认值 | 含义 |
| --- | --- | --- | --- |
| `Horizontal` | `bool` | `false` | 横向排列。 |
| `Label` | `string` | `""` | 组的无障碍名称。 |
| `Disabled` | `bool` | `false` | 禁用整组。 |
`value` 为 nil 或 `items` 为空时 panic。`*value` 不在选项中时没有选中项。
## 状态
未选(空心圆)、悬停与按下(AccentText 边)、选中(酒红实心圆与象牙白圆点)、键盘聚焦、禁用。
## 事件
`Changed()`:用户选择了另一个值(点击、Space 或方向键)。
## 键盘操作
Tab 进入组并落在已选项;Up/Down/Left/Right 移动并直接选择,循环,跳过禁用项;Home、End 选择首末可用项。
## 限制
- 方向键对横向与纵向组都同时响应上下左右(MyGo `RadioGroup` 固定使用 `Horizontal|Vertical`)。