Skip to content

Commit

Permalink
feat(vue3/modal): added new slot for custom footers
Browse files Browse the repository at this point in the history
  • Loading branch information
achaaoui-yc committed Nov 19, 2024
1 parent 50b09ca commit 869d4fb
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 15 deletions.
37 changes: 33 additions & 4 deletions packages/vue3/src/_dev/App.vue
Original file line number Diff line number Diff line change
@@ -1,15 +1,40 @@
<script setup lang="ts">
import 'uno.css';
import '../assets/main.css';
import { ref } from 'vue';
import SingleDateInput from '~/components/DateInput/SingleDateInput.vue';
import { reactive } from 'vue';
import Modal from '~/components/Modal/Modal.vue';
import PrimaryButton from '~/components/Button/PrimaryButton.vue';
const date = ref();
const state = reactive({
showModal : false,

Check failure on line 9 in packages/vue3/src/_dev/App.vue

View workflow job for this annotation

GitHub Actions / Run linters

Extra space after key 'showModal'
isLoading : false,

Check failure on line 10 in packages/vue3/src/_dev/App.vue

View workflow job for this annotation

GitHub Actions / Run linters

Extra space after key 'isLoading'
});
const clicked = async () => {
state.isLoading = true;
state.showModal = true;
(await new Promise(r => setTimeout(r, 1000)))

Check failure on line 17 in packages/vue3/src/_dev/App.vue

View workflow job for this annotation

GitHub Actions / Run linters

Promise constructor parameters must be named to match "^_?resolve$"

Check failure on line 17 in packages/vue3/src/_dev/App.vue

View workflow job for this annotation

GitHub Actions / Run linters

Missing semicolon

Check failure on line 17 in packages/vue3/src/_dev/App.vue

View workflow job for this annotation

GitHub Actions / Run linters

Missing semicolon
state.isLoading = false

Check failure on line 18 in packages/vue3/src/_dev/App.vue

View workflow job for this annotation

GitHub Actions / Run linters

Missing semicolon

Check failure on line 18 in packages/vue3/src/_dev/App.vue

View workflow job for this annotation

GitHub Actions / Run linters

Missing semicolon
state.showModal = false

Check failure on line 19 in packages/vue3/src/_dev/App.vue

View workflow job for this annotation

GitHub Actions / Run linters

Missing semicolon

Check failure on line 19 in packages/vue3/src/_dev/App.vue

View workflow job for this annotation

GitHub Actions / Run linters

Missing semicolon
};
</script>

<template>
<div class="container">
<SingleDateInput v-model="date" />
<Modal v-model:visible="state.showModal" title="Edit profile">
<p class="content">
The quick brown fox jumps over the lazy dog.
</p>
<template #footer>
<div class="footer">
<PrimaryButton :disabled="state.isLoading" @click="clicked">Click me</PrimaryButton>

Check warning on line 31 in packages/vue3/src/_dev/App.vue

View workflow job for this annotation

GitHub Actions / Run linters

Expected 1 line break after opening tag (`<PrimaryButton>`), but no line breaks found

Check warning on line 31 in packages/vue3/src/_dev/App.vue

View workflow job for this annotation

GitHub Actions / Run linters

Expected 1 line break before closing tag (`</PrimaryButton>`), but no line breaks found
</div>
</template>
</Modal>
<PrimaryButton @click="state.showModal = true;">
<span>Open Modal</span>
</PrimaryButton>
</div>
</template>

Expand All @@ -23,4 +48,8 @@ const date = ref();
height: 100vh;
gap: 40px;
}
.footer {
display: flex;
justify-content: end;
}
</style>
35 changes: 24 additions & 11 deletions packages/vue3/src/components/Modal/Modal.vue
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
<script lang="ts" setup>
import { onMounted, onUnmounted } from 'vue';
import { onMounted, onUnmounted, ref, useSlots, watchEffect } from 'vue';

Check failure on line 2 in packages/vue3/src/components/Modal/Modal.vue

View workflow job for this annotation

GitHub Actions / Run linters

'watchEffect' is defined but never used
import type { ModalProps } from '~/types';
import Overlay from '~/components/Overlay/Overlay.vue';
import { PrimaryButton, SecondaryButton, TertiaryButton } from '~/components';
import { watch } from 'fs';
const props = withDefaults(defineProps<ModalProps>(), {
title: 'Customer address',
confirmLabel: 'Save',
cancelLabel: 'Cancel',
});
const confirmLabel = ref(props.confirmLabel);
const cancelLabel = ref(props.cancelLabel);
const emit = defineEmits(['update:visible', 'onConfirm']);
const close = () => {
emit('update:visible', false);
Expand All @@ -27,6 +31,10 @@ onMounted(() => {
onUnmounted(() => {
window.removeEventListener('keydown', handleKeypress);
});
const slots = useSlots();
const showCustomFooter = !!slots.footer;
</script>

<template>
Expand All @@ -45,15 +53,20 @@ onUnmounted(() => {
<slot />
</div>
<div class="footer">
<PrimaryButton v-if="!cancelOnly" @click="emit('onConfirm')">
<template v-if="confirmIcon" #icon>
<i :class="confirmIcon" />
</template>
<span>{{ confirmLabel }}</span>
</PrimaryButton>
<SecondaryButton @click="close">
<span>{{ cancelLabel }}</span>
</SecondaryButton>
<div v-if="showCustomFooter">
<slot name="footer" />
</div>
<div v-else class="footer-content">
<PrimaryButton v-if="!cancelOnly" @click="emit('onConfirm')">
<template v-if="confirmIcon" #icon>
<i :class="confirmIcon" />
</template>
<span>{{ confirmLabel }}</span>
</PrimaryButton>
<SecondaryButton @click="close">
<span>{{ cancelLabel }}</span>
</SecondaryButton>
</div>
</div>
</div>
</Transition>
Expand Down Expand Up @@ -84,7 +97,7 @@ onUnmounted(() => {
}
.modal .header,
.modal .footer {
.modal .footer-content {
display: flex;
flex-direction: row-reverse;
align-items: center;
Expand Down

0 comments on commit 869d4fb

Please sign in to comment.