@cosmicdrift/kumiko-renderer 0.332.0 → 0.334.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.
Files changed (35) hide show
  1. package/dist/app/config-edit-shim.d.ts +7 -0
  2. package/dist/app/config-edit-shim.js +39 -0
  3. package/dist/app/facet-count-bridge.d.ts +10 -0
  4. package/dist/app/facet-count-bridge.js +20 -0
  5. package/dist/app/kumiko-screen.js +103 -42
  6. package/dist/app/list-facets.d.ts +14 -2
  7. package/dist/app/list-facets.js +74 -0
  8. package/dist/app/query-state-banners.d.ts +8 -0
  9. package/dist/app/query-state-banners.js +14 -0
  10. package/dist/app/row-actions.js +50 -40
  11. package/dist/app/secret-mint-body.js +3 -3
  12. package/dist/app/secrets-edit-body.js +46 -17
  13. package/dist/components/grid-cell-for-field.d.ts +7 -2
  14. package/dist/components/grid-cell-for-field.js +2 -2
  15. package/dist/components/query-options-select.d.ts +12 -3
  16. package/dist/components/query-options-select.js +45 -2
  17. package/dist/components/related-list-section.js +41 -8
  18. package/dist/components/render-edit-types.d.ts +24 -1
  19. package/dist/components/render-edit.js +100 -28
  20. package/dist/components/render-field.d.ts +7 -1
  21. package/dist/components/render-field.js +32 -4
  22. package/dist/components/render-list.d.ts +4 -1
  23. package/dist/components/render-list.js +2 -2
  24. package/dist/components/write-form-section.d.ts +5 -1
  25. package/dist/components/write-form-section.js +17 -5
  26. package/dist/context/embedded-screen-context.d.ts +5 -0
  27. package/dist/context/embedded-screen-context.js +12 -0
  28. package/dist/hooks/use-list-url-state.d.ts +2 -1
  29. package/dist/hooks/use-list-url-state.js +23 -9
  30. package/dist/i18n-defaults.js +31 -5
  31. package/dist/index.d.ts +2 -1
  32. package/dist/index.js +1 -0
  33. package/dist/primitives.d.ts +95 -13
  34. package/package.json +5 -5
  35. package/src/changes.json +7 -0
