Skip to content
This repository was archived by the owner on Jan 1, 2025. It is now read-only.

Add node-click emit support #97

Merged
merged 6 commits into from
Feb 11, 2022
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 26 additions & 12 deletions docs/src/guide/emits.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,52 @@

You can access up-to-date data in the operations you perform for the tree with the `emit`'s we use in the package.

### `nodeClick`

This emit is triggered when a node is clicked or selected.

#### Usage

```vue
<Tree :nodes="data" @nodeClick="nodeClick" />
```

```js
const onNodeClick = (node) => {
console.log(node);
};
```

### `nodeExpanded`

When you click on an item, you can use the emit "nodeExpanded" if you want to see the current values of that item and the data below it. This way you will only be able to access the data for that item.

#### Usage

```vue
<Tree
:nodes="data"
@nodeExpanded="onNodeExpanded"
/>
<Tree :nodes="data" @nodeExpanded="onNodeExpanded" />
```

```js
const onNodeExpanded = (node, state) => {
console.log("node: ", node);
console.log("state: ", state);
console.log('node: ', node);
console.log('state: ', state);
};
```

### `update:nodes`

Returns the current data of the tree when a data is deleted or a checkbox is clicked in the tree.
If you are considering to use `@update:nodes` for only updating data, you can also use `v-model:nodes`

#### Usage

```vue
<Tree
:nodes="data"
@update:nodes="onUpdate"
/>
<Tree :nodes="data" @update:nodes="onUpdate" />
```

