Improve consistency between scrollTop and scrollTo

This commit is contained in:
midzelis
2025-08-24 14:51:50 +00:00
parent ff9e3428be
commit abd97c4a93
4 changed files with 19 additions and 25 deletions
@@ -32,7 +32,7 @@
styleMarginRightOverride?: string; styleMarginRightOverride?: string;
onAssetOpen?: (dayGroup: DayGroup, asset: TimelineAsset, defaultAssetOpen: () => void) => void; onAssetOpen?: (dayGroup: DayGroup, asset: TimelineAsset, defaultAssetOpen: () => void) => void;
onSelect?: (asset: TimelineAsset) => void; onSelect?: (asset: TimelineAsset) => void;
header?: Snippet<[handleScrollTop: (top: number) => void]>; header?: Snippet<[scrollToFunction: (top: number) => void]>;
children?: Snippet; children?: Snippet;
empty?: Snippet; empty?: Snippet;
handleTimelineScroll?: () => void; handleTimelineScroll?: () => void;
@@ -86,20 +86,12 @@
element.scrollTo({ top }); element.scrollTo({ top });
} }
}; };
const scrollTop = (top: number) => {
if (element) {
element.scrollTop = top;
}
};
const scrollBy = (y: number) => { const scrollBy = (y: number) => {
if (element) { if (element) {
element.scrollBy(0, y); element.scrollBy(0, y);
} }
}; };
const scrollToTop = () => {
scrollTo(0);
};
const onScrollToTop = scrollToTop;
const getAssetHeight = (assetId: string, monthGroup: MonthGroup) => { const getAssetHeight = (assetId: string, monthGroup: MonthGroup) => {
// the following method may trigger any layouts, so need to // the following method may trigger any layouts, so need to
@@ -158,7 +150,7 @@
} }
if (!scrolled) { if (!scrolled) {
// if the asset is not found, scroll to the top // if the asset is not found, scroll to the top
scrollToTop(); scrollTo(0);
} }
showSkeleton = false; showSkeleton = false;
}; };
@@ -207,7 +199,7 @@
}} }}
/> />
{@render header?.(scrollTop)} {@render header?.(scrollTo)}
<!-- Right margin MUST be equal to the width of scrubber --> <!-- Right margin MUST be equal to the width of scrubber -->
<section <section
@@ -274,8 +266,12 @@
{singleSelect} {singleSelect}
{monthGroup} {monthGroup}
{onAssetOpen} {onAssetOpen}
{onSelect} onSelect={(isSingleSelect: boolean, asset: TimelineAsset) => {
{onScrollToTop} if (isSingleSelect) {
scrollTo(0);
}
onSelect?.(asset);
}}
{onScrollCompensation} {onScrollCompensation}
/> />
</div> </div>
@@ -133,13 +133,13 @@
scrubberMonth, scrubberMonth,
overallScrollPercent, overallScrollPercent,
scrubberMonthScrollPercent, scrubberMonthScrollPercent,
handleScrollTop, scrollToFunction,
}) => { }) => {
if (!scrubberMonth || timelineManager.timelineHeight < timelineManager.viewportHeight * 2) { if (!scrubberMonth || timelineManager.timelineHeight < timelineManager.viewportHeight * 2) {
// edge case - scroll limited due to size of content, must adjust - use use the overall percent instead // edge case - scroll limited due to size of content, must adjust - use use the overall percent instead
const maxScroll = timelineManager.getMaxScroll(); const maxScroll = timelineManager.getMaxScroll();
const offset = maxScroll * overallScrollPercent; const offset = maxScroll * overallScrollPercent;
handleScrollTop?.(offset); scrollToFunction?.(offset);
} else { } else {
const monthGroup = timelineManager.months.find( const monthGroup = timelineManager.months.find(
({ yearMonth: { year, month } }) => year === scrubberMonth.year && month === scrubberMonth.month, ({ yearMonth: { year, month } }) => year === scrubberMonth.year && month === scrubberMonth.month,
@@ -147,7 +147,7 @@
if (!monthGroup) { if (!monthGroup) {
return; return;
} }
scrollToMonthGroupAndOffset(monthGroup, scrubberMonthScrollPercent, handleScrollTop); scrollToMonthGroupAndOffset(monthGroup, scrubberMonthScrollPercent, scrollToFunction);
} }
}; };
@@ -185,7 +185,7 @@
{empty} {empty}
{handleTimelineScroll} {handleTimelineScroll}
> >
{#snippet header(handleScrollTop)} {#snippet header(scrollTo)}
{#if timelineManager.months.length > 0} {#if timelineManager.months.length > 0}
<Scrubber <Scrubber
{timelineManager} {timelineManager}
@@ -196,7 +196,7 @@
{scrubOverallPercent} {scrubOverallPercent}
{scrubberMonthPercent} {scrubberMonthPercent}
{scrubberMonth} {scrubberMonth}
onScrub={(args) => onScrub({ ...args, handleScrollTop })} onScrub={(args) => onScrub({ ...args, scrollToFunction: scrollTo })}
bind:scrubberWidth bind:scrubberWidth
/> />
{/if} {/if}
@@ -24,9 +24,8 @@
customThumbnailLayout?: Snippet<[TimelineAsset]>; customThumbnailLayout?: Snippet<[TimelineAsset]>;
onAssetOpen?: (dayGroup: DayGroup, asset: TimelineAsset, defaultAssetOpen: () => void) => void; onAssetOpen?: (dayGroup: DayGroup, asset: TimelineAsset, defaultAssetOpen: () => void) => void;
onSelect?: (asset: TimelineAsset) => void; onSelect?: (isSingleSelect: boolean, asset: TimelineAsset) => void;
onScrollCompensation: (compensation: { heightDelta?: number; scrollTop?: number }) => void; onScrollCompensation: (compensation: { heightDelta?: number; scrollTop?: number }) => void;
onScrollToTop: () => void;
} }
let { let {
@@ -41,7 +40,6 @@
onAssetOpen, onAssetOpen,
onSelect, onSelect,
onScrollCompensation, onScrollCompensation,
onScrollToTop,
}: Props = $props(); }: Props = $props();
let lastAssetMouseEvent: TimelineAsset | null = $state(null); let lastAssetMouseEvent: TimelineAsset | null = $state(null);
@@ -161,10 +159,10 @@
if (!asset) { if (!asset) {
return; return;
} }
onSelect?.(asset); onSelect?.(singleSelect, asset);
if (singleSelect) { if (singleSelect) {
onScrollToTop(); // onScrollToTop();
return; return;
} }
+1 -1
View File
@@ -27,7 +27,7 @@ export type ScrubberListener = (args: {
scrubberMonth: { year: number; month: number }; scrubberMonth: { year: number; month: number };
overallScrollPercent: number; overallScrollPercent: number;
scrubberMonthScrollPercent: number; scrubberMonthScrollPercent: number;
handleScrollTop?: (top: number) => void; scrollToFunction?: (top: number) => void;
}) => void | Promise<void>; }) => void | Promise<void>;
// used for AssetResponseDto.dateTimeOriginal, amongst others // used for AssetResponseDto.dateTimeOriginal, amongst others