@parhelia/core 0.3.12771 → 0.3.12788

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.
Files changed (574) hide show
  1. package/dist/agents-view/AgentCard.js +1 -5
  2. package/dist/agents-view/AgentCard.js.map +1 -1
  3. package/dist/agents-view/AgentsView.js +1 -1
  4. package/dist/agents-view/AgentsView.js.map +1 -1
  5. package/dist/components/ActionButton.d.ts +7 -0
  6. package/dist/components/ActionButton.js +2 -2
  7. package/dist/components/ActionButton.js.map +1 -1
  8. package/dist/components/MarkdownDisplay.js +1 -1
  9. package/dist/components/ui/CardConnector.js +1 -1
  10. package/dist/components/ui/LanguageSelectionGrid.js +1 -1
  11. package/dist/components/ui/LanguageSelector.js +3 -3
  12. package/dist/components/ui/LanguageSelector.js.map +1 -1
  13. package/dist/components/ui/PlaceholderItemSelector.js +1 -1
  14. package/dist/components/ui/alert.d.ts +1 -1
  15. package/dist/components/ui/button.d.ts +2 -2
  16. package/dist/components/ui/card.js +1 -1
  17. package/dist/components/ui/close-button.d.ts +1 -1
  18. package/dist/components/ui/context-menu.js +1 -1
  19. package/dist/components/ui/copy-button.js +1 -1
  20. package/dist/components/ui/delete-button.d.ts +1 -1
  21. package/dist/components/ui/paste-button.js +1 -1
  22. package/dist/components/ui/popover.d.ts +1 -0
  23. package/dist/components/ui/popover.js +16 -7
  24. package/dist/components/ui/popover.js.map +1 -1
  25. package/dist/components/ui/sonner.js +1 -1
  26. package/dist/components/ui/upload-button.js +1 -1
  27. package/dist/config/config.js +18 -4
  28. package/dist/config/config.js.map +1 -1
  29. package/dist/editor/ConcurrentUserLimitDialog.js +1 -1
  30. package/dist/editor/ContentTree.d.ts +12 -1
  31. package/dist/editor/ContentTree.js +20 -3
  32. package/dist/editor/ContentTree.js.map +1 -1
  33. package/dist/editor/FieldActionsOverlay.js.map +1 -1
  34. package/dist/editor/FieldHistory.d.ts +15 -1
  35. package/dist/editor/FieldHistory.js +85 -52
  36. package/dist/editor/FieldHistory.js.map +1 -1
  37. package/dist/editor/FieldList.js +5 -2
  38. package/dist/editor/FieldList.js.map +1 -1
  39. package/dist/editor/FieldListField.js +7 -2
  40. package/dist/editor/FieldListField.js.map +1 -1
  41. package/dist/editor/FieldListFieldWithFallbacks.js +1 -1
  42. package/dist/editor/GlobalMenuBar.js +1 -1
  43. package/dist/editor/ItemInfo.js +2 -2
  44. package/dist/editor/ItemInfo.js.map +1 -1
  45. package/dist/editor/LinkEditorDialog.js +1 -1
  46. package/dist/editor/MigrationsView.js +1 -1
  47. package/dist/editor/PictureCropper.js +1 -1
  48. package/dist/editor/PictureCropper.js.map +1 -1
  49. package/dist/editor/SetupWizard.js.map +1 -1
  50. package/dist/editor/WorkspaceTitleSwitcher.js +1 -1
  51. package/dist/editor/ai/AgentImageCopyButton.d.ts +6 -0
  52. package/dist/editor/ai/AgentImageCopyButton.js +93 -0
  53. package/dist/editor/ai/AgentImageCopyButton.js.map +1 -0
  54. package/dist/editor/ai/AgentSharingSection.js +1 -1
  55. package/dist/editor/ai/Agents.d.ts +2 -2
  56. package/dist/editor/ai/Agents.js +2 -10
  57. package/dist/editor/ai/Agents.js.map +1 -1
  58. package/dist/editor/ai/GuidanceOverlay.js +1 -1
  59. package/dist/editor/ai/GuidanceOverlay.js.map +1 -1
  60. package/dist/editor/ai/InlineAiDialog.js +1 -1
  61. package/dist/editor/ai/InlineAiDialog.js.map +1 -1
  62. package/dist/editor/ai/InlineAiTrigger.js +1 -1
  63. package/dist/editor/ai/MediaImage.js +2 -1
  64. package/dist/editor/ai/MediaImage.js.map +1 -1
  65. package/dist/editor/ai/agentActivitySummary.js.map +1 -1
  66. package/dist/editor/ai/agentMessageHelpers.js.map +1 -1
  67. package/dist/editor/ai/dialogs/AgentDialogHandler.js +103 -6
  68. package/dist/editor/ai/dialogs/AgentDialogHandler.js.map +1 -1
  69. package/dist/editor/ai/dialogs/QuestionnaireInline.js +1 -1
  70. package/dist/editor/ai/dialogs/agentDialogTypes.d.ts +21 -0
  71. package/dist/editor/ai/dialogs/agentDialogTypes.js +3 -1
  72. package/dist/editor/ai/dialogs/agentDialogTypes.js.map +1 -1
  73. package/dist/editor/ai/dialogs/offscreenPageCapture.d.ts +14 -1
  74. package/dist/editor/ai/dialogs/offscreenPageCapture.js +95 -27
  75. package/dist/editor/ai/dialogs/offscreenPageCapture.js.map +1 -1
  76. package/dist/editor/ai/terminal/agentCost.d.ts +1 -0
  77. package/dist/editor/ai/terminal/agentCost.js +10 -3
  78. package/dist/editor/ai/terminal/agentCost.js.map +1 -1
  79. package/dist/editor/ai/terminal/agentSessionSelectors.js.map +1 -1
  80. package/dist/editor/ai/terminal/agentSessionState.js +4 -1
  81. package/dist/editor/ai/terminal/agentSessionState.js.map +1 -1
  82. package/dist/editor/ai/terminal/components/AgentCostDisplay.d.ts +1 -1
  83. package/dist/editor/ai/terminal/components/AgentCostDisplay.js +3 -3
  84. package/dist/editor/ai/terminal/components/AgentCostDisplay.js.map +1 -1
  85. package/dist/editor/ai/terminal/components/AgentDocumentList.js +2 -2
  86. package/dist/editor/ai/terminal/components/AgentDocumentList.js.map +1 -1
  87. package/dist/editor/ai/terminal/components/AgentFullPromptControls.js +1 -1
  88. package/dist/editor/ai/terminal/components/AgentMemoryPanel.d.ts +22 -5
  89. package/dist/editor/ai/terminal/components/AgentMemoryPanel.js +102 -19
  90. package/dist/editor/ai/terminal/components/AgentMemoryPanel.js.map +1 -1
  91. package/dist/editor/ai/terminal/components/AgentProfileModelSettingsSection.js +1 -1
  92. package/dist/editor/ai/terminal/components/AgentProfileSwitcher.js +1 -1
  93. package/dist/editor/ai/terminal/components/AgentPromptInputArea.js +8 -3
  94. package/dist/editor/ai/terminal/components/AgentPromptInputArea.js.map +1 -1
  95. package/dist/editor/ai/terminal/components/AgentPromptTrayPopovers.js +46 -6
  96. package/dist/editor/ai/terminal/components/AgentPromptTrayPopovers.js.map +1 -1
  97. package/dist/editor/ai/terminal/components/AgentRunStatusBanners.js +1 -1
  98. package/dist/editor/ai/terminal/components/AgentSettingsContent.js +1 -1
  99. package/dist/editor/ai/terminal/components/AgentTerminalContextChrome.d.ts +1 -0
  100. package/dist/editor/ai/terminal/components/AgentTerminalContextChrome.js.map +1 -1
  101. package/dist/editor/ai/terminal/components/AgentTerminalContextPanels.js +1 -1
  102. package/dist/editor/ai/terminal/components/AgentTerminalContextPanels.js.map +1 -1
  103. package/dist/editor/ai/terminal/components/AgentTerminalFullLayout.js +1 -1
  104. package/dist/editor/ai/terminal/components/AgentTerminalMessageGroups.js +1 -1
  105. package/dist/editor/ai/terminal/components/AgentTerminalStatusBar.js +1 -1
  106. package/dist/editor/ai/terminal/components/AgentTerminalStatusBar.js.map +1 -1
  107. package/dist/editor/ai/terminal/components/AgentTerminalView.d.ts +1 -1
  108. package/dist/editor/ai/terminal/components/AgentTerminalView.js +1 -1
  109. package/dist/editor/ai/terminal/components/AiResponseMessage.js +1 -1
  110. package/dist/editor/ai/terminal/components/AiResponseMessage.js.map +1 -1
  111. package/dist/editor/ai/terminal/components/ContextInfoBar.d.ts +2 -1
  112. package/dist/editor/ai/terminal/components/ContextInfoBar.js +2 -2
  113. package/dist/editor/ai/terminal/components/ContextInfoBar.js.map +1 -1
  114. package/dist/editor/ai/terminal/components/EditOperationsPanel.js +1 -1
  115. package/dist/editor/ai/terminal/components/QuestionnaireRecap.d.ts +2 -2
  116. package/dist/editor/ai/terminal/components/ToolCallDisplay.js +3 -2
  117. package/dist/editor/ai/terminal/components/ToolCallDisplay.js.map +1 -1
  118. package/dist/editor/ai/terminal/components/UserMessage.js +1 -1
  119. package/dist/editor/ai/terminal/useAgentContextDisplayNames.d.ts +2 -0
  120. package/dist/editor/ai/terminal/useAgentContextDisplayNames.js +73 -29
  121. package/dist/editor/ai/terminal/useAgentContextDisplayNames.js.map +1 -1
  122. package/dist/editor/ai/terminal/useAgentEditorContextPipeline.d.ts +1 -0
  123. package/dist/editor/ai/terminal/useAgentInlineDialogPipeline.d.ts +1 -1
  124. package/dist/editor/ai/terminal/useAgentLoader.js +5 -2
  125. package/dist/editor/ai/terminal/useAgentLoader.js.map +1 -1
  126. package/dist/editor/ai/terminal/useAgentPromptComposerSurface.d.ts +2 -2
  127. package/dist/editor/ai/terminal/useAgentPromptQueueSocketHandler.d.ts +2 -0
  128. package/dist/editor/ai/terminal/useAgentPromptQueueSocketHandler.js +5 -3
  129. package/dist/editor/ai/terminal/useAgentPromptQueueSocketHandler.js.map +1 -1
  130. package/dist/editor/ai/terminal/useAgentRunMessagePipeline.d.ts +4 -4
  131. package/dist/editor/ai/terminal/useAgentRunStatusSocketHandler.js +3 -0
  132. package/dist/editor/ai/terminal/useAgentRunStatusSocketHandler.js.map +1 -1
  133. package/dist/editor/ai/terminal/useAgentSettingsPanel.d.ts +31 -31
  134. package/dist/editor/ai/terminal/useAgentSettleCompletedRun.js.map +1 -1
  135. package/dist/editor/ai/terminal/useAgentStopCommand.js +4 -0
  136. package/dist/editor/ai/terminal/useAgentStopCommand.js.map +1 -1
  137. package/dist/editor/ai/terminal/useAgentStreamPipeline.js +1 -0
  138. package/dist/editor/ai/terminal/useAgentStreamPipeline.js.map +1 -1
  139. package/dist/editor/ai/terminal/useAgentTerminalChrome.d.ts +1 -0
  140. package/dist/editor/ai/terminal/useAgentTerminalChrome.js +2 -2
  141. package/dist/editor/ai/terminal/useAgentTerminalChrome.js.map +1 -1
  142. package/dist/editor/ai/terminal/useAgentTerminalController.js +3 -1
  143. package/dist/editor/ai/terminal/useAgentTerminalController.js.map +1 -1
  144. package/dist/editor/ai/useAgentPanes.js.map +1 -1
  145. package/dist/editor/ai/useAgentStatus.js.map +1 -1
  146. package/dist/editor/ai/useInlineAiPosition.js.map +1 -1
  147. package/dist/editor/ai-image-editor/AiImageEditorDialog.js +42 -23
  148. package/dist/editor/ai-image-editor/AiImageEditorDialog.js.map +1 -1
  149. package/dist/editor/bridge/BridgeClient.js +6 -6
  150. package/dist/editor/bridge/BridgeClient.js.map +1 -1
  151. package/dist/editor/bridge/protocol.d.ts +26 -0
  152. package/dist/editor/bridge/protocol.js +1 -1
  153. package/dist/editor/bridge/protocol.js.map +1 -1
  154. package/dist/editor/client/AboutDialog.js +1 -1
  155. package/dist/editor/client/EditorShell.js +125 -90
  156. package/dist/editor/client/EditorShell.js.map +1 -1
  157. package/dist/editor/client/SessionExpiredOverlay.js +1 -1
  158. package/dist/editor/client/SessionExpiredOverlay.js.map +1 -1
  159. package/dist/editor/client/editContext.d.ts +26 -3
  160. package/dist/editor/client/editContext.js.map +1 -1
  161. package/dist/editor/client/fieldModificationStore.js +0 -21
  162. package/dist/editor/client/fieldModificationStore.js.map +1 -1
  163. package/dist/editor/client/hooks/useClientInfoRegistration.d.ts +13 -0
  164. package/dist/editor/client/hooks/useClientInfoRegistration.js +38 -0
  165. package/dist/editor/client/hooks/useClientInfoRegistration.js.map +1 -0
  166. package/dist/editor/client/itemsRepository.js +1 -34
  167. package/dist/editor/client/itemsRepository.js.map +1 -1
  168. package/dist/editor/client/operations.d.ts +4 -2
  169. package/dist/editor/client/operations.js +89 -65
  170. package/dist/editor/client/operations.js.map +1 -1
  171. package/dist/editor/client/pageModelBuilder.js +7 -1
  172. package/dist/editor/client/pageModelBuilder.js.map +1 -1
  173. package/dist/editor/client/ui/EditorChrome.d.ts +1 -0
  174. package/dist/editor/client/ui/EditorChrome.js +7 -2
  175. package/dist/editor/client/ui/EditorChrome.js.map +1 -1
  176. package/dist/editor/client/ui/FullscreenControls.d.ts +3 -0
  177. package/dist/editor/client/ui/FullscreenControls.js +7 -12
  178. package/dist/editor/client/ui/FullscreenControls.js.map +1 -1
  179. package/dist/editor/client/undoTargetResolution.d.ts +28 -0
  180. package/dist/editor/client/undoTargetResolution.js +69 -0
  181. package/dist/editor/client/undoTargetResolution.js.map +1 -0
  182. package/dist/editor/commands/componentCommands.js +2 -2
  183. package/dist/editor/commands/componentCommands.js.map +1 -1
  184. package/dist/editor/commands/customCommandConverter.js.map +1 -1
  185. package/dist/editor/commands/itemCommands.js +19 -2
  186. package/dist/editor/commands/itemCommands.js.map +1 -1
  187. package/dist/editor/componentTreeHelper.js +13 -7
  188. package/dist/editor/componentTreeHelper.js.map +1 -1
  189. package/dist/editor/content-tree/IndicatorSettings.js +1 -1
  190. package/dist/editor/content-tree/TreeOptions.js +1 -1
  191. package/dist/editor/context-menu/InsertMenu.js +1 -1
  192. package/dist/editor/editor-warnings/NoLanguageWriteAccess.js +1 -1
  193. package/dist/editor/field-types/AttachmentEditor.js +7 -0
  194. package/dist/editor/field-types/AttachmentEditor.js.map +1 -1
  195. package/dist/editor/field-types/LinkFieldEditor.js +1 -1
  196. package/dist/editor/field-types/PictureFieldEditor.js +21 -21
  197. package/dist/editor/field-types/PictureFieldEditor.js.map +1 -1
  198. package/dist/editor/field-types/RichTextEditor.js +1 -1
  199. package/dist/editor/field-types/RichTextEditorComponent.js +6 -0
  200. package/dist/editor/field-types/RichTextEditorComponent.js.map +1 -1
  201. package/dist/editor/field-types/SingleLineText.js +0 -34
  202. package/dist/editor/field-types/SingleLineText.js.map +1 -1
  203. package/dist/editor/field-types/richtext/bridgeRichTextProfile.d.ts +1 -1
  204. package/dist/editor/field-types/richtext/components/EditorDropdown.js +1 -1
  205. package/dist/editor/field-types/richtext/components/ReactSlate.js +1 -1
  206. package/dist/editor/field-types/richtext/components/SimpleDropdown.js +1 -1
  207. package/dist/editor/field-types/richtext/components/SimpleToolbar.js +1 -1
  208. package/dist/editor/field-types/richtext/hooks/useRichTextProfile.js.map +1 -1
  209. package/dist/editor/field-types/richtext/utils/conversion.js +2 -4
  210. package/dist/editor/field-types/richtext/utils/conversion.js.map +1 -1
  211. package/dist/editor/field-types/richtext/utils/plugins.d.ts +1 -0
  212. package/dist/editor/field-types/richtext/utils/plugins.js +12 -0
  213. package/dist/editor/field-types/richtext/utils/plugins.js.map +1 -1
  214. package/dist/editor/field-types/richtext/utils/profileMapper.js.map +1 -1
  215. package/dist/editor/field-types/useFormFieldCaretPresence.js.map +1 -1
  216. package/dist/editor/fieldValueDiagnostics.js.map +1 -1
  217. package/dist/editor/insertOptionCompatibility.d.ts +7 -0
  218. package/dist/editor/insertOptionCompatibility.js +15 -0
  219. package/dist/editor/insertOptionCompatibility.js.map +1 -0
  220. package/dist/editor/media-selector/MediaFolderBrowser.js +26 -4
  221. package/dist/editor/media-selector/MediaFolderBrowser.js.map +1 -1
  222. package/dist/editor/media-selector/Preview.js +6 -11
  223. package/dist/editor/media-selector/Preview.js.map +1 -1
  224. package/dist/editor/media-selector/Thumbnails.js +31 -3
  225. package/dist/editor/media-selector/Thumbnails.js.map +1 -1
  226. package/dist/editor/media-selector/TreeSelector.js +53 -6
  227. package/dist/editor/media-selector/TreeSelector.js.map +1 -1
  228. package/dist/editor/media-selector/UploadZone.d.ts +1 -2
  229. package/dist/editor/media-selector/UploadZone.js +3 -4
  230. package/dist/editor/media-selector/UploadZone.js.map +1 -1
  231. package/dist/editor/media-selector/mediaItemDrag.d.ts +28 -0
  232. package/dist/editor/media-selector/mediaItemDrag.js +42 -0
  233. package/dist/editor/media-selector/mediaItemDrag.js.map +1 -0
  234. package/dist/editor/menubar/ActiveUsers.js +6 -3
  235. package/dist/editor/menubar/ActiveUsers.js.map +1 -1
  236. package/dist/editor/menubar/GenericToolbar.js +1 -1
  237. package/dist/editor/menubar/GenericToolbar.js.map +1 -1
  238. package/dist/editor/menubar/ItemActionsMenu.js +1 -1
  239. package/dist/editor/menubar/ItemLanguageVersion.js +1 -1
  240. package/dist/editor/menubar/ItemLanguageVersion.js.map +1 -1
  241. package/dist/editor/menubar/OperationsIndicator.js +1 -1
  242. package/dist/editor/menubar/PageSelector.d.ts +2 -1
  243. package/dist/editor/menubar/PageSelector.js +14 -4
  244. package/dist/editor/menubar/PageSelector.js.map +1 -1
  245. package/dist/editor/menubar/VersionPreviewCard.js +1 -1
  246. package/dist/editor/menubar/VersionSelector.js +1 -1
  247. package/dist/editor/menubar/toolbar-sections/CustomCommandsToolbar.js +1 -1
  248. package/dist/editor/menubar/toolbar-sections/DeviceSwitchToolbar.d.ts +3 -1
  249. package/dist/editor/menubar/toolbar-sections/DeviceSwitchToolbar.js +6 -7
  250. package/dist/editor/menubar/toolbar-sections/DeviceSwitchToolbar.js.map +1 -1
  251. package/dist/editor/menubar/toolbar-sections/EditControls.js +5 -5
  252. package/dist/editor/menubar/toolbar-sections/EditControls.js.map +1 -1
  253. package/dist/editor/menubar/toolbar-sections/InsertControls.js +1 -1
  254. package/dist/editor/menubar/toolbar-sections/InsertControls.js.map +1 -1
  255. package/dist/editor/menubar/toolbar-sections/ManualBrowser.js +14 -4
  256. package/dist/editor/menubar/toolbar-sections/ManualBrowser.js.map +1 -1
  257. package/dist/editor/menubar/toolbar-sections/PreviewModeControl.d.ts +1 -0
  258. package/dist/editor/menubar/toolbar-sections/PreviewModeControl.js +14 -0
  259. package/dist/editor/menubar/toolbar-sections/PreviewModeControl.js.map +1 -0
  260. package/dist/editor/menubar/toolbar-sections/RefreshPageControl.d.ts +7 -0
  261. package/dist/editor/menubar/toolbar-sections/RefreshPageControl.js +44 -0
  262. package/dist/editor/menubar/toolbar-sections/RefreshPageControl.js.map +1 -0
  263. package/dist/editor/menubar/toolbar-sections/ReviewCommands.js +1 -1
  264. package/dist/editor/menubar/toolbar-sections/UtilityControls.js +1 -1
  265. package/dist/editor/menubar/toolbar-sections/ViewportControls.d.ts +7 -0
  266. package/dist/editor/menubar/toolbar-sections/ViewportControls.js +16 -8
  267. package/dist/editor/menubar/toolbar-sections/ViewportControls.js.map +1 -1
  268. package/dist/editor/menubar/toolbar-sections/index.d.ts +1 -0
  269. package/dist/editor/menubar/toolbar-sections/index.js +1 -0
  270. package/dist/editor/menubar/toolbar-sections/index.js.map +1 -1
  271. package/dist/editor/notifications/NotificationCenter.js +1 -1
  272. package/dist/editor/notifications/WatchButton.js +1 -1
  273. package/dist/editor/notifications/notificationListState.d.ts +1 -1
  274. package/dist/editor/notifications/notificationRoutes.js.map +1 -1
  275. package/dist/editor/notifications/useNotifications.d.ts +1 -1
  276. package/dist/editor/page-editor-chrome/BridgeInlineFormatOverlay.js +6 -3
  277. package/dist/editor/page-editor-chrome/BridgeInlineFormatOverlay.js.map +1 -1
  278. package/dist/editor/page-editor-chrome/CommentHighlightings.js +1 -1
  279. package/dist/editor/page-editor-chrome/DragInsertionOverlay.js +51 -23
  280. package/dist/editor/page-editor-chrome/DragInsertionOverlay.js.map +1 -1
  281. package/dist/editor/page-editor-chrome/EmptyImageFieldIndicators.js +1 -1
  282. package/dist/editor/page-editor-chrome/FeedbackHighlightBadge.js.map +1 -1
  283. package/dist/editor/page-editor-chrome/FieldActionIndicators.js +1 -1
  284. package/dist/editor/page-editor-chrome/FieldEditedIndicators.js +1 -1
  285. package/dist/editor/page-editor-chrome/FrameMenu.js +1 -1
  286. package/dist/editor/page-editor-chrome/FrameMenus.js +1 -1
  287. package/dist/editor/page-editor-chrome/InlineFieldHistoryButton.d.ts +58 -0
  288. package/dist/editor/page-editor-chrome/InlineFieldHistoryButton.js +709 -0
  289. package/dist/editor/page-editor-chrome/InlineFieldHistoryButton.js.map +1 -0
  290. package/dist/editor/page-editor-chrome/LockedFieldIndicator.js +12 -2
  291. package/dist/editor/page-editor-chrome/LockedFieldIndicator.js.map +1 -1
  292. package/dist/editor/page-editor-chrome/PageEditorChrome.js +7 -2
  293. package/dist/editor/page-editor-chrome/PageEditorChrome.js.map +1 -1
  294. package/dist/editor/page-editor-chrome/PictureEditorOverlay.js +57 -10
  295. package/dist/editor/page-editor-chrome/PictureEditorOverlay.js.map +1 -1
  296. package/dist/editor/page-editor-chrome/PlaceholderDropZone.js +1 -8
  297. package/dist/editor/page-editor-chrome/PlaceholderDropZone.js.map +1 -1
  298. package/dist/editor/page-editor-chrome/PlaceholderDropZones.d.ts +1 -0
  299. package/dist/editor/page-editor-chrome/PlaceholderDropZones.js +10 -3
  300. package/dist/editor/page-editor-chrome/PlaceholderDropZones.js.map +1 -1
  301. package/dist/editor/page-editor-chrome/SuggestionHighlightings.js +5 -2
  302. package/dist/editor/page-editor-chrome/SuggestionHighlightings.js.map +1 -1
  303. package/dist/editor/page-editor-chrome/SuggestionVariantSwitcher.js +7 -2
  304. package/dist/editor/page-editor-chrome/SuggestionVariantSwitcher.js.map +1 -1
  305. package/dist/editor/page-editor-chrome/VersionDiffHighlightings.d.ts +5 -2
  306. package/dist/editor/page-editor-chrome/VersionDiffHighlightings.js +153 -51
  307. package/dist/editor/page-editor-chrome/VersionDiffHighlightings.js.map +1 -1
  308. package/dist/editor/page-editor-chrome/componentDragObject.d.ts +5 -4
  309. package/dist/editor/page-editor-chrome/componentDragObject.js +8 -8
  310. package/dist/editor/page-editor-chrome/componentDragObject.js.map +1 -1
  311. package/dist/editor/page-editor-chrome/overlay/IframeOverlayProvider.js.map +1 -1
  312. package/dist/editor/page-editor-chrome/overlay/geometry.d.ts +7 -0
  313. package/dist/editor/page-editor-chrome/overlay/geometry.js +35 -17
  314. package/dist/editor/page-editor-chrome/overlay/geometry.js.map +1 -1
  315. package/dist/editor/page-editor-chrome/overlay/placeholderZones.js +4 -9
  316. package/dist/editor/page-editor-chrome/overlay/placeholderZones.js.map +1 -1
  317. package/dist/editor/page-editor-chrome/useBridgeInlineEditing.js +18 -70
  318. package/dist/editor/page-editor-chrome/useBridgeInlineEditing.js.map +1 -1
  319. package/dist/editor/page-viewer/MiniMap.js +1 -1
  320. package/dist/editor/page-viewer/MiniMap.js.map +1 -1
  321. package/dist/editor/page-viewer/MinimapDropTargets.js +1 -1
  322. package/dist/editor/page-viewer/PageViewer.js +5 -3
  323. package/dist/editor/page-viewer/PageViewer.js.map +1 -1
  324. package/dist/editor/page-viewer/PageViewerFrame.js +256 -125
  325. package/dist/editor/page-viewer/PageViewerFrame.js.map +1 -1
  326. package/dist/editor/page-viewer/bridgeFieldPatch.js +0 -45
  327. package/dist/editor/page-viewer/bridgeFieldPatch.js.map +1 -1
  328. package/dist/editor/page-viewer/bridgeKeyboardShortcuts.d.ts +12 -0
  329. package/dist/editor/page-viewer/bridgeKeyboardShortcuts.js +27 -0
  330. package/dist/editor/page-viewer/bridgeKeyboardShortcuts.js.map +1 -1
  331. package/dist/editor/page-viewer/fullscreenPagePath.d.ts +1 -0
  332. package/dist/editor/page-viewer/fullscreenPagePath.js +11 -0
  333. package/dist/editor/page-viewer/fullscreenPagePath.js.map +1 -0
  334. package/dist/editor/page-viewer/internalLinkNavigation.d.ts +9 -0
  335. package/dist/editor/page-viewer/internalLinkNavigation.js +104 -0
  336. package/dist/editor/page-viewer/internalLinkNavigation.js.map +1 -0
  337. package/dist/editor/page-viewer/pageViewContext.d.ts +3 -1
  338. package/dist/editor/page-viewer/pageViewContext.js +14 -10
  339. package/dist/editor/page-viewer/pageViewContext.js.map +1 -1
  340. package/dist/editor/page-viewer/parentBridgeInjection.d.ts +6 -1
  341. package/dist/editor/page-viewer/parentBridgeInjection.js +117 -24
  342. package/dist/editor/page-viewer/parentBridgeInjection.js.map +1 -1
  343. package/dist/editor/page-viewer/renderUrl.d.ts +1 -1
  344. package/dist/editor/personalization/ConditionTreeEditor.js +1 -1
  345. package/dist/editor/personalization/ConditionTreeEditor.js.map +1 -1
  346. package/dist/editor/personalization/PersonalizationPanel.js +1 -1
  347. package/dist/editor/personalization/TreeItemPicker.js +7 -1
  348. package/dist/editor/personalization/TreeItemPicker.js.map +1 -1
  349. package/dist/editor/personalization/utils.js.map +1 -1
  350. package/dist/editor/reviews/CommentEditor.js +1 -1
  351. package/dist/editor/reviews/CommentEditor.js.map +1 -1
  352. package/dist/editor/reviews/CommentView.js +1 -1
  353. package/dist/editor/reviews/Comments.js +5 -20
  354. package/dist/editor/reviews/Comments.js.map +1 -1
  355. package/dist/editor/reviews/CreateReviewDialog.js +1 -1
  356. package/dist/editor/reviews/DecisionsMatrix.js +1 -1
  357. package/dist/editor/reviews/EditReviewSettingsDialog.js +1 -1
  358. package/dist/editor/reviews/FeedbackFilters.d.ts +16 -0
  359. package/dist/editor/reviews/FeedbackFilters.js +45 -0
  360. package/dist/editor/reviews/FeedbackFilters.js.map +1 -0
  361. package/dist/editor/reviews/FeedbackModeIntro.js +2 -2
  362. package/dist/editor/reviews/FeedbackModeIntro.js.map +1 -1
  363. package/dist/editor/reviews/MentionText.js +1 -1
  364. package/dist/editor/reviews/ReviewCard.js +1 -1
  365. package/dist/editor/reviews/ReviewDetail.js +5 -1
  366. package/dist/editor/reviews/ReviewDetail.js.map +1 -1
  367. package/dist/editor/reviews/ReviewItemsPanel.js +74 -11
  368. package/dist/editor/reviews/ReviewItemsPanel.js.map +1 -1
  369. package/dist/editor/reviews/SecretPhraseInput.js +1 -1
  370. package/dist/editor/reviews/suggestedEditState.js.map +1 -1
  371. package/dist/editor/reviews/useMultiReview.js +45 -17
  372. package/dist/editor/reviews/useMultiReview.js.map +1 -1
  373. package/dist/editor/reviews/useReviews.js +24 -5
  374. package/dist/editor/reviews/useReviews.js.map +1 -1
  375. package/dist/editor/services/agentService.d.ts +91 -10
  376. package/dist/editor/services/agentService.js +100 -27
  377. package/dist/editor/services/agentService.js.map +1 -1
  378. package/dist/editor/services/aiService.js.map +1 -1
  379. package/dist/editor/services/contentService.d.ts +3 -1
  380. package/dist/editor/services/contentService.js +8 -0
  381. package/dist/editor/services/contentService.js.map +1 -1
  382. package/dist/editor/services/contextService.js.map +1 -1
  383. package/dist/editor/services/editService.js.map +1 -1
  384. package/dist/editor/services/favouritesService.d.ts +0 -7
  385. package/dist/editor/services/favouritesService.js +0 -7
  386. package/dist/editor/services/favouritesService.js.map +1 -1
  387. package/dist/editor/services/indexService.d.ts +3 -1
  388. package/dist/editor/services/indexService.js +8 -0
  389. package/dist/editor/services/indexService.js.map +1 -1
  390. package/dist/editor/services/localStorageService.js.map +1 -1
  391. package/dist/editor/services/reviewsService.js.map +1 -1
  392. package/dist/editor/services/serviceHelper.d.ts +3 -0
  393. package/dist/editor/services/serviceHelper.js +51 -1
  394. package/dist/editor/services/serviceHelper.js.map +1 -1
  395. package/dist/editor/services/suggestedEditsService.js.map +1 -1
  396. package/dist/editor/services/systemService.d.ts +10 -0
  397. package/dist/editor/services/systemService.js +3 -0
  398. package/dist/editor/services/systemService.js.map +1 -1
  399. package/dist/editor/services/textCompletionService.js +5 -0
  400. package/dist/editor/services/textCompletionService.js.map +1 -1
  401. package/dist/editor/settings/About.js +2 -4
  402. package/dist/editor/settings/About.js.map +1 -1
  403. package/dist/editor/settings/IndexOverview.js +3 -2
  404. package/dist/editor/settings/IndexOverview.js.map +1 -1
  405. package/dist/editor/settings/SettingsBreadcrumb.js +1 -1
  406. package/dist/editor/settings/SettingsView.js +1 -1
  407. package/dist/editor/settings/StatusSummary.js +1 -1
  408. package/dist/editor/settings/index/IndexGenerationsSection.d.ts +8 -0
  409. package/dist/editor/settings/index/IndexGenerationsSection.js +93 -0
  410. package/dist/editor/settings/index/IndexGenerationsSection.js.map +1 -0
  411. package/dist/editor/settings/panels/AgentProfileConfigPanel.js +1 -1
  412. package/dist/editor/settings/panels/AgentsPanel.js +1 -1
  413. package/dist/editor/settings/panels/CreateAgentProfileDialog.js +1 -1
  414. package/dist/editor/settings/panels/CreateJavaScriptToolDialog.js +1 -1
  415. package/dist/editor/settings/panels/CreateMcpServerDialog.js +1 -1
  416. package/dist/editor/settings/panels/JavaScriptToolsPanel.js +1 -1
  417. package/dist/editor/settings/panels/MemoriesPanel.d.ts +16 -0
  418. package/dist/editor/settings/panels/MemoriesPanel.js +291 -0
  419. package/dist/editor/settings/panels/MemoriesPanel.js.map +1 -0
  420. package/dist/editor/settings/panels/MemoryEntryDialog.d.ts +45 -0
  421. package/dist/editor/settings/panels/MemoryEntryDialog.js +167 -0
  422. package/dist/editor/settings/panels/MemoryEntryDialog.js.map +1 -0
  423. package/dist/editor/settings/panels/ModelsPanel.js +1 -1
  424. package/dist/editor/settings/panels/ModelsPanel.js.map +1 -1
  425. package/dist/editor/settings/panels/NotificationSubscriptionsPanel.js +1 -1
  426. package/dist/editor/settings/panels/NotificationSubscriptionsPanel.js.map +1 -1
  427. package/dist/editor/settings/panels/ProjectTemplatesPanel.js +1 -1
  428. package/dist/editor/settings/panels/ProjectTemplatesPanel.js.map +1 -1
  429. package/dist/editor/settings/panels/ProvidersPanel.js +1 -1
  430. package/dist/editor/settings/panels/RenderingHostsPanel.d.ts +2 -0
  431. package/dist/editor/settings/panels/RenderingHostsPanel.js +63 -0
  432. package/dist/editor/settings/panels/RenderingHostsPanel.js.map +1 -0
  433. package/dist/editor/settings/panels/SearchConfigPanel.js +6 -4
  434. package/dist/editor/settings/panels/SearchConfigPanel.js.map +1 -1
  435. package/dist/editor/settings/panels/StatusPanel.js +1 -1
  436. package/dist/editor/settings/panels/index.d.ts +2 -0
  437. package/dist/editor/settings/panels/index.js +2 -0
  438. package/dist/editor/settings/panels/index.js.map +1 -1
  439. package/dist/editor/setup-wizard/steps/CompleteStep.js +1 -1
  440. package/dist/editor/setup-wizard/steps/CreateSettingsStep.js +1 -1
  441. package/dist/editor/setup-wizard/steps/LicenseActivationStep.js +1 -1
  442. package/dist/editor/setup-wizard/steps/LicenseEmailStep.js +1 -1
  443. package/dist/editor/setup-wizard/steps/ModelSelectionStep.js +1 -1
  444. package/dist/editor/setup-wizard/steps/ProviderStep.js +1 -1
  445. package/dist/editor/sidebar/ComponentPalette.js +4 -4
  446. package/dist/editor/sidebar/ComponentPalette.js.map +1 -1
  447. package/dist/editor/sidebar/ComponentTree.js +206 -113
  448. package/dist/editor/sidebar/ComponentTree.js.map +1 -1
  449. package/dist/editor/sidebar/ContentTreePanel.d.ts +2 -2
  450. package/dist/editor/sidebar/DictionaryEditor.js +1 -1
  451. package/dist/editor/sidebar/EditHistory.js +1 -1
  452. package/dist/editor/sidebar/Favorites.js.map +1 -1
  453. package/dist/editor/sidebar/NavigationPanelItem.js +1 -1
  454. package/dist/editor/sidebar/OperationItem.js +1 -1
  455. package/dist/editor/sidebar/Sessions.js +20 -9
  456. package/dist/editor/sidebar/Sessions.js.map +1 -1
  457. package/dist/editor/sidebar/Workbox.d.ts +8 -0
  458. package/dist/editor/sidebar/Workbox.js +94 -12
  459. package/dist/editor/sidebar/Workbox.js.map +1 -1
  460. package/dist/editor/sidebar/WorkboxFilters.d.ts +11 -0
  461. package/dist/editor/sidebar/WorkboxFilters.js +61 -0
  462. package/dist/editor/sidebar/WorkboxFilters.js.map +1 -0
  463. package/dist/editor/sidebar/WorkspaceRail.js +1 -1
  464. package/dist/editor/sidebar/useSharedComponentPublishState.js.map +1 -1
  465. package/dist/editor/template-wizard/TemplateBuilderDialog.js +1 -1
  466. package/dist/editor/template-wizard/TemplateStructureInlineEditor.js +1 -1
  467. package/dist/editor/tree-indicators/GutterColumns.js +1 -1
  468. package/dist/editor/tree-indicators/GutterContext.js +2 -2
  469. package/dist/editor/tree-indicators/GutterContext.js.map +1 -1
  470. package/dist/editor/ui/DragPreview.js.map +1 -1
  471. package/dist/editor/ui/ItemCollectionEditor.js +1 -1
  472. package/dist/editor/ui/ItemNameDialogNew.d.ts +11 -0
  473. package/dist/editor/ui/ItemNameDialogNew.js +12 -7
  474. package/dist/editor/ui/ItemNameDialogNew.js.map +1 -1
  475. package/dist/editor/ui/ItemSearch.js +1 -1
  476. package/dist/editor/ui/PerfectTree.d.ts +5 -1
  477. package/dist/editor/ui/PerfectTree.js +7 -5
  478. package/dist/editor/ui/PerfectTree.js.map +1 -1
  479. package/dist/editor/ui/PublishDialog.js +1 -1
  480. package/dist/editor/ui/PublishItemDialog.js +1 -1
  481. package/dist/editor/ui/PublishRestrictionsDialog.js +2 -2
  482. package/dist/editor/ui/PublishRestrictionsDialog.js.map +1 -1
  483. package/dist/editor/ui/RemoveComponentsConfirmMessage.js +1 -1
  484. package/dist/editor/ui/SimpleIconButton.d.ts +1 -1
  485. package/dist/editor/ui/SimpleTable.d.ts +5 -1
  486. package/dist/editor/ui/SimpleTable.js +5 -1
  487. package/dist/editor/ui/SimpleTable.js.map +1 -1
  488. package/dist/editor/ui/Spinner.js +1 -1
  489. package/dist/editor/ui/Spinner.js.map +1 -1
  490. package/dist/editor/ui/WorkboxItemsTable.js +49 -20
  491. package/dist/editor/ui/WorkboxItemsTable.js.map +1 -1
  492. package/dist/editor/utils/selectionContext.js.map +1 -1
  493. package/dist/editor/utils/sitecoreDate.js +8 -2
  494. package/dist/editor/utils/sitecoreDate.js.map +1 -1
  495. package/dist/editor/version-diff/versionDiffGeometryKeys.d.ts +10 -0
  496. package/dist/editor/version-diff/versionDiffGeometryKeys.js +16 -0
  497. package/dist/editor/version-diff/versionDiffGeometryKeys.js.map +1 -0
  498. package/dist/editor/version-diff/versionDiffHighlightStyles.d.ts +6 -0
  499. package/dist/editor/version-diff/versionDiffHighlightStyles.js +6 -0
  500. package/dist/editor/version-diff/versionDiffHighlightStyles.js.map +1 -1
  501. package/dist/editor/version-diff/versionDiffTargets.d.ts +40 -1
  502. package/dist/editor/version-diff/versionDiffTargets.js +176 -15
  503. package/dist/editor/version-diff/versionDiffTargets.js.map +1 -1
  504. package/dist/editor/views/ItemEditor.js +1 -1
  505. package/dist/editor/views/ItemEditorPane.js +1 -1
  506. package/dist/editor/views/ItemEditorPane.js.map +1 -1
  507. package/dist/editor/views/SingleEditView.js +1 -1
  508. package/dist/lib/pointerDrag.js.map +1 -1
  509. package/dist/lib/safelist.js +1 -1
  510. package/dist/licensing/FeatureGate.d.ts +1 -1
  511. package/dist/licensing/LicenseContext.js.map +1 -1
  512. package/dist/licensing/LicenseOverlay.js +1 -1
  513. package/dist/logging/consolePrefix.js.map +1 -1
  514. package/dist/revision.d.ts +2 -2
  515. package/dist/revision.js +2 -2
  516. package/dist/revision.js.map +1 -1
  517. package/dist/setup/services/setupWizardService.d.ts +3 -56
  518. package/dist/setup/services/setupWizardService.js +0 -43
  519. package/dist/setup/services/setupWizardService.js.map +1 -1
  520. package/dist/setup/wizard/steps/ImportModelDialog.js +1 -1
  521. package/dist/splash-screen/NewPage.js +1 -1
  522. package/dist/splash-screen/RecentPages.js +1 -1
  523. package/dist/task-board/TaskBoardWorkspace.js +5 -0
  524. package/dist/task-board/TaskBoardWorkspace.js.map +1 -1
  525. package/dist/task-board/components/ItemCollectionEditorDialog.js +1 -1
  526. package/dist/task-board/components/ProjectDashboard.js +1 -1
  527. package/dist/task-board/components/ProjectGoalsPanel.js +1 -1
  528. package/dist/task-board/components/ProjectSettingsDialog.js +1 -1
  529. package/dist/task-board/components/TaskBoardBreadcrumb.js +1 -1
  530. package/dist/task-board/components/TaskBoardProjectListSidebar.js +1 -1
  531. package/dist/task-board/components/TaskBoardProjectListSidebar.js.map +1 -1
  532. package/dist/task-board/components/TaskBoardTitlebar.js +1 -1
  533. package/dist/task-board/components/TaskDetailPanel.js +1 -1
  534. package/dist/task-board/components/TaskReviewActions.js +1 -1
  535. package/dist/task-board/components/TaskRow.js +1 -1
  536. package/dist/task-board/components/TaskboardPersistentLogPanel.js +1 -1
  537. package/dist/task-board/components/WizardCommunicationCenter.js +1 -1
  538. package/dist/task-board/components/WizardTask.js +1 -1
  539. package/dist/task-board/components/WizardTaskDetailsPanel.js +1 -1
  540. package/dist/task-board/services/goalService.d.ts +1 -14
  541. package/dist/task-board/services/goalService.js +0 -10
  542. package/dist/task-board/services/goalService.js.map +1 -1
  543. package/dist/task-board/services/taskService.d.ts +0 -11
  544. package/dist/task-board/services/taskService.js +0 -3
  545. package/dist/task-board/services/taskService.js.map +1 -1
  546. package/dist/task-board/views/DependencyGraphView.d.ts +13 -0
  547. package/dist/task-board/views/DependencyGraphView.js +62 -11
  548. package/dist/task-board/views/DependencyGraphView.js.map +1 -1
  549. package/dist/task-board/views/ListView.js +1 -1
  550. package/dist/tour/Tour.js +1 -1
  551. package/dist/tour/Tour.js.map +1 -1
  552. package/dist/tour/default-tour.js +1 -1
  553. package/dist/tour/preview-tour.js +1 -1
  554. package/dist/types.d.ts +33 -9
  555. package/package.json +5 -4
  556. package/styles.css +4 -4
  557. package/dist/editor/ai/terminal/components/AgentEditHistoryButton.d.ts +0 -5
  558. package/dist/editor/ai/terminal/components/AgentEditHistoryButton.js +0 -12
  559. package/dist/editor/ai/terminal/components/AgentEditHistoryButton.js.map +0 -1
  560. package/dist/editor/ai/terminal/components/AgentThinkingDots.d.ts +0 -5
  561. package/dist/editor/ai/terminal/components/AgentThinkingDots.js +0 -9
  562. package/dist/editor/ai/terminal/components/AgentThinkingDots.js.map +0 -1
  563. package/dist/editor/reviews/CommentsAndFeedback.d.ts +0 -8
  564. package/dist/editor/reviews/CommentsAndFeedback.js +0 -17
  565. package/dist/editor/reviews/CommentsAndFeedback.js.map +0 -1
  566. package/dist/editor/reviews/CreateReviewDetailsStep.d.ts +0 -53
  567. package/dist/editor/reviews/CreateReviewDetailsStep.js +0 -77
  568. package/dist/editor/reviews/CreateReviewDetailsStep.js.map +0 -1
  569. package/dist/splash-screen/ParheliaAssistantChat.d.ts +0 -8
  570. package/dist/splash-screen/ParheliaAssistantChat.js +0 -507
  571. package/dist/splash-screen/ParheliaAssistantChat.js.map +0 -1
  572. package/dist/splash-screen/SplashScreenAgentContext.d.ts +0 -28
  573. package/dist/splash-screen/SplashScreenAgentContext.js +0 -51
  574. package/dist/splash-screen/SplashScreenAgentContext.js.map +0 -1
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { providerDistinguishesSharedComponents } from "../services/contentService";
4
4
  import { useCanvasSelection, useEditContext, useEditContextRef, } from "../client/editContext";
