@uxf/localize 11.124.0 → 11.126.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.
- package/README.md +23 -19
- package/package.json +5 -5
- package/src/format-money/format-money.js +5 -1
- package/src/format-money/format-money.test.js +7 -0
- package/src/format-number/format-number.js +5 -2
- package/src/format-number/format-number.test.js +7 -0
- package/src/format-percentage/format-percentage.test.js +5 -0
- package/src/types.d.ts +3 -0
- package/src/utils/apply-sign-to-pattern.d.ts +1 -0
- package/src/utils/apply-sign-to-pattern.js +5 -0
- package/src/utils/apply-sign-to-pattern.test.d.ts +1 -0
- package/src/utils/apply-sign-to-pattern.test.js +17 -0
package/README.md
CHANGED
|
@@ -169,6 +169,7 @@ const formatNumber = useFormatNumber();
|
|
|
169
169
|
|
|
170
170
|
formatNumber(2000.78); // 2 001 (default precision 0)
|
|
171
171
|
formatNumber(2000.78, { precision: 2 }); // 2 000,78
|
|
172
|
+
formatNumber(2000, { showPlusSign: true }); // +2 000 (+ only on positive values)
|
|
172
173
|
|
|
173
174
|
<FormatNumber value={2000.78} />;
|
|
174
175
|
```
|
|
@@ -219,6 +220,7 @@ formatMoney({ amount: "2000.78", currency: "USD" }); // 2 001 $
|
|
|
219
220
|
formatMoney({ amount: "2000.78", currency: "CZK" }, { precision: 1 }); // 2 000,8 Kč
|
|
220
221
|
formatMoney({ amount: "2000.78", currency: "CZK" }, { precision: 1, preferIsoCode: true }); // 2 000,8 CZK
|
|
221
222
|
formatMoney({ amount: "2000.78", currency: "CZK" }, { precision: 1, hideSymbol: true }); // 2 000,8
|
|
223
|
+
formatMoney({ amount: "500", currency: "CZK" }, { showPlusSign: true }); // +500 Kč (+ only on positive values)
|
|
222
224
|
|
|
223
225
|
<FormatMoney money={{ amount: "2000.78", currency: "CZK" }} />;
|
|
224
226
|
```
|
|
@@ -236,6 +238,7 @@ formatPercentage(0.782); // 78 % (default precision 0)
|
|
|
236
238
|
formatPercentage(0.782, null, { precision: 2 }); // 78,20 %
|
|
237
239
|
formatPercentage(0.782, "up"); // 79 %
|
|
238
240
|
formatPercentage(0.788, "down"); // 78 %
|
|
241
|
+
formatPercentage(0.5, null, { showPlusSign: true }); // +50 % (+ only on positive values)
|
|
239
242
|
|
|
240
243
|
<FormatPercentage roundingType="up" value={0.782} />;
|
|
241
244
|
```
|
|
@@ -268,25 +271,25 @@ createLocalize<DT extends string = DateTimes, T extends string = Times, Locales
|
|
|
268
271
|
|
|
269
272
|
Returns an object with the following members:
|
|
270
273
|
|
|
271
|
-
| Member
|
|
272
|
-
|
|
|
273
|
-
| `LocalizeProvider`
|
|
274
|
-
| `useLocaleConfig`
|
|
275
|
-
| `formatNumber`
|
|
276
|
-
| `useFormatNumber`
|
|
277
|
-
| `FormatNumber`
|
|
278
|
-
| `formatMoney`
|
|
279
|
-
| `useFormatMoney`
|
|
280
|
-
| `FormatMoney`
|
|
281
|
-
| `formatPercentage`
|
|
282
|
-
| `useFormatPercentage` | `() => (value, roundingType?, options?) => string`
|
|
283
|
-
| `FormatPercentage`
|
|
284
|
-
| `formatDateTime`
|
|
285
|
-
| `useFormatDateTime`
|
|
286
|
-
| `FormatDateTime`
|
|
287
|
-
| `formatTime`
|
|
288
|
-
| `useFormatTime`
|
|
289
|
-
| `FormatTime`
|
|
274
|
+
| Member | Signature | Notes |
|
|
275
|
+
| --------------------- | ---------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
|
|
276
|
+
| `LocalizeProvider` | `Provider<string>` | React context provider; `value` is the active locale key. |
|
|
277
|
+
| `useLocaleConfig` | `() => LocalizeConfig<DT, T>` | Returns the config for the current locale. |
|
|
278
|
+
| `formatNumber` | `(locale, value, options?) => string` | `options: { precision?, showPlusSign? }`. |
|
|
279
|
+
| `useFormatNumber` | `() => (value, options?) => string` | Locale from context. |
|
|
280
|
+
| `FormatNumber` | `FC<{ value; options? }>` | |
|
|
281
|
+
| `formatMoney` | `(locale, money, options?) => string` | `options: { hideSymbol?, precision?, preferIsoCode?, showPlusSign? }`. |
|
|
282
|
+
| `useFormatMoney` | `() => (money, options?) => string` | Locale from context. |
|
|
283
|
+
| `FormatMoney` | `FC<{ money; options? }>` | |
|
|
284
|
+
| `formatPercentage` | `(locale, value, roundingType?, options?) => string` | `roundingType: "nearest" \| "up" \| "down" \| null`; `options: { precision?, showPlusSign? }`. |
|
|
285
|
+
| `useFormatPercentage` | `() => (value, roundingType?, options?) => string` | Locale from context. |
|
|
286
|
+
| `FormatPercentage` | `FC<{ value; roundingType?; options? }>` | |
|
|
287
|
+
| `formatDateTime` | `(locale, value, format, timeZone?) => string` | `value: DateValue`; default `timeZone` is `Europe/Prague`. |
|
|
288
|
+
| `useFormatDateTime` | `() => (value, format) => string` | No `timeZone` param (fixed to default). |
|
|
289
|
+
| `FormatDateTime` | `FC<{ value; format; timeZone? }>` | |
|
|
290
|
+
| `formatTime` | `(locale, value, format) => string` | `value: TimeString`. |
|
|
291
|
+
| `useFormatTime` | `() => (value, format) => string` | Locale from context. |
|
|
292
|
+
| `FormatTime` | `FC<{ value; format }>` | |
|
|
290
293
|
|
|
291
294
|
### Exported types
|
|
292
295
|
|
|
@@ -305,6 +308,7 @@ Returns an object with the following members:
|
|
|
305
308
|
- **Time zone defaults to `Europe/Prague`** for date/time formatting. The `useFormatDateTime` hook is fixed to that default; to override, use the standalone `formatDateTime(locale, value, format, timeZone)` or the `FormatDateTime` component's `timeZone` prop.
|
|
306
309
|
- **Date-only strings** (`"YYYY-MM-DD"`) are parsed as midnight in the target time zone, while `Date` instances represent a concrete instant and are shifted into that zone — the same wall-clock string can render differently depending on the input form.
|
|
307
310
|
- **Currency patterns** use currency.js placeholders: `#` = amount, `!` = symbol. Built-in defaults exist for `EUR` and `USD`; `specialCases` in the config override per currency; otherwise a plain `# <symbol>` pattern is used, and `preferIsoCode` forces the ISO code instead of the symbol.
|
|
311
|
+
- **`showPlusSign` only adds `+`** to a positive, non-zero **final** value (e.g. `+500 Kč`, `+50 %`). It never touches the negative sign — `-` is always shown regardless (handled by currency.js `negativePattern`) — and a value that rounds to `0` stays unsigned. Matches `Intl.NumberFormat`'s `signDisplay: "exceptZero"`.
|
|
308
312
|
- **Separators are non-breaking spaces** in some locales (e.g. `cs`), so `"2 001"` contains ` `, not a regular space.
|
|
309
313
|
|
|
310
314
|
## Links
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uxf/localize",
|
|
3
|
-
"version": "11.
|
|
3
|
+
"version": "11.126.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -19,8 +19,8 @@
|
|
|
19
19
|
"currency.js": "2.0.4"
|
|
20
20
|
},
|
|
21
21
|
"peerDependencies": {
|
|
22
|
-
"@uxf/core": "11.
|
|
23
|
-
"@uxf/core-react": "11.
|
|
22
|
+
"@uxf/core": "11.126.0",
|
|
23
|
+
"@uxf/core-react": "11.126.0",
|
|
24
24
|
"dayjs": "^1.11.21",
|
|
25
25
|
"react": ">=18.2.0",
|
|
26
26
|
"react-dom": ">=18.2.0"
|
|
@@ -28,8 +28,8 @@
|
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"@types/react": "18.3.31",
|
|
30
30
|
"@types/react-dom": "18.3.7",
|
|
31
|
-
"@uxf/core": "11.
|
|
32
|
-
"@uxf/core-react": "11.
|
|
31
|
+
"@uxf/core": "11.126.0",
|
|
32
|
+
"@uxf/core-react": "11.126.0",
|
|
33
33
|
"dayjs": "^1.11.21",
|
|
34
34
|
"react": "18.3.1",
|
|
35
35
|
"react-dom": "18.3.1"
|
|
@@ -9,6 +9,7 @@ const empty_object_1 = require("@uxf/core/constants/empty-object");
|
|
|
9
9
|
const currency_js_1 = __importDefault(require("currency.js"));
|
|
10
10
|
const react_1 = require("react");
|
|
11
11
|
const context_1 = require("../context/context");
|
|
12
|
+
const apply_sign_to_pattern_1 = require("../utils/apply-sign-to-pattern");
|
|
12
13
|
const curry_1 = require("../utils/curry");
|
|
13
14
|
const money_defaults_1 = require("../utils/money-defaults");
|
|
14
15
|
const defaultPatterns = {
|
|
@@ -32,14 +33,17 @@ function createFormatMoney(localizeConfigs) {
|
|
|
32
33
|
: !(options === null || options === void 0 ? void 0 : options.preferIsoCode)
|
|
33
34
|
? currentPatterns
|
|
34
35
|
: defaultPatterns;
|
|
36
|
+
const amount = (0, currency_js_1.default)(money.amount, { precision });
|
|
37
|
+
const pattern = (0, apply_sign_to_pattern_1._applySignToPattern)(patterns.pattern, amount.value, options === null || options === void 0 ? void 0 : options.showPlusSign);
|
|
35
38
|
const formatOptions = {
|
|
36
39
|
...patterns,
|
|
40
|
+
pattern,
|
|
37
41
|
decimal: config.decimalSeparator,
|
|
38
42
|
separator: config.thousandsSeparator,
|
|
39
43
|
precision,
|
|
40
44
|
symbol,
|
|
41
45
|
};
|
|
42
|
-
return
|
|
46
|
+
return amount.format(formatOptions);
|
|
43
47
|
};
|
|
44
48
|
}
|
|
45
49
|
function createUseFormatMoney(localizeConfigs) {
|
|
@@ -28,4 +28,11 @@ describe("money formatter", function () {
|
|
|
28
28
|
expect(formatMoneyWithLocales("en", { amount: "2000.78", currency: "USD" }, { precision: 1, preferIsoCode: true })).toBe("2,000.8\xa0USD");
|
|
29
29
|
expect(formatMoneyWithLocales("en", { amount: "2000.78", currency: "USD" }, { precision: 1, hideSymbol: true })).toBe("2,000.8");
|
|
30
30
|
});
|
|
31
|
+
it("format money with sign", function () {
|
|
32
|
+
expect(formatMoneyWithLocales("cs", { amount: "500", currency: "CZK" }, { showPlusSign: true })).toBe("+500\xa0Kč");
|
|
33
|
+
expect(formatMoneyWithLocales("cs", { amount: "-500", currency: "CZK" }, { showPlusSign: true })).toBe("-500\xa0Kč");
|
|
34
|
+
expect(formatMoneyWithLocales("cs", { amount: "0", currency: "CZK" }, { showPlusSign: true })).toBe("0\xa0Kč");
|
|
35
|
+
expect(formatMoneyWithLocales("cs", { amount: "500", currency: "CZK" }, { showPlusSign: true, hideSymbol: true })).toBe("+500");
|
|
36
|
+
expect(formatMoneyWithLocales("cs", { amount: "500", currency: "CZK" }, { showPlusSign: true, preferIsoCode: true })).toBe("+500\xa0CZK");
|
|
37
|
+
});
|
|
31
38
|
});
|
|
@@ -8,14 +8,17 @@ exports.createUseFormatNumber = createUseFormatNumber;
|
|
|
8
8
|
const currency_js_1 = __importDefault(require("currency.js"));
|
|
9
9
|
const react_1 = require("react");
|
|
10
10
|
const context_1 = require("../context/context");
|
|
11
|
+
const apply_sign_to_pattern_1 = require("../utils/apply-sign-to-pattern");
|
|
11
12
|
const curry_1 = require("../utils/curry");
|
|
12
13
|
const map_options_1 = require("../utils/map-options");
|
|
13
14
|
function createFormatNumber(localizeConfigs) {
|
|
14
15
|
return (locale, value, options) => {
|
|
15
16
|
var _a;
|
|
16
17
|
const precision = (_a = options === null || options === void 0 ? void 0 : options.precision) !== null && _a !== void 0 ? _a : 0;
|
|
17
|
-
const
|
|
18
|
-
|
|
18
|
+
const amount = (0, currency_js_1.default)(value, { precision });
|
|
19
|
+
const base = (0, map_options_1._mapOptions)(localizeConfigs[locale].number);
|
|
20
|
+
const pattern = (0, apply_sign_to_pattern_1._applySignToPattern)(base.pattern, amount.value, options === null || options === void 0 ? void 0 : options.showPlusSign);
|
|
21
|
+
return amount.format({ ...base, pattern, precision });
|
|
19
22
|
};
|
|
20
23
|
}
|
|
21
24
|
function createUseFormatNumber(localizeConfigs) {
|
|
@@ -16,4 +16,11 @@ describe("number formatter", function () {
|
|
|
16
16
|
expect(formatNumberWithLocales("en", 2000.78)).toBe("2,001");
|
|
17
17
|
expect(formatNumberWithLocales("en", 2000.78, { precision: 2 })).toBe("2,000.78");
|
|
18
18
|
});
|
|
19
|
+
it("format number with sign", function () {
|
|
20
|
+
expect(formatNumberWithLocales("cs", 2000, { showPlusSign: true })).toBe("+2\xa0000");
|
|
21
|
+
expect(formatNumberWithLocales("cs", -2000, { showPlusSign: true })).toBe("-2\xa0000");
|
|
22
|
+
expect(formatNumberWithLocales("cs", 0, { showPlusSign: true })).toBe("0");
|
|
23
|
+
expect(formatNumberWithLocales("cs", 0.4, { showPlusSign: true })).toBe("0");
|
|
24
|
+
expect(formatNumberWithLocales("cs", 0.04, { showPlusSign: true, precision: 2 })).toBe("+0,04");
|
|
25
|
+
});
|
|
19
26
|
});
|
|
@@ -22,4 +22,9 @@ describe("percentage formatter", function () {
|
|
|
22
22
|
expect(formatPercentageWithLocales("en", 0.782, "up")).toBe("79\xa0%");
|
|
23
23
|
expect(formatPercentageWithLocales("en", 0.788, "down")).toBe("78\xa0%");
|
|
24
24
|
});
|
|
25
|
+
it("format percentage with sign", function () {
|
|
26
|
+
expect(formatPercentageWithLocales("cs", 0.5, null, { showPlusSign: true })).toBe("+50\xa0%");
|
|
27
|
+
expect(formatPercentageWithLocales("cs", -0.5, null, { showPlusSign: true })).toBe("-50\xa0%");
|
|
28
|
+
expect(formatPercentageWithLocales("cs", 0, null, { showPlusSign: true })).toBe("0\xa0%");
|
|
29
|
+
});
|
|
25
30
|
});
|
package/src/types.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { FC, Provider } from "react";
|
|
|
4
4
|
import { TimeZone as CoreTimeZone } from "./utils/time-zone";
|
|
5
5
|
export type FormatNumberOptions = {
|
|
6
6
|
precision?: number;
|
|
7
|
+
showPlusSign?: boolean;
|
|
7
8
|
};
|
|
8
9
|
export type FormatNumberFunction<Locales extends string> = (locale: Locales, value: number, options?: FormatNumberOptions) => string;
|
|
9
10
|
export type UseFormatNumberFunction = () => (value: number, options?: FormatNumberOptions) => string;
|
|
@@ -21,6 +22,7 @@ export type FormatMoneyOptions = {
|
|
|
21
22
|
hideSymbol?: boolean;
|
|
22
23
|
precision?: number;
|
|
23
24
|
preferIsoCode?: boolean;
|
|
25
|
+
showPlusSign?: boolean;
|
|
24
26
|
};
|
|
25
27
|
export type FormatMoneyFunction<Locales extends string> = (locale: Locales, money: Money, options?: FormatMoneyOptions) => string;
|
|
26
28
|
export type UseFormatMoneyFunction = () => (money: Money, options?: FormatMoneyOptions) => string;
|
|
@@ -31,6 +33,7 @@ export type FormatMoneyComponent = FC<{
|
|
|
31
33
|
export type RoundingType = "nearest" | "up" | "down";
|
|
32
34
|
export type FormatPercentageOptions = {
|
|
33
35
|
precision?: number;
|
|
36
|
+
showPlusSign?: boolean;
|
|
34
37
|
};
|
|
35
38
|
export type FormatPercentageFunction<Locales extends string> = (locale: Locales, value: number, roundingType?: RoundingType | null, options?: FormatPercentageOptions) => string;
|
|
36
39
|
export type UseFormatPercentageFunction = () => (value: number, roundingType?: RoundingType | null, options?: FormatPercentageOptions) => string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const _applySignToPattern: (pattern: string | undefined, value: number, showPlusSign?: boolean) => string | undefined;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports._applySignToPattern = void 0;
|
|
4
|
+
const _applySignToPattern = (pattern, value, showPlusSign) => (pattern !== undefined && showPlusSign && value > 0 ? `+${pattern}` : pattern);
|
|
5
|
+
exports._applySignToPattern = _applySignToPattern;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const apply_sign_to_pattern_1 = require("./apply-sign-to-pattern");
|
|
4
|
+
describe("_applySignToPattern", () => {
|
|
5
|
+
it("prepends + to a positive value when showPlusSign is enabled", () => {
|
|
6
|
+
expect((0, apply_sign_to_pattern_1._applySignToPattern)("#", 500, true)).toBe("+#");
|
|
7
|
+
expect((0, apply_sign_to_pattern_1._applySignToPattern)("#\xa0!", 500, true)).toBe("+#\xa0!");
|
|
8
|
+
});
|
|
9
|
+
it("does not touch zero or negative values", () => {
|
|
10
|
+
expect((0, apply_sign_to_pattern_1._applySignToPattern)("#", 0, true)).toBe("#");
|
|
11
|
+
expect((0, apply_sign_to_pattern_1._applySignToPattern)("#", -500, true)).toBe("#");
|
|
12
|
+
});
|
|
13
|
+
it("returns the pattern unchanged when showPlusSign is falsy", () => {
|
|
14
|
+
expect((0, apply_sign_to_pattern_1._applySignToPattern)("#", 500)).toBe("#");
|
|
15
|
+
expect((0, apply_sign_to_pattern_1._applySignToPattern)("#", 500, false)).toBe("#");
|
|
16
|
+
});
|
|
17
|
+
});
|