Skip to content
Back to skills

Lynx Ui Slider

ASecurity

`lynx-ui-slider` is a primitives-first slider package for ReactLynx. It provides composable building blocks (`SliderRoot`, `SliderTrack`, `SliderIndicator`, `SliderThumb`) for single-value and two-thumb range selection.

  • 119 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added June 5, 2026
developmentreactnodeapi

Works with

  • api

Security analysis

A100/100

Pro scans all 20 files and shows the line behind each finding

Scanned September 21, 2026

npx -y skills add lynx-family/lynx-ui --skill lynx-ui-slider --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Lynx Ui Slider?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Lynx Ui Slider
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/lynx-family-lynx-ui-slider/badge)](https://www.skillsdirectory.com/skills/lynx-family-lynx-ui-slider)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
# lynx-ui-slider SKILL

`lynx-ui-slider` is a primitives-first slider package for ReactLynx. It provides composable building blocks (`SliderRoot`, `SliderTrack`, `SliderIndicator`, `SliderThumb`) for single-value and two-thumb range selection.

## 1. Core Capabilities

- **Primitives Composition**: Build slider UI with `SliderRoot` + `SliderTrack` + `SliderIndicator` + `SliderThumb`.
- **Range Selection**: Pass a `[lower, upper]` tuple and render thumbs with `index={0}` and `index={1}`.
- **Shared Base Props**: All primitives inherit `className` and `style` from `ComponentBasicProps`.
- **Controlled & Uncontrolled Modes**: Use `value` + `onValueChange` for controlled mode, or `defaultValue` for uncontrolled mode, with either a number or range tuple.
- **Imperative API** (uncontrolled only): Access `updateValue` and `getValue` through `SliderRef<Value>`. Use its default `number` shape for a single value or `SliderRef<SliderRangeValue>` for a range. Throws in controlled mode.
- **RTL Support**: Set `enableRTL` to make the indicator and thumb resolve right-to-left.
- **Stepping**: Set `step` to snap values to discrete increments.
- **Disabled Mode**: Set `disabled` to prevent dragging while still displaying the current value.
- **Interaction Callbacks**: `onDragging(value)` when dragging state changes, `onValueChange(value, source)` for slider-driven updates, `onValueCommit(value)` at drag end.
- **Ordered Range Dragging**: Lower and upper thumbs may meet but cannot cross during a drag.
- **Headless Styling**: Supports styling via `className` and `style` props on every primitive.

## 2. AI Coding Guide

### Minimal Usable Example (Uncontrolled)

```tsx
import {
  SliderRoot,
  SliderTrack,
  SliderIndicator,
  SliderThumb,
} from '@lynx-js/lynx-ui'

function BasicSlider() {
  return (
    <SliderRoot
      defaultValue={0.3}
      onValueCommit={(value) => console.log(value)}
    >
      <SliderTrack className='track'>
        <SliderIndicator className='indicator' />
        <SliderThumb className='thumb'>
          <view />
        </SliderThumb>
      </SliderTrack>
    </SliderRoot>
  )
}
```

### Controlled Mode Example

```tsx
import { useState } from '@lynx-js/react'
import {
  SliderRoot,
  SliderTrack,
  SliderIndicator,
  SliderThumb,
} from '@lynx-js/lynx-ui'

function ControlledSlider() {
  const [value, setValue] = useState(0.5)

  return (
    <SliderRoot
      value={value}
      onValueChange={(v) => setValue(v)}
    >
      <SliderTrack className='track'>
        <SliderIndicator className='indicator' />
        <SliderThumb className='thumb'>
          <view />
        </SliderThumb>
      </SliderTrack>
    </SliderRoot>
  )
}
```

### Controlled Range Example

```tsx
import { useState } from '@lynx-js/react'
import {
  SliderIndicator,
  SliderRoot,
  SliderThumb,
  SliderTrack,
} from '@lynx-js/lynx-ui'
import type { SliderRangeValue } from '@lynx-js/lynx-ui'

function ControlledRangeSlider() {
  const [range, setRange] = useState<SliderRangeValue>([0.2, 0.8])

  return (
    <SliderRoot value={range} onValueChange={setRange}>
      <SliderTrack className='track'>
        <SliderIndicator className='indicator' />
        <SliderThumb index={0} className='thumb'>
          <view />
        </SliderThumb>
        <SliderThumb index={1} className='thumb'>
          <view />
        </SliderThumb>
      </SliderTrack>
    </SliderRoot>
  )
}
```

Use `index={0}` only for the lower thumb and `index={1}` only for the upper
thumb. `SliderIndicator` automatically spans between the two values. Input
tuples are sorted, clamped to `[0, 1]`, and snapped to `step`; an active thumb
is constrained by the other thumb and cannot cross it.

### RTL Example

```tsx
<SliderRoot enableRTL defaultValue={0.4}>
  <SliderTrack className='track'>
    <SliderIndicator className='indicator' />
    <SliderThumb className='thumb'>
      <view />
    </SliderThumb>
  </SliderTrack>
</SliderRoot>
```

### Recommended Prompt Formula

> **State mode** + **Visual structure** + **Interaction callbacks** + **Styling hooks**

**Example Prompts:**

- "Create a controlled slider with custom thumb UI and `onValueCommit` callback."
- "Build a controlled price-range slider with indexed lower and upper thumbs."
- "Build a headless slider with `step={0.1}` and custom class names for each primitive."
- "Add an RTL slider with `enableRTL` and optional RTL container styling."

## 3. Props Reference

### SliderRootProps<Value>

`SliderRootProps`, `SliderTrackProps`, `SliderIndicatorProps`, and `SliderThumbProps` all inherit `className` and `style` from `ComponentBasicProps`.

`Value` is either `number` or `SliderRangeValue`. It defaults to `number` for existing single-value usage and is inferred automatically from `value` or `defaultValue`.

| Prop            | Type                             | Default | Description                                                                           |
| --------------- | -------------------------------- | ------- | ------------------------------------------------------------------------------------- |
| `value`         | `Value`                          | —       | Controlled value. Do not use with `defaultValue`.                                     |
| `defaultValue`  | `Value`                          | `0`     | Initial uncontrolled value. Range usage must provide a tuple here or through `value`. |
| `step`          | `number`                         | —       | Snap interval in `[0, 1]`.                                                            |
| `disabled`      | `boolean`                        | `false` | Prevent interaction while keeping the slider value visible.                           |
| `enableRTL`     | `boolean`                        | `false` | Reverse slider direction (right-to-left).                                              |
| `onDragging`    | `(value: Value) => void`         | —       | Fires when dragging starts and when dragging ends.                                    |
| `onValueChange` | `(value: Value, source) => void` | —       | Fires after slider-driven updates. Source is `'drag'` or `'external'`.                 |
| `onValueCommit` | `(value: Value) => void`         | —       | Fires at drag end with the final value.                                               |

For explicit annotations, use `SliderRootProps` for a single value and `SliderRootProps<SliderRangeValue>` for a range. Both shapes use the same component and callbacks.

### SliderRef<Value> (uncontrolled only)

| Method        | Signature                          | Description                                        |
| ------------- | ---------------------------------- | -------------------------------------------------- |
| `updateValue` | `(value: Value, options?) => void` | Set value imperatively. Throws in controlled mode. |
| `getValue`    | `() => Value`                      | Read current value. Throws in controlled mode.     |

Use `SliderRef` for a single value and `SliderRef<SliderRangeValue>` for a range.

### SliderThumbProps in range mode

Single-value sliders use the default `index={0}`. For a range, set `index={0}` on the lower thumb and `index={1}` on the upper thumb.

### SliderUIVariants

Slider primitives receive `ui-disabled` when disabled. During interaction,
the root, track, and indicator receive `ui-active`; only the thumb being moved
receives `ui-active` in range mode.

## 4. FAQ

**Q: Should I use controlled or uncontrolled mode?**

A: Use controlled (`value` + `onValueChange`) when you need to sync slider state with external state. Use uncontrolled (`defaultValue`) for simpler cases where internal state suffices.

**Q: What is the difference between `onDragging`, `onValueChange`, and `onValueCommit`?**

A: `onDragging` fires when dragging starts and when dragging ends. `onValueChange` fires after slider-driven value updates during drag and imperative `updateValue` calls. `onValueCommit` fires once at drag end — useful for persisting the final value.

**Q: How do I prevent user interaction while still showing the value?**

A: Set `disabled` on `SliderRoot`. The slider will display the current value but will not respond to touch or pointer events.

**Q: What happens if I call `updateValue` / `getValue` in controlled mode?**

A: They will throw an error. In controlled mode, update external state through `onValueChange` so the `value` prop stays in sync with the rendered value.

**Q: Can I set value outside `[0, 1]`?**

A: Input values are clamped to `[0, 1]` internally.

**Q: How do I create a two-thumb range slider?**

A: Pass a `[lower, upper]` tuple to `value` or `defaultValue`, then render two `SliderThumb` primitives with `index={0}` and `index={1}`. The indicator fills the selected interval.

**Q: Can the lower and upper thumbs cross?**

A: No. A dragged thumb is clamped to the other value. The two thumbs may meet,
but their lower/upper identities remain stable: the active thumb does not swap
with or push the other thumb. This non-crossing policy is the stable default.

**Q: How do I enable RTL?**

A: Pass `enableRTL` to `SliderRoot`. Add `direction: rtl` only if you also want the surrounding container layout or text flow to follow RTL.

**Q: Which primitive should own the fill styling?**

A: `SliderIndicator` is the pure visual fill layer. Keep `SliderThumb` as a sibling inside `SliderTrack`, and style the thumb content independently from the filled portion.

## 5. Sub Components

- **`SliderRoot`**: Owns measurement, drag behavior, value management, and context provider.
- **`SliderTrack`**: Base rail plus the measurement/layout coordinate space for its children.
- **`SliderIndicator`**: Foreground visual indicator from the origin to a single value, or between both range values. Supports RTL.
- **`SliderThumb`**: Visual thumb node positioned inside `SliderTrack`; use `index` to identify both range endpoints.

Files in this skill

  • CHANGELOG.md831 B
  • LICENSE11.1 KB
  • README.md2.4 KB
  • README_zh.md1014 B
  • SKILL.md6.9 KB
  • docs/APIReference.mdx12.8 KB
  • docs/README.mdx259 B
  • docs/README.zh.mdx266 B
  • package.json1.1 KB
  • rslib.config.ts338 B
  • src/SliderIndicator/index.tsx894 B
  • src/SliderRoot/index.tsx8.6 KB
  • src/SliderThumb/index.tsx924 B
  • src/SliderTrack/index.tsx901 B
  • src/context/index.tsx957 B
  • src/index.tsx556 B
  • src/types/index.docs.ts5.5 KB
  • src/types/index.ts225 B
  • src/utils/index.ts1.1 KB
  • tsconfig.docs.json122 B

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.