@almadar/ui 6.6.0 → 6.8.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.
@@ -52614,7 +52614,9 @@ function UISlotComponentInner({
52614
52614
  className,
52615
52615
  children,
52616
52616
  pattern,
52617
- sourceTrait
52617
+ sourceTrait,
52618
+ fallback,
52619
+ mode = "replace"
52618
52620
  }) {
52619
52621
  const { slots, clear } = useUISlots();
52620
52622
  const eventBus = useEventBus();
@@ -52666,12 +52668,26 @@ function UISlotComponentInner({
52666
52668
  );
52667
52669
  }
52668
52670
  if (!content) {
52671
+ if (fallback !== void 0) {
52672
+ return /* @__PURE__ */ jsx(
52673
+ Box,
52674
+ {
52675
+ id: `slot-${slot}`,
52676
+ className: cn("ui-slot", `ui-slot-${slot}`, className),
52677
+ "data-testid": `ui-slot-${slot}`,
52678
+ "data-slot-mode": "fallback",
52679
+ children: fallback
52680
+ }
52681
+ );
52682
+ }
52669
52683
  if (!portal) {
52670
52684
  return /* @__PURE__ */ jsx(
52671
52685
  Box,
52672
52686
  {
52673
52687
  id: `slot-${slot}`,
52674
- className: cn("ui-slot", `ui-slot-${slot}`, className)
52688
+ className: cn("ui-slot", `ui-slot-${slot}`, className),
52689
+ "data-testid": `ui-slot-${slot}`,
52690
+ "data-slot-mode": "empty"
52675
52691
  }
52676
52692
  );
52677
52693
  }
@@ -52688,29 +52704,51 @@ function UISlotComponentInner({
52688
52704
  clear(slot);
52689
52705
  };
52690
52706
  if (portal) {
52691
- if (contained) {
52692
- return renderContainedPortal(t, slot, content, handleDismiss);
52693
- }
52694
- return /* @__PURE__ */ jsx(
52695
- SlotPortal,
52707
+ const inlineFallback = mode === "append" && fallback !== void 0 ? /* @__PURE__ */ jsx(
52708
+ Box,
52696
52709
  {
52697
- slot,
52698
- content,
52699
- position,
52700
- onDismiss: handleDismiss
52710
+ id: `slot-${slot}-fallback`,
52711
+ className: cn("ui-slot", `ui-slot-${slot}-fallback`, className),
52712
+ "data-testid": `ui-slot-${slot}-fallback`,
52713
+ "data-slot-mode": "append",
52714
+ children: fallback
52701
52715
  }
52702
- );
52716
+ ) : null;
52717
+ if (contained) {
52718
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
52719
+ inlineFallback,
52720
+ renderContainedPortal(t, slot, content, handleDismiss)
52721
+ ] });
52722
+ }
52723
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
52724
+ inlineFallback,
52725
+ /* @__PURE__ */ jsx(
52726
+ SlotPortal,
52727
+ {
52728
+ slot,
52729
+ content,
52730
+ position,
52731
+ onDismiss: handleDismiss
52732
+ }
52733
+ )
52734
+ ] });
52703
52735
  }
52704
52736
  const slotContent = /* @__PURE__ */ jsx(SlotContentRenderer, { content, onDismiss: handleDismiss });
52705
52737
  const wrappedContent = suspenseConfig.enabled ? /* @__PURE__ */ jsx(ErrorBoundary, { children: /* @__PURE__ */ jsx(Suspense, { fallback: getSlotFallback(slot, suspenseConfig), children: slotContent }) }) : /* @__PURE__ */ jsx(ErrorBoundary, { children: slotContent });
52706
- return /* @__PURE__ */ jsx(
52738
+ const showFallback = mode === "append" && fallback !== void 0;
52739
+ return /* @__PURE__ */ jsxs(
52707
52740
  Box,
52708
52741
  {
52709
52742
  id: `slot-${slot}`,
52710
52743
  className: cn("ui-slot", `ui-slot-${slot}`, className),
52711
52744
  "data-pattern": content.pattern,
52712
52745
  "data-source-trait": content.sourceTrait,
52713
- children: /* @__PURE__ */ jsx(MaybeTraitScope, { sourceTrait: content.sourceTrait, children: wrappedContent })
52746
+ "data-testid": `ui-slot-${slot}`,
52747
+ "data-slot-mode": showFallback ? "append" : "content",
52748
+ children: [
52749
+ showFallback ? fallback : null,
52750
+ /* @__PURE__ */ jsx(MaybeTraitScope, { sourceTrait: content.sourceTrait, children: wrappedContent })
52751
+ ]
52714
52752
  }
52715
52753
  );
52716
52754
  }
@@ -55918,4 +55956,18 @@ function useGitHubBranches(owner, repo, enabled = true) {
55918
55956
  });
55919
55957
  }
55920
55958
 
