@almadar/ui 6.28.0 → 6.29.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.
@@ -102,6 +102,17 @@ interface OrbitalEventResponse {
102
102
  source?: BusEventSource;
103
103
  }>;
104
104
  data?: Record<string, EntityRow[]>;
105
+ /**
106
+ * The entity row each trait's effects left behind THIS request, keyed by
107
+ * trait name (Fix C, the stateless entity round-trip). The stateless
108
+ * deployment holds no server-side memory across requests — a `set`-only
109
+ * field a trait wrote here would otherwise vanish on the client's next
110
+ * request, since `entityByTrait` in the REQUEST only ever reflects the
111
+ * client's own prior local writes. Undefined on a server that doesn't
112
+ * send it (older servers, the stateful path) — the client simply keeps
113
+ * behaving as it always has.
114
+ */
115
+ entityByTrait?: Record<string, EntityRow>;
105
116
  clientEffects?: ClientEffectTuple[];
106
117
  /**
107
118
  * Same effects as `clientEffects`, paired with the trait that produced
@@ -151,6 +162,8 @@ interface ServerResponseMeta {
151
162
  dataEntities: Record<string, number>;
152
163
  /** Raw entity data from server response (for EntityStore advancement) */
153
164
  data?: Record<string, EntityRow[]>;
165
+ /** See `OrbitalEventResponse.entityByTrait`'s doc. */
166
+ entityByTrait?: Record<string, EntityRow>;
154
167
  emittedEvents: string[];
155
168
  /** Server-side effect outcomes — see `OrbitalEventResponse.effectResults`. */
156
169
  effectResults?: ServerEffectResult[];
@@ -102,6 +102,17 @@ interface OrbitalEventResponse {
102
102
  source?: BusEventSource;
103
103
  }>;
104
104
  data?: Record<string, EntityRow[]>;
105
+ /**
106
+ * The entity row each trait's effects left behind THIS request, keyed by
107
+ * trait name (Fix C, the stateless entity round-trip). The stateless
108
+ * deployment holds no server-side memory across requests — a `set`-only
109
+ * field a trait wrote here would otherwise vanish on the client's next
110
+ * request, since `entityByTrait` in the REQUEST only ever reflects the
111
+ * client's own prior local writes. Undefined on a server that doesn't
112
+ * send it (older servers, the stateful path) — the client simply keeps
113
+ * behaving as it always has.
114
+ */
115
+ entityByTrait?: Record<string, EntityRow>;
105
116
  clientEffects?: ClientEffectTuple[];
106
117
  /**
107
118
  * Same effects as `clientEffects`, paired with the trait that produced
@@ -151,6 +162,8 @@ interface ServerResponseMeta {
151
162
  dataEntities: Record<string, number>;
152
163
  /** Raw entity data from server response (for EntityStore advancement) */
153
164
  data?: Record<string, EntityRow[]>;
165
+ /** See `OrbitalEventResponse.entityByTrait`'s doc. */
166
+ entityByTrait?: Record<string, EntityRow>;
154
167
  emittedEvents: string[];
155
168
  /** Server-side effect outcomes — see `OrbitalEventResponse.effectResults`. */
156
169
  effectResults?: ServerEffectResult[];
@@ -6158,6 +6158,13 @@ var init_slot_types = __esm({
6158
6158
  nextRefId = 1;
6159
6159
  }
6160
6160
  });
