@strapi/upload 5.59.0 → 5.61.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (295) hide show
  1. package/dist/admin/components/AssetPickerDialog/AssetPickerDialog.js +434 -0
  2. package/dist/admin/components/AssetPickerDialog/AssetPickerDialog.js.map +1 -0
  3. package/dist/admin/components/AssetPickerDialog/AssetPickerDialog.mjs +432 -0
  4. package/dist/admin/components/AssetPickerDialog/AssetPickerDialog.mjs.map +1 -0
  5. package/dist/admin/components/AssetPickerDialog/FolderBreadcrumbs.js +91 -0
  6. package/dist/admin/components/AssetPickerDialog/FolderBreadcrumbs.js.map +1 -0
  7. package/dist/admin/components/AssetPickerDialog/FolderBreadcrumbs.mjs +89 -0
  8. package/dist/admin/components/AssetPickerDialog/FolderBreadcrumbs.mjs.map +1 -0
  9. package/dist/admin/components/AssetPickerDialog/MediaLibraryPickerDialog.js +29 -0
  10. package/dist/admin/components/AssetPickerDialog/MediaLibraryPickerDialog.js.map +1 -0
  11. package/dist/admin/components/AssetPickerDialog/MediaLibraryPickerDialog.mjs +27 -0
  12. package/dist/admin/components/AssetPickerDialog/MediaLibraryPickerDialog.mjs.map +1 -0
  13. package/dist/admin/components/AssetPickerDialog/PickerSelectionProvider.js +178 -0
  14. package/dist/admin/components/AssetPickerDialog/PickerSelectionProvider.js.map +1 -0
  15. package/dist/admin/components/AssetPickerDialog/PickerSelectionProvider.mjs +175 -0
  16. package/dist/admin/components/AssetPickerDialog/PickerSelectionProvider.mjs.map +1 -0
  17. package/dist/admin/components/AssetPickerDialog/SortableSelection.js +143 -0
  18. package/dist/admin/components/AssetPickerDialog/SortableSelection.js.map +1 -0
  19. package/dist/admin/components/AssetPickerDialog/SortableSelection.mjs +141 -0
  20. package/dist/admin/components/AssetPickerDialog/SortableSelection.mjs.map +1 -0
  21. package/dist/admin/components/AssetPickerDialog/pickerSelection.js +49 -0
  22. package/dist/admin/components/AssetPickerDialog/pickerSelection.js.map +1 -0
  23. package/dist/admin/components/AssetPickerDialog/pickerSelection.mjs +41 -0
  24. package/dist/admin/components/AssetPickerDialog/pickerSelection.mjs.map +1 -0
  25. package/dist/admin/components/Drawer.js +12 -7
  26. package/dist/admin/components/Drawer.js.map +1 -1
  27. package/dist/admin/components/Drawer.mjs +12 -7
  28. package/dist/admin/components/Drawer.mjs.map +1 -1
  29. package/dist/admin/components/EditorFileDropZone/EditorFileDropZone.js +188 -0
  30. package/dist/admin/components/EditorFileDropZone/EditorFileDropZone.js.map +1 -0
  31. package/dist/admin/components/EditorFileDropZone/EditorFileDropZone.mjs +186 -0
  32. package/dist/admin/components/EditorFileDropZone/EditorFileDropZone.mjs.map +1 -0
  33. package/dist/admin/components/MediaLibraryInput/AddAssetMenu.js +9 -4
  34. package/dist/admin/components/MediaLibraryInput/AddAssetMenu.js.map +1 -1
  35. package/dist/admin/components/MediaLibraryInput/AddAssetMenu.mjs +9 -4
  36. package/dist/admin/components/MediaLibraryInput/AddAssetMenu.mjs.map +1 -1
  37. package/dist/admin/components/MediaLibraryInput/AssetCard.js +240 -0
  38. package/dist/admin/components/MediaLibraryInput/AssetCard.js.map +1 -0
  39. package/dist/admin/components/MediaLibraryInput/AssetCard.mjs +237 -0
  40. package/dist/admin/components/MediaLibraryInput/AssetCard.mjs.map +1 -0
  41. package/dist/admin/components/MediaLibraryInput/AssetCarousel.js +161 -0
  42. package/dist/admin/components/MediaLibraryInput/AssetCarousel.js.map +1 -0
  43. package/dist/admin/components/MediaLibraryInput/AssetCarousel.mjs +159 -0
  44. package/dist/admin/components/MediaLibraryInput/AssetCarousel.mjs.map +1 -0
  45. package/dist/admin/components/MediaLibraryInput/AssetDropZone.js +76 -49
  46. package/dist/admin/components/MediaLibraryInput/AssetDropZone.js.map +1 -1
  47. package/dist/admin/components/MediaLibraryInput/AssetDropZone.mjs +77 -50
  48. package/dist/admin/components/MediaLibraryInput/AssetDropZone.mjs.map +1 -1
  49. package/dist/admin/components/MediaLibraryInput/AssetPreview.js +109 -0
  50. package/dist/admin/components/MediaLibraryInput/AssetPreview.js.map +1 -0
  51. package/dist/admin/components/MediaLibraryInput/AssetPreview.mjs +106 -0
  52. package/dist/admin/components/MediaLibraryInput/AssetPreview.mjs.map +1 -0
  53. package/dist/admin/components/MediaLibraryInput/AssetRow.js +146 -79
  54. package/dist/admin/components/MediaLibraryInput/AssetRow.js.map +1 -1
  55. package/dist/admin/components/MediaLibraryInput/AssetRow.mjs +148 -82
  56. package/dist/admin/components/MediaLibraryInput/AssetRow.mjs.map +1 -1
  57. package/dist/admin/components/MediaLibraryInput/FieldControls.js +32 -0
  58. package/dist/admin/components/MediaLibraryInput/FieldControls.js.map +1 -0
  59. package/dist/admin/components/MediaLibraryInput/FieldControls.mjs +29 -0
  60. package/dist/admin/components/MediaLibraryInput/FieldControls.mjs.map +1 -0
  61. package/dist/admin/components/MediaLibraryInput/MediaLibraryInput.js +163 -111
  62. package/dist/admin/components/MediaLibraryInput/MediaLibraryInput.js.map +1 -1
  63. package/dist/admin/components/MediaLibraryInput/MediaLibraryInput.mjs +162 -114
  64. package/dist/admin/components/MediaLibraryInput/MediaLibraryInput.mjs.map +1 -1
  65. package/dist/admin/components/MediaLibraryInput/UploadProgressBar.js +42 -0
  66. package/dist/admin/components/MediaLibraryInput/UploadProgressBar.js.map +1 -0
  67. package/dist/admin/components/MediaLibraryInput/UploadProgressBar.mjs +40 -0
  68. package/dist/admin/components/MediaLibraryInput/UploadProgressBar.mjs.map +1 -0
  69. package/dist/admin/components/MediaLibraryInput/openAssetDetails.js +46 -0
  70. package/dist/admin/components/MediaLibraryInput/openAssetDetails.js.map +1 -0
  71. package/dist/admin/components/MediaLibraryInput/openAssetDetails.mjs +43 -0
  72. package/dist/admin/components/MediaLibraryInput/openAssetDetails.mjs.map +1 -0
  73. package/dist/admin/components/MediaLibraryInput/useFieldUploads.js +122 -0
  74. package/dist/admin/components/MediaLibraryInput/useFieldUploads.js.map +1 -0
  75. package/dist/admin/components/MediaLibraryInput/useFieldUploads.mjs +120 -0
  76. package/dist/admin/components/MediaLibraryInput/useFieldUploads.mjs.map +1 -0
  77. package/dist/admin/components/UploadProgressDialog.js +2 -1
  78. package/dist/admin/components/UploadProgressDialog.js.map +1 -1
  79. package/dist/admin/components/UploadProgressDialog.mjs +2 -1
  80. package/dist/admin/components/UploadProgressDialog.mjs.map +1 -1
  81. package/dist/admin/hooks/useMediaLibraryPermissions.js +12 -2
  82. package/dist/admin/hooks/useMediaLibraryPermissions.js.map +1 -1
  83. package/dist/admin/hooks/useMediaLibraryPermissions.mjs +12 -2
  84. package/dist/admin/hooks/useMediaLibraryPermissions.mjs.map +1 -1
  85. package/dist/admin/index.js +10 -1
  86. package/dist/admin/index.js.map +1 -1
  87. package/dist/admin/index.mjs +10 -1
  88. package/dist/admin/index.mjs.map +1 -1
  89. package/dist/admin/pages/Assets/AssetsPage.js +14 -303
  90. package/dist/admin/pages/Assets/AssetsPage.js.map +1 -1
  91. package/dist/admin/pages/Assets/AssetsPage.mjs +13 -282
  92. package/dist/admin/pages/Assets/AssetsPage.mjs.map +1 -1
  93. package/dist/admin/pages/Assets/components/AssetDetails/AssetCropEditor.mjs +2 -2
  94. package/dist/admin/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js +181 -65
  95. package/dist/admin/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js.map +1 -1
  96. package/dist/admin/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs +184 -69
  97. package/dist/admin/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs.map +1 -1
  98. package/dist/admin/pages/Assets/components/AssetDetails/AssetPreview.mjs +1 -1
  99. package/dist/admin/pages/Assets/components/AssetsGrid.js +142 -31
  100. package/dist/admin/pages/Assets/components/AssetsGrid.js.map +1 -1
  101. package/dist/admin/pages/Assets/components/AssetsGrid.mjs +145 -34
  102. package/dist/admin/pages/Assets/components/AssetsGrid.mjs.map +1 -1
  103. package/dist/admin/pages/Assets/components/AssetsSearchInput.js +43 -2
  104. package/dist/admin/pages/Assets/components/AssetsSearchInput.js.map +1 -1
  105. package/dist/admin/pages/Assets/components/AssetsSearchInput.mjs +45 -4
  106. package/dist/admin/pages/Assets/components/AssetsSearchInput.mjs.map +1 -1
  107. package/dist/admin/pages/Assets/components/AssetsTable.js +58 -34
  108. package/dist/admin/pages/Assets/components/AssetsTable.js.map +1 -1
  109. package/dist/admin/pages/Assets/components/AssetsTable.mjs +60 -36
  110. package/dist/admin/pages/Assets/components/AssetsTable.mjs.map +1 -1
  111. package/dist/admin/pages/Assets/components/AssetsView.js +145 -0
  112. package/dist/admin/pages/Assets/components/AssetsView.js.map +1 -0
  113. package/dist/admin/pages/Assets/components/AssetsView.mjs +143 -0
  114. package/dist/admin/pages/Assets/components/AssetsView.mjs.map +1 -0
  115. package/dist/admin/pages/Assets/components/BulkActionsBar.mjs +1 -1
  116. package/dist/admin/pages/Assets/components/BusyOverlay.mjs +1 -1
  117. package/dist/admin/pages/Assets/components/Dnd/DragOverlayChip.mjs +1 -1
  118. package/dist/admin/pages/Assets/components/Dnd/ReorderHandle.js +40 -0
  119. package/dist/admin/pages/Assets/components/Dnd/ReorderHandle.js.map +1 -0
  120. package/dist/admin/pages/Assets/components/Dnd/ReorderHandle.mjs +38 -0
  121. package/dist/admin/pages/Assets/components/Dnd/ReorderHandle.mjs.map +1 -0
  122. package/dist/admin/pages/Assets/components/Dnd/assetSortable.js +29 -0
  123. package/dist/admin/pages/Assets/components/Dnd/assetSortable.js.map +1 -0
  124. package/dist/admin/pages/Assets/components/Dnd/assetSortable.mjs +24 -0
  125. package/dist/admin/pages/Assets/components/Dnd/assetSortable.mjs.map +1 -0
  126. package/dist/admin/pages/Assets/components/Dnd/dndIds.js +5 -0
  127. package/dist/admin/pages/Assets/components/Dnd/dndIds.js.map +1 -1
  128. package/dist/admin/pages/Assets/components/Dnd/dndIds.mjs +5 -1
  129. package/dist/admin/pages/Assets/components/Dnd/dndIds.mjs.map +1 -1
  130. package/dist/admin/pages/Assets/components/Dnd/useAssetDnd.js +41 -13
  131. package/dist/admin/pages/Assets/components/Dnd/useAssetDnd.js.map +1 -1
  132. package/dist/admin/pages/Assets/components/Dnd/useAssetDnd.mjs +41 -13
  133. package/dist/admin/pages/Assets/components/Dnd/useAssetDnd.mjs.map +1 -1
  134. package/dist/admin/pages/Assets/components/FilterBadges.mjs +2 -2
  135. package/dist/admin/pages/Assets/components/FilterMenu.mjs +2 -2
  136. package/dist/admin/pages/Assets/components/FolderTree/FolderTree.js +274 -55
  137. package/dist/admin/pages/Assets/components/FolderTree/FolderTree.js.map +1 -1
  138. package/dist/admin/pages/Assets/components/FolderTree/FolderTree.mjs +277 -59
  139. package/dist/admin/pages/Assets/components/FolderTree/FolderTree.mjs.map +1 -1
  140. package/dist/admin/pages/Assets/components/FolderTree/collapsedBranch.js +32 -0
  141. package/dist/admin/pages/Assets/components/FolderTree/collapsedBranch.js.map +1 -0
  142. package/dist/admin/pages/Assets/components/FolderTree/collapsedBranch.mjs +29 -0
  143. package/dist/admin/pages/Assets/components/FolderTree/collapsedBranch.mjs.map +1 -0
  144. package/dist/admin/pages/Assets/components/ViewToggle.js +126 -0
  145. package/dist/admin/pages/Assets/components/ViewToggle.js.map +1 -0
  146. package/dist/admin/pages/Assets/components/ViewToggle.mjs +104 -0
  147. package/dist/admin/pages/Assets/components/ViewToggle.mjs.map +1 -0
  148. package/dist/admin/pages/Assets/hooks/useAssetSearch.js +2 -2
  149. package/dist/admin/pages/Assets/hooks/useAssetSearch.js.map +1 -1
  150. package/dist/admin/pages/Assets/hooks/useAssetSearch.mjs +2 -2
  151. package/dist/admin/pages/Assets/hooks/useAssetSearch.mjs.map +1 -1
  152. package/dist/admin/pages/Assets/hooks/useAssetSelection.js +19 -1
  153. package/dist/admin/pages/Assets/hooks/useAssetSelection.js.map +1 -1
  154. package/dist/admin/pages/Assets/hooks/useAssetSelection.mjs +20 -3
  155. package/dist/admin/pages/Assets/hooks/useAssetSelection.mjs.map +1 -1
  156. package/dist/admin/pages/Assets/hooks/useAssetsList.js +87 -0
  157. package/dist/admin/pages/Assets/hooks/useAssetsList.js.map +1 -0
  158. package/dist/admin/pages/Assets/hooks/useAssetsList.mjs +85 -0
  159. package/dist/admin/pages/Assets/hooks/useAssetsList.mjs.map +1 -0
  160. package/dist/admin/pages/Assets/hooks/useBusyAssets.mjs +1 -1
  161. package/dist/admin/pages/Assets/hooks/useFolderNavigation.js +2 -1
  162. package/dist/admin/pages/Assets/hooks/useFolderNavigation.js.map +1 -1
  163. package/dist/admin/pages/Assets/hooks/useFolderNavigation.mjs +3 -2
  164. package/dist/admin/pages/Assets/hooks/useFolderNavigation.mjs.map +1 -1
  165. package/dist/admin/pages/Assets/hooks/useIsAssetDetailsOpen.js +2 -6
  166. package/dist/admin/pages/Assets/hooks/useIsAssetDetailsOpen.js.map +1 -1
  167. package/dist/admin/pages/Assets/hooks/useIsAssetDetailsOpen.mjs +2 -6
  168. package/dist/admin/pages/Assets/hooks/useIsAssetDetailsOpen.mjs.map +1 -1
  169. package/dist/admin/pages/Assets/hooks/useListFilters.js +2 -1
  170. package/dist/admin/pages/Assets/hooks/useListFilters.js.map +1 -1
  171. package/dist/admin/pages/Assets/hooks/useListFilters.mjs +3 -2
  172. package/dist/admin/pages/Assets/hooks/useListFilters.mjs.map +1 -1
  173. package/dist/admin/pages/Assets/hooks/useListQueryParams.js +80 -0
  174. package/dist/admin/pages/Assets/hooks/useListQueryParams.js.map +1 -0
  175. package/dist/admin/pages/Assets/hooks/useListQueryParams.mjs +77 -0
  176. package/dist/admin/pages/Assets/hooks/useListQueryParams.mjs.map +1 -0
  177. package/dist/admin/pages/Assets/hooks/useListSettings.js +32 -0
  178. package/dist/admin/pages/Assets/hooks/useListSettings.js.map +1 -0
  179. package/dist/admin/pages/Assets/hooks/useListSettings.mjs +29 -0
  180. package/dist/admin/pages/Assets/hooks/useListSettings.mjs.map +1 -0
  181. package/dist/admin/pages/Assets/hooks/useListSort.js +2 -1
  182. package/dist/admin/pages/Assets/hooks/useListSort.js.map +1 -1
  183. package/dist/admin/pages/Assets/hooks/useListSort.mjs +3 -2
  184. package/dist/admin/pages/Assets/hooks/useListSort.mjs.map +1 -1
  185. package/dist/admin/services/api.js +92 -7
  186. package/dist/admin/services/api.js.map +1 -1
  187. package/dist/admin/services/api.mjs +91 -9
  188. package/dist/admin/services/api.mjs.map +1 -1
  189. package/dist/admin/src/components/AssetPickerDialog/AssetPickerDialog.d.ts +19 -0
  190. package/dist/admin/src/components/AssetPickerDialog/FolderBreadcrumbs.d.ts +10 -0
  191. package/dist/admin/src/components/AssetPickerDialog/MediaLibraryPickerDialog.d.ts +19 -0
  192. package/dist/admin/src/components/AssetPickerDialog/PickerSelectionProvider.d.ts +28 -0
  193. package/dist/admin/src/components/AssetPickerDialog/SortableSelection.d.ts +12 -0
  194. package/dist/admin/src/components/AssetPickerDialog/pickerSelection.d.ts +26 -0
  195. package/dist/admin/src/components/Drawer.d.ts +8 -0
  196. package/dist/admin/src/components/EditorFileDropZone/EditorFileDropZone.d.ts +21 -0
  197. package/dist/admin/src/components/MediaLibraryInput/AddAssetMenu.d.ts +7 -1
  198. package/dist/admin/src/components/MediaLibraryInput/AssetCard.d.ts +25 -0
  199. package/dist/admin/src/components/MediaLibraryInput/AssetCarousel.d.ts +16 -0
  200. package/dist/admin/src/components/MediaLibraryInput/AssetDropZone.d.ts +11 -3
  201. package/dist/admin/src/components/MediaLibraryInput/AssetPreview.d.ts +17 -0
  202. package/dist/admin/src/components/MediaLibraryInput/AssetRow.d.ts +13 -3
  203. package/dist/admin/src/components/MediaLibraryInput/FieldControls.d.ts +19 -0
  204. package/dist/admin/src/components/MediaLibraryInput/MediaLibraryInput.d.ts +3 -1
  205. package/dist/admin/src/components/MediaLibraryInput/UploadProgressBar.d.ts +7 -0
  206. package/dist/admin/src/components/MediaLibraryInput/openAssetDetails.d.ts +10 -0
  207. package/dist/admin/src/components/MediaLibraryInput/useFieldUploads.d.ts +31 -0
  208. package/dist/admin/src/hooks/useMediaLibraryPermissions.d.ts +2 -0
  209. package/dist/admin/src/pages/Assets/components/AssetDetails/AssetDetailsDrawer.d.ts +41 -5
  210. package/dist/admin/src/pages/Assets/components/AssetsGrid.d.ts +3 -1
  211. package/dist/admin/src/pages/Assets/components/AssetsSearchInput.d.ts +11 -1
  212. package/dist/admin/src/pages/Assets/components/AssetsView.d.ts +29 -0
  213. package/dist/admin/src/pages/Assets/components/Dnd/ReorderHandle.d.ts +12 -0
  214. package/dist/admin/src/pages/Assets/components/Dnd/assetSortable.d.ts +37 -0
  215. package/dist/admin/src/pages/Assets/components/Dnd/dndIds.d.ts +5 -0
  216. package/dist/admin/src/pages/Assets/components/Dnd/useAssetDnd.d.ts +23 -2
  217. package/dist/admin/src/pages/Assets/components/FolderTree/FolderTree.d.ts +1 -0
  218. package/dist/admin/src/pages/Assets/components/FolderTree/collapsedBranch.d.ts +21 -0
  219. package/dist/admin/src/pages/Assets/components/ViewToggle.d.ts +8 -0
  220. package/dist/admin/src/pages/Assets/hooks/useAssetSelection.d.ts +26 -0
  221. package/dist/admin/src/pages/Assets/hooks/useAssetsList.d.ts +30 -0
  222. package/dist/admin/src/pages/Assets/hooks/useIsAssetDetailsOpen.d.ts +2 -6
  223. package/dist/admin/src/pages/Assets/hooks/useListQueryParams.d.ts +27 -0
  224. package/dist/admin/src/pages/Assets/hooks/useListSettings.d.ts +29 -0
  225. package/dist/admin/src/services/api.d.ts +24 -1
  226. package/dist/admin/src/store/uploadProgress.d.ts +14 -1
  227. package/dist/admin/src/utils/findFolderPath.d.ts +6 -0
  228. package/dist/admin/src/utils/isAllowedAssetType.d.ts +14 -0
  229. package/dist/admin/store/uploadProgress.js +30 -3
  230. package/dist/admin/store/uploadProgress.js.map +1 -1
  231. package/dist/admin/store/uploadProgress.mjs +29 -4
  232. package/dist/admin/store/uploadProgress.mjs.map +1 -1
  233. package/dist/admin/translations/en.json.js +24 -0
  234. package/dist/admin/translations/en.json.js.map +1 -1
  235. package/dist/admin/translations/en.json.mjs +24 -0
  236. package/dist/admin/translations/en.json.mjs.map +1 -1
  237. package/dist/admin/utils/findFolderPath.js +26 -0
  238. package/dist/admin/utils/findFolderPath.js.map +1 -0
  239. package/dist/admin/utils/findFolderPath.mjs +24 -0
  240. package/dist/admin/utils/findFolderPath.mjs.map +1 -0
  241. package/dist/admin/utils/isAllowedAssetType.js +33 -0
  242. package/dist/admin/utils/isAllowedAssetType.js.map +1 -0
  243. package/dist/admin/utils/isAllowedAssetType.mjs +31 -0
  244. package/dist/admin/utils/isAllowedAssetType.mjs.map +1 -0
  245. package/dist/server/audit-logs.js +264 -0
  246. package/dist/server/audit-logs.js.map +1 -0
  247. package/dist/server/audit-logs.mjs +255 -0
  248. package/dist/server/audit-logs.mjs.map +1 -0
  249. package/dist/server/bootstrap.js +4 -0
  250. package/dist/server/bootstrap.js.map +1 -1
  251. package/dist/server/bootstrap.mjs +4 -0
  252. package/dist/server/bootstrap.mjs.map +1 -1
  253. package/dist/server/controllers/admin-folder-file.js +23 -1
  254. package/dist/server/controllers/admin-folder-file.js.map +1 -1
  255. package/dist/server/controllers/admin-folder-file.mjs +23 -1
  256. package/dist/server/controllers/admin-folder-file.mjs.map +1 -1
  257. package/dist/server/controllers/admin-settings.js +5 -1
  258. package/dist/server/controllers/admin-settings.js.map +1 -1
  259. package/dist/server/controllers/admin-settings.mjs +5 -1
  260. package/dist/server/controllers/admin-settings.mjs.map +1 -1
  261. package/dist/server/services/folder.js +48 -1
  262. package/dist/server/services/folder.js.map +1 -1
  263. package/dist/server/services/folder.mjs +48 -1
  264. package/dist/server/services/folder.mjs.map +1 -1
  265. package/dist/server/services/image-manipulation.js +14 -7
  266. package/dist/server/services/image-manipulation.js.map +1 -1
  267. package/dist/server/services/image-manipulation.mjs +14 -7
  268. package/dist/server/services/image-manipulation.mjs.map +1 -1
  269. package/dist/server/services/upload.js +100 -16
  270. package/dist/server/services/upload.js.map +1 -1
  271. package/dist/server/services/upload.mjs +102 -18
  272. package/dist/server/services/upload.mjs.map +1 -1
  273. package/dist/server/src/audit-logs.d.ts +142 -0
  274. package/dist/server/src/audit-logs.d.ts.map +1 -0
  275. package/dist/server/src/bootstrap.d.ts.map +1 -1
  276. package/dist/server/src/controllers/admin-folder-file.d.ts.map +1 -1
  277. package/dist/server/src/controllers/admin-settings.d.ts.map +1 -1
  278. package/dist/server/src/index.d.ts +4 -4
  279. package/dist/server/src/index.d.ts.map +1 -1
  280. package/dist/server/src/mcp/ambient-instance.d.ts.map +1 -1
  281. package/dist/server/src/services/extensions/utils.d.ts +11 -11
  282. package/dist/server/src/services/folder.d.ts.map +1 -1
  283. package/dist/server/src/services/image-manipulation.d.ts +4 -4
  284. package/dist/server/src/services/image-manipulation.d.ts.map +1 -1
  285. package/dist/server/src/services/index.d.ts +4 -4
  286. package/dist/server/src/services/index.d.ts.map +1 -1
  287. package/dist/server/src/services/upload.d.ts.map +1 -1
  288. package/dist/server/src/types.d.ts +63 -12
  289. package/dist/server/src/types.d.ts.map +1 -1
  290. package/package.json +11 -16
  291. package/dist/admin/components/MediaLibraryInput/NoLibraryAccessDialog.js +0 -45
  292. package/dist/admin/components/MediaLibraryInput/NoLibraryAccessDialog.js.map +0 -1
  293. package/dist/admin/components/MediaLibraryInput/NoLibraryAccessDialog.mjs +0 -43
  294. package/dist/admin/components/MediaLibraryInput/NoLibraryAccessDialog.mjs.map +0 -1
  295. package/dist/admin/src/components/MediaLibraryInput/NoLibraryAccessDialog.d.ts +0 -10
