<template>
	<div class="pi-icon-select">
		<div class="pi-icon-select__wrapper" :class="{'hasValue':value}" style="width: 100%;">
			<el-input v-model="value" :disabled="disabled" readonly>
				<template #append>
					<el-icon size="22" @click="open">
						<component :is="value||'el-icon-plus'"/>
					</el-icon>
				</template>
			</el-input>
		</div>
		<el-dialog title="图标选择器" v-model="dialogVisible" :width="760" destroy-on-close append-to-body>
			<div class="pi-icon-select__dialog">
				<el-form :rules="{}">
					<el-form-item prop="searchText">
						<el-input class="pi-icon-select__search-input" prefix-icon="el-icon-search" v-model="searchText"
								  placeholder="搜索" size="large" clearable/>
					</el-form-item>
				</el-form>
				<el-tabs>
					<el-tab-pane v-for="item in data" :key="item.name" lazy>
						<template #label>
							{{ item.name }}
							<el-tag size="small" type="info">{{ item.icons.length }}</el-tag>
						</template>
						<div class="pi-icon-select__list">
							<el-scrollbar>
								<ul @click="selectIcon">
									<el-empty v-if="item.icons.length===0" :image-size="100"
											  description="未查询到相关图标"/>
									<li v-for="icon in item.icons" :key="icon">
										<span :data-icon="icon"></span>
										<el-icon>
											<component :is="icon"/>
										</el-icon>
									</li>
								</ul>
							</el-scrollbar>
						</div>
					</el-tab-pane>
				</el-tabs>
			</div>
			<template #footer>
				<el-button @click="clear" text>清除</el-button>
				<el-button @click="dialogVisible=false">取消</el-button>
			</template>
		</el-dialog>
	</div>
</template>

<script setup>
import {ref, watch, onMounted, getCurrentInstance} from "vue";
import config from "@/config/icon"

const {proxy} = getCurrentInstance()
const prop = defineProps({
	modelValue: {type: String, default: ""},
	disabled: {type: Boolean, default: false},
})

let value = ref("")
let dialogVisible = ref(false)
let data = ref([])
let searchText = ref("")


watch(() => prop.modelValue, (val) => {
	value.value = val
})

watch(value, (val) => {
	proxy.$emit('update:modelValue', val)
})

watch(searchText, (val) => {
	search(val)
})

onMounted(() => {
	value.value = prop.modelValue
	data.value.push(...config.icons)
})

function open() {
	if (prop.disabled) {
		return false
	}
	dialogVisible.value = true
}

function selectIcon(e) {
	if (e.target.tagName != 'SPAN') {
		return false
	}
	value.value = e.target.dataset.icon
	dialogVisible.value = false
}

function clear() {
	value.value = ""
	dialogVisible.value = false
}

function search(text) {
	if (text) {
		const filterData = JSON.parse(JSON.stringify(config.icons))
		filterData.forEach(t => {
			t.icons = t.icons.filter(n => n.includes(text))
		})
		data.value = filterData
	} else {
		data.value = JSON.parse(JSON.stringify(config.icons))
	}
}

</script>

<style scoped>
.pi-icon-select {
	display: inline-flex;
	width: 100%;
}

.pi-icon-select__wrapper.hasValue:deep(.el-input__icon) {
	color: var(--el-text-color-regular);
}

.pi-icon-select__wrapper:deep(.el-input-group__append, .el-input-group__prepend) {
	padding: 0 10px;
}

.pi-icon-select__list {
	height: 270px;
	overflow: auto;
}

.pi-icon-select__list li {
	display: inline-block;
	width: 80px;
	height: 80px;
	margin: 5px;
	vertical-align: top;
	transition: all 0.1s;
	border-radius: 4px;
	position: relative;
}

.pi-icon-select__list li span {
	position: absolute;
	top: 0;
	left: 0;
	right: 0;
	bottom: 0;
	z-index: 1;
	cursor: pointer;
}

.pi-icon-select__list li i {
	display: inline-block;
	width: 100%;
	height: 100%;
	font-size: 26px;
	color: #6d7882;
	display: flex;
	justify-content: center;
	align-items: center;
	border-radius: 4px;
}

.pi-icon-select__list li:hover {
	box-shadow: 0 0 1px 4px var(--el-color-primary);
	background: var(--el-color-primary-light-9);
}

.pi-icon-select__list li:hover i {
	color: var(--el-color-primary);
}
</style>
