@firecms/core 3.0.0-canary.98 → 3.0.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (349) hide show
  1. package/README.md +2 -2
  2. package/dist/app/Drawer.d.ts +0 -1
  3. package/dist/app/Scaffold.d.ts +4 -0
  4. package/dist/components/ArrayContainer.d.ts +31 -12
  5. package/dist/components/{DeleteConfirmationDialog.d.ts → ConfirmationDialog.d.ts} +1 -1
  6. package/dist/components/EntityCollectionTable/EntityCollectionRowActions.d.ts +3 -1
  7. package/dist/components/EntityCollectionTable/EntityCollectionTable.d.ts +2 -2
  8. package/dist/components/EntityCollectionTable/EntityCollectionTableProps.d.ts +17 -3
  9. package/dist/components/EntityCollectionTable/fields/TableReferenceField.d.ts +1 -1
  10. package/dist/components/EntityCollectionTable/index.d.ts +1 -1
  11. package/dist/components/EntityCollectionTable/internal/popup_field/PopupFormField.d.ts +6 -3
  12. package/dist/components/EntityCollectionView/EntityCollectionView.d.ts +8 -0
  13. package/dist/components/EntityCollectionView/utils.d.ts +3 -0
  14. package/dist/components/EntityJsonPreview.d.ts +3 -0
  15. package/dist/components/EntityPreview.d.ts +8 -6
  16. package/dist/components/HomePage/DefaultHomePage.d.ts +2 -15
  17. package/dist/components/HomePage/HomePageDnD.d.ts +76 -0
  18. package/dist/components/HomePage/NavigationCard.d.ts +3 -1
  19. package/dist/components/HomePage/NavigationCardBinding.d.ts +3 -2
  20. package/dist/components/HomePage/NavigationGroup.d.ts +8 -1
  21. package/dist/components/HomePage/RenameGroupDialog.d.ts +9 -0
  22. package/dist/components/PropertyConfigBadge.d.ts +2 -1
  23. package/dist/components/PropertyIdCopyTooltip.d.ts +8 -0
  24. package/dist/components/SelectableTable/SelectableTable.d.ts +13 -3
  25. package/dist/components/SelectableTable/filters/ReferenceFilterField.d.ts +1 -1
  26. package/dist/components/UnsavedChangesDialog.d.ts +8 -0
  27. package/dist/components/VirtualTable/VirtualTableProps.d.ts +11 -2
  28. package/dist/components/common/default_entity_actions.d.ts +0 -2
  29. package/dist/components/common/index.d.ts +1 -1
  30. package/dist/components/common/useColumnsIds.d.ts +1 -0
  31. package/dist/components/common/{useDataSourceEntityCollectionTableController.d.ts → useDataSourceTableController.d.ts} +10 -2
  32. package/dist/components/common/useDebouncedCallback.d.ts +1 -0
  33. package/dist/components/common/useScrollRestoration.d.ts +14 -0
  34. package/dist/components/index.d.ts +3 -1
  35. package/dist/contexts/BreacrumbsContext.d.ts +8 -0
  36. package/dist/core/DefaultAppBar.d.ts +8 -2
  37. package/dist/core/DrawerNavigationItem.d.ts +2 -1
  38. package/dist/core/EntityEditView.d.ts +40 -22
  39. package/dist/core/EntityEditViewFormActions.d.ts +2 -0
  40. package/dist/core/FireCMS.d.ts +2 -2
  41. package/dist/core/FireCMSRouter.d.ts +4 -0
  42. package/dist/core/NavigationRoutes.d.ts +0 -1
  43. package/dist/core/SideDialogs.d.ts +4 -2
  44. package/dist/core/field_configs.d.ts +1 -1
  45. package/dist/core/index.d.ts +2 -1
  46. package/dist/form/EntityForm.d.ts +50 -0
  47. package/dist/form/EntityFormActions.d.ts +21 -0
  48. package/dist/form/PropertyFieldBinding.d.ts +1 -1
  49. package/dist/form/components/FormEntry.d.ts +6 -0
  50. package/dist/form/components/FormLayout.d.ts +5 -0
  51. package/dist/form/components/LabelWithIcon.d.ts +1 -1
  52. package/dist/form/components/LabelWithIconAndTooltip.d.ts +15 -0
  53. package/dist/form/components/index.d.ts +3 -1
  54. package/dist/form/field_bindings/ArrayCustomShapedFieldBinding.d.ts +1 -1
  55. package/dist/form/field_bindings/ArrayOfReferencesFieldBinding.d.ts +1 -1
  56. package/dist/form/field_bindings/BlockFieldBinding.d.ts +1 -1
  57. package/dist/form/field_bindings/KeyValueFieldBinding.d.ts +1 -1
  58. package/dist/form/field_bindings/MapFieldBinding.d.ts +1 -1
  59. package/dist/form/field_bindings/MarkdownEditorFieldBinding.d.ts +11 -0
  60. package/dist/form/field_bindings/{MultiSelectBinding.d.ts → MultiSelectFieldBinding.d.ts} +1 -1
  61. package/dist/form/field_bindings/ReadOnlyFieldBinding.d.ts +1 -1
  62. package/dist/form/field_bindings/ReferenceAsStringFieldBinding.d.ts +9 -0
  63. package/dist/form/field_bindings/ReferenceFieldBinding.d.ts +2 -2
  64. package/dist/form/field_bindings/RepeatFieldBinding.d.ts +1 -1
  65. package/dist/form/field_bindings/SelectFieldBinding.d.ts +1 -1
  66. package/dist/form/field_bindings/StorageUploadFieldBinding.d.ts +4 -10
  67. package/dist/form/field_bindings/SwitchFieldBinding.d.ts +1 -2
  68. package/dist/form/field_bindings/TextFieldBinding.d.ts +1 -1
  69. package/dist/form/index.d.ts +17 -16
  70. package/dist/form/useClearRestoreValue.d.ts +2 -2
  71. package/dist/hooks/data/delete.d.ts +4 -4
  72. package/dist/hooks/data/save.d.ts +3 -3
  73. package/dist/hooks/data/useCollectionFetch.d.ts +1 -1
  74. package/dist/hooks/data/useEntityFetch.d.ts +4 -3
  75. package/dist/hooks/useAuthController.d.ts +1 -1
  76. package/dist/hooks/useBreadcrumbsController.d.ts +26 -0
  77. package/dist/hooks/useBuildNavigationController.d.ts +57 -12
  78. package/dist/hooks/useFireCMSContext.d.ts +1 -1
  79. package/dist/hooks/useModeController.d.ts +1 -2
  80. package/dist/hooks/useProjectLog.d.ts +7 -1
  81. package/dist/hooks/useResolvedNavigationFrom.d.ts +3 -3
  82. package/dist/hooks/useValidateAuthenticator.d.ts +3 -3
  83. package/dist/index.es.js +20108 -14471
  84. package/dist/index.es.js.map +1 -1
  85. package/dist/index.umd.js +20039 -14407
  86. package/dist/index.umd.js.map +1 -1
  87. package/dist/internal/useBuildDataSource.d.ts +3 -2
  88. package/dist/internal/useBuildSideEntityController.d.ts +3 -3
  89. package/dist/internal/useUnsavedChangesDialog.d.ts +7 -9
  90. package/dist/preview/PropertyPreviewProps.d.ts +1 -1
  91. package/dist/preview/components/EnumValuesChip.d.ts +1 -1
  92. package/dist/preview/components/ReferencePreview.d.ts +2 -2
  93. package/dist/preview/util.d.ts +3 -3
  94. package/dist/routes/CustomCMSRoute.d.ts +4 -0
  95. package/dist/routes/FireCMSRoute.d.ts +1 -0
  96. package/dist/routes/HomePageRoute.d.ts +3 -0
  97. package/dist/types/analytics.d.ts +1 -1
  98. package/dist/types/auth.d.ts +7 -9
  99. package/dist/types/collections.d.ts +86 -25
  100. package/dist/types/customization_controller.d.ts +8 -0
  101. package/dist/types/datasource.d.ts +19 -17
  102. package/dist/types/dialogs_controller.d.ts +7 -3
  103. package/dist/types/entities.d.ts +2 -1
  104. package/dist/types/entity_actions.d.ts +58 -8
  105. package/dist/types/entity_callbacks.d.ts +16 -16
  106. package/dist/types/entity_overrides.d.ts +2 -2
  107. package/dist/types/export_import.d.ts +4 -4
  108. package/dist/types/fields.d.ts +43 -17
  109. package/dist/types/firecms.d.ts +16 -3
  110. package/dist/types/firecms_context.d.ts +1 -1
  111. package/dist/types/navigation.d.ts +60 -17
  112. package/dist/types/permissions.d.ts +4 -4
  113. package/dist/types/plugins.d.ts +42 -9
  114. package/dist/types/properties.d.ts +65 -22
  115. package/dist/types/property_config.d.ts +1 -3
  116. package/dist/types/roles.d.ts +3 -0
  117. package/dist/types/side_dialogs_controller.d.ts +10 -0
  118. package/dist/types/side_entity_controller.d.ts +14 -1
  119. package/dist/types/storage.d.ts +75 -0
  120. package/dist/types/user.d.ts +1 -0
  121. package/dist/util/builders.d.ts +3 -3
  122. package/dist/util/callbacks.d.ts +2 -0
  123. package/dist/util/createFormexStub.d.ts +2 -0
  124. package/dist/util/entities.d.ts +2 -2
  125. package/dist/util/entity_actions.d.ts +2 -0
  126. package/dist/util/entity_cache.d.ts +23 -0
  127. package/dist/util/icon_synonyms.d.ts +0 -1
  128. package/dist/util/icons.d.ts +5 -2
  129. package/dist/util/index.d.ts +3 -0
  130. package/dist/util/navigation_from_path.d.ts +10 -1
  131. package/dist/util/navigation_utils.d.ts +13 -1
  132. package/dist/util/objects.d.ts +2 -1
  133. package/dist/util/permissions.d.ts +4 -4
  134. package/dist/util/property_utils.d.ts +4 -4
  135. package/dist/util/references.d.ts +2 -2
  136. package/dist/util/resolutions.d.ts +30 -6
  137. package/dist/util/storage.d.ts +1 -1
  138. package/dist/util/useStorageUploadController.d.ts +2 -2
  139. package/package.json +133 -125
  140. package/src/app/Drawer.tsx +0 -1
  141. package/src/app/Scaffold.tsx +33 -29
  142. package/src/components/ArrayContainer.tsx +447 -229
  143. package/src/components/CircularProgressCenter.tsx +1 -1
  144. package/src/components/ClearFilterSortButton.tsx +1 -1
  145. package/src/components/{DeleteConfirmationDialog.tsx → ConfirmationDialog.tsx} +12 -11
  146. package/src/components/DeleteEntityDialog.tsx +13 -20
  147. package/src/components/EntityCollectionTable/EntityCollectionRowActions.tsx +59 -25
  148. package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +23 -17
  149. package/src/components/EntityCollectionTable/EntityCollectionTableProps.tsx +20 -3
  150. package/src/components/EntityCollectionTable/PropertyTableCell.tsx +35 -9
  151. package/src/components/EntityCollectionTable/fields/TableReferenceField.tsx +21 -16
  152. package/src/components/EntityCollectionTable/fields/TableStorageUpload.tsx +6 -12
  153. package/src/components/EntityCollectionTable/index.tsx +1 -1
  154. package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +6 -6
  155. package/src/components/EntityCollectionTable/internal/EntityTableCell.tsx +35 -26
  156. package/src/components/EntityCollectionTable/internal/EntityTableCellActions.tsx +20 -8
  157. package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +132 -101
  158. package/src/components/EntityCollectionTable/internal/popup_field/useDraggable.tsx +9 -9
  159. package/src/components/EntityCollectionView/EntityCollectionView.tsx +178 -85
  160. package/src/components/EntityCollectionView/EntityCollectionViewActions.tsx +7 -4
  161. package/src/components/EntityCollectionView/useSelectionController.tsx +5 -4
  162. package/src/components/EntityCollectionView/utils.ts +19 -0
  163. package/src/components/EntityJsonPreview.tsx +66 -0
  164. package/src/components/EntityPreview.tsx +75 -57
  165. package/src/components/EntityView.tsx +8 -5
  166. package/src/components/ErrorView.tsx +3 -3
  167. package/src/components/FireCMSLogo.tsx +7 -51
  168. package/src/components/HomePage/DefaultHomePage.tsx +522 -160
  169. package/src/components/HomePage/FavouritesView.tsx +9 -14
  170. package/src/components/HomePage/HomePageDnD.tsx +642 -0
  171. package/src/components/HomePage/NavigationCard.tsx +47 -38
  172. package/src/components/HomePage/NavigationCardBinding.tsx +16 -15
  173. package/src/components/HomePage/NavigationGroup.tsx +144 -30
  174. package/src/components/HomePage/RenameGroupDialog.tsx +117 -0
  175. package/src/components/HomePage/SmallNavigationCard.tsx +1 -2
  176. package/src/components/NotFoundPage.tsx +2 -2
  177. package/src/components/PropertyConfigBadge.tsx +9 -3
  178. package/src/components/PropertyIdCopyTooltip.tsx +47 -0
  179. package/src/components/ReferenceTable/ReferenceSelectionTable.tsx +22 -13
  180. package/src/components/SearchIconsView.tsx +2 -2
  181. package/src/components/SelectableTable/SelectableTable.tsx +154 -142
  182. package/src/components/SelectableTable/filters/DateTimeFilterField.tsx +4 -2
  183. package/src/components/SelectableTable/filters/ReferenceFilterField.tsx +10 -8
  184. package/src/components/SelectableTable/filters/StringNumberFilterField.tsx +59 -10
  185. package/src/components/UnsavedChangesDialog.tsx +46 -0
  186. package/src/components/VirtualTable/VirtualTable.tsx +65 -44
  187. package/src/components/VirtualTable/VirtualTableCell.tsx +0 -8
  188. package/src/components/VirtualTable/VirtualTableHeader.tsx +8 -8
  189. package/src/components/VirtualTable/VirtualTableHeaderRow.tsx +1 -1
  190. package/src/components/VirtualTable/VirtualTableProps.tsx +12 -2
  191. package/src/components/VirtualTable/VirtualTableRow.tsx +1 -1
  192. package/src/components/VirtualTable/fields/VirtualTableDateField.tsx +4 -4
  193. package/src/components/VirtualTable/fields/VirtualTableInput.tsx +2 -2
  194. package/src/components/VirtualTable/fields/VirtualTableNumberInput.tsx +2 -1
  195. package/src/components/VirtualTable/fields/VirtualTableSelect.tsx +16 -28
  196. package/src/components/common/default_entity_actions.tsx +62 -42
  197. package/src/components/common/index.ts +1 -1
  198. package/src/components/common/useColumnsIds.tsx +1 -1
  199. package/src/components/common/useDataSourceTableController.tsx +420 -0
  200. package/src/components/common/useDebouncedCallback.tsx +20 -0
  201. package/src/components/common/useScrollRestoration.tsx +68 -0
  202. package/src/components/common/useTableSearchHelper.ts +1 -0
  203. package/src/components/index.tsx +4 -1
  204. package/src/contexts/BreacrumbsContext.tsx +38 -0
  205. package/src/contexts/DialogsProvider.tsx +3 -2
  206. package/src/contexts/ModeController.tsx +1 -3
  207. package/src/contexts/SnackbarProvider.tsx +2 -0
  208. package/src/core/DefaultAppBar.tsx +124 -85
  209. package/src/core/DefaultDrawer.tsx +30 -22
  210. package/src/core/DrawerNavigationItem.tsx +32 -28
  211. package/src/core/EntityEditView.tsx +388 -995
  212. package/src/core/EntityEditViewFormActions.tsx +329 -0
  213. package/src/core/EntitySidePanel.tsx +88 -20
  214. package/src/core/FireCMS.tsx +46 -25
  215. package/src/core/FireCMSRouter.tsx +17 -0
  216. package/src/core/NavigationRoutes.tsx +23 -32
  217. package/src/core/SideDialogs.tsx +22 -12
  218. package/src/core/field_configs.tsx +24 -10
  219. package/src/core/index.tsx +4 -2
  220. package/src/form/EntityForm.tsx +814 -0
  221. package/src/form/EntityFormActions.tsx +211 -0
  222. package/src/form/PropertyFieldBinding.tsx +55 -41
  223. package/src/form/components/CustomIdField.tsx +9 -3
  224. package/src/form/components/FieldHelperText.tsx +1 -1
  225. package/src/form/components/FormEntry.tsx +22 -0
  226. package/src/form/components/FormLayout.tsx +16 -0
  227. package/src/form/components/LabelWithIcon.tsx +30 -19
  228. package/src/form/components/LabelWithIconAndTooltip.tsx +28 -0
  229. package/src/form/components/StorageItemPreview.tsx +5 -4
  230. package/src/form/components/StorageUploadProgress.tsx +2 -3
  231. package/src/form/components/index.tsx +3 -1
  232. package/src/form/field_bindings/ArrayCustomShapedFieldBinding.tsx +30 -18
  233. package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +47 -36
  234. package/src/form/field_bindings/BlockFieldBinding.tsx +55 -33
  235. package/src/form/field_bindings/DateTimeFieldBinding.tsx +18 -14
  236. package/src/form/field_bindings/KeyValueFieldBinding.tsx +19 -15
  237. package/src/form/field_bindings/MapFieldBinding.tsx +72 -62
  238. package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +159 -0
  239. package/src/form/field_bindings/{MultiSelectBinding.tsx → MultiSelectFieldBinding.tsx} +26 -21
  240. package/src/form/field_bindings/ReadOnlyFieldBinding.tsx +10 -8
  241. package/src/form/field_bindings/ReferenceAsStringFieldBinding.tsx +135 -0
  242. package/src/form/field_bindings/ReferenceFieldBinding.tsx +28 -19
  243. package/src/form/field_bindings/RepeatFieldBinding.tsx +56 -32
  244. package/src/form/field_bindings/SelectFieldBinding.tsx +22 -13
  245. package/src/form/field_bindings/StorageUploadFieldBinding.tsx +247 -168
  246. package/src/form/field_bindings/SwitchFieldBinding.tsx +29 -24
  247. package/src/form/field_bindings/TextFieldBinding.tsx +28 -24
  248. package/src/form/index.tsx +17 -37
  249. package/src/form/useClearRestoreValue.tsx +2 -2
  250. package/src/form/validation.ts +12 -6
  251. package/src/hooks/data/delete.ts +6 -5
  252. package/src/hooks/data/save.ts +26 -35
  253. package/src/hooks/data/useCollectionFetch.tsx +3 -3
  254. package/src/hooks/data/useDataSource.tsx +10 -2
  255. package/src/hooks/data/useEntityFetch.tsx +10 -6
  256. package/src/hooks/useAuthController.tsx +1 -1
  257. package/src/hooks/useBreadcrumbsController.tsx +31 -0
  258. package/src/hooks/useBrowserTitleAndIcon.tsx +1 -1
  259. package/src/hooks/useBuildModeController.tsx +15 -28
  260. package/src/hooks/useBuildNavigationController.tsx +386 -124
  261. package/src/hooks/useFireCMSContext.tsx +3 -33
  262. package/src/hooks/useLargeLayout.tsx +0 -35
  263. package/src/hooks/useModeController.tsx +1 -2
  264. package/src/hooks/useProjectLog.tsx +16 -5
  265. package/src/hooks/useResolvedNavigationFrom.tsx +9 -11
  266. package/src/hooks/useValidateAuthenticator.tsx +3 -3
  267. package/src/internal/useBuildDataSource.ts +67 -80
  268. package/src/internal/useBuildSideDialogsController.tsx +4 -2
  269. package/src/internal/useBuildSideEntityController.tsx +149 -86
  270. package/src/internal/useUnsavedChangesDialog.tsx +127 -91
  271. package/src/preview/PropertyPreview.tsx +28 -12
  272. package/src/preview/PropertyPreviewProps.tsx +1 -1
  273. package/src/preview/components/BooleanPreview.tsx +1 -1
  274. package/src/preview/components/EmptyValue.tsx +1 -1
  275. package/src/preview/components/EnumValuesChip.tsx +1 -1
  276. package/src/preview/components/ImagePreview.tsx +10 -9
  277. package/src/preview/components/ReferencePreview.tsx +6 -16
  278. package/src/preview/components/UrlComponentPreview.tsx +20 -21
  279. package/src/preview/property_previews/ArrayOfMapsPreview.tsx +6 -5
  280. package/src/preview/property_previews/ArrayOfReferencesPreview.tsx +5 -4
  281. package/src/preview/property_previews/ArrayOfStorageComponentsPreview.tsx +5 -3
  282. package/src/preview/property_previews/ArrayOfStringsPreview.tsx +4 -3
  283. package/src/preview/property_previews/ArrayOneOfPreview.tsx +6 -4
  284. package/src/preview/property_previews/ArrayPropertyPreview.tsx +5 -3
  285. package/src/preview/property_previews/MapPropertyPreview.tsx +7 -6
  286. package/src/preview/property_previews/SkeletonPropertyComponent.tsx +13 -13
  287. package/src/preview/property_previews/StringPropertyPreview.tsx +2 -2
  288. package/src/preview/util.ts +10 -10
  289. package/src/routes/CustomCMSRoute.tsx +21 -0
  290. package/src/routes/FireCMSRoute.tsx +246 -0
  291. package/src/routes/HomePageRoute.tsx +17 -0
  292. package/src/types/analytics.ts +3 -0
  293. package/src/types/auth.tsx +8 -12
  294. package/src/types/collections.ts +101 -28
  295. package/src/types/customization_controller.tsx +9 -0
  296. package/src/types/datasource.ts +21 -20
  297. package/src/types/dialogs_controller.tsx +7 -3
  298. package/src/types/entities.ts +3 -1
  299. package/src/types/entity_actions.tsx +71 -8
  300. package/src/types/entity_callbacks.ts +18 -18
  301. package/src/types/entity_overrides.tsx +2 -2
  302. package/src/types/export_import.ts +4 -4
  303. package/src/types/fields.tsx +52 -19
  304. package/src/types/firecms.tsx +18 -4
  305. package/src/types/firecms_context.tsx +1 -1
  306. package/src/types/navigation.ts +76 -22
  307. package/src/types/permissions.ts +5 -5
  308. package/src/types/plugins.tsx +50 -9
  309. package/src/types/properties.ts +74 -22
  310. package/src/types/property_config.tsx +1 -2
  311. package/src/types/roles.ts +3 -0
  312. package/src/types/side_dialogs_controller.tsx +15 -0
  313. package/src/types/side_entity_controller.tsx +16 -1
  314. package/src/types/storage.ts +82 -0
  315. package/src/types/user.ts +2 -0
  316. package/src/util/builders.ts +10 -8
  317. package/src/util/callbacks.ts +119 -0
  318. package/src/util/createFormexStub.tsx +62 -0
  319. package/src/util/entities.ts +5 -3
  320. package/src/util/entity_actions.ts +28 -0
  321. package/src/util/entity_cache.ts +204 -0
  322. package/src/util/icon_list.ts +1 -1
  323. package/src/util/icon_synonyms.ts +0 -1
  324. package/src/util/icons.tsx +36 -11
  325. package/src/util/index.ts +3 -0
  326. package/src/util/join_collections.ts +9 -2
  327. package/src/util/make_properties_editable.ts +13 -5
  328. package/src/util/navigation_from_path.ts +33 -12
  329. package/src/util/navigation_utils.ts +135 -19
  330. package/src/util/objects.ts +74 -14
  331. package/src/util/parent_references_from_path.ts +3 -3
  332. package/src/util/permissions.ts +8 -8
  333. package/src/util/property_utils.tsx +17 -6
  334. package/src/util/references.ts +19 -8
  335. package/src/util/resolutions.ts +93 -24
  336. package/src/util/storage.ts +6 -2
  337. package/src/util/useStorageUploadController.tsx +74 -29
  338. package/dist/components/EntityCollectionTable/internal/popup_field/ElementResizeListener.d.ts +0 -5
  339. package/dist/components/PropertyIdCopyTooltipContent.d.ts +0 -3
  340. package/dist/form/PropertiesForm.d.ts +0 -8
  341. package/dist/form/components/FormikArrayContainer.d.ts +0 -18
  342. package/dist/form/field_bindings/MarkdownFieldBinding.d.ts +0 -9
  343. package/src/components/EntityCollectionTable/internal/popup_field/ElementResizeListener.tsx +0 -59
  344. package/src/components/PropertyIdCopyTooltipContent.tsx +0 -27
  345. package/src/components/common/useDataSourceEntityCollectionTableController.tsx +0 -236
  346. package/src/form/PropertiesForm.tsx +0 -81
  347. package/src/form/components/FormikArrayContainer.tsx +0 -44
  348. package/src/form/field_bindings/MarkdownFieldBinding.tsx +0 -695
  349. /package/src/util/{common.tsx → common.ts} +0 -0
