{"schemaVersion":"1.0","type":"Article","slug":"mantine-selectstepper-2-0-0-swipe-scroll-resize-repeat-eilfa","url":"https://api.zyvop.com/mantine-selectstepper-2-0-0-swipe-scroll-resize-repeat-eilfa","title":"Mantine SelectStepper 2.0.0 — Swipe, Scroll, Resize, Repeat","subtitle":null,"tldr":"Vertical orientation, touch gestures, responsive props, imperative API, and 9 bug fixes — all in one...","keywords":["webdev","Programming","JavaScript","TypeScript"],"entities":["Giovambattista Fazioli","Senior Full-stack Engineer, Lead Developer","webdev","Programming","JavaScript","TypeScript","ZyVOP"],"keyTakeaways":["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."],"headings":["Introduction","✨ What's New","Vertical Orientation","Swipe &amp; Touch Gestures","Imperative API","Responsive Props (CSS-Native)","Size Prop","Animation Callbacks","Gradient Variant","Accessible Button Labels","New Props Summary","💥 Breaking Changes","defaultValue={null} no longer auto-selects","viewWidth type changed to StyleProp","onChange timing changed","🐛 Bug Fixes","🔧 Improvements","Full ARIA Accessibility","Orientation-Aware Keyboard Navigation","66 Tests (up from 2)","Documentation Reorganized","📦 Installation","🔗 Links"],"outboundLinks":["https://github.com/kruschid","https://github.com/gfazioli/mantine-select-stepper/pull/5","https://www.npmjs.com/package/@gfazioli/mantine-select-stepper","https://gfazioli.github.io/mantine-select-stepper/","https://github.com/gfazioli/mantine-select-stepper","https://www.youtube.com/playlist?list=PL85tTROKkZrWyqCcmNCdWajpx05-cTal4","https://mantine-extensions.vercel.app/"],"contentText":"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. &lt;SelectStepperdata={['XS', 'S', 'M', 'L', 'XL']}orientation=\"vertical\"label=\"Size\"/&gt; Enter fullscreen mode Exit fullscreen mode The orientation prop is also responsive — vertical on mobile, horizontal on desktop: &lt;SelectStepperorientation={{ base: 'vertical', sm: 'horizontal' }}data={['XS', 'S', 'M', 'L', 'XL']}/&gt; Enter fullscreen mode Exit fullscreen mode Swipe &amp; 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. &lt;SelectStepperdata={['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']}swipeable // true by defaultswipeThreshold={30} // pixelsloop/&gt; 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&lt;SelectStepperRef | null&gt;(null); &lt;SelectSteppercontrolRef={controlRef}data={['React', 'Vue', 'Angular', 'Svelte']}/&gt; // 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. &lt;SelectStepperdata={['React', 'Vue', 'Angular']}viewWidth={{ base: 120, sm: 180, md: 260 }}size={{ base: 'xs', sm: 'sm', md: 'md' }}/&gt; Enter fullscreen mode Exit fullscreen mode Size Prop Control the ActionIcon button size independently from xs to xl. Supports responsive breakpoint objects. &lt;SelectStepper data={data} size=\"lg\" /&gt;&lt;SelectStepper data={data} size={{ base: 'xs', md: 'md' }} /&gt; Enter fullscreen mode Exit fullscreen mode Animation Callbacks Synchronize external logic with navigation transitions using onStepStart and onStepEnd. &lt;SelectStepperdata={data}onStepStart={() =&gt; setAnimating(true)}onStepEnd={() =&gt; setAnimating(false)}/&gt; Enter fullscreen mode Exit fullscreen mode Gradient Variant Full gradient support for navigation buttons, consistent with Mantine's variant system. &lt;SelectStepperdata={['Low', 'Medium', 'High', 'Ultra']}variant=\"gradient\"gradient={{ from: 'indigo', to: 'cyan', deg: 45 }}/&gt; Enter fullscreen mode Exit fullscreen mode Accessible Button Labels Localize navigation button labels for screen readers. &lt;SelectStepperpreviousLabel=\"Vorheriges Element\"nextLabel=\"Nächstes Element\"/&gt; Enter fullscreen mode Exit fullscreen mode New Props Summary Prop Type Default Description orientation `StyleProp&lt;'horizontal' \\ 'vertical'&gt;` 'horizontal' viewHeight StyleProp&lt;CSSProperties['height']&gt; 36 Viewport height in vertical mode size StyleProp&lt;MantineSize&gt; 'sm' ActionIcon button size swipeable boolean true Enable touch/swipe navigation swipeThreshold number 30 Min swipe distance in pixels onStepStart () =&gt; void — Fired when animation starts onStepEnd () =&gt; void — Fired when animation ends controlRef `RefObject&lt;SelectStepperRef \\ null&gt;` — 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:&lt;SelectStepper data={data} /&gt; // ← 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&lt;CSSProperties['width']&gt;. 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 &amp; Demos 🐙 GitHub 🎬 YouTube Playlist 🧩 All Mantine Extensions","contentHash":"sha256:1b6b353e2ebf39d5c6b4648e1f0c36137c09fb2452fecb18560b7b34cf8a19ef","authorName":"Giovambattista Fazioli","authorUrl":"https://api.zyvop.com/author/giovambattista","authorSameAs":["https://gfazioli.github.io","https://github.com/gfazioli","https://x.com/gfazioli","https://www.linkedin.com/in/giovambattistafazioli/"],"category":null,"tags":["webdev","Programming","JavaScript","TypeScript"],"audience":"Readers researching webdev","tone":"Professional, senior full-stack engineer, lead developer perspective","readingTimeMinutes":4,"wordCount":983,"faqs":null,"primaryTopic":"webdev","publishedAt":"2026-09-04T09:25:37.203Z","updatedAt":"2026-09-04T09:25:37.203Z","canonicalUrl":"https://dev.to/undolog/mantine-selectstepper-200-swipe-scroll-resize-repeat-6ch"}