@young1lin/dsh-ui-gitworkbench 0.1.12 → 0.1.13
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 +15 -0
- package/CHANGELOG_EN.md +15 -0
- package/README.md +50 -0
- package/README_EN.md +1 -1
- package/lib/client.js +698 -304
- package/package.json +1 -1
- package/src/client/CodeEditor.tsx +129 -3
- package/src/client/cm-search-theme.ts +250 -0
- package/src/client/search-count.ts +125 -0
- package/src/client/styles/changes.css +11 -10
- package/src/client/styles/controls.css +19 -8
- package/src/client/styles/files.css +6 -4
- package/src/client/styles/history-filters.css +25 -35
- package/src/client/styles/history.css +1 -1
- package/src/client/styles/shell.css +6 -5
|
@@ -82,9 +82,20 @@
|
|
|
82
82
|
because it has to win against the grouped rule above by source order. */
|
|
83
83
|
.scopeBtn { flex: 1 1 0; }
|
|
84
84
|
|
|
85
|
-
/* The single "this one is selected" idiom
|
|
86
|
-
|
|
87
|
-
|
|
85
|
+
/* The single "this one is selected" idiom: accent text, in an accent tint,
|
|
86
|
+
inside an accent border. Everything that can be the chosen one is here — a
|
|
87
|
+
tree leaf, a commit, a ref, a palette, a segment, a funnel tab, a date
|
|
88
|
+
bound, a preset — because the drawer had reached three spellings of one
|
|
89
|
+
meaning (this chip, a filled panel, a left accent bar) and showed two of
|
|
90
|
+
them at once whenever the Changes tree sat beside the history.
|
|
91
|
+
|
|
92
|
+
A modifier applied as `${css.base} ${css.mod}` carries the SAME specificity
|
|
93
|
+
as its base, so source order decides. Every base named here is declared
|
|
94
|
+
above this rule; `.fbRow.fbRowActive` is the one exception and is written
|
|
95
|
+
qualified, because `files.css` is imported after this file. */
|
|
96
|
+
.scopeBtnActive, .miniBtnPrimary, .segmentActive, .refRowActive, .paletteRowActive,
|
|
97
|
+
.fileActive, .commitActive, .funnelTabActive, .funnelBoundBtnActive, .funnelPresetActive,
|
|
98
|
+
.fbRow.fbRowActive {
|
|
88
99
|
border-color: var(--gs-accent-border);
|
|
89
100
|
background: var(--gs-accent-bg);
|
|
90
101
|
color: var(--gs-accent);
|
|
@@ -125,10 +136,10 @@
|
|
|
125
136
|
/* Publishing a branch that exists nowhere else is the one moment this bar has a
|
|
126
137
|
primary action, so it gets the solid fill Commit uses — and only then. */
|
|
127
138
|
.btnPrimary {
|
|
128
|
-
border-color: var(--gs-accent); background: var(--gs-accent); color: var(--gs-on-accent
|
|
139
|
+
border-color: var(--gs-accent); background: var(--gs-accent); color: var(--gs-on-accent);
|
|
129
140
|
font-weight: 600;
|
|
130
141
|
}
|
|
131
|
-
.btnPrimary:hover:not(:disabled) { background: var(--gs-accent); color: var(--gs-on-accent
|
|
142
|
+
.btnPrimary:hover:not(:disabled) { background: var(--gs-accent); color: var(--gs-on-accent); border-color: var(--gs-accent); }
|
|
132
143
|
|
|
133
144
|
/* The count riding inside Pull / Push. Reads as part of the label rather than a
|
|
134
145
|
badge stuck on it: same colour, tabular, just set apart by a hairline. */
|
|
@@ -165,7 +176,7 @@
|
|
|
165
176
|
background: var(--gs-border);
|
|
166
177
|
background-clip: padding-box;
|
|
167
178
|
border: 3px solid transparent;
|
|
168
|
-
border-radius:
|
|
179
|
+
border-radius: var(--gs-r-pill);
|
|
169
180
|
}
|
|
170
181
|
.drawer ::-webkit-scrollbar-thumb:hover { background: var(--gs-fg-faint); background-clip: padding-box; }
|
|
171
182
|
|
|
@@ -219,7 +230,7 @@
|
|
|
219
230
|
`.btn` wherever either rule sits, which is the failure the drawer already
|
|
220
231
|
shipped once. */
|
|
221
232
|
.btn.btnDanger {
|
|
222
|
-
border-color: var(--gs-del); background: var(--gs-del); color: var(--gs-on-accent
|
|
233
|
+
border-color: var(--gs-del); background: var(--gs-del); color: var(--gs-on-accent);
|
|
223
234
|
font-weight: 600;
|
|
224
235
|
}
|
|
225
|
-
.btn.btnDanger:hover:not(:disabled) { border-color: var(--gs-del); background: var(--gs-del); color: var(--gs-on-accent
|
|
236
|
+
.btn.btnDanger:hover:not(:disabled) { border-color: var(--gs-del); background: var(--gs-del); color: var(--gs-on-accent); }
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
color: var(--gs-fg);
|
|
22
22
|
background: var(--gs-surface);
|
|
23
23
|
border: 1px solid var(--gs-border);
|
|
24
|
-
border-radius:
|
|
24
|
+
border-radius: var(--gs-r-control);
|
|
25
25
|
}
|
|
26
26
|
.fbSearch:focus { outline: none; border-color: var(--gs-accent); }
|
|
27
27
|
.fbNote { flex: none; font-size: var(--gs-t-meta); color: var(--gs-fg-dim); padding: 2px 4px; }
|
|
@@ -38,14 +38,16 @@
|
|
|
38
38
|
text-align: left;
|
|
39
39
|
background: none;
|
|
40
40
|
border: 0;
|
|
41
|
-
border-radius:
|
|
41
|
+
border-radius: var(--gs-r-control);
|
|
42
42
|
cursor: pointer;
|
|
43
43
|
white-space: nowrap;
|
|
44
44
|
overflow: hidden;
|
|
45
45
|
text-overflow: ellipsis;
|
|
46
46
|
}
|
|
47
|
-
.fbRow:hover { background: var(--gs-
|
|
48
|
-
.fbRowActive
|
|
47
|
+
.fbRow:hover { background: var(--gs-raise); }
|
|
48
|
+
/* .fbRowActive: see the shared selected-state rule in controls.css. It is
|
|
49
|
+
written there qualified, because this file is imported after that one and a
|
|
50
|
+
bare modifier declared above its base loses the cascade. */
|
|
49
51
|
.fbDirName { overflow: hidden; text-overflow: ellipsis; }
|
|
50
52
|
.fbFileName { overflow: hidden; text-overflow: ellipsis; }
|
|
51
53
|
.fbMain {
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
font-family: inherit; font-size: var(--gs-t-dense); line-height: 20px;
|
|
48
48
|
cursor: pointer;
|
|
49
49
|
}
|
|
50
|
-
.filterChipRemove:hover { color: var(--gs-
|
|
50
|
+
.filterChipRemove:hover { color: var(--gs-del); }
|
|
51
51
|
.filterClear {
|
|
52
52
|
border: none; background: transparent;
|
|
53
53
|
padding: 2px 4px;
|
|
@@ -91,13 +91,17 @@
|
|
|
91
91
|
display: flex; gap: 2px;
|
|
92
92
|
margin: 8px 8px 0;
|
|
93
93
|
padding: 2px;
|
|
94
|
-
border: 1px solid var(--gs-border-soft); border-radius: var(--gs-r-
|
|
94
|
+
border: 1px solid var(--gs-border-soft); border-radius: var(--gs-r-control);
|
|
95
95
|
background: var(--gs-bg);
|
|
96
96
|
}
|
|
97
97
|
.funnelTab {
|
|
98
98
|
flex: 1; min-width: 0;
|
|
99
|
-
|
|
100
|
-
|
|
99
|
+
box-sizing: border-box;
|
|
100
|
+
height: var(--gs-h-compact); padding: 0 8px;
|
|
101
|
+
/* Transparent rather than none: the shared selected rule paints its
|
|
102
|
+
members through `border-color`, and a border that is not there takes
|
|
103
|
+
no colour. Inside `border-box`, so the strip does not grow by 2px. */
|
|
104
|
+
border: 1px solid transparent; border-radius: calc(var(--gs-r-control) - 3px);
|
|
101
105
|
background: transparent;
|
|
102
106
|
color: var(--gs-fg-dim);
|
|
103
107
|
font-family: inherit; font-size: var(--gs-t-dense); line-height: 1;
|
|
@@ -106,11 +110,7 @@
|
|
|
106
110
|
transition: background 120ms ease, color 120ms ease;
|
|
107
111
|
}
|
|
108
112
|
.funnelTab:hover { color: var(--gs-fg); }
|
|
109
|
-
.
|
|
110
|
-
color: var(--gs-fg);
|
|
111
|
-
background: var(--gs-raise);
|
|
112
|
-
box-shadow: inset 0 0 0 1px var(--gs-border);
|
|
113
|
-
}
|
|
113
|
+
/* .funnelTabActive: see the shared selected-state rule in controls.css. */
|
|
114
114
|
.funnelTab:focus-visible { outline: 2px solid var(--gs-accent); outline-offset: 1px; }
|
|
115
115
|
/* A tab's own criteria count, so the two sections nobody is looking at still
|
|
116
116
|
say they hold something. */
|
|
@@ -126,7 +126,7 @@
|
|
|
126
126
|
.funnelCaption {
|
|
127
127
|
flex: none;
|
|
128
128
|
color: var(--gs-fg-faint);
|
|
129
|
-
font-size:
|
|
129
|
+
font-size: var(--gs-t-meta); line-height: 14px;
|
|
130
130
|
letter-spacing: 0.04em; text-transform: uppercase;
|
|
131
131
|
}
|
|
132
132
|
|
|
@@ -143,8 +143,9 @@
|
|
|
143
143
|
}
|
|
144
144
|
.funnelBoundBtn {
|
|
145
145
|
flex: 1; min-width: 0;
|
|
146
|
-
|
|
147
|
-
|
|
146
|
+
box-sizing: border-box;
|
|
147
|
+
height: var(--gs-h-compact); padding: 0 6px;
|
|
148
|
+
border: 1px solid transparent; border-radius: calc(var(--gs-r-control) - 3px);
|
|
148
149
|
background: transparent;
|
|
149
150
|
color: var(--gs-fg-dim);
|
|
150
151
|
font-family: inherit; font-size: var(--gs-t-dense); line-height: 1;
|
|
@@ -152,11 +153,7 @@
|
|
|
152
153
|
transition: background 120ms ease, color 120ms ease;
|
|
153
154
|
}
|
|
154
155
|
.funnelBoundBtn:hover { color: var(--gs-fg); }
|
|
155
|
-
.
|
|
156
|
-
color: var(--gs-accent);
|
|
157
|
-
background: var(--gs-accent-bg);
|
|
158
|
-
box-shadow: inset 0 0 0 1px var(--gs-accent-border);
|
|
159
|
-
}
|
|
156
|
+
/* .funnelBoundBtnActive: see the shared selected-state rule in controls.css. */
|
|
160
157
|
|
|
161
158
|
/* The calendar — modern-grid look in the drawer's own tokens. */
|
|
162
159
|
.cal { flex: none; display: flex; flex-direction: column; gap: 4px; }
|
|
@@ -168,7 +165,7 @@
|
|
|
168
165
|
}
|
|
169
166
|
.calNav {
|
|
170
167
|
flex: none;
|
|
171
|
-
width:
|
|
168
|
+
width: var(--gs-h-compact); height: var(--gs-h-compact); padding: 0;
|
|
172
169
|
border: none; border-radius: var(--gs-r-control);
|
|
173
170
|
background: transparent;
|
|
174
171
|
color: var(--gs-fg-dim);
|
|
@@ -184,10 +181,10 @@
|
|
|
184
181
|
.calWeek span {
|
|
185
182
|
text-align: center;
|
|
186
183
|
color: var(--gs-fg-faint);
|
|
187
|
-
font-size:
|
|
184
|
+
font-size: var(--gs-t-meta); line-height: 14px;
|
|
188
185
|
}
|
|
189
186
|
.calGrid button {
|
|
190
|
-
height:
|
|
187
|
+
height: var(--gs-h-compact);
|
|
191
188
|
border: none; border-radius: var(--gs-r-control);
|
|
192
189
|
background: transparent;
|
|
193
190
|
color: var(--gs-fg-muted);
|
|
@@ -215,7 +212,7 @@
|
|
|
215
212
|
padding: 3px 6px;
|
|
216
213
|
border: 1px solid var(--gs-border-soft); border-radius: var(--gs-r-control);
|
|
217
214
|
background: var(--gs-bg);
|
|
218
|
-
font-size:
|
|
215
|
+
font-size: var(--gs-t-meta); line-height: 16px;
|
|
219
216
|
}
|
|
220
217
|
.funnelBoundKey { flex: none; color: var(--gs-fg-faint); }
|
|
221
218
|
.funnelBoundVal {
|
|
@@ -233,12 +230,12 @@
|
|
|
233
230
|
font-family: inherit; font-size: var(--gs-t-dense); line-height: 1;
|
|
234
231
|
cursor: pointer;
|
|
235
232
|
}
|
|
236
|
-
.funnelBoundClear:hover { color: var(--gs-
|
|
233
|
+
.funnelBoundClear:hover { color: var(--gs-del); }
|
|
237
234
|
|
|
238
235
|
.funnelSearch {
|
|
239
236
|
flex: none;
|
|
240
237
|
box-sizing: border-box;
|
|
241
|
-
height:
|
|
238
|
+
height: var(--gs-h-compact); padding: 0 8px;
|
|
242
239
|
border: 1px solid var(--gs-border-soft); border-radius: var(--gs-r-control);
|
|
243
240
|
background: var(--gs-bg); color: var(--gs-fg);
|
|
244
241
|
font-family: inherit; font-size: var(--gs-t-dense);
|
|
@@ -257,7 +254,7 @@
|
|
|
257
254
|
.funnelList::-webkit-scrollbar-track { background: transparent; }
|
|
258
255
|
.funnelList::-webkit-scrollbar-thumb {
|
|
259
256
|
background: var(--gs-fg-fainter);
|
|
260
|
-
border: 3px solid transparent; border-radius:
|
|
257
|
+
border: 3px solid transparent; border-radius: var(--gs-r-pill);
|
|
261
258
|
background-clip: content-box;
|
|
262
259
|
}
|
|
263
260
|
/* Every row is the same four slots — chevron, tick, glyph, name — then the
|
|
@@ -339,7 +336,7 @@
|
|
|
339
336
|
.funnelCount {
|
|
340
337
|
flex: none;
|
|
341
338
|
color: var(--gs-fg-faint);
|
|
342
|
-
font-size:
|
|
339
|
+
font-size: var(--gs-t-meta);
|
|
343
340
|
font-variant-numeric: tabular-nums;
|
|
344
341
|
}
|
|
345
342
|
.funnelMore { color: var(--gs-fg-faint); padding: 4px 6px; }
|
|
@@ -360,14 +357,7 @@
|
|
|
360
357
|
the drawer. It is in both selector lists now; this only sizes them to share
|
|
361
358
|
one row. */
|
|
362
359
|
.funnelPreset { flex: 1 1 0; min-width: 0; padding: 0 6px; }
|
|
363
|
-
/*
|
|
364
|
-
several hundred lines BELOW this one, so a bare modifier would lose its
|
|
365
|
-
background to that rule's `background: transparent`. */
|
|
366
|
-
.funnelPreset.funnelPresetActive {
|
|
367
|
-
color: var(--gs-accent);
|
|
368
|
-
border-color: var(--gs-accent);
|
|
369
|
-
background: var(--gs-accent-bg);
|
|
370
|
-
}
|
|
360
|
+
/* .funnelPresetActive: see the shared selected-state rule in controls.css. */
|
|
371
361
|
|
|
372
362
|
/* The footer says what the panel is currently asking git for. Without it the
|
|
373
363
|
only feedback lived on the chip row BEHIND the panel, so a reader had to
|
|
@@ -378,7 +368,7 @@
|
|
|
378
368
|
padding: 6px 10px;
|
|
379
369
|
border-top: 1px solid var(--gs-border-soft);
|
|
380
370
|
background: var(--gs-bg);
|
|
381
|
-
font-size:
|
|
371
|
+
font-size: var(--gs-t-meta); line-height: 16px;
|
|
382
372
|
}
|
|
383
373
|
.funnelFootCount { color: var(--gs-fg-faint); font-variant-numeric: tabular-nums; }
|
|
384
374
|
.funnelFootCountOn { color: var(--gs-fg-muted); }
|
|
@@ -388,7 +378,7 @@
|
|
|
388
378
|
border: none; border-radius: var(--gs-r-control);
|
|
389
379
|
background: transparent;
|
|
390
380
|
color: var(--gs-fg-dim);
|
|
391
|
-
font-family: inherit; font-size:
|
|
381
|
+
font-family: inherit; font-size: var(--gs-t-meta); line-height: 16px;
|
|
392
382
|
cursor: pointer;
|
|
393
383
|
}
|
|
394
384
|
.funnelFootClear:hover:not(:disabled) { color: var(--gs-fg); background: var(--gs-raise); }
|
|
@@ -208,7 +208,7 @@
|
|
|
208
208
|
min-width: 0;
|
|
209
209
|
}
|
|
210
210
|
.commit:hover { background: var(--gs-raise); }
|
|
211
|
-
.commitActive
|
|
211
|
+
/* .commitActive: see the shared selected-state rule in controls.css. */
|
|
212
212
|
/* Pushed to the right end of the row, and never squeezed: the subject is what
|
|
213
213
|
gives way when the pane narrows, because it is the part with an ellipsis to
|
|
214
214
|
give. */
|
|
@@ -41,8 +41,9 @@
|
|
|
41
41
|
|
|
42
42
|
/* Radii. Four values, each with one job; nothing else may invent a fifth. */
|
|
43
43
|
--gs-r-pill: 999px; /* drawer chrome: header actions, ref chips, triggers */
|
|
44
|
-
--gs-r-control: 8px; /* controls inside a panel or pane; inputs; badges
|
|
45
|
-
|
|
44
|
+
--gs-r-control: 8px; /* controls inside a panel or pane; inputs; badges;
|
|
45
|
+
and the dense list rows a tree or a picker is made of */
|
|
46
|
+
--gs-r-surface: 12px; /* the tall card rows, popovers and panes they sit in */
|
|
46
47
|
--gs-r-drawer: 14px; /* the drawer and its companion card */
|
|
47
48
|
|
|
48
49
|
/* Type — dsh's --dsw-font-* ladder, which tops out at 11px for meta text. */
|
|
@@ -215,7 +216,7 @@
|
|
|
215
216
|
display: inline-flex; align-items: center; gap: 6px;
|
|
216
217
|
padding: 2px 10px;
|
|
217
218
|
border: 1px solid var(--gs-accent-border);
|
|
218
|
-
border-radius:
|
|
219
|
+
border-radius: var(--gs-r-pill);
|
|
219
220
|
background: var(--gs-accent-bg);
|
|
220
221
|
color: var(--gs-accent);
|
|
221
222
|
font-weight: 600;
|
|
@@ -271,7 +272,7 @@
|
|
|
271
272
|
.headerView {
|
|
272
273
|
flex: none;
|
|
273
274
|
padding: 1px 8px;
|
|
274
|
-
border-radius:
|
|
275
|
+
border-radius: var(--gs-r-pill);
|
|
275
276
|
background: var(--gs-neutral-bg);
|
|
276
277
|
color: var(--gs-fg-muted);
|
|
277
278
|
font-size: var(--gs-t-meta);
|
|
@@ -279,7 +280,7 @@
|
|
|
279
280
|
}
|
|
280
281
|
.headerDetached {
|
|
281
282
|
padding: 1px 8px;
|
|
282
|
-
border-radius:
|
|
283
|
+
border-radius: var(--gs-r-pill);
|
|
283
284
|
background: var(--gs-warn-bg);
|
|
284
285
|
color: var(--gs-warn);
|
|
285
286
|
font-size: var(--gs-t-meta);
|