Untitled
unknown
plain_text
2 years ago
8.5 kB
5
Indexable
<template> <transition name="modal"> <div :style="`z-index: ${zIndex}`" class="modal-mask"> <div class="modal-wrapper"> <template v-if="modalType === 'custom-slot'"> <div class="modal-container" :style="{ width: width }"> <div class="modal-header font-16 font-weight-bold" v-if="!noHeader"> <slot name="header"> {{ title }} </slot> <slot name="close"> <img @click="closeModal()" class="icon-close icon-close-custom-slot" style="cursor: pointer" src="/assets/frontend/images/symbols/icon-close.png" alt="close" /> </slot> </div> <div class="modal-body"> <slot name="body"> default body </slot> </div> <div class="modal-footer" v-if="!noFooter"> <slot name="footer"> <!-- Default Footer --> <button @click="handleConfirm()" class="w-100 modal-button-footer" :style="`background-color: ${confirmButtonColor}`" > {{ buttonTitle }} </button> </slot> </div> </div> </template> <template v-else> <div class="modals-wrapper" :style="`width: ${customWidth};`"> <div class="header" v-if="!noHeader"> <div @click.prevent="closeModal()" class="close-wrapper"> <slot name="close"> <img class="icon-close" src="/assets/frontend/images/symbols/icon-close.png" alt="close" /> </slot> </div> </div> <template v-if="modalType != 'information'"> <slot name="icon"> <div class="icon-modal d-flex justify-content-center" > <img v-if="modalType === 'success'" src="/assets/frontend/images/symbols/icon-success.png" alt="success" /> <img v-else-if="modalType === 'retry'" src="/assets/frontend/images/symbols/icon-warning.png" alt="retry" > <img v-else-if="modalType === 'failed'" src="/assets/frontend/images/symbols/icon-failed.png" alt="failed" > </div> </slot> <slot name="title"> <div class="title d-flex justify-content-center" > <p>{{ title }}</p> </div> </slot> </template> <slot name="description"> <div class="description d-flex justify-content-center" :class="modalType === 'information' ? 'font-14 text-btg' : ''" > <p v-html="description"></p> </div> </slot> <slot name="button"> <div v-if="modalType != 'information'" class="modal-buttons"> <button v-if=" modalType === 'retry' || modalType === 'failed' || modalType === 'success' " @click="handleConfirm()" class="w-100 modal-button-warning" :style="`background-color: ${confirmButtonColor}`" > {{ buttonTitle }} </button> <div v-else-if="modalType === 'confirm'" class="d-flex justify-content-center" style="gap: 20px" > <button @click="handleCancel()" class="button-no" :style="`background-color: ${cancelButtonColor}`" > {{ cancelButtonTitle }} </button> <button @click="handleConfirm()" class="button-yes" :style="`background-color: ${confirmButtonColor}`" > {{ confirmButtonTitle }} </button> </div> </div> </slot> </div> </template> </div> </div> </transition> </template> <script> export default { props: { title: { type: String, default: "", }, description: { type: String, default: "", }, buttonTitle: { type: String, default: "Coba Lagi", }, confirmButtonColor: { type: String, default: "#ff8136" }, cancelButtonColor: { type: String, default: "rgb(221, 51, 51)" }, modalType: { type: String, default: "failed", required: true // retry => Try Again => handleConfirm() // failed => OK => handleConfirm() // success => OK => handleConfirm() // confirm => Yes and No => handleConfirm() dan handleCancel() // information => without button => - // custom-slot => Modal Custom With Slot => if(noFooter == false) handleConfirm() // if (noFooter === true) => without button }, noFooter: { type: Boolean, default: false, }, noHeader: { type: Boolean, default: false, }, width: { type: String, default: "520px", }, customWidth: { type: String, default: "282px", }, cancelButtonTitle: { type: String, default: "Batal" }, confirmButtonTitle: { type: String, default: "Ok" }, zIndex: { type: Number, default: 1060 } }, methods: { closeModal() { this.$emit("close"); }, handleConfirm() { this.$emit("handleConfirm"); }, handleCancel() { this.$emit("handleCancel"); }, }, }; </script> <style scoped> /* Animation */ @keyframes fade-in { 0% { transform: scale(70%) translate(-50%, -50%); } 50% { transform: scale(110%) translate(-50%, -50%); } 100% { transform: scale(100%) translate(-50%, -50%); } } @keyframes fade-out { 0% { transform: scale(100%) translate(-50%, -50%); } 50% { transform: scale(110%) translate(-50%, -50%); } 100% { transform: scale(70%) translate(-50%, -50%); } } @keyframes bounce { 0% { transform: scale(70%); } 50% { transform: scale(110%); } 100% { transform: scale(100%); } } /* Animation */ .modal-container { animation: bounce .4s ease-in; } .modal-header, .modal-body, .modal-footer { padding: 20px 40px !important; } .modal-body { max-height: 600px; overflow-y: scroll; overflow-x: hidden; } .modal-header, .modal-footer { border: none !important; } .modal-footer > * { margin: 0px; } .modals-wrapper { position: fixed; height: auto; background-color: #fff; box-shadow: 2px 1px 10px 0px rgba(0, 0, 0, 0.15); border-radius: 25px; left: 50%; top: 50%; z-index: 9999; transform: translate(-50%, -50%); padding: 20px 30px; animation: fade-in .2s ease-in; } .close-wrapper { position: absolute; top: -11px; right: -11px; display: grid; place-items: center; background-color: #fff; border-radius: 50%; width: 30px; height: 30px; box-shadow: 2px 1px 10px 0px rgba(0, 0, 0, 0.25); cursor: pointer; } .icon-close { width: 15px; height: 15px; } .title p { color: #ff7a00; font-size: 14px; font-weight: 700; margin-top: 12px; } .icon-modal > img { width: 60px; height: 60px; } .description { margin-top: 10px; font-size: 12px; text-align: center; color: #404040; } .modal-buttons button { margin-top: 20px; border: none; height: 35px; border-radius: 8px; color: #fff; font-size: 12px; font-weight: 700; } .modal-button-warning { background: #ff8136; } .button-yes, .button-no { padding: 0.625em 1.1em; } .button-no, .button-yes { /* background-color: rgb(221, 51, 51); */ min-width: 80px; } .modal-button-footer { /* background: #ff8136; */ border: none; padding: 14px; border-radius: 12px; color: #fff; font-size: 16px; font-weight: 700; } .icon-close-custom-slot { filter: brightness(0) invert(1); } @media screen and (max-width: 768px) { .modal-body { max-height: 80%; } .modal-header, .modal-body, .modal-footer { padding: 20px 16px !important; } } </style>
Editor is loading...