@almadar/ui 4.8.0 → 4.10.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.
@@ -1,7 +1,7 @@
1
1
  import * as React116 from 'react';
2
- import React116__default, { createContext, useContext, useRef, useEffect, useCallback, Suspense, useState, useMemo, useLayoutEffect, lazy, useId } from 'react';
2
+ import React116__default, { createContext, useContext, useMemo, useRef, useEffect, useCallback, Suspense, useState, useLayoutEffect, lazy, useId } from 'react';
3
3
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
4
- import { EventBusContext } from '@almadar/ui/providers';
4
+ import { EventBusContext, useTraitScope, TraitScopeProvider } from '@almadar/ui/providers';
5
5
  import { clsx } from 'clsx';
6
6
  import { twMerge } from 'tailwind-merge';
7
7
  import * as LucideIcons from 'lucide-react';
@@ -391,7 +391,23 @@ function getGlobalEventBus() {
391
391
  }
392
392
  function useEventBus() {
393
393
  const context = useContext(EventBusContext);
394
- return context ?? getGlobalEventBus() ?? fallbackEventBus;
394
+ const baseBus = context ?? getGlobalEventBus() ?? fallbackEventBus;
395
+ const scope = useTraitScope();
396
+ return useMemo(() => {
397
+ if (!scope) return baseBus;
398
+ return {
399
+ ...baseBus,
400
+ emit: (type, payload, source) => {
401
+ if (typeof type === "string" && type.startsWith("UI:")) {
402
+ const tail = type.slice(3);
403
+ const qualified = tail.includes(".") ? type : `UI:${scope.orbital}.${scope.trait}.${tail}`;
404
+ baseBus.emit(qualified, payload, source);
405
+ return;
406
+ }
407
+ baseBus.emit(type, payload, source);
408
+ }
409
+ };
410
+ }, [baseBus, scope]);
395
411
  }
396
412
  function useEventListener(event, handler) {
397
413
  const eventBus = useEventBus();
@@ -37809,6 +37825,17 @@ function renderContainedPortal(slot, content, onDismiss) {
37809
37825
  return /* @__PURE__ */ jsx(Box, { id: slotId, children: slotContent });
37810
37826
  }
37811
37827
  }
37828
+ function MaybeTraitScope({
37829
+ sourceTrait,
37830
+ children
37831
+ }) {
37832
+ const schemaCtx = useEntitySchemaOptional();
37833
+ const orbital = sourceTrait !== void 0 && schemaCtx !== null ? schemaCtx.orbitalsByTrait.get(sourceTrait) : void 0;
37834
+ if (sourceTrait !== void 0 && orbital !== void 0) {
37835
+ return /* @__PURE__ */ jsx(TraitScopeProvider, { orbital, trait: sourceTrait, children });
37836
+ }
37837
+ return /* @__PURE__ */ jsx(Fragment, { children });
37838
+ }
37812
37839
  function UISlotComponent({
37813
37840
  slot,
37814
37841
  portal = false,
@@ -37836,11 +37863,11 @@ function UISlotComponent({
37836
37863
  className: cn("ui-slot", `ui-slot-${slot}`, className),
37837
37864
  "data-pattern": pattern,
37838
37865
  "data-source-trait": sourceTrait,
37839
- children
37866
+ children: /* @__PURE__ */ jsx(MaybeTraitScope, { sourceTrait, children })
37840
37867
  }
37841
37868
  );
37842
37869
  }
37843
- return /* @__PURE__ */ jsx(CompiledPortal, { slot, className, pattern, sourceTrait, children });
37870
+ return /* @__PURE__ */ jsx(CompiledPortal, { slot, className, pattern, sourceTrait, children: /* @__PURE__ */ jsx(MaybeTraitScope, { sourceTrait, children }) });
37844
37871
  }
