@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 +1 @@
1
- {"version":3,"file":"AssetsGrid.mjs","sources":["../../../../../admin/src/pages/Assets/components/AssetsGrid.tsx"],"sourcesContent":["import { Box, Card, CardBody, CardHeader, Checkbox, Flex } from '@strapi/design-system';\nimport { Folder as FolderIcon } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { styled, css } from 'styled-components';\n\nimport { TruncatedText } from '../../../components/TruncatedText';\nimport { ASSET_TYPES } from '../../../enums';\nimport { useMediaLibraryPermissions } from '../../../hooks/useMediaLibraryPermissions';\nimport { prefixFileUrlWithBackendUrl } from '../../../utils/files';\nimport { getAssetIcon } from '../../../utils/getAssetIcon';\nimport { isEventFromWithin } from '../../../utils/isEventFromWithin';\nimport { getTranslationKey } from '../../../utils/translations';\nimport { ASSET_DETAILS_TRIGGER_PROPS, ASSET_ITEM_CONTROL_PROPS } from '../constants';\nimport { useAssetSelection } from '../hooks/useAssetSelection';\nimport { useBusyAssetsOptional } from '../hooks/useBusyAssets';\nimport { useFolderNavigation } from '../hooks/useFolderNavigation';\nimport { buildRenderedKeys } from '../utils/renderedKeys';\nimport { assetKey, folderKey, type ItemKey } from '../utils/selection';\n\nimport { AssetActionsMenu } from './AssetActionsMenu';\nimport { BusyOverlay } from './BusyOverlay';\nimport { useAssetsDndOptional } from './Dnd/AssetsDndProvider';\nimport { useFileDraggable, useFolderDraggableDroppable } from './Dnd/useAssetDnd';\nimport { FolderActionsMenu } from './FolderActionsMenu';\nimport { useItemContextMenuTrigger } from './ItemContextMenu';\n\nimport type { File } from '../../../../../shared/contracts/files';\nimport type { Folder } from '../../../../../shared/contracts/folders';\n\nconst EMPTY_FOLDERS: NonNullable<AssetsGridProps['folders']> = [];\n\n/* -------------------------------------------------------------------------------------------------\n * AssetsGrid\n * -----------------------------------------------------------------------------------------------*/\n\n// Cards own click, Enter and Space; the controls sitting on them (checkbox, \"...\"\n// menu) must not let those reach the card. Scoped to the wrapper's own DOM\n// subtree so the menu's portaled content — a React child of the wrapper, but\n// never a DOM descendant — still reaches `document`, where Radix listens in\n// order to dismiss its layers.\nconst stopCardEvent = (e: React.SyntheticEvent) => {\n if (isEventFromWithin(e)) {\n e.stopPropagation();\n }\n};\n\n// Top-left selection checkbox overlaid on the asset preview, always visible.\nconst CheckboxOverlay = styled(Flex)`\n position: absolute;\n top: ${({ theme }) => theme.spaces[3]};\n left: ${({ theme }) => theme.spaces[3]};\n z-index: 1;\n box-shadow: ${({ theme }) => theme.shadows.filterShadow};\n`;\n\nconst StyledCard = styled(Card)<{\n $isDragging?: boolean;\n $isMovePending?: boolean;\n $isBusy?: boolean;\n $isSelected?: boolean;\n}>`\n border: 1px solid\n ${({ theme, $isSelected }) => ($isSelected ? theme.colors.primary600 : theme.colors.neutral200)};\n border-radius: 8px;\n overflow: hidden;\n isolation: isolate;\n cursor: ${({ $isMovePending, $isBusy }) => ($isMovePending || $isBusy ? 'wait' : 'pointer')};\n opacity: ${({ $isDragging }) => ($isDragging ? 0.4 : 1)};\n /* No opacity change while busy — the overlay does the dimming, and stacking\n one on the other would wash the card out. */\n pointer-events: ${({ $isMovePending, $isBusy }) => ($isMovePending || $isBusy ? 'none' : 'auto')};\n background: ${({ theme, $isSelected }) => ($isSelected ? theme.colors.primary100 : undefined)};\n /* Shift+click range selection must not highlight card text. */\n user-select: none;\n\n &:hover {\n background: ${({ theme }) => theme.colors.primary100};\n }\n\n &:focus-visible {\n outline: 2px solid ${({ theme }) => theme.colors.primary600};\n outline-offset: 2px;\n }\n`;\n\n/* -------------------------------------------------------------------------------------------------\n * FolderCard\n * -----------------------------------------------------------------------------------------------*/\n\nconst FoldersRow = styled(Box)`\n grid-column: 1 / -1;\n`;\n\nconst MIN_TILE_WIDTH = '240px';\n\nconst ItemsGrid = styled(Box)`\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(min(${MIN_TILE_WIDTH}, 100%), 1fr));\n gap: ${({ theme }) => theme.spaces[4]};\n`;\n\nconst StyledFolderCard = styled(Flex)<{\n $isDragging?: boolean;\n $isMovePending?: boolean;\n $isValidDropTarget?: boolean;\n $isInvalidDropTarget?: boolean;\n $isSelected?: boolean;\n}>`\n width: 100%;\n user-select: none;\n padding: ${({ theme }) => `${theme.spaces[2]} ${theme.spaces[3]}`}; // 8px 12px\n align-items: center;\n gap: ${({ theme }) => theme.spaces[2]}; // 8px\n border: 1px solid\n ${({ theme, $isSelected }) => ($isSelected ? theme.colors.primary600 : theme.colors.neutral200)};\n border-radius: ${({ theme }) => theme.borderRadius};\n background: ${({ theme, $isSelected }) =>\n $isSelected ? theme.colors.primary100 : theme.colors.neutral0};\n cursor: ${({ $isMovePending, $isInvalidDropTarget }) => {\n if ($isMovePending) {\n return 'wait';\n }\n\n return $isInvalidDropTarget ? 'not-allowed' : 'pointer';\n }};\n opacity: ${({ $isDragging }) => ($isDragging ? 0.4 : 1)};\n pointer-events: ${({ $isMovePending }) => ($isMovePending ? 'none' : 'auto')};\n transition: background 0.2s;\n\n ${({ $isValidDropTarget, theme }) =>\n $isValidDropTarget &&\n css`\n background: ${theme.colors.primary100};\n border: 1px dashed ${theme.colors.primary600};\n `}\n\n &:hover {\n background: ${({ theme }) => theme.colors.primary100};\n }\n\n &:focus-visible {\n outline: 2px solid ${({ theme }) => theme.colors.primary600};\n outline-offset: 2px;\n }\n`;\n\nconst FolderIconContainer = styled(Flex)`\n flex-shrink: 0;\n color: ${({ theme }) => theme.colors.neutral600};\n`;\n\nconst FolderName = styled(TruncatedText)`\n flex: 1;\n min-width: 0;\n`;\n\ninterface FolderCardProps {\n folder: Folder;\n orderedItemKeys: ItemKey[];\n}\n\nconst FolderCard = ({ folder, orderedItemKeys }: FolderCardProps) => {\n const { formatMessage } = useIntl();\n const { navigateToFolder } = useFolderNavigation();\n const { isMovePending } = useAssetsDndOptional() ?? { isMovePending: false };\n const { isSelected, toggle, selectRange } = useAssetSelection();\n const { canUpdate } = useMediaLibraryPermissions();\n const openContextMenu = useItemContextMenuTrigger();\n const {\n dragData,\n draggable: { attributes, listeners, setNodeRef: setDragRef, isDragging },\n droppable: { setNodeRef: setDropRef },\n showValidDropHighlight,\n showInvalidDropCursor,\n } = useFolderDraggableDroppable(folder);\n\n const key = folderKey(folder.id);\n\n const setNodeRef = (node: HTMLElement | null) => {\n setDragRef(node);\n setDropRef(node);\n };\n\n // Folders share the selection mechanism with assets (toggle, range,\n // select-all). Only the plain-click semantic differs: it navigates into the\n // folder instead of selecting it.\n //\n // The containment guard on this and the handlers below is what keeps the\n // actions menu's portaled dialogs — React children of this card — from\n // navigating into the folder or starting a drag.\n const handleClick = (e: React.MouseEvent) => {\n if (!isEventFromWithin(e)) {\n return;\n }\n\n if (e.shiftKey) {\n selectRange(orderedItemKeys, key);\n } else if (e.metaKey || e.ctrlKey) {\n toggle(key);\n } else {\n navigateToFolder(folder);\n }\n };\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (!isEventFromWithin(e)) {\n return;\n }\n\n if (e.key === 'Enter') {\n e.preventDefault();\n navigateToFolder(folder);\n } else if (e.key === ' ') {\n e.preventDefault();\n toggle(key);\n }\n };\n\n // Checkbox is the pointer path to selection; Shift extends the range.\n const handleCheckboxClick = (e: React.MouseEvent) => {\n e.stopPropagation();\n if (e.shiftKey) {\n selectRange(orderedItemKeys, key);\n } else {\n toggle(key);\n }\n };\n\n return (\n <StyledFolderCard\n ref={setNodeRef}\n {...attributes}\n {...listeners}\n $isDragging={isDragging}\n $isMovePending={isMovePending}\n $isValidDropTarget={showValidDropHighlight}\n $isInvalidDropTarget={showInvalidDropCursor}\n $isSelected={isSelected(key)}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n onPointerDown={(e: React.PointerEvent) => {\n if (isEventFromWithin(e)) {\n listeners?.onPointerDown?.(e);\n }\n }}\n role=\"listitem\"\n tabIndex={0}\n // Right-click opens this folder's own actions, or the selection's when it\n // is part of one. Still marked as \"not the background gesture\" so\n // MainAreaContextMenu's create menu stays out of it.\n data-native-context-menu\n onContextMenu={(e: React.MouseEvent) => {\n if (isEventFromWithin(e)) {\n openContextMenu?.(e, key, { kind: 'folder', folder, dragData });\n }\n }}\n >\n {canUpdate && (\n <Flex onKeyDown={(e: React.KeyboardEvent) => e.stopPropagation()}>\n <Checkbox\n checked={isSelected(key)}\n onClick={handleCheckboxClick}\n aria-label={formatMessage(\n {\n id: getTranslationKey('list.table.row.select'),\n defaultMessage: 'Select {name}',\n },\n { name: folder.name }\n )}\n />\n </Flex>\n )}\n <FolderIconContainer>\n <FolderIcon width={20} height={20} />\n </FolderIconContainer>\n <FolderName textColor=\"neutral800\">{folder.name}</FolderName>\n <Flex onClick={stopCardEvent} onKeyDown={stopCardEvent} onPointerDown={stopCardEvent}>\n <FolderActionsMenu folder={folder} dragData={dragData} />\n </Flex>\n </StyledFolderCard>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * AssetPreview\n * -----------------------------------------------------------------------------------------------*/\n\nconst PreviewContainer = styled(Box)`\n position: relative;\n width: 100%;\n padding-bottom: 62.5%;\n height: 0;\n overflow: hidden;\n background: repeating-conic-gradient(\n ${({ theme }) => theme.colors.neutral100} 0% 25%,\n transparent 0% 50%\n )\n 50% / 20px 20px;\n`;\n\nconst StyledImage = styled.img`\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n object-fit: cover;\n`;\n\nconst IconPreview = styled(Flex)`\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n color: ${({ theme }) => theme.colors.neutral500};\n background: ${({ theme }) => theme.colors.neutral100};\n`;\n\ninterface AssetPreviewProps {\n asset: File;\n}\n\nconst AssetPreview = ({ asset }: AssetPreviewProps) => {\n const { alternativeText, ext, formats, mime, url, updatedAt, isLocal, isUrlSigned } = asset;\n\n if (mime?.includes(ASSET_TYPES.Image)) {\n // Replace keeps the same hash/URL, so without a cache-buster the browser\n // serves the stale thumbnail after a Replace Media. `updatedAt`\n // changes on replace, so it re-fetches exactly once per replacement.\n // Skipped for signed URLs — an extra query param invalidates the signature.\n const cacheKey = updatedAt && !isUrlSigned ? new Date(updatedAt).getTime() : undefined;\n const appendCacheBuster = (raw: string) => {\n if (cacheKey === undefined) {\n return raw;\n }\n return raw.includes('?') ? `${raw}&v=${cacheKey}` : `${raw}?v=${cacheKey}`;\n };\n\n const rawMediaURL =\n prefixFileUrlWithBackendUrl(formats?.thumbnail?.url) ?? prefixFileUrlWithBackendUrl(url);\n const mediaURL = rawMediaURL ? appendCacheBuster(rawMediaURL) : rawMediaURL;\n\n if (mediaURL) {\n return (\n <PreviewContainer>\n <StyledImage\n src={mediaURL}\n alt={alternativeText || ''}\n // Only signed remote URLs need crossOrigin (cache collision with\n // the preview). Public/unsigned remote thumbnails must render\n // without a bucket CORS rule. See #26581.\n crossOrigin={!isLocal && isUrlSigned ? 'anonymous' : undefined}\n draggable={false}\n onDragStart={(e) => e.preventDefault()}\n />\n </PreviewContainer>\n );\n }\n }\n\n const DocIcon = getAssetIcon(mime, ext);\n\n return (\n <PreviewContainer>\n <IconPreview justifyContent=\"center\" alignItems=\"center\">\n <DocIcon width={48} height={48} />\n </IconPreview>\n </PreviewContainer>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * AssetCard\n * -----------------------------------------------------------------------------------------------*/\n\nconst StyledCardHeader = styled(CardHeader)`\n position: relative;\n border-bottom: 1px solid ${({ theme }) => theme.colors.neutral200};\n`;\n\nconst CardFooter = styled(Flex)`\n min-width: 0;\n width: 100%;\n`;\n\nconst FileTypeIcon = styled(Flex)`\n color: ${({ theme }) => theme.colors.neutral600};\n flex-shrink: 0;\n`;\n\nconst FileName = styled(TruncatedText)`\n flex: 1;\n min-width: 0;\n`;\n\n// The asset filename is its own interactive element: clicking it opens the\n// details drawer instead of selecting the card (mirrors the table view).\nconst NameButton = styled.button`\n display: inline-flex;\n flex: 1;\n min-width: 0;\n border: none;\n background: transparent;\n padding: 0;\n margin: 0;\n cursor: pointer;\n text-align: left;\n color: inherit;\n font: inherit;\n\n &:focus-visible {\n outline: 2px solid ${({ theme }) => theme.colors.primary600};\n outline-offset: 2px;\n border-radius: 2px;\n }\n`;\n\ninterface AssetCardProps {\n asset: File;\n orderedItemKeys: ItemKey[];\n onAssetItemClick: (assetId: number) => void;\n}\n\nconst AssetCard = ({ asset, orderedItemKeys, onAssetItemClick }: AssetCardProps) => {\n const { formatMessage } = useIntl();\n const TypeIcon = getAssetIcon(asset.mime, asset.ext);\n const { isMovePending } = useAssetsDndOptional() ?? { isMovePending: false };\n const { attributes, listeners, setNodeRef, isDragging, dragData } = useFileDraggable(asset);\n const { isSelected, toggle, selectRange } = useAssetSelection();\n const { canUpdate } = useMediaLibraryPermissions();\n const busyMessage = useBusyAssetsOptional()?.getBusyMessage(asset.id) ?? null;\n const openContextMenu = useItemContextMenuTrigger();\n\n const key = assetKey(asset.id);\n const selected = isSelected(key);\n\n // Plain click opens the asset details; pointer selection lives on the\n // checkbox only. Modifier clicks keep the selection semantics: shift selects\n // a range, cmd/ctrl toggles.\n //\n // The containment guard on this and the handler below is what keeps the\n // actions menu's portaled dialogs — React children of this card — from\n // opening the details drawer or toggling the selection.\n const handleCardClick = (e: React.MouseEvent) => {\n if (!isEventFromWithin(e)) {\n return;\n }\n\n if (e.shiftKey) {\n selectRange(orderedItemKeys, key);\n } else if (e.metaKey || e.ctrlKey) {\n toggle(key);\n } else {\n onAssetItemClick(asset.id);\n }\n };\n\n // Space toggles selection (additive), Enter opens the details drawer.\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (!isEventFromWithin(e)) {\n return;\n }\n\n if (e.key === 'Enter') {\n e.preventDefault();\n onAssetItemClick(asset.id);\n } else if (e.key === ' ') {\n e.preventDefault();\n toggle(key);\n }\n };\n\n const handleNameClick = (e: React.MouseEvent) => {\n e.stopPropagation();\n onAssetItemClick(asset.id);\n };\n\n // Same semantics as the table's row checkbox: Shift extends the range,\n // otherwise a plain additive toggle. Never bubbles into the card click.\n const handleCheckboxClick = (e: React.MouseEvent) => {\n e.stopPropagation();\n if (e.shiftKey) {\n selectRange(orderedItemKeys, key);\n } else {\n toggle(key);\n }\n };\n\n return (\n <StyledCard\n ref={setNodeRef}\n {...attributes}\n {...listeners}\n {...ASSET_DETAILS_TRIGGER_PROPS}\n $isDragging={isDragging}\n $isMovePending={isMovePending}\n $isBusy={busyMessage !== null}\n $isSelected={selected}\n tabIndex={0}\n role=\"listitem\"\n // Right-click opens this asset's own actions, or the selection's when it\n // is part of one. Still marked as \"not the background gesture\" so\n // MainAreaContextMenu's create menu stays out of it.\n data-native-context-menu\n onContextMenu={(e: React.MouseEvent) => {\n if (isEventFromWithin(e)) {\n openContextMenu?.(e, key, { kind: 'asset', asset, dragData });\n }\n }}\n onDragStart={(e) => e.preventDefault()}\n onClick={handleCardClick}\n onKeyDown={handleKeyDown}\n onPointerDown={(e: React.PointerEvent) => {\n if (isEventFromWithin(e)) {\n listeners?.onPointerDown?.(e);\n }\n }}\n >\n <StyledCardHeader>\n {canUpdate && (\n <CheckboxOverlay\n {...ASSET_ITEM_CONTROL_PROPS}\n onKeyDown={(e: React.KeyboardEvent) => e.stopPropagation()}\n >\n <Checkbox\n checked={selected}\n onClick={handleCheckboxClick}\n aria-label={formatMessage(\n {\n id: getTranslationKey('list.table.row.select'),\n defaultMessage: 'Select {name}',\n },\n { name: asset.name }\n )}\n />\n </CheckboxOverlay>\n )}\n <AssetPreview asset={asset} />\n {/* The header is the card's only positioned ancestor, and it's the part\n worth covering — the footer keeps the name legible while the preview\n is mid-replace. Below the checkbox overlay (z-index 1) would hide\n the spinner, so it sits above it. */}\n {busyMessage !== null ? <BusyOverlay zIndex={2}>{busyMessage}</BusyOverlay> : null}\n </StyledCardHeader>\n <CardBody>\n <CardFooter alignItems=\"center\" gap={2}>\n <FileTypeIcon>\n <TypeIcon width={20} height={20} />\n </FileTypeIcon>\n <NameButton type=\"button\" onClick={handleNameClick}>\n <FileName textColor=\"primary800\">{asset.name}</FileName>\n </NameButton>\n <Flex\n {...ASSET_ITEM_CONTROL_PROPS}\n onClick={stopCardEvent}\n onKeyDown={stopCardEvent}\n onPointerDown={stopCardEvent}\n >\n <AssetActionsMenu asset={asset} dragData={dragData} />\n </Flex>\n </CardFooter>\n </CardBody>\n </StyledCard>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * AssetsGrid\n * -----------------------------------------------------------------------------------------------*/\n\ninterface AssetsGridProps {\n assets: File[];\n folders?: Folder[];\n /** Keys of the rendered items, in render order. Owned by the view. */\n renderedKeys?: ItemKey[];\n onAssetItemClick: (assetId: number) => void;\n}\n\nexport const AssetsGrid = ({\n assets,\n folders = EMPTY_FOLDERS,\n renderedKeys,\n onAssetItemClick,\n}: AssetsGridProps) => {\n const totalItems = folders.length + assets.length;\n\n // Render order: folders always on top in the grid (mixing is table-only) —\n // range selection follows it.\n const orderedItemKeys: ItemKey[] = renderedKeys ?? buildRenderedKeys({ folders, assets });\n\n // The empty state is owned by the page (`AssetsView` renders `EmptyState`) — an\n // empty grid renders nothing at all.\n if (totalItems === 0) {\n return null;\n }\n\n return (\n <ItemsGrid role=\"list\" data-testid=\"assets-grid\">\n {folders.length > 0 && (\n <FoldersRow>\n <ItemsGrid>\n {folders.map((folder) => (\n <FolderCard\n folder={folder}\n orderedItemKeys={orderedItemKeys}\n key={`folder-${folder.id}`}\n />\n ))}\n </ItemsGrid>\n </FoldersRow>\n )}\n {assets.map((asset) => (\n <Flex key={asset.id} direction=\"column\" alignItems=\"stretch\">\n <AssetCard\n asset={asset}\n orderedItemKeys={orderedItemKeys}\n onAssetItemClick={onAssetItemClick}\n />\n </Flex>\n ))}\n </ItemsGrid>\n );\n};\n"],"names":["EMPTY_FOLDERS","stopCardEvent","e","isEventFromWithin","stopPropagation","CheckboxOverlay","styled","Flex","theme","spaces","shadows","filterShadow","StyledCard","Card","$isSelected","colors","primary600","neutral200","$isMovePending","$isBusy","$isDragging","primary100","undefined","FoldersRow","Box","MIN_TILE_WIDTH","ItemsGrid","StyledFolderCard","borderRadius","neutral0","$isInvalidDropTarget","$isValidDropTarget","css","FolderIconContainer","neutral600","FolderName","TruncatedText","FolderCard","folder","orderedItemKeys","formatMessage","useIntl","navigateToFolder","useFolderNavigation","isMovePending","useAssetsDndOptional","isSelected","toggle","selectRange","useAssetSelection","canUpdate","useMediaLibraryPermissions","openContextMenu","useItemContextMenuTrigger","dragData","draggable","attributes","listeners","setNodeRef","setDragRef","isDragging","droppable","setDropRef","showValidDropHighlight","showInvalidDropCursor","useFolderDraggableDroppable","key","folderKey","id","node","handleClick","shiftKey","metaKey","ctrlKey","handleKeyDown","preventDefault","handleCheckboxClick","_jsxs","ref","onClick","onKeyDown","onPointerDown","role","tabIndex","data-native-context-menu","onContextMenu","kind","_jsx","Checkbox","checked","aria-label","getTranslationKey","defaultMessage","name","FolderIcon","width","height","textColor","FolderActionsMenu","PreviewContainer","neutral100","StyledImage","img","IconPreview","neutral500","AssetPreview","asset","alternativeText","ext","formats","mime","url","updatedAt","isLocal","isUrlSigned","includes","ASSET_TYPES","Image","cacheKey","Date","getTime","appendCacheBuster","raw","rawMediaURL","prefixFileUrlWithBackendUrl","thumbnail","mediaURL","src","alt","crossOrigin","onDragStart","DocIcon","getAssetIcon","justifyContent","alignItems","StyledCardHeader","CardHeader","CardFooter","FileTypeIcon","FileName","NameButton","button","AssetCard","onAssetItemClick","TypeIcon","useFileDraggable","busyMessage","useBusyAssetsOptional","getBusyMessage","assetKey","selected","handleCardClick","handleNameClick","ASSET_DETAILS_TRIGGER_PROPS","ASSET_ITEM_CONTROL_PROPS","BusyOverlay","zIndex","CardBody","gap","type","AssetActionsMenu","AssetsGrid","assets","folders","renderedKeys","totalItems","length","buildRenderedKeys","data-testid","map","direction"],"mappings":"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"}
1
+ {"version":3,"file":"AssetsGrid.mjs","sources":["../../../../../admin/src/pages/Assets/components/AssetsGrid.tsx"],"sourcesContent":["import {\n Box,\n Card,\n CardBody,\n CardHeader,\n Checkbox,\n Divider,\n Flex,\n Typography,\n} from '@strapi/design-system';\nimport { Folder as FolderIcon } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { styled, css } from 'styled-components';\n\nimport { TruncatedText } from '../../../components/TruncatedText';\nimport { ASSET_TYPES } from '../../../enums';\nimport { useTracking } from '../../../hooks/useTracking';\nimport { prefixFileUrlWithBackendUrl } from '../../../utils/files';\nimport { getAssetIcon } from '../../../utils/getAssetIcon';\nimport { isEventFromWithin } from '../../../utils/isEventFromWithin';\nimport { getTranslationKey } from '../../../utils/translations';\nimport { ASSET_DETAILS_TRIGGER_PROPS, ASSET_ITEM_CONTROL_PROPS } from '../constants';\nimport { useAssetSelection } from '../hooks/useAssetSelection';\nimport { useBusyAssetsOptional } from '../hooks/useBusyAssets';\nimport { useFolderNavigation } from '../hooks/useFolderNavigation';\nimport { useListSettings } from '../hooks/useListSettings';\nimport { buildRenderedKeys } from '../utils/renderedKeys';\nimport { assetKey, folderKey, getSelectAllState, type ItemKey } from '../utils/selection';\n\nimport { AssetActionsMenu } from './AssetActionsMenu';\nimport { BusyOverlay } from './BusyOverlay';\nimport { useAssetsDndOptional } from './Dnd/AssetsDndProvider';\nimport { isFromReorderHandle } from './Dnd/assetSortable';\nimport { ReorderHandle } from './Dnd/ReorderHandle';\nimport { useFileDraggable, useFolderDraggableDroppable } from './Dnd/useAssetDnd';\nimport { FolderActionsMenu } from './FolderActionsMenu';\nimport { useItemContextMenuTrigger } from './ItemContextMenu';\n\nimport type { File } from '../../../../../shared/contracts/files';\nimport type { Folder } from '../../../../../shared/contracts/folders';\n\nconst EMPTY_FOLDERS: NonNullable<AssetsGridProps['folders']> = [];\n\n/* -------------------------------------------------------------------------------------------------\n * AssetsGrid\n * -----------------------------------------------------------------------------------------------*/\n\n// Cards own click, Enter and Space; the controls sitting on them (checkbox, \"...\"\n// menu) must not let those reach the card. Scoped to the wrapper's own DOM\n// subtree so the menu's portaled content — a React child of the wrapper, but\n// never a DOM descendant — still reaches `document`, where Radix listens in\n// order to dismiss its layers.\nconst stopCardEvent = (e: React.SyntheticEvent) => {\n if (isEventFromWithin(e)) {\n e.stopPropagation();\n }\n};\n\n// Top-left selection checkbox overlaid on the asset preview, always visible.\nconst CheckboxOverlay = styled(Flex)`\n position: absolute;\n top: ${({ theme }) => theme.spaces[3]};\n left: ${({ theme }) => theme.spaces[3]};\n z-index: 1;\n box-shadow: ${({ theme }) => theme.shadows.filterShadow};\n`;\n\nconst StyledCard = styled(Card)<{\n $isDragging?: boolean;\n $isMovePending?: boolean;\n $isBusy?: boolean;\n $isSelected?: boolean;\n /** Shown but not choosable here (the picker's `allowedTypes`). */\n $isUnselectable?: boolean;\n}>`\n border: 1px solid\n ${({ theme, $isSelected }) => ($isSelected ? theme.colors.primary600 : theme.colors.neutral200)};\n border-radius: 8px;\n overflow: hidden;\n isolation: isolate;\n cursor: ${({ $isMovePending, $isBusy, $isUnselectable }) => {\n if ($isMovePending || $isBusy) return 'wait';\n return $isUnselectable ? 'not-allowed' : 'pointer';\n }};\n opacity: ${({ $isDragging, $isUnselectable }) => ($isDragging || $isUnselectable ? 0.4 : 1)};\n /* No opacity change while busy — the overlay does the dimming, and stacking\n one on the other would wash the card out. */\n pointer-events: ${({ $isMovePending, $isBusy }) => ($isMovePending || $isBusy ? 'none' : 'auto')};\n background: ${({ theme, $isSelected }) => ($isSelected ? theme.colors.primary100 : undefined)};\n /* Shift+click range selection must not highlight card text. */\n user-select: none;\n\n &:hover {\n background: ${({ theme }) => theme.colors.primary100};\n }\n\n &:focus-visible {\n outline: 2px solid ${({ theme }) => theme.colors.primary600};\n outline-offset: 2px;\n }\n`;\n\n/* -------------------------------------------------------------------------------------------------\n * FolderCard\n * -----------------------------------------------------------------------------------------------*/\n\nconst FoldersRow = styled(Box)`\n grid-column: 1 / -1;\n`;\n\nconst StyledItemsGrid = styled(Box)<{ $minTileWidth: string }>`\n display: grid;\n grid-template-columns: ${({ $minTileWidth }) =>\n `repeat(auto-fill, minmax(min(${$minTileWidth}, 100%), 1fr))`};\n gap: ${({ theme }) => theme.spaces[4]};\n`;\n\nconst ItemsGrid = (props: React.ComponentProps<typeof Box>) => {\n const { gridMinTileWidth } = useListSettings();\n\n return <StyledItemsGrid $minTileWidth={gridMinTileWidth} {...props} />;\n};\n\nconst StyledFolderCard = styled(Flex)<{\n $isDragging?: boolean;\n $isMovePending?: boolean;\n $isValidDropTarget?: boolean;\n $isInvalidDropTarget?: boolean;\n $isSelected?: boolean;\n}>`\n width: 100%;\n user-select: none;\n padding: ${({ theme }) => `${theme.spaces[2]} ${theme.spaces[3]}`}; // 8px 12px\n align-items: center;\n gap: ${({ theme }) => theme.spaces[2]}; // 8px\n border: 1px solid\n ${({ theme, $isSelected }) => ($isSelected ? theme.colors.primary600 : theme.colors.neutral200)};\n border-radius: ${({ theme }) => theme.borderRadius};\n background: ${({ theme, $isSelected }) =>\n $isSelected ? theme.colors.primary100 : theme.colors.neutral0};\n cursor: ${({ $isMovePending, $isInvalidDropTarget }) => {\n if ($isMovePending) {\n return 'wait';\n }\n\n return $isInvalidDropTarget ? 'not-allowed' : 'pointer';\n }};\n opacity: ${({ $isDragging }) => ($isDragging ? 0.4 : 1)};\n pointer-events: ${({ $isMovePending }) => ($isMovePending ? 'none' : 'auto')};\n transition: background 0.2s;\n\n ${({ $isValidDropTarget, theme }) =>\n $isValidDropTarget &&\n css`\n background: ${theme.colors.primary100};\n border: 1px dashed ${theme.colors.primary600};\n `}\n\n &:hover {\n background: ${({ theme }) => theme.colors.primary100};\n }\n\n &:focus-visible {\n outline: 2px solid ${({ theme }) => theme.colors.primary600};\n outline-offset: 2px;\n }\n`;\n\nconst FolderIconContainer = styled(Flex)`\n flex-shrink: 0;\n color: ${({ theme }) => theme.colors.neutral600};\n`;\n\nconst FolderName = styled(TruncatedText)`\n flex: 1;\n min-width: 0;\n`;\n\ninterface FolderCardProps {\n folder: Folder;\n orderedItemKeys: ItemKey[];\n}\n\nconst FolderCard = ({ folder, orderedItemKeys }: FolderCardProps) => {\n const { formatMessage } = useIntl();\n const { navigateToFolder } = useFolderNavigation();\n const { isMovePending } = useAssetsDndOptional() ?? { isMovePending: false };\n const { isSelected, toggle, selectRange, getSelectability } = useAssetSelection();\n const { showItemActions } = useListSettings();\n const openContextMenu = useItemContextMenuTrigger();\n const {\n dragData,\n draggable: { attributes, listeners, setNodeRef: setDragRef, isDragging },\n droppable: { setNodeRef: setDropRef },\n showValidDropHighlight,\n showInvalidDropCursor,\n } = useFolderDraggableDroppable(folder);\n\n const key = folderKey(folder.id);\n const selectability = getSelectability(key);\n\n const setNodeRef = (node: HTMLElement | null) => {\n setDragRef(node);\n setDropRef(node);\n };\n\n // Folders share the selection mechanism with assets (toggle, range,\n // select-all). Only the plain-click semantic differs: it navigates into the\n // folder instead of selecting it.\n //\n // The containment guard on this and the handlers below is what keeps the\n // actions menu's portaled dialogs — React children of this card — from\n // navigating into the folder or starting a drag.\n const handleClick = (e: React.MouseEvent) => {\n if (!isEventFromWithin(e)) {\n return;\n }\n\n if (e.shiftKey) {\n selectRange(orderedItemKeys, key);\n } else if (e.metaKey || e.ctrlKey) {\n toggle(key);\n } else {\n navigateToFolder(folder);\n }\n };\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (!isEventFromWithin(e)) {\n return;\n }\n\n if (e.key === 'Enter') {\n e.preventDefault();\n navigateToFolder(folder);\n } else if (e.key === ' ') {\n e.preventDefault();\n toggle(key);\n }\n };\n\n // Checkbox is the pointer path to selection; Shift extends the range.\n const handleCheckboxClick = (e: React.MouseEvent) => {\n e.stopPropagation();\n if (e.shiftKey) {\n selectRange(orderedItemKeys, key);\n } else {\n toggle(key);\n }\n };\n\n return (\n <StyledFolderCard\n ref={setNodeRef}\n {...attributes}\n {...listeners}\n $isDragging={isDragging}\n $isMovePending={isMovePending}\n $isValidDropTarget={showValidDropHighlight}\n $isInvalidDropTarget={showInvalidDropCursor}\n $isSelected={isSelected(key)}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n onPointerDown={(e: React.PointerEvent) => {\n if (isEventFromWithin(e)) {\n listeners?.onPointerDown?.(e);\n }\n }}\n role=\"listitem\"\n tabIndex={0}\n // Right-click opens this folder's own actions, or the selection's when it\n // is part of one. Still marked as \"not the background gesture\" so\n // MainAreaContextMenu's create menu stays out of it.\n data-native-context-menu\n onContextMenu={(e: React.MouseEvent) => {\n if (isEventFromWithin(e)) {\n openContextMenu?.(e, key, { kind: 'folder', folder, dragData });\n }\n }}\n >\n {selectability !== 'hidden' && (\n <Flex onKeyDown={(e: React.KeyboardEvent) => e.stopPropagation()}>\n <Checkbox\n checked={isSelected(key)}\n disabled={selectability === 'disabled'}\n onClick={handleCheckboxClick}\n aria-label={formatMessage(\n {\n id: getTranslationKey('list.table.row.select'),\n defaultMessage: 'Select {name}',\n },\n { name: folder.name }\n )}\n />\n </Flex>\n )}\n <FolderIconContainer>\n <FolderIcon width={20} height={20} />\n </FolderIconContainer>\n <FolderName textColor=\"neutral800\">{folder.name}</FolderName>\n {showItemActions && (\n <Flex onClick={stopCardEvent} onKeyDown={stopCardEvent} onPointerDown={stopCardEvent}>\n <FolderActionsMenu folder={folder} dragData={dragData} />\n </Flex>\n )}\n </StyledFolderCard>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * AssetPreview\n * -----------------------------------------------------------------------------------------------*/\n\nconst PreviewContainer = styled(Box)`\n position: relative;\n width: 100%;\n padding-bottom: 62.5%;\n height: 0;\n overflow: hidden;\n background: repeating-conic-gradient(\n ${({ theme }) => theme.colors.neutral100} 0% 25%,\n transparent 0% 50%\n )\n 50% / 20px 20px;\n`;\n\nconst StyledImage = styled.img`\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n object-fit: cover;\n`;\n\nconst IconPreview = styled(Flex)`\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n color: ${({ theme }) => theme.colors.neutral500};\n background: ${({ theme }) => theme.colors.neutral100};\n`;\n\ninterface AssetPreviewProps {\n asset: File;\n}\n\nconst AssetPreview = ({ asset }: AssetPreviewProps) => {\n const { alternativeText, ext, formats, mime, url, updatedAt, isLocal, isUrlSigned } = asset;\n\n if (mime?.includes(ASSET_TYPES.Image)) {\n // Replace keeps the same hash/URL, so without a cache-buster the browser\n // serves the stale thumbnail after a Replace Media. `updatedAt`\n // changes on replace, so it re-fetches exactly once per replacement.\n // Skipped for signed URLs — an extra query param invalidates the signature.\n const cacheKey = updatedAt && !isUrlSigned ? new Date(updatedAt).getTime() : undefined;\n const appendCacheBuster = (raw: string) => {\n if (cacheKey === undefined) {\n return raw;\n }\n return raw.includes('?') ? `${raw}&v=${cacheKey}` : `${raw}?v=${cacheKey}`;\n };\n\n const rawMediaURL =\n prefixFileUrlWithBackendUrl(formats?.thumbnail?.url) ?? prefixFileUrlWithBackendUrl(url);\n const mediaURL = rawMediaURL ? appendCacheBuster(rawMediaURL) : rawMediaURL;\n\n if (mediaURL) {\n return (\n <PreviewContainer>\n <StyledImage\n src={mediaURL}\n alt={alternativeText || ''}\n // Only signed remote URLs need crossOrigin (cache collision with\n // the preview). Public/unsigned remote thumbnails must render\n // without a bucket CORS rule. See #26581.\n crossOrigin={!isLocal && isUrlSigned ? 'anonymous' : undefined}\n draggable={false}\n onDragStart={(e) => e.preventDefault()}\n />\n </PreviewContainer>\n );\n }\n }\n\n const DocIcon = getAssetIcon(mime, ext);\n\n return (\n <PreviewContainer>\n <IconPreview justifyContent=\"center\" alignItems=\"center\">\n <DocIcon width={48} height={48} />\n </IconPreview>\n </PreviewContainer>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * AssetCard\n * -----------------------------------------------------------------------------------------------*/\n\nconst StyledCardHeader = styled(CardHeader)`\n position: relative;\n border-bottom: 1px solid ${({ theme }) => theme.colors.neutral200};\n`;\n\nconst CardFooter = styled(Flex)`\n min-width: 0;\n width: 100%;\n`;\n\nconst FileTypeIcon = styled(Flex)`\n color: ${({ theme }) => theme.colors.neutral600};\n flex-shrink: 0;\n`;\n\nconst FileName = styled(TruncatedText)`\n flex: 1;\n min-width: 0;\n`;\n\n// The asset filename is its own interactive element: clicking it opens the\n// details drawer instead of selecting the card (mirrors the table view).\nconst NameButton = styled.button`\n display: inline-flex;\n flex: 1;\n min-width: 0;\n border: none;\n background: transparent;\n padding: 0;\n margin: 0;\n cursor: pointer;\n text-align: left;\n color: inherit;\n font: inherit;\n\n &:focus-visible {\n outline: 2px solid ${({ theme }) => theme.colors.primary600};\n outline-offset: 2px;\n border-radius: 2px;\n }\n`;\n\ninterface AssetCardProps {\n asset: File;\n orderedItemKeys: ItemKey[];\n onAssetItemClick: (assetId: number) => void;\n}\n\nconst AssetCard = ({ asset, orderedItemKeys, onAssetItemClick }: AssetCardProps) => {\n const { formatMessage } = useIntl();\n const TypeIcon = getAssetIcon(asset.mime, asset.ext);\n const { isMovePending } = useAssetsDndOptional() ?? { isMovePending: false };\n const { attributes, listeners, setNodeRef, isDragging, dragData, dragStyle, dragHandle } =\n useFileDraggable(asset);\n const { isSelected, toggle, selectRange, getSelectability } = useAssetSelection();\n const { showItemActions } = useListSettings();\n const busyMessage = useBusyAssetsOptional()?.getBusyMessage(asset.id) ?? null;\n const openContextMenu = useItemContextMenuTrigger();\n\n const key = assetKey(asset.id);\n const selected = isSelected(key);\n const selectability = getSelectability(key);\n\n // Plain click opens the asset details; pointer selection lives on the\n // checkbox only. Modifier clicks keep the selection semantics: shift selects\n // a range, cmd/ctrl toggles.\n //\n // The containment guard on this and the handler below is what keeps the\n // actions menu's portaled dialogs — React children of this card — from\n // opening the details drawer or toggling the selection.\n const handleCardClick = (e: React.MouseEvent) => {\n if (!isEventFromWithin(e)) {\n return;\n }\n\n if (e.shiftKey) {\n selectRange(orderedItemKeys, key);\n } else if (e.metaKey || e.ctrlKey) {\n toggle(key);\n } else {\n onAssetItemClick(asset.id);\n }\n };\n\n // Space toggles selection (additive), Enter opens the details drawer.\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (!isEventFromWithin(e) || isFromReorderHandle(e)) {\n return;\n }\n\n if (e.key === 'Enter') {\n e.preventDefault();\n onAssetItemClick(asset.id);\n } else if (e.key === ' ') {\n e.preventDefault();\n toggle(key);\n }\n };\n\n const handleNameClick = (e: React.MouseEvent) => {\n e.stopPropagation();\n onAssetItemClick(asset.id);\n };\n\n // Same semantics as the table's row checkbox: Shift extends the range,\n // otherwise a plain additive toggle. Never bubbles into the card click.\n const handleCheckboxClick = (e: React.MouseEvent) => {\n e.stopPropagation();\n if (e.shiftKey) {\n selectRange(orderedItemKeys, key);\n } else {\n toggle(key);\n }\n };\n\n return (\n <StyledCard\n ref={setNodeRef}\n {...attributes}\n {...listeners}\n {...ASSET_DETAILS_TRIGGER_PROPS}\n $isDragging={isDragging}\n $isMovePending={isMovePending}\n $isBusy={busyMessage !== null}\n $isSelected={selected}\n $isUnselectable={selectability === 'disabled'}\n style={dragStyle}\n tabIndex={0}\n role=\"listitem\"\n // Right-click opens this asset's own actions, or the selection's when it\n // is part of one. Still marked as \"not the background gesture\" so\n // MainAreaContextMenu's create menu stays out of it.\n data-native-context-menu\n onContextMenu={(e: React.MouseEvent) => {\n if (isEventFromWithin(e)) {\n openContextMenu?.(e, key, { kind: 'asset', asset, dragData });\n }\n }}\n onDragStart={(e) => e.preventDefault()}\n onClick={handleCardClick}\n onKeyDown={handleKeyDown}\n onPointerDown={(e: React.PointerEvent) => {\n if (isEventFromWithin(e)) {\n listeners?.onPointerDown?.(e);\n }\n }}\n >\n <StyledCardHeader>\n {selectability !== 'hidden' && (\n <CheckboxOverlay\n {...ASSET_ITEM_CONTROL_PROPS}\n onKeyDown={(e: React.KeyboardEvent) => e.stopPropagation()}\n >\n <Checkbox\n checked={selected}\n disabled={selectability === 'disabled'}\n onClick={handleCheckboxClick}\n aria-label={formatMessage(\n {\n id: getTranslationKey('list.table.row.select'),\n defaultMessage: 'Select {name}',\n },\n { name: asset.name }\n )}\n />\n </CheckboxOverlay>\n )}\n <AssetPreview asset={asset} />\n {/* The header is the card's only positioned ancestor, and it's the part\n worth covering — the footer keeps the name legible while the preview\n is mid-replace. Below the checkbox overlay (z-index 1) would hide\n the spinner, so it sits above it. */}\n {busyMessage !== null ? <BusyOverlay zIndex={2}>{busyMessage}</BusyOverlay> : null}\n </StyledCardHeader>\n <CardBody>\n <CardFooter alignItems=\"center\" gap={2}>\n {/* The grip takes the type icon's place: the preview above already\n shows what the asset is. */}\n {dragHandle ? (\n <ReorderHandle name={asset.name} handle={dragHandle} />\n ) : (\n <FileTypeIcon>\n <TypeIcon width={20} height={20} />\n </FileTypeIcon>\n )}\n <NameButton type=\"button\" onClick={handleNameClick}>\n <FileName textColor=\"primary800\">{asset.name}</FileName>\n </NameButton>\n {showItemActions && (\n <Flex\n {...ASSET_ITEM_CONTROL_PROPS}\n onClick={stopCardEvent}\n onKeyDown={stopCardEvent}\n onPointerDown={stopCardEvent}\n >\n <AssetActionsMenu asset={asset} dragData={dragData} />\n </Flex>\n )}\n </CardFooter>\n </CardBody>\n </StyledCard>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * AssetsGrid\n * -----------------------------------------------------------------------------------------------*/\n\ninterface GridSectionProps {\n title: string;\n /** Sits at the end of the heading row. */\n action?: React.ReactNode;\n children: React.ReactNode;\n}\n\n// Headings sit outside the `role=\"list\"` grid: a list may only contain items.\nconst GridSection = ({ title, action, children }: GridSectionProps) => (\n <Flex tag=\"section\" direction=\"column\" alignItems=\"stretch\" gap={4}>\n <Flex justifyContent=\"space-between\" alignItems=\"center\" gap={4}>\n <Typography variant=\"delta\" tag=\"h3\">\n {title}\n </Typography>\n {action}\n </Flex>\n <ItemsGrid role=\"list\">{children}</ItemsGrid>\n </Flex>\n);\n\n/**\n * The grid's counterpart of the table's header checkbox: selects the loaded\n * assets that can be selected, or un-selects them when they all are.\n */\nconst GridSelectAll = ({ assets }: { assets: File[] }) => {\n const { formatMessage } = useIntl();\n const { selectedKeys, selectAll, deselectAll, getSelectability } = useAssetSelection();\n const { trackUsage } = useTracking();\n\n const selectableKeys = assets\n .map((asset) => assetKey(asset.id))\n .filter((key) => getSelectability(key) === 'enabled');\n const { allSelected, isIndeterminate } = getSelectAllState(selectedKeys, selectableKeys);\n\n const handleChange = () => {\n if (allSelected) {\n deselectAll(selectableKeys);\n } else {\n trackUsage('didSelectAllMediaLibraryElements');\n selectAll(selectableKeys);\n }\n };\n\n return (\n <Checkbox\n checked={isIndeterminate ? 'indeterminate' : allSelected}\n disabled={selectableKeys.length === 0}\n onCheckedChange={handleChange}\n >\n {formatMessage({\n id: getTranslationKey('list.table.header.select-all'),\n defaultMessage: 'Select all',\n })}\n </Checkbox>\n );\n};\n\ninterface AssetsGridProps {\n assets: File[];\n /** Shown in the \"Assets (n)\" heading; falls back to the loaded count. */\n assetsTotal?: number;\n folders?: Folder[];\n /** Keys of the rendered items, in render order. Owned by the view. */\n renderedKeys?: ItemKey[];\n onAssetItemClick: (assetId: number) => void;\n}\n\nexport const AssetsGrid = ({\n assets,\n assetsTotal,\n folders = EMPTY_FOLDERS,\n renderedKeys,\n onAssetItemClick,\n}: AssetsGridProps) => {\n const { formatMessage } = useIntl();\n const { showSectionHeadings, showGridSelectAll } = useListSettings();\n const { isEnabled, canSelectAll } = useAssetSelection();\n const totalItems = folders.length + assets.length;\n\n // Render order: folders always on top in the grid (mixing is table-only) —\n // range selection follows it.\n const orderedItemKeys: ItemKey[] = renderedKeys ?? buildRenderedKeys({ folders, assets });\n\n // The empty state is owned by the page (`AssetsView` renders `EmptyState`) — an\n // empty grid renders nothing at all.\n if (totalItems === 0) {\n return null;\n }\n\n const folderCards = folders.map((folder) => (\n <FolderCard folder={folder} orderedItemKeys={orderedItemKeys} key={`folder-${folder.id}`} />\n ));\n const assetCards = assets.map((asset) => (\n <Flex key={asset.id} direction=\"column\" alignItems=\"stretch\">\n <AssetCard\n asset={asset}\n orderedItemKeys={orderedItemKeys}\n onAssetItemClick={onAssetItemClick}\n />\n </Flex>\n ));\n\n if (showSectionHeadings) {\n return (\n <Flex direction=\"column\" alignItems=\"stretch\" gap={6} data-testid=\"assets-grid\">\n {folders.length > 0 && (\n <GridSection\n title={formatMessage(\n { id: getTranslationKey('list.folders.title'), defaultMessage: 'Folders ({count})' },\n { count: folders.length }\n )}\n >\n {folderCards}\n </GridSection>\n )}\n {folders.length > 0 && assets.length > 0 && <Divider />}\n {assets.length > 0 && (\n <GridSection\n title={formatMessage(\n { id: getTranslationKey('list.assets.title'), defaultMessage: 'Assets ({count})' },\n { count: assetsTotal ?? assets.length }\n )}\n action={\n showGridSelectAll && isEnabled && canSelectAll ? (\n <GridSelectAll assets={assets} />\n ) : undefined\n }\n >\n {assetCards}\n </GridSection>\n )}\n </Flex>\n );\n }\n\n return (\n <ItemsGrid role=\"list\" data-testid=\"assets-grid\">\n {folders.length > 0 && (\n <FoldersRow>\n <ItemsGrid>{folderCards}</ItemsGrid>\n </FoldersRow>\n )}\n {assetCards}\n </ItemsGrid>\n );\n};\n"],"names":["EMPTY_FOLDERS","stopCardEvent","e","isEventFromWithin","stopPropagation","CheckboxOverlay","styled","Flex","theme","spaces","shadows","filterShadow","StyledCard","Card","$isSelected","colors","primary600","neutral200","$isMovePending","$isBusy","$isUnselectable","$isDragging","primary100","undefined","FoldersRow","Box","StyledItemsGrid","$minTileWidth","ItemsGrid","props","gridMinTileWidth","useListSettings","_jsx","StyledFolderCard","borderRadius","neutral0","$isInvalidDropTarget","$isValidDropTarget","css","FolderIconContainer","neutral600","FolderName","TruncatedText","FolderCard","folder","orderedItemKeys","formatMessage","useIntl","navigateToFolder","useFolderNavigation","isMovePending","useAssetsDndOptional","isSelected","toggle","selectRange","getSelectability","useAssetSelection","showItemActions","openContextMenu","useItemContextMenuTrigger","dragData","draggable","attributes","listeners","setNodeRef","setDragRef","isDragging","droppable","setDropRef","showValidDropHighlight","showInvalidDropCursor","useFolderDraggableDroppable","key","folderKey","id","selectability","node","handleClick","shiftKey","metaKey","ctrlKey","handleKeyDown","preventDefault","handleCheckboxClick","_jsxs","ref","onClick","onKeyDown","onPointerDown","role","tabIndex","data-native-context-menu","onContextMenu","kind","Checkbox","checked","disabled","aria-label","getTranslationKey","defaultMessage","name","FolderIcon","width","height","textColor","FolderActionsMenu","PreviewContainer","neutral100","StyledImage","img","IconPreview","neutral500","AssetPreview","asset","alternativeText","ext","formats","mime","url","updatedAt","isLocal","isUrlSigned","includes","ASSET_TYPES","Image","cacheKey","Date","getTime","appendCacheBuster","raw","rawMediaURL","prefixFileUrlWithBackendUrl","thumbnail","mediaURL","src","alt","crossOrigin","onDragStart","DocIcon","getAssetIcon","justifyContent","alignItems","StyledCardHeader","CardHeader","CardFooter","FileTypeIcon","FileName","NameButton","button","AssetCard","onAssetItemClick","TypeIcon","dragStyle","dragHandle","useFileDraggable","busyMessage","useBusyAssetsOptional","getBusyMessage","assetKey","selected","handleCardClick","isFromReorderHandle","handleNameClick","ASSET_DETAILS_TRIGGER_PROPS","style","ASSET_ITEM_CONTROL_PROPS","BusyOverlay","zIndex","CardBody","gap","ReorderHandle","handle","type","AssetActionsMenu","GridSection","title","action","children","tag","direction","Typography","variant","GridSelectAll","assets","selectedKeys","selectAll","deselectAll","trackUsage","useTracking","selectableKeys","map","filter","allSelected","isIndeterminate","getSelectAllState","handleChange","length","onCheckedChange","AssetsGrid","assetsTotal","folders","renderedKeys","showSectionHeadings","showGridSelectAll","isEnabled","canSelectAll","totalItems","buildRenderedKeys","folderCards","assetCards","data-testid","count","Divider"],"mappings":"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"}
@@ -4,11 +4,13 @@ var jsxRuntime = require('react/jsx-runtime');
4
4
  var React = require('react');
