WIP feedback 3

This commit is contained in:
ZacharyZhang-NY committed 2026-10-05 12:19:28 -04:00
1 parent 036de19d86
commit 9ce5953640
17 files changed
+1148 -3

No files matched your search

+51
View File
@@ -0,0 +1,51 @@
# 091 Alert 提示条
## 用途
在页面内显示一条信息、成功、警告或错误提示,可带标题、一个操作按钮和关闭按钮。严重程度同时由左侧色条、图标和无障碍名称(如“Error”)表达,不只靠颜色。
## 最小示例
```go
open := true
r := mujica.Alert(c, &open, "The archive could not be read.", mujica.AlertOptions{
Severity: mujica.SeverityError,
Title: "Import failed",
Action: "Retry",
})
if r.Action {
// retry the import
}
```
签名:`func Alert(c *ui.Context, open *bool, message string, opts AlertOptions) AlertResult`
## 参数
| 字段 | 类型 | 默认值 | 含义 |
| --- | --- | --- | --- |
| `open` | `*bool` | `nil` | 非 nil 时显示关闭按钮,关闭后置为 `false`;为 `false` 时不构建任何元素。`nil` 表示不可关闭。 |
| `message` | `string` | 必填 | 正文;为空时 panic。 |
| `Severity` | `Severity` | `SeverityInfo` | `SeverityInfo`、`SeveritySuccess`、`SeverityWarning`、`SeverityError`。 |
| `Title` | `string` | `""` | 正文上方的粗体标题。 |
| `Action` | `string` | `""` | 操作按钮文字;为空不显示。 |
返回 `AlertResult{Element, Action, Closed}`;关闭状态下 `Element` 为 nil。
## 状态
四种严重程度;操作与关闭按钮有悬停、按下和 2 DIP 焦点环。警告与错误在出现或文字变化时通过 `Context.Announce` 播报一次。
## 事件
- `Action`:操作按钮被点击或经键盘触发。
- `Closed`:用户关闭;同时 `*open` 变为 `false`。
## 键盘操作
Tab 依次聚焦操作按钮与关闭按钮;Enter 或 Space 触发。
## 限制
- 信息与成功提示不主动播报,避免页面加载时打扰读屏用户。
- 关闭不带退出动画;需要动画时由调用方在外层加 `Transition`。
+58
View File
@@ -0,0 +1,58 @@
# 092 Toast 轻提示
## 用途
在窗口右下角短暂显示操作结果,可带一个操作(如撤销)与关闭按钮。每个窗口一条队列:按 ID 去重,同时最多显示 3 条,其余排队。
## 最小示例
```go
if mujica.Button(c, "Delete note", mujica.ButtonOptions{Variant: mujica.Danger}).Clicked() {
mujica.ShowToast(c, mujica.ToastMessage{ID: "note-1", Message: "Note deleted", Action: "Undo"})
}
// Last in the view:
if r := mujica.Toaster(c); r.Action == "note-1" {
// restore the note
}
```
接口:
- `func ShowToast(c *ui.Context, m ToastMessage)`:加入队列,须在界面线程调用(后台任务经 `Window.Update` 回到界面线程)。
- `func DismissToast(c *ui.Context, id string)`:关闭显示中或排队中的消息。
- `func Toaster(c *ui.Context) ToasterResult`:每帧在视图末尾调用一次,绘制消息并报告事件。
## 参数
`ToastMessage`:
| 字段 | 类型 | 默认值 | 含义 |
| --- | --- | --- | --- |
| `ID` | `string` | `Message` | 去重键。相同 ID 再次显示时替换内容并重新计时,不新增一条。 |
| `Severity` | `Severity` | `SeverityInfo` | 图标、色条与颜色。 |
| `Message` | `string` | 必填 | 文字;为空时 panic。 |
| `Action` | `string` | `""` | 操作按钮文字。 |
| `Duration` | `time.Duration` | `ToastDuration`(5 秒) | 显示时长;负数 panic。错误消息在为 0 时一直保留到用户关闭。 |
常量:`ToastDuration = 5 * time.Second`,`ToastVisible = 3`。
## 状态
- 排队消息在显示时才开始计时。
- 指针悬停或焦点位于消息内时暂停计时,离开后从剩余时间继续。
- 出现时向读屏播报文字;进出场 160 ms 位移与淡入,减少动画时直接切换。
## 事件
`ToasterResult{Action, Closed}`:本帧被点击操作或被关闭的消息 ID;两者都会移除该消息。到时自动消失不报告。
## 键盘操作
消息从不抢夺焦点,正在输入的文本框保持焦点。Tab 在页面之后到达消息中的按钮;焦点在消息内时 Escape 关闭该消息。
## 复用与限制
MyGo 自带 `c.Toast` / `c.ToastAction`(docs/ui/toast.md),但它按文字去重、没有 ID、不限制条数、无关闭按钮、错误不能常驻、外观不可替换,计时只在悬停时暂停而不在聚焦时暂停。这些都是 PRD §5.5 的要求,因此 MujicaUI 自建队列,只复用 MyGo 的 `Overlay`、`Transition`、`Announce` 与 `After` 定时唤醒。
- 所有消息(不只是含操作的消息)都在悬停或聚焦时暂停,这是 PRD 要求的超集,便于阅读。
- 位置固定在右下角;切换到未调用 `Toaster` 的视图时消息仍在队列中,回来后继续显示。
+64
View File
@@ -0,0 +1,64 @@
# 093 Progress 进度
## 用途
显示任务进度(确定或不确定,线形或环形),以及计量值(如磁盘占用)及其阈值。归并 MyGo 的 Progress bar 与 Meter:`Progress` 为进度模式,`Meter` 为计量模式。两者分别基于 `ui.Progress` 与 `ui.Meter` 元素重绘,保留其无障碍角色与数值。
## 最小示例
```go
mujica.Progress(c, 0.62, mujica.ProgressOptions{Label: "Uploading", ShowValue: true})
mujica.Progress(c, 0, mujica.ProgressOptions{Shape: mujica.ProgressRing, Indeterminate: true, Label: "Connecting"})
mujica.Meter(c, 93, mujica.MeterOptions{
Max: 100, Label: "Disk", ShowValue: true,
Levels: &ui.MeterLevels{Warning: 70, Critical: 90},
})
```
签名:
- `func Progress(c *ui.Context, value float64, opts ProgressOptions) *ui.Element`
- `func Meter(c *ui.Context, value float64, opts MeterOptions) *ui.Element`
## 参数
`ProgressOptions`:
| 字段 | 类型 | 默认值 | 含义 |
| --- | --- | --- | --- |
| `value` | `float64` | 必填 | 0 到 1;超出或 NaN 时 panic(不确定模式忽略)。 |
| `Shape` | `ProgressShape` | `ProgressLinear` | `ProgressLinear` 或 `ProgressRing`。 |
| `Indeterminate` | `bool` | `false` | 未知长度的进度。 |
| `Label` | `string` | `""` | 显示在旁边并作为无障碍名称;为空时名称为“Loading”。 |
| `ShowValue` | `bool` | `false` | 显示百分比。 |
| `Size` | `float32` | 环形 48、线形填满 | 环形直径或线形宽度;负数 panic。 |
`MeterOptions`:
| 字段 | 类型 | 默认值 | 含义 |
| --- | --- | --- | --- |
| `value` | `float64` | 必填 | 须在范围内,否则 panic。 |
| `Min`, `Max` | `float64` | 0, 1(两者都为 0 时) | 范围;`Max <= Min` panic。 |
| `Levels` | `*ui.MeterLevels` | `nil` | 阈值:达到 `Warning` 为偏高、达到 `Critical` 为严重;`Critical < Warning` 时低值为坏(如电量)。须在范围内。 |
| `Label` | `string` | `""` | 名称。 |
| `ShowValue` | `bool` | `false` | 显示“值 / 最大值”。 |
| `Width` | `float32` | 填满 | 宽度。 |
## 状态
- 确定进度变化时以 120 ms 过渡,减少动画时直接跳到新值。
- 不确定进度只在绘制时移动(只重绘、不重建视图);减少动画时显示静态填充和“In progress”文字。
- 计量条按级别使用 Success / Warning / Danger 颜色,同时显示“Normal / High / Critical / Low”文字与阈值刻度,并把级别写入无障碍名称。
## 事件
无。
## 键盘操作
不可聚焦;读屏读取名称与数值。
## 限制
- 环形直径小于 44 DIP 时百分比显示在旁边,而不是环内。
- MyGo 不提供自定义无障碍数值的公开接口,因此必须基于 `ui.Progress` / `ui.Meter` 元素绘制。
+39
View File
@@ -0,0 +1,39 @@
# 094 Spinner 加载标记
## 用途
表示未知长度的加载:四个菱形绕中心旋转。可调尺寸,可显示说明文字。Button 的加载状态也使用它。标记基于 MyGo `ui.Spinner` 元素重绘,读屏视为不确定进度。
## 最小示例
```go
mujica.Spinner(c, mujica.SpinnerOptions{Size: 20, Label: "Syncing", ShowLabel: true})
```
签名:`func Spinner(c *ui.Context, opts SpinnerOptions) *ui.Element`
## 参数
| 字段 | 类型 | 默认值 | 含义 |
| --- | --- | --- | --- |
| `Size` | `float32` | 16 | 标记边长(DIP)。 |
| `Label` | `string` | 内置“Loading / 加载中” | 无障碍名称;`ShowLabel` 时也显示在旁边。 |
| `ShowLabel` | `bool` | `false` | 在标记旁显示说明。 |
| `Color` | `ui.Color` | `AccentText` | 标记颜色。 |
## 状态
- 只在被绘制时请求重绘:不再构建(隐藏或停止加载)或滚出视口后动画立即停止,不留定时器。
- 减少动画模式下静止显示,保留名称与说明。
## 事件
无。
## 键盘操作
不可聚焦。
## 限制
- 每帧重绘,而非 MyGo 自带 spinner 的分步重绘;只在显示时产生开销。
+45
View File
@@ -0,0 +1,45 @@
# 095 Skeleton 骨架屏
## 用途
内容加载前占位,形状为文字行、圆形或矩形。尺寸固定,加载完成后替换为真实内容时不跳动。
## 最小示例
```go
ui.Row(c).Gap(12).Children(func() {
mujica.Skeleton(c, mujica.SkeletonOptions{Shape: mujica.SkeletonCircle})
ui.Column(c).Grow(1).Children(func() {
mujica.Skeleton(c, mujica.SkeletonOptions{Lines: 2})
})
})
```
签名:`func Skeleton(c *ui.Context, opts SkeletonOptions) *ui.Element`
## 参数
| 字段 | 类型 | 默认值 | 含义 |
| --- | --- | --- | --- |
| `Shape` | `SkeletonShape` | `SkeletonText` | `SkeletonText`、`SkeletonCircle`、`SkeletonRect`。 |
| `Width` | `float32` | 填满父级;圆形 40 | 宽度;圆形为直径。 |
| `Height` | `float32` | 当前密度控件高度 | 矩形高度;文字形状由行数决定(每行 21 DIP)。 |
| `Lines` | `int` | 1 | 文字行数,多行时最后一行为 60% 宽。 |
负值 panic。
## 状态
明暗缓慢脉动(1.6 秒周期),只重绘不重建视图;减少动画模式使用静态填充。
## 事件
无。
## 键盘操作
不可聚焦,不进入无障碍树。
## 限制
- 骨架本身不向读屏报告加载;请在容器上配合 Spinner 或 LoadingOverlay 的说明文字。
+48
View File
@@ -0,0 +1,48 @@
# 096 EmptyState 空状态
## 用途
说明视图为何为空并给出下一步。区分“无数据”(集合本身为空)与“无搜索结果”(筛选没有匹配),两者使用不同的默认图标与文案。
## 最小示例
```go
r := mujica.EmptyState(c, mujica.EmptyStateOptions{
Kind: mujica.EmptyNoResults,
Query: query,
Action: "Clear search",
})
if r.Action {
query = ""
}
```
签名:`func EmptyState(c *ui.Context, opts EmptyStateOptions) EmptyStateResult`
## 参数
| 字段 | 类型 | 默认值 | 含义 |
| --- | --- | --- | --- |
| `Kind` | `EmptyKind` | `EmptyNoData` | `EmptyNoData` 或 `EmptyNoResults`。 |
| `Title` | `string` | 按类型的内置文案 | 衬线标题。 |
| `Description` | `string` | 按类型的内置文案 | 说明。 |
| `Query` | `string` | `""` | 仅 `EmptyNoResults`:默认说明写出该关键词。用于 `EmptyNoData` 时 panic。 |
| `Icon` | `*ui.SVG` | inbox / search | 替换图标。 |
| `NoIcon` | `bool` | `false` | 不显示图标;与 `Icon` 同时设置时 panic。 |
| `Action` | `string` | `""` | 次按钮文字。 |
## 状态
静态展示;操作按钮有悬停、按下与焦点状态。
## 事件
`EmptyStateResult.Action`:操作按钮被触发。
## 键盘操作
Tab 聚焦操作按钮;Enter 或 Space 触发。
## 限制
- 只有一个操作;需要多个下一步时使用 Result。
+46
View File
@@ -0,0 +1,46 @@
# 097 Result 结果页
## 用途
任务完成后的整页结果:成功、失败或无权限,附说明与下一步操作。组件只报告选择了哪个操作,不执行跳转。标题与操作之间用旧金色细线与菱形分隔。
## 最小示例
```go
r := mujica.Result(c, mujica.ResultOptions{
Kind: mujica.ResultForbidden,
Description: "You need the Editor role to change billing.",
Actions: []string{"Request access", "Go back"},
})
switch r.Action {
case 0: // send the request
case 1: // navigate back
}
```
签名:`func Result(c *ui.Context, opts ResultOptions) ResultResult`
## 参数
| 字段 | 类型 | 默认值 | 含义 |
| --- | --- | --- | --- |
| `Kind` | `ResultKind` | `ResultSuccess` | `ResultSuccess`、`ResultFailure`、`ResultForbidden`;未知值 panic。 |
| `Title` | `string` | 按类型的内置文案 | 衬线标题。 |
| `Description` | `string` | `""` | 说明。 |
| `Actions` | `[]string` | 无 | 下一步操作;第一个为主按钮,其余为次按钮。 |
## 状态
图标(对勾、叉、盾牌)与标题文字共同表达结果,不只靠颜色。按钮有悬停、按下与焦点状态。
## 事件
`ResultResult.Action`:被触发的操作序号,未触发为 -1。
## 键盘操作
Tab 按顺序聚焦操作按钮;Enter 或 Space 触发。
## 限制
- 不含路由;导航由调用方完成。
+37
View File
@@ -0,0 +1,37 @@
# 098 StatusIndicator 状态标记
## 用途
以图形加文字标出状态:成功、警告、错误、离线、处理中。每种状态有独立形状(对勾圆、三角、叉圆、断开的 Wi-Fi、旋转菱形),并总是显示文字,不只靠颜色。
## 最小示例
```go
mujica.StatusIndicator(c, mujica.StatusSuccess, mujica.StatusIndicatorOptions{Label: "API online"})
mujica.StatusIndicator(c, mujica.StatusOffline, mujica.StatusIndicatorOptions{})
```
签名:`func StatusIndicator(c *ui.Context, status Status, opts StatusIndicatorOptions) *ui.Element`
## 参数
| 字段 | 类型 | 默认值 | 含义 |
| --- | --- | --- | --- |
| `status` | `Status` | `StatusSuccess` | `StatusSuccess`、`StatusWarning`、`StatusError`、`StatusOffline`、`StatusBusy`;未知值 panic。 |
| `Label` | `string` | 内置词(Healthy、Degraded、Failing、Offline、Working) | 替换显示的文字。 |
## 状态
处理中使用 Spinner,减少动画时静止。整体为 `RoleStatus`,名称为文字。
## 事件
无。
## 键盘操作
不可聚焦。
## 限制
- 无 Badge 式的纯圆点模式;PRD 要求不能只靠颜色。
@@ -0,0 +1,51 @@
# 099 NotificationCenter 通知中心
## 用途
应用内消息列表:未读标记、已读/未读切换、单条清除、全部已读、全部清除和每条消息的操作。消息列表与持久化由调用方持有;组件就地修改调用方的切片,并报告发生了什么,供调用方保存。
## 最小示例
```go
r := mujica.NotificationCenter(c, &items, mujica.NotificationCenterOptions{})
if r.Action == "a" {
// open the build log
}
```
签名:`func NotificationCenter(c *ui.Context, items *[]Notification, opts NotificationCenterOptions) NotificationCenterResult`
## 参数
`Notification`:
| 字段 | 类型 | 默认值 | 含义 |
| --- | --- | --- | --- |
| `ID` | `string` | 必填 | 列表内唯一;为空或重复时 panic。 |
| `Title` | `string` | `""` | 标题,未读时加粗。 |
| `Body` | `string` | `""` | 正文。 |
| `Time` | `string` | `""` | 按原样显示的时间,如“5 min ago”。 |
| `Read` | `bool` | `false` | 是否已读。 |
| `Action` | `string` | `""` | 操作按钮文字。 |
`NotificationCenterOptions.Title`:面板标题,默认“Notifications / 通知”。`items` 为 nil 时 panic。
## 状态
- 未读:左侧酒红菱形、粗体标题、无障碍名称前缀“Unread”。
- 行悬停加浅底;按钮有悬停、按下与焦点状态;无未读或无消息时头部按钮禁用。
- 空列表显示 EmptyState。
- 面板标题下为旧金细线。列表超出容器高度时滚动。
## 事件
`NotificationCenterResult`:`Action`、`Toggled`(已读状态切换)、`Opened`(点击正文后标为已读)、`Removed` 为对应 ID;`MarkedAllRead`、`ClearedAll` 为布尔值。
## 键盘操作
列表是一个 Tab 停靠点;方向键在各条消息及其按钮之间移动,Home/End 到首尾。焦点在消息正文上时 Enter 或 Space 标为已读;Delete 或 Backspace 清除当前消息。
## 限制
- 不分页,也不虚拟化;面向几十到几百条的应用内消息。
- 时间文字由调用方格式化。
+48
View File
@@ -0,0 +1,48 @@
# 100 LoadingOverlay 加载遮罩
## 用途
在一个容器范围内显示加载遮罩:被覆盖的内容不接收指针、按键和焦点,防止重复操作;窗口其余部分照常可用。显示说明文字与可选取消操作。
## 最小示例
```go
r := mujica.LoadingOverlay(c, loading, mujica.LoadingOverlayOptions{Cancel: "Cancel"}, func() {
ui.Text(c, "Quarterly report")
mujica.Button(c, "Export", mujica.ButtonOptions{})
})
if r.Canceled {
loading = false
}
```
签名:`func LoadingOverlay(c *ui.Context, loading bool, opts LoadingOverlayOptions, content func()) LoadingOverlayResult`
## 参数
| 字段 | 类型 | 默认值 | 含义 |
| --- | --- | --- | --- |
| `loading` | `bool` | 必填 | 是否覆盖。 |
| `content` | `func()` | 必填 | 构建被覆盖的内容;nil 时 panic。 |
| `Label` | `string` | 内置“Loading… / 正在加载…” | 说明文字。 |
| `Cancel` | `string` | `""` | 取消按钮文字;为空时不显示。 |
返回 `LoadingOverlayResult{Element, Canceled}`。`Element` 即遮罩所覆盖的范围,可在其上设置宽高。
## 状态
- 加载时内容经 MyGo `Disabled` 阻止输入(MyGo 统一减淡),上方为半透明背景与居中面板。
- 开始加载时播报说明;焦点原在内容内时移到取消按钮(无取消时移到可聚焦的说明面板),焦点不会离开该区域。
- 遮罩淡入淡出,减少动画时直接切换。
## 事件
`Canceled`:点击取消,或焦点在面板内时按 Escape。
## 键盘操作
Tab 到达取消按钮;Enter、Space 或 Escape 取消。被覆盖的控件不进入 Tab 序列。
## 限制
- 只遮盖容器自身范围;整窗阻塞请使用模态对话框。