feat: add modal and drawer components and examples (#4229)

* feat: add modal component

* feat: add drawer component

* feat: apply new modal and drawer components to the layout

* chore: typo

* feat: add some unit tests
This commit is contained in:
Vben
2024-08-25 23:40:52 +08:00
committed by GitHub
parent edb55b1fc0
commit 20a3868594
96 changed files with 2700 additions and 743 deletions

View File

@@ -1,12 +1,8 @@
<script setup lang="ts">
import { computed, reactive } from 'vue';
import { useVbenModal } from '@vben-core/popup-ui';
import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
VbenAvatar,
VbenButton,
VbenInputPassword,
@@ -28,28 +24,33 @@ interface RegisterEmits {
defineOptions({
name: 'LockScreenModal',
});
withDefaults(defineProps<Props>(), {
avatar: '',
text: '',
});
const emit = defineEmits<{
submit: RegisterEmits['submit'];
}>();
const [Modal] = useVbenModal({
onConfirm() {
handleSubmit();
},
});
const formState = reactive({
lockScreenPassword: '',
submitted: false,
});
const openModal = defineModel<boolean>('open');
const passwordStatus = computed(() => {
return formState.submitted && !formState.lockScreenPassword
? 'error'
: 'default';
});
function handleClose() {
openModal.value = false;
}
function handleSubmit() {
formState.submitted = true;
if (passwordStatus.value !== 'default') {
@@ -62,51 +63,40 @@ function handleSubmit() {
</script>
<template>
<div>
<Dialog :open="openModal">
<DialogContent
class="top-0 h-full w-full -translate-y-0 border-none p-0 shadow-xl sm:top-[20%] sm:h-[unset] sm:w-[600px] sm:rounded-2xl"
@close="handleClose"
>
<DialogDescription />
<DialogHeader>
<DialogTitle
class="border-border flex h-8 items-center px-5 font-normal"
>
{{ $t('widgets.lockScreen.title') }}
</DialogTitle>
</DialogHeader>
<div
class="mb-10 flex w-full flex-col items-center"
@keypress.enter.prevent="handleSubmit"
>
<div class="w-2/3">
<div class="ml-2 flex w-full flex-col items-center">
<VbenAvatar
:src="avatar"
class="size-24"
dot-class="bottom-0 right-1 border-2 size-4 bg-green-500"
/>
<div class="text-foreground my-6 flex items-center font-medium">
{{ text }}
</div>
</div>
<VbenInputPassword
v-model="formState.lockScreenPassword"
:error-tip="$t('widgets.lockScreen.placeholder')"
:label="$t('widgets.lockScreen.password')"
:placeholder="$t('widgets.lockScreen.placeholder')"
:status="passwordStatus"
name="password"
required
type="password"
/>
<VbenButton class="w-full" @click="handleSubmit">
{{ $t('widgets.lockScreen.screenButton') }}
</VbenButton>
<Modal
:footer="false"
:fullscreen-button="false"
:title="$t('widgets.lockScreen.title')"
>
<div
class="mb-10 flex w-full flex-col items-center px-10"
@keypress.enter.prevent="handleSubmit"
>
<div class="w-full">
<div class="ml-2 flex w-full flex-col items-center">
<VbenAvatar
:src="avatar"
class="size-20"
dot-class="bottom-0 right-1 border-2 size-4 bg-green-500"
/>
<div class="text-foreground my-6 flex items-center font-medium">
{{ text }}
</div>
</div>
</DialogContent>
</Dialog>
</div>
<VbenInputPassword
v-model="formState.lockScreenPassword"
:error-tip="$t('widgets.lockScreen.placeholder')"
:label="$t('widgets.lockScreen.password')"
:placeholder="$t('widgets.lockScreen.placeholder')"
:status="passwordStatus"
name="password"
required
type="password"
/>
<VbenButton class="w-full" @click="handleSubmit">
{{ $t('widgets.lockScreen.screenButton') }}
</VbenButton>
</div>
</div>
</Modal>
</template>