From 1799c50c7a3af7ba69e4020cd92dc9d7c7a0e905 Mon Sep 17 00:00:00 2001 From: varun2735126 Date: Tue, 18 Aug 2026 00:14:57 +0530 Subject: [PATCH 1/3] feat(slider): add SliderMark and snapPoints for tick marks and pointer snapping Adds the pieces of adobe/react-spectrum#8285 that cannot be built on top of the current API. useSliderState gains snapPoints and snapThreshold. Snapping is applied in setThumbPercent, which only pointer interactions go through, so keyboard interactions continue to move by step. Snap points bypass step rounding so that a snap point off the step grid is still reachable with a pointer. The closest-thumb search moves out of useSlider onto the state as getClosestThumbIndex, so SliderMark can reuse it. useSlider now seeds the track drag position from the pointer instead of the thumb, so a value adjusted to fit the step or a snap point no longer offsets the rest of the drag. --- .../dev/s2-docs/pages/react-aria/Slider.mdx | 47 ++++++- .../react-aria-components/exports/Slider.ts | 5 +- .../react-aria-components/exports/index.ts | 5 +- packages/react-aria-components/src/Slider.tsx | 128 +++++++++++++++++ .../stories/Slider.stories.tsx | 50 ++++++- .../react-aria-components/test/Slider.test.js | 130 ++++++++++++++++++ packages/react-aria/src/slider/useSlider.ts | 31 +---- .../react-aria/test/slider/useSlider.test.js | 21 +++ .../src/slider/useSliderState.ts | 88 ++++++++++-- .../test/slider/useSliderState.test.js | 89 ++++++++++++ starters/docs/src/Slider.css | 69 ++++++++++ starters/docs/src/Slider.tsx | 10 ++ 12 files changed, 635 insertions(+), 38 deletions(-) diff --git a/packages/dev/s2-docs/pages/react-aria/Slider.mdx b/packages/dev/s2-docs/pages/react-aria/Slider.mdx index 893ff592436..0dc63878da9 100644 --- a/packages/dev/s2-docs/pages/react-aria/Slider.mdx +++ b/packages/dev/s2-docs/pages/react-aria/Slider.mdx @@ -99,6 +99,46 @@ By default, slider values are percentages between 0 and 100. Use the `minValue`, fillOffset: 75 }} /> +## Marks + +Render a `` for each value you want to label along the track. Pressing a mark moves the nearest thumb to its value, so labels stay usable when they sit outside the track's bounds. Marks are not focusable — the thumb remains the keyboard interface — so keep their content short, or add `aria-hidden` where it would only repeat what the thumb already announces. + +```tsx render +"use client"; +import {Slider} from 'vanilla-starter/Slider'; + + + {/*- end highlight -*/} +``` + +### Snapping + +Marks alone do not change how a thumb moves. Use `snapPoints` to make a pointer snap to values as it passes them, while leaving the values in between reachable. `snapThreshold` controls how close the pointer must get, as a fraction of the track length. + +Keyboard interactions are deliberately unaffected — arrow keys continue to move by `step` — so a snap point is a pointer affordance rather than a restriction on the value. + + + +Snap points do not have to be multiples of `step`. A value such as `0` on a slider that steps by 25 is only reachable with a pointer. + ## Examples @@ -107,12 +147,13 @@ By default, slider values are percentages between 0 and 100. Use the `minValue`, -```tsx links={{Slider: '#slider', SliderOutput: '#slideroutput', SliderTrack: '#slidertrack', SliderFill: '#sliderfill', SliderThumb: '#sliderthumb'}} +```tsx links={{Slider: '#slider', SliderOutput: '#slideroutput', SliderTrack: '#slidertrack', SliderFill: '#sliderfill', SliderMark: '#slidermark', SliderThumb: '#sliderthumb'}}