@strapi/upload 5.51.1 → 5.51.2

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 (262) hide show
  1. package/dist/admin/components/AssetCard/VideoPreview.js +1 -1
  2. package/dist/admin/components/AssetCard/VideoPreview.js.map +1 -1
  3. package/dist/admin/components/AssetCard/VideoPreview.mjs +1 -1
  4. package/dist/admin/components/AssetCard/VideoPreview.mjs.map +1 -1
  5. package/dist/admin/components/TableList/TableList.js +1 -1
  6. package/dist/admin/components/TableList/TableList.js.map +1 -1
  7. package/dist/admin/components/TableList/TableList.mjs +1 -1
  8. package/dist/admin/components/TableList/TableList.mjs.map +1 -1
  9. package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromUrlForm.js +21 -4
  10. package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromUrlForm.js.map +1 -1
  11. package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromUrlForm.mjs +21 -4
  12. package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromUrlForm.mjs.map +1 -1
  13. package/dist/admin/future/components/Drawer.js +3 -1
  14. package/dist/admin/future/components/Drawer.js.map +1 -1
  15. package/dist/admin/future/components/Drawer.mjs +3 -1
  16. package/dist/admin/future/components/Drawer.mjs.map +1 -1
  17. package/dist/admin/future/components/UploadProgressDialog.js +200 -27
  18. package/dist/admin/future/components/UploadProgressDialog.js.map +1 -1
  19. package/dist/admin/future/components/UploadProgressDialog.mjs +203 -30
  20. package/dist/admin/future/components/UploadProgressDialog.mjs.map +1 -1
  21. package/dist/admin/future/hooks/useMediaLibraryPermissions.js +35 -0
  22. package/dist/admin/future/hooks/useMediaLibraryPermissions.js.map +1 -0
  23. package/dist/admin/future/hooks/useMediaLibraryPermissions.mjs +33 -0
  24. package/dist/admin/future/hooks/useMediaLibraryPermissions.mjs.map +1 -0
  25. package/dist/admin/future/pages/Assets/AssetsPage.js +203 -78
  26. package/dist/admin/future/pages/Assets/AssetsPage.js.map +1 -1
  27. package/dist/admin/future/pages/Assets/AssetsPage.mjs +200 -75
  28. package/dist/admin/future/pages/Assets/AssetsPage.mjs.map +1 -1
  29. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetCropEditor.js +75 -32
  30. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetCropEditor.js.map +1 -1
  31. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetCropEditor.mjs +75 -32
  32. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetCropEditor.mjs.map +1 -1
  33. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js +46 -19
  34. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js.map +1 -1
  35. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs +47 -20
  36. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs.map +1 -1
  37. package/dist/admin/future/pages/Assets/components/AssetsGrid.js +5 -2
  38. package/dist/admin/future/pages/Assets/components/AssetsGrid.js.map +1 -1
  39. package/dist/admin/future/pages/Assets/components/AssetsGrid.mjs +5 -2
  40. package/dist/admin/future/pages/Assets/components/AssetsGrid.mjs.map +1 -1
  41. package/dist/admin/future/pages/Assets/components/AssetsSearchInput.js +100 -0
  42. package/dist/admin/future/pages/Assets/components/AssetsSearchInput.js.map +1 -0
  43. package/dist/admin/future/pages/Assets/components/AssetsSearchInput.mjs +98 -0
  44. package/dist/admin/future/pages/Assets/components/AssetsSearchInput.mjs.map +1 -0
  45. package/dist/admin/future/pages/Assets/components/AssetsTable.js +10 -4
  46. package/dist/admin/future/pages/Assets/components/AssetsTable.js.map +1 -1
  47. package/dist/admin/future/pages/Assets/components/AssetsTable.mjs +10 -4
  48. package/dist/admin/future/pages/Assets/components/AssetsTable.mjs.map +1 -1
  49. package/dist/admin/future/pages/Assets/components/BulkActionsBar.js +140 -22
  50. package/dist/admin/future/pages/Assets/components/BulkActionsBar.js.map +1 -1
  51. package/dist/admin/future/pages/Assets/components/BulkActionsBar.mjs +142 -24
  52. package/dist/admin/future/pages/Assets/components/BulkActionsBar.mjs.map +1 -1
  53. package/dist/admin/future/pages/Assets/components/DateRangeCalendar.js +193 -0
  54. package/dist/admin/future/pages/Assets/components/DateRangeCalendar.js.map +1 -0
  55. package/dist/admin/future/pages/Assets/components/DateRangeCalendar.mjs +191 -0
  56. package/dist/admin/future/pages/Assets/components/DateRangeCalendar.mjs.map +1 -0
  57. package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.js +18 -1
  58. package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.js.map +1 -1
  59. package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.mjs +18 -1
  60. package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.mjs.map +1 -1
  61. package/dist/admin/future/pages/Assets/components/DropZone/UploadDropZoneContext.js +13 -3
  62. package/dist/admin/future/pages/Assets/components/DropZone/UploadDropZoneContext.js.map +1 -1
  63. package/dist/admin/future/pages/Assets/components/DropZone/UploadDropZoneContext.mjs +13 -3
  64. package/dist/admin/future/pages/Assets/components/DropZone/UploadDropZoneContext.mjs.map +1 -1
  65. package/dist/admin/future/pages/Assets/components/EmptyState.js +62 -3
  66. package/dist/admin/future/pages/Assets/components/EmptyState.js.map +1 -1
  67. package/dist/admin/future/pages/Assets/components/EmptyState.mjs +62 -4
  68. package/dist/admin/future/pages/Assets/components/EmptyState.mjs.map +1 -1
  69. package/dist/admin/future/pages/Assets/components/FilterBadges.js +408 -0
  70. package/dist/admin/future/pages/Assets/components/FilterBadges.js.map +1 -0
  71. package/dist/admin/future/pages/Assets/components/FilterBadges.mjs +406 -0
  72. package/dist/admin/future/pages/Assets/components/FilterBadges.mjs.map +1 -0
  73. package/dist/admin/future/pages/Assets/components/FilterMenu.js +273 -0
  74. package/dist/admin/future/pages/Assets/components/FilterMenu.js.map +1 -0
  75. package/dist/admin/future/pages/Assets/components/FilterMenu.mjs +267 -0
  76. package/dist/admin/future/pages/Assets/components/FilterMenu.mjs.map +1 -0
  77. package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.js +76 -19
  78. package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.js.map +1 -1
  79. package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.mjs +78 -21
  80. package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.mjs.map +1 -1
  81. package/dist/admin/future/pages/Assets/components/FolderTree/filterFolderTree.js +33 -0
  82. package/dist/admin/future/pages/Assets/components/FolderTree/filterFolderTree.js.map +1 -0
  83. package/dist/admin/future/pages/Assets/components/FolderTree/filterFolderTree.mjs +31 -0
  84. package/dist/admin/future/pages/Assets/components/FolderTree/filterFolderTree.mjs.map +1 -0
  85. package/dist/admin/future/pages/Assets/components/SortMenu.js +21 -32
  86. package/dist/admin/future/pages/Assets/components/SortMenu.js.map +1 -1
  87. package/dist/admin/future/pages/Assets/components/SortMenu.mjs +22 -33
  88. package/dist/admin/future/pages/Assets/components/SortMenu.mjs.map +1 -1
  89. package/dist/admin/future/pages/Assets/hooks/useAssetSearch.js +40 -0
  90. package/dist/admin/future/pages/Assets/hooks/useAssetSearch.js.map +1 -0
  91. package/dist/admin/future/pages/Assets/hooks/useAssetSearch.mjs +38 -0
  92. package/dist/admin/future/pages/Assets/hooks/useAssetSearch.mjs.map +1 -0
  93. package/dist/admin/future/pages/Assets/hooks/useAssetSelection.js +21 -5
  94. package/dist/admin/future/pages/Assets/hooks/useAssetSelection.js.map +1 -1
  95. package/dist/admin/future/pages/Assets/hooks/useAssetSelection.mjs +21 -5
  96. package/dist/admin/future/pages/Assets/hooks/useAssetSelection.mjs.map +1 -1
  97. package/dist/admin/future/pages/Assets/hooks/useFolderNavigation.js +33 -12
  98. package/dist/admin/future/pages/Assets/hooks/useFolderNavigation.js.map +1 -1
  99. package/dist/admin/future/pages/Assets/hooks/useFolderNavigation.mjs +33 -12
  100. package/dist/admin/future/pages/Assets/hooks/useFolderNavigation.mjs.map +1 -1
  101. package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.js +40 -4
  102. package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.js.map +1 -1
  103. package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.mjs +40 -4
  104. package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.mjs.map +1 -1
  105. package/dist/admin/future/pages/Assets/hooks/useListFilters.js +168 -0
  106. package/dist/admin/future/pages/Assets/hooks/useListFilters.js.map +1 -0
  107. package/dist/admin/future/pages/Assets/hooks/useListFilters.mjs +162 -0
  108. package/dist/admin/future/pages/Assets/hooks/useListFilters.mjs.map +1 -0
  109. package/dist/admin/future/pages/Assets/utils/buildAssetFilters.js +201 -0
  110. package/dist/admin/future/pages/Assets/utils/buildAssetFilters.js.map +1 -0
  111. package/dist/admin/future/pages/Assets/utils/buildAssetFilters.mjs +198 -0
  112. package/dist/admin/future/pages/Assets/utils/buildAssetFilters.mjs.map +1 -0
  113. package/dist/admin/future/pages/Assets/utils/listQueryKey.js +2 -2
  114. package/dist/admin/future/pages/Assets/utils/listQueryKey.js.map +1 -1
  115. package/dist/admin/future/pages/Assets/utils/listQueryKey.mjs +2 -2
  116. package/dist/admin/future/pages/Assets/utils/listQueryKey.mjs.map +1 -1
  117. package/dist/admin/future/services/api.js +163 -28
  118. package/dist/admin/future/services/api.js.map +1 -1
  119. package/dist/admin/future/services/api.mjs +163 -30
  120. package/dist/admin/future/services/api.mjs.map +1 -1
  121. package/dist/admin/future/services/assets.js +29 -17
  122. package/dist/admin/future/services/assets.js.map +1 -1
  123. package/dist/admin/future/services/assets.mjs +29 -17
  124. package/dist/admin/future/services/assets.mjs.map +1 -1
  125. package/dist/admin/future/services/folders.js +29 -17
  126. package/dist/admin/future/services/folders.js.map +1 -1
  127. package/dist/admin/future/services/folders.mjs +29 -17
  128. package/dist/admin/future/services/folders.mjs.map +1 -1
  129. package/dist/admin/future/services/settings.js +10 -3
  130. package/dist/admin/future/services/settings.js.map +1 -1
  131. package/dist/admin/future/services/settings.mjs +10 -3
  132. package/dist/admin/future/services/settings.mjs.map +1 -1
  133. package/dist/admin/future/store/uploadProgress.js +109 -2
  134. package/dist/admin/future/store/uploadProgress.js.map +1 -1
  135. package/dist/admin/future/store/uploadProgress.mjs +105 -3
  136. package/dist/admin/future/store/uploadProgress.mjs.map +1 -1
  137. package/dist/admin/future/utils/searchQueryParam.js +11 -0
  138. package/dist/admin/future/utils/searchQueryParam.js.map +1 -0
  139. package/dist/admin/future/utils/searchQueryParam.mjs +9 -0
  140. package/dist/admin/future/utils/searchQueryParam.mjs.map +1 -0
  141. package/dist/admin/hooks/useSelectionState.js +2 -4
  142. package/dist/admin/hooks/useSelectionState.js.map +1 -1
  143. package/dist/admin/hooks/useSelectionState.mjs +2 -4
  144. package/dist/admin/hooks/useSelectionState.mjs.map +1 -1
  145. package/dist/admin/shared/constants.js +43 -0
  146. package/dist/admin/shared/constants.js.map +1 -0
  147. package/dist/admin/shared/constants.mjs +38 -0
  148. package/dist/admin/shared/constants.mjs.map +1 -0
  149. package/dist/admin/src/future/hooks/useMediaLibraryPermissions.d.ts +21 -0
  150. package/dist/admin/src/future/pages/Assets/components/AssetDetails/AssetCropEditor.d.ts +7 -1
  151. package/dist/admin/src/future/pages/Assets/components/AssetsSearchInput.d.ts +5 -0
  152. package/dist/admin/src/future/pages/Assets/components/BulkActionsBar.d.ts +14 -1
  153. package/dist/admin/src/future/pages/Assets/components/DateRangeCalendar.d.ts +8 -0
  154. package/dist/admin/src/future/pages/Assets/components/DropZone/UploadDropZoneContext.d.ts +8 -1
  155. package/dist/admin/src/future/pages/Assets/components/EmptyState.d.ts +18 -1
  156. package/dist/admin/src/future/pages/Assets/components/FilterBadges.d.ts +6 -0
  157. package/dist/admin/src/future/pages/Assets/components/FilterMenu.d.ts +22 -0
  158. package/dist/admin/src/future/pages/Assets/components/FolderTree/FolderTree.d.ts +13 -4
  159. package/dist/admin/src/future/pages/Assets/components/FolderTree/filterFolderTree.d.ts +16 -0
  160. package/dist/admin/src/future/pages/Assets/components/SortMenu.d.ts +6 -0
  161. package/dist/admin/src/future/pages/Assets/hooks/useAssetSearch.d.ts +12 -0
  162. package/dist/admin/src/future/pages/Assets/hooks/useAssetSelection.d.ts +8 -1
  163. package/dist/admin/src/future/pages/Assets/hooks/useInfiniteAssets.d.ts +13 -3
  164. package/dist/admin/src/future/pages/Assets/hooks/useListFilters.d.ts +69 -0
  165. package/dist/admin/src/future/pages/Assets/utils/buildAssetFilters.d.ts +46 -0
  166. package/dist/admin/src/future/pages/Assets/utils/listQueryKey.d.ts +3 -4
  167. package/dist/admin/src/future/services/api.d.ts +53 -5
  168. package/dist/admin/src/future/services/assets.d.ts +9 -1
  169. package/dist/admin/src/future/services/folders.d.ts +3 -0
  170. package/dist/admin/src/future/services/settings.d.ts +2 -2
  171. package/dist/admin/src/future/store/uploadProgress.d.ts +83 -1
  172. package/dist/admin/src/future/utils/searchQueryParam.d.ts +7 -0
  173. package/dist/admin/src/hooks/useAiAvailability.d.ts +1 -1
  174. package/dist/admin/src/hooks/useEditAsset.d.ts +4 -4
  175. package/dist/admin/src/hooks/useEditFolder.d.ts +4 -4
  176. package/dist/admin/src/hooks/useSettings.d.ts +1 -0
  177. package/dist/admin/src/hooks/useTracking.d.ts +1 -1
  178. package/dist/admin/src/hooks/useUpload.d.ts +1 -1
  179. package/dist/admin/translations/en.json.js +53 -3
  180. package/dist/admin/translations/en.json.js.map +1 -1
  181. package/dist/admin/translations/en.json.mjs +53 -3
  182. package/dist/admin/translations/en.json.mjs.map +1 -1
  183. package/dist/admin/utils/urlYupSchema.js +33 -9
  184. package/dist/admin/utils/urlYupSchema.js.map +1 -1
  185. package/dist/admin/utils/urlYupSchema.mjs +33 -9
  186. package/dist/admin/utils/urlYupSchema.mjs.map +1 -1
  187. package/dist/server/config.js +13 -5
  188. package/dist/server/config.js.map +1 -1
  189. package/dist/server/config.mjs +13 -5
  190. package/dist/server/config.mjs.map +1 -1
  191. package/dist/server/constants.js.map +1 -1
  192. package/dist/server/constants.mjs.map +1 -1
  193. package/dist/server/controllers/admin-file.js +30 -0
  194. package/dist/server/controllers/admin-file.js.map +1 -1
  195. package/dist/server/controllers/admin-file.mjs +30 -0
  196. package/dist/server/controllers/admin-file.mjs.map +1 -1
  197. package/dist/server/controllers/admin-settings.js +20 -2
  198. package/dist/server/controllers/admin-settings.js.map +1 -1
  199. package/dist/server/controllers/admin-settings.mjs +21 -3
  200. package/dist/server/controllers/admin-settings.mjs.map +1 -1
  201. package/dist/server/controllers/content-api.js +1 -2
  202. package/dist/server/controllers/content-api.js.map +1 -1
  203. package/dist/server/controllers/content-api.mjs +2 -2
  204. package/dist/server/controllers/content-api.mjs.map +1 -1
  205. package/dist/server/controllers/validation/admin/ai-metadata.js +12 -0
  206. package/dist/server/controllers/validation/admin/ai-metadata.js.map +1 -0
  207. package/dist/server/controllers/validation/admin/ai-metadata.mjs +10 -0
  208. package/dist/server/controllers/validation/admin/ai-metadata.mjs.map +1 -0
  209. package/dist/server/controllers/validation/admin/settings.js +4 -1
  210. package/dist/server/controllers/validation/admin/settings.js.map +1 -1
  211. package/dist/server/controllers/validation/admin/settings.mjs +1 -1
  212. package/dist/server/controllers/validation/admin/settings.mjs.map +1 -1
  213. package/dist/server/routes/admin.js +18 -0
  214. package/dist/server/routes/admin.js.map +1 -1
  215. package/dist/server/routes/admin.mjs +18 -0
  216. package/dist/server/routes/admin.mjs.map +1 -1
  217. package/dist/server/services/ai-metadata.js +108 -11
  218. package/dist/server/services/ai-metadata.js.map +1 -1
  219. package/dist/server/services/ai-metadata.mjs +108 -11
  220. package/dist/server/services/ai-metadata.mjs.map +1 -1
  221. package/dist/server/services/file.js +86 -13
  222. package/dist/server/services/file.js.map +1 -1
  223. package/dist/server/services/file.mjs +87 -14
  224. package/dist/server/services/file.mjs.map +1 -1
  225. package/dist/server/services/image-manipulation.js +4 -4
  226. package/dist/server/services/image-manipulation.js.map +1 -1
  227. package/dist/server/services/image-manipulation.mjs +4 -4
  228. package/dist/server/services/image-manipulation.mjs.map +1 -1
  229. package/dist/server/shared/constants.js +43 -0
  230. package/dist/server/shared/constants.js.map +1 -0
  231. package/dist/server/shared/constants.mjs +38 -0
  232. package/dist/server/shared/constants.mjs.map +1 -0
  233. package/dist/server/src/config.d.ts +2 -0
  234. package/dist/server/src/config.d.ts.map +1 -1
  235. package/dist/server/src/constants.d.ts +2 -1
  236. package/dist/server/src/constants.d.ts.map +1 -1
  237. package/dist/server/src/controllers/admin-file.d.ts +10 -0
  238. package/dist/server/src/controllers/admin-file.d.ts.map +1 -1
  239. package/dist/server/src/controllers/admin-settings.d.ts.map +1 -1
  240. package/dist/server/src/controllers/index.d.ts +1 -0
  241. package/dist/server/src/controllers/index.d.ts.map +1 -1
  242. package/dist/server/src/controllers/validation/admin/ai-metadata.d.ts +2 -0
  243. package/dist/server/src/controllers/validation/admin/ai-metadata.d.ts.map +1 -0
  244. package/dist/server/src/controllers/validation/admin/settings.d.ts +1 -1
  245. package/dist/server/src/controllers/validation/admin/settings.d.ts.map +1 -1
  246. package/dist/server/src/index.d.ts +7 -1
  247. package/dist/server/src/index.d.ts.map +1 -1
  248. package/dist/server/src/routes/admin.d.ts.map +1 -1
  249. package/dist/server/src/services/ai-metadata.d.ts +19 -0
  250. package/dist/server/src/services/ai-metadata.d.ts.map +1 -1
  251. package/dist/server/src/services/file.d.ts +12 -2
  252. package/dist/server/src/services/file.d.ts.map +1 -1
  253. package/dist/server/src/services/index.d.ts +4 -1
  254. package/dist/server/src/services/index.d.ts.map +1 -1
  255. package/dist/server/src/types.d.ts +3 -0
  256. package/dist/server/src/types.d.ts.map +1 -1
  257. package/dist/shared/constants.d.ts +35 -0
  258. package/dist/shared/constants.d.ts.map +1 -0
  259. package/dist/shared/contracts/files.d.ts +25 -0
  260. package/dist/shared/contracts/files.d.ts.map +1 -1
  261. package/dist/shared/contracts/settings.d.ts +7 -0
  262. package/package.json +7 -7
