Upgrading from v3 to v4

This guide documents the changes required when upgrading from Svelte Range Slider Pips v3 to v4.

General Upgrade Steps

1. Update Dependencies

First, update the package to version 4:

npm install svelte-range-slider-pips@4
# or
yarn add svelte-range-slider-pips@4
# or
pnpm add svelte-range-slider-pips@4

2. Breaking Changes

The following changes require immediate attention:

  • CSS Class Names: Most component classes are now prefixed with rs to prevent conflicts with other frameworks

    • See the CSS Class Name Changes section for detailed mapping
    • Update any custom CSS selectors targeting these classes
    • Update any JavaScript code that queries or manipulates these classes
  • If you were never applying custom CSS, you can ignore this change.

  • All previous css variable names (ie: --range-slider, --range-handle, etc) remain valid.

  • Positioning of the Handles: The handles are now positioned using translate property instead of left/right.

3. New Features to Consider

The following features are optional but recommended for review:

  1. Range Controls:

    • rangeGapMin and rangeGapMax for controlling handle distances
    • rangeFloat for displaying range values
    • rangeFormatter for custom range value formatting
  2. Draggable Ranges:

    • New draggy property for range dragging
    • Enhanced user experience for range adjustments
  3. Animation Control:

    • New spring property to control animations
    • class property for custom styling

4. Bug Fixes and Improvements

The following improvements are automatically applied:

  1. Keyboard Navigation:

    • More precise percentage-based movements
    • Fixed PageUp/PageDown behavior
    • Better step alignment
  2. Input Validation:

    • Improved min/max validation
    • Better aria labels handling
    • Enhanced precision handling
  3. Hover States:

    • More consistent disabled state behavior
    • Better visual feedback

5. Testing Checklist

After upgrading, verify the following:

  1. All custom CSS styles are still applied correctly
  2. Hover and focus states work correctly
  3. The component works correctly with your CSS framework

6. Getting Help

If you encounter issues during the upgrade:


New Range Properties

807a2ae6 [feature] resolves #105

In v4, several new properties have been added to enhance range slider functionality. These properties provide more control over range behavior and display.

Range Gap Controls

Two new properties allow you to control the minimum and maximum distance between handles in a range slider:

  • rangeGapMin: Sets the minimum allowed distance between handles
  • rangeGapMax: Sets the maximum allowed distance between handles

These properties work in conjunction with the existing pushy option:

  • When pushy is true, moving a handle past the gap limit will push the other handle
  • When pushy is false, handles will stop at the gap limits

Example usage:

<RangeSlider
  range={true}
  rangeGapMin={10}
  rangeGapMax={50}
  pushy={true}
/>

Range Float Display

The new rangeFloat property allows you to display the range values between the handles:

  • When true, shows the range values (e.g., “20 - 80”)
  • Respects existing prefix and suffix properties
  • Works with both regular and reversed ranges

Example usage:

<RangeSlider
  range={true}
  rangeFloat={true}
  prefix="$"
/>

Range Value Formatting

The new rangeFormatter property provides custom formatting for the range float display:

  • Takes a function with signature: (value1, value2, percent1, percent2)
  • Allows complete control over how the range is displayed
  • Can return HTML strings for rich formatting

Example usage:

<RangeSlider
  range={true}
  rangeFloat={true}
  rangeFormatter={(v1, v2) => `${v1} to ${v2}`}
/>

Important Notes

  • These properties only affect range sliders (when range={true})
  • The gap controls respect the slider’s step and precision settings
  • Range float display works independently of handle float display
  • All new properties are optional and have sensible defaults

Draggable Range

a473ef7f [feature] resolves #150

In v4, range sliders now support dragging the range area between handles. This provides a more intuitive way to adjust both handles simultaneously, particularly useful for date ranges or time periods where you want to maintain a consistent duration while moving the range.

New Property

  • draggy: Enables dragging of the range area between handles
    • Only works on range sliders (when range={true})
    • Defaults to false

Event Payload Changes

When dragging the range area, the event payloads are slightly different from handle movement events:

  • start event:

    • activeHandle: number is set to -1 (indicating range drag)
    • value: number[] is an array of both handle values (not in the payload for dragging ranges)
    • values: number[] contains the initial positions of both handles
  • stop event:

    • activeHandle: number is set to -1
    • startValue: number[] is an array of initial handle positions
    • value: number is the current position of the active handle (not in the payload for dragging ranges)
    • values: number[] contains the final positions of both handles
  • change event:

    • activeHandle: number is set to -1
    • startValue: number[] is an array of initial handle positions
    • previousValue: number[] is an array of previous handle positions
    • value: number is the current position of the active handle (not in the payload for dragging ranges)
    • values: number[] contains the current positions of both handles

