raqam 0.3.2 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/README.md +25 -9
  2. package/dist/chunk-4BC3KFIL.js +2 -0
  3. package/dist/chunk-4BC3KFIL.js.map +1 -0
  4. package/dist/chunk-4GNLVHAM.js +2 -0
  5. package/dist/chunk-4GNLVHAM.js.map +1 -0
  6. package/dist/chunk-5LYK54TH.js +2 -0
  7. package/dist/chunk-5LYK54TH.js.map +1 -0
  8. package/dist/chunk-7D2IPNCM.cjs +2 -0
  9. package/dist/chunk-7D2IPNCM.cjs.map +1 -0
  10. package/dist/chunk-C5MK5U3F.js +2 -0
  11. package/dist/chunk-C5MK5U3F.js.map +1 -0
  12. package/dist/chunk-CAHEQQ5J.cjs +2 -0
  13. package/dist/chunk-CAHEQQ5J.cjs.map +1 -0
  14. package/dist/chunk-I3H3UMZD.cjs +2 -0
  15. package/dist/chunk-I3H3UMZD.cjs.map +1 -0
  16. package/dist/chunk-LD6OTXXT.js +2 -0
  17. package/dist/chunk-LD6OTXXT.js.map +1 -0
  18. package/dist/chunk-MNYIBO2M.cjs +2 -0
  19. package/dist/chunk-MNYIBO2M.cjs.map +1 -0
  20. package/dist/chunk-MOES3T6R.js +2 -0
  21. package/dist/chunk-MOES3T6R.js.map +1 -0
  22. package/dist/chunk-MUO4XNLX.cjs +2 -0
  23. package/dist/chunk-MUO4XNLX.cjs.map +1 -0
  24. package/dist/chunk-SQWLQ664.js +2 -0
  25. package/dist/chunk-SQWLQ664.js.map +1 -0
  26. package/dist/chunk-TFY7JMI6.js +2 -0
  27. package/dist/chunk-TFY7JMI6.js.map +1 -0
  28. package/dist/chunk-UUHQOMSX.cjs +2 -0
  29. package/dist/chunk-UUHQOMSX.cjs.map +1 -0
  30. package/dist/chunk-UYZYSVT5.cjs +2 -0
  31. package/dist/chunk-UYZYSVT5.cjs.map +1 -0
  32. package/dist/chunk-XJZHLJ2C.cjs +2 -0
  33. package/dist/chunk-XJZHLJ2C.cjs.map +1 -0
  34. package/dist/chunk-ZKLZ7UKZ.cjs +2 -0
  35. package/dist/chunk-ZKLZ7UKZ.cjs.map +1 -0
  36. package/dist/chunk-ZWDI6EPF.js +2 -0
  37. package/dist/chunk-ZWDI6EPF.js.map +1 -0
  38. package/dist/core.cjs +1 -1
  39. package/dist/core.cjs.map +1 -1
  40. package/dist/core.d.cts +68 -295
  41. package/dist/core.d.ts +68 -295
  42. package/dist/core.js +1 -1
  43. package/dist/core.js.map +1 -1
  44. package/dist/index.cjs +1 -1
  45. package/dist/index.cjs.map +1 -1
  46. package/dist/index.d.cts +12 -133
  47. package/dist/index.d.ts +12 -133
  48. package/dist/index.js +1 -1
  49. package/dist/index.js.map +1 -1
  50. package/dist/locales/ar.cjs +1 -35
  51. package/dist/locales/ar.cjs.map +1 -1
  52. package/dist/locales/ar.js +1 -3
  53. package/dist/locales/bn.cjs +1 -35
  54. package/dist/locales/bn.cjs.map +1 -1
  55. package/dist/locales/bn.js +1 -3
  56. package/dist/locales/fa.cjs +1 -37
  57. package/dist/locales/fa.cjs.map +1 -1
  58. package/dist/locales/fa.js +1 -3
  59. package/dist/locales/hi.cjs +1 -35
  60. package/dist/locales/hi.cjs.map +1 -1
  61. package/dist/locales/hi.js +1 -3
  62. package/dist/locales/index.cjs +1 -77
  63. package/dist/locales/index.cjs.map +1 -1
  64. package/dist/locales/index.js +1 -7
  65. package/dist/locales/th.cjs +1 -35
  66. package/dist/locales/th.cjs.map +1 -1
  67. package/dist/locales/th.js +1 -3
  68. package/dist/react.cjs +1 -1
  69. package/dist/react.cjs.map +1 -1
  70. package/dist/react.d.cts +117 -3
  71. package/dist/react.d.ts +117 -3
  72. package/dist/react.js +1 -1
  73. package/dist/react.js.map +1 -1
  74. package/dist/{index-BMFJwudG.d.cts → types-B2ZqkJI-.d.cts} +34 -107
  75. package/dist/{index-BMFJwudG.d.ts → types-B2ZqkJI-.d.ts} +34 -107
  76. package/package.json +28 -6
  77. package/dist/chunk-4AMLNJEK.js +0 -14
  78. package/dist/chunk-4AMLNJEK.js.map +0 -1
  79. package/dist/chunk-7IEJOMYT.js +0 -14
  80. package/dist/chunk-7IEJOMYT.js.map +0 -1
  81. package/dist/chunk-HPUEM7JB.js +0 -14
  82. package/dist/chunk-HPUEM7JB.js.map +0 -1
  83. package/dist/chunk-OLLREWX6.js +0 -16
  84. package/dist/chunk-OLLREWX6.js.map +0 -1
  85. package/dist/chunk-RP3DVBGJ.js +0 -14
  86. package/dist/chunk-RP3DVBGJ.js.map +0 -1
  87. package/dist/chunk-TISOJTKH.js +0 -25
  88. package/dist/chunk-TISOJTKH.js.map +0 -1
