SelectionInViewMixin

Scrolls to ensure the selected item is visible

Overview

Purpose: ensures the selected item is scrolled into view.

This mixin works at the very end of the Elix render pipeline:

events → methods → setState → updates → render DOM → post-render

Expects the component to provide:

  • items property that returns the list's items. You can supply that with ContentItemsMixin.
  • state.selectedIndex state member updatable via setState.

Provides the component with:

  • Automatic scrolling of the selected item into view.
  • scrollSelectionIntoView method to force the currently-selected item into view.

Usage

import SelectionInViewMixin from 'elix/src/SelectionInViewMixin.js';
class MyElement extends SelectionInViewMixin(HTMLElement) {}

In horizontally or vertically scrollable lists, the component may be asked to select an item which is not currently in view. The SelectionInViewMixin listens for changes in the selection and, if the newly-selected item is not in view, scrolls the component by the minimum amount necessary to bring the item into view.

For reference, the Blink engine has a scrollIntoViewIfNeeded() function that does something similar, but unfortunately it's non-standard, and often ends up scrolling more than is absolutely necessary.

Example

Acai
Acerola
Apple
Apricot
Banana
Blackberry
Blueberry
Cantaloupe
Cherry
Cranberry
Currant
Date
Durian
Fig
Goji berry
Gooseberry
Grape
Grapefruit
Honeydew
Jackfruit
Kiwi
Kumquat
Lemon
Lime
Lychee
Mango
Mangosteen
Mulberry
Nectarine
Orange
Papaya
Passion Fruit
Peach
Pear
Pineapple
Plum
Pomegranate
Pomelo
Prickly Pear
Raspberry
Strawberry
Tangerine
Watermelon
Demo: A list that keeps its selection (if one exists) in view

The above ListBox lets users navigate the selection with the keyboard using Up/Down keys, Page Up/Page Down, Home/End. Navigation in the list is handled by KeyboardDirectionMixin and KeyboardPagedSelectionMixin. Those mixins only change the selected item, but not directly scroll the list. It is SelectionInViewMixin that scrolls the list to ensure a newly-selected item is made visible.

Determining which element to scroll

The component's scrolling surface may be the component itself, or it may be an element within the component's shadow subtree. By default, SelectionInViewMixin will try to determine which element should be scrolled. If the component has a default (unnamed) <slot>, the mixin will find the closest ancestor of that slot that has overflow: auto or overflow: scroll. If no such element is found, the component itself will be assumed to be the scrollable element.

A component can also explicitly indicate which of its shadow subtree elements should be scrolled by defining a property called symbols.scrollTarget that returns the desired element.

API

Used by classes ListBox and Menu.

scrollSelectionIntoView() method

Scroll the selected item element completely into view, minimizing the degree of scrolling performed.

Blink has a scrollIntoViewIfNeeded() function that does something similar, but unfortunately it's non-standard, and in any event often ends up scrolling more than is absolutely necessary.

This scrolls the containing element defined by the scrollTarget property. By default, it will scroll the element itself.

symbols.scrollTarget property

The element that should be scrolled to get the selected item into view.

By default, this uses the defaultScrollTarget helper to find the most likely candidate for scrolling. You can override this property to directly identify which element should be scrolled.

See also symbols.scrollTarget.