@ticatec/topside-elements 1.0.3 → 1.0.5

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 CHANGED
@@ -1,5 +1,20 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.0.5
4
+
5
+ ### 修复
6
+ - **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 等)在暗色主题下随主题切换。
7
+
8
+ ## 1.0.4
9
+
10
+ ### 变更
11
+ - **ProgressStepBar 布局重做**:横向改为圆圈在上、标题 / comment 居中在圆圈下方,步骤等分宽度、长标题截断;连接线不再用贯穿整块的 `linear-gradient`,改为指示器上的伪元素只在相邻圆圈之间画线段(横向 `::before` / `::after` 两段,纵向一段),首尾圆圈外侧无线。线的颜色跟随左侧 / 上方步骤:该步 `Completed` 为蓝,否则为灰;横向两个半段由内部 `connected` 标记保持一致。
12
+ - **纵向不再要求父容器有高度**:按内容撑开、步骤间距 12px;父容器给了高度时步骤才拉伸均分。
13
+ - 连接线不再依赖 `--topside-progress-step-bar-color-surface` 是纯色,透明 / 图片 / 渐变背景下圆圈处不会漏线;该变量现在只是容器背景。
14
+
15
+ ### 文档
16
+ - 更新 `progress_step_bar/README(_CN).md`、AI 编码指南中步骤条示例(原示例用的 `steps` / `activeIndex` 并不存在,改为 `items` + `status`);测试套件 `/test/navigation/progress-step-bar` 扩充为横向 / 纵向 / 窄容器 / 动态 / 非纯色背景 / 自定义颜色等示例。
17
+
3
18
  ## 1.0.3
4
19
 
5
20
  ### 变更
@@ -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
- justify-items: flex-start;
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.processing .step-indicator span {
138
- background-color: var(--topside-progress-step-processing-color, #0061FF);
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
- .progress-step-block.completed .step-comment {
157
- color: var(--topside-progress-step-completed-color, #374151);
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
- /* Vertical styles */
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
- margin-left: 0;
163
- background: linear-gradient(to right, transparent 12px, var(--topside-progress-step-pending-color, #B3BCCA) 14px,
164
- var(--topside-progress-step-pending-color, #B3BCCA) 14px, transparent 13px);
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.completed {
168
- background: linear-gradient(to right, transparent 12px, var(--topside-progress-step-completed-icon-color, #0061FF) 14px,
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
- margin-left: 0;
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
- background: var(--topside-progress-step-bar-color-surface);
178
- padding: 4px 0;
204
+ position: relative;
205
+ z-index: 1;
206
+ line-height: 0;
179
207
  }
180
208
 
181
- .progress-step-block.vertical:last-child {
182
- background: unset;
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-topic span {
186
- padding-left: 0;
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:last-child {
191
- background: unset;
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:last-child .step-indicator > div {
195
- background: transparent;
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**: drawn via CSS `linear-gradient` between adjacent circles; the line color follows step status (blue when completed, gray when pending)
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
- Done ...
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. The connecting line is blue when the step is `Completed`, gray when `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 (also used as the "background behind the line" so the line appears to break around the circle) |
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
- Each step's `background` is a `linear-gradient` that draws a 2px horizontal (or vertical) line at the indicator's center. The circle itself sits on top with a same-color background, making it look like the line breaks around the circle. Status-specific classes override the gradient color.
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
- This is fragile — if you change `--topside-progress-step-bar-color-surface` to a non-solid background (image, gradient), the line will visually leak through the circle.
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="height: 480px;">
190
+ <div style="width: 240px;">
189
191
  <ProgressStepBar {items} direction="vertical" />
190
192
  </div>
191
193
  ```
192
194
 
193
- Vertical mode fills the parent's height — make sure the parent has a height or the layout collapses.
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
- - **First step has no left margin**; subsequent steps use `margin-left: 8px` (horizontal) or no margin (vertical, since the line connects vertically).
222
- - **Last step keeps the line** for visual continuity — there's a `.progress-step-block:last-child` rule but it's empty in horizontal mode. In vertical mode, the line is unset on the last step.
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
- 1. **The connector line is implemented via `background` gradient** on each step block. If you change the surface color (`--topside-progress-step-bar-color-surface`) to a non-solid background, the line will leak through the circles.
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. **Use `direction="vertical"` only inside a height-constrained parent** (sidebar, drawer). Otherwise it collapses.
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 — the structure is fragile (see connector line note).
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
- - **连接线**:通过 CSS `linear-gradient` 在相邻圆圈之间画线;线颜色跟随步骤状态(已完成蓝、未开始灰)
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
- 实心圆(●)是已完成或进行中;空心圆(○)是未开始。连接线在步骤 `Completed` 时为蓝色,`Pending` 时为灰色。
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
- 每个步骤的 `background` 是个 `linear-gradient`,在指示器中心画一条 2px 横线(或竖线)。圆圈本身在上面,背景同色,让线看起来在圆圈处断开。状态相关的类覆盖 gradient 颜色。
142
+ **横向**:每个 `.step-indicator` 是 `position: relative`,用 `::before`(进入段:左边缘到圆圈)和 `::after`(离开段:圆圈到右边缘)各画一条 2px 线段。首步隐藏 `::before`,末步隐藏 `::after`。本步 `Completed` 时 `::after` 变蓝;块带 `connected` 类(前一步 `Completed`)时 `::before` 变蓝,所以同一条连接线的两半颜色总是一致。不依赖 surface 颜色。
143
143
 
144
- 这个机制脆弱 —— 把 `--topside-progress-step-bar-color-surface` 改成非纯色背景(图片、渐变),线会从圆圈里漏出来。
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="height: 480px;">
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
- - **首步无左 margin**;后续步骤横向 `margin-left: 8px`,纵向无 margin(因为线是竖向连接的)
222
- - **末步保留线**为了视觉连续 —— 有 `.progress-step-block:last-child` 规则但横向模式下为空。纵向模式下末步的线被 unset
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
- 1. **连接线通过每个步骤块的 `background` gradient 实现。** 把 surface 色(`--topside-progress-step-bar-color-surface`)改成非纯色背景(图片、渐变),线会从圆圈里漏出来
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>:global(:root) {
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ticatec/topside-elements",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "description": "A comprehensive UI component library for Svelte applications with rich form controls, data tables, layouts and interactive elements",
5
5
  "keywords": [
6
6
  "svelte",