@strapi/upload 5.59.0 → 5.60.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 (231) 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/PickerSelectionProvider.js +178 -0
  10. package/dist/admin/components/AssetPickerDialog/PickerSelectionProvider.js.map +1 -0
  11. package/dist/admin/components/AssetPickerDialog/PickerSelectionProvider.mjs +175 -0
  12. package/dist/admin/components/AssetPickerDialog/PickerSelectionProvider.mjs.map +1 -0
  13. package/dist/admin/components/AssetPickerDialog/SortableSelection.js +143 -0
  14. package/dist/admin/components/AssetPickerDialog/SortableSelection.js.map +1 -0
  15. package/dist/admin/components/AssetPickerDialog/SortableSelection.mjs +141 -0
  16. package/dist/admin/components/AssetPickerDialog/SortableSelection.mjs.map +1 -0
  17. package/dist/admin/components/AssetPickerDialog/pickerSelection.js +49 -0
  18. package/dist/admin/components/AssetPickerDialog/pickerSelection.js.map +1 -0
  19. package/dist/admin/components/AssetPickerDialog/pickerSelection.mjs +41 -0
  20. package/dist/admin/components/AssetPickerDialog/pickerSelection.mjs.map +1 -0
  21. package/dist/admin/components/MediaLibraryInput/AddAssetMenu.js +4 -3
  22. package/dist/admin/components/MediaLibraryInput/AddAssetMenu.js.map +1 -1
  23. package/dist/admin/components/MediaLibraryInput/AddAssetMenu.mjs +4 -3
  24. package/dist/admin/components/MediaLibraryInput/AddAssetMenu.mjs.map +1 -1
  25. package/dist/admin/components/MediaLibraryInput/AssetCard.js +240 -0
  26. package/dist/admin/components/MediaLibraryInput/AssetCard.js.map +1 -0
  27. package/dist/admin/components/MediaLibraryInput/AssetCard.mjs +237 -0
  28. package/dist/admin/components/MediaLibraryInput/AssetCard.mjs.map +1 -0
  29. package/dist/admin/components/MediaLibraryInput/AssetCarousel.js +161 -0
  30. package/dist/admin/components/MediaLibraryInput/AssetCarousel.js.map +1 -0
  31. package/dist/admin/components/MediaLibraryInput/AssetCarousel.mjs +159 -0
  32. package/dist/admin/components/MediaLibraryInput/AssetCarousel.mjs.map +1 -0
  33. package/dist/admin/components/MediaLibraryInput/AssetDropZone.js +76 -49
  34. package/dist/admin/components/MediaLibraryInput/AssetDropZone.js.map +1 -1
  35. package/dist/admin/components/MediaLibraryInput/AssetDropZone.mjs +77 -50
  36. package/dist/admin/components/MediaLibraryInput/AssetDropZone.mjs.map +1 -1
  37. package/dist/admin/components/MediaLibraryInput/AssetPreview.js +109 -0
  38. package/dist/admin/components/MediaLibraryInput/AssetPreview.js.map +1 -0
  39. package/dist/admin/components/MediaLibraryInput/AssetPreview.mjs +106 -0
  40. package/dist/admin/components/MediaLibraryInput/AssetPreview.mjs.map +1 -0
  41. package/dist/admin/components/MediaLibraryInput/AssetRow.js +146 -79
  42. package/dist/admin/components/MediaLibraryInput/AssetRow.js.map +1 -1
  43. package/dist/admin/components/MediaLibraryInput/AssetRow.mjs +148 -82
  44. package/dist/admin/components/MediaLibraryInput/AssetRow.mjs.map +1 -1
  45. package/dist/admin/components/MediaLibraryInput/FieldControls.js +32 -0
  46. package/dist/admin/components/MediaLibraryInput/FieldControls.js.map +1 -0
  47. package/dist/admin/components/MediaLibraryInput/FieldControls.mjs +29 -0
  48. package/dist/admin/components/MediaLibraryInput/FieldControls.mjs.map +1 -0
  49. package/dist/admin/components/MediaLibraryInput/MediaLibraryInput.js +130 -88
  50. package/dist/admin/components/MediaLibraryInput/MediaLibraryInput.js.map +1 -1
  51. package/dist/admin/components/MediaLibraryInput/MediaLibraryInput.mjs +129 -91
  52. package/dist/admin/components/MediaLibraryInput/MediaLibraryInput.mjs.map +1 -1
  53. package/dist/admin/components/MediaLibraryInput/UploadProgressBar.js +42 -0
  54. package/dist/admin/components/MediaLibraryInput/UploadProgressBar.js.map +1 -0
  55. package/dist/admin/components/MediaLibraryInput/UploadProgressBar.mjs +40 -0
  56. package/dist/admin/components/MediaLibraryInput/UploadProgressBar.mjs.map +1 -0
  57. package/dist/admin/components/MediaLibraryInput/useFieldUploads.js +122 -0
  58. package/dist/admin/components/MediaLibraryInput/useFieldUploads.js.map +1 -0
  59. package/dist/admin/components/MediaLibraryInput/useFieldUploads.mjs +120 -0
  60. package/dist/admin/components/MediaLibraryInput/useFieldUploads.mjs.map +1 -0
  61. package/dist/admin/components/UploadProgressDialog.js +2 -1
  62. package/dist/admin/components/UploadProgressDialog.js.map +1 -1
  63. package/dist/admin/components/UploadProgressDialog.mjs +2 -1
  64. package/dist/admin/components/UploadProgressDialog.mjs.map +1 -1
  65. package/dist/admin/hooks/useMediaLibraryPermissions.js +12 -2
  66. package/dist/admin/hooks/useMediaLibraryPermissions.js.map +1 -1
  67. package/dist/admin/hooks/useMediaLibraryPermissions.mjs +12 -2
  68. package/dist/admin/hooks/useMediaLibraryPermissions.mjs.map +1 -1
  69. package/dist/admin/pages/Assets/AssetsPage.js +13 -302
  70. package/dist/admin/pages/Assets/AssetsPage.js.map +1 -1
  71. package/dist/admin/pages/Assets/AssetsPage.mjs +11 -280
  72. package/dist/admin/pages/Assets/AssetsPage.mjs.map +1 -1
  73. package/dist/admin/pages/Assets/components/AssetsGrid.js +142 -31
  74. package/dist/admin/pages/Assets/components/AssetsGrid.js.map +1 -1
  75. package/dist/admin/pages/Assets/components/AssetsGrid.mjs +145 -34
  76. package/dist/admin/pages/Assets/components/AssetsGrid.mjs.map +1 -1
  77. package/dist/admin/pages/Assets/components/AssetsSearchInput.js +43 -2
  78. package/dist/admin/pages/Assets/components/AssetsSearchInput.js.map +1 -1
  79. package/dist/admin/pages/Assets/components/AssetsSearchInput.mjs +45 -4
  80. package/dist/admin/pages/Assets/components/AssetsSearchInput.mjs.map +1 -1
  81. package/dist/admin/pages/Assets/components/AssetsTable.js +58 -34
  82. package/dist/admin/pages/Assets/components/AssetsTable.js.map +1 -1
  83. package/dist/admin/pages/Assets/components/AssetsTable.mjs +60 -36
  84. package/dist/admin/pages/Assets/components/AssetsTable.mjs.map +1 -1
  85. package/dist/admin/pages/Assets/components/AssetsView.js +145 -0
  86. package/dist/admin/pages/Assets/components/AssetsView.js.map +1 -0
  87. package/dist/admin/pages/Assets/components/AssetsView.mjs +143 -0
  88. package/dist/admin/pages/Assets/components/AssetsView.mjs.map +1 -0
  89. package/dist/admin/pages/Assets/components/BulkActionsBar.mjs +1 -1
  90. package/dist/admin/pages/Assets/components/BusyOverlay.mjs +1 -1
  91. package/dist/admin/pages/Assets/components/Dnd/DragOverlayChip.mjs +1 -1
  92. package/dist/admin/pages/Assets/components/Dnd/ReorderHandle.js +40 -0
  93. package/dist/admin/pages/Assets/components/Dnd/ReorderHandle.js.map +1 -0
  94. package/dist/admin/pages/Assets/components/Dnd/ReorderHandle.mjs +38 -0
  95. package/dist/admin/pages/Assets/components/Dnd/ReorderHandle.mjs.map +1 -0
  96. package/dist/admin/pages/Assets/components/Dnd/assetSortable.js +29 -0
  97. package/dist/admin/pages/Assets/components/Dnd/assetSortable.js.map +1 -0
  98. package/dist/admin/pages/Assets/components/Dnd/assetSortable.mjs +24 -0
  99. package/dist/admin/pages/Assets/components/Dnd/assetSortable.mjs.map +1 -0
  100. package/dist/admin/pages/Assets/components/Dnd/dndIds.js +5 -0
  101. package/dist/admin/pages/Assets/components/Dnd/dndIds.js.map +1 -1
  102. package/dist/admin/pages/Assets/components/Dnd/dndIds.mjs +5 -1
  103. package/dist/admin/pages/Assets/components/Dnd/dndIds.mjs.map +1 -1
  104. package/dist/admin/pages/Assets/components/Dnd/useAssetDnd.js +41 -13
  105. package/dist/admin/pages/Assets/components/Dnd/useAssetDnd.js.map +1 -1
  106. package/dist/admin/pages/Assets/components/Dnd/useAssetDnd.mjs +41 -13
  107. package/dist/admin/pages/Assets/components/Dnd/useAssetDnd.mjs.map +1 -1
  108. package/dist/admin/pages/Assets/components/FilterBadges.mjs +2 -2
  109. package/dist/admin/pages/Assets/components/FilterMenu.mjs +2 -2
  110. package/dist/admin/pages/Assets/components/FolderTree/FolderTree.js +274 -55
  111. package/dist/admin/pages/Assets/components/FolderTree/FolderTree.js.map +1 -1
  112. package/dist/admin/pages/Assets/components/FolderTree/FolderTree.mjs +277 -59
  113. package/dist/admin/pages/Assets/components/FolderTree/FolderTree.mjs.map +1 -1
  114. package/dist/admin/pages/Assets/components/FolderTree/collapsedBranch.js +32 -0
  115. package/dist/admin/pages/Assets/components/FolderTree/collapsedBranch.js.map +1 -0
  116. package/dist/admin/pages/Assets/components/FolderTree/collapsedBranch.mjs +29 -0
  117. package/dist/admin/pages/Assets/components/FolderTree/collapsedBranch.mjs.map +1 -0
  118. package/dist/admin/pages/Assets/components/ViewToggle.js +126 -0
  119. package/dist/admin/pages/Assets/components/ViewToggle.js.map +1 -0
  120. package/dist/admin/pages/Assets/components/ViewToggle.mjs +104 -0
  121. package/dist/admin/pages/Assets/components/ViewToggle.mjs.map +1 -0
  122. package/dist/admin/pages/Assets/hooks/useAssetSearch.js +2 -2
  123. package/dist/admin/pages/Assets/hooks/useAssetSearch.js.map +1 -1
  124. package/dist/admin/pages/Assets/hooks/useAssetSearch.mjs +2 -2
  125. package/dist/admin/pages/Assets/hooks/useAssetSearch.mjs.map +1 -1
  126. package/dist/admin/pages/Assets/hooks/useAssetSelection.js +19 -1
  127. package/dist/admin/pages/Assets/hooks/useAssetSelection.js.map +1 -1
  128. package/dist/admin/pages/Assets/hooks/useAssetSelection.mjs +20 -3
  129. package/dist/admin/pages/Assets/hooks/useAssetSelection.mjs.map +1 -1
  130. package/dist/admin/pages/Assets/hooks/useAssetsList.js +87 -0
  131. package/dist/admin/pages/Assets/hooks/useAssetsList.js.map +1 -0
  132. package/dist/admin/pages/Assets/hooks/useAssetsList.mjs +85 -0
  133. package/dist/admin/pages/Assets/hooks/useAssetsList.mjs.map +1 -0
  134. package/dist/admin/pages/Assets/hooks/useBusyAssets.mjs +1 -1
  135. package/dist/admin/pages/Assets/hooks/useFolderNavigation.js +2 -1
  136. package/dist/admin/pages/Assets/hooks/useFolderNavigation.js.map +1 -1
  137. package/dist/admin/pages/Assets/hooks/useFolderNavigation.mjs +3 -2
  138. package/dist/admin/pages/Assets/hooks/useFolderNavigation.mjs.map +1 -1
  139. package/dist/admin/pages/Assets/hooks/useListFilters.js +2 -1
  140. package/dist/admin/pages/Assets/hooks/useListFilters.js.map +1 -1
  141. package/dist/admin/pages/Assets/hooks/useListFilters.mjs +3 -2
  142. package/dist/admin/pages/Assets/hooks/useListFilters.mjs.map +1 -1
  143. package/dist/admin/pages/Assets/hooks/useListQueryParams.js +80 -0
  144. package/dist/admin/pages/Assets/hooks/useListQueryParams.js.map +1 -0
  145. package/dist/admin/pages/Assets/hooks/useListQueryParams.mjs +77 -0
  146. package/dist/admin/pages/Assets/hooks/useListQueryParams.mjs.map +1 -0
  147. package/dist/admin/pages/Assets/hooks/useListSettings.js +32 -0
  148. package/dist/admin/pages/Assets/hooks/useListSettings.js.map +1 -0
  149. package/dist/admin/pages/Assets/hooks/useListSettings.mjs +29 -0
  150. package/dist/admin/pages/Assets/hooks/useListSettings.mjs.map +1 -0
  151. package/dist/admin/pages/Assets/hooks/useListSort.js +2 -1
  152. package/dist/admin/pages/Assets/hooks/useListSort.js.map +1 -1
  153. package/dist/admin/pages/Assets/hooks/useListSort.mjs +3 -2
  154. package/dist/admin/pages/Assets/hooks/useListSort.mjs.map +1 -1
  155. package/dist/admin/services/api.js +92 -7
  156. package/dist/admin/services/api.js.map +1 -1
  157. package/dist/admin/services/api.mjs +91 -9
  158. package/dist/admin/services/api.mjs.map +1 -1
  159. package/dist/admin/src/components/AssetPickerDialog/AssetPickerDialog.d.ts +19 -0
  160. package/dist/admin/src/components/AssetPickerDialog/FolderBreadcrumbs.d.ts +10 -0
  161. package/dist/admin/src/components/AssetPickerDialog/PickerSelectionProvider.d.ts +28 -0
  162. package/dist/admin/src/components/AssetPickerDialog/SortableSelection.d.ts +12 -0
  163. package/dist/admin/src/components/AssetPickerDialog/pickerSelection.d.ts +26 -0
  164. package/dist/admin/src/components/MediaLibraryInput/AssetCard.d.ts +25 -0
  165. package/dist/admin/src/components/MediaLibraryInput/AssetCarousel.d.ts +16 -0
  166. package/dist/admin/src/components/MediaLibraryInput/AssetDropZone.d.ts +11 -3
  167. package/dist/admin/src/components/MediaLibraryInput/AssetPreview.d.ts +17 -0
  168. package/dist/admin/src/components/MediaLibraryInput/AssetRow.d.ts +13 -3
  169. package/dist/admin/src/components/MediaLibraryInput/FieldControls.d.ts +19 -0
  170. package/dist/admin/src/components/MediaLibraryInput/MediaLibraryInput.d.ts +3 -1
  171. package/dist/admin/src/components/MediaLibraryInput/UploadProgressBar.d.ts +7 -0
  172. package/dist/admin/src/components/MediaLibraryInput/useFieldUploads.d.ts +31 -0
  173. package/dist/admin/src/hooks/useMediaLibraryPermissions.d.ts +2 -0
  174. package/dist/admin/src/pages/Assets/components/AssetsGrid.d.ts +3 -1
  175. package/dist/admin/src/pages/Assets/components/AssetsSearchInput.d.ts +11 -1
  176. package/dist/admin/src/pages/Assets/components/AssetsView.d.ts +29 -0
  177. package/dist/admin/src/pages/Assets/components/Dnd/ReorderHandle.d.ts +12 -0
  178. package/dist/admin/src/pages/Assets/components/Dnd/assetSortable.d.ts +37 -0
  179. package/dist/admin/src/pages/Assets/components/Dnd/dndIds.d.ts +5 -0
  180. package/dist/admin/src/pages/Assets/components/Dnd/useAssetDnd.d.ts +23 -2
  181. package/dist/admin/src/pages/Assets/components/FolderTree/FolderTree.d.ts +1 -0
  182. package/dist/admin/src/pages/Assets/components/FolderTree/collapsedBranch.d.ts +21 -0
  183. package/dist/admin/src/pages/Assets/components/ViewToggle.d.ts +8 -0
  184. package/dist/admin/src/pages/Assets/hooks/useAssetSelection.d.ts +26 -0
  185. package/dist/admin/src/pages/Assets/hooks/useAssetsList.d.ts +30 -0
  186. package/dist/admin/src/pages/Assets/hooks/useListQueryParams.d.ts +27 -0
  187. package/dist/admin/src/pages/Assets/hooks/useListSettings.d.ts +29 -0
  188. package/dist/admin/src/services/api.d.ts +24 -1
  189. package/dist/admin/src/store/uploadProgress.d.ts +14 -1
  190. package/dist/admin/src/utils/findFolderPath.d.ts +6 -0
  191. package/dist/admin/src/utils/isAllowedAssetType.d.ts +14 -0
  192. package/dist/admin/store/uploadProgress.js +30 -3
  193. package/dist/admin/store/uploadProgress.js.map +1 -1
  194. package/dist/admin/store/uploadProgress.mjs +29 -4
  195. package/dist/admin/store/uploadProgress.mjs.map +1 -1
  196. package/dist/admin/translations/en.json.js +20 -0
  197. package/dist/admin/translations/en.json.js.map +1 -1
  198. package/dist/admin/translations/en.json.mjs +20 -0
  199. package/dist/admin/translations/en.json.mjs.map +1 -1
  200. package/dist/admin/utils/findFolderPath.js +26 -0
  201. package/dist/admin/utils/findFolderPath.js.map +1 -0
  202. package/dist/admin/utils/findFolderPath.mjs +24 -0
  203. package/dist/admin/utils/findFolderPath.mjs.map +1 -0
  204. package/dist/admin/utils/isAllowedAssetType.js +33 -0
  205. package/dist/admin/utils/isAllowedAssetType.js.map +1 -0
  206. package/dist/admin/utils/isAllowedAssetType.mjs +31 -0
  207. package/dist/admin/utils/isAllowedAssetType.mjs.map +1 -0
  208. package/dist/server/controllers/admin-settings.js +5 -1
  209. package/dist/server/controllers/admin-settings.js.map +1 -1
  210. package/dist/server/controllers/admin-settings.mjs +5 -1
  211. package/dist/server/controllers/admin-settings.mjs.map +1 -1
  212. package/dist/server/services/image-manipulation.js +2 -2
  213. package/dist/server/services/image-manipulation.js.map +1 -1
  214. package/dist/server/services/image-manipulation.mjs +2 -2
  215. package/dist/server/services/image-manipulation.mjs.map +1 -1
  216. package/dist/server/services/upload.js.map +1 -1
  217. package/dist/server/services/upload.mjs.map +1 -1
  218. package/dist/server/src/controllers/admin-settings.d.ts.map +1 -1
  219. package/dist/server/src/index.d.ts +1 -1
  220. package/dist/server/src/services/extensions/utils.d.ts +11 -11
  221. package/dist/server/src/services/image-manipulation.d.ts +1 -1
  222. package/dist/server/src/services/image-manipulation.d.ts.map +1 -1
  223. package/dist/server/src/services/index.d.ts +1 -1
  224. package/dist/server/src/types.d.ts +63 -12
  225. package/dist/server/src/types.d.ts.map +1 -1
  226. package/package.json +8 -6
  227. package/dist/admin/components/MediaLibraryInput/NoLibraryAccessDialog.js +0 -45
  228. package/dist/admin/components/MediaLibraryInput/NoLibraryAccessDialog.js.map +0 -1
  229. package/dist/admin/components/MediaLibraryInput/NoLibraryAccessDialog.mjs +0 -43
  230. package/dist/admin/components/MediaLibraryInput/NoLibraryAccessDialog.mjs.map +0 -1
  231. package/dist/admin/src/components/MediaLibraryInput/NoLibraryAccessDialog.d.ts +0 -10