5
5
  import { useCallback, useEffect, useMemo, useRef, useState } from "react";
@@ -15,8 +15,10 @@ import { SimpleIconButton, SimpleIconButtonStyleProvider, } from "../ui/SimpleIc
15
15
  import { Spinner } from "../ui/Spinner";
16
16
  import { SearchInput } from "../../components/SearchInput";
17
17
  import { Tooltip, TooltipContent, TooltipTrigger, } from "../../components/ui/tooltip";
18
+ import { Popover, PopoverContent, PopoverTrigger, } from "../../components/ui/popover";
18
19
  import { cn } from "../../lib/utils";
19
20
  import { InsertComponentMenu } from "../page-editor-chrome/InsertComponentMenu";
21
+ import { buildComponentDragObject } from "../page-editor-chrome/componentDragObject";
20
22
  import { useSharedComponentPublishState } from "./useSharedComponentPublishState";
21
23
  const publishStateDisplay = {
22
24
  success: {
@@ -53,7 +55,8 @@ export function ComponentTree({ pageViewContext, itemDescriptor, item, isLoading
53
55
  const [nodeDictionary, setNodeDictionary] = useState({});
54
56
  const [isTreeReady, setIsTreeReady] = useState(false);
55
57
  const [treeKey, setTreeKey] = useState(null);
56
- const [activeInsertBelowKey, setActiveInsertBelowKey] = useState(null);
58
+ const [activeInsertTargetKey, setActiveInsertTargetKey] = useState(null);
59
+ const [hoveredInsertTargetKey, setHoveredInsertTargetKey] = useState(null);
57
60
  let editContextRef = useEditContextRef();
58
61
  const editContext = useEditContext();
59
62
  const canvasSelection = useCanvasSelection();
@@ -79,7 +82,6 @@ export function ComponentTree({ pageViewContext, itemDescriptor, item, isLoading
79
82
  const getSharedPublishState = useSharedComponentPublishState(page, pageLanguage);
80
83
  const treeRef = useRef(null);
81
84
  const confirmDialogRef = useRef(null);
82
- const pendingDragStartTimeoutRef = useRef(null);
83
85
  // Helper function to clean placeholder labels by removing _{guid} pattern
84
86
  function cleanPlaceholderLabel(label) {
85
87
  return label.replace(/_{[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}}$/, "");
@@ -190,7 +192,7 @@ export function ComponentTree({ pageViewContext, itemDescriptor, item, isLoading
190
192
  const selection = canvasSelection;
191
193
  useEffect(() => {
192
194
  if (editContext?.currentOverlay !== "context-menu") {
193
- setActiveInsertBelowKey(null);
195
+ setActiveInsertTargetKey(null);
194
196
  }
195
197
  }, [editContext?.currentOverlay]);
196
198
  useEffect(() => {
@@ -724,7 +726,7 @@ export function ComponentTree({ pageViewContext, itemDescriptor, item, isLoading
724
726
  }
725
727
  }, [expandedKeys, handleCollapseItem]);
726
728
  // Handle collapsing nodes
727
- const getPlaceholder = (node) => {
729
+ const getPlaceholder = useCallback((node) => {
728
730
  if (!node)
729
731
  return null;
730
732
  if (node.type === "placeholder") {
@@ -737,7 +739,7 @@ export function ComponentTree({ pageViewContext, itemDescriptor, item, isLoading
737
739
  return editablePlaceholders[0];
738
740
  }
739
741
  return null;
740
- };
742
+ }, []);
741
743
  const getPlaceholderWithSettingsItem = (node) => {
742
744
  if (!node)
743
745
  return null;
@@ -755,14 +757,14 @@ export function ComponentTree({ pageViewContext, itemDescriptor, item, isLoading
755
757
  return null;
756
758
  };
757
759
  // Resolve placeholder and correct index for drop zones even when placeholders are hidden/flattened
758
- const getSiblingsForParent = (parent) => {
760
+ const getSiblingsForParent = useCallback((parent) => {
759
761
  if (!parent)
760
762
  return rootNodes || [];
761
763
  const parentNode = nodeDictionary[parent.key];
762
764
  return (parentNode?.children ||
763
765
  []);
764
- };
765
- const findNearestComponentNeighbor = (siblings, index) => {
766
+ }, [nodeDictionary, rootNodes]);
767
+ const findNearestComponentNeighbor = useCallback((siblings, index) => {
766
768
  // Prefer right neighbor
767
769
  for (let i = index; i < siblings.length; i++) {
768
770
  if (siblings[i]?.type === "component")
@@ -774,8 +776,8 @@ export function ComponentTree({ pageViewContext, itemDescriptor, item, isLoading
774
776
  return siblings[j];
775
777
  }
776
778
  return null;
777
- };
778
- const resolveDropContext = (dragOverParent, index) => {
779
+ }, []);
780
+ const resolveDropContext = useCallback((dragOverParent, index) => {
779
781
  // Direct placeholder parent
780
782
  if (dragOverParent && dragOverParent.type === "placeholder") {
781
783
  const placeholder = dragOverParent.data;
@@ -836,7 +838,7 @@ export function ComponentTree({ pageViewContext, itemDescriptor, item, isLoading
836
838
  return { placeholder: ph, indexInPlaceholder };
837
839
  }
838
840
  return { placeholder: null, indexInPlaceholder: 0 };
839
- };
841
+ }, [findNearestComponentNeighbor, getSiblingsForParent]);
840
842
  // Handle drag over node (memoized)
841
843
  const handleDragOverZone = useCallback((dragOverNode, index, event) => {
842
844
  if (!editContext?.dragObject)
@@ -847,7 +849,7 @@ export function ComponentTree({ pageViewContext, itemDescriptor, item, isLoading
847
849
  const isValid = isValidPlaceholder(placeholder, editContext.dragObject);
848
850
  event.dataTransfer.dropEffect = isValid ? "move" : "none";
849
851
  return isValid;
850
- }, [editContext?.dragObject]);
852
+ }, [editContext?.dragObject, resolveDropContext]);
851
853
  // Handle drop on node (memoized)
852
854
  const handleDropZone = useCallback((droppedOnNode, index, event) => {
853
855
  // When dropping on a node (index < 0), use legacy behavior
@@ -862,7 +864,7 @@ export function ComponentTree({ pageViewContext, itemDescriptor, item, isLoading
862
864
  if (!placeholder)
863
865
  return;
864
866
  editContext.droppedInPlaceholder(placeholder.key, indexInPlaceholder);
865
- }, [editContext]);
867
+ }, [editContext, getPlaceholder, resolveDropContext]);
866
868
  // Memoize isValidDropZone callback
867
869
  const handleIsValidDropZone = useCallback((parent, index) => {
868
870
  const { placeholder } = resolveDropContext(parent, index);
@@ -872,7 +874,7 @@ export function ComponentTree({ pageViewContext, itemDescriptor, item, isLoading
872
874
  return false;
873
875
  const result = isValidPlaceholder(placeholder, editContext.dragObject);
874
876
  return result;
875
- }, [editContext?.dragObject]);
877
+ }, [editContext?.dragObject, resolveDropContext]);
876
878
  // Memoize onStartDrag callback
877
879
  const handleStartDrag = useCallback((data) => {
878
880
  const component = data.node.data;
@@ -881,85 +883,99 @@ export function ComponentTree({ pageViewContext, itemDescriptor, item, isLoading
881
883
  // Align with FrameMenu: include componentId and allowed effect
882
884
  data.event.dataTransfer.setData("componentId", component.id);
883
885
  data.event.dataTransfer.effectAllowed = "copyMove";
884
- // Only create drag object for components with datasourceItem
885
- if (!component?.datasourceItem)
886
- return;
887
- pendingDragStartTimeoutRef.current = setTimeout(() => {
888
- if (!pageLanguage || pageVersion == null)
889
- return;
890
- const language = pageLanguage;
891
- const version = pageVersion;
892
- const currentSelection = editContext?.getSelection() ?? [];
893
- const selectedIds = currentSelection.length > 1 && currentSelection.includes(component.id)
894
- ? currentSelection
895
- : [component.id];
896
- const componentsToDrag = selectedIds.map((id) => ({
897
- id,
898
- language,
899
- version,
900
- }));
901
- editContext.dragStart({
902
- type: "component",
903
- typeId: component.typeId,
904
- templateId: component.datasourceItem?.templateId,
905
- name: component.name,
906
- components: componentsToDrag,
907
- });
908
- }, 50);
909
- // Prevent any upstream handlers from interfering
886
+ // Prevent any upstream handlers from interfering.
910
887
  data.event.stopPropagation();
911
- }, [editContext]);
888
+ if (!pageLanguage || pageVersion == null)
889
+ return;
890
+ const currentSelection = editContext?.getSelection() ?? [];
891
+ const selectedIds = currentSelection.length > 1 && currentSelection.includes(component.id)
892
+ ? currentSelection
893
+ : [component.id];
894
+ editContext?.dragStart(buildComponentDragObject(component, selectedIds, {
895
+ language: pageLanguage,
896
+ version: pageVersion,
897
+ }));
898
+ }, [editContext, pageLanguage, pageVersion]);
912
899
  // Memoize onDragEnd callback
913
900
  const handleDragEnd = useCallback((event) => {
914
- if (pendingDragStartTimeoutRef.current) {
915
- clearTimeout(pendingDragStartTimeoutRef.current);
916
- pendingDragStartTimeoutRef.current = null;
917
- }
918
901
  editContext.dragEnd();
919
902
  }, [editContext]);
920
- // Cleanup pending drag start timeout on unmount
921
- useEffect(() => {
922
- return () => {
923
- if (pendingDragStartTimeoutRef.current) {
924
- clearTimeout(pendingDragStartTimeoutRef.current);
925
- pendingDragStartTimeoutRef.current = null;
926
- }
927
- };
928
- }, []);
929
- // Whether a component can have a sibling inserted right after it. Mirrors the
930
- // on-canvas "append" affordance: the parent placeholder must be editable and
931
- // expose at least one visible insert option.
932
- const canInsertBelow = useCallback((component) => {
903
+ // A tree insertion target is useful only when its placeholder is editable and
904
+ // has at least one visible component option.
905
+ const canInsertIntoPlaceholder = useCallback((placeholder) => {
933
906
  if (!editContext || editContext.readonly || editContext.mode !== "edit") {
934
907
  return false;
935
908
  }
936
- const placeholder = component.parentPlaceholder;
937
- if (!placeholder?.editable)
909
+ if (!placeholder.editable)
938
910
  return false;
939
911
  return getVisibleInsertOptions(placeholder.insertOptions).length > 0;
940
912
  }, [editContext]);
941
- const getInsertBelowOptions = useCallback((component) => {
942
- const placeholder = component.parentPlaceholder;
943
- if (!placeholder?.editable)
913
+ const getPlaceholderInsertOptions = useCallback((placeholder) => {
914
+ if (!placeholder.editable)
944
915
  return [];
945
916
  return getVisibleInsertOptions(placeholder.insertOptions);
946
917
  }, []);
947
- // Add a component directly after the given one. The menu itself is the same
948
- // popover used by WYSIWYG placeholder dropzones; this keeps only the
949
- // component-tree-specific insertion index here.
950
- const handleInsertBelowSelect = useCallback(async (component, option) => {
918
+ const handleInsertSelect = useCallback(async (placeholder, insertIndex, option) => {
951
919
  const ctx = editContextRef.current;
952
- setActiveInsertBelowKey(null);
920
+ setActiveInsertTargetKey(null);
953
921
  if (!ctx || ctx.readonly || ctx.mode !== "edit")
954
922
  return;
955
- const placeholder = component.parentPlaceholder;
956
- if (!placeholder?.editable)
923
+ if (!placeholder.editable)
957
924
  return;
958
- const insertIndex = placeholder.components.findIndex((c) => c.id === component.id) + 1;
959
925
  await editContextRef.current?.operations.addComponent(option.typeId, placeholder.key, insertIndex, pageItemDescriptor);
960
926
  }, [editContextRef, pageItemDescriptor]);
961
- const handleInsertBelowOpenChange = useCallback((component, open) => {
962
- setActiveInsertBelowKey(open ? component.id : null);
927
+ const handleInsertOpenChange = useCallback((targetKey, open) => {
928
+ setActiveInsertTargetKey(open ? targetKey : null);
929
+ }, []);
930
+ const handleNodeInsertTargetHover = useCallback((node, event) => {
931
+ const treeNode = node;
932
+ if (treeNode.type !== "component") {
933
+ return;
934
+ }
935
+ const component = treeNode.data;
936
+ const parentPlaceholder = component.parentPlaceholder;
937
+ const canInsertSibling = !!parentPlaceholder && canInsertIntoPlaceholder(parentPlaceholder);
938
+ const componentIndex = parentPlaceholder?.components.findIndex((sibling) => sibling.id === component.id) ?? -1;
939
+ const precedingComponent = componentIndex > 0
940
+ ? parentPlaceholder?.components[componentIndex - 1]
941
+ : undefined;
942
+ const precedingGapTargetKey = precedingComponent
943
+ ? `below:${precedingComponent.id}`
944
+ : `above:${component.id}`;
945
+ const innerPlaceholders = component.placeholders?.filter(canInsertIntoPlaceholder) ?? [];
946
+ const innerTargetKey = innerPlaceholders.length === 1
947
+ ? getPlaceholderInsertTargetKey(component, innerPlaceholders[0])
948
+ : innerPlaceholders.length > 1
949
+ ? getPlaceholderPickerTargetKey(component)
950
+ : null;
951
+ const rowRect = event.currentTarget.getBoundingClientRect();
952
+ const relativeY = Math.max(0, Math.min(rowRect.height, event.clientY - rowRect.top));
953
+ const verticalRatio = rowRect.height > 0 ? relativeY / rowRect.height : 0;
954
+ let targetKey = null;
955
+ if (canInsertSibling && innerTargetKey) {
956
+ targetKey =
957
+ verticalRatio < 1 / 3
958
+ ? precedingGapTargetKey
959
+ : verticalRatio > 2 / 3
960
+ ? `below:${component.id}`
961
+ : innerTargetKey;
962
+ }
963
+ else if (innerTargetKey) {
964
+ targetKey = innerTargetKey;
965
+ }
966
+ else if (canInsertSibling) {
967
+ targetKey =
968
+ verticalRatio < 1 / 2
969
+ ? precedingGapTargetKey
970
+ : `below:${component.id}`;
971
+ }
972
+ setHoveredInsertTargetKey((current) => current === targetKey ? current : targetKey);
973
+ }, [canInsertIntoPlaceholder]);
974
+ const handleNodeInsertTargetLeave = useCallback(() => {
975
+ setHoveredInsertTargetKey(null);
976
+ }, []);
977
+ const handleInsertTargetHover = useCallback((targetKey) => {
978
+ setHoveredInsertTargetKey(targetKey);
963
979
  }, []);
964
980
  // Check if we have a valid page model
965
981
  const hasPageModel = page && page.rootComponent && page.item;
@@ -998,44 +1014,49 @@ export function ComponentTree({ pageViewContext, itemDescriptor, item, isLoading
998
1014
  };
999
1015
  // Only show error if page model failed to load (not if page is just empty)
1000
1016
  if (hasInvalidPageModel && isTreeReady && !isSlotLoading && !isRefreshing) {
1001
- return (_jsxs("div", { className: "flex h-full flex-col", children: [_jsx(SimpleIconButtonStyleProvider, { selectedClassName: "bg-neutral-grey-5 text-neutral-grey-100", children: _jsxs("div", { className: "border-border-default badge-pad flex items-center justify-between border-b", children: [_jsx("div", { className: "flex items-center gap-1", children: _jsx(SimpleIconButton, { icon: _jsx(Plus, { strokeWidth: 1, className: "h-5 w-5" }), label: "Add component", size: "small", className: "h-[30px] w-[30px]", "data-testid": "component-tree-add-component", selected: insertMode, disabled: !canWriteItem ||
1017
+ return (_jsxs("div", { className: "flex h-full flex-col", children: [_jsx(SimpleIconButtonStyleProvider, { selectedClassName: "bg-neutral-grey-5 text-neutral-grey-100", children: _jsxs("div", { className: "border-border-default badge-pad flex items-center justify-between border-b", children: [_jsx("div", { className: "flex items-center gap-1", children: _jsx(SimpleIconButton, { icon: _jsx(Plus, { size: 16, strokeWidth: 1, absoluteStrokeWidth: true, className: "m-0.5" }), label: "Add component (Insert)", size: "small", className: "min-w-0 shrink gap-1.5 px-2 py-1 [&>svg]:shrink-0", "data-testid": "component-tree-add-component", selected: insertMode, showTooltip: false, disabled: !canWriteItem ||
1002
1018
  !editContext ||
1003
1019
  editContext.readonly ||
1004
- editContext.mode !== "edit", onClick: toggleInsertMode }) }), _jsx("div", { className: "flex items-center gap-1", children: _jsx(SimpleIconButton, { icon: _jsx(LayoutTemplate, { strokeWidth: 1, className: "h-5 w-5" }), label: editContext?.showLayoutComponents
1020
+ editContext.mode !== "edit", onClick: toggleInsertMode, children: _jsx("span", { className: "min-w-0 truncate", children: "Add component" }) }) }), _jsx("div", { className: "flex items-center gap-1", children: _jsx(SimpleIconButton, { icon: _jsx(LayoutTemplate, { strokeWidth: 1, className: "h-5 w-5" }), label: editContext?.showLayoutComponents
1005
1021
  ? "Hide layout"
1006
1022
  : "Show layout", size: "small", className: "h-[30px] w-[30px]", selected: editContext?.showLayoutComponents, "data-testid": "component-tree-toggle-layout", onClick: () => editContext?.setShowLayoutComponents(!editContext.showLayoutComponents) }) })] }) }), _jsx("div", { className: "text-neutral-grey-50 flex flex-1 items-center justify-center text-xs", children: "Page did not load. Please refresh or try again." }), _jsx(ConfirmationDialog, { ref: confirmDialogRef })] }));
1007
1023
  }
1008
- return (_jsxs("div", { className: "flex h-full flex-col", children: [_jsx(SimpleIconButtonStyleProvider, { selectedClassName: "bg-neutral-grey-5 text-neutral-grey-100", children: _jsxs("div", { className: "border-border-default badge-pad flex items-center justify-between border-b", children: [_jsx("div", { className: "flex items-center gap-1", children: _jsx(SimpleIconButton, { icon: _jsx(Plus, { strokeWidth: 1, className: "h-4 w-4" }), label: "Add component", size: "small", "data-testid": "component-tree-add-component", selected: insertMode, disabled: !canWriteItem ||
1024
+ return (_jsxs("div", { className: "flex h-full flex-col", children: [_jsx(SimpleIconButtonStyleProvider, { selectedClassName: "bg-neutral-grey-5 text-neutral-grey-100", children: _jsxs("div", { className: "border-border-default badge-pad flex items-center justify-between border-b", children: [_jsx("div", { className: "flex items-center gap-1", children: _jsx(SimpleIconButton, { icon: _jsx(Plus, { size: 16, strokeWidth: 1, absoluteStrokeWidth: true, className: "m-0.5" }), label: "Add component (Insert)", size: "small", className: "min-w-0 shrink gap-1.5 px-2 py-1 [&>svg]:shrink-0", "data-testid": "component-tree-add-component", selected: insertMode, showTooltip: false, disabled: !canWriteItem ||
1009
1025
  !editContext ||
1010
1026
  editContext.readonly ||
1011
- editContext.mode !== "edit", onClick: toggleInsertMode }) }), _jsx("div", { className: "flex items-center gap-1", children: _jsx(SimpleIconButton, { icon: _jsx(LayoutTemplate, { strokeWidth: 1, className: "h-5 w-5" }), label: editContext?.showLayoutComponents
1027
+ editContext.mode !== "edit", onClick: toggleInsertMode, children: _jsx("span", { className: "min-w-0 truncate", children: "Add component" }) }) }), _jsx("div", { className: "flex items-center gap-1", children: _jsx(SimpleIconButton, { icon: _jsx(LayoutTemplate, { strokeWidth: 1, className: "h-5 w-5" }), label: editContext?.showLayoutComponents
1012
1028
  ? "Hide layout"
1013
- : "Show layout", size: "small", className: "h-[30px] w-[30px]", selected: editContext?.showLayoutComponents, "data-testid": "component-tree-toggle-layout", onClick: () => editContext?.setShowLayoutComponents(!editContext.showLayoutComponents) }) })] }) }), _jsx("div", { className: "border-border-default border-b p-2", "data-testid": "component-tree-search", children: _jsx(SearchInput, { value: filter, onChange: setFilter, className: "w-full", placeholder: "Search IDs, names, types..." }) }), _jsx("div", { className: "min-h-0 flex-1 overflow-auto overflow-x-hidden p-2", ref: treeRef, "data-testid": "component-tree", children: isFiltering && visibleRootNodes.length === 0 ? (_jsxs("div", { className: "text-neutral-grey-50 flex h-full items-center justify-center px-4 text-center text-xs", children: ["No components match \"", filter.trim(), "\"."] })) : (_jsx(PerfectTree, { nodes: visibleRootNodes, isDragging: !isFiltering && !!editContext?.dragObject, multiDragNoun: "components", selectedKeys: selectedItems, expandedKeys: expandedItems, onToggleExpand: isFiltering ? undefined : handleToggle, onSelect: handleTreeSelection, onContextMenu: handleTreeContextMenu, enableDragAndDrop: !isFiltering, onDragOverZone: handleDragOverZone, isValidDropZone: handleIsValidDropZone, onStartDrag: handleStartDrag, onDragEnd: handleDragEnd, onDrop: handleDropZone, renderNodePrefix: (node) => {
1029
+ : "Show layout", size: "small", className: "h-[30px] w-[30px]", selected: editContext?.showLayoutComponents, "data-testid": "component-tree-toggle-layout", onClick: () => editContext?.setShowLayoutComponents(!editContext.showLayoutComponents) }) })] }) }), _jsx("div", { className: "border-border-default border-b p-2", "data-testid": "component-tree-search", children: _jsx(SearchInput, { value: filter, onChange: setFilter, className: "w-full", placeholder: "Search IDs, names, types..." }) }), _jsx("div", { className: "min-h-0 flex-1 overflow-auto overflow-x-hidden p-2", ref: treeRef, "data-testid": "component-tree", children: isFiltering && visibleRootNodes.length === 0 ? (_jsxs("div", { className: "text-neutral-grey-50 flex h-full items-center justify-center px-4 text-center text-xs", children: ["No components match \"", filter.trim(), "\"."] })) : (_jsx(PerfectTree, { nodes: visibleRootNodes, isDragging: !isFiltering && !!editContext?.dragObject, multiDragNoun: "components", selectedKeys: selectedItems, expandedKeys: expandedItems, onToggleExpand: isFiltering ? undefined : handleToggle, onSelect: handleTreeSelection, onContextMenu: handleTreeContextMenu, enableDragAndDrop: !isFiltering, onDragOverZone: handleDragOverZone, isValidDropZone: handleIsValidDropZone, onStartDrag: handleStartDrag, onDragEnd: handleDragEnd, onDrop: handleDropZone, onNodeMouseMove: handleNodeInsertTargetHover, onNodeMouseLeave: handleNodeInsertTargetLeave, renderNodePrefix: (node) => {
1014
1030
  const treeNode = node;
1015
1031
  if (treeNode.type !== "component")
1016
1032
  return null;
1017
- return (_jsx("span", { className: cn("text-neutral-grey-50 hover:text-neutral-grey-100 flex h-[23px] w-4 flex-none cursor-grab items-center justify-center transition-colors active:cursor-grabbing"), "data-testid": "component-tree-drag-handle", "aria-hidden": "true", children: _jsx(GripVertical, { strokeWidth: 1, className: "h-4 w-4" }) }));
1033
+ return (_jsx("span", { className: cn("text-neutral-grey-50 hover:text-neutral-grey-100 group-hover:text-neutral-grey-100 flex h-[23px] w-4 flex-none cursor-grab items-center justify-center transition-colors active:cursor-grabbing"), "data-testid": "component-tree-drag-handle", "aria-hidden": "true", children: _jsx(GripVertical, { strokeWidth: 1, className: "h-4 w-4" }) }));
1018
1034
  }, renderToggleIcon: () => (_jsx("svg", { width: "12", height: "12", viewBox: "0 0 12 12", fill: "none", className: "text-neutral-grey-100", "aria-hidden": "true", children: _jsx("path", { d: "M9 6L4.5 1.66987L4.5 10.3301L9 6Z", fill: "currentColor" }) })), suppressDefaultNodeChrome: (node) => node.type === "component", getRowClassName: (node, _depth, { isSelected, isDragOver }) => {
1019
1035
  const nodeType = node.type;
1020
1036
  if (nodeType === "component") {
1021
- return cn("group mb-1.5 gap-1 rounded-[4px] border px-1 py-2 transition-colors", isDragOver
1037
+ return cn("group mb-2 gap-1 rounded-[2px] border px-1 py-2 transition-colors", isDragOver
1022
1038
  ? "border-component-default bg-component-default/10"
1023
1039
  : isSelected
1024
1040
  ? "border-border-default bg-neutral-grey-5"
1025
1041
  : "border-border-default hover:border-neutral-grey-50");
1026
1042
  }
1027
- if (nodeType === "page" || nodeType === "placeholder") {
1028
- return "mb-1.5 [&>div:last-child]:py-2 [&[data-selected=true]>div:last-child]:bg-neutral-grey-5";
1043
+ if (nodeType === "page") {
1044
+ return cn("mb-1.5 [&>div:last-child]:py-2 [&[data-selected=true]>div:last-child]:bg-neutral-grey-5", isSelected && "bg-neutral-grey-5");
1045
+ }
1046
+ if (nodeType === "placeholder") {
1047
+ return cn("mb-1.5 [&>div:last-child]:py-2 [&[data-selected=true]>div:last-child]:bg-neutral-grey-5", isSelected && "bg-neutral-grey-5");
1029
1048
  }
1030
1049
  return undefined;
1031
1050
  }, renderNode: (node) => {
1032
1051
  const treeNode = node;
1033
1052
  return renderNode(treeNode, filter, {
1034
- canInsertBelow,
1035
- getInsertBelowOptions,
1036
- onInsertBelowSelect: handleInsertBelowSelect,
1037
- onInsertBelowOpenChange: handleInsertBelowOpenChange,
1038
- isInsertBelowActive: activeInsertBelowKey === treeNode.key,
1053
+ canInsertIntoPlaceholder,
1054
+ getPlaceholderInsertOptions,
1055
+ onInsertSelect: handleInsertSelect,
1056
+ onInsertOpenChange: handleInsertOpenChange,
1057
+ onInsertTargetHover: handleInsertTargetHover,
1058
+ activeInsertTargetKey,
1059
+ hoveredInsertTargetKey,
1039
1060
  });
1040
1061
  } })) }), _jsx(ConfirmationDialog, { ref: confirmDialogRef })] }));
1041
1062
  }
@@ -1043,34 +1064,106 @@ function renderNode(node, filter = "", opts) {
1043
1064
  const trimmedFilter = filter.trim();
1044
1065
  const filterDetails = trimmedFilter ? getNodeFilterDetails(node) : null;
1045
1066
  const component = node.type === "component" ? node.data : null;
1046
- const showInsertBelow = !!component && (opts?.canInsertBelow?.(component) ?? false);
1047
- const isInsertBelowActive = !!opts?.isInsertBelowActive;
1048
- const insertBelowOptions = showInsertBelow && component
1049
- ? (opts?.getInsertBelowOptions?.(component) ?? [])
1067
+ const parentPlaceholder = component?.parentPlaceholder;
1068
+ const showSiblingInsertTargets = !!parentPlaceholder &&
1069
+ (opts?.canInsertIntoPlaceholder?.(parentPlaceholder) ?? false);
1070
+ const componentIndex = component && parentPlaceholder
1071
+ ? parentPlaceholder.components.findIndex((item) => item.id === component.id)
1072
+ : -1;
1073
+ const siblingInsertOptions = showSiblingInsertTargets && parentPlaceholder
1074
+ ? (opts?.getPlaceholderInsertOptions?.(parentPlaceholder) ?? [])
1050
1075
  : [];
1051
- return (_jsxs("div", { className: `component-tree-node ${node.type ? `component-tree-${node.type}` : ""}`, "data-component-node": node.type === "component" ? "true" : undefined, "data-testid": "component-tree-node", "data-component-key": node.key, "data-component-type": node.type, children: [_jsxs("div", { className: "text-neutral-grey-100 flex items-center gap-2 text-[12px]", children: [typeof node.icon === "string" ? (_jsx("i", { className: node.icon })) : (node.icon), _jsx("span", { className: node.className, "data-testid": "component-tree-node-label", children: highlightSearchMatch(node.label, trimmedFilter) }), node.tags?.map((x) => (_jsx("div", { children: _jsxs("span", { id: `id-${node.key}-${x.id}`, className: "ml-2 flex rounded p-0.5 px-1.5 text-xs text-white", style: {
1052
- backgroundColor: x.color,
1053
- marginLeft: "8px",
1054
- fontSize: "10px",
1055
- }, title: x.tooltip, onClick: x.onClick
1056
- ? (e) => {
1057
- e.stopPropagation();
1058
- x.onClick();
1059
- }
1060
- : undefined, children: [x.icon, highlightSearchMatch(x.value, trimmedFilter)] }) }, `tag-${node.key}-${x.id}`)))] }), filterDetails ? (_jsx("div", { className: "text-neutral-grey-50 mt-0.5 ml-6 truncate text-[10px]", title: filterDetails, children: highlightSearchMatch(filterDetails, trimmedFilter) })) : null, showInsertBelow ? (_jsxs(Tooltip, { children: [_jsx(InsertComponentMenu, { open: isInsertBelowActive, onOpenChange: (open) => opts?.onInsertBelowOpenChange?.(component, open), title: "Insert below", options: insertBelowOptions, onSelect: (option) => opts?.onInsertBelowSelect?.(component, option), side: "right", align: "start", sideOffset: 12, children: _jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", "data-testid": "component-tree-insert-below", "data-active": isInsertBelowActive ? "true" : undefined, "aria-label": "Insert component below", onMouseDown: (e) => e.stopPropagation(), onClick: (e) => {
1061
- e.stopPropagation();
1062
- if (e.ctrlKey || e.metaKey) {
1063
- e.preventDefault();
1064
- const matchingOption = getMatchingInsertBelowOption(component, insertBelowOptions);
1065
- if (matchingOption) {
1066
- opts?.onInsertBelowSelect?.(component, matchingOption);
1076
+ const isBetweenGap = !!parentPlaceholder &&
1077
+ componentIndex >= 0 &&
1078
+ componentIndex < parentPlaceholder.components.length - 1;
1079
+ const placeholderInsertTargets = component?.placeholders?.filter((placeholder) => opts?.canInsertIntoPlaceholder?.(placeholder) ?? false) ?? [];
1080
+ return (_jsxs("div", { className: `component-tree-node w-full min-w-0 ${node.type ? `component-tree-${node.type}` : ""}`, "data-component-node": node.type === "component" ? "true" : undefined, "data-testid": "component-tree-node", "data-component-key": node.key, "data-component-type": node.type, children: [_jsxs("div", { className: "text-neutral-grey-100 flex min-w-0 items-center gap-2 text-[12px]", children: [_jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [typeof node.icon === "string" ? (_jsx("i", { className: node.icon })) : (node.icon), _jsx("span", { className: cn("truncate", node.className), "data-testid": "component-tree-node-label", children: highlightSearchMatch(node.label, trimmedFilter) }), node.tags?.map((x) => (_jsx("div", { children: _jsxs("span", { id: `id-${node.key}-${x.id}`, className: "ml-2 flex rounded p-0.5 px-1.5 text-xs text-white", style: {
1081
+ backgroundColor: x.color,
1082
+ marginLeft: "8px",
1083
+ fontSize: "10px",
1084
+ }, title: x.tooltip, onClick: x.onClick
1085
+ ? (e) => {
1086
+ e.stopPropagation();
1087
+ x.onClick();
1067
1088
  }
1068
- }
1069
- }, className: cn("bg-component-default absolute bottom-0 left-1/2 z-20 flex h-6 w-6 -translate-x-1/2 translate-y-1/2 items-center justify-center rounded-[4px] text-white transition-all hover:brightness-105 active:scale-95", isInsertBelowActive
1070
- ? "pointer-events-auto opacity-100"
1071
- : "pointer-events-none opacity-0 group-hover:pointer-events-auto group-hover:opacity-100 focus-visible:pointer-events-auto focus-visible:opacity-100"), children: _jsx(Plus, { className: "h-4 w-4", strokeWidth: 1 }) }) }) }), _jsx(TooltipContent, { side: "right", sideOffset: 8, children: "Insert component below" })] })) : null] }));
1089
+ : undefined, children: [x.icon, highlightSearchMatch(x.value, trimmedFilter)] }) }, `tag-${node.key}-${x.id}`)))] }), component && placeholderInsertTargets.length > 0 ? (_jsx(ComponentTreePlaceholderInsertControl, { component: component, placeholders: placeholderInsertTargets, activeTargetKey: opts?.activeInsertTargetKey, hoveredTargetKey: opts?.hoveredInsertTargetKey, getOptions: (placeholder) => opts?.getPlaceholderInsertOptions?.(placeholder) ?? [], onOpenChange: opts?.onInsertOpenChange, onSelect: (placeholder, option) => opts?.onInsertSelect?.(placeholder, placeholder.components.length, option) })) : null] }), filterDetails ? (_jsx("div", { className: "text-neutral-grey-50 mt-0.5 ml-6 truncate text-[10px]", title: filterDetails, children: highlightSearchMatch(filterDetails, trimmedFilter) })) : null, showSiblingInsertTargets && parentPlaceholder && componentIndex >= 0 ? (_jsxs(_Fragment, { children: [componentIndex === 0 ? (_jsx(ComponentTreeGapInsertControl, { placement: "above", targetKey: `above:${component.id}`, activeTargetKey: opts?.activeInsertTargetKey, hoveredTargetKey: opts?.hoveredInsertTargetKey, onHoverTarget: opts?.onInsertTargetHover, testId: "component-tree-insert-above", title: "Insert above", ariaLabel: "Insert component above", options: siblingInsertOptions, onOpenChange: opts?.onInsertOpenChange, onSelect: (option) => opts?.onInsertSelect?.(parentPlaceholder, componentIndex, option), quickInsertComponent: component })) : null, _jsx(ComponentTreeGapInsertControl, { placement: "below", targetKey: `below:${component.id}`, activeTargetKey: opts?.activeInsertTargetKey, hoveredTargetKey: opts?.hoveredInsertTargetKey, onHoverTarget: opts?.onInsertTargetHover, testId: "component-tree-insert-below", title: isBetweenGap ? "Insert between" : "Insert below", ariaLabel: isBetweenGap
1090
+ ? "Insert component between"
1091
+ : "Insert component below", options: siblingInsertOptions, onOpenChange: opts?.onInsertOpenChange, onSelect: (option) => opts?.onInsertSelect?.(parentPlaceholder, componentIndex + 1, option), quickInsertComponent: component })] })) : null] }));
1092
+ }
1093
+ function ComponentTreePlaceholderInsertControl({ component, placeholders, activeTargetKey, hoveredTargetKey, getOptions, onOpenChange, onSelect, }) {
1094
+ const [selectedPlaceholder, setSelectedPlaceholder] = useState(null);
1095
+ const pickerTargetKey = getPlaceholderPickerTargetKey(component);
1096
+ const selectedTargetKey = selectedPlaceholder
1097
+ ? getPlaceholderInsertTargetKey(component, selectedPlaceholder)
1098
+ : null;
1099
+ if (placeholders.length === 1) {
1100
+ const placeholder = placeholders[0];
1101
+ const targetKey = getPlaceholderInsertTargetKey(component, placeholder);
1102
+ const label = cleanComponentTreePlaceholderLabel(placeholder);
1103
+ return (_jsx("div", { className: "ml-auto flex max-w-[60%] min-w-0 shrink items-center justify-end", "data-testid": "component-tree-placeholder-actions", children: _jsx(ComponentTreeInsertButton, { targetKey: targetKey, activeTargetKey: activeTargetKey, hoverVisible: hoveredTargetKey === targetKey, testId: "component-tree-insert-placeholder", title: `Insert into ${label}`, ariaLabel: `Insert component into ${label} placeholder`, options: getOptions(placeholder), onOpenChange: onOpenChange, onSelect: (option) => onSelect(placeholder, option), className: "relative h-6 w-6 shrink-0", children: _jsx(Plus, { className: "h-4 w-4", strokeWidth: 1 }) }) }));
1104
+ }
1105
+ if (selectedPlaceholder &&
1106
+ selectedTargetKey &&
1107
+ activeTargetKey === selectedTargetKey) {
1108
+ const label = cleanComponentTreePlaceholderLabel(selectedPlaceholder);
1109
+ return (_jsx("div", { className: "ml-auto flex max-w-[60%] min-w-0 shrink items-center justify-end", "data-testid": "component-tree-placeholder-actions", children: _jsx(ComponentTreeInsertButton, { targetKey: selectedTargetKey, activeTargetKey: activeTargetKey, hoverVisible: hoveredTargetKey === selectedTargetKey, testId: "component-tree-insert-placeholder", title: `Insert into ${label}`, ariaLabel: `Insert component into ${label} placeholder`, options: getOptions(selectedPlaceholder), onOpenChange: (targetKey, open) => {
1110
+ if (!open)
1111
+ setSelectedPlaceholder(null);
1112
+ onOpenChange?.(targetKey, open);
1113
+ }, onSelect: (option) => {
1114
+ setSelectedPlaceholder(null);
1115
+ onSelect(selectedPlaceholder, option);
1116
+ }, className: "relative h-6 w-6 shrink-0", children: _jsx(Plus, { className: "h-4 w-4", strokeWidth: 1 }) }) }));
1117
+ }
1118
+ const pickerOpen = activeTargetKey === pickerTargetKey;
1119
+ const pickerHoverVisible = hoveredTargetKey === pickerTargetKey;
1120
+ return (_jsx("div", { className: "ml-auto flex max-w-[60%] min-w-0 shrink items-center justify-end", "data-testid": "component-tree-placeholder-actions", children: _jsxs(Popover, { open: pickerOpen, onOpenChange: (open) => onOpenChange?.(pickerTargetKey, open), children: [_jsx(PopoverTrigger, { asChild: true, children: _jsx("button", { type: "button", "data-testid": "component-tree-insert-placeholder", "data-insert-target": pickerTargetKey, "data-active": pickerOpen ? "true" : undefined, "aria-label": "Choose a placeholder to insert a component into", onMouseDown: (event) => event.stopPropagation(), onClick: (event) => event.stopPropagation(), className: cn("bg-component-default relative flex h-6 w-6 shrink-0 items-center justify-center rounded-[4px] text-white transition-all hover:brightness-105 active:scale-95", pickerOpen || pickerHoverVisible
1121
+ ? "pointer-events-auto opacity-100"
1122
+ : "pointer-events-none opacity-0 focus-visible:pointer-events-auto focus-visible:opacity-100"), children: _jsx(Plus, { className: "h-4 w-4", strokeWidth: 1 }) }) }), _jsxs(PopoverContent, { side: "right", align: "start", sideOffset: 12, collisionPadding: 12, onOpenAutoFocus: (event) => event.preventDefault(), "data-testid": "component-tree-placeholder-picker", className: "border-border-default text-popover-foreground z-250 w-60 max-w-[15rem] overflow-hidden rounded-[4px] border bg-white/95 p-1.5 backdrop-blur-md", children: [_jsx("div", { className: "text-neutral-grey-50 px-2 pt-1 pb-1.5 text-[11px] font-semibold tracking-wide uppercase", children: "Choose placeholder" }), _jsx("div", { className: "flex flex-col gap-0.5", children: placeholders.map((placeholder) => {
1123
+ const label = cleanComponentTreePlaceholderLabel(placeholder);
1124
+ return (_jsxs("button", { type: "button", "data-testid": "component-tree-placeholder-option", "data-placeholder-key": placeholder.key, onClick: (event) => {
1125
+ event.preventDefault();
1126
+ event.stopPropagation();
1127
+ setSelectedPlaceholder(placeholder);
1128
+ onOpenChange?.(getPlaceholderInsertTargetKey(component, placeholder), true);
1129
+ }, className: "hover:bg-neutral-grey-5 focus-visible:bg-neutral-grey-5 flex w-full items-center gap-2 rounded-[4px] px-2 py-1.5 text-left text-[12px] transition-colors focus-visible:outline-none", children: [_jsx(Folder, { className: "text-neutral-grey-50 h-4 w-4 shrink-0", strokeWidth: 1 }), _jsx("span", { className: "min-w-0 flex-1 truncate", children: label }), _jsx(ChevronRight, { className: "text-neutral-grey-50 h-3.5 w-3.5 shrink-0", strokeWidth: 1 })] }, placeholder.key));
1130
+ }) })] })] }) }));
1131
+ }
1132
+ function ComponentTreeGapInsertControl({ placement, targetKey, activeTargetKey, hoveredTargetKey, onHoverTarget, testId, title, ariaLabel, options, onOpenChange, onSelect, quickInsertComponent, }) {
1133
+ const isActive = activeTargetKey === targetKey;
1134
+ const isHoverVisible = hoveredTargetKey === targetKey;
1135
+ return (_jsxs("div", { className: cn("pointer-events-none absolute right-0 left-0 z-20 flex h-6 items-center justify-center transition-opacity", placement === "above"
1136
+ ? "top-0 -translate-y-[17px]"
1137
+ : "bottom-0 translate-y-[17px]", isActive || isHoverVisible
1138
+ ? "opacity-100"
1139
+ : "opacity-0 focus-within:opacity-100"), "data-testid": `${testId}-gap`, onMouseEnter: () => onHoverTarget?.(targetKey), onMouseLeave: () => onHoverTarget?.(null), children: [_jsx("span", { className: "pointer-events-auto absolute inset-x-0 top-1/2 h-2 -translate-y-1/2", "data-testid": "component-tree-insert-gap-hover-zone", "data-insert-target": targetKey }), _jsx("span", { className: "bg-component-default absolute inset-x-0 top-1/2 h-[2px] -translate-y-1/2 rounded-full", "data-testid": "component-tree-insert-gap-line" }), _jsx(ComponentTreeInsertButton, { targetKey: targetKey, activeTargetKey: activeTargetKey, hoverVisible: isHoverVisible, testId: testId, title: title, ariaLabel: ariaLabel, options: options, onOpenChange: onOpenChange, onSelect: onSelect, quickInsertComponent: quickInsertComponent, className: "relative z-10 h-6 w-6 shrink-0", children: _jsx(Plus, { className: "h-4 w-4", strokeWidth: 1 }) })] }));
1140
+ }
1141
+ function ComponentTreeInsertButton({ targetKey, activeTargetKey, hoverVisible, testId, title, ariaLabel, options, onOpenChange, onSelect, quickInsertComponent, className, children, }) {
1142
+ const isActive = activeTargetKey === targetKey;
1143
+ return (_jsxs(Tooltip, { children: [_jsx(InsertComponentMenu, { open: isActive, onOpenChange: (open) => onOpenChange?.(targetKey, open), title: title, options: options, onSelect: onSelect, side: "right", align: "start", sideOffset: 12, children: _jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", "data-testid": testId, "data-insert-target": targetKey, "data-active": isActive ? "true" : undefined, "aria-label": ariaLabel, onMouseDown: (event) => event.stopPropagation(), onClick: (event) => {
1144
+ event.stopPropagation();
1145
+ if (quickInsertComponent && (event.ctrlKey || event.metaKey)) {
1146
+ event.preventDefault();
1147
+ const matchingOption = getMatchingInsertOption(quickInsertComponent, options);
1148
+ if (matchingOption)
1149
+ onSelect(matchingOption);
1150
+ }
1151
+ }, className: cn("bg-component-default flex items-center justify-center rounded-[4px] text-white transition-all hover:brightness-105 active:scale-95", isActive || hoverVisible
1152
+ ? "pointer-events-auto opacity-100"
1153
+ : "pointer-events-none opacity-0 focus-visible:pointer-events-auto focus-visible:opacity-100", className), children: children }) }) }), _jsx(TooltipContent, { side: "right", sideOffset: 8, children: title })] }));
1154
+ }
1155
+ function getPlaceholderInsertTargetKey(component, placeholder) {
1156
+ return `placeholder:${component.id}:${placeholder.key}`;
1157
+ }
1158
+ function getPlaceholderPickerTargetKey(component) {
1159
+ return `placeholder-picker:${component.id}`;
1160
+ }
1161
+ function cleanComponentTreePlaceholderLabel(placeholder) {
1162
+ return (placeholder.description ||
1163
+ placeholder.name ||
1164
+ placeholder.key).replace(/_{[0-9a-fA-F-]+}$/, "");
1072
1165
  }
1073
- function getMatchingInsertBelowOption(component, insertOptions) {
1166
+ function getMatchingInsertOption(component, insertOptions) {
1074
1167
  const componentTypeId = normalizeInsertTypeId(component.typeId);
1075
1168
  if (!componentTypeId)
1076
1169
  return undefined;