@@ -1,7 +1,3 @@
1
- import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import * as React$1 from 'react';
3
- import React__default, { RefObject } from 'react';
4
-
5
1
  interface LocaleInfo {
6
2
  /** Decimal separator for this locale (e.g. "." en-US, "," de-DE, "٫" fa-IR) */
7
3
  decimalSeparator: string;
@@ -44,7 +40,13 @@ interface UseNumberFieldStateOptions {
44
40
  defaultValue?: number | null;
45
41
  /** Fires on every meaningful value change */
46
42
  onChange?: (value: number | null) => void;
47
- /** BCP 47 locale tag (default: browser locale) */
43
+ /**
44
+ * BCP 47 locale tag. When omitted, the runtime default is used — the browser
45
+ * locale on the client, but the host's ICU/OS locale on the server. For SSR,
46
+ * pass an explicit `locale` so the server and first client render format
47
+ * identically; otherwise the initial formatted value can differ and trigger a
48
+ * React hydration mismatch.
49
+ */
48
50
  locale?: string;
49
51
  /** Full Intl.NumberFormatOptions — currency, percent, decimal, etc. */
50
52
  formatOptions?: Intl.NumberFormatOptions;
@@ -147,6 +149,13 @@ interface NumberFieldState {
147
149
  _setLastChangeReason: (reason: ChangeReason) => void;
148
150
  /** Internal: read the current change reason (used by NumberField.Root) */
149
151
  _getLastChangeReason: () => ChangeReason;
152
+ /**
153
+ * Internal: read the display string that matches the value most recently
154
+ * emitted via onChange. Updated synchronously before the state setter, so it is
155
+ * accurate at onChange time (unlike `inputValue`, which still reflects the
156
+ * previous render). Used by NumberField.Root to report `formattedValue`.
157
+ */
158
+ _getLatestDisplay: () => string;
150
159
  /**
151
160
  * Update display string (triggers parse + onChange). `knownValue` overrides
152
161
  * the parsed value when `val` is a formatted string that cannot be reversed
@@ -193,6 +202,10 @@ interface UseNumberFieldProps extends UseNumberFieldStateOptions {
193
202
  stepHoldDelay?: number;
194
203
  /** Initial milliseconds between repeats during press-and-hold (default: 200) */
195
204
  stepHoldInterval?: number;
205
+ /** Accessible label for the increment button (default: "Increase") */
206
+ incrementLabel?: string;
207
+ /** Accessible label for the decrement button (default: "Decrease") */
208
+ decrementLabel?: string;
196
209
  onFocus?: (e: React.FocusEvent<HTMLInputElement>) => void;
197
210
  onBlur?: (e: React.FocusEvent<HTMLInputElement>) => void;
198
211
  /**
@@ -221,7 +234,14 @@ interface NumberFieldAria {
221
234
  hiddenInputProps: React.InputHTMLAttributes<HTMLInputElement> | null;
222
235
  incrementButtonProps: React.ButtonHTMLAttributes<HTMLButtonElement>;
223
236
  decrementButtonProps: React.ButtonHTMLAttributes<HTMLButtonElement>;
224
- descriptionProps: React.HTMLAttributes<HTMLElement>;
237
+ descriptionProps: React.HTMLAttributes<HTMLElement> & {
238
+ /**
239
+ * Registration ref — spread it onto the rendered description element so the
240
+ * input's `aria-describedby` only points here while a description is mounted
241
+ * (mirrors `labelProps.ref`, avoiding a dangling reference otherwise).
242
+ */
243
+ ref?: React.RefCallback<HTMLElement>;
244
+ };
225
245
  errorMessageProps: React.HTMLAttributes<HTMLElement>;
226
246
  }
227
247
  interface ScrubAreaOptions {
@@ -232,8 +252,14 @@ interface ScrubAreaOptions {
232
252
  * - 'both': uses whichever axis has greater movement
233
253
  */
234
254
  direction?: "horizontal" | "vertical" | "both";
235
- /** Pixels of drag movement required for one step (default: 4) */
255
+ /**
256
+ * Pixels of drag movement required for one step (default: 4). Values below 1
257
+ * are clamped to 1 to keep stepping bounded (0 or negative would otherwise
258
+ * loop forever).
259
+ */
236
260
  pixelSensitivity?: number;
261
+ /** Accessible label for the scrub area (default: "Scrub to change value") */
262
+ label?: string;
237
263
  }
238
264
  type StateRenderFn = (props: Record<string, unknown>, state: NumberFieldState) => React.ReactElement;
239
265
  type RenderProp = React.ReactElement | StateRenderFn;
@@ -259,103 +285,4 @@ interface NumberFieldRootProps extends UseNumberFieldProps {
259
285
  }) => void;
260
286
  }
