Components · Data Entry
Slider
Drag to set a value across a known range — volume, opacity, thresholds, ranges — rendered through the shared Slider.
Examples
<!-- Paste-and-run: save as .html and open in a browser. No build step, no bundler.
Slider is a COMPOSITE (antd, no framework-free element), so its HTML form is a CDN-React
page — React + antd load from a CDN (esm.sh) and mount on open. It consumes the SAME shared
`sliderTheme` the React/Vue wrappers use, so it renders the DS V3 look (brand track + handle,
gray-30 rail).
No JSX here (JSX needs a compiler) — we use React.createElement via the `h` alias. -->
<div id="root"></div>
<script type="module">
import React from 'https://esm.sh/react@18';
import { createRoot } from 'https://esm.sh/react-dom@18/client';
import { ConfigProvider, Slider } from 'https://esm.sh/antd@6?deps=react@18,react-dom@18';
import { sliderTheme } from 'https://cdn.jsdelivr.net/gh/ahaslides-product/ahaslides-design@master/lib/slider-theme.js';
const h = React.createElement;
const marks = { 0: '0', 50: '50', 100: '100' };
createRoot(document.getElementById('root')).render(
h(ConfigProvider, { theme: sliderTheme },
h('div', { style: { width: 280 } },
h(Slider, { defaultValue: 40 }), // single
h(Slider, { range: true, defaultValue: [20, 70] }), // range · two thumbs
h(Slider, { defaultValue: 50, marks: marks, step: null }), // marks, snap
h('div', { style: { height: 200 } }, h(Slider, { vertical: true, defaultValue: 40 })), // vertical
h(Slider, { defaultValue: 40, disabled: true }) // disabled
)
)
);
</script>
import { ConfigProvider, Slider } from 'antd'; // antd v6
import { sliderTheme } from '@ahaslides-product/design/slider-theme';
const marks = { 0: '0', 50: '50', 100: '100' };
<ConfigProvider theme={sliderTheme}>
<Slider defaultValue={40} onChange={setVolume} /> {/* single */}
<Slider range defaultValue={[20, 70]} onChange={setWindow} /> {/* range · two thumbs */}
<Slider defaultValue={50} marks={marks} step={null} /> {/* marks, snap to marks */}
<div style={{ height: 200 }}><Slider vertical defaultValue={40} /></div> {/* vertical */}
<Slider defaultValue={40} disabled /> {/* disabled */}
</ConfigProvider>
// One shared sliderTheme → the DS V3 look; pair with a value readout when the exact number matters.
<script setup>
import { ref } from 'vue';
import { ConfigProvider, Slider } from 'ant-design-vue'; // ant-design-vue v4
import { sliderTheme } from '@ahaslides-product/design/slider-theme';
const volume = ref(40);
const window = ref([20, 70]);
const snapped = ref(50);
const marks = { 0: '0', 50: '50', 100: '100' };
</script>
<template>
<a-config-provider :theme="sliderTheme">
<a-slider v-model:value="volume" /> <!-- single -->
<a-slider v-model:value="window" range /> <!-- range · two thumbs -->
<a-slider v-model:value="snapped" :marks="marks" :step="null" /> <!-- marks, snap -->
<div style="height: 200px"><a-slider v-model:value="volume" vertical /></div> <!-- vertical -->
<a-slider v-model:value="volume" disabled /> <!-- disabled -->
</a-config-provider>
</template>
<!-- The SAME sliderTheme as React → one DS V3 look across both vendor libraries. -->
// @ahaslides-product/design/slider-theme — declared ONCE, consumed by both tiers.
import { sliderTheme } from '@ahaslides-product/design/slider-theme';
export const sliderTheme = {
token: {
colorPrimary: '#6A1EBB',
borderRadius: 8,
fontFamily: 'var(--aha-font-product, "Plus Jakarta Sans", sans-serif)',
},
components: {
Slider: {
railBg: '#F1F1F1', // gray-30 rest rail
railHoverBg: '#E3E3E3', // gray-40 hover rail
trackBg: '#6A1EBB', // brand track
trackHoverBg: '#5715A0', // purple-80 hover track
handleColor: '#6A1EBB', // brand handle ring
handleActiveColor: '#5715A0',
dotActiveBorderColor: '#6A1EBB',
railSize: 4,
handleSize: 14,
handleSizeHover: 16,
},
},
};
API
| Prop | Type | Default | Notes |
|---|---|---|---|
value | number | [number, number] | — | Position(s); a pair renders a range slider |
min | number | 0 | Range floor |
max | number | 100 | Range ceiling |
step | number | null | 1 | Increment; null with marks to snap to marks only |
marks | { [value]: label } | — | Labelled tick positions |
range | boolean | false | Two thumbs — select a [low, high] span |
vertical | boolean | false | Orient the rail vertically |
disabled | boolean | false | Non-interactive, dimmed track + handle |
onChange | (value) => void | — | Fires with the new value(s) |
Install
# .npmrc — once: point the @ahaslides-product scope at GitHub Packages
@ahaslides-product:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=${GITHUB_TOKEN} # a GitHub token with read:packages
npm i @ahaslides-product/design
import '@ahaslides-product/design/tokens.css'; // once, at the app root
import '@ahaslides-product/design/slider-theme'; // registers <slider>
Agent feed for this component (absolute, fetchable anywhere): slider.agent.json · slider.md · slider.llms.txt
When to use
When to use
- Slider — an approximate value across a continuous range where feel beats an exact number
- InputNumber — the exact number matters — a precise limit or count
- Slider range — a span with a low and high bound — a price or time window
Pair a slider with a live value readout (or an InputNumber) when the exact number matters. Use marks and step to snap to meaningful positions rather than an arbitrary continuum.
Surfaces
editor dashboard settings
Spec
Rail 4px · #F1F1F1 (gray-30) · Track brand #6A1EBB · Handle 14px · brand ring · Hover rail #E3E3E3 (gray-40) · Range two thumbs when value is a [min,max] pair