diff --git a/packages/core/upload/admin/src/components/AssetCard/AssetCardBase.js b/packages/core/upload/admin/src/components/AssetCard/AssetCardBase.js
new file mode 100644
index 0000000000..8562c1267e
--- /dev/null
+++ b/packages/core/upload/admin/src/components/AssetCard/AssetCardBase.js
@@ -0,0 +1,122 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import styled from 'styled-components';
+import { Box } from '@strapi/design-system/Box';
+import {
+ Card,
+ CardAction,
+ CardBadge,
+ CardBody,
+ CardCheckbox,
+ CardContent,
+ CardHeader,
+ CardTitle,
+ CardSubtitle,
+} from '@strapi/design-system/Card';
+import { IconButton } from '@strapi/design-system/IconButton';
+import Pencil from '@strapi/icons/Pencil';
+import Trash from '@strapi/icons/Trash';
+import { useIntl } from 'react-intl';
+
+import { getTrad } from '../../utils';
+
+const Extension = styled.span`
+ text-transform: uppercase;
+`;
+
+const CardActionsContainer = styled(CardAction)``;
+
+const CardContainer = styled(Card)`
+ ${CardActionsContainer} {
+ display: none;
+ }
+
+ &:hover {
+ ${CardActionsContainer} {
+ display: block;
+ }
+ }
+`;
+
+export const AssetCardBase = ({
+ children,
+ name,
+ extension,
+ selected,
+ onSelect,
+ onRemove,
+ onEdit,
+ subtitle,
+ variant,
+}) => {
+ const { formatMessage } = useIntl();
+
+ return (
+
+
+ {onSelect && }
+ {(onRemove || onEdit) && (
+
+ {onRemove && (
+ }
+ onClick={onRemove}
+ />
+ )}
+
+ {onEdit && (
+ }
+ onClick={onEdit}
+ />
+ )}
+
+ )}
+ {children}
+
+
+
+
+ {name}
+
+
+ {extension}
+ {subtitle}
+
+
+
+ {formatMessage({
+ id: getTrad(`settings.section.${variant.toLowerCase()}.label`),
+ defaultMessage: variant,
+ })}
+
+
+
+ );
+};
+
+AssetCardBase.defaultProps = {
+ selected: false,
+ onEdit: undefined,
+ onSelect: undefined,
+ onRemove: undefined,
+ subtitle: '',
+ variant: 'Image',
+};
+
+AssetCardBase.propTypes = {
+ children: PropTypes.node.isRequired,
+ extension: PropTypes.string.isRequired,
+ name: PropTypes.string.isRequired,
+ onEdit: PropTypes.func,
+ onSelect: PropTypes.func,
+ onRemove: PropTypes.func,
+ selected: PropTypes.bool,
+ subtitle: PropTypes.string,
+ variant: PropTypes.oneOf(['Image', 'Video', 'Audio', 'Doc']),
+};
diff --git a/packages/core/upload/admin/src/components/AssetCard/AudioAssetCard.js b/packages/core/upload/admin/src/components/AssetCard/AudioAssetCard.js
index 09d864e0e3..c553ff953c 100644
--- a/packages/core/upload/admin/src/components/AssetCard/AudioAssetCard.js
+++ b/packages/core/upload/admin/src/components/AssetCard/AudioAssetCard.js
@@ -1,29 +1,11 @@
import React from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';
-import {
- Card,
- CardAction,
- CardAsset,
- CardBadge,
- CardBody,
- CardCheckbox,
- CardContent,
- CardHeader,
- CardTitle,
- CardSubtitle,
-} from '@strapi/design-system/Card';
-import { IconButton } from '@strapi/design-system/IconButton';
-import Pencil from '@strapi/icons/Pencil';
-import Trash from '@strapi/icons/Trash';
-import { useIntl } from 'react-intl';
+import { CardAsset } from '@strapi/design-system/Card';
import { Box } from '@strapi/design-system/Box';
-import { AudioPreview } from './AudioPreview';
-import { getTrad } from '../../utils';
-const Extension = styled.span`
- text-transform: uppercase;
-`;
+import { AudioPreview } from './AudioPreview';
+import { AssetCardBase } from './AssetCardBase';
const AudioPreviewWrapper = styled(Box)`
canvas,
@@ -34,64 +16,15 @@ const AudioPreviewWrapper = styled(Box)`
}
`;
-export const AudioAssetCard = ({
- name,
- extension,
- url,
- selected,
- onSelect,
- onEdit,
- onRemove,
- size,
-}) => {
- const { formatMessage } = useIntl();
-
+export const AudioAssetCard = ({ name, url, size, ...restProps }) => {
return (
-
-
-
-
-
-
-
- {onSelect && }
- {(onRemove || onEdit) && (
-
- {onRemove && (
- }
- onClick={onRemove}
- />
- )}
-
- {onEdit && (
- }
- onClick={onEdit}
- />
- )}
-
- )}
-
-
-
-
- {name}
-
-
- {extension}
-
-
-
- {formatMessage({ id: getTrad('settings.section.audio.label'), defaultMessage: 'Audio' })}
-
-
-
+
+
+
+
+
+
+
);
};
diff --git a/packages/core/upload/admin/src/components/AssetCard/DocAssetCard.js b/packages/core/upload/admin/src/components/AssetCard/DocAssetCard.js
index 605577dfbe..cd3030d935 100644
--- a/packages/core/upload/admin/src/components/AssetCard/DocAssetCard.js
+++ b/packages/core/upload/admin/src/components/AssetCard/DocAssetCard.js
@@ -1,31 +1,12 @@
import React from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';
-import {
- Card,
- CardAction,
- CardBadge,
- CardBody,
- CardCheckbox,
- CardContent,
- CardHeader,
- CardTitle,
- CardSubtitle,
-} from '@strapi/design-system/Card';
-import { Box } from '@strapi/design-system/Box';
import { Flex } from '@strapi/design-system/Flex';
-import { IconButton } from '@strapi/design-system/IconButton';
-import Pencil from '@strapi/icons/Pencil';
import FileIcon from '@strapi/icons/File';
import FilePdfIcon from '@strapi/icons/FilePdf';
-import Trash from '@strapi/icons/Trash';
import { pxToRem } from '@strapi/helper-plugin';
-import { useIntl } from 'react-intl';
-import { getTrad } from '../../utils';
-const Extension = styled.span`
- text-transform: uppercase;
-`;
+import { AssetCardBase } from './AssetCardBase';
const IconWrapper = styled.span`
svg {
@@ -38,80 +19,28 @@ const CardAsset = styled(Flex)`
background: linear-gradient(180deg, #ffffff 0%, #f6f6f9 121.48%);
`;
-export const DocAssetCard = ({ name, extension, selected, onSelect, onEdit, onRemove, size }) => {
- const { formatMessage } = useIntl();
-
+export const DocAssetCard = ({ name, extension, size, ...restProps }) => {
return (
-
-
- {onSelect && }
- {(onRemove || onEdit) && (
-
- {onRemove && (
- }
- onClick={onRemove}
- />
- )}
-
- {onEdit && (
- }
- onClick={onEdit}
- />
- )}
-
- )}
-
-
- {extension === 'pdf' ? (
-
- ) : (
-
- )}
-
-
-
-
-
-
- {name}
-
-
- {extension}
-
-
-
- {formatMessage({ id: getTrad('settings.section.doc.label'), defaultMessage: 'Doc' })}
-
-
-
+
+
+
+ {extension === 'pdf' ? : }
+
+
+
);
};
DocAssetCard.defaultProps = {
- selected: false,
- onEdit: undefined,
- onSelect: undefined,
- onRemove: undefined,
size: 'M',
};
DocAssetCard.propTypes = {
- extension: PropTypes.string.isRequired,
+ ...AssetCardBase.propTypes,
name: PropTypes.string.isRequired,
- onEdit: PropTypes.func,
- onRemove: PropTypes.func,
- onSelect: PropTypes.func,
- selected: PropTypes.bool,
size: PropTypes.oneOf(['S', 'M']),
};
diff --git a/packages/core/upload/admin/src/components/AssetCard/ImageAssetCard.js b/packages/core/upload/admin/src/components/AssetCard/ImageAssetCard.js
index 08029f53df..a678f6dd57 100644
--- a/packages/core/upload/admin/src/components/AssetCard/ImageAssetCard.js
+++ b/packages/core/upload/admin/src/components/AssetCard/ImageAssetCard.js
@@ -1,92 +1,19 @@
import React from 'react';
import PropTypes from 'prop-types';
-import styled from 'styled-components';
-import { Box } from '@strapi/design-system/Box';
-import {
- Card,
- CardAction,
- CardAsset,
- CardBadge,
- CardBody,
- CardCheckbox,
- CardContent,
- CardHeader,
- CardTitle,
- CardSubtitle,
-} from '@strapi/design-system/Card';
-import { IconButton } from '@strapi/design-system/IconButton';
-import Pencil from '@strapi/icons/Pencil';
-import Trash from '@strapi/icons/Trash';
-import { useIntl } from 'react-intl';
-import { getTrad } from '../../utils';
+import { CardAsset } from '@strapi/design-system/Card';
-const Extension = styled.span`
- text-transform: uppercase;
-`;
-
-export const ImageAssetCard = ({
- name,
- extension,
- height,
- width,
- thumbnail,
- selected,
- onSelect,
- onEdit,
- onRemove,
- size,
- alt,
-}) => {
- const { formatMessage } = useIntl();
+import { AssetCardBase } from './AssetCardBase';
+export const ImageAssetCard = ({ height, width, thumbnail, size, alt, ...props }) => {
// Prevents the browser from caching the URL for all sizes and allow react-query to make a smooth update
// instead of a full refresh
const optimizedCachingThumbnail =
width && height ? `${thumbnail}?width=${width}&height=${height}` : thumbnail;
return (
-
-
- {onSelect && }
- {(onRemove || onEdit) && (
-
- {onRemove && (
- }
- onClick={onRemove}
- />
- )}
-
- {onEdit && (
- }
- onClick={onEdit}
- />
- )}
-
- )}
-
-
-
-
-
- {name}
-
-
- {extension}
- {height && width && ` - ${width}✕${height}`}
-
-
-
- {formatMessage({ id: getTrad('settings.section.image.label'), defaultMessage: 'Image' })}
-
-
-
+
+
+
);
};
diff --git a/packages/core/upload/admin/src/components/AssetCard/VideoAssetCard.js b/packages/core/upload/admin/src/components/AssetCard/VideoAssetCard.js
index ba6341f5ca..15670157f3 100644
--- a/packages/core/upload/admin/src/components/AssetCard/VideoAssetCard.js
+++ b/packages/core/upload/admin/src/components/AssetCard/VideoAssetCard.js
@@ -1,30 +1,13 @@
import React, { useState } from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';
-import {
- Card,
- CardAction,
- CardAsset,
- CardBadge,
- CardBody,
- CardCheckbox,
- CardContent,
- CardHeader,
- CardTitle,
- CardSubtitle,
- CardTimer,
-} from '@strapi/design-system/Card';
-import { IconButton } from '@strapi/design-system/IconButton';
-import Pencil from '@strapi/icons/Pencil';
-import Trash from '@strapi/icons/Trash';
-import { useIntl } from 'react-intl';
+import { CardAsset, CardTimer } from '@strapi/design-system/Card';
import { Box } from '@strapi/design-system/Box';
-import { VideoPreview } from './VideoPreview';
-import { getTrad, formatDuration } from '../../utils';
-const Extension = styled.span`
- text-transform: uppercase;
-`;
+import { VideoPreview } from './VideoPreview';
+import { AssetCardBase } from './AssetCardBase';
+
+import { formatDuration } from '../../utils';
const VideoPreviewWrapper = styled(Box)`
canvas,
@@ -35,69 +18,20 @@ const VideoPreviewWrapper = styled(Box)`
}
`;
-export const VideoAssetCard = ({
- name,
- extension,
- url,
- mime,
- selected,
- onSelect,
- onEdit,
- onRemove,
- size,
-}) => {
- const { formatMessage } = useIntl();
+export const VideoAssetCard = ({ name, url, mime, size, ...props }) => {
const [duration, setDuration] = useState();
const formattedDuration = duration && formatDuration(duration);
return (
-
-
- {onSelect && }
- {(onRemove || onEdit) && (
-
- {onRemove && (
- }
- onClick={onRemove}
- />
- )}
-
- {onEdit && (
- }
- onClick={onEdit}
- />
- )}
-
- )}
-
-
-
-
-
- {formattedDuration || '...'}
-
-
-
-
- {name}
-
-
- {extension}
-
-
-
- {formatMessage({ id: getTrad('settings.section.video.label'), defaultMessage: 'Video' })}
-
-
-
+
+
+
+
+
+
+ {formattedDuration || '...'}
+
);
};