@data-slot/slider

中文文档
1.1.3发布于 2026/11/05MITTypeScriptESM + CJS构建来源已验证近 30 天下载 4280

Headless slider component for vanilla JavaScript. Supports single value and range sliders with full keyboard navigation and ARIA compliance.

原始使用文档
文档目录15 节
  1. Installation
  2. Usage
  3. HTML Structure
  4. JavaScript
  5. API
  6. Initialization
  7. Slots
  8. Data Attributes
  9. Options
  10. Controller
  11. Events
  12. Styling
  13. Keyboard Navigation
  14. Accessibility
  15. License

@data-slot/slider

Headless slider component for vanilla JavaScript. Supports single value and range sliders with full keyboard navigation and ARIA compliance.

Installation

bun add @data-slot/slider
# or
npm install @data-slot/slider

Usage

HTML Structure

<!-- Single value slider -->
<div data-slot="slider" data-default-value="50">
  <div data-slot="slider-track">
    <div data-slot="slider-range"></div>
  </div>
  <div data-slot="slider-thumb"></div>
</div>

<!-- Optional control wrapper -->
<div data-slot="slider" data-default-value="50">
  <div data-slot="slider-control">
    <div data-slot="slider-track">
      <div data-slot="slider-range"></div>
    </div>
    <div data-slot="slider-thumb"></div>
  </div>
</div>

<!-- Range slider (two thumbs) -->
<div data-slot="slider" data-default-value="25,75">
  <div data-slot="slider-track">
    <div data-slot="slider-range"></div>
  </div>
  <div data-slot="slider-thumb"></div>
  <div data-slot="slider-thumb"></div>
</div>

JavaScript

import { create, createSlider } from "@data-slot/slider";

// Auto-discover and bind all [data-slot="slider"] elements
const controllers = create();

// Or target a specific element
const slider = createSlider(element, {
  defaultValue: 50,
  min: 0,
  max: 100,
  step: 1,
  thumbAlignment: "edge",
  onValueChange: (value) => console.log("Changed:", value),
  onValueCommit: (value) => console.log("Committed:", value),
});

// Programmatic control
slider.setValue(75);
console.log(slider.value); // 75

// Cleanup
slider.destroy();

API

Initialization

create(scope?)

Find and bind uninitialized [data-slot="slider"] descendants of scope (defaults to document). Returns SliderController[] for newly bound roots. To initialize the scope element itself, use createSlider.

import { create } from "@data-slot/slider";

const controllers = create();

createSlider(root, options?)

Create a SliderController for one root element. JavaScript options take precedence over the corresponding data attributes. Calling this again for a bound root returns its existing controller; destroy it before rebinding with new options.

import { createSlider } from "@data-slot/slider";

const controller = createSlider(element, {});

Slots

Runtime Slots

  • slider - Root element that manages the value, bounds, orientation, and disabled state.
  • slider-control - Optional interaction wrapper around the track and thumbs. When omitted, the track's parent is used, typically the root.
  • slider-track - Required track used to measure pointer position and lay out the range and thumbs.
  • slider-range - Optional filled portion of the track; its position and size follow the selected value or range.
  • slider-thumb - Required draggable control with slider semantics and keyboard support. Use one for a single value or two for a range; two thumbs enable range mode.

Data Attributes

AttributeDescriptionDefault
data-default-valueInitial value (50 or 25,75 for range)min (single), [min, min] (range)
data-minMinimum value0
data-maxMaximum value100
data-stepStep increment1
data-large-stepLarge step for PageUp/PageDownstep * 10
data-orientationhorizontal or verticalhorizontal
data-thumb-alignmentcenter, edge, or edge-client-onlycenter
data-disabledDisable the slider-

Options

JavaScript options take precedence over root data attributes.

OptionTypeDefaultDescription
defaultValuenumber | [number, number]min (single), [min, min] (range)Initial value; clamped to the bounds and snapped to step. Two thumbs enable range mode.
minnumber0Minimum value
maxnumber100Maximum value
stepnumber1Step increment; non-positive values fall back to 1
largeStepnumberstep * 10Increment for PageUp/PageDown and Shift+Arrow
orientation"horizontal" | "vertical""horizontal"Slider orientation
thumbAlignment"center" | "edge" | "edge-client-only""center"Thumb placement at the track edges
disabledbooleanfalseDisable user interaction and inbound set events
onValueChange(value: number | [number, number]) => voidundefinedCalled for value changes, including programmatic updates; silent on initialization and unchanged values
onValueCommit(value: number | [number, number]) => voidundefinedCalled on pointer release/cancel, blur after a keyboard value change, or a changed slider:set update

Controller

Method/PropertyDescription
setValue(value: number | [number, number])Update the value, including when disabled. Emits change when the value changes, but does not emit commit.
valueCurrent value (readonly number | [number, number])
minResolved minimum (readonly number)
maxResolved maximum (readonly number)
disabledWhether interaction is disabled (readonly boolean)
destroy()Remove listeners and release the root binding

Events

Outbound Events

Listen for these events on the root element.

EventDetailDescription
slider:change{ value: number | [number, number] }Fires during value changes
slider:commit{ value: number | [number, number] }Fires on pointer release/cancel, blur after a keyboard value change, or a changed slider:set update

Inbound Events

Dispatch these events on the root element.

EventDetailDescription
slider:set{ value: number | [number, number] }Set value programmatically
// Listen for changes
root.addEventListener("slider:change", (e) => {
  console.log("Value:", e.detail.value);
});