55921
- export { ALL_PRESETS, ALMADAR_DND_MIME, AR_BOOK_FIELDS, AboutPageTemplate, Accordion, Card2 as ActionCard, ActionPalette, ActionTile, ActivationBlock, Alert, AlgoGraphCanvas, AlgorithmCanvas, AnimatedCounter, AnimatedGraphic, AnimatedReveal, ArticleSection, Aside, AssetPicker, AtlasImage, AtlasPanel, AuthLayout, Avatar, Badge, BehaviorView, BiologyCanvas, BloomQuizBlock, BookChapterView, BookCoverPage, BookNavBar, BookTableOfContents, BookViewer, Box, BranchingLogicBuilder, Breadcrumb, Button, ButtonGroup, CTABanner, CalendarGrid, Canvas, Canvas2D, Card, CardBody, CardContent, CardFooter, CardGrid, CardHeader, CardTitle, Carousel, CaseStudyCard, CaseStudyOrganism, Center, Chart, ChartLegend, ChatBar, Checkbox, ChemistryCanvas, ChoiceButton, Coachmark, CodeBlock, CodeRunnerPanel, CollapsibleSection, CommandPalette, CommunityLinks, ConditionalWrapper, ConfettiEffect, ConfirmDialog, ConnectionBlock, Container, ContentRenderer, ContentSection, ControlButton, ControlGrid, CounterTemplate, DEFAULT_LIKERT_OPTIONS, DEFAULT_MATRIX_COLUMNS, DEFAULT_SLOTS, DIAMOND_TOP_Y, DashboardGrid, DashboardLayout, DataGrid, DataList, DataTable, DateRangePicker, DateRangeSelector, DayCell, DetailPanel, Dialog, DialogueBubble, Divider, DocBreadcrumb, DocPagination, DocSearch, DocSidebar, DocTOC, DockLayout, DocumentDetails, DocumentPanel, DocumentViewer, StateMachineView as DomStateMachineVisualizer, Drawer, DrawerSlot, ELEMENT_SELECTED_EVENT, EdgeDecoration, EditorCheckbox, EditorSelect, EditorSlider, EditorTextInput, EditorToolbar, EmojiPicker, EmptyState, EntityDisplayEvents, ErrorBoundary, ErrorState, FEATURE_COLORS, FEATURE_TYPES, FLOOR_HEIGHT, FeatureCard, FeatureDetailPageTemplate, FeatureGrid, FeatureGridOrganism, FileTree, FilterGroup, FilterPill, Flex, FlipCard, FlipContainer, FloatingActionButton, FloatingToolbar, Form, FormActions, FormField, FormLayout, FormSection, FormSectionHeader, FxOverlay, GameAudioCue, GameAudioToggle, GameHud, GameIcon, GameMenu, GameShell, GenericAppTemplate, GeometricPattern, GradientDivider, GraphCanvas, GraphView, Grid, GridPicker, HStack, Header, HealthBar, HeroOrganism, HeroSection, I18nProvider, IDENTITY_BOOK_FIELDS, Icon, IconPicker, ImportPreviewTree, ImportProgress, ImportSourcePicker, InfiniteScrollSentinel, Input, InputGroup, InstallBox, JazariStateMachine, JsonTreeEditor, Label, LandingPageTemplate, LawReferenceTooltip, LearningCanvas, LearningScene3D, Lightbox, LikertScale, LineChart2 as LineChart, List3 as List, LoadingState, MapView, MarkdownContent, MarketingFooter, MarketingStatCard, MasterDetail, MasterDetailLayout, MathCanvas, MatrixQuestion, MediaGallery, Menu, Meter, Modal, ModalSlot, ModuleCard, Navigation, NodeSlotEditor, NotifyListener, NumberStepper, OnboardingSpotlight, OptionConstraintGroup, StateMachineView as OrbitalStateMachineView, OrbitalVisualization, Overlay, PageHeader, PageTransition, Pagination, PatternTile, PhysicsCanvas, Popover, PositionedCanvas, Presence, PricingCard, PricingGrid, PricingOrganism, PricingPageTemplate, ProgressBar, ProgressDots, PropertyInspector, PullQuote, PullToRefresh, QrScanner, QuizBlock, Radio, RangeSlider, ReflectionBlock, RelationSelect, RepeatableFormSection, ReplyTree, RichTextEditor, RuntimeDebugger, SHEET_COLUMNS, SPRITE_SHEET_LAYOUT, ScaledDiagram, ScoreDisplay, SearchInput, Section, SectionHeader, SegmentRenderer, Select, SequenceBar, ServiceCatalog, SharedEntityStoreContext, ShowcaseCard, ShowcaseOrganism, SidePanel, Sidebar, SignaturePad, SimpleGrid, Skeleton, SlotContentRenderer, SocialProof, SortableList, Spacer, Sparkline, Spinner, Split, SplitPane, SplitSection, Stack, StarRating, StatBadge, StatCard, StatDisplay, StateGraph, StateJsonView, StateMachineView, StateNode2 as StateNode, StatsGrid, StatsOrganism, StatusBar, StatusDot, StepFlow, StepFlowOrganism, SubagentTracePanel, SvgBranch, SvgConnection, SvgFlow, SvgGrid, SvgLobe, SvgMesh, SvgMorph, SvgNode, SvgPulse, SvgRing, SvgShield, SvgStack, SwipeableRow, Switch, TERRAIN_COLORS, TILE_HEIGHT, TILE_WIDTH, TabbedContainer, TableView, Tabs, TagCloud, TagInput, TeamCard, TeamOrganism, TerrainPalette, TextHighlight, Textarea, ThemeToggle, TimeSlotCell, Timeline, TimerDisplay, Toast, ToastSlot, Tooltip, TraitFrame, TraitSlot, TraitStateViewer, TransitionArrow, TrendIndicator, TypewriterText, Typography, UISlotComponent, UISlotRenderer, UploadDropZone, VStack, VersionDiff, ViolationAlert, VoteStack, WizardContainer, WizardNavigation, WizardProgress, arrowBetween, billboardLabel, boardEntity, bool, calculateAttackTargets, calculateValidMoves, cn, createInitialGameState, createSharedEntityStore, createTranslate, createUnitAnimationState, cylinderBetween, dispatchCommandPaletteCommand, get3DClickPayload, getCurrentFrame, getTileDimensions, inferDirection, isoToScreen, makeAsset, makeAssetMap, mapBookData, meshSphere, num, objAvailableActions, objAvailableEvents, objCurrentState, objIcon, objId, objMaxRules, objName, objRules, objStates, parseEditFocus, parseLessonSegments, parseMarkdownWithCodeBlocks, parseQueryBinding, pendulum, projectileMotion, registerCodeLanguageLoader, renderPatternValue, resolveFieldMap, resolveFrame, resolveSheetDirection, rows, runTickFrame, sanitizeRichHtml, screenToIso, springOscillator, str, tickAnimationState, toCodeLanguage, transitionAnimation, unitHealth, unitPosition, unitTeam, useAgentChat, useAnchorRect, useAtlasSliceDataUrl, useAuthContext, useCamera, useCanvasGestures, useCompile, useConnectGitHub, useDeepAgentGeneration, useDisconnectGitHub, useDragReorder, useDraggable, useDropZone, useEmitEvent, useEventBus, useEventListener, useExtensions, useFileEditor, useFileSystem, useGameAudio, useGitHubBranches, useGitHubRepo, useGitHubRepos, useGitHubStatus, useImageCache, useInfiniteScroll, useKeyboardRouter, useLongPress, useMediaQuery, useOrbitalHistory, usePresence, usePreview, usePullToRefresh, useQuerySingleton, useRenderInterpolation, useSharedEntitySnapshot, useSharedEntityStore, useSharedEntityStoreContext, useSwipeGesture, useTapReveal, useTraitListens, useTranslate117 as useTranslate, useUIEvents, useUISlotManager, useUnitSpriteAtlas, useValidation, vec2 };
55959
+ // types/slot-host.ts
55960
+ function assertUniqueSlotsPerHost(manifest) {
55961
+ const seenBySlot = /* @__PURE__ */ new Map();
55962
+ for (const [regionId, region] of Object.entries(manifest.regions)) {
55963
+ const existingRegionId = seenBySlot.get(region.slot);
55964
+ if (existingRegionId !== void 0) {
55965
+ throw new Error(
55966
+ `assertUniqueSlotsPerHost: regions "${existingRegionId}" and "${regionId}" both bind slot "${region.slot}" \u2014 a slot may be mounted by only one region per host.`
55967
+ );
55968
+ }
55969
+ seenBySlot.set(region.slot, regionId);
55970
+ }
55971
+ }
55972
+
55973
+ export { ALL_PRESETS, ALMADAR_DND_MIME, AR_BOOK_FIELDS, AboutPageTemplate, Accordion, Card2 as ActionCard, ActionPalette, ActionTile, ActivationBlock, Alert, AlgoGraphCanvas, AlgorithmCanvas, AnimatedCounter, AnimatedGraphic, AnimatedReveal, ArticleSection, Aside, AssetPicker, AtlasImage, AtlasPanel, AuthLayout, Avatar, Badge, BehaviorView, BiologyCanvas, BloomQuizBlock, BookChapterView, BookCoverPage, BookNavBar, BookTableOfContents, BookViewer, Box, BranchingLogicBuilder, Breadcrumb, Button, ButtonGroup, CTABanner, CalendarGrid, Canvas, Canvas2D, Card, CardBody, CardContent, CardFooter, CardGrid, CardHeader, CardTitle, Carousel, CaseStudyCard, CaseStudyOrganism, Center, Chart, ChartLegend, ChatBar, Checkbox, ChemistryCanvas, ChoiceButton, Coachmark, CodeBlock, CodeRunnerPanel, CollapsibleSection, CommandPalette, CommunityLinks, ConditionalWrapper, ConfettiEffect, ConfirmDialog, ConnectionBlock, Container, ContentRenderer, ContentSection, ControlButton, ControlGrid, CounterTemplate, DEFAULT_LIKERT_OPTIONS, DEFAULT_MATRIX_COLUMNS, DEFAULT_SLOTS, DIAMOND_TOP_Y, DashboardGrid, DashboardLayout, DataGrid, DataList, DataTable, DateRangePicker, DateRangeSelector, DayCell, DetailPanel, Dialog, DialogueBubble, Divider, DocBreadcrumb, DocPagination, DocSearch, DocSidebar, DocTOC, DockLayout, DocumentDetails, DocumentPanel, DocumentViewer, StateMachineView as DomStateMachineVisualizer, Drawer, DrawerSlot, ELEMENT_SELECTED_EVENT, EdgeDecoration, EditorCheckbox, EditorSelect, EditorSlider, EditorTextInput, EditorToolbar, EmojiPicker, EmptyState, EntityDisplayEvents, ErrorBoundary, ErrorState, FEATURE_COLORS, FEATURE_TYPES, FLOOR_HEIGHT, FeatureCard, FeatureDetailPageTemplate, FeatureGrid, FeatureGridOrganism, FileTree, FilterGroup, FilterPill, Flex, FlipCard, FlipContainer, FloatingActionButton, FloatingToolbar, Form, FormActions, FormField, FormLayout, FormSection, FormSectionHeader, FxOverlay, GameAudioCue, GameAudioToggle, GameHud, GameIcon, GameMenu, GameShell, GenericAppTemplate, GeometricPattern, GradientDivider, GraphCanvas, GraphView, Grid, GridPicker, HStack, Header, HealthBar, HeroOrganism, HeroSection, I18nProvider, IDENTITY_BOOK_FIELDS, Icon, IconPicker, ImportPreviewTree, ImportProgress, ImportSourcePicker, InfiniteScrollSentinel, Input, InputGroup, InstallBox, JazariStateMachine, JsonTreeEditor, Label, LandingPageTemplate, LawReferenceTooltip, LearningCanvas, LearningScene3D, Lightbox, LikertScale, LineChart2 as LineChart, List3 as List, LoadingState, MapView, MarkdownContent, MarketingFooter, MarketingStatCard, MasterDetail, MasterDetailLayout, MathCanvas, MatrixQuestion, MediaGallery, Menu, Meter, Modal, ModalSlot, ModuleCard, Navigation, NodeSlotEditor, NotifyListener, NumberStepper, OnboardingSpotlight, OptionConstraintGroup, StateMachineView as OrbitalStateMachineView, OrbitalVisualization, Overlay, PageHeader, PageTransition, Pagination, PatternTile, PhysicsCanvas, Popover, PositionedCanvas, Presence, PricingCard, PricingGrid, PricingOrganism, PricingPageTemplate, ProgressBar, ProgressDots, PropertyInspector, PullQuote, PullToRefresh, QrScanner, QuizBlock, Radio, RangeSlider, ReflectionBlock, RelationSelect, RepeatableFormSection, ReplyTree, RichTextEditor, RuntimeDebugger, SHEET_COLUMNS, SPRITE_SHEET_LAYOUT, ScaledDiagram, ScoreDisplay, SearchInput, Section, SectionHeader, SegmentRenderer, Select, SequenceBar, ServiceCatalog, SharedEntityStoreContext, ShowcaseCard, ShowcaseOrganism, SidePanel, Sidebar, SignaturePad, SimpleGrid, Skeleton, SlotContentRenderer, SocialProof, SortableList, Spacer, Sparkline, Spinner, Split, SplitPane, SplitSection, Stack, StarRating, StatBadge, StatCard, StatDisplay, StateGraph, StateJsonView, StateMachineView, StateNode2 as StateNode, StatsGrid, StatsOrganism, StatusBar, StatusDot, StepFlow, StepFlowOrganism, SubagentTracePanel, SvgBranch, SvgConnection, SvgFlow, SvgGrid, SvgLobe, SvgMesh, SvgMorph, SvgNode, SvgPulse, SvgRing, SvgShield, SvgStack, SwipeableRow, Switch, TERRAIN_COLORS, TILE_HEIGHT, TILE_WIDTH, TabbedContainer, TableView, Tabs, TagCloud, TagInput, TeamCard, TeamOrganism, TerrainPalette, TextHighlight, Textarea, ThemeToggle, TimeSlotCell, Timeline, TimerDisplay, Toast, ToastSlot, Tooltip, TraitFrame, TraitSlot, TraitStateViewer, TransitionArrow, TrendIndicator, TypewriterText, Typography, UISlotComponent, UISlotRenderer, UploadDropZone, VStack, VersionDiff, ViolationAlert, VoteStack, WizardContainer, WizardNavigation, WizardProgress, arrowBetween, assertUniqueSlotsPerHost, billboardLabel, boardEntity, bool, calculateAttackTargets, calculateValidMoves, cn, createInitialGameState, createSharedEntityStore, createTranslate, createUnitAnimationState, cylinderBetween, dispatchCommandPaletteCommand, get3DClickPayload, getCurrentFrame, getTileDimensions, inferDirection, isoToScreen, makeAsset, makeAssetMap, mapBookData, meshSphere, num, objAvailableActions, objAvailableEvents, objCurrentState, objIcon, objId, objMaxRules, objName, objRules, objStates, parseEditFocus, parseLessonSegments, parseMarkdownWithCodeBlocks, parseQueryBinding, pendulum, projectileMotion, registerCodeLanguageLoader, renderPatternValue, resolveFieldMap, resolveFrame, resolveSheetDirection, rows, runTickFrame, sanitizeRichHtml, screenToIso, springOscillator, str, tickAnimationState, toCodeLanguage, transitionAnimation, unitHealth, unitPosition, unitTeam, useAgentChat, useAnchorRect, useAtlasSliceDataUrl, useAuthContext, useCamera, useCanvasGestures, useCompile, useConnectGitHub, useDeepAgentGeneration, useDisconnectGitHub, useDragReorder, useDraggable, useDropZone, useEmitEvent, useEventBus, useEventListener, useExtensions, useFileEditor, useFileSystem, useGameAudio, useGitHubBranches, useGitHubRepo, useGitHubRepos, useGitHubStatus, useImageCache, useInfiniteScroll, useKeyboardRouter, useLongPress, useMediaQuery, useOrbitalHistory, usePresence, usePreview, usePullToRefresh, useQuerySingleton, useRenderInterpolation, useSharedEntitySnapshot, useSharedEntityStore, useSharedEntityStoreContext, useSwipeGesture, useTapReveal, useTraitListens, useTranslate117 as useTranslate, useUIEvents, useUISlotManager, useUnitSpriteAtlas, useValidation, vec2 };
@@ -51418,7 +51418,9 @@ function UISlotComponentInner({
51418
51418
  className,
51419
51419
  children,
51420
51420
  pattern,
51421
- sourceTrait
51421
+ sourceTrait,
51422
+ fallback,
51423
+ mode = "replace"
51422
51424
  }) {
51423
51425
  const { slots, clear } = context.useUISlots();
51424
51426
  const eventBus = useEventBus();
@@ -51470,12 +51472,26 @@ function UISlotComponentInner({
51470
51472
  );
51471
51473
  }
51472
51474
  if (!content) {
51475
+ if (fallback !== void 0) {
51476
+ return /* @__PURE__ */ jsxRuntime.jsx(
51477
+ Box,
51478
+ {
51479
+ id: `slot-${slot}`,
51480
+ className: cn("ui-slot", `ui-slot-${slot}`, className),
51481
+ "data-testid": `ui-slot-${slot}`,
51482
+ "data-slot-mode": "fallback",
51483
+ children: fallback
51484
+ }
51485
+ );
51486
+ }
51473
51487
  if (!portal) {
51474
51488
  return /* @__PURE__ */ jsxRuntime.jsx(
51475
51489
  Box,
51476
51490
  {
51477
51491
  id: `slot-${slot}`,
51478
- className: cn("ui-slot", `ui-slot-${slot}`, className)
51492
+ className: cn("ui-slot", `ui-slot-${slot}`, className),
51493
+ "data-testid": `ui-slot-${slot}`,
51494
+ "data-slot-mode": "empty"
51479
51495
  }
51480
51496
  );
51481
51497
  }
@@ -51492,29 +51508,51 @@ function UISlotComponentInner({
51492
51508
  clear(slot);
51493
51509
  };
51494
51510
  if (portal) {
51495
- if (contained) {
51496
- return renderContainedPortal(t, slot, content, handleDismiss);
51497
- }
51498
- return /* @__PURE__ */ jsxRuntime.jsx(
51499
- SlotPortal,
51511
+ const inlineFallback = mode === "append" && fallback !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx(
51512
+ Box,
51500
51513
  {
51501
- slot,
51502
- content,
51503
- position,
51504
- onDismiss: handleDismiss
51514
+ id: `slot-${slot}-fallback`,
51515
+ className: cn("ui-slot", `ui-slot-${slot}-fallback`, className),
51516
+ "data-testid": `ui-slot-${slot}-fallback`,
51517
+ "data-slot-mode": "append",
51518
+ children: fallback
51505
51519
  }
51506
- );
51520
+ ) : null;
51521
+ if (contained) {
51522
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
51523
+ inlineFallback,
51524
+ renderContainedPortal(t, slot, content, handleDismiss)
51525
+ ] });
51526
+ }
51527
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
51528
+ inlineFallback,
51529
+ /* @__PURE__ */ jsxRuntime.jsx(
51530
+ SlotPortal,
51531
+ {
51532
+ slot,
51533
+ content,
51534
+ position,
51535
+ onDismiss: handleDismiss
51536
+ }
51537
+ )
51538
+ ] });
51507
51539
  }