@@ -1,55 +1,84 @@
1
1
  import { jsxs, jsx } from 'react/jsx-runtime';
2
2
  import { useState, useRef, useCallback } from 'react';
3
3
  import { Flex, Typography } from '@strapi/design-system';
4
- import { PlusCircle } from '@strapi/icons';
4
+ import { Images } from '@strapi/icons';
5
5
  import { useIntl } from 'react-intl';
6
6
  import { styled } from 'styled-components';
7
7
  import { getTranslationKey } from '../../utils/translations.mjs';
8
8
 
9
- const Zone = styled.button`
9
+ const DRAG_FRAME_COLORS = {
10
+ accept: {
11
+ border: 'primary600',
12
+ background: 'primary100'
13
+ },
14
+ reject: {
15
+ border: 'neutral300',
16
+ background: 'neutral150'
17
+ }
18
+ };
19
+ const Zone = styled.div`
10
20
  position: relative;
11
21
  display: flex;
12
- flex-direction: column;
13
22
  align-items: center;
14
- justify-content: center;
15
- gap: ${({ theme })=>theme.spaces[2]};
23
+ gap: ${({ theme })=>theme.spaces[4]};
16
24
  width: 100%;
17
- min-height: 12rem;
18
- padding: ${({ theme })=>theme.spaces[6]};
19
- border: 1px solid ${({ theme })=>theme.colors.neutral200};
20
25
  border-radius: ${({ theme })=>theme.borderRadius};
