import { Slider } from "@chakra-ui/react"
const Demo = () => {
return (
<Slider.Root width="200px" defaultValue={[40]}>
<Slider.Control>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumbs />
</Slider.Control>
</Slider.Root>
)
}
用法
import { Slider } from "@chakra-ui/react"
<Slider.Root>
<Slider.Label />
<Slider.ValueText />
<Slider.Control>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumb>
<Slider.DraggingIndicator />
<Slider.HiddenInput />
</Slider.Thumb>
<Slider.MarkerGroup>
<Slider.Marker />
</Slider.MarkerGroup>
</Slider.Control>
</Slider.Root>
快捷方式
Slider.Thumbs
此组件为每个值渲染 Slider.Thumb
和 Slider.HiddenInput
组件。
以下代码可行
<Slider.Thumb index={0}>
<Slider.HiddenInput />
</Slider.Thumb>
但如果您不需要自定义滑块手柄,这可能会更好
<Slider.Thumbs />
Slider.Marks
此组件为每个值渲染 Slider.MarkerGroup
和 Slider.Marker
组件。
以下代码可行
<Slider.MarkerGroup>
<Slider.Marker value={0} />
<Slider.Marker value={50} />
</Slider.MarkerGroup>
但如果您不需要自定义标记,这可能会更好
<Slider.Marks marks={[0, 50]} />
示例
尺寸
使用 size
属性来改变滑块的尺寸。
import { For, Slider, Stack } from "@chakra-ui/react"
const Demo = () => {
return (
<Stack width="200px" gap="4">
<For each={["sm", "md", "lg"]}>
{(size) => (
<Slider.Root defaultValue={[40]} size={size} key={size}>
<Slider.Label>Slider - {size}</Slider.Label>
<Slider.Control>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumbs />
</Slider.Control>
</Slider.Root>
)}
</For>
</Stack>
)
}
变体
使用 variant
属性来改变滑块的视觉样式。
import { For, Slider, Stack } from "@chakra-ui/react"
const Demo = () => {
return (
<Stack width="200px" gap="4">
<For each={["outline", "solid"]}>
{(variant) => (
<Slider.Root defaultValue={[40]} variant={variant} key={variant}>
<Slider.Label>Slider - {variant}</Slider.Label>
<Slider.Control>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumbs />
</Slider.Control>
</Slider.Root>
)}
</For>
</Stack>
)
}
颜色
使用 colorPalette
属性来改变滑块的颜色。
import { For, Slider, Stack } from "@chakra-ui/react"
const colors = ["gray", "blue", "red", "green", "pink"]
const Demo = () => {
return (
<Stack gap="4" align="flex-start">
<For each={colors}>
{(color) => (
<Slider.Root
key={color}
width="200px"
colorPalette={color}
defaultValue={[40]}
>
<Slider.Control>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumbs />
</Slider.Control>
</Slider.Root>
)}
</For>
</Stack>
)
}
标签
使用 label
属性为滑块添加标签。
import { Slider } from "@chakra-ui/react"
const Demo = () => {
return (
<Slider.Root width="200px" defaultValue={[40]}>
<Slider.Label>Quantity</Slider.Label>
<Slider.Control>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumbs />
</Slider.Control>
</Slider.Root>
)
}
范围滑块
将 value
或 defaultValue
属性设置为数组,以创建范围滑块。
import { Slider } from "@chakra-ui/react"
const Demo = () => {
return (
<Slider.Root width="200px" defaultValue={[30, 60]}>
<Slider.Control>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumbs />
</Slider.Control>
</Slider.Root>
)
}
防止重叠
使用 minStepsBetweenThumbs
属性,以避免滑块手柄具有相同值。
import { Slider } from "@chakra-ui/react"
const Demo = () => {
return (
<Slider.Root maxW="md" defaultValue={[20, 60]} minStepsBetweenThumbs={8}>
<Slider.Control>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumbs />
</Slider.Control>
</Slider.Root>
)
}
自定义
这是一个使用自定义图标和背景来自定义滑块手柄的示例。
"use client"
import { Box, Slider } from "@chakra-ui/react"
import { MdGraphicEq } from "react-icons/md"
const Demo = () => {
return (
<Slider.Root defaultValue={[30]}>
<Slider.Control>
<Slider.Track bg="red.100">
<Slider.Range bg="tomato" />
</Slider.Track>
<Slider.Thumb index={0} boxSize={6} borderColor="tomato" shadow="md">
<Box color="tomato" as={MdGraphicEq} />
</Slider.Thumb>
</Slider.Control>
</Slider.Root>
)
}
值文本
使用 Slider.ValueText
组件来显示滑块的当前值。
import { HStack, Slider } from "@chakra-ui/react"
const Demo = () => {
return (
<Slider.Root maxW="sm" size="sm" defaultValue={[40]}>
<HStack justify="space-between">
<Slider.Label>Volume</Slider.Label>
<Slider.ValueText />
</HStack>
<Slider.Control>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumbs rounded="l1" />
</Slider.Control>
</Slider.Root>
)
}
受控
使用 value
和 onValueChange
属性来控制滑块的值。
"use client"
import { Slider } from "@chakra-ui/react"
import { useState } from "react"
const Demo = () => {
const [value, setValue] = useState([40])
return (
<Slider.Root
maxW="200px"
value={value}
onValueChange={(e) => setValue(e.value)}
>
<Slider.Control>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumbs />
</Slider.Control>
</Slider.Root>
)
}
状态管理
控制滑块的另一种方法是使用 RootProvider
组件和 useSlider
状态管理钩子。
通过这种方式,您可以从滑块外部访问滑块的状态和方法。
当前40
"use client"
import { Code, Slider, Stack, useSlider } from "@chakra-ui/react"
const Demo = () => {
const slider = useSlider({
defaultValue: [40],
thumbAlignment: "center",
})
return (
<Stack align="flex-start">
<Code>current: {slider.value}</Code>
<Slider.RootProvider value={slider} width="200px">
<Slider.Label>Slider</Slider.Label>
<Slider.Control>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumbs />
</Slider.Control>
</Slider.RootProvider>
</Stack>
)
}
Hook 表单
这是一个如何将滑块与 react-hook-form
集成的示例。
"use client"
import { Button, Field, Slider, Stack } from "@chakra-ui/react"
import { zodResolver } from "@hookform/resolvers/zod"
import { Controller, useForm } from "react-hook-form"
import { z } from "zod"
const formSchema = z.object({
value: z.array(
z
.number({ message: "Value is required" })
.min(60, { message: "Value must be greater than 60" }),
),
})
type FormValues = z.infer<typeof formSchema>
const Demo = () => {
const {
control,
handleSubmit,
formState: { errors },
} = useForm<FormValues>({
resolver: zodResolver(formSchema),
defaultValues: { value: [40] },
})
const onSubmit = handleSubmit((data) => console.log(data))
return (
<form onSubmit={onSubmit}>
<Stack align="flex-start" gap="4" maxW="300px">
<Controller
name="value"
control={control}
render={({ field }) => (
<Field.Root invalid={!!errors.value?.length}>
<Field.Label>Slider: {field.value[0]}</Field.Label>
<Slider.Root
width="full"
name={field.name}
value={field.value}
onValueChange={({ value }) => {
field.onChange(value)
}}
onFocusChange={({ focusedIndex }) => {
if (focusedIndex !== -1) return
field.onBlur()
}}
>
<Slider.Control>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumbs />
</Slider.Control>
</Slider.Root>
<Field.ErrorText>{errors.value?.[0]?.message}</Field.ErrorText>
</Field.Root>
)}
/>
<Button size="sm" type="submit">
Submit
</Button>
</Stack>
</form>
)
}
禁用
使用 disabled
属性来禁用滑块。
import { Slider } from "@chakra-ui/react"
const Demo = () => {
return (
<Slider.Root width="200px" disabled defaultValue={[40]}>
<Slider.Control>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumbs />
</Slider.Control>
</Slider.Root>
)
}
改变结束
使用 onValueChangeEnd
属性来监听滑块值改变的结束事件。
onChange: 50
onChangeEnd: 50
"use client"
import { Box, Code, Slider, Stack } from "@chakra-ui/react"
import { useState } from "react"
const initialValue = [50]
const Demo = () => {
const [value, setValue] = useState(initialValue)
const [endValue, setEndValue] = useState(initialValue)
return (
<Box maxW="240px">
<Slider.Root
value={value}
onValueChange={(e) => setValue(e.value)}
onValueChangeEnd={(e) => setEndValue(e.value)}
>
<Slider.Control>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumbs />
</Slider.Control>
</Slider.Root>
<Stack mt="3" gap="1">
<Code>
onChange: <b>{value}</b>
</Code>
<Code>
onChangeEnd: <b>{endValue}</b>
</Code>
</Stack>
</Box>
)
}
步长
使用 step
属性来设置滑块的步长值。
import { Slider } from "@chakra-ui/react"
const Demo = () => {
return (
<Slider.Root width="200px" defaultValue={[40]} step={10}>
<Slider.Control>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumbs />
</Slider.Control>
</Slider.Root>
)
}
手柄对齐
使用 thumbAlignment
和 thumbSize
属性来将滑块手柄对齐到轨道内。默认情况下,手柄对齐到轨道的起始位置。
import { Slider, Stack } from "@chakra-ui/react"
const Demo = () => {
return (
<Stack maxW="200px" gap="4">
<Slider.Root
thumbAlignment="contain"
thumbSize={{ width: 16, height: 16 }}
defaultValue={[40]}
>
<Slider.Label>Slider (contain)</Slider.Label>
<Slider.Control>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumbs />
</Slider.Control>
</Slider.Root>
<Slider.Root thumbAlignment="center" defaultValue={[40]}>
<Slider.Label>Slider (center)</Slider.Label>
<Slider.Control>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumbs />
</Slider.Control>
</Slider.Root>
</Stack>
)
}
标记
使用 marks
属性在滑块上显示标记。
尺寸 =小
尺寸 =中
尺寸 =大
import { For, Slider, Stack, Text, VStack } from "@chakra-ui/react"
const Demo = () => {
return (
<Stack gap="4">
<For each={["sm", "md", "lg"]}>
{(size) => (
<VStack key={size} align="flex-start">
<Slider.Root
key={size}
size={size}
defaultValue={[40]}
width="200px"
>
<Slider.Control>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumbs />
<Slider.Marks marks={[0, 50, 100]} />
</Slider.Control>
</Slider.Root>
<Text>size = {size}</Text>
</VStack>
)}
</For>
</Stack>
)
}
您还可以使用 marks
属性为标记添加标签。
import { Slider } from "@chakra-ui/react"
const marks = [
{ value: 0, label: "0%" },
{ value: 50, label: "50%" },
{ value: 100, label: "100%" },
]
const Demo = () => {
return (
<Slider.Root width="200px" colorPalette="pink" defaultValue={[40]}>
<Slider.Control>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumbs />
<Slider.Marks marks={marks} />
</Slider.Control>
</Slider.Root>
)
}
垂直
使用 orientation
属性来改变滑块的方向。
import { Slider } from "@chakra-ui/react"
const Demo = () => {
return (
<Slider.Root height="200px" orientation="vertical" defaultValue={[40]}>
<Slider.Control>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumbs />
</Slider.Control>
</Slider.Root>
)
}
带标记的垂直滑块
这是一个带标记的垂直滑块示例。
import { Slider } from "@chakra-ui/react"
const marks = [
{ value: 0, label: "0%" },
{ value: 50, label: "50%" },
{ value: 100, label: "100%" },
]
const Demo = () => {
return (
<Slider.Root
height="200px"
orientation="vertical"
colorPalette="pink"
defaultValue={[40]}
>
<Slider.Control>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumbs />
<Slider.Marks marks={marks} />
</Slider.Control>
</Slider.Root>
)
}
拖动指示器
渲染 Slider.DraggingIndicator
组件,以在拖动滑块手柄时显示指示器或工具提示。
专业提示:您可以在 Slider.DraggingIndicator
组件内部渲染 Slider.ValueText
组件,以显示当前值。
import { Slider } from "@chakra-ui/react"
const Demo = () => {
return (
<Slider.Root maxW="200px" defaultValue={[40]}>
<Slider.Control>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumb index={0}>
<Slider.DraggingIndicator
layerStyle="fill.solid"
top="6"
rounded="sm"
px="1.5"
>
<Slider.ValueText />
</Slider.DraggingIndicator>
</Slider.Thumb>
</Slider.Control>
</Slider.Root>
)
}
封闭式组件
如果您更喜欢封闭式的组件组合,请查看下方代码片段。
import { Slider as ChakraSlider, HStack } from "@chakra-ui/react"
import * as React from "react"
export interface SliderProps extends ChakraSlider.RootProps {
marks?: Array<number | { value: number; label: React.ReactNode }>
label?: React.ReactNode
showValue?: boolean
}
export const Slider = React.forwardRef<HTMLDivElement, SliderProps>(
function Slider(props, ref) {
const { label, showValue, marks, ...rest } = props
return (
<ChakraSlider.Root ref={ref} thumbAlignment="center" {...rest}>
{label && !showValue && (
<ChakraSlider.Label>{label}</ChakraSlider.Label>
)}
{label && showValue && (
<HStack justify="space-between">
<ChakraSlider.Label>{label}</ChakraSlider.Label>
<ChakraSlider.ValueText />
</HStack>
)}
<ChakraSlider.Control>
<ChakraSlider.Track>
<ChakraSlider.Range />
</ChakraSlider.Track>
<ChakraSlider.Thumbs />
<ChakraSlider.Marks marks={marks} />
</ChakraSlider.Control>
</ChakraSlider.Root>
)
},
)
如果您想自动将封闭式组件添加到您的项目中,请运行命令
npx @chakra-ui/cli snippet add slider
属性
属性 | 默认值 | 类型 |
---|---|---|
max | '100' | number 滑块的最大值 |
min | '0' | number 滑块的最小值 |
minStepsBetweenThumbs | '0' | number 多个滑块手柄之间允许的最小步长。 |
orientation | 'horizontal' | 'vertical' | 'horizontal' 组件的方向 |
origin | '\'start\'' | 'center' | 'start' 滑块范围的起点 - “start”:当值代表绝对值时很有用 - “center”:当值代表偏移量(相对值)时很有用 |
step | '1' | number 滑块的步长值 |
thumbAlignment | '\'contain\'' | 'center' | 'contain' 滑块手柄相对于轨道的对齐方式 - `center`:手柄将超出滑块轨道的边界。 - `contain`:手柄将包含在轨道的边界内。 |
colorPalette | 'gray' | 'gray' | 'red' | 'orange' | 'yellow' | 'green' | 'teal' | 'blue' | 'cyan' | 'purple' | 'pink' 组件的调色板 |
size | 'md' | 'sm' | 'md' | 'lg' 组件的尺寸 |
variant | 'outline' | 'outline' | 'solid' 组件的变体 |
aria-label | string[] 每个滑块手柄的 aria-label。用于为滑块提供无障碍名称。 | |
aria-labelledby | string[] 标注每个滑块手柄的元素的 `id`。用于为滑块提供无障碍名称。 | |
asChild | ||
defaultValue | number[] 滑块首次渲染时的初始值。当您不需要控制滑块选择器的状态时使用。 | |
disabled | boolean 滑块是否被禁用 | |
form | string 底层输入元素的关联表单。 | |
getAriaValueText | (details: ValueTextDetails) => string 返回滑块手柄可读值的函数 | |
id | string 机器的唯一标识符。 | |
ids | Partial<{ root: string thumb(index: number): string hiddenInput(index: number): string control: string track: string range: string label: string valueText: string marker(index: number): string }> 范围滑块中元素的 ID。用于组合。 | |
invalid | boolean 滑块是否无效 | |
name | string 与每个滑块手柄关联的名称(在表单中使用时) | |
onFocusChange | (details: FocusChangeDetails) => void 当滑块的焦点索引改变时调用的函数 | |
onValueChange | (details: ValueChangeDetails) => void 当滑块的值改变时调用的函数 | |
onValueChangeEnd | (details: ValueChangeDetails) => void 当滑块值改变完成时调用的函数 | |
readOnly | boolean 滑块是否为只读 | |
thumbSize | { width: number; height: number } 滑块手柄的尺寸 | |
value | number[] 范围滑块的值 |