@deepseek-ai/dsh-client-ui-primitives 0.1.6-alpha.1 → 0.1.7-alpha.1
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/README.i18n.yaml +2 -2
- package/README.md +33 -13
- package/README.zh.md +33 -13
- package/lib/Checkbox.module.css +28 -0
- package/lib/ConnectionIndicator.module.css +1 -10
- package/lib/HoverCard.module.css +27 -0
- package/lib/Menu.module.css +81 -48
- package/lib/Modal.module.css +6 -2
- package/lib/OnboardingSurface.module.css +1 -2
- package/lib/PathLabel.module.css +28 -0
- package/lib/RiskConfirmation.module.css +1 -1
- package/lib/SegmentedControl.module.css +76 -0
- package/lib/SegmentedTabs.module.css +55 -0
- package/lib/StateDot.module.css +64 -37
- package/lib/TerminalBlock.module.css +16 -9
- package/lib/TextShimmer.module.css +27 -0
- package/lib/Toast.module.css +31 -2
- package/lib/Tooltip.module.css +12 -0
- package/lib/index.js +6154 -3051
- package/lib/markdown/MarkdownText.module.css +145 -5
- package/lib/settings-form/SettingsForm.module.css +53 -0
- package/lib/settings-form/fields.module.css +145 -0
- package/lib/types/Checkbox.d.ts +20 -0
- package/lib/types/ConfigField.d.ts +33 -0
- package/lib/types/DisclosureRow.d.ts +4 -1
- package/lib/types/HoverCard.d.ts +14 -4
- package/lib/types/LinkIcon.d.ts +16 -20
- package/lib/types/Menu.d.ts +57 -7
- package/lib/types/Modal.d.ts +2 -1
- package/lib/types/PathLabel.d.ts +13 -0
- package/lib/types/PermissionIcon.d.ts +39 -0
- package/lib/types/ReferenceIcon.d.ts +12 -7
- package/lib/types/SegmentedControl.d.ts +35 -0
- package/lib/types/SegmentedTabs.d.ts +26 -0
- package/lib/types/SiteGlyph.d.ts +25 -0
- package/lib/types/StateDot.d.ts +6 -4
- package/lib/types/TerminalBlock.d.ts +21 -4
- package/lib/types/TextShimmer.d.ts +13 -0
- package/lib/types/Toast.d.ts +19 -2
- package/lib/types/Tooltip.d.ts +12 -2
- package/lib/types/code-file-types.d.ts +1 -1
- package/lib/types/code-highlighting.d.ts +19 -0
- package/lib/types/darwin-desktop.d.ts +9 -0
- package/lib/types/icons/index.d.ts +376 -191
- package/lib/types/icons/props.d.ts +1 -1
- package/lib/types/icons/shared-artwork.d.ts +36 -0
- package/lib/types/index.d.ts +25 -4
- package/lib/types/markdown/MarkdownDelegate.d.ts +36 -0
- package/lib/types/markdown/MarkdownText.d.ts +13 -6
- package/lib/types/markdown/file-link.d.ts +13 -0
- package/lib/types/markdown/render.d.ts +2 -2
- package/lib/types/overlay-top-margin.d.ts +14 -0
- package/lib/types/plugin-artwork.d.ts +17 -0
- package/lib/types/settings-form/SettingsForm.d.ts +46 -0
- package/lib/types/settings-form/fields.d.ts +69 -0
- package/lib/types/settings-form/form-model.d.ts +214 -0
- package/lib/types/useAnchoredMaxHeight.d.ts +4 -1
- package/lib/types/useAnchoredPosition.d.ts +3 -1
- package/package.json +6 -3
package/lib/Menu.module.css
CHANGED
|
@@ -3,19 +3,19 @@
|
|
|
3
3
|
display: inline-flex;
|
|
4
4
|
}
|
|
5
5
|
|
|
6
|
-
/*
|
|
7
|
-
* r12, elevation-prominent (hairline stroke in shadow), 4px inset padding. */
|
|
6
|
+
/* Compact translucent dropdown card shared by feature menus. */
|
|
8
7
|
.list,
|
|
9
8
|
.submenu {
|
|
10
9
|
/* min-widths below are the design's outer card widths — include the pad. */
|
|
11
10
|
box-sizing: border-box;
|
|
12
|
-
padding:
|
|
11
|
+
padding: 3px;
|
|
13
12
|
display: flex;
|
|
14
13
|
flex-direction: column;
|
|
15
14
|
gap: 0;
|
|
16
15
|
border: 0;
|
|
17
|
-
border-radius:
|
|
16
|
+
border-radius: 16px;
|
|
18
17
|
background: var(--dsw-specific-menu);
|
|
18
|
+
backdrop-filter: var(--dsw-menu-backdrop-filter);
|
|
19
19
|
--dsw-elevation-stroke-color: var(--dsw-alias-border-l1);
|
|
20
20
|
box-shadow: var(--dsw-elevation-prominent);
|
|
21
21
|
/* Elevated surface: the scrollbar thumb takes the l2 elevation tokens. The
|
|
@@ -27,13 +27,13 @@
|
|
|
27
27
|
--dsh-scrollbar-thumb-hover: var(--dsw-alias-scrollbar-hover-l2);
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
/* Primary
|
|
30
|
+
/* Primary cards grow with their content between compact and readable bounds. */
|
|
31
31
|
.list {
|
|
32
32
|
position: absolute;
|
|
33
33
|
top: calc(100% + 4px);
|
|
34
34
|
left: 0;
|
|
35
35
|
z-index: 100;
|
|
36
|
-
min-width:
|
|
36
|
+
min-width: 144px;
|
|
37
37
|
max-width: 360px;
|
|
38
38
|
}
|
|
39
39
|
|
|
@@ -60,12 +60,13 @@
|
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
/* Viewport fit: the card stops 12px short of the viewport's top/bottom edges
|
|
63
|
-
* (
|
|
63
|
+
* (the portal MARGIN in Menu.tsx; the top side widens to the frame's published
|
|
64
|
+
* top clearance, the macOS window strip) and taller content scrolls inside
|
|
64
65
|
* .viewport, so a pinned .footer stays visible. Menus with submenu rows skip
|
|
65
66
|
* this class — the overflow clip would crop the side card, so they rely on
|
|
66
67
|
* staying short. */
|
|
67
68
|
.scrollable {
|
|
68
|
-
max-height: calc(100vh -
|
|
69
|
+
max-height: calc(100vh - 12px - max(12px, var(--dsh-frame-top-clearance, 12px)));
|
|
69
70
|
}
|
|
70
71
|
|
|
71
72
|
.viewport {
|
|
@@ -84,8 +85,8 @@
|
|
|
84
85
|
flex: none;
|
|
85
86
|
display: flex;
|
|
86
87
|
flex-direction: column;
|
|
87
|
-
margin-top:
|
|
88
|
-
padding-top:
|
|
88
|
+
margin-top: 3px;
|
|
89
|
+
padding-top: 3px;
|
|
89
90
|
border-top: 0.5px solid var(--dsw-alias-border-l2);
|
|
90
91
|
}
|
|
91
92
|
|
|
@@ -93,21 +94,20 @@
|
|
|
93
94
|
position: relative;
|
|
94
95
|
}
|
|
95
96
|
|
|
96
|
-
/* Menu cell
|
|
97
|
-
* gap 8 between leading icon / label / trailing check. */
|
|
97
|
+
/* Menu cell: compact text, icon, and selection spacing. */
|
|
98
98
|
.item {
|
|
99
99
|
display: flex;
|
|
100
100
|
align-items: center;
|
|
101
|
-
gap:
|
|
101
|
+
gap: 6px;
|
|
102
102
|
width: 100%;
|
|
103
|
-
min-height:
|
|
104
|
-
padding: 8px
|
|
103
|
+
min-height: 34px;
|
|
104
|
+
padding: 6px 8px;
|
|
105
105
|
border: none;
|
|
106
|
-
border-radius:
|
|
106
|
+
border-radius: 8px;
|
|
107
107
|
background: transparent;
|
|
108
108
|
cursor: pointer;
|
|
109
|
-
font-size:
|
|
110
|
-
line-height:
|
|
109
|
+
font-size: 13px;
|
|
110
|
+
line-height: 20px;
|
|
111
111
|
color: var(--dsw-alias-label-primary);
|
|
112
112
|
text-align: left;
|
|
113
113
|
}
|
|
@@ -116,34 +116,42 @@
|
|
|
116
116
|
background: var(--dsw-alias-interactive-bg-hover);
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
+
/* Arrow navigation moves real focus, so the row the keyboard is on carries the
|
|
120
|
+
same fill the pointer gets: the fill is the row's focus indication, and the
|
|
121
|
+
browser's default ring would double it. */
|
|
122
|
+
.item:focus-visible:not(:disabled) {
|
|
123
|
+
background: var(--dsw-alias-interactive-bg-hover);
|
|
124
|
+
outline: none;
|
|
125
|
+
}
|
|
126
|
+
|
|
119
127
|
.denseList .item {
|
|
120
|
-
min-height:
|
|
121
|
-
padding-block:
|
|
128
|
+
min-height: 30px;
|
|
129
|
+
padding-block: 4px;
|
|
122
130
|
}
|
|
123
131
|
|
|
124
132
|
.denseList .label {
|
|
125
|
-
padding-block:
|
|
133
|
+
padding-block: 3px;
|
|
126
134
|
}
|
|
127
135
|
|
|
128
136
|
.list.compactList,
|
|
129
137
|
.submenu.compactList {
|
|
130
|
-
min-width:
|
|
138
|
+
min-width: 156px;
|
|
131
139
|
padding: 2px;
|
|
132
140
|
border-radius: 7px;
|
|
133
141
|
}
|
|
134
142
|
|
|
135
143
|
.compactList .item {
|
|
136
|
-
min-height:
|
|
137
|
-
gap:
|
|
138
|
-
padding:
|
|
144
|
+
min-height: 24px;
|
|
145
|
+
gap: 5px;
|
|
146
|
+
padding: 2px 6px;
|
|
139
147
|
border-radius: 5px;
|
|
140
|
-
font-size:
|
|
141
|
-
line-height:
|
|
148
|
+
font-size: 11px;
|
|
149
|
+
line-height: 17px;
|
|
142
150
|
}
|
|
143
151
|
|
|
144
152
|
.compactList .itemIcon {
|
|
145
|
-
width:
|
|
146
|
-
height:
|
|
153
|
+
width: 12px;
|
|
154
|
+
height: 12px;
|
|
147
155
|
}
|
|
148
156
|
|
|
149
157
|
.compactList .separator {
|
|
@@ -151,9 +159,9 @@
|
|
|
151
159
|
}
|
|
152
160
|
|
|
153
161
|
.compactList .label {
|
|
154
|
-
padding:
|
|
155
|
-
font-size:
|
|
156
|
-
line-height:
|
|
162
|
+
padding: 3px 6px;
|
|
163
|
+
font-size: 10px;
|
|
164
|
+
line-height: 15px;
|
|
157
165
|
}
|
|
158
166
|
|
|
159
167
|
.item:disabled {
|
|
@@ -164,13 +172,25 @@
|
|
|
164
172
|
.itemIcon {
|
|
165
173
|
display: inline-flex;
|
|
166
174
|
flex: none;
|
|
167
|
-
width:
|
|
168
|
-
height:
|
|
175
|
+
width: 14px;
|
|
176
|
+
height: 14px;
|
|
169
177
|
align-items: center;
|
|
170
178
|
justify-content: center;
|
|
171
179
|
color: var(--dsw-alias-label-tertiary);
|
|
172
180
|
}
|
|
173
181
|
|
|
182
|
+
.itemIcon svg,
|
|
183
|
+
.check {
|
|
184
|
+
width: 14px;
|
|
185
|
+
height: 14px;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
.compactList .itemIcon svg,
|
|
189
|
+
.compactList .check {
|
|
190
|
+
width: 12px;
|
|
191
|
+
height: 12px;
|
|
192
|
+
}
|
|
193
|
+
|
|
174
194
|
.itemLabel {
|
|
175
195
|
flex: 1;
|
|
176
196
|
min-width: 0;
|
|
@@ -208,32 +228,45 @@
|
|
|
208
228
|
background: var(--dsw-alias-interactive-bg-hover-danger);
|
|
209
229
|
}
|
|
210
230
|
|
|
231
|
+
.danger:focus-visible:not(:disabled) {
|
|
232
|
+
background: var(--dsw-alias-interactive-bg-hover-danger);
|
|
233
|
+
outline: none;
|
|
234
|
+
}
|
|
235
|
+
|
|
211
236
|
/* Heading row: non-interactive small grey text, padding aligned with items. */
|
|
212
237
|
.label {
|
|
213
|
-
padding: 8px
|
|
214
|
-
font-size:
|
|
215
|
-
line-height:
|
|
238
|
+
padding: 6px 8px;
|
|
239
|
+
font-size: 11px;
|
|
240
|
+
line-height: 15px;
|
|
216
241
|
color: var(--dsw-alias-label-tertiary);
|
|
217
242
|
}
|
|
218
243
|
|
|
219
|
-
/* Separator cell (figma 122:9481): py 4 / px 2 around the hairline.
|
|
244
|
+
/* Separator cell (figma 122:9481): py 4 / px 2 around the hairline. l2, not
|
|
245
|
+
* l1, for the same reason as .footer: l1 is near-invisible on this surface. */
|
|
220
246
|
.separator {
|
|
221
247
|
height: 0.5px;
|
|
222
|
-
margin:
|
|
223
|
-
background: var(--dsw-alias-border-
|
|
248
|
+
margin: 3px 2px;
|
|
249
|
+
background: var(--dsw-alias-border-l2);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/* A data separator directly followed by a row that starts a group draws one
|
|
253
|
+
* line, not two; a group start on the list's first row draws none. */
|
|
254
|
+
.separator + .separator,
|
|
255
|
+
.separator + .itemWrap > .separator:first-child,
|
|
256
|
+
.itemWrap:first-child > .separator:first-child {
|
|
257
|
+
display: none;
|
|
224
258
|
}
|
|
225
259
|
|
|
226
|
-
/* Nested card to the right of the parent row
|
|
260
|
+
/* Nested card to the right of the parent row.
|
|
227
261
|
* Bottom-aligned with the parent menu card (grows upward): itemWrap sits in
|
|
228
|
-
* .list's
|
|
229
|
-
* Horizontal: list pad (
|
|
230
|
-
* `100% + 6px` collapses to ~2px between outer card edges.
|
|
262
|
+
* .list's 3px pad, so bottom: -3px matches the list's outer bottom edge.
|
|
263
|
+
* Horizontal: list pad (3px) + 6px card gap = 9px past itemWrap.
|
|
231
264
|
* ::before bridges the full gap so the pointer can cross without mouseLeave. */
|
|
232
265
|
.submenu {
|
|
233
266
|
position: absolute;
|
|
234
267
|
top: auto;
|
|
235
|
-
bottom: -
|
|
236
|
-
left: calc(100% +
|
|
268
|
+
bottom: -3px;
|
|
269
|
+
left: calc(100% + 9px);
|
|
237
270
|
z-index: 101;
|
|
238
271
|
min-width: 163px;
|
|
239
272
|
}
|
|
@@ -243,6 +276,6 @@
|
|
|
243
276
|
position: absolute;
|
|
244
277
|
top: 0;
|
|
245
278
|
bottom: 0;
|
|
246
|
-
left: -
|
|
247
|
-
width:
|
|
279
|
+
left: -9px;
|
|
280
|
+
width: 9px;
|
|
248
281
|
}
|
package/lib/Modal.module.css
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
/* Full-viewport layer (figma Mask + Dialog 451:18655): mask + centered card.
|
|
1
|
+
/* Full-viewport layer (figma Mask + Dialog 451:18655): mask + centered card.
|
|
2
|
+
24px of air on every side; the top/bottom widen to the frame's published
|
|
3
|
+
top clearance (the macOS window strip) so a tall card stays clear of it.
|
|
4
|
+
Cards size against this padding box: consumers cap growth with
|
|
5
|
+
`max-height: 100%`, never their own viewport calc. */
|
|
2
6
|
.root {
|
|
3
7
|
position: fixed;
|
|
4
8
|
inset: 0;
|
|
@@ -6,7 +10,7 @@
|
|
|
6
10
|
display: flex;
|
|
7
11
|
align-items: center;
|
|
8
12
|
justify-content: center;
|
|
9
|
-
padding: 24px;
|
|
13
|
+
padding: max(24px, var(--dsh-frame-top-clearance, 24px)) 24px;
|
|
10
14
|
}
|
|
11
15
|
|
|
12
16
|
/* User/spec mask: rgba(0,0,0,0.24) + blur(2px) via --dsw-alias-bg-mask-1 /
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/* Auto margin keeps fitting text at the left. On overflow it becomes zero,
|
|
2
|
+
so flex-end preserves the filename suffix at the right edge. */
|
|
3
|
+
.path {
|
|
4
|
+
display: flex;
|
|
5
|
+
flex: 1 1 auto;
|
|
6
|
+
justify-content: flex-end;
|
|
7
|
+
min-width: 0;
|
|
8
|
+
overflow: hidden;
|
|
9
|
+
font-size: 12px;
|
|
10
|
+
white-space: nowrap;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.path[data-path-clipped] {
|
|
14
|
+
mask-image: linear-gradient(to right, transparent, black 28px);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.text {
|
|
18
|
+
flex: none;
|
|
19
|
+
margin-right: auto;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.directory {
|
|
23
|
+
color: var(--dsw-alias-label-tertiary);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.name {
|
|
27
|
+
color: var(--dsw-alias-label-primary);
|
|
28
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/* The track is the same translucent fill the hover state uses, so it reads as
|
|
2
|
+
* a place rather than a second button; the one raised part is the indicator,
|
|
3
|
+
* a white pill that slides under the selected segment. Its stroke rides inside
|
|
4
|
+
* the soft elevation shadow (border: 0), the way every elevated surface draws
|
|
5
|
+
* its edge, so the elevation gate keeps it off the alias-border set.
|
|
6
|
+
*
|
|
7
|
+
* Segments are equal-width grid tracks sized to the widest label, which is
|
|
8
|
+
* what lets one indicator be placed arithmetically: the tablist carries the
|
|
9
|
+
* segment count and the selected index as custom properties, and the indicator
|
|
10
|
+
* derives its width and offset from them instead of measuring the DOM. */
|
|
11
|
+
.control {
|
|
12
|
+
position: relative;
|
|
13
|
+
display: inline-grid;
|
|
14
|
+
grid-auto-flow: column;
|
|
15
|
+
grid-auto-columns: 1fr;
|
|
16
|
+
gap: 2px;
|
|
17
|
+
padding: 3px;
|
|
18
|
+
border-radius: 9px;
|
|
19
|
+
background: var(--dsw-alias-interactive-bg-hover);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.indicator {
|
|
23
|
+
position: absolute;
|
|
24
|
+
top: 3px;
|
|
25
|
+
left: 3px;
|
|
26
|
+
width: calc((100% - 6px - 2px * (var(--dsh-segment-count) - 1)) / var(--dsh-segment-count));
|
|
27
|
+
height: calc(100% - 6px);
|
|
28
|
+
border: 0;
|
|
29
|
+
border-radius: 7px;
|
|
30
|
+
background: var(--dsw-alias-bg-layer-1);
|
|
31
|
+
box-shadow: var(--dsw-elevation-soft);
|
|
32
|
+
transform: translateX(calc(var(--dsh-segment-index) * (100% + 2px)));
|
|
33
|
+
transition: transform 160ms ease;
|
|
34
|
+
pointer-events: none;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.tab {
|
|
38
|
+
box-sizing: border-box;
|
|
39
|
+
position: relative;
|
|
40
|
+
z-index: 1;
|
|
41
|
+
height: 28px;
|
|
42
|
+
padding: 0 16px;
|
|
43
|
+
border: 0;
|
|
44
|
+
border-radius: 7px;
|
|
45
|
+
background: transparent;
|
|
46
|
+
color: var(--dsw-alias-label-secondary);
|
|
47
|
+
font: inherit;
|
|
48
|
+
font-size: 13px;
|
|
49
|
+
line-height: 20px;
|
|
50
|
+
font-weight: 500;
|
|
51
|
+
white-space: nowrap;
|
|
52
|
+
cursor: pointer;
|
|
53
|
+
transition: color 120ms ease;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.tab:hover:not(:disabled),
|
|
57
|
+
.tab[aria-selected='true'] {
|
|
58
|
+
color: var(--dsw-alias-label-primary);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.tab:disabled {
|
|
62
|
+
cursor: default;
|
|
63
|
+
opacity: 0.4;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.tab:focus-visible {
|
|
67
|
+
outline: 2px solid var(--dsw-alias-brand-primary);
|
|
68
|
+
outline-offset: -2px;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
@media (prefers-reduced-motion: reduce) {
|
|
72
|
+
.indicator,
|
|
73
|
+
.tab {
|
|
74
|
+
transition: none;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
.tabs {
|
|
2
|
+
position: relative;
|
|
3
|
+
display: grid;
|
|
4
|
+
padding: 4px;
|
|
5
|
+
border-radius: 12px;
|
|
6
|
+
background: var(--dsw-alias-bg-module-platform);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.indicator {
|
|
10
|
+
position: absolute;
|
|
11
|
+
inset: 4px auto 4px 4px;
|
|
12
|
+
box-sizing: border-box;
|
|
13
|
+
border: 0.5px solid var(--dsw-alias-border-l3);
|
|
14
|
+
border-radius: 8px;
|
|
15
|
+
background: var(--dsw-alias-bg-layer-3);
|
|
16
|
+
transition: transform 180ms ease;
|
|
17
|
+
pointer-events: none;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.tab {
|
|
21
|
+
position: relative;
|
|
22
|
+
justify-content: center;
|
|
23
|
+
height: 34px;
|
|
24
|
+
padding: 0 12px;
|
|
25
|
+
border-radius: 8px;
|
|
26
|
+
font-size: 14px;
|
|
27
|
+
line-height: 20px;
|
|
28
|
+
background: transparent;
|
|
29
|
+
color: var(--dsw-alias-label-secondary);
|
|
30
|
+
transition: color 180ms ease;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.tab:hover,
|
|
34
|
+
.tab[aria-selected='true'] {
|
|
35
|
+
background: transparent;
|
|
36
|
+
color: var(--dsw-alias-label-primary);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.tab[aria-selected='true'] {
|
|
40
|
+
font-weight: 600;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.tab:focus-visible {
|
|
44
|
+
outline: none;
|
|
45
|
+
text-decoration: underline;
|
|
46
|
+
text-decoration-thickness: 1px;
|
|
47
|
+
text-underline-offset: 4px;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
@media (prefers-reduced-motion: reduce) {
|
|
51
|
+
.indicator,
|
|
52
|
+
.tab {
|
|
53
|
+
transition: none;
|
|
54
|
+
}
|
|
55
|
+
}
|
package/lib/StateDot.module.css
CHANGED
|
@@ -1,28 +1,10 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* not this 450) — component-level var pinned to the static scale instead. */
|
|
3
|
-
.dot,
|
|
4
|
-
.matrix {
|
|
5
|
-
--dsh-state-ongoing: var(--dsw-static-deepseek-450);
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
/* Solid states: same-color halo via a 0.10-opacity outer layer (::before)
|
|
9
|
-
* with a 6/10-scale solid core. Layer color rides currentColor set per state. */
|
|
1
|
+
/* Solid states keep the 10px layout slot but paint one 6px currentColor core. */
|
|
10
2
|
.dot {
|
|
11
3
|
position: relative;
|
|
12
4
|
display: inline-block;
|
|
13
5
|
flex: none;
|
|
14
6
|
}
|
|
15
7
|
|
|
16
|
-
.dot::before {
|
|
17
|
-
content: '';
|
|
18
|
-
position: absolute;
|
|
19
|
-
inset: 0;
|
|
20
|
-
border-radius: 50%;
|
|
21
|
-
corner-shape: round;
|
|
22
|
-
background: currentColor;
|
|
23
|
-
opacity: 0.1;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
8
|
.dot::after {
|
|
27
9
|
content: '';
|
|
28
10
|
position: absolute;
|
|
@@ -44,30 +26,75 @@
|
|
|
44
26
|
color: var(--dsw-alias-state-error-primary);
|
|
45
27
|
}
|
|
46
28
|
|
|
47
|
-
/* Idle is the absence of activity
|
|
48
|
-
* tertiary label color so it recedes beside the three outcome colors. */
|
|
29
|
+
/* Idle is the absence of activity and uses the theme's neutral state step. */
|
|
49
30
|
.dot[data-state='idle'] {
|
|
50
|
-
color: var(--dsw-alias-
|
|
31
|
+
color: var(--dsw-alias-state-idle-primary);
|
|
51
32
|
}
|
|
52
33
|
|
|
53
|
-
/*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
|
|
57
|
-
.matrix {
|
|
34
|
+
/* Ongoing is the sole non-dot state: a quiet full ring sits behind a centered
|
|
35
|
+
* breathing arc while the complete glyph rotates continuously. Both animations
|
|
36
|
+
* share one 1.5s period so pinning their start times aligns them together. */
|
|
37
|
+
.spinner {
|
|
58
38
|
flex: none;
|
|
59
|
-
color: var(--
|
|
39
|
+
color: var(--dsw-alias-label-tertiary);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.spinnerMotion {
|
|
43
|
+
transform-origin: center;
|
|
44
|
+
animation: dsh-state-dot-spin 1.5s linear infinite;
|
|
60
45
|
}
|
|
61
46
|
|
|
62
|
-
.
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
47
|
+
.spinnerTrack,
|
|
48
|
+
.spinnerArc {
|
|
49
|
+
fill: none;
|
|
50
|
+
stroke: currentColor;
|
|
51
|
+
stroke-width: 2;
|
|
52
|
+
stroke-linecap: round;
|
|
66
53
|
}
|
|
67
54
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
12.5%, 24.9% { opacity: 0.6; }
|
|
71
|
-
25%, 37.4% { opacity: 0.35; }
|
|
72
|
-
37.5%, 100% { opacity: 0.15; }
|
|
55
|
+
.spinnerTrack {
|
|
56
|
+
opacity: 0.25;
|
|
73
57
|
}
|
|
58
|
+
|
|
59
|
+
.spinnerArc {
|
|
60
|
+
stroke-dasharray: 12 150;
|
|
61
|
+
animation: dsh-state-dot-dash 1.5s ease-in-out infinite;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
@keyframes dsh-state-dot-spin {
|
|
65
|
+
to { transform: rotate(360deg); }
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
@keyframes dsh-state-dot-dash {
|
|
69
|
+
0% {
|
|
70
|
+
stroke-dasharray: 12 150;
|
|
71
|
+
stroke-dashoffset: 0;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
50% {
|
|
75
|
+
stroke-dasharray: 24 150;
|
|
76
|
+
stroke-dashoffset: -6;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
100% {
|
|
80
|
+
stroke-dasharray: 12 150;
|
|
81
|
+
stroke-dashoffset: 0;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
@media (prefers-reduced-motion: reduce) {
|
|
86
|
+
.spinnerMotion,
|
|
87
|
+
.spinnerArc {
|
|
88
|
+
animation: none;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.spinnerArc {
|
|
92
|
+
stroke-dasharray: 18 150;
|
|
93
|
+
stroke-dashoffset: -3;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.step { display: inline-flex; flex: none; align-items: center; justify-content: center; box-sizing: border-box; border-radius: 50%; corner-shape: round; border: 1.5px solid var(--dsw-alias-label-tertiary); color: var(--dsw-alias-label-primary-foreground); }
|
|
98
|
+
.step[data-state='done'] { border-color: var(--dsw-alias-state-success-primary); background: var(--dsw-alias-state-success-primary); }
|
|
99
|
+
.step[data-state='error'] { border-color: var(--dsw-alias-state-error-primary); background: var(--dsw-alias-state-error-primary); }
|
|
100
|
+
.step[data-state='warning'] { border-color: var(--dsw-alias-state-warn-primary); }
|
|
@@ -59,9 +59,9 @@
|
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
/* Full-width l2 hairline between the command banner and the body — the same
|
|
62
|
-
divider the IN/OUT card draws between its sections. A
|
|
63
|
-
|
|
64
|
-
.block
|
|
62
|
+
divider the IN/OUT card draws between its sections. A banner-only card (a
|
|
63
|
+
running command that has printed nothing yet) draws none. */
|
|
64
|
+
.block[data-body] .header {
|
|
65
65
|
border-bottom: 0.5px solid var(--dsw-alias-border-l2);
|
|
66
66
|
}
|
|
67
67
|
|
|
@@ -110,15 +110,18 @@
|
|
|
110
110
|
color: var(--dsw-alias-label-tertiary);
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
-
/* `pre`, not `nowrap`: the prompt row renders the command verbatim,
|
|
114
|
-
`nowrap`
|
|
115
|
-
continuation.
|
|
113
|
+
/* Default `pre`, not `nowrap`: the prompt row renders the command verbatim,
|
|
114
|
+
and `nowrap` would collapse the repeated spaces, tabs, and alignment of an
|
|
115
|
+
indented continuation. Hosts opt into wrapping long commands by rebinding
|
|
116
|
+
the variable to `pre-wrap`; the ellipsis then simply never engages, and
|
|
117
|
+
overflow-wrap is inert while white-space stays `pre`. */
|
|
116
118
|
.command {
|
|
117
119
|
min-width: 0;
|
|
118
120
|
color: var(--dsw-alias-label-primary);
|
|
119
121
|
overflow: hidden;
|
|
120
122
|
text-overflow: ellipsis;
|
|
121
|
-
white-space: pre;
|
|
123
|
+
white-space: var(--dsl-terminal-command-whitespace, pre);
|
|
124
|
+
overflow-wrap: anywhere;
|
|
122
125
|
}
|
|
123
126
|
|
|
124
127
|
/* Capped to the prompt's line height (Pill's own 24px height would exceed a
|
|
@@ -176,10 +179,14 @@
|
|
|
176
179
|
margin: 6px;
|
|
177
180
|
}
|
|
178
181
|
|
|
179
|
-
/*
|
|
182
|
+
/* Default `pre`: alignment is the payload of terminal output. Hosts opt
|
|
183
|
+
into wrapping long lines by rebinding the variable to `pre-wrap`, which
|
|
184
|
+
also keeps the output region from ever scrolling sideways; overflow-wrap
|
|
185
|
+
is inert while white-space stays `pre`. */
|
|
180
186
|
.line {
|
|
181
187
|
min-height: var(--dsl-terminal-line-height);
|
|
182
|
-
white-space: pre;
|
|
188
|
+
white-space: var(--dsl-terminal-line-whitespace, pre);
|
|
189
|
+
overflow-wrap: anywhere;
|
|
183
190
|
}
|
|
184
191
|
|
|
185
192
|
.expand {
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
.root[data-text-shimmer] {
|
|
2
|
+
background-image: linear-gradient(
|
|
3
|
+
90deg,
|
|
4
|
+
currentColor calc(50% - var(--dsh-text-shimmer-spread)),
|
|
5
|
+
color-mix(in oklab, currentColor 50%, transparent),
|
|
6
|
+
currentColor calc(50% + var(--dsh-text-shimmer-spread))
|
|
7
|
+
);
|
|
8
|
+
background-position: 100% center;
|
|
9
|
+
background-repeat: no-repeat;
|
|
10
|
+
background-size: 250% 100%;
|
|
11
|
+
background-clip: text;
|
|
12
|
+
-webkit-background-clip: text;
|
|
13
|
+
-webkit-text-fill-color: transparent;
|
|
14
|
+
animation: dsh-text-shimmer 1.5s cubic-bezier(0.33, 0, 0.67, 1) infinite;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
@keyframes dsh-text-shimmer {
|
|
18
|
+
66.6667%, 100% { background-position: 0% center; }
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
@media (prefers-reduced-motion: reduce) {
|
|
22
|
+
.root[data-text-shimmer] {
|
|
23
|
+
background-image: none;
|
|
24
|
+
-webkit-text-fill-color: currentColor;
|
|
25
|
+
animation: none;
|
|
26
|
+
}
|
|
27
|
+
}
|