{"id":26715707,"url":"https://github.com/fmaclen/svelte-currency-input","last_synced_at":"2026-01-02T22:30:15.538Z","repository":{"id":59363089,"uuid":"536862927","full_name":"fmaclen/svelte-currency-input","owner":"fmaclen","description":"A masked form input that converts numbers to localized currency formats as you type","archived":false,"fork":false,"pushed_at":"2024-11-01T21:04:47.000Z","size":405,"stargazers_count":42,"open_issues_count":9,"forks_count":5,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-03-16T23:42:34.125Z","etag":null,"topics":["currency","i18n","input","svelte"],"latest_commit_sha":null,"homepage":"https://svelte-currency-input.fernando.is","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fmaclen.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-09-15T04:25:38.000Z","updated_at":"2025-02-09T17:50:46.000Z","dependencies_parsed_at":"2023-11-10T15:25:58.576Z","dependency_job_id":"2ed90482-c0a9-4d2a-9e6d-72aa322f3767","html_url":"https://github.com/fmaclen/svelte-currency-input","commit_stats":null,"previous_names":[],"tags_count":27,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fmaclen%2Fsvelte-currency-input","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fmaclen%2Fsvelte-currency-input/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fmaclen%2Fsvelte-currency-input/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fmaclen%2Fsvelte-currency-input/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fmaclen","download_url":"https://codeload.github.com/fmaclen/svelte-currency-input/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247608160,"owners_count":20965953,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["currency","i18n","input","svelte"],"created_at":"2025-03-27T14:35:04.683Z","updated_at":"2026-01-02T22:30:15.531Z","avatar_url":"https://github.com/fmaclen.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# svelte-currency-input\n\nA fully-featured currency input component for Svelte 5 that handles formatting, localization, and validation as you type.\n\n![svelte-currency-input examples](static/svelte-currency-input-examples.png)\n\n\u003cp align=\"center\"\u003e\n  👩‍💻 Play with it in the \u003ca href=\"https://svelte-currency-input.fernando.is\" target=\"_blank\"\u003elive demo\u003c/a\u003e\n\u003c/p\u003e\n\n---\n\n- [Features](#features)\n- [Installation](#installation)\n- [Usage](#usage)\n- [How it works](#how-it-works)\n- [API](#api)\n- [Examples](#examples)\n- [Styling](#styling)\n- [Exported utilities](#exported-utilities)\n- [Svelte 4 / migration guide](#svelte-4)\n- [Contributing](#contributing)\n\n## Features\n\n- Formats **positive** and **negative** values\n- Leverages [`Intl.NumberFormat`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat) for **localizing** currency denominations\n- Supports **abbreviations** (k, m, b) for quick input\n- Configurable **decimal precision** with multiple control options\n- **Min/max constraints** with arrow key stepping\n- Custom **prefix** and **suffix** support\n- **Zero built-in styles** — works with Tailwind, vanilla CSS, or any framework\n- Simple, single `\u003cinput\u003e` element (no wrapper)\n- Full **TypeScript** support\n- **Lightweight** — ~3.6KB gzipped with no runtime dependencies\n- API and logic heavily inspired by [@cchanxzy](https://github.com/cchanxzy)'s [react-currency-input-field](https://github.com/cchanxzy/react-currency-input-field)\n\n## Installation\n\n```bash\n# bun\nbun add @canutin/svelte-currency-input\n\n# pnpm\npnpm add @canutin/svelte-currency-input\n\n# npm\nnpm install @canutin/svelte-currency-input\n\n# yarn\nyarn add @canutin/svelte-currency-input\n```\n\n## Usage\n\n```svelte\n\u003cscript lang=\"ts\"\u003e\n\timport { CurrencyInput } from '@canutin/svelte-currency-input';\n\n\tlet value = $state('1234.56');\n\u003c/script\u003e\n\n\u003cCurrencyInput bind:value intlConfig={{ locale: 'en-US', currency: 'USD' }} /\u003e\n```\n\nThe input displays `$1,234.56` while `value` contains the raw string `\"1234.56\"`.\n\n## How it works\n\nThe component renders a single `\u003cinput\u003e` element. The `value` prop is a **string** representing the unformatted number:\n\n- `\"\"` = empty input\n- `\"0\"` = zero\n- `\"1234.56\"` = the number 1234.56\n\nThe formatted display (e.g., `$1,234.56`) is handled internally. For form submissions where you need the raw value, you can add a hidden input:\n\n```svelte\n\u003cform\u003e\n\t\u003cCurrencyInput bind:value name=\"display\" /\u003e\n\t\u003cinput type=\"hidden\" name=\"amount\" {value} /\u003e\n\u003c/form\u003e\n```\n\n## API\n\n### Props\n\n| Prop                     | Type                                    | Default     | Description                                                                     |\n| ------------------------ | --------------------------------------- | ----------- | ------------------------------------------------------------------------------- |\n| `value`                  | `string`                                | `''`        | Bindable raw value (e.g., `\"1234.56\"`)                                          |\n| `intlConfig`             | `IntlConfig`                            | `undefined` | Locale and currency configuration                                               |\n| `prefix`                 | `string`                                | From locale | Override the currency prefix                                                    |\n| `suffix`                 | `string`                                | `''`        | Override the currency suffix                                                    |\n| `decimalSeparator`       | `string`                                | From locale | Override the decimal separator                                                  |\n| `groupSeparator`         | `string`                                | From locale | Override the grouping separator                                                 |\n| `disableGroupSeparators` | `boolean`                               | `false`     | Disable thousand separators                                                     |\n| `allowDecimals`          | `boolean`                               | `true`      | Allow decimal values                                                            |\n| `decimalsLimit`          | `number`                                | `2`         | Max decimal digits while typing                                                 |\n| `decimalScale`           | `number`                                | `undefined` | Pad/trim decimals on blur                                                       |\n| `fixedDecimalLength`     | `number`                                | `undefined` | Fixed decimal input (e.g., `2`: typing `123` → `1.23`)                          |\n| `allowNegativeValue`     | `boolean`                               | `true`      | Allow negative values                                                           |\n| `min`                    | `number`                                | `undefined` | Minimum value (enforced on arrow key step)                                      |\n| `max`                    | `number`                                | `undefined` | Maximum value (enforced on arrow key step)                                      |\n| `maxLength`              | `number`                                | `undefined` | Max characters (excluding formatting)                                           |\n| `step`                   | `number`                                | `undefined` | Arrow key increment/decrement                                                   |\n| `disableAbbreviations`   | `boolean`                               | `false`     | Disable k/m/b abbreviations                                                     |\n| `formatValueOnBlur`      | `boolean`                               | `true`      | Apply formatting when input loses focus                                         |\n| `transformRawValue`      | `(value: string) =\u003e string`             | `undefined` | Transform the raw value before processing                                       |\n| `oninputvalue`           | `(values: CurrencyInputValues) =\u003e void` | `undefined` | Callback on every input change                                                  |\n| `onchangevalue`          | `(values: CurrencyInputValues) =\u003e void` | `undefined` | Callback on blur/commit                                                         |\n| `ref`                    | `HTMLInputElement \\| null`              | `null`      | Bindable reference to the input element                                         |\n| `class`                  | `string`                                | `undefined` | CSS class(es) for the input                                                     |\n| `...restProps`           | `HTMLInputAttributes`                   | —           | All standard input attributes (id, name, placeholder, disabled, required, etc.) |\n\n### Types\n\n```typescript\ninterface IntlConfig {\n\tlocale: string;\n\tcurrency?: string;\n\t// Also accepts other Intl.NumberFormatOptions\n}\n\ninterface CurrencyInputValues {\n\tfloat: number | null; // Parsed number or null if empty\n\tformatted: string; // Display value: \"$1,234.56\"\n\tvalue: string; // Raw value: \"1234.56\"\n}\n```\n\n## Examples\n\n### International currencies\n\n```svelte\n\u003cCurrencyInput bind:value intlConfig={{ locale: 'de-DE', currency: 'EUR' }} /\u003e\n\u003c!-- Displays: 1.234,56 € --\u003e\n```\n\n### Decimal precision\n\n```svelte\n\u003c!-- Limit to 2 decimals while typing, pad to 2 on blur --\u003e\n\u003cCurrencyInput\n\tbind:value\n\tintlConfig={{ locale: 'en-US', currency: 'USD' }}\n\tdecimalsLimit={2}\n\tdecimalScale={2}\n/\u003e\n```\n\n### Min, max, and step\n\n```svelte\n\u003c!-- Use arrow keys to increment/decrement by 10, constrained to 0-100 --\u003e\n\u003cCurrencyInput\n\tbind:value\n\tintlConfig={{ locale: 'en-US', currency: 'USD' }}\n\tmin={0}\n\tmax={100}\n\tstep={10}\n/\u003e\n```\n\n### Custom prefix and suffix\n\n```svelte\n\u003c!-- Points system --\u003e\n\u003cCurrencyInput bind:value suffix=\" pts\" decimalsLimit={0} /\u003e\n\n\u003c!-- Bitcoin --\u003e\n\u003cCurrencyInput bind:value prefix=\"₿ \" decimalsLimit={8} /\u003e\n```\n\n### Abbreviations\n\nType `1k`, `2.5m`, or `1b` to quickly enter large numbers:\n\n```svelte\n\u003cCurrencyInput\n\tbind:value\n\tintlConfig={{ locale: 'en-US', currency: 'USD' }}\n\tplaceholder=\"Try 1k, 2.5m, or 1b\"\n/\u003e\n\u003c!-- Typing \"2.5m\" results in value=\"2500000\" --\u003e\n```\n\n### Callbacks\n\n```svelte\n\u003cCurrencyInput\n\tbind:value\n\tintlConfig={{ locale: 'en-US', currency: 'USD' }}\n\toninputvalue={({ float, formatted, value }) =\u003e {\n\t\tconsole.log('On input:', { float, formatted, value });\n\t}}\n\tonchangevalue={({ float, formatted, value }) =\u003e {\n\t\tconsole.log('On blur:', { float, formatted, value });\n\t}}\n/\u003e\n```\n\n### Input element reference\n\n```svelte\n\u003cscript\u003e\n\tlet inputRef = $state(null);\n\n\tfunction focusInput() {\n\t\tinputRef?.focus();\n\t}\n\u003c/script\u003e\n\n\u003cCurrencyInput bind:ref={inputRef} bind:value /\u003e\n\u003cbutton onclick={focusInput}\u003eFocus\u003c/button\u003e\n```\n\n## Styling\n\nThe component renders a single `\u003cinput\u003e` element with no built-in styles. You can use the `class` prop to style it:\n\n```svelte\n\u003c!-- Tailwind CSS --\u003e\n\u003cCurrencyInput bind:value class=\"rounded border px-3 py-2 focus:ring-2 focus:ring-blue-500\" /\u003e\n\n\u003c!-- Custom CSS class --\u003e\n\u003cCurrencyInput bind:value class=\"my-currency-input\" /\u003e\n```\n\nFor dynamic styling based on value (positive/negative/zero), use the callback:\n\n```svelte\n\u003cscript\u003e\n\tlet value = $state('');\n\tlet colorClass = $state('');\n\n\tfunction updateStyle({ float }) {\n\t\tif (float === null || float === 0) colorClass = 'text-gray-500';\n\t\telse if (float \u003e 0) colorClass = 'text-green-600';\n\t\telse colorClass = 'text-red-600';\n\t}\n\u003c/script\u003e\n\n\u003cCurrencyInput bind:value class=\"border px-3 py-2 {colorClass}\" oninputvalue={updateStyle} /\u003e\n```\n\n## Exported utilities\n\nThe package exports utility functions for use outside the component:\n\n```typescript\nimport {\n\tformatValue,\n\tgetLocaleConfig,\n\tcleanValue,\n\tparseAbbrValue,\n\tabbrValue\n} from '@canutin/svelte-currency-input';\n\n// Format a value with locale\nconst formatted = formatValue({\n\tvalue: '1234.56',\n\tintlConfig: { locale: 'en-US', currency: 'USD' }\n});\n// → \"$1,234.56\"\n\n// Get locale configuration\nconst config = getLocaleConfig({ locale: 'de-DE', currency: 'EUR' });\n// → { decimalSeparator: ',', groupSeparator: '.', prefix: '', suffix: ' €', ... }\n\n// Parse abbreviations\nconst expanded = parseAbbrValue('2.5m', 'en-US');\n// → \"2500000\"\n```\n\n## Svelte 4\n\nFor Svelte 4 support, use the [0.x version](https://github.com/fmaclen/svelte-currency-input/tree/v0.13.0):\n\n```bash\nnpm install @canutin/svelte-currency-input@0\n```\n\nIf you're upgrading from v0.x, see the [migration guide](./MIGRATION.md).\n\n## Contributing\n\nSee [CONTRIBUTING.md](./CONTRIBUTING.md) for development setup, testing, and contribution guidelines.\n\n## License\n\n[MIT](./LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffmaclen%2Fsvelte-currency-input","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffmaclen%2Fsvelte-currency-input","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffmaclen%2Fsvelte-currency-input/lists"}