EOS UI
Components

Card Stack

A swipeable stack with reversible, pointer-driven transitions and bounded DOM rendering.

Import

import '@eosjs/ui/card-stack';

Card Stack

The previous card peeks out on the left, the current card is largest and on top, and the next card peeks out on the right at a smaller size. During a mouse drag or touch swipe, the dragged card shrinks while its neighbour grows toward the centre. At a quarter of the card width, the dragged card moves below the incoming card; the new neighbour gradually appears behind it as dragging continues. Release to settle the card into the opposite side of the stack. A shorter drag springs back. Swipe right to return to the previous card. Desktop users can also use the 44px buttons or focus the stack and press the arrow keys.

10,000-card data source

Showing 1 of 10,000 cards. At most four cards are mounted during a swipe.

API

Generated from custom-elements.json for eos-card-stack.

Attributes

NameTypeDefaultDescription
item-countnumber—Number of cards in the external data source
initial-indexnumber—Initial zero-based index
loopboolean—Wrap at either end

Events

NameTypeDescription
changeCustomEventdetail: { currentIndex, previousIndex }

Methods

NameSignatureDescription
refresh—Rebuild the visible window after an external item changes.
next——
prev——
goTo—Adjacent moves animate; distant jumps replace the visible window directly.

Set itemCount and assign renderItem(index) on the DOM element. The callback must return an HTMLElement. The component mounts three adjacent cards at rest and at most one incoming card during a transition, so the caller can keep a large array, paginated cache, or other indexed source without creating one DOM node per record. Call refresh() after changing data at the current index. Prefetch neighbouring image URLs in your data layer if their loading time matters.

const stack = document.querySelector('eos-card-stack');
stack.itemCount = records.length;
stack.renderItem = (index) => createCard(records[index]);
stack.addEventListener('change', (event) => console.log(event.detail.currentIndex));
MemberDescription
item-countNumber of items in the external source
initial-indexZero-based initial card; read only after connection
loopWrap navigation at the ends
currentIndexCurrent zero-based index
next(), prev(), goTo(index)Navigate; adjacent moves animate
refresh()Recreate the visible three-card window
changeCustomEvent with { currentIndex, previousIndex }
--card-stack-heightStack height, default 420px
--card-stack-card-widthCard width, default 320px

The component uses EOS semantic surface, border, foreground, focus, and motion rules in both themes. Content returned by renderItem should use the same tokens. Interactive controls inside a card are excluded from drag initiation; add data-no-swipe to any other interactive region.

At the first card, the left side is empty and the next card peeks out on the right. At the last card, the right side is empty. Add loop only if you want the ends to wrap and all three positions to stay populated.

On this page