init
This commit is contained in:
161
src/component/iconPicker/index.less
Normal file
161
src/component/iconPicker/index.less
Normal file
@@ -0,0 +1,161 @@
|
||||
@import "../dropdown/index.less";
|
||||
|
||||
:root {
|
||||
--icon-picker-border-radius: var(--global-border-radius);
|
||||
--icon-picker-checked-color: var(--global-checked-color);
|
||||
}
|
||||
|
||||
.layui-iconpicker {
|
||||
position: relative;
|
||||
height: 38px;
|
||||
line-height: 38px;
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
border-radius: var(--icon-picker-border-radius);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.layui-iconpicker .layui-inline {
|
||||
height: 36px;
|
||||
line-height: 36px;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.layui-iconpicker-title {
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
.layui-iconpicker-main {
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
.layui-iconpicker-main .layui-icon {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.layui-iconpicker-main .layui-inline {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.layui-iconpicker-split .layui-iconpicker-main {
|
||||
padding: 0 15px;
|
||||
border-right-width: 1px;
|
||||
border-right-style: solid;
|
||||
}
|
||||
|
||||
.layui-iconpicker-suffix {
|
||||
position: relative;
|
||||
width: 35px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.layui-iconpicker-suffix .layui-icon {
|
||||
font-size: 14px;
|
||||
color: rgba(0, 0, 0, 0.5);
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.layui-iconpicker-down .layui-iconpicker-suffix .layui-icon-down {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.layui-iconpicker-search {
|
||||
padding: 10px;
|
||||
box-shadow: 0 2px 8px #f0f1f2;
|
||||
border-bottom: 1px solid whitesmoke;
|
||||
}
|
||||
|
||||
.layui-iconpicker-list {
|
||||
width: 321px;
|
||||
}
|
||||
|
||||
.layui-iconpicker-list ul {
|
||||
margin: 6px;
|
||||
}
|
||||
|
||||
.layui-iconpicker-list li {
|
||||
vertical-align: top;
|
||||
display: inline-block;
|
||||
width: 60px;
|
||||
margin: 2.5px;
|
||||
padding: 5px;
|
||||
overflow: hidden;
|
||||
border: 1px solid #eee;
|
||||
border-radius: 2px;
|
||||
cursor: pointer;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.layui-iconpicker-list li:hover {
|
||||
background-color: var(--global-neutral-color-1);
|
||||
color: rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
.layui-iconpicker-list li.layui-this {
|
||||
border-color: var(--icon-picker-checked-color);
|
||||
color: var(--icon-picker-checked-color);
|
||||
}
|
||||
|
||||
.layui-iconpicker-list li .layui-icon {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.layui-iconpicker-list li .layui-elip {
|
||||
margin-top: 2px;
|
||||
line-height: 20px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.layui-iconpicker-list .layui-none {
|
||||
margin: 30px 0 35px;
|
||||
}
|
||||
|
||||
.layui-iconpicker-scroll .layui-iconpicker-list {
|
||||
max-height: 200px;
|
||||
}
|
||||
|
||||
.layui-iconpicker-page {
|
||||
position: relative;
|
||||
padding: 10px 10px 5px;
|
||||
border-top: 1px solid #eee;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.layui-iconpicker-page .layui-laypage {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.layui-iconpicker-page .layui-laypage a,
|
||||
.layui-iconpicker-page .layui-laypage span {
|
||||
padding: 0 10px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.layui-iconpicker-page .layui-laypage-count {
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
}
|
||||
|
||||
.layui-iconpicker-page .layui-laypage-curr .layui-laypage-em {
|
||||
background: 0 0;
|
||||
}
|
||||
|
||||
.layui-iconpicker-page .layui-laypage-curr em {
|
||||
color: #666;
|
||||
color: rgba(0, 0, 0, 0.6);
|
||||
}
|
||||
|
||||
.layui-iconpicker-page .layui-laypage-first,
|
||||
.layui-iconpicker-page .layui-laypage-last,
|
||||
.layui-iconpicker-page .layui-laypage-spr {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.layui-colorpicker-disabled {
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.layui-colorpicker-disabled,
|
||||
.layui-colorpicker-disabled * {
|
||||
cursor: not-allowed !important;
|
||||
}
|
||||
5
src/component/iconPicker/index.ts
Normal file
5
src/component/iconPicker/index.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { withInstall, WithInstallType } from "../../utils";
|
||||
import Component from "./index.vue";
|
||||
|
||||
const component: WithInstallType<typeof Component> = withInstall(Component);
|
||||
export default component;
|
||||
217
src/component/iconPicker/index.vue
Normal file
217
src/component/iconPicker/index.vue
Normal file
@@ -0,0 +1,217 @@
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: "LayIconPicker",
|
||||
};
|
||||
</script>
|
||||
|
||||
<script setup lang="ts">
|
||||
import "./index.less";
|
||||
import { computed, Ref, ref, StyleValue } from "vue";
|
||||
import { LayIconList as icons } from "@layui/icons-vue";
|
||||
import LayDropdown from "../dropdown/index.vue";
|
||||
import LayInput from "../input/index.vue";
|
||||
import LayScroll from "../scroll/index.vue";
|
||||
|
||||
export interface IconPickerProps {
|
||||
page?: boolean;
|
||||
modelValue?: string;
|
||||
disabled?: boolean;
|
||||
showSearch?: boolean;
|
||||
contentClass?: string | Array<string | object> | object;
|
||||
contentStyle?: StyleValue;
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<IconPickerProps>(), {
|
||||
modelValue: "layui-icon-face-smile",
|
||||
disabled: false,
|
||||
page: false,
|
||||
});
|
||||
|
||||
const emit = defineEmits(["update:modelValue", "change"]);
|
||||
const selectedIcon = computed(() => props.modelValue);
|
||||
const dropdownRef = ref<any>(null);
|
||||
|
||||
const selectIcon = function (icon: string): void {
|
||||
emit("update:modelValue", icon);
|
||||
emit("change", icon);
|
||||
dropdownRef.value?.hide();
|
||||
};
|
||||
|
||||
const icones: Ref = ref([]);
|
||||
const total: Ref<number> = ref(icons.length);
|
||||
const totalPage: Ref<number> = ref(total.value / 12);
|
||||
const currentPage: Ref<number> = ref(1);
|
||||
|
||||
if (props.page) {
|
||||
icones.value = icons.slice(0, 12);
|
||||
} else {
|
||||
icones.value = icons;
|
||||
}
|
||||
|
||||
const next = () => {
|
||||
if (currentPage.value === totalPage.value) {
|
||||
return;
|
||||
}
|
||||
currentPage.value = currentPage.value + 1;
|
||||
const start = (currentPage.value - 1) * 12;
|
||||
const end = start + 12;
|
||||
icones.value = icons.slice(start, end);
|
||||
};
|
||||
|
||||
const prev = () => {
|
||||
if (currentPage.value === 1) {
|
||||
return;
|
||||
}
|
||||
currentPage.value = currentPage.value - 1;
|
||||
const start = (currentPage.value - 1) * 12;
|
||||
const end = start + 12;
|
||||
icones.value = icons.slice(start, end);
|
||||
};
|
||||
|
||||
const clear = () => {
|
||||
const start = (currentPage.value - 1) * 12;
|
||||
const end = start + 12;
|
||||
if (props.page) {
|
||||
icones.value = icons.slice(start, end);
|
||||
total.value = icons.length;
|
||||
totalPage.value = Math.ceil(icons.length / 12);
|
||||
} else {
|
||||
icones.value = icons;
|
||||
}
|
||||
};
|
||||
|
||||
const search = (e: any) => {
|
||||
currentPage.value = 1;
|
||||
const start = (currentPage.value - 1) * 12;
|
||||
const end = start + 12;
|
||||
const text = e;
|
||||
if (text) {
|
||||
if (props.page) {
|
||||
icones.value = searchList(text, icons).slice(start, end);
|
||||
total.value = searchList(text, icons).length;
|
||||
totalPage.value = Math.ceil(searchList(text, icons).length / 12);
|
||||
} else {
|
||||
icones.value = searchList(text, icons);
|
||||
}
|
||||
} else {
|
||||
if (props.page) {
|
||||
icones.value = icons.slice(start, end);
|
||||
total.value = icons.length;
|
||||
totalPage.value = Math.ceil(icons.length / 12);
|
||||
} else {
|
||||
icones.value = icons;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const searchList = (str: string, container: any) => {
|
||||
var newList = [];
|
||||
var startChar = str.charAt(0);
|
||||
var strLen = str.length;
|
||||
for (var i = 0; i < container.length; i++) {
|
||||
var obj = container[i];
|
||||
var isMatch = false;
|
||||
for (var p in obj) {
|
||||
if (typeof obj[p] == "function") {
|
||||
obj[p]();
|
||||
} else {
|
||||
var curItem = "";
|
||||
if (obj[p] != null) {
|
||||
curItem = obj[p];
|
||||
}
|
||||
for (var j = 0; j < curItem.length; j++) {
|
||||
if (curItem.charAt(j) == startChar) {
|
||||
if (curItem.substring(j).substring(0, strLen) == str) {
|
||||
isMatch = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isMatch) {
|
||||
newList.push(obj);
|
||||
}
|
||||
}
|
||||
return newList;
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<lay-dropdown
|
||||
ref="dropdownRef"
|
||||
:disabled="disabled"
|
||||
:contentClass="contentClass"
|
||||
:contentStyle="contentStyle"
|
||||
updateAtScroll
|
||||
>
|
||||
<div
|
||||
class="layui-inline layui-border-box layui-iconpicker layui-iconpicker-split"
|
||||
:class="[{ 'layui-colorpicker-disabled': disabled }]"
|
||||
>
|
||||
<div class="layui-inline layui-iconpicker-main">
|
||||
<i class="layui-inline layui-icon" :class="[selectedIcon]"></i>
|
||||
</div>
|
||||
<span class="layui-inline layui-iconpicker-suffix"
|
||||
><i class="layui-icon layui-icon-down layui-anim"></i
|
||||
></span>
|
||||
</div>
|
||||
<template #content>
|
||||
<div class="layui-iconpicker-view layui-iconpicker-scroll">
|
||||
<div v-if="showSearch" class="layui-iconpicker-search">
|
||||
<lay-input
|
||||
@input="search"
|
||||
@clear="clear"
|
||||
autocomplete="true"
|
||||
:allow-clear="true"
|
||||
>
|
||||
<template #prefix>
|
||||
<i class="layui-icon layui-icon-search"></i>
|
||||
</template>
|
||||
</lay-input>
|
||||
</div>
|
||||
<div class="layui-iconpicker-list">
|
||||
<lay-scroll style="height: 200px" thumbColor="rgb(238, 238, 238)">
|
||||
<ul>
|
||||
<li
|
||||
v-for="icon in icones"
|
||||
:key="icon"
|
||||
:class="[selectedIcon === icon.class ? 'layui-this' : '']"
|
||||
@click="selectIcon(icon.class)"
|
||||
>
|
||||
<i class="layui-icon" :class="[icon.class]"></i>
|
||||
<p class="layui-elip">
|
||||
{{ icon.name }}
|
||||
</p>
|
||||
</li>
|
||||
</ul>
|
||||
</lay-scroll>
|
||||
</div>
|
||||
<div v-if="page" class="layui-iconpicker-page">
|
||||
<div id="layui-laypage-1" class="layui-laypage layui-laypage-default">
|
||||
<span class="layui-laypage-count">共 {{ total }} 个</span
|
||||
><a
|
||||
href="javascript:;"
|
||||
class="layui-laypage-prev"
|
||||
:class="[currentPage === 1 ? 'layui-disabled' : '']"
|
||||
@click="prev()"
|
||||
><i class="layui-icon layui-icon-left"></i></a
|
||||
><span class="layui-laypage-curr"
|
||||
><em class="layui-laypage-em"></em
|
||||
><em>{{ currentPage }} / {{ totalPage }}</em></span
|
||||
><span class="layui-laypage-spr">…</span
|
||||
><a href="javascript:;" class="layui-laypage-last" title="尾页"
|
||||
>14</a
|
||||
><a
|
||||
href="javascript:;"
|
||||
:class="[currentPage === totalPage ? 'layui-disabled' : '']"
|
||||
class="layui-laypage-next"
|
||||
@click="next()"
|
||||
><i class="layui-icon layui-icon-right"></i
|
||||
></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</lay-dropdown>
|
||||
</template>
|
||||
Reference in New Issue
Block a user