// Set value from outside
root.dispatchEvent(new CustomEvent("slider:set", {
  detail: { value: 50 }
}));

// Set range value
root.dispatchEvent(new CustomEvent("slider:set", {
  detail: { value: [25, 75] }
}));

Note: Blocked when slider is disabled.

Deprecated Shapes

The following shapes are deprecated and will be removed in v1.0:

// Deprecated: bare number
root.dispatchEvent(new CustomEvent("slider:set", {
  detail: 50
}));

// Deprecated: bare array
root.dispatchEvent(new CustomEvent("slider:set", {
  detail: [25, 75]
}));

Use { value: ... } instead.

Styling

The component sets data attributes and inline styles for CSS hooks:

/* Root state */
[data-slot="slider"][data-orientation="horizontal"] { ... }
[data-slot="slider"][data-orientation="vertical"] { ... }
[data-slot="slider"][data-disabled] { ... }
[data-slot="slider"][data-dragging] { ... }

/* Parts mirror shared state for shadcn/Base-style selectors */
[data-slot="slider-track"][data-orientation="horizontal"] { ... }
[data-slot="slider-track"][data-orientation="vertical"] { ... }
[data-slot="slider-range"][data-orientation="horizontal"] { ... }
[data-slot="slider-range"][data-orientation="vertical"] { ... }
[data-slot="slider-track"][data-disabled] { ... }
[data-slot="slider-range"][data-disabled] { ... }
[data-slot="slider-thumb"][data-orientation="horizontal"] { ... }
[data-slot="slider-thumb"][data-orientation="vertical"] { ... }
[data-slot="slider-thumb"][data-disabled] { ... }

/* Thumb positioning (set automatically) */
[data-slot="slider-thumb"] {
  position: absolute;
  /* --position: X%; inset-inline-start/top or bottom/left are applied inline */
  /* translate is applied inline to center the thumb on the resolved visual position */
}

/* Range thumbs expose their index */
[data-slot="slider-thumb"][data-index="0"] { ... }
[data-slot="slider-thumb"][data-index="1"] { ... }

/* Range positioning (set automatically) */
[data-slot="slider-range"] {
  /* horizontal: relative + inset-inline-start/width */
  /* vertical: absolute + bottom/height */
}

/* Thumb dragging state */
[data-slot="slider-thumb"][data-dragging] { ... }

slider-track, slider-range, and slider-thumb also get Base-style inline layout styles from the controller. The runtime owns the track's position: relative, the range's start/size positioning, and the thumb's absolute position / translate, so authors only need to supply visual styles unless they intentionally want to override that layout behavior.

When thumbAlignment is "edge" or "edge-client-only", the runtime measures the track and thumb size to keep the thumb inside the visible track. In those modes, --position and the range start/size vars represent rendered layout positions rather than raw value percentages.

Thumb Alignment

By default, slider thumbs are centered on the active value. That means the thumb can extend beyond the track when the value is at min or max.

Use thumbAlignment or data-thumb-alignment to change that behavior:

  • "center" - Default. The thumb is centered on the value and may overflow the track edges.
  • "edge" - Insets the thumb so its edge aligns with the track edge at min and max.
  • "edge-client-only" - Accepted for Base UI API parity. In this vanilla package it behaves the same as "edge".
<div data-slot="slider" data-default-value="25" data-thumb-alignment="edge">
  <div data-slot="slider-track">
    <div data-slot="slider-range"></div>
  </div>
  <div data-slot="slider-thumb"></div>
</div>
createSlider(element, {
  defaultValue: 25,
  thumbAlignment: "edge",
});

Keyboard Navigation

KeyAction
ArrowRight / ArrowLeftIncrease / decrease by step in horizontal sliders
ArrowUp / ArrowDownIncrease / decrease by step in vertical sliders
PageUpIncrease by largeStep
PageDownDecrease by largeStep
HomeSet to min
EndSet to max
Shift+ArrowMove by largeStep

Accessibility

Each thumb element receives:

  • role="slider"
  • tabindex="0"
  • aria-valuemin / aria-valuemax / aria-valuenow
  • aria-orientation
  • aria-disabled (when disabled)
  • aria-label (from data-label or auto-generated for range)

slider-track, slider-range, and slider-thumb also mirror the root's data-orientation and data-disabled attrs for styling. slider-control is optional; when omitted, the root acts as the interactive control surface.

License

MIT

版本与发布记录

@data-slot/slider 共发布 151 个版本,首次发布于 2026/02/01;过去 12 个月发布了 151 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
1.1.3latest2026/11/056 天前
1.1.22026/10/1428 天前
1.1.12026/10/051 个月前
1.1.02026/10/021 个月前
1.0.22026/09/271 个月前
1.0.12026/09/261 个月前

关于 @data-slot/slider 的常见问题

@data-slot/slider 是什么?

Headless slider component for vanilla JavaScript. Supports single value and range sliders with full keyboard navigation and ARIA compliance.

如何安装 @data-slot/slider?

在项目目录运行 npm install @data-slot/slider,或使用 pnpm add / yarn add / bun add。

@data-slot/slider 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@data-slot/slider 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@data-slot/slider 可以商用吗?

@data-slot/slider 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@data-slot/slider 的下载量有多少?

根据 npm 官方下载统计,@data-slot/slider 在 2026/10/12 – 2026/11/10 这 30 天内被下载 4,280 次,日均约 143 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@data-slot/slider 还在维护吗?

最新版本 1.1.3 发布于 2026/11/05(6 天前);至今共发布 151 个版本,其中过去 12 个月发布了 151 个;首次发布于 2026/02/01。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。