@ticatec/topside-elements 1.0.3 → 1.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +23 -0
- package/dist/app_layout/ClassicLayout.svelte +0 -3
- package/dist/app_layout/HeaderLayout.svelte +0 -1
- package/dist/app_layout/SidebarLayout.svelte +0 -2
- package/dist/navigation/progress_step_bar/ProgressStepBar.svelte +4 -3
- package/dist/navigation/progress_step_bar/ProgressStepBlock.svelte +116 -77
- package/dist/navigation/progress_step_bar/ProgressStepBlock.svelte.d.ts +2 -0
- package/dist/navigation/progress_step_bar/README.md +20 -18
- package/dist/navigation/progress_step_bar/README_CN.md +15 -13
- package/dist/overlay/dialog/Dialog.svelte +2 -8
- package/dist/topside-elements.css +13 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,28 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.0.6
|
|
4
|
+
|
|
5
|
+
### 变更
|
|
6
|
+
- **应用布局组件样式调整**:`SidebarLayout`、`HeaderLayout` 与 `ClassicLayout` 移除多余的容器外间距 `gap` 与面板硬编码边框,统一配合内置拖拽分割线(`Split`)实现无间距贴合与平滑拖拽。
|
|
7
|
+
|
|
8
|
+
### 测试与文档
|
|
9
|
+
- **AppLayout 测试演示套件完善**:在 `topside-test-suite` 中补充「应用布局」完整演示路由(包含 `/test/app-layout` 总览,以及 `sidebar-layout`、`header-layout`、`classic-layout`、`columns-layout`、`rows-layout` 独立演示页面),完善测试站首页与侧边栏导航入口。
|
|
10
|
+
|
|
11
|
+
## 1.0.5
|
|
12
|
+
|
|
13
|
+
### 修复
|
|
14
|
+
- **Dialog 暗色主题**:`.topside-dialog-box` 不再硬编码 `#ffffff` 背景,改读 `--topside-dialog-color-surface`(默认 `var(--topside-color-surface)`);原先只在组件内 `:global(:root)` 定义、且暗色下无覆盖的 `--topside-dialog-border-color` / `--topside-dialog-action-button-color` / `--topside-dialog-action-button-hover-background-color`,以及从未定义只靠回退值的 `--topside-dialog-divider-color` / `--topside-dialog-header-color`,统一移到 `topside-root.scss`,亮色保持原值,`[data-theme=dark]` 下分别跟随 `--topside-color-border-primary` / `--topside-color-border-secondary` / `--topside-primary-color-font` / `--topside-secondary-color-font` / `--topside-color-surface-variant`。对话框(含基于 Dialog 的 MessageBox 等)在暗色主题下随主题切换。
|
|
15
|
+
|
|
16
|
+
## 1.0.4
|
|
17
|
+
|
|
18
|
+
### 变更
|
|
19
|
+
- **ProgressStepBar 布局重做**:横向改为圆圈在上、标题 / comment 居中在圆圈下方,步骤等分宽度、长标题截断;连接线不再用贯穿整块的 `linear-gradient`,改为指示器上的伪元素只在相邻圆圈之间画线段(横向 `::before` / `::after` 两段,纵向一段),首尾圆圈外侧无线。线的颜色跟随左侧 / 上方步骤:该步 `Completed` 为蓝,否则为灰;横向两个半段由内部 `connected` 标记保持一致。
|
|
20
|
+
- **纵向不再要求父容器有高度**:按内容撑开、步骤间距 12px;父容器给了高度时步骤才拉伸均分。
|
|
21
|
+
- 连接线不再依赖 `--topside-progress-step-bar-color-surface` 是纯色,透明 / 图片 / 渐变背景下圆圈处不会漏线;该变量现在只是容器背景。
|
|
22
|
+
|
|
23
|
+
### 文档
|
|
24
|
+
- 更新 `progress_step_bar/README(_CN).md`、AI 编码指南中步骤条示例(原示例用的 `steps` / `activeIndex` 并不存在,改为 `items` + `status`);测试套件 `/test/navigation/progress-step-bar` 扩充为横向 / 纵向 / 窄容器 / 动态 / 非纯色背景 / 自定义颜色等示例。
|
|
25
|
+
|
|
3
26
|
## 1.0.3
|
|
4
27
|
|
|
5
28
|
### 变更
|
|
@@ -115,7 +115,6 @@
|
|
|
115
115
|
flex: 0 0 auto;
|
|
116
116
|
overflow: auto;
|
|
117
117
|
width: 100%;
|
|
118
|
-
border-right: 1px solid var(--topside-color-border-secondary);
|
|
119
118
|
}
|
|
120
119
|
|
|
121
120
|
.content-area {
|
|
@@ -127,7 +126,6 @@
|
|
|
127
126
|
flex: 0 0 auto;
|
|
128
127
|
overflow: auto;
|
|
129
128
|
width: 100%;
|
|
130
|
-
border-left: 1px solid var(--topside-color-border-secondary);
|
|
131
129
|
}
|
|
132
130
|
|
|
133
131
|
.bottom-area {
|
|
@@ -135,6 +133,5 @@
|
|
|
135
133
|
position: relative;
|
|
136
134
|
width: 100%;
|
|
137
135
|
overflow: hidden;
|
|
138
|
-
border-top: 1px solid var(--topside-color-border-secondary);
|
|
139
136
|
}
|
|
140
137
|
</style>
|
|
@@ -61,14 +61,12 @@
|
|
|
61
61
|
box-sizing: border-box;
|
|
62
62
|
display: flex;
|
|
63
63
|
flex-direction: row;
|
|
64
|
-
gap: var(--topside-spacing-2);
|
|
65
64
|
}
|
|
66
65
|
|
|
67
66
|
.sidebar {
|
|
68
67
|
height: 100%;
|
|
69
68
|
flex: 0 0 auto;
|
|
70
69
|
overflow: auto;
|
|
71
|
-
border-right: 1px solid var(--topside-color-border-secondary);
|
|
72
70
|
}
|
|
73
71
|
|
|
74
72
|
.main-content {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type ProgressStep from "./ProgressStep";
|
|
3
|
+
import {ProgressStepStatus} from "./ProgressStep";
|
|
3
4
|
import ProgressStepBlock from "./ProgressStepBlock.svelte";
|
|
4
5
|
|
|
5
6
|
interface Props {
|
|
@@ -22,7 +23,8 @@
|
|
|
22
23
|
<div class="topside-progress-step-container {direction}" data-theme={theme} {style}>
|
|
23
24
|
<div class="container-panel">
|
|
24
25
|
{#each items as step, idx}
|
|
25
|
-
<ProgressStepBlock pos={idx+1} status={step.status} comment={step.comment} title={step.title} {direction}
|
|
26
|
+
<ProgressStepBlock pos={idx+1} status={step.status} comment={step.comment} title={step.title} {direction}
|
|
27
|
+
connected={idx > 0 && items[idx - 1].status === ProgressStepStatus.Completed}/>
|
|
26
28
|
{/each}
|
|
27
29
|
</div>
|
|
28
30
|
</div>
|
|
@@ -40,9 +42,8 @@
|
|
|
40
42
|
width: 100%;
|
|
41
43
|
display: flex;
|
|
42
44
|
flex-direction: row;
|
|
43
|
-
|
|
45
|
+
align-items: flex-start;
|
|
44
46
|
background-color: inherit;
|
|
45
|
-
z-index: 2;
|
|
46
47
|
}
|
|
47
48
|
|
|
48
49
|
.topside-progress-step-container.vertical {
|
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
comment?: string;
|
|
9
9
|
style?: string;
|
|
10
10
|
direction: 'vertical' | 'horizontal';
|
|
11
|
+
/** 前一个步骤是否已完成(决定进入本步骤的连接线颜色,仅水平布局使用;纵向每段线只由上一步自身状态决定) */
|
|
12
|
+
connected?: boolean;
|
|
11
13
|
}
|
|
12
14
|
|
|
13
15
|
let {
|
|
@@ -16,13 +18,14 @@
|
|
|
16
18
|
title,
|
|
17
19
|
comment = '',
|
|
18
20
|
style = '',
|
|
19
|
-
direction
|
|
21
|
+
direction,
|
|
22
|
+
connected = false
|
|
20
23
|
}: Props = $props();
|
|
21
24
|
|
|
22
25
|
|
|
23
26
|
</script>
|
|
24
27
|
|
|
25
|
-
<div class="progress-step-block {status} {direction}" {style}>
|
|
28
|
+
<div class="progress-step-block {status} {direction}" class:connected {style}>
|
|
26
29
|
<div class="step-indicator">
|
|
27
30
|
<div>
|
|
28
31
|
{#if status === ProgressStepStatus.Completed}
|
|
@@ -46,38 +49,14 @@
|
|
|
46
49
|
|
|
47
50
|
<style>
|
|
48
51
|
|
|
52
|
+
/* ---------- shared ---------- */
|
|
53
|
+
|
|
49
54
|
.progress-step-block {
|
|
50
55
|
flex: 1 1;
|
|
51
56
|
min-width: 100px;
|
|
52
57
|
display: flex;
|
|
53
|
-
flex-direction: row;
|
|
54
|
-
justify-items: flex-start;
|
|
55
58
|
color: var(--topside-progress-step-pending-color, #B3BCCA);
|
|
56
|
-
margin-left: 8px;
|
|
57
59
|
background-color: inherit;
|
|
58
|
-
background: linear-gradient(to bottom, transparent 12px,
|
|
59
|
-
var(--topside-progress-step-pending-color, #B3BCCA) 12px,
|
|
60
|
-
var(--topside-progress-step-pending-color, #B3BCCA) 14px,
|
|
61
|
-
transparent 14px);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
.progress-step-block:first-child {
|
|
65
|
-
margin-left: 0;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
.progress-step-block:first-child .step-indicator {
|
|
69
|
-
margin-left: 0;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
.step-indicator {
|
|
73
|
-
flex: 0 0 auto;
|
|
74
|
-
padding-right: 12px;
|
|
75
|
-
margin-left: 12px;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
.step-indicator > div {
|
|
79
|
-
background-color: var(--topside-progress-step-bar-color-surface);
|
|
80
|
-
display: inline-block;
|
|
81
60
|
}
|
|
82
61
|
|
|
83
62
|
.step-indicator span {
|
|
@@ -89,36 +68,32 @@
|
|
|
89
68
|
border-radius: 50%;
|
|
90
69
|
border: 1px solid var(--topside-progress-step-pending-color, #B3BCCA);
|
|
91
70
|
font-size: 1.1em;
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
.progress-step-block.completed {
|
|
95
|
-
background: linear-gradient(to bottom, transparent 12px,
|
|
96
|
-
var(--topside-progress-step-completed-icon-color, #0061FF) 12px,
|
|
97
|
-
var(--topside-progress-step-completed-icon-color, #0061FF) 14px,
|
|
98
|
-
transparent 14px);
|
|
71
|
+
box-sizing: border-box;
|
|
99
72
|
}
|
|
100
73
|
|
|
101
74
|
.progress-step-block.completed .step-indicator span {
|
|
102
75
|
border: 1px solid var(--topside-progress-step-completed-icon-color, #0061FF);
|
|
76
|
+
background-color: var(--topside-progress-step-completed-icon-bg, #0061FF1A);
|
|
77
|
+
color: var(--topside-progress-step-completed-icon-color, #0061FF);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.progress-step-block.processing .step-indicator span {
|
|
81
|
+
border-color: var(--topside-progress-step-processing-color, #0061FF);
|
|
82
|
+
background-color: var(--topside-progress-step-processing-color, #0061FF);
|
|
83
|
+
color: var(--topside-progress-step-bar-bg, #ffffff);
|
|
103
84
|
}
|
|
104
85
|
|
|
105
86
|
.step-text {
|
|
106
|
-
width: 100%;
|
|
107
87
|
overflow: hidden;
|
|
108
88
|
}
|
|
109
89
|
|
|
110
90
|
.step-topic {
|
|
111
|
-
width: 100%;
|
|
112
|
-
background-color: transparent;
|
|
113
91
|
line-height: 24px;
|
|
114
92
|
overflow: hidden;
|
|
115
93
|
}
|
|
116
94
|
|
|
117
95
|
.step-topic span {
|
|
118
96
|
display: inline-block;
|
|
119
|
-
background-color: var(--topside-progress-step-bar-color-surface);
|
|
120
|
-
padding-right: 6px;
|
|
121
|
-
padding-left: 6px;
|
|
122
97
|
max-width: 100%;
|
|
123
98
|
overflow: hidden;
|
|
124
99
|
white-space: nowrap;
|
|
@@ -126,72 +101,136 @@
|
|
|
126
101
|
vertical-align: top;
|
|
127
102
|
}
|
|
128
103
|
|
|
129
|
-
.progress-step-block:last-child .step-topic {
|
|
130
|
-
background-color: var(--topside-progress-step-bar-color-surface);
|
|
131
|
-
}
|
|
132
|
-
|
|
133
104
|
.progress-step-block.processing .step-topic {
|
|
134
105
|
color: var(--topside-progress-step-processing-color, #0061FF);
|
|
135
106
|
}
|
|
136
107
|
|
|
137
|
-
.progress-step-block.
|
|
138
|
-
|
|
139
|
-
color: var(--topside-progress-step-bar-bg, #ffffff);
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
.progress-step-block.completed .step-topic {
|
|
108
|
+
.progress-step-block.completed .step-topic,
|
|
109
|
+
.progress-step-block.completed .step-comment {
|
|
143
110
|
color: var(--topside-progress-step-completed-color, #374151);
|
|
144
111
|
}
|
|
145
112
|
|
|
146
|
-
.progress-step-block.completed .step-indicator span {
|
|
147
|
-
background-color: var(--topside-progress-step-completed-icon-bg, #0061FF1A);
|
|
148
|
-
color: var(--topside-progress-step-completed-icon-color, #0061FF);
|
|
149
|
-
}
|
|
150
|
-
|
|
151
113
|
.step-comment {
|
|
152
114
|
line-height: 1.4;
|
|
153
115
|
font-size: 0.9em;
|
|
154
116
|
}
|
|
155
117
|
|
|
156
|
-
|
|
157
|
-
|
|
118
|
+
/* ---------- horizontal: circle on top, text below, connector between circles ---------- */
|
|
119
|
+
|
|
120
|
+
.progress-step-block.horizontal {
|
|
121
|
+
flex-direction: column;
|
|
122
|
+
align-items: center;
|
|
123
|
+
min-width: 0;
|
|
124
|
+
text-align: center;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
.progress-step-block.horizontal .step-indicator {
|
|
128
|
+
position: relative;
|
|
129
|
+
width: 100%;
|
|
130
|
+
display: flex;
|
|
131
|
+
justify-content: center;
|
|
132
|
+
flex: 0 0 auto;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
.progress-step-block.horizontal .step-indicator > div {
|
|
136
|
+
position: relative;
|
|
137
|
+
z-index: 1;
|
|
138
|
+
line-height: 0;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/* connector segments: ::before = incoming (left), ::after = outgoing (right) */
|
|
142
|
+
.progress-step-block.horizontal .step-indicator::before,
|
|
143
|
+
.progress-step-block.horizontal .step-indicator::after {
|
|
144
|
+
content: '';
|
|
145
|
+
position: absolute;
|
|
146
|
+
top: 11px;
|
|
147
|
+
height: 2px;
|
|
148
|
+
background-color: var(--topside-progress-step-pending-color, #B3BCCA);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
.progress-step-block.horizontal .step-indicator::before {
|
|
152
|
+
left: 0;
|
|
153
|
+
right: calc(50% + 16px);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
.progress-step-block.horizontal .step-indicator::after {
|
|
157
|
+
left: calc(50% + 16px);
|
|
158
|
+
right: 0;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
.progress-step-block.horizontal:first-child .step-indicator::before,
|
|
162
|
+
.progress-step-block.horizontal:last-child .step-indicator::after {
|
|
163
|
+
display: none;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
.progress-step-block.horizontal.completed .step-indicator::after,
|
|
167
|
+
.progress-step-block.horizontal.connected .step-indicator::before {
|
|
168
|
+
background-color: var(--topside-progress-step-completed-icon-color, #0061FF);
|
|
158
169
|
}
|
|
159
170
|
|
|
160
|
-
|
|
171
|
+
.progress-step-block.horizontal .step-text {
|
|
172
|
+
width: 100%;
|
|
173
|
+
padding: 0 4px;
|
|
174
|
+
margin-top: 6px;
|
|
175
|
+
box-sizing: border-box;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
.progress-step-block.horizontal .step-topic span {
|
|
179
|
+
padding: 0 2px;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/* ---------- vertical: circle on the left, text on the right, connector between circles ---------- */
|
|
183
|
+
|
|
161
184
|
.progress-step-block.vertical {
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
185
|
+
flex-direction: row;
|
|
186
|
+
align-items: flex-start;
|
|
187
|
+
min-width: 0;
|
|
188
|
+
padding-bottom: 12px;
|
|
165
189
|
}
|
|
166
190
|
|
|
167
|
-
.progress-step-block.vertical
|
|
168
|
-
|
|
169
|
-
var(--topside-progress-step-completed-icon-color, #0061FF) 14px, transparent 13px);
|
|
191
|
+
.progress-step-block.vertical:last-child {
|
|
192
|
+
padding-bottom: 0;
|
|
170
193
|
}
|
|
171
194
|
|
|
172
195
|
.progress-step-block.vertical .step-indicator {
|
|
173
|
-
|
|
196
|
+
position: relative;
|
|
197
|
+
flex: 0 0 auto;
|
|
198
|
+
width: 24px;
|
|
199
|
+
align-self: stretch;
|
|
200
|
+
margin-right: 12px;
|
|
174
201
|
}
|
|
175
202
|
|
|
176
203
|
.progress-step-block.vertical .step-indicator > div {
|
|
177
|
-
|
|
178
|
-
|
|
204
|
+
position: relative;
|
|
205
|
+
z-index: 1;
|
|
206
|
+
line-height: 0;
|
|
179
207
|
}
|
|
180
208
|
|
|
181
|
-
|
|
182
|
-
|
|
209
|
+
/* connector segment: from just below the circle to the bottom of the block */
|
|
210
|
+
.progress-step-block.vertical .step-indicator::after {
|
|
211
|
+
content: '';
|
|
212
|
+
position: absolute;
|
|
213
|
+
left: 11px;
|
|
214
|
+
width: 2px;
|
|
215
|
+
top: 28px;
|
|
216
|
+
bottom: 4px;
|
|
217
|
+
background-color: var(--topside-progress-step-pending-color, #B3BCCA);
|
|
183
218
|
}
|
|
184
219
|
|
|
185
|
-
.progress-step-block.vertical .step-
|
|
186
|
-
|
|
187
|
-
display: block;
|
|
220
|
+
.progress-step-block.vertical:last-child .step-indicator::after {
|
|
221
|
+
display: none;
|
|
188
222
|
}
|
|
189
223
|
|
|
190
|
-
.progress-step-block.vertical
|
|
191
|
-
background:
|
|
224
|
+
.progress-step-block.vertical.completed .step-indicator::after {
|
|
225
|
+
background-color: var(--topside-progress-step-completed-icon-color, #0061FF);
|
|
192
226
|
}
|
|
193
227
|
|
|
194
|
-
.progress-step-block.vertical
|
|
195
|
-
|
|
228
|
+
.progress-step-block.vertical .step-text {
|
|
229
|
+
flex: 1 1 auto;
|
|
230
|
+
min-width: 0;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
.progress-step-block.vertical .step-topic span {
|
|
234
|
+
display: block;
|
|
196
235
|
}
|
|
197
236
|
</style>
|
|
@@ -6,6 +6,8 @@ interface Props {
|
|
|
6
6
|
comment?: string;
|
|
7
7
|
style?: string;
|
|
8
8
|
direction: 'vertical' | 'horizontal';
|
|
9
|
+
/** 前一个步骤是否已完成(决定进入本步骤的连接线颜色,仅水平布局使用;纵向每段线只由上一步自身状态决定) */
|
|
10
|
+
connected?: boolean;
|
|
9
11
|
}
|
|
10
12
|
declare const ProgressStepBlock: import("svelte").Component<Props, {}, "">;
|
|
11
13
|
type ProgressStepBlock = ReturnType<typeof ProgressStepBlock>;
|
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
> **Renamed in 5.1.0**: this document uses the names from the [API Naming Guide](../../../docs/NAMING.md); the old names `steps`, `topic` were removed in 5.1.0 (no compatibility aliases are kept).
|
|
4
4
|
|
|
5
|
-
A multi-step progress indicator showing sequential steps with their completion status. Renders numbered circles connected by a line; each step is `Pending`, `Processing`, or `Completed`. Supports horizontal (default) and vertical layouts. Pure display — no click handlers.
|
|
5
|
+
A multi-step progress indicator showing sequential steps with their completion status. Renders numbered circles connected by a line; each step is `Pending`, `Processing`, or `Completed`. Supports horizontal (default — circle on top, title/comment centered below, connector segments between circles) and vertical layouts. Pure display — no click handlers.
|
|
6
6
|
|
|
7
7
|
## Features
|
|
8
8
|
|
|
9
9
|
- **Three statuses per step**: `Pending` (gray number), `Processing` (solid blue circle), `Completed` (blue tinted circle with checkmark)
|
|
10
|
-
- **Connector line**:
|
|
10
|
+
- **Connector line**: short segments drawn between adjacent circles with pseudo-elements on the indicator (never through the text, no dependence on the background color). The line after a step is blue once that step is `Completed`, gray otherwise
|
|
11
11
|
- **Horizontal or vertical layout**: horizontal default, vertical for sidebars
|
|
12
12
|
- **Optional comment per step**: smaller secondary text under the topic
|
|
13
13
|
- **Theme hook**: `data-theme="{theme}"` on the outer wrapper
|
|
@@ -76,10 +76,10 @@ The enum value is also the CSS class on each step block (`Pending` → `.pending
|
|
|
76
76
|
```text
|
|
77
77
|
Horizontal:
|
|
78
78
|
|
|
79
|
-
|
|
80
|
-
1 2 3 4
|
|
81
|
-
Reg Ver Setup Done
|
|
82
|
-
|
|
79
|
+
●─────●─────●─────○─────○
|
|
80
|
+
1 2 3 4 5
|
|
81
|
+
Reg Ver Setup Review Done
|
|
82
|
+
note note note note note
|
|
83
83
|
|
|
84
84
|
Vertical:
|
|
85
85
|
|
|
@@ -96,7 +96,7 @@ Vertical:
|
|
|
96
96
|
Setup
|
|
97
97
|
```
|
|
98
98
|
|
|
99
|
-
Filled circles (●) are completed or processing; outlined circles (○) are pending.
|
|
99
|
+
Filled circles (●) are completed or processing; outlined circles (○) are pending. In horizontal mode the title (and optional comment) sits centered under its circle, and the segment between two circles is blue when the step on its left is `Completed`, gray otherwise. The line never passes under the text.
|
|
100
100
|
|
|
101
101
|
## DOM Structure & CSS
|
|
102
102
|
|
|
@@ -106,7 +106,7 @@ Rendered output:
|
|
|
106
106
|
<div class="topside-progress-step-container {direction}" data-theme="..." style="...">
|
|
107
107
|
<div class="container-panel">
|
|
108
108
|
<!-- per step -->
|
|
109
|
-
<div class="progress-step-block {status} {direction}">
|
|
109
|
+
<div class="progress-step-block {status} {direction} [connected]"> <!-- .connected = previous step is Completed (horizontal line color) -->
|
|
110
110
|
<div class="step-indicator">
|
|
111
111
|
<div>
|
|
112
112
|
<span>✔</span> <!-- Completed -->
|
|
@@ -129,7 +129,7 @@ Rendered output:
|
|
|
129
129
|
|
|
130
130
|
| Variable | Purpose |
|
|
131
131
|
|----------|---------|
|
|
132
|
-
| `--topside-progress-step-bar-color-surface` | Container background
|
|
132
|
+
| `--topside-progress-step-bar-color-surface` | Container background |
|
|
133
133
|
| `--topside-progress-step-bar-bg` | Foreground inside processing circle (default white) |
|
|
134
134
|
| `--topside-progress-step-pending-color` | Pending circle border + line + text (gray) |
|
|
135
135
|
| `--topside-progress-step-completed-color` | Completed title/comment text (dark gray) |
|
|
@@ -139,9 +139,11 @@ Rendered output:
|
|
|
139
139
|
|
|
140
140
|
### How the connector line works
|
|
141
141
|
|
|
142
|
-
|
|
142
|
+
**Horizontal**: each `.step-indicator` is `position: relative` and draws two 2px segments with `::before` (incoming, from the left edge to the circle) and `::after` (outgoing, from the circle to the right edge). The first step hides `::before`, the last hides `::after`. `::after` turns blue when the step itself is `Completed`; `::before` turns blue when the block has the `connected` class (previous step `Completed`), so both halves of one connector always match. Nothing depends on the surface color.
|
|
143
143
|
|
|
144
|
-
|
|
144
|
+
**Vertical**: the indicator column is `align-self: stretch`, and a single `::after` segment runs from just below the circle to the bottom of the block (4px gap on both ends, so the next circle starts cleanly). The last step hides it. It turns blue when the step itself is `Completed` — in vertical mode one segment covers the whole gap, so `connected` is not needed. Each block adds `padding-bottom: 12px` as the spacing between steps.
|
|
145
|
+
|
|
146
|
+
Neither mode paints anything over the surface color, so any container background (transparent, image, gradient) works.
|
|
145
147
|
|
|
146
148
|
## Examples
|
|
147
149
|
|
|
@@ -185,12 +187,12 @@ This is fragile — if you change `--topside-progress-step-bar-color-surface` to
|
|
|
185
187
|
### Vertical Layout
|
|
186
188
|
|
|
187
189
|
```svelte
|
|
188
|
-
<div style="
|
|
190
|
+
<div style="width: 240px;">
|
|
189
191
|
<ProgressStepBar {items} direction="vertical" />
|
|
190
192
|
</div>
|
|
191
193
|
```
|
|
192
194
|
|
|
193
|
-
Vertical mode
|
|
195
|
+
Vertical mode sizes to its content; if the parent has an explicit height the steps stretch to fill it (`flex: 1`), otherwise each step takes its natural height with 12px spacing.
|
|
194
196
|
|
|
195
197
|
### Pure Display (Static Steps)
|
|
196
198
|
|
|
@@ -218,8 +220,8 @@ For a "your order is at step N" type view:
|
|
|
218
220
|
- **Reactive.** Mutate `items[i].status` (with `$state` array) and the UI updates. The component re-renders via Svelte 5 reactivity.
|
|
219
221
|
- **`title` truncates with `…`** (`white-space: nowrap; text-overflow: ellipsis`). Keep topics short.
|
|
220
222
|
- **`comment` is multi-line** but doesn't have its own truncation — long comments can break the layout.
|
|
221
|
-
- **
|
|
222
|
-
- **
|
|
223
|
+
- **Horizontal steps share the width equally** (`flex: 1 1 0`, `min-width: 0`) and center their text under the circle; long titles truncate instead of pushing siblings.
|
|
224
|
+
- **No line outside the first/last circle** in either mode.
|
|
223
225
|
|
|
224
226
|
## Accessibility
|
|
225
227
|
|
|
@@ -230,15 +232,15 @@ For a "your order is at step N" type view:
|
|
|
230
232
|
|
|
231
233
|
## Known Quirks
|
|
232
234
|
|
|
233
|
-
|
|
235
|
+
None currently. The connector line is drawn with pseudo-elements in both modes, so it no longer depends on `--topside-progress-step-bar-color-surface` being a solid color.
|
|
234
236
|
|
|
235
237
|
## Best Practices
|
|
236
238
|
|
|
237
239
|
1. **Use `$state` for the `items` array** if you want live progress updates. Mutating `items[i].status` re-renders.
|
|
238
240
|
2. **Keep `title` short** — it truncates with `…`. Move detail to `comment`.
|
|
239
|
-
3.
|
|
241
|
+
3. **`direction="vertical"` works with or without a fixed-height parent** — give the parent a height only when you want the steps spread out evenly.
|
|
240
242
|
4. **One `Processing` step at a time** — having multiple gives a confusing visual. Mark earlier steps `Completed`.
|
|
241
|
-
5. **Override colors via CSS variables**, not by styling the inner classes
|
|
243
|
+
5. **Override colors via CSS variables**, not by styling the inner classes.
|
|
242
244
|
6. **For interactive step nav, use [Navigator](../navigator/README.md)** instead — this component is display-only.
|
|
243
245
|
|
|
244
246
|
## Related Components
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
## 功能特性
|
|
8
8
|
|
|
9
9
|
- **三种状态**:`Pending`(灰色数字)、`Processing`(实心蓝圆)、`Completed`(蓝色淡背景圆 + 对勾)
|
|
10
|
-
-
|
|
10
|
+
- **连接线**:两种方向都用指示器上的伪元素在相邻圆圈之间画短线段,不穿过文字、不依赖背景色。某步 `Completed` 后它之后的线段为蓝色,否则为灰色
|
|
11
11
|
- **横向或纵向布局**:横向默认,纵向用于侧边栏
|
|
12
12
|
- **每步可选注释**:在 topic 下方显示较小的次要文字
|
|
13
13
|
- **主题钩子**:外层 wrapper 暴露 `data-theme="{theme}"`
|
|
@@ -96,7 +96,7 @@ enum ProgressStepStatus {
|
|
|
96
96
|
设置
|
|
97
97
|
```
|
|
98
98
|
|
|
99
|
-
|
|
99
|
+
实心圆(●)是已完成或进行中;空心圆(○)是未开始。横向布局下标题(和可选注释)居中显示在圆圈正下方,两个圆圈之间的线段在左侧步骤 `Completed` 时为蓝色,否则为灰色;线不会从文字下方穿过。
|
|
100
100
|
|
|
101
101
|
## DOM 结构与 CSS
|
|
102
102
|
|
|
@@ -106,7 +106,7 @@ enum ProgressStepStatus {
|
|
|
106
106
|
<div class="topside-progress-step-container {direction}" data-theme="..." style="...">
|
|
107
107
|
<div class="container-panel">
|
|
108
108
|
<!-- 每步 -->
|
|
109
|
-
<div class="progress-step-block {status} {direction}">
|
|
109
|
+
<div class="progress-step-block {status} {direction} [connected]"> <!-- .connected = 前一步已完成(决定横向进入线段颜色) -->
|
|
110
110
|
<div class="step-indicator">
|
|
111
111
|
<div>
|
|
112
112
|
<span>✔</span> <!-- Completed -->
|
|
@@ -129,7 +129,7 @@ enum ProgressStepStatus {
|
|
|
129
129
|
|
|
130
130
|
| 变量 | 用途 |
|
|
131
131
|
|------|------|
|
|
132
|
-
| `--topside-progress-step-bar-color-surface` |
|
|
132
|
+
| `--topside-progress-step-bar-color-surface` | 容器背景 |
|
|
133
133
|
| `--topside-progress-step-bar-bg` | 进行中圆圈内的前景色(默认白) |
|
|
134
134
|
| `--topside-progress-step-pending-color` | 未开始圆圈边框 + 线 + 文字(灰) |
|
|
135
135
|
| `--topside-progress-step-completed-color` | 已完成 title / comment 文字(深灰) |
|
|
@@ -139,9 +139,11 @@ enum ProgressStepStatus {
|
|
|
139
139
|
|
|
140
140
|
### 连接线怎么画的
|
|
141
141
|
|
|
142
|
-
|
|
142
|
+
**横向**:每个 `.step-indicator` 是 `position: relative`,用 `::before`(进入段:左边缘到圆圈)和 `::after`(离开段:圆圈到右边缘)各画一条 2px 线段。首步隐藏 `::before`,末步隐藏 `::after`。本步 `Completed` 时 `::after` 变蓝;块带 `connected` 类(前一步 `Completed`)时 `::before` 变蓝,所以同一条连接线的两半颜色总是一致。不依赖 surface 颜色。
|
|
143
143
|
|
|
144
|
-
|
|
144
|
+
**纵向**:指示器列 `align-self: stretch`,用一条 `::after` 线段从圆圈下方画到块底部(上下各留 4px 空隙,下一个圆圈紧接着开始),末步隐藏。本步 `Completed` 时变蓝 —— 纵向一段线覆盖整个间隔,所以不需要 `connected`。每个块加 `padding-bottom: 12px` 作为步骤间距。
|
|
145
|
+
|
|
146
|
+
两种模式都不会在 surface 颜色上盖任何东西,所以容器背景透明、图片、渐变都没问题。
|
|
145
147
|
|
|
146
148
|
## 示例
|
|
147
149
|
|
|
@@ -185,12 +187,12 @@ enum ProgressStepStatus {
|
|
|
185
187
|
### 纵向布局
|
|
186
188
|
|
|
187
189
|
```svelte
|
|
188
|
-
<div style="
|
|
190
|
+
<div style="width: 240px;">
|
|
189
191
|
<ProgressStepBar {items} direction="vertical" />
|
|
190
192
|
</div>
|
|
191
193
|
```
|
|
192
194
|
|
|
193
|
-
|
|
195
|
+
纵向模式按内容撑开;父容器给了明确高度时步骤会拉伸填满(`flex: 1`),否则每步取自然高度、间距 12px。
|
|
194
196
|
|
|
195
197
|
### 纯展示(静态步骤)
|
|
196
198
|
|
|
@@ -218,8 +220,8 @@ enum ProgressStepStatus {
|
|
|
218
220
|
- **响应式。** 修改 `items[i].status`(用 `$state` 数组)UI 就更新。组件通过 Svelte 5 响应式重渲染
|
|
219
221
|
- **`title` 用 `…` 截断**(`white-space: nowrap; text-overflow: ellipsis`)。保持 topic 简短
|
|
220
222
|
- **`comment` 可多行**,但本身不截断 —— 长注释可能破坏布局
|
|
221
|
-
-
|
|
222
|
-
-
|
|
223
|
+
- **横向步骤等分宽度**(`flex: 1 1 0`、`min-width: 0`),文字在圆圈下方居中;长标题会截断而不是挤压相邻步骤
|
|
224
|
+
- **首尾圆圈外侧没有线**,横向纵向都一样
|
|
223
225
|
|
|
224
226
|
## 无障碍访问
|
|
225
227
|
|
|
@@ -230,15 +232,15 @@ enum ProgressStepStatus {
|
|
|
230
232
|
|
|
231
233
|
## 已知怪异
|
|
232
234
|
|
|
233
|
-
|
|
235
|
+
暂无。两种模式的连接线都用伪元素画,不再要求 `--topside-progress-step-bar-color-surface` 是纯色。
|
|
234
236
|
|
|
235
237
|
## 最佳实践
|
|
236
238
|
|
|
237
239
|
1. **`items` 数组用 `$state`**,需要实时进度更新时。修改 `items[i].status` 触发重渲染
|
|
238
240
|
2. **`title` 保持简短** —— 会用 `…` 截断。详情移到 `comment`
|
|
239
|
-
3. **`direction="vertical"`
|
|
241
|
+
3. **`direction="vertical"` 父容器有没有固定高度都可以** —— 想让步骤均匀铺开时再给父容器高度
|
|
240
242
|
4. **同时只一个 `Processing` 步骤** —— 多了视觉混乱。把之前的标 `Completed`
|
|
241
|
-
5. **颜色通过 CSS 变量覆盖**,不要改内部类样式
|
|
243
|
+
5. **颜色通过 CSS 变量覆盖**,不要改内部类样式
|
|
242
244
|
6. **需要交互式步骤导航用 [Navigator](../navigator/README_CN.md)** —— 这个组件是纯展示
|
|
243
245
|
|
|
244
246
|
## 相关组件
|
|
@@ -163,13 +163,7 @@
|
|
|
163
163
|
</div>
|
|
164
164
|
</div>
|
|
165
165
|
|
|
166
|
-
<style
|
|
167
|
-
--topside-dialog-border-color: #0000000D;
|
|
168
|
-
--topside-dialog-action-button-hover-background-color: #E2E8F0;
|
|
169
|
-
--topside-dialog-action-button-color: #6B7280;
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
.topside-dialog {
|
|
166
|
+
<style>.topside-dialog {
|
|
173
167
|
position: fixed;
|
|
174
168
|
top: 0;
|
|
175
169
|
left: 0;
|
|
@@ -187,7 +181,7 @@
|
|
|
187
181
|
}
|
|
188
182
|
.topside-dialog .topside-dialog-box {
|
|
189
183
|
margin: 0;
|
|
190
|
-
background-color: #ffffff;
|
|
184
|
+
background-color: var(--topside-dialog-color-surface, var(--topside-color-surface, #ffffff));
|
|
191
185
|
position: relative;
|
|
192
186
|
border-radius: 4px;
|
|
193
187
|
border: 1px solid var(--topside-dialog-border-color, rgba(0, 0, 0, 0.0509803922));
|
|
@@ -82,6 +82,13 @@
|
|
|
82
82
|
--topside-dialog-action-bar-margin: 16px 24px;
|
|
83
83
|
--topside-dialog-action-bar-text-align: right;
|
|
84
84
|
--topside-dialog-action-button-color-hover-surface: rgba(0, 0, 0, 0.05);
|
|
85
|
+
/* Dialog box (light) */
|
|
86
|
+
--topside-dialog-color-surface: var(--topside-color-surface);
|
|
87
|
+
--topside-dialog-border-color: #0000000D;
|
|
88
|
+
--topside-dialog-divider-color: #F0F0F0;
|
|
89
|
+
--topside-dialog-header-color: #07123C;
|
|
90
|
+
--topside-dialog-action-button-color: #6B7280;
|
|
91
|
+
--topside-dialog-action-button-hover-background-color: #E2E8F0;
|
|
85
92
|
/* Options popover layer tokens*/
|
|
86
93
|
--topside-popover-layer-top-margin: 0;
|
|
87
94
|
--topside-option-item-margin: 6px 8px;
|
|
@@ -547,6 +554,12 @@
|
|
|
547
554
|
--topside-toast-color: var(--topside-color-primary); /* 文字依然保持高清晰度的白 */
|
|
548
555
|
/* Dialog and message box*/
|
|
549
556
|
--topside-dialog-action-button-color-hover-surface: rgba(0, 0, 0, 0.07);
|
|
557
|
+
--topside-dialog-color-surface: var(--topside-color-surface);
|
|
558
|
+
--topside-dialog-border-color: var(--topside-color-border-primary);
|
|
559
|
+
--topside-dialog-divider-color: var(--topside-color-border-secondary);
|
|
560
|
+
--topside-dialog-header-color: var(--topside-primary-color-font);
|
|
561
|
+
--topside-dialog-action-button-color: var(--topside-secondary-color-font);
|
|
562
|
+
--topside-dialog-action-button-hover-background-color: var(--topside-color-surface-variant);
|
|
550
563
|
/* Options popover layer tokens*/
|
|
551
564
|
--topside-popover-layer-color-surface: #262626;
|
|
552
565
|
--topside-popover-layer-color: #e5e7eb;
|
package/package.json
CHANGED