feat: added card and modal component

This commit is contained in:
akhilmhdh
2023-01-23 22:10:50 +05:30
parent 606a5e5317
commit 89ba80740b
7 changed files with 399 additions and 296 deletions
+5 -3
View File
@@ -34,6 +34,7 @@ export const CardBody = ({ children, className }: CardBodyProps) => (
export type CardProps = {
children: ReactNode;
className?: string;
isFullHeight?: boolean;
isRounded?: boolean;
isPlain?: boolean;
@@ -41,16 +42,17 @@ export type CardProps = {
};
export const Card = forwardRef<HTMLDivElement, CardProps>(
({ children, isFullHeight, isRounded, isHoverable, isPlain }, ref): JSX.Element => {
({ children, isFullHeight, isRounded, isHoverable, isPlain, className }, ref): JSX.Element => {
return (
<div
ref={ref}
className={twMerge(
'flex flex-col w-full text-gray-200 bg-mineshaft shadow-md',
'flex flex-col w-full text-gray-200 bg-mineshaft-700 shadow-md',
isFullHeight && 'h-full',
isRounded && 'rounded-md',
isPlain && 'shadow-none',
isHoverable && 'hover:shadow-xl'
isHoverable && 'hover:shadow-xl',
className
)}
>
{children}
@@ -0,0 +1,33 @@
// eslint-disable-next-line import/no-extraneous-dependencies
import { Meta, StoryObj } from '@storybook/react';
import { Button } from '../Button';
import { Modal, ModalContent, ModalContentProps, ModalTrigger } from './Modal';
const meta: Meta<typeof Modal> = {
title: 'Components/Modal',
component: Modal,
tags: ['v2'],
argTypes: {}
};
export default meta;
type Story = StoryObj<typeof ModalContent>;
const Template = (args: ModalContentProps) => (
<Modal>
<ModalTrigger asChild>
<Button>Open</Button>
</ModalTrigger>
<ModalContent {...args}>Hello world</ModalContent>
</Modal>
);
export const Basic: Story = {
render: (args) => <Template {...args} />,
args: {
title: 'Title',
subTitle: 'Something as subtitle',
footerContent: 'footer content'
}
};
@@ -0,0 +1,55 @@
import { forwardRef, ReactNode } from 'react';
import { faTimes } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import * as DialogPrimitive from '@radix-ui/react-dialog';
import { twMerge } from 'tailwind-merge';
import { Card, CardBody, CardFooter, CardTitle } from '../Card';
import { IconButton } from '../IconButton';
export type ModalContentProps = Omit<DialogPrimitive.DialogContentProps, 'open'> & {
title?: ReactNode;
subTitle?: string;
footerContent?: ReactNode;
};
export const ModalContent = forwardRef<HTMLDivElement, ModalContentProps>(
({ children, title, subTitle, className, footerContent, ...props }, forwardedRef) => (
<DialogPrimitive.Portal>
<DialogPrimitive.Overlay
className="fixed inset-0 w-full h-full animate-fadeIn"
style={{ backgroundColor: 'rgba(0, 0, 0, 0.5)' }}
/>
<DialogPrimitive.Content {...props} ref={forwardedRef}>
<Card
isRounded
className={twMerge(
'fixed max-w-md animate-popIn top-1/2 left-1/2 -translate-y-2/4 -translate-x-2/4',
className
)}
>
{title && <CardTitle subTitle={subTitle}>{title}</CardTitle>}
<CardBody>{children}</CardBody>
{footerContent && <CardFooter>{footerContent}</CardFooter>}
<DialogPrimitive.Close aria-label="Close" asChild>
<IconButton
variant="plain"
ariaLabel="close"
className="absolute top-2.5 right-2.5 text-white hover:bg-gray-600 rounded"
>
<FontAwesomeIcon icon={faTimes} size="sm" className="cursor-pointer" />
</IconButton>
</DialogPrimitive.Close>
</Card>
</DialogPrimitive.Content>
</DialogPrimitive.Portal>
)
);
ModalContent.displayName = 'ModalContent';
export const Modal = DialogPrimitive.Root;
export type ModalProps = DialogPrimitive.DialogProps;
export const ModalTrigger = DialogPrimitive.Trigger;
export type ModalTriggerProps = DialogPrimitive.DialogTriggerProps;
@@ -0,0 +1,2 @@
export type { ModalContentProps, ModalProps, ModalTriggerProps } from './Modal';
export { Modal, ModalContent, ModalTrigger } from './Modal';
+1
View File
@@ -3,4 +3,5 @@ export * from './Card';
export * from './FormControl';
export * from './IconButton';
export * from './Input';
export * from './Modal';
export * from './Select';