5
5
  var strapiAdmin = require('@strapi/admin/strapi-admin');
6
6
  var designSystem = require('@strapi/design-system');
7
+ var icons = require('@strapi/icons');
7
8
  var reactIntl = require('react-intl');
8
9
  var styledComponents = require('styled-components');
9
10
  var useTracking = require('../../../hooks/useTracking.js');
10
11
  var translations = require('../../../utils/translations.js');
11
12
  var useAssetSearch = require('../hooks/useAssetSearch.js');
13
+ var useListQueryParams = require('../hooks/useListQueryParams.js');
12
14
 
13
15
  const DEBOUNCE_MS = 300;
14
16
  // The DS Searchbar nests two bordered boxes: its own shell (neutral150) wrapping
@@ -25,20 +27,47 @@ const StyledSearchForm = styledComponents.styled(designSystem.SearchForm)`
25
27
  /**
26
28
  * Keyword search over the whole Media Library. Owns the typing state and the
27
29
  * debounce; `useAssetSearch` owns the `?_q=` URL param.
28
- */ const AssetsSearchInput = ()=>{
30
+ */ const AssetsSearchInput = ({ collapsible = false })=>{
29
31
  const { formatMessage } = reactIntl.useIntl();
30
32
  const { searchQuery, setSearchQuery } = useAssetSearch.useAssetSearch();
31
33
  const { trackUsage } = useTracking.useTracking();
32
34
  const isMobile = strapiAdmin.useIsMobile();
33
35
  const [value, setValue] = React.useState(searchQuery);
34
36
  const debouncedValue = strapiAdmin.useDebounce(value, DEBOUNCE_MS);
37
+ const inputRef = React.useRef(null);
38
+ const [isExpanded, setIsExpanded] = React.useState(false);
39
+ // A term keeps the field open: folding it would hide an active search.
40
+ const isCollapsed = collapsible && !isMobile && !isExpanded && value === '';
41
+ // Only after the button opened it: a field shown on mount must not take focus.
42
+ React.useEffect(()=>{
43
+ if (isExpanded) {
44
+ inputRef.current?.focus();
45
+ }
46
+ }, [
47
+ isExpanded
48
+ ]);
49
+ // Emptied from elsewhere (a folder opened, the empty state's "Clear search")
50
+ // after the field was left with a term in it: the blur already happened, so
51
+ // fold it here. Not while it has focus: that is the user clearing it to type.
52
+ React.useEffect(()=>{
53
+ if (value === '' && document.activeElement !== inputRef.current) {
54
+ setIsExpanded(false);
55
+ }
56
+ }, [
57
+ value
58
+ ]);
59
+ const handleBlur = (event)=>{
60
+ if (event.currentTarget.value === '') {
61
+ setIsExpanded(false);
62
+ }
63
+ };
35
64
  // Tracks the last value the URL and the input agreed on. Without it the two
36
65
  // effects below would ping-pong: each would see the other's write as a change
37
66
  // worth reacting to.
38
67
  const lastCommittedRef = React.useRef(searchQuery);
39
68
  // Read directly rather than through `useFolderNavigation`, which strips
40
69
  // malformed `?folder=` values as a side effect.
41
- const [{ query }] = strapiAdmin.useQueryParams();
70
+ const [{ query }] = useListQueryParams.useListQueryParams();
42
71
  const folderParam = query?.folder ?? '';
43
72
  const lastFolderRef = React.useRef(folderParam);
44
73
  // Commit settled input to the URL.
@@ -88,6 +117,7 @@ const StyledSearchForm = styledComponents.styled(designSystem.SearchForm)`
88
117
  const searchForm = /*#__PURE__*/ jsxRuntime.jsx(StyledSearchForm, {
89
118
  onSubmit: (event)=>event.preventDefault(),
90
119
  children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Searchbar, {
120
+ ref: inputRef,
91
121
  name: "search-assets",
92
122
  value: value,
93
123
  onChange: (event)=>setValue(event.target.value),
@@ -101,12 +131,23 @@ const StyledSearchForm = styledComponents.styled(designSystem.SearchForm)`
101
131
  defaultMessage: 'Search'
102
132
  }),
103
133
  size: "S",
134
+ onBlur: collapsible ? handleBlur : undefined,
104
135
  children: formatMessage({
105
136
  id: translations.getTranslationKey('search.label'),
106
137
  defaultMessage: 'Search for an asset'
107
138
  })
108
139
  })
109
140
  });
141
+ if (isCollapsed) {
142
+ return /*#__PURE__*/ jsxRuntime.jsx(designSystem.IconButton, {
143
+ label: formatMessage({
144
+ id: 'global.search',
145
+ defaultMessage: 'Search'
146
+ }),
147
+ onClick: ()=>setIsExpanded(true),
148
+ children: /*#__PURE__*/ jsxRuntime.jsx(icons.Search, {})
149
+ });
150
+ }
110
151
  // Mobile: fills the toolbar row (own line). Desktop: keeps its intrinsic size,
111
152
  // with empty space between it and the right-aligned Sort/Toggle group.
112
153
  if (isMobile) {
@@ -1 +1 @@
1
- {"version":3,"file":"AssetsSearchInput.js","sources":["../../../../../admin/src/pages/Assets/components/AssetsSearchInput.tsx"],"sourcesContent":["import { useEffect, useRef, useState, type ChangeEvent, type FormEvent } from 'react';\n\nimport { useDebounce, useIsMobile, useQueryParams } from '@strapi/admin/strapi-admin';\nimport { Box, Searchbar, SearchForm } from '@strapi/design-system';\nimport { useIntl } from 'react-intl';\nimport { styled } from 'styled-components';\n\nimport { useTracking, MEDIA_LIBRARY_LOCATION } from '../../../hooks/useTracking';\nimport { getTranslationKey } from '../../../utils/translations';\nimport { useAssetSearch } from '../hooks/useAssetSearch';\n\nconst DEBOUNCE_MS = 300;\n\n// The DS Searchbar nests two bordered boxes: its own shell (neutral150) wrapping\n// the field (neutral200). Side by side they read as a single 2px, two-tone\n// border, which sits oddly next to the 1px neutral200 on the Filter button in the\n// same toolbar. Dropping the shell's border leaves the field's own — same width\n// and colour as the button — and costs nothing, since the focus ring lives on the\n// field too.\nconst StyledSearchForm = styled(SearchForm)`\n > div {\n border: none;\n }\n`;\n\n/**\n * Keyword search over the whole Media Library. Owns the typing state and the\n * debounce; `useAssetSearch` owns the `?_q=` URL param.\n */\nexport const AssetsSearchInput = () => {\n const { formatMessage } = useIntl();\n const { searchQuery, setSearchQuery } = useAssetSearch();\n const { trackUsage } = useTracking();\n const isMobile = useIsMobile();\n\n const [value, setValue] = useState(searchQuery);\n const debouncedValue = useDebounce(value, DEBOUNCE_MS);\n\n // Tracks the last value the URL and the input agreed on. Without it the two\n // effects below would ping-pong: each would see the other's write as a change\n // worth reacting to.\n const lastCommittedRef = useRef(searchQuery);\n\n // Read directly rather than through `useFolderNavigation`, which strips\n // malformed `?folder=` values as a side effect.\n const [{ query }] = useQueryParams<{ folder?: string }>();\n const folderParam = query?.folder ?? '';\n const lastFolderRef = useRef(folderParam);\n\n // Commit settled input to the URL.\n useEffect(() => {\n if (debouncedValue === lastCommittedRef.current) {\n return;\n }\n\n lastCommittedRef.current = debouncedValue;\n // Only a real query counts as a search — clearing the box (empty value) is\n // a reset, not a `didSearch`.\n if (debouncedValue) {\n trackUsage('didSearchMediaLibraryElements', { location: MEDIA_LIBRARY_LOCATION });\n }\n setSearchQuery(debouncedValue);\n }, [debouncedValue, setSearchQuery, trackUsage]);\n\n // Re-sync on external changes — back/forward, or \"Clear search\" in the empty\n // state.\n useEffect(() => {\n if (searchQuery === lastCommittedRef.current) {\n return;\n }\n\n lastCommittedRef.current = searchQuery;\n setValue(searchQuery);\n }, [searchQuery]);\n\n // A folder navigation clears `_q`, but a term typed and never committed lives\n // only in the debounce — without this it lands afterwards and reactivates the\n // global search. `_q` alone can't see it: it was never non-empty.\n useEffect(() => {\n if (folderParam === lastFolderRef.current) {\n return;\n }\n\n lastFolderRef.current = folderParam;\n lastCommittedRef.current = searchQuery;\n setValue(searchQuery);\n }, [folderParam, searchQuery]);\n\n const searchForm = (\n <StyledSearchForm onSubmit={(event: FormEvent<HTMLFormElement>) => event.preventDefault()}>\n <Searchbar\n name=\"search-assets\"\n value={value}\n onChange={(event: ChangeEvent<HTMLInputElement>) => setValue(event.target.value)}\n onClear={() => setValue('')}\n clearLabel={formatMessage({ id: 'clearLabel', defaultMessage: 'Clear' })}\n placeholder={formatMessage({\n id: getTranslationKey('header.search.placeholder'),\n defaultMessage: 'Search',\n })}\n size=\"S\"\n >\n {formatMessage({\n id: getTranslationKey('search.label'),\n defaultMessage: 'Search for an asset',\n })}\n </Searchbar>\n </StyledSearchForm>\n );\n\n // Mobile: fills the toolbar row (own line). Desktop: keeps its intrinsic size,\n // with empty space between it and the right-aligned Sort/Toggle group.\n if (isMobile) {\n return <Box width=\"100%\">{searchForm}</Box>;\n }\n\n return searchForm;\n};\n"],"names":["DEBOUNCE_MS","StyledSearchForm","styled","SearchForm","AssetsSearchInput","formatMessage","useIntl","searchQuery","setSearchQuery","useAssetSearch","trackUsage","useTracking","isMobile","useIsMobile","value","setValue","useState","debouncedValue","useDebounce","lastCommittedRef","useRef","query","useQueryParams","folderParam","folder","lastFolderRef","useEffect","current","location","MEDIA_LIBRARY_LOCATION","searchForm","_jsx","onSubmit","event","preventDefault","Searchbar","name","onChange","target","onClear","clearLabel","id","defaultMessage","placeholder","getTranslationKey","size","Box","width"],"mappings":"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"}
1
+ {"version":3,"file":"AssetsSearchInput.js","sources":["../../../../../admin/src/pages/Assets/components/AssetsSearchInput.tsx"],"sourcesContent":["import {\n useEffect,\n useRef,\n useState,\n type ChangeEvent,\n type FocusEvent,\n type FormEvent,\n} from 'react';\n\nimport { useDebounce, useIsMobile } from '@strapi/admin/strapi-admin';\nimport { Box, IconButton, Searchbar, SearchForm } from '@strapi/design-system';\nimport { Search as SearchIcon } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { styled } from 'styled-components';\n\nimport { useTracking, MEDIA_LIBRARY_LOCATION } from '../../../hooks/useTracking';\nimport { getTranslationKey } from '../../../utils/translations';\nimport { useAssetSearch } from '../hooks/useAssetSearch';\nimport { useListQueryParams } from '../hooks/useListQueryParams';\n\nconst DEBOUNCE_MS = 300;\n\n// The DS Searchbar nests two bordered boxes: its own shell (neutral150) wrapping\n// the field (neutral200). Side by side they read as a single 2px, two-tone\n// border, which sits oddly next to the 1px neutral200 on the Filter button in the\n// same toolbar. Dropping the shell's border leaves the field's own — same width\n// and colour as the button — and costs nothing, since the focus ring lives on the\n// field too.\nconst StyledSearchForm = styled(SearchForm)`\n > div {\n border: none;\n }\n`;\n\ninterface AssetsSearchInputProps {\n /**\n * Starts as an icon button that opens the field, which folds back once it\n * loses focus empty, like the admin's own `SearchInput` in list views. Used\n * where the toolbar is narrow (the Content Manager asset picker). Mobile\n * always shows the field.\n */\n collapsible?: boolean;\n}\n\n/**\n * Keyword search over the whole Media Library. Owns the typing state and the\n * debounce; `useAssetSearch` owns the `?_q=` URL param.\n */\nexport const AssetsSearchInput = ({ collapsible = false }: AssetsSearchInputProps) => {\n const { formatMessage } = useIntl();\n const { searchQuery, setSearchQuery } = useAssetSearch();\n const { trackUsage } = useTracking();\n const isMobile = useIsMobile();\n\n const [value, setValue] = useState(searchQuery);\n const debouncedValue = useDebounce(value, DEBOUNCE_MS);\n\n const inputRef = useRef<HTMLInputElement>(null);\n const [isExpanded, setIsExpanded] = useState(false);\n // A term keeps the field open: folding it would hide an active search.\n const isCollapsed = collapsible && !isMobile && !isExpanded && value === '';\n\n // Only after the button opened it: a field shown on mount must not take focus.\n useEffect(() => {\n if (isExpanded) {\n inputRef.current?.focus();\n }\n }, [isExpanded]);\n\n // Emptied from elsewhere (a folder opened, the empty state's \"Clear search\")\n // after the field was left with a term in it: the blur already happened, so\n // fold it here. Not while it has focus: that is the user clearing it to type.\n useEffect(() => {\n if (value === '' && document.activeElement !== inputRef.current) {\n setIsExpanded(false);\n }\n }, [value]);\n\n const handleBlur = (event: FocusEvent<HTMLInputElement>) => {\n if (event.currentTarget.value === '') {\n setIsExpanded(false);\n }\n };\n\n // Tracks the last value the URL and the input agreed on. Without it the two\n // effects below would ping-pong: each would see the other's write as a change\n // worth reacting to.\n const lastCommittedRef = useRef(searchQuery);\n\n // Read directly rather than through `useFolderNavigation`, which strips\n // malformed `?folder=` values as a side effect.\n const [{ query }] = useListQueryParams<{ folder?: string }>();\n const folderParam = query?.folder ?? '';\n const lastFolderRef = useRef(folderParam);\n\n // Commit settled input to the URL.\n useEffect(() => {\n if (debouncedValue === lastCommittedRef.current) {\n return;\n }\n\n lastCommittedRef.current = debouncedValue;\n // Only a real query counts as a search — clearing the box (empty value) is\n // a reset, not a `didSearch`.\n if (debouncedValue) {\n trackUsage('didSearchMediaLibraryElements', { location: MEDIA_LIBRARY_LOCATION });\n }\n setSearchQuery(debouncedValue);\n }, [debouncedValue, setSearchQuery, trackUsage]);\n\n // Re-sync on external changes — back/forward, or \"Clear search\" in the empty\n // state.\n useEffect(() => {\n if (searchQuery === lastCommittedRef.current) {\n return;\n }\n\n lastCommittedRef.current = searchQuery;\n setValue(searchQuery);\n }, [searchQuery]);\n\n // A folder navigation clears `_q`, but a term typed and never committed lives\n // only in the debounce — without this it lands afterwards and reactivates the\n // global search. `_q` alone can't see it: it was never non-empty.\n useEffect(() => {\n if (folderParam === lastFolderRef.current) {\n return;\n }\n\n lastFolderRef.current = folderParam;\n lastCommittedRef.current = searchQuery;\n setValue(searchQuery);\n }, [folderParam, searchQuery]);\n\n const searchForm = (\n <StyledSearchForm onSubmit={(event: FormEvent<HTMLFormElement>) => event.preventDefault()}>\n <Searchbar\n ref={inputRef}\n name=\"search-assets\"\n value={value}\n onChange={(event: ChangeEvent<HTMLInputElement>) => setValue(event.target.value)}\n onClear={() => setValue('')}\n clearLabel={formatMessage({ id: 'clearLabel', defaultMessage: 'Clear' })}\n placeholder={formatMessage({\n id: getTranslationKey('header.search.placeholder'),\n defaultMessage: 'Search',\n })}\n size=\"S\"\n onBlur={collapsible ? handleBlur : undefined}\n >\n {formatMessage({\n id: getTranslationKey('search.label'),\n defaultMessage: 'Search for an asset',\n })}\n </Searchbar>\n </StyledSearchForm>\n );\n\n if (isCollapsed) {\n return (\n <IconButton\n label={formatMessage({ id: 'global.search', defaultMessage: 'Search' })}\n onClick={() => setIsExpanded(true)}\n >\n <SearchIcon />\n </IconButton>\n );\n }\n\n // Mobile: fills the toolbar row (own line). Desktop: keeps its intrinsic size,\n // with empty space between it and the right-aligned Sort/Toggle group.\n if (isMobile) {\n return <Box width=\"100%\">{searchForm}</Box>;\n }\n\n return searchForm;\n};\n"],"names":["DEBOUNCE_MS","StyledSearchForm","styled","SearchForm","AssetsSearchInput","collapsible","formatMessage","useIntl","searchQuery","setSearchQuery","useAssetSearch","trackUsage","useTracking","isMobile","useIsMobile","value","setValue","useState","debouncedValue","useDebounce","inputRef","useRef","isExpanded","setIsExpanded","isCollapsed","useEffect","current","focus","document","activeElement","handleBlur","event","currentTarget","lastCommittedRef","query","useListQueryParams","folderParam","folder","lastFolderRef","location","MEDIA_LIBRARY_LOCATION","searchForm","_jsx","onSubmit","preventDefault","Searchbar","ref","name","onChange","target","onClear","clearLabel","id","defaultMessage","placeholder","getTranslationKey","size","onBlur","undefined","IconButton","label","onClick","SearchIcon","Box","width"],"mappings":";;;;;;;;;;;;;;AAoBA,MAAMA,WAAAA,GAAc,GAAA;AAEpB;AACA;AACA;AACA;AACA;AACA;AACA,MAAMC,gBAAAA,GAAmBC,uBAAAA,CAAOC,uBAAAA,CAAW;;;;AAI3C,CAAC;AAYD;;;AAGC,IACM,MAAMC,iBAAAA,GAAoB,CAAC,EAAEC,WAAAA,GAAc,KAAK,EAA0B,GAAA;IAC/E,MAAM,EAAEC,aAAa,EAAE,GAAGC,iBAAAA,EAAAA;AAC1B,IAAA,MAAM,EAAEC,WAAW,EAAEC,cAAc,EAAE,GAAGC,6BAAAA,EAAAA;IACxC,MAAM,EAAEC,UAAU,EAAE,GAAGC,uBAAAA,EAAAA;AACvB,IAAA,MAAMC,QAAAA,GAAWC,uBAAAA,EAAAA;AAEjB,IAAA,MAAM,CAACC,KAAAA,EAAOC,QAAAA,CAAS,GAAGC,cAAAA,CAAST,WAAAA,CAAAA;IACnC,MAAMU,cAAAA,GAAiBC,wBAAYJ,KAAAA,EAAOf,WAAAA,CAAAA;AAE1C,IAAA,MAAMoB,WAAWC,YAAAA,CAAyB,IAAA,CAAA;AAC1C,IAAA,MAAM,CAACC,UAAAA,EAAYC,aAAAA,CAAc,GAAGN,cAAAA,CAAS,KAAA,CAAA;;AAE7C,IAAA,MAAMO,cAAcnB,WAAAA,IAAe,CAACQ,QAAAA,IAAY,CAACS,cAAcP,KAAAA,KAAU,EAAA;;IAGzEU,eAAAA,CAAU,IAAA;AACR,QAAA,IAAIH,UAAAA,EAAY;AACdF,YAAAA,QAAAA,CAASM,OAAO,EAAEC,KAAAA,EAAAA;AACpB,QAAA;IACF,CAAA,EAAG;AAACL,QAAAA;AAAW,KAAA,CAAA;;;;IAKfG,eAAAA,CAAU,IAAA;AACR,QAAA,IAAIV,UAAU,EAAA,IAAMa,QAAAA,CAASC,aAAa,KAAKT,QAAAA,CAASM,OAAO,EAAE;YAC/DH,aAAAA,CAAc,KAAA,CAAA;AAChB,QAAA;IACF,CAAA,EAAG;AAACR,QAAAA;AAAM,KAAA,CAAA;AAEV,IAAA,MAAMe,aAAa,CAACC,KAAAA,GAAAA;AAClB,QAAA,IAAIA,KAAAA,CAAMC,aAAa,CAACjB,KAAK,KAAK,EAAA,EAAI;YACpCQ,aAAAA,CAAc,KAAA,CAAA;AAChB,QAAA;AACF,IAAA,CAAA;;;;AAKA,IAAA,MAAMU,mBAAmBZ,YAAAA,CAAOb,WAAAA,CAAAA;;;AAIhC,IAAA,MAAM,CAAC,EAAE0B,KAAK,EAAE,CAAC,GAAGC,qCAAAA,EAAAA;IACpB,MAAMC,WAAAA,GAAcF,OAAOG,MAAAA,IAAU,EAAA;AACrC,IAAA,MAAMC,gBAAgBjB,YAAAA,CAAOe,WAAAA,CAAAA;;IAG7BX,eAAAA,CAAU,IAAA;QACR,IAAIP,cAAAA,KAAmBe,gBAAAA,CAAiBP,OAAO,EAAE;AAC/C,YAAA;AACF,QAAA;AAEAO,QAAAA,gBAAAA,CAAiBP,OAAO,GAAGR,cAAAA;;;AAG3B,QAAA,IAAIA,cAAAA,EAAgB;AAClBP,YAAAA,UAAAA,CAAW,+BAAA,EAAiC;gBAAE4B,QAAAA,EAAUC;AAAuB,aAAA,CAAA;AACjF,QAAA;QACA/B,cAAAA,CAAeS,cAAAA,CAAAA;IACjB,CAAA,EAAG;AAACA,QAAAA,cAAAA;AAAgBT,QAAAA,cAAAA;AAAgBE,QAAAA;AAAW,KAAA,CAAA;;;IAI/Cc,eAAAA,CAAU,IAAA;QACR,IAAIjB,WAAAA,KAAgByB,gBAAAA,CAAiBP,OAAO,EAAE;AAC5C,YAAA;AACF,QAAA;AAEAO,QAAAA,gBAAAA,CAAiBP,OAAO,GAAGlB,WAAAA;QAC3BQ,QAAAA,CAASR,WAAAA,CAAAA;IACX,CAAA,EAAG;AAACA,QAAAA;AAAY,KAAA,CAAA;;;;IAKhBiB,eAAAA,CAAU,IAAA;QACR,IAAIW,WAAAA,KAAgBE,aAAAA,CAAcZ,OAAO,EAAE;AACzC,YAAA;AACF,QAAA;AAEAY,QAAAA,aAAAA,CAAcZ,OAAO,GAAGU,WAAAA;AACxBH,QAAAA,gBAAAA,CAAiBP,OAAO,GAAGlB,WAAAA;QAC3BQ,QAAAA,CAASR,WAAAA,CAAAA;IACX,CAAA,EAAG;AAAC4B,QAAAA,WAAAA;AAAa5B,QAAAA;AAAY,KAAA,CAAA;AAE7B,IAAA,MAAMiC,2BACJC,cAAA,CAACzC,gBAAAA,EAAAA;QAAiB0C,QAAAA,EAAU,CAACZ,KAAAA,GAAsCA,KAAAA,CAAMa,cAAc,EAAA;AACrF,QAAA,QAAA,gBAAAF,cAAA,CAACG,sBAAAA,EAAAA;YACCC,GAAAA,EAAK1B,QAAAA;YACL2B,IAAAA,EAAK,eAAA;YACLhC,KAAAA,EAAOA,KAAAA;AACPiC,YAAAA,QAAAA,EAAU,CAACjB,KAAAA,GAAyCf,QAAAA,CAASe,KAAAA,CAAMkB,MAAM,CAAClC,KAAK,CAAA;AAC/EmC,YAAAA,OAAAA,EAAS,IAAMlC,QAAAA,CAAS,EAAA,CAAA;AACxBmC,YAAAA,UAAAA,EAAY7C,aAAAA,CAAc;gBAAE8C,EAAAA,EAAI,YAAA;gBAAcC,cAAAA,EAAgB;AAAQ,aAAA,CAAA;AACtEC,YAAAA,WAAAA,EAAahD,aAAAA,CAAc;AACzB8C,gBAAAA,EAAAA,EAAIG,8BAAAA,CAAkB,2BAAA,CAAA;gBACtBF,cAAAA,EAAgB;AAClB,aAAA,CAAA;YACAG,IAAAA,EAAK,GAAA;AACLC,YAAAA,MAAAA,EAAQpD,cAAcyB,UAAAA,GAAa4B,SAAAA;sBAElCpD,aAAAA,CAAc;AACb8C,gBAAAA,EAAAA,EAAIG,8BAAAA,CAAkB,cAAA,CAAA;gBACtBF,cAAAA,EAAgB;AAClB,aAAA;;;AAKN,IAAA,IAAI7B,WAAAA,EAAa;AACf,QAAA,qBACEkB,cAAA,CAACiB,uBAAAA,EAAAA;AACCC,YAAAA,KAAAA,EAAOtD,aAAAA,CAAc;gBAAE8C,EAAAA,EAAI,eAAA;gBAAiBC,cAAAA,EAAgB;AAAS,aAAA,CAAA;AACrEQ,YAAAA,OAAAA,EAAS,IAAMtC,aAAAA,CAAc,IAAA,CAAA;AAE7B,YAAA,QAAA,gBAAAmB,cAAA,CAACoB,YAAAA,EAAAA,EAAAA;;AAGP,IAAA;;;AAIA,IAAA,IAAIjD,QAAAA,EAAU;AACZ,QAAA,qBAAO6B,cAAA,CAACqB,gBAAAA,EAAAA;YAAIC,KAAAA,EAAM,MAAA;AAAQvB,YAAAA,QAAAA,EAAAA;;AAC5B,IAAA;IAEA,OAAOA,UAAAA;AACT;;;;"}
@@ -1,12 +1,14 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
2
  import { useState, useRef, useEffect } from 'react';
3
- import { useIsMobile, useDebounce, useQueryParams } from '@strapi/admin/strapi-admin';
4
- import { Searchbar, Box, SearchForm } from '@strapi/design-system';
3
+ import { useIsMobile, useDebounce } from '@strapi/admin/strapi-admin';
4
+ import { SearchForm, Searchbar, IconButton, Box } from '@strapi/design-system';
5
+ import { Search } from '@strapi/icons';
5
6
  import { useIntl } from 'react-intl';
6
7
  import { styled } from 'styled-components';
7
8
  import { useTracking, MEDIA_LIBRARY_LOCATION } from '../../../hooks/useTracking.mjs';
8
9
  import { getTranslationKey } from '../../../utils/translations.mjs';
9
10
  import { useAssetSearch } from '../hooks/useAssetSearch.mjs';
11
+ import { useListQueryParams } from '../hooks/useListQueryParams.mjs';
10
12
 
11
13
  const DEBOUNCE_MS = 300;
12
14
  // The DS Searchbar nests two bordered boxes: its own shell (neutral150) wrapping
@@ -23,20 +25,47 @@ const StyledSearchForm = styled(SearchForm)`
23
25
  /**
24
26
  * Keyword search over the whole Media Library. Owns the typing state and the
25
27
  * debounce; `useAssetSearch` owns the `?_q=` URL param.
26
- */ const AssetsSearchInput = ()=>{
28
+ */ const AssetsSearchInput = ({ collapsible = false })=>{
27
29
  const { formatMessage } = useIntl();
28
30
  const { searchQuery, setSearchQuery } = useAssetSearch();
29
31
  const { trackUsage } = useTracking();
30
32
  const isMobile = useIsMobile();
31
33
  const [value, setValue] = useState(searchQuery);
32
34
  const debouncedValue = useDebounce(value, DEBOUNCE_MS);
35
+ const inputRef = useRef(null);
36
+ const [isExpanded, setIsExpanded] = useState(false);
37
+ // A term keeps the field open: folding it would hide an active search.
38
+ const isCollapsed = collapsible && !isMobile && !isExpanded && value === '';
39
+ // Only after the button opened it: a field shown on mount must not take focus.
40
+ useEffect(()=>{
41
+ if (isExpanded) {
42
+ inputRef.current?.focus();
43
+ }
44
+ }, [
45
+ isExpanded
46
+ ]);
47
+ // Emptied from elsewhere (a folder opened, the empty state's "Clear search")
48
+ // after the field was left with a term in it: the blur already happened, so
49
+ // fold it here. Not while it has focus: that is the user clearing it to type.
50
+ useEffect(()=>{
51
+ if (value === '' && document.activeElement !== inputRef.current) {
52
+ setIsExpanded(false);
53
+ }
54
+ }, [
55
+ value
56
+ ]);
57
+ const handleBlur = (event)=>{
58
+ if (event.currentTarget.value === '') {
59
+ setIsExpanded(false);
60
+ }
61
+ };
33
62
  // Tracks the last value the URL and the input agreed on. Without it the two
34
63
  // effects below would ping-pong: each would see the other's write as a change
35
64
  // worth reacting to.
36
65
  const lastCommittedRef = useRef(searchQuery);
37
66
  // Read directly rather than through `useFolderNavigation`, which strips
38
67
  // malformed `?folder=` values as a side effect.
39
- const [{ query }] = useQueryParams();
68
+ const [{ query }] = useListQueryParams();
40
69
  const folderParam = query?.folder ?? '';
41
70
  const lastFolderRef = useRef(folderParam);
42
71
  // Commit settled input to the URL.
@@ -86,6 +115,7 @@ const StyledSearchForm = styled(SearchForm)`
86
115
  const searchForm = /*#__PURE__*/ jsx(StyledSearchForm, {
87
116
  onSubmit: (event)=>event.preventDefault(),
88
117
  children: /*#__PURE__*/ jsx(Searchbar, {
118
+ ref: inputRef,
89
119
  name: "search-assets",
90
120
  value: value,
91
121
  onChange: (event)=>setValue(event.target.value),
@@ -99,12 +129,23 @@ const StyledSearchForm = styled(SearchForm)`
99
129
  defaultMessage: 'Search'
100
130
  }),
101
131
  size: "S",
132
+ onBlur: collapsible ? handleBlur : undefined,
102
133
  children: formatMessage({
103
134
  id: getTranslationKey('search.label'),
104
135
  defaultMessage: 'Search for an asset'
105
136
  })
106
137
  })
107
138
  });
