Skip to content

Commit

Permalink
Modal component
Browse files Browse the repository at this point in the history
  • Loading branch information
mdl95r committed Feb 25, 2024
1 parent 4b49985 commit b2e86df
Show file tree
Hide file tree
Showing 4 changed files with 160 additions and 0 deletions.
68 changes: 68 additions & 0 deletions src/components/Modal/Modal.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
@keyframes slide-down {
0% {
top: -100%;
}

100% {
top: 0;
}
}

.modal {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100%;
top: -100%;
pointer-events: none;
transition: opacity .1s ease-in;
z-index: 100;
opacity: 0;

&.open {
pointer-events: all;
animation: slide-down ease-in .2s;
animation-fill-mode: forwards;
opacity: 1;
}

// .modal__backdrop
&__backdrop {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(1, 1, 1, .65);
}

// .modal__body
&__body {
max-height: 100vh;
overflow-y: auto;
overflow: hidden;
position: absolute;
top: 50%;
left: 50%;
max-width: var(--modal-max-width, 500px);
width: 100%;
transform: translate(-50%, -50%);
padding: var(--modal-y-padding, 24px) var(--modal-x-padding, 24px);
background-color: #fff;
}

// .modal__close
&__close {
--button-size-sm: 24px;

position: absolute;
top: 0;
right: 0;
height: 24px;

&:deep(.icon) {
font-size: 16px;
}
}
}
61 changes: 61 additions & 0 deletions src/components/Modal/Modal.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<template>
<Teleport to="body">
<div
ref="modal"
class="modal"
:class="{ 'open': open }"
tabindex="0"
@keydown.esc="closeHandler"
>
<div
class="modal__backdrop"
@click="closeHandler">
</div>

<div class="modal__body">
<Button
icon-left="times"
variant="clear"
size="sm"
shape="square"
class="modal__close"
@click="closeHandler"
/>
<slot />
</div>
</div>
</Teleport>
</template>

<script setup>
import { ref, watch } from 'vue';
import Button from '../Button';
const modal = ref(null);
const props = defineProps({
/**
* v-model:open
*/
open: {
type: Boolean,
default: false,
},
})
const emit = defineEmits(['update:open'])
const closeHandler = () => {
emit('update:open', false);
}
watch(() => props.open, (bool) => {
if (bool) {
modal.value.focus();
}
})
</script>

<style scoped lang="scss">
@use './Modal.scss';
</style>
1 change: 1 addition & 0 deletions src/components/Modal/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './Modal.vue';
30 changes: 30 additions & 0 deletions stories/Modal.stories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import UiModal from "../src/components/Modal";
import UiButton from "../src/components/Button";
import './assets/main.scss';

export default {
title: 'Elements/Modal',
component: UiModal,
tags: ['autodocs'],
};

export const Base = {
render: (args) => ({
components: { UiModal, UiButton },
setup() {
return { args };
},
data() {
return {
isOpen: false,
};
},
template: `
<UiButton @click="isOpen = true">open modal</UiButton>
<UiModal v-bind="args" v-model:open="isOpen">
<p style="text-align: center;">Place content here</p>
</UiModal>
`,
}),
};

0 comments on commit b2e86df

Please sign in to comment.