Example Usage

<RangeSlider
  range={true}
  draggy={true}
  on:start={({ values }) => console.log('Range drag started:', values)}
  on:change={({ values }) => console.log('Range changed:', values)}
  on:stop={({ values }) => console.log('Range drag ended:', values)}
/>

Important Notes

  • Range dragging respects all existing constraints (min, max, step, precision)
  • The range area provides visual feedback during hover and drag
  • Range dragging works with both regular and reversed ranges
  • The feature is disabled when the slider is disabled

Keyboard Navigation Improvements

8d809dd [bugfix] resolves #152

In v4, keyboard navigation has been improved to provide more precise and intuitive control over the slider values.

Percentage-Based Movement

The calculation of percentage-based movements has been refined:

  • Ctrl/Cmd + Arrow: Moves by 1% of the total range
  • Shift + Arrow or PageUp/PageDown: Moves by 10% of the total range

All percentage-based movements are now properly aligned to the slider’s step value, ensuring consistent behavior.

PageUp/PageDown Fix

The behavior of PageUp and PageDown keys has been corrected:

  • PageUp: Moves the handle up/right (previously was inverted)
  • PageDown: Moves the handle down/left (previously was inverted)

Example Usage

<RangeSlider
  min={0}
  max={100}
  step={1}
  // Now Ctrl/Cmd + Arrow moves by 1 unit
  // Shift + Arrow or PageUp/PageDown moves by 10 units
/>

Important Notes

  • All movements respect the slider’s step and precision settings
  • Percentage-based movements are now more predictable and consistent
  • The changes affect both single and range sliders

Input Validation Improvements

d631a69 [bugfix]

In v4, input validation has been enhanced to provide better error handling and prevent invalid states.

Min/Max Validation

The component now validates and corrects invalid min/max values:

  • If min is greater than or equal to max, the values are reset to defaults (0 and 100)
  • A console error is logged to inform developers of the issue
  • This prevents the slider from entering an invalid state

Aria Labels Validation

The ariaLabels property now has improved validation:

  • If ariaLabels is not an array when using multiple handles, it’s automatically converted to an empty array
  • A console warning is logged to inform developers of the issue
  • This ensures proper accessibility even if labels are incorrectly provided

Precision Handling

The precision property has been moved to the top of the component for better organization and is now properly respected in all calculations.

Example Usage

<RangeSlider
  min={0}
  max={100}
  precision={2}
  ariaLabels={['Minimum value', 'Maximum value']}
/>

Important Notes

  • Invalid min/max values are automatically corrected to prevent slider malfunctions
  • The component now provides helpful console messages for debugging
  • All validation respects the slider’s precision settings
  • These changes help prevent runtime errors and improve developer experience

Hover State Changes

d1c86e7 [bugfix]

In v4, hover state behavior has been improved to be more consistent with disabled states.

Disabled State Behavior

The hover effects are now properly disabled when the slider is disabled:

  • Hover effects only show when both hoverable: true and disabled: false
  • This affects both handle and range bar hover states
  • The change ensures better visual feedback about the slider’s interactive state

Example Usage

<RangeSlider
  hoverable={true}
  disabled={true}  // Hover effects will not show
/>

<RangeSlider
  hoverable={true}
  disabled={false} // Hover effects will show
/>

<RangeSlider
  hoverable={false}
  disabled={false} // Hover effects will not show
/>

Important Notes

  • This change affects both single and range sliders
  • The behavior is consistent across all interactive elements (handles, range bar)
  • No changes are needed if you’re already properly handling disabled states

Spring Control & Custom Classes

1d83ae6 [feature] resolves #92

In v4, you have more control over the slider’s animations and styling through new properties. This feature was added in response to user feedback about animation behavior during continuous sliding.

Animation Control

The new spring property allows you to control handle animations:

  • Defaults to true
  • When set to false, disables all animations on the slider handles
  • Useful for performance optimization or when instant updates are preferred
  • Particularly helpful when users are continuously sliding the handle, as it prevents the “gliding” effect through values

Custom Class Names

The new class property allows you to add custom CSS classes to the slider:

  • Similar to the existing id prop
  • Classes are added to the base slider element
  • Useful for custom styling or framework integration

