@strapi/upload 5.59.0 → 5.61.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin/components/AssetPickerDialog/AssetPickerDialog.js +434 -0
- package/dist/admin/components/AssetPickerDialog/AssetPickerDialog.js.map +1 -0
- package/dist/admin/components/AssetPickerDialog/AssetPickerDialog.mjs +432 -0
- package/dist/admin/components/AssetPickerDialog/AssetPickerDialog.mjs.map +1 -0
- package/dist/admin/components/AssetPickerDialog/FolderBreadcrumbs.js +91 -0
- package/dist/admin/components/AssetPickerDialog/FolderBreadcrumbs.js.map +1 -0
- package/dist/admin/components/AssetPickerDialog/FolderBreadcrumbs.mjs +89 -0
- package/dist/admin/components/AssetPickerDialog/FolderBreadcrumbs.mjs.map +1 -0
- package/dist/admin/components/AssetPickerDialog/MediaLibraryPickerDialog.js +29 -0
- package/dist/admin/components/AssetPickerDialog/MediaLibraryPickerDialog.js.map +1 -0
- package/dist/admin/components/AssetPickerDialog/MediaLibraryPickerDialog.mjs +27 -0
- package/dist/admin/components/AssetPickerDialog/MediaLibraryPickerDialog.mjs.map +1 -0
- package/dist/admin/components/AssetPickerDialog/PickerSelectionProvider.js +178 -0
- package/dist/admin/components/AssetPickerDialog/PickerSelectionProvider.js.map +1 -0
- package/dist/admin/components/AssetPickerDialog/PickerSelectionProvider.mjs +175 -0
- package/dist/admin/components/AssetPickerDialog/PickerSelectionProvider.mjs.map +1 -0
- package/dist/admin/components/AssetPickerDialog/SortableSelection.js +143 -0
- package/dist/admin/components/AssetPickerDialog/SortableSelection.js.map +1 -0
- package/dist/admin/components/AssetPickerDialog/SortableSelection.mjs +141 -0
- package/dist/admin/components/AssetPickerDialog/SortableSelection.mjs.map +1 -0
- package/dist/admin/components/AssetPickerDialog/pickerSelection.js +49 -0
- package/dist/admin/components/AssetPickerDialog/pickerSelection.js.map +1 -0
- package/dist/admin/components/AssetPickerDialog/pickerSelection.mjs +41 -0
- package/dist/admin/components/AssetPickerDialog/pickerSelection.mjs.map +1 -0
- package/dist/admin/components/Drawer.js +12 -7
- package/dist/admin/components/Drawer.js.map +1 -1
- package/dist/admin/components/Drawer.mjs +12 -7
- package/dist/admin/components/Drawer.mjs.map +1 -1
- package/dist/admin/components/EditorFileDropZone/EditorFileDropZone.js +188 -0
- package/dist/admin/components/EditorFileDropZone/EditorFileDropZone.js.map +1 -0
- package/dist/admin/components/EditorFileDropZone/EditorFileDropZone.mjs +186 -0
- package/dist/admin/components/EditorFileDropZone/EditorFileDropZone.mjs.map +1 -0
- package/dist/admin/components/MediaLibraryInput/AddAssetMenu.js +9 -4
- package/dist/admin/components/MediaLibraryInput/AddAssetMenu.js.map +1 -1
- package/dist/admin/components/MediaLibraryInput/AddAssetMenu.mjs +9 -4
- package/dist/admin/components/MediaLibraryInput/AddAssetMenu.mjs.map +1 -1
- package/dist/admin/components/MediaLibraryInput/AssetCard.js +240 -0
- package/dist/admin/components/MediaLibraryInput/AssetCard.js.map +1 -0
- package/dist/admin/components/MediaLibraryInput/AssetCard.mjs +237 -0
- package/dist/admin/components/MediaLibraryInput/AssetCard.mjs.map +1 -0
- package/dist/admin/components/MediaLibraryInput/AssetCarousel.js +161 -0
- package/dist/admin/components/MediaLibraryInput/AssetCarousel.js.map +1 -0
- package/dist/admin/components/MediaLibraryInput/AssetCarousel.mjs +159 -0
- package/dist/admin/components/MediaLibraryInput/AssetCarousel.mjs.map +1 -0
- package/dist/admin/components/MediaLibraryInput/AssetDropZone.js +76 -49
- package/dist/admin/components/MediaLibraryInput/AssetDropZone.js.map +1 -1
- package/dist/admin/components/MediaLibraryInput/AssetDropZone.mjs +77 -50
- package/dist/admin/components/MediaLibraryInput/AssetDropZone.mjs.map +1 -1
- package/dist/admin/components/MediaLibraryInput/AssetPreview.js +109 -0
- package/dist/admin/components/MediaLibraryInput/AssetPreview.js.map +1 -0
- package/dist/admin/components/MediaLibraryInput/AssetPreview.mjs +106 -0
- package/dist/admin/components/MediaLibraryInput/AssetPreview.mjs.map +1 -0
- package/dist/admin/components/MediaLibraryInput/AssetRow.js +146 -79
- package/dist/admin/components/MediaLibraryInput/AssetRow.js.map +1 -1
- package/dist/admin/components/MediaLibraryInput/AssetRow.mjs +148 -82
- package/dist/admin/components/MediaLibraryInput/AssetRow.mjs.map +1 -1
- package/dist/admin/components/MediaLibraryInput/FieldControls.js +32 -0
- package/dist/admin/components/MediaLibraryInput/FieldControls.js.map +1 -0
- package/dist/admin/components/MediaLibraryInput/FieldControls.mjs +29 -0
- package/dist/admin/components/MediaLibraryInput/FieldControls.mjs.map +1 -0
- package/dist/admin/components/MediaLibraryInput/MediaLibraryInput.js +163 -111
- package/dist/admin/components/MediaLibraryInput/MediaLibraryInput.js.map +1 -1
- package/dist/admin/components/MediaLibraryInput/MediaLibraryInput.mjs +162 -114
- package/dist/admin/components/MediaLibraryInput/MediaLibraryInput.mjs.map +1 -1
- package/dist/admin/components/MediaLibraryInput/UploadProgressBar.js +42 -0
- package/dist/admin/components/MediaLibraryInput/UploadProgressBar.js.map +1 -0
- package/dist/admin/components/MediaLibraryInput/UploadProgressBar.mjs +40 -0
- package/dist/admin/components/MediaLibraryInput/UploadProgressBar.mjs.map +1 -0
- package/dist/admin/components/MediaLibraryInput/openAssetDetails.js +46 -0
- package/dist/admin/components/MediaLibraryInput/openAssetDetails.js.map +1 -0
- package/dist/admin/components/MediaLibraryInput/openAssetDetails.mjs +43 -0
- package/dist/admin/components/MediaLibraryInput/openAssetDetails.mjs.map +1 -0
- package/dist/admin/components/MediaLibraryInput/useFieldUploads.js +122 -0
- package/dist/admin/components/MediaLibraryInput/useFieldUploads.js.map +1 -0
- package/dist/admin/components/MediaLibraryInput/useFieldUploads.mjs +120 -0
- package/dist/admin/components/MediaLibraryInput/useFieldUploads.mjs.map +1 -0
- package/dist/admin/components/UploadProgressDialog.js +2 -1
- package/dist/admin/components/UploadProgressDialog.js.map +1 -1
- package/dist/admin/components/UploadProgressDialog.mjs +2 -1
- package/dist/admin/components/UploadProgressDialog.mjs.map +1 -1
- package/dist/admin/hooks/useMediaLibraryPermissions.js +12 -2
- package/dist/admin/hooks/useMediaLibraryPermissions.js.map +1 -1
- package/dist/admin/hooks/useMediaLibraryPermissions.mjs +12 -2
- package/dist/admin/hooks/useMediaLibraryPermissions.mjs.map +1 -1
- package/dist/admin/index.js +10 -1
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/index.mjs +10 -1
- package/dist/admin/index.mjs.map +1 -1
- package/dist/admin/pages/Assets/AssetsPage.js +14 -303
- package/dist/admin/pages/Assets/AssetsPage.js.map +1 -1
- package/dist/admin/pages/Assets/AssetsPage.mjs +13 -282
- package/dist/admin/pages/Assets/AssetsPage.mjs.map +1 -1
- package/dist/admin/pages/Assets/components/AssetDetails/AssetCropEditor.mjs +2 -2
- package/dist/admin/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js +181 -65
- package/dist/admin/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js.map +1 -1
- package/dist/admin/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs +184 -69
- package/dist/admin/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs.map +1 -1
- package/dist/admin/pages/Assets/components/AssetDetails/AssetPreview.mjs +1 -1
- package/dist/admin/pages/Assets/components/AssetsGrid.js +142 -31
- package/dist/admin/pages/Assets/components/AssetsGrid.js.map +1 -1
- package/dist/admin/pages/Assets/components/AssetsGrid.mjs +145 -34
- package/dist/admin/pages/Assets/components/AssetsGrid.mjs.map +1 -1
- package/dist/admin/pages/Assets/components/AssetsSearchInput.js +43 -2
- package/dist/admin/pages/Assets/components/AssetsSearchInput.js.map +1 -1
- package/dist/admin/pages/Assets/components/AssetsSearchInput.mjs +45 -4
- package/dist/admin/pages/Assets/components/AssetsSearchInput.mjs.map +1 -1
- package/dist/admin/pages/Assets/components/AssetsTable.js +58 -34
- package/dist/admin/pages/Assets/components/AssetsTable.js.map +1 -1
- package/dist/admin/pages/Assets/components/AssetsTable.mjs +60 -36
- package/dist/admin/pages/Assets/components/AssetsTable.mjs.map +1 -1
- package/dist/admin/pages/Assets/components/AssetsView.js +145 -0
- package/dist/admin/pages/Assets/components/AssetsView.js.map +1 -0
- package/dist/admin/pages/Assets/components/AssetsView.mjs +143 -0
- package/dist/admin/pages/Assets/components/AssetsView.mjs.map +1 -0
- package/dist/admin/pages/Assets/components/BulkActionsBar.mjs +1 -1
- package/dist/admin/pages/Assets/components/BusyOverlay.mjs +1 -1
- package/dist/admin/pages/Assets/components/Dnd/DragOverlayChip.mjs +1 -1
- package/dist/admin/pages/Assets/components/Dnd/ReorderHandle.js +40 -0
- package/dist/admin/pages/Assets/components/Dnd/ReorderHandle.js.map +1 -0
- package/dist/admin/pages/Assets/components/Dnd/ReorderHandle.mjs +38 -0
- package/dist/admin/pages/Assets/components/Dnd/ReorderHandle.mjs.map +1 -0
- package/dist/admin/pages/Assets/components/Dnd/assetSortable.js +29 -0
- package/dist/admin/pages/Assets/components/Dnd/assetSortable.js.map +1 -0
- package/dist/admin/pages/Assets/components/Dnd/assetSortable.mjs +24 -0
- package/dist/admin/pages/Assets/components/Dnd/assetSortable.mjs.map +1 -0
- package/dist/admin/pages/Assets/components/Dnd/dndIds.js +5 -0
- package/dist/admin/pages/Assets/components/Dnd/dndIds.js.map +1 -1
- package/dist/admin/pages/Assets/components/Dnd/dndIds.mjs +5 -1
- package/dist/admin/pages/Assets/components/Dnd/dndIds.mjs.map +1 -1
- package/dist/admin/pages/Assets/components/Dnd/useAssetDnd.js +41 -13
- package/dist/admin/pages/Assets/components/Dnd/useAssetDnd.js.map +1 -1
- package/dist/admin/pages/Assets/components/Dnd/useAssetDnd.mjs +41 -13
- package/dist/admin/pages/Assets/components/Dnd/useAssetDnd.mjs.map +1 -1
- package/dist/admin/pages/Assets/components/FilterBadges.mjs +2 -2
- package/dist/admin/pages/Assets/components/FilterMenu.mjs +2 -2
- package/dist/admin/pages/Assets/components/FolderTree/FolderTree.js +274 -55
- package/dist/admin/pages/Assets/components/FolderTree/FolderTree.js.map +1 -1
- package/dist/admin/pages/Assets/components/FolderTree/FolderTree.mjs +277 -59
- package/dist/admin/pages/Assets/components/FolderTree/FolderTree.mjs.map +1 -1
- package/dist/admin/pages/Assets/components/FolderTree/collapsedBranch.js +32 -0
- package/dist/admin/pages/Assets/components/FolderTree/collapsedBranch.js.map +1 -0
- package/dist/admin/pages/Assets/components/FolderTree/collapsedBranch.mjs +29 -0
- package/dist/admin/pages/Assets/components/FolderTree/collapsedBranch.mjs.map +1 -0
- package/dist/admin/pages/Assets/components/ViewToggle.js +126 -0
- package/dist/admin/pages/Assets/components/ViewToggle.js.map +1 -0
- package/dist/admin/pages/Assets/components/ViewToggle.mjs +104 -0
- package/dist/admin/pages/Assets/components/ViewToggle.mjs.map +1 -0
- package/dist/admin/pages/Assets/hooks/useAssetSearch.js +2 -2
- package/dist/admin/pages/Assets/hooks/useAssetSearch.js.map +1 -1
- package/dist/admin/pages/Assets/hooks/useAssetSearch.mjs +2 -2
- package/dist/admin/pages/Assets/hooks/useAssetSearch.mjs.map +1 -1
- package/dist/admin/pages/Assets/hooks/useAssetSelection.js +19 -1
- package/dist/admin/pages/Assets/hooks/useAssetSelection.js.map +1 -1
- package/dist/admin/pages/Assets/hooks/useAssetSelection.mjs +20 -3
- package/dist/admin/pages/Assets/hooks/useAssetSelection.mjs.map +1 -1
- package/dist/admin/pages/Assets/hooks/useAssetsList.js +87 -0
- package/dist/admin/pages/Assets/hooks/useAssetsList.js.map +1 -0
- package/dist/admin/pages/Assets/hooks/useAssetsList.mjs +85 -0
- package/dist/admin/pages/Assets/hooks/useAssetsList.mjs.map +1 -0
- package/dist/admin/pages/Assets/hooks/useBusyAssets.mjs +1 -1
- package/dist/admin/pages/Assets/hooks/useFolderNavigation.js +2 -1
- package/dist/admin/pages/Assets/hooks/useFolderNavigation.js.map +1 -1
- package/dist/admin/pages/Assets/hooks/useFolderNavigation.mjs +3 -2
- package/dist/admin/pages/Assets/hooks/useFolderNavigation.mjs.map +1 -1
- package/dist/admin/pages/Assets/hooks/useIsAssetDetailsOpen.js +2 -6
- package/dist/admin/pages/Assets/hooks/useIsAssetDetailsOpen.js.map +1 -1
- package/dist/admin/pages/Assets/hooks/useIsAssetDetailsOpen.mjs +2 -6
- package/dist/admin/pages/Assets/hooks/useIsAssetDetailsOpen.mjs.map +1 -1
- package/dist/admin/pages/Assets/hooks/useListFilters.js +2 -1
- package/dist/admin/pages/Assets/hooks/useListFilters.js.map +1 -1
- package/dist/admin/pages/Assets/hooks/useListFilters.mjs +3 -2
- package/dist/admin/pages/Assets/hooks/useListFilters.mjs.map +1 -1
- package/dist/admin/pages/Assets/hooks/useListQueryParams.js +80 -0
- package/dist/admin/pages/Assets/hooks/useListQueryParams.js.map +1 -0
- package/dist/admin/pages/Assets/hooks/useListQueryParams.mjs +77 -0
- package/dist/admin/pages/Assets/hooks/useListQueryParams.mjs.map +1 -0
- package/dist/admin/pages/Assets/hooks/useListSettings.js +32 -0
- package/dist/admin/pages/Assets/hooks/useListSettings.js.map +1 -0
- package/dist/admin/pages/Assets/hooks/useListSettings.mjs +29 -0
- package/dist/admin/pages/Assets/hooks/useListSettings.mjs.map +1 -0
- package/dist/admin/pages/Assets/hooks/useListSort.js +2 -1
- package/dist/admin/pages/Assets/hooks/useListSort.js.map +1 -1
- package/dist/admin/pages/Assets/hooks/useListSort.mjs +3 -2
- package/dist/admin/pages/Assets/hooks/useListSort.mjs.map +1 -1
- package/dist/admin/services/api.js +92 -7
- package/dist/admin/services/api.js.map +1 -1
- package/dist/admin/services/api.mjs +91 -9
- package/dist/admin/services/api.mjs.map +1 -1
- package/dist/admin/src/components/AssetPickerDialog/AssetPickerDialog.d.ts +19 -0
- package/dist/admin/src/components/AssetPickerDialog/FolderBreadcrumbs.d.ts +10 -0
- package/dist/admin/src/components/AssetPickerDialog/MediaLibraryPickerDialog.d.ts +19 -0
- package/dist/admin/src/components/AssetPickerDialog/PickerSelectionProvider.d.ts +28 -0
- package/dist/admin/src/components/AssetPickerDialog/SortableSelection.d.ts +12 -0
- package/dist/admin/src/components/AssetPickerDialog/pickerSelection.d.ts +26 -0
- package/dist/admin/src/components/Drawer.d.ts +8 -0
- package/dist/admin/src/components/EditorFileDropZone/EditorFileDropZone.d.ts +21 -0
- package/dist/admin/src/components/MediaLibraryInput/AddAssetMenu.d.ts +7 -1
- package/dist/admin/src/components/MediaLibraryInput/AssetCard.d.ts +25 -0
- package/dist/admin/src/components/MediaLibraryInput/AssetCarousel.d.ts +16 -0
- package/dist/admin/src/components/MediaLibraryInput/AssetDropZone.d.ts +11 -3
- package/dist/admin/src/components/MediaLibraryInput/AssetPreview.d.ts +17 -0
- package/dist/admin/src/components/MediaLibraryInput/AssetRow.d.ts +13 -3
- package/dist/admin/src/components/MediaLibraryInput/FieldControls.d.ts +19 -0
- package/dist/admin/src/components/MediaLibraryInput/MediaLibraryInput.d.ts +3 -1
- package/dist/admin/src/components/MediaLibraryInput/UploadProgressBar.d.ts +7 -0
- package/dist/admin/src/components/MediaLibraryInput/openAssetDetails.d.ts +10 -0
- package/dist/admin/src/components/MediaLibraryInput/useFieldUploads.d.ts +31 -0
- package/dist/admin/src/hooks/useMediaLibraryPermissions.d.ts +2 -0
- package/dist/admin/src/pages/Assets/components/AssetDetails/AssetDetailsDrawer.d.ts +41 -5
- package/dist/admin/src/pages/Assets/components/AssetsGrid.d.ts +3 -1
- package/dist/admin/src/pages/Assets/components/AssetsSearchInput.d.ts +11 -1
- package/dist/admin/src/pages/Assets/components/AssetsView.d.ts +29 -0
- package/dist/admin/src/pages/Assets/components/Dnd/ReorderHandle.d.ts +12 -0
- package/dist/admin/src/pages/Assets/components/Dnd/assetSortable.d.ts +37 -0
- package/dist/admin/src/pages/Assets/components/Dnd/dndIds.d.ts +5 -0
- package/dist/admin/src/pages/Assets/components/Dnd/useAssetDnd.d.ts +23 -2
- package/dist/admin/src/pages/Assets/components/FolderTree/FolderTree.d.ts +1 -0
- package/dist/admin/src/pages/Assets/components/FolderTree/collapsedBranch.d.ts +21 -0
- package/dist/admin/src/pages/Assets/components/ViewToggle.d.ts +8 -0
- package/dist/admin/src/pages/Assets/hooks/useAssetSelection.d.ts +26 -0
- package/dist/admin/src/pages/Assets/hooks/useAssetsList.d.ts +30 -0
- package/dist/admin/src/pages/Assets/hooks/useIsAssetDetailsOpen.d.ts +2 -6
- package/dist/admin/src/pages/Assets/hooks/useListQueryParams.d.ts +27 -0
- package/dist/admin/src/pages/Assets/hooks/useListSettings.d.ts +29 -0
- package/dist/admin/src/services/api.d.ts +24 -1
- package/dist/admin/src/store/uploadProgress.d.ts +14 -1
- package/dist/admin/src/utils/findFolderPath.d.ts +6 -0
- package/dist/admin/src/utils/isAllowedAssetType.d.ts +14 -0
- package/dist/admin/store/uploadProgress.js +30 -3
- package/dist/admin/store/uploadProgress.js.map +1 -1
- package/dist/admin/store/uploadProgress.mjs +29 -4
- package/dist/admin/store/uploadProgress.mjs.map +1 -1
- package/dist/admin/translations/en.json.js +24 -0
- package/dist/admin/translations/en.json.js.map +1 -1
- package/dist/admin/translations/en.json.mjs +24 -0
- package/dist/admin/translations/en.json.mjs.map +1 -1
- package/dist/admin/utils/findFolderPath.js +26 -0
- package/dist/admin/utils/findFolderPath.js.map +1 -0
- package/dist/admin/utils/findFolderPath.mjs +24 -0
- package/dist/admin/utils/findFolderPath.mjs.map +1 -0
- package/dist/admin/utils/isAllowedAssetType.js +33 -0
- package/dist/admin/utils/isAllowedAssetType.js.map +1 -0
- package/dist/admin/utils/isAllowedAssetType.mjs +31 -0
- package/dist/admin/utils/isAllowedAssetType.mjs.map +1 -0
- package/dist/server/audit-logs.js +264 -0
- package/dist/server/audit-logs.js.map +1 -0
- package/dist/server/audit-logs.mjs +255 -0
- package/dist/server/audit-logs.mjs.map +1 -0
- package/dist/server/bootstrap.js +4 -0
- package/dist/server/bootstrap.js.map +1 -1
- package/dist/server/bootstrap.mjs +4 -0
- package/dist/server/bootstrap.mjs.map +1 -1
- package/dist/server/controllers/admin-folder-file.js +23 -1
- package/dist/server/controllers/admin-folder-file.js.map +1 -1
- package/dist/server/controllers/admin-folder-file.mjs +23 -1
- package/dist/server/controllers/admin-folder-file.mjs.map +1 -1
- package/dist/server/controllers/admin-settings.js +5 -1
- package/dist/server/controllers/admin-settings.js.map +1 -1
- package/dist/server/controllers/admin-settings.mjs +5 -1
- package/dist/server/controllers/admin-settings.mjs.map +1 -1
- package/dist/server/services/folder.js +48 -1
- package/dist/server/services/folder.js.map +1 -1
- package/dist/server/services/folder.mjs +48 -1
- package/dist/server/services/folder.mjs.map +1 -1
- package/dist/server/services/image-manipulation.js +14 -7
- package/dist/server/services/image-manipulation.js.map +1 -1
- package/dist/server/services/image-manipulation.mjs +14 -7
- package/dist/server/services/image-manipulation.mjs.map +1 -1
- package/dist/server/services/upload.js +100 -16
- package/dist/server/services/upload.js.map +1 -1
- package/dist/server/services/upload.mjs +102 -18
- package/dist/server/services/upload.mjs.map +1 -1
- package/dist/server/src/audit-logs.d.ts +142 -0
- package/dist/server/src/audit-logs.d.ts.map +1 -0
- package/dist/server/src/bootstrap.d.ts.map +1 -1
- package/dist/server/src/controllers/admin-folder-file.d.ts.map +1 -1
- package/dist/server/src/controllers/admin-settings.d.ts.map +1 -1
- package/dist/server/src/index.d.ts +4 -4
- package/dist/server/src/index.d.ts.map +1 -1
- package/dist/server/src/mcp/ambient-instance.d.ts.map +1 -1
- package/dist/server/src/services/extensions/utils.d.ts +11 -11
- package/dist/server/src/services/folder.d.ts.map +1 -1
- package/dist/server/src/services/image-manipulation.d.ts +4 -4
- package/dist/server/src/services/image-manipulation.d.ts.map +1 -1
- package/dist/server/src/services/index.d.ts +4 -4
- package/dist/server/src/services/index.d.ts.map +1 -1
- package/dist/server/src/services/upload.d.ts.map +1 -1
- package/dist/server/src/types.d.ts +63 -12
- package/dist/server/src/types.d.ts.map +1 -1
- package/package.json +11 -16
- package/dist/admin/components/MediaLibraryInput/NoLibraryAccessDialog.js +0 -45
- package/dist/admin/components/MediaLibraryInput/NoLibraryAccessDialog.js.map +0 -1
- package/dist/admin/components/MediaLibraryInput/NoLibraryAccessDialog.mjs +0 -43
- package/dist/admin/components/MediaLibraryInput/NoLibraryAccessDialog.mjs.map +0 -1
- package/dist/admin/src/components/MediaLibraryInput/NoLibraryAccessDialog.d.ts +0 -10
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AssetCard.mjs","sources":["../../../../admin/src/components/MediaLibraryInput/AssetCard.tsx"],"sourcesContent":["import { Badge, Box, Flex, IconButton, Menu, Typography } from '@strapi/design-system';\nimport { ArrowClockwise, Cross, Link, More, Pencil, Trash } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { styled } from 'styled-components';\n\nimport { getTranslationKey } from '../../utils/translations';\n\nimport { AssetPreview, UploadPreview } from './AssetPreview';\nimport { FieldMenuItem, GhostIconButton } from './FieldControls';\nimport { UploadProgressBar } from './UploadProgressBar';\n\nimport type { FieldUpload } from './useFieldUploads';\nimport type { File } from '../../../../shared/contracts/files';\n\ntype CardTone = 'neutral' | 'primary' | 'danger';\n\nconst CARD_COLORS = {\n neutral: { background: 'neutral0', border: 'neutral200' },\n primary: { background: 'primary100', border: 'primary200' },\n danger: { background: 'danger100', border: 'danger200' },\n} as const;\n\nconst Card = styled(Flex)<{ $tone: CardTone }>`\n position: relative;\n min-width: 0;\n overflow: hidden;\n background: ${({ theme, $tone }) => theme.colors[CARD_COLORS[$tone].background]};\n border: 1px solid ${({ theme, $tone }) => theme.colors[CARD_COLORS[$tone].border]};\n border-radius: ${({ theme }) => theme.borderRadius};\n`;\n\nconst Name = styled(Typography)`\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n`;\n\nconst PreviewOverlay = styled(Box)`\n position: absolute;\n inset: auto 0 0 0;\n`;\n\nconst DangerIconButton = styled(IconButton)`\n color: ${({ theme }) => theme.colors.danger600};\n background: ${({ theme }) => theme.colors.danger100};\n border-color: ${({ theme }) => theme.colors.danger200};\n\n svg path {\n fill: currentColor;\n }\n`;\n\ninterface CardFrameProps {\n tone: CardTone;\n preview: React.ReactNode;\n overlay?: React.ReactNode;\n name: React.ReactNode;\n actions: React.ReactNode;\n}\n\nconst CardFrame = ({ tone, preview, overlay, name, actions }: CardFrameProps) => (\n <Card $tone={tone} direction=\"column\" alignItems=\"stretch\">\n <Box position=\"relative\">\n {preview}\n {overlay}\n </Box>\n <Flex\n gap={3}\n paddingLeft={3}\n paddingRight={2}\n paddingTop={2}\n paddingBottom={2}\n minHeight=\"4.8rem\"\n >\n {name}\n <Flex gap={1} shrink={0} marginLeft=\"auto\">\n {actions}\n </Flex>\n </Flex>\n </Card>\n);\n\ninterface AssetCardProps {\n asset: File;\n disabled?: boolean;\n onCopyLink: (asset: File) => void;\n onEdit?: (asset: File) => void;\n onRemove: (asset: File) => void;\n}\n\n/**\n * An asset a multiple-value field holds.\n */\nexport const AssetCard = ({\n asset,\n disabled = false,\n onCopyLink,\n onEdit,\n onRemove,\n}: AssetCardProps) => {\n const { formatMessage } = useIntl();\n\n return (\n <CardFrame\n tone=\"neutral\"\n preview={<AssetPreview asset={asset} size=\"L\" />}\n name={<Name textColor=\"neutral800\">{asset.name}</Name>}\n actions={\n <Menu.Root modal={false}>\n <Menu.Trigger\n tag={IconButton}\n icon={<More />}\n variant=\"ghost\"\n label={formatMessage(\n {\n id: getTranslationKey('content-manager.input.actions.more'),\n defaultMessage: 'More actions for {name}',\n },\n { name: asset.name }\n )}\n />\n <Menu.Content popoverPlacement=\"bottom-end\">\n <FieldMenuItem startIcon={<Link />} onSelect={() => onCopyLink(asset)}>\n {formatMessage({\n id: getTranslationKey('asset-details.copy-link.trigger'),\n defaultMessage: 'Copy link',\n })}\n </FieldMenuItem>\n {onEdit && (\n <FieldMenuItem\n startIcon={<Pencil />}\n disabled={disabled}\n onSelect={() => onEdit(asset)}\n >\n {formatMessage({\n id: getTranslationKey('control-card.edit'),\n defaultMessage: 'Edit',\n })}\n </FieldMenuItem>\n )}\n <FieldMenuItem\n variant=\"danger\"\n startIcon={<Trash />}\n disabled={disabled}\n onSelect={() => onRemove(asset)}\n >\n {formatMessage({\n id: getTranslationKey('content-manager.input.actions.remove-failed'),\n defaultMessage: 'Remove',\n })}\n </FieldMenuItem>\n </Menu.Content>\n </Menu.Root>\n }\n />\n );\n};\n\ninterface UploadCardProps {\n upload: FieldUpload;\n disabled?: boolean;\n onCancel: (upload: FieldUpload) => void;\n onRetry: (upload: FieldUpload) => void;\n onRemove: (upload: FieldUpload) => void;\n}\n\n/**\n * A file a multiple-value field is uploading, or failed to upload.\n */\nexport const UploadCard = ({\n upload,\n disabled = false,\n onCancel,\n onRetry,\n onRemove,\n}: UploadCardProps) => {\n const { formatMessage } = useIntl();\n const preview = <UploadPreview file={upload.sourceFile} size=\"L\" />;\n\n if (upload.status === 'failed') {\n const canRetry = upload.isInStore || upload.sourceFile !== undefined;\n\n return (\n <CardFrame\n tone=\"danger\"\n preview={preview}\n name={<Name textColor=\"danger600\">{upload.name}</Name>}\n actions={\n <>\n {canRetry && (\n <GhostIconButton\n disabled={disabled}\n onClick={() => onRetry(upload)}\n label={formatMessage(\n {\n id: getTranslationKey('content-manager.input.actions.retry'),\n defaultMessage: 'Retry uploading {name}',\n },\n { name: upload.name }\n )}\n >\n <ArrowClockwise />\n </GhostIconButton>\n )}\n <DangerIconButton\n disabled={disabled}\n onClick={() => onRemove(upload)}\n label={formatMessage(\n {\n id: getTranslationKey('content-manager.input.actions.remove'),\n defaultMessage: 'Remove {name}',\n },\n { name: upload.name }\n )}\n >\n <Trash />\n </DangerIconButton>\n </>\n }\n />\n );\n }\n\n const uploadingLabel = formatMessage({\n id: getTranslationKey('content-manager.input.status.uploading'),\n defaultMessage: 'Uploading',\n });\n\n return (\n <CardFrame\n tone=\"primary\"\n preview={preview}\n overlay={\n <>\n <Box position=\"absolute\" top={2} left={2}>\n <Badge backgroundColor=\"primary100\" textColor=\"primary600\">\n {uploadingLabel}\n </Badge>\n </Box>\n <PreviewOverlay>\n <UploadProgressBar progress={upload.progress} label={uploadingLabel} />\n </PreviewOverlay>\n </>\n }\n name={<Name textColor=\"neutral800\">{upload.name}</Name>}\n actions={\n <GhostIconButton\n onClick={() => onCancel(upload)}\n label={formatMessage(\n {\n id: getTranslationKey('content-manager.input.actions.cancel'),\n defaultMessage: 'Cancel upload of {name}',\n },\n { name: upload.name }\n )}\n >\n <Cross />\n </GhostIconButton>\n }\n />\n );\n};\n"],"names":["CARD_COLORS","neutral","background","border","primary","danger","Card","styled","Flex","theme","$tone","colors","borderRadius","Name","Typography","PreviewOverlay","Box","DangerIconButton","IconButton","danger600","danger100","danger200","CardFrame","tone","preview","overlay","name","actions","_jsxs","direction","alignItems","position","gap","paddingLeft","paddingRight","paddingTop","paddingBottom","minHeight","_jsx","shrink","marginLeft","AssetCard","asset","disabled","onCopyLink","onEdit","onRemove","formatMessage","useIntl","AssetPreview","size","textColor","Menu","Root","modal","Trigger","tag","icon","More","variant","label","id","getTranslationKey","defaultMessage","Content","popoverPlacement","FieldMenuItem","startIcon","Link","onSelect","Pencil","Trash","UploadCard","upload","onCancel","onRetry","UploadPreview","file","sourceFile","status","canRetry","isInStore","undefined","_Fragment","GhostIconButton","onClick","ArrowClockwise","uploadingLabel","top","left","Badge","backgroundColor","UploadProgressBar","progress","Cross"],"mappings":"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"}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
var React = require('react');
|
|
5
|
+
var strapiAdmin = require('@strapi/admin/strapi-admin');
|
|
6
|
+
var designSystem = require('@strapi/design-system');
|
|
7
|
+
var icons = require('@strapi/icons');
|
|
8
|
+
var reactIntl = require('react-intl');
|
|
9
|
+
var styledComponents = require('styled-components');
|
|
10
|
+
var translations = require('../../utils/translations.js');
|
|
11
|
+
|
|
12
|
+
/** Narrowest a card and the tile get side by side before stacking, in px. */ const MIN_CARD_WIDTH = 130;
|
|
13
|
+
/**
|
|
14
|
+
* Narrowest a card gets when two share the row, in px. Wider than the single
|
|
15
|
+
* card's, so the row drops to one card before names are cut to a few letters.
|
|
16
|
+
*/ const MIN_CARD_WIDTH_FOR_TWO = 180;
|
|
17
|
+
const GAP = 16;
|
|
18
|
+
const MAX_CARDS = 2;
|
|
19
|
+
const Container = styledComponents.styled(designSystem.Box)`
|
|
20
|
+
background: ${({ theme })=>theme.colors.neutral100};
|
|
21
|
+
border: 1px solid ${({ theme })=>theme.colors.neutral200};
|
|
22
|
+
border-radius: ${({ theme })=>theme.borderRadius};
|
|
23
|
+
`;
|
|
24
|
+
const Track = styledComponents.styled.div`
|
|
25
|
+
display: grid;
|
|
26
|
+
grid-template-columns: repeat(${({ $columns })=>$columns}, minmax(0, 1fr));
|
|
27
|
+
gap: ${GAP}px;
|
|
28
|
+
`;
|
|
29
|
+
const Cards = styledComponents.styled.div`
|
|
30
|
+
position: relative;
|
|
31
|
+
display: grid;
|
|
32
|
+
grid-column: span ${({ $columns })=>$columns};
|
|
33
|
+
grid-template-columns: repeat(${({ $columns })=>$columns}, minmax(0, 1fr));
|
|
34
|
+
gap: ${GAP}px;
|
|
35
|
+
`;
|
|
36
|
+
const Arrow = styledComponents.styled(designSystem.Box)`
|
|
37
|
+
position: absolute;
|
|
38
|
+
top: 50%;
|
|
39
|
+
transform: translateY(-50%);
|
|
40
|
+
z-index: 1;
|
|
41
|
+
${({ $side })=>$side === 'start' ? 'left: -1.6rem;' : 'right: -1.6rem;'}
|
|
42
|
+
|
|
43
|
+
button {
|
|
44
|
+
border-radius: 50%;
|
|
45
|
+
box-shadow: ${({ theme })=>theme.shadows.filterShadow};
|
|
46
|
+
}
|
|
47
|
+
`;
|
|
48
|
+
/**
|
|
49
|
+
* How the row fits the field. The edit layout's size sets it: a third of the
|
|
50
|
+
* form stacks one card over the drop zone, a full-width field shows two cards
|
|
51
|
+
* beside it, anything in between one. Mobile always shows one card, stacked on
|
|
52
|
+
* a phone. The measured width can only take cards away, for a field squeezed
|
|
53
|
+
* by a narrow component.
|
|
54
|
+
*/ const getRowLayout = ({ width, layoutSize, isMobile, isPhone })=>{
|
|
55
|
+
const isNarrowLayout = isPhone || layoutSize !== undefined && layoutSize <= 4;
|
|
56
|
+
const maxCards = isMobile || layoutSize !== undefined && layoutSize < 12 ? 1 : MAX_CARDS;
|
|
57
|
+
// Unmeasured: no layout yet, or no `ResizeObserver`.
|
|
58
|
+
const isMeasured = width > 0;
|
|
59
|
+
const fitsCardAndTile = !isMeasured || width >= 2 * MIN_CARD_WIDTH + GAP;
|
|
60
|
+
const fitsTwoCardsAndTile = !isMeasured || width >= 3 * MIN_CARD_WIDTH_FOR_TWO + 2 * GAP;
|
|
61
|
+
if (isNarrowLayout || !fitsCardAndTile) {
|
|
62
|
+
return {
|
|
63
|
+
cards: 1,
|
|
64
|
+
isStacked: true
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
return {
|
|
68
|
+
cards: fitsTwoCardsAndTile ? maxCards : 1,
|
|
69
|
+
isStacked: false
|
|
70
|
+
};
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* A single row of cards followed by the drop tile. When the field holds more
|
|
74
|
+
* than fit, arrows page through the cards and the tile stays put.
|
|
75
|
+
*/ const AssetCarousel = ({ children, renderDropZone, layoutSize })=>{
|
|
76
|
+
const { formatMessage } = reactIntl.useIntl();
|
|
77
|
+
const theme = styledComponents.useTheme();
|
|
78
|
+
const isMobile = strapiAdmin.useIsMobile();
|
|
79
|
+
const isPhone = !strapiAdmin.useMediaQuery(theme.breakpoints.small);
|
|
80
|
+
const trackRef = React.useRef(null);
|
|
81
|
+
const [width, setWidth] = React.useState(0);
|
|
82
|
+
const [start, setStart] = React.useState(0);
|
|
83
|
+
const cards = React.Children.toArray(children);
|
|
84
|
+
const { cards: cardsPerRow, isStacked } = getRowLayout({
|
|
85
|
+
width,
|
|
86
|
+
layoutSize,
|
|
87
|
+
isMobile,
|
|
88
|
+
isPhone
|
|
89
|
+
});
|
|
90
|
+
const maxStart = Math.max(cards.length - cardsPerRow, 0);
|
|
91
|
+
const firstVisible = Math.min(start, maxStart);
|
|
92
|
+
// Fewer cards than fit leave the tile right after them, not at the far end.
|
|
93
|
+
const visibleCount = Math.min(cards.length, cardsPerRow);
|
|
94
|
+
React.useLayoutEffect(()=>{
|
|
95
|
+
const track = trackRef.current;
|
|
96
|
+
if (!track || typeof ResizeObserver === 'undefined') {
|
|
97
|
+
return undefined;
|
|
98
|
+
}
|
|
99
|
+
const observer = new ResizeObserver(([entry])=>setWidth(entry.contentRect.width));
|
|
100
|
+
observer.observe(track);
|
|
101
|
+
return ()=>observer.disconnect();
|
|
102
|
+
}, []);
|
|
103
|
+
// A card added at the end (a new upload) is scrolled into view.
|
|
104
|
+
const previousCount = React.useRef(cards.length);
|
|
105
|
+
React.useEffect(()=>{
|
|
106
|
+
if (cards.length > previousCount.current) {
|
|
107
|
+
setStart(maxStart);
|
|
108
|
+
}
|
|
109
|
+
previousCount.current = cards.length;
|
|
110
|
+
}, [
|
|
111
|
+
cards.length,
|
|
112
|
+
maxStart
|
|
113
|
+
]);
|
|
114
|
+
return /*#__PURE__*/ jsxRuntime.jsxs(Container, {
|
|
115
|
+
padding: 4,
|
|
116
|
+
children: [
|
|
117
|
+
/*#__PURE__*/ jsxRuntime.jsxs(Track, {
|
|
118
|
+
ref: trackRef,
|
|
119
|
+
$columns: isStacked ? 1 : cardsPerRow + 1,
|
|
120
|
+
children: [
|
|
121
|
+
/*#__PURE__*/ jsxRuntime.jsxs(Cards, {
|
|
122
|
+
$columns: visibleCount,
|
|
123
|
+
children: [
|
|
124
|
+
cards.slice(firstVisible, firstVisible + cardsPerRow),
|
|
125
|
+
firstVisible > 0 && /*#__PURE__*/ jsxRuntime.jsx(Arrow, {
|
|
126
|
+
$side: "start",
|
|
127
|
+
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.IconButton, {
|
|
128
|
+
onClick: ()=>setStart(firstVisible - 1),
|
|
129
|
+
label: formatMessage({
|
|
130
|
+
id: translations.getTranslationKey('mediaLibraryInput.actions.previousSlide'),
|
|
131
|
+
defaultMessage: 'Previous slide'
|
|
132
|
+
}),
|
|
133
|
+
children: /*#__PURE__*/ jsxRuntime.jsx(icons.ChevronLeft, {})
|
|
134
|
+
})
|
|
135
|
+
}),
|
|
136
|
+
firstVisible < maxStart && /*#__PURE__*/ jsxRuntime.jsx(Arrow, {
|
|
137
|
+
$side: "end",
|
|
138
|
+
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.IconButton, {
|
|
139
|
+
onClick: ()=>setStart(firstVisible + 1),
|
|
140
|
+
label: formatMessage({
|
|
141
|
+
id: translations.getTranslationKey('mediaLibraryInput.actions.nextSlide'),
|
|
142
|
+
defaultMessage: 'Next slide'
|
|
143
|
+
}),
|
|
144
|
+
children: /*#__PURE__*/ jsxRuntime.jsx(icons.ChevronRight, {})
|
|
145
|
+
})
|
|
146
|
+
})
|
|
147
|
+
]
|
|
148
|
+
}),
|
|
149
|
+
!isStacked && renderDropZone('tile')
|
|
150
|
+
]
|
|
151
|
+
}),
|
|
152
|
+
isStacked && /*#__PURE__*/ jsxRuntime.jsx(designSystem.Box, {
|
|
153
|
+
paddingTop: 4,
|
|
154
|
+
children: renderDropZone('stacked')
|
|
155
|
+
})
|
|
156
|
+
]
|
|
157
|
+
});
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
exports.AssetCarousel = AssetCarousel;
|
|
161
|
+
//# sourceMappingURL=AssetCarousel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AssetCarousel.js","sources":["../../../../admin/src/components/MediaLibraryInput/AssetCarousel.tsx"],"sourcesContent":["import { Children, useEffect, useLayoutEffect, useRef, useState, type ReactNode } from 'react';\n\nimport { useIsMobile, useMediaQuery } from '@strapi/admin/strapi-admin';\nimport { Box, IconButton } from '@strapi/design-system';\nimport { ChevronLeft, ChevronRight } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { styled, useTheme } from 'styled-components';\n\nimport { getTranslationKey } from '../../utils/translations';\n\nimport type { ZoneVariant } from './AssetDropZone';\n\n/** Narrowest a card and the tile get side by side before stacking, in px. */\nconst MIN_CARD_WIDTH = 130;\n/**\n * Narrowest a card gets when two share the row, in px. Wider than the single\n * card's, so the row drops to one card before names are cut to a few letters.\n */\nconst MIN_CARD_WIDTH_FOR_TWO = 180;\nconst GAP = 16;\nconst MAX_CARDS = 2;\n\nconst Container = styled(Box)`\n background: ${({ theme }) => theme.colors.neutral100};\n border: 1px solid ${({ theme }) => theme.colors.neutral200};\n border-radius: ${({ theme }) => theme.borderRadius};\n`;\n\nconst Track = styled.div<{ $columns: number }>`\n display: grid;\n grid-template-columns: repeat(${({ $columns }) => $columns}, minmax(0, 1fr));\n gap: ${GAP}px;\n`;\n\nconst Cards = styled.div<{ $columns: number }>`\n position: relative;\n display: grid;\n grid-column: span ${({ $columns }) => $columns};\n grid-template-columns: repeat(${({ $columns }) => $columns}, minmax(0, 1fr));\n gap: ${GAP}px;\n`;\n\nconst Arrow = styled(Box)<{ $side: 'start' | 'end' }>`\n position: absolute;\n top: 50%;\n transform: translateY(-50%);\n z-index: 1;\n ${({ $side }) => ($side === 'start' ? 'left: -1.6rem;' : 'right: -1.6rem;')}\n\n button {\n border-radius: 50%;\n box-shadow: ${({ theme }) => theme.shadows.filterShadow};\n }\n`;\n\ninterface RowLayout {\n /** Cards per row, the drop zone not included. */\n cards: number;\n /** Too narrow for a card and the tile side by side: the drop zone goes below. */\n isStacked: boolean;\n}\n\n/**\n * How the row fits the field. The edit layout's size sets it: a third of the\n * form stacks one card over the drop zone, a full-width field shows two cards\n * beside it, anything in between one. Mobile always shows one card, stacked on\n * a phone. The measured width can only take cards away, for a field squeezed\n * by a narrow component.\n */\nconst getRowLayout = ({\n width,\n layoutSize,\n isMobile,\n isPhone,\n}: {\n width: number;\n layoutSize?: number;\n /** Below the tablet breakpoint: one card, whatever the layout says. */\n isMobile: boolean;\n /** Below the small breakpoint: the drop zone goes under the card. */\n isPhone: boolean;\n}): RowLayout => {\n const isNarrowLayout = isPhone || (layoutSize !== undefined && layoutSize <= 4);\n const maxCards = isMobile || (layoutSize !== undefined && layoutSize < 12) ? 1 : MAX_CARDS;\n\n // Unmeasured: no layout yet, or no `ResizeObserver`.\n const isMeasured = width > 0;\n const fitsCardAndTile = !isMeasured || width >= 2 * MIN_CARD_WIDTH + GAP;\n const fitsTwoCardsAndTile = !isMeasured || width >= 3 * MIN_CARD_WIDTH_FOR_TWO + 2 * GAP;\n\n if (isNarrowLayout || !fitsCardAndTile) {\n return { cards: 1, isStacked: true };\n }\n\n return { cards: fitsTwoCardsAndTile ? maxCards : 1, isStacked: false };\n};\n\ninterface AssetCarouselProps {\n /** One card per asset or upload, in field order. */\n children: ReactNode;\n /** Always shown: after the cards, or below them on a narrow field. */\n renderDropZone: (variant: Exclude<ZoneVariant, 'bar'>) => ReactNode;\n /** The field's width in the edit layout, out of 12, when the host knows it. */\n layoutSize?: number;\n}\n\n/**\n * A single row of cards followed by the drop tile. When the field holds more\n * than fit, arrows page through the cards and the tile stays put.\n */\nexport const AssetCarousel = ({ children, renderDropZone, layoutSize }: AssetCarouselProps) => {\n const { formatMessage } = useIntl();\n const theme = useTheme();\n const isMobile = useIsMobile();\n const isPhone = !useMediaQuery(theme.breakpoints.small);\n const trackRef = useRef<HTMLDivElement>(null);\n const [width, setWidth] = useState(0);\n const [start, setStart] = useState(0);\n\n const cards = Children.toArray(children);\n const { cards: cardsPerRow, isStacked } = getRowLayout({ width, layoutSize, isMobile, isPhone });\n const maxStart = Math.max(cards.length - cardsPerRow, 0);\n const firstVisible = Math.min(start, maxStart);\n // Fewer cards than fit leave the tile right after them, not at the far end.\n const visibleCount = Math.min(cards.length, cardsPerRow);\n\n useLayoutEffect(() => {\n const track = trackRef.current;\n\n if (!track || typeof ResizeObserver === 'undefined') {\n return undefined;\n }\n\n const observer = new ResizeObserver(([entry]) => setWidth(entry.contentRect.width));\n observer.observe(track);\n\n return () => observer.disconnect();\n }, []);\n\n // A card added at the end (a new upload) is scrolled into view.\n const previousCount = useRef(cards.length);\n useEffect(() => {\n if (cards.length > previousCount.current) {\n setStart(maxStart);\n }\n previousCount.current = cards.length;\n }, [cards.length, maxStart]);\n\n return (\n <Container padding={4}>\n <Track ref={trackRef} $columns={isStacked ? 1 : cardsPerRow + 1}>\n <Cards $columns={visibleCount}>\n {cards.slice(firstVisible, firstVisible + cardsPerRow)}\n\n {firstVisible > 0 && (\n <Arrow $side=\"start\">\n <IconButton\n onClick={() => setStart(firstVisible - 1)}\n label={formatMessage({\n id: getTranslationKey('mediaLibraryInput.actions.previousSlide'),\n defaultMessage: 'Previous slide',\n })}\n >\n <ChevronLeft />\n </IconButton>\n </Arrow>\n )}\n\n {firstVisible < maxStart && (\n <Arrow $side=\"end\">\n <IconButton\n onClick={() => setStart(firstVisible + 1)}\n label={formatMessage({\n id: getTranslationKey('mediaLibraryInput.actions.nextSlide'),\n defaultMessage: 'Next slide',\n })}\n >\n <ChevronRight />\n </IconButton>\n </Arrow>\n )}\n </Cards>\n {!isStacked && renderDropZone('tile')}\n </Track>\n {isStacked && <Box paddingTop={4}>{renderDropZone('stacked')}</Box>}\n </Container>\n );\n};\n"],"names":["MIN_CARD_WIDTH","MIN_CARD_WIDTH_FOR_TWO","GAP","MAX_CARDS","Container","styled","Box","theme","colors","neutral100","neutral200","borderRadius","Track","div","$columns","Cards","Arrow","$side","shadows","filterShadow","getRowLayout","width","layoutSize","isMobile","isPhone","isNarrowLayout","undefined","maxCards","isMeasured","fitsCardAndTile","fitsTwoCardsAndTile","cards","isStacked","AssetCarousel","children","renderDropZone","formatMessage","useIntl","useTheme","useIsMobile","useMediaQuery","breakpoints","small","trackRef","useRef","setWidth","useState","start","setStart","Children","toArray","cardsPerRow","maxStart","Math","max","length","firstVisible","min","visibleCount","useLayoutEffect","track","current","ResizeObserver","observer","entry","contentRect","observe","disconnect","previousCount","useEffect","_jsxs","padding","ref","slice","_jsx","IconButton","onClick","label","id","getTranslationKey","defaultMessage","ChevronLeft","ChevronRight","paddingTop"],"mappings":"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"}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { useRef, useState, Children, useLayoutEffect, useEffect } from 'react';
|
|
3
|
+
import { useIsMobile, useMediaQuery } from '@strapi/admin/strapi-admin';
|
|
4
|
+
import { Box, IconButton } from '@strapi/design-system';
|
|
5
|
+
import { ChevronLeft, ChevronRight } from '@strapi/icons';
|
|
6
|
+
import { useIntl } from 'react-intl';
|
|
7
|
+
import { styled, useTheme } from 'styled-components';
|
|
8
|
+
import { getTranslationKey } from '../../utils/translations.mjs';
|
|
9
|
+
|
|
10
|
+
/** Narrowest a card and the tile get side by side before stacking, in px. */ const MIN_CARD_WIDTH = 130;
|
|
11
|
+
/**
|
|
12
|
+
* Narrowest a card gets when two share the row, in px. Wider than the single
|
|
13
|
+
* card's, so the row drops to one card before names are cut to a few letters.
|
|
14
|
+
*/ const MIN_CARD_WIDTH_FOR_TWO = 180;
|
|
15
|
+
const GAP = 16;
|
|
16
|
+
const MAX_CARDS = 2;
|
|
17
|
+
const Container = styled(Box)`
|
|
18
|
+
background: ${({ theme })=>theme.colors.neutral100};
|
|
19
|
+
border: 1px solid ${({ theme })=>theme.colors.neutral200};
|
|
20
|
+
border-radius: ${({ theme })=>theme.borderRadius};
|
|
21
|
+
`;
|
|
22
|
+
const Track = styled.div`
|
|
23
|
+
display: grid;
|
|
24
|
+
grid-template-columns: repeat(${({ $columns })=>$columns}, minmax(0, 1fr));
|
|
25
|
+
gap: ${GAP}px;
|
|
26
|
+
`;
|
|
27
|
+
const Cards = styled.div`
|
|
28
|
+
position: relative;
|
|
29
|
+
display: grid;
|
|
30
|
+
grid-column: span ${({ $columns })=>$columns};
|
|
31
|
+
grid-template-columns: repeat(${({ $columns })=>$columns}, minmax(0, 1fr));
|
|
32
|
+
gap: ${GAP}px;
|
|
33
|
+
`;
|
|
34
|
+
const Arrow = styled(Box)`
|
|
35
|
+
position: absolute;
|
|
36
|
+
top: 50%;
|
|
37
|
+
transform: translateY(-50%);
|
|
38
|
+
z-index: 1;
|
|
39
|
+
${({ $side })=>$side === 'start' ? 'left: -1.6rem;' : 'right: -1.6rem;'}
|
|
40
|
+
|
|
41
|
+
button {
|
|
42
|
+
border-radius: 50%;
|
|
43
|
+
box-shadow: ${({ theme })=>theme.shadows.filterShadow};
|
|
44
|
+
}
|
|
45
|
+
`;
|
|
46
|
+
/**
|
|
47
|
+
* How the row fits the field. The edit layout's size sets it: a third of the
|
|
48
|
+
* form stacks one card over the drop zone, a full-width field shows two cards
|
|
49
|
+
* beside it, anything in between one. Mobile always shows one card, stacked on
|
|
50
|
+
* a phone. The measured width can only take cards away, for a field squeezed
|
|
51
|
+
* by a narrow component.
|
|
52
|
+
*/ const getRowLayout = ({ width, layoutSize, isMobile, isPhone })=>{
|
|
53
|
+
const isNarrowLayout = isPhone || layoutSize !== undefined && layoutSize <= 4;
|
|
54
|
+
const maxCards = isMobile || layoutSize !== undefined && layoutSize < 12 ? 1 : MAX_CARDS;
|
|
55
|
+
// Unmeasured: no layout yet, or no `ResizeObserver`.
|
|
56
|
+
const isMeasured = width > 0;
|
|
57
|
+
const fitsCardAndTile = !isMeasured || width >= 2 * MIN_CARD_WIDTH + GAP;
|
|
58
|
+
const fitsTwoCardsAndTile = !isMeasured || width >= 3 * MIN_CARD_WIDTH_FOR_TWO + 2 * GAP;
|
|
59
|
+
if (isNarrowLayout || !fitsCardAndTile) {
|
|
60
|
+
return {
|
|
61
|
+
cards: 1,
|
|
62
|
+
isStacked: true
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
return {
|
|
66
|
+
cards: fitsTwoCardsAndTile ? maxCards : 1,
|
|
67
|
+
isStacked: false
|
|
68
|
+
};
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* A single row of cards followed by the drop tile. When the field holds more
|
|
72
|
+
* than fit, arrows page through the cards and the tile stays put.
|
|
73
|
+
*/ const AssetCarousel = ({ children, renderDropZone, layoutSize })=>{
|
|
74
|
+
const { formatMessage } = useIntl();
|
|
75
|
+
const theme = useTheme();
|
|
76
|
+
const isMobile = useIsMobile();
|
|
77
|
+
const isPhone = !useMediaQuery(theme.breakpoints.small);
|
|
78
|
+
const trackRef = useRef(null);
|
|
79
|
+
const [width, setWidth] = useState(0);
|
|
80
|
+
const [start, setStart] = useState(0);
|
|
81
|
+
const cards = Children.toArray(children);
|
|
82
|
+
const { cards: cardsPerRow, isStacked } = getRowLayout({
|
|
83
|
+
width,
|
|
84
|
+
layoutSize,
|
|
85
|
+
isMobile,
|
|
86
|
+
isPhone
|
|
87
|
+
});
|
|
88
|
+
const maxStart = Math.max(cards.length - cardsPerRow, 0);
|
|
89
|
+
const firstVisible = Math.min(start, maxStart);
|
|
90
|
+
// Fewer cards than fit leave the tile right after them, not at the far end.
|
|
91
|
+
const visibleCount = Math.min(cards.length, cardsPerRow);
|
|
92
|
+
useLayoutEffect(()=>{
|
|
93
|
+
const track = trackRef.current;
|
|
94
|
+
if (!track || typeof ResizeObserver === 'undefined') {
|
|
95
|
+
return undefined;
|
|
96
|
+
}
|
|
97
|
+
const observer = new ResizeObserver(([entry])=>setWidth(entry.contentRect.width));
|
|
98
|
+
observer.observe(track);
|
|
99
|
+
return ()=>observer.disconnect();
|
|
100
|
+
}, []);
|
|
101
|
+
// A card added at the end (a new upload) is scrolled into view.
|
|
102
|
+
const previousCount = useRef(cards.length);
|
|
103
|
+
useEffect(()=>{
|
|
104
|
+
if (cards.length > previousCount.current) {
|
|
105
|
+
setStart(maxStart);
|
|
106
|
+
}
|
|
107
|
+
previousCount.current = cards.length;
|
|
108
|
+
}, [
|
|
109
|
+
cards.length,
|
|
110
|
+
maxStart
|
|
111
|
+
]);
|
|
112
|
+
return /*#__PURE__*/ jsxs(Container, {
|
|
113
|
+
padding: 4,
|
|
114
|
+
children: [
|
|
115
|
+
/*#__PURE__*/ jsxs(Track, {
|
|
116
|
+
ref: trackRef,
|
|
117
|
+
$columns: isStacked ? 1 : cardsPerRow + 1,
|
|
118
|
+
children: [
|
|
119
|
+
/*#__PURE__*/ jsxs(Cards, {
|
|
120
|
+
$columns: visibleCount,
|
|
121
|
+
children: [
|
|
122
|
+
cards.slice(firstVisible, firstVisible + cardsPerRow),
|
|
123
|
+
firstVisible > 0 && /*#__PURE__*/ jsx(Arrow, {
|
|
124
|
+
$side: "start",
|
|
125
|
+
children: /*#__PURE__*/ jsx(IconButton, {
|
|
126
|
+
onClick: ()=>setStart(firstVisible - 1),
|
|
127
|
+
label: formatMessage({
|
|
128
|
+
id: getTranslationKey('mediaLibraryInput.actions.previousSlide'),
|
|
129
|
+
defaultMessage: 'Previous slide'
|
|
130
|
+
}),
|
|
131
|
+
children: /*#__PURE__*/ jsx(ChevronLeft, {})
|
|
132
|
+
})
|
|
133
|
+
}),
|
|
134
|
+
firstVisible < maxStart && /*#__PURE__*/ jsx(Arrow, {
|
|
135
|
+
$side: "end",
|
|
136
|
+
children: /*#__PURE__*/ jsx(IconButton, {
|
|
137
|
+
onClick: ()=>setStart(firstVisible + 1),
|
|
138
|
+
label: formatMessage({
|
|
139
|
+
id: getTranslationKey('mediaLibraryInput.actions.nextSlide'),
|
|
140
|
+
defaultMessage: 'Next slide'
|
|
141
|
+
}),
|
|
142
|
+
children: /*#__PURE__*/ jsx(ChevronRight, {})
|
|
143
|
+
})
|
|
144
|
+
})
|
|
145
|
+
]
|
|
146
|
+
}),
|
|
147
|
+
!isStacked && renderDropZone('tile')
|
|
148
|
+
]
|
|
149
|
+
}),
|
|
150
|
+
isStacked && /*#__PURE__*/ jsx(Box, {
|
|
151
|
+
paddingTop: 4,
|
|
152
|
+
children: renderDropZone('stacked')
|
|
153
|
+
})
|
|
154
|
+
]
|
|
155
|
+
});
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
export { AssetCarousel };
|
|
159
|
+
//# sourceMappingURL=AssetCarousel.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AssetCarousel.mjs","sources":["../../../../admin/src/components/MediaLibraryInput/AssetCarousel.tsx"],"sourcesContent":["import { Children, useEffect, useLayoutEffect, useRef, useState, type ReactNode } from 'react';\n\nimport { useIsMobile, useMediaQuery } from '@strapi/admin/strapi-admin';\nimport { Box, IconButton } from '@strapi/design-system';\nimport { ChevronLeft, ChevronRight } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { styled, useTheme } from 'styled-components';\n\nimport { getTranslationKey } from '../../utils/translations';\n\nimport type { ZoneVariant } from './AssetDropZone';\n\n/** Narrowest a card and the tile get side by side before stacking, in px. */\nconst MIN_CARD_WIDTH = 130;\n/**\n * Narrowest a card gets when two share the row, in px. Wider than the single\n * card's, so the row drops to one card before names are cut to a few letters.\n */\nconst MIN_CARD_WIDTH_FOR_TWO = 180;\nconst GAP = 16;\nconst MAX_CARDS = 2;\n\nconst Container = styled(Box)`\n background: ${({ theme }) => theme.colors.neutral100};\n border: 1px solid ${({ theme }) => theme.colors.neutral200};\n border-radius: ${({ theme }) => theme.borderRadius};\n`;\n\nconst Track = styled.div<{ $columns: number }>`\n display: grid;\n grid-template-columns: repeat(${({ $columns }) => $columns}, minmax(0, 1fr));\n gap: ${GAP}px;\n`;\n\nconst Cards = styled.div<{ $columns: number }>`\n position: relative;\n display: grid;\n grid-column: span ${({ $columns }) => $columns};\n grid-template-columns: repeat(${({ $columns }) => $columns}, minmax(0, 1fr));\n gap: ${GAP}px;\n`;\n\nconst Arrow = styled(Box)<{ $side: 'start' | 'end' }>`\n position: absolute;\n top: 50%;\n transform: translateY(-50%);\n z-index: 1;\n ${({ $side }) => ($side === 'start' ? 'left: -1.6rem;' : 'right: -1.6rem;')}\n\n button {\n border-radius: 50%;\n box-shadow: ${({ theme }) => theme.shadows.filterShadow};\n }\n`;\n\ninterface RowLayout {\n /** Cards per row, the drop zone not included. */\n cards: number;\n /** Too narrow for a card and the tile side by side: the drop zone goes below. */\n isStacked: boolean;\n}\n\n/**\n * How the row fits the field. The edit layout's size sets it: a third of the\n * form stacks one card over the drop zone, a full-width field shows two cards\n * beside it, anything in between one. Mobile always shows one card, stacked on\n * a phone. The measured width can only take cards away, for a field squeezed\n * by a narrow component.\n */\nconst getRowLayout = ({\n width,\n layoutSize,\n isMobile,\n isPhone,\n}: {\n width: number;\n layoutSize?: number;\n /** Below the tablet breakpoint: one card, whatever the layout says. */\n isMobile: boolean;\n /** Below the small breakpoint: the drop zone goes under the card. */\n isPhone: boolean;\n}): RowLayout => {\n const isNarrowLayout = isPhone || (layoutSize !== undefined && layoutSize <= 4);\n const maxCards = isMobile || (layoutSize !== undefined && layoutSize < 12) ? 1 : MAX_CARDS;\n\n // Unmeasured: no layout yet, or no `ResizeObserver`.\n const isMeasured = width > 0;\n const fitsCardAndTile = !isMeasured || width >= 2 * MIN_CARD_WIDTH + GAP;\n const fitsTwoCardsAndTile = !isMeasured || width >= 3 * MIN_CARD_WIDTH_FOR_TWO + 2 * GAP;\n\n if (isNarrowLayout || !fitsCardAndTile) {\n return { cards: 1, isStacked: true };\n }\n\n return { cards: fitsTwoCardsAndTile ? maxCards : 1, isStacked: false };\n};\n\ninterface AssetCarouselProps {\n /** One card per asset or upload, in field order. */\n children: ReactNode;\n /** Always shown: after the cards, or below them on a narrow field. */\n renderDropZone: (variant: Exclude<ZoneVariant, 'bar'>) => ReactNode;\n /** The field's width in the edit layout, out of 12, when the host knows it. */\n layoutSize?: number;\n}\n\n/**\n * A single row of cards followed by the drop tile. When the field holds more\n * than fit, arrows page through the cards and the tile stays put.\n */\nexport const AssetCarousel = ({ children, renderDropZone, layoutSize }: AssetCarouselProps) => {\n const { formatMessage } = useIntl();\n const theme = useTheme();\n const isMobile = useIsMobile();\n const isPhone = !useMediaQuery(theme.breakpoints.small);\n const trackRef = useRef<HTMLDivElement>(null);\n const [width, setWidth] = useState(0);\n const [start, setStart] = useState(0);\n\n const cards = Children.toArray(children);\n const { cards: cardsPerRow, isStacked } = getRowLayout({ width, layoutSize, isMobile, isPhone });\n const maxStart = Math.max(cards.length - cardsPerRow, 0);\n const firstVisible = Math.min(start, maxStart);\n // Fewer cards than fit leave the tile right after them, not at the far end.\n const visibleCount = Math.min(cards.length, cardsPerRow);\n\n useLayoutEffect(() => {\n const track = trackRef.current;\n\n if (!track || typeof ResizeObserver === 'undefined') {\n return undefined;\n }\n\n const observer = new ResizeObserver(([entry]) => setWidth(entry.contentRect.width));\n observer.observe(track);\n\n return () => observer.disconnect();\n }, []);\n\n // A card added at the end (a new upload) is scrolled into view.\n const previousCount = useRef(cards.length);\n useEffect(() => {\n if (cards.length > previousCount.current) {\n setStart(maxStart);\n }\n previousCount.current = cards.length;\n }, [cards.length, maxStart]);\n\n return (\n <Container padding={4}>\n <Track ref={trackRef} $columns={isStacked ? 1 : cardsPerRow + 1}>\n <Cards $columns={visibleCount}>\n {cards.slice(firstVisible, firstVisible + cardsPerRow)}\n\n {firstVisible > 0 && (\n <Arrow $side=\"start\">\n <IconButton\n onClick={() => setStart(firstVisible - 1)}\n label={formatMessage({\n id: getTranslationKey('mediaLibraryInput.actions.previousSlide'),\n defaultMessage: 'Previous slide',\n })}\n >\n <ChevronLeft />\n </IconButton>\n </Arrow>\n )}\n\n {firstVisible < maxStart && (\n <Arrow $side=\"end\">\n <IconButton\n onClick={() => setStart(firstVisible + 1)}\n label={formatMessage({\n id: getTranslationKey('mediaLibraryInput.actions.nextSlide'),\n defaultMessage: 'Next slide',\n })}\n >\n <ChevronRight />\n </IconButton>\n </Arrow>\n )}\n </Cards>\n {!isStacked && renderDropZone('tile')}\n </Track>\n {isStacked && <Box paddingTop={4}>{renderDropZone('stacked')}</Box>}\n </Container>\n );\n};\n"],"names":["MIN_CARD_WIDTH","MIN_CARD_WIDTH_FOR_TWO","GAP","MAX_CARDS","Container","styled","Box","theme","colors","neutral100","neutral200","borderRadius","Track","div","$columns","Cards","Arrow","$side","shadows","filterShadow","getRowLayout","width","layoutSize","isMobile","isPhone","isNarrowLayout","undefined","maxCards","isMeasured","fitsCardAndTile","fitsTwoCardsAndTile","cards","isStacked","AssetCarousel","children","renderDropZone","formatMessage","useIntl","useTheme","useIsMobile","useMediaQuery","breakpoints","small","trackRef","useRef","setWidth","useState","start","setStart","Children","toArray","cardsPerRow","maxStart","Math","max","length","firstVisible","min","visibleCount","useLayoutEffect","track","current","ResizeObserver","observer","entry","contentRect","observe","disconnect","previousCount","useEffect","_jsxs","padding","ref","slice","_jsx","IconButton","onClick","label","id","getTranslationKey","defaultMessage","ChevronLeft","ChevronRight","paddingTop"],"mappings":"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"}
|
|
@@ -8,50 +8,79 @@ var reactIntl = require('react-intl');
|
|
|
8
8
|
var styledComponents = require('styled-components');
|
|
9
9
|
var translations = require('../../utils/translations.js');
|
|
10
10
|
|
|
11
|
-
const
|
|
11
|
+
const DRAG_FRAME_COLORS = {
|
|
12
|
+
accept: {
|
|
13
|
+
border: 'primary600',
|
|
14
|
+
background: 'primary100'
|
|
15
|
+
},
|
|
16
|
+
reject: {
|
|
17
|
+
border: 'neutral300',
|
|
18
|
+
background: 'neutral150'
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
const Zone = styledComponents.styled.div`
|
|
12
22
|
position: relative;
|
|
13
23
|
display: flex;
|
|
14
|
-
flex-direction: column;
|
|
15
24
|
align-items: center;
|
|
16
|
-
|
|
17
|
-
gap: ${({ theme })=>theme.spaces[2]};
|
|
25
|
+
gap: ${({ theme })=>theme.spaces[4]};
|
|
18
26
|
width: 100%;
|
|
19
|
-
min-height: 12rem;
|
|
20
|
-
padding: ${({ theme })=>theme.spaces[6]};
|
|
21
|
-
border: 1px solid ${({ theme })=>theme.colors.neutral200};
|
|
22
27
|
border-radius: ${({ theme })=>theme.borderRadius};
|
|
23
|
-
|
|
24
|
-
cursor: pointer;
|
|
28
|
+
text-align: ${({ $variant })=>$variant === 'bar' ? 'start' : 'center'};
|
|
25
29
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
30
|
+
${({ $variant, theme })=>$variant !== 'bar' ? `
|
|
31
|
+
flex-direction: column;
|
|
32
|
+
justify-content: center;
|
|
33
|
+
height: 100%;
|
|
34
|
+
min-height: ${$variant === 'tile' ? '20.8rem' : 'auto'};
|
|
35
|
+
padding: ${theme.spaces[4]};
|
|
36
|
+
border: 1px dashed ${theme.colors.neutral300};
|
|
37
|
+
background: ${theme.colors.neutral0};
|
|
38
|
+
` : `
|
|
39
|
+
min-height: 7.2rem;
|
|
40
|
+
padding: ${theme.spaces[4]};
|
|
41
|
+
border: 1px solid ${theme.colors.neutral200};
|
|
42
|
+
background: ${theme.colors.neutral100};
|
|
43
|
+
`}
|
|
39
44
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
}
|
|
45
|
+
// Only while a file is dragged over the zone: a solid frame inset from the
|
|
46
|
+
// zone's own border marks where the file will land, greyed out when it can't.
|
|
47
|
+
${({ $dragState, theme })=>$dragState !== 'idle' && `
|
|
48
|
+
&::after {
|
|
49
|
+
content: '';
|
|
50
|
+
position: absolute;
|
|
51
|
+
inset: ${theme.spaces[2]};
|
|
52
|
+
border: 1px solid ${theme.colors[DRAG_FRAME_COLORS[$dragState].border]};
|
|
53
|
+
border-radius: ${theme.borderRadius};
|
|
54
|
+
background: ${theme.colors[DRAG_FRAME_COLORS[$dragState].background]};
|
|
55
|
+
pointer-events: none;
|
|
56
|
+
}
|
|
43
57
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
58
|
+
& > * {
|
|
59
|
+
z-index: 1;
|
|
60
|
+
}
|
|
61
|
+
`}
|
|
62
|
+
|
|
63
|
+
&[data-disabled='true'] {
|
|
64
|
+
cursor: not-allowed;
|
|
47
65
|
}
|
|
48
66
|
`;
|
|
67
|
+
const IconFrame = styledComponents.styled(designSystem.Flex)`
|
|
68
|
+
flex-shrink: 0;
|
|
69
|
+
width: 4rem;
|
|
70
|
+
height: 4rem;
|
|
71
|
+
border-radius: ${({ theme })=>theme.borderRadius};
|
|
72
|
+
background: ${({ theme })=>theme.colors.neutral200};
|
|
73
|
+
color: ${({ theme })=>theme.colors.neutral500};
|
|
74
|
+
`;
|
|
49
75
|
/**
|
|
50
|
-
* The field's own drop target.
|
|
76
|
+
* The field's own drop target. It only takes drops: browsing and picking files
|
|
77
|
+
* go through the "Add asset" menu, so the field has one way in, not two.
|
|
78
|
+
*
|
|
79
|
+
* Deliberately not the Media Library page's
|
|
51
80
|
* `UploadDropZoneProvider`: that one covers a whole route and paints a
|
|
52
81
|
* full-surface overlay, where this has to stay inside one field on a form that
|
|
53
82
|
* may hold several of them.
|
|
54
|
-
*/ const AssetDropZone = ({ disabled = false,
|
|
83
|
+
*/ const AssetDropZone = ({ variant = 'bar', disabled = false, onDropFiles })=>{
|
|
55
84
|
const { formatMessage } = reactIntl.useIntl();
|
|
56
85
|
const [isDragging, setIsDragging] = React.useState(false);
|
|
57
86
|
// Drag events fire on descendants too, so a plain boolean flickers as the
|
|
@@ -59,14 +88,12 @@ const Zone = styledComponents.styled.button`
|
|
|
59
88
|
const dragDepth = React.useRef(0);
|
|
60
89
|
const handleDragEnter = React.useCallback((event)=>{
|
|
61
90
|
event.preventDefault();
|
|
62
|
-
if (
|
|
91
|
+
if (!event.dataTransfer.types.includes('Files')) {
|
|
63
92
|
return;
|
|
64
93
|
}
|
|
65
94
|
dragDepth.current += 1;
|
|
66
95
|
setIsDragging(true);
|
|
67
|
-
}, [
|
|
68
|
-
disabled
|
|
69
|
-
]);
|
|
96
|
+
}, []);
|
|
70
97
|
const handleDragLeave = React.useCallback((event)=>{
|
|
71
98
|
event.preventDefault();
|
|
72
99
|
dragDepth.current -= 1;
|
|
@@ -77,8 +104,11 @@ const Zone = styledComponents.styled.button`
|
|
|
77
104
|
}, []);
|
|
78
105
|
const handleDragOver = React.useCallback((event)=>{
|
|
79
106
|
event.preventDefault();
|
|
80
|
-
|
|
81
|
-
|
|
107
|
+
// `none` shows the no-drop cursor, and the browser then fires no `drop`.
|
|
108
|
+
event.dataTransfer.dropEffect = disabled ? 'none' : 'copy';
|
|
109
|
+
}, [
|
|
110
|
+
disabled
|
|
111
|
+
]);
|
|
82
112
|
const handleDrop = React.useCallback((event)=>{
|
|
83
113
|
event.preventDefault();
|
|
84
114
|
dragDepth.current = 0;
|
|
@@ -95,30 +125,27 @@ const Zone = styledComponents.styled.button`
|
|
|
95
125
|
onDropFiles
|
|
96
126
|
]);
|
|
97
127
|
return /*#__PURE__*/ jsxRuntime.jsxs(Zone, {
|
|
98
|
-
|
|
99
|
-
$
|
|
100
|
-
"
|
|
101
|
-
onClick: ()=>!disabled && onClick(),
|
|
128
|
+
$dragState: isDragging ? disabled ? 'reject' : 'accept' : 'idle',
|
|
129
|
+
$variant: variant,
|
|
130
|
+
"data-disabled": disabled,
|
|
102
131
|
onDragEnter: handleDragEnter,
|
|
103
132
|
onDragLeave: handleDragLeave,
|
|
104
133
|
onDragOver: handleDragOver,
|
|
105
134
|
onDrop: handleDrop,
|
|
106
135
|
children: [
|
|
107
|
-
/*#__PURE__*/ jsxRuntime.jsx(
|
|
136
|
+
/*#__PURE__*/ jsxRuntime.jsx(IconFrame, {
|
|
108
137
|
justifyContent: "center",
|
|
109
|
-
|
|
110
|
-
children: /*#__PURE__*/ jsxRuntime.jsx(icons.
|
|
111
|
-
width: "
|
|
112
|
-
height: "
|
|
138
|
+
alignItems: "center",
|
|
139
|
+
children: /*#__PURE__*/ jsxRuntime.jsx(icons.Images, {
|
|
140
|
+
width: "2.4rem",
|
|
141
|
+
height: "2.4rem"
|
|
113
142
|
})
|
|
114
143
|
}),
|
|
115
144
|
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
|
|
116
145
|
textColor: "neutral600",
|
|
117
|
-
fontWeight: "bold",
|
|
118
|
-
variant: "pi",
|
|
119
146
|
children: formatMessage({
|
|
120
|
-
id: translations.getTranslationKey('
|
|
121
|
-
defaultMessage: '
|
|
147
|
+
id: translations.getTranslationKey('content-manager.input.placeholder'),
|
|
148
|
+
defaultMessage: 'Drag & drop an asset here'
|
|
122
149
|
})
|
|
123
150
|
})
|
|
124
151
|
]
|