import { jsx, jsxs } from 'react/jsx-runtime'; import { Box, Typography, Grid, IconButton, CardBody, Flex, Card, CardHeader } from '@strapi/design-system'; import { Folder, More } from '@strapi/icons'; import { useIntl } from 'react-intl'; import { styled, css } from 'styled-components'; import { ASSET_TYPES } from '../../../../enums.mjs'; import { prefixFileUrlWithBackendUrl } from '../../../utils/files.mjs'; import { getAssetIcon } from '../../../utils/getAssetIcon.mjs'; import { getTranslationKey } from '../../../utils/translations.mjs'; import { useFolderNavigation } from '../hooks/useFolderNavigation.mjs'; import { useAssetsDndOptional } from './Dnd/AssetsDndProvider.mjs'; import { useFolderDraggableDroppable, useFileDraggable } from './Dnd/useAssetDnd.mjs'; /* ------------------------------------------------------------------------------------------------- * AssetsGrid * -----------------------------------------------------------------------------------------------*/ const StyledCard = styled(Card)` border: 1px solid ${({ theme })=>theme.colors.neutral200}; border-radius: 8px; overflow: hidden; cursor: ${({ $isMovePending })=>$isMovePending ? 'wait' : 'pointer'}; opacity: ${({ $isDragging })=>$isDragging ? 0.4 : 1}; pointer-events: ${({ $isMovePending })=>$isMovePending ? 'none' : 'auto'}; &:hover { background: ${({ theme })=>theme.colors.primary100}; } &:focus-visible { outline: 2px solid ${({ theme })=>theme.colors.primary600}; outline-offset: 2px; } `; /* ------------------------------------------------------------------------------------------------- * FolderCard * -----------------------------------------------------------------------------------------------*/ const FoldersRow = styled(Box)` grid-column: 1 / -1; `; const StyledFolderCard = styled(Flex)` width: 100%; padding: ${({ theme })=>`${theme.spaces[2]} ${theme.spaces[3]}`}; // 8px 12px align-items: center; gap: ${({ theme })=>theme.spaces[2]}; // 8px border: 1px solid ${({ theme })=>theme.colors.neutral200}; border-radius: ${({ theme })=>theme.borderRadius}; background: ${({ theme })=>theme.colors.neutral0}; cursor: ${({ $isMovePending, $isInvalidDropTarget })=>{ if ($isMovePending) { return 'wait'; } return $isInvalidDropTarget ? 'not-allowed' : 'pointer'; }}; opacity: ${({ $isDragging })=>$isDragging ? 0.4 : 1}; pointer-events: ${({ $isMovePending })=>$isMovePending ? 'none' : 'auto'}; transition: background 0.2s; ${({ $isValidDropTarget, theme })=>$isValidDropTarget && css` background: ${theme.colors.primary100}; border: 1px dashed ${theme.colors.primary600}; `} &:hover { background: ${({ theme })=>theme.colors.primary100}; } &:focus-visible { outline: 2px solid ${({ theme })=>theme.colors.primary600}; outline-offset: 2px; } `; const FolderIconContainer = styled(Flex)` flex-shrink: 0; color: ${({ theme })=>theme.colors.neutral600}; `; const FolderName = styled(Typography)` flex: 1; min-width: 0; `; const FolderCard = ({ folder })=>{ const { formatMessage } = useIntl(); const { navigateToFolder } = useFolderNavigation(); const { isMovePending } = useAssetsDndOptional() ?? { isMovePending: false }; const { draggable: { attributes, listeners, setNodeRef: setDragRef, isDragging }, droppable: { setNodeRef: setDropRef }, showValidDropHighlight, showInvalidDropCursor } = useFolderDraggableDroppable(folder); const setNodeRef = (node)=>{ setDragRef(node); setDropRef(node); }; const handleKeyDown = (e)=>{ if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); navigateToFolder(folder); } }; return /*#__PURE__*/ jsxs(StyledFolderCard, { ref: setNodeRef, ...attributes, ...listeners, $isDragging: isDragging, $isMovePending: isMovePending, $isValidDropTarget: showValidDropHighlight, $isInvalidDropTarget: showInvalidDropCursor, onClick: ()=>navigateToFolder(folder), onKeyDown: handleKeyDown, role: "listitem", tabIndex: 0, children: [ /*#__PURE__*/ jsx(FolderIconContainer, { children: /*#__PURE__*/ jsx(Folder, { width: 20, height: 20 }) }), /*#__PURE__*/ jsx(FolderName, { textColor: "neutral800", ellipsis: true, children: folder.name }), /*#__PURE__*/ jsx(IconButton, { label: formatMessage({ id: getTranslationKey('control-card.more-actions'), defaultMessage: 'More actions' }), variant: "ghost", onClick: (e)=>e.stopPropagation(), children: /*#__PURE__*/ jsx(More, {}) }) ] }); }; /* ------------------------------------------------------------------------------------------------- * AssetPreview * -----------------------------------------------------------------------------------------------*/ const PreviewContainer = styled(Box)` position: relative; width: 100%; padding-bottom: 62.5%; height: 0; overflow: hidden; background: repeating-conic-gradient( ${({ theme })=>theme.colors.neutral100} 0% 25%, transparent 0% 50% ) 50% / 20px 20px; `; const StyledImage = styled.img` position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: cover; `; const IconPreview = styled(Flex)` position: absolute; top: 0; left: 0; width: 100%; height: 100%; color: ${({ theme })=>theme.colors.neutral500}; background: ${({ theme })=>theme.colors.neutral100}; `; const AssetPreview = ({ asset })=>{ const { alternativeText, ext, formats, mime, url } = asset; if (mime?.includes(ASSET_TYPES.Image)) { const mediaURL = prefixFileUrlWithBackendUrl(formats?.thumbnail?.url) ?? prefixFileUrlWithBackendUrl(url); if (mediaURL) { return /*#__PURE__*/ jsx(PreviewContainer, { children: /*#__PURE__*/ jsx(StyledImage, { src: mediaURL, alt: alternativeText || '', draggable: false, onDragStart: (e)=>e.preventDefault() }) }); } } const DocIcon = getAssetIcon(mime, ext); return /*#__PURE__*/ jsx(PreviewContainer, { children: /*#__PURE__*/ jsx(IconPreview, { justifyContent: "center", alignItems: "center", children: /*#__PURE__*/ jsx(DocIcon, { width: 48, height: 48 }) }) }); }; /* ------------------------------------------------------------------------------------------------- * AssetCard * -----------------------------------------------------------------------------------------------*/ const StyledCardHeader = styled(CardHeader)` border-bottom: 1px solid ${({ theme })=>theme.colors.neutral200}; `; const CardFooter = styled(Flex)` min-width: 0; width: 100%; `; const FileTypeIcon = styled(Flex)` color: ${({ theme })=>theme.colors.neutral600}; flex-shrink: 0; `; const FileName = styled(Typography)` flex: 1; min-width: 0; `; const AssetCard = ({ asset, onAssetItemClick })=>{ const { formatMessage } = useIntl(); const TypeIcon = getAssetIcon(asset.mime, asset.ext); const { isMovePending } = useAssetsDndOptional() ?? { isMovePending: false }; const { attributes, listeners, setNodeRef, isDragging } = useFileDraggable(asset); const handleKeyDown = (e)=>{ if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); onAssetItemClick(asset.id); } }; return /*#__PURE__*/ jsxs(StyledCard, { ref: setNodeRef, ...attributes, ...listeners, $isDragging: isDragging, $isMovePending: isMovePending, tabIndex: 0, role: "listitem", onDragStart: (e)=>e.preventDefault(), onClick: ()=>onAssetItemClick(asset.id), onKeyDown: handleKeyDown, children: [ /*#__PURE__*/ jsx(StyledCardHeader, { children: /*#__PURE__*/ jsx(AssetPreview, { asset: asset }) }), /*#__PURE__*/ jsx(CardBody, { children: /*#__PURE__*/ jsxs(CardFooter, { alignItems: "center", gap: 2, children: [ /*#__PURE__*/ jsx(FileTypeIcon, { children: /*#__PURE__*/ jsx(TypeIcon, { width: 20, height: 20 }) }), /*#__PURE__*/ jsx(FileName, { textColor: "primary800", ellipsis: true, children: asset.name }), /*#__PURE__*/ jsx(IconButton, { label: formatMessage({ id: getTranslationKey('control-card.more-actions'), defaultMessage: 'More actions' }), variant: "ghost", onClick: (e)=>e.stopPropagation(), children: /*#__PURE__*/ jsx(More, {}) }) ] }) }) ] }); }; const AssetsGrid = ({ assets, folders = [], onAssetItemClick })=>{ const { formatMessage } = useIntl(); const totalItems = folders.length + assets.length; if (totalItems === 0) { return /*#__PURE__*/ jsx(Box, { padding: 8, children: /*#__PURE__*/ jsx(Typography, { textColor: "neutral600", children: formatMessage({ id: 'app.components.EmptyStateLayout.content-document', defaultMessage: 'No content found' }) }) }); } return /*#__PURE__*/ jsxs(Grid.Root, { gap: 4, role: "list", "data-testid": "assets-grid", children: [ folders.length > 0 && /*#__PURE__*/ jsx(FoldersRow, { children: /*#__PURE__*/ jsx(Grid.Root, { gap: 4, children: folders.map((folder)=>/*#__PURE__*/ jsx(Grid.Item, { col: 3, m: 4, s: 6, xs: 12, children: /*#__PURE__*/ jsx(FolderCard, { folder: folder }) }, `folder-${folder.id}`)) }) }), assets.map((asset)=>/*#__PURE__*/ jsx(Grid.Item, { col: 3, m: 4, s: 6, xs: 12, direction: "column", alignItems: "stretch", children: /*#__PURE__*/ jsx(AssetCard, { asset: asset, onAssetItemClick: onAssetItemClick }) }, asset.id)) ] }); }; export { AssetsGrid }; //# sourceMappingURL=AssetsGrid.mjs.map