Angle Slider
A component for selecting a value within a circular range.
Examples
Basic
Here's a basic example of the Angle Slider component.
import { AngleSlider } from '@ark-ui/react/angle-slider'
export const Basic = () => {
  return (
    <AngleSlider.Root>
      <AngleSlider.Label>Wind direction</AngleSlider.Label>
      <AngleSlider.Control>
        <AngleSlider.Thumb />
        <AngleSlider.MarkerGroup>
          {[0, 45, 90, 135, 180, 225, 270, 315].map((value, i) => (
            <AngleSlider.Marker key={i} value={value} />
          ))}
        </AngleSlider.MarkerGroup>
      </AngleSlider.Control>
      <AngleSlider.ValueText />
      <AngleSlider.HiddenInput />
    </AngleSlider.Root>
  )
}
import { AngleSlider } from '@ark-ui/solid/angle-slider'
import { For } from 'solid-js'
export const Basic = () => {
  return (
    <AngleSlider.Root>
      <AngleSlider.Label>Angle</AngleSlider.Label>
      <AngleSlider.Control>
        <AngleSlider.Thumb />
        <AngleSlider.MarkerGroup>
          <For each={[0, 45, 90, 135, 180, 225, 270, 315]}>
            {(value) => <AngleSlider.Marker value={value}>{value}°</AngleSlider.Marker>}
          </For>
        </AngleSlider.MarkerGroup>
      </AngleSlider.Control>
      <AngleSlider.ValueText />
      <AngleSlider.HiddenInput />
    </AngleSlider.Root>
  )
}
<script setup lang="ts">
import { AngleSlider } from '@ark-ui/vue/angle-slider'
</script>
<template>
  <AngleSlider.Root>
    <AngleSlider.Label>Wind direction</AngleSlider.Label>
    <AngleSlider.Control>
      <AngleSlider.Thumb />
      <AngleSlider.MarkerGroup>
        <AngleSlider.Marker v-for="(value, i) in [0, 45, 90, 135, 180, 225, 270, 315]" :key="i" :value="value" />
      </AngleSlider.MarkerGroup>
    </AngleSlider.Control>
    <AngleSlider.ValueText />
    <AngleSlider.HiddenInput />
  </AngleSlider.Root>
</template>
<script lang="ts">
  import { AngleSlider } from '@ark-ui/svelte/angle-slider'
