ZYVOPMulti-Platform Sync
SeriesAI NewsWhy ZyVOPJoin Discord
LoginGet Started
ZYVOPMulti-Platform Sync

The Developer Publishing Hub. Write once, publish everywhere, and make your work citation-ready with built-in SEO, AEO, and GEO discovery support. Zero reader paywalls.

Content

  • Categories
  • Tags
  • Badges
  • Leaderboard
  • Write Article
  • Newsletter

Company

  • About Us
  • Why ZyVOP
  • Developer API & CLI
  • Write for Us
  • Contact

Connect

  • Privacy Policy
  • Terms of Service
  • Cookie Policy
  • DMCA Policy
  • Code of Conduct

© 2026 ZyVOP. Developer Publishing Hub.

Zero paywalls · Full content ownership
All systems operational
HomeMantine SelectStepper 2.0.0 — Swipe, Scroll, Resize, Repeat

Mantine SelectStepper 2.0.0 — Swipe, Scroll, Resize, Repeat

Giovambattista Fazioli
Giovambattista Fazioli
Senior Full-stack Engineer, Lead DeveloperSupport
September 4, 2026
4 min read
Mantine SelectStepper 2.0.0 — Swipe, Scroll, Resize, Repeat
#webdev#Programming#JavaScript#TypeScript

Vertical orientation, touch gestures, responsive props, imperative API, and 9 bug fixes — all in one major release.

Introduction

This release started with a one-line CSS fix from a community contributor: wrap="nowrap". That PR from @kruschid — just a single prop addition — exposed a deeper truth: SelectStepper v1 wasn't ready for the real world. Narrow containers broke it. Touch devices couldn't use it. Vertical layouts weren't possible. And the animation engine had a race condition hiding in plain sight. So instead of patching, we rebuilt — keeping the same API surface but rearchitecting the internals to handle every scenario we'd been ignoring. The result is v2.0.0: the same component, but now it actually works everywhere.

✨ What's New

Vertical Orientation

Flip the stepper on its side. Navigation buttons switch to up/down arrows, keyboard keys remap automatically, and swipe gestures respond to vertical movement.

<SelectStepperdata={['XS', 'S', 'M', 'L', 'XL']}orientation="vertical"label="Size"/>

Enter fullscreen mode Exit fullscreen mode

The orientation prop is also responsive — vertical on mobile, horizontal on desktop:

<SelectStepperorientation={{ base: 'vertical', sm: 'horizontal' }}data={['XS', 'S', 'M', 'L', 'XL']}/>

Enter fullscreen mode Exit fullscreen mode

Swipe & Touch Gestures

Native Pointer Events — no external dependencies. Swipe left/right in horizontal mode, up/down in vertical. Enabled by default with a configurable threshold.

<SelectStepperdata={['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']}swipeable            // true by defaultswipeThreshold={30}  // pixelsloop/>

Enter fullscreen mode Exit fullscreen mode

Imperative API

Control the stepper programmatically via controlRef. Navigate, reset, or jump to any value from parent code.

const controlRef = useRef<SelectStepperRef | null>(null);

<SelectSteppercontrolRef={controlRef}data={['React', 'Vue', 'Angular', 'Svelte']}/>

// From anywhere in the parent:controlRef.current?.next();controlRef.current?.prev();controlRef.current?.reset();controlRef.current?.navigateTo('Svelte');

Enter fullscreen mode Exit fullscreen mode

Responsive Props (CSS-Native)

viewWidth, viewHeight, and size accept Mantine breakpoint objects. Under the hood, responsive values are resolved via InlineStyles with real CSS @media queries — the same pattern Mantine core uses in SimpleGrid and Grid. Zero React re-renders on resize.

<SelectStepperdata={['React', 'Vue', 'Angular']}viewWidth={{ base: 120, sm: 180, md: 260 }}size={{ base: 'xs', sm: 'sm', md: 'md' }}/>

Enter fullscreen mode Exit fullscreen mode

Size Prop

Control the ActionIcon button size independently from xs to xl. Supports responsive breakpoint objects.

<SelectStepper data={data} size="lg" /><SelectStepper data={data} size={{ base: 'xs', md: 'md' }} />

Enter fullscreen mode Exit fullscreen mode

Animation Callbacks

Synchronize external logic with navigation transitions using onStepStart and onStepEnd.

<SelectStepperdata={data}onStepStart={() => setAnimating(true)}onStepEnd={() => setAnimating(false)}/>

Enter fullscreen mode Exit fullscreen mode

Gradient Variant

Full gradient support for navigation buttons, consistent with Mantine's variant system.

<SelectStepperdata={['Low', 'Medium', 'High', 'Ultra']}variant="gradient"gradient={{ from: 'indigo', to: 'cyan', deg: 45 }}/>

Enter fullscreen mode Exit fullscreen mode

Accessible Button Labels

Localize navigation button labels for screen readers.

<SelectStepperpreviousLabel="Vorheriges Element"nextLabel="Nächstes Element"/>

Enter fullscreen mode Exit fullscreen mode

New Props Summary

Prop

Type

Default

Description

orientation

`StyleProp<'horizontal' \

'vertical'>`

'horizontal'

