@cosmicdrift/kumiko-renderer-web 0.163.2 → 0.164.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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cosmicdrift/kumiko-renderer-web",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.164.0",
|
|
4
4
|
"description": "Web-platform bindings for @cosmicdrift/kumiko-renderer. HTML default-primitives, browser history-based navigation, EventSource-backed live events, and a one-call createKumikoApp that mounts the whole stack via react-dom.",
|
|
5
5
|
"license": "BUSL-1.1",
|
|
6
6
|
"author": "Marc Frost <marc@cosmicdriftgamestudio.com>",
|
|
@@ -16,9 +16,9 @@
|
|
|
16
16
|
"./styles.css": "./src/styles.css"
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@cosmicdrift/kumiko-dispatcher-live": "0.
|
|
20
|
-
"@cosmicdrift/kumiko-headless": "0.
|
|
21
|
-
"@cosmicdrift/kumiko-renderer": "0.
|
|
19
|
+
"@cosmicdrift/kumiko-dispatcher-live": "0.164.0",
|
|
20
|
+
"@cosmicdrift/kumiko-headless": "0.164.0",
|
|
21
|
+
"@cosmicdrift/kumiko-renderer": "0.164.0",
|
|
22
22
|
"@radix-ui/react-dialog": "^1.1.15",
|
|
23
23
|
"@radix-ui/react-dropdown-menu": "^2.1.16",
|
|
24
24
|
"@radix-ui/react-label": "^2.1.8",
|
|
@@ -164,4 +164,19 @@ describe("defaultCellRender", () => {
|
|
|
164
164
|
expect(defaultCellRender("hallo", "text")).toBe("hallo");
|
|
165
165
|
expect(defaultCellRender(42, "number")).toBe("42");
|
|
166
166
|
});
|
|
167
|
+
|
|
168
|
+
test("money → { amount, currency } formatiert, kein [object Object]", () => {
|
|
169
|
+
const result = defaultCellRender({ amount: 45000, currency: "EUR" }, "money");
|
|
170
|
+
expect(result).not.toBe("[object Object]");
|
|
171
|
+
expect(result.replace(/[^0-9]/g, "")).toBe("45000");
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
test("money → JPY ohne Nachkommastellen (currencyDecimals)", () => {
|
|
175
|
+
const result = defaultCellRender({ amount: 1000, currency: "JPY" }, "money");
|
|
176
|
+
expect(result.replace(/[^0-9]/g, "")).toBe("1000");
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
test("money → unerwarteter Value-Shape fällt auf String zurück", () => {
|
|
180
|
+
expect(defaultCellRender(45000, "money")).toBe("45000");
|
|
181
|
+
});
|
|
167
182
|
});
|
package/src/primitives/index.tsx
CHANGED
|
@@ -79,7 +79,7 @@ import {
|
|
|
79
79
|
import { FileUploadInput } from "./file-upload";
|
|
80
80
|
import { DefaultLightbox } from "./lightbox";
|
|
81
81
|
import { LocatedTimestampInput } from "./located-timestamp-input";
|
|
82
|
-
import { MoneyInput } from "./money-input";
|
|
82
|
+
import { currencyDecimals, MoneyInput } from "./money-input";
|
|
83
83
|
import { TimestampInput } from "./timestamp-input";
|
|
84
84
|
import { useToast } from "./toast";
|
|
85
85
|
|
|
@@ -1256,6 +1256,15 @@ export function isComponentRendererRef(renderer: unknown): { readonly name: stri
|
|
|
1256
1256
|
// applyFormatSpec re-exported from headless (platform-agnostic).
|
|
1257
1257
|
export { applyFormatSpec };
|
|
1258
1258
|
|
|
1259
|
+
function isMoneyValue(value: unknown): value is { amount: number; currency: string } {
|
|
1260
|
+
return (
|
|
1261
|
+
typeof value === "object" &&
|
|
1262
|
+
value !== null &&
|
|
1263
|
+
typeof (value as Record<string, unknown>)["amount"] === "number" &&
|
|
1264
|
+
typeof (value as Record<string, unknown>)["currency"] === "string"
|
|
1265
|
+
);
|
|
1266
|
+
}
|
|
1267
|
+
|
|
1259
1268
|
// Type-spezifische Default-Cell-Renderer. Author kann pro Spalte einen
|
|
1260
1269
|
// expliziten renderer setzen (FormatSpec oder PlatformComponent); ohne
|
|
1261
1270
|
// expliziten renderer fällt DataTableCell hier durch.
|
|
@@ -1263,6 +1272,7 @@ export { applyFormatSpec };
|
|
|
1263
1272
|
// - boolean → ✓ / leer
|
|
1264
1273
|
// - timestamp/date → locale-formatiert (kein roher ISO-String)
|
|
1265
1274
|
// - select → human-lesbar (kebab-case → Title Case)
|
|
1275
|
+
// - money → { amount, currency } formatted via Intl (not "[object Object]")
|
|
1266
1276
|
// - text/number/sonst → toString
|
|
1267
1277
|
export function defaultCellRender(
|
|
1268
1278
|
value: unknown,
|
|
@@ -1272,6 +1282,16 @@ export function defaultCellRender(
|
|
|
1272
1282
|
if (value === null || value === undefined || value === "") return "";
|
|
1273
1283
|
if (type === "boolean") return value === true ? "✓" : "";
|
|
1274
1284
|
if (type === "timestamp" || type === "date") return applyFormatSpec({ format: type }, value);
|
|
1285
|
+
if (type === "money") {
|
|
1286
|
+
if (!isMoneyValue(value)) return String(value);
|
|
1287
|
+
const decimals = currencyDecimals(value.currency);
|
|
1288
|
+
return new Intl.NumberFormat(undefined, {
|
|
1289
|
+
style: "currency",
|
|
1290
|
+
currency: value.currency,
|
|
1291
|
+
minimumFractionDigits: decimals,
|
|
1292
|
+
maximumFractionDigits: decimals,
|
|
1293
|
+
}).format(value.amount / 10 ** decimals);
|
|
1294
|
+
}
|
|
1275
1295
|
if (type === "select") {
|
|
1276
1296
|
const raw = String(value);
|
|
1277
1297
|
// Translated Label aus dem ViewModel-Builder (Convention-Key
|