@cosmicdrift/kumiko-types 0.332.0 → 0.333.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.
@@ -5,5 +5,5 @@ export interface KumikoExtensionOptionsMap {
5
5
  export type ExtensionOptionsFor<N extends string> = N extends keyof KumikoExtensionOptionsMap ? KumikoExtensionOptionsMap[N] & {
6
6
  readonly escapeHatch?: EscapeHatchDeclaration;
7
7
  } : Record<string, unknown>;
8
- /** Rest-tuple for useExtension's positional options arg: required for an augmented name, optional otherwise. */
9
- export type ExtensionOptionsArgs<N extends string> = N extends keyof KumikoExtensionOptionsMap ? [options: ExtensionOptionsFor<N>] : [options?: Record<string, unknown>];
8
+ /** Rest-tuple for useExtension's positional options arg: required for an augmented name with required keys, optional otherwise. */
9
+ export type ExtensionOptionsArgs<N extends string> = N extends keyof KumikoExtensionOptionsMap ? Record<never, never> extends KumikoExtensionOptionsMap[N] ? [options?: ExtensionOptionsFor<N>] : [options: ExtensionOptionsFor<N>] : [options?: Record<string, unknown>];
package/dist/screen.d.ts CHANGED
@@ -147,6 +147,16 @@ export type RowFieldExtractor = {
147
147
  } | {
148
148
  readonly map: Readonly<Record<string, string>>;
149
149
  };
150
+ /** How a row action renders inline in the row-action column. `"button"` is a
151
+ * bordered button (its colour follows the action's `style`), `"link"` a text
152
+ * link, `"icon"` an icon-only button (needs a resolved icon, falls back to
153
+ * `"link"` without one). Unset: the renderer decides (primary action as link,
154
+ * the rest in the kebab menu). */
155
+ export type RowActionDisplay = "button" | "link" | "icon";
156
+ /** Row-action column layout. `"adaptive"` (default): primary action as link,
157
+ * the rest in a kebab menu — except actions with an explicit `display`, which
158
+ * stay inline. `"inline"`: every action inline, no kebab. */
159
+ export type RowActionMode = "adaptive" | "inline";
150
160
  export type RowAction = RowActionWriteHandler | RowActionNavigate | RowActionDrawer;
151
161
  export type RowActionWriteHandler = {
152
162
  /** Default für RowActions ohne explizit gesetzten `kind` —
@@ -182,6 +192,8 @@ export type RowActionWriteHandler = {
182
192
  * kumiko-renderer) — closed IconKey vocabulary into the ICONS registry
183
193
  * (renderer-web), analogous to EditFieldSpec.icon. */
184
194
  readonly icon?: IconKey;
195
+ /** Inline render form in the row-action column — see `RowActionDisplay`. */
196
+ readonly display?: RowActionDisplay;
185
197
  };
186
198
  export type RowActionNavigateBase = {
187
199
  readonly kind: "navigate";
@@ -216,6 +228,8 @@ export type RowActionNavigateBase = {
216
228
  * kumiko-renderer) — closed IconKey vocabulary into the ICONS registry
217
229
  * (renderer-web), analogous to EditFieldSpec.icon. */
218
230
  readonly icon?: IconKey;
231
+ /** Inline render form in the row-action column — see `RowActionDisplay`. */
232
+ readonly display?: RowActionDisplay;
219
233
  };
220
234
  /** Exactly one of `screen` / `entity` — mutual exclusivity is type-enforced
221
235
  * (boot validator still rejects both/neither for untyped schemas). */
@@ -252,6 +266,15 @@ export type RowActionDrawer = {
252
266
  * kumiko-renderer) — closed IconKey vocabulary into the ICONS registry
253
267
  * (renderer-web), analogous to EditFieldSpec.icon. */
254
268
  readonly icon?: IconKey;
269
+ /** Inline render form in the row-action column — see `RowActionDisplay`. */
270
+ readonly display?: RowActionDisplay;
271
+ /** Drawer heading (i18n key) instead of the action `label`. `{name}`
272
+ * placeholders resolve from the drawer prefill (`params`), formatted for
273
+ * display like `ActionFormScreenDefinition.summary`. */
274
+ readonly title?: string;
275
+ /** Line under the drawer heading (i18n key or a bare `{name}` template),
276
+ * resolved like `title`. */
277
+ readonly subtitle?: string;
255
278
  };
