Skip to content

Commit

Permalink
feat : 로딩 Portal 구현
Browse files Browse the repository at this point in the history
  • Loading branch information
guesung committed Aug 23, 2023
1 parent 448c29b commit 7be6fbe
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 22 deletions.
Binary file removed public/lotties/talk_after_loading.png
Binary file not shown.
19 changes: 14 additions & 5 deletions src/app/(Main)/pick/components/PickSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import Lottie from 'react-lottie-player';
import lottiePick from '#/lotties/pick.json';
import { usePosePickQuery } from '@/apis';
import { BottomFixedButton } from '@/components/Button';
import { Loading } from '@/components/Loading';
import { Spacing } from '@/components/Spacing';

const countList = ['1인', '2인', '3인', '4인', '5인+'];
Expand Down Expand Up @@ -36,6 +37,11 @@ export default function PickSection() {

return (
<section className="flex flex-col px-20">
{isLoading && (
<Loading>
<Lottie loop animationData={lottiePick} play style={{ width: '100%', height: '33rem' }} />
</Loading>
)}
<div className="flex justify-evenly rounded-8 py-16">
{countList.map((count) => (
<CountItem
Expand All @@ -50,11 +56,14 @@ export default function PickSection() {
<Spacing size={13} />

<div className="relative h-520">
{isLoading ? (
<Lottie loop animationData={lottiePick} play style={{ width: '100%', height: '100%' }} />
) : (
<Image src={image || '/images/sample.png'} fill alt="sample" priority />
)}
<Image
src={image || '/images/sample.png'}
fill
alt="sample"
priority
loading="eager"
className={isLoading ? 'hidden' : ''}
/>
</div>

<BottomFixedButton className="bg-main-violet text-white" onClick={handlePickClick}>
Expand Down
27 changes: 19 additions & 8 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { StrictPropsWithChildren } from '@/types';
import '../../styles/font.css';
import '../../styles/typography.css';
import './globals.css';
Expand Down Expand Up @@ -47,14 +48,24 @@ export const metadata: Metadata = {

export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="ko">
<body className="flex h-[100dvh] w-screen touch-none justify-center bg-slate-100 py-px">
<div className="h-full w-full max-w-440 bg-white text-primary drop-shadow-2xl">
<QueryProvider>
<OverlayProvider>{children}</OverlayProvider>
</QueryProvider>
<div id="portal" />
</div>
<Layout>
<QueryProvider>
<OverlayProvider>{children}</OverlayProvider>
</QueryProvider>
<div id="loading" />
<div id="portal" />
</Layout>
);
}

function Layout({ children }: StrictPropsWithChildren) {
return (
<html
lang="ko"
className="flex h-[100dvh] w-screen touch-none justify-center bg-slate-100 py-px"
>
<body className="h-full w-full max-w-440 bg-white text-primary drop-shadow-2xl">
{children}
</body>
</html>
);
Expand Down
13 changes: 13 additions & 0 deletions src/components/Loading/Loading.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import PortalWrapper from '../Modal/PortalWrapper';
import { Portal } from '../Portal';
import { StrictPropsWithChildren } from '@/types';

export default function Loading({ children }: StrictPropsWithChildren) {
return (
<Portal documentId="loading">
<PortalWrapper isBackGroundBlur={false} className="top-190">
{children}
</PortalWrapper>
</Portal>
);
}
1 change: 1 addition & 0 deletions src/components/Loading/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as Loading } from './Loading';
20 changes: 11 additions & 9 deletions src/components/Modal/PortalWrapper.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use client';
import clsx from 'clsx';
import { useRef } from 'react';
import { twMerge } from 'tailwind-merge';

import { AnimatedPortal } from '../Portal';
import { useOnClickOutside } from '@/hooks/useOnClickOutside';
Expand All @@ -10,12 +11,14 @@ import type { StrictPropsWithChildren } from '@/types';
interface PortalWrapperProps {
onClose?: () => void;
isBackGroundBlur?: boolean;
className?: string;
}

export default function PortalWrapper({
onClose = () => {},
children,
isBackGroundBlur = true,
className,
}: StrictPropsWithChildren<PortalWrapperProps>) {
const portalRef = useRef<HTMLDivElement>(null);

Expand All @@ -26,16 +29,15 @@ export default function PortalWrapper({
motionProps={{ initial: { opacity: 0 }, animate: { opacity: 1 }, exit: { opacity: 0 } }}
>
<div
className={clsx('fixed left-1/2 top-0 z-10 h-full w-full max-w-440 -translate-x-1/2', {
'bg-neutral-900 bg-opacity-90': isBackGroundBlur,
})}
className={clsx(
'fixed left-1/2 top-0 z-10 h-full w-full max-w-440 -translate-x-1/2',
{
'bg-neutral-900 bg-opacity-90': isBackGroundBlur,
},
className
)}
>
<div
ref={portalRef}
className="absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 "
>
{children}
</div>
{children}
</div>
</AnimatedPortal>
);
Expand Down

0 comments on commit 7be6fbe

Please sign in to comment.