@@ -0,0 +1,143 @@
1
+ 'use strict';
2
+
3
+ var jsxRuntime = require('react/jsx-runtime');
4
+ var React = require('react');
5
+ var core = require('@dnd-kit/core');
6
+ var sortable = require('@dnd-kit/sortable');
7
+ var utilities = require('@dnd-kit/utilities');
8
+ var reactIntl = require('react-intl');
9
+ var assetSortable = require('../../pages/Assets/components/Dnd/assetSortable.js');
10
+ var translations = require('../../utils/translations.js');
11
+ var PickerSelectionProvider = require('./PickerSelectionProvider.js');
12
+
13
+ /** Module scope, so every item of the list gets the same hook (see `AssetSortableContext`). */ const usePickerSortableAsset = (assetId)=>{
14
+ const { attributes, listeners, setNodeRef, setActivatorNodeRef, transform, transition, isDragging } = sortable.useSortable({
15
+ id: assetId
16
+ });
17
+ return {
18
+ setNodeRef,
19
+ isDragging,
20
+ style: {
21
+ transform: utilities.CSS.Transform.toString(transform),
22
+ transition
23
+ },
24
+ // The item drags with the pointer from anywhere; the keyboard starts from the grip.
25
+ listeners: listeners?.onPointerDown ? {
26
+ onPointerDown: listeners.onPointerDown
27
+ } : undefined,
28
+ handle: {
29
+ ...attributes,
30
+ ref: setActivatorNodeRef,
31
+ onKeyDown: (event)=>listeners?.onKeyDown?.(event)
32
+ }
33
+ };
34
+ };
35
+ /**
36
+ * A pointer release over the item it was dragging would also count as a click,
37
+ * which on a selected item un-picks it. Swallow that one click.
38
+ */ const swallowNextClick = ()=>{
39
+ const swallow = (event)=>{
40
+ event.stopPropagation();
41
+ event.preventDefault();
42
+ };
43
+ window.addEventListener('click', swallow, {
44
+ capture: true,
45
+ once: true
46
+ });
47
+ // No click follows a keyboard drop: don't leave the listener behind.
48
+ setTimeout(()=>window.removeEventListener('click', swallow, {
49
+ capture: true
50
+ }), 0);
51
+ };
52
+ /** Makes the picker's selected assets reorderable (the Selected tab is always a grid). */ const SortableSelection = ({ children, onReorderingChange })=>{
53
+ const { formatMessage } = reactIntl.useIntl();
54
+ const { selection, moveFile } = PickerSelectionProvider.usePickerSelection();
55
+ const sensors = core.useSensors(// A few pixels of travel before it counts as a drag, so clicks still pick.
56
+ core.useSensor(core.PointerSensor, {
57
+ activationConstraint: {
58
+ distance: 8
59
+ }
60
+ }), core.useSensor(core.KeyboardSensor, {
61
+ coordinateGetter: sortable.sortableKeyboardCoordinates
62
+ }));
63
+ const ids = React.useMemo(()=>selection.map(({ id })=>id), [
64
+ selection
65
+ ]);
66
+ const announcements = React.useMemo(()=>{
67
+ const describe = (id)=>{
68
+ const index = ids.indexOf(Number(id));
69
+ return {
70
+ name: selection[index]?.name ?? '',
71
+ position: index + 1,
72
+ count: ids.length
73
+ };
74
+ };
75
+ return {
76
+ onDragStart: ({ active })=>formatMessage({
77
+ id: translations.getTranslationKey('list.reorder.picked-up'),
78
+ defaultMessage: 'Picked up {name}. Position {position} of {count}.'
79
+ }, describe(active.id)),
80
+ onDragOver: ({ active, over })=>over ? formatMessage({
81
+ id: translations.getTranslationKey('list.reorder.moved'),
82
+ defaultMessage: '{name} moved to position {position} of {count}.'
83
+ }, {
84
+ ...describe(active.id),
85
+ position: describe(over.id).position
86
+ }) : undefined,
87
+ onDragEnd: ({ active, over })=>formatMessage({
88
+ id: translations.getTranslationKey('list.reorder.dropped'),
89
+ defaultMessage: '{name} dropped at position {position} of {count}.'
90
+ }, {
91
+ ...describe(active.id),
92
+ position: describe((over ?? active).id).position
93
+ }),
94
+ onDragCancel: ({ active })=>formatMessage({
95
+ id: translations.getTranslationKey('list.reorder.cancelled'),
96
+ defaultMessage: 'Reordering cancelled. {name} is back at position {position} of {count}.'
97
+ }, describe(active.id))
98
+ };
99
+ }, [
100
+ formatMessage,
101
+ ids,
102
+ selection
103
+ ]);
104
+ const handleDragEnd = ({ active, over })=>{
105
+ if (active.data.current?.sortable && over) {
106
+ moveFile(Number(active.id), Number(over.id));
107
+ }
108
+ onReorderingChange?.(false);
109
+ swallowNextClick();
110
+ };
111
+ // Escape cancels a pointer drag while the button is still down, so the click
112
+ // that would un-pick the item comes with the release, possibly much later.
113
+ const handleDragCancel = ({ activatorEvent })=>{
114
+ onReorderingChange?.(false);
115
+ if (activatorEvent.type === 'pointerdown') {
116
+ window.addEventListener('pointerup', swallowNextClick, {
117
+ capture: true,
118
+ once: true
119
+ });
120
+ }
121
+ };
122
+ return /*#__PURE__*/ jsxRuntime.jsx(core.DndContext, {
123
+ sensors: sensors,
124
+ collisionDetection: core.closestCenter,
125
+ onDragStart: ()=>onReorderingChange?.(true),
126
+ onDragEnd: handleDragEnd,
127
+ onDragCancel: handleDragCancel,
128
+ accessibility: {
129
+ announcements
130
+ },
131
+ children: /*#__PURE__*/ jsxRuntime.jsx(sortable.SortableContext, {
132
+ items: ids,
133
+ strategy: sortable.rectSortingStrategy,
134
+ children: /*#__PURE__*/ jsxRuntime.jsx(assetSortable.AssetSortableContext.Provider, {
135
+ value: usePickerSortableAsset,
136
+ children: children
137
+ })
138
+ })
139
+ });
140
+ };
141
+
142
+ exports.SortableSelection = SortableSelection;
143
+ //# sourceMappingURL=SortableSelection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SortableSelection.js","sources":["../../../../admin/src/components/AssetPickerDialog/SortableSelection.tsx"],"sourcesContent":["import { useMemo, type ReactNode } from 'react';\n\nimport {\n closestCenter,\n DndContext,\n KeyboardSensor,\n PointerSensor,\n useSensor,\n useSensors,\n type Announcements,\n type DragCancelEvent,\n type DragEndEvent,\n} from '@dnd-kit/core';\nimport {\n rectSortingStrategy,\n SortableContext,\n sortableKeyboardCoordinates,\n useSortable,\n} from '@dnd-kit/sortable';\nimport { CSS } from '@dnd-kit/utilities';\nimport { useIntl } from 'react-intl';\n\nimport {\n AssetSortableContext,\n type AssetSortable,\n} from '../../pages/Assets/components/Dnd/assetSortable';\nimport { getTranslationKey } from '../../utils/translations';\n\nimport { usePickerSelection } from './PickerSelectionProvider';\n\n/** Module scope, so every item of the list gets the same hook (see `AssetSortableContext`). */\nconst usePickerSortableAsset = (assetId: number): AssetSortable => {\n const {\n attributes,\n listeners,\n setNodeRef,\n setActivatorNodeRef,\n transform,\n transition,\n isDragging,\n } = useSortable({ id: assetId });\n\n return {\n setNodeRef,\n isDragging,\n style: { transform: CSS.Transform.toString(transform), transition },\n // The item drags with the pointer from anywhere; the keyboard starts from the grip.\n listeners: listeners?.onPointerDown ? { onPointerDown: listeners.onPointerDown } : undefined,\n handle: {\n ...attributes,\n ref: setActivatorNodeRef,\n onKeyDown: (event) => listeners?.onKeyDown?.(event),\n },\n };\n};\n\n/**\n * A pointer release over the item it was dragging would also count as a click,\n * which on a selected item un-picks it. Swallow that one click.\n */\nconst swallowNextClick = () => {\n const swallow = (event: MouseEvent) => {\n event.stopPropagation();\n event.preventDefault();\n };\n\n window.addEventListener('click', swallow, { capture: true, once: true });\n // No click follows a keyboard drop: don't leave the listener behind.\n setTimeout(() => window.removeEventListener('click', swallow, { capture: true }), 0);\n};\n\ninterface SortableSelectionProps {\n children: ReactNode;\n /**\n * Called with `true` when a drag starts and `false` when it ends or is\n * cancelled, so the dialog can keep Escape for cancelling the drag.\n */\n onReorderingChange?: (reordering: boolean) => void;\n}\n\n/** Makes the picker's selected assets reorderable (the Selected tab is always a grid). */\nexport const SortableSelection = ({ children, onReorderingChange }: SortableSelectionProps) => {\n const { formatMessage } = useIntl();\n const { selection, moveFile } = usePickerSelection();\n\n const sensors = useSensors(\n // A few pixels of travel before it counts as a drag, so clicks still pick.\n useSensor(PointerSensor, { activationConstraint: { distance: 8 } }),\n useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates })\n );\n\n const ids = useMemo(() => selection.map(({ id }) => id), [selection]);\n\n const announcements = useMemo<Announcements>(() => {\n const describe = (id: string | number) => {\n const index = ids.indexOf(Number(id));\n\n return {\n name: selection[index]?.name ?? '',\n position: index + 1,\n count: ids.length,\n };\n };\n\n return {\n onDragStart: ({ active }) =>\n formatMessage(\n {\n id: getTranslationKey('list.reorder.picked-up'),\n defaultMessage: 'Picked up {name}. Position {position} of {count}.',\n },\n describe(active.id)\n ),\n onDragOver: ({ active, over }) =>\n over\n ? formatMessage(\n {\n id: getTranslationKey('list.reorder.moved'),\n defaultMessage: '{name} moved to position {position} of {count}.',\n },\n { ...describe(active.id), position: describe(over.id).position }\n )\n : undefined,\n onDragEnd: ({ active, over }) =>\n formatMessage(\n {\n id: getTranslationKey('list.reorder.dropped'),\n defaultMessage: '{name} dropped at position {position} of {count}.',\n },\n { ...describe(active.id), position: describe((over ?? active).id).position }\n ),\n onDragCancel: ({ active }) =>\n formatMessage(\n {\n id: getTranslationKey('list.reorder.cancelled'),\n defaultMessage:\n 'Reordering cancelled. {name} is back at position {position} of {count}.',\n },\n describe(active.id)\n ),\n };\n }, [formatMessage, ids, selection]);\n\n const handleDragEnd = ({ active, over }: DragEndEvent) => {\n if (active.data.current?.sortable && over) {\n moveFile(Number(active.id), Number(over.id));\n }\n\n onReorderingChange?.(false);\n swallowNextClick();\n };\n\n // Escape cancels a pointer drag while the button is still down, so the click\n // that would un-pick the item comes with the release, possibly much later.\n const handleDragCancel = ({ activatorEvent }: DragCancelEvent) => {\n onReorderingChange?.(false);\n\n if (activatorEvent.type === 'pointerdown') {\n window.addEventListener('pointerup', swallowNextClick, { capture: true, once: true });\n }\n };\n\n return (\n <DndContext\n sensors={sensors}\n collisionDetection={closestCenter}\n onDragStart={() => onReorderingChange?.(true)}\n onDragEnd={handleDragEnd}\n onDragCancel={handleDragCancel}\n accessibility={{ announcements }}\n >\n <SortableContext items={ids} strategy={rectSortingStrategy}>\n <AssetSortableContext.Provider value={usePickerSortableAsset}>\n {children}\n </AssetSortableContext.Provider>\n </SortableContext>\n </DndContext>\n );\n};\n"],"names":["usePickerSortableAsset","assetId","attributes","listeners","setNodeRef","setActivatorNodeRef","transform","transition","isDragging","useSortable","id","style","CSS","Transform","toString","onPointerDown","undefined","handle","ref","onKeyDown","event","swallowNextClick","swallow","stopPropagation","preventDefault","window","addEventListener","capture","once","setTimeout","removeEventListener","SortableSelection","children","onReorderingChange","formatMessage","useIntl","selection","moveFile","usePickerSelection","sensors","useSensors","useSensor","PointerSensor","activationConstraint","distance","KeyboardSensor","coordinateGetter","sortableKeyboardCoordinates","ids","useMemo","map","announcements","describe","index","indexOf","Number","name","position","count","length","onDragStart","active","getTranslationKey","defaultMessage","onDragOver","over","onDragEnd","onDragCancel","handleDragEnd","data","current","sortable","handleDragCancel","activatorEvent","type","_jsx","DndContext","collisionDetection","closestCenter","accessibility","SortableContext","items","strategy","rectSortingStrategy","AssetSortableContext","Provider","value"],"mappings":";;;;;;;;;;;;AA8BA,gGACA,MAAMA,sBAAAA,GAAyB,CAACC,OAAAA,GAAAA;AAC9B,IAAA,MAAM,EACJC,UAAU,EACVC,SAAS,EACTC,UAAU,EACVC,mBAAmB,EACnBC,SAAS,EACTC,UAAU,EACVC,UAAU,EACX,GAAGC,oBAAAA,CAAY;QAAEC,EAAAA,EAAIT;AAAQ,KAAA,CAAA;IAE9B,OAAO;AACLG,QAAAA,UAAAA;AACAI,QAAAA,UAAAA;QACAG,KAAAA,EAAO;AAAEL,YAAAA,SAAAA,EAAWM,aAAAA,CAAIC,SAAS,CAACC,QAAQ,CAACR,SAAAA,CAAAA;AAAYC,YAAAA;AAAW,SAAA;;AAElEJ,QAAAA,SAAAA,EAAWA,WAAWY,aAAAA,GAAgB;AAAEA,YAAAA,aAAAA,EAAeZ,UAAUY;SAAc,GAAIC,SAAAA;QACnFC,MAAAA,EAAQ;AACN,YAAA,GAAGf,UAAU;YACbgB,GAAAA,EAAKb,mBAAAA;YACLc,SAAAA,EAAW,CAACC,KAAAA,GAAUjB,SAAAA,EAAWgB,SAAAA,GAAYC,KAAAA;AAC/C;AACF,KAAA;AACF,CAAA;AAEA;;;AAGC,IACD,MAAMC,gBAAAA,GAAmB,IAAA;AACvB,IAAA,MAAMC,UAAU,CAACF,KAAAA,GAAAA;AACfA,QAAAA,KAAAA,CAAMG,eAAe,EAAA;AACrBH,QAAAA,KAAAA,CAAMI,cAAc,EAAA;AACtB,IAAA,CAAA;IAEAC,MAAAA,CAAOC,gBAAgB,CAAC,OAAA,EAASJ,OAAAA,EAAS;QAAEK,OAAAA,EAAS,IAAA;QAAMC,IAAAA,EAAM;AAAK,KAAA,CAAA;;AAEtEC,IAAAA,UAAAA,CAAW,IAAMJ,MAAAA,CAAOK,mBAAmB,CAAC,SAASR,OAAAA,EAAS;YAAEK,OAAAA,EAAS;SAAK,CAAA,EAAI,CAAA,CAAA;AACpF,CAAA;AAWA,2FACO,MAAMI,iBAAAA,GAAoB,CAAC,EAAEC,QAAQ,EAAEC,kBAAkB,EAA0B,GAAA;IACxF,MAAM,EAAEC,aAAa,EAAE,GAAGC,iBAAAA,EAAAA;AAC1B,IAAA,MAAM,EAAEC,SAAS,EAAEC,QAAQ,EAAE,GAAGC,0CAAAA,EAAAA;IAEhC,MAAMC,OAAAA,GAAUC;AAEdC,IAAAA,cAAAA,CAAUC,kBAAAA,EAAe;QAAEC,oBAAAA,EAAsB;YAAEC,QAAAA,EAAU;AAAE;AAAE,KAAA,CAAA,EACjEH,eAAUI,mBAAAA,EAAgB;QAAEC,gBAAAA,EAAkBC;AAA4B,KAAA,CAAA,CAAA;IAG5E,MAAMC,GAAAA,GAAMC,aAAAA,CAAQ,IAAMb,SAAAA,CAAUc,GAAG,CAAC,CAAC,EAAExC,EAAE,EAAE,GAAKA,EAAAA,CAAAA,EAAK;AAAC0B,QAAAA;AAAU,KAAA,CAAA;AAEpE,IAAA,MAAMe,gBAAgBF,aAAAA,CAAuB,IAAA;AAC3C,QAAA,MAAMG,WAAW,CAAC1C,EAAAA,GAAAA;AAChB,YAAA,MAAM2C,KAAAA,GAAQL,GAAAA,CAAIM,OAAO,CAACC,MAAAA,CAAO7C,EAAAA,CAAAA,CAAAA;YAEjC,OAAO;AACL8C,gBAAAA,IAAAA,EAAMpB,SAAS,CAACiB,KAAAA,CAAM,EAAEG,IAAAA,IAAQ,EAAA;AAChCC,gBAAAA,QAAAA,EAAUJ,KAAAA,GAAQ,CAAA;AAClBK,gBAAAA,KAAAA,EAAOV,IAAIW;AACb,aAAA;AACF,QAAA,CAAA;QAEA,OAAO;AACLC,YAAAA,WAAAA,EAAa,CAAC,EAAEC,MAAM,EAAE,GACtB3B,aAAAA,CACE;AACExB,oBAAAA,EAAAA,EAAIoD,8BAAAA,CAAkB,wBAAA,CAAA;oBACtBC,cAAAA,EAAgB;iBAClB,EACAX,QAAAA,CAASS,OAAOnD,EAAE,CAAA,CAAA;YAEtBsD,UAAAA,EAAY,CAAC,EAAEH,MAAM,EAAEI,IAAI,EAAE,GAC3BA,OACI/B,aAAAA,CACE;AACExB,oBAAAA,EAAAA,EAAIoD,8BAAAA,CAAkB,oBAAA,CAAA;oBACtBC,cAAAA,EAAgB;iBAClB,EACA;oBAAE,GAAGX,QAAAA,CAASS,MAAAA,CAAOnD,EAAE,CAAC;AAAE+C,oBAAAA,QAAAA,EAAUL,QAAAA,CAASa,IAAAA,CAAKvD,EAAE,CAAA,CAAE+C;iBAAS,CAAA,GAEjEzC,SAAAA;AACNkD,YAAAA,SAAAA,EAAW,CAAC,EAAEL,MAAM,EAAEI,IAAI,EAAE,GAC1B/B,aAAAA,CACE;AACExB,oBAAAA,EAAAA,EAAIoD,8BAAAA,CAAkB,sBAAA,CAAA;oBACtBC,cAAAA,EAAgB;iBAClB,EACA;oBAAE,GAAGX,QAAAA,CAASS,MAAAA,CAAOnD,EAAE,CAAC;oBAAE+C,QAAAA,EAAUL,QAAAA,CAAS,CAACa,IAAAA,IAAQJ,MAAK,EAAGnD,EAAE,EAAE+C;AAAS,iBAAA,CAAA;AAE/EU,YAAAA,YAAAA,EAAc,CAAC,EAAEN,MAAM,EAAE,GACvB3B,aAAAA,CACE;AACExB,oBAAAA,EAAAA,EAAIoD,8BAAAA,CAAkB,wBAAA,CAAA;oBACtBC,cAAAA,EACE;iBACJ,EACAX,QAAAA,CAASS,OAAOnD,EAAE,CAAA;AAExB,SAAA;IACF,CAAA,EAAG;AAACwB,QAAAA,aAAAA;AAAec,QAAAA,GAAAA;AAAKZ,QAAAA;AAAU,KAAA,CAAA;AAElC,IAAA,MAAMgC,gBAAgB,CAAC,EAAEP,MAAM,EAAEI,IAAI,EAAgB,GAAA;AACnD,QAAA,IAAIJ,OAAOQ,IAAI,CAACC,OAAO,EAAEC,YAAYN,IAAAA,EAAM;AACzC5B,YAAAA,QAAAA,CAASkB,OAAOM,MAAAA,CAAOnD,EAAE,CAAA,EAAG6C,MAAAA,CAAOU,KAAKvD,EAAE,CAAA,CAAA;AAC5C,QAAA;QAEAuB,kBAAAA,GAAqB,KAAA,CAAA;AACrBZ,QAAAA,gBAAAA,EAAAA;AACF,IAAA,CAAA;;;AAIA,IAAA,MAAMmD,gBAAAA,GAAmB,CAAC,EAAEC,cAAc,EAAmB,GAAA;QAC3DxC,kBAAAA,GAAqB,KAAA,CAAA;QAErB,IAAIwC,cAAAA,CAAeC,IAAI,KAAK,aAAA,EAAe;YACzCjD,MAAAA,CAAOC,gBAAgB,CAAC,WAAA,EAAaL,gBAAAA,EAAkB;gBAAEM,OAAAA,EAAS,IAAA;gBAAMC,IAAAA,EAAM;AAAK,aAAA,CAAA;AACrF,QAAA;AACF,IAAA,CAAA;AAEA,IAAA,qBACE+C,cAAA,CAACC,eAAAA,EAAAA;QACCrC,OAAAA,EAASA,OAAAA;QACTsC,kBAAAA,EAAoBC,kBAAAA;AACpBlB,QAAAA,WAAAA,EAAa,IAAM3B,kBAAAA,GAAqB,IAAA,CAAA;QACxCiC,SAAAA,EAAWE,aAAAA;QACXD,YAAAA,EAAcK,gBAAAA;QACdO,aAAAA,EAAe;AAAE5B,YAAAA;AAAc,SAAA;AAE/B,QAAA,QAAA,gBAAAwB,cAAA,CAACK,wBAAAA,EAAAA;YAAgBC,KAAAA,EAAOjC,GAAAA;YAAKkC,QAAAA,EAAUC,4BAAAA;oCACrCR,cAAA,CAACS,mCAAqBC,QAAQ,EAAA;gBAACC,KAAAA,EAAOtF,sBAAAA;AACnCgC,gBAAAA,QAAAA,EAAAA;;;;AAKX;;;;"}
@@ -0,0 +1,141 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import { useMemo } from 'react';
3
+ import { useSensors, useSensor, PointerSensor, KeyboardSensor, DndContext, closestCenter } from '@dnd-kit/core';
4
+ import { sortableKeyboardCoordinates, SortableContext, rectSortingStrategy, useSortable } from '@dnd-kit/sortable';
5
+ import { CSS } from '@dnd-kit/utilities';
6
+ import { useIntl } from 'react-intl';
7
+ import { AssetSortableContext } from '../../pages/Assets/components/Dnd/assetSortable.mjs';
8
+ import { getTranslationKey } from '../../utils/translations.mjs';
9
+ import { usePickerSelection } from './PickerSelectionProvider.mjs';
10
+
11
+ /** Module scope, so every item of the list gets the same hook (see `AssetSortableContext`). */ const usePickerSortableAsset = (assetId)=>{
12
+ const { attributes, listeners, setNodeRef, setActivatorNodeRef, transform, transition, isDragging } = useSortable({
13
+ id: assetId
14
+ });
15
+ return {
16
+ setNodeRef,
17
+ isDragging,
18
+ style: {
19
+ transform: CSS.Transform.toString(transform),
20
+ transition
21
+ },
22
+ // The item drags with the pointer from anywhere; the keyboard starts from the grip.
23
+ listeners: listeners?.onPointerDown ? {
24
+ onPointerDown: listeners.onPointerDown
25
+ } : undefined,
26
+ handle: {
27
+ ...attributes,
28
+ ref: setActivatorNodeRef,
29
+ onKeyDown: (event)=>listeners?.onKeyDown?.(event)
30
+ }
31
+ };
32
+ };
33
+ /**
34
+ * A pointer release over the item it was dragging would also count as a click,
35
+ * which on a selected item un-picks it. Swallow that one click.
36
+ */ const swallowNextClick = ()=>{
37
+ const swallow = (event)=>{
38
+ event.stopPropagation();
39
+ event.preventDefault();
40
+ };
41
+ window.addEventListener('click', swallow, {
42
+ capture: true,
43
+ once: true
44
+ });
45
+ // No click follows a keyboard drop: don't leave the listener behind.
46
+ setTimeout(()=>window.removeEventListener('click', swallow, {
47
+ capture: true
48
+ }), 0);
49
+ };
50
+ /** Makes the picker's selected assets reorderable (the Selected tab is always a grid). */ const SortableSelection = ({ children, onReorderingChange })=>{
51
+ const { formatMessage } = useIntl();
52
+ const { selection, moveFile } = usePickerSelection();
53
+ const sensors = useSensors(// A few pixels of travel before it counts as a drag, so clicks still pick.
54
+ useSensor(PointerSensor, {
55
+ activationConstraint: {
56
+ distance: 8
57
+ }
58
+ }), useSensor(KeyboardSensor, {
59
+ coordinateGetter: sortableKeyboardCoordinates
60
+ }));
61
+ const ids = useMemo(()=>selection.map(({ id })=>id), [
62
+ selection
63
+ ]);
64
+ const announcements = useMemo(()=>{
65
+ const describe = (id)=>{
66
+ const index = ids.indexOf(Number(id));
67
+ return {
68
+ name: selection[index]?.name ?? '',
69
+ position: index + 1,
70
+ count: ids.length
71
+ };
72
+ };
73
+ return {
74
+ onDragStart: ({ active })=>formatMessage({
75
+ id: getTranslationKey('list.reorder.picked-up'),
76
+ defaultMessage: 'Picked up {name}. Position {position} of {count}.'
77
+ }, describe(active.id)),
78
+ onDragOver: ({ active, over })=>over ? formatMessage({
79
+ id: getTranslationKey('list.reorder.moved'),
80
+ defaultMessage: '{name} moved to position {position} of {count}.'
81
+ }, {
82
+ ...describe(active.id),
83
+ position: describe(over.id).position
84
+ }) : undefined,
85
+ onDragEnd: ({ active, over })=>formatMessage({
86
+ id: getTranslationKey('list.reorder.dropped'),
87
+ defaultMessage: '{name} dropped at position {position} of {count}.'
88
+ }, {
89
+ ...describe(active.id),
90
+ position: describe((over ?? active).id).position
91
+ }),
92
+ onDragCancel: ({ active })=>formatMessage({
93
+ id: getTranslationKey('list.reorder.cancelled'),
94
+ defaultMessage: 'Reordering cancelled. {name} is back at position {position} of {count}.'
95
+ }, describe(active.id))
96
+ };
97
+ }, [
98
+ formatMessage,
99
+ ids,
100
+ selection
101
+ ]);
102
+ const handleDragEnd = ({ active, over })=>{
103
+ if (active.data.current?.sortable && over) {
104
+ moveFile(Number(active.id), Number(over.id));
105
+ }
106
+ onReorderingChange?.(false);
107
+ swallowNextClick();
108
+ };
109
+ // Escape cancels a pointer drag while the button is still down, so the click
110
+ // that would un-pick the item comes with the release, possibly much later.
111
+ const handleDragCancel = ({ activatorEvent })=>{
112
+ onReorderingChange?.(false);
113
+ if (activatorEvent.type === 'pointerdown') {
114
+ window.addEventListener('pointerup', swallowNextClick, {
115
+ capture: true,
116
+ once: true
117
+ });
118
+ }
119
+ };
120
+ return /*#__PURE__*/ jsx(DndContext, {
121
+ sensors: sensors,
122
+ collisionDetection: closestCenter,
123
+ onDragStart: ()=>onReorderingChange?.(true),
124
+ onDragEnd: handleDragEnd,
125
+ onDragCancel: handleDragCancel,
126
+ accessibility: {
127
+ announcements
128
+ },
129
+ children: /*#__PURE__*/ jsx(SortableContext, {
130
+ items: ids,
131
+ strategy: rectSortingStrategy,
132
+ children: /*#__PURE__*/ jsx(AssetSortableContext.Provider, {
133
+ value: usePickerSortableAsset,
134
+ children: children
135
+ })
136
+ })
137
+ });
138
+ };
139
+
140
+ export { SortableSelection };
141
+ //# sourceMappingURL=SortableSelection.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SortableSelection.mjs","sources":["../../../../admin/src/components/AssetPickerDialog/SortableSelection.tsx"],"sourcesContent":["import { useMemo, type ReactNode } from 'react';\n\nimport {\n closestCenter,\n DndContext,\n KeyboardSensor,\n PointerSensor,\n useSensor,\n useSensors,\n type Announcements,\n type DragCancelEvent,\n type DragEndEvent,\n} from '@dnd-kit/core';\nimport {\n rectSortingStrategy,\n SortableContext,\n sortableKeyboardCoordinates,\n useSortable,\n} from '@dnd-kit/sortable';\nimport { CSS } from '@dnd-kit/utilities';\nimport { useIntl } from 'react-intl';\n\nimport {\n AssetSortableContext,\n type AssetSortable,\n} from '../../pages/Assets/components/Dnd/assetSortable';\nimport { getTranslationKey } from '../../utils/translations';\n\nimport { usePickerSelection } from './PickerSelectionProvider';\n\n/** Module scope, so every item of the list gets the same hook (see `AssetSortableContext`). */\nconst usePickerSortableAsset = (assetId: number): AssetSortable => {\n const {\n attributes,\n listeners,\n setNodeRef,\n setActivatorNodeRef,\n transform,\n transition,\n isDragging,\n } = useSortable({ id: assetId });\n\n return {\n setNodeRef,\n isDragging,\n style: { transform: CSS.Transform.toString(transform), transition },\n // The item drags with the pointer from anywhere; the keyboard starts from the grip.\n listeners: listeners?.onPointerDown ? { onPointerDown: listeners.onPointerDown } : undefined,\n handle: {\n ...attributes,\n ref: setActivatorNodeRef,\n onKeyDown: (event) => listeners?.onKeyDown?.(event),\n },\n };\n};\n\n/**\n * A pointer release over the item it was dragging would also count as a click,\n * which on a selected item un-picks it. Swallow that one click.\n */\nconst swallowNextClick = () => {\n const swallow = (event: MouseEvent) => {\n event.stopPropagation();\n event.preventDefault();\n };\n\n window.addEventListener('click', swallow, { capture: true, once: true });\n // No click follows a keyboard drop: don't leave the listener behind.\n setTimeout(() => window.removeEventListener('click', swallow, { capture: true }), 0);\n};\n\ninterface SortableSelectionProps {\n children: ReactNode;\n /**\n * Called with `true` when a drag starts and `false` when it ends or is\n * cancelled, so the dialog can keep Escape for cancelling the drag.\n */\n onReorderingChange?: (reordering: boolean) => void;\n}\n\n/** Makes the picker's selected assets reorderable (the Selected tab is always a grid). */\nexport const SortableSelection = ({ children, onReorderingChange }: SortableSelectionProps) => {\n const { formatMessage } = useIntl();\n const { selection, moveFile } = usePickerSelection();\n\n const sensors = useSensors(\n // A few pixels of travel before it counts as a drag, so clicks still pick.\n useSensor(PointerSensor, { activationConstraint: { distance: 8 } }),\n useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates })\n );\n\n const ids = useMemo(() => selection.map(({ id }) => id), [selection]);\n\n const announcements = useMemo<Announcements>(() => {\n const describe = (id: string | number) => {\n const index = ids.indexOf(Number(id));\n\n return {\n name: selection[index]?.name ?? '',\n position: index + 1,\n count: ids.length,\n };\n };\n\n return {\n onDragStart: ({ active }) =>\n formatMessage(\n {\n id: getTranslationKey('list.reorder.picked-up'),\n defaultMessage: 'Picked up {name}. Position {position} of {count}.',\n },\n describe(active.id)\n ),\n onDragOver: ({ active, over }) =>\n over\n ? formatMessage(\n {\n id: getTranslationKey('list.reorder.moved'),\n defaultMessage: '{name} moved to position {position} of {count}.',\n },\n { ...describe(active.id), position: describe(over.id).position }\n )\n : undefined,\n onDragEnd: ({ active, over }) =>\n formatMessage(\n {\n id: getTranslationKey('list.reorder.dropped'),\n defaultMessage: '{name} dropped at position {position} of {count}.',\n },\n { ...describe(active.id), position: describe((over ?? active).id).position }\n ),\n onDragCancel: ({ active }) =>\n formatMessage(\n {\n id: getTranslationKey('list.reorder.cancelled'),\n defaultMessage:\n 'Reordering cancelled. {name} is back at position {position} of {count}.',\n },\n describe(active.id)\n ),\n };\n }, [formatMessage, ids, selection]);\n\n const handleDragEnd = ({ active, over }: DragEndEvent) => {\n if (active.data.current?.sortable && over) {\n moveFile(Number(active.id), Number(over.id));\n }\n\n onReorderingChange?.(false);\n swallowNextClick();\n };\n\n // Escape cancels a pointer drag while the button is still down, so the click\n // that would un-pick the item comes with the release, possibly much later.\n const handleDragCancel = ({ activatorEvent }: DragCancelEvent) => {\n onReorderingChange?.(false);\n\n if (activatorEvent.type === 'pointerdown') {\n window.addEventListener('pointerup', swallowNextClick, { capture: true, once: true });\n }\n };\n\n return (\n <DndContext\n sensors={sensors}\n collisionDetection={closestCenter}\n onDragStart={() => onReorderingChange?.(true)}\n onDragEnd={handleDragEnd}\n onDragCancel={handleDragCancel}\n accessibility={{ announcements }}\n >\n <SortableContext items={ids} strategy={rectSortingStrategy}>\n <AssetSortableContext.Provider value={usePickerSortableAsset}>\n {children}\n </AssetSortableContext.Provider>\n </SortableContext>\n </DndContext>\n );\n};\n"],"names":["usePickerSortableAsset","assetId","attributes","listeners","setNodeRef","setActivatorNodeRef","transform","transition","isDragging","useSortable","id","style","CSS","Transform","toString","onPointerDown","undefined","handle","ref","onKeyDown","event","swallowNextClick","swallow","stopPropagation","preventDefault","window","addEventListener","capture","once","setTimeout","removeEventListener","SortableSelection","children","onReorderingChange","formatMessage","useIntl","selection","moveFile","usePickerSelection","sensors","useSensors","useSensor","PointerSensor","activationConstraint","distance","KeyboardSensor","coordinateGetter","sortableKeyboardCoordinates","ids","useMemo","map","announcements","describe","index","indexOf","Number","name","position","count","length","onDragStart","active","getTranslationKey","defaultMessage","onDragOver","over","onDragEnd","onDragCancel","handleDragEnd","data","current","sortable","handleDragCancel","activatorEvent","type","_jsx","DndContext","collisionDetection","closestCenter","accessibility","SortableContext","items","strategy","rectSortingStrategy","AssetSortableContext","Provider","value"],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ 'use strict';
2
+
3
+ const hasFile = (selection, id)=>selection.some((file)=>file.id === id);
4
+ /**
5
+ * Adds the file, or removes it if it is already there. On a single-value field
6
+ * a new pick replaces whatever was selected.
7
+ */ const toggleFile = (selection, file, { multiple })=>{
8
+ if (hasFile(selection, file.id)) {
9
+ return selection.filter(({ id })=>id !== file.id);
10
+ }
11
+ return multiple ? [
12
+ ...selection,
13
+ file
14
+ ] : [
15
+ file
16
+ ];
17
+ };
18
+ /** Appends every file not already selected, keeping their order (select-all). */ const addFiles = (selection, files)=>[
19
+ ...selection,
20
+ ...files.filter((file)=>!hasFile(selection, file.id))
21
+ ];
22
+ const removeFile = (selection, id)=>selection.filter((file)=>file.id !== id);
23
+ const removeFiles = (selection, ids)=>selection.filter((file)=>!ids.has(file.id));
24
+ /**
25
+ * Moves one file to where another one is, the others shifting to make room.
26
+ * Unknown ids leave the selection as it is.
27
+ */ const moveFile = (selection, activeId, overId)=>{
28
+ const from = selection.findIndex(({ id })=>id === activeId);
29
+ const to = selection.findIndex(({ id })=>id === overId);
30
+ if (from === -1 || to === -1 || from === to) {
31
+ return selection;
32
+ }
33
+ const next = [
34
+ ...selection
35
+ ];
36
+ const [file] = next.splice(from, 1);
37
+ next.splice(to, 0, file);
38
+ return next;
39
+ };
40
+ /** Same files in the same order: confirming would change nothing. */ const isSameSelection = (a, b)=>a.length === b.length && a.every((file, index)=>file.id === b[index].id);
41
+
42
+ exports.addFiles = addFiles;
43
+ exports.hasFile = hasFile;
44
+ exports.isSameSelection = isSameSelection;
45
+ exports.moveFile = moveFile;
46
+ exports.removeFile = removeFile;
47
+ exports.removeFiles = removeFiles;
48
+ exports.toggleFile = toggleFile;
49
+ //# sourceMappingURL=pickerSelection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pickerSelection.js","sources":["../../../../admin/src/components/AssetPickerDialog/pickerSelection.ts"],"sourcesContent":["import type { File } from '../../../../shared/contracts/files';\n\n/**\n * The picker's selection is the value the field will hold once confirmed:\n * whole `File` objects, in order. Assets already in the field come first, new\n * picks are appended in the order they are clicked.\n */\nexport type PickerSelection = File[];\n\nexport const hasFile = (selection: PickerSelection, id: number) =>\n selection.some((file) => file.id === id);\n\n/**\n * Adds the file, or removes it if it is already there. On a single-value field\n * a new pick replaces whatever was selected.\n */\nexport const toggleFile = (\n selection: PickerSelection,\n file: File,\n { multiple }: { multiple: boolean }\n): PickerSelection => {\n if (hasFile(selection, file.id)) {\n return selection.filter(({ id }) => id !== file.id);\n }\n\n return multiple ? [...selection, file] : [file];\n};\n\n/** Appends every file not already selected, keeping their order (select-all). */\nexport const addFiles = (selection: PickerSelection, files: File[]): PickerSelection => [\n ...selection,\n ...files.filter((file) => !hasFile(selection, file.id)),\n];\n\nexport const removeFile = (selection: PickerSelection, id: number): PickerSelection =>\n selection.filter((file) => file.id !== id);\n\nexport const removeFiles = (selection: PickerSelection, ids: Set<number>): PickerSelection =>\n selection.filter((file) => !ids.has(file.id));\n\n/**\n * Moves one file to where another one is, the others shifting to make room.\n * Unknown ids leave the selection as it is.\n */\nexport const moveFile = (\n selection: PickerSelection,\n activeId: number,\n overId: number\n): PickerSelection => {\n const from = selection.findIndex(({ id }) => id === activeId);\n const to = selection.findIndex(({ id }) => id === overId);\n\n if (from === -1 || to === -1 || from === to) {\n return selection;\n }\n\n const next = [...selection];\n const [file] = next.splice(from, 1);\n next.splice(to, 0, file);\n\n return next;\n};\n\n/** Same files in the same order: confirming would change nothing. */\nexport const isSameSelection = (a: PickerSelection, b: PickerSelection) =>\n a.length === b.length && a.every((file, index) => file.id === b[index].id);\n"],"names":["hasFile","selection","id","some","file","toggleFile","multiple","filter","addFiles","files","removeFile","removeFiles","ids","has","moveFile","activeId","overId","from","findIndex","to","next","splice","isSameSelection","a","b","length","every","index"],"mappings":";;AASO,MAAMA,OAAAA,GAAU,CAACC,SAAAA,EAA4BC,EAAAA,GAClDD,SAAAA,CAAUE,IAAI,CAAC,CAACC,IAAAA,GAASA,IAAAA,CAAKF,EAAE,KAAKA,EAAAA;AAEvC;;;UAIaG,UAAAA,GAAa,CACxBJ,WACAG,IAAAA,EACA,EAAEE,QAAQ,EAAyB,GAAA;AAEnC,IAAA,IAAIN,OAAAA,CAAQC,SAAAA,EAAWG,IAAAA,CAAKF,EAAE,CAAA,EAAG;QAC/B,OAAOD,SAAAA,CAAUM,MAAM,CAAC,CAAC,EAAEL,EAAE,EAAE,GAAKA,EAAAA,KAAOE,IAAAA,CAAKF,EAAE,CAAA;AACpD,IAAA;AAEA,IAAA,OAAOI,QAAAA,GAAW;AAAIL,QAAAA,GAAAA,SAAAA;AAAWG,QAAAA;KAAK,GAAG;AAACA,QAAAA;AAAK,KAAA;AACjD;AAEA,kFACO,MAAMI,QAAAA,GAAW,CAACP,WAA4BQ,KAAAA,GAAmC;AACnFR,QAAAA,GAAAA,SAAAA;WACAQ,KAAAA,CAAMF,MAAM,CAAC,CAACH,IAAAA,GAAS,CAACJ,OAAAA,CAAQC,SAAAA,EAAWG,KAAKF,EAAE,CAAA;;AAGhD,MAAMQ,UAAAA,GAAa,CAACT,SAAAA,EAA4BC,EAAAA,GACrDD,SAAAA,CAAUM,MAAM,CAAC,CAACH,IAAAA,GAASA,IAAAA,CAAKF,EAAE,KAAKA,EAAAA;MAE5BS,WAAAA,GAAc,CAACV,SAAAA,EAA4BW,GAAAA,GACtDX,UAAUM,MAAM,CAAC,CAACH,IAAAA,GAAS,CAACQ,GAAAA,CAAIC,GAAG,CAACT,IAAAA,CAAKF,EAAE,CAAA;AAE7C;;;AAGC,IACM,MAAMY,QAAAA,GAAW,CACtBb,WACAc,QAAAA,EACAC,MAAAA,GAAAA;IAEA,MAAMC,IAAAA,GAAOhB,UAAUiB,SAAS,CAAC,CAAC,EAAEhB,EAAE,EAAE,GAAKA,EAAAA,KAAOa,QAAAA,CAAAA;IACpD,MAAMI,EAAAA,GAAKlB,UAAUiB,SAAS,CAAC,CAAC,EAAEhB,EAAE,EAAE,GAAKA,EAAAA,KAAOc,MAAAA,CAAAA;AAElD,IAAA,IAAIC,SAAS,EAAC,IAAKE,OAAO,EAAC,IAAKF,SAASE,EAAAA,EAAI;QAC3C,OAAOlB,SAAAA;AACT,IAAA;AAEA,IAAA,MAAMmB,IAAAA,GAAO;AAAInB,QAAAA,GAAAA;AAAU,KAAA;AAC3B,IAAA,MAAM,CAACG,IAAAA,CAAK,GAAGgB,IAAAA,CAAKC,MAAM,CAACJ,IAAAA,EAAM,CAAA,CAAA;IACjCG,IAAAA,CAAKC,MAAM,CAACF,EAAAA,EAAI,CAAA,EAAGf,IAAAA,CAAAA;IAEnB,OAAOgB,IAAAA;AACT;AAEA,sEACO,MAAME,eAAAA,GAAkB,CAACC,CAAAA,EAAoBC,CAAAA,GAClDD,CAAAA,CAAEE,MAAM,KAAKD,CAAAA,CAAEC,MAAM,IAAIF,CAAAA,CAAEG,KAAK,CAAC,CAACtB,IAAAA,EAAMuB,KAAAA,GAAUvB,IAAAA,CAAKF,EAAE,KAAKsB,CAAC,CAACG,KAAAA,CAAM,CAACzB,EAAE;;;;;;;;;;"}
@@ -0,0 +1,41 @@
1
+ const hasFile = (selection, id)=>selection.some((file)=>file.id === id);
2
+ /**
3
+ * Adds the file, or removes it if it is already there. On a single-value field
4
+ * a new pick replaces whatever was selected.
5
+ */ const toggleFile = (selection, file, { multiple })=>{
6
+ if (hasFile(selection, file.id)) {
7
+ return selection.filter(({ id })=>id !== file.id);
8
+ }
9
+ return multiple ? [
10
+ ...selection,
11
+ file
12
+ ] : [
13
+ file
14
+ ];
15
+ };
16
+ /** Appends every file not already selected, keeping their order (select-all). */ const addFiles = (selection, files)=>[
17
+ ...selection,
18
+ ...files.filter((file)=>!hasFile(selection, file.id))
19
+ ];
20
+ const removeFile = (selection, id)=>selection.filter((file)=>file.id !== id);
21
+ const removeFiles = (selection, ids)=>selection.filter((file)=>!ids.has(file.id));
22
+ /**
23
+ * Moves one file to where another one is, the others shifting to make room.
24
+ * Unknown ids leave the selection as it is.
25
+ */ const moveFile = (selection, activeId, overId)=>{
26
+ const from = selection.findIndex(({ id })=>id === activeId);
27
+ const to = selection.findIndex(({ id })=>id === overId);
28
+ if (from === -1 || to === -1 || from === to) {
29
+ return selection;
30
+ }
31
+ const next = [
32
+ ...selection
33
+ ];
34
+ const [file] = next.splice(from, 1);
35
+ next.splice(to, 0, file);
36
+ return next;
37
+ };
38
+ /** Same files in the same order: confirming would change nothing. */ const isSameSelection = (a, b)=>a.length === b.length && a.every((file, index)=>file.id === b[index].id);
39
+
40
+ export { addFiles, hasFile, isSameSelection, moveFile, removeFile, removeFiles, toggleFile };
41
+ //# sourceMappingURL=pickerSelection.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pickerSelection.mjs","sources":["../../../../admin/src/components/AssetPickerDialog/pickerSelection.ts"],"sourcesContent":["import type { File } from '../../../../shared/contracts/files';\n\n/**\n * The picker's selection is the value the field will hold once confirmed:\n * whole `File` objects, in order. Assets already in the field come first, new\n * picks are appended in the order they are clicked.\n */\nexport type PickerSelection = File[];\n\nexport const hasFile = (selection: PickerSelection, id: number) =>\n selection.some((file) => file.id === id);\n\n/**\n * Adds the file, or removes it if it is already there. On a single-value field\n * a new pick replaces whatever was selected.\n */\nexport const toggleFile = (\n selection: PickerSelection,\n file: File,\n { multiple }: { multiple: boolean }\n): PickerSelection => {\n if (hasFile(selection, file.id)) {\n return selection.filter(({ id }) => id !== file.id);\n }\n\n return multiple ? [...selection, file] : [file];\n};\n\n/** Appends every file not already selected, keeping their order (select-all). */\nexport const addFiles = (selection: PickerSelection, files: File[]): PickerSelection => [\n ...selection,\n ...files.filter((file) => !hasFile(selection, file.id)),\n];\n\nexport const removeFile = (selection: PickerSelection, id: number): PickerSelection =>\n selection.filter((file) => file.id !== id);\n\nexport const removeFiles = (selection: PickerSelection, ids: Set<number>): PickerSelection =>\n selection.filter((file) => !ids.has(file.id));\n\n/**\n * Moves one file to where another one is, the others shifting to make room.\n * Unknown ids leave the selection as it is.\n */\nexport const moveFile = (\n selection: PickerSelection,\n activeId: number,\n overId: number\n): PickerSelection => {\n const from = selection.findIndex(({ id }) => id === activeId);\n const to = selection.findIndex(({ id }) => id === overId);\n\n if (from === -1 || to === -1 || from === to) {\n return selection;\n }\n\n const next = [...selection];\n const [file] = next.splice(from, 1);\n next.splice(to, 0, file);\n\n return next;\n};\n\n/** Same files in the same order: confirming would change nothing. */\nexport const isSameSelection = (a: PickerSelection, b: PickerSelection) =>\n a.length === b.length && a.every((file, index) => file.id === b[index].id);\n"],"names":["hasFile","selection","id","some","file","toggleFile","multiple","filter","addFiles","files","removeFile","removeFiles","ids","has","moveFile","activeId","overId","from","findIndex","to","next","splice","isSameSelection","a","b","length","every","index"],"mappings":"AASO,MAAMA,OAAAA,GAAU,CAACC,SAAAA,EAA4BC,EAAAA,GAClDD,SAAAA,CAAUE,IAAI,CAAC,CAACC,IAAAA,GAASA,IAAAA,CAAKF,EAAE,KAAKA,EAAAA;AAEvC;;;UAIaG,UAAAA,GAAa,CACxBJ,WACAG,IAAAA,EACA,EAAEE,QAAQ,EAAyB,GAAA;AAEnC,IAAA,IAAIN,OAAAA,CAAQC,SAAAA,EAAWG,IAAAA,CAAKF,EAAE,CAAA,EAAG;QAC/B,OAAOD,SAAAA,CAAUM,MAAM,CAAC,CAAC,EAAEL,EAAE,EAAE,GAAKA,EAAAA,KAAOE,IAAAA,CAAKF,EAAE,CAAA;AACpD,IAAA;AAEA,IAAA,OAAOI,QAAAA,GAAW;AAAIL,QAAAA,GAAAA,SAAAA;AAAWG,QAAAA;KAAK,GAAG;AAACA,QAAAA;AAAK,KAAA;AACjD;AAEA,kFACO,MAAMI,QAAAA,GAAW,CAACP,WAA4BQ,KAAAA,GAAmC;AACnFR,QAAAA,GAAAA,SAAAA;WACAQ,KAAAA,CAAMF,MAAM,CAAC,CAACH,IAAAA,GAAS,CAACJ,OAAAA,CAAQC,SAAAA,EAAWG,KAAKF,EAAE,CAAA;;AAGhD,MAAMQ,UAAAA,GAAa,CAACT,SAAAA,EAA4BC,EAAAA,GACrDD,SAAAA,CAAUM,MAAM,CAAC,CAACH,IAAAA,GAASA,IAAAA,CAAKF,EAAE,KAAKA,EAAAA;MAE5BS,WAAAA,GAAc,CAACV,SAAAA,EAA4BW,GAAAA,GACtDX,UAAUM,MAAM,CAAC,CAACH,IAAAA,GAAS,CAACQ,GAAAA,CAAIC,GAAG,CAACT,IAAAA,CAAKF,EAAE,CAAA;AAE7C;;;AAGC,IACM,MAAMY,QAAAA,GAAW,CACtBb,WACAc,QAAAA,EACAC,MAAAA,GAAAA;IAEA,MAAMC,IAAAA,GAAOhB,UAAUiB,SAAS,CAAC,CAAC,EAAEhB,EAAE,EAAE,GAAKA,EAAAA,KAAOa,QAAAA,CAAAA;IACpD,MAAMI,EAAAA,GAAKlB,UAAUiB,SAAS,CAAC,CAAC,EAAEhB,EAAE,EAAE,GAAKA,EAAAA,KAAOc,MAAAA,CAAAA;AAElD,IAAA,IAAIC,SAAS,EAAC,IAAKE,OAAO,EAAC,IAAKF,SAASE,EAAAA,EAAI;QAC3C,OAAOlB,SAAAA;AACT,IAAA;AAEA,IAAA,MAAMmB,IAAAA,GAAO;AAAInB,QAAAA,GAAAA;AAAU,KAAA;AAC3B,IAAA,MAAM,CAACG,IAAAA,CAAK,GAAGgB,IAAAA,CAAKC,MAAM,CAACJ,IAAAA,EAAM,CAAA,CAAA;IACjCG,IAAAA,CAAKC,MAAM,CAACF,EAAAA,EAAI,CAAA,EAAGf,IAAAA,CAAAA;IAEnB,OAAOgB,IAAAA;AACT;AAEA,sEACO,MAAME,eAAAA,GAAkB,CAACC,CAAAA,EAAoBC,CAAAA,GAClDD,CAAAA,CAAEE,MAAM,KAAKD,CAAAA,CAAEC,MAAM,IAAIF,CAAAA,CAAEG,KAAK,CAAC,CAACtB,IAAAA,EAAMuB,KAAAA,GAAUvB,IAAAA,CAAKF,EAAE,KAAKsB,CAAC,CAACG,KAAAA,CAAM,CAACzB,EAAE;;;;"}
@@ -88,12 +88,15 @@ const DrawerContainer = styledComponents.styled(designSystem.Flex)`
88
88
  width: 100%;
89
89
  padding: ${({ theme })=>theme.spaces[2]};
90
90
  max-width: 100%;
91
- /* Sit just below the overlay token (300) so that:
92
- - popovers (500) and tooltips (1000) rendered from descendant components
93
- surface above the drawer panel,
94
- - AlertDialog overlays (300) and contents (310) opened from inside the
95
- drawer (e.g. the asset details "delete" confirm) cover the drawer. */
96
- z-index: 200;
91
+ /* On the overlay token, so ties resolve by DOM order, as they do between DS
92
+ modals: a drawer opened from inside a modal (e.g. a media field in the
93
+ content manager's relation modal) portals in after it and sits above its
94
+ overlay, while a dialog opened from inside the drawer (e.g. the asset
95
+ details "delete" confirm) portals in after the drawer and covers it.
96
+ Not the modal token (310): a DS dialog's content stacks inside its own
97
+ overlay at 300, so the drawer would cover its own confirmations.
98
+ Popovers (500) and tooltips (1000) still surface above the panel. */
99
+ z-index: ${({ theme })=>theme.zIndices.overlay};
97
100
  overflow: hidden;
98
101
  /* dvh, not vh: anchored to the bottom, a 100vh cap on mobile (visual
99
102
  viewport < 100vh under the URL bar) would push the drawer top off-screen. */
@@ -162,11 +165,13 @@ const CloseIconButton = styledComponents.styled(designSystem.IconButton)`
162
165
  }
