2026-05-31 11:51:52 +03:30
|
|
|
<template>
|
|
|
|
|
<BasicModal
|
|
|
|
|
v-if="!isMobileView"
|
|
|
|
|
:key="`action-sheet-modal-${overlayKey}`"
|
|
|
|
|
v-model:visible="visibleProxy"
|
|
|
|
|
:title="title"
|
|
|
|
|
:width="modalWidth"
|
|
|
|
|
:loading="loading"
|
|
|
|
|
custom-footer
|
|
|
|
|
@close="handleCancel"
|
|
|
|
|
@ok="$emit('ok')"
|
|
|
|
|
>
|
|
|
|
|
<slot />
|
|
|
|
|
<template #footer>
|
|
|
|
|
<div
|
|
|
|
|
v-if="showButton && (showCancel || showOk)"
|
|
|
|
|
class="grid gap-3"
|
|
|
|
|
:class="[!showOk || !showCancel ? 'grid-cols-1' : 'grid-cols-12']"
|
|
|
|
|
>
|
|
|
|
|
<AButton
|
|
|
|
|
v-if="showCancel"
|
|
|
|
|
type="primary"
|
|
|
|
|
:class="[{ 'col-span-4': showOk }]"
|
|
|
|
|
size="large"
|
|
|
|
|
ghost
|
|
|
|
|
block
|
|
|
|
|
@click="handleCancel"
|
|
|
|
|
>
|
|
|
|
|
{{ cancelText }}
|
|
|
|
|
</AButton>
|
|
|
|
|
<AButton
|
|
|
|
|
v-if="showOk"
|
|
|
|
|
type="primary"
|
|
|
|
|
:class="[{ 'col-span-8': showCancel }]"
|
|
|
|
|
size="large"
|
|
|
|
|
block
|
|
|
|
|
@click="$emit('ok')"
|
|
|
|
|
>
|
|
|
|
|
{{ okText }}
|
|
|
|
|
</AButton>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
</BasicModal>
|
|
|
|
|
|
|
|
|
|
<ADrawer
|
|
|
|
|
v-else-if="isMobileView"
|
|
|
|
|
:key="`action-sheet-drawer-${overlayKey}`"
|
|
|
|
|
v-model:visible="visibleProxy"
|
|
|
|
|
placement="bottom"
|
|
|
|
|
:closable="false"
|
|
|
|
|
:destroy-on-close="true"
|
|
|
|
|
:height="drawerHeight"
|
2026-06-03 17:51:27 +03:30
|
|
|
:z-index="ACTION_SHEET_Z_INDEX"
|
2026-06-04 22:35:57 +03:30
|
|
|
:class="['basic-action-sheet', { 'basic-action-sheet--compact': compact }]"
|
2026-05-31 11:51:52 +03:30
|
|
|
>
|
2026-06-04 22:35:57 +03:30
|
|
|
<div class="basic-action-sheet__container" :class="{ 'basic-action-sheet__container--compact': compact }">
|
2026-05-31 11:51:52 +03:30
|
|
|
<div class="flex cursor-pointer justify-center pt-2" @click="visibleProxy = false">
|
|
|
|
|
<span class="w-12 rounded-sm border-t-2 border-t-solid border-t-gray-500"></span>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="basic-action-sheet__content">
|
|
|
|
|
<slot />
|
|
|
|
|
</div>
|
|
|
|
|
<div
|
|
|
|
|
v-if="showButton && (showCancel || showOk)"
|
|
|
|
|
class="basic-action-sheet__footer grid gap-3"
|
|
|
|
|
:class="[!showOk || !showCancel ? 'grid-cols-1' : 'grid-cols-12']"
|
|
|
|
|
>
|
|
|
|
|
<AButton
|
|
|
|
|
v-if="showCancel"
|
|
|
|
|
type="primary"
|
|
|
|
|
:class="[{ 'col-span-4': showOk }]"
|
|
|
|
|
size="large"
|
|
|
|
|
ghost
|
|
|
|
|
block
|
|
|
|
|
@click="handleCancel"
|
|
|
|
|
>
|
|
|
|
|
{{ cancelText }}
|
|
|
|
|
</AButton>
|
|
|
|
|
<AButton
|
|
|
|
|
v-if="showOk"
|
|
|
|
|
type="primary"
|
|
|
|
|
:class="[{ 'col-span-8': showCancel }]"
|
|
|
|
|
size="large"
|
|
|
|
|
block
|
|
|
|
|
@click="$emit('ok')"
|
|
|
|
|
>
|
|
|
|
|
{{ okText }}
|
|
|
|
|
</AButton>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</ADrawer>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script lang="ts" setup>
|
|
|
|
|
import { computed } from 'vue'
|
|
|
|
|
|
|
|
|
|
import BasicModal from '@/components/BasicModal.vue'
|
|
|
|
|
import { ACTION_SHEET_HEIGHT } from '@/constants/actionSheet'
|
2026-06-03 17:51:27 +03:30
|
|
|
import { ACTION_SHEET_Z_INDEX } from '@/constants/overlayZIndex'
|
2026-05-31 11:51:52 +03:30
|
|
|
import { isMobile } from '@core/utils/is'
|
|
|
|
|
|
|
|
|
|
interface Props {
|
|
|
|
|
visible?: boolean
|
|
|
|
|
title?: string
|
|
|
|
|
modalWidth?: string
|
|
|
|
|
loading?: boolean
|
|
|
|
|
drawerHeight?: string
|
2026-06-04 22:35:57 +03:30
|
|
|
compact?: boolean
|
2026-05-31 11:51:52 +03:30
|
|
|
cancelText?: string
|
|
|
|
|
showButton?: boolean
|
|
|
|
|
showCancel?: boolean
|
|
|
|
|
showOk?: boolean
|
|
|
|
|
okText?: string
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const props = withDefaults(defineProps<Props>(), {
|
|
|
|
|
visible: false,
|
|
|
|
|
title: '',
|
|
|
|
|
modalWidth: '36rem',
|
|
|
|
|
loading: false,
|
|
|
|
|
drawerHeight: ACTION_SHEET_HEIGHT,
|
2026-06-04 22:35:57 +03:30
|
|
|
compact: false,
|
2026-05-31 11:51:52 +03:30
|
|
|
cancelText: 'بازگشت',
|
|
|
|
|
showButton: false,
|
|
|
|
|
showCancel: true,
|
|
|
|
|
showOk: true,
|
|
|
|
|
okText: 'ثبت'
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
const emit = defineEmits<{
|
|
|
|
|
(e: 'update:visible', value: boolean): void
|
|
|
|
|
(e: 'update:show', value: boolean): void
|
|
|
|
|
(e: 'ok'): void
|
|
|
|
|
(e: 'cancel'): void
|
|
|
|
|
(e: 'close'): void
|
|
|
|
|
}>()
|
|
|
|
|
|
|
|
|
|
const isMobileView = computed(() => isMobile.value)
|
|
|
|
|
const overlayKey = computed(() => (isMobileView.value ? 'drawer' : 'modal'))
|
|
|
|
|
|
|
|
|
|
const visibleProxy = computed({
|
|
|
|
|
get: () => props.visible,
|
|
|
|
|
set: (value: boolean) => {
|
|
|
|
|
emit('update:visible', value)
|
|
|
|
|
emit('update:show', value)
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
function handleCancel() {
|
|
|
|
|
emit('cancel')
|
|
|
|
|
emit('close')
|
|
|
|
|
visibleProxy.value = false
|
|
|
|
|
}
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<style lang="less">
|
|
|
|
|
.basic-action-sheet {
|
|
|
|
|
.ant-drawer-content {
|
|
|
|
|
border-radius: 16px 16px 0 0;
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.ant-drawer-body {
|
|
|
|
|
padding: 0;
|
|
|
|
|
height: 100%;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.basic-action-sheet__container {
|
|
|
|
|
height: 100%;
|
|
|
|
|
min-height: 100%;
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.basic-action-sheet__content {
|
|
|
|
|
flex: 1;
|
|
|
|
|
overflow-y: auto;
|
|
|
|
|
padding: 0 16px 12px;
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-04 22:35:57 +03:30
|
|
|
.basic-action-sheet--compact {
|
|
|
|
|
.ant-drawer-content-wrapper {
|
|
|
|
|
height: auto !important;
|
|
|
|
|
max-height: 88vh;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.ant-drawer-content {
|
|
|
|
|
height: auto !important;
|
|
|
|
|
max-height: 88vh;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.basic-action-sheet__container--compact {
|
|
|
|
|
height: auto;
|
|
|
|
|
min-height: 0;
|
|
|
|
|
max-height: 88vh;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.basic-action-sheet__container--compact .basic-action-sheet__content {
|
|
|
|
|
flex: 0 1 auto;
|
|
|
|
|
max-height: calc(88vh - 40px);
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-31 11:51:52 +03:30
|
|
|
.basic-action-sheet__footer {
|
|
|
|
|
position: sticky;
|
|
|
|
|
bottom: 0;
|
|
|
|
|
z-index: 2;
|
2026-06-14 21:04:26 +03:30
|
|
|
background: var(--admin-bg-elevated);
|
2026-05-31 11:51:52 +03:30
|
|
|
padding: 8px 16px calc(16px + env(safe-area-inset-bottom));
|
2026-06-14 21:04:26 +03:30
|
|
|
border-top: 1px solid var(--admin-border);
|
2026-05-31 11:51:52 +03:30
|
|
|
}
|
|
|
|
|
</style>
|