Refactors header and scroll management logic

Updates ScrollManager to dynamically sync header spacer height using ResizeObserver

Removes explicit spacer animation from HeaderDrawerManager
Simplifies header and scroll interaction by moving height synchronization logic to ScrollManager
This commit is contained in:
Janus C. H. Knudsen 2025-12-07 23:25:02 +01:00
parent 899c600e44
commit dee977d4df
3 changed files with 32 additions and 7 deletions

View file

@ -1,13 +1,13 @@
export class HeaderDrawerManager {
private drawer!: HTMLElement;
private spacer!: HTMLElement;
private expanded = false;
private readonly expandedHeight = 24;
private readonly duration = 200;
init(container: HTMLElement): void {
this.drawer = container.querySelector('swp-header-drawer')!;
this.spacer = container.querySelector('swp-header-spacer')!;
if (!this.drawer) console.error('HeaderDrawerManager: swp-header-drawer not found');
}
toggle(): void {
@ -37,8 +37,8 @@ export class HeaderDrawerManager {
fill: 'forwards'
};
// Kun animér drawer - ScrollManager synkroniserer header-spacer via ResizeObserver
this.drawer.animate(keyframes, options);
this.spacer.animate(keyframes, options);
}
isExpanded(): boolean {

View file

@ -2,13 +2,29 @@ export class ScrollManager {
private scrollableContent!: HTMLElement;
private timeAxisContent!: HTMLElement;
private calendarHeader!: HTMLElement;
private headerViewport!: HTMLElement;
private headerSpacer!: HTMLElement;
private resizeObserver!: ResizeObserver;
init(container: HTMLElement): void {
this.scrollableContent = container.querySelector('swp-scrollable-content')!;
this.timeAxisContent = container.querySelector('swp-time-axis-content')!;
this.calendarHeader = container.querySelector('swp-calendar-header')!;
this.headerViewport = container.querySelector('swp-header-viewport')!;
this.headerSpacer = container.querySelector('swp-header-spacer')!;
this.scrollableContent.addEventListener('scroll', () => this.onScroll());
// Synkroniser header-spacer højde med header-viewport
this.resizeObserver = new ResizeObserver(() => this.syncHeaderSpacerHeight());
this.resizeObserver.observe(this.headerViewport);
this.syncHeaderSpacerHeight();
}
private syncHeaderSpacerHeight(): void {
// Kopier den faktiske computed height direkte fra header-viewport
const computedHeight = getComputedStyle(this.headerViewport).height;
this.headerSpacer.style.height = computedHeight;
}
private onScroll(): void {

View file

@ -5,6 +5,7 @@
--day-column-min-width: 200px;
--day-start-hour: 6;
--day-end-hour: 18;
--header-height: 70px;
--color-border: #e0e0e0;
--color-surface: #fff;
--color-text-secondary: #666;
@ -81,12 +82,16 @@ swp-time-axis {
grid-column: 1;
grid-row: 1 / 3;
display: grid;
grid-template-rows: subgrid;
grid-template-rows: auto 1fr;
border-right: 1px solid var(--color-border);
background: var(--color-surface);
overflow: hidden;
}
swp-header-spacer {
border-bottom: 1px solid var(--color-border);
}
swp-header-drawer {
display: block;
height: 0;
@ -96,9 +101,9 @@ swp-header-drawer {
}
swp-time-axis-content {
display: grid;
grid-auto-rows: var(--hour-height);
overflow: hidden;
display: flex;
flex-direction: column;
position: relative;
}
swp-hour-marker {
@ -118,6 +123,10 @@ swp-hour-marker {
height: 1px;
background: var(--color-hour-line);
}
&:first-child::after {
display: none;
}
}
/* Grid container */