bigbuffet-rw/app/soapbox/components/ui/card/card.tsx

86 lines
2.3 KiB
TypeScript
Raw Normal View History

2022-03-21 11:09:01 -07:00
import classNames from 'classnames';
import React from 'react';
import { defineMessages, useIntl } from 'react-intl';
import { Link } from 'react-router-dom';
2022-03-24 16:56:22 -07:00
import { Text } from 'soapbox/components/ui';
import SvgIcon from 'soapbox/components/ui/icon/svg-icon';
2022-03-24 16:56:22 -07:00
2022-03-21 11:09:01 -07:00
const sizes = {
md: 'p-4 sm:rounded-xl',
lg: 'p-4 sm:p-6 sm:rounded-xl',
xl: 'p-4 sm:p-10 sm:rounded-3xl',
};
const messages = defineMessages({
back: { id: 'card.back.label', defaultMessage: 'Back' },
});
interface ICard {
variant?: 'rounded',
size?: 'md' | 'lg' | 'xl',
className?: string,
2022-04-28 11:05:00 -07:00
children: React.ReactNode,
2022-03-21 11:09:01 -07:00
}
2022-04-28 11:05:00 -07:00
const Card = React.forwardRef<HTMLDivElement, ICard>(({ children, variant, size = 'md', className, ...filteredProps }, ref): JSX.Element => (
2022-03-21 11:09:01 -07:00
<div
ref={ref}
{...filteredProps}
className={classNames({
'space-y-4': true,
'bg-white dark:bg-slate-800 text-black dark:text-white sm:shadow-lg dark:sm:shadow-inset overflow-hidden': variant === 'rounded',
2022-03-21 11:09:01 -07:00
[sizes[size]]: true,
}, className)}
2022-03-21 11:09:01 -07:00
>
{children}
</div>
));
interface ICardHeader {
backHref?: string,
onBackClick?: (event: React.MouseEvent) => void
}
const CardHeader: React.FC<ICardHeader> = ({ children, backHref, onBackClick }): JSX.Element => {
const intl = useIntl();
const renderBackButton = () => {
if (!backHref && !onBackClick) {
return null;
}
const Comp: React.ElementType = backHref ? Link : 'button';
const backAttributes = backHref ? { to: backHref } : { onClick: onBackClick };
return (
2022-03-24 16:56:22 -07:00
<Comp {...backAttributes} className='mr-2 text-gray-900 dark:text-gray-100' aria-label={intl.formatMessage(messages.back)}>
<SvgIcon src={require('@tabler/icons/icons/arrow-left.svg')} className='h-6 w-6' />
<span className='sr-only' data-testid='back-button'>Back</span>
2022-03-21 11:09:01 -07:00
</Comp>
);
};
return (
<div className='mb-4 flex flex-row items-center'>
{renderBackButton()}
{children}
</div>
);
};
interface ICardTitle {
title: string | React.ReactNode
}
const CardTitle = ({ title }: ICardTitle): JSX.Element => (
<Text size='xl' weight='bold' tag='h1' data-testid='card-title'>{title}</Text>
2022-03-21 11:09:01 -07:00
);
const CardBody: React.FC = ({ children }): JSX.Element => (
<div data-testid='card-body'>{children}</div>
2022-03-21 11:09:01 -07:00
);
export { Card, CardHeader, CardTitle, CardBody };