@cosmicdrift/kumiko-renderer 0.337.1 → 0.338.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.
@@ -2386,6 +2386,23 @@ function mapFailedConfigCommandIssuesToField(error, failedIndex, commandFieldNam
2386
2386
  },
2387
2387
  };
2388
2388
  }
2389
+ // A number/money field without a declared default starts empty: buildInitialValues
2390
+ // maps it to 0, which a save would persist as a deliberate "0" override.
2391
+ function buildConfigEditDefaults(fields) {
2392
+ const defaults = buildInitialValues(fields); // @cast-boundary render-helper
2393
+ for (const [shortName, fieldDef] of Object.entries(fields)) {
2394
+ const { type, default: fieldDefault } = fieldDef; // @cast-boundary schema-walk
2395
+ if ((type === "number" || type === "money") && fieldDefault === undefined) {
2396
+ defaults[shortName] = undefined;
2397
+ }
2398
+ }
2399
+ return defaults;
2400
+ }
2401
+ function isEmptyNumericFormValue(value) {
2402
+ if (value === undefined || value === null || value === "")
2403
+ return true;
2404
+ return typeof value === "number" && !Number.isFinite(value);
2405
+ }
2389
2406
  function ConfigEditBody({ schema, screen, translate, }) {
2390
2407
  const { ConfigCascadeView } = usePrimitives();
2391
2408
  const t = useTranslation();
@@ -2408,7 +2425,7 @@ function ConfigEditBody({ schema, screen, translate, }) {
2408
2425
  if (valuesQuery.data === null)
2409
2426
  return null;
2410
2427
  const out = {};
2411
- const defaults = buildInitialValues(screen.fields); // @cast-boundary render-helper
2428
+ const defaults = buildConfigEditDefaults(screen.fields);
2412
2429
  for (const [shortName, fieldDef] of Object.entries(screen.fields)) {
2413
2430
  const qualified = screen.configKeys[shortName];
2414
2431
  if (qualified === undefined) {
@@ -2512,6 +2529,16 @@ function ConfigEditBody({ schema, screen, translate, }) {
2512
2529
  });
2513
2530
  continue;
2514
2531
  }
2532
+ // Cleared number/money: drop this scope's override instead of storing an empty value.
2533
+ if ((ftype === "number" || ftype === "money") &&
2534
+ isEmptyNumericFormValue(ftype === "money" ? unwrapMoneyValue(value) : value)) {
2535
+ commandFieldNames.push(shortName);
2536
+ commands.push({
2537
+ type: "config:write:reset",
2538
+ payload: { key: qualified, scope: screen.scope },
2539
+ });
2540
+ continue;
2541
+ }
2515
2542
  commandFieldNames.push(shortName);
2516
2543
  commands.push({
2517
2544
  type: "config:write:set",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cosmicdrift/kumiko-renderer",
3
- "version": "0.337.1",
3
+ "version": "0.338.0",
4
4
  "description": "Platform-agnostic React renderer for Kumiko screens. Contains the shared logic — primitives-contract, hooks, KumikoScreen, navigation & SSE abstractions — that any platform-specific renderer (web, native) composes. No DOM, no EventSource, no react-dom.",
5
5
  "license": "BUSL-1.1",
6
6
  "author": "Marc Frost <marc@cosmicdriftgamestudio.com>",
@@ -15,9 +15,9 @@
15
15
  }
16
16
  },
17
17
  "dependencies": {
18
- "@cosmicdrift/kumiko-framework": "0.337.1",
19
- "@cosmicdrift/kumiko-headless": "0.337.1",
20
- "@cosmicdrift/kumiko-types": "0.337.1",
18
+ "@cosmicdrift/kumiko-framework": "0.338.0",
19
+ "@cosmicdrift/kumiko-headless": "0.338.0",
20
+ "@cosmicdrift/kumiko-types": "0.338.0",
21
21
  "react": "^19.2.6",
22
22
  "temporal-polyfill": "^0.3.2",
23
23
  "zod": "^4.4.3"
@@ -28,7 +28,7 @@
28
28
  "@types/react-dom": "^19.2.3",
29
29
  "jsdom": "^29.1.1",
30
30
  "react-dom": "^19.2.6",
31
- "@cosmicdrift/kumiko-locale-de": "0.337.1"
31
+ "@cosmicdrift/kumiko-locale-de": "0.338.0"
32
32
  },
33
33
  "repository": {
34
34
  "type": "git",
package/src/changes.json CHANGED
@@ -1,4 +1,10 @@
1
1
  [
2
+ {
3
+ "version": "0.338.0",
4
+ "type": "fix",
5
+ "title": "configEdit number and money fields start empty without a default",
6
+ "detail": "Number and money fields without a default no longer show 0, so saving does not write an unintended 0. Clearing a stored value resets this scope's override instead of sending an empty number."
7
+ },
2
8
  {
3
9
  "version": "0.337.1",
4
10
  "type": "improvement",