37845
37872
  return /* @__PURE__ */ jsx(
37846
37873
  Box,
@@ -37849,7 +37876,7 @@ function UISlotComponent({
37849
37876
  className: cn("ui-slot", `ui-slot-${slot}`, className),
37850
37877
  "data-pattern": pattern,
37851
37878
  "data-source-trait": sourceTrait,
37852
- children
37879
+ children: /* @__PURE__ */ jsx(MaybeTraitScope, { sourceTrait, children })
37853
37880
  }
37854
37881
  );
37855
37882
  }
@@ -37895,7 +37922,7 @@ function UISlotComponent({
37895
37922
  className: cn("ui-slot", `ui-slot-${slot}`, className),
37896
37923
  "data-pattern": content.pattern,
37897
37924
  "data-source-trait": content.sourceTrait,
37898
- children: wrappedContent
37925
+ children: /* @__PURE__ */ jsx(MaybeTraitScope, { sourceTrait: content.sourceTrait, children: wrappedContent })
37899
37926
  }
37900
37927
  );
37901
37928
  }
@@ -38003,7 +38030,7 @@ function SlotPortal({
38003
38030
  });
38004
38031
  if (!portalRoot) return null;
38005
38032
  const slotId = `slot-${slot}`;
38006
- const slotContent = /* @__PURE__ */ jsx(SlotContentRenderer, { content, onDismiss });
38033
+ const slotContent = /* @__PURE__ */ jsx(MaybeTraitScope, { sourceTrait: content.sourceTrait, children: /* @__PURE__ */ jsx(SlotContentRenderer, { content, onDismiss }) });
38007
38034
  let wrapper;
38008
38035
  switch (slot) {
38009
38036
  case "modal":
@@ -38835,6 +38862,18 @@ function OrbitalProvider({
38835
38862
  );
38836
38863
  }
38837
38864
  OrbitalProvider.displayName = "OrbitalProvider";
38865
+ var TraitScopeContext = createContext(null);
38866
+ function TraitScopeProvider2({
38867
+ orbital,
38868
+ trait,
38869
+ children
38870
+ }) {
38871
+ const value = useMemo(() => ({ orbital, trait }), [orbital, trait]);
38872
+ return /* @__PURE__ */ jsx(TraitScopeContext.Provider, { value, children });
38873
+ }
38874
+ function useTraitScope2() {
38875
+ return useContext(TraitScopeContext);
38876
+ }
38838
38877
 
38839
38878
  // providers/OfflineModeProvider.tsx
38840
38879
  init_offline_executor();
@@ -38868,4 +38907,4 @@ function useOptionalOfflineMode() {
38868
38907
  return useContext(OfflineModeContext);
38869
38908
  }
38870
38909
 
38871
- export { EventBusContext2 as EventBusContext, EventBusProvider, OfflineModeProvider, OrbitalProvider, SelectionContext, SelectionProvider, VerificationProvider, useOfflineMode, useOptionalOfflineMode, useSelection, useSelectionOptional };
38910
+ export { EventBusContext2 as EventBusContext, EventBusProvider, OfflineModeProvider, OrbitalProvider, SelectionContext, SelectionProvider, TraitScopeProvider2 as TraitScopeProvider, VerificationProvider, useOfflineMode, useOptionalOfflineMode, useSelection, useSelectionOptional, useTraitScope2 as useTraitScope };
@@ -29,6 +29,14 @@ export interface EntitySchemaContextValue {
29
29
  * etc.) and an enum field renders as a plain text input. Closes VR3.
30
30
  */
31
31
  traitLinkedEntities: ReadonlyMap<string, string>;
32
+ /**
33
+ * Per-trait owning-orbital name. Same shape as `traitLinkedEntities`,
34
+ * built from `schema.orbitals[].traits[]`. UISlotRenderer uses this
35
+ * to wrap each slot's rendered subtree in `TraitScopeProvider` so
36
+ * descendant pure components (Button, etc.) emit qualified
37
+ * `UI:Orbital.Trait.EVENT` keys via the scoped useEventBus.
38
+ */
39
+ orbitalsByTrait: ReadonlyMap<string, string>;
32
40
  }
