Todos os componentes

Dialog Default

Dialog Default é um componente de sobreposição para React e Tailwind CSS, da biblioteca UI Layouts, com licença MIT. Copia e cola no teu projeto.

UI Layouts MIT overlays

O que é

Dialog Default é um componente de sobreposição para React e Tailwind CSS, da biblioteca UI Layouts, com licença MIT. Copia e cola no teu projeto.

Como usar

Abre o componente no catálogo, carrega em copiar, e cola no teu projeto. O prompt copiado leva o código e as regras para o teu agente o reproduzir sem alterar nada.

Abrir no catálogo

Cinco cópias grátis por mês. Sem cartão.

Precisa de

npm i motion lucide-react

Licença

Este componente vem de UI Layouts e é redistribuído sob a licença MIT, que permite uso comercial. O aviso de copyright viaja com o código.

Dialog Default

./registry/components/modal/dialog-default.tsx
'use client';
import { FramerModal, ModalContent } from '@/components/ui/dialog';
import type React from 'react';
import { useState } from 'react';

const DialogDefault: React.FC = () => {
  const [modalOpen, setModalOpen] = useState(false);

  return (
    <div className=' h-full flex justify-center items-center'>
      <button
        onClick={() => setModalOpen(true)}
        className='i h-12  rounded-md border-2 dark:border-[#656fe2] border-[#c0c6fc] dark:bg-[linear-gradient(110deg,#1e2a78,45%,#3749be,55%,#1e2a78)] bg-[linear-gradient(110deg,#3d5af1,45%,#5471ff,55%,#3d5af1)] bg-size-[200%_100%] dark:hover:border-white px-6 font-medium text-white dark:text-white transition-colors focus:outline-hidden focus:ring-2 dark:focus:ring-neutral-400 focus:ring-offset-2 focus:ring-offset-neutral-50'
      >
        Open Dialog
      </button>

      <FramerModal open={modalOpen} setOpen={setModalOpen}>
        <ModalContent>
          <div className='flex flex-col space-y-1.5 text-center sm:text-left'>
            <h2 className='text-lg font-semibold leading-none tracking-tight'>Edit profile</h2>
            <p className='text-sm text-muted-foreground'>
              Make changes to your profile here. Click save when you're done.
            </p>
          </div>
          <div className='grid gap-4 py-4'>
            <div className='grid grid-cols-4 items-center gap-4'>
              <label className='text-sm font-medium leading-none text-right'>Name</label>
              <input
                className='flex h-9 w-full rounded-md border bg-transparent px-3 py-1 text-sm shadow-xs transition-colors placeholder:text-muted-foreground focus-visible:outline-hidden focus-visible:ring-1 disabled:cursor-not-allowed disabled:opacity-50 col-span-3'
                id='name'
                defaultValue='Pedro Duarte'
              />
            </div>
            <div className='grid grid-cols-4 items-center gap-4'>
              <label className='text-sm font-medium leading-none text-right'>Username</label>
              <input
                className='flex h-9 w-full rounded-md border bg-transparent px-3 py-1 text-sm shadow-xs transition-colors placeholder:text-muted-foreground focus-visible:outline-hidden focus-visible:ring-1 disabled:cursor-not-allowed disabled:opacity-50 col-span-3'
                id='username'
                defaultValue='@peduarte'
              />
            </div>
          </div>
          <div className='mt-4'>
            <button
              onClick={() => setModalOpen(false)}
              className='w-full p-3 bg-black dark:bg-white text-white dark:text-black rounded-md'
              type='button'
            >
              Got it, thanks!
            </button>
          </div>
        </ModalContent>
      </FramerModal>
    </div>
  );
};

export default DialogDefault;
./components/ui/dialog.tsx
'use client';
import { X } from 'lucide-react';
import { AnimatePresence, motion } from 'motion/react';
import React, { createContext, type ReactNode, useContext, useEffect, useState } from 'react';

interface ModalContextProps {
  open: boolean;
  setOpen: (open: boolean) => void;
}

const ModalContext = createContext<ModalContextProps | undefined>(undefined);

const useModal = () => {
  const context = useContext(ModalContext);
  if (!context) {
    throw new Error('useModal must be used within a ModalProvider');
  }
  return context;
};

interface FramerModalProps {
  children: ReactNode;
  open?: boolean;
  setOpen?: (open: boolean) => void;
}

export function FramerModal({
  children,
  open: controlledOpen,
  setOpen: controlledSetOpen,
}: FramerModalProps) {
  const [internalOpen, setInternalOpen] = useState(false);
  const open = controlledOpen !== undefined ? controlledOpen : internalOpen;
  const setOpen = controlledSetOpen !== undefined ? controlledSetOpen : setInternalOpen;
  useEffect(() => {
    if (open) {
      document.body.classList.add('overflow-hidden');
    } else {
      document.body.classList.remove('overflow-hidden');
    }

    const handleKeyDown = (event: KeyboardEvent) => {
      if (event.key === 'Escape') {
        setOpen(false);
      }
    };

    document.addEventListener('keydown', handleKeyDown);
    return () => {
      document.removeEventListener('keydown', handleKeyDown);
    };
  }, [open, setOpen]);
  return (
    <ModalContext.Provider value={{ open, setOpen }}>
      <AnimatePresence>
        {open && (
          <motion.div
            initial={{ opacity: 0 }}
            animate={{ opacity: 1 }}
            exit={{ opacity: 0 }}
            className='fixed inset-0 z-50 top-0 left-0 right-0 bottom-0 flex flex-col items-center w-full h-screen justify-center dark:bg-black/90 bg-white/90 backdrop-blur-xs cursor-zoom-out border'
            onClick={() => setOpen(false)}
          >
            <motion.div
              initial={{ opacity: 0, y: 8 }}
              animate={{ opacity: 1, y: 0 }}
              exit={{ opacity: 0, y: 8 }}
              onClick={(e) => e.stopPropagation()}
              className=' w-full max-w-md rounded-xl bg-white/5 p-6 backdrop-blur-2xl border'
            >
              <button className='absolute top-2 right-2' onClick={() => setOpen(false)}>
                <X />
              </button>
              {children}
            </motion.div>
          </motion.div>
        )}
      </AnimatePresence>
    </ModalContext.Provider>
  );
}

export function ModalContent({ children }: { children: ReactNode }) {
  return <>{children}</>;
}

Componentes parecidos