<template>
	<div class="slider" :disabled="disabled">
		<div class="input-range">
			<span
				class="tip"
				:style="{
					'--progress': (value - props.min) / (props.max - props.min),
				}"
				>{{ props.tipFormatter(value) }}</span
			>
			<input
				type="range"
				v-model="value"
				:min="props.min"
				:max="props.max"
				:step="props.step"
				@input="onInput"
				@change="onChange"
				:disabled="disabled"
			/>
		</div>
		<div class="input" v-show="isInput">
			<input
				type="number"
				v-model="value"
				:min="props.min"
				:max="props.max"
				:step="props.step"
				@input="onInput"
				@change="onChange"
				:disabled="disabled"
			/>
		</div>
	</div>
</template>

<script setup lang="ts">
	import { ref, defineProps, defineEmits, watch } from "vue";
	const props = defineProps({
		disabled: {
			type: Boolean,
			default: false,
		},
		value: {
			type: Number,
			default: 0,
		},
		min: {
			type: Number,
			default: 0,
		},
		max: {
			type: Number,
			default: 100,
		},
		step: {
			type: Number,
			default: 1,
		},
		tipFormatter: {
			type: Function,
			default: (v) => v,
		},
		isInput: {
			type: Boolean,
			default: false,
		},
	});
	const emit = defineEmits(["change", "input"]);
	const value = ref(props.value);
	watch(
		() => props.value,
		(v) => (value.value = v)
	);
	const onInput = () => !props.disabled && emit("input", Number(value.value));
	var changeTime: any = null;
	const onChange = () => {
		if (props.disabled) return;
		clearTimeout(changeTime);
		changeTime = setTimeout(() => emit("change", Number(value.value)), 500);
	};
</script>

<style scoped lang="less">
	.slider {
		position: relative;
		display: flex;
		align-items: center;
		--input-thumb-size: 12px;
		width: 150px;
		// &:focus-within,
		&:hover {
			> .input-range > .tip {
				display: block;
			}
		}
		> .input-range {
			position: relative;
			flex: 2;
			> input {
				width: 100%;
				-webkit-appearance: none;
				appearance: none;
				height: 5px;
				border-radius: 5px;
				background: rgba(0, 0, 0, 0.1); /* 更柔和的颜色 */
				outline: none;
				&::-webkit-slider-thumb {
					-webkit-appearance: none;
					appearance: none;
					width: var(--input-thumb-size);
					height: var(--input-thumb-size);
					border-radius: 50%;
					background: #4285f4; /* 蓝色滑块 */
					cursor: pointer;
					transition: all 0.2s;
					box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
				}
				&::-webkit-slider-thumb:hover {
					background: #3b77db;
					transform: scale(1.1);
				}
			}
			> .tip {
				position: absolute;
				font-size: 10px;
				pointer-events: none;
				user-select: none;
				color: #666;
				top: 0;
				left: calc(
					(100% - var(--input-thumb-size)) * var(--progress) +
						var(--input-thumb-size) / 2
				);
				transform: translate(-50%, -100%);
				background-color: rgba(0, 0, 0, 0.7);
				color: white;
				padding: 0.4rem 0.8rem;
				border-radius: 0.4rem;
				font-size: 1.2rem;
				white-space: nowrap;
				pointer-events: none;
				display: none;
				&::after {
					content: "";
					position: absolute;
					top: 97%;
					left: 50%;
					transform: translateX(-50%);
					width: 0;
					height: 0;
					border-left: 5px solid transparent;
					border-right: 5px solid transparent;
					border-top: 5px solid rgba(0, 0, 0, 0.8);
				}
			}
		}
		> .input {
			flex: 1;
			margin-left: 10px;
			> input {
				border-radius: 3px;
				width: 100%;
			}
		}
	}
</style>