163
166
  `;
164
167
  /** Vetoes an outside interaction that would otherwise dismiss the drawer. */ const keepOpen = (event)=>event.preventDefault();
165
- const DrawerBody = /*#__PURE__*/ React__namespace.forwardRef(({ animationDirection, width, maxHeight, onPointerDownOutside = keepOpen, children, ...props }, ref)=>/*#__PURE__*/ jsxRuntime.jsx(Dialog__namespace.Content, {
168
+ const DrawerBody = /*#__PURE__*/ React__namespace.forwardRef(({ animationDirection, width, maxHeight, onPointerDownOutside = keepOpen, onOpenAutoFocus, onCloseAutoFocus, children, ...props }, ref)=>/*#__PURE__*/ jsxRuntime.jsx(Dialog__namespace.Content, {
166
169
  ref: ref,
167
170
  forceMount: true,
168
171
  asChild: true,
169
172
  onPointerDownOutside: onPointerDownOutside,
173
+ onOpenAutoFocus: onOpenAutoFocus,
174
+ onCloseAutoFocus: onCloseAutoFocus,
170
175
  // Non-modal, so focus legitimately moves outside (tabbing past the last
171
176
  // field); only a pointer press should ever dismiss.
172
177
  onFocusOutside: keepOpen,
@@ -1 +1 @@
1
- {"version":3,"file":"Drawer.js","sources":["../../../admin/src/components/Drawer.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport * as Dialog from '@radix-ui/react-dialog';\nimport { Box, ScrollArea, IconButton, Flex, FlexProps } from '@strapi/design-system';\nimport { Cross } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { keyframes, styled } from 'styled-components';\n\n/** Duration of the close animation in ms. Use for timing cleanup (e.g. removing URL params). */\nexport const DRAWER_CLOSE_ANIMATION_MS = 300;\n\n/* -------------------------------------------------------------------------------------------------\n * Animations\n * -----------------------------------------------------------------------------------------------*/\n\n// Direction: up\nconst slideUpFromBottomIn = keyframes`\n from {\n opacity: 0;\n transform: translateY(100%);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n`;\n\nconst slideUpFromBottomOut = keyframes`\n from {\n opacity: 1;\n transform: translateY(0);\n }\n to {\n opacity: 0;\n transform: translateY(100%);\n }\n`;\n\n// Direction: left\nconst slideLeftFromRightIn = keyframes`\n from {\n opacity: 0;\n transform: translateX(100%);\n }\n to {\n opacity: 1;\n transform: translateX(0);\n }\n`;\n\nconst slideLeftFromRightOut = keyframes`\n from {\n opacity: 1;\n transform: translateX(0);\n }\n to {\n opacity: 0;\n transform: translateX(100%);\n }\n`;\n\n/* -------------------------------------------------------------------------------------------------\n * Styled components\n * -----------------------------------------------------------------------------------------------*/\n\ninterface DrawerContainerProps {\n $animationDirection?: DrawerBodyProps['animationDirection'];\n $width?: string;\n $maxHeight?: string;\n}\n\nconst DrawerContainer = styled(Flex)<DrawerContainerProps>`\n flex-direction: column;\n position: fixed;\n bottom: 0;\n /* Mobile: full-bleed sheet. Anchoring to the right at a fixed width left a\n dead gutter on every phone wider than the panel, and the panel only filled\n the screen once the viewport happened to be narrower than it. Below the\n medium breakpoint the panel is the screen; medium+ restores the\n right-anchored rail. */\n left: 0;\n right: 0;\n width: 100%;\n padding: ${({ theme }) => theme.spaces[2]};\n max-width: 100%;\n /* Sit just below the overlay token (300) so that:\n - popovers (500) and tooltips (1000) rendered from descendant components\n surface above the drawer panel,\n - AlertDialog overlays (300) and contents (310) opened from inside the\n drawer (e.g. the asset details \"delete\" confirm) cover the drawer. */\n z-index: 200;\n overflow: hidden;\n /* dvh, not vh: anchored to the bottom, a 100vh cap on mobile (visual\n viewport < 100vh under the URL bar) would push the drawer top off-screen. */\n max-height: ${({ $maxHeight }) => $maxHeight ?? '100dvh'};\n\n ${({ theme }) => theme.breakpoints.medium} {\n left: auto;\n width: ${({ $width }) => $width ?? '400px'};\n }\n\n &:focus {\n outline: none;\n }\n\n @media (prefers-reduced-motion: no-preference) {\n &[data-state='open'] {\n animation: ${({ $animationDirection }) =>\n $animationDirection === 'up' ? slideUpFromBottomIn : slideLeftFromRightIn}\n ${DRAWER_CLOSE_ANIMATION_MS}ms cubic-bezier(0.32, 0.72, 0, 1) forwards;\n }\n\n &[data-state='closed'] {\n animation: ${({ $animationDirection }) =>\n $animationDirection === 'up' ? slideUpFromBottomOut : slideLeftFromRightOut}\n ${DRAWER_CLOSE_ANIMATION_MS}ms cubic-bezier(0.32, 0.72, 0, 1) forwards;\n pointer-events: none;\n }\n }\n`;\n\nconst DrawerContent = styled(Box)`\n display: flex;\n flex-direction: column;\n flex: 1;\n min-height: 0;\n width: 100%;\n background-color: ${({ theme }) => theme.colors.neutral0};\n border-radius: ${({ theme }) => theme.borderRadius};\n box-shadow: ${({ theme }) => theme.shadows.popupShadow};\n overflow: hidden;\n border: 1px solid ${({ theme }) => theme.colors.neutral150};\n`;\n\ninterface CollapsibleContentProps {\n $isVisible: boolean;\n}\n\nconst CollapsibleContent = styled(Box)<CollapsibleContentProps>`\n display: grid;\n flex: 1;\n min-height: 0;\n grid-template-rows: ${({ $isVisible }) => ($isVisible ? '1fr' : '0fr')};\n transition: grid-template-rows 0.3s ease-in-out;\n\n > div {\n overflow: hidden;\n min-height: 0;\n }\n\n /* The scroll area wraps its children in a div styled inline as\n display: table, min-width: 100%. A table box grows to its content, so a\n single unbreakable string (a long file name) widens it past the scrollport\n and the panel gains a horizontal scrollbar — with nothing left to clamp the\n row, the name never truncates. Overriding to a block box makes the\n scrollport the width again, which is what the vertical-only list wants.\n Inline styles, hence the important. */\n [data-radix-scroll-area-viewport] > div {\n display: block !important;\n }\n`;\n\nconst CloseIconButton = styled(IconButton)`\n &:hover {\n background: transparent;\n }\n`;\n\n/* -------------------------------------------------------------------------------------------------\n * Drawer.Body\n * -----------------------------------------------------------------------------------------------*/\n\ntype PointerDownOutsideHandler = NonNullable<Dialog.DialogContentProps['onPointerDownOutside']>;\n\n/** Vetoes an outside interaction that would otherwise dismiss the drawer. */\nconst keepOpen = (event: { preventDefault: () => void }) => event.preventDefault();\n\ninterface DrawerBodyProps extends Omit<FlexProps, 'width' | 'maxHeight'> {\n animationDirection?: 'up' | 'left';\n /** Width of the panel from the medium breakpoint up. Mobile is always full-bleed. */\n width?: string;\n /** Cap on the panel height. Defaults to the dynamic viewport height. */\n maxHeight?: string;\n /**\n * Opt in to dismiss-on-outside-click. Omitted, an outside pointer press never\n * closes the drawer — it must be closed explicitly, as long-running panels\n * like the upload progress dialog need. Passed, the handler can still veto\n * individual presses via `event.preventDefault()`. Content rendered from\n * inside the panel but portaled elsewhere (DS dialogs, popovers, tooltips)\n * never counts as outside — Radix reads the React tree, not the DOM.\n */\n onPointerDownOutside?: PointerDownOutsideHandler;\n children: React.ReactNode;\n}\n\nconst DrawerBody = React.forwardRef<HTMLDivElement, DrawerBodyProps>(\n (\n { animationDirection, width, maxHeight, onPointerDownOutside = keepOpen, children, ...props },\n ref\n ) => (\n <Dialog.Content\n ref={ref}\n forceMount\n asChild\n onPointerDownOutside={onPointerDownOutside}\n // Non-modal, so focus legitimately moves outside (tabbing past the last\n // field); only a pointer press should ever dismiss.\n onFocusOutside={keepOpen}\n data-animation-direction={animationDirection}\n >\n {/* width/maxHeight go through transient props so the DS Flex never emits a\n competing `width` rule that would outrank the mobile full-bleed one. */}\n <DrawerContainer\n $animationDirection={animationDirection}\n $width={width}\n $maxHeight={maxHeight}\n {...props}\n >\n <DrawerContent>{children}</DrawerContent>\n </DrawerContainer>\n </Dialog.Content>\n )\n);\nDrawerBody.displayName = 'DrawerBody';\n\n/* -------------------------------------------------------------------------------------------------\n * Drawer.Root\n * -----------------------------------------------------------------------------------------------*/\n\ninterface DrawerRootProps {\n isVisible?: boolean;\n onClose?: () => void;\n children: React.ReactNode;\n}\n\nconst DrawerRoot = ({ isVisible, onClose, children }: DrawerRootProps): React.ReactElement => (\n <Dialog.Root\n open={isVisible}\n onOpenChange={(nextVisible) => !nextVisible && onClose?.()}\n modal={false}\n >\n <Dialog.Portal>{children}</Dialog.Portal>\n </Dialog.Root>\n);\n\n/* -------------------------------------------------------------------------------------------------\n * Drawer.Content - composable content slot (collapsible when isContentExpanded is used)\n * Contains a scrollable area\n * -----------------------------------------------------------------------------------------------*/\n\ninterface DrawerScrollableContentProps {\n children: React.ReactNode;\n /** When provided, content can collapse/expand (e.g. for minimize). Omit to always show. */\n isContentExpanded?: boolean;\n}\n\nconst DrawerScrollableContent = ({\n children,\n isContentExpanded = true,\n}: DrawerScrollableContentProps) => (\n <CollapsibleContent $isVisible={isContentExpanded} data-collapsed={!isContentExpanded}>\n <ScrollArea>{children}</ScrollArea>\n </CollapsibleContent>\n);\n\n/* -------------------------------------------------------------------------------------------------\n * Drawer.CloseButton - composable close icon button (Cross icon by default)\n * -----------------------------------------------------------------------------------------------*/\n\ninterface DrawerCloseButtonProps extends React.PropsWithChildren {\n onClose: () => void;\n label?: string;\n}\n\nconst DrawerCloseButton = ({ onClose, label, children }: DrawerCloseButtonProps) => {\n const { formatMessage } = useIntl();\n const labelMessage = label ?? formatMessage({ id: 'global.close', defaultMessage: 'Close' });\n return (\n <CloseIconButton onClick={onClose} label={labelMessage} variant=\"ghost\">\n {children ?? <Cross />}\n </CloseIconButton>\n );\n};\n\nconst Drawer = {\n Root: DrawerRoot,\n Body: DrawerBody,\n ScrollableContent: DrawerScrollableContent,\n CloseButton: DrawerCloseButton,\n Title: Dialog.Title,\n Description: Dialog.Description,\n};\n\nexport { Drawer };\n"],"names":["DRAWER_CLOSE_ANIMATION_MS","slideUpFromBottomIn","keyframes","slideUpFromBottomOut","slideLeftFromRightIn","slideLeftFromRightOut","DrawerContainer","styled","Flex","theme","spaces","$maxHeight","breakpoints","medium","$width","$animationDirection","DrawerContent","Box","colors","neutral0","borderRadius","shadows","popupShadow","neutral150","CollapsibleContent","$isVisible","CloseIconButton","IconButton","keepOpen","event","preventDefault","DrawerBody","React","forwardRef","animationDirection","width","maxHeight","onPointerDownOutside","children","props","ref","_jsx","Dialog","Content","forceMount","asChild","onFocusOutside","data-animation-direction","displayName","DrawerRoot","isVisible","onClose","Root","open","onOpenChange","nextVisible","modal","Portal","DrawerScrollableContent","isContentExpanded","data-collapsed","ScrollArea","DrawerCloseButton","label","formatMessage","useIntl","labelMessage","id","defaultMessage","onClick","variant","Cross","Drawer","Body","ScrollableContent","CloseButton","Title","Description"],"mappings":"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"}
1
+ {"version":3,"file":"Drawer.js","sources":["../../../admin/src/components/Drawer.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport * as Dialog from '@radix-ui/react-dialog';\nimport { Box, ScrollArea, IconButton, Flex, FlexProps } from '@strapi/design-system';\nimport { Cross } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { keyframes, styled } from 'styled-components';\n\n/** Duration of the close animation in ms. Use for timing cleanup (e.g. removing URL params). */\nexport const DRAWER_CLOSE_ANIMATION_MS = 300;\n\n/* -------------------------------------------------------------------------------------------------\n * Animations\n * -----------------------------------------------------------------------------------------------*/\n\n// Direction: up\nconst slideUpFromBottomIn = keyframes`\n from {\n opacity: 0;\n transform: translateY(100%);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n`;\n\nconst slideUpFromBottomOut = keyframes`\n from {\n opacity: 1;\n transform: translateY(0);\n }\n to {\n opacity: 0;\n transform: translateY(100%);\n }\n`;\n\n// Direction: left\nconst slideLeftFromRightIn = keyframes`\n from {\n opacity: 0;\n transform: translateX(100%);\n }\n to {\n opacity: 1;\n transform: translateX(0);\n }\n`;\n\nconst slideLeftFromRightOut = keyframes`\n from {\n opacity: 1;\n transform: translateX(0);\n }\n to {\n opacity: 0;\n transform: translateX(100%);\n }\n`;\n\n/* -------------------------------------------------------------------------------------------------\n * Styled components\n * -----------------------------------------------------------------------------------------------*/\n\ninterface DrawerContainerProps {\n $animationDirection?: DrawerBodyProps['animationDirection'];\n $width?: string;\n $maxHeight?: string;\n}\n\nconst DrawerContainer = styled(Flex)<DrawerContainerProps>`\n flex-direction: column;\n position: fixed;\n bottom: 0;\n /* Mobile: full-bleed sheet. Anchoring to the right at a fixed width left a\n dead gutter on every phone wider than the panel, and the panel only filled\n the screen once the viewport happened to be narrower than it. Below the\n medium breakpoint the panel is the screen; medium+ restores the\n right-anchored rail. */\n left: 0;\n right: 0;\n width: 100%;\n padding: ${({ theme }) => theme.spaces[2]};\n max-width: 100%;\n /* On the overlay token, so ties resolve by DOM order, as they do between DS\n modals: a drawer opened from inside a modal (e.g. a media field in the\n content manager's relation modal) portals in after it and sits above its\n overlay, while a dialog opened from inside the drawer (e.g. the asset\n details \"delete\" confirm) portals in after the drawer and covers it.\n Not the modal token (310): a DS dialog's content stacks inside its own\n overlay at 300, so the drawer would cover its own confirmations.\n Popovers (500) and tooltips (1000) still surface above the panel. */\n z-index: ${({ theme }) => theme.zIndices.overlay};\n overflow: hidden;\n /* dvh, not vh: anchored to the bottom, a 100vh cap on mobile (visual\n viewport < 100vh under the URL bar) would push the drawer top off-screen. */\n max-height: ${({ $maxHeight }) => $maxHeight ?? '100dvh'};\n\n ${({ theme }) => theme.breakpoints.medium} {\n left: auto;\n width: ${({ $width }) => $width ?? '400px'};\n }\n\n &:focus {\n outline: none;\n }\n\n @media (prefers-reduced-motion: no-preference) {\n &[data-state='open'] {\n animation: ${({ $animationDirection }) =>\n $animationDirection === 'up' ? slideUpFromBottomIn : slideLeftFromRightIn}\n ${DRAWER_CLOSE_ANIMATION_MS}ms cubic-bezier(0.32, 0.72, 0, 1) forwards;\n }\n\n &[data-state='closed'] {\n animation: ${({ $animationDirection }) =>\n $animationDirection === 'up' ? slideUpFromBottomOut : slideLeftFromRightOut}\n ${DRAWER_CLOSE_ANIMATION_MS}ms cubic-bezier(0.32, 0.72, 0, 1) forwards;\n pointer-events: none;\n }\n }\n`;\n\nconst DrawerContent = styled(Box)`\n display: flex;\n flex-direction: column;\n flex: 1;\n min-height: 0;\n width: 100%;\n background-color: ${({ theme }) => theme.colors.neutral0};\n border-radius: ${({ theme }) => theme.borderRadius};\n box-shadow: ${({ theme }) => theme.shadows.popupShadow};\n overflow: hidden;\n border: 1px solid ${({ theme }) => theme.colors.neutral150};\n`;\n\ninterface CollapsibleContentProps {\n $isVisible: boolean;\n}\n\nconst CollapsibleContent = styled(Box)<CollapsibleContentProps>`\n display: grid;\n flex: 1;\n min-height: 0;\n grid-template-rows: ${({ $isVisible }) => ($isVisible ? '1fr' : '0fr')};\n transition: grid-template-rows 0.3s ease-in-out;\n\n > div {\n overflow: hidden;\n min-height: 0;\n }\n\n /* The scroll area wraps its children in a div styled inline as\n display: table, min-width: 100%. A table box grows to its content, so a\n single unbreakable string (a long file name) widens it past the scrollport\n and the panel gains a horizontal scrollbar — with nothing left to clamp the\n row, the name never truncates. Overriding to a block box makes the\n scrollport the width again, which is what the vertical-only list wants.\n Inline styles, hence the important. */\n [data-radix-scroll-area-viewport] > div {\n display: block !important;\n }\n`;\n\nconst CloseIconButton = styled(IconButton)`\n &:hover {\n background: transparent;\n }\n`;\n\n/* -------------------------------------------------------------------------------------------------\n * Drawer.Body\n * -----------------------------------------------------------------------------------------------*/\n\ntype PointerDownOutsideHandler = NonNullable<Dialog.DialogContentProps['onPointerDownOutside']>;\ntype AutoFocusHandler = NonNullable<Dialog.DialogContentProps['onOpenAutoFocus']>;\n\n/** Vetoes an outside interaction that would otherwise dismiss the drawer. */\nconst keepOpen = (event: { preventDefault: () => void }) => event.preventDefault();\n\ninterface DrawerBodyProps extends Omit<FlexProps, 'width' | 'maxHeight'> {\n animationDirection?: 'up' | 'left';\n /** Width of the panel from the medium breakpoint up. Mobile is always full-bleed. */\n width?: string;\n /** Cap on the panel height. Defaults to the dynamic viewport height. */\n maxHeight?: string;\n /**\n * Opt in to dismiss-on-outside-click. Omitted, an outside pointer press never\n * closes the drawer — it must be closed explicitly, as long-running panels\n * like the upload progress dialog need. Passed, the handler can still veto\n * individual presses via `event.preventDefault()`. Content rendered from\n * inside the panel but portaled elsewhere (DS dialogs, popovers, tooltips)\n * never counts as outside — Radix reads the React tree, not the DOM.\n */\n onPointerDownOutside?: PointerDownOutsideHandler;\n /** Radix's hook as focus moves into the panel on open. */\n onOpenAutoFocus?: AutoFocusHandler;\n /**\n * Radix's hook as the panel gives focus back on close. Opened from state\n * rather than a `Dialog.Trigger`, it has nowhere to send it unless this does.\n */\n onCloseAutoFocus?: AutoFocusHandler;\n children: React.ReactNode;\n}\n\nconst DrawerBody = React.forwardRef<HTMLDivElement, DrawerBodyProps>(\n (\n {\n animationDirection,\n width,\n maxHeight,\n onPointerDownOutside = keepOpen,\n onOpenAutoFocus,\n onCloseAutoFocus,\n children,\n ...props\n },\n ref\n ) => (\n <Dialog.Content\n ref={ref}\n forceMount\n asChild\n onPointerDownOutside={onPointerDownOutside}\n onOpenAutoFocus={onOpenAutoFocus}\n onCloseAutoFocus={onCloseAutoFocus}\n // Non-modal, so focus legitimately moves outside (tabbing past the last\n // field); only a pointer press should ever dismiss.\n onFocusOutside={keepOpen}\n data-animation-direction={animationDirection}\n >\n {/* width/maxHeight go through transient props so the DS Flex never emits a\n competing `width` rule that would outrank the mobile full-bleed one. */}\n <DrawerContainer\n $animationDirection={animationDirection}\n $width={width}\n $maxHeight={maxHeight}\n {...props}\n >\n <DrawerContent>{children}</DrawerContent>\n </DrawerContainer>\n </Dialog.Content>\n )\n);\nDrawerBody.displayName = 'DrawerBody';\n\n/* -------------------------------------------------------------------------------------------------\n * Drawer.Root\n * -----------------------------------------------------------------------------------------------*/\n\ninterface DrawerRootProps {\n isVisible?: boolean;\n onClose?: () => void;\n children: React.ReactNode;\n}\n\nconst DrawerRoot = ({ isVisible, onClose, children }: DrawerRootProps): React.ReactElement => (\n <Dialog.Root\n open={isVisible}\n onOpenChange={(nextVisible) => !nextVisible && onClose?.()}\n modal={false}\n >\n <Dialog.Portal>{children}</Dialog.Portal>\n </Dialog.Root>\n);\n\n/* -------------------------------------------------------------------------------------------------\n * Drawer.Content - composable content slot (collapsible when isContentExpanded is used)\n * Contains a scrollable area\n * -----------------------------------------------------------------------------------------------*/\n\ninterface DrawerScrollableContentProps {\n children: React.ReactNode;\n /** When provided, content can collapse/expand (e.g. for minimize). Omit to always show. */\n isContentExpanded?: boolean;\n}\n\nconst DrawerScrollableContent = ({\n children,\n isContentExpanded = true,\n}: DrawerScrollableContentProps) => (\n <CollapsibleContent $isVisible={isContentExpanded} data-collapsed={!isContentExpanded}>\n <ScrollArea>{children}</ScrollArea>\n </CollapsibleContent>\n);\n\n/* -------------------------------------------------------------------------------------------------\n * Drawer.CloseButton - composable close icon button (Cross icon by default)\n * -----------------------------------------------------------------------------------------------*/\n\ninterface DrawerCloseButtonProps extends React.PropsWithChildren {\n onClose: () => void;\n label?: string;\n}\n\nconst DrawerCloseButton = ({ onClose, label, children }: DrawerCloseButtonProps) => {\n const { formatMessage } = useIntl();\n const labelMessage = label ?? formatMessage({ id: 'global.close', defaultMessage: 'Close' });\n return (\n <CloseIconButton onClick={onClose} label={labelMessage} variant=\"ghost\">\n {children ?? <Cross />}\n </CloseIconButton>\n );\n};\n\nconst Drawer = {\n Root: DrawerRoot,\n Body: DrawerBody,\n ScrollableContent: DrawerScrollableContent,\n CloseButton: DrawerCloseButton,\n Title: Dialog.Title,\n Description: Dialog.Description,\n};\n\nexport { Drawer };\n"],"names":["DRAWER_CLOSE_ANIMATION_MS","slideUpFromBottomIn","keyframes","slideUpFromBottomOut","slideLeftFromRightIn","slideLeftFromRightOut","DrawerContainer","styled","Flex","theme","spaces","zIndices","overlay","$maxHeight","breakpoints","medium","$width","$animationDirection","DrawerContent","Box","colors","neutral0","borderRadius","shadows","popupShadow","neutral150","CollapsibleContent","$isVisible","CloseIconButton","IconButton","keepOpen","event","preventDefault","DrawerBody","React","forwardRef","animationDirection","width","maxHeight","onPointerDownOutside","onOpenAutoFocus","onCloseAutoFocus","children","props","ref","_jsx","Dialog","Content","forceMount","asChild","onFocusOutside","data-animation-direction","displayName","DrawerRoot","isVisible","onClose","Root","open","onOpenChange","nextVisible","modal","Portal","DrawerScrollableContent","isContentExpanded","data-collapsed","ScrollArea","DrawerCloseButton","label","formatMessage","useIntl","labelMessage","id","defaultMessage","onClick","variant","Cross","Drawer","Body","ScrollableContent","CloseButton","Title","Description"],"mappings":"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"}
@@ -65,12 +65,15 @@ const DrawerContainer = styled(Flex)`
65
65
  width: 100%;
66
66
  padding: ${({ theme })=>theme.spaces[2]};
67
67
  max-width: 100%;
68
- /* Sit just below the overlay token (300) so that:
69
- - popovers (500) and tooltips (1000) rendered from descendant components
70
- surface above the drawer panel,
71
- - AlertDialog overlays (300) and contents (310) opened from inside the
72
- drawer (e.g. the asset details "delete" confirm) cover the drawer. */
73
- z-index: 200;
68
+ /* On the overlay token, so ties resolve by DOM order, as they do between DS
69
+ modals: a drawer opened from inside a modal (e.g. a media field in the
70
+ content manager's relation modal) portals in after it and sits above its
71
+ overlay, while a dialog opened from inside the drawer (e.g. the asset
72
+ details "delete" confirm) portals in after the drawer and covers it.
73
+ Not the modal token (310): a DS dialog's content stacks inside its own
74
+ overlay at 300, so the drawer would cover its own confirmations.
75
+ Popovers (500) and tooltips (1000) still surface above the panel. */
76
+ z-index: ${({ theme })=>theme.zIndices.overlay};
74
77
  overflow: hidden;
75
78
  /* dvh, not vh: anchored to the bottom, a 100vh cap on mobile (visual
76
79
  viewport < 100vh under the URL bar) would push the drawer top off-screen. */
@@ -139,11 +142,13 @@ const CloseIconButton = styled(IconButton)`
139
142
  }
140
143
  `;
141
144
  /** Vetoes an outside interaction that would otherwise dismiss the drawer. */ const keepOpen = (event)=>event.preventDefault();
142
- const DrawerBody = /*#__PURE__*/ React.forwardRef(({ animationDirection, width, maxHeight, onPointerDownOutside = keepOpen, children, ...props }, ref)=>/*#__PURE__*/ jsx(Dialog.Content, {
145
+ const DrawerBody = /*#__PURE__*/ React.forwardRef(({ animationDirection, width, maxHeight, onPointerDownOutside = keepOpen, onOpenAutoFocus, onCloseAutoFocus, children, ...props }, ref)=>/*#__PURE__*/ jsx(Dialog.Content, {
143
146
  ref: ref,
144
147
  forceMount: true,
145
148
  asChild: true,
146
149
  onPointerDownOutside: onPointerDownOutside,
150
+ onOpenAutoFocus: onOpenAutoFocus,
151
+ onCloseAutoFocus: onCloseAutoFocus,
147
152
  // Non-modal, so focus legitimately moves outside (tabbing past the last
148
153
  // field); only a pointer press should ever dismiss.
149
154
  onFocusOutside: keepOpen,