<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Kole UI · Slider (H5)</title>
<link rel="stylesheet" href="../.design_library/kole-ui/colors_and_type.css">
<link rel="stylesheet" href="./Slider.css">
<style>
  .demo { padding: 24px; background: var(--kole-color-page-bg); font-family: var(--font-family); }
  h1 { font-size: 20px; margin: 0 0 4px; color: var(--kole-color-text-title); }
  .sub { color: var(--kole-color-text-secondary); margin: 0 0 24px; font-size: 12px; }
  .demo-block { background: var(--kole-color-card-bg); border-radius: 8px; padding: 20px 24px; margin-bottom: 20px; }
  .demo-block > .hint { color: var(--kole-color-text-secondary); font-size: 12px; margin: 0 0 12px; }
  .slider-row { display: flex; align-items: center; gap: 12px; margin-bottom: 16px; }
  .slider-row .lab { width: 72px; font-size: 13px; color: var(--kole-color-text-body); }
</style>
</head>
<body>
<div class="demo">
  <h1>Kole UI · Slider 组件（纯 H5）</h1>
  <p class="sub">对齐 SliderInput 规范：单/双滑块、刻度、输入框联动</p>

  <div class="demo-block">
    <p class="hint">单滑块 + 数值联动</p>
    <div class="slider-row">
      <span class="lab">音量</span>
      <div class="kole-slider" role="slider" tabindex="0" aria-valuemin="0" aria-valuemax="100" data-slider data-min="0" data-max="100" data-value="30" data-input></div>
    </div>
  </div>

  <div class="demo-block">
    <p class="hint">带刻度</p>
    <div class="kole-slider" role="slider" tabindex="0" aria-valuemin="0" aria-valuemax="100" data-slider data-min="0" data-max="100" data-step="10" data-value="50" data-ticks></div>
  </div>

  <div class="demo-block">
    <p class="hint">双滑块范围</p>
    <div class="kole-slider" role="slider" tabindex="0" aria-valuemin="0" aria-valuemax="100" data-slider data-range data-min="0" data-max="100" data-value="20,60"></div>
  </div>

  <div class="demo-block">
    <p class="hint">禁用</p>
    <div class="kole-slider is-disabled" role="slider" tabindex="0" aria-valuemin="0" aria-valuemax="100" data-slider data-min="0" data-max="100" data-value="40"></div>
  </div>
</div>

<script>
function initSlider(root) {
  const min = +root.dataset.min || 0, max = +root.dataset.max || 100, step = +root.dataset.step || 1;
  const range = root.hasAttribute('data-range');
  const showTicks = root.hasAttribute('data-ticks');
  const showInput = root.hasAttribute('data-input');
  let value = range
    ? root.dataset.value.split(',').map(Number)
    : (+root.dataset.value || 0);

  const track = document.createElement('div');
  track.className = 'kole-slider-track';
  track.innerHTML = '<div class="kole-slider-rail" role="slider" tabindex="0" aria-valuemin="0" aria-valuemax="100"></div><div class="kole-slider-fill" aria-valuemin="0" aria-valuemax="100"></div><div class="kole-slider-ticks" role="slider" tabindex="0" aria-valuemin="0" aria-valuemax="100"></div>';
  if (range) {
    track.insertAdjacentHTML('beforeend', '<div class="kole-slider-handle" role="slider" tabindex="0" aria-valuemin="0" aria-valuemax="100" data-i="0"></div><div class="kole-slider-handle" role="slider" tabindex="0" aria-valuemin="0" aria-valuemax="100" data-i="1"></div>');
  } else {
    track.insertAdjacentHTML('beforeend', '<div class="kole-slider-handle" role="slider" tabindex="0" aria-valuemin="0" aria-valuemax="100" data-i="0"></div>');
  }
  root.appendChild(track);

  const valueWrap = document.createElement('div');
  valueWrap.className = 'kole-slider-value';
  if (showInput) {
    if (range) {
      valueWrap.innerHTML = '<input type="number"><span>—</span><input type="number">';
    } else {
      valueWrap.innerHTML = '<input type="number">';
    }
    root.appendChild(valueWrap);
    valueWrap.querySelectorAll('input').forEach(inp => {
      inp.addEventListener('change', () => {
        if (range) {
          const a = +valueWrap.querySelectorAll('input')[0].value;
          const b = +valueWrap.querySelectorAll('input')[1].value;
          value = [Math.min(a, b), Math.max(a, b)];
        } else {
          value = +inp.value;
        }
        paint();
      });
    });
  }

  const rail = track.querySelector('.kole-slider-rail');
  const fill = track.querySelector('.kole-slider-fill');
  const ticks = track.querySelector('.kole-slider-ticks');
  const handles = [...track.querySelectorAll('.kole-slider-handle')];

  if (showTicks) {
    const n = Math.floor((max - min) / step);
    for (let i = 0; i <= n; i++) {
      const v = min + i * step;
      const t = document.createElement('div');
      t.className = 'kole-slider-tick';
      t.style.left = ((v - min) / (max - min) * 100) + '%';
      ticks.appendChild(t);
    }
  }

  function clamp(v) { v = Math.round((v - min) / step) * step + min; return Math.max(min, Math.min(max, v)); }
  function pct(v) { return (v - min) / (max - min) * 100; }
  function fromClientX(x) {
    const rect = track.getBoundingClientRect();
    return clamp(min + (x - rect.left) / rect.width * (max - min));
  }

  function paint() {
    if (range) {
      const [lo, hi] = value;
      fill.style.left = pct(lo) + '%';
      fill.style.width = (pct(hi) - pct(lo)) + '%';
      handles[0].style.left = pct(lo) + '%';
      handles[1].style.left = pct(hi) + '%';
      if (showInput) {
        valueWrap.querySelectorAll('input')[0].value = lo;
        valueWrap.querySelectorAll('input')[1].value = hi;
      }
    } else {
      fill.style.left = '0%';
      fill.style.width = pct(value) + '%';
      handles[0].style.left = pct(value) + '%';
      if (showInput) valueWrap.querySelector('input').value = value;
    }
  }

  function startDrag(i, e) {
    e.preventDefault();
    const move = (ev) => {
      const x = (ev.touches ? ev.touches[0].clientX : ev.clientX);
      const nv = fromClientX(x);
      if (range) {
        value[i] = nv;
        value.sort((a, b) => a - b); // 保持顺序
      } else {
        value = nv;
      }
      paint();
    };
    const up = () => {
      document.removeEventListener('pointermove', move);
      document.removeEventListener('pointerup', up);
    };
    document.addEventListener('pointermove', move);
    document.addEventListener('pointerup', up);
  }

  handles.forEach((h, i) => {
    h.addEventListener('pointerdown', (e) => startDrag(i, e));
  });

  // 点击轨道定位最近的手柄
  track.addEventListener('pointerdown', (e) => {
    if (e.target.classList.contains('kole-slider-handle')) return;
    const nv = fromClientX(e.clientX);
    if (range) {
      const i = Math.abs(nv - value[0]) <= Math.abs(nv - value[1]) ? 0 : 1;
      value[i] = nv; value.sort((a, b) => a - b);
    } else {
      value = nv;
    }
    paint();
  });

  paint();
}
document.querySelectorAll('[data-slider]').forEach(initSlider);
</script>
</body>
</html>