51508
51540
  const slotContent = /* @__PURE__ */ jsxRuntime.jsx(SlotContentRenderer, { content, onDismiss: handleDismiss });
51509
51541
  const wrappedContent = suspenseConfig.enabled ? /* @__PURE__ */ jsxRuntime.jsx(ErrorBoundary, { children: /* @__PURE__ */ jsxRuntime.jsx(React89.Suspense, { fallback: getSlotFallback(slot, suspenseConfig), children: slotContent }) }) : /* @__PURE__ */ jsxRuntime.jsx(ErrorBoundary, { children: slotContent });
51510
- return /* @__PURE__ */ jsxRuntime.jsx(
51542
+ const showFallback = mode === "append" && fallback !== void 0;
51543
+ return /* @__PURE__ */ jsxRuntime.jsxs(
51511
51544
  Box,
51512
51545
  {
51513
51546
  id: `slot-${slot}`,
51514
51547
  className: cn("ui-slot", `ui-slot-${slot}`, className),
51515
51548
  "data-pattern": content.pattern,
51516
51549
  "data-source-trait": content.sourceTrait,
51517
- children: /* @__PURE__ */ jsxRuntime.jsx(MaybeTraitScope, { sourceTrait: content.sourceTrait, children: wrappedContent })
51550
+ "data-testid": `ui-slot-${slot}`,
51551
+ "data-slot-mode": showFallback ? "append" : "content",
51552
+ children: [
51553
+ showFallback ? fallback : null,
51554
+ /* @__PURE__ */ jsxRuntime.jsx(MaybeTraitScope, { sourceTrait: content.sourceTrait, children: wrappedContent })
51555
+ ]
51518
51556
  }
51519
51557
  );
51520
51558
  }
