UNPKG

various-ui

Version:

This is a test version of the Vue 3 component library

262 lines (259 loc) 8.7 kB
import { reactive, ref, shallowRef, watch, nextTick } from 'vue'; import gsap from 'gsap'; const useComposable = (define, emits) => { const refs = { sorts: reactive({ key: "", value: "" }), //* 排序数据 selects: ref([]), //* 选择数据 childrens: ref([]) //* 嵌套数据 }; const nodes = { head: ref(), main: ref(), bodys: ref([]), container: ref() }; const variable = { size: 0, observer: shallowRef() }; const disposable = { //* 表格内容属性 body: (data, index) => { if (refs.selects.value.includes(index) || refs.childrens.value.includes(index)) { return { class: "ui-active" }; } return {}; }, //* 表头额外控件属性 extra: (data) => { return { "align": "center", "trigger": "click", "direction": "bottom", "class-extra-name": data["extra-name"] }; }, //* 表格内容对齐属性 align: (data) => { switch (data.align) { case "singularity": return { "justify-content": "center", "text-align": "left" }; case "center": return { "justify-content": "center", "text-align": "center" }; case "right": return { "justify-content": "flex-end", "text-align": "right" }; default: return { "justify-content": "flex-start", "text-align": "left" }; } } }; const methods = { //* 初始化函数 init: () => { var _a, _b; if (!nodes.container.value || !nodes.main.value || !nodes.head.value) return; else { nodes.container.value.querySelectorAll(":scope>div").forEach((node) => node.style.width = ""); } const rows = [nodes.head.value, ...nodes.bodys.value]; const vars = { replenish: 0, size: Math.floor(nodes.head.value.clientWidth) - 4, //! 这里-4是预留宽度,用于解决因小数点计算导致的尺寸偏差 data: [] }; if (vars.size <= 0) return; define.option.forEach((value) => { const result = { key: value.key, min: value["min-width"] || 0, max: value["max-width"] || 0, width: value.width || value["min-width"] || 0, replenish: !value.width }; if (!value.width) { rows.forEach((row) => { const node = row.querySelector(`.ui-table2-column[name=${value.key}]`); const context = node.firstElementChild; if (!node) return; else { node.style.whiteSpace = "nowrap"; node.style.width = ""; if (context) { context.style.width = ""; } if (node.clientWidth > result.width) { if (result.max && node.clientWidth > result.max) { result.width = result.max; } else { result.width = Math.ceil(node.clientWidth) + 4; } } node.style.whiteSpace = ""; } }); } vars.data.push(result); }); const real = vars.data.reduce((former, current) => { return former + current.width; }, 0); if (!define.overflow || define.overflow && vars.size >= real) { vars.replenish = vars.size - real; while (Math.floor(Math.abs(vars.replenish)) != 0) { const data = vars.data.filter((val) => { return val.replenish && (vars.replenish > 0 ? !val.max || val.width < val.max : !val.min || val.width > val.min); }); if (!data.length || vars.replenish / data.length == 0) break; if (vars.replenish > 0) { const replenish = vars.replenish / data.length; data.forEach((value) => { if (value.max && value.width + replenish > value.max) { vars.replenish -= value.max - value.width; value.width = value.max; } else { value.width += replenish; vars.replenish -= replenish; } }); } else if (vars.replenish < 0) { const max = ((_b = (_a = data.sort((a, b) => b.width - a.width)) == null ? void 0 : _a[0]) == null ? void 0 : _b.width) || 0; for (let i = 0; i < data.length; i++) { if (vars.replenish == 0) break; if (data[i].width == max && data[i].width > data[i].min) { if (data[i].min && data[i].width - 1 < data[i].min) { vars.replenish += data[i].width - data[i].min; data[i].width = data[i].min; } else { vars.replenish += 1; data[i].width -= 1; } } } } } } else { const size = real + Math.ceil(nodes.container.value.clientWidth - nodes.head.value.clientWidth) + 4; nodes.container.value.querySelectorAll(":scope>div").forEach((node) => { node.style.width = size + "px"; }); } vars.data.forEach((value) => { rows.forEach((row) => { const node = row.querySelector(`.ui-table2-column[name=${value.key}]`); if (!node) return; else { node.style.width = value.width + "px"; } }); }); define.option.filter((value) => value.align == "singularity").forEach((value) => { let result = 0; nodes.bodys.value.forEach((row) => { const node = row.querySelector(`.ui-table2-column[name=${value.key}] > .ui-table2-context`); if (!node) return; else { result = Math.max(result, node.offsetWidth); } }); nodes.bodys.value.forEach((row) => { const node = row.querySelector(`.ui-table2-column[name=${value.key}] > .ui-table2-context`); if (node && node.offsetWidth >= result) return; else { node.style.width = result + "px"; } }); }); }, //* 排序 sort: (data) => { if (!data) { refs.sorts.key = ""; refs.sorts.value = ""; } else { if (refs.sorts.key != data.key) { refs.sorts.key = data.key; refs.sorts.value = "asc"; } else { if (refs.sorts.value == "asc") { refs.sorts.value = "desc"; } else { refs.sorts.key = ""; refs.sorts.value = ""; } } emits("sort", refs.sorts); } }, //* 单选 radio: (index) => { if (index == void 0) refs.selects.value = []; else { refs.selects.value = [index]; emits("radio", define.data[index]); } }, //* 选择 select: (index) => { if (define.selector == "checkbox") methods.checkbox(index); else if (define.selector == "children") methods.children(index); else if (define.selector == "radio") { methods.radio(index); } }, //* 多选 checkbox: (index) => { if (index == void 0) refs.selects.value = []; else { const key = refs.selects.value.findIndex((value) => value == index); if (key != -1) { refs.selects.value.splice(key, 1); } else { refs.selects.value.push(index); } const result = refs.selects.value.map((index2) => define.data[index2]); emits("checkbox", result); } }, //* 嵌套 children: (index, callBack) => { if (index == void 0) refs.childrens.value = []; else { const key = refs.childrens.value.findIndex((value) => value == index); if (key != -1) { refs.childrens.value.splice(key, 1); callBack && callBack(false); } else { refs.childrens.value.push(index); callBack && callBack(true); } } } }; const watchs = { watch_stop: watch( () => define.data, () => { refs.selects.value = []; refs.childrens.value = []; nextTick(() => methods.init()); } ) }; const ons = { animation: { //* 动画(入场前) "before-enter": (el) => gsap.set(el, { height: 0, opacity: 0 }), //* 动画(离场) "leave": (el, onComplete) => gsap.to(el, { height: 0, opacity: 0, duration: 0.2, onComplete }), //* 动画(入场) "enter": (el, onComplete) => gsap.to(el, { height: "auto", opacity: 1, duration: 0.2, onComplete }) } }; return { ons, refs, nodes, watchs, methods, variable, disposable }; }; export { useComposable }; //# sourceMappingURL=composable.mjs.map