diff --git a/src/styles.css b/src/styles.css index 1582dcec..b4e821da 100644 --- a/src/styles.css +++ b/src/styles.css @@ -1166,12 +1166,23 @@ textarea::placeholder { overflow-x: auto; overflow-y: hidden; padding: 2px 6px 2px 4px; + scrollbar-width: auto; + scrollbar-color: auto; /* Native clickable-preview margins: scrollIntoView keeps 64px of each neighbor visible, and edge clamping snaps the first/last task flush. Keep in sync with TASK_CLICKABLE_PREVIEW_PX in src/store/focused-panel.ts. */ scroll-padding-inline: 64px; } +.tiling-layout-strip::-webkit-scrollbar { + height: 10px; +} + +.tiling-layout-strip::-webkit-scrollbar-thumb { + border-block: 2px solid transparent; + background-clip: padding-box; +} + .tiling-layout-scroll-affordance { position: absolute; top: 2px; diff --git a/src/tiling-layout-scrollbar-styles.test.ts b/src/tiling-layout-scrollbar-styles.test.ts new file mode 100644 index 00000000..cf89866e --- /dev/null +++ b/src/tiling-layout-scrollbar-styles.test.ts @@ -0,0 +1,37 @@ +import { readFileSync } from 'node:fs'; +import { resolve } from 'node:path'; +import { Window } from 'happy-dom'; +import { describe, expect, it } from 'vitest'; + +const window = new Window(); +const style = window.document.createElement('style'); +style.textContent = readFileSync(resolve(__dirname, 'styles.css'), 'utf8'); +window.document.head.append(style); + +function declarationsFor(selector: string): CSSStyleDeclaration { + const rule = Array.from(style.sheet?.cssRules ?? []).find( + (candidate) => 'selectorText' in candidate && candidate.selectorText === selector, + ) as CSSStyleRule | undefined; + + if (!rule) throw new Error(`Missing CSS rule for ${selector}`); + return rule.style; +} + +describe('tiling layout horizontal scrollbar', () => { + it('scopes a 10px hit target and 6px painted thumb to the tiling strip', () => { + const strip = declarationsFor('.tiling-layout-strip'); + expect(strip.getPropertyValue('scrollbar-width')).toBe('auto'); + expect(strip.getPropertyValue('scrollbar-color')).toBe('auto'); + + const scrollbar = declarationsFor('.tiling-layout-strip::-webkit-scrollbar'); + expect(scrollbar.getPropertyValue('height')).toBe('10px'); + + const thumb = declarationsFor('.tiling-layout-strip::-webkit-scrollbar-thumb'); + expect(thumb.getPropertyValue('border-block')).toBe('2px solid transparent'); + expect(thumb.getPropertyValue('background-clip')).toBe('padding-box'); + + const globalScrollbar = declarationsFor('::-webkit-scrollbar'); + expect(globalScrollbar.getPropertyValue('width')).toBe('5px'); + expect(globalScrollbar.getPropertyValue('height')).toBe('5px'); + }); +});