@@ -51344,7 +51344,9 @@ function UISlotComponentInner({
51344
51344
  className,
51345
51345
  children,
51346
51346
  pattern,
51347
- sourceTrait
51347
+ sourceTrait,
51348
+ fallback,
51349
+ mode = "replace"
51348
51350
  }) {
51349
51351
  const { slots, clear } = useUISlots();
51350
51352
  const eventBus = useEventBus();
@@ -51396,12 +51398,26 @@ function UISlotComponentInner({
51396
51398
  );
51397
51399
  }
51398
51400
  if (!content) {
51401
+ if (fallback !== void 0) {
51402
+ return /* @__PURE__ */ jsx(
51403
+ Box,
51404
+ {
51405
+ id: `slot-${slot}`,
51406
+ className: cn("ui-slot", `ui-slot-${slot}`, className),
51407
+ "data-testid": `ui-slot-${slot}`,
51408
+ "data-slot-mode": "fallback",
51409
+ children: fallback
51410
+ }
51411
+ );
51412
+ }
51399
51413
  if (!portal) {
51400
51414
  return /* @__PURE__ */ jsx(
51401
51415
  Box,
51402
51416
  {
51403
51417
  id: `slot-${slot}`,
51404
- className: cn("ui-slot", `ui-slot-${slot}`, className)
51418
+ className: cn("ui-slot", `ui-slot-${slot}`, className),
51419
+ "data-testid": `ui-slot-${slot}`,
51420
+ "data-slot-mode": "empty"
51405
51421
  }
51406
51422
  );
51407
51423
  }
@@ -51418,29 +51434,51 @@ function UISlotComponentInner({
51418
51434
  clear(slot);
51419
51435
  };
51420
51436
  if (portal) {
51421
- if (contained) {
51422
- return renderContainedPortal(t, slot, content, handleDismiss);
51423
- }
51424
- return /* @__PURE__ */ jsx(
51425
- SlotPortal,
51437
+ const inlineFallback = mode === "append" && fallback !== void 0 ? /* @__PURE__ */ jsx(
51438
+ Box,
51426
51439
  {
51427
- slot,
51428
- content,
51429
- position,
51430
- onDismiss: handleDismiss
51440
+ id: `slot-${slot}-fallback`,
51441
+ className: cn("ui-slot", `ui-slot-${slot}-fallback`, className),
51442
+ "data-testid": `ui-slot-${slot}-fallback`,
51443
+ "data-slot-mode": "append",
51444
+ children: fallback
51431
51445
  }
51432
- );
51446
+ ) : null;
51447
+ if (contained) {
51448
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
51449
+ inlineFallback,
51450
+ renderContainedPortal(t, slot, content, handleDismiss)
51451
+ ] });
51452
+ }
51453
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
51454
+ inlineFallback,
51455
+ /* @__PURE__ */ jsx(
51456
+ SlotPortal,
51457
+ {
51458
+ slot,
51459
+ content,
51460
+ position,
51461
+ onDismiss: handleDismiss
51462
+ }
51463
+ )
51464
+ ] });
51433
51465
  }
