Skip to content

MotionRailState

Current state of the carousel.

Type Definition

ts
type MotionRailState = {
  totalItems: number;
  visibleItemIndexes: number[];
  isFirstItemVisible: boolean;
  isLastItemVisible: boolean;
}

Properties

totalItems

Total number of items in the carousel.

  • Type: number
ts
const state = carousel.getState();
console.log(state.totalItems);  // 10

visibleItemIndexes

Array of currently visible item indexes (0-based).

  • Type: number[]
ts
const state = carousel.getState();
console.log(state.visibleItemIndexes);  // [0, 1, 2]

This array updates as the user scrolls and items enter/exit the viewport.


isFirstItemVisible

Whether the first item is currently visible.

  • Type: boolean
ts
const state = carousel.getState();
console.log(state.isFirstItemVisible);  // true

// Use for disabling "previous" button
const prevButton = document.querySelector('.prev-button');
prevButton.disabled = state.isFirstItemVisible;

isLastItemVisible

Whether the last item is currently visible.

  • Type: boolean
ts
const state = carousel.getState();
console.log(state.isLastItemVisible);  // false

// Use for disabling "next" button
const nextButton = document.querySelector('.next-button');
nextButton.disabled = state.isLastItemVisible;

Usage

Getting Current State

Use the getState() method to retrieve the current state:

ts
const state = carousel.getState();
console.log(state);
// {
//   totalItems: 10,
//   visibleItemIndexes: [0, 1, 2],
//   isFirstItemVisible: true,
//   isLastItemVisible: false
// }

Listening to State Changes

Use the onChange option to receive state updates:

ts
const carousel = new MotionRail(element, {
  onChange: (state) => {
    console.log('Total:', state.totalItems);
    console.log('Visible:', state.visibleItemIndexes);
    console.log('At start:', state.isFirstItemVisible);
    console.log('At end:', state.isLastItemVisible);
  }
});

Common Patterns

Disable Navigation at Boundaries

ts
const prevButton = document.querySelector('.prev');
const nextButton = document.querySelector('.next');

const carousel = new MotionRail(element, {
  onChange: (state) => {
    prevButton.disabled = state.isFirstItemVisible;
    nextButton.disabled = state.isLastItemVisible;
  }
});

Update Pagination Counter

ts
const counter = document.querySelector('.counter');

const carousel = new MotionRail(element, {
  onChange: (state) => {
    const currentPage = state.visibleItemIndexes[0] + 1;
    counter.textContent = `${currentPage} / ${state.totalItems}`;
  }
});

Custom Dot Indicators

ts
const dotsContainer = document.querySelector('.dots');

const carousel = new MotionRail(element, {
  onChange: (state) => {
    // Update active dot based on first visible item
    const firstVisibleIndex = state.visibleItemIndexes[0];
    document.querySelectorAll('.dot').forEach((dot, index) => {
      dot.classList.toggle('active', index === firstVisibleIndex);
    });
  }
});

Conditional Auto-Pause

ts
const carousel = new MotionRail(element, {
  autoplay: true,
  onChange: (state) => {
    // Pause when reaching the last item
    if (state.isLastItemVisible) {
      carousel.pause();
    }
  }
});

Next Steps