@cluetec/ngcx-tree 0.1.0-angular-15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +4 -0
- package/LICENSE +21 -0
- package/README.md +318 -0
- package/esm2020/cluetec-ngcx-tree.mjs +5 -0
- package/esm2020/lib/ngcx-tree/ngcx-tree-data.source.mjs +16 -0
- package/esm2020/lib/ngcx-tree/ngcx-tree-models.mjs +2 -0
- package/esm2020/lib/ngcx-tree/ngcx-tree-node/ngcx-tree-node.component.mjs +49 -0
- package/esm2020/lib/ngcx-tree/ngcx-tree-utils.mjs +10 -0
- package/esm2020/lib/ngcx-tree/ngcx-tree.component.mjs +323 -0
- package/esm2020/public-api.mjs +6 -0
- package/fesm2015/cluetec-ngcx-tree.mjs +410 -0
- package/fesm2015/cluetec-ngcx-tree.mjs.map +1 -0
- package/fesm2020/cluetec-ngcx-tree.mjs +400 -0
- package/fesm2020/cluetec-ngcx-tree.mjs.map +1 -0
- package/index.d.ts +5 -0
- package/lib/ngcx-tree/ngcx-tree-data.source.d.ts +9 -0
- package/lib/ngcx-tree/ngcx-tree-models.d.ts +46 -0
- package/lib/ngcx-tree/ngcx-tree-node/ngcx-tree-node.component.d.ts +19 -0
- package/lib/ngcx-tree/ngcx-tree-utils.d.ts +2 -0
- package/lib/ngcx-tree/ngcx-tree.component.d.ts +56 -0
- package/package.json +52 -0
- package/public-api.d.ts +2 -0
- package/styles/_ngcx-common.scss +5 -0
- package/styles/_ngcx-doted-tree-line.scss +44 -0
- package/styles/_ngcx-icon-color.scss +7 -0
- package/styles/_ngcx-selection.scss +24 -0
- package/styles/styles.scss +4 -0
package/CHANGELOG.md
ADDED
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 cluetec GmbH
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
A reusable tree component for Angular based on the CDK Tree and the CDK Drag n
|
|
2
|
+
Drop features.
|
|
3
|
+
|
|
4
|
+
<br>
|
|
5
|
+
Status is beta - feedback welcome :)
|
|
6
|
+
|
|
7
|
+
# Table of Content
|
|
8
|
+
|
|
9
|
+
- [Table of Content](#table-of-content)
|
|
10
|
+
- [Getting Started](#getting-started)
|
|
11
|
+
- [Inputs](#inputs)
|
|
12
|
+
- [Outputs](#outputs)
|
|
13
|
+
- [Model](#model)
|
|
14
|
+
- [NgcxTreeConfig](#ngcxtreeconfig)
|
|
15
|
+
- [NgcxTreeNode](#ngcxtreenode)
|
|
16
|
+
- [NgcxTreeNodeWrapper](#ngcxtreenodewrapper)
|
|
17
|
+
- [NgcxTreeNodeMovedEvent](#ngcxtreenodemovedevent)
|
|
18
|
+
- [NgcxCustomComponent](#ngcxcustomcomponent)
|
|
19
|
+
- [Input](#input)
|
|
20
|
+
- [Output](#output)
|
|
21
|
+
- [Api](#api)
|
|
22
|
+
- [treeControl](#treecontrol)
|
|
23
|
+
- [Helper methods](#helper-methods)
|
|
24
|
+
- [selectNodeById](#selectnodebyid)
|
|
25
|
+
- [findNodeById](#findnodebyid)
|
|
26
|
+
- [Styling](#styling)
|
|
27
|
+
- [Include Styles](#include-styles)
|
|
28
|
+
- [Common styling](#common-styling)
|
|
29
|
+
- [Dotted tree lines](#dotted-tree-lines)
|
|
30
|
+
- [Selection highlighting](#selection-highlighting)
|
|
31
|
+
- [Icon color](#icon-color)
|
|
32
|
+
- [Font Awesome](#font-awesome)
|
|
33
|
+
- [Selection](#selection)
|
|
34
|
+
- [Simple Sample](#simple-sample)
|
|
35
|
+
- [Contributions](#contributions)
|
|
36
|
+
|
|
37
|
+
# Getting Started
|
|
38
|
+
|
|
39
|
+
1. Install the library:
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
npm install @cluetec/ngcx-tree
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
2. Import the component. Since it is standalone, either add it directly to
|
|
46
|
+
another standlone component or import it into your existing `NgModule`:
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
import { NgcxTreeComponent } from '@cluetec/ngcx-tree';
|
|
50
|
+
|
|
51
|
+
@Component({
|
|
52
|
+
standalone: true,
|
|
53
|
+
imports: [NgcxTreeComponent],
|
|
54
|
+
})
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
import { NgcxTreeComponent } from '@cluetec/ngcx-tree';
|
|
59
|
+
|
|
60
|
+
@NgModule({
|
|
61
|
+
declarations: [AppComponent],
|
|
62
|
+
imports: [NgcxTreeComponent],
|
|
63
|
+
bootstrap: [AppComponent]
|
|
64
|
+
})
|
|
65
|
+
export class AppModule {}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
<br><br>
|
|
69
|
+
|
|
70
|
+
# Inputs
|
|
71
|
+
|
|
72
|
+
| Property | Type | required | Description |
|
|
73
|
+
| -------- | --------------------------------- | -------- | ------------------------------------------------------------------- |
|
|
74
|
+
| nodes | [NgcxTreeNode](#NgcxTreeNode)[] | no | list of nodes to show in the tree |
|
|
75
|
+
| config | [NgcxTreeConfig](#NgcxTreeConfig) | no | used to render the node when no custom template or component is set |
|
|
76
|
+
|
|
77
|
+
# Outputs
|
|
78
|
+
|
|
79
|
+
| Property | event content type | Description |
|
|
80
|
+
| ----------- | ---------------------- | ----------------------------------------------------------------------------------------- |
|
|
81
|
+
| nodeMoved | NgcxTreeNodeMovedEvent | fired when a node is moved |
|
|
82
|
+
| customEvent | any | may be fired by your own custom component |
|
|
83
|
+
| clickEvent | NgcxTreeNodeWrapper | fired when node is clicked |
|
|
84
|
+
| selectEvent | NgcxTreeNodeWrapper | fired when node is selected or un-selected. Clicking a selected node un-selects the node. |
|
|
85
|
+
|
|
86
|
+
# Model
|
|
87
|
+
|
|
88
|
+
## NgcxTreeConfig
|
|
89
|
+
|
|
90
|
+
The component includes a model called `NgcxTreeConfig` with some basic optional
|
|
91
|
+
settings.
|
|
92
|
+
|
|
93
|
+
- `allowDrag` method that decides if a node can be dragged:
|
|
94
|
+
`(node: NgcxTreeNodeWrapper<T>) => boolean` - all nodes are draggable by
|
|
95
|
+
default<br><br>
|
|
96
|
+
- `allowDrop` method that decides if node can be dropped into another node
|
|
97
|
+
`(node: NgcxTreeNodeWrapper<T>, intoNode?: NgcxTreeNodeWrapper<T>) => boolean ` -
|
|
98
|
+
every node may be draggable everywhere by default<br><br>
|
|
99
|
+
- `allowSelection` method that decides if node can be selected
|
|
100
|
+
`(node: NgcxTreeNodeWrapper<T>) => boolean ` - nodes are not selectable by
|
|
101
|
+
default<br><br>
|
|
102
|
+
- `treeNodeContentTemplate` Angular TemplateRef that will be used to render a
|
|
103
|
+
node<br><br> `let-nodeWrapper="nodeWrapper"` may be used to access the node
|
|
104
|
+
wrapper to render the node
|
|
105
|
+
- `treeNodeContentComponent` Angular Component that will be used to render a
|
|
106
|
+
node. (use `treeNodeContentComponent` or `treeNodeContentTemplate`, but not
|
|
107
|
+
both). see [NgcxCustomComponent<T>](#NgcxCustomComponent)
|
|
108
|
+
|
|
109
|
+
<br><br>
|
|
110
|
+
|
|
111
|
+
## NgcxTreeNode
|
|
112
|
+
|
|
113
|
+
If no data is passed to the component, it will simply display some mock data.
|
|
114
|
+
Data is provided to the tree in the following format:
|
|
115
|
+
|
|
116
|
+
| Property | Type | required | Description |
|
|
117
|
+
| -------- | -------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
118
|
+
| id | string | yes | necessary unique id of the node |
|
|
119
|
+
| title | string | no | used to render the node when no custom template or component is set |
|
|
120
|
+
| faIcon | string | no | font awesome icon used to render the node when no custom template or component is set. You must include fontawesome on your own if you want |
|
|
121
|
+
| children | NgcxTreeNode[] | no | children of the node |
|
|
122
|
+
|
|
123
|
+
## NgcxTreeNodeWrapper<T>
|
|
124
|
+
|
|
125
|
+
Generic T is the same as the elements of the input `nodes`.
|
|
126
|
+
|
|
127
|
+
| Property | Type | Description |
|
|
128
|
+
| ------------ | ----------------------------------- | ------------------------------------------------------------------------------------------ |
|
|
129
|
+
| id | string | same as NgcxTreeNode.id |
|
|
130
|
+
| data | T | data of the input nodes `nodes` |
|
|
131
|
+
| depth | number | depth in the tree starting with 0 |
|
|
132
|
+
| index | number | index of the node in it's parent |
|
|
133
|
+
| isSelectable | boolean | if the node is selectable. Depending on the config.allowSelection method. (default: false) |
|
|
134
|
+
| isFirstChild | boolean | is first node from the same parent |
|
|
135
|
+
| isLastChild | boolean | is last node from the same parent |
|
|
136
|
+
| children | NgcxTreeNodeWrapper<T>[] | list of children wrappers around the original nodes |
|
|
137
|
+
| parent | NgcxTreeNodeWrapper<T> \| undefined | parent node |
|
|
138
|
+
| next | NgcxTreeNodeWrapper<T> \| undefined | node after this node in same parent, if one exists. |
|
|
139
|
+
| previous | NgcxTreeNodeWrapper<T> \| undefined | node before this node in same parent, if one exists. |
|
|
140
|
+
|
|
141
|
+
## NgcxTreeNodeMovedEvent
|
|
142
|
+
|
|
143
|
+
| Property | Type | Description |
|
|
144
|
+
| ---------- | ----------------------------------- | ---------------------------------- |
|
|
145
|
+
| node | NgcxTreeNodeWrapper<T> | the moved node |
|
|
146
|
+
| parent | NgcxTreeNodeWrapper<T> \| undefined | moved into this parent node |
|
|
147
|
+
| afterNode | NgcxTreeNodeWrapper<T> \| undefined | moved to position after this node |
|
|
148
|
+
| beforeNode | NgcxTreeNodeWrapper<T> \| undefined | moved to position before this node |
|
|
149
|
+
|
|
150
|
+
## NgcxCustomComponent<T>
|
|
151
|
+
|
|
152
|
+
Your component can implement this interface and can be set as
|
|
153
|
+
`Type<NgcxCustomComponent<T>>` in the config.treeNodeContentComponent input.
|
|
154
|
+
|
|
155
|
+
### Input
|
|
156
|
+
|
|
157
|
+
`nodeWrapper` the input to render the node. Type: NgcxTreeNodeWrapper<T>
|
|
158
|
+
|
|
159
|
+
### Output
|
|
160
|
+
|
|
161
|
+
`customEvent` `EventEmitter<any>` can be used to trigger the output
|
|
162
|
+
'customEvent'
|
|
163
|
+
|
|
164
|
+
# Api
|
|
165
|
+
|
|
166
|
+
## treeControl
|
|
167
|
+
|
|
168
|
+
the treeControl (`NestedTreeControl<NgcxTreeNodeWrapper<T>, string>`) of Angular
|
|
169
|
+
CDK can be mainly used to expand and collapse nodes.
|
|
170
|
+
|
|
171
|
+
## Helper methods
|
|
172
|
+
|
|
173
|
+
### selectNodeById
|
|
174
|
+
|
|
175
|
+
Can be called to select a node by id. the selectEvent event is fired afterwards.
|
|
176
|
+
|
|
177
|
+
### findNodeById
|
|
178
|
+
|
|
179
|
+
Can be used to get the `NgcxTreeNodeWrapper<T>` for an id. returns `undefined`
|
|
180
|
+
if no node is available for the id.
|
|
181
|
+
|
|
182
|
+
# Styling
|
|
183
|
+
|
|
184
|
+
## Include Styles
|
|
185
|
+
|
|
186
|
+
Or All styles from below:
|
|
187
|
+
|
|
188
|
+
```scss
|
|
189
|
+
@import '@cluetec/ngcx-tree/styles/styles';
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
## Common styling
|
|
193
|
+
|
|
194
|
+
you should set the width of cdk-drop-list to 100%, otherwise, the node content
|
|
195
|
+
may be on wrong place:
|
|
196
|
+
|
|
197
|
+
```css
|
|
198
|
+
.ngcx-tree .cdk-drop-list {
|
|
199
|
+
width: 100%;
|
|
200
|
+
}
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
Or Include this:
|
|
204
|
+
|
|
205
|
+
```scss
|
|
206
|
+
@import '@cluetec/ngcx-tree/styles/ngcx-common';
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### Dotted tree lines
|
|
210
|
+
|
|
211
|
+
Import or copy the scss to show tree lines:
|
|
212
|
+
|
|
213
|
+
```scss
|
|
214
|
+
@import '@cluetec/ngcx-tree/styles/ngcx-doted-tree-line';
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### Selection highlighting
|
|
218
|
+
|
|
219
|
+
Import or copy the scss to show some selection styling:
|
|
220
|
+
|
|
221
|
+
```scss
|
|
222
|
+
@import '@cluetec/ngcx-tree/styles/ngcx-selection';
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
### Icon color
|
|
226
|
+
|
|
227
|
+
Import or copy the scss to set the color of the node icon:
|
|
228
|
+
|
|
229
|
+
```scss
|
|
230
|
+
@import '@cluetec/ngcx-tree/styles/ngcx-icon-color';
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
## Font Awesome
|
|
234
|
+
|
|
235
|
+
Font Awesome is not referenced included here, but to show icons for the nodes
|
|
236
|
+
you must include font-awesome on your own and may use the `node.faIcon` property
|
|
237
|
+
to set the icon.
|
|
238
|
+
|
|
239
|
+
Include like this:
|
|
240
|
+
[projects/ngcx-tree/stories/styles/styles.scss](projects/ngcx-tree/stories/styles/styles.scss)
|
|
241
|
+
|
|
242
|
+
## Selection
|
|
243
|
+
|
|
244
|
+
Selected node can be styled like this:
|
|
245
|
+
|
|
246
|
+
```css
|
|
247
|
+
.tree-node-content-container.selected .tree-node-content {
|
|
248
|
+
background-color: #555;
|
|
249
|
+
padding-left: 5px;
|
|
250
|
+
}
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
Hover effect on selectable node:
|
|
254
|
+
|
|
255
|
+
```css
|
|
256
|
+
.ngcx-tree:not(.dragging)
|
|
257
|
+
.tree-node-content-container.is-selectable:hover
|
|
258
|
+
.tree-node-content {
|
|
259
|
+
background-color: #fbfbfb;
|
|
260
|
+
}
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
Remove Selection css on dragging element:
|
|
264
|
+
|
|
265
|
+
```css
|
|
266
|
+
.cdk-drag-preview .tree-node-content-container.selected .tree-node-content {
|
|
267
|
+
background-color: inherit;
|
|
268
|
+
}
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
# Simple Sample
|
|
272
|
+
|
|
273
|
+
```ts
|
|
274
|
+
import { DragDropModule } from '@angular/cdk/drag-drop';
|
|
275
|
+
import { CdkTreeModule } from '@angular/cdk/tree';
|
|
276
|
+
import { Component } from '@angular/core';
|
|
277
|
+
import { NgcxTreeComponent } from '@cluetec/ngcx-tree';
|
|
278
|
+
|
|
279
|
+
@Component({
|
|
280
|
+
selector: 'app-simple-tree-sample',
|
|
281
|
+
template: '<ngcx-tree [nodes]="data"></ngcx-tree>',
|
|
282
|
+
standalone: true,
|
|
283
|
+
imports: [CdkTreeModule, DragDropModule, NgcxTreeComponent],
|
|
284
|
+
})
|
|
285
|
+
export class SimpleTreeSampleComponent {
|
|
286
|
+
data = [
|
|
287
|
+
{
|
|
288
|
+
id: 'fru',
|
|
289
|
+
title: 'Fruit',
|
|
290
|
+
children: [
|
|
291
|
+
{
|
|
292
|
+
id: 'app',
|
|
293
|
+
title: 'Apple',
|
|
294
|
+
},
|
|
295
|
+
{
|
|
296
|
+
id: 'ban',
|
|
297
|
+
title: 'Banana',
|
|
298
|
+
},
|
|
299
|
+
],
|
|
300
|
+
},
|
|
301
|
+
{
|
|
302
|
+
id: 'fish',
|
|
303
|
+
title: 'Fish',
|
|
304
|
+
},
|
|
305
|
+
];
|
|
306
|
+
}
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
<br><br>
|
|
310
|
+
|
|
311
|
+
# Contributions
|
|
312
|
+
|
|
313
|
+
Contributions and improvement suggestions are always welcome!
|
|
314
|
+
|
|
315
|
+
##Samples
|
|
316
|
+
|
|
317
|
+
For samples see the storybook stories. run `npm run storybook` to see the
|
|
318
|
+
samples.
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generated bundle index. Do not edit.
|
|
3
|
+
*/
|
|
4
|
+
export * from './public-api';
|
|
5
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2x1ZXRlYy1uZ2N4LXRyZWUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9wcm9qZWN0cy9uZ2N4LXRyZWUvc3JjL2NsdWV0ZWMtbmdjeC10cmVlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBRUgsY0FBYyxjQUFjLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEdlbmVyYXRlZCBidW5kbGUgaW5kZXguIERvIG5vdCBlZGl0LlxuICovXG5cbmV4cG9ydCAqIGZyb20gJy4vcHVibGljLWFwaSc7XG4iXX0=
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { DataSource } from '@angular/cdk/collections';
|
|
2
|
+
import { BehaviorSubject } from 'rxjs';
|
|
3
|
+
export class NgcxTreeDataSource extends DataSource {
|
|
4
|
+
constructor(data) {
|
|
5
|
+
super();
|
|
6
|
+
this.data$ = new BehaviorSubject(data);
|
|
7
|
+
}
|
|
8
|
+
connect() {
|
|
9
|
+
return this.data$.asObservable();
|
|
10
|
+
}
|
|
11
|
+
disconnect() { }
|
|
12
|
+
update(data) {
|
|
13
|
+
this.data$.next([...data]);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmdjeC10cmVlLWRhdGEuc291cmNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmdjeC10cmVlL3NyYy9saWIvbmdjeC10cmVlL25nY3gtdHJlZS1kYXRhLnNvdXJjZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDdEQsT0FBTyxFQUFFLGVBQWUsRUFBYyxNQUFNLE1BQU0sQ0FBQztBQUVuRCxNQUFNLE9BQU8sa0JBQXNCLFNBQVEsVUFBYTtJQUd0RCxZQUFZLElBQVM7UUFDbkIsS0FBSyxFQUFFLENBQUM7UUFDUixJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksZUFBZSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3pDLENBQUM7SUFFRCxPQUFPO1FBQ0wsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLFlBQVksRUFBRSxDQUFDO0lBQ25DLENBQUM7SUFDRCxVQUFVLEtBQVUsQ0FBQztJQUVyQixNQUFNLENBQUMsSUFBUztRQUNkLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDO0lBQzdCLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IERhdGFTb3VyY2UgfSBmcm9tICdAYW5ndWxhci9jZGsvY29sbGVjdGlvbnMnO1xuaW1wb3J0IHsgQmVoYXZpb3JTdWJqZWN0LCBPYnNlcnZhYmxlIH0gZnJvbSAncnhqcyc7XG5cbmV4cG9ydCBjbGFzcyBOZ2N4VHJlZURhdGFTb3VyY2U8VD4gZXh0ZW5kcyBEYXRhU291cmNlPFQ+IHtcbiAgZGF0YSQ6IEJlaGF2aW9yU3ViamVjdDxUW10+O1xuXG4gIGNvbnN0cnVjdG9yKGRhdGE6IFRbXSkge1xuICAgIHN1cGVyKCk7XG4gICAgdGhpcy5kYXRhJCA9IG5ldyBCZWhhdmlvclN1YmplY3QoZGF0YSk7XG4gIH1cblxuICBjb25uZWN0KCk6IE9ic2VydmFibGU8cmVhZG9ubHkgVFtdPiB7XG4gICAgcmV0dXJuIHRoaXMuZGF0YSQuYXNPYnNlcnZhYmxlKCk7XG4gIH1cbiAgZGlzY29ubmVjdCgpOiB2b2lkIHt9XG5cbiAgdXBkYXRlKGRhdGE6IFRbXSkge1xuICAgIHRoaXMuZGF0YSQubmV4dChbLi4uZGF0YV0pO1xuICB9XG59XG4iXX0=
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export {};
|
|
2
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmdjeC10cmVlLW1vZGVscy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25nY3gtdHJlZS9zcmMvbGliL25nY3gtdHJlZS9uZ2N4LXRyZWUtbW9kZWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBOZXN0ZWRUcmVlQ29udHJvbCB9IGZyb20gJ0Bhbmd1bGFyL2Nkay90cmVlJztcbmltcG9ydCB7IEV2ZW50RW1pdHRlciwgVGVtcGxhdGVSZWYsIFR5cGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuZXhwb3J0IGludGVyZmFjZSBOZ2N4VHJlZUNvbmZpZzxUPiB7XG4gIHRyZWVOb2RlQ29udGVudENvbXBvbmVudD86IFR5cGU8TmdjeEN1c3RvbUNvbXBvbmVudDxUPj47XG4gIHRyZWVOb2RlQ29udGVudFRlbXBsYXRlPzogVGVtcGxhdGVSZWY8YW55PjtcblxuICBhbGxvd0Ryb3A/OiAoXG4gICAgbm9kZTogTmdjeFRyZWVOb2RlV3JhcHBlcjxUPixcbiAgICBpbnRvTm9kZT86IE5nY3hUcmVlTm9kZVdyYXBwZXI8VD5cbiAgKSA9PiBib29sZWFuO1xuICBhbGxvd0RyYWc/OiAobm9kZTogTmdjeFRyZWVOb2RlV3JhcHBlcjxUPikgPT4gYm9vbGVhbjtcbiAgYWxsb3dTZWxlY3Rpb24/OiAobm9kZTogTmdjeFRyZWVOb2RlV3JhcHBlcjxUPikgPT4gYm9vbGVhbjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBOZ2N4Q3VzdG9tQ29tcG9uZW50PFQ+IHtcbiAgbm9kZVdyYXBwZXI/OiBOZ2N4VHJlZU5vZGVXcmFwcGVyPFQ+O1xuICBjdXN0b21FdmVudD86IEV2ZW50RW1pdHRlcjxhbnk+O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIE5nY3hUcmVlTm9kZSB7XG4gIGlkOiBzdHJpbmc7XG4gIHRpdGxlPzogYW55O1xuICBmYUljb24/OiBzdHJpbmc7XG4gIGNoaWxkcmVuPzogTmdjeFRyZWVOb2RlW107XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTmdjeFRyZWVOb2RlV3JhcHBlcjxUPiB7XG4gIGlkOiBzdHJpbmc7XG4gIGRhdGE6IFQ7XG4gIGRlcHRoOiBudW1iZXI7XG4gIGluZGV4OiBudW1iZXI7XG4gIGlzU2VsZWN0YWJsZT86IGJvb2xlYW47XG4gIGlzRmlyc3RDaGlsZDogYm9vbGVhbjtcbiAgaXNMYXN0Q2hpbGQ6IGJvb2xlYW47XG4gIGNoaWxkcmVuOiBOZ2N4VHJlZU5vZGVXcmFwcGVyPFQ+W107XG4gIHBhcmVudD86IE5nY3hUcmVlTm9kZVdyYXBwZXI8VD47XG4gIG5leHQ/OiBOZ2N4VHJlZU5vZGVXcmFwcGVyPFQ+O1xuICBwcmV2aW91cz86IE5nY3hUcmVlTm9kZVdyYXBwZXI8VD47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTmdjeFRyZWVOb2RlQ29tcG9uZW50PFQ+IHtcbiAgbm9kZVdyYXBwZXI/OiBOZ2N4VHJlZU5vZGVXcmFwcGVyPFQ+O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIE5nY3hUcmVlTm9kZU1vdmVkRXZlbnQ8VD4ge1xuICBub2RlOiBOZ2N4VHJlZU5vZGVXcmFwcGVyPFQ+O1xuICBwYXJlbnQ/OiBOZ2N4VHJlZU5vZGVXcmFwcGVyPFQ+O1xuICBhZnRlck5vZGU/OiBOZ2N4VHJlZU5vZGVXcmFwcGVyPFQ+O1xuICBiZWZvcmVOb2RlPzogTmdjeFRyZWVOb2RlV3JhcHBlcjxUPjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBOZ2N4VHJlZUFwaTxUPiB7XG4gIHNlbGVjdE5vZGVCeUlkKGlkOiBzdHJpbmcpOiB2b2lkO1xuICBmaW5kTm9kZUJ5SWQoaWQ6IHN0cmluZyk6IE5nY3hUcmVlTm9kZVdyYXBwZXI8VD4gfCB1bmRlZmluZWQ7XG5cbiAgZ2V0IHRyZWVDb250cm9sKCk6IE5lc3RlZFRyZWVDb250cm9sPE5nY3hUcmVlTm9kZVdyYXBwZXI8YW55Piwgc3RyaW5nPjtcbn1cbiJdfQ==
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { CdkTreeModule } from '@angular/cdk/tree';
|
|
2
|
+
import { Component, EventEmitter, Input, Output, ViewChild, ViewContainerRef, } from '@angular/core';
|
|
3
|
+
import { NgIf, NgTemplateOutlet } from '@angular/common';
|
|
4
|
+
import { Subject, takeUntil } from 'rxjs';
|
|
5
|
+
import * as i0 from "@angular/core";
|
|
6
|
+
import * as i1 from "@angular/cdk/tree";
|
|
7
|
+
export class NgcxTreeNodeComponent {
|
|
8
|
+
constructor() {
|
|
9
|
+
this.isSelected = false;
|
|
10
|
+
this.customEvent = new EventEmitter();
|
|
11
|
+
this.clickEvent = new EventEmitter();
|
|
12
|
+
this.ngUnsubscribe = new Subject();
|
|
13
|
+
}
|
|
14
|
+
ngOnInit() {
|
|
15
|
+
if (this.vcRef && this.treeConfig?.treeNodeContentComponent) {
|
|
16
|
+
const nodeComponent = this.vcRef.createComponent(this.treeConfig.treeNodeContentComponent);
|
|
17
|
+
nodeComponent.instance.nodeWrapper = this.nodeWrapper;
|
|
18
|
+
nodeComponent.instance.customEvent
|
|
19
|
+
?.pipe(takeUntil(this.ngUnsubscribe))
|
|
20
|
+
.subscribe((value) => this.customEvent.emit(value));
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
ngOnDestroy() {
|
|
24
|
+
this.ngUnsubscribe.next(undefined);
|
|
25
|
+
this.ngUnsubscribe.complete();
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
NgcxTreeNodeComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: NgcxTreeNodeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
29
|
+
NgcxTreeNodeComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: NgcxTreeNodeComponent, isStandalone: true, selector: "ngcx-tree-node", inputs: { nodeWrapper: "nodeWrapper", treeControl: "treeControl", treeConfig: "treeConfig", isSelected: "isSelected" }, outputs: { customEvent: "customEvent", clickEvent: "clickEvent" }, viewQueries: [{ propertyName: "vcRef", first: true, predicate: ["ref"], descendants: true, read: ViewContainerRef, static: true }], ngImport: i0, template: "<div\n class=\"tree-node-content-container\"\n [class.selected]=\"isSelected\"\n [class.first]=\"nodeWrapper.isFirstChild\"\n [class.last]=\"nodeWrapper.isLastChild\"\n [class.is-selectable]=\"nodeWrapper.isSelectable\"\n (click)=\"clickEvent.emit()\">\n <div class=\"tree-node-expand-container\">\n <button\n *ngIf=\"nodeWrapper.children.length > 0\"\n class=\"tree-node-expand\"\n cdkTreeNodeToggle\n [attr.aria-label]=\"'Toggle ' + nodeWrapper.data.title\"\n (click)=\"$event.preventDefault()\">\n <div class=\"chevron\" [class.rotate]=\"treeControl.isExpanded(nodeWrapper)\">\n <svg id=\"a\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 9 9\">\n <path\n d=\"m2.83.09l4.2,4.2c.05.05.09.14.09.21s-.04.15-.09.21l-4.2,4.2c-.05.05-.14.09-.21.09s-.15-.04-.21-.09l-.45-.45c-.05-.05-.09-.13-.09-.21,0-.07.04-.15.09-.21l3.54-3.54L1.97.96c-.05-.05-.09-.14-.09-.21s.04-.15.09-.21l.45-.45c.05-.05.14-.09.21-.09s.15.04.21.09Z\"\n style=\"fill: var(--icon-color, #333); stroke-width: 0px\" />\n </svg>\n </div>\n </button>\n </div>\n <div class=\"small-horizontal-tree-line\"></div>\n <div class=\"tree-node-icon-container\" *ngIf=\"nodeWrapper.data.faIcon\">\n <i class=\"fa\" [class]=\"nodeWrapper.data.faIcon\"></i>\n </div>\n <div class=\"tree-node-content\">\n <span\n *ngIf=\"\n !treeConfig?.treeNodeContentComponent &&\n !treeConfig?.treeNodeContentTemplate\n \">\n {{ nodeWrapper.data.title }}\n </span>\n <ng-container #ref></ng-container>\n <ng-container *ngIf=\"treeConfig?.treeNodeContentTemplate as template\">\n <ng-container\n *ngTemplateOutlet=\"\n template;\n context: {\n nodeWrapper: nodeWrapper\n }\n \"></ng-container>\n </ng-container>\n </div>\n</div>\n", styles: [".tree-node-content-container{display:flex;flex-direction:row;justify-content:flex-start;align-items:center;width:100%}.tree-node-content-container.is-selectable{cursor:pointer}.tree-node-content-container .tree-node-expand-container{display:flex;flex-direction:row;justify-content:center;align-items:center;width:30px;height:30px;margin-right:5px}.tree-node-content-container .tree-node-expand-container>.tree-node-expand{color:#2587be;background:none;border:none;font:inherit;cursor:pointer;outline:inherit;width:30px;height:30px;display:flex;justify-content:center;align-items:center}.tree-node-content-container .tree-node-expand-container>.tree-node-expand .chevron{width:10px;transition:transform .1s ease-in-out}.tree-node-content-container .tree-node-expand-container>.tree-node-expand .chevron.rotate{transform:rotate(90deg)}.tree-node-content-container .tree-node-icon-container{margin-right:7px;color:#2587be}\n"], dependencies: [{ kind: "ngmodule", type: CdkTreeModule }, { kind: "directive", type: i1.CdkTreeNodeToggle, selector: "[cdkTreeNodeToggle]", inputs: ["cdkTreeNodeToggleRecursive"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
|
|
30
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: NgcxTreeNodeComponent, decorators: [{
|
|
31
|
+
type: Component,
|
|
32
|
+
args: [{ selector: 'ngcx-tree-node', standalone: true, imports: [CdkTreeModule, NgTemplateOutlet, NgIf], template: "<div\n class=\"tree-node-content-container\"\n [class.selected]=\"isSelected\"\n [class.first]=\"nodeWrapper.isFirstChild\"\n [class.last]=\"nodeWrapper.isLastChild\"\n [class.is-selectable]=\"nodeWrapper.isSelectable\"\n (click)=\"clickEvent.emit()\">\n <div class=\"tree-node-expand-container\">\n <button\n *ngIf=\"nodeWrapper.children.length > 0\"\n class=\"tree-node-expand\"\n cdkTreeNodeToggle\n [attr.aria-label]=\"'Toggle ' + nodeWrapper.data.title\"\n (click)=\"$event.preventDefault()\">\n <div class=\"chevron\" [class.rotate]=\"treeControl.isExpanded(nodeWrapper)\">\n <svg id=\"a\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 9 9\">\n <path\n d=\"m2.83.09l4.2,4.2c.05.05.09.14.09.21s-.04.15-.09.21l-4.2,4.2c-.05.05-.14.09-.21.09s-.15-.04-.21-.09l-.45-.45c-.05-.05-.09-.13-.09-.21,0-.07.04-.15.09-.21l3.54-3.54L1.97.96c-.05-.05-.09-.14-.09-.21s.04-.15.09-.21l.45-.45c.05-.05.14-.09.21-.09s.15.04.21.09Z\"\n style=\"fill: var(--icon-color, #333); stroke-width: 0px\" />\n </svg>\n </div>\n </button>\n </div>\n <div class=\"small-horizontal-tree-line\"></div>\n <div class=\"tree-node-icon-container\" *ngIf=\"nodeWrapper.data.faIcon\">\n <i class=\"fa\" [class]=\"nodeWrapper.data.faIcon\"></i>\n </div>\n <div class=\"tree-node-content\">\n <span\n *ngIf=\"\n !treeConfig?.treeNodeContentComponent &&\n !treeConfig?.treeNodeContentTemplate\n \">\n {{ nodeWrapper.data.title }}\n </span>\n <ng-container #ref></ng-container>\n <ng-container *ngIf=\"treeConfig?.treeNodeContentTemplate as template\">\n <ng-container\n *ngTemplateOutlet=\"\n template;\n context: {\n nodeWrapper: nodeWrapper\n }\n \"></ng-container>\n </ng-container>\n </div>\n</div>\n", styles: [".tree-node-content-container{display:flex;flex-direction:row;justify-content:flex-start;align-items:center;width:100%}.tree-node-content-container.is-selectable{cursor:pointer}.tree-node-content-container .tree-node-expand-container{display:flex;flex-direction:row;justify-content:center;align-items:center;width:30px;height:30px;margin-right:5px}.tree-node-content-container .tree-node-expand-container>.tree-node-expand{color:#2587be;background:none;border:none;font:inherit;cursor:pointer;outline:inherit;width:30px;height:30px;display:flex;justify-content:center;align-items:center}.tree-node-content-container .tree-node-expand-container>.tree-node-expand .chevron{width:10px;transition:transform .1s ease-in-out}.tree-node-content-container .tree-node-expand-container>.tree-node-expand .chevron.rotate{transform:rotate(90deg)}.tree-node-content-container .tree-node-icon-container{margin-right:7px;color:#2587be}\n"] }]
|
|
33
|
+
}], propDecorators: { nodeWrapper: [{
|
|
34
|
+
type: Input
|
|
35
|
+
}], treeControl: [{
|
|
36
|
+
type: Input
|
|
37
|
+
}], treeConfig: [{
|
|
38
|
+
type: Input
|
|
39
|
+
}], isSelected: [{
|
|
40
|
+
type: Input
|
|
41
|
+
}], customEvent: [{
|
|
42
|
+
type: Output
|
|
43
|
+
}], clickEvent: [{
|
|
44
|
+
type: Output
|
|
45
|
+
}], vcRef: [{
|
|
46
|
+
type: ViewChild,
|
|
47
|
+
args: ['ref', { read: ViewContainerRef, static: true }]
|
|
48
|
+
}] } });
|
|
49
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmdjeC10cmVlLW5vZGUuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmdjeC10cmVlL3NyYy9saWIvbmdjeC10cmVlL25nY3gtdHJlZS1ub2RlL25nY3gtdHJlZS1ub2RlLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25nY3gtdHJlZS9zcmMvbGliL25nY3gtdHJlZS9uZ2N4LXRyZWUtbm9kZS9uZ2N4LXRyZWUtbm9kZS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsYUFBYSxFQUFxQixNQUFNLG1CQUFtQixDQUFDO0FBQ3JFLE9BQU8sRUFDTCxTQUFTLEVBQ1QsWUFBWSxFQUNaLEtBQUssRUFHTCxNQUFNLEVBQ04sU0FBUyxFQUNULGdCQUFnQixHQUNqQixNQUFNLGVBQWUsQ0FBQztBQUd2QixPQUFPLEVBQUUsSUFBSSxFQUFFLGdCQUFnQixFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDekQsT0FBTyxFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxNQUFNLENBQUM7OztBQVMxQyxNQUFNLE9BQU8scUJBQXFCO0lBUGxDO1FBV1csZUFBVSxHQUFHLEtBQUssQ0FBQztRQUVsQixnQkFBVyxHQUFHLElBQUksWUFBWSxFQUFPLENBQUM7UUFDdEMsZUFBVSxHQUFHLElBQUksWUFBWSxFQUFRLENBQUM7UUFLaEQsa0JBQWEsR0FBRyxJQUFJLE9BQU8sRUFBRSxDQUFDO0tBbUIvQjtJQWpCQyxRQUFRO1FBQ04sSUFBSSxJQUFJLENBQUMsS0FBSyxJQUFJLElBQUksQ0FBQyxVQUFVLEVBQUUsd0JBQXdCLEVBQUU7WUFDM0QsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxlQUFlLENBQzlDLElBQUksQ0FBQyxVQUFVLENBQUMsd0JBQXdCLENBQ3pDLENBQUM7WUFDRixhQUFhLENBQUMsUUFBUSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDO1lBRXRELGFBQWEsQ0FBQyxRQUFRLENBQUMsV0FBVztnQkFDaEMsRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQztpQkFDcEMsU0FBUyxDQUFDLENBQUMsS0FBVSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1NBQzVEO0lBQ0gsQ0FBQztJQUVELFdBQVc7UUFDVCxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNuQyxJQUFJLENBQUMsYUFBYSxDQUFDLFFBQVEsRUFBRSxDQUFDO0lBQ2hDLENBQUM7O21IQTlCVSxxQkFBcUI7dUdBQXJCLHFCQUFxQiw4VUFTTixnQkFBZ0IsMkNDaEM1QyxxMURBK0NBLGs5QkQxQlksYUFBYSwySkFBRSxnQkFBZ0Isb0pBQUUsSUFBSTs0RkFFcEMscUJBQXFCO2tCQVBqQyxTQUFTOytCQUNFLGdCQUFnQixjQUdkLElBQUksV0FDUCxDQUFDLGFBQWEsRUFBRSxnQkFBZ0IsRUFBRSxJQUFJLENBQUM7OEJBR3ZDLFdBQVc7c0JBQW5CLEtBQUs7Z0JBQ0csV0FBVztzQkFBbkIsS0FBSztnQkFDRyxVQUFVO3NCQUFsQixLQUFLO2dCQUNHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBRUksV0FBVztzQkFBcEIsTUFBTTtnQkFDRyxVQUFVO3NCQUFuQixNQUFNO2dCQUdQLEtBQUs7c0JBREosU0FBUzt1QkFBQyxLQUFLLEVBQUUsRUFBRSxJQUFJLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENka1RyZWVNb2R1bGUsIE5lc3RlZFRyZWVDb250cm9sIH0gZnJvbSAnQGFuZ3VsYXIvY2RrL3RyZWUnO1xuaW1wb3J0IHtcbiAgQ29tcG9uZW50LFxuICBFdmVudEVtaXR0ZXIsXG4gIElucHV0LFxuICBPbkRlc3Ryb3ksXG4gIE9uSW5pdCxcbiAgT3V0cHV0LFxuICBWaWV3Q2hpbGQsXG4gIFZpZXdDb250YWluZXJSZWYsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgTmdjeFRyZWVDb25maWcsIE5nY3hUcmVlTm9kZVdyYXBwZXIgfSBmcm9tICcuLi9uZ2N4LXRyZWUtbW9kZWxzJztcblxuaW1wb3J0IHsgTmdJZiwgTmdUZW1wbGF0ZU91dGxldCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBTdWJqZWN0LCB0YWtlVW50aWwgfSBmcm9tICdyeGpzJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnbmdjeC10cmVlLW5vZGUnLFxuICB0ZW1wbGF0ZVVybDogJy4vbmdjeC10cmVlLW5vZGUuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9uZ2N4LXRyZWUtbm9kZS5jb21wb25lbnQuc2NzcyddLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbQ2RrVHJlZU1vZHVsZSwgTmdUZW1wbGF0ZU91dGxldCwgTmdJZl0sXG59KVxuZXhwb3J0IGNsYXNzIE5nY3hUcmVlTm9kZUNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcbiAgQElucHV0KCkgbm9kZVdyYXBwZXIhOiBOZ2N4VHJlZU5vZGVXcmFwcGVyPGFueT47XG4gIEBJbnB1dCgpIHRyZWVDb250cm9sITogTmVzdGVkVHJlZUNvbnRyb2w8TmdjeFRyZWVOb2RlV3JhcHBlcjxhbnk+LCBzdHJpbmc+O1xuICBASW5wdXQoKSB0cmVlQ29uZmlnPzogTmdjeFRyZWVDb25maWc8YW55PjtcbiAgQElucHV0KCkgaXNTZWxlY3RlZCA9IGZhbHNlO1xuXG4gIEBPdXRwdXQoKSBjdXN0b21FdmVudCA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xuICBAT3V0cHV0KCkgY2xpY2tFdmVudCA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcblxuICBAVmlld0NoaWxkKCdyZWYnLCB7IHJlYWQ6IFZpZXdDb250YWluZXJSZWYsIHN0YXRpYzogdHJ1ZSB9KVxuICB2Y1JlZj86IFZpZXdDb250YWluZXJSZWY7XG5cbiAgbmdVbnN1YnNjcmliZSA9IG5ldyBTdWJqZWN0KCk7XG5cbiAgbmdPbkluaXQoKSB7XG4gICAgaWYgKHRoaXMudmNSZWYgJiYgdGhpcy50cmVlQ29uZmlnPy50cmVlTm9kZUNvbnRlbnRDb21wb25lbnQpIHtcbiAgICAgIGNvbnN0IG5vZGVDb21wb25lbnQgPSB0aGlzLnZjUmVmLmNyZWF0ZUNvbXBvbmVudChcbiAgICAgICAgdGhpcy50cmVlQ29uZmlnLnRyZWVOb2RlQ29udGVudENvbXBvbmVudFxuICAgICAgKTtcbiAgICAgIG5vZGVDb21wb25lbnQuaW5zdGFuY2Uubm9kZVdyYXBwZXIgPSB0aGlzLm5vZGVXcmFwcGVyO1xuXG4gICAgICBub2RlQ29tcG9uZW50Lmluc3RhbmNlLmN1c3RvbUV2ZW50XG4gICAgICAgID8ucGlwZSh0YWtlVW50aWwodGhpcy5uZ1Vuc3Vic2NyaWJlKSlcbiAgICAgICAgLnN1YnNjcmliZSgodmFsdWU6IGFueSkgPT4gdGhpcy5jdXN0b21FdmVudC5lbWl0KHZhbHVlKSk7XG4gICAgfVxuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5uZ1Vuc3Vic2NyaWJlLm5leHQodW5kZWZpbmVkKTtcbiAgICB0aGlzLm5nVW5zdWJzY3JpYmUuY29tcGxldGUoKTtcbiAgfVxufVxuIiwiPGRpdlxuICBjbGFzcz1cInRyZWUtbm9kZS1jb250ZW50LWNvbnRhaW5lclwiXG4gIFtjbGFzcy5zZWxlY3RlZF09XCJpc1NlbGVjdGVkXCJcbiAgW2NsYXNzLmZpcnN0XT1cIm5vZGVXcmFwcGVyLmlzRmlyc3RDaGlsZFwiXG4gIFtjbGFzcy5sYXN0XT1cIm5vZGVXcmFwcGVyLmlzTGFzdENoaWxkXCJcbiAgW2NsYXNzLmlzLXNlbGVjdGFibGVdPVwibm9kZVdyYXBwZXIuaXNTZWxlY3RhYmxlXCJcbiAgKGNsaWNrKT1cImNsaWNrRXZlbnQuZW1pdCgpXCI+XG4gIDxkaXYgY2xhc3M9XCJ0cmVlLW5vZGUtZXhwYW5kLWNvbnRhaW5lclwiPlxuICAgIDxidXR0b25cbiAgICAgICpuZ0lmPVwibm9kZVdyYXBwZXIuY2hpbGRyZW4ubGVuZ3RoID4gMFwiXG4gICAgICBjbGFzcz1cInRyZWUtbm9kZS1leHBhbmRcIlxuICAgICAgY2RrVHJlZU5vZGVUb2dnbGVcbiAgICAgIFthdHRyLmFyaWEtbGFiZWxdPVwiJ1RvZ2dsZSAnICsgbm9kZVdyYXBwZXIuZGF0YS50aXRsZVwiXG4gICAgICAoY2xpY2spPVwiJGV2ZW50LnByZXZlbnREZWZhdWx0KClcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJjaGV2cm9uXCIgW2NsYXNzLnJvdGF0ZV09XCJ0cmVlQ29udHJvbC5pc0V4cGFuZGVkKG5vZGVXcmFwcGVyKVwiPlxuICAgICAgICA8c3ZnIGlkPVwiYVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB2aWV3Qm94PVwiMCAwIDkgOVwiPlxuICAgICAgICAgIDxwYXRoXG4gICAgICAgICAgICBkPVwibTIuODMuMDlsNC4yLDQuMmMuMDUuMDUuMDkuMTQuMDkuMjFzLS4wNC4xNS0uMDkuMjFsLTQuMiw0LjJjLS4wNS4wNS0uMTQuMDktLjIxLjA5cy0uMTUtLjA0LS4yMS0uMDlsLS40NS0uNDVjLS4wNS0uMDUtLjA5LS4xMy0uMDktLjIxLDAtLjA3LjA0LS4xNS4wOS0uMjFsMy41NC0zLjU0TDEuOTcuOTZjLS4wNS0uMDUtLjA5LS4xNC0uMDktLjIxcy4wNC0uMTUuMDktLjIxbC40NS0uNDVjLjA1LS4wNS4xNC0uMDkuMjEtLjA5cy4xNS4wNC4yMS4wOVpcIlxuICAgICAgICAgICAgc3R5bGU9XCJmaWxsOiB2YXIoLS1pY29uLWNvbG9yLCAjMzMzKTsgc3Ryb2tlLXdpZHRoOiAwcHhcIiAvPlxuICAgICAgICA8L3N2Zz5cbiAgICAgIDwvZGl2PlxuICAgIDwvYnV0dG9uPlxuICA8L2Rpdj5cbiAgPGRpdiBjbGFzcz1cInNtYWxsLWhvcml6b250YWwtdHJlZS1saW5lXCI+PC9kaXY+XG4gIDxkaXYgY2xhc3M9XCJ0cmVlLW5vZGUtaWNvbi1jb250YWluZXJcIiAqbmdJZj1cIm5vZGVXcmFwcGVyLmRhdGEuZmFJY29uXCI+XG4gICAgPGkgY2xhc3M9XCJmYVwiIFtjbGFzc109XCJub2RlV3JhcHBlci5kYXRhLmZhSWNvblwiPjwvaT5cbiAgPC9kaXY+XG4gIDxkaXYgY2xhc3M9XCJ0cmVlLW5vZGUtY29udGVudFwiPlxuICAgIDxzcGFuXG4gICAgICAqbmdJZj1cIlxuICAgICAgICAhdHJlZUNvbmZpZz8udHJlZU5vZGVDb250ZW50Q29tcG9uZW50ICYmXG4gICAgICAgICF0cmVlQ29uZmlnPy50cmVlTm9kZUNvbnRlbnRUZW1wbGF0ZVxuICAgICAgXCI+XG4gICAgICB7eyBub2RlV3JhcHBlci5kYXRhLnRpdGxlIH19XG4gICAgPC9zcGFuPlxuICAgIDxuZy1jb250YWluZXIgI3JlZj48L25nLWNvbnRhaW5lcj5cbiAgICA8bmctY29udGFpbmVyICpuZ0lmPVwidHJlZUNvbmZpZz8udHJlZU5vZGVDb250ZW50VGVtcGxhdGUgYXMgdGVtcGxhdGVcIj5cbiAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgKm5nVGVtcGxhdGVPdXRsZXQ9XCJcbiAgICAgICAgICB0ZW1wbGF0ZTtcbiAgICAgICAgICBjb250ZXh0OiB7XG4gICAgICAgICAgICBub2RlV3JhcHBlcjogbm9kZVdyYXBwZXJcbiAgICAgICAgICB9XG4gICAgICAgIFwiPjwvbmctY29udGFpbmVyPlxuICAgIDwvbmctY29udGFpbmVyPlxuICA8L2Rpdj5cbjwvZGl2PlxuIl19
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export const isParentOf = (parent, node) => {
|
|
2
|
+
if (!node.parent) {
|
|
3
|
+
return false;
|
|
4
|
+
}
|
|
5
|
+
if (parent.id === node.parent.id) {
|
|
6
|
+
return true;
|
|
7
|
+
}
|
|
8
|
+
return isParentOf(parent, node.parent);
|
|
9
|
+
};
|
|
10
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmdjeC10cmVlLXV0aWxzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmdjeC10cmVlL3NyYy9saWIvbmdjeC10cmVlL25nY3gtdHJlZS11dGlscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQSxNQUFNLENBQUMsTUFBTSxVQUFVLEdBQUcsQ0FDeEIsTUFBZ0MsRUFDaEMsSUFBOEIsRUFDckIsRUFBRTtJQUNYLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFO1FBQ2hCLE9BQU8sS0FBSyxDQUFDO0tBQ2Q7SUFDRCxJQUFJLE1BQU0sQ0FBQyxFQUFFLEtBQUssSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUU7UUFDaEMsT0FBTyxJQUFJLENBQUM7S0FDYjtJQUNELE9BQU8sVUFBVSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7QUFDekMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgTmdjeFRyZWVOb2RlV3JhcHBlciB9IGZyb20gJy4vbmdjeC10cmVlLW1vZGVscyc7XG5cbmV4cG9ydCBjb25zdCBpc1BhcmVudE9mID0gKFxuICBwYXJlbnQ6IE5nY3hUcmVlTm9kZVdyYXBwZXI8YW55PixcbiAgbm9kZTogTmdjeFRyZWVOb2RlV3JhcHBlcjxhbnk+XG4pOiBib29sZWFuID0+IHtcbiAgaWYgKCFub2RlLnBhcmVudCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpZiAocGFyZW50LmlkID09PSBub2RlLnBhcmVudC5pZCkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIHJldHVybiBpc1BhcmVudE9mKHBhcmVudCwgbm9kZS5wYXJlbnQpO1xufTtcbiJdfQ==
|