From 9431325cd19e7780a44fdc8fba17f065794afc0b Mon Sep 17 00:00:00 2001 From: Tom Most Date: Tue, 29 Oct 2024 20:15:34 -0700 Subject: [PATCH 1/9] Standardize on FracInput --- src/lib/Form.svelte | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/lib/Form.svelte b/src/lib/Form.svelte index 34db728..16289ba 100644 --- a/src/lib/Form.svelte +++ b/src/lib/Form.svelte @@ -14,7 +14,6 @@ } from "$lib/stores" import { frac } from "$lib/frac" import FracInput from "$lib/FracInput.svelte" - import FracRange from "$lib/FracRange.svelte"

Inputs

@@ -27,7 +26,7 @@ - - Date: Tue, 29 Oct 2024 20:55:42 -0700 Subject: [PATCH 2/9] Accept " in inputs so the masking round-trips The browser may remember and restore the masked value across page reloads, so it should round-trip. --- src/lib/frac.test.ts | 5 +++++ src/lib/frac.ts | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/lib/frac.test.ts b/src/lib/frac.test.ts index 9d4592f..f29b99c 100644 --- a/src/lib/frac.test.ts +++ b/src/lib/frac.test.ts @@ -57,6 +57,11 @@ describe("parseFrac converts strings to numbers", () => { [" 123", NaN], ["123 ", NaN], ["1/2.3", NaN], + // " is accepted following the number + ['8"', 8], + ['8" 1/2"', 8.5], + ['6" + 1/2" - 0.25 + 1/2"', 6.75], + ['1"/2', NaN], ] test.for(cases)("parses %j as %d", ([s, n]) => { expect(parseFrac(s)).toEqual(n) diff --git a/src/lib/frac.ts b/src/lib/frac.ts index b25db95..9fa8a15 100644 --- a/src/lib/frac.ts +++ b/src/lib/frac.ts @@ -44,7 +44,7 @@ export function frac(n: number): string { export function parseFrac(s: string): number { const matches = [ ...s.matchAll( - /((?:[+-]\s*)?)(\.\d+|\d+(?:\.\d*)?)(?:[/\u2044](\d+))?(\s+|$|(?=[+-]))/dg + /((?:[+-]\s*)?)(\.\d+|\d+(?:\.\d*)?)(?:[/\u2044](\d+))?"?(\s+|$|(?=[+-]))/dg ), ] if (matches.length === 0 || matches[0].index !== 0) { From a83ae9ffa74921b29d915b9e5398b66fafcb9124 Mon Sep 17 00:00:00 2001 From: Tom Most Date: Tue, 29 Oct 2024 20:58:35 -0700 Subject: [PATCH 3/9] Lower unit handling to frac.ts It doesn't make sense to accept a unit that wasn't entered. --- src/lib/FracInput.svelte | 2 +- src/lib/frac.test.ts | 26 +++++++++++++------------- src/lib/frac.ts | 4 ++-- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/lib/FracInput.svelte b/src/lib/FracInput.svelte index 3ead720..a482d1c 100644 --- a/src/lib/FracInput.svelte +++ b/src/lib/FracInput.svelte @@ -41,7 +41,7 @@ if (input) { if (validate(input, v, min, max)) { value = v - displayValue = frac(v) + '"' + displayValue = frac(v) } else { displayValue = rawValue } diff --git a/src/lib/frac.test.ts b/src/lib/frac.test.ts index f29b99c..80789dd 100644 --- a/src/lib/frac.test.ts +++ b/src/lib/frac.test.ts @@ -3,19 +3,19 @@ import { frac, parseFrac } from "$lib/frac" describe("frac renders numbers as mixed fractions", () => { const cases: [number, string][] = [ - [-1 - 3 / 8, "-1\u20093⁄8"], - [-1, "-1"], - [0, "0"], - [1, "1"], - [1.5, "1\u20091⁄2"], - [12.25, "12\u20091⁄4"], - [-6.125, "-6\u20091⁄8"], - [1 / 4, "1⁄4"], - [7 / 8, "7⁄8"], - [15 / 16, "15⁄16"], - [1 + 17 / 32, "1\u200917⁄32"], - [23 / 32, "23⁄32"], - [3 + 61.5 / 64, "3\u200931⁄32"], + [-1 - 3 / 8, "-1\u20093⁄8\""], + [-1, "-1\""], + [0, "0\""], + [1, "1\""], + [1.5, "1\u20091⁄2\""], + [12.25, "12\u20091⁄4\""], + [-6.125, "-6\u20091⁄8\""], + [1 / 4, "1⁄4\""], + [7 / 8, "7⁄8\""], + [15 / 16, "15⁄16\""], + [1 + 17 / 32, "1\u200917⁄32\""], + [23 / 32, "23⁄32\""], + [3 + 61.5 / 64, "3\u200931⁄32\""], ] test.for(cases)("renders %d as %s", ([n, s]) => { expect(frac(n)).toEqual(s) diff --git a/src/lib/frac.ts b/src/lib/frac.ts index 9fa8a15..d13afc6 100644 --- a/src/lib/frac.ts +++ b/src/lib/frac.ts @@ -1,5 +1,5 @@ /** - * Present a number as a mixed fraction. + * Present a number as a mixed fraction, in inches. * * The value is rounded to the nearest 1⁄32nd, and the * denominator is one of 32, 16, 8, or 4, as on a measuring tape. @@ -35,7 +35,7 @@ export function frac(n: number): string { s += `${num}\u2044${denom}` } - return s + return s + '"' } /** From e7eee4e793b8d127ebdf6cb2ca24d4f9278eb401 Mon Sep 17 00:00:00 2001 From: Tom Most Date: Tue, 29 Oct 2024 21:20:11 -0700 Subject: [PATCH 4/9] Accept ' for feet --- src/lib/frac.test.ts | 11 ++++++++++- src/lib/frac.ts | 8 ++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/lib/frac.test.ts b/src/lib/frac.test.ts index 80789dd..269ffa8 100644 --- a/src/lib/frac.test.ts +++ b/src/lib/frac.test.ts @@ -57,11 +57,20 @@ describe("parseFrac converts strings to numbers", () => { [" 123", NaN], ["123 ", NaN], ["1/2.3", NaN], - // " is accepted following the number + // " is allowed following the number ['8"', 8], ['8" 1/2"', 8.5], ['6" + 1/2" - 0.25 + 1/2"', 6.75], ['1"/2', NaN], + // ' following the number multiplies by 12 (feet to inches) + ["1'", 12], + ["1'2", 14], // No whitespace necessary + ["1' 2", 14], + ["1' 2\"", 14], + ["1' + 2", 14], + ["1'+2\"", 14], + ["1/2' +12\"", 18], + ["3'4'5'6'1/2'", (3 + 4 + 5 + 6 + 0.5) * 12] ] test.for(cases)("parses %j as %d", ([s, n]) => { expect(parseFrac(s)).toEqual(n) diff --git a/src/lib/frac.ts b/src/lib/frac.ts index d13afc6..46d78de 100644 --- a/src/lib/frac.ts +++ b/src/lib/frac.ts @@ -44,7 +44,7 @@ export function frac(n: number): string { export function parseFrac(s: string): number { const matches = [ ...s.matchAll( - /((?:[+-]\s*)?)(\.\d+|\d+(?:\.\d*)?)(?:[/\u2044](\d+))?"?(\s+|$|(?=[+-]))/dg + /((?:[+-]\s*)?)(\.\d+|\d+(?:\.\d*)?)(?:[/\u2044](\d+))?(["']?)(\s+|$|(?=[+-])|(?<=["'])(?=\d))/dg ), ] if (matches.length === 0 || matches[0].index !== 0) { @@ -58,9 +58,13 @@ export function parseFrac(s: string): number { let sign = m[1].substring(0, 1) let v = parseFloat(m[2]) const denom = m[3] + const unit = m[4] if (denom) { v /= parseFloat(denom) } + if (unit === "'") { + v *= 12 // Feet to inches + } if (!sign) { sign = lastSign } @@ -73,7 +77,7 @@ export function parseFrac(s: string): number { } } - const [lastStart] = matches[matches.length - 1].indices![4] + const [lastStart] = matches[matches.length - 1].indices![5] if (lastStart !== s.length) { // Failure to match, or trailing whitespace or other gunk. return NaN From 2ac0a1f13e2e60aafe49570394cbea9beb3a4e8f Mon Sep 17 00:00:00 2001 From: Tom Most Date: Tue, 29 Oct 2024 21:39:36 -0700 Subject: [PATCH 5/9] Add step button support --- src/lib/FracInput.svelte | 43 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/src/lib/FracInput.svelte b/src/lib/FracInput.svelte index a482d1c..9938e57 100644 --- a/src/lib/FracInput.svelte +++ b/src/lib/FracInput.svelte @@ -27,12 +27,13 @@ export let value: number export let min: number | null = null export let max: number | null = null + export let step: number | null = null // TODO: Add step buttons export let required: boolean = false let focused: boolean = false let input: HTMLInputElement let rawValue = frac(value) - let displayValue = frac(value) + '"' + let displayValue = frac(value) $: { // Round to the nearest 1⁄32nd to match the masked value. @@ -66,9 +67,29 @@ focused = false }} /> + {#if step !== null} + + + {/if} From 4b41920d61bf5d5927ebd3cce188a7823de36c55 Mon Sep 17 00:00:00 2001 From: Tom Most Date: Tue, 29 Oct 2024 21:40:01 -0700 Subject: [PATCH 6/9] Remove FracRange It didn't work well on a phone. --- src/lib/FracRange.svelte | 30 ------------------------------ 1 file changed, 30 deletions(-) delete mode 100644 src/lib/FracRange.svelte diff --git a/src/lib/FracRange.svelte b/src/lib/FracRange.svelte deleted file mode 100644 index 9e86480..0000000 --- a/src/lib/FracRange.svelte +++ /dev/null @@ -1,30 +0,0 @@ - - - - {frac(value)}" - - - - From 082b76e0de3d8e6d2b9b39dbd81e125583850abe Mon Sep 17 00:00:00 2001 From: Tom Most Date: Tue, 29 Oct 2024 21:42:25 -0700 Subject: [PATCH 7/9] Prettier --- src/lib/FracInput.svelte | 18 +++++++++--------- src/lib/frac.test.ts | 28 ++++++++++++++-------------- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/lib/FracInput.svelte b/src/lib/FracInput.svelte index 9938e57..0d64e09 100644 --- a/src/lib/FracInput.svelte +++ b/src/lib/FracInput.svelte @@ -71,17 +71,17 @@ + value -= step + rawValue = frac(value) + }}>-{frac(step)} + value += step + rawValue = frac(value) + }}>+{frac(step)} {/if} @@ -113,7 +113,7 @@ background: white; } button:active { - border-style: inset; /* even prettier ✨ */ + border-style: inset; /* even prettier ✨ */ } button:disabled { opacity: 0.5; diff --git a/src/lib/frac.test.ts b/src/lib/frac.test.ts index 269ffa8..885798f 100644 --- a/src/lib/frac.test.ts +++ b/src/lib/frac.test.ts @@ -3,19 +3,19 @@ import { frac, parseFrac } from "$lib/frac" describe("frac renders numbers as mixed fractions", () => { const cases: [number, string][] = [ - [-1 - 3 / 8, "-1\u20093⁄8\""], - [-1, "-1\""], - [0, "0\""], - [1, "1\""], - [1.5, "1\u20091⁄2\""], - [12.25, "12\u20091⁄4\""], - [-6.125, "-6\u20091⁄8\""], - [1 / 4, "1⁄4\""], - [7 / 8, "7⁄8\""], - [15 / 16, "15⁄16\""], - [1 + 17 / 32, "1\u200917⁄32\""], - [23 / 32, "23⁄32\""], - [3 + 61.5 / 64, "3\u200931⁄32\""], + [-1 - 3 / 8, '-1\u20093⁄8"'], + [-1, '-1"'], + [0, '0"'], + [1, '1"'], + [1.5, '1\u20091⁄2"'], + [12.25, '12\u20091⁄4"'], + [-6.125, '-6\u20091⁄8"'], + [1 / 4, '1⁄4"'], + [7 / 8, '7⁄8"'], + [15 / 16, '15⁄16"'], + [1 + 17 / 32, '1\u200917⁄32"'], + [23 / 32, '23⁄32"'], + [3 + 61.5 / 64, '3\u200931⁄32"'], ] test.for(cases)("renders %d as %s", ([n, s]) => { expect(frac(n)).toEqual(s) @@ -70,7 +70,7 @@ describe("parseFrac converts strings to numbers", () => { ["1' + 2", 14], ["1'+2\"", 14], ["1/2' +12\"", 18], - ["3'4'5'6'1/2'", (3 + 4 + 5 + 6 + 0.5) * 12] + ["3'4'5'6'1/2'", (3 + 4 + 5 + 6 + 0.5) * 12], ] test.for(cases)("parses %j as %d", ([s, n]) => { expect(parseFrac(s)).toEqual(n) From 84ac63243376937429b410dd6ad00c1bc1d7bb1a Mon Sep 17 00:00:00 2001 From: Tom Most Date: Tue, 29 Oct 2024 21:43:07 -0700 Subject: [PATCH 8/9] Update screenshots --- tests/test.ts-snapshots/calculator-layout-1-Desktop-linux.png | 4 ++-- tests/test.ts-snapshots/calculator-layout-1-Phone-linux.png | 4 ++-- tests/test.ts-snapshots/calculator-layout-1-Tablet-linux.png | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/test.ts-snapshots/calculator-layout-1-Desktop-linux.png b/tests/test.ts-snapshots/calculator-layout-1-Desktop-linux.png index a97f813..7105daa 100644 --- a/tests/test.ts-snapshots/calculator-layout-1-Desktop-linux.png +++ b/tests/test.ts-snapshots/calculator-layout-1-Desktop-linux.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:baec87da52f1ca95b7ee03713c597ad8f3f0b2ef6dddd736372077705a469112 -size 269629 +oid sha256:2df97ab82b13b07ff8c1dfce2f111bb6df6da6dc9253a783025ad31d8afcce0a +size 268525 diff --git a/tests/test.ts-snapshots/calculator-layout-1-Phone-linux.png b/tests/test.ts-snapshots/calculator-layout-1-Phone-linux.png index 58c8947..0e2d2be 100644 --- a/tests/test.ts-snapshots/calculator-layout-1-Phone-linux.png +++ b/tests/test.ts-snapshots/calculator-layout-1-Phone-linux.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:49cd414b6f94ae7258ef18581f31f082e83d6bb0301d5b00d35aea0b065eb6a3 -size 543009 +oid sha256:59287a85e5d48a277d5c05761bad8970d4bf85b08c55489b25a0c2b71e593d0d +size 537648 diff --git a/tests/test.ts-snapshots/calculator-layout-1-Tablet-linux.png b/tests/test.ts-snapshots/calculator-layout-1-Tablet-linux.png index d86bbc7..5c1afae 100644 --- a/tests/test.ts-snapshots/calculator-layout-1-Tablet-linux.png +++ b/tests/test.ts-snapshots/calculator-layout-1-Tablet-linux.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d304b822cfa92a9c8f5fcbf2eaa4e53f6266e1da41af5ea8f3f26a9e0006d7a9 -size 558511 +oid sha256:b5dc1a89f7b0d2a8eb5b9565732e845517880fe5941a6d76229b693d837b656a +size 556998 From 59614064631f629b59d4966816f89da545f0d6f7 Mon Sep 17 00:00:00 2001 From: Tom Most Date: Tue, 29 Oct 2024 22:19:03 -0700 Subject: [PATCH 9/9] Fix duplicate units --- src/lib/Form.svelte | 2 +- src/lib/PartList.svelte | 2 +- tests/test.ts-snapshots/calculator-layout-1-Desktop-linux.png | 4 ++-- tests/test.ts-snapshots/calculator-layout-1-Phone-linux.png | 4 ++-- tests/test.ts-snapshots/calculator-layout-1-Tablet-linux.png | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/lib/Form.svelte b/src/lib/Form.svelte index bf8b992..8f2e892 100644 --- a/src/lib/Form.svelte +++ b/src/lib/Form.svelte @@ -56,7 +56,7 @@
- {frac($stockLength)}" + {frac($stockLength)}