@@ -1 +1 @@
1
- {"version":3,"file":"AssetsPage.mjs","sources":["../../../../../admin/src/future/pages/Assets/AssetsPage.tsx"],"sourcesContent":["import { useRef, useCallback, useMemo, useState, useEffect, type ChangeEvent } from 'react';\n\nimport * as ToggleGroup from '@radix-ui/react-toggle-group';\nimport { Layouts, useElementOnScreen, usePersistentState } from '@strapi/admin/strapi-admin';\nimport {\n Box,\n Flex,\n Loader,\n MenuItem,\n SimpleMenu,\n Typography,\n VisuallyHidden,\n} from '@strapi/design-system';\nimport { ChevronDown, Files, Folder, GridFour as GridIcon, Link, List } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { styled } from 'styled-components';\n\nimport { useUploadFromUrlsMutation, useUploadFilesMutation } from '../../services/api';\nimport { useGetFolderQuery, useGetFoldersQuery } from '../../services/folders';\nimport { getTranslationKey } from '../../utils/translations';\n\nimport {\n AssetDetailsDrawer,\n useAssetDetailsParam,\n} from './components/AssetDetails/AssetDetailsDrawer';\nimport { AssetsGrid } from './components/AssetsGrid';\nimport { AssetsTable } from './components/AssetsTable';\nimport { BulkActionsBar } from './components/BulkActionsBar';\nimport { CreateFolderDialog } from './components/CreateFolderDialog';\nimport { AssetsDndProvider } from './components/Dnd/AssetsDndProvider';\nimport { DropFilesMessage, DropZoneWithOverlay } from './components/DropZone/UploadDropZone';\nimport { UploadDropZoneProvider } from './components/DropZone/UploadDropZoneContext';\nimport { EmptyState } from './components/EmptyState';\nimport { FolderTree } from './components/FolderTree/FolderTree';\nimport { ImportFromUrlDialog } from './components/ImportFromUrlDialog';\nimport { SortMenu } from './components/SortMenu';\nimport { localStorageKeys, viewOptions } from './constants';\nimport { AssetSelectionProvider, useAssetSelection } from './hooks/useAssetSelection';\nimport { useFolderInfo } from './hooks/useFolderInfo';\nimport { useFolderNavigation } from './hooks/useFolderNavigation';\nimport { useInfiniteAssets } from './hooks/useInfiniteAssets';\nimport { useListSort, type FoldersPosition } from './hooks/useListSort';\nimport { getListQueryKey } from './utils/listQueryKey';\nimport { mergeMixedList } from './utils/mergeMixedList';\n\nimport type { UploadFileInfo } from '../../../../../shared/contracts/files';\n\nconst INTERSECTION_OPTIONS: IntersectionObserverInit = { threshold: 0.1 };\n\n/* -------------------------------------------------------------------------------------------------\n * AssetsView\n * -----------------------------------------------------------------------------------------------*/\n\ninterface AssetsViewProps {\n view: number;\n folderId: number | null;\n assetsSort: string;\n foldersSort: string;\n foldersPosition: FoldersPosition;\n onAssetItemClick: (assetId: number) => void;\n onAddAssets: () => void;\n}\n\nconst AssetsView = ({\n view,\n folderId,\n assetsSort,\n foldersSort,\n foldersPosition,\n onAssetItemClick,\n onAddAssets,\n}: AssetsViewProps) => {\n const { formatMessage } = useIntl();\n const {\n assets,\n isLoading: isLoadingAssets,\n isFetchingMore,\n hasNextPage,\n fetchNextPage,\n error,\n } = useInfiniteAssets({ folder: folderId, sort: assetsSort });\n const { data: folders = [], isLoading: isLoadingFolders } = useGetFoldersQuery({\n parentId: folderId,\n sort: foldersSort,\n });\n\n const isGridView = view === viewOptions.GRID;\n const isLoading = isLoadingAssets || isLoadingFolders;\n\n // \"Folders: Mixed with files\" — interleave the complete folder list into the\n // loaded asset stream client-side, following the active sort. Table view\n // only: the grid always keeps folders in their own band on top.\n const mixedItems = useMemo(\n () =>\n foldersPosition === 'mixed' && !isGridView\n ? mergeMixedList({ folders, assets, sort: assetsSort, hasNextPage })\n : null,\n [foldersPosition, isGridView, folders, assets, assetsSort, hasNextPage]\n );\n\n const loadMoreRef = useElementOnScreen<HTMLDivElement>(\n useCallback(\n (isVisible) => {\n if (isVisible && hasNextPage && !isFetchingMore) {\n fetchNextPage();\n }\n },\n [hasNextPage, isFetchingMore, fetchNextPage]\n ),\n INTERSECTION_OPTIONS\n );\n\n if (isLoading) {\n return (\n <Flex justifyContent=\"center\" padding={8}>\n <Loader>{formatMessage({ id: 'app.loading', defaultMessage: 'Loading...' })}</Loader>\n </Flex>\n );\n }\n\n if (error) {\n return (\n <Box padding={8}>\n <Typography textColor=\"danger600\">\n {formatMessage({\n id: getTranslationKey('list.assets.error'),\n defaultMessage: 'An error occurred while fetching assets.',\n })}\n </Typography>\n </Box>\n );\n }\n\n if (folders.length === 0 && assets.length === 0) {\n return <EmptyState onAddAssets={onAddAssets} />;\n }\n return (\n <>\n {isGridView ? (\n <AssetsGrid folders={folders} assets={assets} onAssetItemClick={onAssetItemClick} />\n ) : (\n <AssetsTable\n assets={assets}\n folders={folders}\n mixedItems={mixedItems}\n onAssetItemClick={onAssetItemClick}\n />\n )}\n <div ref={loadMoreRef} style={{ height: 1 }} />\n {isFetchingMore && (\n <Flex justifyContent=\"center\" padding={4}>\n <Loader>\n {formatMessage({\n id: getTranslationKey('list.assets.loading-more'),\n defaultMessage: 'Loading more assets...',\n })}\n </Loader>\n </Flex>\n )}\n </>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * ClearSelectionOnChange\n *\n * Selection is list-scoped: it resets when the user is looking at a different list.\n * The list fingerprint is getListQueryKey() — folder, search, sort, filter.\n *\n * Hybrid rule: infinite scroll does not change the key (selection persists).\n * Search/sort/filter changes do (selection clears) — same mental model as folder nav.\n * -----------------------------------------------------------------------------------------------*/\n\ninterface ClearSelectionOnChangeProps {\n listQueryKey: string;\n}\n\nconst ClearSelectionOnChange = ({ listQueryKey }: ClearSelectionOnChangeProps) => {\n const { clear } = useAssetSelection();\n\n useEffect(() => {\n clear();\n }, [listQueryKey, clear]);\n\n return null;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * AssetsPage\n * -----------------------------------------------------------------------------------------------*/\n\n/**\n * Mirrors the design-system Toggle look (grey track, white active segment\n * card) — reproduced locally because the DS component is a labels-only\n * boolean input (no icons) and paints its left segment in danger red. Here\n * both segments use the primary blue when active.\n */\nconst StyledToggleGroup = styled(ToggleGroup.Root)`\n display: flex;\n padding: ${({ theme }) => theme.spaces[1]};\n background: ${({ theme }) => theme.colors.neutral100};\n border: 1px solid ${({ theme }) => theme.colors.neutral200};\n border-radius: ${({ theme }) => theme.borderRadius};\n`;\n\nconst StyledToggleItem = styled(ToggleGroup.Item)`\n display: flex;\n flex: 1 1 50%;\n align-items: center;\n justify-content: center;\n gap: ${({ theme }) => theme.spaces[2]};\n padding: 0.6rem ${({ theme }) => theme.spaces[3]};\n border: 1px solid transparent;\n border-radius: ${({ theme }) => theme.borderRadius};\n background: transparent;\n color: ${({ theme }) => theme.colors.neutral600};\n cursor: pointer;\n font-size: ${({ theme }) => theme.fontSizes[1]};\n font-weight: ${({ theme }) => theme.fontWeights.semiBold};\n white-space: nowrap;\n\n &:hover {\n color: ${({ theme }) => theme.colors.neutral700};\n }\n\n &[data-state='on'] {\n background: ${({ theme }) => theme.colors.neutral0};\n border-color: ${({ theme }) => theme.colors.neutral200};\n color: ${({ theme }) => theme.colors.primary600};\n }\n\n svg {\n width: 1.6rem;\n height: 1.6rem;\n }\n`;\n\nconst HeaderWrapper = styled(Box)`\n [data-strapi-header] {\n background: ${({ theme }) => theme.colors.neutral0};\n\n h1 {\n font-size: 1.8rem;\n }\n }\n`;\n\nexport const AssetsPage = () => {\n const { formatMessage } = useIntl();\n const { openDetails } = useAssetDetailsParam();\n\n const { currentFolderId, navigateToFolderId, navigateToRoot } = useFolderNavigation();\n // Deleted or missing folders (404) need a fetch — handled here, not in\n // `useFolderNavigation` (which only strips malformed ?folder= values).\n const { error: currentFolderError } = useGetFolderQuery(\n { id: currentFolderId! },\n { skip: currentFolderId === null }\n );\n\n useEffect(() => {\n if (currentFolderError?.name === 'NotFoundError') {\n navigateToRoot();\n }\n }, [currentFolderError, navigateToRoot]);\n const { title, itemCount } = useFolderInfo(currentFolderId);\n const itemCountLabel = formatMessage(\n {\n id: getTranslationKey('header.content.item-count'),\n defaultMessage: '{count, plural, =1 {# item} other {# items}}',\n },\n { count: itemCount }\n );\n const pageHeaderTitle = title\n ? `${title} (${itemCountLabel})`\n : formatMessage({ id: 'app.loading', defaultMessage: 'Loading...' });\n\n const [isCreateFolderDialogOpen, setIsCreateFolderDialogOpen] = useState(false);\n\n // View state\n const [view, setView] = usePersistentState(localStorageKeys.view, viewOptions.GRID);\n const isGridView = view === viewOptions.GRID;\n\n // Dialog state\n const [isUrlDialogOpen, setIsUrlDialogOpen] = useState(false);\n\n // Refs\n const fileInputRef = useRef<HTMLInputElement>(null);\n const uploadDropZoneRef = useRef<HTMLDivElement>(null);\n\n // Upload handlers\n const [uploadFiles] = useUploadFilesMutation();\n const [uploadFromUrls] = useUploadFromUrlsMutation();\n\n const uploadFilesToFolder = async (files: globalThis.File[], folderId: number | null) => {\n if (files.length === 0) return;\n\n const formData = new FormData();\n const fileInfoArray: UploadFileInfo[] = [];\n\n files.forEach((file) => {\n formData.append('files', file);\n fileInfoArray.push({\n name: file.name,\n caption: null,\n alternativeText: null,\n folder: folderId,\n });\n });\n\n formData.append('fileInfo', JSON.stringify(fileInfoArray));\n try {\n await uploadFiles({ formData, totalFiles: files.length }).unwrap();\n } catch (error) {\n // Error is already dispatched to store from the API queryFn\n }\n };\n\n const handleFileSelect = () => {\n fileInputRef.current?.click();\n };\n\n const handleFileChange = async (e: ChangeEvent<HTMLInputElement>) => {\n const files = e.target.files;\n if (files && files.length > 0) {\n await uploadFilesToFolder(Array.from(files), currentFolderId);\n }\n e.target.value = '';\n };\n\n const handleDrop = async (files: globalThis.File[]) => {\n await uploadFilesToFolder(files, currentFolderId);\n };\n\n const handleUrlUpload = async (urls: string[]) => {\n try {\n await uploadFromUrls({ urls, folderId: currentFolderId }).unwrap();\n } catch (error) {\n // Error is already dispatched to store from the API queryFn\n }\n };\n\n const listSort = useListSort();\n\n // The view is deliberately absent: table and grid render the same list, so\n // toggling views keeps the selection.\n const listQueryKey = getListQueryKey({\n folderId: currentFolderId,\n search: '', // TODO: wire when building header search\n // Folder position changes the render order too — selection must reset.\n sort: `${listSort.assetsSort};folders=${listSort.foldersPosition}`,\n filter: null, // TODO: wire when building header filters\n });\n\n return (\n <>\n <UploadDropZoneProvider onDrop={handleDrop}>\n <AssetSelectionProvider>\n <AssetsDndProvider>\n <ClearSelectionOnChange listQueryKey={listQueryKey} />\n <Box ref={uploadDropZoneRef}>\n <Layouts.Root\n minHeight=\"100vh\"\n background=\"neutral0\"\n sideNav={\n <FolderTree\n currentFolderId={currentFolderId}\n onSelectFolder={navigateToFolderId}\n />\n }\n >\n <VisuallyHidden>\n <input type=\"file\" ref={fileInputRef} onChange={handleFileChange} multiple />\n </VisuallyHidden>\n\n <HeaderWrapper>\n <Layouts.Header\n title={pageHeaderTitle}\n primaryAction={\n <SimpleMenu\n popoverPlacement=\"bottom-end\"\n variant=\"default\"\n endIcon={<ChevronDown />}\n label={formatMessage({\n id: getTranslationKey('new'),\n defaultMessage: 'New',\n })}\n >\n <MenuItem\n onSelect={() => setIsCreateFolderDialogOpen(true)}\n startIcon={<Folder />}\n >\n {formatMessage({\n id: getTranslationKey('folder.create.title'),\n defaultMessage: 'New folder',\n })}\n </MenuItem>\n <MenuItem onSelect={handleFileSelect} startIcon={<Files />}>\n {formatMessage({\n id: getTranslationKey('import-files'),\n defaultMessage: 'Import files',\n })}\n </MenuItem>\n <MenuItem onSelect={() => setIsUrlDialogOpen(true)} startIcon={<Link />}>\n {formatMessage({\n id: getTranslationKey('import-from-url'),\n defaultMessage: 'Import from URL',\n })}\n </MenuItem>\n </SimpleMenu>\n }\n subtitle={\n <Flex justifyContent=\"space-between\" alignItems=\"center\" gap={4} width=\"100%\">\n <Flex gap={4} alignItems=\"center\">\n TODO: Filters and search\n </Flex>\n\n <Flex gap={4} alignItems=\"stretch\">\n <SortMenu sort={listSort} showFoldersGroup={!isGridView} />\n <StyledToggleGroup\n type=\"single\"\n value={isGridView ? 'grid' : 'table'}\n onValueChange={(value) =>\n value &&\n setView(value === 'grid' ? viewOptions.GRID : viewOptions.TABLE)\n }\n aria-label={formatMessage({\n id: getTranslationKey('view.switch.label'),\n defaultMessage: 'View options',\n })}\n >\n <StyledToggleItem\n value=\"table\"\n aria-label={formatMessage({\n id: getTranslationKey('view.table'),\n defaultMessage: 'Table view',\n })}\n >\n <List />\n {formatMessage({\n id: getTranslationKey('view.table'),\n defaultMessage: 'Table view',\n })}\n </StyledToggleItem>\n <StyledToggleItem\n value=\"grid\"\n aria-label={formatMessage({\n id: getTranslationKey('view.grid'),\n defaultMessage: 'Grid view',\n })}\n >\n <GridIcon />\n {formatMessage({\n id: getTranslationKey('view.grid'),\n defaultMessage: 'Grid view',\n })}\n </StyledToggleItem>\n </StyledToggleGroup>\n </Flex>\n </Flex>\n }\n />\n </HeaderWrapper>\n\n <Layouts.Content>\n <DropZoneWithOverlay>\n <DropFilesMessage uploadDropZoneRef={uploadDropZoneRef} folderName={title} />\n <AssetsView\n view={view}\n folderId={currentFolderId}\n assetsSort={listSort.assetsSort}\n foldersSort={listSort.foldersSort}\n foldersPosition={listSort.foldersPosition}\n onAssetItemClick={openDetails}\n onAddAssets={handleFileSelect}\n />\n </DropZoneWithOverlay>\n </Layouts.Content>\n </Layouts.Root>\n </Box>\n <BulkActionsBar />\n </AssetsDndProvider>\n </AssetSelectionProvider>\n </UploadDropZoneProvider>\n <CreateFolderDialog\n open={isCreateFolderDialogOpen}\n folderName={title}\n parentFolderId={currentFolderId}\n onClose={() => setIsCreateFolderDialogOpen(false)}\n />\n <ImportFromUrlDialog\n open={isUrlDialogOpen}\n onClose={() => setIsUrlDialogOpen(false)}\n onUpload={handleUrlUpload}\n />\n <AssetDetailsDrawer />\n </>\n );\n};\n"],"names":["INTERSECTION_OPTIONS","threshold","AssetsView","view","folderId","assetsSort","foldersSort","foldersPosition","onAssetItemClick","onAddAssets","formatMessage","useIntl","assets","isLoading","isLoadingAssets","isFetchingMore","hasNextPage","fetchNextPage","error","useInfiniteAssets","folder","sort","data","folders","isLoadingFolders","useGetFoldersQuery","parentId","isGridView","viewOptions","GRID","mixedItems","useMemo","mergeMixedList","loadMoreRef","useElementOnScreen","useCallback","isVisible","_jsx","Flex","justifyContent","padding","Loader","id","defaultMessage","Box","Typography","textColor","getTranslationKey","length","EmptyState","_jsxs","_Fragment","AssetsGrid","AssetsTable","div","ref","style","height","ClearSelectionOnChange","listQueryKey","clear","useAssetSelection","useEffect","StyledToggleGroup","styled","ToggleGroup","Root","theme","spaces","colors","neutral100","neutral200","borderRadius","StyledToggleItem","Item","neutral600","fontSizes","fontWeights","semiBold","neutral700","neutral0","primary600","HeaderWrapper","AssetsPage","openDetails","useAssetDetailsParam","currentFolderId","navigateToFolderId","navigateToRoot","useFolderNavigation","currentFolderError","useGetFolderQuery","skip","name","title","itemCount","useFolderInfo","itemCountLabel","count","pageHeaderTitle","isCreateFolderDialogOpen","setIsCreateFolderDialogOpen","useState","setView","usePersistentState","localStorageKeys","isUrlDialogOpen","setIsUrlDialogOpen","fileInputRef","useRef","uploadDropZoneRef","uploadFiles","useUploadFilesMutation","uploadFromUrls","useUploadFromUrlsMutation","uploadFilesToFolder","files","formData","FormData","fileInfoArray","forEach","file","append","push","caption","alternativeText","JSON","stringify","totalFiles","unwrap","handleFileSelect","current","click","handleFileChange","e","target","Array","from","value","handleDrop","handleUrlUpload","urls","listSort","useListSort","getListQueryKey","search","filter","UploadDropZoneProvider","onDrop","AssetSelectionProvider","AssetsDndProvider","Layouts","minHeight","background","sideNav","FolderTree","onSelectFolder","VisuallyHidden","input","type","onChange","multiple","Header","primaryAction","SimpleMenu","popoverPlacement","variant","endIcon","ChevronDown","label","MenuItem","onSelect","startIcon","Folder","Files","Link","subtitle","alignItems","gap","width","SortMenu","showFoldersGroup","onValueChange","TABLE","aria-label","List","GridIcon","Content","DropZoneWithOverlay","DropFilesMessage","folderName","BulkActionsBar","CreateFolderDialog","open","parentFolderId","onClose","ImportFromUrlDialog","onUpload","AssetDetailsDrawer"],"mappings":"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"}
1
+ {"version":3,"file":"AssetsPage.mjs","sources":["../../../../../admin/src/future/pages/Assets/AssetsPage.tsx"],"sourcesContent":["import { useRef, useCallback, useMemo, useState, useEffect, type ChangeEvent } from 'react';\n\nimport * as ToggleGroup from '@radix-ui/react-toggle-group';\nimport { Layouts, useElementOnScreen, usePersistentState } from '@strapi/admin/strapi-admin';\nimport {\n Box,\n Flex,\n Loader,\n MenuItem,\n SimpleMenu,\n Typography,\n VisuallyHidden,\n} from '@strapi/design-system';\nimport {\n ChevronDown,\n Files,\n Folder as FolderIcon,\n GridFour as GridIcon,\n Link,\n List,\n} from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { styled } from 'styled-components';\n\nimport { useAIAvailability } from '../../../hooks/useAiAvailability';\nimport { useMediaLibraryPermissions } from '../../hooks/useMediaLibraryPermissions';\nimport { useUploadFromUrlsMutation, useUploadFilesMutation } from '../../services/api';\nimport { useGetFolderQuery, useGetFoldersQuery } from '../../services/folders';\nimport { useGetUploadSettingsQuery } from '../../services/settings';\nimport { getTranslationKey } from '../../utils/translations';\n\nimport {\n AssetDetailsDrawer,\n useAssetDetailsParam,\n} from './components/AssetDetails/AssetDetailsDrawer';\nimport { AssetsGrid } from './components/AssetsGrid';\nimport { AssetsSearchInput } from './components/AssetsSearchInput';\nimport { AssetsTable } from './components/AssetsTable';\nimport { BulkActionsBar } from './components/BulkActionsBar';\nimport { CreateFolderDialog } from './components/CreateFolderDialog';\nimport { AssetsDndProvider } from './components/Dnd/AssetsDndProvider';\nimport { DropFilesMessage, DropZoneWithOverlay } from './components/DropZone/UploadDropZone';\nimport { UploadDropZoneProvider } from './components/DropZone/UploadDropZoneContext';\nimport { EmptyState, FilteredEmptyState } from './components/EmptyState';\nimport { FilterBadges } from './components/FilterBadges';\nimport { FilterMenu } from './components/FilterMenu';\nimport { FolderTree } from './components/FolderTree/FolderTree';\nimport { ImportFromUrlDialog } from './components/ImportFromUrlDialog';\nimport { SortMenu } from './components/SortMenu';\nimport { localStorageKeys, viewOptions } from './constants';\nimport { useAssetSearch } from './hooks/useAssetSearch';\nimport { AssetSelectionProvider, useAssetSelection } from './hooks/useAssetSelection';\nimport { useFolderInfo } from './hooks/useFolderInfo';\nimport { useFolderNavigation } from './hooks/useFolderNavigation';\nimport { useInfiniteAssets } from './hooks/useInfiniteAssets';\nimport { useListFilters } from './hooks/useListFilters';\nimport { useListSort, type FoldersPosition } from './hooks/useListSort';\nimport { buildAssetFilters } from './utils/buildAssetFilters';\nimport { getListQueryKey } from './utils/listQueryKey';\nimport { mergeMixedList } from './utils/mergeMixedList';\n\nimport type { File, UploadFileInfo } from '../../../../../shared/contracts/files';\nimport type { Folder } from '../../../../../shared/contracts/folders';\n\nconst INTERSECTION_OPTIONS: IntersectionObserverInit = { threshold: 0.1 };\n\nconst ITEM_COUNT_MESSAGE = {\n id: getTranslationKey('header.content.item-count'),\n defaultMessage: '{count, plural, =1 {# item} other {# items}}',\n};\n\nconst SEARCH_RESULTS_COUNT_MESSAGES = {\n both: {\n id: getTranslationKey('header.search-results.count'),\n defaultMessage:\n '{numberFolders, plural, one {1 folder} other {# folders}} - {numberAssets, plural, one {1 asset} other {# assets}}',\n },\n folders: {\n id: getTranslationKey('header.search-results.count.folders'),\n defaultMessage: '{numberFolders, plural, one {1 folder} other {# folders}}',\n },\n assets: {\n id: getTranslationKey('header.search-results.count.assets'),\n defaultMessage: '{numberAssets, plural, =0 {0 assets} one {1 asset} other {# assets}}',\n },\n};\n\nconst getSearchResultsCountMessage = (numberFolders: number, numberAssets: number) => {\n if (numberFolders === 0) {\n return SEARCH_RESULTS_COUNT_MESSAGES.assets;\n }\n\n if (numberAssets === 0) {\n return SEARCH_RESULTS_COUNT_MESSAGES.folders;\n }\n\n return SEARCH_RESULTS_COUNT_MESSAGES.both;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * AssetsView\n * -----------------------------------------------------------------------------------------------*/\n\ninterface AssetsViewProps {\n view: number;\n folders: Folder[];\n isLoadingFolders: boolean;\n assets: File[];\n isLoadingAssets: boolean;\n isFetchingMore: boolean;\n hasNextPage: boolean;\n fetchNextPage: () => void;\n error: unknown;\n searchQuery: string;\n assetsSort: string;\n foldersPosition: FoldersPosition;\n hasActiveFilters: boolean;\n onClearFilters: () => void;\n onAssetItemClick: (assetId: number) => void;\n onAddAssets: () => void;\n canAddAssets: boolean;\n onClearSearch: () => void;\n}\n\nconst AssetsView = ({\n view,\n folders,\n isLoadingFolders,\n assets,\n isLoadingAssets,\n isFetchingMore,\n hasNextPage,\n fetchNextPage,\n error,\n searchQuery,\n assetsSort,\n foldersPosition,\n hasActiveFilters,\n onClearFilters,\n onAssetItemClick,\n onAddAssets,\n canAddAssets,\n onClearSearch,\n}: AssetsViewProps) => {\n const { formatMessage } = useIntl();\n\n const isGridView = view === viewOptions.GRID;\n const isLoading = isLoadingAssets || isLoadingFolders;\n\n // \"Folders: Mixed with files\" — interleave the complete folder list into the\n // loaded asset stream client-side, following the active sort. Table view\n // only: the grid always keeps folders in their own band on top.\n const mixedItems = useMemo(\n () =>\n foldersPosition === 'mixed' && !isGridView\n ? mergeMixedList({ folders, assets, sort: assetsSort, hasNextPage })\n : null,\n [foldersPosition, isGridView, folders, assets, assetsSort, hasNextPage]\n );\n\n const loadMoreRef = useElementOnScreen<HTMLDivElement>(\n useCallback(\n (isVisible) => {\n if (isVisible && hasNextPage && !isFetchingMore) {\n fetchNextPage();\n }\n },\n [hasNextPage, isFetchingMore, fetchNextPage]\n ),\n INTERSECTION_OPTIONS\n );\n\n if (isLoading) {\n return (\n <Flex justifyContent=\"center\" padding={8}>\n <Loader>{formatMessage({ id: 'app.loading', defaultMessage: 'Loading...' })}</Loader>\n </Flex>\n );\n }\n\n if (error) {\n return (\n <Box padding={8}>\n <Typography textColor=\"danger600\">\n {formatMessage({\n id: getTranslationKey('list.assets.error'),\n defaultMessage: 'An error occurred while fetching assets.',\n })}\n </Typography>\n </Box>\n );\n }\n\n if (folders.length === 0 && assets.length === 0) {\n // While searching, the search empty state wins (it names the query); a\n // filter-only dead end gets the filtered variant with its Clear action.\n return hasActiveFilters && !searchQuery ? (\n <FilteredEmptyState onClearFilters={onClearFilters} />\n ) : (\n <EmptyState\n onAddAssets={onAddAssets}\n canAddAssets={canAddAssets}\n searchQuery={searchQuery}\n onClearSearch={onClearSearch}\n />\n );\n }\n return (\n <>\n {isGridView ? (\n <AssetsGrid folders={folders} assets={assets} onAssetItemClick={onAssetItemClick} />\n ) : (\n <AssetsTable\n assets={assets}\n folders={folders}\n mixedItems={mixedItems}\n onAssetItemClick={onAssetItemClick}\n />\n )}\n <div ref={loadMoreRef} style={{ height: 1 }} />\n {isFetchingMore && (\n <Flex justifyContent=\"center\" padding={4}>\n <Loader>\n {formatMessage({\n id: getTranslationKey('list.assets.loading-more'),\n defaultMessage: 'Loading more assets...',\n })}\n </Loader>\n </Flex>\n )}\n {/* Lives here rather than in `AssetsPage` so it can read the loaded\n assets: the AI metadata action needs their mime types to know what\n the provider can handle. `position: fixed` keeps it visually anchored\n regardless of where it sits in the tree. */}\n <BulkActionsBar assets={assets} />\n </>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * ClearSelectionOnChange\n *\n * Selection is list-scoped: it resets when the user is looking at a different list.\n * The list fingerprint is getListQueryKey() — folder, search, sort, filter.\n *\n * Hybrid rule: infinite scroll does not change the key (selection persists), and\n * neither does the table/grid toggle — both views render the same list.\n * Search/sort/filter changes do (selection clears) — same mental model as folder nav.\n * -----------------------------------------------------------------------------------------------*/\n\ninterface ClearSelectionOnChangeProps {\n listQueryKey: string;\n}\n\nconst ClearSelectionOnChange = ({ listQueryKey }: ClearSelectionOnChangeProps) => {\n const { clear } = useAssetSelection();\n\n useEffect(() => {\n clear();\n }, [listQueryKey, clear]);\n\n return null;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * AssetsPage\n * -----------------------------------------------------------------------------------------------*/\n\n/**\n * Mirrors the design-system Toggle look (grey track, white active segment\n * card) — reproduced locally because the DS component is a labels-only\n * boolean input (no icons) and paints its left segment in danger red. Here\n * both segments use the primary blue when active.\n */\nconst StyledToggleGroup = styled(ToggleGroup.Root)`\n display: flex;\n padding: ${({ theme }) => theme.spaces[1]};\n background: ${({ theme }) => theme.colors.neutral100};\n border: 1px solid ${({ theme }) => theme.colors.neutral200};\n border-radius: ${({ theme }) => theme.borderRadius};\n`;\n\nconst StyledToggleItem = styled(ToggleGroup.Item)`\n display: flex;\n flex: 1 1 50%;\n align-items: center;\n justify-content: center;\n gap: ${({ theme }) => theme.spaces[2]};\n padding: 0.6rem ${({ theme }) => theme.spaces[3]};\n border: 1px solid transparent;\n border-radius: ${({ theme }) => theme.borderRadius};\n background: transparent;\n color: ${({ theme }) => theme.colors.neutral600};\n cursor: pointer;\n font-size: ${({ theme }) => theme.fontSizes[1]};\n font-weight: ${({ theme }) => theme.fontWeights.semiBold};\n white-space: nowrap;\n\n &:hover {\n color: ${({ theme }) => theme.colors.neutral700};\n }\n\n &[data-state='on'] {\n background: ${({ theme }) => theme.colors.neutral0};\n border-color: ${({ theme }) => theme.colors.neutral200};\n color: ${({ theme }) => theme.colors.primary600};\n }\n\n svg {\n width: 1.6rem;\n height: 1.6rem;\n }\n`;\n\nconst HeaderWrapper = styled(Box)`\n [data-strapi-header] {\n background: ${({ theme }) => theme.colors.neutral0};\n\n h1 {\n font-size: 1.8rem;\n }\n }\n`;\n\nexport const AssetsPage = () => {\n const { formatMessage } = useIntl();\n const { openDetails } = useAssetDetailsParam();\n const { canCreate, canUpdate } = useMediaLibraryPermissions();\n\n const { currentFolderId, navigateToFolderId, navigateToRoot } = useFolderNavigation();\n // Deleted or missing folders (404) need a fetch — handled here, not in\n // `useFolderNavigation` (which only strips malformed ?folder= values).\n const { error: currentFolderError } = useGetFolderQuery(\n { id: currentFolderId! },\n { skip: currentFolderId === null }\n );\n\n useEffect(() => {\n if (currentFolderError?.name === 'NotFoundError') {\n navigateToRoot();\n }\n }, [currentFolderError, navigateToRoot]);\n const { title, itemCount } = useFolderInfo(currentFolderId);\n\n const { searchQuery, isSearching, clearSearch } = useAssetSearch();\n const listSort = useListSort();\n const listFilters = useListFilters();\n\n // Resolve relative presets against \"now\" only when the filters change —\n // keeps the query args (and RTK cache keys) stable between renders.\n const builtFilters = useMemo(\n () => buildAssetFilters(listFilters.filters, new Date()),\n // eslint-disable-next-line react-hooks/exhaustive-deps -- serialized is the value identity of filters\n [listFilters.serialized]\n );\n\n const {\n assets,\n pagination,\n isLoading: isLoadingAssets,\n isFetchingMore,\n hasNextPage,\n fetchNextPage,\n error: assetsError,\n } = useInfiniteAssets({\n // The real folder is passed even while searching: the service drops the folder\n // filter when `search` is set, so results are still global. List filters\n // compose with both modes.\n folder: currentFolderId,\n search: searchQuery || undefined,\n sort: listSort.assetsSort,\n filters: builtFilters.fileClauses,\n filtersKey: listFilters.serialized,\n enabled: builtFilters.showFiles,\n });\n\n const { data: fetchedFolders = [], isLoading: isLoadingFolders } = useGetFoldersQuery(\n {\n parentId: currentFolderId,\n search: searchQuery || undefined,\n sort: listSort.foldersSort,\n filters: builtFilters.folderClauses,\n },\n { skip: !builtFilters.showFolders }\n );\n // A type badge can exclude folders structurally (e.g. \"Type is Picture\").\n const folders = useMemo(\n () => (builtFilters.showFolders ? fetchedFolders : []),\n [builtFilters.showFolders, fetchedFolders]\n );\n\n const itemCountLabel = formatMessage(ITEM_COUNT_MESSAGE, { count: itemCount });\n\n const searchResultsTitle = formatMessage(\n {\n id: getTranslationKey('header.search-results'),\n defaultMessage: 'Search results for \"{query}\"',\n },\n { query: searchQuery }\n );\n const numberFolders = folders.length;\n const numberAssets = pagination?.total ?? 0;\n\n const searchResultsCountLabel = formatMessage(\n getSearchResultsCountMessage(numberFolders, numberAssets),\n { numberFolders, numberAssets }\n );\n\n let pageHeaderTitle: string;\n if (isSearching) {\n pageHeaderTitle = `${searchResultsTitle} (${searchResultsCountLabel})`;\n } else if (title) {\n pageHeaderTitle = `${title} (${itemCountLabel})`;\n } else {\n pageHeaderTitle = formatMessage({ id: 'app.loading', defaultMessage: 'Loading...' });\n }\n\n const [isCreateFolderDialogOpen, setIsCreateFolderDialogOpen] = useState(false);\n\n // View state\n const [view, setView] = usePersistentState(localStorageKeys.view, viewOptions.GRID);\n const isGridView = view === viewOptions.GRID;\n\n // Dialog state\n const [isUrlDialogOpen, setIsUrlDialogOpen] = useState(false);\n\n // Refs\n const fileInputRef = useRef<HTMLInputElement>(null);\n const uploadDropZoneRef = useRef<HTMLDivElement>(null);\n\n // Upload handlers\n const [uploadFiles] = useUploadFilesMutation();\n const [uploadFromUrls] = useUploadFromUrlsMutation();\n // `concurrentUploadRequests` echoes the app config. Missing settings (still\n // loading, no permission) fall back to sequential — never faster than the\n // server asked for.\n const { data: settings } = useGetUploadSettingsQuery();\n const concurrency = settings?.data?.concurrentUploadRequests ?? 1;\n // Drives the post-upload AI metadata phase shown per row in the progress dialog.\n const { isEnabled: isAiMetadataEnabled } = useAIAvailability();\n\n const uploadFilesToFolder = async (files: globalThis.File[], folderId: number | null) => {\n if (files.length === 0) return;\n\n const formData = new FormData();\n const fileInfoArray: UploadFileInfo[] = [];\n\n files.forEach((file) => {\n formData.append('files', file);\n fileInfoArray.push({\n name: file.name,\n caption: null,\n alternativeText: null,\n folder: folderId,\n });\n });\n\n formData.append('fileInfo', JSON.stringify(fileInfoArray));\n try {\n await uploadFiles({\n formData,\n totalFiles: files.length,\n concurrency,\n generateAiMetadata: Boolean(isAiMetadataEnabled),\n }).unwrap();\n } catch {\n // Error is already dispatched to store from the API queryFn\n }\n };\n\n const handleFileSelect = () => {\n fileInputRef.current?.click();\n };\n\n const handleFileChange = async (e: ChangeEvent<HTMLInputElement>) => {\n const files = e.target.files;\n if (files && files.length > 0) {\n await uploadFilesToFolder(Array.from(files), currentFolderId);\n }\n e.target.value = '';\n };\n\n const handleDrop = async (files: globalThis.File[]) => {\n // Defence in depth: the provider is `disabled` without `assets.create`\n // (so onDrop won't fire), but guard here too in case it's ever wired live.\n if (!canCreate) return;\n await uploadFilesToFolder(files, currentFolderId);\n };\n\n const handleUrlUpload = async (urls: string[]) => {\n try {\n await uploadFromUrls({\n urls,\n folderId: currentFolderId,\n generateAiMetadata: Boolean(isAiMetadataEnabled),\n }).unwrap();\n } catch {\n // Error is already dispatched to store from the API queryFn\n }\n };\n\n // The view is deliberately absent: table and grid render the same list, so\n // toggling views keeps the selection.\n const listQueryKey = getListQueryKey({\n folderId: currentFolderId,\n search: searchQuery,\n // Folder position changes the render order too — selection must reset.\n sort: `${listSort.assetsSort};folders=${listSort.foldersPosition}`,\n filter: listFilters.serialized || null,\n });\n\n return (\n <>\n <UploadDropZoneProvider onDrop={handleDrop} disabled={!canCreate}>\n <AssetSelectionProvider disabled={!canUpdate}>\n <AssetsDndProvider>\n <ClearSelectionOnChange listQueryKey={listQueryKey} />\n <Box ref={uploadDropZoneRef}>\n <Layouts.Root\n minHeight=\"100vh\"\n background=\"neutral0\"\n sideNav={\n <FolderTree\n currentFolderId={currentFolderId}\n showActiveFolder={!isSearching}\n onSelectFolder={navigateToFolderId}\n />\n }\n >\n <VisuallyHidden>\n <input type=\"file\" ref={fileInputRef} onChange={handleFileChange} multiple />\n </VisuallyHidden>\n\n <HeaderWrapper>\n <Layouts.Header\n title={pageHeaderTitle}\n primaryAction={\n canCreate && (\n <SimpleMenu\n popoverPlacement=\"bottom-end\"\n variant=\"default\"\n endIcon={<ChevronDown />}\n label={formatMessage({\n id: getTranslationKey('new'),\n defaultMessage: 'New',\n })}\n >\n <MenuItem\n onSelect={() => setIsCreateFolderDialogOpen(true)}\n startIcon={<FolderIcon />}\n >\n {formatMessage({\n id: getTranslationKey('folder.create.title'),\n defaultMessage: 'New folder',\n })}\n </MenuItem>\n <MenuItem onSelect={handleFileSelect} startIcon={<Files />}>\n {formatMessage({\n id: getTranslationKey('import-files'),\n defaultMessage: 'Import files',\n })}\n </MenuItem>\n <MenuItem onSelect={() => setIsUrlDialogOpen(true)} startIcon={<Link />}>\n {formatMessage({\n id: getTranslationKey('import-from-url'),\n defaultMessage: 'Import from URL',\n })}\n </MenuItem>\n </SimpleMenu>\n )\n }\n subtitle={\n <>\n <Flex\n justifyContent=\"space-between\"\n alignItems=\"center\"\n gap={4}\n width=\"100%\"\n >\n <Flex gap={4} alignItems=\"center\">\n <FilterMenu listFilters={listFilters} />\n <AssetsSearchInput />\n </Flex>\n\n <Flex gap={4} alignItems=\"center\">\n <SortMenu sort={listSort} showFoldersGroup={!isGridView} />\n <StyledToggleGroup\n type=\"single\"\n value={isGridView ? 'grid' : 'table'}\n onValueChange={(value) =>\n value &&\n setView(value === 'grid' ? viewOptions.GRID : viewOptions.TABLE)\n }\n aria-label={formatMessage({\n id: getTranslationKey('view.switch.label'),\n defaultMessage: 'View options',\n })}\n >\n <StyledToggleItem\n value=\"table\"\n aria-label={formatMessage({\n id: getTranslationKey('view.table'),\n defaultMessage: 'Table view',\n })}\n >\n <List />\n {formatMessage({\n id: getTranslationKey('view.table'),\n defaultMessage: 'Table view',\n })}\n </StyledToggleItem>\n <StyledToggleItem\n value=\"grid\"\n aria-label={formatMessage({\n id: getTranslationKey('view.grid'),\n defaultMessage: 'Grid view',\n })}\n >\n <GridIcon />\n {formatMessage({\n id: getTranslationKey('view.grid'),\n defaultMessage: 'Grid view',\n })}\n </StyledToggleItem>\n </StyledToggleGroup>\n </Flex>\n </Flex>\n <FilterBadges listFilters={listFilters} />\n </>\n }\n />\n </HeaderWrapper>\n\n <Layouts.Content>\n <DropZoneWithOverlay>\n <DropFilesMessage uploadDropZoneRef={uploadDropZoneRef} folderName={title} />\n <AssetsView\n view={view}\n folders={folders}\n isLoadingFolders={isLoadingFolders}\n assets={assets}\n isLoadingAssets={isLoadingAssets}\n isFetchingMore={isFetchingMore}\n hasNextPage={hasNextPage}\n fetchNextPage={fetchNextPage}\n error={assetsError}\n searchQuery={searchQuery}\n assetsSort={listSort.assetsSort}\n foldersPosition={listSort.foldersPosition}\n hasActiveFilters={listFilters.filters.length > 0}\n onClearFilters={listFilters.clearFilters}\n onAssetItemClick={openDetails}\n onAddAssets={handleFileSelect}\n canAddAssets={canCreate}\n onClearSearch={clearSearch}\n />\n </DropZoneWithOverlay>\n </Layouts.Content>\n </Layouts.Root>\n </Box>\n </AssetsDndProvider>\n </AssetSelectionProvider>\n </UploadDropZoneProvider>\n <CreateFolderDialog\n open={isCreateFolderDialogOpen}\n folderName={title}\n parentFolderId={currentFolderId}\n onClose={() => setIsCreateFolderDialogOpen(false)}\n />\n <ImportFromUrlDialog\n open={isUrlDialogOpen}\n onClose={() => setIsUrlDialogOpen(false)}\n onUpload={handleUrlUpload}\n />\n <AssetDetailsDrawer />\n </>\n );\n};\n"],"names":["INTERSECTION_OPTIONS","threshold","ITEM_COUNT_MESSAGE","id","getTranslationKey","defaultMessage","SEARCH_RESULTS_COUNT_MESSAGES","both","folders","assets","getSearchResultsCountMessage","numberFolders","numberAssets","AssetsView","view","isLoadingFolders","isLoadingAssets","isFetchingMore","hasNextPage","fetchNextPage","error","searchQuery","assetsSort","foldersPosition","hasActiveFilters","onClearFilters","onAssetItemClick","onAddAssets","canAddAssets","onClearSearch","formatMessage","useIntl","isGridView","viewOptions","GRID","isLoading","mixedItems","useMemo","mergeMixedList","sort","loadMoreRef","useElementOnScreen","useCallback","isVisible","_jsx","Flex","justifyContent","padding","Loader","Box","Typography","textColor","length","FilteredEmptyState","EmptyState","_jsxs","_Fragment","AssetsGrid","AssetsTable","div","ref","style","height","BulkActionsBar","ClearSelectionOnChange","listQueryKey","clear","useAssetSelection","useEffect","StyledToggleGroup","styled","ToggleGroup","Root","theme","spaces","colors","neutral100","neutral200","borderRadius","StyledToggleItem","Item","neutral600","fontSizes","fontWeights","semiBold","neutral700","neutral0","primary600","HeaderWrapper","AssetsPage","openDetails","useAssetDetailsParam","canCreate","canUpdate","useMediaLibraryPermissions","currentFolderId","navigateToFolderId","navigateToRoot","useFolderNavigation","currentFolderError","useGetFolderQuery","skip","name","title","itemCount","useFolderInfo","isSearching","clearSearch","useAssetSearch","listSort","useListSort","listFilters","useListFilters","builtFilters","buildAssetFilters","filters","Date","serialized","pagination","assetsError","useInfiniteAssets","folder","search","undefined","fileClauses","filtersKey","enabled","showFiles","data","fetchedFolders","useGetFoldersQuery","parentId","foldersSort","folderClauses","showFolders","itemCountLabel","count","searchResultsTitle","query","total","searchResultsCountLabel","pageHeaderTitle","isCreateFolderDialogOpen","setIsCreateFolderDialogOpen","useState","setView","usePersistentState","localStorageKeys","isUrlDialogOpen","setIsUrlDialogOpen","fileInputRef","useRef","uploadDropZoneRef","uploadFiles","useUploadFilesMutation","uploadFromUrls","useUploadFromUrlsMutation","settings","useGetUploadSettingsQuery","concurrency","concurrentUploadRequests","isEnabled","isAiMetadataEnabled","useAIAvailability","uploadFilesToFolder","files","folderId","formData","FormData","fileInfoArray","forEach","file","append","push","caption","alternativeText","JSON","stringify","totalFiles","generateAiMetadata","Boolean","unwrap","handleFileSelect","current","click","handleFileChange","e","target","Array","from","value","handleDrop","handleUrlUpload","urls","getListQueryKey","filter","UploadDropZoneProvider","onDrop","disabled","AssetSelectionProvider","AssetsDndProvider","Layouts","minHeight","background","sideNav","FolderTree","showActiveFolder","onSelectFolder","VisuallyHidden","input","type","onChange","multiple","Header","primaryAction","SimpleMenu","popoverPlacement","variant","endIcon","ChevronDown","label","MenuItem","onSelect","startIcon","FolderIcon","Files","Link","subtitle","alignItems","gap","width","FilterMenu","AssetsSearchInput","SortMenu","showFoldersGroup","onValueChange","TABLE","aria-label","List","GridIcon","FilterBadges","Content","DropZoneWithOverlay","DropFilesMessage","folderName","clearFilters","CreateFolderDialog","open","parentFolderId","onClose","ImportFromUrlDialog","onUpload","AssetDetailsDrawer"],"mappings":"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"}
@@ -47,6 +47,8 @@ const Overlay = styledComponents.styled(designSystem.Flex)`
47
47
  border-radius: ${({ theme })=>theme.borderRadius};
48
48
  border: 1px solid ${({ theme })=>theme.colors.neutral150};
49
49
  background: ${({ theme })=>theme.colors.neutral0};
50
+ /* Focused programmatically on open (tabIndex -1) — no visible ring needed. */
51
+ outline: none;
50
52
  `;
