# Comet Dial

> Circular dial you set by angle. A comet trail streaks behind the lit head when it moves fast, and a flick carries the value on.

Press anywhere on the ring and drag around it to set the value. The reading follows on a spring, and a comet trail grows behind the bead with its speed. Flick and let go to carry the value past where you released. Arrow keys, Page Up, Page Down, Home and End also work.

<demo-comet-dial>



</demo-comet-dial>

## Installation

```bash
npx shadcn-vue@latest add "https://nxui.geoql.in/r/comet-dial.json"
```

## Usage

```vue
<script setup lang="ts">
  import { ref } from 'vue';
  import CometDial from '~/components/ui/comet-dial/CometDial.vue';

  const level = ref(62);
</script>

<template>
  <CometDial v-model="level" unit="%" label="Level" :comet-reach="180" />
</template>
```

## Props

<table>
<thead>
  <tr>
    <th>
      Prop
    </th>
    
    <th>
      Type
    </th>
    
    <th>
      Default
    </th>
    
    <th>
      Description
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        model-value
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      —
    </td>
    
    <td>
      Controlled value (<code>
        v-model
      </code>
      
      ). A change from outside springs the reading.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        default-value
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        62
      </code>
    </td>
    
    <td>
      Initial value when uncontrolled.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        min
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0
      </code>
    </td>
    
    <td>
      Lowest value.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        max
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        100
      </code>
    </td>
    
    <td>
      Highest value.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        step
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      Snapping grid, and the keyboard nudge.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        unit
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        '%'
      </code>
    </td>
    
    <td>
      Suffix after the figure. Empty hides it.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        label
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        'Level'
      </code>
    </td>
    
    <td>
      Accessible name of the slider.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        accent
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        '#f5f5f5'
      </code>
    </td>
    
    <td>
      The lit arc, the bead and the comet.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        ink
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        '#fdfdfd'
      </code>
    </td>
    
    <td>
      The track and the readout.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        size
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        250
      </code>
    </td>
    
    <td>
      Diameter in pixels. Everything inside scales with it.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        sweep
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        320
      </code>
    </td>
    
    <td>
      Degrees the arc covers, with the gap centred at the bottom.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        thickness
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        5
      </code>
    </td>
    
    <td>
      Stroke width of the track and the arc. The bead follows it.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        speed
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        25
      </code>
    </td>
    
    <td>
      How quickly the reading arrives, 0 to 100.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        tap-bounce
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.2
      </code>
    </td>
    
    <td>
      Ring-down after a tap. <code>
        0
      </code>
      
       stops dead.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        flick-bounce
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.1
      </code>
    </td>
    
    <td>
      Ring-down after a full-speed flick. A slower release lands between the two.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        momentum
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      How far a flick carries past where you let go. <code>
        0
      </code>
      
       drops it there.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        comet-reach
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        180
      </code>
    </td>
    
    <td>
      Degrees of trail behind the bead at full speed.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        comet-width
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        12
      </code>
    </td>
    
    <td>
      Extra stroke width at the head of the trail at full speed.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        disabled
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        false
      </code>
    </td>
    
    <td>
      Dims the dial and ignores input.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        class
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        ''
      </code>
    </td>
    
    <td>
      Extra classes for the root element.
    </td>
  </tr>
</tbody>
</table>

## Events

<table>
<thead>
  <tr>
    <th>
      Name
    </th>
    
    <th>
      Payload
    </th>
    
    <th>
      Description
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        update:model-value
      </code>
    </td>
    
    <td>
      <code>
        value: number
      </code>
    </td>
    
    <td>
      Fires on every snapped change, including mid-drag.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        change-end
      </code>
    </td>
    
    <td>
      <code>
        value: number, { velocity, bounce }
      </code>
    </td>
    
    <td>
      Fires on release and on a key press.
    </td>
  </tr>
</tbody>
</table>

## Accessibility

- The ring is a focusable `role="slider"` with `aria-valuenow`, `aria-valuemin`, `aria-valuemax` and `aria-valuetext`.
- Arrow keys step by `step` (Shift steps by ten), Page Up and Page Down step by ten, Home and End jump to the ends.
- The centre of the dial is a dead zone, so a press there does nothing.
- With reduced motion, the reading jumps to the value and no comet is drawn.
- Ported from [React Bits](https://reactbits.dev/micro/comet-dial) by David Haz.
