Slider

Pick a number, or a range, by dragging a thumb.

import { … } from '@inlaylab/ivorie/slider'
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { IvSlider } from '@inlaylab/ivorie/slider';

@Component({
  selector: 'demo-slider',
  imports: [IvSlider],
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `
    <iv-slider aria-label="Volume" [value]="[75]" [max]="100" [step]="1" class="max-w-xs" />
  `,
})
export default class SliderDemo {}

Installation

CLInpm
npx ivorie add slider

Usage

import { IvSlider } from '@inlaylab/ivorie/slider';
<iv-slider aria-label="Volume" [(value)]="volume" />

The value is an array: one number per thumb. [50] is one thumb, [20, 80] is a range.

Examples

Range

200 to 800

import { ChangeDetectionStrategy, Component, signal } from '@angular/core';
import { IvSlider } from '@inlaylab/ivorie/slider';

@Component({
  selector: 'demo-slider-range',
  imports: [IvSlider],
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `
    <div class="flex w-full max-w-xs flex-col gap-3">
      <iv-slider aria-label="Price" [(value)]="price" [min]="0" [max]="1000" [step]="10" />
      <p class="text-muted-foreground text-sm">{{ price()?.[0] }} to {{ price()?.[1] }}</p>
    </div>
  `,
})
export default class SliderRangeDemo {
  protected readonly price = signal<number[] | null>([200, 800]);
}

Vertical

import { ChangeDetectionStrategy, Component } from '@angular/core';
import { IvSlider } from '@inlaylab/ivorie/slider';

@Component({
  selector: 'demo-slider-vertical',
  imports: [IvSlider],
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `
    <div class="flex h-48 gap-8">
      <iv-slider aria-label="Bass" orientation="vertical" [value]="[50]" />
      <iv-slider aria-label="Treble" orientation="vertical" [value]="[25, 75]" />
    </div>
  `,
})
export default class SliderVerticalDemo {}

Reactive forms

Value: 0.5

import { ChangeDetectionStrategy, Component } from '@angular/core';
import { FormControl, ReactiveFormsModule } from '@angular/forms';
import { IvSlider } from '@inlaylab/ivorie/slider';

@Component({
  selector: 'demo-slider-reactive-forms',
  imports: [IvSlider, ReactiveFormsModule],
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `
    <div class="flex w-full max-w-xs flex-col gap-3">
      <iv-slider aria-label="Opacity" [step]="0.1" [max]="1" [formControl]="opacity" />
      <p class="text-muted-foreground text-sm">Value: {{ opacity.value }}</p>
    </div>
  `,
})
export default class SliderReactiveFormsDemo {
  protected readonly opacity = new FormControl<number[] | null>([0.5]);
}

API

Every part also accepts class.

iv-slider

Works with formControl, formControlName and ngModel.

Name Type Default Description
value number[] | null null (one thumb at min) One number per thumb.
min number 0 Lowest value.
max number 100 Highest value.
step number 1 Values snap to this grid.
disabled boolean false Blocks pointer and keys.
orientation 'horizontal' | 'vertical' 'horizontal' Vertical needs a height on the parent.
aria-label string Moved to every thumb.
aria-labelledby string Moved to every thumb.

Outputs:

Name Payload Description
valueChange number[] The new values.

Accessibility

  • Each thumb is role="slider" with aria-valuemin, aria-valuemax and aria-valuenow.
  • Arrows move one step. Page Up and Page Down move ten steps. Home and End go to the ends.
  • Thumbs never cross.