Units correctness: exact imperial entry, garden grid at dimension scale (#47) (#60)
Build image / build-and-push (push) Successful in 6s

Co-authored-by: Steve Dudenhoeffer <[email protected]>
This commit was merged in pull request #60.
This commit is contained in:
2026-07-21 04:50:49 +00:00
committed by steve
parent 1716362981
commit 8a12069118
7 changed files with 204 additions and 57 deletions
+21 -7
View File
@@ -12,19 +12,32 @@ const INCHES_PER_FOOT = 12
export const MIN_DIMENSION_CM = 1
export const MAX_DIMENSION_CM = 10_000
// Below this, a garden-scale grid is fine enough to be worth questioning — it
// usually means someone reached for plant spacing, which belongs to the bed, not
// the garden. Soft: the form hints, it doesn't refuse.
export const MIN_GARDEN_GRID_CM = 10
/** Whether a centimeter dimension is within the server's accepted range. */
export function isValidDimensionCm(cm: number): boolean {
return Number.isFinite(cm) && cm >= MIN_DIMENSION_CM && cm <= MAX_DIMENSION_CM
}
/** Feet (+ optional inches) → whole centimeters. */
export function cmFromFtIn(feet: number, inches = 0): number {
return Math.round((feet * INCHES_PER_FOOT + inches) * CM_PER_INCH)
/** Round away IEEE-754 dust without rounding away precision: 12 × 2.54 is
* 30.479999999999997 in binary floating point, and the 1e-6 cm (10 nm) grain
* here is far below anything a garden cares about. Every cm column is REAL, so
* entry stays exact — this only stops 30.48 being stored as 30.479999999999997. */
function roundCm(cm: number): number {
return Math.round(cm * 1e6) / 1e6
}
/** Meters → whole centimeters. */
/** Feet (+ optional inches) → centimeters, exactly (1 ft → 30.48). */
export function cmFromFtIn(feet: number, inches = 0): number {
return roundCm((feet * INCHES_PER_FOOT + inches) * CM_PER_INCH)
}
/** Meters → centimeters, exactly. */
export function cmFromMeters(meters: number): number {
return Math.round(meters * CM_PER_METER)
return roundCm(meters * CM_PER_METER)
}
/** A value typed in the given unit (meters, or feet) → centimeters. */
@@ -79,9 +92,10 @@ export function formatSpacing(cm: number, unit: UnitPref): string {
return `${Math.round(cm)} cm`
}
/** A spacing value typed in the given unit (cm, or inches) → whole centimeters. */
/** A spacing value typed in the given unit (cm, or inches) → centimeters,
* exactly (12 in → 30.48). */
export function cmFromSpacing(value: number, unit: UnitPref): number {
return unit === 'imperial' ? Math.round(value * CM_PER_INCH) : Math.round(value)
return roundCm(unit === 'imperial' ? value * CM_PER_INCH : value)
}
/** Centimeters → a spacing number in the given unit, for prefilling an input.