</script>
<AngleSlider.Root>
  <AngleSlider.Label>Wind direction</AngleSlider.Label>
  <AngleSlider.Control>
    <AngleSlider.Thumb />
    <AngleSlider.MarkerGroup>
      {#each [0, 45, 90, 135, 180, 225, 270, 315] as value}
        <AngleSlider.Marker {value} />
      {/each}
    </AngleSlider.MarkerGroup>
  </AngleSlider.Control>
  <AngleSlider.ValueText />
  <AngleSlider.HiddenInput />
</AngleSlider.Root>
Controlled
Use the value and onValueChange props to control the value of the Angle Slider.
import { AngleSlider } from '@ark-ui/react/angle-slider'
import { useState } from 'react'
export const Controlled = () => {
  const [angle, setAngle] = useState(180)
  return (
    <AngleSlider.Root value={angle} onValueChange={({ value }) => setAngle(value)}>
      <AngleSlider.Label>Temperature</AngleSlider.Label>
      <AngleSlider.Control>
        <AngleSlider.Thumb />
        <AngleSlider.MarkerGroup>
          {[0, 45, 90, 135, 180, 225, 270, 315].map((value, i) => (
            <AngleSlider.Marker key={i} value={value} />
          ))}
        </AngleSlider.MarkerGroup>
      </AngleSlider.Control>
      <AngleSlider.ValueText>{angle} ºC </AngleSlider.ValueText>
      <AngleSlider.HiddenInput />
    </AngleSlider.Root>
  )
}
import { AngleSlider } from '@ark-ui/solid/angle-slider'
import { For, createSignal } from 'solid-js'
export const Controlled = () => {
  const [value, setValue] = createSignal(0)
  return (
    <AngleSlider.Root value={value()} onValueChange={(e) => setValue(e.value)}>
      <AngleSlider.Label>Angle</AngleSlider.Label>
      <AngleSlider.Control>
        <AngleSlider.Thumb />
        <AngleSlider.MarkerGroup>
          <For each={[0, 45, 90, 135, 180, 225, 270, 315]}>
            {(value) => <AngleSlider.Marker value={value}>{value}°</AngleSlider.Marker>}
          </For>
        </AngleSlider.MarkerGroup>
      </AngleSlider.Control>
      <AngleSlider.ValueText />
      <AngleSlider.HiddenInput />
    </AngleSlider.Root>
  )
}
<script setup lang="ts">
import { AngleSlider } from '@ark-ui/vue/angle-slider'
import { ref } from 'vue'
const angle = ref(180)
</script>
<template>
  <AngleSlider.Root v-model="angle">
    <AngleSlider.Label>Temperature</AngleSlider.Label>
    <AngleSlider.Control>
      <AngleSlider.Thumb />
      <AngleSlider.MarkerGroup>
        <AngleSlider.Marker v-for="(value, i) in [0, 45, 90, 135, 180, 225, 270, 315]" :key="i" :value="value" />
      </AngleSlider.MarkerGroup>
    </AngleSlider.Control>
    <AngleSlider.ValueText>{{ angle }} ºC</AngleSlider.ValueText>
    <AngleSlider.HiddenInput />
  </AngleSlider.Root>
</template>
<script lang="ts">
  import { AngleSlider } from '@ark-ui/svelte/angle-slider'
  let value = $state(180)
</script>
<AngleSlider.Root bind:value>
  <AngleSlider.Label>Temperature</AngleSlider.Label>
  <AngleSlider.Control>
    <AngleSlider.Thumb />
    <AngleSlider.MarkerGroup>
      {#each [0, 45, 90, 135, 180, 225, 270, 315] as value}
        <AngleSlider.Marker {value} />
      {/each}
    </AngleSlider.MarkerGroup>
  </AngleSlider.Control>
  <AngleSlider.ValueText>{value} ºC</AngleSlider.ValueText>
  <AngleSlider.HiddenInput />
</AngleSlider.Root>
Steps
Use the step prop to set the discrete steps of the Angle Slider.
import { AngleSlider } from '@ark-ui/react/angle-slider'
export const Step = () => {
  return (
    <AngleSlider.Root step={15}>
      <AngleSlider.Label>Wind direction (15 step)</AngleSlider.Label>
      <AngleSlider.Control>
        <AngleSlider.Thumb />
        <AngleSlider.MarkerGroup>
          {[0, 45, 90, 135, 180, 225, 270, 315].map((value, i) => (
            <AngleSlider.Marker key={i} value={value} />
          ))}
        </AngleSlider.MarkerGroup>
      </AngleSlider.Control>
      <AngleSlider.ValueText />
      <AngleSlider.HiddenInput />
    </AngleSlider.Root>
  )
}
import { AngleSlider } from '@ark-ui/solid/angle-slider'
import { For } from 'solid-js'
export const Step = () => {
  return (
    <AngleSlider.Root step={45}>
      <AngleSlider.Label>Angle</AngleSlider.Label>
      <AngleSlider.Control>
        <AngleSlider.Thumb />
        <AngleSlider.MarkerGroup>
          <For each={[0, 45, 90, 135, 180, 225, 270, 315]}>{(value) => <AngleSlider.Marker value={value} />}</For>
        </AngleSlider.MarkerGroup>
      </AngleSlider.Control>
      <AngleSlider.ValueText />
      <AngleSlider.HiddenInput />
    </AngleSlider.Root>
  )
}
<script setup lang="ts">
import { AngleSlider } from '@ark-ui/vue/angle-slider'
</script>
<template>
  <AngleSlider.Root :step="45">
    <AngleSlider.Label>Angle</AngleSlider.Label>
    <AngleSlider.Control>
      <AngleSlider.Thumb />
      <AngleSlider.MarkerGroup>
        <AngleSlider.Marker v-for="(value, i) in [0, 45, 90, 135, 180, 225, 270, 315]" :key="i" :value="value" />
      </AngleSlider.MarkerGroup>
    </AngleSlider.Control>
    <AngleSlider.ValueText />
    <AngleSlider.HiddenInput />
  </AngleSlider.Root>
</template>
<script lang="ts">
  import { AngleSlider } from '@ark-ui/svelte/angle-slider'
</script>
<AngleSlider.Root step={15}>
  <AngleSlider.Label>Wind direction (15 step)</AngleSlider.Label>
  <AngleSlider.Control>
    <AngleSlider.Thumb />
    <AngleSlider.MarkerGroup>
      {#each [0, 45, 90, 135, 180, 225, 270, 315] as value}
        <AngleSlider.Marker {value} />
      {/each}
    </AngleSlider.MarkerGroup>
  </AngleSlider.Control>
  <AngleSlider.ValueText />
  <AngleSlider.HiddenInput />
</AngleSlider.Root>
API Reference
Root
| Prop | Default | Type | 
|---|---|---|
| asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior.For more details, read our Composition guide. | |
| defaultValue | 0 | numberThe initial value of the slider. Use when you don't need to control the value of the slider. | 
| disabled | booleanWhether the slider is disabled. | |
| id | stringThe unique identifier of the machine. | |
| ids | Partial<{ root: string; thumb: string; hiddenInput: string; control: string; valueText: string }>The ids of the elements in the machine. Useful for composition. | |
| invalid | booleanWhether the slider is invalid. | |
| name | stringThe name of the slider. Useful for form submission. | |
| onValueChange | (details: ValueChangeDetails) => voidThe callback function for when the value changes. | |
| onValueChangeEnd | (details: ValueChangeDetails) => voidThe callback function for when the value changes ends. | |
| readOnly | booleanWhether the slider is read-only. | |
| step | 1 | numberThe step value for the slider. | 
| value | numberThe value of the slider. | 
| CSS Variable | Description | 
|---|---|
| --value | The current value | 
| --angle | The angle in degrees | 
| Data Attribute | Value | 
|---|---|
| [data-scope] | angle-slider | 
| [data-part] | root | 
| [data-disabled] | Present when disabled | 
| [data-invalid] | Present when invalid | 
| [data-readonly] | Present when read-only | 
Control
| Prop | Default | Type | 
|---|---|---|
| asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior.For more details, read our Composition guide. | 
| Data Attribute | Value | 
|---|---|
| [data-scope] | angle-slider | 
| [data-part] | control | 
| [data-disabled] | Present when disabled | 
| [data-invalid] | Present when invalid | 
| [data-readonly] | Present when read-only | 
HiddenInput
| Prop | Default | Type | 
|---|---|---|
| asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior.For more details, read our Composition guide. | 
Label
| Prop | Default | Type | 
|---|---|---|
| asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior.For more details, read our Composition guide. | 
| Data Attribute | Value | 
|---|---|
| [data-scope] | angle-slider | 
| [data-part] | label | 
| [data-disabled] | Present when disabled | 
| [data-invalid] | Present when invalid | 
| [data-readonly] | Present when read-only | 
MarkerGroup
| Prop | Default | Type | 
|---|---|---|
| asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior.For more details, read our Composition guide. | 
Marker
| Prop | Default | Type | 
|---|---|---|
| value | numberThe value of the marker | |
| asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior.For more details, read our Composition guide. | 
| CSS Variable | Description | 
|---|---|
| --marker-value | The marker value value for the Marker | 
| Data Attribute | Value | 
|---|---|
| [data-scope] | angle-slider | 
| [data-part] | marker | 
| [data-value] | The value of the item | 
| [data-state] | |
| [data-disabled] | Present when disabled | 
RootProvider
| Prop | Default | Type | 
|---|---|---|
| value | UseAngleSliderReturn | |
| asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior.For more details, read our Composition guide. | 
Thumb
| Prop | Default | Type | 
|---|---|---|
| asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior.For more details, read our Composition guide. | 
| Data Attribute | Value | 
|---|---|
| [data-scope] | angle-slider | 
| [data-part] | thumb | 
| [data-disabled] | Present when disabled | 
| [data-invalid] | Present when invalid | 
| [data-readonly] | Present when read-only | 
ValueText
| Prop | Default | Type | 
|---|---|---|
| asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior.For more details, read our Composition guide. |