@ethisyscore/core-utils 1.92.1 → 1.94.0

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.
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Framework-agnostic number DISPLAY formatting.
3
+ *
4
+ * Pure helpers for rendering plain numeric values and ratios as strings, with a
5
+ * deterministic `en-GB` fallback locale so output is machine-stable regardless
6
+ * of the host OS locale - the same principle as the money and date seams.
7
+ *
8
+ * It is pure - no React, no host access - so it lives in core-utils behind the
9
+ * `@ethisyscore/core-utils/number` sub-path.
10
+ */
11
+ /**
12
+ * Deterministic fallback locale. Matches the money/date seams so numbers render
13
+ * consistently when no explicit locale is supplied, and so output does not drift
14
+ * with the OS locale of whatever host renders it.
15
+ */
16
+ declare const NUMBER_FALLBACK_LOCALE = "en-GB";
17
+ /**
18
+ * Formats a numeric value with grouping and a fixed number of decimal places via
19
+ * `Intl.NumberFormat`. Returns an em-dash (`"—"`) for null/undefined so an
20
+ * absent value renders as a readable placeholder rather than `"NaN"` or `"null"`.
21
+ *
22
+ * Defaults to two decimal places in {@link NUMBER_FALLBACK_LOCALE}.
23
+ */
24
+ declare function formatNumber(value: number | null | undefined, options?: {
25
+ decimalPlaces?: number;
26
+ locale?: string;
27
+ }): string;
28
+ /**
29
+ * Formats a RATIO as a percentage string with a fixed number of decimal places -
30
+ * e.g. `0.1234` -> `"12.34%"`. The input is a ratio, not an already-scaled
31
+ * percentage.
32
+ *
33
+ * Uses `toFixed` (no grouping) rather than `Intl` percent style so output is a
34
+ * plain fixed-decimal percentage, matching what callers expect on compact labels.
35
+ * Defaults to two decimal places.
36
+ */
37
+ declare function formatPercent(ratio: number, options?: {
38
+ decimalPlaces?: number;
39
+ }): string;
40
+
41
+ export { NUMBER_FALLBACK_LOCALE, formatNumber, formatPercent };
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Framework-agnostic number DISPLAY formatting.
3
+ *
4
+ * Pure helpers for rendering plain numeric values and ratios as strings, with a
5
+ * deterministic `en-GB` fallback locale so output is machine-stable regardless
6
+ * of the host OS locale - the same principle as the money and date seams.
7
+ *
8
+ * It is pure - no React, no host access - so it lives in core-utils behind the
9
+ * `@ethisyscore/core-utils/number` sub-path.
10
+ */
11
+ /**
12
+ * Deterministic fallback locale. Matches the money/date seams so numbers render
13
+ * consistently when no explicit locale is supplied, and so output does not drift
14
+ * with the OS locale of whatever host renders it.
15
+ */
16
+ declare const NUMBER_FALLBACK_LOCALE = "en-GB";
17
+ /**
18
+ * Formats a numeric value with grouping and a fixed number of decimal places via
19
+ * `Intl.NumberFormat`. Returns an em-dash (`"—"`) for null/undefined so an
20
+ * absent value renders as a readable placeholder rather than `"NaN"` or `"null"`.
21
+ *
22
+ * Defaults to two decimal places in {@link NUMBER_FALLBACK_LOCALE}.
23
+ */
24
+ declare function formatNumber(value: number | null | undefined, options?: {
25
+ decimalPlaces?: number;
26
+ locale?: string;
27
+ }): string;
28
+ /**
29
+ * Formats a RATIO as a percentage string with a fixed number of decimal places -
30
+ * e.g. `0.1234` -> `"12.34%"`. The input is a ratio, not an already-scaled
31
+ * percentage.
32
+ *
33
+ * Uses `toFixed` (no grouping) rather than `Intl` percent style so output is a
34
+ * plain fixed-decimal percentage, matching what callers expect on compact labels.
35
+ * Defaults to two decimal places.
36
+ */
37
+ declare function formatPercent(ratio: number, options?: {
38
+ decimalPlaces?: number;
39
+ }): string;
40
+
41
+ export { NUMBER_FALLBACK_LOCALE, formatNumber, formatPercent };
@@ -0,0 +1,19 @@
1
+ // src/number/format.ts
2
+ var NUMBER_FALLBACK_LOCALE = "en-GB";
3
+ function formatNumber(value, options) {
4
+ if (value == null) {
5
+ return "\u2014";
6
+ }
7
+ const dp = options?.decimalPlaces ?? 2;
8
+ return new Intl.NumberFormat(options?.locale ?? NUMBER_FALLBACK_LOCALE, {
9
+ minimumFractionDigits: dp,
10
+ maximumFractionDigits: dp
11
+ }).format(value);
12
+ }
13
+ function formatPercent(ratio, options) {
14
+ return `${(ratio * 100).toFixed(options?.decimalPlaces ?? 2)}%`;
15
+ }
16
+
17
+ export { NUMBER_FALLBACK_LOCALE, formatNumber, formatPercent };
18
+ //# sourceMappingURL=index.js.map
19
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/number/format.ts"],"names":[],"mappings":";AAgBO,IAAM,sBAAA,GAAyB;AAS/B,SAAS,YAAA,CACd,OACA,OAAA,EACQ;AACR,EAAA,IAAI,SAAS,IAAA,EAAM;AACjB,IAAA,OAAO,QAAA;AAAA,EACT;AAEA,EAAA,MAAM,EAAA,GAAK,SAAS,aAAA,IAAiB,CAAA;AACrC,EAAA,OAAO,IAAI,IAAA,CAAK,YAAA,CAAa,OAAA,EAAS,UAAU,sBAAA,EAAwB;AAAA,IACtE,qBAAA,EAAuB,EAAA;AAAA,IACvB,qBAAA,EAAuB;AAAA,GACxB,CAAA,CAAE,MAAA,CAAO,KAAK,CAAA;AACjB;AAWO,SAAS,aAAA,CAAc,OAAe,OAAA,EAA8C;AACzF,EAAA,OAAO,IAAI,KAAA,GAAQ,GAAA,EAAK,QAAQ,OAAA,EAAS,aAAA,IAAiB,CAAC,CAAC,CAAA,CAAA,CAAA;AAC9D","file":"index.js","sourcesContent":["/**\n * Framework-agnostic number DISPLAY formatting.\n *\n * Pure helpers for rendering plain numeric values and ratios as strings, with a\n * deterministic `en-GB` fallback locale so output is machine-stable regardless\n * of the host OS locale - the same principle as the money and date seams.\n *\n * It is pure - no React, no host access - so it lives in core-utils behind the\n * `@ethisyscore/core-utils/number` sub-path.\n */\n\n/**\n * Deterministic fallback locale. Matches the money/date seams so numbers render\n * consistently when no explicit locale is supplied, and so output does not drift\n * with the OS locale of whatever host renders it.\n */\nexport const NUMBER_FALLBACK_LOCALE = \"en-GB\";\n\n/**\n * Formats a numeric value with grouping and a fixed number of decimal places via\n * `Intl.NumberFormat`. Returns an em-dash (`\"—\"`) for null/undefined so an\n * absent value renders as a readable placeholder rather than `\"NaN\"` or `\"null\"`.\n *\n * Defaults to two decimal places in {@link NUMBER_FALLBACK_LOCALE}.\n */\nexport function formatNumber(\n value: number | null | undefined,\n options?: { decimalPlaces?: number; locale?: string },\n): string {\n if (value == null) {\n return \"—\";\n }\n\n const dp = options?.decimalPlaces ?? 2;\n return new Intl.NumberFormat(options?.locale ?? NUMBER_FALLBACK_LOCALE, {\n minimumFractionDigits: dp,\n maximumFractionDigits: dp,\n }).format(value);\n}\n\n/**\n * Formats a RATIO as a percentage string with a fixed number of decimal places -\n * e.g. `0.1234` -> `\"12.34%\"`. The input is a ratio, not an already-scaled\n * percentage.\n *\n * Uses `toFixed` (no grouping) rather than `Intl` percent style so output is a\n * plain fixed-decimal percentage, matching what callers expect on compact labels.\n * Defaults to two decimal places.\n */\nexport function formatPercent(ratio: number, options?: { decimalPlaces?: number }): string {\n return `${(ratio * 100).toFixed(options?.decimalPlaces ?? 2)}%`;\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ethisyscore/core-utils",
3
- "version": "1.92.1",
3
+ "version": "1.94.0",
4
4
  "description": "Framework-agnostic utilities shared by the EthisysCore monolith and plugins: date/time/duration helpers (over date-fns), RFC 6902 JSON Patch generate/apply (over mutative), and list-response envelope normalisation. Pure TypeScript; no React or MUI. The dayjs-backed picker helper lives behind the ./date/dayjs sub-path so the core entry stays dayjs-free.",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",
@@ -41,6 +41,11 @@
41
41
  "types": "./dist/money/index.d.ts",
42
42
  "import": "./dist/money/index.js",
43
43
  "require": "./dist/money/index.cjs"
44
+ },
45
+ "./number": {
46
+ "types": "./dist/number/index.d.ts",
47
+ "import": "./dist/number/index.js",
48
+ "require": "./dist/number/index.cjs"
44
49
  }
45
50
  },
46
51
  "files": [