feat: added scale buttons
This commit is contained in:
parent
a96734c394
commit
53c25c9da3
4 changed files with 391 additions and 22 deletions
|
|
@ -136,6 +136,70 @@ function toImperialValue(value, unit) {
|
|||
}
|
||||
}
|
||||
|
||||
// ─── Base Unit Conversion (for scaling) ─────────────────
|
||||
|
||||
function toBaseGrams(value, unit) {
|
||||
switch (unit) {
|
||||
case 'g': return value;
|
||||
case 'kg': return value * 1000;
|
||||
case 'oz': return value * 28.3495;
|
||||
case 'lb': return value * 453.592;
|
||||
default: return value;
|
||||
}
|
||||
}
|
||||
|
||||
function toBaseMl(value, unit) {
|
||||
switch (unit) {
|
||||
case 'ml': return value;
|
||||
case 'L': return value * 1000;
|
||||
case 'cup': return value * 236.588;
|
||||
case 'tablespoon': return value * 14.787;
|
||||
case 'teaspoon': return value * 4.929;
|
||||
case 'quart': return value * 946.353;
|
||||
case 'gallon': return value * 3785.41;
|
||||
case 'pint': return value * 473.176;
|
||||
case 'fl oz': return value * 29.5735;
|
||||
default: return value;
|
||||
}
|
||||
}
|
||||
|
||||
function computeScaleData(measurement) {
|
||||
const { type, amount, unit, approximate } = measurement;
|
||||
if (unit === 'parts by volume' || unit === 'parts by weight') return null;
|
||||
if (type !== 'weight' && type !== 'volume' && type !== 'count') return null;
|
||||
|
||||
if (type === 'count') {
|
||||
if (amount.min !== undefined) {
|
||||
return {
|
||||
base: [amount.min.value, amount.max.value],
|
||||
type: 'count',
|
||||
approx: approximate || amount.min.approximate || false,
|
||||
};
|
||||
}
|
||||
return {
|
||||
base: amount.value,
|
||||
type: 'count',
|
||||
approx: approximate || false,
|
||||
};
|
||||
}
|
||||
|
||||
const toBase = type === 'weight' ? toBaseGrams : toBaseMl;
|
||||
|
||||
if (amount.min !== undefined) {
|
||||
return {
|
||||
base: [toBase(amount.min.value, unit), toBase(amount.max.value, unit)],
|
||||
type: type,
|
||||
approx: approximate || amount.min.approximate || false,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
base: toBase(amount.value, unit),
|
||||
type: type,
|
||||
approx: approximate || false,
|
||||
};
|
||||
}
|
||||
|
||||
// ─── Time Formatting ────────────────────────────────────
|
||||
|
||||
function toMinutes(value, unit) {
|
||||
|
|
@ -183,6 +247,12 @@ function generateTexts(measurement) {
|
|||
return { defaultText: text, altText: text };
|
||||
}
|
||||
|
||||
// Bare counts — just display the number, no conversion
|
||||
if (type === 'count') {
|
||||
const text = formatCountText(amount, approximate);
|
||||
return { defaultText: text, altText: text };
|
||||
}
|
||||
|
||||
if (type === 'time') {
|
||||
return generateTimeTexts(amount, unit, approximate);
|
||||
}
|
||||
|
|
@ -190,6 +260,14 @@ function generateTexts(measurement) {
|
|||
return generateUnitTexts(amount, unit, approximate, type);
|
||||
}
|
||||
|
||||
function formatCountText(amount, approximate) {
|
||||
const prefix = approximate ? '~' : '';
|
||||
if (amount.min !== undefined) {
|
||||
return prefix + formatNumber(amount.min.value) + '-' + formatNumber(amount.max.value);
|
||||
}
|
||||
return prefix + formatNumber(amount.value);
|
||||
}
|
||||
|
||||
function generateTimeTexts(amount, unit, approximate) {
|
||||
if (amount.min !== undefined) {
|
||||
const prefix = amount.min.approximate ? '~' : '';
|
||||
|
|
@ -306,6 +384,13 @@ function replaceMeasurementsInToken(token, Token) {
|
|||
open.attrSet('data-default', defaultText);
|
||||
open.attrSet('data-alt', altText);
|
||||
open.attrSet('title', m.match);
|
||||
|
||||
// Add scaling data for weight/volume
|
||||
const scaleData = computeScaleData(m);
|
||||
if (scaleData) {
|
||||
open.attrSet('data-scalable', JSON.stringify(scaleData));
|
||||
}
|
||||
|
||||
newTokens.push(open);
|
||||
|
||||
// Display metric-normalized text by default
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue