format everything as decimals for ease of input
This commit is contained in:
parent
9c271b0d2f
commit
7a34bc0629
2 changed files with 31 additions and 32 deletions
|
@ -1,8 +1,8 @@
|
||||||
import React, { useState, useEffect, useMemo, useCallback, useRef } from 'react'
|
import React, { useState, useEffect, useMemo, useCallback, useRef } from 'react'
|
||||||
import { useTranslation } from 'next-i18next'
|
import { useTranslation } from 'next-i18next'
|
||||||
import { isDegreeMeasurement } from '../../../config/measurements'
|
import { isDegreeMeasurement } from '../../../config/measurements'
|
||||||
import measurementAsMm from 'pkgs/utils/measurementAsMm'
|
import measurementAsMm from 'pkgs/utils/src/measurementAsMm'
|
||||||
import formatMm from 'pkgs/utils/formatMm'
|
import formatMm from 'pkgs/utils/src/formatMm'
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is a single input for a measurements
|
* This is a single input for a measurements
|
||||||
|
@ -16,7 +16,9 @@ const MeasurementInput = ({ m, gist, app, updateMeasurements }) => {
|
||||||
const { t } = useTranslation(['app', 'measurements'])
|
const { t } = useTranslation(['app', 'measurements'])
|
||||||
const prefix = (app.site === 'org') ? '' : 'https://freesewing.org'
|
const prefix = (app.site === 'org') ? '' : 'https://freesewing.org'
|
||||||
const title = t(`measurements:${m}`)
|
const title = t(`measurements:${m}`)
|
||||||
const isDegree = isDegreeMeasurement(m)
|
|
||||||
|
const isDegree = isDegreeMeasurement(m);
|
||||||
|
const factor = useMemo(() => (isDegree ? 1 : (gist.units == 'imperial' ? 25.4 : 10)), [gist.units])
|
||||||
|
|
||||||
const isValValid = val => (typeof val === 'undefined' || val === '')
|
const isValValid = val => (typeof val === 'undefined' || val === '')
|
||||||
? null
|
? null
|
||||||
|
@ -25,52 +27,45 @@ const MeasurementInput = ({ m, gist, app, updateMeasurements }) => {
|
||||||
? isValValid(val)
|
? isValValid(val)
|
||||||
: isValValid(newVal)
|
: isValValid(newVal)
|
||||||
|
|
||||||
const [val, setVal] = useState(formatMm(gist?.measurements?.[m], gist.units, false) || '')
|
const [val, setVal] = useState(gist?.measurements?.[m] / factor || '')
|
||||||
|
|
||||||
// keep a single reference to a debounce timer
|
// keep a single reference to a debounce timer
|
||||||
const debounceTimeout = useRef(null);
|
const debounceTimeout = useRef(null);
|
||||||
|
|
||||||
// this callback will track to current gist values
|
|
||||||
const cb = useCallback((evt) => {
|
|
||||||
let evtVal = evt.target.value;
|
|
||||||
// cleat the timeout reference
|
|
||||||
debounceTimeout.current = null;
|
|
||||||
|
|
||||||
let useVal = isDegree ? evtVal : measurementAsMm(evtVal, gist.units);
|
|
||||||
const ok = isValid(useVal)
|
|
||||||
// only set to the gist if it's valid
|
|
||||||
if (ok) {
|
|
||||||
updateMeasurements(useVal, m)
|
|
||||||
}
|
|
||||||
}, [gist]);
|
|
||||||
|
|
||||||
// onChange
|
// onChange
|
||||||
const update = (evt) => {
|
const update = useCallback((evt) => {
|
||||||
evt.stopPropagation();
|
evt.stopPropagation();
|
||||||
let evtVal = evt.target.value;
|
let evtVal = evt.target.value;
|
||||||
// set Val immediately so that the input reflects it
|
// set Val immediately so that the input reflects it
|
||||||
setVal(evtVal)
|
setVal(evtVal)
|
||||||
|
|
||||||
// debounce the rest of the callback
|
let useVal = isDegree ? evtVal : measurementAsMm(evtVal, gist.units);
|
||||||
if (debounceTimeout.current !== null) { clearTimeout(debounceTimeout.current);
|
const ok = isValid(useVal)
|
||||||
}
|
// only set to the gist if it's valid
|
||||||
|
if (ok) {
|
||||||
|
// debounce in case it's still changing
|
||||||
|
if (debounceTimeout.current !== null) { clearTimeout(debounceTimeout.current); }
|
||||||
debounceTimeout.current = setTimeout(() => {
|
debounceTimeout.current = setTimeout(() => {
|
||||||
cb(evt)
|
// clear the timeout reference
|
||||||
|
debounceTimeout.current = null;
|
||||||
|
updateMeasurements(useVal, m)
|
||||||
}, 500);
|
}, 500);
|
||||||
}
|
}
|
||||||
|
}, [gist.units])
|
||||||
|
|
||||||
// use this for better update efficiency
|
// use this for better update efficiency
|
||||||
const memoVal = useMemo(() => gist?.measurements[m], [gist])
|
const memoVal = useMemo(() => gist?.measurements[m], [gist])
|
||||||
// track validity against the value and the units
|
// track validity against the value and the units
|
||||||
const valid = useMemo(() => isValid(measurementAsMm(val, gist.units)), [val, gist.units])
|
const valid = useMemo(() => isValid(isDegree ? val : measurementAsMm(val, gist.units)), [val, gist.units])
|
||||||
|
|
||||||
// hook to update the value when the gist changes
|
// hook to update the value or format when the gist changes
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
// set the value to the proper value and format
|
||||||
if (memoVal) {
|
if (memoVal) {
|
||||||
let gistVal = isDegree ? memoVal : formatMm(memoVal, gist.units, false);
|
let gistVal = +(memoVal / factor).toFixed(2);
|
||||||
setVal(gistVal)
|
setVal(gistVal)
|
||||||
}
|
}
|
||||||
}, [memoVal, gist.units])
|
}, [memoVal, factor])
|
||||||
|
|
||||||
// cleanup
|
// cleanup
|
||||||
useEffect(() => clearTimeout(debounceTimeout.current), [])
|
useEffect(() => clearTimeout(debounceTimeout.current), [])
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
const measurementAsMm = (value, units = "metric") => {
|
const measurementAsMm = (value, units = "metric") => {
|
||||||
if (typeof value === "number")
|
if (typeof value === "number")
|
||||||
return value * (units === "imperial" ? 25.4 : 10);
|
return value * (units === "imperial" ? 25.4 : 10);
|
||||||
|
|
||||||
|
if (value.endsWith('.'))
|
||||||
|
return false;
|
||||||
|
|
||||||
if (units === "metric") {
|
if (units === "metric") {
|
||||||
value = Number(value);
|
value = Number(value);
|
||||||
if (isNaN(value)) return false;
|
if (isNaN(value)) return false;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue