Skip to main content
cngx-src documentation

CngxRangeSliderTrack

Directivev0.1.0WCAG AA

projects/common/interactive/slider/range-slider.directive.ts

Import#

import { CngxRangeSliderTrack } from '@cngx/common/interactive'

Description#

Headless dual-thumb (range) slider brain. Put cngxRangeSliderTrack on your own track container and host two CngxSliderThumb children (start / end); the value is a model<[number, number]>() tuple this directive owns. It provides CNGX_SLIDER_RANGE so each thumb reads the shared config, learns its sibling-clamped bounds, and commits its end. The thumbs cannot cross because boundsFor narrows each thumb's range to the other thumb's current value - clamp math, not an effect (Pillar 1).

Most consumers want the finished CngxRangeSlider component (<cngx-range-slider>) which renders the track, fill band, and both thumbs and uses this directive as its brain. Reach for cngxRangeSliderTrack only when you want to own the skin markup.

<div cngxRangeSliderTrack role="group" aria-label="Price range" [(value)]="price" [min]="0" [max]="1000">
  <span class="cngx-slider__track"></span>
  <span cngxSliderThumb="start" aria-label="Minimum"></span>
  <span cngxSliderThumb="end" aria-label="Maximum"></span>
</div>

Metadata#

Host#

Providers#

CNGX_SLIDER_RANGE
useExisting CngxRangeSliderTrack

Relationships

Index#

Inputs#

describedBy#string | null
input()

Optional consumer-supplied id of an external description element. Consumers bind via [cngxDescribedBy]="someId" - same surface as CngxChipInteraction. The active disabled-reason wins.

default null, { alias: 'cngxDescribedBy', }
disabled#boolean
model()

Whether the range slider is disabled. A ModelSignal so form-field bridges can drive it programmatically, mirroring the checkbox/toggle family's bridge write path.

default false
disabledReason#string
input()

Consumer-supplied "why" for the disabled state (no library default per the EN-defaults rule). Announced via an sr-only span the directive appends to the group host; both the span's visibility and the host's aria-describedby reference are gated on disabled() && disabledReason() (Toggle/Radio convergence).

default ''
largeStep#number | undefined
input()

Page-key jump size for both thumbs (absolute, not a step multiple). Defaults to the larger of one step and a tenth of the range.

input()

Track upper bound.

default 100
input()

Track lower bound.

default 0
orientation#"horizontal" | "vertical"
input()

Track axis shared by both thumbs.

default 'horizontal'
input()

Step granularity shared by both thumbs.

default 1
value#[number, number]
model()

Two-way [start, end] tuple - the single source of truth for both thumbs.

default [0, 100]

Outputs#

disabled#boolean
model()

Whether the range slider is disabled. A ModelSignal so form-field bridges can drive it programmatically, mirroring the checkbox/toggle family's bridge write path.

value#[number, number]
model()

Two-way [start, end] tuple - the single source of truth for both thumbs.

Instance Properties#

reason#unknown
ProtectedReadonly

Disabled-"why" span + gated aria-describedby resolution.

createSliderDisabledReason({
  idPrefix: 'cngx-range-slider-desc',
  disabled: () => this.disabled(),
  reason: () => this.disabledReason(),
  describedBy: () => this.describedBy(),
})
valueText#unknown
Readonly

Optional aria-valuetext formatter shared across both thumbs.

input<((value: number) => string) | undefined>(undefined)

Methods#

commit#void
commit(position: CngxSliderThumbPosition, value: number)
@paramvaluenumber
fractionFromPointer#number
fractionFromPointer(clientX: number, clientY: number)
@paramclientXnumber
@paramclientYnumber

HostBindings#

BindingExpression
[attr.aria-disabled]disabled() || null
[attr.aria-describedby]reason.resolvedDescribedBy()
[attr.aria-orientation]orientation()
[style.--cngx-slider-start-fraction]startFraction()
[style.--cngx-slider-end-fraction]endFraction()