import React, { useState } from "react"; import styled from "styled-components"; const SliderWrapper = styled.div` display: flex; flex-direction: column; align-items: center; justify-content: center; height: 120px; width: 40px; gap: 8px; `; interface SliderProps { min?: number; max?: number; step?: number; value?: number; onChange?: (value: number) => void; } interface TrackTransientProps { $fillPercent: number; } const Track = styled.input.attrs({ type: "range" }) ` appearance: none; -webkit-appearance: none; writing-mode: vertical-lr; direction: rtl; width: 6px; height: 100%; background: linear-gradient( to top, white ${({ $fillPercent }) => $fillPercent}%, var(--secondary-color) ${({ $fillPercent }) => $fillPercent}% ); border-radius: 0; outline: none; cursor: pointer; transition: background 0.15s ease; &::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 22px; height: 22px; border-radius: 0; background: #ffffff; border: 3px solid var(--secondary-color); box-shadow: 0 0 6px rgba(255, 68, 68, 0.6); cursor: grab; transition: transform 0.1s ease, box-shadow 0.1s ease; &:active { cursor: grabbing; transform: scale(1.2); box-shadow: 0 0 12px rgba(255, 68, 68, 0.9); } } &::-moz-range-thumb { width: 22px; height: 22px; border-radius: 0; background: #ffffff; border: 3px solid #ff4444; box-shadow: 0 0 6px rgba(255, 68, 68, 0.6); cursor: grab; transition: transform 0.1s ease; &:active { cursor: grabbing; transform: scale(1.2); } } &::-moz-range-track { background: transparent; } `; const ValueLabel = styled.span` font-size: 13px; color: white; letter-spacing: 0.05em; `; interface SliderProps { min?: number; max?: number; step?: number; value?: number; onLabelClick?: () => void; onChange?: (value: number) => void; } export function VerticalSlider({ min = 0, max = 100, step = 1, onLabelClick, value: controlledValue, onChange, }: SliderProps) { const [internalValue, setInternalValue] = useState( controlledValue ?? Math.floor((max - min) / 2) ); const value = controlledValue ?? internalValue; const fillPercent = ((value - min) / (max - min)) * 100; const handleChange = (e: React.ChangeEvent) => { const next = Number(e.target.value); setInternalValue(next); onChange?.(next); }; return ( { onLabelClick?.(); }}>{value} ); };