21
- background: ${({ theme })=>theme.colors.neutral100};
22
- cursor: pointer;
26
+ text-align: ${({ $variant })=>$variant === 'bar' ? 'start' : 'center'};
23
27
 
24
- // Only while a file is dragged over the zone: it marks where the file will
25
- // land, so it has nothing to say to a pointer that is merely passing through.
26
- // Drawn inside rather than on the box itself, so the field keeps its own
27
- // outline and the invitation reads as an area to drop into.
28
- &::after {
29
- content: '';
30
- position: absolute;
31
- inset: ${({ theme })=>theme.spaces[2]} ${({ theme })=>theme.spaces[4]};
32
- border: 1px dashed ${({ theme })=>theme.colors.primary600};
33
- border-radius: ${({ theme })=>theme.borderRadius};
34
- opacity: ${({ $isDragging })=>$isDragging ? 1 : 0};
35
- pointer-events: none;
36
- }
28
+ ${({ $variant, theme })=>$variant !== 'bar' ? `
29
+ flex-direction: column;
30
+ justify-content: center;
31
+ height: 100%;
32
+ min-height: ${$variant === 'tile' ? '20.8rem' : 'auto'};
33
+ padding: ${theme.spaces[4]};
34
+ border: 1px dashed ${theme.colors.neutral300};
35
+ background: ${theme.colors.neutral0};
36
+ ` : `
37
+ min-height: 7.2rem;
38
+ padding: ${theme.spaces[4]};
39
+ border: 1px solid ${theme.colors.neutral200};
40
+ background: ${theme.colors.neutral100};
41
+ `}
37
42
 
38
- &[aria-disabled='true'] {
39
- cursor: not-allowed;
40
- }
43
+ // Only while a file is dragged over the zone: a solid frame inset from the
44
+ // zone's own border marks where the file will land, greyed out when it can't.
45
+ ${({ $dragState, theme })=>$dragState !== 'idle' && `
46
+ &::after {
47
+ content: '';
48
+ position: absolute;
49
+ inset: ${theme.spaces[2]};
50
+ border: 1px solid ${theme.colors[DRAG_FRAME_COLORS[$dragState].border]};
51
+ border-radius: ${theme.borderRadius};
52
+ background: ${theme.colors[DRAG_FRAME_COLORS[$dragState].background]};
53
+ pointer-events: none;
54
+ }
41
55
 
42
- &:focus-visible {
43
- outline: 2px solid ${({ theme })=>theme.colors.primary600};
44
- outline-offset: 2px;
56
+ & > * {
57
+ z-index: 1;
58
+ }
59
+ `}
60
+
61
+ &[data-disabled='true'] {
62
+ cursor: not-allowed;
45
63
  }
46
64
  `;
65
+ const IconFrame = styled(Flex)`
66
+ flex-shrink: 0;
67
+ width: 4rem;
68
+ height: 4rem;
69
+ border-radius: ${({ theme })=>theme.borderRadius};
70
+ background: ${({ theme })=>theme.colors.neutral200};
71
+ color: ${({ theme })=>theme.colors.neutral500};
72
+ `;
47
73
  /**
48
- * The field's own drop target. Deliberately not the Media Library page's
74
+ * The field's own drop target. It only takes drops: browsing and picking files
75
+ * go through the "Add asset" menu, so the field has one way in, not two.
76
+ *
77
+ * Deliberately not the Media Library page's
49
78
  * `UploadDropZoneProvider`: that one covers a whole route and paints a
50
79
  * full-surface overlay, where this has to stay inside one field on a form that
51
80
  * may hold several of them.
52
- */ const AssetDropZone = ({ disabled = false, onClick, onDropFiles })=>{
81
+ */ const AssetDropZone = ({ variant = 'bar', disabled = false, onDropFiles })=>{
53
82
  const { formatMessage } = useIntl();
54
83
  const [isDragging, setIsDragging] = useState(false);
55
84
  // Drag events fire on descendants too, so a plain boolean flickers as the
@@ -57,14 +86,12 @@ const Zone = styled.button`
57
86
  const dragDepth = useRef(0);
