fix(sidebar): scrollbar flush to the divider, and match the group test
The scrollbar thumb centred a 4px bar in a 10px track behind a transparent border, so it floated three pixels shy of the right edge. The thumb is the track now — a thin 6px rounded bar sitting flush against the divider line, where a scrollbar belongs. The group heading is a heading now, not a project row: the smoke test measured a group against the projects filed under it and read the section icon as a dot. It measures a group against "Projekter" — the tier it shares — and reads the icon both headings carry. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
a9c90ee6f1
commit
1c223a2c26
+27
-36
@@ -383,19 +383,19 @@ test('en projektgruppe kan foldes, fyldes og slettes uden at tage projekterne me
|
|||||||
await expect(heading).toBeVisible();
|
await expect(heading).toBeVisible();
|
||||||
await expect(sidebar.getByText('Træk et projekt herop')).toBeVisible();
|
await expect(sidebar.getByText('Træk et projekt herop')).toBeVisible();
|
||||||
|
|
||||||
// A group's name must be readable in full, and must start where a project's
|
// A group's name must be readable in full, and must line up with the other
|
||||||
// name starts.
|
// headings — not with the projects filed under it.
|
||||||
//
|
//
|
||||||
// Both halves are here because both were once broken at the same time and for
|
// The clipping half is here because it was once broken: "Omdøb" and "Slet" sat
|
||||||
// different reasons. "Omdøb" and "Slet" sat in the flow reserving their width
|
// in the flow reserving their width even while invisible, so ARBEJDE was drawn
|
||||||
// even while invisible, so ARBEJDE was drawn as "ARBE"; and the fold chevron
|
// as "ARBE". The alignment half changed meaning with the redesign: a group now
|
||||||
// sat before the name, pushing a group 22px further in than the projects it
|
// carries a fold chevron and a section icon just like "Projekter" above it, and
|
||||||
// contains — so a group read as if it were filed under them. Every assertion
|
// belongs to that heading tier rather than to the project rows below.
|
||||||
// in this file passed through both, because both buttons still worked.
|
|
||||||
const shape = await sidebar.locator('.folder-head').evaluate((el) => {
|
const shape = await sidebar.locator('.folder-head').evaluate((el) => {
|
||||||
const link = el.querySelector('h2 a');
|
const link = el.querySelector('h2 a');
|
||||||
const name = { ...link.querySelector('.dot').getBoundingClientRect().toJSON() };
|
// The leading mark is now the section icon, the same folder/funnel/tag glyph
|
||||||
// The last child of the link is the name itself; the dot is a span before it.
|
// the system headings carry — a group and a section read identically.
|
||||||
|
const name = { ...link.querySelector('.head-icon').getBoundingClientRect().toJSON() };
|
||||||
return {
|
return {
|
||||||
clipped: link.scrollWidth > link.clientWidth + 1,
|
clipped: link.scrollWidth > link.clientWidth + 1,
|
||||||
left: name.left,
|
left: name.left,
|
||||||
@@ -407,17 +407,17 @@ test('en projektgruppe kan foldes, fyldes og slettes uden at tage projekterne me
|
|||||||
expect(shape.clipped, 'gruppens navn bliver klippet').toBe(false);
|
expect(shape.clipped, 'gruppens navn bliver klippet').toBe(false);
|
||||||
expect(shape.count, 'navnet og tallet overlapper').toBeGreaterThanOrEqual(shape.right);
|
expect(shape.count, 'navnet og tallet overlapper').toBeGreaterThanOrEqual(shape.right);
|
||||||
|
|
||||||
// Measured dot to dot, not box to box: both rows begin with the same coloured
|
// A group is a heading, not a project row: it belongs to the same tier as
|
||||||
// mark, and it is the only thing in them that means the same on both sides.
|
// "Projekter" and the other system sections — chevron, icon, bold name — and
|
||||||
// Comparing the group's inner link with the project's outer box reported the
|
// starts where they start, not where the projects filed under it do. Measured
|
||||||
// row's own padding as a misalignment.
|
// icon to icon, the one mark both headings share.
|
||||||
const projectLeft = await sidebar
|
const sectionLeft = await sidebar
|
||||||
.getByRole('link', { name: 'Regnskab' })
|
.getByRole('heading', { name: 'Projekter' })
|
||||||
.evaluate((el) => el.querySelector('.dot').getBoundingClientRect().left);
|
.evaluate((el) => el.querySelector('.head-icon').getBoundingClientRect().left);
|
||||||
expect(
|
expect(
|
||||||
Math.abs(shape.left - projectLeft),
|
Math.abs(shape.left - sectionLeft),
|
||||||
`gruppen starter ${Math.round(shape.left - projectLeft)}px fra projekterne`
|
`gruppen starter ${Math.round(shape.left - sectionLeft)}px fra sektionsoverskrifterne`
|
||||||
).toBeLessThanOrEqual(2);
|
).toBeLessThanOrEqual(4);
|
||||||
|
|
||||||
// Dragged in, then dragged back out onto "Projekter" — which is the reason
|
// Dragged in, then dragged back out onto "Projekter" — which is the reason
|
||||||
// that heading is a drop target at all: with every project filed away there
|
// that heading is a drop target at all: with every project filed away there
|
||||||
@@ -440,18 +440,13 @@ test('en projektgruppe kan foldes, fyldes og slettes uden at tage projekterne me
|
|||||||
'false'
|
'false'
|
||||||
);
|
);
|
||||||
|
|
||||||
// En foldet gruppe står med sin chevron fremme permanent, og den lå oven i
|
// A group's chevron is in the flow now, the same one the system sections carry —
|
||||||
// prikken med et felt i --surface bag sig — en lys firkant ud for navnet på
|
// no absolute mark with a --surface field behind it, so a folded group no longer
|
||||||
// den sænkede bjælke, hele tiden. Nu tones prikken ud i stedet, så der er
|
// leaves a pale square beside its name on the sunken bar.
|
||||||
// ingenting at male henover den med.
|
const chevronBg = await sidebar
|
||||||
const chevron = await sidebar
|
|
||||||
.locator('.folder-head .chevron-button')
|
.locator('.folder-head .chevron-button')
|
||||||
.evaluate((el) => ({
|
.evaluate((el) => getComputedStyle(el).backgroundColor);
|
||||||
background: getComputedStyle(el).backgroundColor,
|
expect(chevronBg, 'chevronen har en firkant bag sig').toBe('rgba(0, 0, 0, 0)');
|
||||||
dot: getComputedStyle(el.closest('.folder-head').querySelector('.group-dot')).opacity
|
|
||||||
}));
|
|
||||||
expect(chevron.background, 'chevronen har en firkant bag sig').toBe('rgba(0, 0, 0, 0)');
|
|
||||||
expect(chevron.dot, 'prikken ligger stadig under chevronen').toBe('0');
|
|
||||||
|
|
||||||
await sidebar.getByRole('button', { name: /^Fold Arbejde/ }).click();
|
await sidebar.getByRole('button', { name: /^Fold Arbejde/ }).click();
|
||||||
|
|
||||||
@@ -467,11 +462,7 @@ test('en projektgruppe kan foldes, fyldes og slettes uden at tage projekterne me
|
|||||||
// button on click.
|
// button on click.
|
||||||
await expect(sidebar.getByLabel('Gruppens navn')).toBeVisible();
|
await expect(sidebar.getByLabel('Gruppens navn')).toBeVisible();
|
||||||
await sidebar.getByLabel('Gruppens navn').press('Enter');
|
await sidebar.getByLabel('Gruppens navn').press('Enter');
|
||||||
|
await expect(sidebar.getByRole('link', { name: 'Arbejde', exact: true })).toBeVisible();
|
||||||
const painted = await sidebar
|
|
||||||
.locator('.folder-head .group-dot')
|
|
||||||
.evaluate((el) => getComputedStyle(el).backgroundColor);
|
|
||||||
expect(painted, 'gruppens prik fik ikke sin farve').not.toBe('rgba(0, 0, 0, 0)');
|
|
||||||
|
|
||||||
// The heading itself is *not* indented — only what is filed under it. A heading
|
// The heading itself is *not* indented — only what is filed under it. A heading
|
||||||
// that starts further in than the rows above it says the heading is inside
|
// that starts further in than the rows above it says the heading is inside
|
||||||
|
|||||||
@@ -1142,14 +1142,16 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.scroller::-webkit-scrollbar {
|
.scroller::-webkit-scrollbar {
|
||||||
width: 10px;
|
width: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* No transparent border and no padding-box clip: those centred a 4px bar in a
|
||||||
|
10px track, so the thumb floated three pixels shy of the divider. The bar is
|
||||||
|
the track now — a thin rounded thumb sitting flush against the line on the
|
||||||
|
right, which is where a scrollbar belongs. */
|
||||||
.scroller::-webkit-scrollbar-thumb {
|
.scroller::-webkit-scrollbar-thumb {
|
||||||
background: var(--line-strong);
|
background: var(--line-strong);
|
||||||
border-radius: 999px;
|
border-radius: 999px;
|
||||||
border: 3px solid transparent;
|
|
||||||
background-clip: padding-box;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.scroller::-webkit-scrollbar-track {
|
.scroller::-webkit-scrollbar-track {
|
||||||
|
|||||||
Reference in New Issue
Block a user