6161
+ var SlotContainedContext;
6162
+ var init_slotContained = __esm({
6163
+ "lib/slotContained.ts"() {
6164
+ "use client";
6165
+ SlotContainedContext = React96.createContext(false);
6166
+ }
6167
+ });
6161
6168
  function buildForkPaths(x, y, branches, scale) {
6162
6169
  const inLength = 30 * scale;
6163
6170
  const outLength = 30 * scale;
@@ -38470,7 +38477,6 @@ function TableView({
38470
38477
  columns,
38471
38478
  fields,
38472
38479
  itemActions,
38473
- maxInlineActions,
38474
38480
  itemClickEvent = "",
38475
38481
  selectable = false,
38476
38482
  selectEvent,
@@ -38504,8 +38510,7 @@ function TableView({
38504
38510
  const [localSelected, setLocalSelected] = React96__namespace.default.useState(/* @__PURE__ */ new Set());
38505
38511
  const colDefs = (Array.isArray(columns) ? columns : void 0) ?? (Array.isArray(fields) ? fields : void 0) ?? [];
38506
38512
  const actionDefs = Array.isArray(itemActions) ? itemActions : [];
38507
- const inlineActions = maxInlineActions != null ? actionDefs.slice(0, maxInlineActions) : [];
38508
- const overflowActions = maxInlineActions != null ? actionDefs.slice(maxInlineActions) : actionDefs;
38513
+ const overflowActions = actionDefs;
38509
38514
  const fireAction = (action, row) => eventBus.emit(`UI:${action.event}`, {
38510
38515
  id: row.id,
38511
38516
  row
@@ -38687,7 +38692,7 @@ function TableView({
38687
38692
  }
38688
38693
  return /* @__PURE__ */ jsxRuntime.jsx(Box, { role: "cell", className: cellBase, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-foreground", children: formatCell(raw, col.format, relationsData?.[col.field ?? col.key]) }) }, col.key);
38689
38694
  }),
38690
- hasActions && /* @__PURE__ */ jsxRuntime.jsxs(
38695
+ hasActions && /* @__PURE__ */ jsxRuntime.jsx(
38691
38696
  HStack,
38692
38697
  {
38693
38698
  gap: "xs",
@@ -38701,38 +38706,20 @@ function TableView({
38701
38706
  "border-l border-[var(--color-border)]",
38702
38707
  lk.striped && index % 2 === 1 ? "bg-[var(--color-surface-subtle)]" : "bg-[var(--color-card)] group-hover:bg-[var(--color-surface-subtle)]"
38703
38708
  ),
38704
- children: [
38705
- inlineActions.map((action) => /* @__PURE__ */ jsxRuntime.jsxs(
38706
- Button,
38707
- {
38708
- variant: action.variant ?? "ghost",
38709
- size: "sm",
38710
- onClick: () => fireAction(action, row),
38711
- "data-testid": `action-${action.event}`,
38712
- "data-row-id": String(row.id),
38713
- className: cn(action.variant === "danger" && "text-error hover:bg-error/10"),
38714
- children: [
38715
- action.icon && renderIconInput3(action.icon, { size: "xs", className: "mr-1" }),
38716
- action.label
38717
- ]
38718
- },
38719
- action.event
38720
- )),
38721
- overflowActions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
38722
- Menu,
38723
- {
38724
- position: "bottom-end",
38725
- trigger: /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "ghost", size: "sm", "aria-label": t("common.actions"), "data-testid": "action-overflow", "data-row-id": String(row.id), children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "more-horizontal", size: "xs" }) }),
38726
- items: overflowActions.map((action) => ({
38727
- label: action.label,
38728
- icon: action.icon,
38729
- event: action.event,
38730
- variant: action.variant === "danger" ? "danger" : "default",
38731
- onClick: () => fireAction(action, row)
38732
- }))
38733
- }
38734
- )
38735
- ]
38709
+ children: overflowActions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
38710
+ Menu,
38711
+ {
38712
+ position: "bottom-end",
38713
+ trigger: /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "ghost", size: "sm", "aria-label": t("common.actions"), "data-testid": "action-overflow", "data-row-id": String(row.id), children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "more-horizontal", size: "xs" }) }),
38714
+ items: overflowActions.map((action) => ({
38715
+ label: action.label,
38716
+ icon: action.icon,
38717
+ event: action.event,
38718
+ variant: action.variant === "danger" ? "danger" : "default",
38719
+ onClick: () => fireAction(action, row)
38720
+ }))
38721
+ }
38722
+ )
38736
38723
  }
38737
38724
  )
38738
38725
  ]