33
41
  export interface EntitySchemaProviderProps {
34
42
  /** Entity definitions from resolved schema */
@@ -40,6 +48,13 @@ export interface EntitySchemaProviderProps {
40
48
  * legacy V1 string-entity-name lookup.
41
49
  */
42
50
  traitLinkedEntities?: ReadonlyMap<string, string>;
51
+ /**
52
+ * Per-trait owning-orbital name. Required for the runtime path's
53
+ * trait-scoped event qualification (Button etc. emit qualified keys
54
+ * via TraitScopeProvider). Optional for back-compat with consumers
55
+ * that don't yet thread the orbital map through.
56
+ */
57
+ orbitalsByTrait?: ReadonlyMap<string, string>;
43
58
  /** Children */
44
59
  children: React.ReactNode;
45
60
  }
@@ -50,7 +65,7 @@ export interface EntitySchemaProviderProps {
50
65
  * Actual entity rows arrive via `@payload.data` on the rendering trait's
51
66
  * success transition — they do NOT live in this context.
52
67
  */
53
- export declare function EntitySchemaProvider({ entities, traitLinkedEntities, children, }: EntitySchemaProviderProps): React.ReactElement;
68
+ export declare function EntitySchemaProvider({ entities, traitLinkedEntities, orbitalsByTrait, children, }: EntitySchemaProviderProps): React.ReactElement;
54
69
  /**
55
70
  * Access entity schema definitions.
56
71
  * Use this for field metadata (form building, filter enrichment).
@@ -183,7 +183,23 @@ function getGlobalEventBus() {
183
183
  }
184
184
  function useEventBus() {
185
185
  const context = React115.useContext(providers.EventBusContext);
186
- return context ?? getGlobalEventBus() ?? fallbackEventBus;
186
+ const baseBus = context ?? getGlobalEventBus() ?? fallbackEventBus;
187
+ const scope = providers.useTraitScope();
188
+ return React115.useMemo(() => {
189
+ if (!scope) return baseBus;
190
+ return {
191
+ ...baseBus,
192
+ emit: (type, payload, source) => {
193
+ if (typeof type === "string" && type.startsWith("UI:")) {
194
+ const tail = type.slice(3);
195
+ const qualified = tail.includes(".") ? type : `UI:${scope.orbital}.${scope.trait}.${tail}`;
196
+ baseBus.emit(qualified, payload, source);
197
+ return;
198
+ }
199
+ baseBus.emit(type, payload, source);
200
+ }
201
+ };
202
+ }, [baseBus, scope]);
187
203
  }
188
204
  function useEventListener(event, handler) {
189
205
  const eventBus = useEventBus();
@@ -785,6 +801,7 @@ var init_usePullToRefresh = __esm({
785
801
  function EntitySchemaProvider({
786
802
  entities,
787
803
  traitLinkedEntities,
804
+ orbitalsByTrait,
788
805
  children
789
806
  }) {
790
807
  const entitiesMap = React115.useMemo(() => {
@@ -797,12 +814,16 @@ function EntitySchemaProvider({
797
814
  const linkedMap = React115.useMemo(() => {
798
815
  return traitLinkedEntities ?? /* @__PURE__ */ new Map();
799
816
  }, [traitLinkedEntities]);
817
+ const orbitalsMap = React115.useMemo(() => {
818
+ return orbitalsByTrait ?? /* @__PURE__ */ new Map();
819
+ }, [orbitalsByTrait]);
800
820
  const contextValue = React115.useMemo(
801
821
  () => ({
802
822
  entities: entitiesMap,
803
- traitLinkedEntities: linkedMap
823
+ traitLinkedEntities: linkedMap,
824
+ orbitalsByTrait: orbitalsMap
804
825
  }),
805
- [entitiesMap, linkedMap]
826
+ [entitiesMap, linkedMap, orbitalsMap]
806
827
  );