139
+ if (isCollapsed) {
140
+ return /*#__PURE__*/ jsx(IconButton, {
141
+ label: formatMessage({
142
+ id: 'global.search',
143
+ defaultMessage: 'Search'
144
+ }),
145
+ onClick: ()=>setIsExpanded(true),
146
+ children: /*#__PURE__*/ jsx(Search, {})
147
+ });
148
+ }
108
149
  // Mobile: fills the toolbar row (own line). Desktop: keeps its intrinsic size,
109
150
  // with empty space between it and the right-aligned Sort/Toggle group.
110
151
  if (isMobile) {
@@ -1 +1 @@
1
- {"version":3,"file":"AssetsSearchInput.mjs","sources":["../../../../../admin/src/pages/Assets/components/AssetsSearchInput.tsx"],"sourcesContent":["import { useEffect, useRef, useState, type ChangeEvent, type FormEvent } from 'react';\n\nimport { useDebounce, useIsMobile, useQueryParams } from '@strapi/admin/strapi-admin';\nimport { Box, Searchbar, SearchForm } from '@strapi/design-system';\nimport { useIntl } from 'react-intl';\nimport { styled } from 'styled-components';\n\nimport { useTracking, MEDIA_LIBRARY_LOCATION } from '../../../hooks/useTracking';\nimport { getTranslationKey } from '../../../utils/translations';\nimport { useAssetSearch } from '../hooks/useAssetSearch';\n\nconst DEBOUNCE_MS = 300;\n\n// The DS Searchbar nests two bordered boxes: its own shell (neutral150) wrapping\n// the field (neutral200). Side by side they read as a single 2px, two-tone\n// border, which sits oddly next to the 1px neutral200 on the Filter button in the\n// same toolbar. Dropping the shell's border leaves the field's own — same width\n// and colour as the button — and costs nothing, since the focus ring lives on the\n// field too.\nconst StyledSearchForm = styled(SearchForm)`\n > div {\n border: none;\n }\n`;\n\n/**\n * Keyword search over the whole Media Library. Owns the typing state and the\n * debounce; `useAssetSearch` owns the `?_q=` URL param.\n */\nexport const AssetsSearchInput = () => {\n const { formatMessage } = useIntl();\n const { searchQuery, setSearchQuery } = useAssetSearch();\n const { trackUsage } = useTracking();\n const isMobile = useIsMobile();\n\n const [value, setValue] = useState(searchQuery);\n const debouncedValue = useDebounce(value, DEBOUNCE_MS);\n\n // Tracks the last value the URL and the input agreed on. Without it the two\n // effects below would ping-pong: each would see the other's write as a change\n // worth reacting to.\n const lastCommittedRef = useRef(searchQuery);\n\n // Read directly rather than through `useFolderNavigation`, which strips\n // malformed `?folder=` values as a side effect.\n const [{ query }] = useQueryParams<{ folder?: string }>();\n const folderParam = query?.folder ?? '';\n const lastFolderRef = useRef(folderParam);\n\n // Commit settled input to the URL.\n useEffect(() => {\n if (debouncedValue === lastCommittedRef.current) {\n return;\n }\n\n lastCommittedRef.current = debouncedValue;\n // Only a real query counts as a search — clearing the box (empty value) is\n // a reset, not a `didSearch`.\n if (debouncedValue) {\n trackUsage('didSearchMediaLibraryElements', { location: MEDIA_LIBRARY_LOCATION });\n }\n setSearchQuery(debouncedValue);\n }, [debouncedValue, setSearchQuery, trackUsage]);\n\n // Re-sync on external changes — back/forward, or \"Clear search\" in the empty\n // state.\n useEffect(() => {\n if (searchQuery === lastCommittedRef.current) {\n return;\n }\n\n lastCommittedRef.current = searchQuery;\n setValue(searchQuery);\n }, [searchQuery]);\n\n // A folder navigation clears `_q`, but a term typed and never committed lives\n // only in the debounce — without this it lands afterwards and reactivates the\n // global search. `_q` alone can't see it: it was never non-empty.\n useEffect(() => {\n if (folderParam === lastFolderRef.current) {\n return;\n }\n\n lastFolderRef.current = folderParam;\n lastCommittedRef.current = searchQuery;\n setValue(searchQuery);\n }, [folderParam, searchQuery]);\n\n const searchForm = (\n <StyledSearchForm onSubmit={(event: FormEvent<HTMLFormElement>) => event.preventDefault()}>\n <Searchbar\n name=\"search-assets\"\n value={value}\n onChange={(event: ChangeEvent<HTMLInputElement>) => setValue(event.target.value)}\n onClear={() => setValue('')}\n clearLabel={formatMessage({ id: 'clearLabel', defaultMessage: 'Clear' })}\n placeholder={formatMessage({\n id: getTranslationKey('header.search.placeholder'),\n defaultMessage: 'Search',\n })}\n size=\"S\"\n >\n {formatMessage({\n id: getTranslationKey('search.label'),\n defaultMessage: 'Search for an asset',\n })}\n </Searchbar>\n </StyledSearchForm>\n );\n\n // Mobile: fills the toolbar row (own line). Desktop: keeps its intrinsic size,\n // with empty space between it and the right-aligned Sort/Toggle group.\n if (isMobile) {\n return <Box width=\"100%\">{searchForm}</Box>;\n }\n\n return searchForm;\n};\n"],"names":["DEBOUNCE_MS","StyledSearchForm","styled","SearchForm","AssetsSearchInput","formatMessage","useIntl","searchQuery","setSearchQuery","useAssetSearch","trackUsage","useTracking","isMobile","useIsMobile","value","setValue","useState","debouncedValue","useDebounce","lastCommittedRef","useRef","query","useQueryParams","folderParam","folder","lastFolderRef","useEffect","current","location","MEDIA_LIBRARY_LOCATION","searchForm","_jsx","onSubmit","event","preventDefault","Searchbar","name","onChange","target","onClear","clearLabel","id","defaultMessage","placeholder","getTranslationKey","size","Box","width"],"mappings":"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"}
1
+ {"version":3,"file":"AssetsSearchInput.mjs","sources":["../../../../../admin/src/pages/Assets/components/AssetsSearchInput.tsx"],"sourcesContent":["import {\n useEffect,\n useRef,\n useState,\n type ChangeEvent,\n type FocusEvent,\n type FormEvent,\n} from 'react';\n\nimport { useDebounce, useIsMobile } from '@strapi/admin/strapi-admin';\nimport { Box, IconButton, Searchbar, SearchForm } from '@strapi/design-system';\nimport { Search as SearchIcon } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { styled } from 'styled-components';\n\nimport { useTracking, MEDIA_LIBRARY_LOCATION } from '../../../hooks/useTracking';\nimport { getTranslationKey } from '../../../utils/translations';\nimport { useAssetSearch } from '../hooks/useAssetSearch';\nimport { useListQueryParams } from '../hooks/useListQueryParams';\n\nconst DEBOUNCE_MS = 300;\n\n// The DS Searchbar nests two bordered boxes: its own shell (neutral150) wrapping\n// the field (neutral200). Side by side they read as a single 2px, two-tone\n// border, which sits oddly next to the 1px neutral200 on the Filter button in the\n// same toolbar. Dropping the shell's border leaves the field's own — same width\n// and colour as the button — and costs nothing, since the focus ring lives on the\n// field too.\nconst StyledSearchForm = styled(SearchForm)`\n > div {\n border: none;\n }\n`;\n\ninterface AssetsSearchInputProps {\n /**\n * Starts as an icon button that opens the field, which folds back once it\n * loses focus empty, like the admin's own `SearchInput` in list views. Used\n * where the toolbar is narrow (the Content Manager asset picker). Mobile\n * always shows the field.\n */\n collapsible?: boolean;\n}\n\n/**\n * Keyword search over the whole Media Library. Owns the typing state and the\n * debounce; `useAssetSearch` owns the `?_q=` URL param.\n */\nexport const AssetsSearchInput = ({ collapsible = false }: AssetsSearchInputProps) => {\n const { formatMessage } = useIntl();\n const { searchQuery, setSearchQuery } = useAssetSearch();\n const { trackUsage } = useTracking();\n const isMobile = useIsMobile();\n\n const [value, setValue] = useState(searchQuery);\n const debouncedValue = useDebounce(value, DEBOUNCE_MS);\n\n const inputRef = useRef<HTMLInputElement>(null);\n const [isExpanded, setIsExpanded] = useState(false);\n // A term keeps the field open: folding it would hide an active search.\n const isCollapsed = collapsible && !isMobile && !isExpanded && value === '';\n\n // Only after the button opened it: a field shown on mount must not take focus.\n useEffect(() => {\n if (isExpanded) {\n inputRef.current?.focus();\n }\n }, [isExpanded]);\n\n // Emptied from elsewhere (a folder opened, the empty state's \"Clear search\")\n // after the field was left with a term in it: the blur already happened, so\n // fold it here. Not while it has focus: that is the user clearing it to type.\n useEffect(() => {\n if (value === '' && document.activeElement !== inputRef.current) {\n setIsExpanded(false);\n }\n }, [value]);\n\n const handleBlur = (event: FocusEvent<HTMLInputElement>) => {\n if (event.currentTarget.value === '') {\n setIsExpanded(false);\n }\n };\n\n // Tracks the last value the URL and the input agreed on. Without it the two\n // effects below would ping-pong: each would see the other's write as a change\n // worth reacting to.\n const lastCommittedRef = useRef(searchQuery);\n\n // Read directly rather than through `useFolderNavigation`, which strips\n // malformed `?folder=` values as a side effect.\n const [{ query }] = useListQueryParams<{ folder?: string }>();\n const folderParam = query?.folder ?? '';\n const lastFolderRef = useRef(folderParam);\n\n // Commit settled input to the URL.\n useEffect(() => {\n if (debouncedValue === lastCommittedRef.current) {\n return;\n }\n\n lastCommittedRef.current = debouncedValue;\n // Only a real query counts as a search — clearing the box (empty value) is\n // a reset, not a `didSearch`.\n if (debouncedValue) {\n trackUsage('didSearchMediaLibraryElements', { location: MEDIA_LIBRARY_LOCATION });\n }\n setSearchQuery(debouncedValue);\n }, [debouncedValue, setSearchQuery, trackUsage]);\n\n // Re-sync on external changes — back/forward, or \"Clear search\" in the empty\n // state.\n useEffect(() => {\n if (searchQuery === lastCommittedRef.current) {\n return;\n }\n\n lastCommittedRef.current = searchQuery;\n setValue(searchQuery);\n }, [searchQuery]);\n\n // A folder navigation clears `_q`, but a term typed and never committed lives\n // only in the debounce — without this it lands afterwards and reactivates the\n // global search. `_q` alone can't see it: it was never non-empty.\n useEffect(() => {\n if (folderParam === lastFolderRef.current) {\n return;\n }\n\n lastFolderRef.current = folderParam;\n lastCommittedRef.current = searchQuery;\n setValue(searchQuery);\n }, [folderParam, searchQuery]);\n\n const searchForm = (\n <StyledSearchForm onSubmit={(event: FormEvent<HTMLFormElement>) => event.preventDefault()}>\n <Searchbar\n ref={inputRef}\n name=\"search-assets\"\n value={value}\n onChange={(event: ChangeEvent<HTMLInputElement>) => setValue(event.target.value)}\n onClear={() => setValue('')}\n clearLabel={formatMessage({ id: 'clearLabel', defaultMessage: 'Clear' })}\n placeholder={formatMessage({\n id: getTranslationKey('header.search.placeholder'),\n defaultMessage: 'Search',\n })}\n size=\"S\"\n onBlur={collapsible ? handleBlur : undefined}\n >\n {formatMessage({\n id: getTranslationKey('search.label'),\n defaultMessage: 'Search for an asset',\n })}\n </Searchbar>\n </StyledSearchForm>\n );\n\n if (isCollapsed) {\n return (\n <IconButton\n label={formatMessage({ id: 'global.search', defaultMessage: 'Search' })}\n onClick={() => setIsExpanded(true)}\n >\n <SearchIcon />\n </IconButton>\n );\n }\n\n // Mobile: fills the toolbar row (own line). Desktop: keeps its intrinsic size,\n // with empty space between it and the right-aligned Sort/Toggle group.\n if (isMobile) {\n return <Box width=\"100%\">{searchForm}</Box>;\n }\n\n return searchForm;\n};\n"],"names":["DEBOUNCE_MS","StyledSearchForm","styled","SearchForm","AssetsSearchInput","collapsible","formatMessage","useIntl","searchQuery","setSearchQuery","useAssetSearch","trackUsage","useTracking","isMobile","useIsMobile","value","setValue","useState","debouncedValue","useDebounce","inputRef","useRef","isExpanded","setIsExpanded","isCollapsed","useEffect","current","focus","document","activeElement","handleBlur","event","currentTarget","lastCommittedRef","query","useListQueryParams","folderParam","folder","lastFolderRef","location","MEDIA_LIBRARY_LOCATION","searchForm","_jsx","onSubmit","preventDefault","Searchbar","ref","name","onChange","target","onClear","clearLabel","id","defaultMessage","placeholder","getTranslationKey","size","onBlur","undefined","IconButton","label","onClick","SearchIcon","Box","width"],"mappings":"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"}