@sparkelf/dsh-patch-state-dot-brand-blue 0.2.0-rc.26

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 DeepSeek
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/package.json ADDED
@@ -0,0 +1,39 @@
1
+ {
2
+ "description": "Exact source patch restoring the pixel-matrix loading animation in the brand blue",
3
+ "dshPatch": {
4
+ "formatVersion": 1,
5
+ "variants": [
6
+ {
7
+ "dsh": ">=0.1.7-rc.2",
8
+ "file": "./patches/state-dot-brand-blue.patch",
9
+ "id": "state-dot-brand-blue",
10
+ "target": {
11
+ "baseRevision": "477b4f420553e8a52c2fbccc464d7561b239c443",
12
+ "kind": "dsh-source",
13
+ "paths": [
14
+ "packages/client/ui-primitives/src/"
15
+ ]
16
+ }
17
+ }
18
+ ]
19
+ },
20
+ "exports": {
21
+ "./package.json": "./package.json",
22
+ "./patches/state-dot-brand-blue.patch": "./patches/state-dot-brand-blue.patch"
23
+ },
24
+ "files": [
25
+ "patches/*.patch"
26
+ ],
27
+ "license": "MIT",
28
+ "name": "@sparkelf/dsh-patch-state-dot-brand-blue",
29
+ "publishConfig": {
30
+ "access": "public"
31
+ },
32
+ "repository": {
33
+ "directory": "patches/npm/state-dot-brand-blue",
34
+ "type": "git",
35
+ "url": "git+https://github.com/SparkElf/deepseek-harness-plus.git"
36
+ },
37
+ "type": "module",
38
+ "version": "0.2.0-rc.26"
39
+ }
@@ -0,0 +1,174 @@
1
+ diff --git a/packages/client/ui-primitives/src/StateDot.module.css b/packages/client/ui-primitives/src/StateDot.module.css
2
+ index 1a692c6892..3aa3186b94 100644
3
+ --- a/packages/client/ui-primitives/src/StateDot.module.css
4
+ +++ b/packages/client/ui-primitives/src/StateDot.module.css
5
+ @@ -1,4 +1,12 @@
6
+ -/* Solid states keep the 10px layout slot but paint one 6px currentColor core. */
7
+ +/* Ongoing blue has no alias token (state-business-primary is the 500 step,
8
+ + * not this 450) — component-level var pinned to the static scale instead. */
9
+ +.dot,
10
+ +.matrix {
11
+ + --dsh-state-ongoing: var(--dsw-static-deepseek-450);
12
+ +}
13
+ +
14
+ +/* Solid states: same-color halo via a 0.10-opacity outer layer (::before)
15
+ + * with a 6/10-scale solid core. Layer color rides currentColor set per state. */
16
+ .dot {
17
+ position: relative;
18
+ display: inline-block;
19
+ @@ -31,70 +39,29 @@
20
+ color: var(--dsw-alias-state-idle-primary);
21
+ }
22
+
23
+ -/* Ongoing is the sole non-dot state: a quiet full ring sits behind a centered
24
+ - * breathing arc while the complete glyph rotates continuously. Both animations
25
+ - * share one 1.5s period so pinning their start times aligns them together. */
26
+ -.spinner {
27
+ +/* Pixel chase: each outer cell holds a discrete brightness step (flat keyframe
28
+ + * holds, no tweening — the retro feel), peaking when the chase hits it and
29
+ + * decaying over the next three cells. Phase offsets come from per-rect
30
+ + * animation-delay (index * -125ms) set inline by the component. */
31
+ +.matrix {
32
+ flex: none;
33
+ - color: var(--dsw-alias-label-tertiary);
34
+ -}
35
+ -
36
+ -.spinnerMotion {
37
+ - transform-origin: center;
38
+ - animation: dsh-state-dot-spin 1.5s linear infinite;
39
+ -}
40
+ -
41
+ -.spinnerTrack,
42
+ -.spinnerArc {
43
+ - fill: none;
44
+ - stroke: currentColor;
45
+ - stroke-width: 2;
46
+ - stroke-linecap: round;
47
+ -}
48
+ -
49
+ -.spinnerTrack {
50
+ - opacity: 0.25;
51
+ + color: var(--dsh-state-ongoing);
52
+ }
53
+
54
+ -.spinnerArc {
55
+ - stroke-dasharray: 12 150;
56
+ - animation: dsh-state-dot-dash 1.5s ease-in-out infinite;
57
+ +.cell {
58
+ + fill: currentColor;
59
+ + opacity: 0.15;
60
+ + animation: dsh-state-dot-chase 1s infinite;
61
+ }
62
+
63
+ -@keyframes dsh-state-dot-spin {
64
+ - to { transform: rotate(360deg); }
65
+ -}
66
+ -
67
+ -@keyframes dsh-state-dot-dash {
68
+ - 0% {
69
+ - stroke-dasharray: 12 150;
70
+ - stroke-dashoffset: 0;
71
+ - }
72
+ -
73
+ - 50% {
74
+ - stroke-dasharray: 24 150;
75
+ - stroke-dashoffset: -6;
76
+ - }
77
+ -
78
+ - 100% {
79
+ - stroke-dasharray: 12 150;
80
+ - stroke-dashoffset: 0;
81
+ - }
82
+ -}
83
+ -
84
+ -@media (prefers-reduced-motion: reduce) {
85
+ - .spinnerMotion,
86
+ - .spinnerArc {
87
+ - animation: none;
88
+ - }
89
+ -
90
+ - .spinnerArc {
91
+ - stroke-dasharray: 18 150;
92
+ - stroke-dashoffset: -3;
93
+ - }
94
+ +@keyframes dsh-state-dot-chase {
95
+ + 0%, 12.4% { opacity: 1; }
96
+ + 12.5%, 24.9% { opacity: 0.6; }
97
+ + 25%, 37.4% { opacity: 0.35; }
98
+ + 37.5%, 100% { opacity: 0.15; }
99
+ }
100
+
101
+ .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); }
102
+ .step[data-state='done'] { border-color: var(--dsw-alias-state-success-primary); background: var(--dsw-alias-state-success-primary); }
103
+ .step[data-state='error'] { border-color: var(--dsw-alias-state-error-primary); background: var(--dsw-alias-state-error-primary); }
104
+ -.step[data-state='warning'] { border-color: var(--dsw-alias-state-warn-primary); }
105
+ +.step[data-state='warning'] { border-color: var(--dsw-alias-state-warn-primary); }
106
+
107
+ diff --git a/packages/client/ui-primitives/src/StateDot.tsx b/packages/client/ui-primitives/src/StateDot.tsx
108
+ index ede3c6b98c..f54ebddf44 100644
109
+ --- a/packages/client/ui-primitives/src/StateDot.tsx
110
+ +++ b/packages/client/ui-primitives/src/StateDot.tsx
111
+ @@ -3,24 +3,15 @@ import css from './StateDot.module.css'
112
+ import { IconCheckOutlineRegular } from './icons/index.tsx'
113
+
114
+ /**
115
+ - * State semantic: green done / amber user-attention / tertiary-grey loading /
116
+ + * State semantic: green done / amber user-attention / blue running ring /
117
+ * red error / neutral-grey idle for a tracked subject with nothing in progress.
118
+ */
119
+ export type StateDotState = 'done' | 'warning' | 'ongoing' | 'error' | 'idle'
120
+
121
+ -/**
122
+ - * Pin the loader's CSS animations to document time zero. A CSS animation starts
123
+ - * when its element is inserted, so loaders mounted at different moments rotate
124
+ - * out of phase; one shared start time keeps every visible loader in step.
125
+ - * @param element - the mounted loader, or null on unmount.
126
+ - */
127
+ -function syncSpinner(element: SVGSVGElement | null): void {
128
+ - if (element === null) return
129
+ - // jsdom (the unit lane) implements no Web Animations despite lib.dom's
130
+ - // non-optional typing; the optional call leaves that lane unsynced.
131
+ - const spinner = element as { getAnimations?: SVGSVGElement['getAnimations'] }
132
+ - for (const animation of spinner.getAnimations?.({ subtree: true }) ?? []) animation.startTime = 0
133
+ -}
134
+ +/** Outer 3x3 matrix cells (2px pixels on a 10px grid), clockwise from top-left. */
135
+ +const MATRIX_CELLS: readonly (readonly [number, number])[] = [
136
+ + [0, 0], [4, 0], [8, 0], [8, 4], [8, 8], [4, 8], [0, 8], [0, 4],
137
+ +]
138
+
139
+ /**
140
+ * Render a state dot.
141
+ @@ -40,18 +31,26 @@ export function StateDot({ state, size, className, appearance = 'dot' }: {
142
+ if (state === 'ongoing') {
143
+ return (
144
+ <svg
145
+ - ref={syncSpinner}
146
+ - className={clsx(css.spinner, className)}
147
+ + className={clsx(css.matrix, className)}
148
+ data-state="ongoing"
149
+ width={edge}
150
+ height={edge}
151
+ - viewBox="0 0 24 24"
152
+ + viewBox="0 0 10 10"
153
+ + shapeRendering="crispEdges"
154
+ aria-hidden="true"
155
+ >
156
+ - <g className={css.spinnerMotion}>
157
+ - <circle className={css.spinnerTrack} cx="12" cy="12" r="9.5" />
158
+ - <circle className={css.spinnerArc} cx="12" cy="12" r="9.5" />
159
+ - </g>
160
+ + {MATRIX_CELLS.map(([x, y], index) => (
161
+ + <rect
162
+ + key={`${x}-${y}`}
163
+ + className={css.cell}
164
+ + x={x}
165
+ + y={y}
166
+ + width="2"
167
+ + height="2"
168
+ + /* Negative delay phases the chase so every cell animates from mount. */
169
+ + style={{ animationDelay: `${(index - MATRIX_CELLS.length) * 125}ms` }}
170
+ + />
171
+ + ))}
172
+ </svg>
173
+ )
174
+ }