Improve consistency between scrollTop and scrollTo

This commit is contained in:
midzelis 2025-08-24 14:51:50 +00:00
parent 46c7adf764
commit de8c54ba26
4 changed files with 19 additions and 25 deletions

View File

@ -28,7 +28,7 @@
isShowDeleteConfirmation?: boolean;
styleMarginRightOverride?: string;
onSelect?: (asset: TimelineAsset) => void;
header?: Snippet<[handleScrollTop: (top: number) => void]>;
header?: Snippet<[scrollToFunction: (top: number) => void]>;
children?: Snippet;
empty?: Snippet;
handleTimelineScroll?: () => void;
@ -78,20 +78,12 @@
element.scrollTo({ top });
}
};
const scrollTop = (top: number) => {
if (element) {
element.scrollTop = top;
}
};
const scrollBy = (y: number) => {
if (element) {
element.scrollBy(0, y);
}
};
const scrollToTop = () => {
scrollTo(0);
};
const onScrollToTop = scrollToTop;
const getAssetHeight = (assetId: string, monthGroup: MonthGroup) => {
// the following method may trigger any layouts, so need to
@ -150,7 +142,7 @@
}
if (!scrolled) {
// if the asset is not found, scroll to the top
scrollToTop();
scrollTo(0);
}
showSkeleton = false;
};
@ -199,7 +191,7 @@
}}
/>
{@render header?.(scrollTop)}
{@render header?.(scrollTo)}
<!-- Right margin MUST be equal to the width of scrubber -->
<section
@ -264,8 +256,12 @@
{isSelectionMode}
{singleSelect}
{monthGroup}
{onSelect}
{onScrollToTop}
onSelect={(isSingleSelect: boolean, asset: TimelineAsset) => {
if (isSingleSelect) {
scrollTo(0);
}
onSelect?.(asset);
}}
{onScrollCompensation}
/>
</div>

View File

@ -127,13 +127,13 @@
scrubberMonth,
overallScrollPercent,
scrubberMonthScrollPercent,
handleScrollTop,
scrollToFunction,
}) => {
if (!scrubberMonth || timelineManager.timelineHeight < timelineManager.viewportHeight * 2) {
// edge case - scroll limited due to size of content, must adjust - use use the overall percent instead
const maxScroll = timelineManager.getMaxScroll();
const offset = maxScroll * overallScrollPercent;
handleScrollTop?.(offset);
scrollToFunction?.(offset);
} else {
const monthGroup = timelineManager.months.find(
({ yearMonth: { year, month } }) => year === scrubberMonth.year && month === scrubberMonth.month,
@ -141,7 +141,7 @@
if (!monthGroup) {
return;
}
scrollToMonthGroupAndOffset(monthGroup, scrubberMonthScrollPercent, handleScrollTop);
scrollToMonthGroupAndOffset(monthGroup, scrubberMonthScrollPercent, scrollToFunction);
}
};
@ -178,7 +178,7 @@
{empty}
{handleTimelineScroll}
>
{#snippet header(handleScrollTop)}
{#snippet header(scrollTo)}
{#if timelineManager.months.length > 0}
<Scrubber
{timelineManager}
@ -189,7 +189,7 @@
{scrubOverallPercent}
{scrubberMonthPercent}
{scrubberMonth}
onScrub={(args) => onScrub({ ...args, handleScrollTop })}
onScrub={(args) => onScrub({ ...args, scrollToFunction: scrollTo })}
bind:scrubberWidth
/>
{/if}

View File

@ -19,9 +19,8 @@
monthGroup: MonthGroup;
timelineManager: TimelineManager;
assetInteraction: AssetInteraction;
onSelect?: (asset: TimelineAsset) => void;
onSelect?: (isSingleSelect: boolean, asset: TimelineAsset) => void;
onScrollCompensation: (compensation: { heightDelta?: number; scrollTop?: number }) => void;
onScrollToTop: () => void;
}
let {
@ -34,7 +33,6 @@
timelineManager,
onSelect,
onScrollCompensation,
onScrollToTop,
}: Props = $props();
let lastAssetMouseEvent: TimelineAsset | null = $state(null);
@ -146,10 +144,10 @@
if (!asset) {
return;
}
onSelect?.(asset);
onSelect?.(singleSelect, asset);
if (singleSelect) {
onScrollToTop();
// onScrollToTop();
return;
}

View File

@ -27,7 +27,7 @@ export type ScrubberListener = (args: {
scrubberMonth: { year: number; month: number };
overallScrollPercent: number;
scrubberMonthScrollPercent: number;
handleScrollTop?: (top: number) => void;
scrollToFunction?: (top: number) => void;
}) => void | Promise<void>;
// used for AssetResponseDto.dateTimeOriginal, amongst others