@cosmicdrift/kumiko-renderer 0.314.0 → 0.316.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 +5 -5
- package/src/changes.json +7 -0
- package/src/components/render-edit.tsx +8 -2
- package/src/index.ts +2 -0
- package/src/primitives.tsx +9 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cosmicdrift/kumiko-renderer",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.316.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.
|
|
19
|
-
"@cosmicdrift/kumiko-headless": "0.
|
|
20
|
-
"@cosmicdrift/kumiko-types": "0.
|
|
18
|
+
"@cosmicdrift/kumiko-framework": "0.316.0",
|
|
19
|
+
"@cosmicdrift/kumiko-headless": "0.316.0",
|
|
20
|
+
"@cosmicdrift/kumiko-types": "0.316.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.
|
|
31
|
+
"@cosmicdrift/kumiko-locale-de": "0.316.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.316.0",
|
|
4
|
+
"type": "fix",
|
|
5
|
+
"title": "An app footer-slot action can opt into the wizard's sticky primary group",
|
|
6
|
+
"detail": "fw#1918 pinned the primary action into a sticky footer on mobile by checking\neach form-action element's `type === \"submit\"` prop. An app's\n`screen.slots.footer` renders through EditSlotMount, which never carries\n`type=\"submit\"` (its button is opaque app code), so that slot always landed\nin the non-sticky secondary group even on a wizard's last step — regressing\napps like offlot-app whose wizard-final \"Publish\" action lives in the footer\nslot. `ScreenSlots.footerPrimary?: boolean` now marks that slot as the\nsticky-primary action; `FormFooter` in kumiko-renderer-web recognizes it via\nthe shared `STICKY_PRIMARY_ACTION_PROP` marker exported from kumiko-renderer.\nBuilt-in submit buttons are unaffected.",
|
|
7
|
+
"migration": "Additive — no action needed unless a footer-slot action must become the\nsticky primary action on mobile. Set `slots.footerPrimary: true` next to\nthat screen's `slots.footer` registration to opt in."
|
|
8
|
+
},
|
|
2
9
|
{
|
|
3
10
|
"version": "0.310.0",
|
|
4
11
|
"type": "improvement",
|
|
@@ -37,7 +37,12 @@ import { useDraftStorage } from "../context/draft-storage-context";
|
|
|
37
37
|
import { formatWhen } from "../format-when";
|
|
38
38
|
import { useForm } from "../hooks/use-form";
|
|
39
39
|
import { useTranslation } from "../i18n";
|
|
40
|
-
import {
|
|
40
|
+
import {
|
|
41
|
+
STICKY_PRIMARY_ACTION_PROP,
|
|
42
|
+
type StickyPrimaryActionMarker,
|
|
43
|
+
shouldRenderActionsIconOnly,
|
|
44
|
+
usePrimitives,
|
|
45
|
+
} from "../primitives";
|
|
41
46
|
import { GridCellForField } from "./grid-cell-for-field";
|
|
42
47
|
import { RelatedListSection } from "./related-list-section";
|
|
43
48
|
import {
|
|
@@ -253,7 +258,7 @@ function EditSlotMount({
|
|
|
253
258
|
readonly values: Readonly<Record<string, unknown>>;
|
|
254
259
|
readonly hasUnsavedChanges?: boolean;
|
|
255
260
|
readonly wizardStep?: { readonly index: number; readonly isLast: boolean };
|
|
256
|
-
}): ReactNode {
|
|
261
|
+
} & StickyPrimaryActionMarker): ReactNode {
|
|
257
262
|
const name = extensionSectionName(slot);
|
|
258
263
|
const Component = useExtensionSectionComponent(name);
|
|
259
264
|
useEffect(() => {
|
|
@@ -1199,6 +1204,7 @@ export function RenderEdit<TValues extends FormValues, TCtx = unknown>(
|
|
|
1199
1204
|
values={snapshot.values}
|
|
1200
1205
|
hasUnsavedChanges={snapshot.isDirty || extensionDirty}
|
|
1201
1206
|
wizardStep={isWizard ? { index: currentStep, isLast: isLastWizardStep } : undefined}
|
|
1207
|
+
{...(screen.slots?.footerPrimary === true && { [STICKY_PRIMARY_ACTION_PROP]: true })}
|
|
1202
1208
|
/>
|
|
1203
1209
|
)}
|
|
1204
1210
|
{isWizard && !isLastWizardStep && (
|
package/src/index.ts
CHANGED
|
@@ -231,12 +231,14 @@ export type {
|
|
|
231
231
|
StatusBadgeProps,
|
|
232
232
|
StatusTone,
|
|
233
233
|
StepBarProps,
|
|
234
|
+
StickyPrimaryActionMarker,
|
|
234
235
|
TabsProps,
|
|
235
236
|
TextProps,
|
|
236
237
|
WizardStepGroupProps,
|
|
237
238
|
} from "./primitives";
|
|
238
239
|
export {
|
|
239
240
|
PrimitivesProvider,
|
|
241
|
+
STICKY_PRIMARY_ACTION_PROP,
|
|
240
242
|
shouldRenderActionsIconOnly,
|
|
241
243
|
statusToneForValue,
|
|
242
244
|
usePrimitives,
|
package/src/primitives.tsx
CHANGED
|
@@ -66,6 +66,15 @@ export type { RuntimeRenderer };
|
|
|
66
66
|
* element; native impls ignore it (precedent: `className`). */
|
|
67
67
|
export type DataAttributes = Readonly<Record<`data-${string}`, string>>;
|
|
68
68
|
|
|
69
|
+
/** Structural marker a top-level `actions` node can carry so DefaultForm's
|
|
70
|
+
* sticky-footer split (fw#1918) treats it as the pinned primary action even
|
|
71
|
+
* though it isn't a `Button` with `type="submit"` — e.g. RenderEdit's
|
|
72
|
+
* footer-slot mount, whose actual rendered button is opaque app code the
|
|
73
|
+
* split can't inspect (see `ScreenSlots.footerPrimary`). */
|
|
74
|
+
export const STICKY_PRIMARY_ACTION_PROP = "kumikoStickyPrimaryAction" as const;
|
|
75
|
+
|
|
76
|
+
export type StickyPrimaryActionMarker = Partial<Record<typeof STICKY_PRIMARY_ACTION_PROP, boolean>>;
|
|
77
|
+
|
|
69
78
|
/** Standard-Button. `loading` zeigt einen Spinner statt der Children
|
|
70
79
|
* und sollte mit `disabled` kombiniert werden, wenn die Action wirklich
|
|
71
80
|
* blockiert bis das Loading durch ist (z.B. async submit). Native-
|