Skip to content

Commit

Permalink
Merge 07cfea4 into 5407c8f
Browse files Browse the repository at this point in the history
  • Loading branch information
eidng8 committed Apr 13, 2020
2 parents 5407c8f + 07cfea4 commit 54b5b33
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 69 deletions.
12 changes: 3 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,12 @@
# vue-tree

[![Master Build](https://travis-ci.com/eidng8/vue-tree.svg?branch=master)](https://travis-ci.com/eidng8/vue-tree)
[![Master Coverage](https://coveralls.io/repos/github/eidng8/vue-tree/badge.svg?branch=master)](https://coveralls.io/github/eidng8/vue-tree?branch=master)

A Vue.js tree view component with stable DOM tree. By stable, it means the
DOM structure will not change once it is rendered.


## Master Branch
[![Build](https://travis-ci.com/eidng8/vue-tree.svg?branch=master)](https://travis-ci.com/eidng8/vue-tree)
[![Coverage](https://coveralls.io/repos/github/eidng8/vue-tree/badge.svg?branch=master)](https://coveralls.io/github/eidng8/vue-tree?branch=master)

## Dev Branch
[![Build](https://travis-ci.com/eidng8/vue-tree.svg?branch=dev)](https://travis-ci.com/eidng8/vue-tree)
[![Coverage](https://coveralls.io/repos/github/eidng8/vue-tree/badge.svg?branch=dev)](https://coveralls.io/github/eidng8/vue-tree?branch=dev)


## Performance Consideration

The DOM structure of this component doesn't change once rendered.
Expand Down
9 changes: 7 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"name": "g8-vue-tree",
"version": "0.0.21",
"version": "0.0.22",
"repository": "git@github.com:eidng8/vue-tree.git",
"bugs": "git@github.com:eidng8/vue-tree/issues",
"author": "eidng8 <cheung.jackey@gmail.com>",
"author": "eidng8",
"license": "GPL-3.0",
"main": "./dist/g8-vue-tree.umd.min.js",
"typings": "./typings/index.d.ts",
Expand All @@ -14,12 +14,17 @@
"/src/components",
"/typings"
],
"keywords": [
"typescript",
"vue"
],
"scripts": {
"build": "vue-cli-service build --target lib --mode production ./src/index.ts",
"serve": "vue-cli-service serve",
"start": "npm run serve",
"test": "npm run test:unit && npm run test:e2e",
"test:unit": "vue-cli-service test:unit",
"test:cover": "npm run test:unit -- --coverage",
"test:e2e": "vue-cli-service test:e2e --headless",
"test:e2e:visual": "vue-cli-service test:e2e",
"lint": "vue-cli-service lint"
Expand Down
63 changes: 31 additions & 32 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

<template>
<div id="app">
<button @click="populate()">populate tree</button>
<ul class="g8-tree-view g8-tree__highlight_hover">
<g8-tree-view
checker="1"
Expand All @@ -25,7 +26,7 @@

<script lang="ts">
import {Component, Vue} from 'vue-property-decorator';
import {G8TreeView, G8TreeItem} from './';
import {G8TreeItem, G8TreeView} from './';
@Component({
components: {
Expand All @@ -35,37 +36,7 @@ import {G8TreeView, G8TreeItem} from './';
export default class App extends Vue {
item: G8TreeItem = {
key: 'root',
name: 'root name',
tags: [{key: 'root tag', label: 'root label'}],
children: [
{
key: 'item-1',
name: 'item 1',
tags: [
{key: 1, label: 'tag1.1'},
{key: 1, label: 'tag1.2', hint: '2nd tag in the 2nd branch'},
],
},
{
key: 'item-2',
name: 'item 2',
tags: [{key: 2, label: 'tag1.1'}],
children: [
{
key: 'item-2.1',
name: 'item 2.1',
tags: [
{key: '2.1.1', label: 'tag2.1.1'},
{key: '2.1.2', label: 'tag2.1.2'},
],
},
{
key: 'item-2.2',
name: 'item 2.2',
},
],
},
],
name: 'Click the button above to populate me.',
};
itemClicked = '';
Expand All @@ -75,6 +46,34 @@ export default class App extends Vue {
tagClicked = '';
tagDblClicked = '';
populate() {
const total = 1000;
this.item = {
key: 'root',
name: 'root name',
tags: [{key: 'root tag', label: 'root label'}],
children: [],
};
for (let i = 1; i < total; i++) {
const child: G8TreeItem = {
key: `key-${i}`,
name: `name ${i}`,
tags: [{key: `tag-${i}`, label: `tag ${i}`}],
children: [],
};
for (let j = 1; j < total; j++) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
child.children!.push({
key: `key-${i}`,
name: `name ${i}`,
tags: [{key: `tag-${i}`, label: `tag ${i}`}],
});
}
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
this.item.children!.push(child);
}
}
}
</script>

Expand Down
11 changes: 7 additions & 4 deletions src/components/G8TreeView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
>{{ tag.label }}</label>
</span>
</div>
<ul v-if="hasChild" class="g8-tree__branch">
<ul v-if="expanded || item.rendered" class="g8-tree__branch">
<g8-tree-view v-for="(child, index) in item.children"
:key="index"
:item="child"
Expand All @@ -45,9 +45,7 @@
import {Component, Prop, Vue} from 'vue-property-decorator';
import {G8StateChangeEvent, G8TreeItem} from './types';
@Component({
name: 'g8-tree-view',
})
@Component({name: 'g8-tree-view'})
export default class G8TreeView extends Vue {
@Prop() item!: G8TreeItem;
Expand All @@ -67,6 +65,10 @@ export default class G8TreeView extends Vue {
return this.item.children && this.item.children.length;
}
created() {
// console.log(`created: ${this.item.name}`);
}
setState(state: boolean) {
this.item.checked = this.checked = state;
this.$children.forEach(c => (c as G8TreeView).setState(state));
Expand All @@ -75,6 +77,7 @@ export default class G8TreeView extends Vue {
clicked() {
if (this.hasChild) {
this.item.rendered = true;
this.expanded = !this.expanded;
}
this.$emit('click', this.item.key);
Expand Down
2 changes: 2 additions & 0 deletions src/components/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ export interface G8TreeItem {
*/
ints?: boolean;

rendered?: boolean;

tags?: G8TreeItemTag[];

children?: G8TreeItem[];
Expand Down
44 changes: 22 additions & 22 deletions tests/unit/G8TreeView.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,34 +78,34 @@ describe('Tree View', () => {
.toBe('tag2');
});

it('renders hierarchy', async () => {
expect.assertions(4);
const wrapper = mount(G8TreeView, {propsData: tree});
expect(wrapper.props('item')).toEqual(tree.item);
const labels = wrapper.findAll('.g8-tree__node_label_text');
expect(labels.length).toBe(5);
expect(labels.at(0).text()).toBe('root name');
expect(labels.at(1).text()).toBe('item 1');
});

it('expends/collapses branches on click', async () => {
expect.assertions(5);
// initially no branch were expanded
it('expends/collapses and renders branches on click', async () => {
expect.assertions(11);
// initially no branch were expanded nor rendered
const wrapper = mount(G8TreeView, {propsData: tree});
expect(wrapper.find('.g8-tree__node_expended').exists()).toBeFalsy();
expect(wrapper.findAll('.g8-tree__branch').length).toBe(2);
// click the first branch to expand it
expect(wrapper.findAll('.g8-tree__branch').length).toBe(0);
expect(wrapper.findAll('.g8-tree__node_label_text').length).toBe(1);
// click the first branch to expand it and render the sub-tree
wrapper.find('.g8-tree__node_label').trigger('click');
await wrapper.vm.$nextTick();
expect(wrapper.findAll('.g8-tree__node_expended').length).toBe(1);
// click the second branch to expand it
await wrapper.vm.$nextTick(() => {
expect(wrapper.findAll('.g8-tree__node_expended').length).toBe(1);
const labels = wrapper.findAll('.g8-tree__node_label_text');
expect(labels.length).toBe(3);
expect(labels.at(0).text()).toBe('root name');
expect(labels.at(1).text()).toBe('item 1');
});
// click the second branch to expand it and render the sub-tree
wrapper.findAll('.g8-tree__branch .g8-tree__node_label').trigger('click');
await wrapper.vm.$nextTick();
expect(wrapper.findAll('.g8-tree__node_expended').length).toBe(2);
await wrapper.vm.$nextTick(() => {
expect(wrapper.findAll('.g8-tree__node_expended').length).toBe(2);
expect(wrapper.findAll('.g8-tree__node_label_text').length).toBe(5);
});
// click branches to collapse them all
wrapper.findAll('.g8-tree__node_label').trigger('click');
await wrapper.vm.$nextTick();
expect(wrapper.find('.g8-tree__node_expended').exists()).toBeFalsy();
await wrapper.vm.$nextTick(() => {
expect(wrapper.find('.g8-tree__node_expended').exists()).toBeFalsy();
expect(wrapper.findAll('.g8-tree__node_label_text').length).toBe(5);
});
});

it('emits click events', async () => {
Expand Down

0 comments on commit 54b5b33

Please sign in to comment.