51
53
  const HeaderBar = styledComponents.styled(designSystem.Flex)`
52
54
  width: 100%;
@@ -56,6 +58,9 @@ const HeaderBar = styledComponents.styled(designSystem.Flex)`
56
58
  background: ${({ theme })=>theme.colors.neutral0};
57
59
  `;
58
60
  // Fills the remaining space between header/footer; checkerboard pattern.
61
+ // The horizontal padding keeps the image off the viewport edges — the corner
62
+ // handles overhang the image by half their size, and on narrow (mobile)
63
+ // screens an edge-to-edge image leaves nothing to grab.
59
64
  const Body = styledComponents.styled(designSystem.Box)`
60
65
  width: 100%;
61
66
  position: relative;
@@ -65,6 +70,7 @@ const Body = styledComponents.styled(designSystem.Box)`
65
70
  align-items: center;
66
71
  justify-content: center;
67
72
  overflow: hidden;
73
+ padding: 0 ${({ theme })=>theme.spaces[4]};
68
74
  background: repeating-conic-gradient(
69
75
  ${({ theme })=>theme.colors.neutral100} 0% 25%,
70
76
  ${({ theme })=>theme.colors.neutral0} 0% 50%
@@ -95,6 +101,9 @@ const CropOverlay = styledComponents.styled.div`
95
101
  border: 1px dashed ${({ theme })=>theme.colors.primary600};
