<template>
	<view
		class="cl-loading"
		:class="[
			{
				'cl-loading--dark': isDark && color == '',
				'cl-loading--spin': loading,
				'!border-primary-500': color == 'primary',
				'!border-green-500': color == 'success',
				'!border-yellow-500': color == 'warn',
				'!border-red-500': color == 'error',
				'!border-surface-500': color == 'info',
				'!border-surface-700': color == 'dark',
				'!border-white': color == 'light',
				'!border-surface-300': color == 'disabled',
				'!border-r-transparent': true
			},
			pt.className
		]"
		:style="{
			// #ifdef APP
			transform: `rotate(${rotate}deg)`,
			// #endif
			height: getRpx(size!),
			width: getRpx(size!),
			borderWidth: getRpx(2),
			borderTopColor: color,
			borderRightColor: 'transparent',
			borderBottomColor: color,
			borderLeftColor: color
		}"
		v-if="loading"
	>
	</view>
</template>

<script setup lang="ts">
import { computed, onMounted, ref, watch } from "vue";
import { isDark, parsePt } from "@/cool";
import type { ClIconProps } from "../cl-icon/props";
import { useSize } from "../../hooks";

defineOptions({
	name: "cl-loading"
});

// 定义组件属性
const props = defineProps({
	// 透传样式
	pt: {
		type: Object,
		default: () => ({})
	},
	// 是否加载中
	loading: {
		type: Boolean,
		default: true
	},
	// 图标大小
	size: {
		type: [Number, String],
		default: 24
	},
	// 图标颜色
	color: {
		type: String,
		default: ""
	}
});

const { getRpx } = useSize();

// 透传样式类型定义
type PassThrough = {
	className?: string;
	icon?: ClIconProps;
};

// 解析透传样式
const pt = computed(() => parsePt<PassThrough>(props.pt));

// 旋转角度
const rotate = ref(0);

// 开始旋转动画
function start() {
	requestAnimationFrame(() => {
		// 增加旋转角度
		rotate.value += 1;

		// 如果仍在加载中则继续旋转
		if (props.loading) {
			start();
		}
	});
}

// 组件挂载后监听loading状态
onMounted(() => {
	// #ifdef APP-UVUE
	watch(
		computed(() => props.loading),
		(val: boolean) => {
			// 当loading为true时开始旋转
			if (val) {
				start();
			}
		},
		{
			immediate: true
		}
	);
	// #endif
});
</script>

<style lang="scss" scoped>
.cl-loading {
	@apply flex flex-row items-center justify-center rounded-full;
	@apply border-surface-700 border-solid;

	&--dark {
		border-color: white !important;
		border-right-color: transparent !important;
	}

	// #ifdef H5 || MP
	&--spin {
		animation: spin 2.5s linear infinite;
	}

	@keyframes spin {
		from {
			transform: rotate(0deg);
		}
		to {
			transform: rotate(360deg);
		}
	}
	// #endif
}
</style>