51434
51466
  const slotContent = /* @__PURE__ */ jsx(SlotContentRenderer, { content, onDismiss: handleDismiss });
51435
51467
  const wrappedContent = suspenseConfig.enabled ? /* @__PURE__ */ jsx(ErrorBoundary, { children: /* @__PURE__ */ jsx(Suspense, { fallback: getSlotFallback(slot, suspenseConfig), children: slotContent }) }) : /* @__PURE__ */ jsx(ErrorBoundary, { children: slotContent });
51436
- return /* @__PURE__ */ jsx(
51468
+ const showFallback = mode === "append" && fallback !== void 0;
51469
+ return /* @__PURE__ */ jsxs(
51437
51470
  Box,
51438
51471
  {
51439
51472
  id: `slot-${slot}`,
51440
51473
  className: cn("ui-slot", `ui-slot-${slot}`, className),
51441
51474
  "data-pattern": content.pattern,
51442
51475
  "data-source-trait": content.sourceTrait,
51443
- children: /* @__PURE__ */ jsx(MaybeTraitScope, { sourceTrait: content.sourceTrait, children: wrappedContent })
51476
+ "data-testid": `ui-slot-${slot}`,
51477
+ "data-slot-mode": showFallback ? "append" : "content",
51478
+ children: [
51479
+ showFallback ? fallback : null,
51480
+ /* @__PURE__ */ jsx(MaybeTraitScope, { sourceTrait: content.sourceTrait, children: wrappedContent })
51481
+ ]
51444
51482
  }
51445
51483
  );
51446
51484
  }
