# Slider

A single-thumb control for picking a number within a range.

## Installation

```tsx
import { Slider } from "@makeplane/propel/components/slider";
```
## Usage

```tsx
import { Slider } from "@makeplane/propel/components/slider";
import * as React from "react";

export default function BasicDemo() {
  const [value, setValue] = React.useState(40);
  return (
    <Slider
      label="Volume"
      size="md"
      value={value}
      onValueChange={(next) => setValue(next as number)}
      min={0}
      max={100}
      step={1}
    />
  );
}
```
## Examples

### Sizes

The `size` axis sets the thumb and hit-area size; the track bar height stays the same.

```tsx
import { Slider } from "@makeplane/propel/components/slider";

export default function SizesDemo() {
  return (
    <div className="flex flex-col gap-6">
      <Slider label="sm" size="sm" defaultValue={40} min={0} max={100} step={1} />
      <Slider label="md" size="md" defaultValue={40} min={0} max={100} step={1} />
      <Slider label="lg" size="lg" defaultValue={40} min={0} max={100} step={1} />
    </div>
  );
}
```

### Formatted value

Pass `format` (an `Intl.NumberFormatOptions`) to control the readout — here a percentage.

```tsx
import { Slider } from "@makeplane/propel/components/slider";
import * as React from "react";

export default function FormattedValueDemo() {
  const [value, setValue] = React.useState(0.6);
  return (
    <Slider
      label="Opacity"
      size="md"
      value={value}
      onValueChange={(next) => setValue(next as number)}
      min={0}
      max={1}
      step={0.01}
      format={{ style: "percent", maximumFractionDigits: 0 }}
    />
  );
}
```

### Edge-aligned thumb

With `thumbAlignment="edge"` the thumb stays fully inside the track at the extremes instead of overhanging it.

```tsx
import { Slider } from "@makeplane/propel/components/slider";
import * as React from "react";

export default function EdgeAlignedThumbDemo() {
  const [value, setValue] = React.useState(25);
  return (
    <Slider
      label="Progress"
      size="md"
      value={value}
      onValueChange={(next) => setValue(next as number)}
      min={0}
      max={100}
      step={1}
      thumbAlignment="edge"
    />
  );
}
```

### In a form

Wrap the slider in a `Field` with a `name` and its value serializes with the surrounding `Form`.

```tsx
import { Button } from "@makeplane/propel/components/button";
import { Field } from "@makeplane/propel/components/field";
import { Form, FormActions, FormBody } from "@makeplane/propel/components/form";
import { Slider } from "@makeplane/propel/components/slider";
import * as React from "react";

export default function InAFormDemo() {
  const [submitted, setSubmitted] = React.useState<{ volume: number } | null>(null);
  return (
    <div className="flex flex-col gap-3">
      <Form<{ volume: number }> onFormSubmit={(values) => setSubmitted(values)}>
        <FormBody layout="single">
          <Field name="volume">
            <Slider label="Volume" size="md" defaultValue={40} min={0} max={100} step={1} />
          </Field>
        </FormBody>
        <FormActions layout="inline">
          <Button stretch="auto" type="submit" variant="primary" size="sm" label="Save" />
        </FormActions>
      </Form>
      <output className="text-body-xs-regular text-secondary">
        {submitted ? `Volume: ${submitted.volume}` : null}
      </output>
    </div>
  );
}
```
## API Reference

### Slider

The ready-made slider: a single-thumb control for picking a number within a range. Drive it with
`value`/`defaultValue` + `onValueChange`, and bound it with `min`/`max`/`step`. Pass `label`
(visible) or `aria-label` to name the thumb, and `format` (an `Intl.NumberFormatOptions`) to
format the readout.

`size` sets the thumb and hit-area size (`sm` / `md` / `lg`). The track bar height and shape are
always the same per the design spec.

Grafts Base UI `Slider` behavior onto the `elements/slider` styled parts (`Slider` root +
`SliderLabel` + `SliderValue` + `SliderControl` + `SliderTrack` + `SliderIndicator` +
`SliderThumb`). For multiple thumbs or fully custom layout, graft the `elements/slider` parts
directly.

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `size` (required) | `"sm" \| "md" \| "lg"` | — | Thumb and control size. `sm` = 12 px thumb, `md` = 16 px, `lg` = 20 px. |
| `aria-label` | `string` | — | Defines a string value that labels the current element. Accessible name for the thumb. Required when there is no visible `label`. @see aria-labelledby. |
| `render` | `ReactElement<unknown, string \| JSXElementConstructor<any>> \| ComponentRenderFn<HTMLProps, SliderRootState>` | — | Allows you to replace the component's HTML element with a different tag, or compose it with another component. Accepts a `ReactElement` or a function that returns the element to render. |
| `label` | `string` | — | Optional visible label rendered above the track (e.g. "Volume"). When omitted, provide an `aria-label` for the thumb so the control is still named for assistive tech. |