261
287
 
262
- declare function useNumberFieldState(options: UseNumberFieldStateOptions): NumberFieldState;
263
-
264
- declare function useNumberField(props: UseNumberFieldProps, state: NumberFieldState, inputRef: React.RefObject<HTMLInputElement | null>): NumberFieldAria;
265
-
266
- type FormatOptions = Pick<UseNumberFieldStateOptions, "locale" | "formatOptions" | "prefix" | "suffix" | "minimumFractionDigits" | "maximumFractionDigits" | "fixedDecimalScale">;
267
- /**
268
- * Lightweight display-only formatting hook. Returns the formatted string for
269
- * a numeric value using the same Intl.NumberFormat engine as the full input.
270
- *
271
- * Use this when you need to display a formatted number in a read-only context
272
- * (table cells, summaries, labels) without the overhead of a full input state machine.
273
- *
274
- * @example
275
- * const price = useNumberFieldFormat(1234567.89, {
276
- * locale: 'en-US',
277
- * formatOptions: { style: 'currency', currency: 'USD' },
278
- * })
279
- * // price === "$1,234,567.89"
280
- *
281
- * @example
282
- * const pct = useNumberFieldFormat(0.4267, {
283
- * formatOptions: { style: 'percent', maximumFractionDigits: 1 },
284
- * })
285
- * // pct === "42.7%"
286
- */
287
- declare function useNumberFieldFormat(value: number | null, options?: FormatOptions): string;
288
-
289
- interface UseControllableStateOptions<T> {
290
- value?: T;
291
- defaultValue?: T;
292
- onChange?: (value: T) => void;
293
- }
294
- /**
295
- * Manages controlled vs uncontrolled state.
296
- * - If `value` is provided, the component is controlled.
297
- * - Otherwise it manages its own state starting from `defaultValue`.
298
- * Warns in dev mode if the component switches between controlled/uncontrolled.
299
- */
300
- declare function useControllableState<T>({ value, defaultValue, onChange, }: UseControllableStateOptions<T>): [
301
- T | undefined,
302
- (next: T | ((prev: T | undefined) => T)) => void
303
- ];
304
-
305
- interface LabelProps extends React__default.LabelHTMLAttributes<HTMLLabelElement> {
306
- render?: RenderProp;
307
- children?: React__default.ReactNode;
308
- }
309
- interface GroupProps extends React__default.HTMLAttributes<HTMLDivElement> {
310
- render?: RenderProp;
311
- children?: React__default.ReactNode;
312
- }
313
- interface InputProps extends Omit<React__default.InputHTMLAttributes<HTMLInputElement>, "type"> {
314
- render?: RenderProp;
315
- }
316
- interface IncrementProps extends React__default.ButtonHTMLAttributes<HTMLButtonElement> {
317
- render?: RenderProp;
318
- children?: React__default.ReactNode;
319
- }
320
- interface DecrementProps extends React__default.ButtonHTMLAttributes<HTMLButtonElement> {
321
- render?: RenderProp;
322
- children?: React__default.ReactNode;
323
- }
324
- interface DescriptionProps extends React__default.HTMLAttributes<HTMLParagraphElement> {
325
- children?: React__default.ReactNode;
326
- }
327
- interface ErrorMessageProps extends React__default.HTMLAttributes<HTMLParagraphElement> {
328
- children?: React__default.ReactNode;
329
- }
330
- interface FormattedProps extends React__default.HTMLAttributes<HTMLSpanElement> {
331
- render?: RenderProp;
332
- }
333
- declare const NumberField: {
334
- Root: React__default.ForwardRefExoticComponent<NumberFieldRootProps & React__default.RefAttributes<HTMLDivElement>>;
335
- Label: React__default.ForwardRefExoticComponent<LabelProps & React__default.RefAttributes<HTMLLabelElement>>;
336
- Group: React__default.ForwardRefExoticComponent<GroupProps & React__default.RefAttributes<HTMLDivElement>>;
337
- Input: React__default.ForwardRefExoticComponent<InputProps & React__default.RefAttributes<HTMLInputElement>>;
338
- Increment: React__default.ForwardRefExoticComponent<IncrementProps & React__default.RefAttributes<HTMLButtonElement>>;
339
- Decrement: React__default.ForwardRefExoticComponent<DecrementProps & React__default.RefAttributes<HTMLButtonElement>>;
340
- HiddenInput: () => react_jsx_runtime.JSX.Element | null;
341
- ScrubArea: React__default.ForwardRefExoticComponent<ScrubAreaProps & React__default.RefAttributes<HTMLSpanElement>>;
342
- ScrubAreaCursor: React__default.ForwardRefExoticComponent<ScrubAreaCursorProps & React__default.RefAttributes<HTMLSpanElement>>;
343
- Description: React__default.ForwardRefExoticComponent<DescriptionProps & React__default.RefAttributes<HTMLParagraphElement>>;
344
- ErrorMessage: React__default.ForwardRefExoticComponent<ErrorMessageProps & React__default.RefAttributes<HTMLParagraphElement>>;
345
- Formatted: React__default.ForwardRefExoticComponent<FormattedProps & React__default.RefAttributes<HTMLSpanElement>>;
346
- };
347
-
348
- interface NumberFieldContextValue {
349
- state: NumberFieldState;
350
- aria: NumberFieldAria;
351
- inputRef: RefObject<HTMLInputElement | null>;
352
- props: UseNumberFieldProps;
353
- }
354
- declare const NumberFieldContext: React$1.Context<NumberFieldContextValue | null>;
355
- /**
356
- * Hook for sub-components to access the NumberField context.
357
- * Throws if used outside NumberField.Root.
358
- */
359
- declare function useNumberFieldContext(): NumberFieldContextValue;
360
-
361
- export { type CaretBoundary as C, type DigitBlock as D, type FormatResult as F, type LocaleInfo as L, type NumberFieldState as N, type ParseResult as P, type RenderProp as R, type ScrubAreaOptions as S, type UseNumberFieldProps as U, type ChangeReason as a, NumberField as b, type NumberFieldAria as c, NumberFieldContext as d, type NumberFieldContextValue as e, type NumberFieldRootProps as f, type ScrubAreaCursorProps as g, type ScrubAreaProps as h, type StateRenderFn as i, type UseNumberFieldStateOptions as j, useNumberField as k, useNumberFieldContext as l, useNumberFieldFormat as m, useNumberFieldState as n, useControllableState as u };
288
+ export type { CaretBoundary as C, DigitBlock as D, FormatResult as F, LocaleInfo as L, NumberFieldState as N, ParseResult as P, RenderProp as R, ScrubAreaOptions as S, UseNumberFieldProps as U, ChangeReason as a, NumberFieldAria as b, NumberFieldRootProps as c, ScrubAreaCursorProps as d, ScrubAreaProps as e, StateRenderFn as f, UseNumberFieldStateOptions as g };
package/package.json CHANGED
@@ -1,15 +1,20 @@
1
1
  {
2
2
  "name": "raqam",
3
- "version": "0.3.2",
3
+ "version": "0.4.1",
4
4
  "description": "The definitive React number input: live formatting, full i18n, headless, accessible",
5
5
  "type": "module",
6
- "sideEffects": false,
6
+ "sideEffects": [
7
+ "./dist/locales/*.js",
8
+ "./dist/locales/*.cjs",
9
+ "./dist/chunk-*.js",
10
+ "./dist/chunk-*.cjs"
11
+ ],
7
12
  "main": "./dist/index.cjs",
8
13
  "module": "./dist/index.js",
9
14
  "types": "./dist/index.d.ts",
10
15
  "author": "47vigen",
11
16
  "license": "MIT",
12
- "homepage": "https://47vigen.github.io/raqam",
17
+ "homepage": "https://raqam.47vigen.com/",
13
18
  "repository": {
14
19
  "type": "git",
15
20
  "url": "https://github.com/47vigen/raqam"
@@ -29,6 +34,9 @@
29
34
  "react": [
30
35
  "./dist/react.d.ts"
31
36
  ],
37
+ "locales": [
38
+ "./dist/locales/index.d.ts"
39
+ ],
32
40
  "locales/*": [
33
41
  "./dist/locales/*.d.ts"
34
42
  ],
@@ -68,6 +76,16 @@
68
76
  "default": "./dist/react.cjs"
69
77
  }
70
78
  },
