Skip to content

Commit 3f4537b

Browse files
committed
fix: expose tree item decoration lane
Closes: #548 Signed-off-by: dankeboy36 <[email protected]>
1 parent eda2fab commit 3f4537b

File tree

6 files changed

+1023
-17
lines changed

6 files changed

+1023
-17
lines changed
Lines changed: 363 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,363 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>VSCode Elements</title>
7+
<link
8+
rel="stylesheet"
9+
href="/node_modules/@vscode/codicons/dist/codicon.css"
10+
id="vscode-codicon-stylesheet"
11+
>
12+
<script
13+
type="module"
14+
src="/node_modules/@vscode-elements/webview-playground/dist/index.js"
15+
></script>
16+
<script type="module" src="/dist/main.js"></script>
17+
<style>
18+
main {
19+
max-width: 640px;
20+
}
21+
22+
.demo-controls {
23+
display: flex;
24+
align-items: center;
25+
gap: 12px;
26+
margin-bottom: 16px;
27+
flex-wrap: wrap;
28+
}
29+
30+
.demo-controls .range-control {
31+
display: inline-flex;
32+
align-items: center;
33+
gap: 8px;
34+
flex: 1 1 260px;
35+
min-width: 240px;
36+
}
37+
38+
.demo-controls .range-control label {
39+
white-space: nowrap;
40+
}
41+
42+
.demo-controls .range-control input[type='range'] {
43+
flex: 1 1 auto;
44+
}
45+
46+
.actions-demo-frame {
47+
width: var(--demo-tree-width, 520px);
48+
border-radius: 8px;
49+
border: 1px solid rgba(255, 255, 255, 0.08);
50+
padding: 12px;
51+
background: rgba(255, 255, 255, 0.02);
52+
}
53+
54+
.scm-section-label,
55+
.scm-item-label {
56+
display: inline-flex;
57+
align-items: center;
58+
gap: 6px;
59+
min-width: 0;
60+
}
61+
62+
.scm-label-text {
63+
display: inline-block;
64+
min-width: 0;
65+
max-width: 100%;
66+
overflow: hidden;
67+
text-overflow: ellipsis;
68+
white-space: nowrap;
69+
}
70+
71+
.status-badge {
72+
font-size: 90%;
73+
font-weight: 600;
74+
letter-spacing: 0.3px;
75+
text-transform: uppercase;
76+
background: none;
77+
border: none;
78+
opacity: 0.75;
79+
margin: auto 4px 0 0;
80+
text-align: center;
81+
}
82+
83+
.status-badge--deleted {
84+
color: var(--vscode-gitDecoration-deletedResourceForeground, #ad0707);
85+
}
86+
87+
.status-badge--modified {
88+
color: var(--vscode-gitDecoration-modifiedResourceForeground, #895503);
89+
}
90+
91+
.status-badge--untracked {
92+
color: var(--vscode-gitDecoration-untrackedResourceForeground, #007100);
93+
}
94+
95+
.status-counter {
96+
font-weight: 600;
97+
text-transform: none;
98+
}
99+
100+
.scm-tree vscode-tree-item[selected][keyboard-focus] .status-badge,
101+
.scm-tree vscode-tree-item[selected][focus-visible] .status-badge,
102+
.scm-tree vscode-tree-item[selected]:focus-within .status-badge {
103+
color: inherit !important;
104+
}
105+
106+
.scm-item-label.deleted .scm-label-text,
107+
.scm-description.deleted {
108+
text-decoration-line: line-through;
109+
}
110+
111+
.toolbar-group {
112+
display: inline-flex;
113+
align-items: center;
114+
color: inherit;
115+
--vscode-toolbar-foreground: currentColor;
116+
--vscode-toolbar-hoverForeground: currentColor;
117+
--vscode-icon-foreground: currentColor;
118+
--vscode-foreground: currentColor;
119+
}
120+
</style>
121+
</head>
122+
123+
<body>
124+
<h1>Decoration lane</h1>
125+
<main>
126+
<div class="demo-controls">
127+
<div class="range-control">
128+
<label for="tree-width">Width</label>
129+
<input id="tree-width" type="range" min="280" max="640" value="500">
130+
<span id="tree-width-value">500px</span>
131+
</div>
132+
</div>
133+
<vscode-demo class="actions-demo-frame">
134+
<vscode-tree class="scm-tree">
135+
<vscode-tree-item
136+
class="scm-node"
137+
branch
138+
open
139+
data-node="Staged Changes"
140+
>
141+
<span class="scm-section-label">
142+
<span class="scm-label-text">Staged Changes</span>
143+
</span>
144+
<vscode-badge slot="decoration" variant="counter" aria-hidden="true"
145+
>1</vscode-badge
146+
>
147+
<div slot="actions" class="toolbar-group">
148+
<vscode-toolbar-button
149+
icon="comment"
150+
aria-label="Code Review - Staged Changes"
151+
data-action="code-review-staged-changes"
152+
></vscode-toolbar-button>
153+
<vscode-toolbar-button
154+
icon="request-changes"
155+
aria-label="Open Staged Changes"
156+
data-action="open-staged-changes"
157+
></vscode-toolbar-button>
158+
<vscode-toolbar-button
159+
icon="remove"
160+
aria-label="Unstage All Changes"
161+
data-action="unstage-all-changes"
162+
></vscode-toolbar-button>
163+
</div>
164+
<vscode-tree-item
165+
class="scm-node"
166+
data-node="src/hooks/useClient.js"
167+
>
168+
<vscode-icon slot="icon-leaf" name="file-text"></vscode-icon>
169+
<span class="scm-item-label deleted">
170+
<span class="scm-label-text">useClient.js</span>
171+
</span>
172+
<span slot="description" class="scm-description deleted"
173+
>src/hooks</span
174+
>
175+
<span
176+
slot="decoration"
177+
class="badge status-badge status-badge--deleted"
178+
aria-hidden="true"
179+
>D</span
180+
>
181+
<div slot="actions" class="toolbar-group">
182+
<vscode-toolbar-button
183+
icon="go-to-file"
184+
aria-label="Open File"
185+
data-action="open-file"
186+
></vscode-toolbar-button>
187+
<vscode-toolbar-button
188+
icon="remove"
189+
aria-label="Unstage Changes"
190+
data-action="unstage-file"
191+
></vscode-toolbar-button>
192+
</div>
193+
</vscode-tree-item>
194+
</vscode-tree-item>
195+
<vscode-tree-item class="scm-node" branch open data-node="Changes">
196+
<span class="scm-section-label">
197+
<span class="scm-label-text">Changes</span>
198+
</span>
199+
<vscode-badge slot="decoration" variant="counter" aria-hidden="true"
200+
>2</vscode-badge
201+
>
202+
<div slot="actions" class="toolbar-group">
203+
<vscode-toolbar-button
204+
icon="comment"
205+
aria-label="Code Review - Unstaged Changes"
206+
data-action="code-review-unstaged-changes"
207+
></vscode-toolbar-button>
208+
<vscode-toolbar-button
209+
icon="request-changes"
210+
aria-label="Open Changes"
211+
data-action="open-changes"
212+
></vscode-toolbar-button>
213+
<vscode-toolbar-button
214+
icon="discard"
215+
aria-label="Discard All Changes"
216+
data-action="discard-all"
217+
></vscode-toolbar-button>
218+
<vscode-toolbar-button
219+
icon="plus"
220+
aria-label="Stage All Changes"
221+
data-action="stage-all"
222+
></vscode-toolbar-button>
223+
</div>
224+
<vscode-tree-item class="scm-node" data-node="src/utils/strings.js">
225+
<vscode-icon slot="icon-leaf" name="file-text"></vscode-icon>
226+
<span class="scm-item-label">
227+
<span class="scm-label-text">strings.js</span>
228+
</span>
229+
<span slot="description">src/utils</span>
230+
<span
231+
slot="decoration"
232+
class="badge status-badge status-badge--modified"
233+
aria-hidden="true"
234+
>M</span
235+
>
236+
<div slot="actions" class="toolbar-group">
237+
<vscode-toolbar-button
238+
icon="go-to-file"
239+
aria-label="Open File"
240+
data-action="open-file"
241+
></vscode-toolbar-button>
242+
<vscode-toolbar-button
243+
icon="discard"
244+
aria-label="Discard Changes"
245+
data-action="discard-file"
246+
></vscode-toolbar-button>
247+
<vscode-toolbar-button
248+
icon="plus"
249+
aria-label="Stage Changes"
250+
data-action="stage-file"
251+
></vscode-toolbar-button>
252+
</div>
253+
</vscode-tree-item>
254+
<vscode-tree-item
255+
class="scm-node"
256+
data-node="src/nested/deep/inside/somewhere/longLongLongLongModule.js"
257+
>
258+
<vscode-icon slot="icon-leaf" name="file-text"></vscode-icon>
259+
<span class="scm-item-label">
260+
<span class="scm-label-text">longLongLongLongModule.js</span>
261+
</span>
262+
<span slot="description">src/nested/deep/inside/somewhere</span>
263+
<span
264+
slot="decoration"
265+
class="badge status-badge status-badge--untracked"
266+
aria-hidden="true"
267+
>U</span
268+
>
269+
<div slot="actions" class="toolbar-group">
270+
<vscode-toolbar-button
271+
icon="go-to-file"
272+
aria-label="Open File"
273+
data-action="open-file"
274+
></vscode-toolbar-button>
275+
<vscode-toolbar-button
276+
icon="discard"
277+
aria-label="Discard Changes"
278+
data-action="discard-file"
279+
></vscode-toolbar-button>
280+
<vscode-toolbar-button
281+
icon="plus"
282+
aria-label="Stage Changes"
283+
data-action="stage-file"
284+
></vscode-toolbar-button>
285+
</div>
286+
</vscode-tree-item>
287+
</vscode-tree-item>
288+
</vscode-tree>
289+
</vscode-demo>
290+
</main>
291+
<script type="module">
292+
const demoFrame = document.querySelector('.actions-demo-frame');
293+
const widthInput = document.getElementById('tree-width');
294+
const widthValue = document.getElementById('tree-width-value');
295+
296+
const setupActionGuards = () => {
297+
if (!demoFrame) {
298+
return;
299+
}
300+
301+
const groups = demoFrame.querySelectorAll('.scm-tree .toolbar-group');
302+
303+
groups.forEach((group) => {
304+
if (!(group instanceof HTMLElement)) {
305+
return;
306+
}
307+
308+
if (group.dataset.guardAttached) {
309+
return;
310+
}
311+
312+
group.addEventListener(
313+
'click',
314+
(ev) => {
315+
ev.preventDefault();
316+
ev.stopPropagation();
317+
318+
const target =
319+
ev.target instanceof HTMLElement ? ev.target : null;
320+
const button = target?.closest('vscode-toolbar-button');
321+
322+
if (!button) {
323+
return;
324+
}
325+
326+
const action =
327+
button.dataset.action ??
328+
button.getAttribute('icon') ??
329+
'action';
330+
const treeItem = button.closest('vscode-tree-item');
331+
const label = treeItem?.dataset.node ?? 'tree-item';
332+
console.log(`Action "${action}" on ${label}`);
333+
334+
button.blur();
335+
treeItem?.focus();
336+
},
337+
{capture: true}
338+
);
339+
340+
group.dataset.guardAttached = 'true';
341+
});
342+
};
343+
344+
const syncWidth = () => {
345+
if (!(widthInput instanceof HTMLInputElement) || !demoFrame) {
346+
return;
347+
}
348+
349+
const width = `${widthInput.value}px`;
350+
demoFrame.style.setProperty('--demo-tree-width', width);
351+
if (widthValue) {
352+
widthValue.textContent = width;
353+
}
354+
};
355+
356+
setupActionGuards();
357+
syncWidth();
358+
359+
window.addEventListener('load', setupActionGuards);
360+
widthInput?.addEventListener('input', syncWidth);
361+
</script>
362+
</body>
363+
</html>

0 commit comments

Comments
 (0)