# Knob
> Form-associated rotary knob drawn as a dithered sphere with an arc of lit cells; set it by drag, scroll wheel or arrow keys.
- Element: `<hf-knob>`
- React: `import { HfKnob } from "@/components/lumesec/hf-knob"`
- Collection: Pixel HD (https://elements.lumesec.ai/components/pixel-hd)
- Registry item: https://elements.lumesec.ai/r/hf-knob.json
- Page: https://elements.lumesec.ai/components/pixel-hd/knob



Live preview: https://elements.lumesec.ai/view/hf-knob

```html
<hf-knob name="gain" label="Gain" min="0" max="12" step="0.5" value="7" unit=" dB"></hf-knob>
```

## Playground

Change a prop and the component updates. Props marked live animate to the new value; the others rebuild the element.

## Installation

```bash
npx shadcn@latest add @lumesec/hf-knob
```

First time with the @lumesec registry? Register it once, or install by URL:

```bash
npx shadcn@latest registry add @lumesec=https://elements.lumesec.ai/r/{name}.json
npx shadcn@latest add https://elements.lumesec.ai/r/hf-knob.json
```

## Usage

React:

```tsx
import { HfKnob } from "@/components/lumesec/hf-knob";

export function Example() {
  return (
    <HfKnob name="gain" label="Gain" min={0} max={12} step={0.5} value={7} unit=" dB" />
  );
}
```

HTML:

```html
<script type="module" src="https://elements.lumesec.ai/cdn/hf-knob.js"></script>

<hf-knob name="gain" label="Gain" min="0" max="12" step="0.5" value="7" unit=" dB"></hf-knob>
```

## Behaviour

A dithered sphere with an arc of lit cells. Drag up or down, scroll, or use the arrow keys; the value rolls in below.

## API reference

### Attributes

| Attribute | React prop | Type     | Default | Description                                                                              |
| --------- | ---------- | -------- | ------- | ---------------------------------------------------------------------------------------- |
| `value`   | `value`    | `number` | `50`    | Initial value, clamped to `min`–`max` and snapped to `step`. Read once on connect.       |
| `min`     | `min`      | `number` | `0`     | Lower bound.                                                                             |
| `max`     | `max`      | `number` | `100`   | Upper bound.                                                                             |
| `step`    | `step`     | `number` | `1`     | Step size for drag, wheel and keys. Its decimal places also set the displayed precision. |
| `unit`    | `unit`     | `string` | —       | Text after the displayed value, for example ` dB`.                                       |
| `label`   | `label`    | `string` | `Gain`  | Text under the value; also the slider `aria-label`.                                      |
| `name`    | `name`     | `string` | —       | Form field name.                                                                         |

### Events

Events bubble and cross the shadow boundary unless the description says otherwise.

| Event    | React prop | Detail              | Description                                                   |
| -------- | ---------- | ------------------- | ------------------------------------------------------------- |
| `input`  | `onInput`  | `{ value: number }` | Fires on every value change from drag, wheel or keys.         |
| `change` | `onChange` | `{ value: number }` | Fires on pointer release and on each wheel step or key press. |

### Properties

| Property           | Type     | Description                                                                                             |
| ------------------ | -------- | ------------------------------------------------------------------------------------------------------- |
| `value`            | `number` | Current value. Setting it clamps and snaps without firing events; it is not reflected to the attribute. |
| `min` (read-only)  | `number` | Parsed `min`.                                                                                           |
| `max` (read-only)  | `number` | Parsed `max`.                                                                                           |
| `step` (read-only) | `number` | Parsed `step`.                                                                                          |

## Keyboard

| Keys                  | Action                  |
| --------------------- | ----------------------- |
| ArrowUp / ArrowRight  | Increase by one step.   |
| ArrowDown / ArrowLeft | Decrease by one step.   |
| PageUp / PageDown     | Change by five steps.   |
| Home / End            | Jump to `min` or `max`. |

## Accessibility

* The canvas has `role="slider"`, `tabindex="0"` and `aria-label` from `label`.
* Sets `aria-valuenow`, `aria-valuemin`, `aria-valuemax` and `aria-valuetext` (value with `unit`) on every change.
* The visible value text is `aria-hidden`.
* Pressing on the dial focuses it.
* Submits the current value as a string under `name`. No validation; form reset does not change the value.
* Reduced motion: the indicator and arc jump to the value without the spring and the value text swaps without rolling.

## Theming

The element reads your shadcn theme tokens through its shadow root, so light and dark follow your theme. The accent comes from `--lumesec`. See [Theming](/docs/theming).

This component reads `--foreground`, `--lumesec` and `--muted-foreground`.

To restyle only LumeSec elements, set the matching `--ui-*` overrides: `--ui-accent`, `--ui-fg` and `--ui-muted`.

## Notes

* Dragging sets the value from the pointer angle around the centre over a 270° sweep; it is not a vertical drag.
* The wheel handler calls `preventDefault()`, so scrolling over the knob does not scroll the page.
* The dial is fixed at 200 × 200 px. Attributes are not observed.


