Enhance slider UX
Make sliders "snappy" to multiples of 10 and add indicators to both ends.
This commit is contained in:
parent
b725498696
commit
615c43f72a
2 changed files with 38 additions and 8 deletions
|
|
@ -183,14 +183,29 @@ const BalancedTernaryGame: React.FC<BalancedTernaryGameProps> = ({ showSocialSha
|
|||
<Card className="p-6">
|
||||
<div className="space-y-4">
|
||||
<Label className="text-lg font-semibold">Target Number Range</Label>
|
||||
<div className="space-y-2">
|
||||
<div className="space-y-4">
|
||||
<div className="flex justify-between text-sm text-muted-foreground">
|
||||
<span>Min: {targetRange[0]}</span>
|
||||
<span>Max: {targetRange[1]}</span>
|
||||
<div className="flex items-center space-x-2">
|
||||
<div className="w-3 h-3 bg-primary rounded-full"></div>
|
||||
<span>Min: {targetRange[0]}</span>
|
||||
</div>
|
||||
<div className="flex items-center space-x-2">
|
||||
<span>Max: {targetRange[1]}</span>
|
||||
<div className="w-3 h-3 bg-primary rounded-full"></div>
|
||||
</div>
|
||||
</div>
|
||||
<Slider
|
||||
value={targetRange}
|
||||
onValueChange={(value) => setTargetRange(value as [number, number])}
|
||||
onValueChange={(value) => {
|
||||
// Snap to multiples of 10 if close enough
|
||||
const snappedValue = value.map(v => {
|
||||
const remainder = Math.abs(v) % 10;
|
||||
if (remainder <= 2) return v - Math.sign(v) * remainder;
|
||||
if (remainder >= 8) return v + Math.sign(v) * (10 - remainder);
|
||||
return v;
|
||||
});
|
||||
setTargetRange(snappedValue as [number, number]);
|
||||
}}
|
||||
min={-3280}
|
||||
max={3280}
|
||||
step={1}
|
||||
|
|
|
|||
|
|
@ -134,14 +134,29 @@ const TernaryNumberGame: React.FC<TernaryNumberGameProps> = ({ showSocialShare =
|
|||
<Card className="p-6">
|
||||
<div className="space-y-4">
|
||||
<Label className="text-lg font-semibold">Target Number Range</Label>
|
||||
<div className="space-y-2">
|
||||
<div className="space-y-4">
|
||||
<div className="flex justify-between text-sm text-muted-foreground">
|
||||
<span>Min: {targetRange[0]}</span>
|
||||
<span>Max: {targetRange[1]}</span>
|
||||
<div className="flex items-center space-x-2">
|
||||
<div className="w-3 h-3 bg-primary rounded-full"></div>
|
||||
<span>Min: {targetRange[0]}</span>
|
||||
</div>
|
||||
<div className="flex items-center space-x-2">
|
||||
<span>Max: {targetRange[1]}</span>
|
||||
<div className="w-3 h-3 bg-primary rounded-full"></div>
|
||||
</div>
|
||||
</div>
|
||||
<Slider
|
||||
value={targetRange}
|
||||
onValueChange={(value) => setTargetRange(value as [number, number])}
|
||||
onValueChange={(value) => {
|
||||
// Snap to multiples of 10 if close enough
|
||||
const snappedValue = value.map(v => {
|
||||
const remainder = v % 10;
|
||||
if (remainder <= 2) return v - remainder;
|
||||
if (remainder >= 8) return v + (10 - remainder);
|
||||
return v;
|
||||
});
|
||||
setTargetRange(snappedValue as [number, number]);
|
||||
}}
|
||||
min={1}
|
||||
max={3280}
|
||||
step={1}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue