<template>
	<view
		v-if="show"
		class="zy-half-screen-dialog"
		:class="extClass"
		data-target="screen-dialog"
		@click="tapMask"
	>
		<view
			class="zy-half-screen-dialog-content"
			:style="{ height: height }"
			:data-visible="visible"
			:animation="contentAnimation"
			@transitionend="updateVisible"
			@click.stop=""
		>
			<slot></slot>
		</view>
	</view>
</template>

<script lang="ts" setup>
import { nextTick, ref, watch } from 'vue';

const props = defineProps({
	show: {
		type: Boolean,
		default: false,
	},
	height: {
		type: String,
		default: '80%',
	},
	extClass: {
		type: String,
		default: '',
	},
});

const maskClosable = ref(true);
const duration = 300;
const contentAnimation = ref(null);
const visible = ref(false);

const emits = defineEmits(['update:show']);

const tapMask = (e) => {
	if (e.currentTarget.dataset.target !== 'screen-dialog') {
		return;
	}
	if (maskClosable.value) {
		close();
	}
};
const updateVisible = (e) => {
	const { visible } = e.currentTarget.dataset;
	nextTick(() => {
		if (!visible) {
			emits('update:show', visible);
		}
	});
};
const open = () => {
	const up = uni.createAnimation({
		duration,
	});
	up.translateY(0).step();
	contentAnimation.value = up.export();
	visible.value = true;
};
const close = () => {
	const down = uni.createAnimation({
		duration,
	});
	down.translateY('120%').step();
	contentAnimation.value = down.export();
	visible.value = false;
};

watch(
	() => props.show,
	(v) => {
		visible.value = v;
		if (v) {
			nextTick(() => open());
		} else {
			nextTick(() => close());
		}
	}
);
</script>

<style lang="scss" scoped>
.zy-half-screen-dialog {
	height: 100%;
	width: 100%;
	background-color: #00000083;
	position: fixed;
	top: 0;
	left: 0;
	z-index: 999999;
}

.zy-half-screen-dialog-content {
	position: absolute;
	bottom: 0;
	left: 0;
	width: 100%;
	background-color: #ffffff;
	border-top-left-radius: 30rpx;
	border-top-right-radius: 30rpx;
	overflow: hidden;
	min-height: 20%;
	height: 80%;
	transform: translateY('100%');
}
</style>
