Skip to content

Commit

Permalink
Formatting for calculator output and packed footnote
Browse files Browse the repository at this point in the history
  • Loading branch information
dpilafian committed May 28, 2024
1 parent ecdc446 commit 6ce57e4
Show file tree
Hide file tree
Showing 9 changed files with 167 additions and 131 deletions.
2 changes: 0 additions & 2 deletions src/templates/doc-begin.html
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,7 @@
<a href={{webRoot}}>Home</a>
<a href={{webRoot}}/products>Products</a>
<a href={{webRoot}}/do-not-learn-metric>Just Use It</a>
<!--
<a href={{webRoot}}/calculator>Calculator</a>
-->
<a href={{webRoot}}/elsewhere>Elsewhere</a>
</nav>
<h1>Think Metric</h1>
Expand Down
72 changes: 42 additions & 30 deletions src/website/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,30 +22,36 @@ const app = {
},

calculator: {
// <section class=calculator data-on-load=app.calculator.init>
// <form>
// <label>
// <input name=quantity>
// <label>
// <select name=units>
// <option value=teaspoon data-type=volume data-per-cup=48>
// <option value=lb data-type=weight data-grams=453.592>
// <label>
// <select name=ingredient>
// <option id=input-ingredient class=dna-template>~~name~~</option>
fractionToFloat(str) {
// Example:
// fractionToFloat('1 3/4') -> 1.75
const qtyClean = str.replace(/\s+/g, ' ').trim(); //ex: '1 3/4'
const qtyParts = qtyClean.replace(/[^0-9.\/\s]/g, '').split(' '); //ex: ['1', '3/4']
const toDecimal = (fraction) => Number(fraction[0]) / Number(fraction[1]); //ex: ['3', '4'] -> 0.75
const toNum = (part) => part.includes('/') ? toDecimal(part.split('/')) : Number(part); //ex: '3/4' -> 0.75
const qty = qtyParts.map(toNum).reduce((sum, num) => sum + num, 0); //ex: 1.75
const qtyValid = !isNaN(qty) && qty > 0 && qty < 100000;
return qtyValid ? qty : null;
},
convertToGrams(elem) {
const calculatorForm = elem.closest('form');
// <section class=calculator data-on-load=app.calculator.init>
// <form>
// <label>
// <input name=quantity>
// <label>
// <select name=units>
// <option value=teaspoon data-type=volume data-per-cup=48>
// <option value=lb data-type=weight data-grams=453.592>
// <label>
// <select name=ingredient>
// <option id=input-ingredient class=dna-template>~~name~~</option>
const form = elem.closest('form');
const elemMap = {
quantity: calculatorForm.querySelector('input[name=quantity]'),
units: calculatorForm.querySelector('select[name=units]'),
ingredient: calculatorForm.querySelector('select[name=ingredient]'),
quantity: form.querySelector('input[name=quantity]'),
units: form.querySelector('select[name=units]'),
ingredient: form.querySelector('select[name=ingredient]'),
};
const qtyClean = elemMap.quantity.value.replace(/\s+/g, ' ').trim(); //ex: '1 3/4'
const qtyParts = qtyClean.replace(/[^0-9.\/\s]/g, '').split(' '); //ex: ['1', '3/4']
const toDecimal = (fraction) => Number(fraction[0]) / Number(fraction[1]); //ex: ['3', '4'] -> 0.75
const toNum = (part) => part.includes('/') ? toDecimal(part.split('/')) : Number(part); //ex: '3/4' -> 0.75
const qty = qtyParts.map(toNum).reduce((sum, num) => sum + num, 0); //ex: 1.75
const qtyValid = !isNaN(qty) && qty > 0 && qty < 100000;
const qty = app.calculator.fractionToFloat(elemMap.quantity.value);
const unitsOption = elemMap.units.options[elemMap.units.selectedIndex]; //ex: <option value=teaspoon data-type=volume data-per-cup=48>Teaspoons</option>
const unitsLabel = unitsOption.textContent.replace(/\(.*/, '').trim().toLowerCase(); //ex: 'cups'
const isVolume = unitsOption.dataset.type === 'volume'; //check if 'volume' or 'weight'
Expand All @@ -54,16 +60,21 @@ const app = {
const key = elemMap.ingredient.value; //ex: 'Almonds'
const ingredients = globalThis.ingredientsDB.filter(ingredient => ingredient.key === key); //ex: [{ key: 'Almonds', ...
const byVolume = (ingredient) => qty * ingredient.gramsPerCup / unitsPerCup;
const toGrams = (ingredient) => isVolume ? byVolume(ingredient) : qty * gramsPerUnit;
const round5 = (grams) => Math.round(dna.util.round(grams, 2) / 5) * 5;
const round = (grams) => grams < 10 ? Math.ceil(grams) : round5(grams);
const toGrams = (ingredient) => round((isVolume ? byVolume(ingredient) : qty * gramsPerUnit));
const toMetric = (ingredient) => ({ ingredient: ingredient, grams: toGrams(ingredient)});
const calcResults = () => ({ quantity: qty, unitsLabel, name: key, metric: ingredients.map(toMetric) });

console.log({ calculatorForm, elemMap, qty, qtyValid, unitsOption, unitsLabel, isVolume, unitsPerCup, gramsPerUnit, name: key, ingredients });

if (qtyValid)
dna.clone('calculator-result', calcResults(), { empty: true });
const calcResults = () => ({
qty,
unitsLabel,
key,
metric: ingredients.map(toMetric),
packed: ingredients.some(ingredient => ingredient.packed),
});
if (qty)
dna.clone('grams-calculator-result', calcResults(), { empty: true });
},
updateTemperature(elem) {
convertToCelsius(elem) {
const tempF = Number(elem.value);
const output = elem.closest('section').querySelector('output');
const toCelsius = () => Math.round((tempF - 32) * 5 / 9);
Expand All @@ -83,7 +94,8 @@ const app = {
},
init() {
app.calculator.populateIngredientDropDown();
globalThis.document.activeElement.select(); //highlight the "Quantity" field value
const highlightInputField = () => globalThis.document.activeElement.select();
globalThis.requestAnimationFrame(highlightInputField);
},
},

Expand Down
30 changes: 24 additions & 6 deletions src/website/calculator/calculator.less
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
// Think Metric
// Style: Calculator


// <label>
// <span>Color:</span>
// <select>
// <option>Plum</option>
/// <option>Pink</option>
// </select>
// </label>
label:has(select) {
position: relative;
max-width: 25em;
Expand All @@ -18,16 +29,16 @@ label:has(select) {
appearance: none;
background-color: mintcream;
border: 1px solid silver;
padding: 0.3em 2em 0.3em 0.3em;
padding: 0.3em 2.0em 0.3em 0.3em;
margin: 0px;
&:invalid {
color: red;
color: firebrick;
}
}
}

section.calculator {
min-height: 600px; //prevent jitter when calculations refresh
section.grams-calculator {
min-height: 750px; //prevent jitter when calculations refresh
>form {
position: relative;
display: flex;
Expand Down Expand Up @@ -69,6 +80,9 @@ section.calculator {
>figcaption {
font-style: normal;
margin-bottom: 15px;
span {
font-weight: normal;
}
}
>p {
font-size: 2rem;
Expand All @@ -78,16 +92,20 @@ section.calculator {
>div {
>output {
display: block;
text-align: left;
font-style: normal;
margin-bottom: 5px;
b {
}
}
}
>small {
display: block;
margin-top: 20px;
}
}
}

section.oven-temperature {
section.celsius-calculator {
>div {
display: flex;
justify-content: center;
Expand Down
24 changes: 13 additions & 11 deletions src/website/calculator/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

<main class=center-line>

<section class=calculator data-on-load=app.calculator.init>
<section class=grams-calculator data-on-load=app.calculator.init>
<h2>{{articleTitle}}</h2>
<form>
<label>
Expand Down Expand Up @@ -39,28 +39,28 @@ <h2>{{articleTitle}}</h2>
</label>
<p>Quantity can include fractions, such as: <i>3 1/2</i></p>
</form>
<figure id=calculator-result class=dna-template>
<figure id=grams-calculator-result class=dna-template>
<figcaption>
<b data-format-number=#.###>~~quantity~~</b>
<b>~~unitsLabel~~</b> <b>~~name~~</b>
<b data-format-number=#.###>~~qty~~</b>
<span>~~unitsLabel~~</span> <b>~~key~~</b>
</figcaption>
<p><i data-icon=arrow-alt-circle-down></i></p>
<div>
<output data-array=~~metric~~>
<b data-precision=2 data-format-number=#>~~grams~~</b>
<b>grams</b>
<b>~~ingredient.description~~</b>
<b data-format-number=#>~~grams~~</b> grams
<b>~~ingredient.description~~</b><span data-true=~~ingredient.packed~~>*</span>
</output>
</div>
<small data-true=~~packed~~>* Use this measurment if the ingredients in <span>~~unitsLabel~~</span> were pressed or packed.</small>
</figure>
</section>

<section class=oven-temperature>
<section class=celsius-calculator>
<h2>Oven Temperature Conversion</h2>
<div>
<form><input value=350 data-on-input=app.calculator.updateTemperature>&deg;F</form>
<form><input value=350 data-on-input=app.calculator.convertToCelsius>&deg;F</form>
<i data-icon=arrow-alt-circle-right></i>
<figure><output id=celsius class=dna->180</output>&deg;C</figure>
<figure><output>180</output>&deg;C</figure> <!-- Start at 350°F = 180°C -->
</div>
</section>

Expand Down Expand Up @@ -90,7 +90,9 @@ <h2>NIST Metric Kitchen</h2>
<h2>Open Source</h2>
<p>
The <i>Recipe Converter Calculator</i> is an open source community project.&nbsp;
You can help out by submitting corrections and additions.&nbsp;
You can help out by submitting corrections and additions on GitHub or by posting to the
<a href=https://www.reddit.com/r/ThinkMetric>r/ThinkMetric</a> sub on Reddit.&nbsp;
If you post to Reddit, add the <i>"Food, Recipies, & Grams"</i> flair.&nbsp;
</p>
<p>
Data for the calculator is on GitHub at:<br>
Expand Down
77 changes: 77 additions & 0 deletions src/website/css/components.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// Think Metric
// Style: Components

main.center-line {
>section {
p {
text-align: center;
}
>i.font-icon {
font-size: 3rem;
}
}
}

ul.plain-list {
list-style-type: none;
padding-left: 0px;
li {
text-align: center;
}
}

figure.box-frame {
background-color: white;
border: 5px solid silver;
padding: 5px 20px;
img {
height: 100px;
.MobileMode({ height: 70px; })
}
}

figure.small-picture {
max-width: 200px;
.MobileMode({ max-width: 150px; })
}

table.big-table {
margin: 0px;
.TableCell() {
font-size: 1em;
text-align: left;
&:first-child {
padding-left: 0px;
}
&:last-child {
padding-right: 0px;
}
}
thead {
tr {
th {
.TableCell();
}
}
}
tbody {
tr {
td {
.TableCell();
img {
max-width: 120px;
}
}
}
}
}

// Responsive Design
.MobileMode({
table.big-table { //hide 2nd column in compact mode
thead tr th:nth-child(2),
tbody tr td:nth-child(2) {
display : none;
}
}
});
4 changes: 3 additions & 1 deletion src/website/css/layout.less
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
// Layout
// Think Metric
// Style: Layout

body {
>header {
background-image: url(graphics/kg-weights-by-ylanite-koppens-at-pexels.jpg);
Expand Down
3 changes: 3 additions & 0 deletions src/website/css/metrication-checklist.less
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// Think Metric
// Style: Metrication Checklist

ol.metrication-checklist {
@rowHeight: 3.0rem;
list-style: none;
Expand Down
3 changes: 2 additions & 1 deletion src/website/css/static/utility-box.less
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// Constants and utilities -- Reusable values and mixins
// Think Metric
// Style: Constants and Utilities -- Reusable values and mixins

// Layers for z-index
@layerDialogBox: 500; //cream of the crop
Expand Down
Loading

0 comments on commit 6ce57e4

Please sign in to comment.