79
+ "./locales": {
80
+ "import": {
81
+ "types": "./dist/locales/index.d.ts",
82
+ "default": "./dist/locales/index.js"
83
+ },
84
+ "require": {
85
+ "types": "./dist/locales/index.d.cts",
86
+ "default": "./dist/locales/index.cjs"
87
+ }
88
+ },
71
89
  "./locales/*": {
72
90
  "import": {
73
91
  "types": "./dist/locales/*.d.ts",
@@ -87,13 +105,17 @@
87
105
  "types": "./dist/core.d.cts",
88
106
  "default": "./dist/core.cjs"
89
107
  }
90
- }
108
+ },
109
+ "./package.json": "./package.json"
91
110
  },
92
111
  "files": [
93
112
  "dist",
94
113
  "README.md",
95
114
  "LICENSE"
96
115
  ],
116
+ "engines": {
117
+ "node": ">=20.9"
118
+ },
97
119
  "keywords": [
98
120
  "react",
99
121
  "number",
@@ -164,8 +186,8 @@
164
186
  "test:e2e": "playwright test -c playwright-ct.config.ts",
165
187
  "test:e2e:ui": "playwright test -c playwright-ct.config.ts --ui",
166
188
  "test:e2e:debug": "playwright test -c playwright-ct.config.ts --headed --project=chromium",
167
- "docs:dev": "cd docs && pnpm astro dev",
168
- "docs:build": "pnpm build && cd docs && pnpm astro build",
189
+ "docs:dev": "pnpm --filter raqam-docs dev",
190
+ "docs:build": "pnpm --filter raqam-docs build",
169
191
  "release:beta": "changeset version --snapshot beta && changeset publish --tag beta"
170
192
  }
