npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

svelte-currency

v0.0.8

Published

A svelte currency input action with optimized UX

Downloads

16

Readme

svelte-currency

A svelte currency input action with optimized UX

While looking for a currency input component I found a number of issues with existing solutions:

  • included the currency symbol inside the input
  • allowed addional inputs beyond the decimal digit limit (often corrupting the entered value)
  • outright handle inputs wrong (e.g. entering "1.23" results in "13")
  • inputs were left formatted, when numbers are typically right aligned
  • formatting wasn't applied until the input loses focus
  • cursor position jumped around especially when dealing with grouping
  • showed input spinners / wrong keyboard on mobile

This is my attempt to create the currency input I wanted. It has the following features:

  • ✅ Tiny 2kb size, as a Svelte use:action (also usable without Svelte!)
  • ✅ Automatically configures the input type and inputmode attributes for best experience
  • ✅ Pass the ISO currency code to use, support popular crypto-currencies such as BTC
  • ✅ Automatically set an appropriate placeholder based on the currencies decimal points
  • ✅ Handle locale formatting, specifically the opposite decimal point and grouping symbols in Europe
  • ✅ Works with TailwindCSS / TailwindUI currency input layout (see example)

Usage

Install using your package manager of choice, which should be pnpm:

pnpm i -D svelte-currency

Import it into the component you want to use it:

<script lang="ts">
	import { currency } from 'svelte-currency'
</script>

Add it to an HTML input element with the use: syntax:

<input id="price" name="price" use:currency={{ currency: 'USD' }} />

Set the currency to have the input formatted appropriately. By default it will use the browser locale but you can override that by passing it in, and also set the decimals to use if dealing with non-traditional currencies (e.g. bitcoin)

<input id="price" name="price" use:currency={{ currency: 'BTC', locale: 'en', digits: 8 }} />

Vanilla JS

As it's a Svelte Action, there aren't really any dependencies on Svelte itself - you can apply it to any HTML Input manually:

const input: HTMLInputElement = document.querySelector('input')!
const action = currency(input, { currency: 'USD' })

// update the options:
action.update({ currency: 'CAD' })

// remove it:
action.destroy()

Output Value

Because the input value is the formatted string, you may have issues if you try to convert it to a numeric value using parseFloat because that doesn't handle group separators or decimal commas. Use the .valueAsNumber property of the input to access the numberic value as a number that has been pre-normalized / parsed for you.

Example

An empty input for USD with an English locale will show a placeholder of 0.00, a European local would show 0,00

Entering digits will fill them ahead of the decimal point, with the cursor positioned before it. The current cursor position is indicated with |:

| Key Entry | Value | European | | --------- | ---------------: | ---------------: | | Enter 1 | 1\|.00 | 1\|,00 | | Enter 2 | 12\|.00 | 12\|,00 | | Enter 3 | 123\|.00 | 123\|,00 | | Enter 4 | 1,234\|.00 | 1.234\|,00 | | Enter 5 | 12,345\|.00 | 12.345\|,00 | | Enter 6 | 123,456\|.00 | 123.456\|,00 | | Enter 7 | 1,234,567\|.00 | 1.234.567\|,00 | | Enter . | 1,234,567.\|00 | 1.234.567,\|00 | | Enter 8 | 1,234,567.8\|0 | 1.234.567,8\|0 | | Enter 9 | 1,234,567.89\| | 1.234.567,89\| |

The decimal point can be entered at any point to position the input cursor to after it which feels natural.

Once the input is filled, no more key presses will be allowed - the decimals won't be rounded as a result and the cursor won't jump to the main unit input as happens on many other currency inputs.

Pressing + or - at any point will change the sign of the input (- if negative will toggle it)

Backspace will remove digits to the left of the cursor, moving the cursor if it's to the right of the decimal point and pulling the input right when to the left. The decimal point is jumped as are any group separators.

| Key Entry | Value | European | | ----------- | ---------------: | ---------------: | | | 1,234,567.89\| | 1.234.567,89\| | | Backspace | 1,234,567.8\|0 | 1.234.567,8\|0 | | Backspace | 1,234,567.\|00 | 1.234.567,\|00 | | Backspace | 123,456\|.00 | 123.456\|,00 | | Backspace | 12,345\|.00 | 12.345\|,00 | | Backspace | 1,234\|.00 | 1.234\|,00 | | Backspace | 123\|.00 | 123\|,00 | | Backspace | 12\|.00 | 12\|,00 | | Backspace | 1\|.00 | 1\|,00 | | Backspace | 0.00\| | 0,00\| |

Delete will delete the digit to the right of the cursor, jumping grouping symbols and moving to the right when past the decimal point.

Entering grouping character will be ignored. ArrowLeft and ArrowRight change the cursor position.

Pasted values will be parsed and formatted and the cursor positioned at the end.

Selecting text and entering any digit or pressing Backspace or Delete will replace or remove the selected characters, positioning the cursor to the right of the selection or the decimal point.