fixed price
This commit is contained in:
@@ -1,6 +1,14 @@
|
||||
<template>
|
||||
<div>
|
||||
<DatePicker :locale="locale" v-model:value="_date" :size="props.size" v-bind="_attrs" inputReadOnly/>
|
||||
<div ref="rootRef" @click="onWrapperClick">
|
||||
<DatePicker
|
||||
:locale="locale"
|
||||
v-model:value="_date"
|
||||
:size="props.size"
|
||||
v-bind="_attrs"
|
||||
:open="open"
|
||||
inputReadOnly
|
||||
@openChange="onOpenChange"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -9,7 +17,7 @@ import DatePicker from './datePick'
|
||||
import locale from 'ant-design-vue/es/date-picker/locale/fa_IR'
|
||||
import dayjs, { Dayjs } from 'dayjs'
|
||||
import { omit } from 'lodash'
|
||||
import { computed, useAttrs } from 'vue'
|
||||
import { computed, onBeforeUnmount, onMounted, ref, useAttrs } from 'vue'
|
||||
|
||||
interface Props {
|
||||
value?: string | Dayjs
|
||||
@@ -34,12 +42,71 @@ const emit = defineEmits<{
|
||||
(e: 'onchange', val: string | null): void,
|
||||
}>()
|
||||
|
||||
// روی iOS باز کردن تقویم از mousedown/mouseup داخلی پیکر قابل اتکا نیست.
|
||||
// وضعیت باز/بسته کنترلشده است؛ بعد از بستن، iOS اغلب یک click/mouseup
|
||||
// دیررس ارسال میکند که دوباره open=true میزند — با suppressOpen موقتاً
|
||||
// نادیده گرفته میشود.
|
||||
const open = ref(false)
|
||||
const rootRef = ref<HTMLElement | null>(null)
|
||||
const suppressOpen = ref(false)
|
||||
let suppressOpenTimer: ReturnType<typeof setTimeout> | undefined
|
||||
|
||||
function isInsidePicker(target: EventTarget | null): boolean {
|
||||
if (!(target instanceof Element)) return false
|
||||
if (rootRef.value?.contains(target)) return true
|
||||
return !!target.closest('.ant-picker-dropdown')
|
||||
}
|
||||
|
||||
function closePicker() {
|
||||
if (!open.value) return
|
||||
open.value = false
|
||||
armSuppressOpen()
|
||||
}
|
||||
|
||||
function handleOutsidePointer(event: Event) {
|
||||
if (!open.value) return
|
||||
const target =
|
||||
event instanceof TouchEvent
|
||||
? event.touches[0]?.target ?? event.target
|
||||
: event.target
|
||||
if (isInsidePicker(target)) return
|
||||
closePicker()
|
||||
}
|
||||
|
||||
function armSuppressOpen(ms = 400) {
|
||||
suppressOpen.value = true
|
||||
if (suppressOpenTimer) clearTimeout(suppressOpenTimer)
|
||||
suppressOpenTimer = setTimeout(() => {
|
||||
suppressOpen.value = false
|
||||
}, ms)
|
||||
}
|
||||
|
||||
const onOpenChange = (val: boolean) => {
|
||||
if (val && suppressOpen.value) return
|
||||
open.value = val
|
||||
if (!val) armSuppressOpen()
|
||||
}
|
||||
|
||||
const onWrapperClick = (e: MouseEvent) => {
|
||||
if (suppressOpen.value) return
|
||||
const target = e.target as HTMLElement
|
||||
if (target.closest('.ant-picker-clear')) return
|
||||
if (target.closest('.ant-picker-dropdown')) return
|
||||
if (open.value) {
|
||||
closePicker()
|
||||
return
|
||||
}
|
||||
open.value = true
|
||||
}
|
||||
|
||||
const _date = computed({
|
||||
set: (val) => {
|
||||
let temp: string | null = null
|
||||
if (val) {
|
||||
temp = val.calendar('gregory').locale('en').format(props.format)
|
||||
}
|
||||
open.value = false
|
||||
armSuppressOpen()
|
||||
emit('update:value', temp)
|
||||
emit('onchange', temp)
|
||||
},
|
||||
@@ -49,6 +116,18 @@ const _date = computed({
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
// mousedown داخلی پیکر روی iOS/touch قابل اتکا نیست — pointerdown/touchstart بیرون را میگیریم
|
||||
document.addEventListener('pointerdown', handleOutsidePointer, true)
|
||||
document.addEventListener('touchstart', handleOutsidePointer, true)
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
document.removeEventListener('pointerdown', handleOutsidePointer, true)
|
||||
document.removeEventListener('touchstart', handleOutsidePointer, true)
|
||||
if (suppressOpenTimer) clearTimeout(suppressOpenTimer)
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="less"></style>
|
||||
|
||||
Reference in New Issue
Block a user