Example Usage

<RangeSlider
  spring={false}  // Disable animations for instant updates
  class="my-custom-slider"  // Add custom class
/>

<RangeSlider
  spring={true}  // Enable animations (default)
  class="custom-theme"  // Add custom class
/>

Important Notes

  • The spring property affects all handle movements (drag, keyboard, programmatic)
  • When spring is false, handle movements are instant
  • Custom classes are added alongside the component’s internal classes
  • These changes are compatible with both single and range sliders
  • This feature was added to address the “gliding” effect during continuous sliding, making the slider feel more responsive and precise

Float Positioning Changes

dd7847f b5b54ac [improvement]

In v4, the positioning of float elements has been updated to improve performance and fix visual glitches:

CSS Transforms Update

The component now uses the modern translate property instead of transform: translate():

  • Changed transform: translate(-50%, -50%) to translate: -50% -50% 0.01px
  • Added hardware acceleration via 3D transforms for better performance
  • Improved animation easing with cubic-bezier timing

Float Visual Improvements

  • Refined padding and border radius for better appearance
  • Resolved positioning issues in vertical mode

Impact on Custom CSS

If you’ve written custom CSS targeting the float elements, you may need to update:

  1. Custom positioning: If overriding the position of floats, use the translate property instead of transform
  2. Animations: If customizing float animations, update to match the new properties
  3. Z-index handling: The component now uses 3D transforms which create a new stacking context

Example of Updated Custom CSS

/* Before (v3) */
.rangeSlider .rangeHandle.active .rangeFloat {
  transform: translate(-50%, -10px);
}

/* After (v4) */
.rangeSlider .rangeHandle.rsActive .rangeFloat {
  translate: -50% -10px 0.01px;
}

Important Notes

  • These changes improve rendering on high-DPI displays
  • The visual appearance of floats should be preserved by default
  • Only users with custom float positioning CSS need to make updates
  • The changes affect both handle floats and range floats

CSS Positioning Changes

0ef2b0e [improvement]

We’ve completely changed how handles and range bars are positioned in v4. This is a significant improvement, but might need your attention if you’ve written custom CSS.

What Changed

  • Handles and range bar now use CSS translate instead of left/right positioning
  • Added GPU acceleration with 3D transforms for smoother animations
  • Better pip rendering that won’t kill your browser when you have tons of them

If You’ve Written Custom CSS

If you’ve styled the slider positions with custom CSS, you might need to update your code. The component now uses CSS custom properties internally to control positions. The handles use --handle-pos and the range uses --range-start, --range-end and --range-size.

Take a look at your slider implementation and see if it looks mis-aligned. It should be easily fixable by changing your custom left/right/top/bottom positioning to use the translate property instead.

Performance Boost

These changes make a big difference in how smoothly the slider runs:

  • Much smoother animations, especially on mobile
  • Better performance with lots of pips
  • No more janky movements when dragging quickly

You don’t need to do anything to get these benefits unless you had custom positioning CSS.

CSS Class Name Changes

2343440f [breaking-change]

In v4, CSS class names have been prefixed with rs to prevent conflicts with generic CSS frameworks like DaisyUI or UnoCSS. This change affects state and modifier classes used in the component.

Only the class names have changed, the css variables remain the same.

State Classes

v3 Classv4 ClassDescription
disabledrsDisabledApplied when slider is disabled
hoverablersHoverableApplied when hover effects are enabled
verticalrsVerticalApplied when slider is vertical
reversedrsReversedApplied when slider values are reversed
focusrsFocusApplied when slider has focus
rangersRangeApplied when slider is in range mode
minrsMinApplied when range mode is set to ‘min’
maxrsMaxApplied when range mode is set to ‘max’
pipsrsPipsApplied when pips are enabled
pip-labelsrsPipLabelsApplied when pip labels are enabled

Handle Classes

v3 Classv4 ClassDescription
activersActiveApplied when handle is active
pressrsPressApplied when handle is being pressed

Pip Classes

v3 Classv4 ClassDescription
piprsPipBase class for pips
pip--firstrsPip--firstApplied to first pip
pip--lastrsPip--lastApplied to last pip
selectedrsSelectedApplied when pip is selected
in-rangersInRangeApplied when pip is within range
out-of-limitrsOutOfLimitApplied when pip is outside limits
pipValrsPipValClass for pip value display
pipVal-prefixrsPipValPrefixClass for pip value prefix
pipVal-suffixrsPipValSuffixClass for pip value suffix

