增加一个用于拣选数值的滑杆组件。

This commit is contained in:
徐涛 2025-01-06 06:48:33 +08:00
parent 837a01467c
commit b9a37b795c
2 changed files with 81 additions and 0 deletions

View File

@ -0,0 +1,23 @@
@layer components {
.labeled_picker {
width: 100%;
display: flex;
flex-direction: column;
align-items: stretch;
gap: var(--spacing-xs);
.title_row {
width: 100%;
display: flex;
flex-direction: row;
align-items: baseline;
label {
flex: 1;
font-size: var(--font-size-xs);
}
& > span {
text-align: right;
font-size: var(--font-size-xs);
}
}
}
}

View File

@ -0,0 +1,58 @@
import cx from 'clsx';
import { isEqual, isNil } from 'lodash-es';
import { useEffect, useState } from 'react';
import styles from './LabeledPicker.module.css';
type LabeledPickerProps = {
title?: string;
value?: number;
unit?: string;
onChange: (value: number) => void;
min?: number;
max?: number;
step?: number;
};
export function LabeledPicker({
title,
value,
unit,
onChange,
min = 0,
max = 100,
step = 1,
}: LabeledPickerProps) {
const [pickerValue, setPickerValue] = useState(value ?? min);
const handlePickerChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const value = event.target.value as number;
setPickerValue(value);
onChange?.(value);
};
useEffect(() => {
if (!isEqual(value, pickerValue)) {
setPickerValue(value);
}
}, [value]);
return (
<div className={styles.labeled_picker}>
<div className={styles.title_row}>
{!isNil(title) && <label>{title}</label>}
<div className="spacer" />
<span>
{pickerValue} {unit}
</span>
</div>
<input
type="range"
className={cx('picker')}
value={pickerValue}
onChange={handlePickerChange}
min={min}
max={max}
step={step}
/>
</div>
);
}