@cosmicdrift/kumiko-headless 0.53.0 → 0.55.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-headless",
3
- "version": "0.53.0",
3
+ "version": "0.55.0",
4
4
  "description": "Headless UI logic for Kumiko — Dispatcher contract, Form-Controller, View-Model, Nav-Resolver. Plattform- und React-frei; jeder Renderer (renderer, renderer-web, renderer-native, …) komponiert darauf.",
5
5
  "license": "BUSL-1.1",
6
6
  "author": "Marc Frost <marc@cosmicdriftgamestudio.com>",
@@ -259,3 +259,41 @@ describe("computeEditViewModel", () => {
259
259
  expect(asFields(vm.sections[0]).fields[0]?.span).toBe(2);
260
260
  });
261
261
  });
262
+
263
+ describe("computeEditViewModel — date/timestamp min/max/locale (#369)", () => {
264
+ test("date-Field reicht min/max/locale ins ViewModel", () => {
265
+ const entity = {
266
+ fields: {
267
+ born: { type: "date", min: "1900-01-01", max: "2026-06-15", locale: "en-US" },
268
+ },
269
+ } as unknown as EntityDefinition;
270
+ const vm = computeEditViewModel({
271
+ screen: editScreen({ sections: [{ title: "X", fields: ["born"] }] }),
272
+ entity,
273
+ values: {},
274
+ translate,
275
+ featureName: "orders",
276
+ });
277
+ const field = asFields(vm.sections[0]).fields[0];
278
+ expect(field?.min).toBe("1900-01-01");
279
+ expect(field?.max).toBe("2026-06-15");
280
+ expect(field?.dateLocale).toBe("en-US");
281
+ });
282
+
283
+ test("date-Field ohne bounds: min/max/dateLocale bleiben weg", () => {
284
+ const entity = {
285
+ fields: { born: { type: "date" } },
286
+ } as unknown as EntityDefinition;
287
+ const vm = computeEditViewModel({
288
+ screen: editScreen({ sections: [{ title: "X", fields: ["born"] }] }),
289
+ entity,
290
+ values: {},
291
+ translate,
292
+ featureName: "orders",
293
+ });
294
+ const field = asFields(vm.sections[0]).fields[0];
295
+ expect(field?.min).toBeUndefined();
296
+ expect(field?.max).toBeUndefined();
297
+ expect(field?.dateLocale).toBeUndefined();
298
+ });
299
+ });
@@ -88,6 +88,15 @@ export function computeEditViewModel<
88
88
  (fieldDef as unknown as { locatedBy?: string }).locatedBy !== undefined
89
89
  ? true
90
90
  : undefined;
91
+ // Datumsgrenzen + Format/Locale-Override bei date/timestamp — der
92
+ // Renderer begrenzt damit den Picker. Quelle: Date/TimestampFieldDef.
93
+ const dateBounds =
94
+ fieldDef.type === "date" || fieldDef.type === "timestamp"
95
+ ? (fieldDef as unknown as { min?: string; max?: string; locale?: string })
96
+ : undefined;
97
+ const min = dateBounds?.min;
98
+ const max = dateBounds?.max;
99
+ const dateLocale = dateBounds?.locale;
91
100
  // Tier 2.7e-3: Reference-Field — refEntity + refLabelField in
92
101
  // das ViewModel reichen damit der Renderer die Lookup-Query
93
102
  // bauen kann ohne noch an EntityDefinition zu greifen.
@@ -124,6 +133,9 @@ export function computeEditViewModel<
124
133
  ...(optionLabels !== undefined && { optionLabels }),
125
134
  ...(multiline !== undefined && { multiline }),
126
135
  ...(wallClock !== undefined && { wallClock }),
136
+ ...(min !== undefined && { min }),
137
+ ...(max !== undefined && { max }),
138
+ ...(dateLocale !== undefined && { dateLocale }),
127
139
  ...(refEntity !== undefined && { refEntity }),
128
140
  ...(refFeature !== undefined && { refFeature }),
129
141
  ...(refLabelField !== undefined && { refLabelField }),
@@ -111,6 +111,12 @@ export type EditFieldViewModel = {
111
111
  * existiert — Wall-Clock-Zeit ohne Offset. Der Renderer emittiert
112
112
  * dann lokale Zeit ohne `Z` statt eines UTC-Instants. */
113
113
  readonly wallClock?: boolean;
114
+ /** Nur bei `type: "date" | "timestamp"` — Datumsgrenzen (ISO) und
115
+ * Format/Locale-Override aus der FieldDefinition. Der Renderer begrenzt
116
+ * damit den Picker; die Write-Validierung läuft separat über Zod. */
117
+ readonly min?: string;
118
+ readonly max?: string;
119
+ readonly dateLocale?: string;
114
120
  /** Nur bei `type: "reference"` gesetzt — Tier 2.7e-3.
115
121
  * Die referenced Entity (kurz, ohne feature-prefix). Der Renderer
116
122
  * baut die Query-QN als `<refFeature>:query:<refEntity>:list`. */