Carousel extraction

This commit is contained in:
mfrachet 2021-10-28 17:22:14 +02:00
parent 10830fab7c
commit d4c662f431
3 changed files with 116 additions and 67 deletions

View File

@ -0,0 +1,106 @@
import React, { useState } from 'react';
import PropTypes from 'prop-types';
import { useIntl } from 'react-intl';
import { Carousel, CarouselSlide } from '@strapi/parts/Carousel';
import getTrad from '../../../utils/getTrad';
import { AssetDefinition } from '../../../constants';
import { CarouselAssetActions } from './CarouselAssetActions';
import { CarouselAsset } from './CarouselAsset';
import { EmptyStateAsset } from './EmptyStateAsset';
export const CarouselAssets = ({
label,
assets,
error,
hint,
disabled,
onDeleteAsset,
onEditAsset,
onAddAsset,
}) => {
const [selectedIndex, setSelectedIndex] = useState(0);
const { formatMessage } = useIntl();
const handleNext = () => {
setSelectedIndex(current => (current < assets.length - 1 ? current + 1 : 0));
};
const handlePrevious = () => {
setSelectedIndex(current => (current > 0 ? current - 1 : assets.length - 1));
};
const currentAsset = assets[selectedIndex];
return (
<Carousel
label={label}
selectedSlide={selectedIndex}
previousLabel={formatMessage({
id: getTrad('mediaLibraryInput.actions.previousSlide'),
defaultMessage: 'Previous slide',
})}
nextLabel={formatMessage({
id: getTrad('mediaLibraryInput.actions.nextSlide'),
defaultMessage: 'Next slide',
})}
onNext={handleNext}
onPrevious={handlePrevious}
hint={hint}
error={error}
actions={
currentAsset ? (
<CarouselAssetActions
asset={currentAsset}
onDeleteAsset={onDeleteAsset}
onAddAsset={onAddAsset}
onEditAsset={onEditAsset}
/>
) : (
undefined
)
}
>
{assets.length === 0 ? (
<CarouselSlide
label={formatMessage(
{ id: getTrad('mediaLibraryInput.slideCount'), defaultMessage: '{n} of {m} slides' },
{ n: 1, m: 1 }
)}
>
<EmptyStateAsset disabled={disabled} onClick={onAddAsset} />
</CarouselSlide>
) : (
assets.map((asset, index) => (
<CarouselSlide
key={asset.id}
label={formatMessage(
{
id: getTrad('mediaLibraryInput.slideCount'),
defaultMessage: '{n} of {m} slides',
},
{ n: index + 1, m: assets.length }
)}
>
<CarouselAsset asset={asset} />
</CarouselSlide>
))
)}
</Carousel>
);
};
CarouselAssets.defaultProps = {
disabled: false,
error: undefined,
hint: undefined,
};
CarouselAssets.propTypes = {
assets: PropTypes.arrayOf(AssetDefinition).isRequired,
disabled: PropTypes.bool,
label: PropTypes.string.isRequired,
onDeleteAsset: PropTypes.func.isRequired,
onAddAsset: PropTypes.func.isRequired,
onEditAsset: PropTypes.func.isRequired,
error: PropTypes.string,
hint: PropTypes.string,
};

View File

@ -6,7 +6,7 @@ import { Flex } from '@strapi/parts/Flex';
import { Text } from '@strapi/parts/Text';
import { Box } from '@strapi/parts/Box';
import AddAsset from '@strapi/icons/AddAsset';
import getTrad from '../../utils/getTrad';
import getTrad from '../../../utils/getTrad';
export const EmptyStateAsset = ({ disabled, onClick }) => {
const { formatMessage } = useIntl();

View File

@ -1,13 +1,9 @@
import React, { useState } from 'react';
import PropTypes from 'prop-types';
import { useIntl } from 'react-intl';
import { Carousel, CarouselSlide } from '@strapi/parts/Carousel';
import getTrad from '../../utils/getTrad';
import { EmptyStateAsset } from './EmptyStateAsset';
import { AssetDialog } from './AssetDialog';
import { CarouselAsset } from './Carousel/CarouselAsset';
import { CarouselAssetActions } from './Carousel/CarouselAssetActions';
import { AssetDefinition } from '../../constants';
import { CarouselAssets } from './Carousel/CarouselAssets';
export const MediaLibraryInput = ({
intlLabel,
@ -24,15 +20,6 @@ export const MediaLibraryInput = ({
const { formatMessage } = useIntl();
const selectedAssets = Array.isArray(value) ? value : [value];
const currentAsset = selectedAssets[selectedIndex];
const handleNext = () => {
setSelectedIndex(current => (current < selectedAssets.length - 1 ? current + 1 : 0));
};
const handlePrevious = () => {
setSelectedIndex(current => (current > 0 ? current - 1 : selectedAssets.length - 1));
};
const handleValidation = nextSelectedAssets => {
onChange({
@ -77,60 +64,16 @@ export const MediaLibraryInput = ({
return (
<>
<Carousel
<CarouselAssets
assets={selectedAssets}
disabled={disabled}
label={label}
selectedSlide={selectedIndex}
previousLabel={formatMessage({
id: getTrad('mediaLibraryInput.actions.previousSlide'),
defaultMessage: 'Previous slide',
})}
nextLabel={formatMessage({
id: getTrad('mediaLibraryInput.actions.nextSlide'),
defaultMessage: 'Next slide',
})}
onNext={handleNext}
onPrevious={handlePrevious}
hint={hint}
onDeleteAsset={handleDeleteAsset}
onAddAsset={() => setIsAssetDialogOpen(true)}
onEditAsset={handleAssetEdit}
error={errorMessage}
actions={
currentAsset ? (
<CarouselAssetActions
asset={currentAsset}
onDeleteAsset={handleDeleteAsset}
onAddAsset={() => setIsAssetDialogOpen(true)}
onEditAsset={handleAssetEdit}
/>
) : (
undefined
)
}
>
{selectedAssets.length === 0 ? (
<CarouselSlide
label={formatMessage(
{ id: getTrad('mediaLibraryInput.slideCount'), defaultMessage: '{n} of {m} slides' },
{ n: 1, m: 1 }
)}
>
<EmptyStateAsset disabled={disabled} onClick={() => setIsAssetDialogOpen(true)} />
</CarouselSlide>
) : (
selectedAssets.map((asset, index) => (
<CarouselSlide
key={asset.id}
label={formatMessage(
{
id: getTrad('mediaLibraryInput.slideCount'),
defaultMessage: '{n} of {m} slides',
},
{ n: index + 1, m: selectedAssets.length }
)}
>
<CarouselAsset asset={asset} />
</CarouselSlide>
))
)}
</Carousel>
hint={hint}
/>
{isAssetDialogOpen && (
<AssetDialog