807
828
  return /* @__PURE__ */ jsxRuntime.jsx(EntitySchemaContext.Provider, { value: contextValue, children });
808
829
  }
@@ -37536,6 +37557,17 @@ function renderContainedPortal(slot, content, onDismiss) {
37536
37557
  return /* @__PURE__ */ jsxRuntime.jsx(Box, { id: slotId, children: slotContent });
37537
37558
  }
37538
37559
  }
37560
+ function MaybeTraitScope({
37561
+ sourceTrait,
37562
+ children
37563
+ }) {
37564
+ const schemaCtx = useEntitySchemaOptional();
37565
+ const orbital = sourceTrait !== void 0 && schemaCtx !== null ? schemaCtx.orbitalsByTrait.get(sourceTrait) : void 0;
37566
+ if (sourceTrait !== void 0 && orbital !== void 0) {
37567
+ return /* @__PURE__ */ jsxRuntime.jsx(providers.TraitScopeProvider, { orbital, trait: sourceTrait, children });
37568
+ }
37569
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children });
37570
+ }
37539
37571
  function UISlotComponent({
37540
37572
  slot,
37541
37573
  portal = false,
@@ -37563,11 +37595,11 @@ function UISlotComponent({
37563
37595
  className: cn("ui-slot", `ui-slot-${slot}`, className),
37564
37596
  "data-pattern": pattern,
37565
37597
  "data-source-trait": sourceTrait,
37566
- children
37598
+ children: /* @__PURE__ */ jsxRuntime.jsx(MaybeTraitScope, { sourceTrait, children })
37567
37599
  }
37568
37600
  );
37569
37601
  }
37570
- return /* @__PURE__ */ jsxRuntime.jsx(CompiledPortal, { slot, className, pattern, sourceTrait, children });
37602
+ return /* @__PURE__ */ jsxRuntime.jsx(CompiledPortal, { slot, className, pattern, sourceTrait, children: /* @__PURE__ */ jsxRuntime.jsx(MaybeTraitScope, { sourceTrait, children }) });
37571
37603
  }
37572
37604
  return /* @__PURE__ */ jsxRuntime.jsx(
37573
37605
  Box,
@@ -37576,7 +37608,7 @@ function UISlotComponent({
37576
37608
  className: cn("ui-slot", `ui-slot-${slot}`, className),
37577
37609
  "data-pattern": pattern,
37578
37610
  "data-source-trait": sourceTrait,
37579
- children
37611
+ children: /* @__PURE__ */ jsxRuntime.jsx(MaybeTraitScope, { sourceTrait, children })
37580
37612
  }
37581
37613
  );
37582
37614
  }
@@ -37622,7 +37654,7 @@ function UISlotComponent({
37622
37654
  className: cn("ui-slot", `ui-slot-${slot}`, className),
37623
37655
  "data-pattern": content.pattern,
37624
37656
  "data-source-trait": content.sourceTrait,
37625
- children: wrappedContent
37657
+ children: /* @__PURE__ */ jsxRuntime.jsx(MaybeTraitScope, { sourceTrait: content.sourceTrait, children: wrappedContent })
37626
37658
  }
37627
37659
  );
37628
37660
  }
@@ -37730,7 +37762,7 @@ function SlotPortal({
37730
37762
  });
37731
37763
  if (!portalRoot) return null;
37732
37764
  const slotId = `slot-${slot}`;
37733
- const slotContent = /* @__PURE__ */ jsxRuntime.jsx(SlotContentRenderer, { content, onDismiss });
37765
+ const slotContent = /* @__PURE__ */ jsxRuntime.jsx(MaybeTraitScope, { sourceTrait: content.sourceTrait, children: /* @__PURE__ */ jsxRuntime.jsx(SlotContentRenderer, { content, onDismiss }) });
37734
37766
  let wrapper;
