Files
aurora-admin/site/sources/treetable/html.txt
T

112 lines
5.0 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Kole UI · TreeTable (H5)</title>
<link rel="stylesheet" href="../.design_library/kole-ui/colors_and_type.css">
<link rel="stylesheet" href="./TreeTable.css">
<style>
/* 演示页布局脚手架 —— 组件样式已并入 TreeTable.css(S9-P7 单一样式真源) */
.demo { padding: 24px; background: var(--kole-color-page-bg); color: var(--kole-color-text-body); font-family: var(--font-family); }
h1 { font-size: 20px; margin: 0 0 4px; }
.sub { color: var(--kole-color-text-secondary); margin: 0 0 24px; font-size: 12px; }
</style>
</head>
<body>
<div class="demo">
<h1>Kole UI · TreeTable 组件(纯 H5)</h1>
<p class="sub">对齐 TreeTable 规范:层级缩进16px/级、展开/折叠箭头、父级汇总(子节点合计)、选择父级联动子级</p>
<div class="kole-tt" role="table">
<table>
<thead>
<tr>
<th class="col-selection" style="width:48px"><input type="checkbox" id="ttAll" class="tt-check"></th>
<th>部门 / 人员</th>
<th class="align-right">人数</th>
<th class="align-right">预算(万)</th>
</tr>
</thead>
<tbody id="ttBody"></tbody>
<tfoot><tr><td></td><td>合计</td><td class="align-right" id="sumCount">0</td><td class="align-right" id="sumBudget">0</td></tr></tfoot>
</table>
</div>
</div>
<script>
const treeData = [
{ key: 'tech', name: '技术中心', count: 0, budget: 0, children: [
{ key: 'fe', name: '前端组', count: 12, budget: 80 },
{ key: 'be', name: '后端组', count: 18, budget: 120 }
]},
{ key: 'product', name: '产品中心', count: 0, budget: 0, children: [
{ key: 'pm', name: '产品组', count: 8, budget: 60 },
{ key: 'ux', name: '设计组', count: 6, budget: 40 }
]}
];
let expanded = new Set(['tech', 'product']);
let selected = new Set();
function hasChildren(n) { return n.children && n.children.length; }
function leafSum(node, key) {
if (!hasChildren(node)) return node[key] || 0;
return node.children.reduce((s, c) => s + leafSum(c, key), 0);
}
function flatten(nodes, depth, out) {
nodes.forEach(n => {
out.push({ node: n, depth });
if (hasChildren(n) && expanded.has(n.key)) flatten(n.children, depth + 1, out);
});
return out;
}
function allChildrenSelected(node) {
if (!hasChildren(node)) return selected.has(node.key);
return node.children.every(c => allChildrenSelected(c));
}
function render() {
const rows = flatten(treeData, 0, []);
document.getElementById('ttBody').innerHTML = rows.map(({ node, depth }) => {
const open = expanded.has(node.key);
const arrow = hasChildren(node)
? `<span class="tt-arrow ${open ? 'is-open' : ''}" role="button" tabindex="0" onclick="toggle('${node.key}')">▸</span>`
: `<span class="tt-arrow-placeholder"></span>`;
const check = `<input type="checkbox" class="tt-check" ${selected.has(node.key) ? 'checked' : ''} onclick="event.stopPropagation();check('${node.key}')">`;
const count = hasChildren(node) ? leafSum(node, 'count') : node.count;
const budget = hasChildren(node) ? leafSum(node, 'budget') : node.budget;
const sel = selected.has(node.key) ? ' is-selected' : '';
return `<tr class="${sel.trim()}" role="row" tabindex="0" aria-selected="${selected.has(node.key)}" onclick="rowClick('${node.key}')" onkeydown="if(event.key==='Enter'||event.key===' '){event.preventDefault();rowClick('${node.key}')}">
<td>${check}</td>
<td><div class="tree-cell" style="padding-left:${depth * 16}px">${arrow}<span>${node.name}</span></div></td>
<td class="align-right">${count}</td>
<td class="align-right">${budget}${hasChildren(node) ? '<span class="tt-summary">(汇总)</span>' : ''}</td>
</tr>`;
}).join('');
document.getElementById('sumCount').textContent = treeData.reduce((s, n) => s + leafSum(n, 'count'), 0);
document.getElementById('sumBudget').textContent = treeData.reduce((s, n) => s + leafSum(n, 'budget'), 0);
}
function toggle(key) { expanded.has(key) ? expanded.delete(key) : expanded.add(key); render(); }
function rowClick(key) { selected = new Set([key]); render(); }
function check(key) {
const node = treeData.flatMap(f => [f]).find(n => n.key === key) || find(key, treeData);
const willCheck = !selected.has(key);
const desc = [key, ...descendantKeys(node)];
desc.forEach(k => willCheck ? selected.add(k) : selected.delete(k));
propagate(treeData);
render();
}
function find(key, nodes) {
for (const n of nodes) { if (n.key === key) return n; if (n.children) { const f = find(key, n.children); if (f) return f; } }
}
function descendantKeys(node) { let o = []; (node.children||[]).forEach(c => { o.push(c.key); o = o.concat(descendantKeys(c)); }); return o; }
function propagate(nodes) {
nodes.forEach(n => {
if (hasChildren(n)) { allChildrenSelected(n) ? selected.add(n.key) : selected.delete(n.key); propagate(n.children); }
});
}
render();
</script>
</body>
</html>