Skip to content

Commit 448d717

Browse files
committed
feat: add VModal
1 parent ada892f commit 448d717

File tree

10 files changed

+616
-10
lines changed

10 files changed

+616
-10
lines changed
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<script setup lang="ts">
2+
const isOpen = ref(false)
3+
const hasLeave = ref(!isOpen.value)
4+
5+
const alignments = ['top-left', 'top', 'top-right', 'right', 'bottom-right', 'bottom', 'bottom-left', 'left']
6+
const selectedAlign = ref('')
7+
8+
function onSelect(event: Event) {
9+
const el = event.target as HTMLSelectElement
10+
selectedAlign.value = el.options[el.selectedIndex].value
11+
}
12+
13+
function open() {
14+
isOpen.value = true
15+
hasLeave.value = false
16+
}
17+
</script>
18+
19+
<template>
20+
<NuxtStory :class="$style.root">
21+
<template #aside>
22+
<p>Modal position on enter:</p>
23+
<br />
24+
<select id="alignment-select" name="alignments" @input="onSelect">
25+
<option value="">--Please choose an alignment--</option>
26+
<option v-for="alignment in alignments" :key="alignment" :value="alignment">
27+
{{ alignment }}
28+
</option>
29+
</select>
30+
<br />
31+
<br />
32+
<VButton emphasis="primary" @click="open">Open</VButton>
33+
</template>
34+
35+
<VModal
36+
v-if="!hasLeave"
37+
v-model="isOpen"
38+
:align="selectedAlign"
39+
@after-leave="hasLeave = true"
40+
@enter="hasLeave = false"
41+
>
42+
<div :class="$style.content">content</div>
43+
</VModal>
44+
</NuxtStory>
45+
</template>
46+
47+
<style lang="scss" module>
48+
.root {
49+
min-height: 300vh;
50+
}
51+
52+
.content {
53+
min-height: rem(300);
54+
padding: rem(40);
55+
}
56+
</style>
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<script lang="ts" setup>
2+
const isOpen = ref(false)
3+
const hasLeave = ref(!isOpen.value)
4+
5+
function onClick() {
6+
isOpen.value = true
7+
hasLeave.value = false
8+
}
9+
</script>
10+
11+
<template>
12+
<NuxtStory :class="$style.root">
13+
<VButton :class="$style.button" emphasis="secondary" @click="onClick">Open</VButton>
14+
15+
<VModal v-if="!hasLeave" v-model="isOpen" @enter="hasLeave = false" @after-leave="hasLeave = true">
16+
<div :class="$style.content">content test</div>
17+
</VModal>
18+
</NuxtStory>
19+
</template>
20+
21+
<style lang="scss" module>
22+
.root {
23+
min-height: 200vh;
24+
}
25+
26+
.button {
27+
position: sticky;
28+
top: rem(30);
29+
}
30+
31+
.content {
32+
padding: rem(40);
33+
border: 1px solid black;
34+
margin: rem(50);
35+
}
36+
</style>
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<script lang="ts" setup>
2+
const isOpen = ref(false)
3+
const hasLeave = ref(!isOpen.value)
4+
5+
function open() {
6+
isOpen.value = true
7+
hasLeave.value = false
8+
}
9+
</script>
10+
11+
<template>
12+
<NuxtStory :class="$style.root">
13+
<template #aside>
14+
<VButton
15+
emphasis="primary"
16+
@click="open"
17+
>
18+
Open
19+
</VButton>
20+
</template>
21+
22+
<VModal
23+
v-if="!hasLeave"
24+
v-model="isOpen"
25+
:class="$style.modal"
26+
align="bottom"
27+
@enter="hasLeave = false"
28+
@after-leave="hasLeave = true"
29+
>
30+
<div :class="$style.inner">
31+
content
32+
</div>
33+
</VModal>
34+
</NuxtStory>
35+
</template>
36+
37+
<style lang="scss" module>
38+
.root {
39+
min-height: 300vh;
40+
}
41+
42+
.modal {
43+
--v-modal-content-width: #{60vw};
44+
45+
position: absolute;
46+
bottom: 0;
47+
overflow: auto scroll;
48+
width: 100%;
49+
height: 50vh;
50+
min-height: rem(300);
51+
max-height: 100%;
52+
padding: rem(40);
53+
}
54+
55+
.inner {
56+
height: 200vh;
57+
background-color: lightgrey;
58+
}
59+
</style>

0 commit comments

Comments
 (0)