fix(web): inset sidebar scrollbar by 2px
This commit is contained in:
@@ -106,7 +106,9 @@ interface ListMetrics {
|
|||||||
overflows: boolean
|
overflows: boolean
|
||||||
/** Border-box width minus client width: the space the scrollbar takes out of the content area. */
|
/** Border-box width minus client width: the space the scrollbar takes out of the content area. */
|
||||||
band: number
|
band: number
|
||||||
/** Distance from the first row background's right edge to the list border box. */
|
/** Distance from the scrollbar's right edge to the sidebar edge. */
|
||||||
|
scrollbarEdgeOffset: number
|
||||||
|
/** Distance from the first row background's right edge to the sidebar edge. */
|
||||||
rowEdgeInset: number
|
rowEdgeInset: number
|
||||||
/** Client-area right edge in viewport coordinates (`clientWidth` excludes the scrollbar band). */
|
/** Client-area right edge in viewport coordinates (`clientWidth` excludes the scrollbar band). */
|
||||||
clientRight: number
|
clientRight: number
|
||||||
@@ -172,6 +174,8 @@ function measureList(page: Page): Promise<ListMetrics> {
|
|||||||
const pseudoWidth = getComputedStyle(list, '::-webkit-scrollbar').width
|
const pseudoWidth = getComputedStyle(list, '::-webkit-scrollbar').width
|
||||||
const barWidth = pseudoWidth === 'auto' ? 15 : Number.parseFloat(pseudoWidth)
|
const barWidth = pseudoWidth === 'auto' ? 15 : Number.parseFloat(pseudoWidth)
|
||||||
const listRect = list.getBoundingClientRect()
|
const listRect = list.getBoundingClientRect()
|
||||||
|
const sidebarEdge = list.parentElement?.getBoundingClientRect().right
|
||||||
|
if (sidebarEdge === undefined) throw new Error('sidebar session list has no layout parent')
|
||||||
return {
|
return {
|
||||||
gutter: style.scrollbarGutter,
|
gutter: style.scrollbarGutter,
|
||||||
width: pseudoWidth,
|
width: pseudoWidth,
|
||||||
@@ -183,7 +187,8 @@ function measureList(page: Page): Promise<ListMetrics> {
|
|||||||
hoverToken: resolve('--dsh-scrollbar-thumb-hover'),
|
hoverToken: resolve('--dsh-scrollbar-thumb-hover'),
|
||||||
overflows: list.scrollHeight > list.clientHeight,
|
overflows: list.scrollHeight > list.clientHeight,
|
||||||
band: listRect.width - list.clientWidth,
|
band: listRect.width - list.clientWidth,
|
||||||
rowEdgeInset: listRect.right - row.getBoundingClientRect().right,
|
scrollbarEdgeOffset: sidebarEdge - listRect.right,
|
||||||
|
rowEdgeInset: sidebarEdge - row.getBoundingClientRect().right,
|
||||||
clientRight: listRect.left + list.clientWidth,
|
clientRight: listRect.left + list.clientWidth,
|
||||||
borderRight: listRect.right,
|
borderRight: listRect.right,
|
||||||
timeRight: time.getBoundingClientRect().right,
|
timeRight: time.getBoundingClientRect().right,
|
||||||
@@ -211,9 +216,11 @@ function measureRowInset(page: Page): Promise<Pick<ListMetrics, 'overflows' | 'r
|
|||||||
if (list === null) throw new Error('sidebar session list not in the DOM')
|
if (list === null) throw new Error('sidebar session list not in the DOM')
|
||||||
const row = list.querySelector<HTMLElement>('[role="treeitem"]')
|
const row = list.querySelector<HTMLElement>('[role="treeitem"]')
|
||||||
if (row === null) throw new Error('no row in the sidebar list')
|
if (row === null) throw new Error('no row in the sidebar list')
|
||||||
|
const sidebarEdge = list.parentElement?.getBoundingClientRect().right
|
||||||
|
if (sidebarEdge === undefined) throw new Error('sidebar session list has no layout parent')
|
||||||
return {
|
return {
|
||||||
overflows: list.scrollHeight > list.clientHeight,
|
overflows: list.scrollHeight > list.clientHeight,
|
||||||
rowEdgeInset: list.getBoundingClientRect().right - row.getBoundingClientRect().right,
|
rowEdgeInset: sidebarEdge - row.getBoundingClientRect().right,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -247,6 +254,7 @@ function renderGeometry(light: ListMetrics, dark: ListMetrics): string {
|
|||||||
`- --dsh-scrollbar-thumb-hover: ${metrics.hoverToken}`,
|
`- --dsh-scrollbar-thumb-hover: ${metrics.hoverToken}`,
|
||||||
`- list overflows: ${String(metrics.overflows)}`,
|
`- list overflows: ${String(metrics.overflows)}`,
|
||||||
`- reserved band: ${String(metrics.band)}px`,
|
`- reserved band: ${String(metrics.band)}px`,
|
||||||
|
`- scrollbar inset from the sidebar edge: ${String(metrics.scrollbarEdgeOffset)}px`,
|
||||||
`- row background inset from the sidebar edge: ${String(metrics.rowEdgeInset)}px`,
|
`- row background inset from the sidebar edge: ${String(metrics.rowEdgeInset)}px`,
|
||||||
`- relative time covered by the bar: ${String(metrics.timeCoveredBy)}px`,
|
`- relative time covered by the bar: ${String(metrics.timeCoveredBy)}px`,
|
||||||
`- relative time ends inside the content area: ${String(metrics.timeRight <= metrics.clientRight)}`,
|
`- relative time ends inside the content area: ${String(metrics.timeRight <= metrics.clientRight)}`,
|
||||||
@@ -325,6 +333,7 @@ describe('web e2e: sidebar session list scrollbar (reserved gutter / themed thum
|
|||||||
// drawn over it. Removing the declaration makes it exactly 0. The value
|
// drawn over it. Removing the declaration makes it exactly 0. The value
|
||||||
// itself is not pinned — it tracks `scrollbar-width` and the platform.
|
// itself is not pinned — it tracks `scrollbar-width` and the platform.
|
||||||
expect(metrics.band).toBeGreaterThan(0)
|
expect(metrics.band).toBeGreaterThan(0)
|
||||||
|
expect(metrics.scrollbarEdgeOffset).toBe(2)
|
||||||
expect(metrics.rowEdgeInset).toBe(12)
|
expect(metrics.rowEdgeInset).toBe(12)
|
||||||
// The reported symptom, stated directly: no part of the row's relative time
|
// The reported symptom, stated directly: no part of the row's relative time
|
||||||
// lies under the bar. Measures 7 on clean master — the `h` of `1h` is the
|
// lies under the bar. Measures 7 on clean master — the `h` of `1h` is the
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
- --dsh-scrollbar-thumb-hover: rgb(212, 212, 212)
|
- --dsh-scrollbar-thumb-hover: rgb(212, 212, 212)
|
||||||
- list overflows: true
|
- list overflows: true
|
||||||
- reserved band: 8px
|
- reserved band: 8px
|
||||||
|
- scrollbar inset from the sidebar edge: 2px
|
||||||
- row background inset from the sidebar edge: 12px
|
- row background inset from the sidebar edge: 12px
|
||||||
- relative time covered by the bar: 0px
|
- relative time covered by the bar: 0px
|
||||||
- relative time ends inside the content area: true
|
- relative time ends inside the content area: true
|
||||||
@@ -29,6 +30,7 @@
|
|||||||
- --dsh-scrollbar-thumb-hover: rgb(84, 85, 87)
|
- --dsh-scrollbar-thumb-hover: rgb(84, 85, 87)
|
||||||
- list overflows: true
|
- list overflows: true
|
||||||
- reserved band: 8px
|
- reserved band: 8px
|
||||||
|
- scrollbar inset from the sidebar edge: 2px
|
||||||
- row background inset from the sidebar edge: 12px
|
- row background inset from the sidebar edge: 12px
|
||||||
- relative time covered by the bar: 0px
|
- relative time covered by the bar: 0px
|
||||||
- relative time ends inside the content area: true
|
- relative time ends inside the content area: true
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
.root {
|
.root {
|
||||||
--dsh-session-list-edge-inset: var(--dsh-sidebar-inline-padding);
|
--dsh-session-list-edge-inset: var(--dsh-sidebar-inline-padding);
|
||||||
--dsh-session-list-scrollbar-width: 8px;
|
--dsh-session-list-scrollbar-width: 8px;
|
||||||
|
--dsh-session-list-scrollbar-offset: 2px;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -214,13 +215,19 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* List: the only scrolling region. Block children keep their design heights
|
/* List: the only scrolling region. Block children keep their design heights
|
||||||
under content overflow. The stable 8px themed scrollbar and the remaining
|
under content overflow. The 2px edge offset, stable 8px themed scrollbar,
|
||||||
padding together equal the shell's right inset, with or without overflow. */
|
and remaining padding equal the shell's right inset, with or without
|
||||||
|
overflow, so moving the bar does not move the rows. */
|
||||||
.list {
|
.list {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
padding-right: calc(var(--dsh-session-list-edge-inset) - var(--dsh-session-list-scrollbar-width));
|
margin-right: var(--dsh-session-list-scrollbar-offset);
|
||||||
|
padding-right: calc(
|
||||||
|
var(--dsh-session-list-edge-inset)
|
||||||
|
- var(--dsh-session-list-scrollbar-width)
|
||||||
|
- var(--dsh-session-list-scrollbar-offset)
|
||||||
|
);
|
||||||
padding-bottom: 12px;
|
padding-bottom: 12px;
|
||||||
scrollbar-gutter: stable;
|
scrollbar-gutter: stable;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,12 +43,18 @@ describe('WorkspaceBrowser.module.css list', () => {
|
|||||||
it('counts the themed scrollbar inside the shell trailing inset', () => {
|
it('counts the themed scrollbar inside the shell trailing inset', () => {
|
||||||
expect(root?.get('--dsh-session-list-edge-inset')).toBe('var(--dsh-sidebar-inline-padding)')
|
expect(root?.get('--dsh-session-list-edge-inset')).toBe('var(--dsh-sidebar-inline-padding)')
|
||||||
expect(root?.get('--dsh-session-list-scrollbar-width')).toBe('8px')
|
expect(root?.get('--dsh-session-list-scrollbar-width')).toBe('8px')
|
||||||
|
expect(root?.get('--dsh-session-list-scrollbar-offset')).toBe('2px')
|
||||||
expect(root?.get('padding-right')).toBe('var(--dsh-session-list-edge-inset)')
|
expect(root?.get('padding-right')).toBe('var(--dsh-session-list-edge-inset)')
|
||||||
expect(listArea?.get('margin-right')).toBe('calc(-1 * var(--dsh-session-list-edge-inset))')
|
expect(listArea?.get('margin-right')).toBe('calc(-1 * var(--dsh-session-list-edge-inset))')
|
||||||
expect(declarations('.fade')?.get('right')).toBe('var(--dsh-session-list-edge-inset)')
|
expect(declarations('.fade')?.get('right')).toBe('var(--dsh-session-list-edge-inset)')
|
||||||
expect(list?.get('padding-right')).toBe(
|
expect(list?.get('margin-right')).toBe('var(--dsh-session-list-scrollbar-offset)')
|
||||||
'calc(var(--dsh-session-list-edge-inset) - var(--dsh-session-list-scrollbar-width))',
|
expect(list?.get('padding-right')).toBe([
|
||||||
)
|
'calc(',
|
||||||
|
'var(--dsh-session-list-edge-inset)',
|
||||||
|
'- var(--dsh-session-list-scrollbar-width)',
|
||||||
|
'- var(--dsh-session-list-scrollbar-offset)',
|
||||||
|
')',
|
||||||
|
].join(' '))
|
||||||
expect(declarations('.list::-webkit-scrollbar')).toBeUndefined()
|
expect(declarations('.list::-webkit-scrollbar')).toBeUndefined()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user