96
102
  box-shadow: 0 0 0 9999px rgba(33, 33, 52, 0.5);
97
103
  cursor: move;
104
+ /* Without this, touch browsers claim the gesture for scrolling and fire
105
+ pointercancel mid-drag — the crop drag dies while the finger is down. */
106
+ touch-action: none;
98
107
  `;
99
108
  const ResizeHandle = styledComponents.styled.button`
100
109
  position: absolute;
@@ -106,6 +115,7 @@ const ResizeHandle = styledComponents.styled.button`
106
115
  border-radius: 2px;
107
116
  background: ${({ theme })=>theme.colors.neutral0};
108
117
  cursor: ${({ $cursor })=>$cursor};
118
+ touch-action: none;
109
119
  `;
110
120
  const FocalPointHandle = styledComponents.styled.button`
111
121
  position: absolute;
@@ -117,6 +127,7 @@ const FocalPointHandle = styledComponents.styled.button`
117
127
  background: transparent;
118
128
  cursor: grab;
119
129
  padding: 0;
130
+ touch-action: none;
120
131
 
121
132
  &::before {
122
133
  content: '';
@@ -201,7 +212,7 @@ const BackgroundPreserveRatio = ()=>/*#__PURE__*/ jsxRuntime.jsx(BackgroundPrese
201
212
  })
