# Slider

滑动条组件，支持离散模式、刻度点、刻度标签。

> 文件：`src/hyperOS/IotComponents/slider/Slider.tsx`

## 导入

```ts
import { Slider } from '@hyperOS/IotComponents/slider';
```

## 基础用法

```tsx
import React, { useState } from 'react';
import Slider from '@hyperOS/IotComponents/slider/Slider';

export default function Demo() {
  const [value, setValue] = useState(50);
  return <Slider min={0} max={100} value={value} step={1} onChange={setValue} />;
}
```

## 刻度点与标签

`pattern` 控制是否显示刻度点（小圆点），`showLabel` 控制是否显示刻度数值标签。两者均依赖 `mark` 数组校验通过后才会渲染。

```tsx
<Slider
  min={0} max={100} value={50} step={10}
  mark={[0, 50, 100]}
  pattern
  showLabel
/>
```

### mark 数组校验规则

| 规则 | 说明 |
| --- | --- |
| 头尾固定 | `mark[0]` 必须等于 `min`，`mark[末尾]` 必须等于 `max` |
| 点数限制 | 总点数 2–6 个（含头尾） |
| 间距校验 | 相邻两点差值 ≥ 总跨度的 20% |
| 步长对齐 | 每个点自动对齐到最近的 step 倍数后再做上述校验 |

**任一规则不满足时**，`pattern` 和 `showLabel` 均不渲染，降级为普通 Slider。

### 校验示例

| mark | min | max | step | 结果 |
| --- | --- | --- | --- | --- |
| `[0, 50, 100]` | 0 | 100 | 1 | ✅ 合规，渲染 3 个点 |
| `[0, 100]` | 0 | 100 | 1 | ✅ 合规（最少 2 个点） |
| `[0, 10, 100]` | 0 | 100 | 1 | ❌ 间距 10 < 20，不渲染 |
| `[5, 50, 100]` | 0 | 100 | 1 | ❌ 头部 5 ≠ min 0，不渲染 |
| `[0, 25, 100]` | 0 | 100 | 10 | ✅ 25→snap→30，渲染 `[0, 30, 100]` |
| `[0,20,40,60,80,100]` | 0 | 100 | 1 | ✅ 6 个点，合规 |
| `[0,10,20,30,40,50,100]` | 0 | 100 | 1 | ❌ 7 个点 > 6，不渲染 |

## 离散模式

`discrete={true}` 时，松手后滑块强制吸附到最近的 step 点（或 mark 点）。

```tsx
<Slider min={0} max={100} value={0} step={25} discrete />
```

## Props

| 属性 | 类型 | 默认值 | 说明 |
| --- | --- | --- | --- |
| `min` | `number` | `0` | 最小值 |
| `max` | `number` | `100` | 最大值 |
| `value` | `number` | `0` | 受控值 |
| `step` | `number` | `1` | 步长 |
| `height` | `number` | `28` | 组件高度 |
| `color` | `ColorType` | `'blue'` | 激活轨道颜色 |
| `disabled` | `boolean` | `false` | 禁用态（透明 + 无交互） |
| `active` | `boolean` | `true` | 工作态（灰显 + 无交互） |
| `discrete` | `boolean` | `false` | 离散模式，强制吸附到 step 点 |
| `mark` | `number[]` | `[]` | 刻度点数值数组，须通过校验才生效 |
| `pattern` | `boolean` | `false` | 是否显示刻度点（小圆点），依赖 mark 校验 |
| `showLabel` | `boolean` | `false` | 是否显示刻度数值标签，依赖 mark 校验 |
| `isPercent` | `boolean` | `false` | `showLabel` 时以百分比格式显示 |
| `onChange` | `(value: number) => void` | - | 滑动中回调 |
| `onAfterChange` | `(value: number) => void` | - | 松手后回调 |

## 注意事项

1. `pattern` / `showLabel` 单独开启均有效，两者相互独立。
2. 未传 `mark` 时，`pattern` / `showLabel` 不渲染（校验直接跳过）。
3. `isPercent` 仅影响 `showLabel` 的显示格式，不影响 `mark` 值的语义。
4. 标签宽度固定 28pt，居中对齐，最多显示 2 行。
