2 min read

MainScroll

MainScroll

Extends the scroll making it able to sync the first visible element, and allowing the children position to be restored.

Each child element that wants to have this support must be wrapped in a MainScrollItem component.

Props

Name Description Type Default
useWindow If true, sets this scroll instance to the main of the application. Being the main
scroll implies that features like restoring the scroll when the query changes, or storing
the scroll position in the URL will be enabled for this container.
boolean false
restoreScrollTimeoutMs Timeout in milliseconds to abort trying to restore the scroll position to the target
element.
number 5000
threshold Intersection percentage to consider an element visible. number 0.3
margin Adjusts the size of the scroll container bounds. string '0px'

Slots

Name Description Bindings
(name - type - description)
default None

Events

This component emits the following events:

See it in action

The MainScroll component must be an ancestor of the MainScrollItem components. This is because it injects the needed utilities to determine the first visible item.

<template>
  <MainScroll>
    <ul>
      <MainScrollItem v-for="item in 24" tag="li">Item {{ item }}</MainScrollItem>
    </ul>
  </MainScroll>
</template>
<script>
  import { MainScroll, MainScrollItem } from '@empathyco/x-components/scroll';
  export default {
    name: 'MainScrollDemo',
    components: {
      MainScroll,
      MainScrollItem
    }
  };
</script>
<style scoped>
  ul {
    overflow: auto;
    max-height: 200px;
  }
  li {
    height: 50px;
    line-height: 50px;
  }
</style>

Play with props

Window scroll

In case you aren't using a custom scrolling element like the Scroll panel, and want to use the default browser scroll, you can do so by using the useWindow prop:

<template>
  <MainScroll useWindow>
    <ul>
      <MainScrollItem v-for="item in 24" tag="li">Item {{ item }}</MainScrollItem>
    </ul>
  </MainScroll>
</template>
<script>
  import { MainScroll, MainScrollItem } from '@empathyco/x-components/scroll';
  export default {
    name: 'MainScrollDemo',
    components: {
      MainScroll,
      MainScrollItem
    }
  };
</script>

Timeout for restoring scroll

When your application is loaded, this component, together with the MainScrollItem will try to restore the scroll to the provided position (if available). Because of the dynamic nature of JavaScript applications, the element that it tries to restore the scroll to might not be available anymore. For this reason after a defined time, the scroll restoration will be considered failed.

This time can be configured through the restore-scroll-timeout-ms prop. This is specially useful when combined with the URL X Module.

<template>
  <MainScroll :restoreScrollTimeoutMs="1000">
    <ul>
      <MainScrollItem v-for="item in 24" tag="li">Item {{ item }}</MainScrollItem>
    </ul>
  </MainScroll>
</template>
<script>
  import { MainScroll, MainScrollItem } from '@empathyco/x-components/scroll';
  export default {
    name: 'MainScrollDemo',
    components: {
      MainScroll,
      MainScrollItem
    }
  };
</script>

Adjust first visible item

By default this component will consider the first visible item, the first element that is at least intersecting a 50% with its container. However this arbitrary number might not always be the best.

To configure this, you can use the margin and threshold props, which work exactly like in the IntersectionObserver API. In this example we are reducing the bounds of the intersection by 50px, and adjusting the element to be at least 75% intersecting.

<template>
  <MainScroll :threshold="0.75" margin="-50px">
    <ul>
      <MainScrollItem v-for="item in 24" tag="li">Item {{ item }}</MainScrollItem>
    </ul>
  </MainScroll>
</template>
<script>
  import { MainScroll, MainScrollItem } from '@empathyco/x-components/scroll';
  export default {
    name: 'MainScrollDemo',
    components: {
      MainScroll,
      MainScrollItem
    }
  };
</script>