@@ -51067,7 +51067,9 @@ function UISlotComponentInner({
51067
51067
  className,
51068
51068
  children,
51069
51069
  pattern,
51070
- sourceTrait
51070
+ sourceTrait,
51071
+ fallback,
51072
+ mode = "replace"
51071
51073
  }) {
51072
51074
  const { slots, clear } = context.useUISlots();
51073
51075
  const eventBus = useEventBus();
@@ -51119,12 +51121,26 @@ function UISlotComponentInner({
51119
51121
  );
51120
51122
  }
51121
51123
  if (!content) {
51124
+ if (fallback !== void 0) {
51125
+ return /* @__PURE__ */ jsxRuntime.jsx(
51126
+ Box,
51127
+ {
51128
+ id: `slot-${slot}`,
51129
+ className: cn("ui-slot", `ui-slot-${slot}`, className),
51130
+ "data-testid": `ui-slot-${slot}`,
51131
+ "data-slot-mode": "fallback",
51132
+ children: fallback
51133
+ }
51134
+ );
51135
+ }
51122
51136
  if (!portal) {
51123
51137
  return /* @__PURE__ */ jsxRuntime.jsx(
51124
51138
  Box,
51125
51139
  {
51126
51140
  id: `slot-${slot}`,
51127
- className: cn("ui-slot", `ui-slot-${slot}`, className)
51141
+ className: cn("ui-slot", `ui-slot-${slot}`, className),
51142
+ "data-testid": `ui-slot-${slot}`,
51143
+ "data-slot-mode": "empty"
51128
51144
  }
51129
51145
  );
51130
51146
  }
@@ -51141,29 +51157,51 @@ function UISlotComponentInner({
51141
51157
  clear(slot);
51142
51158
  };
51143
51159
  if (portal) {
51144
- if (contained) {
51145
- return renderContainedPortal(t, slot, content, handleDismiss);
51146
- }
51147
- return /* @__PURE__ */ jsxRuntime.jsx(
51148
- SlotPortal,
51160
+ const inlineFallback = mode === "append" && fallback !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx(
51161
+ Box,
51149
51162
  {
51150
- slot,
51151
- content,
51152
- position,
51153
- onDismiss: handleDismiss
51163
+ id: `slot-${slot}-fallback`,
51164
+ className: cn("ui-slot", `ui-slot-${slot}-fallback`, className),
51165
+ "data-testid": `ui-slot-${slot}-fallback`,
51166
+ "data-slot-mode": "append",
51167
+ children: fallback
51154
51168
  }
51155
- );
51169
+ ) : null;
51170
+ if (contained) {
51171
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
51172
+ inlineFallback,
51173
+ renderContainedPortal(t, slot, content, handleDismiss)
51174
+ ] });
51175
+ }
51176
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
51177
+ inlineFallback,
51178
+ /* @__PURE__ */ jsxRuntime.jsx(
51179
+ SlotPortal,
51180
+ {
51181
+ slot,
51182
+ content,
51183
+ position,
51184
+ onDismiss: handleDismiss
51185
+ }
51186
+ )
51187
+ ] });
51156
51188
  }
51157
51189
  const slotContent = /* @__PURE__ */ jsxRuntime.jsx(SlotContentRenderer, { content, onDismiss: handleDismiss });
51158
51190
  const wrappedContent = suspenseConfig.enabled ? /* @__PURE__ */ jsxRuntime.jsx(ErrorBoundary, { children: /* @__PURE__ */ jsxRuntime.jsx(React87.Suspense, { fallback: getSlotFallback(slot, suspenseConfig), children: slotContent }) }) : /* @__PURE__ */ jsxRuntime.jsx(ErrorBoundary, { children: slotContent });
51159
- return /* @__PURE__ */ jsxRuntime.jsx(
51191
+ const showFallback = mode === "append" && fallback !== void 0;
51192
+ return /* @__PURE__ */ jsxRuntime.jsxs(
51160
51193
  Box,
51161
51194
  {
51162
51195
  id: `slot-${slot}`,
51163
51196
  className: cn("ui-slot", `ui-slot-${slot}`, className),
51164
51197
  "data-pattern": content.pattern,
51165
51198
  "data-source-trait": content.sourceTrait,
51166
- children: /* @__PURE__ */ jsxRuntime.jsx(MaybeTraitScope, { sourceTrait: content.sourceTrait, children: wrappedContent })
51199
+ "data-testid": `ui-slot-${slot}`,
51200
+ "data-slot-mode": showFallback ? "append" : "content",
51201
+ children: [
51202
+ showFallback ? fallback : null,
51203
+ /* @__PURE__ */ jsxRuntime.jsx(MaybeTraitScope, { sourceTrait: content.sourceTrait, children: wrappedContent })
51204
+ ]
51167
51205
  }
51168
51206
  );
51169
51207
  }