58
87
  const handleDragEnter = useCallback((event)=>{
59
88
  event.preventDefault();
60
- if (disabled || !event.dataTransfer.types.includes('Files')) {
89
+ if (!event.dataTransfer.types.includes('Files')) {
61
90
  return;
62
91
  }
63
92
  dragDepth.current += 1;
64
93
  setIsDragging(true);
65
- }, [
66
- disabled
67
- ]);
94
+ }, []);
68
95
  const handleDragLeave = useCallback((event)=>{
69
96
  event.preventDefault();
70
97
  dragDepth.current -= 1;
@@ -75,8 +102,11 @@ const Zone = styled.button`
75
102
  }, []);
76
103
  const handleDragOver = useCallback((event)=>{
77
104
  event.preventDefault();
78
- event.dataTransfer.dropEffect = 'copy';
79
- }, []);
105
+ // `none` shows the no-drop cursor, and the browser then fires no `drop`.
106
+ event.dataTransfer.dropEffect = disabled ? 'none' : 'copy';
107
+ }, [
108
+ disabled
109
+ ]);
80
110
  const handleDrop = useCallback((event)=>{
81
111
  event.preventDefault();
82
112
  dragDepth.current = 0;
@@ -93,30 +123,27 @@ const Zone = styled.button`
93
123
  onDropFiles
94
124
  ]);