@@ -47749,6 +47736,7 @@ var init_DetailPanel = __esm({
47749
47736
  init_EmptyState();
47750
47737
  init_cn();
47751
47738
  init_portalRoot();
47739
+ init_slotContained();
47752
47740
  init_format();
47753
47741
  init_getNestedValue();
47754
47742
  init_relationLabel();
@@ -47780,6 +47768,7 @@ var init_DetailPanel = __esm({
47780
47768
  }) => {
47781
47769
  const eventBus = useEventBus();
47782
47770
  const { t } = hooks.useTranslate();
47771
+ const contained = React96.useContext(SlotContainedContext);
47783
47772
  const [titleDraft, setTitleDraft] = React96__namespace.default.useState(null);
47784
47773
  const isFieldDefArray = (arr) => {
47785
47774
  if (!arr || arr.length === 0) return false;
@@ -48167,8 +48156,9 @@ var init_DetailPanel = __esm({
48167
48156
  if (!slideOver) {
48168
48157
  return /* @__PURE__ */ jsxRuntime.jsx(Box, { className, children: content });
48169
48158
  }
48170
- const panel = /* @__PURE__ */ jsxRuntime.jsx(Box, { className: cn("fixed inset-y-0 right-0 w-full max-w-2xl bg-card shadow-lg z-50 overflow-y-auto p-6", className), children: content });
48171
- return typeof document === "undefined" ? panel : reactDom.createPortal(panel, getOrCreatePortalRoot());
48159
+ const panel = /* @__PURE__ */ jsxRuntime.jsx(Box, { className: cn(contained ? "absolute" : "fixed", "inset-y-0 right-0 w-full max-w-2xl bg-card shadow-lg z-50 overflow-y-auto p-6", className), children: content });
48160
+ if (contained || typeof document === "undefined") return panel;
48161
+ return reactDom.createPortal(panel, getOrCreatePortalRoot());
48172
48162
  };
48173
48163
  DetailPanel.displayName = "DetailPanel";
48174
48164
  }
@@ -54665,6 +54655,7 @@ var init_component_registry_generated = __esm({
54665
54655
  // components/core/organisms/UISlotRenderer.tsx
54666
54656
  var UISlotRenderer_exports = {};
54667
54657
  __export(UISlotRenderer_exports, {
54658
+ SlotContainedContext: () => SlotContainedContext,
54668
54659
  SlotContentRenderer: () => SlotContentRenderer,
54669
54660
  SuspenseConfigProvider: () => SuspenseConfigProvider,
54670
54661
  UISlotComponent: () => UISlotComponent,
@@ -54837,6 +54828,25 @@ function renderContainedPortal(t, slot, content, onDismiss) {
54837
54828
  }
54838
54829
  );
54839
54830
  case "drawer":
54831
+ if (content.pattern === "detail-panel" && content.props.slideOver === true) {
54832
+ return /* @__PURE__ */ jsxRuntime.jsx(
54833
+ Box,
54834
+ {
54835
+ id: slotId,
54836
+ className: "absolute inset-0 z-50 overflow-hidden",
54837
+ style: { backgroundColor: "rgba(0, 0, 0, 0.5)" },
54838
+ onClick: onDismiss,
54839
+ children: /* @__PURE__ */ jsxRuntime.jsx(
54840
+ Box,
54841
+ {
54842
+ className: "absolute inset-y-0 right-0 pointer-events-auto",
54843
+ onClick: (e) => e.stopPropagation(),
54844
+ children: slotContent
54845
+ }
54846
+ )
54847
+ }
54848
+ );
54849
+ }
54840
54850
  return /* @__PURE__ */ jsxRuntime.jsx(
54841
54851
  Box,
54842
54852
  {
@@ -55688,7 +55698,7 @@ function UISlotRenderer({
55688
55698
  }
55689
55699
  return wrapped;
55690
55700
  }
55691
- var scopeWrapLog, TRAIT_BINDING_RE, SuspenseConfigContext, SlotContainedContext, SLOT_SKELETON_MAP, CONTENT_NODE_SLOTS, PATTERNS_WITH_CHILDREN, traitRefPresenceCache;
55701
+ var scopeWrapLog, TRAIT_BINDING_RE, SuspenseConfigContext, SLOT_SKELETON_MAP, CONTENT_NODE_SLOTS, PATTERNS_WITH_CHILDREN, traitRefPresenceCache;
55692
55702
  var init_UISlotRenderer = __esm({
55693
55703
  "components/core/organisms/UISlotRenderer.tsx"() {
55694
55704
  "use client";
@@ -55703,6 +55713,7 @@ var init_UISlotRenderer = __esm({
55703
55713
  init_cn();
55704
55714
  init_format();
55705
55715
  init_portalRoot();
55716
+ init_slotContained();
55706
55717
  init_ErrorBoundary();
55707
55718
  init_Skeleton();
55708
55719
  init_renderer();
@@ -55712,7 +55723,6 @@ var init_UISlotRenderer = __esm({
55712
55723
  scopeWrapLog = logger.createLogger("almadar:ui:scope-wrap");
55713
55724
  TRAIT_BINDING_RE = /^@trait\.([A-Z][A-Za-z0-9]*)$/;
55714
55725
  SuspenseConfigContext = React96.createContext({ enabled: false });
55715
- SlotContainedContext = React96.createContext(false);
55716
55726
  SuspenseConfigProvider.displayName = "SuspenseConfigProvider";
55717
55727
  SLOT_SKELETON_MAP = {
55718
55728
  main: "table",
@@ -60554,6 +60564,9 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
60554
60564
  const normalizedEvent = normalizeEventKey(eventKey);
60555
60565
  return managerRef.current.canHandleEvent(traitName, normalizedEvent);
60556
60566
  }, []);
60567
+ const commitServerEntity = React96.useCallback((traitName, entity) => {
60568
+ traitFieldStatesRef.current.set(traitName, entity);
60569
+ }, []);
60557
60570
  React96.useEffect(() => {
60558
60571
  const allEvents = /* @__PURE__ */ new Set();
60559
60572
  for (const binding of traitBindings) {
@@ -60717,7 +60730,8 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
60717
60730
  sendEvent,
60718
60731
  getTraitState,
60719
60732
  canHandleEvent,
60720
- entityBindingSource
60733
+ entityBindingSource,
60734
+ commitServerEntity
60721
60735
  };
60722
60736
  }
60723
60737
 
@@ -60853,6 +60867,8 @@ function TraitInitializer({ traits: traits2, routeParams, orbitalNames, onNaviga
60853
60867
  [serverActiveTraits]
60854
60868
  );
60855
60869
  const uiSlots = context.useUISlots();
60870
+ const commitServerEntityRef = React96.useRef(() => {
60871
+ });
60856
60872
  const onEventProcessed = React96.useCallback((event, payload, dispatchedOrbitals, tick, sourceTrait, locallyEmitted, results, entityByTrait) => {
60857
60873
  if (!bridge.connected || !orbitalNames?.length) return;
60858
60874
  const targets = dispatchedOrbitals && dispatchedOrbitals.size > 0 ? orbitalNames.filter((n) => dispatchedOrbitals.has(n)) : orbitalNames;
@@ -60869,12 +60885,18 @@ function TraitInitializer({ traits: traits2, routeParams, orbitalNames, onNaviga
60869
60885
  }
60870
60886
  void bridge.sendEvent(name, event, withActiveTraits(payload), void 0, void 0, locallyEmitted, results, entityByTrait, user ?? void 0).then(({ effects, meta }) => {
60871
60887
  recordServerResponse(name, event, { ...meta, effectResults: effectResultsToTraces(meta.effectResults) });
60888
+ if (meta.entityByTrait) {
60889
+ for (const [traitName, entity] of Object.entries(meta.entityByTrait)) {
60890
+ commitServerEntityRef.current(traitName, entity);
60891
+ }
60892
+ }
60872
60893
  applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits, activeTraitNamesRef.current, onNavigateBack);
60873
60894
  });
60874
60895
  }
60875
60896
  }, [bridge.connected, bridge.sendEvent, orbitalNames, uiSlots, onNavigate, onNavigateBack, embeddedTraits, activeTraitNames, withActiveTraits, user]);
60876
60897
  const opts = orbitalNames ? { onEventProcessed, navigate: onNavigate, navigateBack: onNavigateBack, traitConfigsByName, orbitalsByTrait, embeddedTraits, callsiteCaptureChildrenByTrait, initPayload: routeParams } : { navigate: onNavigate, navigateBack: onNavigateBack, persistence, traitConfigsByName, orbitalsByTrait, embeddedTraits, callsiteCaptureChildrenByTrait, initPayload: routeParams };
60877
- const { sendEvent, entityBindingSource } = useTraitStateMachine(traits2, uiSlots, opts);
60898
+ const { sendEvent, entityBindingSource, commitServerEntity } = useTraitStateMachine(traits2, uiSlots, opts);
60899
+ commitServerEntityRef.current = commitServerEntity;
60878
60900
  const initSentRef = React96.useRef(false);
60879
60901
  const prevTraitsRef = React96.useRef(void 0);
60880
60902
  const paramsKey = JSON.stringify(routeParams ?? {});
@@ -60926,6 +60948,11 @@ function TraitInitializer({ traits: traits2, routeParams, orbitalNames, onNaviga
60926
60948
  user ?? void 0
60927
60949
  );
60928
60950
  recordServerResponse(name, "INIT", { ...meta, effectResults: effectResultsToTraces(meta.effectResults) });
60951
+ if (meta.entityByTrait) {
60952
+ for (const [traitName, entity] of Object.entries(meta.entityByTrait)) {
60953
+ commitServerEntityRef.current(traitName, entity);
60954
+ }
60955
+ }
60929
60956
  const effectTraces = [
60930
60957
  { type: "fetch", args: [], status: "executed" },
60931
60958
  ...effects.map((eff) => ({
package/dist/avl/index.js CHANGED
@@ -6082,6 +6082,13 @@ var init_slot_types = __esm({
6082
6082
  nextRefId = 1;
6083
6083
  }
6084
6084
  });
6085
+ var SlotContainedContext;
6086
+ var init_slotContained = __esm({
6087
+ "lib/slotContained.ts"() {
6088
+ "use client";
6089
+ SlotContainedContext = createContext(false);
6090
+ }
6091
+ });
6085
6092
  function buildForkPaths(x, y, branches, scale) {
6086
6093
  const inLength = 30 * scale;
6087
6094
  const outLength = 30 * scale;
@@ -38394,7 +38401,6 @@ function TableView({
38394
38401
  columns,
38395
38402
  fields,
38396
38403
  itemActions,
38397
- maxInlineActions,
38398
38404
  itemClickEvent = "",
38399
38405
  selectable = false,
38400
38406
  selectEvent,
@@ -38428,8 +38434,7 @@ function TableView({
38428
38434
  const [localSelected, setLocalSelected] = React96__default.useState(/* @__PURE__ */ new Set());
38429
38435
  const colDefs = (Array.isArray(columns) ? columns : void 0) ?? (Array.isArray(fields) ? fields : void 0) ?? [];
38430
38436
  const actionDefs = Array.isArray(itemActions) ? itemActions : [];
38431
- const inlineActions = maxInlineActions != null ? actionDefs.slice(0, maxInlineActions) : [];
38432
- const overflowActions = maxInlineActions != null ? actionDefs.slice(maxInlineActions) : actionDefs;
38437
+ const overflowActions = actionDefs;
38433
38438
  const fireAction = (action, row) => eventBus.emit(`UI:${action.event}`, {
38434
38439
  id: row.id,
38435
38440
  row
@@ -38611,7 +38616,7 @@ function TableView({
38611
38616
  }
38612
38617
  return /* @__PURE__ */ jsx(Box, { role: "cell", className: cellBase, children: /* @__PURE__ */ jsx("span", { className: "truncate text-foreground", children: formatCell(raw, col.format, relationsData?.[col.field ?? col.key]) }) }, col.key);
38613
38618
  }),
38614
- hasActions && /* @__PURE__ */ jsxs(
38619
+ hasActions && /* @__PURE__ */ jsx(
38615
38620
  HStack,
38616
38621
  {
38617
38622
  gap: "xs",
@@ -38625,38 +38630,20 @@ function TableView({
38625
38630
  "border-l border-[var(--color-border)]",
38626
38631
  lk.striped && index % 2 === 1 ? "bg-[var(--color-surface-subtle)]" : "bg-[var(--color-card)] group-hover:bg-[var(--color-surface-subtle)]"
38627
38632
  ),
38628
- children: [
38629
- inlineActions.map((action) => /* @__PURE__ */ jsxs(
38630
- Button,
38631
- {
38632
- variant: action.variant ?? "ghost",
38633
- size: "sm",
38634
- onClick: () => fireAction(action, row),
38635
- "data-testid": `action-${action.event}`,
38636
- "data-row-id": String(row.id),
38637
- className: cn(action.variant === "danger" && "text-error hover:bg-error/10"),
38638
- children: [
38639
- action.icon && renderIconInput3(action.icon, { size: "xs", className: "mr-1" }),
38640
- action.label
38641
- ]
38642
- },
38643
- action.event
38644
- )),
38645
- overflowActions.length > 0 && /* @__PURE__ */ jsx(
38646
- Menu,
38647
- {
38648
- position: "bottom-end",
38649
- trigger: /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", "aria-label": t("common.actions"), "data-testid": "action-overflow", "data-row-id": String(row.id), children: /* @__PURE__ */ jsx(Icon, { name: "more-horizontal", size: "xs" }) }),
38650
- items: overflowActions.map((action) => ({
38651
- label: action.label,
38652
- icon: action.icon,
38653
- event: action.event,
38654
- variant: action.variant === "danger" ? "danger" : "default",
38655
- onClick: () => fireAction(action, row)
38656
- }))
38657
- }
38658
- )
38659
- ]
38633
+ children: overflowActions.length > 0 && /* @__PURE__ */ jsx(
38634
+ Menu,
38635
+ {
38636
+ position: "bottom-end",
38637
+ trigger: /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", "aria-label": t("common.actions"), "data-testid": "action-overflow", "data-row-id": String(row.id), children: /* @__PURE__ */ jsx(Icon, { name: "more-horizontal", size: "xs" }) }),
38638
+ items: overflowActions.map((action) => ({
38639
+ label: action.label,
38640
+ icon: action.icon,
38641
+ event: action.event,
38642
+ variant: action.variant === "danger" ? "danger" : "default",
38643
+ onClick: () => fireAction(action, row)
38644
+ }))
38645
+ }
38646
+ )
38660
38647
  }
38661
38648
  )
38662
38649
  ]
@@ -47673,6 +47660,7 @@ var init_DetailPanel = __esm({
47673
47660
  init_EmptyState();
47674
47661
  init_cn();
47675
47662
  init_portalRoot();
47663
+ init_slotContained();
47676
47664
  init_format();
47677
47665
  init_getNestedValue();
47678
47666
  init_relationLabel();
@@ -47704,6 +47692,7 @@ var init_DetailPanel = __esm({
47704
47692
  }) => {
47705
47693
  const eventBus = useEventBus();
47706
47694
  const { t } = useTranslate();
47695
+ const contained = useContext(SlotContainedContext);
47707
47696
  const [titleDraft, setTitleDraft] = React96__default.useState(null);
47708
47697
  const isFieldDefArray = (arr) => {
47709
47698
  if (!arr || arr.length === 0) return false;
@@ -48091,8 +48080,9 @@ var init_DetailPanel = __esm({
48091
48080
  if (!slideOver) {
48092
48081
  return /* @__PURE__ */ jsx(Box, { className, children: content });
48093
48082
  }
48094
- const panel = /* @__PURE__ */ jsx(Box, { className: cn("fixed inset-y-0 right-0 w-full max-w-2xl bg-card shadow-lg z-50 overflow-y-auto p-6", className), children: content });
48095
- return typeof document === "undefined" ? panel : createPortal(panel, getOrCreatePortalRoot());
48083
+ const panel = /* @__PURE__ */ jsx(Box, { className: cn(contained ? "absolute" : "fixed", "inset-y-0 right-0 w-full max-w-2xl bg-card shadow-lg z-50 overflow-y-auto p-6", className), children: content });
48084
+ if (contained || typeof document === "undefined") return panel;
48085
+ return createPortal(panel, getOrCreatePortalRoot());
48096
48086
  };
48097
48087
  DetailPanel.displayName = "DetailPanel";
48098
48088
  }
@@ -54589,6 +54579,7 @@ var init_component_registry_generated = __esm({
54589
54579
  // components/core/organisms/UISlotRenderer.tsx
54590
54580
  var UISlotRenderer_exports = {};
54591
54581
  __export(UISlotRenderer_exports, {
54582
+ SlotContainedContext: () => SlotContainedContext,
54592
54583
  SlotContentRenderer: () => SlotContentRenderer,
54593
54584
  SuspenseConfigProvider: () => SuspenseConfigProvider,
54594
54585
  UISlotComponent: () => UISlotComponent,
@@ -54761,6 +54752,25 @@ function renderContainedPortal(t, slot, content, onDismiss) {
54761
54752
  }
54762
54753
  );
54763
54754
  case "drawer":
54755
+ if (content.pattern === "detail-panel" && content.props.slideOver === true) {
54756
+ return /* @__PURE__ */ jsx(
54757
+ Box,
54758
+ {
54759
+ id: slotId,
54760
+ className: "absolute inset-0 z-50 overflow-hidden",
54761
+ style: { backgroundColor: "rgba(0, 0, 0, 0.5)" },
54762
+ onClick: onDismiss,
54763
+ children: /* @__PURE__ */ jsx(
54764
+ Box,
54765
+ {
54766
+ className: "absolute inset-y-0 right-0 pointer-events-auto",
54767
+ onClick: (e) => e.stopPropagation(),
54768
+ children: slotContent
54769
+ }
54770
+ )
54771
+ }
54772
+ );
54773
+ }
54764
54774
  return /* @__PURE__ */ jsx(
54765
54775
  Box,
54766
54776
  {
@@ -55612,7 +55622,7 @@ function UISlotRenderer({
55612
55622
  }
55613
55623
  return wrapped;
55614
55624
  }
55615
- var scopeWrapLog, TRAIT_BINDING_RE, SuspenseConfigContext, SlotContainedContext, SLOT_SKELETON_MAP, CONTENT_NODE_SLOTS, PATTERNS_WITH_CHILDREN, traitRefPresenceCache;
55625
+ var scopeWrapLog, TRAIT_BINDING_RE, SuspenseConfigContext, SLOT_SKELETON_MAP, CONTENT_NODE_SLOTS, PATTERNS_WITH_CHILDREN, traitRefPresenceCache;
55616
55626
  var init_UISlotRenderer = __esm({
55617
55627
  "components/core/organisms/UISlotRenderer.tsx"() {
55618
55628
  "use client";
@@ -55627,6 +55637,7 @@ var init_UISlotRenderer = __esm({
55627
55637
  init_cn();
55628
55638
  init_format();
55629
55639
  init_portalRoot();
55640
+ init_slotContained();
55630
55641
  init_ErrorBoundary();
55631
55642
  init_Skeleton();
55632
55643
  init_renderer();
@@ -55636,7 +55647,6 @@ var init_UISlotRenderer = __esm({
55636
55647
  scopeWrapLog = createLogger("almadar:ui:scope-wrap");
55637
55648
  TRAIT_BINDING_RE = /^@trait\.([A-Z][A-Za-z0-9]*)$/;
55638
55649
  SuspenseConfigContext = createContext({ enabled: false });
55639
- SlotContainedContext = createContext(false);
55640
55650
  SuspenseConfigProvider.displayName = "SuspenseConfigProvider";
55641
55651
  SLOT_SKELETON_MAP = {
55642
55652
  main: "table",
@@ -60478,6 +60488,9 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
60478
60488
  const normalizedEvent = normalizeEventKey(eventKey);
60479
60489
  return managerRef.current.canHandleEvent(traitName, normalizedEvent);
60480
60490
  }, []);
60491
+ const commitServerEntity = useCallback((traitName, entity) => {
60492
+ traitFieldStatesRef.current.set(traitName, entity);
60493
+ }, []);
60481
60494
  useEffect(() => {
60482
60495
  const allEvents = /* @__PURE__ */ new Set();
60483
60496
  for (const binding of traitBindings) {
@@ -60641,7 +60654,8 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
60641
60654
  sendEvent,
60642
60655
  getTraitState,
60643
60656
  canHandleEvent,
60644
- entityBindingSource
60657
+ entityBindingSource,
60658
+ commitServerEntity
60645
60659
  };
60646
60660
  }
60647
60661
 
@@ -60777,6 +60791,8 @@ function TraitInitializer({ traits: traits2, routeParams, orbitalNames, onNaviga
60777
60791
  [serverActiveTraits]
60778
60792
  );
60779
60793
  const uiSlots = useUISlots();
60794
+ const commitServerEntityRef = useRef(() => {
60795
+ });
60780
60796
  const onEventProcessed = useCallback((event, payload, dispatchedOrbitals, tick, sourceTrait, locallyEmitted, results, entityByTrait) => {
60781
60797
  if (!bridge.connected || !orbitalNames?.length) return;
60782
60798
  const targets = dispatchedOrbitals && dispatchedOrbitals.size > 0 ? orbitalNames.filter((n) => dispatchedOrbitals.has(n)) : orbitalNames;
@@ -60793,12 +60809,18 @@ function TraitInitializer({ traits: traits2, routeParams, orbitalNames, onNaviga
60793
60809
  }
60794
60810
  void bridge.sendEvent(name, event, withActiveTraits(payload), void 0, void 0, locallyEmitted, results, entityByTrait, user ?? void 0).then(({ effects, meta }) => {
60795
60811
  recordServerResponse(name, event, { ...meta, effectResults: effectResultsToTraces(meta.effectResults) });
60812
+ if (meta.entityByTrait) {
60813
+ for (const [traitName, entity] of Object.entries(meta.entityByTrait)) {
60814
+ commitServerEntityRef.current(traitName, entity);
60815
+ }
60816
+ }
60796
60817
  applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits, activeTraitNamesRef.current, onNavigateBack);
60797
60818
  });
60798
60819
  }
60799
60820
  }, [bridge.connected, bridge.sendEvent, orbitalNames, uiSlots, onNavigate, onNavigateBack, embeddedTraits, activeTraitNames, withActiveTraits, user]);
60800
60821
  const opts = orbitalNames ? { onEventProcessed, navigate: onNavigate, navigateBack: onNavigateBack, traitConfigsByName, orbitalsByTrait, embeddedTraits, callsiteCaptureChildrenByTrait, initPayload: routeParams } : { navigate: onNavigate, navigateBack: onNavigateBack, persistence, traitConfigsByName, orbitalsByTrait, embeddedTraits, callsiteCaptureChildrenByTrait, initPayload: routeParams };
60801
- const { sendEvent, entityBindingSource } = useTraitStateMachine(traits2, uiSlots, opts);
60822
+ const { sendEvent, entityBindingSource, commitServerEntity } = useTraitStateMachine(traits2, uiSlots, opts);
60823
+ commitServerEntityRef.current = commitServerEntity;
60802
60824
  const initSentRef = useRef(false);
60803
60825
  const prevTraitsRef = useRef(void 0);
60804
60826
  const paramsKey = JSON.stringify(routeParams ?? {});
@@ -60850,6 +60872,11 @@ function TraitInitializer({ traits: traits2, routeParams, orbitalNames, onNaviga
60850
60872
  user ?? void 0
60851
60873
  );
60852
60874
  recordServerResponse(name, "INIT", { ...meta, effectResults: effectResultsToTraces(meta.effectResults) });
60875
+ if (meta.entityByTrait) {
60876
+ for (const [traitName, entity] of Object.entries(meta.entityByTrait)) {
60877
+ commitServerEntityRef.current(traitName, entity);
60878
+ }
60879
+ }
60853
60880
  const effectTraces = [
60854
60881
  { type: "fetch", args: [], status: "executed" },
60855
60882
  ...effects.map((eff) => ({