mirror of
https://github.com/jellyfin/jellyfin-web
synced 2025-03-30 19:56:21 +00:00
Refactoring Section Container
This commit is contained in:
parent
c3e253d98d
commit
12995545b9
11 changed files with 257 additions and 183 deletions
|
@ -4,19 +4,19 @@ import Typography from '@mui/material/Typography';
|
|||
import globalize from 'lib/globalize';
|
||||
|
||||
interface NoItemsMessageProps {
|
||||
noItemsMessage?: string;
|
||||
message?: string;
|
||||
}
|
||||
|
||||
const NoItemsMessage: FC<NoItemsMessageProps> = ({
|
||||
noItemsMessage = 'MessageNoItemsAvailable'
|
||||
message = 'MessageNoItemsAvailable'
|
||||
}) => {
|
||||
return (
|
||||
<Box className='noItemsMessage centerMessage'>
|
||||
<Typography variant='h2'>
|
||||
<Typography variant='h1'>
|
||||
{globalize.translate('MessageNothingHere')}
|
||||
</Typography>
|
||||
<Typography paragraph variant='h2'>
|
||||
{globalize.translate(noItemsMessage)}
|
||||
<Typography paragraph>
|
||||
{globalize.translate(message)}
|
||||
</Typography>
|
||||
</Box>
|
||||
);
|
||||
|
|
145
src/components/common/SectionContainer.tsx
Normal file
145
src/components/common/SectionContainer.tsx
Normal file
|
@ -0,0 +1,145 @@
|
|||
import React, { type FC, type PropsWithChildren } from 'react';
|
||||
import Box from '@mui/material/Box';
|
||||
import Link from '@mui/material/Link';
|
||||
import Typography from '@mui/material/Typography';
|
||||
import ChevronRightIcon from '@mui/icons-material/ChevronRight';
|
||||
import classNames from 'classnames';
|
||||
import ItemsContainer, {
|
||||
type ItemsContainerProps
|
||||
} from 'elements/emby-itemscontainer/ItemsContainer';
|
||||
import Scroller, { type ScrollerProps } from 'elements/emby-scroller/Scroller';
|
||||
import Cards from 'components/cardbuilder/Card/Cards';
|
||||
import Lists from 'components/listview/List/Lists';
|
||||
import type { CardOptions } from 'types/cardOptions';
|
||||
import type { ListOptions } from 'types/listOptions';
|
||||
import type { ItemDto } from 'types/base/models/item-dto';
|
||||
|
||||
interface SectionHeaderProps {
|
||||
className?: string;
|
||||
itemsLength?: number;
|
||||
url?: string;
|
||||
title: string;
|
||||
}
|
||||
|
||||
const SectionHeader: FC<SectionHeaderProps> = ({
|
||||
title,
|
||||
className,
|
||||
itemsLength = 0,
|
||||
url
|
||||
}) => {
|
||||
const sectionHeaderClass = classNames(
|
||||
'sectionTitleContainer sectionTitleContainer-cards',
|
||||
'padded-left',
|
||||
className
|
||||
);
|
||||
|
||||
return (
|
||||
<Box className={sectionHeaderClass}>
|
||||
{url && itemsLength > 5 ? (
|
||||
<Link
|
||||
className='clearLink button-flat sectionTitleTextButton'
|
||||
underline='none'
|
||||
href={url}
|
||||
>
|
||||
<Typography
|
||||
className='sectionTitle sectionTitle-cards'
|
||||
variant='h2'
|
||||
>
|
||||
{title}
|
||||
</Typography>
|
||||
<ChevronRightIcon sx={{ pt: '5px' }} />
|
||||
</Link>
|
||||
) : (
|
||||
<Typography
|
||||
className='sectionTitle sectionTitle-cards'
|
||||
variant='h2'
|
||||
>
|
||||
{title}
|
||||
</Typography>
|
||||
)}
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
interface SectionContainerProps {
|
||||
className?: string;
|
||||
items?: ItemDto[];
|
||||
sectionHeaderProps?: Omit<SectionHeaderProps, 'itemsLength'>;
|
||||
scrollerProps?: ScrollerProps;
|
||||
itemsContainerProps?: ItemsContainerProps;
|
||||
isListMode?: boolean;
|
||||
isScrollerMode?: boolean;
|
||||
noPadding?: boolean;
|
||||
cardOptions?: CardOptions;
|
||||
listOptions?: ListOptions;
|
||||
}
|
||||
|
||||
const SectionContainer: FC<PropsWithChildren<SectionContainerProps>> = ({
|
||||
className,
|
||||
sectionHeaderProps,
|
||||
scrollerProps,
|
||||
itemsContainerProps,
|
||||
isListMode = false,
|
||||
isScrollerMode = true,
|
||||
noPadding = false,
|
||||
items = [],
|
||||
cardOptions = {},
|
||||
listOptions = {},
|
||||
children
|
||||
}) => {
|
||||
const sectionClass = classNames('verticalSection', className);
|
||||
|
||||
const renderItems = () => {
|
||||
if (React.isValidElement(children)) {
|
||||
return children;
|
||||
}
|
||||
|
||||
if (isListMode && !isScrollerMode) {
|
||||
return <Lists items={items} listOptions={listOptions} />;
|
||||
} else {
|
||||
return <Cards items={items} cardOptions={cardOptions} />;
|
||||
}
|
||||
};
|
||||
|
||||
const content = (
|
||||
<ItemsContainer
|
||||
className={classNames(
|
||||
{ scrollSlider: isScrollerMode },
|
||||
itemsContainerProps?.className
|
||||
)}
|
||||
{...itemsContainerProps}
|
||||
>
|
||||
{renderItems()}
|
||||
</ItemsContainer>
|
||||
);
|
||||
|
||||
return (
|
||||
<Box className={sectionClass}>
|
||||
{sectionHeaderProps?.title && (
|
||||
<SectionHeader
|
||||
className={classNames(
|
||||
{ 'no-padding': noPadding },
|
||||
sectionHeaderProps?.className
|
||||
)}
|
||||
itemsLength={items.length}
|
||||
{...sectionHeaderProps}
|
||||
/>
|
||||
)}
|
||||
{isScrollerMode && !isListMode ? (
|
||||
<Scroller
|
||||
className={classNames(
|
||||
{ 'no-padding': noPadding },
|
||||
scrollerProps?.className
|
||||
)}
|
||||
{...scrollerProps}
|
||||
>
|
||||
{content}
|
||||
</Scroller>
|
||||
) : (
|
||||
content
|
||||
)}
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default SectionContainer;
|
Loading…
Add table
Add a link
Reference in a new issue