DEV Community

pjdev2d
pjdev2d

Posted on

modals

import { X } from "lucide-react";
import { Btn } from "./button";
import { Flex } from "./layout";
import { cn } from "@/src/utils";

interface Props {
  children: React.ReactNode;
  className?: string;
  title?: string;
  description?: string;
  footer?: React.ReactNode;
  close?: () => void;
}
export function ModalCard({
  children,
  title,
  description,
  footer,
  className,
  close,
}: Props) {
  return (
    <Flex
      direction="column"
      className={cn(
        " bg-white max-h-[90vh] max-w-[90vw] rounded-xl overflow-hidden",
        className,
      )}
    >
      <Flex
        direction="row"
        items="center"
        justify="between"
        className="w-full p-4 border-b"
      >
        <Flex direction="column">
          {title && <span className="font-semibold">{title}</span>}
          {description && <span>{description}</span>}
        </Flex>
        <Btn variant="solid-icon" rounded="full" onClick={close}>
          <X strokeWidth={2.5} />
        </Btn>
      </Flex>

      <div className="w-full min-w-0 overflow-auto p-4">{children}</div>

      <div className="flex justify-end w-full p-4 border-t">{footer}</div>
    </Flex>
  );
}

Enter fullscreen mode Exit fullscreen mode

modal

import { Backdrop } from "./backdrop";
import { type Provider as Props } from "@/root.config";
import { Potral } from "./portal";

interface ModalBaseProps {
  children?: Props.BaseProps["children"];
  onClose?: () => void;
  options: Props.BaseProps["options"];
}

export const Modal = ({ children, onClose, options }: ModalBaseProps) => {
  return (
    <Potral>
      <Backdrop {...options} onClose={onClose}>
        <div className="relative z-10000">{children}</div>
      </Backdrop>
    </Potral>
  );
};

Enter fullscreen mode Exit fullscreen mode

import { X } from "lucide-react";
import { Btn } from "./button";
import { Flex } from "./layout";
import { cn } from "@/src/utils";

interface Props {
  children: React.ReactNode;
  title?: string;
  description?: string;
  className?: string;
  close?: () => void;
}
export function SidePanelCard({
  children,
  title,
  description,
  className,
  close,
}: Props) {
  return (
    <Flex
      direction="column"
      className={cn(
        " bg-white min-h-screen min-w-10 overflow-hidden",
        className,
      )}
    >
      <Flex
        direction="row"
        items="center"
        justify="between"
        className="w-full p-4 border-b"
      >
        <Flex direction="column">
          {title && <span className="font-semibold">{title}</span>}
          {description && <span>{description}</span>}
        </Flex>
        <Btn variant="solid-icon" rounded="full" onClick={close}>
          <X strokeWidth={2.5} />
        </Btn>
      </Flex>

      <Flex direction="row" className="min-h-0 w-auto overflow-y-auto p-4">
        {children}
      </Flex>
    </Flex>
  );
}

Enter fullscreen mode Exit fullscreen mode

sidepanel

import type { ReactNode } from "react";
import { Backdrop } from "./backdrop";
import { type Provider as Props } from "@/root.config";
import { Potral } from "./portal";

interface SidePanelBaseProps {
  children?: ReactNode | string;
  onClose?: () => void;
  options: Props.BaseProps["options"];
}

export function SidePanel({ children, onClose, options }: SidePanelBaseProps) {
  const justify = options?.onSide === "left" ? "start" : "end";
  return (
    <>
      <Potral>
        <Backdrop justify={justify} onClose={() => onClose?.()}>
          <div className="relative z-10000">{children}</div>
        </Backdrop>
      </Potral>
    </>
  );
}

Enter fullscreen mode Exit fullscreen mode

callings

export const Dashboard = () => {
  const { open } = useAppProvider();

  const handleOpenModal = () => {
    open(APP_PROVIDER_TYPE.MODAL, ({ close }) => (
      <ModalCard close={close}> this is modal</ModalCard>
    ));
  };

  const handleOpenSidepanel = () => {
    open(APP_PROVIDER_TYPE.SIDE_PANEL, ({ close }) => (
      <SidePanelCard close={close}>this is side panel</SidePanelCard>
    ));
  };

  return (
    <>
      <Btn
        onClick={() => handleOpenModal()}
        variant="solid"
        className="px-4 py-2 text-sm rounded-lg hover:bg-neutral-100 dark:hover:bg-neutral-800 transition"
      >
        Trigger Global Modal
      </Btn>

      <Btn
        onClick={handleOpenSidepanel}
        variant="solid"
        className="px-4 py-2 text-sm rounded-lg hover:bg-neutral-100 dark:hover:bg-neutral-800 transition"
      >
        Trigger Global Sidepanel
      </Btn>
    </>
  );
};
Enter fullscreen mode Exit fullscreen mode

Top comments (0)