Skip to content

amocarski/length-input

Repository files navigation

Length Input

A single-field length input for free-form lengths with mixed units and basic math. The value is stored in metres when you leave the field or press Enter.

image

There is also components/live-length-input/, which is not wired up in the app. I used it to try a different way of showing parsed results; the current UI uses another approach (Rayon's style). I kept the folder instead of deleting it as a record of exploring alternate UX and UI patterns.

Key decisions

These choices mostly match Rayon's input behavior:

  • A chain of regexes instead of a grammar or syntax tree. Keeps the code short and easy to follow.
  • Clean the string first, then split it into tokens. That keeps each small parser simple.
  • Commit on blur/Enter, not on every keystroke. Avoids showing errors mid-typing and keeps the reducer simple. Matches Rayon's behavior where the field only validates and formats when you leave it or press Enter.
  • Append unit suffix on commit, strip on focus. After committing, the display reads e.g. 1.5 m. When the user re-focuses the field, the m suffix is removed so they edit a bare number. This avoids cursor-fighting with a trailing unit while typing.
  • Unknown units fall back to metres. If a user types something like 5 km, the parser does not recognize km; the k is leftover and 5 m is what matches. The number stays the same, only the unit changes. Same idea as Rayon: unknown units are treated as the default.
  • No parentheses or nesting. Left out on purpose to keep scope small.
  • Round off tiny float errors. Simple math in metres can show values like 0.30000000000000004 instead of 0.3. We round to nine decimal places before display so that junk does not appear.

Tradeoffs

  • Bare numbers (no unit) are treated as raw metres.
  • Error messages are generic ("Invalid expression"). The tokenizer knows where it failed but does not show that to the user.
  • Divide by zero does nothing (left value unchanged). When the divisor is 0, the / step is skipped and the value on the left stays the same, e.g. 10 m / 010 m, 25 / 025, like Rayon.

To improve over time

  • Tests. Unit tests for each parser and the evaluate step would be the first thing to add.
  • Undo / history. Let the user step back through committed values.
  • Configurable output unit and precision. Select component or something similar.
  • Expressions with parentheses.
  • Other locales. Formatting is fixed to en-US. Comma-as-decimal locales would break parsing.
  • Select all on re-focus. When the user focuses the field again (after committing or leaving it), select the entire text so the whole value is highlighted and can be replaced in one keystroke.
  • One place for new units. Simple units could come from one list.

Running

pnpm install
pnpm run dev

About

A single-field length input for free-form lengths with mixed units and basic math. The value is stored in metres when you leave the field or press Enter.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors