From e7c69ea6f7358e78acad36eca99c96eeeed096ce Mon Sep 17 00:00:00 2001 From: Adam Malczewski Date: Tue, 10 Mar 2026 16:55:36 +0900 Subject: write app plus touchup --- src/components/ResultDisplay.tsx | 48 ++++++++++++++++++++++++ src/components/SizeSelector.tsx | 81 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 129 insertions(+) create mode 100644 src/components/ResultDisplay.tsx create mode 100644 src/components/SizeSelector.tsx (limited to 'src/components') diff --git a/src/components/ResultDisplay.tsx b/src/components/ResultDisplay.tsx new file mode 100644 index 0000000..3f3f81a --- /dev/null +++ b/src/components/ResultDisplay.tsx @@ -0,0 +1,48 @@ +/** + * ResultDisplay.tsx + * + * Shows the computed circumference in several units inside a styled card. + * When inputs are incomplete / invalid the component shows a helpful prompt. + */ + +import type { CircumferenceResult } from "../types"; + +interface ResultDisplayProps { + result: CircumferenceResult | null; +} + +export default function ResultDisplay({ result }: ResultDisplayProps) { + if (!result) { + return ( +
+
+

+ Select or enter both rim and tire sizes to see the circumference. +

+
+
+ ); + } + + /** Helper to render a single stat inside the stats bar. */ + const stat_item = (title: string, value: string | number, desc: string) => ( +
+
{title}
+
{value}
+
{desc}
+
+ ); + + return ( +
+
+

Wheel Circumference

+
+ {stat_item("Millimeters", result.mm, "mm")} + {stat_item("Centimeters", result.cm, "cm")} + {stat_item("Inches", result.inches, "in")} +
+
+
+ ); +} diff --git a/src/components/SizeSelector.tsx b/src/components/SizeSelector.tsx new file mode 100644 index 0000000..cb4baef --- /dev/null +++ b/src/components/SizeSelector.tsx @@ -0,0 +1,81 @@ +/** + * SizeSelector.tsx + * + * A reusable pair of for choosing a rim or tire size. + * + * Behaviour: + * - Selecting a dropdown option fills the text input with its diameter_mm. + * - Typing a number in the text input auto-selects the first matching + * dropdown option, or falls back to "Custom" if no match exists. + * - Choosing "Custom" in the dropdown does nothing to the text input. + */ + +import type { SizeOption } from "../types"; + +/** Sentinel value used as the