171
193
  }
@@ -1,14 +0,0 @@
1
- import { registerLocale } from './chunk-TISOJTKH.js';
2
-
3
- // src/locales/ar.ts
4
- registerLocale({
5
- digitBlocks: [
6
- [1632, 1641]
7
- // Arabic-Indic ٠–٩
8
- ]
9
- });
10
- var LOCALE_CODES = ["ar", "ar-EG", "ar-SA", "ar-MA", "ar-DZ", "ar-TN"];
11
-
12
- export { LOCALE_CODES };
13
- //# sourceMappingURL=chunk-4AMLNJEK.js.map
14
- //# sourceMappingURL=chunk-4AMLNJEK.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/locales/ar.ts"],"names":[],"mappings":";;;AAUA,cAAA,CAAe;AAAA,EACb,WAAA,EAAa;AAAA,IACX,CAAC,MAAQ,IAAM;AAAA;AAAA;AAEnB,CAAC,CAAA;AAGM,IAAM,eAAe,CAAC,IAAA,EAAM,SAAS,OAAA,EAAS,OAAA,EAAS,SAAS,OAAO","file":"chunk-4AMLNJEK.js","sourcesContent":["/**\n * Arabic (ar) locale plugin.\n *\n * Registers Arabic-Indic digit block (U+0660–U+0669).\n *\n * Usage:\n * import 'raqam/locales/ar'\n */\nimport { registerLocale } from \"../core/normalizer.js\";\n\nregisterLocale({\n digitBlocks: [\n [0x0660, 0x0669], // Arabic-Indic ٠–٩\n ],\n});\n\n/** BCP 47 locale tags that this plugin covers. */\nexport const LOCALE_CODES = [\"ar\", \"ar-EG\", \"ar-SA\", \"ar-MA\", \"ar-DZ\", \"ar-TN\"] as const;\n"]}
@@ -1,14 +0,0 @@
1
- import { registerLocale } from './chunk-TISOJTKH.js';
2
-
3
- // src/locales/bn.ts
4
- registerLocale({
5
- digitBlocks: [
6
- [2534, 2543]
7
- // Bengali ০–৯
8
- ]
9
- });
10
- var LOCALE_CODES = ["bn", "bn-BD", "bn-IN"];
11
-
12
- export { LOCALE_CODES };
13
- //# sourceMappingURL=chunk-7IEJOMYT.js.map
14
- //# sourceMappingURL=chunk-7IEJOMYT.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/locales/bn.ts"],"names":[],"mappings":";;;AAUA,cAAA,CAAe;AAAA,EACb,WAAA,EAAa;AAAA,IACX,CAAC,MAAQ,IAAM;AAAA;AAAA;AAEnB,CAAC,CAAA;AAGM,IAAM,YAAA,GAAe,CAAC,IAAA,EAAM,OAAA,EAAS,OAAO","file":"chunk-7IEJOMYT.js","sourcesContent":["/**\n * Bengali (bn-BD / bn-IN) locale plugin.\n *\n * Registers Bengali digit block (U+09E6–U+09EF).\n *\n * Usage:\n * import 'raqam/locales/bn'\n */\nimport { registerLocale } from \"../core/normalizer.js\";\n\nregisterLocale({\n digitBlocks: [\n [0x09e6, 0x09ef], // Bengali ০–৯\n ],\n});\n\n/** BCP 47 locale tags that this plugin covers. */\nexport const LOCALE_CODES = [\"bn\", \"bn-BD\", \"bn-IN\"] as const;\n"]}
@@ -1,14 +0,0 @@
1
- import { registerLocale } from './chunk-TISOJTKH.js';
2
-
3
- // src/locales/th.ts
4
- registerLocale({
5
- digitBlocks: [
6
- [3664, 3673]
7
- // Thai ๐–๙
8
- ]
9
- });
10
- var LOCALE_CODES = ["th", "th-TH"];
11
-
12
- export { LOCALE_CODES };
13
- //# sourceMappingURL=chunk-HPUEM7JB.js.map
14
- //# sourceMappingURL=chunk-HPUEM7JB.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/locales/th.ts"],"names":[],"mappings":";;;AAUA,cAAA,CAAe;AAAA,EACb,WAAA,EAAa;AAAA,IACX,CAAC,MAAQ,IAAM;AAAA;AAAA;AAEnB,CAAC,CAAA;AAGM,IAAM,YAAA,GAAe,CAAC,IAAA,EAAM,OAAO","file":"chunk-HPUEM7JB.js","sourcesContent":["/**\n * Thai (th-TH) locale plugin.\n *\n * Registers Thai digit block (U+0E50–U+0E59).\n *\n * Usage:\n * import 'raqam/locales/th'\n */\nimport { registerLocale } from \"../core/normalizer.js\";\n\nregisterLocale({\n digitBlocks: [\n [0x0e50, 0x0e59], // Thai ๐–๙\n ],\n});\n\n/** BCP 47 locale tags that this plugin covers. */\nexport const LOCALE_CODES = [\"th\", \"th-TH\"] as const;\n"]}
@@ -1,16 +0,0 @@
1
- import { registerLocale } from './chunk-TISOJTKH.js';
2
-
3
- // src/locales/fa.ts
4
- registerLocale({
5
- digitBlocks: [
6
- [1776, 1785],
7
- // Extended Arabic-Indic (Persian) ۰–۹
8
- [1632, 1641]
9
- // Arabic-Indic ٠–٩
10
- ]
11
- });
12
- var LOCALE_CODES = ["fa", "fa-IR", "fa-AF"];
13
-
14
- export { LOCALE_CODES };
15
- //# sourceMappingURL=chunk-OLLREWX6.js.map
16
- //# sourceMappingURL=chunk-OLLREWX6.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/locales/fa.ts"],"names":[],"mappings":";;;AAeA,cAAA,CAAe;AAAA,EACb,WAAA,EAAa;AAAA,IACX,CAAC,MAAQ,IAAM,CAAA;AAAA;AAAA,IACf,CAAC,MAAQ,IAAM;AAAA;AAAA;AAEnB,CAAC,CAAA;AAGM,IAAM,YAAA,GAAe,CAAC,IAAA,EAAM,OAAA,EAAS,OAAO","file":"chunk-OLLREWX6.js","sourcesContent":["/**\n * Persian (fa-IR) locale plugin.\n *\n * Registers Extended Arabic-Indic digit block (U+06F0–U+06F9).\n * The ISIRI 9147 keyboard produces these codepoints when number keys are\n * pressed on a Persian layout. This side-effect import enables their\n * normalization to ASCII 0–9 before parsing.\n *\n * Also registers the Arabic-Indic block for mixed-input scenarios.\n *\n * Usage:\n * import 'raqam/locales/fa'\n */\nimport { registerLocale } from \"../core/normalizer.js\";\n\nregisterLocale({\n digitBlocks: [\n [0x06f0, 0x06f9], // Extended Arabic-Indic (Persian) ۰–۹\n [0x0660, 0x0669], // Arabic-Indic ٠–٩\n ],\n});\n\n/** BCP 47 locale tags that this plugin covers. */\nexport const LOCALE_CODES = [\"fa\", \"fa-IR\", \"fa-AF\"] as const;\n"]}
@@ -1,14 +0,0 @@
1
- import { registerLocale } from './chunk-TISOJTKH.js';
2
-
3
- // src/locales/hi.ts
4
- registerLocale({
5
- digitBlocks: [
6
- [2406, 2415]
7
- // Devanagari ०–९
8
- ]
9
- });
10
- var LOCALE_CODES = ["hi", "hi-IN", "mr", "mr-IN", "ne", "ne-NP"];
11
-
12
- export { LOCALE_CODES };
13
- //# sourceMappingURL=chunk-RP3DVBGJ.js.map
14
- //# sourceMappingURL=chunk-RP3DVBGJ.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/locales/hi.ts"],"names":[],"mappings":";;;AAUA,cAAA,CAAe;AAAA,EACb,WAAA,EAAa;AAAA,IACX,CAAC,MAAQ,IAAM;AAAA;AAAA;AAEnB,CAAC,CAAA;AAGM,IAAM,eAAe,CAAC,IAAA,EAAM,SAAS,IAAA,EAAM,OAAA,EAAS,MAAM,OAAO","file":"chunk-RP3DVBGJ.js","sourcesContent":["/**\n * Hindi / Devanagari (hi-IN) locale plugin.\n *\n * Registers Devanagari digit block (U+0966–U+096F).\n *\n * Usage:\n * import 'raqam/locales/hi'\n */\nimport { registerLocale } from \"../core/normalizer.js\";\n\nregisterLocale({\n digitBlocks: [\n [0x0966, 0x096f], // Devanagari ०–९\n ],\n});\n\n/** BCP 47 locale tags that this plugin covers. */\nexport const LOCALE_CODES = [\"hi\", \"hi-IN\", \"mr\", \"mr-IN\", \"ne\", \"ne-NP\"] as const;\n"]}
@@ -1,25 +0,0 @@
1
- // src/core/normalizer.ts
2
- var BUILTIN_DIGIT_BLOCKS = [
3
- [1632, 1641],
4
- // Arabic-Indic (arab)
5
- [1776, 1785],
6
- // Extended Arabic-Indic / Persian (arabext)
7
- [2406, 2415],
8
- // Devanagari / Hindi (deva)
9
- [2534, 2543],
10
- // Bengali (beng)
11
- [3664, 3673]
12
- // Thai (thai)
13
- ];
14
- var registeredBlocks = [...BUILTIN_DIGIT_BLOCKS];
15
- function registerLocale(config) {
16
- if (!config.digitBlocks) return;
17
- for (const block of config.digitBlocks) {
18
- const already = registeredBlocks.some(([s]) => s === block[0]);
19
- if (!already) registeredBlocks.push(block);
20
- }
21
- }
22
-
23
- export { registerLocale };
24
- //# sourceMappingURL=chunk-TISOJTKH.js.map
25
- //# sourceMappingURL=chunk-TISOJTKH.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/core/normalizer.ts"],"names":[],"mappings":";AAMA,IAAM,oBAAA,GAAqC;AAAA,EACzC,CAAC,MAAQ,IAAM,CAAA;AAAA;AAAA,EACf,CAAC,MAAQ,IAAM,CAAA;AAAA;AAAA,EACf,CAAC,MAAQ,IAAM,CAAA;AAAA;AAAA,EACf,CAAC,MAAQ,IAAM,CAAA;AAAA;AAAA,EACf,CAAC,MAAQ,IAAM;AAAA;AACjB,CAAA;AAGA,IAAM,gBAAA,GAAiC,CAAC,GAAG,oBAAoB,CAAA;AAaxD,SAAS,eAAe,MAAA,EAA4B;AACzD,EAAA,IAAI,CAAC,OAAO,WAAA,EAAa;AACzB,EAAA,KAAA,MAAW,KAAA,IAAS,OAAO,WAAA,EAAa;AACtC,IAAA,MAAM,OAAA,GAAU,gBAAA,CAAiB,IAAA,CAAK,CAAC,CAAC,CAAC,CAAA,KAAM,CAAA,KAAM,KAAA,CAAM,CAAC,CAAC,CAAA;AAC7D,IAAA,IAAI,CAAC,OAAA,EAAS,gBAAA,CAAiB,IAAA,CAAK,KAAK,CAAA;AAAA,EAC3C;AACF","file":"chunk-TISOJTKH.js","sourcesContent":["import type { DigitBlock } from \"./types.js\";\n\n// ── Built-in digit blocks ────────────────────────────────────────────────────\n// These cover the digit systems required by the spec.\n// Additional blocks can be registered via registerLocale().\n\nconst BUILTIN_DIGIT_BLOCKS: DigitBlock[] = [\n [0x0660, 0x0669], // Arabic-Indic (arab)\n [0x06f0, 0x06f9], // Extended Arabic-Indic / Persian (arabext)\n [0x0966, 0x096f], // Devanagari / Hindi (deva)\n [0x09e6, 0x09ef], // Bengali (beng)\n [0x0e50, 0x0e59], // Thai (thai)\n];\n\n// Mutable registry — locale plugins can add blocks here\nconst registeredBlocks: DigitBlock[] = [...BUILTIN_DIGIT_BLOCKS];\n\n// ── Public API ────────────────────────────────────────────────────────────────\n\nexport interface LocaleConfig {\n /** Extra digit block ranges to register */\n digitBlocks?: DigitBlock[];\n}\n\n/**\n * Register additional digit blocks (called by locale plugins as a side effect).\n * Duplicate ranges are silently ignored.\n */\nexport function registerLocale(config: LocaleConfig): void {\n if (!config.digitBlocks) return;\n for (const block of config.digitBlocks) {\n const already = registeredBlocks.some(([s]) => s === block[0]);\n if (!already) registeredBlocks.push(block);\n }\n}\n\n/**\n * Normalise any Unicode decimal digit in `input` to its ASCII equivalent (0–9).\n * Non-digit characters pass through unchanged.\n */\nexport function normalizeDigits(input: string): string {\n // Fast path: if there are no non-ASCII chars, return as-is\n if (!/[^\\u0020-\\u007e]/.test(input)) return input;\n\n return input.replace(/\\p{Nd}/gu, (ch) => {\n const code = ch.codePointAt(0)!;\n for (const [start, end] of registeredBlocks) {\n if (code >= start && code <= end) {\n return String(code - start);\n }\n }\n // Fallback: let JS try to parse it as a decimal digit\n const digit = Number.parseInt(ch, 10);\n return Number.isNaN(digit) ? ch : String(digit);\n });\n}\n\n/**\n * Inverse of {@link normalizeDigits}: map ASCII digits 0–9 to the locale's\n * native digit block (identified by its \"zero\" character). No-op when the\n * locale already uses ASCII digits. Used to keep intermediate (still-typing)\n * display strings in the user's native script.\n */\nexport function localizeDigits(input: string, zero: string): string {\n if (!zero || zero === \"0\") return input;\n const base = zero.codePointAt(0);\n if (base === undefined) return input;\n return input.replace(/[0-9]/g, (d) => String.fromCodePoint(base + (d.charCodeAt(0) - 48)));\n}\n\n/**\n * Returns true if the character is a non-Latin Unicode decimal digit\n * (i.e. would need normalization).\n */\nexport function isNonLatinDigit(ch: string): boolean {\n const code = ch.codePointAt(0);\n if (code === undefined) return false;\n if (code >= 0x30 && code <= 0x39) return false; // ASCII 0-9\n for (const [start, end] of registeredBlocks) {\n if (code >= start && code <= end) return true;\n }\n return false;\n}\n"]}