Skip to content

Commit

Permalink
Merge pull request #1264 from empathyco/bugfix/EMP-1050-fix-scroll-be…
Browse files Browse the repository at this point in the history
…haviour-when-at-the-end-of-scroll-and-dynamic-height

fix: scroll behaviour when at the end of scroll and dynamic height
  • Loading branch information
lauramargar authored Aug 25, 2023
2 parents 583f904 + 61f89fb commit f9aa70d
Showing 1 changed file with 57 additions and 14 deletions.
71 changes: 57 additions & 14 deletions packages/x-components/src/components/scroll/scroll.mixin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export default class ScrollMixin extends Vue {
@Prop({ default: 100 })
public distanceToBottom!: number;
/**
* Positive vertical distance to still consider that the an element is the first one visible.
* Positive vertical distance to still consider that the element is the first one visible.
* For example, if set to 100, after scrolling 100 pixels, the first rendered element
* will still be considered the first one.
*/
Expand Down Expand Up @@ -98,6 +98,31 @@ export default class ScrollMixin extends Vue {
* @internal
*/
protected scrollHeight = 0;
/**
* Flag to know if the property clientHeight is changing or gets the final value.
*
* @internal
*/
protected isClientHeightChanging = false;
/**
* Property for setting the direction of scroll.
*
* @internal
*/
protected scrollDirection: ScrollDirection = 'UP';

/**
* Restores the clientHeight flag when clientHeight property stops changing.
* Also sets a new previous position, before update the current one.
*
* @internal
*/
protected restoreClientHeightFlag(): void {
this.isClientHeightChanging = false;
this.previousPosition = this.currentPosition;
}

protected throtteledCall = throttle(this.restoreClientHeightFlag, 100);

/**
* Throttled version of the function that stores the DOM scroll related properties.
Expand All @@ -112,9 +137,9 @@ export default class ScrollMixin extends Vue {
}

/**
* Returns distance missing to end position position.
* Returns distance missing to endPosition position.
*
* @returns A number for knowing the distance missing to end position position.
* @returns A number for knowing the distance missing to endPosition position.
* @internal
*/
protected get distanceToEnd(): number {
Expand Down Expand Up @@ -152,16 +177,6 @@ export default class ScrollMixin extends Vue {
return this.currentPosition === 0;
}

/**
* Returns direction of scroll based in {@link ScrollDirection}.
*
* @returns The scroll direction.
* @internal
*/
protected get scrollDirection(): ScrollDirection {
return this.currentPosition > this.previousPosition ? 'DOWN' : 'UP';
}

/**
* Returns end position of scroll.
*
Expand Down Expand Up @@ -206,6 +221,19 @@ export default class ScrollMixin extends Vue {
});
}

/**
* Change the isClientHeightChanging flag when the property clientHeight is changing and
* calls throttleledCall method.
*
* @internal
*/
@Watch('clientHeight', { immediate: true })
protected onClientHeightChanged(): void {
this.isClientHeightChanging = true;

this.throtteledCall();
}

/**
* Emits the `scroll` event.
*
Expand All @@ -219,6 +247,19 @@ export default class ScrollMixin extends Vue {
this.previousPosition = oldScrollPosition;
}

/**
* Sets direction of scroll based in {@link ScrollDirection} when the current position
* has changed.
*
* @internal
*/
@Watch('currentPosition')
protected setScrollDirection(): void {
if (!this.isClientHeightChanging && this.currentPosition !== this.previousPosition) {
this.scrollDirection = this.currentPosition > this.previousPosition ? 'DOWN' : 'UP';
}
}

/**
* Emits the 'scroll:at-start' event when the user reaches the start.
*
Expand Down Expand Up @@ -260,7 +301,9 @@ export default class ScrollMixin extends Vue {
*/
@Watch('scrollDirection')
protected emitScrollDirection(direction: ScrollDirection): void {
this.$emit('scroll:direction-change', direction);
if (!this.isClientHeightChanging) {
this.$emit('scroll:direction-change', direction);
}
}

/**
Expand Down

0 comments on commit f9aa70d

Please sign in to comment.