Refactored BaseModal and fixed overflow that is hidden on various modals

This commit is contained in:
Lucas Oliveira 2024-06-10 11:52:37 -03:00
commit f522667cee
2 changed files with 67 additions and 74 deletions

View file

@ -183,8 +183,8 @@ export default function IOModal({
/> />
</div> </div>
</BaseModal.Header> </BaseModal.Header>
<BaseModal.Content> <BaseModal.Content overflowHidden>
<div className="flex h-full flex-col "> <div className="flex h-full flex-col">
<div className="flex-max-width h-full"> <div className="flex-max-width h-full">
<div <div
className={cn( className={cn(

View file

@ -1,4 +1,4 @@
import { ReactNode, useEffect } from "react"; import { ReactNode, useEffect, useMemo } from "react";
import React from "react"; import React from "react";
import { import {
@ -22,7 +22,7 @@ import { modalHeaderType } from "../../types/components";
import { cn } from "../../utils/utils"; import { cn } from "../../utils/utils";
import { switchCaseModalSize } from "./helpers/switch-case-size"; import { switchCaseModalSize } from "./helpers/switch-case-size";
type ContentProps = { children: ReactNode }; type ContentProps = { children: ReactNode; overflowHidden?: boolean };
type HeaderProps = { children: ReactNode; description: string }; type HeaderProps = { children: ReactNode; description: string };
type FooterProps = { children: ReactNode }; type FooterProps = { children: ReactNode };
type TriggerProps = { type TriggerProps = {
@ -32,8 +32,17 @@ type TriggerProps = {
className?: string; className?: string;
}; };
const Content: React.FC<ContentProps> = ({ children }) => { const Content: React.FC<ContentProps> = ({ children, overflowHidden }) => {
return <div className="flex h-full w-full flex-col">{children}</div>; return (
<div
className={cn(
`flex w-full flex-grow flex-col transition-all duration-300`,
overflowHidden ? "overflow-hidden" : "overflow-visible",
)}
>
{children}
</div>
);
}; };
const Trigger: React.FC<TriggerProps> = ({ const Trigger: React.FC<TriggerProps> = ({
children, children,
@ -59,8 +68,12 @@ const Header: React.FC<{
}> = ({ children, description }: modalHeaderType): JSX.Element => { }> = ({ children, description }: modalHeaderType): JSX.Element => {
return ( return (
<DialogHeader> <DialogHeader>
<DialogTitle className="flex items-center">{children}</DialogTitle> <DialogTitle className="line-clamp-1 flex items-center">
<DialogDescription>{description}</DialogDescription> {children}
</DialogTitle>
<DialogDescription className="line-clamp-2">
{description}
</DialogDescription>
</DialogHeader> </DialogHeader>
); );
}; };
@ -75,27 +88,31 @@ const Footer: React.FC<{
dataTestId?: string; dataTestId?: string;
}; };
}> = ({ children, submit }) => { }> = ({ children, submit }) => {
return submit ? ( return (
<div className="flex w-full items-center justify-between"> <div className="flex flex-shrink-0 flex-row-reverse">
{children ?? <div />} {submit ? (
<div className="flex items-center gap-3"> <div className="flex w-full items-center justify-between">
<DialogClose asChild> {children ?? <div />}
<Button variant="outline" type="button"> <div className="flex items-center gap-3">
Cancel <DialogClose asChild>
</Button> <Button variant="outline" type="button">
</DialogClose> Cancel
<Button </Button>
data-testid={submit.dataTestId} </DialogClose>
type="submit" <Button
loading={submit.loading} data-testid={submit.dataTestId}
> type="submit"
{submit.icon && submit.icon} loading={submit.loading}
{submit.label} >
</Button> {submit.icon && submit.icon}
</div> {submit.label}
</Button>
</div>
</div>
) : (
<>{children && children}</>
)}
</div> </div>
) : (
<>{children && children}</>
); );
}; };
interface BaseModalProps { interface BaseModalProps {
@ -159,71 +176,47 @@ function BaseModal({
} }
}, [open]); }, [open]);
const modalContent = useMemo(
() => (
<>
{headerChild}
{ContentChild}
{ContentFooter && ContentFooter}
</>
),
[headerChild, ContentChild, ContentFooter],
);
const contentClasses = cn(
minWidth,
height,
"flex flex-col duration-300 overflow-hidden",
);
//UPDATE COLORS AND STYLE CLASSSES //UPDATE COLORS AND STYLE CLASSSES
return ( return (
<> <>
{type === "modal" ? ( {type === "modal" ? (
<Modal open={open} onOpenChange={setOpen}> <Modal open={open} onOpenChange={setOpen}>
{triggerChild} {triggerChild}
<ModalContent <ModalContent className={contentClasses}>{modalContent}</ModalContent>
className={cn(minWidth, height, "flex flex-col duration-300")}
>
<div className="flex-shrink-0 truncate-doubleline word-break-break-word">
{headerChild}
</div>
<div
className={`flex w-full flex-1 flex-col transition-all duration-300`}
>
{ContentChild}
</div>
{ContentFooter && (
<div className="flex flex-shrink-0 flex-row-reverse">
{ContentFooter}
</div>
)}
</ModalContent>
</Modal> </Modal>
) : ( ) : (
<Dialog open={open} onOpenChange={setOpen}> <Dialog open={open} onOpenChange={setOpen}>
{triggerChild} {triggerChild}
<DialogContent <DialogContent className={contentClasses}>
className={cn(minWidth, height, "flex flex-col duration-300")}
>
<div className="flex-shrink-0 truncate-doubleline word-break-break-word">
{headerChild}
</div>
{onSubmit ? ( {onSubmit ? (
<Form.Root <Form.Root
onSubmit={(event) => { onSubmit={(event) => {
event.preventDefault(); event.preventDefault();
onSubmit(); onSubmit();
}} }}
className="flex min-h-0 flex-1 flex-col gap-6" asChild
> >
<div {modalContent}
className={`flex w-full flex-1 flex-col overflow-hidden transition-all duration-300`}
>
{ContentChild}
</div>
{ContentFooter && (
<div className="flex flex-shrink-0 flex-row-reverse">
{ContentFooter}
</div>
)}
</Form.Root> </Form.Root>
) : ( ) : (
<> modalContent
<div
className={`flex min-h-0 w-full flex-1 flex-col transition-all duration-300`}
>
{ContentChild}
</div>
{ContentFooter && (
<div className="flex flex-shrink-0 flex-row-reverse">
{ContentFooter}
</div>
)}
</>
)} )}
</DialogContent> </DialogContent>
</Dialog> </Dialog>