omii-ui
Version:
使用OMII开发的WebComponents库,样式采用bootstrap。可以作为标准的esmodule使用
217 lines (207 loc) • 5.95 kB
JSX
import uiBase from "../uiBase";
import css from "./index.scss";
import treeNode from "./node";
import sortable from "../sortable";
const { h, purgeCSSSS, getHost, classNames } = omii;
export { treeNode };
export default class extends uiBase {
static css = css;
static defaultProps = {
nodeCss: null, //节点样式表,可以是任何可以转换成CSSStyleSheet的结构
radioTree: false,
checkboxTree: false,
multiSelect: false, //可單選的樹 | true 多選
sortable: false,
sortGroup: null,
ignoreAttrs: true,
selectedKey: null, //選中的行
selectedKeys: [],
expandedKeys: [], //展開
checkedKeys: [], //多選
radioedKey: null, //單選
nodes: [], //節點
expander: <oi-icon name="keyboard_arrow_right" class="expander" />,
};
static propTypes = {
ignoreAttrs: Boolean,
multiSelect: Boolean,
sortable: Boolean,
selectedKey: String,
selectedKeys: Array,
expandedKeys: Array,
checkedKeys: Array,
radioedKey: String,
nodes: Array,
};
get sortGroup() {
return this.$props.sortGroup ?? `sort-${this.elementId}`;
}
get selectedKeys() {
return this.$props.selectedKeys;
}
get selectedKey() {
return this.$props.selectedKey;
}
get expandedKeys() {
return this.$props.expandedKeys;
}
get checkedKeys() {
return this.$props.checkedKeys;
}
get radioedKey() {
return this.$props.radioedKey;
}
#Sortable;
get Sortable() {
return this.#Sortable;
}
isSelected(key) {
let { multiSelect, selectedKey, selectedKeys } = this.$props;
if (!multiSelect) return selectedKey != null && selectedKey == key;
else return (selectedKeys ?? []).some((k) => k == key);
}
select(val, update = true) {
let { multiSelect, selectedKeys } = this.$props;
if (!multiSelect) this.$props.selectedKey = val;
else {
if (!selectedKeys.some((k) => k == val)) {
selectedKeys.push(val);
}
}
if (update) this.update();
}
unselect(val, update = true) {
return this.unSelect(val, update);
}
unSelect(val, update = true) {
let { multiSelect, selectedKeys } = this.$props;
if (!multiSelect) this.$props.selectedKey = null;
else {
let index = selectedKeys.indexOf(val);
if (index != -1) {
selectedKeys.splice(index, 1);
}
}
if (update) this.update();
}
isChecked(key) {
let { checkboxTree, checkedKeys } = this.$props;
if (checkboxTree) return (checkedKeys ?? []).some((k) => k == key);
return false;
}
check(key, update = true) {
let { checkboxTree, checkedKeys } = this.$props;
if (checkboxTree) {
let index = checkedKeys.indexOf(key);
if (index == -1) {
checkedKeys.push(key);
}
}
if (update) this.update();
}
uncheck(key, update = true) {
let { checkboxTree, checkedKeys } = this.$props;
if (checkboxTree) {
let index = checkedKeys.indexOf(key);
if (index != -1) {
checkedKeys.splice(index, 1);
}
}
if (update) this.update();
}
isRadioed(key) {
let { radioTree, radioedKey } = this.$props;
if (radioTree) return radioedKey != null && radioedKey == key;
return false;
}
radio(key, update = true) {
let { radioTree } = this.$props;
if (radioTree) this.$props.radioedKey = key;
if (update) this.update();
}
unradio(update = true) {
let { radioTree } = this.$props;
if (radioTree) this.$props.radioedKey = null;
if (update) this.update();
}
isExpanded(key) {
let { expandedKeys } = this.$props;
return (expandedKeys ?? []).some((k) => k == key);
}
expand(key, update = true) {
let { expandedKeys } = this.$props;
let index = expandedKeys.indexOf(key);
if (index == -1) expandedKeys.push(key);
if (update) this.update();
}
collapse(key, update = true) {
let { expandedKeys } = this.$props;
let index = expandedKeys.indexOf(key);
if (index != -1) expandedKeys.splice(index, 1);
if (update) this.update();
}
collapseAll(update = true) {
this.expandedKeys.forEach((key) => {
this.collapse(key, false);
});
if (update) {
this.update();
}
}
async installed() {
if (this.$props.sortable) {
const Sortable = await sortable.use();
this.#Sortable = Sortable.create(this.rootNode, {
delay: 150,
fallbackOnBody: true,
invertSwap: true,
group: this.sortGroup,
// onAdd: (evt) => {
// // const toHost = getHost(evt.to);
// // evt.item.update$Props({ nodeLevel: 0 }, true, true);
// //toHost.updateSelf();
// },
onEnd: (evt) => {
const fromHost = getHost(evt.from);
const toHost = getHost(evt.to);
const fromNodes = fromHost.nodes;
const toNodes = toHost.nodes;
this.fire("sorted", {
fromNode: fromHost.node,
fromNodes,
toNode: toHost.node,
toNodes,
fromIndex: evt.oldIndex,
toIndex: evt.newIndex,
});
},
});
}
}
get nodes() {
let nodes = this.$props.nodes;
let host = getHost(this);
if (typeof nodes === "function") {
nodes = nodes.call(host);
}
return nodes;
}
set nodes(value) {
this.$props.nodes = value;
}
render() {
let host = getHost(this);
let cssss = purgeCSSSS(this.$props.nodeCss, host);
return (
<div
class={classNames("tree-container", {
sortable: this.sortable,
})}
>
{this.nodes.map((n) => (
<oi-tree-node node={n} tree={this} cssss={cssss} />
))}
</div>
);
}
}