viewHeight

StyleProp<CSSProperties['height']>

36

Viewport height in vertical mode

size

StyleProp<MantineSize>

'sm'

ActionIcon button size

swipeable

boolean

true

Enable touch/swipe navigation

swipeThreshold

number

30

Min swipe distance in pixels

onStepStart

() => void

—

Fired when animation starts

onStepEnd

() => void

—

Fired when animation ends

controlRef

`RefObject<SelectStepperRef \

null>`

—

previousLabel

string

'Previous item'

Aria label for prev button

nextLabel

string

'Next item'

Aria label for next button

gradient

MantineGradient

—

Gradient config for variant="gradient"

💥 Breaking Changes

defaultValue={null} no longer auto-selects

Before (v1): Passing defaultValue={null} auto-selected the first non-disabled item.
After (v2): defaultValue={null} means "no selection" — the component starts empty.

// If you relied on null to auto-select, just omit the prop:<SelectStepper data={data} />  // ← auto-selects first item

Enter fullscreen mode Exit fullscreen mode

viewWidth type changed to StyleProp

The prop now accepts responsive objects. TypeScript users who explicitly type viewWidth as CSSProperties['width'] will need to update to StyleProp<CSSProperties['width']>. Runtime behavior is backward compatible.

onChange timing changed

The callback is now properly wired through Mantine's useUncontrolled hook. If you had workarounds for stale-state issues in v1, they may no longer be needed.

🐛 Bug Fixes

  • Timeout race condition — Rapid clicks no longer orphan timers or cause setState on unmounted components

  • Controlled mode sync — External value changes during animation no longer cause visual glitches

  • Loop animation — Infinite scroll now consistently moves forward instead of reversing at the boundary

  • Narrow container wrapping — Navigation buttons no longer wrap to a new line (thanks @kruschid)

  • View shrinking misalignment — Resizing below viewWidth no longer misaligns the scroll offset

  • Stale data handling — Changing data while value references a removed item now auto-resets

  • Callback consistency — onStepStart only fires when navigation actually occurs; onLeftIconClick/onRightIconClick respect canGoPrev/canGoNext

  • Demo import typo — Styles API demo no longer references the wrong package

🔧 Improvements

Full ARIA Accessibility

The component now implements role="spinbutton" with complete attributes: aria-valuemin, aria-valuemax, aria-valuenow, aria-valuetext, aria-disabled, aria-label, and aria-labelledby. A hidden aria-live="polite" region announces value changes to screen readers.

Orientation-Aware Keyboard Navigation

Arrow keys are now direction-specific: ArrowLeft/ArrowRight in horizontal, ArrowUp/ArrowDown in vertical. No more confusing cross-axis navigation.

66 Tests (up from 2)

Comprehensive coverage across: navigation, keyboard, controlled/uncontrolled mode, loop, disabled items, empty data, swipe gestures (with PointerEvent polyfill), imperative API, responsive props, ARIA attributes, and animation callbacks.

Documentation Reorganized

Docs follow the Mantine standard: Installation → Usage → Core → Behavior → Visual → Advanced → Reference. Eight new interactive demos added.

📦 Installation

yarn add @gfazioli/mantine-select-stepper

Enter fullscreen mode Exit fullscreen mode

Import styles at your app root:

import '@gfazioli/mantine-select-stepper/styles.css';

Enter fullscreen mode Exit fullscreen mode

Or with CSS layers:

import '@gfazioli/mantine-select-stepper/styles.layer.css';

Enter fullscreen mode Exit fullscreen mode

Compatibility: Mantine 8.x · React 18/19 · TypeScript 5.x · MIT License

🔗 Links

  • 📦 npm

  • 📖 Documentation & Demos

  • 🐙 GitHub

  • 🎬 YouTube Playlist

  • 🧩 All Mantine Extensions

Comments (0)

Login to post a comment.

Giovambattista Fazioli
Giovambattista Fazioli

Senior Full-stack Engineer, Lead Developer

Italian Senior Full-stack Engineer and Lead Developer on the Cloud team at Namecheap. I build developer tools, React/Mantine UI components and native macOS apps — mostly open source. I work across TypeScript, Next.js, Go and SwiftUI, and I've been coding since the Commodore/Assembly days. Creator of WP Bones and 25+ Mantine extensions, and maintainer of the Undolog open-source studio.

Support
Subscribe to Giovambattista Fazioli's Newsletter

More from Giovambattista Fazioli

View profile

FinderGit 0.29.0 — open a commit like a folder

There’s a moment, reading a commit list, where you want to know one small thing: which files did that one touch?

3 minSep 4

Netfox 0.18.0 — is it my connection, or the internet?

There is a question that comes up every time something feels slow, and until now Netfox could not...

3 minSep 4

Mantine Book — Grab Any Edge, Turn Any Page

A realistic iBooks-style book for React built on Mantine: stack two-sided pages and turn them by...

5 minSep 4

Netfox — The macOS app that never loses track of your network

I built Netfox because every existing answer to "what's actually on my network?" annoyed me. The...

5 minSep 4

Audio That Sees Itself

A Mantine-native audio player for React with waveform visualisation and a live spectrum analyser,...

5 minSep 4