256
279
  export type ToolbarAction = {
257
280
  readonly kind: "navigate";
@@ -294,6 +317,10 @@ export type ToolbarAction = {
294
317
  * not force a confirm dialog here: the target form is the
295
318
  * confirmation. */
296
319
  readonly style?: "primary" | "secondary" | "danger";
320
+ /** Drawer heading (i18n key) instead of `label`. */
321
+ readonly title?: string;
322
+ /** Line under the drawer heading (i18n key). */
323
+ readonly subtitle?: string;
297
324
  };
298
325
  export type RelatedListToolbarAction = (Extract<ToolbarAction, {
299
326
  readonly kind: "navigate";
@@ -319,6 +346,31 @@ export type RelatedListToolbarAction = (Extract<ToolbarAction, {
319
346
  * layout and are therefore omitted. `kind` stays the discriminator so further
320
347
  * expansion kinds can be added without a breaking change. */
321
348
  export type EntityListExpandableRow = Omit<EditRelatedListSection, "id" | "countField">;
349
+ /** An extra choice on a facet next to the field's own options: a named
350
+ * bundle of values ("Running" = several statuses) or "no filter" (`values:
351
+ * []`, e.g. "All"). Chips only. */
352
+ export type EntityListFacetExtraOption = {
353
+ readonly id: string;
354
+ /** i18n key. */
355
+ readonly label: string;
356
+ /** Option values this choice selects; `[]` selects nothing, i.e. no filter. */
357
+ readonly values: readonly string[];
358
+ /** Where the chip sits relative to the field's own options. Default "start". */
359
+ readonly position?: "start" | "end";
360
+ };
361
+ export type EntityListFacetConfig = {
362
+ /** `"select"` (default): dropdown with checkboxes. `"chips"`: one toggle
363
+ * chip per option, single choice. */
364
+ readonly display?: "select" | "chips";
365
+ /** Chips show how many rows each option matches (other facets and the
366
+ * search apply). Counts come from the list query itself, one `limit: 1`
367
+ * count request per chip. */
368
+ readonly showCounts?: boolean;
369
+ /** Chips with zero matching rows are not shown. Needs counts; implies
370
+ * `showCounts`'s requests even when the number itself is not shown. */
371
+ readonly hideEmpty?: boolean;
372
+ readonly extraOptions?: readonly EntityListFacetExtraOption[];
373
+ };
322
374
  export type EntityListScreenDefinition = {
323
375
  readonly id: string;
324
376
  readonly type: "entityList";
@@ -340,10 +392,13 @@ export type EntityListScreenDefinition = {
340
392
  readonly columns: readonly ListColumnSpec[];
341
393
  readonly rowRenderer?: PlatformComponent;
342
394
  readonly cardRenderer?: PlatformComponent;
343
- /** Per-Row-Aktionen — rendert eine Actions-Spalte rechts in der Tabelle.
344
- * Bis zu 2 actions als inline-Buttons; >2 als Kebab-Dropdown.
345
- * Reihenfolge im Array = Reihenfolge in der UI. */
395
+ /** Per-row actions, rendered as an actions column on the right.
396
+ * Adaptive (default, see `rowActionMode`): the primary action as a link,
397
+ * the rest in the kebab menu; actions with an explicit `display` stay
398
+ * inline. Array order is UI order. */
346
399
  readonly rowActions?: readonly RowAction[];
400
+ /** Layout of the row-action column — see `RowActionMode`. */
401
+ readonly rowActionMode?: RowActionMode;
347
402
  /** Toolbar-Aktionen (List-Header). "Open Incident", "Schedule Maintenance"
348
403
  * etc. — neben "+ Neu" wenn vorhanden. Reihenfolge im Array = UI-
349
404
  * Reihenfolge, primary-style links. */
@@ -361,6 +416,17 @@ export type EntityListScreenDefinition = {
361
416
  readonly pagination?: ListPaginationMode;
362
417
  readonly pageSize?: number;
363
418
  readonly defaultSort?: ListSortSpec;
419
+ /** Initial facet selection, per filterable field: option values (string
420
+ * facets) or a boolean. Applies only while the URL carries no value for
421
+ * that field, so a link or the user's own choice wins; picking "no filter"
422
+ * (an `extraOptions` entry with `values: []`, or clearing the facet) is
423
+ * remembered in the URL and is not overridden again. */
424
+ readonly defaultFilters?: Readonly<Record<string, readonly string[] | boolean>>;
425
+ /** Per-facet display options for the entity's `filterable` fields, keyed by
426
+ * field name. `false` hides the facet's control (its filter stays usable
427
+ * through `defaultFilters` and the URL). Fields without an entry keep the
428
+ * default dropdown. */
429
+ readonly facets?: Readonly<Record<string, EntityListFacetConfig | false>>;
364
430
  /** i18n key for the primary create button label (default `kumiko.actions.create`). */
365
431
  readonly createLabel?: string;
366
432
  /** i18n key for the search field placeholder (default `kumiko.list.search-placeholder`). */
@@ -430,6 +496,8 @@ export type ProjectionListScreenDefinition = {
430
496
  readonly rowRenderer?: PlatformComponent;
431
497
  readonly cardRenderer?: PlatformComponent;
432
498
  readonly rowActions?: readonly RowAction[];
499
+ /** Layout of the row-action column — see `RowActionMode`. */
500
+ readonly rowActionMode?: RowActionMode;
433
501
  readonly toolbarActions?: readonly ToolbarAction[];
434
502
  readonly pagination?: ListPaginationMode;
435
503
  readonly pageSize?: number;
@@ -723,6 +791,11 @@ export type EditFieldSpec = string | {
723
791
  readonly readOnly?: FieldCondition;
724
792
  readonly required?: FieldCondition;
725
793
  readonly renderer?: FieldRenderer;
794
+ /** `false` keeps the field out of the submitted payload — for values
795
+ * that are shown or prefilled for display only (a label, a counter)
796
+ * and that the write handler's schema does not accept. Validation and
797
+ * rendering are unchanged. */
798
+ readonly submit?: false;
726
799
  /** Prefix icon on the input — closed FieldIconKey vocabulary into
727
800
  * the FIELD_ICONS registry (renderer-web), analogous to
728
801
  * `ScreenNavSugar.icon` / NavIconKey. Only takes effect for
@@ -780,6 +853,10 @@ export type EditFieldsSection = {
780
853
  * Ignored outside tabs mode or when the field's value is not a finite
781
854
  * number. */
782
855
  readonly countField?: string;
856
+ /** Short line (i18n key) under this step's title in the wizard step rail
857
+ * and in the "up next" box. Wizard layouts only; unlike `description` it
858
+ * is not shown inside the step. */
859
+ readonly subtitle?: string;
783
860
  /** Rendered top-right in the section's Card title row — same
784
861
  * navigate/drawer/writeHandler dispatch as `ProjectionDetailScreenDefinition.actions`,
785
862
  * evaluated against the same record. Every action must resolve an icon
@@ -816,6 +893,26 @@ export type EditExtensionSection = {
816
893
  * (declared or id-derived); the boot-validator rejects one that doesn't. */
817
894
  readonly actions?: readonly RowAction[];
818
895
  };
896
+ /** Rows are grouped by `field` in order of first appearance. Every group gets
897
+ * a collapsible header. */
898
+ export type RelatedListGroupBy = {
899
+ readonly field: string;
900
+ /** Groups whose field value equals this start collapsed; the others start open. */
901
+ readonly collapsedWhen?: string | number | boolean | null;
902
+ /** i18n key of the group header. Placeholders: `{count}` rows in the group,
903
+ * `{value}` the group's field value, `{lastDate}` the group's latest
904
+ * `dateField` value as a locale date. */
905
+ readonly label: string;
906
+ /** Header i18n key per group value (as string), overriding `label`. */
907
+ readonly labels?: Readonly<Record<string, string>>;
908
+ /** Row field (ISO date or timestamp) behind `{lastDate}`. */
909
+ readonly dateField?: string;
910
+ };
911
+ /** Row tint rule: rows where the `FieldCondition` (`{ field, eq }`, `{ field,
912
+ * in }` …) holds get the tone. `bad` renders red. */
913
+ export type RelatedListRowTone = Exclude<FieldCondition, boolean> & {
914
+ readonly tone: SelectOptionTone;
915
+ };
819
916
  export type EditRelatedListSection = {
820
917
  /** Kebab-case tab id, used as the `?tab=` value. Required by the
821
918
  * boot-validator when the enclosing `EditLayout.mode` is "tabs". */
@@ -885,6 +982,13 @@ export type EditRelatedListSection = {
885
982
  * writeHandler action re-runs this section's own query, same as a
886
983
  * projectionList row action re-running its list query. */
887
984
  readonly rowActions?: readonly RowAction[];
985
+ /** Layout of the row-action column — see `RowActionMode`. */
986
+ readonly rowActionMode?: RowActionMode;
987
+ /** Groups rows by the value of a field under collapsible group headers. */
988
+ readonly groupBy?: RelatedListGroupBy;
989
+ /** Tints rows whose field matches — a declarative rule, not a function, so
990
+ * the screen definition stays serializable. */
991
+ readonly rowTone?: RelatedListRowTone;
888
992
  /** Toolbar actions above the table — same type and dispatch semantics as
889
993
  * `entityList`/`projectionList`'s `toolbarActions` ("+ Anlegen" etc.),
890
994
  * plus `visible`/`params` evaluated against the parent record (see
@@ -961,6 +1065,14 @@ export type EditLayout = {
961
1065
  /** Persists in-progress wizard state as a resumable draft instead of
962
1066
  * discarding it on navigation away. */
963
1067
  readonly draft?: boolean;
1068
+ /** Wizard layouts only. `upNext: true` adds an "up next" box to the step
1069
+ * rail with the following step's title and `subtitle`; the last step
1070
+ * shows none. */
1071
+ readonly wizard?: {
1072
+ readonly aside?: {
1073
+ readonly upNext: true;
1074
+ };
1075
+ };
964
1076
  };
965
1077
  export type EntityEditScreenDefinition = {
966
1078
  readonly id: string;
@@ -984,6 +1096,11 @@ export type EntityEditScreenDefinition = {
984
1096
  readonly entity: string;
985
1097
  /** Entity field whose value names the loaded record in the header breadcrumb (edit mode only). */
986
1098
  readonly recordTitleField?: string;
1099
+ /** Screen title (i18n key) with `{field}` placeholders filled from the
1100
+ * current form values, so the title follows what the user types (create
1101
+ * wizard: "Add {make} {model}"). Falls back to the plain title while the
1102
+ * placeholders are still empty. */
1103
+ readonly titleTemplate?: string;
987
1104
  readonly layout: EditLayout;
988
1105
  /** Optionaler i18n-Key (oder Roh-String) für den Submit-Button. Default
989
1106
  * `kumiko.actions.save`. Lässt den Auto-Edit-Screen domain-spezifische
@@ -1085,6 +1202,12 @@ export type ActionFormScreenDefinition = {
1085
1202
  /** i18n-key für den Submit-Button. Default: i18n-Default des
1086
1203
  * Renderers (typischerweise "actions.submit"). */
1087
1204
  readonly submitLabel?: string;
1205
+ /** Extra buttons in the form footer next to the submit button. A click
1206
+ * applies `patch` to the form values, then submits the form (same
1207
+ * validation, same handler) — e.g. a "Mark as posted" button that sets
1208
+ * `posted: true`. The patched field need not be rendered by the layout.
1209
+ * Order in the array = order in the footer, before the submit button. */
1210
+ readonly footerActions?: readonly ActionFormFooterAction[];
1088
1211
  /** Context box above the fields (i18n keys). `{name}` placeholders resolve from the
1089
1212
  * drawer prefill (`params` of the opening row action), formatted for display. */
1090
1213
  readonly summary?: {
@@ -1131,6 +1254,17 @@ export type ActionFormScreenDefinition = {
1131
1254
  readonly slots?: ScreenSlots;
1132
1255
  readonly access?: AccessRule;
1133
1256
  };
1257
+ export type ActionFormFooterAction = {
1258
+ /** Stable id (kebab-case), used for the test id. */
1259
+ readonly id: string;
1260
+ /** i18n key. */
1261
+ readonly label: string;
1262
+ readonly icon?: IconKey;
1263
+ /** Button style. Default "secondary". */
1264
+ readonly variant?: "primary" | "secondary" | "danger";
1265
+ /** Form values set before the submit. JSON-safe literals only. */
1266
+ readonly patch: Readonly<Record<string, string | number | boolean | null>>;
1267
+ };
1134
1268
  /** Redirect target plus the success-payload field carrying the navigation
1135
1269
  * id. The write-handler reports the id of what it wrote (`data.id`); when
1136
1270
  * that record is a child and the target screen shows its parent, the
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cosmicdrift/kumiko-types",
3
- "version": "0.332.0",
3
+ "version": "0.333.0",
4
4
  "description": "Framework-Type-Definitions für Kumiko — FeatureDefinition, BootCheck-Types und die reinen Engine-Types. Erlaubt Downstream-Konsumenten, gegen die Type-Contracts zu bauen, ohne das ganze Framework-Package zu importieren. Enthaelt keine identitaets-sensitiven Runtime-Werte mehr (Error-Klassen leben seit #1629 in kumiko-framework, Brand-Symbole nutzen Symbol.for) und ist deshalb eine plain dependency, keine peerDependency.",
5
5
  "license": "BUSL-1.1",
6
6
  "author": "Marc Frost <marc@cosmicdriftgamestudio.com>",