forked from TEAM-MAT/lockerweb
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #64 from EATSTEAK/feat/modal
Modal 기능 구현 및 디자인 수정
- Loading branch information
Showing
3 changed files
with
145 additions
and
69 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -37,4 +37,12 @@ h4 { | |
@apply text-2xl; | ||
} | ||
|
||
h5 { | ||
@apply text-xl; | ||
} | ||
|
||
h6 { | ||
@apply text-lg; | ||
} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,94 +1,145 @@ | ||
<script lang="ts"> | ||
import Button from "../atom/Button.svelte"; | ||
import Dismiss from "../../icons/Dismiss.svelte"; | ||
</script> | ||
<script lang='ts'> | ||
import Button from '../atom/Button.svelte'; | ||
import Dismiss from '../../icons/Dismiss.svelte'; | ||
import { createEventDispatcher } from 'svelte'; | ||
<dialog open class="modal-frame"> | ||
<div class="title-section"> | ||
<div class="text"> | ||
<h3 class="modal-title">MODAL</h3> | ||
<h3 class="modal-subtitle">SUBTITLE</h3> | ||
</div> | ||
<div class="close-btn"> | ||
<span class="dismiss-icon-wrap"><Dismiss /></span> | ||
</div> | ||
</div> | ||
<div class="content-section"> | ||
<slot /> | ||
</div> | ||
<div class="button-section"> | ||
<Button isIconRight="{false}" class="confirm-btn bg-[#7088DF] text-2xl text-white"> | ||
확인 | ||
</Button> | ||
<Button isIconRight="{false}" class="cancel-btn bg-[#D8D8D8] text-2xl text-gray-600 px-3"> | ||
취소 | ||
</Button> | ||
</div> | ||
</dialog> | ||
<div class="background"></div> | ||
export let open: boolean = false; | ||
export let title: string; | ||
export let subtitle: string = ''; | ||
export let noBackdrop: boolean = false; | ||
<style> | ||
.modal-frame { | ||
@apply | ||
grow | ||
export let primaryText: string = '확인'; | ||
export let secondaryText: string = '취소'; | ||
p-2 | ||
let clazz = ''; | ||
export { clazz as class }; | ||
bg-gray-200 | ||
const dispatch = createEventDispatcher(); | ||
-translate-y-1/2 | ||
top-1/2 | ||
let dialog; | ||
rounded-[19px] fixed z-30 | ||
flex-col | ||
overflow-hidden | ||
$: if (open) { | ||
if (!noBackdrop && dialog) dialog.showModal(); | ||
} else { | ||
if(!noBackdrop && dialog) dialog.close(); | ||
} | ||
transition-all; | ||
} | ||
.modal-frame:hover{ | ||
@apply drop-shadow-xl; | ||
function closeModal() { | ||
dispatch('close', {}); | ||
} | ||
function click(btnType: 'primary' | 'secondary') { | ||
if (btnType === 'primary') { | ||
dispatch('click', {}); | ||
} else if (btnType === 'secondary') { | ||
dispatch('click:secondary', {}); | ||
} | ||
} | ||
function outClick(event) { | ||
const rect = dialog.getBoundingClientRect(); | ||
const isInDialog=(rect.top <= event.clientY && event.clientY <= rect.top + rect.height | ||
&& rect.left <= event.clientX && event.clientX <= rect.left + rect.width); | ||
if (!isInDialog) { | ||
closeModal(); | ||
} | ||
} | ||
</script> | ||
|
||
<dialog on:click={outClick} bind:this={dialog} {open} class={`modal-frame ${clazz}`} {...$$restProps}> | ||
<div class='wrap'> | ||
<div class='section-title'> | ||
<div class='text'> | ||
<h4>{title}</h4> | ||
{#if subtitle}<h5>{subtitle}</h5>{/if} | ||
</div> | ||
<button on:click={closeModal} class='close-btn'> | ||
<Dismiss /> | ||
</button> | ||
</div> | ||
<div class='section-contents'> | ||
<slot /> | ||
</div> | ||
<div class='section-actions'> | ||
<slot name='actions'> | ||
<Button on:click={() => click('secondary')} class='secondary-btn bg-[#D8D8D8] text-gray-600'> | ||
{secondaryText} | ||
</Button> | ||
<Button on:click={() => click('primary')} class='primary-btn bg-[#7088DF] text-white'> | ||
{primaryText} | ||
</Button> | ||
</slot> | ||
</div> | ||
</div> | ||
</dialog> | ||
|
||
<style> | ||
.modal-frame { | ||
@apply grow bg-gray-200 | ||
rounded-xl | ||
fixed | ||
p-4 | ||
z-50 | ||
overflow-hidden | ||
transition-all | ||
shadow-xl | ||
md:w-[480px]; | ||
} | ||
.title-section { | ||
@apply w-full h-[16%] px-2 relative select-none; | ||
.wrap { | ||
@apply flex flex-col items-stretch gap-3 w-full h-full; | ||
} | ||
.modal-title { | ||
@apply text-[3rem] text-gray-700 pt-1; | ||
.section-title { | ||
@apply -mx-4 -mt-4 flex justify-between select-none; | ||
} | ||
.modal-subtitle{ | ||
@apply text-3xl text-gray-700; | ||
.text { | ||
@apply pl-4 pt-3 text-gray-700; | ||
} | ||
.close-btn { | ||
@apply w-[70px] h-[50px] bg-gray-300 absolute -top-5 -right-5 rounded-bl-[20px] cursor-pointer transition-all font-extrabold text-center text-2xl pl-[20px] pt-4; | ||
@apply w-14 h-10 bg-gray-300 rounded-bl-[20px] cursor-pointer transition-all text-center text-2xl flex justify-center items-center; | ||
} | ||
.close-btn:hover{ | ||
@apply bg-[#7088DF] text-white drop-shadow-2xl translate-x-[2px]; | ||
} | ||
.close-btn:hover .dismiss-icon-wrap{ | ||
filter: none; | ||
} | ||
.dismiss-icon-wrap { | ||
filter: invert(59%) sepia(91%) saturate(0%) hue-rotate(134deg) brightness(82%) contrast(83%); | ||
.close-btn:hover { | ||
@apply bg-[#7088DF] text-white; | ||
} | ||
.content-section { | ||
@apply w-full h-4/6 mb-4; | ||
} | ||
.button-section { | ||
@apply flex justify-end gap-3 pr-3; | ||
.section-contents { | ||
@apply grow; | ||
} | ||
:global(.confirm-btn) { | ||
@apply h-[53px] pt-[10px] | ||
.section-actions { | ||
@apply flex justify-end gap-3; | ||
} | ||
:global(.cancel-btn) { | ||
@apply h-[53px] pt-[10px] px-6 bg-[#D8D8D8] border-[1px] border-[#CECECE] cursor-pointer text-2xl font-bold; | ||
.section-actions :global(.secondary-btn) { | ||
@apply bg-[#D8D8D8] border-[1px] border-[#CECECE]; | ||
} | ||
:global(.cancel-btn:hover){ | ||
.section-actions :global(.secondary-btn:hover) { | ||
@apply bg-[#EDEDED]; | ||
} | ||
.background { | ||
@apply w-screen h-screen z-10 fixed bg-black opacity-50; | ||
dialog::backdrop { | ||
@apply bg-black opacity-30; | ||
} | ||
dialog[open] { | ||
animation: show 0.1s ease normal; | ||
} | ||
@keyframes show { | ||
from { | ||
transform: translateY(-5%); | ||
opacity: 0; | ||
} | ||
to { | ||
transform: translateY(0%); | ||
opacity: 1; | ||
} | ||
} | ||
</style> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<script lang="ts"> | ||
import Button from "../../components/atom/Button.svelte"; | ||
import Modal from "../../components/molecule/Modal.svelte"; | ||
let open = false; | ||
function openModal() { | ||
open = true; | ||
} | ||
</script> | ||
|
||
<Modal on:close={() => open = false} bind:open title="축하합니다!" subtitle="테스트 페이지를 찾았다!"> | ||
테스트 페이지를 찾으셨습니다! 보상은 뿌듯함..이랄까? | ||
</Modal> | ||
<div> | ||
<Button on:click={openModal}>모달 열기</Button> | ||
</div> |