From a9dcb21c20212e341f5a430d4ddbedb74eb02d85 Mon Sep 17 00:00:00 2001 From: Landon & Emma <80786423+LandonAndEmma@users.noreply.github.com> Date: Wed, 8 Apr 2026 10:59:44 -0400 Subject: [PATCH] Feat: Add Better Sliders Fix #19 --- src/components/mii/instructions.tsx | 22 ++-- src/components/mii/voice-viewer.tsx | 53 ++++---- .../mii-editor/enhanced-slider.tsx | 123 ++++++++++++++++++ .../submit-form/mii-editor/tabs/misc.tsx | 71 ++++------ 4 files changed, 183 insertions(+), 86 deletions(-) create mode 100644 src/components/submit-form/mii-editor/enhanced-slider.tsx diff --git a/src/components/mii/instructions.tsx b/src/components/mii/instructions.tsx index 2e13647..a1b9bda 100644 --- a/src/components/mii/instructions.tsx +++ b/src/components/mii/instructions.tsx @@ -200,24 +200,18 @@ export default function MiiInstructions({ instructions }: Props) { {height && (
- -
- -
-
+ Height + + {height === 64 ? "0" : height > 64 ? `+${height - 64}` : `${height - 64}`} +
)} {weight && (
- -
- -
-
+ Weight + + {weight === 64 ? "0" : weight > 64 ? `+${weight - 64}` : `${weight - 64}`} +
)} {birthday && ( diff --git a/src/components/mii/voice-viewer.tsx b/src/components/mii/voice-viewer.tsx index d809588..d51cb99 100644 --- a/src/components/mii/voice-viewer.tsx +++ b/src/components/mii/voice-viewer.tsx @@ -1,48 +1,45 @@ "use client"; - import { SwitchMiiInstructions } from "@/types"; -import { ChangeEvent } from "react"; +import EnhancedSlider from "@/components/submit-form/mii-editor/enhanced-slider"; interface Props { data: SwitchMiiInstructions["voice"]; - onChange?: (e: ChangeEvent, label: string) => void; + onChange?: (value: number, label: string) => void; onClickTone?: (i: number) => void; } -const VOICE_SETTINGS: string[] = ["Speed", "Pitch", "Depth", "Delivery"]; +const VOICE_SETTINGS = ["Speed", "Pitch", "Depth", "Delivery"]; export default function VoiceViewer({ data, onChange, onClickTone }: Props) { return ( -
- {VOICE_SETTINGS.map((label) => ( -
- -
- { - if (onChange) onChange(e, label.toLowerCase()); - }} - /> -
+
+ {VOICE_SETTINGS.map((label) => { + const value = data[label.toLowerCase() as keyof typeof data] ?? 25; + return onChange ? ( + onChange?.(v, label.toLowerCase())} + min={0} + max={50} + mid={25} + /> + ) : ( +
+ {label} + + {value === 25 ? "0" : value > 25 ? `+${value - 25}` : `${value - 25}`} +
-
- ))} + ); + })}
-
+
{Array.from({ length: 6 }).map((_, i) => ( + +
+ {/* Tick mark at center */} +
+ + handleChange(Number(e.target.value))} + className="w-full h-2 bg-orange-200 rounded-lg appearance-none cursor-pointer slider-thumb" + style={{ + background: `linear-gradient(to right, #fb923c 0%, #fb923c ${((internalValue - min) / (max - min)) * 100}%, #fed7aa ${((internalValue - min) / (max - min)) * 100}%, #fed7aa 100%)` + }} + /> +
+ + +
+ + +
+ ); +} diff --git a/src/components/submit-form/mii-editor/tabs/misc.tsx b/src/components/submit-form/mii-editor/tabs/misc.tsx index 2cfaf1d..31aece1 100644 --- a/src/components/submit-form/mii-editor/tabs/misc.tsx +++ b/src/components/submit-form/mii-editor/tabs/misc.tsx @@ -1,17 +1,16 @@ import { useState } from "react"; import { MiiGender } from "@prisma/client"; - import DatingPreferencesViewer from "@/components/mii/dating-preferences"; import VoiceViewer from "@/components/mii/voice-viewer"; import PersonalityViewer from "@/components/mii/personality-viewer"; - +import EnhancedSlider from "@/components/submit-form/mii-editor/enhanced-slider"; import { SwitchMiiInstructions } from "@/types"; interface Props { instructions: React.RefObject; } -export default function HeadTab({ instructions }: Props) { +export default function MiscTab({ instructions }: Props) { const [height, setHeight] = useState(instructions.current.height ?? 64); const [weight, setWeight] = useState(instructions.current.weight ?? 64); const [datingPreferences, setDatingPreferences] = useState(instructions.current.datingPreferences ?? []); @@ -50,47 +49,31 @@ export default function HeadTab({ instructions }: Props) {
- -
- { - setHeight(e.target.valueAsNumber); - instructions.current.height = e.target.valueAsNumber; - }} - /> -
-
+ { + setHeight(v); + instructions.current.height = v; + }} + min={0} + max={128} + mid={64} + />
- -
- { - setWeight(e.target.valueAsNumber); - instructions.current.weight = e.target.valueAsNumber; - }} - /> -
-
+ { + setWeight(v); + instructions.current.weight = v; + }} + min={0} + max={128} + mid={64} + />
@@ -122,9 +105,9 @@ export default function HeadTab({ instructions }: Props) { { - setVoice((p) => ({ ...p, [label]: e.target.valueAsNumber })); - instructions.current.voice[label as keyof typeof voice] = e.target.valueAsNumber; + onChange={(v, label) => { + setVoice((p) => ({ ...p, [label]: v })); + instructions.current.voice[label as keyof typeof voice] = v; }} onClickTone={(i) => { setVoice((p) => ({ ...p, tone: i }));