diff --git a/memory-bank/activeContext.md b/memory-bank/activeContext.md index 2d4df6b..1170181 100644 --- a/memory-bank/activeContext.md +++ b/memory-bank/activeContext.md @@ -7,6 +7,8 @@ ## Recent Changes - Created `memory-bank/projectBrief.md`. - Created `memory-bank/productContext.md`. +- Implemented unit conversion on toggle in `src/main.ts`. +- Extracted `convertUnits` utility and added tests. ## Current Focus - Completing Memory Bank initialization. @@ -18,3 +20,4 @@ - Using **Vanilla TypeScript** to avoid framework overhead. - Using **Vitest** for unit testing calculation logic. - Target: A single-page application that can be built into a self-contained output. +- **Unit Toggle Behavior**: Switching units now automatically converts existing input values using a factor of 25.4. MM values are rounded to 1 decimal, Inches to 2 decimals. diff --git a/src/calculator.test.ts b/src/calculator.test.ts index 71bb3f9..d62f0da 100644 --- a/src/calculator.test.ts +++ b/src/calculator.test.ts @@ -1,5 +1,22 @@ import { describe, it, expect } from 'vitest'; -import { calculateGridfinity, DEFAULT_SPEC } from './calculator'; +import { calculateGridfinity, DEFAULT_SPEC, convertUnits } from './calculator'; + +describe('Unit Conversion', () => { + it('converts inches to mm correctly', () => { + expect(convertUnits(1, 'in', 'mm')).toBe(25.4); + expect(convertUnits(2, 'in', 'mm')).toBe(50.8); + }); + + it('converts mm to inches correctly', () => { + expect(convertUnits(25.4, 'mm', 'in')).toBe(1); + expect(convertUnits(50.8, 'mm', 'in')).toBe(2); + }); + + it('returns same value if units are same', () => { + expect(convertUnits(42, 'mm', 'mm')).toBe(42); + expect(convertUnits(1, 'in', 'in')).toBe(1); + }); +}); describe('Gridfinity Calculator', () => { it('calculates standard 42mm grids correctly in mm', () => { diff --git a/src/calculator.ts b/src/calculator.ts index f10d1b5..03d848d 100644 --- a/src/calculator.ts +++ b/src/calculator.ts @@ -29,7 +29,14 @@ export interface CalculatorResults { remainingHeight: number; } -const INCH_TO_MM = 25.4; +export const INCH_TO_MM = 25.4; + +export function convertUnits(value: number, from: 'mm' | 'in', to: 'mm' | 'in'): number { + if (from === to) return value; + if (from === 'in' && to === 'mm') return value * INCH_TO_MM; + if (from === 'mm' && to === 'in') return value / INCH_TO_MM; + return value; +} export function calculateGridfinity(inputs: CalculatorInputs): CalculatorResults { const { width, length, height, unit, spec } = inputs; diff --git a/src/main.ts b/src/main.ts index 7a83c78..b01fede 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,4 +1,4 @@ -import { calculateGridfinity, GridfinitySpec } from './calculator'; +import { calculateGridfinity, GridfinitySpec, convertUnits } from './calculator'; // DOM Elements const inputWidth = document.getElementById('input-width') as HTMLInputElement; @@ -69,6 +69,17 @@ function updateResults() { }); unitMmBtn.addEventListener('click', () => { + if (currentUnit === 'mm') return; + + // Convert values + const width = parseFloat(inputWidth.value) || 0; + const length = parseFloat(inputLength.value) || 0; + const height = parseFloat(inputHeight.value) || 0; + + if (width > 0) inputWidth.value = convertUnits(width, 'in', 'mm').toFixed(1); + if (length > 0) inputLength.value = convertUnits(length, 'in', 'mm').toFixed(1); + if (height > 0) inputHeight.value = convertUnits(height, 'in', 'mm').toFixed(1); + currentUnit = 'mm'; unitMmBtn.classList.add('bg-white', 'shadow-sm'); unitMmBtn.classList.remove('text-slate-600'); @@ -78,6 +89,17 @@ unitMmBtn.addEventListener('click', () => { }); unitInBtn.addEventListener('click', () => { + if (currentUnit === 'in') return; + + // Convert values + const width = parseFloat(inputWidth.value) || 0; + const length = parseFloat(inputLength.value) || 0; + const height = parseFloat(inputHeight.value) || 0; + + if (width > 0) inputWidth.value = convertUnits(width, 'mm', 'in').toFixed(2); + if (length > 0) inputLength.value = convertUnits(length, 'mm', 'in').toFixed(2); + if (height > 0) inputHeight.value = convertUnits(height, 'mm', 'in').toFixed(2); + currentUnit = 'in'; unitInBtn.classList.add('bg-white', 'shadow-sm'); unitInBtn.classList.remove('text-slate-600');