37735
37767
  switch (slot) {
37736
37768
  case "modal":
@@ -38752,7 +38784,35 @@ function useResolvedSchema(schema, pageName) {
38752
38784
  const ir = React115.useMemo(() => {
38753
38785
  if (!schema) return null;
38754
38786
  try {
38755
- return core.schemaToIR(schema);
38787
+ const resolved = core.schemaToIR(schema);
38788
+ const sourceListsByTrait = /* @__PURE__ */ new Map();
38789
+ const orbitals = schema.orbitals;
38790
+ if (Array.isArray(orbitals)) {
38791
+ for (const orb of orbitals) {
38792
+ const traits2 = orb.traits;
38793
+ if (!Array.isArray(traits2)) continue;
38794
+ for (const trait of traits2) {
38795
+ const t = trait;
38796
+ if (typeof t.name !== "string" || !Array.isArray(t.listens)) continue;
38797
+ const sources = t.listens.map((listen) => {
38798
+ const l = listen;
38799
+ return l.source;
38800
+ });
38801
+ sourceListsByTrait.set(t.name, sources);
38802
+ }
38803
+ }
38804
+ }
38805
+ for (const [traitName, trait] of resolved.traits) {
38806
+ const sources = sourceListsByTrait.get(traitName);
38807
+ if (!sources) continue;
38808
+ trait.listens.forEach((listen, i) => {
38809
+ const src = sources[i];
38810
+ if (src !== void 0) {
38811
+ listen.source = src;
38812
+ }
38813
+ });
38814
+ }
38815
+ return resolved;
38756
38816
  } catch (err) {
38757
38817
  setError(err instanceof Error ? err.message : "Schema resolution failed");
38758
38818
  return null;
@@ -39300,6 +39360,24 @@ function SchemaRunner({ schema, serverUrl, mockData, pageName, onNavigate, onLoc
39300
39360
  }
39301
39361
  return map;
39302
39362
  }, [schema]);
39363
+ const traitLinkedEntitiesMap = React115.useMemo(() => {
39364
+ const map = /* @__PURE__ */ new Map();
39365
+ if (ir) {
39366
+ for (const page of ir.pages.values()) {
39367
+ for (const binding of page.traits) {
39368
+ if (binding.linkedEntity) {
39369
+ map.set(binding.trait.name, binding.linkedEntity);
39370
+ }
39371
+ }
39372
+ }
39373
+ }
39374
+ return map;
39375
+ }, [ir]);
39376
+ const orbitalsByTraitMap = React115.useMemo(
39377
+ () => new Map(Object.entries(orbitalsByTrait)),
39378
+ [orbitalsByTrait]
39379
+ );
39380
+ const entitiesArray = React115.useMemo(() => Array.from(allEntities.values()), [allEntities]);
39303
39381
  const pageOrbitalNames = React115.useMemo(() => {
39304
39382
  const set = /* @__PURE__ */ new Set();
39305
39383
  for (const binding of allPageTraits) {
@@ -39343,20 +39421,9 @@ function SchemaRunner({ schema, serverUrl, mockData, pageName, onNavigate, onLoc
39343
39421
  const inner = /* @__PURE__ */ jsxRuntime.jsx(providers.VerificationProvider, { enabled: true, children: /* @__PURE__ */ jsxRuntime.jsx(SlotsProvider, { children: /* @__PURE__ */ jsxRuntime.jsxs(
39344
39422
  EntitySchemaProvider,
39345
39423
  {
39346
- entities: Array.from(allEntities.values()),
39347
- traitLinkedEntities: (() => {
39348
- const map = /* @__PURE__ */ new Map();
39349
- if (ir) {
39350
- for (const page of ir.pages.values()) {
39351
- for (const binding of page.traits) {
39352
- if (binding.linkedEntity) {
39353
- map.set(binding.trait.name, binding.linkedEntity);
39354
- }
39355
- }
39356
- }
39357
- }
39358
- return map;
39359
- })(),
39424
+ entities: entitiesArray,
39425
+ traitLinkedEntities: traitLinkedEntitiesMap,
39426
+ orbitalsByTrait: orbitalsByTraitMap,
39360
39427
  children: [
39361
39428
  /* @__PURE__ */ jsxRuntime.jsx(
39362
39429
  TraitInitializer,
@@ -1,6 +1,6 @@
1
1
  import * as React115 from 'react';
2
- import React115__default, { createContext, useContext, useRef, useEffect, useCallback, useMemo, useState, Suspense, useLayoutEffect, lazy, useId } from 'react';
3
- import { EventBusContext, OrbitalProvider, VerificationProvider } from '@almadar/ui/providers';
2
+ import React115__default, { createContext, useContext, useMemo, useRef, useEffect, useCallback, useState, Suspense, useLayoutEffect, lazy, useId } from 'react';
3
+ import { EventBusContext, useTraitScope, OrbitalProvider, TraitScopeProvider, VerificationProvider } from '@almadar/ui/providers';
4
4
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
5
5
  import { clsx } from 'clsx';
6
6
  import { twMerge } from 'tailwind-merge';
@@ -138,7 +138,23 @@ function getGlobalEventBus() {
138
138
  }
139
139
  function useEventBus() {
140
140
  const context = useContext(EventBusContext);
141
- return context ?? getGlobalEventBus() ?? fallbackEventBus;
141
+ const baseBus = context ?? getGlobalEventBus() ?? fallbackEventBus;
142
+ const scope = useTraitScope();
143
+ return useMemo(() => {
144
+ if (!scope) return baseBus;
145
+ return {
146
+ ...baseBus,
147
+ emit: (type, payload, source) => {
148
+ if (typeof type === "string" && type.startsWith("UI:")) {
149
+ const tail = type.slice(3);
150
+ const qualified = tail.includes(".") ? type : `UI:${scope.orbital}.${scope.trait}.${tail}`;
151
+ baseBus.emit(qualified, payload, source);
152
+ return;
153
+ }
154
+ baseBus.emit(type, payload, source);
155
+ }
156
+ };
157
+ }, [baseBus, scope]);
142
158
  }
143
159
  function useEventListener(event, handler) {
144
160
  const eventBus = useEventBus();
@@ -740,6 +756,7 @@ var init_usePullToRefresh = __esm({
740
756
  function EntitySchemaProvider({
741
757
  entities,
742
758
  traitLinkedEntities,
759
+ orbitalsByTrait,
743
760
  children
744
761
  }) {
745
762
  const entitiesMap = useMemo(() => {
@@ -752,12 +769,16 @@ function EntitySchemaProvider({
752
769
  const linkedMap = useMemo(() => {
753
770
  return traitLinkedEntities ?? /* @__PURE__ */ new Map();
754
771
  }, [traitLinkedEntities]);
772
+ const orbitalsMap = useMemo(() => {
773
+ return orbitalsByTrait ?? /* @__PURE__ */ new Map();
774
+ }, [orbitalsByTrait]);
755
775
  const contextValue = useMemo(
756
776
  () => ({
757
777
  entities: entitiesMap,
758
- traitLinkedEntities: linkedMap
778
+ traitLinkedEntities: linkedMap,
779
+ orbitalsByTrait: orbitalsMap
759
780
  }),
760
- [entitiesMap, linkedMap]
781
+ [entitiesMap, linkedMap, orbitalsMap]
761
782
  );
762
783
  return /* @__PURE__ */ jsx(EntitySchemaContext.Provider, { value: contextValue, children });
763
784
  }
@@ -37491,6 +37512,17 @@ function renderContainedPortal(slot, content, onDismiss) {
37491
37512
  return /* @__PURE__ */ jsx(Box, { id: slotId, children: slotContent });
37492
37513
  }
37493
37514
  }
37515
+ function MaybeTraitScope({
37516
+ sourceTrait,
37517
+ children
37518
+ }) {
37519
+ const schemaCtx = useEntitySchemaOptional();
37520
+ const orbital = sourceTrait !== void 0 && schemaCtx !== null ? schemaCtx.orbitalsByTrait.get(sourceTrait) : void 0;
37521
+ if (sourceTrait !== void 0 && orbital !== void 0) {
37522
+ return /* @__PURE__ */ jsx(TraitScopeProvider, { orbital, trait: sourceTrait, children });
37523
+ }
37524
+ return /* @__PURE__ */ jsx(Fragment, { children });
37525
+ }
37494
37526
  function UISlotComponent({
37495
37527
  slot,
37496
37528
  portal = false,
@@ -37518,11 +37550,11 @@ function UISlotComponent({
37518
37550
  className: cn("ui-slot", `ui-slot-${slot}`, className),
37519
37551
  "data-pattern": pattern,
37520
37552
  "data-source-trait": sourceTrait,
37521
- children
37553
+ children: /* @__PURE__ */ jsx(MaybeTraitScope, { sourceTrait, children })
37522
37554
  }
37523
37555
  );
37524
37556
  }
37525
- return /* @__PURE__ */ jsx(CompiledPortal, { slot, className, pattern, sourceTrait, children });
37557
+ return /* @__PURE__ */ jsx(CompiledPortal, { slot, className, pattern, sourceTrait, children: /* @__PURE__ */ jsx(MaybeTraitScope, { sourceTrait, children }) });
37526
37558
  }
37527
37559
  return /* @__PURE__ */ jsx(
37528
37560
  Box,
@@ -37531,7 +37563,7 @@ function UISlotComponent({
37531
37563
  className: cn("ui-slot", `ui-slot-${slot}`, className),
37532
37564
  "data-pattern": pattern,
37533
37565
  "data-source-trait": sourceTrait,
37534
- children
37566
+ children: /* @__PURE__ */ jsx(MaybeTraitScope, { sourceTrait, children })
37535
37567
  }
37536
37568
  );
37537
37569
  }
@@ -37577,7 +37609,7 @@ function UISlotComponent({
37577
37609
  className: cn("ui-slot", `ui-slot-${slot}`, className),
37578
37610
  "data-pattern": content.pattern,
37579
37611
  "data-source-trait": content.sourceTrait,
37580
- children: wrappedContent
37612
+ children: /* @__PURE__ */ jsx(MaybeTraitScope, { sourceTrait: content.sourceTrait, children: wrappedContent })
37581
37613
  }
37582
37614
  );
37583
37615
  }
@@ -37685,7 +37717,7 @@ function SlotPortal({
37685
37717
  });
37686
37718
  if (!portalRoot) return null;
37687
37719
  const slotId = `slot-${slot}`;
37688
- const slotContent = /* @__PURE__ */ jsx(SlotContentRenderer, { content, onDismiss });
37720
+ const slotContent = /* @__PURE__ */ jsx(MaybeTraitScope, { sourceTrait: content.sourceTrait, children: /* @__PURE__ */ jsx(SlotContentRenderer, { content, onDismiss }) });
37689
37721
  let wrapper;
37690
37722
  switch (slot) {
37691
37723
  case "modal":
@@ -38707,7 +38739,35 @@ function useResolvedSchema(schema, pageName) {
38707
38739
  const ir = useMemo(() => {
38708
38740
  if (!schema) return null;
38709
38741
  try {
38710
- return schemaToIR(schema);
38742
+ const resolved = schemaToIR(schema);
38743
+ const sourceListsByTrait = /* @__PURE__ */ new Map();
38744
+ const orbitals = schema.orbitals;
38745
+ if (Array.isArray(orbitals)) {
38746
+ for (const orb of orbitals) {
38747
+ const traits2 = orb.traits;
38748
+ if (!Array.isArray(traits2)) continue;
38749
+ for (const trait of traits2) {
38750
+ const t = trait;
38751
+ if (typeof t.name !== "string" || !Array.isArray(t.listens)) continue;
38752
+ const sources = t.listens.map((listen) => {
38753
+ const l = listen;
38754
+ return l.source;
38755
+ });
38756
+ sourceListsByTrait.set(t.name, sources);
38757
+ }
38758
+ }
38759
+ }
38760
+ for (const [traitName, trait] of resolved.traits) {
38761
+ const sources = sourceListsByTrait.get(traitName);
38762
+ if (!sources) continue;
38763
+ trait.listens.forEach((listen, i) => {
38764
+ const src = sources[i];
38765
+ if (src !== void 0) {
38766
+ listen.source = src;
38767
+ }
38768
+ });
38769
+ }
38770
+ return resolved;
38711
38771
  } catch (err) {
38712
38772
  setError(err instanceof Error ? err.message : "Schema resolution failed");
38713
38773
  return null;
@@ -39255,6 +39315,24 @@ function SchemaRunner({ schema, serverUrl, mockData, pageName, onNavigate, onLoc
39255
39315
  }
39256
39316
  return map;
39257
39317
  }, [schema]);
39318
+ const traitLinkedEntitiesMap = useMemo(() => {
39319
+ const map = /* @__PURE__ */ new Map();
39320
+ if (ir) {
39321
+ for (const page of ir.pages.values()) {
39322
+ for (const binding of page.traits) {
39323
+ if (binding.linkedEntity) {
39324
+ map.set(binding.trait.name, binding.linkedEntity);
39325
+ }
39326
+ }
39327
+ }
39328
+ }
39329
+ return map;
39330
+ }, [ir]);
39331
+ const orbitalsByTraitMap = useMemo(
39332
+ () => new Map(Object.entries(orbitalsByTrait)),
39333
+ [orbitalsByTrait]
39334
+ );
39335
+ const entitiesArray = useMemo(() => Array.from(allEntities.values()), [allEntities]);
39258
39336
  const pageOrbitalNames = useMemo(() => {
39259
39337
  const set = /* @__PURE__ */ new Set();
39260
39338
  for (const binding of allPageTraits) {
@@ -39298,20 +39376,9 @@ function SchemaRunner({ schema, serverUrl, mockData, pageName, onNavigate, onLoc
39298
39376
  const inner = /* @__PURE__ */ jsx(VerificationProvider, { enabled: true, children: /* @__PURE__ */ jsx(SlotsProvider, { children: /* @__PURE__ */ jsxs(
39299
39377
  EntitySchemaProvider,
39300
39378
  {
39301
- entities: Array.from(allEntities.values()),
39302
- traitLinkedEntities: (() => {
39303
- const map = /* @__PURE__ */ new Map();
39304
- if (ir) {
39305
- for (const page of ir.pages.values()) {
39306
- for (const binding of page.traits) {
39307
- if (binding.linkedEntity) {
39308
- map.set(binding.trait.name, binding.linkedEntity);
39309
- }
39310
- }
39311
- }
39312
- }
39313
- return map;
39314
- })(),
39379
+ entities: entitiesArray,
39380
+ traitLinkedEntities: traitLinkedEntitiesMap,
39381
+ orbitalsByTrait: orbitalsByTraitMap,
39315
39382
  children: [
39316
39383
  /* @__PURE__ */ jsx(
39317
39384
  TraitInitializer,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@almadar/ui",
3
- "version": "4.8.0",
3
+ "version": "4.10.0",
4
4
  "description": "React UI components, hooks, and providers for Almadar",
5
5
  "type": "module",
6
6
  "main": "./dist/components/index.js",