@@ -1,10 +1,10 @@
1
1
  import { useNavigate } from "react-router-dom";
2
2
  import { useNavigationController } from "../../hooks";
3
3
  import { useUserConfigurationPersistence } from "../../hooks/useUserConfigurationPersistence";
4
- import { TopNavigationEntry } from "../../types";
5
- import { Chip, Collapse, StarBorderIcon, StarIcon } from "@firecms/ui";
4
+ import { NavigationEntry } from "../../types";
5
+ import { Chip, Collapse, StarIcon } from "@firecms/ui";
6
6
 
7
- function NavigationChip({ entry }: { entry: TopNavigationEntry }) {
7
+ function NavigationChip({ entry }: { entry: NavigationEntry }) {
8
8
 
9
9
  const navigate = useNavigate();
10
10
  const userConfigurationPersistence = useUserConfigurationPersistence();
@@ -29,16 +29,11 @@ function NavigationChip({ entry }: { entry: TopNavigationEntry }) {
29
29
  return <Chip
30
30
  key={entry.path}
31
31
  onClick={() => navigate(entry.url)}
32
- icon={
33
- favourite
34
- ? <StarIcon
35
- onClick={onIconClick}
36
- size={18}
37
- className={"text-secondary"}/>
38
- : <StarBorderIcon
39
- onClick={onIconClick}
40
- size={18}
41
- className={"text-gray-400 dark:text-gray-500"}/>}>
32
+ icon={<StarIcon
33
+ onClick={onIconClick}
34
+ size={18}
35
+ className={favourite ? "text-secondary" : "text-surface-400 dark:text-surface-500"}/>
36
+ }>
42
37
  {entry.name}
43
38
  </Chip>;
44
39
  }
@@ -53,7 +48,7 @@ export function FavouritesView({ hidden }: { hidden: boolean }) {
53
48
 
54
49
  const favouriteCollections = (userConfigurationPersistence?.favouritePaths ?? [])
55
50
  .map((path) => navigationController.topLevelNavigation?.navigationEntries.find((entry) => entry.path === path))
56
- .filter(Boolean) as TopNavigationEntry[];
51
+ .filter(Boolean) as NavigationEntry[];
57
52
 
58
53
  return <Collapse in={favouriteCollections.length > 0}>
59
54
  <div className="flex flex-row flex-wrap gap-2 pb-2 min-h-[32px]">
@@ -0,0 +1,642 @@
1
+ import React, { useCallback, useEffect, useRef, useState } from "react";
2
+ import {
3
+ Active,
4
+ closestCenter,
5
+ closestCorners,
6
+ CollisionDetection,
7
+ DropAnimation,
8
+ getFirstCollision,
9
+ KeyboardSensor,
10
+ MouseSensor,
11
+ pointerWithin,
12
+ rectIntersection,
13
+ TouchSensor,
14
+ UniqueIdentifier,
15
+ useDndMonitor,
16
+ useDroppable,
17
+ useSensor,
18
+ useSensors
19
+ } from "@dnd-kit/core";
20
+ import {
21
+ AnimateLayoutChanges,
22
+ arrayMove,
23
+ defaultAnimateLayoutChanges,
24
+ rectSortingStrategy,
25
+ SortableContext,
26
+ useSortable
27
+ } from "@dnd-kit/sortable";
28
+ import { CSS } from "@dnd-kit/utilities";
29
+
30
+ import { NavigationCardBinding } from "./NavigationCardBinding";
31
+ import { NavigationEntry } from "../../types";
32
+ import { cls } from "@firecms/ui";
33
+
34
+ const animateLayoutChanges: AnimateLayoutChanges = (args) =>
35
+ defaultAnimateLayoutChanges({
36
+ ...args,
37
+ wasDragging: true
38
+ });
39
+
40
+ const dropAnimationConfig: DropAnimation = {};
41
+
42
+ const cloneSerializableNavigationEntry = (entry: NavigationEntry): NavigationEntry => {
43
+ const clonedEntry: Partial<NavigationEntry> = {
44
+ id: entry.id,
45
+ path: entry.path,
46
+ url: entry.url,
47
+ name: entry.name,
48
+ type: entry.type,
49
+ collection: entry.collection ? { ...entry.collection } : undefined,
50
+ view: entry.view ? { ...entry.view } : undefined,
51
+ ...(entry.group && { group: entry.group }),
52
+ ...(entry.description && { description: entry.description })
53
+ };
54
+ return clonedEntry as NavigationEntry;
55
+ };
56
+
57
+ const cloneItemsForDnd = (items: { name: string; entries: NavigationEntry[] }[]) =>
58
+ items.map((g) => ({
59
+ name: g.name,
60
+ entries: g.entries.map(cloneSerializableNavigationEntry)
61
+ }));
62
+
63
+ /* ─────────────────────────────────────────────────────────── */
64
+ /* Sortable card & group */
65
+
66
+ /* ─────────────────────────────────────────────────────────── */
67
+ export function SortableNavigationCard({
68
+ entry,
69
+ onClick
70
+ }: {
71
+ entry: NavigationEntry;
72
+ onClick?: () => void;
73
+ }) {
74
+ const {
75
+ setNodeRef,
76
+ listeners,
77
+ attributes,
78
+ transform,
79
+ transition,
80
+ isDragging
81
+ } =
82
+ useSortable({
83
+ id: entry.url,
84
+ animateLayoutChanges
85
+ });
86
+
87
+ const style = {
88
+ transform: transform ? CSS.Transform.toString(transform) : undefined,
89
+ transition,
90
+ opacity: isDragging ? 0 : 1
91
+ };
92
+
93
+ return (
94
+ <div ref={setNodeRef} style={style} {...attributes} {...listeners}>
95
+ <NavigationCardBinding {...entry} onClick={onClick}/>
96
+ </div>
97
+ );
98
+ }
99
+
100
+ export function NavigationGroupDroppable({
101
+ id,
102
+ itemIds,
103
+ children,
104
+ isPotentialCardDropTarget = false
105
+ }: {
106
+ id: UniqueIdentifier;
107
+ itemIds: UniqueIdentifier[];
108
+ children: React.ReactNode;
109
+ isPotentialCardDropTarget?: boolean;
110
+ }) {
111
+ const { setNodeRef } = useDroppable({ id });
112
+
113
+ return (
114
+ <div
115
+ ref={setNodeRef}
116
+ className={cls(
117
+ isPotentialCardDropTarget
118
+ ? "p-2 bg-surface-accent-200 dark:bg-surface-accent-800 rounded-lg"
119
+ : undefined,
120
+ "transition-all duration-200 ease-in-out"
121
+ )}
122
+ >
123
+ <SortableContext items={itemIds} strategy={rectSortingStrategy}>
124
+ {children}
125
+ </SortableContext>
126
+ </div>
127
+ );
128
+ }
129
+
130
+ export function SortableNavigationGroup({
131
+ groupName,
132
+ children,
133
+ disabled
134
+ }: {
135
+ groupName: string;
136
+ children: React.ReactNode;
137
+ disabled?: boolean;
138
+ }) {
139
+ const {
140
+ attributes,
141
+ listeners,
142
+ setNodeRef,
143
+ transform,
144
+ transition,
145
+ isDragging
146
+ } =
147
+ useSortable({
148
+ id: groupName,
149
+ animateLayoutChanges,
150
+ disabled
151
+ });
152
+
153
+ const style = {
154
+ transform: transform ? CSS.Transform.toString(transform) : undefined,
155
+ transition,
156
+ opacity: isDragging ? 0 : 1
157
+ };
158
+
159
+ return (
160
+ <div ref={setNodeRef} style={style} {...attributes} {...listeners}>
161
+ {children}
162
+ </div>
163
+ );
164
+ }
165
+
166
+ /* ─────────────────────────────────────────────────────────── */
167
+ /* Main DnD hook */
168
+
169
+ /* ─────────────────────────────────────────────────────────── */
170
+ export function useHomePageDnd({
171
+ items: dndItems,
172
+ setItems: setDndItems,
173
+ disabled,
174
+ onCardMovedBetweenGroups,
175
+ onGroupMoved,
176
+ onNewGroupDrop,
177
+ onPersist
178
+ }: {
179
+ items: { name: string; entries: NavigationEntry[] }[];
180
+ setItems: (
181
+ newItemsOrUpdater:
182
+ | { name: string; entries: NavigationEntry[] }[]
183
+ | ((
184
+ currentItems: { name: string; entries: NavigationEntry[] }[]
185
+ ) => { name: string; entries: NavigationEntry[] }[])
186
+ ) => void;
187
+ disabled: boolean;
188
+ onCardMovedBetweenGroups?: (card: NavigationEntry) => void;
189
+ onGroupMoved?: (groupName: string, oldIndex: number, newIndex: number) => void;
190
+ onNewGroupDrop?: () => void;
191
+ onPersist?: (latest: { name: string; entries: NavigationEntry[] }[]) => void;
192
+ }) {
193
+ /* ---------------- local state ---------------- */
194
+ const [activeId, setActiveId] = useState<UniqueIdentifier | null>(null);
195
+ const [activeIsGroup, setActiveIsGroup] = useState(false);
196
+ const [currentDraggingGroupId, setCurrentDraggingGroupId] =
197
+ useState<UniqueIdentifier | null>(null);
198
+ const [dndKitActiveNode, setDndKitActiveNode] = useState<Active | null>(null);
199
+ const [isDraggingCardOnly, setIsDraggingCardOnly] = useState(false);
200
+ const [dialogOpenForGroup, setDialogOpenForGroup] = useState<string | null>(null);
201
+ const [isHoveringNewGroupDropZone, setIsHoveringNewGroupDropZone] =
202
+ useState(false);
203
+
204
+ /* store interim state for cross-group moves */
205
+ const interimItemsRef = useRef<
206
+ { name: string; entries: NavigationEntry[] }[] | null
207
+ >(null);
208
+ useEffect(() => {
209
+ interimItemsRef.current = dndItems;
210
+ }, [dndItems]);
211
+
212
+ /* ---------------- sensors ---------------- */
213
+ const mouseSensor = useSensor(MouseSensor, { activationConstraint: { distance: 10 } });
214
+ const touchSensor = useSensor(TouchSensor, {
215
+ activationConstraint: {
216
+ delay: 150,
217
+ tolerance: 5
218
+ }
219
+ });
220
+ const keyboardSensor = useSensor(KeyboardSensor);
221
+ const sensors = useSensors(mouseSensor, touchSensor, keyboardSensor);
222
+
223
+ /* ---------------- helpers ---------------- */
224
+ const dndContainers = dndItems.map((g) => g.name);
225
+
226
+ const findDndContainer = useCallback(
227
+ (id: UniqueIdentifier): string | undefined => {
228
+ if (!id) return undefined;
229
+ const group = dndItems.find((g) => g.name === id);
230
+ if (group) return group.name;
231
+ for (const g of dndItems) {
232
+ if (g.entries.some((e) => e.url === id)) return g.name;
233
+ }
234
+ return undefined;
235
+ },
236
+ [dndItems]
237
+ );
238
+
239
+ /* ---------------- collision detection ---------------- */
240
+ const lastOverId = useRef<UniqueIdentifier | null>(null);
241
+ const recentlyMovedToNewContainer = useRef(false);
242
+
243
+ const collisionDetection: CollisionDetection = useCallback(
244
+ (args) => {
245
+ if (disabled || !activeId) return [];
246
+
247
+ if (activeIsGroup) {
248
+ const groups = args.droppableContainers.filter((c) =>
249
+ dndItems.some((g) => g.name === c.id)
250
+ );
251
+ if (!groups.length) return [];
252
+
253
+ // Special handling for dropping at the very beginning (first position)
254
+ if (groups.length > 0) {
255
+ const firstGroup = groups[0];
256
+ const firstGroupRect = firstGroup.rect.current;
257
+ const { x, y } = args.pointerCoordinates || { x: 0, y: 0 };
258
+
259
+ // If pointer is above the first group's top edge, treat it as dropping at position 0
260
+ if (firstGroupRect && y < firstGroupRect.top + 20) {
261
+ // Return the first group as target, but we'll handle this specially in onDragEnd
262
+ return [{ id: firstGroup.id, data: { insertBefore: true } }];
263
+ }
264
+ }
265
+
266
+ // Use closestCorners for better collision detection with collapsed groups
267
+ // This provides more precise drop zones between groups
268
+ const cornersResult = closestCorners({
269
+ ...args,
270
+ droppableContainers: groups
271
+ });
272
+
273
+ if (cornersResult.length) {
274
+ return cornersResult;
275
+ }
276
+
277
+ // Fallback to closestCenter if corners detection fails
278
+ return closestCenter({
279
+ ...args,
280
+ droppableContainers: groups
281
+ });
282
+ }
283
+
284
+ const pointer = pointerWithin(args);
285
+ if (pointer.length) {
286
+ const zone = pointer.find((c) => c.id === "new-group-drop-zone");
287
+ if (zone) return [zone];
288
+
289
+ const container = pointer.find((c) =>
290
+ dndItems.some((g) => g.name === c.id)
291
+ );
292
+ if (container) {
293
+ const itemsIn = dndItems.find((g) => g.name === container.id)
294
+ ?.entries;
295
+ if (itemsIn?.length) {
296
+ const closest = closestCorners({
297
+ ...args,
298
+ droppableContainers: args.droppableContainers.filter(
299
+ (c) => itemsIn.some((e) => e.url === c.id)
300
+ )
301
+ });
302
+ if (closest.length) return closest;
303
+ }
304
+ return [container];
305
+ }
306
+ const first = getFirstCollision(pointer, "id");
307
+ if (first) return [{ id: first }];
308
+ }
309
+
310
+ const rects = rectIntersection(args);
311
+ const zoneRect = rects.find((c) => c.id === "new-group-drop-zone");
312
+ if (zoneRect) return [zoneRect];
313
+
314
+ let overId = getFirstCollision(rects, "id");
315
+ if (overId != null) {
316
+ const overIsContainer = dndItems.some((g) => g.name === overId);
317
+ if (overIsContainer) {
318
+ const itemsIn = dndItems.find((g) => g.name === overId)
319
+ ?.entries;
320
+ if (itemsIn?.length) {
321
+ const closestItem = closestCorners({
322
+ ...args,
323
+ droppableContainers: args.droppableContainers.filter(
324
+ (c) => itemsIn.some((e) => e.url === c.id)
325
+ )
326
+ })[0]?.id;
327
+ if (closestItem) overId = closestItem;
328
+ }
329
+ }
330
+ lastOverId.current = overId;
331
+ return [{ id: overId }];
332
+ }
333
+
334
+ if (
335
+ recentlyMovedToNewContainer.current &&
336
+ lastOverId.current &&
337
+ !activeIsGroup
338
+ )
339
+ return [{ id: lastOverId.current }];
340
+
341
+ return [];
342
+ },
343
+ [activeId, dndItems, disabled, activeIsGroup]
344
+ );
345
+
346
+ /* ---------------- drag handlers ---------------- */
347
+ const handleDragStart = ({ active }: { active: Active }) => {
348
+ setDndKitActiveNode(active);
349
+ if (disabled) return;
350
+
351
+ const isGroup = dndItems.some((g) => g.name === active.id);
352
+ if (!active.data.current) active.data.current = {};
353
+ active.data.current.type = isGroup ? "group" : "item";
354
+
355
+ setActiveId(active.id);
356
+ setActiveIsGroup(isGroup);
357
+ setIsDraggingCardOnly(!isGroup);
358
+ if (isGroup) setCurrentDraggingGroupId(active.id);
359
+ recentlyMovedToNewContainer.current = false;
360
+ };
361
+
362
+ const handleDragOver = ({
363
+ active,
364
+ over
365
+ }: { active: Active; over: any }) => {
366
+ if (disabled || !over) return;
367
+
368
+ const activeIdNow = active.id;
369
+ const overIdNow = over.id;
370
+ if (activeIdNow === overIdNow) return;
371
+ if (activeIsGroup) return;
372
+
373
+ const activeCont = findDndContainer(activeIdNow);
374
+ const overCont = findDndContainer(overIdNow);
375
+ if (!activeCont) return;
376
+
377
+ if (overCont && activeCont !== overCont) {
378
+ recentlyMovedToNewContainer.current = true;
379
+ const newState = cloneItemsForDnd(dndItems);
380
+ const srcIdx = newState.findIndex((g) => g.name === activeCont);
381
+ const tgtIdx = newState.findIndex((g) => g.name === overCont);
382
+ if (srcIdx === -1 || tgtIdx === -1) return;
383
+ const src = newState[srcIdx];
384
+ const tgt = newState[tgtIdx];
385
+ const idxInSrc = src.entries.findIndex((e) => e.url === activeIdNow);
386
+ if (idxInSrc === -1) return;
387
+ const [moved] = src.entries.splice(idxInSrc, 1);
388
+ tgt.entries.push(moved);
389
+ interimItemsRef.current = newState;
390
+ setDndItems(newState);
391
+ } else if (activeCont === overCont) {
392
+ recentlyMovedToNewContainer.current = false;
393
+ }
394
+ };
395
+
396
+ const handleDragEnd = ({
397
+ active,
398
+ over
399
+ }: { active: Active; over: any }) => {
400
+ if (disabled || !over) {
401
+ resetDragState();
402
+ return;
403
+ }
404
+
405
+ const activeIdNow = active.id;
406
+ const overIdNow = over.id;
407
+
408
+ /* ─── group reorder ─── */
409
+ if (activeIsGroup) {
410
+ // Check if we're dropping above the first group (insertBefore flag)
411
+ const insertBefore = over.data?.current?.insertBefore;
412
+
413
+ if (insertBefore && activeIdNow !== overIdNow) {
414
+ // Move to first position (before the target group)
415
+ const from = dndItems.findIndex((g) => g.name === activeIdNow);
416
+ if (from !== -1 && from !== 0) {
417
+ const newState = arrayMove(dndItems, from, 0);
418
+ setDndItems(newState);
419
+ onPersist?.(newState);
420
+ onGroupMoved?.(activeIdNow as string, from, 0);
421
+ }
422
+ }
423
+ // Handle dropping on another group (normal case)
424
+ else if (
425
+ activeIdNow !== overIdNow &&
426
+ dndItems.some((g) => g.name === overIdNow)
427
+ ) {
428
+ const from = dndItems.findIndex((g) => g.name === activeIdNow);
429
+ const to = dndItems.findIndex((g) => g.name === overIdNow);
430
+ if (from !== -1 && to !== -1) {
431
+ const newState = arrayMove(dndItems, from, to);
432
+ setDndItems(newState);
433
+ onPersist?.(newState);
434
+ onGroupMoved?.(activeIdNow as string, from, to);
435
+ }
436
+ }
437
+ }
438
+ /* ─── card move ─── */
439
+ else {
440
+ const activeCont = findDndContainer(activeIdNow);
441
+
442
+ /* drop on new-group zone */
443
+ if (overIdNow === "new-group-drop-zone") {
444
+ if (activeCont) {
445
+ const newState = cloneItemsForDnd(dndItems);
446
+ const srcIdx = newState.findIndex((g) => g.name === activeCont);
447
+ if (srcIdx !== -1) {
448
+ const src = newState[srcIdx];
449
+ const idxInSrc = src.entries.findIndex(
450
+ (e) => e.url === activeIdNow
451
+ );
452
+ if (idxInSrc !== -1) {
453
+ const [dragged] = src.entries.splice(idxInSrc, 1);
454
+ if (src.entries.length === 0) newState.splice(srcIdx, 1);
455
+
456
+ let tentative = "New Group";
457
+ let counter = 1;
458
+ while (newState.some((g) => g.name === tentative))
459
+ tentative = `New Group ${counter++}`;
460
+
461
+ newState.push({
462
+ name: tentative,
463
+ entries: [dragged]
464
+ });
465
+ setDndItems(newState);
466
+ onPersist?.(newState);
467
+ setDialogOpenForGroup(tentative);
468
+ onNewGroupDrop?.();
469
+ }
470
+ }
471
+ }
472
+ }
473
+ /* reorder inside same container */
474
+ else {
475
+ const overCont = findDndContainer(overIdNow);
476
+ if (activeCont === overCont) {
477
+ const grpIdx = dndItems.findIndex((g) => g.name === activeCont);
478
+ if (grpIdx !== -1) {
479
+ const group = dndItems[grpIdx];
480
+ const oldIdx = group.entries.findIndex(
481
+ (e) => e.url === activeIdNow
482
+ );
483
+ let newIdx = group.entries.findIndex(
484
+ (e) => e.url === overIdNow
485
+ );
486
+ if (newIdx === -1 && overIdNow === activeCont)
487
+ newIdx = group.entries.length - 1;
488
+ if (
489
+ oldIdx !== -1 &&
490
+ newIdx !== -1 &&
491
+ oldIdx !== newIdx
492
+ ) {
493
+ const reordered = arrayMove(group.entries, oldIdx, newIdx);
494
+ const newState = [...dndItems];
495
+ newState[grpIdx] = {
496
+ ...group,
497
+ entries: reordered
498
+ };
499
+ setDndItems(newState);
500
+ onPersist?.(newState);
501
+ }
502
+ }
503
+ } else if (
504
+ recentlyMovedToNewContainer.current &&
505
+ interimItemsRef.current
506
+ ) {
507
+ onPersist?.(interimItemsRef.current);
508
+ }
509
+
510
+ onCardMovedBetweenGroups?.(
511
+ dndItems
512
+ .flatMap((g) => g.entries)
513
+ .find((e) => e.url === activeIdNow)!
514
+ );
515
+ }
516
+ }
517
+
518
+ resetDragState();
519
+ };
520
+
521
+ const resetDragState = () => {
522
+ setDndKitActiveNode(null);
523
+ setActiveId(null);
524
+ setActiveIsGroup(false);
525
+ setCurrentDraggingGroupId(null);
526
+ setIsDraggingCardOnly(false);
527
+ recentlyMovedToNewContainer.current = false;
528
+ };
529
+
530
+ const handleDragCancel = () => {
531
+ resetDragState();
532
+ };
533
+
534
+ /* ---------------- group rename ---------------- */
535
+ const handleRenameGroup = (oldName: string, newName: string) => {
536
+ setDndItems((current) => {
537
+ const idx = current.findIndex((g) => g.name === oldName);
538
+ if (idx === -1) return current;
539
+ if (current.some((g) => g.name === newName && g.name !== oldName))
540
+ return current;
541
+
542
+ const updated = [...current];
543
+ updated[idx] = {
544
+ ...updated[idx],
545
+ name: newName
546
+ };
547
+ onPersist?.(updated); // <- ensure rename is saved
548
+ return updated;
549
+ });
550
+ };
551
+
552
+ /* ---------------- public API ---------------- */
553
+ const activeItemForOverlay =
554
+ disabled || !activeId || activeIsGroup
555
+ ? null
556
+ : dndItems.flatMap((g) => g.entries).find((e) => e.url === activeId) || null;
557
+
558
+ const activeGroupData =
559
+ disabled || !activeId || !activeIsGroup
560
+ ? null
561
+ : dndItems.find((g) => g.name === activeId) || null;
562
+
563
+ return {
564
+ sensors,
565
+ collisionDetection,
566
+ onDragStart: handleDragStart,
567
+ onDragOver: handleDragOver,
568
+ onDragEnd: handleDragEnd,
569
+ onDragCancel: handleDragCancel,
570
+ dropAnimation: dropAnimationConfig,
571
+ activeItemForOverlay,
572
+ activeGroupData,
573
+ draggingGroupId: currentDraggingGroupId,
574
+ containers: dndContainers,
575
+ dndKitActiveNode,
576
+ isDraggingCardOnly,
577
+ dialogOpenForGroup,
578
+ setDialogOpenForGroup,
579
+ handleRenameGroup,
580
+ isHoveringNewGroupDropZone,
581
+ setIsHoveringNewGroupDropZone
582
+ };
583
+ }
584
+
585
+ /* ─────────────────────────────────────────────────────────── */
586
+ /* New-group drop-zone component */
587
+
588
+ /* ─────────────────────────────────────────────────────────── */
589
+ export function NewGroupDropZone({
590
+ disabled,
591
+ setIsHovering
592
+ }: {
593
+ disabled: boolean;
594
+ setIsHovering: (v: boolean) => void;
595
+ }) {
596
+ const {
597
+ setNodeRef,
598
+ isOver
599
+ } = useDroppable({
600
+ id: "new-group-drop-zone",
601
+ disabled
602
+ });
603
+ const [isVisible, setIsVisible] = useState(false);
604
+
605
+ useDndMonitor({
606
+ onDragStart({ active }) {
607
+ if (disabled) return;
608
+ const tp = active.data.current?.type;
609
+ setIsVisible(tp === "item");
610
+ },
611
+ onDragEnd() {
612
+ setIsVisible(false);
613
+ },
614
+ onDragCancel() {
615
+ setIsVisible(false);
616
+ }
617
+ });
618
+
619
+ useEffect(() => {
620
+ setIsHovering(isOver && isVisible);
621
+ }, [isOver, isVisible, setIsHovering]);
622
+
623
+ if (!isVisible || disabled) return null;
624
+
625
+ return (
626
+ <div
627
+ ref={setNodeRef}
628
+ className={cls(
629
+ "fixed right-8 top-1/2 -translate-y-1/2 w-[200px] h-[120px] border border-dashed rounded-lg flex items-center justify-center transition-all",
630
+ isOver
631
+ ? "bg-surface-accent-100 dark:bg-surface-accent-800 border-surface-300 dark:border-surface-600"
632
+ : "bg-surface-50 dark:bg-surface-900 border-surface-200 dark:border-surface-700"
633
+ )}
634
+ >
635
+ <div className="text-center p-4">
636
+ <span className="block font-medium text-sm">
637
+ Drop here to create a new group
638
+ </span>
639
+ </div>
640
+ </div>
641
+ );
642
+ }