feat: create new dialog component using radix-ui primitives

This commit is contained in:
Nicolas Meienberger 2023-04-07 13:05:56 +02:00
parent 5f0ffbf6dc
commit 67b9c43ae1
3 changed files with 105 additions and 0 deletions

View file

@ -0,0 +1,36 @@
@keyframes zoomIn {
0% {
transform: scale(0.8);
}
50% {
transform: scale(1.05);
}
100% {
transform: scale(1);
}
}
@keyframes dimmedBackground {
from {
background-color: rgba(0, 0, 0, 0);
}
to {
background-color: rgba(0, 0, 0, 0.5);
}
}
.dimmedBackground {
animation-name: dimmedBackground;
animation-duration: 0.2s;
animation-iteration-count: 1;
animation-timing-function: ease-in-out;
animation-fill-mode: forwards;
}
.zoomIn {
animation-name: zoomIn;
animation-duration: 0.25s;
animation-iteration-count: 1;
animation-timing-function: spring;
animation-fill-mode: forwards;
}

View file

@ -0,0 +1,68 @@
'use client';
import * as React from 'react';
import * as DialogPrimitive from '@radix-ui/react-dialog';
import clsx from 'clsx';
import styles from './Dialog.module.scss';
type Sizes = 'sm' | 'md' | 'lg' | 'xl';
type ModalType = 'default' | 'primary' | 'success' | 'info' | 'warning' | 'danger';
type ModalProps = {
size?: Sizes;
type?: ModalType;
};
const Dialog = DialogPrimitive.Root;
const DialogTrigger = DialogPrimitive.Trigger;
const DialogPortal = ({ className, children, ...props }: DialogPrimitive.DialogPortalProps & ModalProps) => (
<DialogPrimitive.Portal className={clsx(className)} {...props}>
<div className={clsx('modal modal-sm d-block', styles.dimmedBackground)}>
<div className={clsx(`modal-dialog modal-dialog-centered modal-${props.size || 'lg'}`, styles.zoomIn)}>
<div className="shadow modal-content">
<DialogPrimitive.Close className="btn-close mt-1">
<button data-testid="modal-close-button" type="button" className="btn-close" aria-label="Close" />
</DialogPrimitive.Close>
<div data-testid="modal-status" className={clsx('modal-status', { [`bg-${props.type}`]: Boolean(props.type), 'd-none': !props.type })} />
{children}
</div>
</div>
</div>
</DialogPrimitive.Portal>
);
DialogPortal.displayName = DialogPrimitive.Portal.displayName;
const DialogOverlay = React.forwardRef<React.ElementRef<typeof DialogPrimitive.Overlay>, React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>>(({ className, children, ...props }, ref) => (
<DialogPrimitive.Overlay className={clsx('', className)} {...props} ref={ref} />
));
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
const DialogContent = React.forwardRef<React.ElementRef<typeof DialogPrimitive.Content>, React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content> & ModalProps>(
({ className, children, ...props }, ref) => (
<DialogPortal type={props.type} size={props.size}>
<DialogPrimitive.Content ref={ref} className={clsx('modal-content mt-1', className)} {...props}>
{children}
</DialogPrimitive.Content>
</DialogPortal>
),
);
DialogContent.displayName = DialogPrimitive.Content.displayName;
const DialogHeader = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => <div data-testid="modal-header" className={clsx('modal-header', className)} {...props} />;
DialogHeader.displayName = 'DialogHeader';
const DialogFooter = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => <div className={clsx('modal-footer', className)} {...props} />;
DialogFooter.displayName = 'DialogFooter';
const DialogTitle = React.forwardRef<React.ElementRef<typeof DialogPrimitive.Title>, React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>>(({ className, ...props }, ref) => (
<DialogPrimitive.Title ref={ref} className={clsx('modal-title', className)} {...props} />
));
DialogTitle.displayName = DialogPrimitive.Title.displayName;
const DialogDescription = React.forwardRef<React.ElementRef<typeof DialogPrimitive.Description>, React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description>>(({ className, ...props }, ref) => (
<DialogPrimitive.Description ref={ref} className={clsx('modal-body', className)} {...props} />
));
DialogDescription.displayName = DialogPrimitive.Description.displayName;
export { Dialog, DialogTrigger, DialogContent, DialogHeader, DialogFooter, DialogTitle, DialogDescription };

View file

@ -0,0 +1 @@
export { Dialog, DialogTitle, DialogFooter, DialogHeader, DialogContent, DialogTrigger, DialogDescription } from './Dialog';