expand
버튼을 눌렀을때, 모달이 켜지고 이미지 갤러리와 info를 보여주는 UI 만들기props
ReactNode
;<aside> 💡 headless ui를 이용해서, 기본적인 Modal을 만든다.
</aside>
'use client';
import { Dialog, Transition } from '@headlessui/react';
import { Fragment, ReactNode } from 'react';
import IconButton from './icon-button';
import { X } from 'lucide-react';
interface ModalProps {
open: boolean;
onClose: () => void;
children: ReactNode;
}
export default function Modal({ open, onClose, children }: ModalProps) {
return (
<Transition show={open} appear as={Fragment}>
<Dialog as='div' className='relative z-10' onClose={onClose}>
<div className='fixed inset-0 bg-black bg-opacity-50'>
<div className='fixed inset-0 overflow-y-auto'>
<div className='flex min-h-full items-center justify-center p-4 text-center'>
<Transition.Child
as={Fragment}
enter='ease-out duration-300'
enterFrom='opacity-0 scale-95'
enterTo='opacity-100 scale-100'
leave='ease-in duration-200'
leaveFrom='opacity-100 scale-100'
leaveTo='opacity-0 scale-95'
>
<Dialog.Panel className='w-full max-w-3xl overflow-hidden rounded-lg text-left align-middle'>
<div className='relative flex w-full items-center overflow-hidden bg-white px-4 pb-8 pt-14 shadow-2xl sm:px-6 sm:pt-8 md:p-6 lg:p-8'>
<div className='absolute right-4 top-4'>
<IconButton onClick={onClose} icon={<X size={15} />} />
</div>
{children}
</div>
</Dialog.Panel>
</Transition.Child>
</div>
</div>
</div>
</Dialog>
</Transition>
);
}
Trigger
Trigger
product data
받아오기import { create } from 'zustand';
import { Product } from '@/types';
interface PreviewModalStore {
isOpen: boolean;
data?: Product;
onOpen: (data: Product) => void;
onClose: () => void;
}
const usePreviewModal = create<PreviewModalStore>((set) => ({
isOpen: false,
data: undefined,
onOpen: (data: Product) => set({ data: data, isOpen: true }),
onClose: () => set({ isOpen: false }),
}));
export default usePreviewModal;
Preview Modal
을 만들기'use client';
import usePreviewModal from '@/hooks/use-preview';
import Modal from './ui/modal';
import Gallery from './gallery';
import Info from './Info';
export default function PreviewModal() {
const previewModal = usePreviewModal();
const product = usePreviewModal((state) => state.data);
if (!product) {
return null;
}
return (
<Modal open={previewModal.isOpen} onClose={previewModal.onClose}>
<div className='grid w-full grid-cols-1 items-start gap-x-6 gap-y-8 sm:grid-cols-12 lg:gap-x-8'>
<div className='sm:col-span-4 lg:col-span-5'>
<Gallery images={product.images} />
</div>
<div className='sm:col-span-8 lg:col-span-7'>
<Info data={product} />
</div>
</div>
</Modal>
);
}