Bar Classes

v3 Classv4 ClassDescription
rangeDragrsDragApplied when bar is being dragged

Float Classes

v3 Classv4 ClassDescription
rangeFloat-prefixrsRangeFloatPrefixClass for float value prefix
rangeFloat-suffixrsRangeFloatSuffixClass for float value suffix

CSS Variables

The CSS variables remain unchanged as they were already prefixed with -- and are specific to the component.

Dark Mode and Color System

1047235e [change]

In v4, the color system has been completely revamped to support dark mode and provide a more flexible theming system. But overall the colours should remain almost identical to v3.

Dark Mode Support

The slider now supports dark mode by adding the darkmode prop

How to Enable Dark Mode

  • Default (Light mode):

    <RangeSlider />
    <RangeSlider darkmode={false} />
    <!-- The slider always uses the light color scheme, 
    regardless of system settings. -->

    This is the same as v3.

  • Automatic (system preference):

    <RangeSlider darkmode="auto" />
    <!-- The slider will use dark colors if the user's 
    system prefers dark mode, and light colors otherwise. -->

    This is the best option if your website has a dark mode toggle.

  • Force Dark Mode:

    <RangeSlider darkmode="force" />
    <!-- The slider always uses the dark color scheme, 
    regardless of system settings. -->

    This is the best option if your website is just dark.

New Color System

The component now uses a comprehensive set of CSS variables for theming:

Light Theme Variables

--slider-accent: #4a40d4;
--slider-accent-100: #838de7;
--slider-base: #99a2a2;
--slider-base-100: #b9c2c2;
--slider-bg: #d7dada;
--slider-fg: #3f3e4f;

Dark Theme Variables

--slider-dark-accent: #6070fc;
--slider-dark-accent-100: #7a7fab;
--slider-dark-base: #82809f;
--slider-dark-base-100: #595868;
--slider-dark-bg: #3f3e4f;
--slider-dark-fg: #d7dada;

Simplified Customization

The new system makes it easier to customize the slider’s appearance:

  1. Theme-Based Customization:

    • Override the base theme variables to change the entire color scheme
    • No need to override individual element colors
  2. Element-Specific Customization:

    • Still supports overriding individual element colors using the existing CSS variables
    • All previous CSS variable names remain valid
  3. Style Prop Support:

    • New style prop allows you to directly pass CSS declarations / variables
    • Works alongside the existing class prop
    • Perfect for dynamic theme changes

Example Usage

<!-- Custom theme colors can be supplied as a css string -->
<RangeSlider
  darkmode="force"
  style="
    --slider-accent: #0ea5e9;
    --slider-bg: #222;
  "
/>

<!-- Custom theme colors using Tailwind classes -->
<RangeSlider
  darkmode="auto"
  class="
    [--slider-accent:var(--color-sky-500)]
    [--slider-accent-100:var(--color-sky-300)]
    [--slider-base:var(--color-slate-500)]
    [--slider-base-100:var(--color-slate-300)]
    [--slider-bg:var(--color-slate-200)]
  "
/>

Important Notes

  • Legacy fallback colors have been removed as all modern browsers support CSS variables
  • The component is light-mode by default
  • Dark mode can be enabled by setting darkmode="force"
  • The component will follow the system color scheme if darkmode="auto" is set.
  • Custom themes can be applied by overriding the base theme variables
  • All existing CSS variable overrides remain supported for backward compatibility
  • The new system provides better color consistency and easier theme management
  • CSS variables are now wrapped in @layer base to prevent conflicts with Tailwind CSS

CSS Improvements

b8bc406 [change]

Range Bar Transitions

The range bar now has smoother transitions:

  • Added subtle transitions on hover

CSS Layer Support

The component’s CSS variables are @layered:

  • Wrapped in @layer base to prevent conflicts with Tailwind CSS
  • this shouldnt affect existing users

Migration Steps

  1. Update any custom CSS selectors that target the component’s state or modifier classes to use the new prefixed names
  2. If you’re using any JavaScript to query or manipulate the component’s elements, update the class names in those queries
  3. Review any CSS framework configurations that might have been targeting these classes
  4. Test the component thoroughly after the update to ensure all styles are applied correctly

Example

Before (v3):

.rangeSlider .pip.selected {
  background-color: blue;
}

After (v4):

.rangeSlider .rsPip.rsSelected {
  background-color: blue;
}