@@ -54243,17 +54281,30 @@ function PluginRuntimeMount({
54243
54281
  () => new Set(plugin.schema.orbitals.map((o) => o.name)),
54244
54282
  [plugin.schema]
54245
54283
  );
54284
+ const inboundBusEvents = React87.useMemo(
54285
+ () => new Set(plugin.inbound.map((row) => row.busEvent)),
54286
+ [plugin.inbound]
54287
+ );
54288
+ const inboundTriggerNames = React87.useMemo(
54289
+ () => new Set(plugin.inbound.map((row) => row.trigger)),
54290
+ [plugin.inbound]
54291
+ );
54292
+ const snapshotAllStates = React87.useCallback(() => {
54293
+ const states = [];
54294
+ if (!mockRuntime) return states;
54295
+ for (const orbital of plugin.schema.orbitals) {
54296
+ for (const traitName of traitNamesOf(orbital)) {
54297
+ const raw = mockRuntime.getState(orbital.name, traitName);
54298
+ if (isTraitState(raw)) states.push([orbital.name, traitName, raw]);
54299
+ }
54300
+ }
54301
+ return states;
54302
+ }, [mockRuntime, plugin.schema]);
54246
54303
  React87.useEffect(() => {
54247
54304
  let cancelled = false;
54248
54305
  void registrationReady.then(() => {
54249
54306
  if (cancelled || !mockRuntime) return;
54250
- const states = [];
54251
- for (const orbital of plugin.schema.orbitals) {
54252
- for (const traitName of traitNamesOf(orbital)) {
54253
- const raw = mockRuntime.getState(orbital.name, traitName);
54254
- if (isTraitState(raw)) states.push([orbital.name, traitName, raw]);
54255
- }
54256
- }
54307
+ const states = snapshotAllStates();
54257
54308
  if (states.length > 0) onDispatched(plugin.id, null, states);
54258
54309
  }).catch((err) => {
54259
54310
  if (!cancelled) onError(plugin.id, err instanceof Error ? err.message : String(err));
@@ -54261,7 +54312,39 @@ function PluginRuntimeMount({
54261
54312
  return () => {
54262
54313
  cancelled = true;
54263
54314
  };
54264
- }, [registrationReady, mockRuntime, plugin, onDispatched, onError]);
54315
+ }, [registrationReady, mockRuntime, plugin, onDispatched, onError, snapshotAllStates]);
54316
+ React87.useEffect(() => {
54317
+ if (!mockRuntime) return;
54318
+ let timer = null;
54319
+ const scheduleResync = () => {
54320
+ if (timer !== null) return;
54321
+ timer = setTimeout(() => {
54322
+ timer = null;
54323
+ const states = snapshotAllStates();
54324
+ if (states.length > 0) onDispatched(plugin.id, null, states);
54325
+ }, 0);
54326
+ };
54327
+ const unsub = mockRuntime.getEventBus().onAny(scheduleResync);
54328
+ return () => {
54329
+ unsub();
54330
+ if (timer !== null) clearTimeout(timer);
54331
+ };
54332
+ }, [mockRuntime, plugin.id, onDispatched, snapshotAllStates]);
54333
+ React87.useEffect(() => {
54334
+ if (!mockRuntime) return;
54335
+ const rebroadcast = /* @__PURE__ */ new WeakSet();
54336
+ const unsub = mockRuntime.getEventBus().onAny((event) => {
54337
+ if (rebroadcast.has(event)) return;
54338
+ if (inboundBusEvents.has(event.type) || inboundTriggerNames.has(event.type)) return;
54339
+ const sourceOrbital = event.source?.orbital;
54340
+ if (sourceOrbital === void 0 || !ownOrbitals.has(sourceOrbital)) return;
54341
+ rebroadcast.add(event);
54342
+ bus.emit(`UI:${event.type}`, event.payload, event.source);
54343
+ });
54344
+ return () => {
54345
+ unsub();
54346
+ };
54347
+ }, [mockRuntime, bus, ownOrbitals, inboundBusEvents, inboundTriggerNames]);
54265
54348
  const dispatch = React87.useCallback(
54266
54349
  async (row, payload) => {
54267
54350
  await registrationReady;
@@ -54280,11 +54363,14 @@ function PluginRuntimeMount({
54280
54363
  if (!response.success) {
54281
54364
  onError(plugin.id, response.error ?? `${plugin.id}: ${row.trigger} failed`);
54282
54365
  }
54283
- for (const entry of response.emittedEvents ?? []) {
54284
- if (entry.event === row.trigger) continue;
54285
- const sourceOrbital = entry.source?.orbital;
54286
- if (sourceOrbital !== void 0 && ownOrbitals.has(sourceOrbital)) {
54287
- bus.emit(`UI:${entry.event}`, entry.payload, entry.source);
54366
+ if (!mockRuntime) {
54367
+ for (const entry of response.emittedEvents ?? []) {
54368
+ if (entry.event === row.trigger) continue;
54369
+ if (inboundBusEvents.has(entry.event)) continue;
54370
+ const sourceOrbital = entry.source?.orbital;
54371
+ if (sourceOrbital !== void 0 && ownOrbitals.has(sourceOrbital)) {
54372
+ bus.emit(`UI:${entry.event}`, entry.payload, entry.source);
54373
+ }
54288
54374
  }
54289
54375
  }
54290
54376
  const states = [];
@@ -54294,7 +54380,7 @@ function PluginRuntimeMount({
54294
54380
  }
54295
54381
  onDispatched(plugin.id, row.trigger, states);
54296
54382
  },
54297
- [registrationReady, mockRuntime, mode, transport, plugin, bus, ownOrbitals, onError, onTransition, onDispatched]
54383
+ [registrationReady, mockRuntime, mode, transport, plugin, bus, ownOrbitals, inboundBusEvents, onError, onTransition, onDispatched]
54298
54384
  );
54299
54385
  React87.useEffect(() => {
54300
54386
  const unsubs = plugin.inbound.map(
@@ -54378,6 +54464,20 @@ function OrbitalPluginHost({
54378
54464
  ] });
54379
54465
  }
54380
54466
 
54467
+ // types/slot-host.ts
54468
+ function assertUniqueSlotsPerHost(manifest) {
54469
+ const seenBySlot = /* @__PURE__ */ new Map();
54470
+ for (const [regionId, region] of Object.entries(manifest.regions)) {
54471
+ const existingRegionId = seenBySlot.get(region.slot);
54472
+ if (existingRegionId !== void 0) {
54473
+ throw new Error(
54474
+ `assertUniqueSlotsPerHost: regions "${existingRegionId}" and "${regionId}" both bind slot "${region.slot}" \u2014 a slot may be mounted by only one region per host.`
54475
+ );
54476
+ }
54477
+ seenBySlot.set(region.slot, regionId);
54478
+ }
54479
+ }
54480
+
54381
54481
  // runtime/index.ts
54382
54482
  init_perf();
54383
54483
 
@@ -54456,6 +54556,7 @@ Object.defineProperty(exports, "wrapCallbackForEvent", {
54456
54556
  exports.BrowserPlayground = BrowserPlayground;
54457
54557
  exports.OrbPreview = OrbPreview;
54458
54558
  exports.OrbitalPluginHost = OrbitalPluginHost;
54559
+ exports.assertUniqueSlotsPerHost = assertUniqueSlotsPerHost;
54459
54560
  exports.clearSchemaCache = clearSchemaCache;
54460
54561
  exports.createClientEffectHandlers = createClientEffectHandlers;
54461
54562
  exports.useDeclaredCaptureTable = useDeclaredCaptureTable;
@@ -9,6 +9,7 @@ import { a as EntityBindingSource, h as ServerBridgeTransport } from '../EntityB
9
9
  export { b as EntitySchemaContextValue, c as EntitySchemaProvider, d as EntitySchemaProviderProps, e as ServerBridgeContextValue, f as ServerBridgeProvider, i as ServerClientEffect, T as TraitContext, k as TraitContextValue, l as TraitInstance, m as TraitProvider, n as TraitProviderProps, o as useEntitySchema, p as useEntitySchemaOptional, q as useServerBridge, r as useTrait, s as useTraitContext } from '../EntityBindingContext-Bn3ePJQC.cjs';
10
10
  export { PERF_NAMESPACE, PerfEntry, PreparedPreviewSchema, adjustSchemaForMockData, buildMockData, clearPerf, perfEnd, perfStart, perfTime, prepareSchemaForPreview, wrapCallbackForEvent } from '@almadar/runtime/ui';
11
11
  import React__default, { ReactNode } from 'react';
12
+ export { S as SlotHostManifest, a as SlotHostRegion, b as assertUniqueSlotsPerHost } from '../slot-host-Czc2JAxo.cjs';
12
13
  export { p as profilerOnRender, u as usePerfBuffer } from '../perf-DaVdsbU0.cjs';
13
14
  import '../event-bus-types-Bl78kokd.cjs';
14
15
  import '../useUISlots-GNwGLlW2.cjs';
@@ -326,6 +327,34 @@ declare function BrowserPlayground({ schema, mode, initialPagePath, height, clas
326
327
  * preview has (in-memory persist, mock services); `deny` is an opt-in
327
328
  * host policy, never a default sandbox.
328
329
  *
330
+ * OUTBOUND = the runtime's internal event bus, not the direct dispatch
331
+ * response. `response.emittedEvents` (mock mode) reflects only the effects
332
+ * of the trait `dispatch()` DIRECTLY targeted — a sibling trait that reacts
333
+ * through the runtime's own cascade (`setupEventListeners`, a SEPARATE
334
+ * `processOrbitalEvent` call whose response is discarded) never shows up
335
+ * there, so its emits never reached the ambient bus (verified 2026-09-04:
336
+ * vim-mode's `Shell` relays `PLUGIN_ENABLED` -> `VimStudioBridge`'s
337
+ * `ENABLED` arm emits `STATUS` + 2x `REGISTER_COMMAND`, none of which
338
+ * reached the studio's status bar/palette). Fix: for `mode: 'mock'`, one
339
+ * `runtime.getEventBus().onAny(...)` subscription per plugin (mounted
340
+ * alongside the runtime, not per-dispatch) is the ONLY outbound path — it
341
+ * sees every emit, direct or cascaded, since every `emit` effect passes
342
+ * through that same bus. `mode: 'server'` has no local bus to subscribe to
343
+ * (the runtime lives on the remote transport), so it keeps reading
344
+ * `response.emittedEvents` for outbound — same single-hop-only limitation
345
+ * this fix removes for mock mode, unaddressed here (no `mode: 'server'`
346
+ * consumer exists yet; see `docs/Almadar_UI_Gaps.md`).
347
+ *
348
+ * RELAY RULE: the plugin's `inbound[]` is its host→plugin vocabulary — one
349
+ * `UI:<busEvent>` bus event per row, dispatching `trigger` at
350
+ * `orbital`/`trait`. Anything a plugin emits under one of those SAME
351
+ * busEvent names (or under an inbound `trigger` name) is a relay for its
352
+ * own siblings' `listens {}` (the runtime's internal event bus already
353
+ * carries that fan-out), never a fresh request back to the host, and must
354
+ * NEVER be re-broadcast — doing so re-fires the very `UI:<busEvent>`
355
+ * listener that produced it, a synchronous self-feeding loop (verified
356
+ * 2026-09-04, see `docs/Almadar_UI_Gaps.md`).
357
+ *
329
358
  * @packageDocumentation
330
359
  */
331
360