@cosmicdrift/kumiko-renderer 0.56.1 → 0.57.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 +1 -1
- package/src/app/kumiko-screen.tsx +36 -2
- package/src/primitives.tsx +8 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cosmicdrift/kumiko-renderer",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.57.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>",
|
|
@@ -1124,11 +1124,28 @@ function ConfigEditBody({
|
|
|
1124
1124
|
if (!result.isSuccess) {
|
|
1125
1125
|
return { validationBlocked: false, isSuccess: false, error: result.error };
|
|
1126
1126
|
}
|
|
1127
|
+
// Cascade-Disclosure + Maskenwerte nach dem Write nachziehen, sonst
|
|
1128
|
+
// bleibt die Anzeige stale bis Reload — gleiche refetch-Calls wie onReset.
|
|
1129
|
+
await valuesQuery.refetch?.();
|
|
1130
|
+
await cascadeQuery.refetch?.();
|
|
1127
1131
|
return { validationBlocked: false, isSuccess: true, data: undefined };
|
|
1128
1132
|
},
|
|
1129
|
-
[dispatcher, screen.configKeys, screen.scope],
|
|
1133
|
+
[dispatcher, screen.configKeys, screen.scope, valuesQuery.refetch, cascadeQuery.refetch],
|
|
1130
1134
|
);
|
|
1131
1135
|
|
|
1136
|
+
// Cascade-Disclosure (#429): Trigger sitzt in der Label-Row, das Panel
|
|
1137
|
+
// unter dem Input — zwei getrennte Render-Slots teilen sich den
|
|
1138
|
+
// expanded-State, der daher hier (pro Feld) statt in der Komponente lebt.
|
|
1139
|
+
const [expandedFields, setExpandedFields] = useState<ReadonlySet<string>>(new Set());
|
|
1140
|
+
const toggleExpanded = useCallback((fieldName: string) => {
|
|
1141
|
+
setExpandedFields((prev) => {
|
|
1142
|
+
const next = new Set(prev);
|
|
1143
|
+
if (next.has(fieldName)) next.delete(fieldName);
|
|
1144
|
+
else next.add(fieldName);
|
|
1145
|
+
return next;
|
|
1146
|
+
});
|
|
1147
|
+
}, []);
|
|
1148
|
+
|
|
1132
1149
|
if (valuesQuery.loading && valuesQuery.data === null) {
|
|
1133
1150
|
return (
|
|
1134
1151
|
<Banner padded variant="loading" testId="kumiko-screen-loading">
|
|
@@ -1159,13 +1176,30 @@ function ConfigEditBody({
|
|
|
1159
1176
|
customSubmit={customSubmit}
|
|
1160
1177
|
{...(screen.submitLabel !== undefined && { submitLabel: screen.submitLabel })}
|
|
1161
1178
|
{...(translate !== undefined && { translate })}
|
|
1162
|
-
|
|
1179
|
+
labelAppendix={(fieldName: string) => {
|
|
1163
1180
|
const cascade = cascades[fieldName];
|
|
1164
1181
|
if (cascade === undefined) return undefined;
|
|
1165
1182
|
return (
|
|
1166
1183
|
<ConfigCascadeView
|
|
1184
|
+
slot="trigger"
|
|
1185
|
+
cascade={cascade}
|
|
1186
|
+
screenScope={screen.scope}
|
|
1187
|
+
expanded={expandedFields.has(fieldName)}
|
|
1188
|
+
onToggle={() => toggleExpanded(fieldName)}
|
|
1189
|
+
/>
|
|
1190
|
+
);
|
|
1191
|
+
}}
|
|
1192
|
+
fieldAppendix={(fieldName: string) => {
|
|
1193
|
+
const cascade = cascades[fieldName];
|
|
1194
|
+
// Panel nur rendern wenn aufgeklappt — sonst kein leerer Abstand
|
|
1195
|
+
// unter dem Input.
|
|
1196
|
+
if (cascade === undefined || !expandedFields.has(fieldName)) return undefined;
|
|
1197
|
+
return (
|
|
1198
|
+
<ConfigCascadeView
|
|
1199
|
+
slot="panel"
|
|
1167
1200
|
cascade={cascade}
|
|
1168
1201
|
screenScope={screen.scope}
|
|
1202
|
+
expanded
|
|
1169
1203
|
qualifiedKey={screen.configKeys[fieldName]}
|
|
1170
1204
|
onReset={async (key, scope) => {
|
|
1171
1205
|
await dispatcher.write("config:write:reset", { key, scope });
|
package/src/primitives.tsx
CHANGED
|
@@ -521,14 +521,19 @@ export type ConfigSourceBadgeProps = {
|
|
|
521
521
|
readonly screenScope?: ConfigScope;
|
|
522
522
|
};
|
|
523
523
|
|
|
524
|
-
/** Collapsible cascade-view
|
|
525
|
-
*
|
|
526
|
-
*
|
|
524
|
+
/** Collapsible cascade-view for a config-edit field. Split into two slots
|
|
525
|
+
* (#429): "trigger" is the collapsed ▶ + source + value line for the label
|
|
526
|
+
* row; "panel" is the expanded cascade + reset shown below the input. In
|
|
527
|
+
* split mode the screen owns the `expanded` state (both slots share it);
|
|
528
|
+
* without `slot` the component renders both with its own state. */
|
|
527
529
|
export type ConfigCascadeViewProps = {
|
|
528
530
|
readonly cascade: ConfigCascade;
|
|
529
531
|
readonly screenScope: ConfigScope;
|
|
530
532
|
readonly onReset?: (key: string, scope: ConfigScope) => void;
|
|
531
533
|
readonly qualifiedKey?: string;
|
|
534
|
+
readonly slot?: "trigger" | "panel";
|
|
535
|
+
readonly expanded?: boolean;
|
|
536
|
+
readonly onToggle?: () => void;
|
|
532
537
|
};
|
|
533
538
|
|
|
534
539
|
// ---- Core-Registry (Kumiko-eigene Primitives) ----
|