@@ -14,6 +14,7 @@ export const kumikoDefaultTranslations = {
14
14
  "kumiko.actions.delete": "Delete",
15
15
  "kumiko.actions.delete-confirm": "Confirm delete?",
16
16
  "kumiko.actions.reload": "Reload",
17
+ "kumiko.actions.retry": "Try again",
17
18
  "kumiko.actions.create": "New",
18
19
  "kumiko.actions.edit": "Edit",
19
20
  "kumiko.actions.view": "View",
@@ -23,6 +24,7 @@ export const kumikoDefaultTranslations = {
23
24
  "kumiko.actions.back": "Back",
24
25
  "kumiko.actions.finish": "Finish",
25
26
  "kumiko.wizard.step": "Step {current} of {total}",
27
+ "kumiko.wizard.up-next": "Up next",
26
28
  "kumiko.wizard.step-with-title": "Step {current} of {total} · {title}",
27
29
  "kumiko.version.update-available": "A new version is available.",
28
30
  "kumiko.toast.learn-more": "Learn more",
@@ -35,6 +37,11 @@ export const kumikoDefaultTranslations = {
35
37
  "kumiko.field.locatedTzHint": "Time local to the given location",
36
38
  "kumiko.field.reference-created-no-id": "Record was created but could not be selected automatically. Please select it manually.",
37
39
  "kumiko.field.unsupported": "This field type can't be edited here yet.",
40
+ "kumiko.field.writeOnly.remove": "Remove stored value",
41
+ "kumiko.field.writeOnly.set": "Set",
42
+ "kumiko.field.writeOnly.setPlaceholder": "Set — leave empty to keep it",
43
+ "kumiko.field.writeOnly.undo": "Undo",
44
+ "kumiko.field.writeOnly.willRemove": "Removed on save",
38
45
  "kumiko.field.embedded-list.add-row": "Add row",
39
46
  "kumiko.field.embedded-list.remove-row": "Remove row",
40
47
  "kumiko.field.embedded-list.duplicate-row": "Duplicate row",
@@ -76,6 +83,9 @@ export const kumikoDefaultTranslations = {
76
83
  "kumiko.list.sort.by": "Sorted by {column}",
77
84
  "kumiko.form.changed": "changed",
78
85
  "kumiko.form.on-this-page": "On this page",
86
+ "kumiko.form.noUnsavedChanges": "No unsaved changes",
87
+ "kumiko.form.discard": "Discard",
88
+ "kumiko.form.saveChanges": "Save changes",
79
89
  "kumiko.form.unsaved.one": "1 unsaved change",
80
90
  "kumiko.form.unsaved.other": "{count} unsaved changes",
81
91
  "kumiko.wizard.next-with-title": "Next: {title}",
@@ -152,16 +162,30 @@ export const kumikoDefaultTranslations = {
152
162
  "kumiko.contentEditor.heading2": "Heading 2",
153
163
  "kumiko.contentEditor.bulletList": "Bullet list",
154
164
  "kumiko.contentEditor.orderedList": "Numbered list",
155
- "kumiko.config.source.user": "My value",
165
+ "kumiko.config.source.user": "Your value",
156
166
  "kumiko.config.source.tenant": "Tenant",
157
- "kumiko.config.source.system": "System",
167
+ "kumiko.config.source.system": "Platform",
158
168
  "kumiko.config.source.appOverride": "App override",
159
169
  "kumiko.config.source.computed": "Computed",
160
170
  "kumiko.config.source.default": "Default",
161
171
  "kumiko.config.source.missing": "Missing",
162
- "kumiko.config.cascade.noValue": "No value set",
163
- "kumiko.config.cascade.activeMarker": "active",
164
- "kumiko.config.cascade.resetTo": "Reset override ({scope})",
172
+ "kumiko.config.cascade.noValue": "Not set",
173
+ "kumiko.config.cascade.noDefault": "not set",
174
+ "kumiko.config.cascade.notSetRequired": "Not set. Required.",
175
+ "kumiko.config.cascade.activeMarker": "in use",
176
+ "kumiko.config.cascade.resetTo": "Reset to default",
177
+ "kumiko.config.cascade.resetToApp": "Reset to app value",
178
+ "kumiko.config.cascade.showLevels": "Show all levels",
179
+ "kumiko.config.cascade.hideLevels": "Hide levels",
180
+ "kumiko.config.cascade.on": "On",
181
+ "kumiko.config.cascade.off": "Off",
182
+ "kumiko.config.cascade.origin.tenant": "Set for this tenant. Default is {value}.",
183
+ "kumiko.config.cascade.origin.user": "Set by you. Default is {value}.",
184
+ "kumiko.config.cascade.originNoDefault.tenant": "Set for this tenant.",
185
+ "kumiko.config.cascade.originNoDefault.user": "Set by you.",
186
+ "kumiko.config.cascade.originNoDefault.system": "Set for the platform.",
187
+ "kumiko.config.cascade.origin.system": "Set for the platform. App default is {value}.",
188
+ "kumiko.config.cascade.origin.default": "Uses the default",
165
189
  "kumiko.form.error.generic": "Something went wrong.",
166
190
  "kumiko.form.error.version-conflict": "Record was modified in the meantime. Reload and try again.",
167
191
  "kumiko.form.extension.save-failed": "A custom field could not be saved.",
@@ -182,6 +206,8 @@ export const kumikoDefaultTranslations = {
182
206
  "errors.validation.invalid_type": "Invalid value.",
183
207
  "errors.validation.too_small": "Too small or too short (minimum: {minimum}).",
184
208
  "errors.validation.too_big": "Too big or too long (maximum: {maximum}).",
209
+ "kumiko.validation.number.min": "Must be at least {minimum}.",
210
+ "kumiko.validation.number.max": "Must be {maximum} or less.",
185
211
  "errors.validation.invalid_format": "Invalid format.",
186
212
  "errors.validation.not_multiple_of": "Must be a multiple of {divisor}.",
187
213
  "errors.validation.unrecognized_keys": "Unknown fields.",
package/dist/index.d.ts CHANGED
@@ -43,6 +43,7 @@ export type { DispatcherProviderProps } from "./context/dispatcher-context.js";
43
43
  export { DispatcherProvider, useDispatcher, useDispatcherStatus, useOptionalDispatcher, } from "./context/dispatcher-context.js";
44
44
  export type { DraftStorage, DraftStorageProviderProps } from "./context/draft-storage-context.js";
45
45
  export { DraftStorageProvider, useDraftStorage } from "./context/draft-storage-context.js";
46
+ export { EmbeddedScreenProvider, useIsEmbeddedScreen } from "./context/embedded-screen-context.js";
46
47
  export type { UserRolesProviderProps } from "./context/user-roles-context.js";
47
48
  export { UserRolesProvider, useUserRoles } from "./context/user-roles-context.js";
48
49
  export { formatWhen } from "./format-when.js";
@@ -67,7 +68,7 @@ export { createStaticLocaleResolver, FormalityProvider, LocaleProvider, mergeTra
67
68
  export { kumikoDefaultTranslations } from "./i18n-defaults.js";
68
69
  export { InsideDrawerProvider, useInsideDrawer } from "./inside-drawer.js";
69
70
  export { PageHeaderCompactProvider, PageHeaderSlotAvailableProvider, usePageHeaderCompact, usePageHeaderSlotAvailable, } from "./page-header-slot.js";
70
- export type { ActionMenuItemSpec, ActionOverflowMenuProps, AppPrimitives, BannerProps, ButtonProps, CardOptions, CardProps, CardSlots, CopyButtonProps, CorePrimitives, DataTableDateRangeFacet, DataTableFacet, DataTableProps, DataTableRowAction, DataTableRowActionMode, DataTableSort, DataTableSortDir, DialogProps, DrawerProps, EmbeddedListCellType, EmbeddedListColumn, EmbeddedListInputProps, EmbeddedListTotal, FieldCellWidth, FieldProps, FillContainerProps, FormProps, FormSectionNavItem, FormWidth, GridCellProps, GridProps, HeadingProps, InputProps, JsonViewProps, LightboxProps, LinkProps, MetricBandProps, MetricProps, ModalProps, PageHeaderProps, PrimitivesProviderProps, PrimitivesRegistry, ProgressProps, ProgressTone, PromoPanelAction, PromoPanelProps, RuntimeRenderer, SecretRevealProps, SecretRevealValue, SectionProps, ShareButtonProps, StatusBadgeProps, StatusTone, StepBarProps, StickyActionBarProps, StickyPrimaryActionMarker, TabsProps, TextProps, WizardStepGroupProps, } from "./primitives.js";
71
+ export type { ActionMenuItemSpec, ActionOverflowMenuProps, AppPrimitives, BannerProps, ButtonProps, CardOptions, CardProps, CardSlots, CopyButtonProps, CorePrimitives, DataTableDateRangeFacet, DataTableFacet, DataTableFacetChip, DataTableProps, DataTableRowAction, DataTableRowActionMode, DataTableRowGrouping, DataTableSort, DataTableSortDir, DialogProps, DrawerProps, EmbeddedListCellType, EmbeddedListColumn, EmbeddedListInputProps, EmbeddedListTotal, FieldCellWidth, FieldProps, FillContainerProps, FormProps, FormSectionNavItem, FormWidth, GridCellProps, GridProps, HeadingProps, InputProps, JsonViewProps, LightboxProps, LinkProps, MetricBandProps, MetricProps, ModalProps, PageHeaderProps, PrimitivesProviderProps, PrimitivesRegistry, ProgressProps, ProgressTone, PromoPanelAction, PromoPanelProps, RuntimeRenderer, SecretRevealProps, SecretRevealValue, SectionProps, ShareButtonProps, StatusBadgeProps, StatusTone, StepBarProps, StickyActionBarProps, StickyPrimaryActionMarker, TabsProps, TextProps, TrailingInputAction, WizardStepGroupProps, } from "./primitives.js";
71
72
  export { PrimitivesProvider, STICKY_PRIMARY_ACTION_PROP, shouldRenderActionsIconOnly, statusToneForOptionTone, statusToneForValue, usePrimitives, } from "./primitives.js";
72
73
  export { buildWhatsAppShareUrl } from "./share-links.js";
73
74
  export { sortByAccessor } from "./sort-by-accessor.js";
package/dist/index.js CHANGED
@@ -33,6 +33,7 @@ export { RenderField } from "./components/render-field.js";
33
33
  export { RenderList } from "./components/render-list.js";
34
34
  export { DispatcherProvider, useDispatcher, useDispatcherStatus, useOptionalDispatcher, } from "./context/dispatcher-context.js";
35
35
  export { DraftStorageProvider, useDraftStorage } from "./context/draft-storage-context.js";
36
+ export { EmbeddedScreenProvider, useIsEmbeddedScreen } from "./context/embedded-screen-context.js";
36
37
  export { UserRolesProvider, useUserRoles } from "./context/user-roles-context.js";
37
38
  export { formatWhen } from "./format-when.js";
38
39
  export { REFERENCE_COMBOBOX_LIMIT, REFERENCE_LIST_LOOKUP_LIMIT, REFERENCE_SEARCH_DEBOUNCE_MS, } from "./hooks/reference-limits.js";
@@ -1,5 +1,5 @@
1
1
  import type { ConfigCascade, ConfigScope, ConfigValueSource } from "@cosmicdrift/kumiko-framework/engine";
2
- import type { FieldIconKey, FormWidth, IconKey, NavIconKey, SelectOptionTone } from "@cosmicdrift/kumiko-framework/ui-types";
2
+ import type { FieldIconKey, FormWidth, IconKey, NavIconKey, RowActionDisplay, SelectOptionTone } from "@cosmicdrift/kumiko-framework/ui-types";
3
3
  import type { FieldIssue, ListColumnViewModel, ListRowViewModel, RuntimeRenderer } from "@cosmicdrift/kumiko-headless";
4
4
  import { type ComponentType, type FormEvent, type KeyboardEvent, type ReactNode, type Ref } from "react";
5
5
  export type { RuntimeRenderer };
@@ -123,11 +123,28 @@ export type FieldProps = {
123
123
  readonly issues?: readonly FieldIssue[];
124
124
  readonly labelAppendix?: ReactNode;
125
125
  readonly fieldAppendix?: ReactNode;
126
+ /** Where `fieldAppendix` sits relative to the control. Default
127
+ * `above-control` (a disclosure panel belongs under its label-row
128
+ * trigger); `below-control` keeps sibling inputs on one line when the
129
+ * appendix is a status line or an expanded detail. */
130
+ readonly appendixPlacement?: "above-control" | "below-control";
131
+ /** Help text directly under the label, above the control. */
132
+ readonly description?: ReactNode;
133
+ /** Status pill at the right end of the label row (e.g. "Saved", "Not set"). */
134
+ readonly status?: {
135
+ readonly tone: StatusTone;
136
+ readonly label: string;
137
+ readonly testId?: string;
138
+ };
126
139
  readonly children: ReactNode;
127
140
  /** Label-Layout. `stacked` (Default): Label über dem Control. `inline`:
128
141
  * Control + Label nebeneinander (Box links, Label rechts) — für
129
142
  * Checkbox/Switch-Felder (boolean), wie das shadcn-Muster. */
130
- readonly layout?: "stacked" | "inline";
143
+ readonly layout?: "stacked" | "inline" | "row";
144
+ /** Marks a field whose value is set at this level (differs from the
145
+ * inherited one). Only `layout="row"` draws it: a 2px primary line on the
146
+ * row's left edge. Ignored by the other layouts. */
147
+ readonly accent?: boolean;
131
148
  /** Collapses the visible label to `sr-only` — stays associated via
132
149
  * `htmlFor` (no separate `aria-label` needed). For tables/grids whose
133
150
  * column header already carries the label for each row. */
@@ -141,6 +158,12 @@ export type FieldProps = {
141
158
  /** Discriminated union — jede Input-Sorte hat ihre eigene value/onChange
142
159
  * Signatur. Custom-Impls dispatchen intern, rendern anders (Toggle
143
160
  * statt Checkbox), oder nur einzelne kinds unterschiedlich. */
161
+ export type TrailingInputAction = {
162
+ readonly icon: "clear" | "undo";
163
+ readonly label: string;
164
+ readonly onPress: () => void;
165
+ readonly testId?: string;
166
+ };
144
167
  export type InputProps = {
145
168
  readonly kind: "text";
146
169
  readonly id: string;
@@ -198,6 +221,9 @@ export type InputProps = {
198
221
  * Browser-Password-Manager nutzen das für die Speicherentscheidung.
199
222
  * Native: textContentType="password" / "newPassword". */
200
223
  readonly autoComplete?: "current-password" | "new-password";
224
+ /** Icon button inside the field's trailing edge (clear a stored value,
225
+ * undo a pending removal). `label` is its accessible name + tooltip. */
226
+ readonly trailingAction?: TrailingInputAction;
201
227
  readonly testId?: string;
202
228
  } | {
203
229
  readonly kind: "number";
@@ -299,8 +325,13 @@ export type InputProps = {
299
325
  readonly options: readonly string[] | readonly {
300
326
  readonly value: string;
301
327
  readonly label: string;
302
- /** Second line under the label; shown by `radioVariant="card"`. */
328
+ /** Muted second line under the label (radio list and dropdown items;
329
+ * the dropdown search matches it too). */
303
330
  readonly description?: string;
331
+ /** Group heading. Groups form in order of first occurrence; options
332
+ * without a group stay ungrouped and come before all groups. Options
333
+ * with description or group never render as a segmented control. */
334
+ readonly group?: string;
304
335
  }[];
305
336
  readonly disabled?: boolean;
306
337
  readonly required?: boolean;
@@ -494,6 +525,10 @@ export type DataTableRowAction = {
494
525
  * drives both the icon-left-of-text render and the icon-only collapse
495
526
  * rule (see `shouldRenderActionsIconOnly`). */
496
527
  readonly icon?: IconKey;
528
+ /** Author-chosen inline form (`RowAction.display`). Set: the action stays
529
+ * inline even in the adaptive layout and is exempt from the automatic
530
+ * icon-only collapse. */
531
+ readonly display?: RowActionDisplay;
497
532
  };
498
533
  /** Teil-C action-icon collapse rule: a group of more than two actions where
499
534
  * every member carries an icon renders icon-only instead of wall-to-wall
@@ -513,6 +548,22 @@ export type DataTableFacet = {
513
548
  readonly value: string;
514
549
  readonly label: string;
515
550
  }[];
551
+ /** Present: render the facet as a row of single-choice toggle chips instead
552
+ * of a dropdown. A chip is pressed while the selection equals its values. */
553
+ readonly chips?: readonly DataTableFacetChip[];
554
+ /** Chips only: show each chip's `count` next to its label. */
555
+ readonly showCounts?: boolean;
556
+ /** Chips only: hide chips whose `count` is 0 (unless pressed). */
557
+ readonly hideEmpty?: boolean;
558
+ };
559
+ export type DataTableFacetChip = {
560
+ readonly id: string;
561
+ /** Translated chip label. */
562
+ readonly label: string;
563
+ /** Selection a click sets; `[]` clears the facet. */
564
+ readonly values: readonly string[];
565
+ /** Matching row count, undefined while unknown. */
566
+ readonly count?: number;
516
567
  };
517
568
  export type DataTableDateRangeFacet = {
518
569
  /** The facet's namespace (its date field) — a key, not a filter value. */
@@ -522,9 +573,19 @@ export type DataTableDateRangeFacet = {
522
573
  readonly from: string;
523
574
  readonly to: string;
524
575
  };
576
+ /** Splits rows into collapsible groups (order of first appearance). A
577
+ * renderer without grouping support shows the flat list. */
578
+ export type DataTableRowGrouping = {
579
+ readonly keyOf: (row: ListRowViewModel) => string;
580
+ readonly headerLabel: (groupKey: string, rows: readonly ListRowViewModel[]) => string;
581
+ readonly startsCollapsed: (groupKey: string) => boolean;
582
+ };
525
583
  export type DataTableProps = {
526
584
  readonly columns: readonly ListColumnViewModel[];
527
585
  readonly rows: readonly ListRowViewModel[];
586
+ readonly rowGrouping?: DataTableRowGrouping;
587
+ /** Tints a row. Renderers without row tinting ignore it. */
588
+ readonly rowTone?: (row: ListRowViewModel) => SelectOptionTone | undefined;
528
589
  readonly onRowClick?: (row: ListRowViewModel) => void;
529
590
  /** Aktuelle Sortierung (oder null = unsorted). Wenn columns ein
530
591
  * `sortable: true`-Feld haben und onSortChange gesetzt ist, rendert
@@ -807,8 +868,8 @@ export type FormProps = {
807
868
  * detail screens (which also fill the height) do not set it. Native impls
808
869
  * may ignore this prop. */
809
870
  readonly screenForm?: boolean;
810
- /** Number of unsaved changes, shown in the pinned footer. Omitted in create
811
- * mode and when nothing changed — the footer then shows no status. */
871
+ /** Number of unsaved changes, shown in the pinned footer; 0 shows the quiet
872
+ * "No unsaved changes" status. Omitted (create mode) — no status at all. */
812
873
  readonly unsavedCount?: number;
813
874
  /** Drawer-hosted forms: context box above the fields. */
814
875
  readonly summary?: {
@@ -840,6 +901,9 @@ export type SectionProps = {
840
901
  * title-less/subtitle-less Section still draws the row when `actions`
841
902
  * is set, so a hideTitle tabs-Section with actions isn't stranded. */
842
903
  readonly actions?: ReactNode;
904
+ /** "settings-list": title + subtitle form a left header column and the
905
+ * children (field rows) the right one on `md:` and up. Default "stacked". */
906
+ readonly layout?: "stacked" | "settings-list";
843
907
  /** "destructive" marks the Section as a warning/danger area (e.g. account
844
908
  * deletion, restrict processing) — border color only, no content change.
845
909
  * Default "default" (normal card border). */
@@ -890,6 +954,9 @@ export type GridProps = {
890
954
  /** Fields flow left to right in wrapping rows sized by `GridCell.width`
891
955
  * instead of equal-width tracks (screen forms and drawers). */
892
956
  readonly flow?: boolean;
957
+ /** One full-width row per child, separated by hairlines — the field rows of
958
+ * a `settings-list` section. Wins over `columns`/`flow`. */
959
+ readonly list?: boolean;
893
960
  };
894
961
  /** Width class of a field cell inside a `flow` grid: sized by what the field holds. */
895
962
  export type FieldCellWidth = "text" | "number" | "money" | "date" | "timestamp" | "select" | "full" | "toggle";
@@ -980,6 +1047,8 @@ export type DrawerProps = {
980
1047
  readonly open: boolean;
981
1048
  readonly onOpenChange: (open: boolean) => void;
982
1049
  readonly title?: string;
1050
+ /** Muted line under the title. */
1051
+ readonly subtitle?: string;
983
1052
  readonly children: ReactNode;
984
1053
  readonly testId?: string;
985
1054
  };
@@ -1004,19 +1073,19 @@ export type ConfigSourceBadgeProps = {
1004
1073
  * rule as ConfigCascadeView's toDisplayLevels. */
1005
1074
  readonly screenScope?: ConfigScope;
1006
1075
  };
1007
- /** Collapsible cascade-view for a config-edit field. Split into two slots
1008
- * (#429): "trigger" is the collapsed ▶ + source + value line for the label
1009
- * row; "panel" is the expanded cascade + reset shown below the input. In
1010
- * split mode the screen owns the `expanded` state (both slots share it);
1011
- * without `slot` the component renders both with its own state. */
1076
+ /** Cascade view for a config-edit field: one origin line ("Set for this
1077
+ * tenant", "Uses the default", …), a reset action for an own value, and a
1078
+ * disclosure listing every level. Owns its disclosure state. */
1012
1079
  export type ConfigCascadeViewProps = {
1013
1080
  readonly cascade: ConfigCascade;
1014
1081
  readonly screenScope: ConfigScope;
1015
1082
  readonly onReset?: (key: string, scope: ConfigScope) => void;
1016
1083
  readonly qualifiedKey?: string;
1017
- readonly slot?: "trigger" | "panel";
1018
- readonly expanded?: boolean;
1019
- readonly onToggle?: () => void;
1084
+ /** The key declares `required: true` — a missing value reads "Not set. Required.". */
1085
+ readonly required?: boolean;
1086
+ /** Display form of a level value (e.g. a select's label instead of its raw
1087
+ * value). Absent = the raw value; a missing value keeps the no-value text. */
1088
+ readonly renderValue?: (value: string | number | boolean) => ReactNode;
1020
1089
  };
1021
1090
  /** Card-Slots — benannte Inhalts-Regionen, alle optional. Neue Slots später =
1022
1091
  * rein additiv → Consumer müssen NIE migriert werden. `header` ist der Escape-
@@ -1050,6 +1119,11 @@ export type CardOptions = {
1050
1119
  /** false drops border, background, shadow and radius but keeps padding and
1051
1120
  * header slots — a panel inside a host surface such as a tab panel. Default true. */
1052
1121
  readonly framed?: boolean;
1122
+ /** The card is the whole screen body (secretMint reveal and done phase):
1123
+ * no frame, the shared screen insets and width of form screens, children
1124
+ * stacked with a gap. Without it such a screen sits raw against the
1125
+ * shell edge. Default false. */
1126
+ readonly screenBody?: boolean;
1053
1127
  };
1054
1128
  /** Generische Card-Chrome (border/bg/radius/shadow + Header/Body/Footer) als
1055
1129
  * Primitive — eine Quelle für alle Card-Flächen, statt pro App nachgebaut.
@@ -1098,6 +1172,14 @@ export type StepBarProps = {
1098
1172
  /** Vertical only: rail heading ("Step 4 of 6") and optional description. */
1099
1173
  readonly heading?: string;
1100
1174
  readonly description?: string;
1175
+ /** Vertical only: line under each step label, same order as `steps`. */
1176
+ readonly subtitles?: readonly (string | undefined)[];
1177
+ /** Vertical only: box under the rail announcing the next step. */
1178
+ readonly upNext?: {
1179
+ readonly heading: string;
1180
+ readonly title: string;
1181
+ readonly subtitle?: string;
1182
+ };
1101
1183
  readonly testId?: string;
1102
1184
  readonly compactTestId?: string;
1103
1185
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cosmicdrift/kumiko-renderer",
3
- "version": "0.332.0",
3
+ "version": "0.334.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.332.0",
19
- "@cosmicdrift/kumiko-headless": "0.332.0",
20
- "@cosmicdrift/kumiko-types": "0.332.0",
18
+ "@cosmicdrift/kumiko-framework": "0.334.0",
19
+ "@cosmicdrift/kumiko-headless": "0.334.0",
20
+ "@cosmicdrift/kumiko-types": "0.334.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.332.0"
31
+ "@cosmicdrift/kumiko-locale-de": "0.334.0"
32
32
  },
33
33
  "repository": {
34
34
  "type": "git",
package/src/changes.json CHANGED
@@ -1,4 +1,11 @@
1
1
  [
2
+ {
3
+ "version": "0.333.0",
4
+ "type": "improvement",
5
+ "title": "New optional screen options for facet chips, default filters, row action display, drawer titles, footer actions, grouped related lists and wizard side info",
6
+ "detail": "entityList: `facets` (per-field `display: \"chips\"`, `showCounts`, `hideEmpty`, `extraOptions`, or `false` to hide), `defaultFilters` (initial value only, the URL wins, \"no filter\" stays chosen) and `rowActionMode`. Row actions get `display: \"button\" | \"link\" | \"icon\"`; with `display` set an action stays inline next to the kebab. Drawer actions get `title` / `subtitle` (i18n keys, `{param}` filled from the row prefill). Edit fields get `submit: false` (kept out of the payload), actionForm gets `footerActions` (patch values, then submit), relatedList gets `groupBy` / `rowTone` / `rowActionMode`. Wizard sections get `subtitle`, `layout.wizard.aside.upNext` adds an \"up next\" box, entityEdit gets `titleTemplate`. `Button` gets a `pressed` style, the DataTable contract `rowGrouping` / `rowTone`, `StepBar` `subtitles` / `upNext`, `Drawer` `subtitle`.\n- Screenshot runner: `SCREENSHOT_DESKTOP_WIDTH` overrides the desktop viewport width (default 1920).",
7
+ "migration": "No code change needed."
8
+ },
2
9
  {
3
10
  "version": "0.332.0",
4
11
  "type": "improvement",