Skip to content

Commit d326e1e

Browse files
authored
Update sidebar to two column layout (#7605)
Part of #7383
1 parent ebe1a04 commit d326e1e

2 files changed

Lines changed: 104 additions & 17 deletions

File tree

webviews/components/sidebar.tsx

Lines changed: 42 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* Licensed under the MIT License. See License.txt in the project root for license information.
44
*--------------------------------------------------------------------------------------------*/
55

6-
import React, { useContext, useRef, useState } from 'react';
6+
import React, { useContext, useEffect, useRef, useState } from 'react';
77
import { COPILOT_LOGINS } from '../../src/common/copilot';
88
import { gitHubLabelColor } from '../../src/common/utils';
99
import { IAccount, IMilestone, IProjectItem, reviewerId, reviewerLabel, ReviewState } from '../../src/github/interface';
@@ -255,7 +255,7 @@ export function CollapsibleSidebar(props: PullRequest) {
255255
>
256256
<Sidebar {...props} />
257257
</div>
258-
<a className='collapsible-label-see-more' onClick={() => setExpanded(e => !e)}>{expanded ? 'See less' : 'See more...'}</a>
258+
<a className='collapsible-label-see-more' onClick={() => setExpanded(e => !e)}>{expanded ? 'See less' : 'See more'}</a>
259259
</div>
260260
);
261261
}
@@ -283,28 +283,61 @@ function CollapsedLabel(props: PullRequest) {
283283
getColor: (item: any) => { backgroundColor: string; textColor: string; borderColor: string },
284284
getText: (item: any) => string
285285
}) => {
286-
return <span className="pill-stack">
287-
{items.slice(0, 5).map((item, i) => {
286+
const containerRef = useRef<HTMLSpanElement>(null);
287+
const [visibleCount, setVisibleCount] = useState(items.length);
288+
289+
useEffect(() => {
290+
if (!containerRef.current || items.length === 0) return;
291+
292+
const resizeObserver = new ResizeObserver(() => {
293+
const container = containerRef.current;
294+
if (!container) return;
295+
296+
const containerWidth = container.offsetWidth;
297+
const overflowTextWidth = 60; // "+N more" text width estimate
298+
299+
// Start with all items and reduce until they fit
300+
let testCount = items.length;
301+
while (testCount > 0) {
302+
const testWidth = testCount * 50 + (testCount < items.length ? overflowTextWidth : 0);
303+
if (testWidth <= containerWidth) {
304+
break;
305+
}
306+
testCount--;
307+
}
308+
309+
setVisibleCount(Math.max(1, testCount));
310+
});
311+
312+
resizeObserver.observe(containerRef.current);
313+
return () => resizeObserver.disconnect();
314+
}, [items.length]);
315+
316+
const visibleItems = items.slice(0, visibleCount);
317+
const hiddenCount = items.length - visibleCount;
318+
319+
return <span className="pill-container" ref={containerRef}>
320+
{visibleItems.map((item) => {
288321
const color = getColor(item);
289-
const pill = (
322+
return (
290323
<span
291324
key={getKey(item)}
292-
className="stacked-pill"
325+
className="pill-item"
293326
style={{
294327
backgroundColor: color.backgroundColor,
295328
color: color.textColor,
296329
borderRadius: '20px',
297-
left: `${(i * 20)}px`,
298330
}}
299331
title={getText(item)}
300332
>
301333
{getText(item)}
302334
</span>
303335
);
304-
return pill;
305336
})}
337+
{hiddenCount > 0 && (
338+
<span className="pill-overflow">+{hiddenCount}</span>
339+
)}
306340
</span>;
307-
308341
};
309342

310343
// Collect non-empty sections in order, with custom rendering

webviews/editorWebview/index.css

Lines changed: 62 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1222,6 +1222,11 @@ code {
12221222
}
12231223

12241224
@media (max-width: 768px) {
1225+
.title {
1226+
border-bottom: none;
1227+
padding-bottom: 0px;
1228+
}
1229+
12251230
#app {
12261231
display: block;
12271232
}
@@ -1473,16 +1478,16 @@ svg.octicon path {
14731478
}
14741479

14751480
.collapsible-sidebar {
1476-
border: 1px solid var(--vscode-editorWidget-border);
1477-
border-radius: 4px;
1481+
border-top: 1px solid var(--vscode-editorWidget-border);
1482+
border-bottom: 1px solid var(--vscode-editorWidget-border);
14781483
margin-bottom: 16px;
14791484
}
14801485

14811486
.collapsible-sidebar-header {
14821487
display: flex;
14831488
align-items: center;
14841489
cursor: pointer;
1485-
padding: 4px 8px;
1490+
padding: 16px 8px 7px;
14861491
user-select: none;
14871492
outline: none;
14881493
}
@@ -1493,33 +1498,81 @@ svg.octicon path {
14931498

14941499
.collapsible-sidebar-title {
14951500
font-size: 14px;
1501+
width: 100%;
14961502
}
14971503

14981504
.collapsible-sidebar-content {
1499-
padding: 18px 22px;
1505+
padding: 6px 22px;
15001506
}
15011507

15021508
.collapsed-label {
15031509
gap: 6px;
1504-
display: flex;
1505-
flex-direction: column;
1510+
display: grid;
1511+
grid-template-columns: 1fr 1fr;
1512+
grid-gap: 6px 12px;
15061513
}
15071514

15081515
.collapsed-section {
15091516
gap: 2px;
15101517
display: inline-flex;
1518+
align-items: center;
1519+
min-width: 0;
1520+
overflow: hidden;
15111521
}
15121522

15131523
.collapsed-section-label {
15141524
padding-right: 4px;
1525+
font-weight: 600;
1526+
flex-shrink: 0;
1527+
}
1528+
1529+
.pill-container {
1530+
display: flex;
1531+
align-items: center;
1532+
min-width: 0;
1533+
flex: 1;
1534+
flex-wrap: nowrap;
1535+
overflow: hidden;
1536+
}
1537+
1538+
.pill-item {
1539+
flex-shrink: 0;
1540+
white-space: nowrap;
1541+
border-radius: 20px;
1542+
padding: 0px 6px;
1543+
font-size: 12px;
1544+
margin-right: 2px;
1545+
}
1546+
1547+
.pill-overflow {
1548+
color: var(--vscode-descriptionForeground);
1549+
font-size: 11px;
1550+
margin-left: 4px;
1551+
flex-shrink: 0;
1552+
white-space: nowrap;
1553+
}
1554+
1555+
.pill-stack {
1556+
position: relative;
1557+
display: inline-block;
1558+
min-height: 20px;
1559+
flex-shrink: 1;
1560+
}
1561+
1562+
.pill-overflow {
1563+
color: var(--vscode-descriptionForeground);
1564+
font-size: 12px;
1565+
margin-left: 4px;
1566+
flex-shrink: 0;
1567+
white-space: nowrap;
15151568
}
15161569

15171570
.collapsed-section .stacked-avatar {
15181571
position: absolute;
15191572
}
15201573

15211574
.collapsed-section .stacked-avatar {
1522-
top: -2px;
1575+
top: -10px;
15231576
}
15241577

15251578
.stacked-pill {
@@ -1535,6 +1588,7 @@ svg.octicon path {
15351588

15361589
.collapsible-label-see-more {
15371590
padding-left: 8px;
1538-
padding-bottom: 4px;
1591+
padding-bottom: 8px;
15391592
display: block;
1593+
font-size: 12px;
15401594
}

0 commit comments

Comments
 (0)