202
213
  })
203
214
  });
204
- const AssetCropEditor = ({ asset, isBusy = false, onClose, onApply, onSaveAsCopy })=>{
215
+ const AssetCropEditor = ({ asset, isBusy = false, onClose, onApply, onSaveAsCopy, canSaveAsCopy })=>{
205
216
  const { formatMessage } = reactIntl.useIntl();
206
217
  const { toggleNotification } = strapiAdmin.useNotification();
207
218
  // The InfoBox is a fixed dark surface in both themes, so its text can't use a
@@ -213,6 +224,14 @@ const AssetCropEditor = ({ asset, isBusy = false, onClose, onApply, onSaveAsCopy
213
224
  const infoMutedColor = isDark ? 'neutral600' : 'neutral200';
214
225
  const imgRef = React__namespace.useRef(null);
215
226
  const cropAreaRef = React__namespace.useRef(null);
227
+ const overlayRef = React__namespace.useRef(null);
228
+ // FocusTrap's auto-focus lands on the first focusable element — the crop
229
+ // width NumberInput — which pops the keyboard on mobile the moment the
230
+ // editor opens. Focus the (tabIndex -1) overlay instead: keyboard users are
231
+ // one Tab away from the first control, Escape still reaches the trap.
232
+ React__namespace.useEffect(()=>{
233
+ overlayRef.current?.focus();
234
+ }, []);
216
235
  const { init, crop, naturalSize, aspectRatio, setCropSize, setCropPosition, setAspectRatio, produceFile, width, height } = useCropImg.useCropImg();
217
236
  const [aspectLocked, setAspectLocked] = React__namespace.useState(false);
218
237
  // Focal point as a percentage of the crop area (matches the {x,y} contract).
@@ -242,40 +261,75 @@ const AssetCropEditor = ({ asset, isBusy = false, onClose, onApply, onSaveAsCopy
242
261
  y: (event.clientY - rect.top) * ratioY
243
262
  };
244
263
  };
245
- // Drag the entire crop rectangle.
246
- const handleMovePointerDown = (event)=>{
264
+ // Teardown for the drag currently in flight, so it can be run both on pointer
265
+ // release AND on unmount. Without the unmount path, closing the editor mid-drag
266
+ // (Escape, drawer close, a re-render dropping the overlay) would never fire a
267
+ // pointer event, leaking the window listeners and letting a stale `onMove`
268
+ // call `setCropPosition` on an unmounted component.
269
+ const activeDragCleanupRef = React__namespace.useRef(null);
270
+ React__namespace.useEffect(()=>{
271
+ return ()=>{
272
+ activeDragCleanupRef.current?.();
273
+ };
274
+ }, []);
275
+ // Track a pointer drag until the pointer is released or the browser cancels
276
+ // it. The pointer is captured so the drag follows the finger even once it
277
+ // leaves the (12px) handle it started on, and pointercancel is treated as
278
+ // release so an interrupted touch never leaves stale window listeners.
279
+ const trackPointerDrag = (event, onMove)=>{
247
280
  event.preventDefault();
248
281
  event.stopPropagation();
282
+ const { pointerId } = event;
283
+ try {
284
+ event.currentTarget.setPointerCapture(pointerId);
285
+ } catch {
286
+ // Unsupported environment (jsdom) — window listeners still track the drag.
287
+ }
288
+ const move = (e)=>{
289
+ if (e.pointerId !== pointerId) return;
290
+ onMove(e);
291
+ };
292
+ const cleanup = ()=>{
293
+ window.removeEventListener('pointermove', move);
294
+ window.removeEventListener('pointerup', end);
295
+ window.removeEventListener('pointercancel', end);
296
+ activeDragCleanupRef.current = null;
297
+ };
298
+ const end = (e)=>{
299
+ if (e.pointerId !== pointerId) return;
300
+ cleanup();
301
+ };
302
+ // Only one drag is ever live at a time; tear down any previous one first.
303
+ activeDragCleanupRef.current?.();
304
+ activeDragCleanupRef.current = cleanup;
305
+ window.addEventListener('pointermove', move);
306
+ window.addEventListener('pointerup', end);
307
+ window.addEventListener('pointercancel', end);
308
+ };
309
+ // Drag the entire crop rectangle.
310
+ const handleMovePointerDown = (event)=>{
249
311
  const start = pointerToNatural(event);
250
312
  if (!start) return;
251
313
  const startCrop = {
252
314
  ...crop
253
315
  };
254
- const move = (e)=>{
316
+ trackPointerDrag(event, (e)=>{
255
317
  const next = pointerToNatural(e);
256
318
  if (!next) return;
257
319
  setCropPosition({
258
320
  x: startCrop.x + (next.x - start.x),
259
321
  y: startCrop.y + (next.y - start.y)
260
322
  });
261
- };
262
- const up = ()=>{
263
- window.removeEventListener('pointermove', move);
264
- window.removeEventListener('pointerup', up);
265
- };
266
- window.addEventListener('pointermove', move);
267
- window.addEventListener('pointerup', up);
323
+ });
268
324
  };
269
325
  // Resize from a corner; the opposite corner stays anchored.
270
326
  const handleResizePointerDown = (corner)=>(event)=>{
271
- event.preventDefault();
272
- event.stopPropagation();
273
327
  const startCrop = {
274
328
  ...crop
275
329
  };
276
330
  const anchorX = corner === 'tl' || corner === 'bl' ? startCrop.x + startCrop.width : startCrop.x;
277
331
  const anchorY = corner === 'tl' || corner === 'tr' ? startCrop.y + startCrop.height : startCrop.y;
278
- const move = (e)=>{
332
+ trackPointerDrag(event, (e)=>{
279
333
  const point = pointerToNatural(e);
280
334
  if (!point) return;
281
335
  const { x, y, width: w, height: h } = useCropImg.resolveCornerResize({
@@ -292,13 +346,7 @@ const AssetCropEditor = ({ asset, isBusy = false, onClose, onApply, onSaveAsCopy
292
346
  width: w,
293
347
  height: h
294
348
  });
295
- };
296
- const up = ()=>{
297
- window.removeEventListener('pointermove', move);
298
- window.removeEventListener('pointerup', up);
299
- };
300
- window.addEventListener('pointermove', move);
301
- window.addEventListener('pointerup', up);
349
+ });
302
350
  };
303
351
  const toggleAspectLock = ()=>{
304
352
  setAspectLocked((locked)=>{
@@ -309,9 +357,7 @@ const AssetCropEditor = ({ asset, isBusy = false, onClose, onApply, onSaveAsCopy
309
357
  };
310
358
  // Drag the focal handle within the crop rectangle, clamped 0–100.
311
359
  const handleFocalPointerDown = (event)=>{
312
- event.preventDefault();
313
- event.stopPropagation();
314
- const move = (e)=>{
360
+ trackPointerDrag(event, (e)=>{
315
361
  const point = pointerToNatural(e);
316
362
  if (!point) return;
317
363
  // Convert pointer to a percentage of the current crop area.
@@ -321,13 +367,7 @@ const AssetCropEditor = ({ asset, isBusy = false, onClose, onApply, onSaveAsCopy
321
367
  x: Math.round(Math.min(100, Math.max(0, px))),
322
368
  y: Math.round(Math.min(100, Math.max(0, py)))
323
369
  });
324
- };
325
- const up = ()=>{
326
- window.removeEventListener('pointermove', move);
327
- window.removeEventListener('pointerup', up);
328
- };
329
- window.addEventListener('pointermove', move);
330
- window.addEventListener('pointerup', up);
370
+ });
331
371
  };
332
372
  const focalPxX = Math.round(focal.x / 100 * width);
333
373
  const focalPxY = Math.round(focal.y / 100 * height);
@@ -377,7 +417,10 @@ const AssetCropEditor = ({ asset, isBusy = false, onClose, onApply, onSaveAsCopy
377
417
  return /*#__PURE__*/ jsxRuntime.jsx(designSystem.Portal, {
378
418
  children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.FocusTrap, {
379
419
  onEscape: onClose,
420
+ skipAutoFocus: true,
380
421
  children: /*#__PURE__*/ jsxRuntime.jsxs(Overlay, {
422
+ ref: overlayRef,
423
+ tabIndex: -1,
381
424
  children: [
382
425
  /*#__PURE__*/ jsxRuntime.jsxs(HeaderBar, {
383
426
  alignItems: "center",
@@ -666,7 +709,7 @@ const AssetCropEditor = ({ asset, isBusy = false, onClose, onApply, onSaveAsCopy
666
709
  /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
667
710
  gap: 2,
668
711
  children: [
669
- /*#__PURE__*/ jsxRuntime.jsx(designSystem.Button, {
712
+ canSaveAsCopy && /*#__PURE__*/ jsxRuntime.jsx(designSystem.Button, {
670
713
  variant: "secondary",
671
714
  onClick: ()=>handleAction('copy'),
672
715
  loading: isBusy,