95
125
  return /*#__PURE__*/ jsxs(Zone, {
96
- type: "button",
97
- $isDragging: isDragging,
98
- "aria-disabled": disabled,
99
- onClick: ()=>!disabled && onClick(),
126
+ $dragState: isDragging ? disabled ? 'reject' : 'accept' : 'idle',
127
+ $variant: variant,
128
+ "data-disabled": disabled,
100
129
  onDragEnter: handleDragEnter,
101
130
  onDragLeave: handleDragLeave,
102
131
  onDragOver: handleDragOver,
103
132
  onDrop: handleDrop,
104
133
  children: [
105
- /*#__PURE__*/ jsx(Flex, {
134
+ /*#__PURE__*/ jsx(IconFrame, {
106
135
  justifyContent: "center",
107
- color: disabled ? 'neutral500' : 'primary600',
108
- children: /*#__PURE__*/ jsx(PlusCircle, {
109
- width: "3.2rem",
110
- height: "3.2rem"
136
+ alignItems: "center",
137
+ children: /*#__PURE__*/ jsx(Images, {
138
+ width: "2.4rem",
139
+ height: "2.4rem"
111
140
  })
112
141
  }),
113
142
  /*#__PURE__*/ jsx(Typography, {
114
143
  textColor: "neutral600",
115
- fontWeight: "bold",
116
- variant: "pi",
117
144
  children: formatMessage({
118
- id: getTranslationKey('mediaLibraryInput.placeholder'),
119
- defaultMessage: 'Click to add an asset or drag and drop one in this area'
145
+ id: getTranslationKey('content-manager.input.placeholder'),
146
+ defaultMessage: 'Drag & drop an asset here'
120
147
  })
121
148
  })
122
149
  ]
@@ -1 +1 @@
1
- {"version":3,"file":"AssetDropZone.mjs","sources":["../../../../admin/src/components/MediaLibraryInput/AssetDropZone.tsx"],"sourcesContent":["import { useCallback, useRef, useState, type DragEvent } from 'react';\n\nimport { Flex, Typography } from '@strapi/design-system';\nimport { PlusCircle } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { styled } from 'styled-components';\n\nimport { getTranslationKey } from '../../utils/translations';\n\nconst Zone = styled.button<{ $isDragging: boolean }>`\n position: relative;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: ${({ theme }) => theme.spaces[2]};\n width: 100%;\n min-height: 12rem;\n padding: ${({ theme }) => theme.spaces[6]};\n border: 1px solid ${({ theme }) => theme.colors.neutral200};\n border-radius: ${({ theme }) => theme.borderRadius};\n background: ${({ theme }) => theme.colors.neutral100};\n cursor: pointer;\n\n // Only while a file is dragged over the zone: it marks where the file will\n // land, so it has nothing to say to a pointer that is merely passing through.\n // Drawn inside rather than on the box itself, so the field keeps its own\n // outline and the invitation reads as an area to drop into.\n &::after {\n content: '';\n position: absolute;\n inset: ${({ theme }) => theme.spaces[2]} ${({ theme }) => theme.spaces[4]};\n border: 1px dashed ${({ theme }) => theme.colors.primary600};\n border-radius: ${({ theme }) => theme.borderRadius};\n opacity: ${({ $isDragging }) => ($isDragging ? 1 : 0)};\n pointer-events: none;\n }\n\n &[aria-disabled='true'] {\n cursor: not-allowed;\n }\n\n &:focus-visible {\n outline: 2px solid ${({ theme }) => theme.colors.primary600};\n outline-offset: 2px;\n }\n`;\n\ninterface AssetDropZoneProps {\n disabled?: boolean;\n onClick: () => void;\n onDropFiles: (files: globalThis.File[]) => void;\n}\n\n/**\n * The field's own drop target. Deliberately not the Media Library page's\n * `UploadDropZoneProvider`: that one covers a whole route and paints a\n * full-surface overlay, where this has to stay inside one field on a form that\n * may hold several of them.\n */\nexport const AssetDropZone = ({ disabled = false, onClick, onDropFiles }: AssetDropZoneProps) => {\n const { formatMessage } = useIntl();\n const [isDragging, setIsDragging] = useState(false);\n // Drag events fire on descendants too, so a plain boolean flickers as the\n // pointer crosses the icon or the label. Counting enter/leave pairs doesn't.\n const dragDepth = useRef(0);\n\n const handleDragEnter = useCallback(\n (event: DragEvent<HTMLElement>) => {\n event.preventDefault();\n if (disabled || !event.dataTransfer.types.includes('Files')) {\n return;\n }\n dragDepth.current += 1;\n setIsDragging(true);\n },\n [disabled]\n );\n\n const handleDragLeave = useCallback((event: DragEvent<HTMLElement>) => {\n event.preventDefault();\n dragDepth.current -= 1;\n if (dragDepth.current <= 0) {\n dragDepth.current = 0;\n setIsDragging(false);\n }\n }, []);\n\n const handleDragOver = useCallback((event: DragEvent<HTMLElement>) => {\n event.preventDefault();\n event.dataTransfer.dropEffect = 'copy';\n }, []);\n\n const handleDrop = useCallback(\n (event: DragEvent<HTMLElement>) => {\n event.preventDefault();\n dragDepth.current = 0;\n setIsDragging(false);\n\n if (disabled) {\n return;\n }\n\n const files = Array.from(event.dataTransfer.files ?? []);\n if (files.length > 0) {\n onDropFiles(files);\n }\n },\n [disabled, onDropFiles]\n );\n\n return (\n <Zone\n type=\"button\"\n $isDragging={isDragging}\n aria-disabled={disabled}\n onClick={() => !disabled && onClick()}\n onDragEnter={handleDragEnter}\n onDragLeave={handleDragLeave}\n onDragOver={handleDragOver}\n onDrop={handleDrop}\n >\n {/* Same treatment as the repeatable-component initializer, so the two\n empty states in a form read as one affordance. */}\n <Flex justifyContent=\"center\" color={disabled ? 'neutral500' : 'primary600'}>\n <PlusCircle width=\"3.2rem\" height=\"3.2rem\" />\n </Flex>\n <Typography textColor=\"neutral600\" fontWeight=\"bold\" variant=\"pi\">\n {/* The legacy field's own key: identical wording, already translated in\n every locale, where a new key would ship English to all of them. */}\n {formatMessage({\n id: getTranslationKey('mediaLibraryInput.placeholder'),\n defaultMessage: 'Click to add an asset or drag and drop one in this area',\n })}\n </Typography>\n </Zone>\n );\n};\n"],"names":["Zone","styled","button","theme","spaces","colors","neutral200","borderRadius","neutral100","primary600","$isDragging","AssetDropZone","disabled","onClick","onDropFiles","formatMessage","useIntl","isDragging","setIsDragging","useState","dragDepth","useRef","handleDragEnter","useCallback","event","preventDefault","dataTransfer","types","includes","current","handleDragLeave","handleDragOver","dropEffect","handleDrop","files","Array","from","length","_jsxs","type","aria-disabled","onDragEnter","onDragLeave","onDragOver","onDrop","_jsx","Flex","justifyContent","color","PlusCircle","width","height","Typography","textColor","fontWeight","variant","id","getTranslationKey","defaultMessage"],"mappings":";;;;;;;;AASA,MAAMA,IAAAA,GAAOC,MAAAA,CAAOC,MAAgC;;;;;;OAM7C,EAAE,CAAC,EAAEC,KAAK,EAAE,GAAKA,KAAAA,CAAMC,MAAM,CAAC,CAAA,CAAE,CAAC;;;WAG7B,EAAE,CAAC,EAAED,KAAK,EAAE,GAAKA,KAAAA,CAAMC,MAAM,CAAC,CAAA,CAAE,CAAC;oBACxB,EAAE,CAAC,EAAED,KAAK,EAAE,GAAKA,KAAAA,CAAME,MAAM,CAACC,UAAU,CAAC;AAC5C,iBAAA,EAAE,CAAC,EAAEH,KAAK,EAAE,GAAKA,KAAAA,CAAMI,YAAY,CAAC;cACvC,EAAE,CAAC,EAAEJ,KAAK,EAAE,GAAKA,KAAAA,CAAME,MAAM,CAACG,UAAU,CAAC;;;;;;;;;;WAU5C,EAAE,CAAC,EAAEL,KAAK,EAAE,GAAKA,KAAAA,CAAMC,MAAM,CAAC,CAAA,CAAE,CAAC,CAAC,EAAE,CAAC,EAAED,KAAK,EAAE,GAAKA,KAAAA,CAAMC,MAAM,CAAC,CAAA,CAAE,CAAC;uBACvD,EAAE,CAAC,EAAED,KAAK,EAAE,GAAKA,KAAAA,CAAME,MAAM,CAACI,UAAU,CAAC;AAC7C,mBAAA,EAAE,CAAC,EAAEN,KAAK,EAAE,GAAKA,KAAAA,CAAMI,YAAY,CAAC;AAC1C,aAAA,EAAE,CAAC,EAAEG,WAAW,EAAE,GAAMA,WAAAA,GAAc,IAAI,CAAA,CAAG;;;;;;;;;uBASnC,EAAE,CAAC,EAAEP,KAAK,EAAE,GAAKA,KAAAA,CAAME,MAAM,CAACI,UAAU,CAAC;;;AAGhE,CAAC;AAQD;;;;;IAMO,MAAME,aAAAA,GAAgB,CAAC,EAAEC,QAAAA,GAAW,KAAK,EAAEC,OAAO,EAAEC,WAAW,EAAsB,GAAA;IAC1F,MAAM,EAAEC,aAAa,EAAE,GAAGC,OAAAA,EAAAA;AAC1B,IAAA,MAAM,CAACC,UAAAA,EAAYC,aAAAA,CAAc,GAAGC,QAAAA,CAAS,KAAA,CAAA;;;AAG7C,IAAA,MAAMC,YAAYC,MAAAA,CAAO,CAAA,CAAA;IAEzB,MAAMC,eAAAA,GAAkBC,YACtB,CAACC,KAAAA,GAAAA;AACCA,QAAAA,KAAAA,CAAMC,cAAc,EAAA;QACpB,IAAIb,QAAAA,IAAY,CAACY,KAAAA,CAAME,YAAY,CAACC,KAAK,CAACC,QAAQ,CAAC,OAAA,CAAA,EAAU;AAC3D,YAAA;AACF,QAAA;AACAR,QAAAA,SAAAA,CAAUS,OAAO,IAAI,CAAA;QACrBX,aAAAA,CAAc,IAAA,CAAA;IAChB,CAAA,EACA;AAACN,QAAAA;AAAS,KAAA,CAAA;IAGZ,MAAMkB,eAAAA,GAAkBP,YAAY,CAACC,KAAAA,GAAAA;AACnCA,QAAAA,KAAAA,CAAMC,cAAc,EAAA;AACpBL,QAAAA,SAAAA,CAAUS,OAAO,IAAI,CAAA;QACrB,IAAIT,SAAAA,CAAUS,OAAO,IAAI,CAAA,EAAG;AAC1BT,YAAAA,SAAAA,CAAUS,OAAO,GAAG,CAAA;YACpBX,aAAAA,CAAc,KAAA,CAAA;AAChB,QAAA;AACF,IAAA,CAAA,EAAG,EAAE,CAAA;IAEL,MAAMa,cAAAA,GAAiBR,YAAY,CAACC,KAAAA,GAAAA;AAClCA,QAAAA,KAAAA,CAAMC,cAAc,EAAA;QACpBD,KAAAA,CAAME,YAAY,CAACM,UAAU,GAAG,MAAA;AAClC,IAAA,CAAA,EAAG,EAAE,CAAA;IAEL,MAAMC,UAAAA,GAAaV,YACjB,CAACC,KAAAA,GAAAA;AACCA,QAAAA,KAAAA,CAAMC,cAAc,EAAA;AACpBL,QAAAA,SAAAA,CAAUS,OAAO,GAAG,CAAA;QACpBX,aAAAA,CAAc,KAAA,CAAA;AAEd,QAAA,IAAIN,QAAAA,EAAU;AACZ,YAAA;AACF,QAAA;QAEA,MAAMsB,KAAAA,GAAQC,MAAMC,IAAI,CAACZ,MAAME,YAAY,CAACQ,KAAK,IAAI,EAAE,CAAA;QACvD,IAAIA,KAAAA,CAAMG,MAAM,GAAG,CAAA,EAAG;YACpBvB,WAAAA,CAAYoB,KAAAA,CAAAA;AACd,QAAA;IACF,CAAA,EACA;AAACtB,QAAAA,QAAAA;AAAUE,QAAAA;AAAY,KAAA,CAAA;AAGzB,IAAA,qBACEwB,IAAA,CAACtC,IAAAA,EAAAA;QACCuC,IAAAA,EAAK,QAAA;QACL7B,WAAAA,EAAaO,UAAAA;QACbuB,eAAAA,EAAe5B,QAAAA;QACfC,OAAAA,EAAS,IAAM,CAACD,QAAAA,IAAYC,OAAAA,EAAAA;QAC5B4B,WAAAA,EAAanB,eAAAA;QACboB,WAAAA,EAAaZ,eAAAA;QACba,UAAAA,EAAYZ,cAAAA;QACZa,MAAAA,EAAQX,UAAAA;;0BAIRY,GAAA,CAACC,IAAAA,EAAAA;gBAAKC,cAAAA,EAAe,QAAA;AAASC,gBAAAA,KAAAA,EAAOpC,WAAW,YAAA,GAAe,YAAA;AAC7D,gBAAA,QAAA,gBAAAiC,GAAA,CAACI,UAAAA,EAAAA;oBAAWC,KAAAA,EAAM,QAAA;oBAASC,MAAAA,EAAO;;;0BAEpCN,GAAA,CAACO,UAAAA,EAAAA;gBAAWC,SAAAA,EAAU,YAAA;gBAAaC,UAAAA,EAAW,MAAA;gBAAOC,OAAAA,EAAQ,IAAA;0BAG1DxC,aAAAA,CAAc;AACbyC,oBAAAA,EAAAA,EAAIC,iBAAAA,CAAkB,+BAAA,CAAA;oBACtBC,cAAAA,EAAgB;AAClB,iBAAA;;;;AAIR;;;;"}
1
+ {"version":3,"file":"AssetDropZone.mjs","sources":["../../../../admin/src/components/MediaLibraryInput/AssetDropZone.tsx"],"sourcesContent":["import { useCallback, useRef, useState, type DragEvent } from 'react';\n\nimport { Flex, Typography } from '@strapi/design-system';\nimport { Images } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { styled } from 'styled-components';\n\nimport { getTranslationKey } from '../../utils/translations';\n\n/**\n * `bar` on an empty field, `tile` after a multiple field's cards, `stacked`\n * below them when the field is too narrow for both on one row.\n */\nexport type ZoneVariant = 'bar' | 'tile' | 'stacked';\n\ntype DragState = 'idle' | 'accept' | 'reject';\n\nconst DRAG_FRAME_COLORS = {\n accept: { border: 'primary600', background: 'primary100' },\n reject: { border: 'neutral300', background: 'neutral150' },\n} as const;\n\nconst Zone = styled.div<{ $dragState: DragState; $variant: ZoneVariant }>`\n position: relative;\n display: flex;\n align-items: center;\n gap: ${({ theme }) => theme.spaces[4]};\n width: 100%;\n border-radius: ${({ theme }) => theme.borderRadius};\n text-align: ${({ $variant }) => ($variant === 'bar' ? 'start' : 'center')};\n\n ${({ $variant, theme }) =>\n $variant !== 'bar'\n ? `\n flex-direction: column;\n justify-content: center;\n height: 100%;\n min-height: ${$variant === 'tile' ? '20.8rem' : 'auto'};\n padding: ${theme.spaces[4]};\n border: 1px dashed ${theme.colors.neutral300};\n background: ${theme.colors.neutral0};\n `\n : `\n min-height: 7.2rem;\n padding: ${theme.spaces[4]};\n border: 1px solid ${theme.colors.neutral200};\n background: ${theme.colors.neutral100};\n `}\n\n // Only while a file is dragged over the zone: a solid frame inset from the\n // zone's own border marks where the file will land, greyed out when it can't.\n ${({ $dragState, theme }) =>\n $dragState !== 'idle' &&\n `\n &::after {\n content: '';\n position: absolute;\n inset: ${theme.spaces[2]};\n border: 1px solid ${theme.colors[DRAG_FRAME_COLORS[$dragState].border]};\n border-radius: ${theme.borderRadius};\n background: ${theme.colors[DRAG_FRAME_COLORS[$dragState].background]};\n pointer-events: none;\n }\n\n & > * {\n z-index: 1;\n }\n `}\n\n &[data-disabled='true'] {\n cursor: not-allowed;\n }\n`;\n\nconst IconFrame = styled(Flex)`\n flex-shrink: 0;\n width: 4rem;\n height: 4rem;\n border-radius: ${({ theme }) => theme.borderRadius};\n background: ${({ theme }) => theme.colors.neutral200};\n color: ${({ theme }) => theme.colors.neutral500};\n`;\n\ninterface AssetDropZoneProps {\n variant?: ZoneVariant;\n disabled?: boolean;\n onDropFiles: (files: globalThis.File[]) => void;\n}\n\n/**\n * The field's own drop target. It only takes drops: browsing and picking files\n * go through the \"Add asset\" menu, so the field has one way in, not two.\n *\n * Deliberately not the Media Library page's\n * `UploadDropZoneProvider`: that one covers a whole route and paints a\n * full-surface overlay, where this has to stay inside one field on a form that\n * may hold several of them.\n */\nexport const AssetDropZone = ({\n variant = 'bar',\n disabled = false,\n onDropFiles,\n}: AssetDropZoneProps) => {\n const { formatMessage } = useIntl();\n const [isDragging, setIsDragging] = useState(false);\n // Drag events fire on descendants too, so a plain boolean flickers as the\n // pointer crosses the icon or the label. Counting enter/leave pairs doesn't.\n const dragDepth = useRef(0);\n\n const handleDragEnter = useCallback((event: DragEvent<HTMLElement>) => {\n event.preventDefault();\n if (!event.dataTransfer.types.includes('Files')) {\n return;\n }\n dragDepth.current += 1;\n setIsDragging(true);\n }, []);\n\n const handleDragLeave = useCallback((event: DragEvent<HTMLElement>) => {\n event.preventDefault();\n dragDepth.current -= 1;\n if (dragDepth.current <= 0) {\n dragDepth.current = 0;\n setIsDragging(false);\n }\n }, []);\n\n const handleDragOver = useCallback(\n (event: DragEvent<HTMLElement>) => {\n event.preventDefault();\n // `none` shows the no-drop cursor, and the browser then fires no `drop`.\n event.dataTransfer.dropEffect = disabled ? 'none' : 'copy';\n },\n [disabled]\n );\n\n const handleDrop = useCallback(\n (event: DragEvent<HTMLElement>) => {\n event.preventDefault();\n dragDepth.current = 0;\n setIsDragging(false);\n\n if (disabled) {\n return;\n }\n\n const files = Array.from(event.dataTransfer.files ?? []);\n if (files.length > 0) {\n onDropFiles(files);\n }\n },\n [disabled, onDropFiles]\n );\n\n return (\n <Zone\n $dragState={isDragging ? (disabled ? 'reject' : 'accept') : 'idle'}\n $variant={variant}\n data-disabled={disabled}\n onDragEnter={handleDragEnter}\n onDragLeave={handleDragLeave}\n onDragOver={handleDragOver}\n onDrop={handleDrop}\n >\n <IconFrame justifyContent=\"center\" alignItems=\"center\">\n <Images width=\"2.4rem\" height=\"2.4rem\" />\n </IconFrame>\n <Typography textColor=\"neutral600\">\n {formatMessage({\n id: getTranslationKey('content-manager.input.placeholder'),\n defaultMessage: 'Drag & drop an asset here',\n })}\n </Typography>\n </Zone>\n );\n};\n"],"names":["DRAG_FRAME_COLORS","accept","border","background","reject","Zone","styled","div","theme","spaces","borderRadius","$variant","colors","neutral300","neutral0","neutral200","neutral100","$dragState","IconFrame","Flex","neutral500","AssetDropZone","variant","disabled","onDropFiles","formatMessage","useIntl","isDragging","setIsDragging","useState","dragDepth","useRef","handleDragEnter","useCallback","event","preventDefault","dataTransfer","types","includes","current","handleDragLeave","handleDragOver","dropEffect","handleDrop","files","Array","from","length","_jsxs","data-disabled","onDragEnter","onDragLeave","onDragOver","onDrop","_jsx","justifyContent","alignItems","Images","width","height","Typography","textColor","id","getTranslationKey","defaultMessage"],"mappings":"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"}
@@ -0,0 +1,109 @@
1
+ 'use strict';
2
+
3
+ var jsxRuntime = require('react/jsx-runtime');
4
+ var React = require('react');
5
+ var designSystem = require('@strapi/design-system');
6
+ var styledComponents = require('styled-components');
7
+ var enums = require('../../enums.js');
8
+ var files = require('../../utils/files.js');
9
+ var getAssetIcon = require('../../utils/getAssetIcon.js');
10
+
11
+ const Frame = styledComponents.styled(designSystem.Flex)`
12
+ flex-shrink: 0;
13
+ overflow: hidden;
14
+ color: ${({ theme })=>theme.colors.neutral500};
15
+ background: ${({ theme })=>theme.colors.neutral150};
16
+
17
+ ${({ $size, theme })=>$size === 'S' ? `
18
+ width: 4rem;
19
+ height: 4rem;
20
+ border-radius: ${theme.borderRadius};
21
+ ` : `
22
+ width: 100%;
23
+ height: 16rem;
24
+ `}
25
+ `;
26
+ const PreviewImage = styledComponents.styled.img`
27
+ width: 100%;
28
+ height: 100%;
29
+ object-fit: cover;
30
+ `;
31
+ const PreviewFrame = ({ size, src, alt = '', crossOrigin, mime, ext })=>{
32
+ if (src) {
33
+ return /*#__PURE__*/ jsxRuntime.jsx(Frame, {
34
+ $size: size,
35
+ children: /*#__PURE__*/ jsxRuntime.jsx(PreviewImage, {
36
+ src: src,
37
+ alt: alt,
38
+ crossOrigin: crossOrigin,
39
+ draggable: false
40
+ })
41
+ });
42
+ }
43
+ const Icon = getAssetIcon.getAssetIcon(mime, ext);
44
+ const iconSize = size === 'S' ? 20 : 32;
45
+ return /*#__PURE__*/ jsxRuntime.jsx(Frame, {
46
+ $size: size,
47
+ justifyContent: "center",
48
+ alignItems: "center",
49
+ children: /*#__PURE__*/ jsxRuntime.jsx(Icon, {
50
+ width: iconSize,
51
+ height: iconSize
52
+ })
53
+ });
54
+ };
55
+ const AssetPreview = ({ asset, size })=>{
56
+ const { alternativeText, ext, formats, mime, url, updatedAt, isLocal, isUrlSigned } = asset;
57
+ if (!mime?.includes(enums.ASSET_TYPES.Image)) {
58
+ return /*#__PURE__*/ jsxRuntime.jsx(PreviewFrame, {
59
+ size: size,
60
+ mime: mime,
61
+ ext: ext
62
+ });
63
+ }
64
+ // Same two rules the grid preview applies: a `updatedAt` cache-buster so a
65
+ // replaced asset stops serving its old thumbnail, skipped on signed URLs
66
+ // because an extra param invalidates the signature (#26581).
67
+ // Cards are wider than a thumbnail, so they take the `small` format when there is one.
68
+ const sizedFormats = formats;
69
+ const preferredUrl = size === 'S' ? formats?.thumbnail?.url : sizedFormats?.small?.url ?? url;
70
+ const rawUrl = files.prefixFileUrlWithBackendUrl(preferredUrl) ?? files.prefixFileUrlWithBackendUrl(url);
71
+ const cacheKey = updatedAt && !isUrlSigned ? new Date(updatedAt).getTime() : undefined;
72
+ const src = rawUrl && cacheKey !== undefined ? `${rawUrl}${rawUrl.includes('?') ? '&' : '?'}v=${cacheKey}` : rawUrl;
73
+ return /*#__PURE__*/ jsxRuntime.jsx(PreviewFrame, {
74
+ size: size,
75
+ src: src,
76
+ alt: alternativeText || '',
77
+ crossOrigin: !isLocal && isUrlSigned ? 'anonymous' : undefined,
78
+ mime: mime,
79
+ ext: ext
80
+ });
81
+ };
82
+ /**
83
+ * Previews a file that has not reached the server yet, straight from the
84
+ * user's disk.
85
+ */ const UploadPreview = ({ file, size })=>{
86
+ const isImage = file?.type.startsWith(enums.ASSET_TYPES.Image) ?? false;
87
+ const [src, setSrc] = React.useState();
88
+ React.useEffect(()=>{
89
+ if (!file || !isImage) {
90
+ setSrc(undefined);
91
+ return undefined;
92
+ }
93
+ const objectUrl = URL.createObjectURL(file);
94
+ setSrc(objectUrl);
95
+ return ()=>URL.revokeObjectURL(objectUrl);
96
+ }, [
97
+ file,
98
+ isImage
99
+ ]);
100
+ return /*#__PURE__*/ jsxRuntime.jsx(PreviewFrame, {
101
+ size: size,
102
+ src: src,
103
+ mime: file?.type
104
+ });
105
+ };
106
+
107
+ exports.AssetPreview = AssetPreview;
108
+ exports.UploadPreview = UploadPreview;
109
+ //# sourceMappingURL=AssetPreview.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AssetPreview.js","sources":["../../../../admin/src/components/MediaLibraryInput/AssetPreview.tsx"],"sourcesContent":["import { useEffect, useState } from 'react';\n\nimport { Flex } from '@strapi/design-system';\nimport { styled } from 'styled-components';\n\nimport { ASSET_TYPES } from '../../enums';\nimport { prefixFileUrlWithBackendUrl } from '../../utils/files';\nimport { getAssetIcon } from '../../utils/getAssetIcon';\n\nimport type { File } from '../../../../shared/contracts/files';\n\ntype PreviewSize = 'S' | 'L';\n\nconst Frame = styled(Flex)<{ $size: PreviewSize }>`\n flex-shrink: 0;\n overflow: hidden;\n color: ${({ theme }) => theme.colors.neutral500};\n background: ${({ theme }) => theme.colors.neutral150};\n\n ${({ $size, theme }) =>\n $size === 'S'\n ? `\n width: 4rem;\n height: 4rem;\n border-radius: ${theme.borderRadius};\n `\n : `\n width: 100%;\n height: 16rem;\n `}\n`;\n\nconst PreviewImage = styled.img`\n width: 100%;\n height: 100%;\n object-fit: cover;\n`;\n\ninterface PreviewFrameProps {\n size: PreviewSize;\n src?: string;\n alt?: string;\n crossOrigin?: 'anonymous';\n mime?: string;\n ext?: string;\n}\n\nconst PreviewFrame = ({ size, src, alt = '', crossOrigin, mime, ext }: PreviewFrameProps) => {\n if (src) {\n return (\n <Frame $size={size}>\n <PreviewImage src={src} alt={alt} crossOrigin={crossOrigin} draggable={false} />\n </Frame>\n );\n }\n\n const Icon = getAssetIcon(mime, ext);\n const iconSize = size === 'S' ? 20 : 32;\n\n return (\n <Frame $size={size} justifyContent=\"center\" alignItems=\"center\">\n <Icon width={iconSize} height={iconSize} />\n </Frame>\n );\n};\n\ninterface AssetPreviewProps {\n asset: File;\n size: PreviewSize;\n}\n\nexport const AssetPreview = ({ asset, size }: AssetPreviewProps) => {\n const { alternativeText, ext, formats, mime, url, updatedAt, isLocal, isUrlSigned } = asset;\n\n if (!mime?.includes(ASSET_TYPES.Image)) {\n return <PreviewFrame size={size} mime={mime} ext={ext} />;\n }\n\n // Same two rules the grid preview applies: a `updatedAt` cache-buster so a\n // replaced asset stops serving its old thumbnail, skipped on signed URLs\n // because an extra param invalidates the signature (#26581).\n // Cards are wider than a thumbnail, so they take the `small` format when there is one.\n const sizedFormats = formats as Record<string, { url?: string } | undefined> | undefined;\n const preferredUrl = size === 'S' ? formats?.thumbnail?.url : (sizedFormats?.small?.url ?? url);\n const rawUrl = prefixFileUrlWithBackendUrl(preferredUrl) ?? prefixFileUrlWithBackendUrl(url);\n const cacheKey = updatedAt && !isUrlSigned ? new Date(updatedAt).getTime() : undefined;\n const src =\n rawUrl && cacheKey !== undefined\n ? `${rawUrl}${rawUrl.includes('?') ? '&' : '?'}v=${cacheKey}`\n : rawUrl;\n\n return (\n <PreviewFrame\n size={size}\n src={src}\n alt={alternativeText || ''}\n crossOrigin={!isLocal && isUrlSigned ? 'anonymous' : undefined}\n mime={mime}\n ext={ext}\n />\n );\n};\n\ninterface UploadPreviewProps {\n file?: globalThis.File;\n size: PreviewSize;\n}\n\n/**\n * Previews a file that has not reached the server yet, straight from the\n * user's disk.\n */\nexport const UploadPreview = ({ file, size }: UploadPreviewProps) => {\n const isImage = file?.type.startsWith(ASSET_TYPES.Image) ?? false;\n const [src, setSrc] = useState<string>();\n\n useEffect(() => {\n if (!file || !isImage) {\n setSrc(undefined);\n return undefined;\n }\n\n const objectUrl = URL.createObjectURL(file);\n setSrc(objectUrl);\n\n return () => URL.revokeObjectURL(objectUrl);\n }, [file, isImage]);\n\n return <PreviewFrame size={size} src={src} mime={file?.type} />;\n};\n"],"names":["Frame","styled","Flex","theme","colors","neutral500","neutral150","$size","borderRadius","PreviewImage","img","PreviewFrame","size","src","alt","crossOrigin","mime","ext","_jsx","draggable","Icon","getAssetIcon","iconSize","justifyContent","alignItems","width","height","AssetPreview","asset","alternativeText","formats","url","updatedAt","isLocal","isUrlSigned","includes","ASSET_TYPES","Image","sizedFormats","preferredUrl","thumbnail","small","rawUrl","prefixFileUrlWithBackendUrl","cacheKey","Date","getTime","undefined","UploadPreview","file","isImage","type","startsWith","setSrc","useState","useEffect","objectUrl","URL","createObjectURL","revokeObjectURL"],"mappings":"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"}
@@ -0,0 +1,106 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import { useState, useEffect } from 'react';
3
+ import { Flex } from '@strapi/design-system';
4
+ import { styled } from 'styled-components';
5
+ import { ASSET_TYPES } from '../../enums.mjs';
6
+ import { prefixFileUrlWithBackendUrl } from '../../utils/files.mjs';
7
+ import { getAssetIcon } from '../../utils/getAssetIcon.mjs';
8
+
9
+ const Frame = styled(Flex)`
10
+ flex-shrink: 0;
11
+ overflow: hidden;
12
+ color: ${({ theme })=>theme.colors.neutral500};
13
+ background: ${({ theme })=>theme.colors.neutral150};
14
+
15
+ ${({ $size, theme })=>$size === 'S' ? `
16
+ width: 4rem;
17
+ height: 4rem;
18
+ border-radius: ${theme.borderRadius};
19
+ ` : `
20
+ width: 100%;
21
+ height: 16rem;
22
+ `}
23
+ `;
24
+ const PreviewImage = styled.img`
25
+ width: 100%;
26
+ height: 100%;
27
+ object-fit: cover;
28
+ `;
29
+ const PreviewFrame = ({ size, src, alt = '', crossOrigin, mime, ext })=>{
30
+ if (src) {
31
+ return /*#__PURE__*/ jsx(Frame, {
32
+ $size: size,
33
+ children: /*#__PURE__*/ jsx(PreviewImage, {
34
+ src: src,
35
+ alt: alt,
36
+ crossOrigin: crossOrigin,
37
+ draggable: false
38
+ })
39
+ });
40
+ }
41
+ const Icon = getAssetIcon(mime, ext);
42
+ const iconSize = size === 'S' ? 20 : 32;
43
+ return /*#__PURE__*/ jsx(Frame, {
44
+ $size: size,
45
+ justifyContent: "center",
46
+ alignItems: "center",
47
+ children: /*#__PURE__*/ jsx(Icon, {
48
+ width: iconSize,
49
+ height: iconSize
50
+ })
51
+ });
52
+ };
53
+ const AssetPreview = ({ asset, size })=>{
54
+ const { alternativeText, ext, formats, mime, url, updatedAt, isLocal, isUrlSigned } = asset;
55
+ if (!mime?.includes(ASSET_TYPES.Image)) {
56
+ return /*#__PURE__*/ jsx(PreviewFrame, {
57
+ size: size,
58
+ mime: mime,
59
+ ext: ext
60
+ });
61
+ }
62
+ // Same two rules the grid preview applies: a `updatedAt` cache-buster so a
63
+ // replaced asset stops serving its old thumbnail, skipped on signed URLs
64
+ // because an extra param invalidates the signature (#26581).
65
+ // Cards are wider than a thumbnail, so they take the `small` format when there is one.
66
+ const sizedFormats = formats;
67
+ const preferredUrl = size === 'S' ? formats?.thumbnail?.url : sizedFormats?.small?.url ?? url;
68
+ const rawUrl = prefixFileUrlWithBackendUrl(preferredUrl) ?? prefixFileUrlWithBackendUrl(url);
69
+ const cacheKey = updatedAt && !isUrlSigned ? new Date(updatedAt).getTime() : undefined;
70
+ const src = rawUrl && cacheKey !== undefined ? `${rawUrl}${rawUrl.includes('?') ? '&' : '?'}v=${cacheKey}` : rawUrl;
71
+ return /*#__PURE__*/ jsx(PreviewFrame, {
72
+ size: size,
73
+ src: src,
74
+ alt: alternativeText || '',
75
+ crossOrigin: !isLocal && isUrlSigned ? 'anonymous' : undefined,
76
+ mime: mime,
77
+ ext: ext
78
+ });
79
+ };
80
+ /**
81
+ * Previews a file that has not reached the server yet, straight from the
82
+ * user's disk.
83
+ */ const UploadPreview = ({ file, size })=>{
84
+ const isImage = file?.type.startsWith(ASSET_TYPES.Image) ?? false;
85
+ const [src, setSrc] = useState();
86
+ useEffect(()=>{
87
+ if (!file || !isImage) {
88
+ setSrc(undefined);
89
+ return undefined;
90
+ }
91
+ const objectUrl = URL.createObjectURL(file);
92
+ setSrc(objectUrl);
93
+ return ()=>URL.revokeObjectURL(objectUrl);
94
+ }, [
95
+ file,
96
+ isImage
97
+ ]);
98
+ return /*#__PURE__*/ jsx(PreviewFrame, {
99
+ size: size,
100
+ src: src,
101
+ mime: file?.type
102
+ });
103
+ };
104
+
105
+ export { AssetPreview, UploadPreview };
106
+ //# sourceMappingURL=AssetPreview.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AssetPreview.mjs","sources":["../../../../admin/src/components/MediaLibraryInput/AssetPreview.tsx"],"sourcesContent":["import { useEffect, useState } from 'react';\n\nimport { Flex } from '@strapi/design-system';\nimport { styled } from 'styled-components';\n\nimport { ASSET_TYPES } from '../../enums';\nimport { prefixFileUrlWithBackendUrl } from '../../utils/files';\nimport { getAssetIcon } from '../../utils/getAssetIcon';\n\nimport type { File } from '../../../../shared/contracts/files';\n\ntype PreviewSize = 'S' | 'L';\n\nconst Frame = styled(Flex)<{ $size: PreviewSize }>`\n flex-shrink: 0;\n overflow: hidden;\n color: ${({ theme }) => theme.colors.neutral500};\n background: ${({ theme }) => theme.colors.neutral150};\n\n ${({ $size, theme }) =>\n $size === 'S'\n ? `\n width: 4rem;\n height: 4rem;\n border-radius: ${theme.borderRadius};\n `\n : `\n width: 100%;\n height: 16rem;\n `}\n`;\n\nconst PreviewImage = styled.img`\n width: 100%;\n height: 100%;\n object-fit: cover;\n`;\n\ninterface PreviewFrameProps {\n size: PreviewSize;\n src?: string;\n alt?: string;\n crossOrigin?: 'anonymous';\n mime?: string;\n ext?: string;\n}\n\nconst PreviewFrame = ({ size, src, alt = '', crossOrigin, mime, ext }: PreviewFrameProps) => {\n if (src) {\n return (\n <Frame $size={size}>\n <PreviewImage src={src} alt={alt} crossOrigin={crossOrigin} draggable={false} />\n </Frame>\n );\n }\n\n const Icon = getAssetIcon(mime, ext);\n const iconSize = size === 'S' ? 20 : 32;\n\n return (\n <Frame $size={size} justifyContent=\"center\" alignItems=\"center\">\n <Icon width={iconSize} height={iconSize} />\n </Frame>\n );\n};\n\ninterface AssetPreviewProps {\n asset: File;\n size: PreviewSize;\n}\n\nexport const AssetPreview = ({ asset, size }: AssetPreviewProps) => {\n const { alternativeText, ext, formats, mime, url, updatedAt, isLocal, isUrlSigned } = asset;\n\n if (!mime?.includes(ASSET_TYPES.Image)) {\n return <PreviewFrame size={size} mime={mime} ext={ext} />;\n }\n\n // Same two rules the grid preview applies: a `updatedAt` cache-buster so a\n // replaced asset stops serving its old thumbnail, skipped on signed URLs\n // because an extra param invalidates the signature (#26581).\n // Cards are wider than a thumbnail, so they take the `small` format when there is one.\n const sizedFormats = formats as Record<string, { url?: string } | undefined> | undefined;\n const preferredUrl = size === 'S' ? formats?.thumbnail?.url : (sizedFormats?.small?.url ?? url);\n const rawUrl = prefixFileUrlWithBackendUrl(preferredUrl) ?? prefixFileUrlWithBackendUrl(url);\n const cacheKey = updatedAt && !isUrlSigned ? new Date(updatedAt).getTime() : undefined;\n const src =\n rawUrl && cacheKey !== undefined\n ? `${rawUrl}${rawUrl.includes('?') ? '&' : '?'}v=${cacheKey}`\n : rawUrl;\n\n return (\n <PreviewFrame\n size={size}\n src={src}\n alt={alternativeText || ''}\n crossOrigin={!isLocal && isUrlSigned ? 'anonymous' : undefined}\n mime={mime}\n ext={ext}\n />\n );\n};\n\ninterface UploadPreviewProps {\n file?: globalThis.File;\n size: PreviewSize;\n}\n\n/**\n * Previews a file that has not reached the server yet, straight from the\n * user's disk.\n */\nexport const UploadPreview = ({ file, size }: UploadPreviewProps) => {\n const isImage = file?.type.startsWith(ASSET_TYPES.Image) ?? false;\n const [src, setSrc] = useState<string>();\n\n useEffect(() => {\n if (!file || !isImage) {\n setSrc(undefined);\n return undefined;\n }\n\n const objectUrl = URL.createObjectURL(file);\n setSrc(objectUrl);\n\n return () => URL.revokeObjectURL(objectUrl);\n }, [file, isImage]);\n\n return <PreviewFrame size={size} src={src} mime={file?.type} />;\n};\n"],"names":["Frame","styled","Flex","theme","colors","neutral500","neutral150","$size","borderRadius","PreviewImage","img","PreviewFrame","size","src","alt","crossOrigin","mime","ext","_jsx","draggable","Icon","getAssetIcon","iconSize","justifyContent","alignItems","width","height","AssetPreview","asset","alternativeText","formats","url","updatedAt","isLocal","isUrlSigned","includes","ASSET_TYPES","Image","sizedFormats","preferredUrl","thumbnail","small","rawUrl","prefixFileUrlWithBackendUrl","cacheKey","Date","getTime","undefined","UploadPreview","file","isImage","type","startsWith","setSrc","useState","useEffect","objectUrl","URL","createObjectURL","revokeObjectURL"],"mappings":"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"}