Skip to content

Commit ab7a9c7

Browse files
berge472geekhybrid
andauthored
Adding append slots (#21)
* Added CSS to terminate vertical lines * cleaned up and added comments * only apply guidelines to child nodes * added style to component * Added item-append and child-append slots * Removing 'checkable' and adding styles * fix typo in readme --------- Co-authored-by: Francis Enyi <39003759+geekhybrid@users.noreply.github.com>
1 parent ca8f6bf commit ab7a9c7

File tree

6 files changed

+202
-73
lines changed

6 files changed

+202
-73
lines changed

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,3 +111,11 @@ export interface TreeViewItem {
111111
| item-prepend-icon | Defines the node's prepend icon.
112112
| item-prepend | Defines a slot to house content before the node's label.
113113
| item-expander | Defines a slot for custom expander implementations
114+
| item-append | Defines a slot for adding custom content after the item name
115+
| child-append | Defines a slot for adding a custom item after the last child
116+
117+
## Classes
118+
119+
| Name | Description |
120+
| -------------|-------------
121+
| on-item-hover | Use in `child-append` and `item-append` slots to only show when the cursor is hovering on the node

dev/serve.vue

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import json from './tree.json';
33
import Vue3TreeVue from '@/tree-component.vue';
44
import { ref } from '@vue/reactivity';
55
import { defineComponent } from '@vue/runtime-core';
6-
import '@/style.css';
76
import { TreeViewItem } from '@/types';
87
98
export default defineComponent({
@@ -20,6 +19,7 @@ export default defineComponent({
2019
2120
return {
2221
isCheckable: ref(true),
22+
hideGuidelines: ref(false),
2323
items,
2424
onItemChecked,
2525
onItemSelected
@@ -31,15 +31,23 @@ export default defineComponent({
3131
<template>
3232
<div id="app">
3333
<div style="display: block">
34+
<span>
3435
<label>Use check items</label>
3536
<input type="checkbox" v-model="isCheckable" />
37+
38+
</span>
39+
&nbsp;
40+
<span>
41+
<label>Hide Guidelines</label>
42+
<input type="checkbox" v-model="hideGuidelines" />
43+
</span>
3644
<button @click="items.forEach(item => item.expanded = false)">Collapse all</button>
3745
<hr>
3846
<div style="display: flex">
3947
<vue3-tree-vue :items="items"
4048
:isCheckable="isCheckable"
41-
:hideGuideLines="true"
42-
:lazy-load="true"
49+
:hideGuideLines="hideGuidelines"
50+
:lazy-load="false"
4351
@dropValidator="(_, __) => true"
4452
@onSelect="onItemSelected"
4553
@onCheck="onItemChecked"
@@ -69,6 +77,18 @@ export default defineComponent({
6977
v-if="treeViewItem.type === 'emails'"
7078
height="20" width="20">
7179
</template>
80+
81+
<template v-slot:item-append="treeViewItem">
82+
<span class="on-item-hover" v-if="treeViewItem.type === 'emails'"><button title="New Email"> item-append</button></span>
83+
</template>
84+
85+
<template v-slot:child-append="treeViewItem">
86+
<span v-if="treeViewItem.id === 6">
87+
<button>child-append for Unsolved Problems</button>
88+
</span>
89+
</template>
90+
91+
7292
</vue3-tree-vue>
7393
</div>
7494
</div>
@@ -80,4 +100,12 @@ export default defineComponent({
80100
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
81101
font-size: 14px;
82102
}
103+
104+
button {
105+
background: none;
106+
border: 1px dashed blue;
107+
border-radius: 4px;
108+
color: blue;
109+
cursor: pointer;
110+
}
83111
</style>

src/composables/use-graph.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ export function useGraph(
5252
}
5353

5454
const emitItemSelected = (node: TreeViewItem) => {
55+
if (node.disabled === true) {
56+
return;
57+
}
5558
itemSelectedEventHandler(node);
5659
Object.values(nodeLookUp).forEach(node => node.selected = false);
5760
node.selected = true;

src/style.css

Lines changed: 149 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,97 +1,176 @@
11
.selected-tree-item {
22
background: rgba(235, 106, 59, 0.795);
33
color: white;
4+
}
5+
6+
.tree-item:hover .on-item-hover{
7+
display: block;
48
}
59

6-
.tree-item {
7-
padding: 0.25em;
10+
.tree-item .on-item-hover{
11+
display: none;
812
}
913

10-
ul {
11-
padding-left: 0;
12-
margin: 0;
13-
list-style-type: none;
14-
display: inline-block;
14+
.tree-item-node:hover li > .on-item-hover{
15+
display: block;
1516
}
1617

17-
li {
18-
border-radius: 4px;
18+
.tree-item-node li > .on-item-hover{
19+
display: none;
1920
}
21+
2022

21-
.tree-item__drag-over {
22-
background-color: rgba(22, 22, 22, 0.068) !important;
23+
.no-guide .tree-item-node {
24+
border: none !important;
25+
}
26+
.no-guide .tree-item-node::before {
27+
border: none !important;
2328
}
2429

30+
.no-guide .horizontal-dashes {
31+
border: none !important;
32+
}
2533

26-
.root__drag-over {
27-
border-left: 6px solid #ccc !important;
34+
.no-guide .horizontal-dashes::before {
35+
border: none !important;
2836
}
2937

3038

31-
.chevron-right {
39+
40+
/**
41+
* Create Vertical Guideline
42+
* Add a dashed border to the left of all but the last child in a parent node.
43+
* There will be a gap between the bottom of this tree-item-node and the top of the next sibling.
44+
*/
45+
.node-child > .tree-item-node-parent .tree-item-node:not(:last-child) {
46+
position: relative;
47+
border-left: 1px dashed rgb(192, 192, 192);
48+
border-radius: 0;
49+
}
50+
51+
/**
52+
* Fill in gap on Vertical Guideline
53+
* use the ::before pseudo-element to create a dashed line that extends down to the next sibling.
54+
* This will be applied to all but the last child in a parent node, and fill in the gap mentioned above.
55+
*/
56+
.node-child > .tree-item-node-parent .tree-item-node:not(:last-child)::before {
57+
content: "";
58+
position: absolute;
59+
top: 100%; /* Extend below the actual element */
60+
left: -1px; /* Match the border-left width */
61+
height: 1em; /* Adjust the desired height */
62+
border-left: 1px dashed rgb(192, 192, 192);
63+
}
64+
65+
66+
.tree-item-node:only-child .tree-view-item{
67+
position: relative; /* Needed to position the ::before pseudo-element */
68+
}
69+
70+
/**
71+
* Create Vertical Guideline for only-children
72+
* Since we rely on the previous sibling to fill in the gap by extending down,
73+
* only-child elements will need to extend up to fill in the gap.
74+
*/
75+
.node-child > .tree-item-node-parent .tree-item-node:only-child > .tree-view-item > .horizontal-dashes::before {
76+
content: "";
77+
position: absolute;
78+
bottom: 50%; /* Extend above the actual element */
79+
left: -1px; /* Match the border-left width */
80+
height: 1em; /* Extend 20px above the element */
81+
border-left: 1px dashed rgb(192, 192, 192);
82+
}
83+
84+
85+
.tree-item {
86+
padding: 0.25em;
87+
}
88+
89+
ul {
90+
padding-left: 0;
91+
margin: 0;
92+
list-style-type: none;
93+
display: inline-block;
94+
}
95+
96+
li {
97+
border-radius: 4px;
98+
}
99+
100+
.tree-item__drag-over {
101+
background-color: rgba(22, 22, 22, 0.068) !important;
102+
}
103+
104+
105+
.root__drag-over {
106+
border-left: 6px solid #ccc !important;
107+
}
108+
109+
110+
.chevron-right {
32111
color: gray;
33-
}
34-
35-
.hide-chevron {
112+
}
113+
114+
.hide-chevron {
36115
visibility: collapse;
37-
}
38-
39-
.icon-area {
116+
}
117+
118+
.icon-area {
40119
width: 22px;
41120
margin-right: 0.4em;
42-
}
43-
44-
.horizontal-dashes {
121+
}
122+
123+
.horizontal-dashes {
45124
width: 1em;
46125
border-top: 1px dashed rgb(192, 192, 192);
47126
}
48-
49-
.node-name {
127+
128+
.node-name {
50129
cursor: pointer;
51130
margin-left: 5px;
52-
}
53-
54-
.d-flex {
131+
}
132+
133+
.d-flex {
55134
display: flex;
56135
align-items: center;
57-
}
58-
59-
.align-items-center {
136+
}
137+
138+
.align-items-center {
60139
align-items: center;
61-
}
62-
63-
.nested {
140+
}
141+
142+
.nested {
64143
margin-left: 47px !important;
65-
}
66-
67-
.root {
144+
}
145+
146+
.root {
68147
margin-left: 30px !important;
69-
}
70-
71-
.tiny_horizontal_margin {
72-
margin-left: 2px;
73-
margin-right: 2px;
74-
}
75-
76-
.tree-item__checkbox-area {
77-
display: flex;
78-
align-items: center;
79-
}
80-
81-
.node-child {
82-
border-left: 1px dashed rgb(192, 192, 192);
148+
}
149+
150+
.tiny_horizontal_margin {
151+
margin-left: 2px;
152+
margin-right: 2px;
153+
}
154+
155+
.tree-item__checkbox-area {
156+
display: flex;
157+
align-items: center;
158+
}
159+
160+
.node-child {
161+
text-align: left;
83162
display: block;
84-
}
85-
86-
.hide {
163+
}
164+
165+
.hide {
87166
display: none;
88-
}
89-
90-
.hide-guidelines {
167+
}
168+
169+
.hide-guidelines {
91170
border-left: none !important;
92-
}
93-
94-
.chevron-right {
171+
}
172+
173+
.chevron-right {
95174
box-sizing: border-box;
96175
position: relative;
97176
display: block;
@@ -101,17 +180,17 @@ li {
101180
border: 2px solid transparent;
102181
border-radius: 100px;
103182
transition: .2s;
104-
}
105-
106-
.pointer {
183+
}
184+
185+
.pointer {
107186
cursor: pointer;
108-
}
109-
110-
.chevron-right.rotate-90::after {
187+
}
188+
189+
.chevron-right.rotate-90::after {
111190
transform: rotateZ(45deg);
112-
}
113-
114-
.chevron-right::after {
191+
}
192+
193+
.chevron-right::after {
115194
content: "";
116195
display: block;
117196
box-sizing: border-box;
@@ -123,4 +202,4 @@ li {
123202
transform: rotate(-45deg);
124203
right: 6px;
125204
top: 5px
126-
}
205+
}

src/tree-component.vue

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<template>
22
<ul id="explorer" class="explorer tree-item-node-parent"
3+
:class="{'no-guide': hideGuideLines}"
34
@dragover.stop.prevent
45
@dragenter.stop.prevent
56
@dragover.stop="addRootHoverClass($event, parent == null)"
@@ -28,6 +29,8 @@
2829
<template v-slot:icon><slot name="item-prepend-icon" v-bind="treeViewItem"></slot></template>
2930
<template v-slot:prepend><slot name="item-prepend" v-bind="treeViewItem"></slot></template>
3031
<template v-slot:expander><slot name="item-expander" v-bind="treeViewItem"></slot></template>
32+
<template v-slot:name><slot name="item-name" v-bind="treeViewItem"></slot></template>
33+
<template v-slot:append><slot name="item-append" v-bind="treeViewItem"></slot></template>
3134
</treeview-item>
3235
<div class="node-child"
3336
:class="{'nested': parent != null, 'root': parent == undefined, 'hide': !treeViewItem.expanded, 'hide-guidelines': hideGuideLines }"
@@ -48,5 +51,9 @@
4851
</div>
4952
</li>
5053
</ul>
54+
<li style="list-style: none;">
55+
<slot v-if="parent" name="child-append" v-bind="parent"></slot>
56+
</li>
5157
</template>
58+
<style src="./style.css" lang="css" />
5259
<script src="./tree-component.ts" lang="ts" />

0 commit comments

Comments
 (0)