滑块

这是一个真正的 <input type="range">——方向键、Home 和 End,以及正确的播报,全都来自浏览器。被改样式的只有轨道和滑钮。

基础滑块

sliderField({ label: '质量', name: 'quality', value: 70 })

范围与步长

stack({ gap: 'lg' },
  sliderField({ label: '音量', name: 'volume', min: 0, max: 100, value: 40 }),
  sliderField({ label: '列数', name: 'columns', min: 1, max: 6, step: 1, value: 3 }),
  sliderField({ label: '缩放', name: 'scale', min: 0.5, max: 2, step: 0.25, value: 1 }),
)

显示数值

showValue 会在轨道旁放一个 <output>,里面是构建时的那个值;第一次拖动时,input 会自己去取它的处理模块,于是数字就跟着滑钮走。没有什么要导入的——一个悄悄过期的数字比没有数字更糟,所以这件事没留给你。

82
数值越高,文件越大,构建也越慢。
sliderField({
  label: '图片质量',
  name: 'jpeg-quality',
  min: 40,
  max: 100,
  value: 82,
  showValue: true,
  help: '数值越高,文件越大,构建也越慢。',
})

从你自己的代码里设置

滑块是表单控件,本该由读者掌控——但预设、重置按钮,或者从网络取回的数值,仍然得能移动它。给它一个 id,setSlider 就能做到,旁边的 <output> 也跟着走。

import { setSlider } from 'sitelo/ui/client'

setSlider('volume', 50)

或者像各个组件取自己的模块那样去取它,完全不用打包:

button({ onclick: "import('/su/slider.js').then(m=>m.set('volume',50))" }, '一半')

浏览器会按 min 和 max 夹住,并对齐到 step,所以返回的是滑块最终停在哪儿,而不是你递给它什么。随后还会发出 input 和 change,因为监听拖动的预览没有别的办法知道这次并非由它引起的移动。getSlider() 则把值读回来。

试一试

本页加载了运行时,所以下面的按钮真的会移动滑块。

40
stack({ gap: 'md' },
  slider({ id: 'demo-slider', value: 40, showValue: true, 'aria-label': '演示' }),
  stack({ direction: 'row', gap: 'sm', wrap: true },
    button({ size: 'sm', variant: 'outline', onclick: "import('/su/slider.js').then(m=>m.set('demo-slider',0))" }, '最小'),
    button({ size: 'sm', variant: 'outline', onclick: "import('/su/slider.js').then(m=>m.set('demo-slider',50))" }, '一半'),
    button({ size: 'sm', variant: 'outline', onclick: "import('/su/slider.js').then(m=>m.set('demo-slider',100))" }, '最大'),
  ),
)

颜色

stack({ gap: 'lg' },
  slider({ value: 70, color: 'primary', 'aria-label': 'Primary' }),
  slider({ value: 55, color: 'success', 'aria-label': 'Success' }),
  slider({ value: 35, color: 'warning', 'aria-label': 'Warning' }),
  slider({ value: 20, color: 'danger', 'aria-label': 'Danger' }),
)

禁用

sliderField({ label: '已锁定', name: 'locked', value: 50, disabled: true })

不带标签

光秃秃的 slider() 就是控件本身——当没有可见标签指向它时,请给它一个 aria-label。

Aa

Aa

stack({ direction: 'row', gap: 'md', align: 'center' },
  text({ variant: 'small', tone: 'muted' }, 'Aa'),
  slider({ min: 12, max: 24, value: 16, 'aria-label': '文字大小' }),
  text({ tone: 'muted' }, 'Aa'),
)

在表单里

1280
82
card(
  cardBody(
    stack({ gap: 'lg' },
      sliderField({ label: '图片最大宽度', name: 'max-width', min: 640, max: 2560, step: 160, value: 1280, showValue: true }),
      sliderField({ label: '质量', name: 'q', min: 40, max: 100, value: 82, showValue: true }),
    ),
  ),
  cardFooter({ divided: true, style: 'justify-content: flex-end' },
    button({ type: 'submit' }, '保存'),
  ),
)

属性

属性类型默认值说明
minnumber | string0下界。
maxnumber | string100上界。
stepnumber | string—步长。省略则用浏览器默认的 1。
valuenumber | string—初始值。
showValuebooleanfalse加一个 <output>,内容是构建时的值。
color'primary' | 'neutral' | 'success' | 'warning' | 'danger''primary'滑钮的颜色。
namestring—表单字段名;id 由它推导而来。
disabledbooleanfalse禁用该控件。

sliderField() 还额外接受 label、help、error 和 required——见 textField()。