@almadar/ui 4.0.1 → 4.2.1
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/dist/avl/index.cjs +231 -134
- package/dist/avl/index.js +231 -134
- package/dist/components/index.cjs +227 -102
- package/dist/components/index.js +227 -102
- package/dist/components/molecules/DataGrid.d.ts +10 -0
- package/dist/context/index.cjs +204 -100
- package/dist/context/index.js +204 -100
- package/dist/hooks/index.cjs +204 -100
- package/dist/hooks/index.js +204 -100
- package/dist/hooks/useUISlots.d.ts +22 -5
- package/dist/providers/index.cjs +23 -2
- package/dist/providers/index.js +23 -2
- package/dist/runtime/index.cjs +52 -31
- package/dist/runtime/index.js +52 -31
- package/package.json +1 -1
package/dist/avl/index.js
CHANGED
|
@@ -4084,12 +4084,42 @@ var init_EntitySchemaContext = __esm({
|
|
|
4084
4084
|
function generateId() {
|
|
4085
4085
|
return `slot-content-${++idCounter}-${Date.now()}`;
|
|
4086
4086
|
}
|
|
4087
|
+
function aggregateSlot(sources) {
|
|
4088
|
+
if (!sources) return null;
|
|
4089
|
+
const entries = Object.entries(sources);
|
|
4090
|
+
if (entries.length === 0) return null;
|
|
4091
|
+
if (entries.length === 1) return entries[0][1];
|
|
4092
|
+
const children = entries.map(([, entry]) => ({
|
|
4093
|
+
type: entry.pattern,
|
|
4094
|
+
...entry.props
|
|
4095
|
+
}));
|
|
4096
|
+
const stackId = `slot-content-stack-${entries.map(([k]) => k).join("-")}`;
|
|
4097
|
+
return {
|
|
4098
|
+
id: stackId,
|
|
4099
|
+
pattern: "stack",
|
|
4100
|
+
props: {
|
|
4101
|
+
direction: "vertical",
|
|
4102
|
+
gap: "lg",
|
|
4103
|
+
children
|
|
4104
|
+
},
|
|
4105
|
+
priority: 0,
|
|
4106
|
+
animation: "fade",
|
|
4107
|
+
sourceTrait: MULTI_SOURCE_STACK_TRAIT
|
|
4108
|
+
};
|
|
4109
|
+
}
|
|
4087
4110
|
function useUISlotManager() {
|
|
4088
|
-
const [
|
|
4111
|
+
const [sources, setSources] = useState(DEFAULT_SOURCES);
|
|
4089
4112
|
const subscribersRef = useRef(/* @__PURE__ */ new Set());
|
|
4090
4113
|
const timersRef = useRef(/* @__PURE__ */ new Map());
|
|
4091
4114
|
const traitIndexRef = useRef(/* @__PURE__ */ new Map());
|
|
4092
4115
|
const traitSubscribersRef = useRef(/* @__PURE__ */ new Map());
|
|
4116
|
+
const slots = useMemo(() => {
|
|
4117
|
+
const out = { ...DEFAULT_SLOTS };
|
|
4118
|
+
for (const slot of ALL_SLOTS) {
|
|
4119
|
+
out[slot] = aggregateSlot(sources[slot]);
|
|
4120
|
+
}
|
|
4121
|
+
return out;
|
|
4122
|
+
}, [sources]);
|
|
4093
4123
|
useEffect(() => {
|
|
4094
4124
|
return () => {
|
|
4095
4125
|
timersRef.current.forEach((timer) => clearTimeout(timer));
|
|
@@ -4128,103 +4158,160 @@ function useUISlotManager() {
|
|
|
4128
4158
|
const unindexTrait = useCallback((traitName) => {
|
|
4129
4159
|
traitIndexRef.current.delete(traitName);
|
|
4130
4160
|
}, []);
|
|
4131
|
-
const render = useCallback(
|
|
4132
|
-
|
|
4133
|
-
|
|
4134
|
-
|
|
4135
|
-
|
|
4136
|
-
|
|
4137
|
-
|
|
4138
|
-
|
|
4139
|
-
|
|
4140
|
-
|
|
4141
|
-
|
|
4142
|
-
|
|
4143
|
-
|
|
4144
|
-
|
|
4145
|
-
|
|
4146
|
-
|
|
4147
|
-
|
|
4148
|
-
|
|
4149
|
-
|
|
4150
|
-
|
|
4161
|
+
const render = useCallback(
|
|
4162
|
+
(config) => {
|
|
4163
|
+
const id = generateId();
|
|
4164
|
+
const sourceKey = config.sourceTrait ?? DEFAULT_SOURCE_KEY;
|
|
4165
|
+
const content = {
|
|
4166
|
+
id,
|
|
4167
|
+
pattern: config.pattern,
|
|
4168
|
+
props: config.props ?? {},
|
|
4169
|
+
priority: config.priority ?? 0,
|
|
4170
|
+
animation: config.animation ?? "fade",
|
|
4171
|
+
onDismiss: config.onDismiss,
|
|
4172
|
+
sourceTrait: config.sourceTrait
|
|
4173
|
+
};
|
|
4174
|
+
if (config.autoDismissMs && config.autoDismissMs > 0) {
|
|
4175
|
+
content.autoDismissAt = Date.now() + config.autoDismissMs;
|
|
4176
|
+
const timer = setTimeout(() => {
|
|
4177
|
+
setSources((prev) => {
|
|
4178
|
+
const slotSources = prev[config.target];
|
|
4179
|
+
if (slotSources && slotSources[sourceKey]?.id === id) {
|
|
4180
|
+
content.onDismiss?.();
|
|
4181
|
+
const next = { ...slotSources };
|
|
4182
|
+
delete next[sourceKey];
|
|
4183
|
+
const updated = { ...prev, [config.target]: next };
|
|
4184
|
+
notifySubscribers(config.target, aggregateSlot(next));
|
|
4185
|
+
return updated;
|
|
4186
|
+
}
|
|
4187
|
+
return prev;
|
|
4188
|
+
});
|
|
4189
|
+
timersRef.current.delete(id);
|
|
4190
|
+
}, config.autoDismissMs);
|
|
4191
|
+
timersRef.current.set(id, timer);
|
|
4192
|
+
}
|
|
4193
|
+
setSources((prev) => {
|
|
4194
|
+
const slotSources = prev[config.target] ?? {};
|
|
4195
|
+
const existing = slotSources[sourceKey];
|
|
4196
|
+
if (existing && existing.priority > content.priority) {
|
|
4197
|
+
console.warn(
|
|
4198
|
+
`[UISlots] Slot "${config.target}" source "${sourceKey}" already has higher priority content (${existing.priority} > ${content.priority})`
|
|
4199
|
+
);
|
|
4151
4200
|
return prev;
|
|
4152
|
-
});
|
|
4153
|
-
timersRef.current.delete(id);
|
|
4154
|
-
}, config.autoDismissMs);
|
|
4155
|
-
timersRef.current.set(id, timer);
|
|
4156
|
-
}
|
|
4157
|
-
setSlots((prev) => {
|
|
4158
|
-
const existing = prev[config.target];
|
|
4159
|
-
if (existing && existing.priority > content.priority) {
|
|
4160
|
-
console.warn(
|
|
4161
|
-
`[UISlots] Slot "${config.target}" already has higher priority content (${existing.priority} > ${content.priority})`
|
|
4162
|
-
);
|
|
4163
|
-
return prev;
|
|
4164
|
-
}
|
|
4165
|
-
if (content.sourceTrait) {
|
|
4166
|
-
indexTraitRender(content.sourceTrait, content);
|
|
4167
|
-
notifyTraitSubscribers(content.sourceTrait, content);
|
|
4168
|
-
}
|
|
4169
|
-
notifySubscribers(config.target, content);
|
|
4170
|
-
return { ...prev, [config.target]: content };
|
|
4171
|
-
});
|
|
4172
|
-
return id;
|
|
4173
|
-
}, [notifySubscribers, notifyTraitSubscribers, indexTraitRender]);
|
|
4174
|
-
const clear = useCallback((slot) => {
|
|
4175
|
-
setSlots((prev) => {
|
|
4176
|
-
const content = prev[slot];
|
|
4177
|
-
if (content) {
|
|
4178
|
-
const timer = timersRef.current.get(content.id);
|
|
4179
|
-
if (timer) {
|
|
4180
|
-
clearTimeout(timer);
|
|
4181
|
-
timersRef.current.delete(content.id);
|
|
4182
4201
|
}
|
|
4183
|
-
|
|
4202
|
+
const nextSources = {
|
|
4203
|
+
...slotSources,
|
|
4204
|
+
[sourceKey]: content
|
|
4205
|
+
};
|
|
4206
|
+
const nextAll = { ...prev, [config.target]: nextSources };
|
|
4184
4207
|
if (content.sourceTrait) {
|
|
4185
|
-
|
|
4186
|
-
notifyTraitSubscribers(content.sourceTrait,
|
|
4208
|
+
indexTraitRender(content.sourceTrait, content);
|
|
4209
|
+
notifyTraitSubscribers(content.sourceTrait, content);
|
|
4210
|
+
}
|
|
4211
|
+
notifySubscribers(config.target, aggregateSlot(nextSources));
|
|
4212
|
+
return nextAll;
|
|
4213
|
+
});
|
|
4214
|
+
return id;
|
|
4215
|
+
},
|
|
4216
|
+
[notifySubscribers, notifyTraitSubscribers, indexTraitRender]
|
|
4217
|
+
);
|
|
4218
|
+
const clear = useCallback(
|
|
4219
|
+
(slot) => {
|
|
4220
|
+
setSources((prev) => {
|
|
4221
|
+
const slotSources = prev[slot];
|
|
4222
|
+
if (!slotSources || Object.keys(slotSources).length === 0) {
|
|
4223
|
+
return prev;
|
|
4224
|
+
}
|
|
4225
|
+
for (const content of Object.values(slotSources)) {
|
|
4226
|
+
const timer = timersRef.current.get(content.id);
|
|
4227
|
+
if (timer) {
|
|
4228
|
+
clearTimeout(timer);
|
|
4229
|
+
timersRef.current.delete(content.id);
|
|
4230
|
+
}
|
|
4231
|
+
content.onDismiss?.();
|
|
4232
|
+
if (content.sourceTrait) {
|
|
4233
|
+
unindexTrait(content.sourceTrait);
|
|
4234
|
+
notifyTraitSubscribers(content.sourceTrait, null);
|
|
4235
|
+
}
|
|
4187
4236
|
}
|
|
4188
4237
|
notifySubscribers(slot, null);
|
|
4189
|
-
|
|
4190
|
-
|
|
4191
|
-
}
|
|
4192
|
-
|
|
4193
|
-
|
|
4194
|
-
|
|
4195
|
-
|
|
4196
|
-
|
|
4197
|
-
|
|
4198
|
-
const
|
|
4238
|
+
return { ...prev, [slot]: {} };
|
|
4239
|
+
});
|
|
4240
|
+
},
|
|
4241
|
+
[notifySubscribers, notifyTraitSubscribers, unindexTrait]
|
|
4242
|
+
);
|
|
4243
|
+
const clearBySource = useCallback(
|
|
4244
|
+
(slot, sourceTrait) => {
|
|
4245
|
+
const sourceKey = sourceTrait;
|
|
4246
|
+
setSources((prev) => {
|
|
4247
|
+
const slotSources = prev[slot];
|
|
4248
|
+
if (!slotSources || !(sourceKey in slotSources)) return prev;
|
|
4249
|
+
const content = slotSources[sourceKey];
|
|
4250
|
+
const timer = timersRef.current.get(content.id);
|
|
4199
4251
|
if (timer) {
|
|
4200
4252
|
clearTimeout(timer);
|
|
4201
|
-
timersRef.current.delete(id);
|
|
4253
|
+
timersRef.current.delete(content.id);
|
|
4202
4254
|
}
|
|
4203
4255
|
content.onDismiss?.();
|
|
4204
4256
|
if (content.sourceTrait) {
|
|
4205
4257
|
unindexTrait(content.sourceTrait);
|
|
4206
4258
|
notifyTraitSubscribers(content.sourceTrait, null);
|
|
4207
4259
|
}
|
|
4208
|
-
|
|
4209
|
-
|
|
4210
|
-
|
|
4211
|
-
|
|
4212
|
-
|
|
4213
|
-
|
|
4260
|
+
const nextSources = { ...slotSources };
|
|
4261
|
+
delete nextSources[sourceKey];
|
|
4262
|
+
notifySubscribers(slot, aggregateSlot(nextSources));
|
|
4263
|
+
return { ...prev, [slot]: nextSources };
|
|
4264
|
+
});
|
|
4265
|
+
},
|
|
4266
|
+
[notifySubscribers, notifyTraitSubscribers, unindexTrait]
|
|
4267
|
+
);
|
|
4268
|
+
const clearById = useCallback(
|
|
4269
|
+
(id) => {
|
|
4270
|
+
setSources((prev) => {
|
|
4271
|
+
for (const slot of ALL_SLOTS) {
|
|
4272
|
+
const slotSources = prev[slot];
|
|
4273
|
+
if (!slotSources) continue;
|
|
4274
|
+
const matchKey = Object.keys(slotSources).find(
|
|
4275
|
+
(k) => slotSources[k].id === id
|
|
4276
|
+
);
|
|
4277
|
+
if (!matchKey) continue;
|
|
4278
|
+
const content = slotSources[matchKey];
|
|
4279
|
+
const timer = timersRef.current.get(id);
|
|
4280
|
+
if (timer) {
|
|
4281
|
+
clearTimeout(timer);
|
|
4282
|
+
timersRef.current.delete(id);
|
|
4283
|
+
}
|
|
4284
|
+
content.onDismiss?.();
|
|
4285
|
+
if (content.sourceTrait) {
|
|
4286
|
+
unindexTrait(content.sourceTrait);
|
|
4287
|
+
notifyTraitSubscribers(content.sourceTrait, null);
|
|
4288
|
+
}
|
|
4289
|
+
const nextSources = { ...slotSources };
|
|
4290
|
+
delete nextSources[matchKey];
|
|
4291
|
+
notifySubscribers(slot, aggregateSlot(nextSources));
|
|
4292
|
+
return { ...prev, [slot]: nextSources };
|
|
4293
|
+
}
|
|
4294
|
+
return prev;
|
|
4295
|
+
});
|
|
4296
|
+
},
|
|
4297
|
+
[notifySubscribers, notifyTraitSubscribers, unindexTrait]
|
|
4298
|
+
);
|
|
4214
4299
|
const clearAll = useCallback(() => {
|
|
4215
4300
|
timersRef.current.forEach((timer) => clearTimeout(timer));
|
|
4216
4301
|
timersRef.current.clear();
|
|
4217
|
-
|
|
4218
|
-
|
|
4219
|
-
|
|
4302
|
+
setSources((prev) => {
|
|
4303
|
+
for (const slot of ALL_SLOTS) {
|
|
4304
|
+
const slotSources = prev[slot];
|
|
4305
|
+
if (!slotSources) continue;
|
|
4306
|
+
for (const content of Object.values(slotSources)) {
|
|
4220
4307
|
content.onDismiss?.();
|
|
4221
4308
|
if (content.sourceTrait) {
|
|
4222
4309
|
notifyTraitSubscribers(content.sourceTrait, null);
|
|
4223
4310
|
}
|
|
4224
|
-
notifySubscribers(slot, null);
|
|
4225
4311
|
}
|
|
4226
|
-
|
|
4227
|
-
|
|
4312
|
+
notifySubscribers(slot, null);
|
|
4313
|
+
}
|
|
4314
|
+
return DEFAULT_SOURCES;
|
|
4228
4315
|
});
|
|
4229
4316
|
traitIndexRef.current.clear();
|
|
4230
4317
|
}, [notifySubscribers, notifyTraitSubscribers]);
|
|
@@ -4234,16 +4321,16 @@ function useUISlotManager() {
|
|
|
4234
4321
|
subscribersRef.current.delete(callback);
|
|
4235
4322
|
};
|
|
4236
4323
|
}, []);
|
|
4237
|
-
const hasContent = useCallback(
|
|
4238
|
-
|
|
4239
|
-
|
|
4240
|
-
|
|
4241
|
-
|
|
4242
|
-
|
|
4324
|
+
const hasContent = useCallback(
|
|
4325
|
+
(slot) => slots[slot] !== null,
|
|
4326
|
+
[slots]
|
|
4327
|
+
);
|
|
4328
|
+
const getContent = useCallback(
|
|
4329
|
+
(slot) => slots[slot],
|
|
4330
|
+
[slots]
|
|
4331
|
+
);
|
|
4243
4332
|
const getTraitContent = useCallback(
|
|
4244
|
-
(traitName) =>
|
|
4245
|
-
return traitIndexRef.current.get(traitName) ?? null;
|
|
4246
|
-
},
|
|
4333
|
+
(traitName) => traitIndexRef.current.get(traitName) ?? null,
|
|
4247
4334
|
[]
|
|
4248
4335
|
);
|
|
4249
4336
|
const subscribeTrait = useCallback(
|
|
@@ -4269,6 +4356,7 @@ function useUISlotManager() {
|
|
|
4269
4356
|
slots,
|
|
4270
4357
|
render,
|
|
4271
4358
|
clear,
|
|
4359
|
+
clearBySource,
|
|
4272
4360
|
clearById,
|
|
4273
4361
|
clearAll,
|
|
4274
4362
|
subscribe: subscribe2,
|
|
@@ -4278,24 +4366,40 @@ function useUISlotManager() {
|
|
|
4278
4366
|
subscribeTrait
|
|
4279
4367
|
};
|
|
4280
4368
|
}
|
|
4281
|
-
var DEFAULT_SLOTS, idCounter;
|
|
4369
|
+
var DEFAULT_SOURCE_KEY, MULTI_SOURCE_STACK_TRAIT, ALL_SLOTS, DEFAULT_SLOTS, DEFAULT_SOURCES, idCounter;
|
|
4282
4370
|
var init_useUISlots = __esm({
|
|
4283
4371
|
"hooks/useUISlots.ts"() {
|
|
4284
4372
|
"use client";
|
|
4285
|
-
|
|
4286
|
-
|
|
4287
|
-
|
|
4288
|
-
|
|
4289
|
-
|
|
4290
|
-
|
|
4291
|
-
|
|
4292
|
-
|
|
4293
|
-
"
|
|
4294
|
-
"
|
|
4295
|
-
"hud-
|
|
4296
|
-
"hud-
|
|
4297
|
-
|
|
4298
|
-
|
|
4373
|
+
DEFAULT_SOURCE_KEY = "__default__";
|
|
4374
|
+
MULTI_SOURCE_STACK_TRAIT = "__multi_source_stack__";
|
|
4375
|
+
ALL_SLOTS = [
|
|
4376
|
+
"main",
|
|
4377
|
+
"sidebar",
|
|
4378
|
+
"modal",
|
|
4379
|
+
"drawer",
|
|
4380
|
+
"overlay",
|
|
4381
|
+
"center",
|
|
4382
|
+
"toast",
|
|
4383
|
+
"hud-top",
|
|
4384
|
+
"hud-bottom",
|
|
4385
|
+
"hud-left",
|
|
4386
|
+
"hud-right",
|
|
4387
|
+
"floating"
|
|
4388
|
+
];
|
|
4389
|
+
DEFAULT_SLOTS = ALL_SLOTS.reduce(
|
|
4390
|
+
(acc, slot) => {
|
|
4391
|
+
acc[slot] = null;
|
|
4392
|
+
return acc;
|
|
4393
|
+
},
|
|
4394
|
+
{}
|
|
4395
|
+
);
|
|
4396
|
+
DEFAULT_SOURCES = ALL_SLOTS.reduce(
|
|
4397
|
+
(acc, slot) => {
|
|
4398
|
+
acc[slot] = {};
|
|
4399
|
+
return acc;
|
|
4400
|
+
},
|
|
4401
|
+
{}
|
|
4402
|
+
);
|
|
4299
4403
|
idCounter = 0;
|
|
4300
4404
|
}
|
|
4301
4405
|
});
|
|
@@ -21588,6 +21692,16 @@ function statusVariant2(value) {
|
|
|
21588
21692
|
if (["new", "created", "scheduled", "queued", "info"].includes(v)) return "info";
|
|
21589
21693
|
return "default";
|
|
21590
21694
|
}
|
|
21695
|
+
function resolveBadgeVariant(field, value) {
|
|
21696
|
+
const fromMap = field.colorMap?.[value];
|
|
21697
|
+
if (fromMap) {
|
|
21698
|
+
const normalised = fromMap === "destructive" ? "danger" : fromMap;
|
|
21699
|
+
if (BADGE_VARIANTS.has(normalised)) {
|
|
21700
|
+
return normalised;
|
|
21701
|
+
}
|
|
21702
|
+
}
|
|
21703
|
+
return statusVariant2(value);
|
|
21704
|
+
}
|
|
21591
21705
|
function formatDate2(value) {
|
|
21592
21706
|
if (!value) return "";
|
|
21593
21707
|
const d = new Date(String(value));
|
|
@@ -21801,7 +21915,7 @@ function DataGrid({
|
|
|
21801
21915
|
if (val === void 0 || val === null) return null;
|
|
21802
21916
|
return /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center", children: [
|
|
21803
21917
|
field.icon && /* @__PURE__ */ jsx(Icon, { name: field.icon, size: "xs" }),
|
|
21804
|
-
/* @__PURE__ */ jsx(Badge, { variant:
|
|
21918
|
+
/* @__PURE__ */ jsx(Badge, { variant: resolveBadgeVariant(field, String(val)), children: String(val) })
|
|
21805
21919
|
] }, field.name);
|
|
21806
21920
|
}) })
|
|
21807
21921
|
] }),
|
|
@@ -21894,7 +22008,7 @@ function DataGrid({
|
|
|
21894
22008
|
)
|
|
21895
22009
|
] });
|
|
21896
22010
|
}
|
|
21897
|
-
var gapStyles6;
|
|
22011
|
+
var BADGE_VARIANTS, gapStyles6;
|
|
21898
22012
|
var init_DataGrid = __esm({
|
|
21899
22013
|
"components/molecules/DataGrid.tsx"() {
|
|
21900
22014
|
"use client";
|
|
@@ -21909,6 +22023,17 @@ var init_DataGrid = __esm({
|
|
|
21909
22023
|
init_Button();
|
|
21910
22024
|
init_Icon();
|
|
21911
22025
|
init_InfiniteScrollSentinel();
|
|
22026
|
+
BADGE_VARIANTS = /* @__PURE__ */ new Set([
|
|
22027
|
+
"default",
|
|
22028
|
+
"primary",
|
|
22029
|
+
"secondary",
|
|
22030
|
+
"success",
|
|
22031
|
+
"warning",
|
|
22032
|
+
"danger",
|
|
22033
|
+
"error",
|
|
22034
|
+
"info",
|
|
22035
|
+
"neutral"
|
|
22036
|
+
]);
|
|
21912
22037
|
gapStyles6 = {
|
|
21913
22038
|
none: "gap-0",
|
|
21914
22039
|
sm: "gap-2",
|
|
@@ -51564,7 +51689,7 @@ function useTraitStateMachine(traitBindings, slotsActions, options) {
|
|
|
51564
51689
|
canHandleEvent
|
|
51565
51690
|
};
|
|
51566
51691
|
}
|
|
51567
|
-
var
|
|
51692
|
+
var DEFAULT_SOURCE_KEY2 = "__default__";
|
|
51568
51693
|
function slotEntriesInOrder(slot) {
|
|
51569
51694
|
if (!slot) return [];
|
|
51570
51695
|
const out = [];
|
|
@@ -51580,7 +51705,7 @@ var SlotsActionsContext = createContext(null);
|
|
|
51580
51705
|
function SlotsProvider({ children }) {
|
|
51581
51706
|
const [slots, setSlots] = useState({});
|
|
51582
51707
|
const setSlotPatterns = useCallback((slot, patterns, source) => {
|
|
51583
|
-
const sourceKey = source?.trait ??
|
|
51708
|
+
const sourceKey = source?.trait ?? DEFAULT_SOURCE_KEY2;
|
|
51584
51709
|
setSlots((prev) => {
|
|
51585
51710
|
const prevSlot = prev[slot] ?? {};
|
|
51586
51711
|
return {
|
|
@@ -51906,13 +52031,11 @@ function SlotBridge() {
|
|
|
51906
52031
|
return null;
|
|
51907
52032
|
}
|
|
51908
52033
|
function applyServerEffects(effects, uiSlots, onNavigate) {
|
|
51909
|
-
const perSlotRenders = /* @__PURE__ */ new Map();
|
|
51910
52034
|
for (const eff of effects) {
|
|
51911
52035
|
if (eff.type === "render-ui" && eff.slot && eff.pattern) {
|
|
51912
52036
|
const patternRecord = eff.pattern;
|
|
51913
52037
|
const { type: patternType, children, ...inlineProps } = patternRecord;
|
|
51914
52038
|
const normalizedChildren = Array.isArray(children) ? children.map((c) => normalizeChild(c)) : children;
|
|
51915
|
-
const sourceTrait = eff.traitName ?? "server";
|
|
51916
52039
|
uiSlots.render({
|
|
51917
52040
|
target: eff.slot,
|
|
51918
52041
|
pattern: patternType,
|
|
@@ -51920,38 +52043,12 @@ function applyServerEffects(effects, uiSlots, onNavigate) {
|
|
|
51920
52043
|
...inlineProps,
|
|
51921
52044
|
...normalizedChildren !== void 0 ? { children: normalizedChildren } : {}
|
|
51922
52045
|
},
|
|
51923
|
-
sourceTrait
|
|
51924
|
-
});
|
|
51925
|
-
const bucket = perSlotRenders.get(eff.slot) ?? [];
|
|
51926
|
-
bucket.push({
|
|
51927
|
-
sourceTrait,
|
|
51928
|
-
pattern: {
|
|
51929
|
-
type: patternType,
|
|
51930
|
-
...inlineProps,
|
|
51931
|
-
...normalizedChildren !== void 0 ? { children: normalizedChildren } : {}
|
|
51932
|
-
}
|
|
52046
|
+
sourceTrait: eff.traitName ?? "server"
|
|
51933
52047
|
});
|
|
51934
|
-
perSlotRenders.set(eff.slot, bucket);
|
|
51935
52048
|
} else if (eff.type === "navigate" && eff.route && onNavigate) {
|
|
51936
52049
|
onNavigate(eff.route, eff.params);
|
|
51937
52050
|
}
|
|
51938
52051
|
}
|
|
51939
|
-
for (const [slot, bucket] of perSlotRenders) {
|
|
51940
|
-
const distinctSources = new Set(bucket.map((b) => b.sourceTrait));
|
|
51941
|
-
if (distinctSources.size <= 1) continue;
|
|
51942
|
-
uiSlots.render({
|
|
51943
|
-
target: slot,
|
|
51944
|
-
pattern: "stack",
|
|
51945
|
-
props: {
|
|
51946
|
-
direction: "vertical",
|
|
51947
|
-
gap: "lg",
|
|
51948
|
-
children: bucket.map((b) => b.pattern)
|
|
51949
|
-
},
|
|
51950
|
-
// Use a synthetic wrapper source trait; individual traits' frames
|
|
51951
|
-
// already live in the per-trait index from the per-effect loop.
|
|
51952
|
-
sourceTrait: "__multi_source_stack__"
|
|
51953
|
-
});
|
|
51954
|
-
}
|
|
51955
52052
|
}
|
|
51956
52053
|
function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFallback, persistence }) {
|
|
51957
52054
|
const slotsActions = useSlotsActions();
|