```js
const onUpdate = (nodes) => {
console.log("nodes: ", nodes);
console.log('nodes: ', nodes);
};
```
```
41 changes: 22 additions & 19 deletions src/lib/components/Tree.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<div class="tree">
<ul :style="{'gap': gap + 'px'}" class="tree-list">
<ul :style="{ 'gap': gap + 'px' }" class="tree-list">
<tree-row
v-for="node in filteredData"
:ref="'tree-row-' + node.id"
Expand All @@ -18,16 +18,18 @@
:update-node="updateNode"
:expandable="expandable"
@delete-row="onDeleteRow"
@node-click="onNodeClick"
@node-select="onNodeClick"
@node-expanded="onNodeExpanded"
@checkbox-toggle="onCheckboxToggle"
@toggle-checkbox="toggleCheckbox"
>
<template #checkbox="{ id, node: slotNode, checked, indeterminate }">
<template #checkbox="{ node: slotNode, checked, indeterminate }">
<slot
name="checkbox"
:node="slotNode"
:checked="checked"
:indeterminate="indeterminate"
:toggleCheckbox="() => toggleCheckbox(id)"
:toggleCheckbox="() => toggleCheckbox(slotNode)"
/>
</template>
<template v-if="useIcon" #iconActive>
Expand Down Expand Up @@ -109,11 +111,11 @@ export default {
type: Boolean,
default: false,
},
useIcon:{
useIcon: {
type: Boolean,
default: true,
},
useRowDelete:{
useRowDelete: {
type: Boolean,
default: false,
},
Expand All @@ -130,7 +132,7 @@ export default {
default: true,
},
},
emits: ['nodeExpanded', 'checkboxToggle', 'update:nodes'],
emits: ['nodeClick', 'nodeExpanded', 'checkboxToggle', 'update:nodes'],
setup(props, { emit }) {
const { search } = useSearch();

Expand All @@ -149,7 +151,6 @@ export default {
return updateNodes(newData);
});


const setNode = (id, node) => {
emit('update:nodes', setNodeById(props.nodes, id, node));
};
Expand All @@ -162,21 +163,22 @@ export default {
emit('update:nodes', updateNodes(updateNodeById(props.nodes, id, data)));
};

const toggleCheckbox = id => {
const { checked } = getNode(id);
updateNode(id, { checked: !checked });
const toggleCheckbox = node => {
const checked = !node.checked;
updateNode(node.id, { checked });
emit('nodeClick', { ...node, checked });
};

watch(()=> props.nodes, ()=>{
watch(() => props.nodes, () => {
emit('update:nodes', props.nodes);
});

const onNodeExpanded = (node, state) => {
emit('nodeExpanded', node, state);
const onNodeClick = node => {
emit('nodeClick', node);
};

const onCheckboxToggle = context => {
emit('checkboxToggle', context);
const onNodeExpanded = (node, state) => {
emit('nodeExpanded', node, state);
};

const onUpdate = () => {
Expand All @@ -192,8 +194,8 @@ export default {
setNode,
getNode,
updateNode,
onNodeClick,
onNodeExpanded,
onCheckboxToggle,
onUpdate,
toggleCheckbox,
onDeleteRow,
Expand All @@ -205,15 +207,16 @@ export default {

<style lang="scss" scoped>
.tree {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen,
Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
}

.tree-list {
margin: 0;
padding: 0;
overflow: hidden;

.tree-row{
.tree-row {
padding-left: 0px !important;
}
}
Expand Down
49 changes: 29 additions & 20 deletions src/lib/components/TreeRow.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
>
<div
class="tree-row-item"
@click.stop="toggleExpanded(node)"
@click.stop="handleClick(node)"
>
<div v-if="useIcon" class="tree-row-item-icon-wrapper">
<template v-if="childCount">
Expand Down Expand Up @@ -38,7 +38,7 @@
type="checkbox"
:checked="node.checked"
:indeterminate="node.indeterminate"
@click.stop="toggleCheckbox"
@click.stop="onToggleCheckbox(node)"
/>
</slot>
<span class="tree-row-txt">
Expand Down Expand Up @@ -87,8 +87,9 @@
:update-node="updateNode"
:expandable="expandable"
@delete-row="removedRow"
@node-click="(item) => handleClick(item, true)"
@toggle-checkbox="onToggleCheckbox"
@node-expanded="onNodeExpanded"
@checkbox-toggle="onCheckboxToggle"
>
<template #childCount="{ count, checkedCount, childs }">
<slot
Expand Down Expand Up @@ -128,7 +129,7 @@
</template>

<script>
import { computed, nextTick, watch } from 'vue';
import { computed, nextTick } from 'vue';
import ArrowRight from './Icons/ArrowRight.vue';
import ArrowDown from './Icons/ArrowDown.vue';
import DeleteIcon from './Icons/DeleteIcon.vue';
Expand Down Expand Up @@ -193,32 +194,41 @@ export default {
default: true,
},
},
emits: ['nodeExpanded', 'checkboxToggle', 'deleteRow'],
emits: [
'nodeSelect',
'nodeClick',
'toggleCheckbox',
'nodeExpanded',
'checkboxToggle',
'deleteRow',
],
setup(props, { emit }) {
const childCount = computed(() => props.node.nodes?.length);
const checkedChildCount = computed(() => props.node.nodes?.filter(item => item.checked).length);

const toggleExpanded = node => {
if (props.expandable && childCount.value) {
props.node.expanded = props.node.nodes ? !props.node.expanded : false;
nextTick(() => {
emit('nodeExpanded', node, props.node.expanded);
});
props.node.expanded = props.node.nodes ? !props.node.expanded : false;
nextTick(() => {
emit('nodeExpanded', node, props.node.expanded);
});
};


const handleClick = (node, passExpand) => {
if (!passExpand && props.expandable && childCount.value) {
toggleExpanded(node);
}

emit('nodeClick', { ...node });
};

// redirect the event toward the Tree component
const onNodeExpanded = (node, state) => {
emit('nodeExpanded', node, state);
};

const toggleCheckbox = () => {
const { node, updateNode } = props;
updateNode(node.id, { checked: !node.checked });
};

const onCheckboxToggle = (context, event) => {
emit('checkboxToggle', context, event);
const onToggleCheckbox = node => {
emit('toggleCheckbox', node);
};

const removedRow = node => {
Expand All @@ -228,10 +238,9 @@ export default {
return {
childCount,
checkedChildCount,
toggleExpanded,
handleClick,
onNodeExpanded,
toggleCheckbox,
onCheckboxToggle,
onToggleCheckbox,
removedRow,
};
},
Expand Down