@keenmate/svelte-treeview 0.1.0

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/README.md ADDED
@@ -0,0 +1,249 @@
1
+ # Svelte Treeview
2
+
3
+ The most elaborate treeview for svelte on earth (or even in our galaxy).
4
+ [DEMO](https://dev.phoenix-svelte-adminlte.demo.keenmate.com/#/tree)
5
+
6
+ ## Table of Contents
7
+
8
+ - [Svelte Treeview](#svelte-treeview)
9
+ - [Props](#props)
10
+ - [Events](#events)
11
+ - [function on component](#function-on-component)
12
+ - [Helper functions](#helper-functions)
13
+ - [basic usage](#basic-usage)
14
+ - [callbacks](#callbacks)
15
+ - [selection](#selection)
16
+ - [search](#search)
17
+ - [drag and drop](#drag-and-drop)
18
+ - [context menu](#context-menu)
19
+
20
+ ## Instalation
21
+
22
+ Font awesome is required
23
+
24
+ ## Props
25
+
26
+ - ***tree*** (array of nodes, default: *null*)
27
+ tree itself.
28
+ - ***treeId*** (string, default: *null*)
29
+ you HAVE to set this to unique string
30
+ - ***maxExpandedDepth*** (number, default: *3*)
31
+ - ***filteredTree*** (array of nodes, default: *null*)
32
+ Nodes that should be rendered (same as tree if null)
33
+ - ***checkboxes*** (string "none"|"perNode"|"All", default: *false*)
34
+ When all checkboxes will be shown if **checkboxVisible** isnt false,whe perNode only nodes with **checkboxVisible** set to true will be shown. None will override **checkboxVisible** .When click on checkbox it will toggle selected on clicked node. You can specify this behavior with **recursive**, **onlyLeafCheckboxes** and **checkboxesDisabled**.
35
+ - ***recursive*** (bool, default: *false*)
36
+ When true, you can only select "leaf nodes" (nodes when **hasChildren** isnt true). When clicking other nodes, it will tooggle all children. Non leaf children will have wont have **selected**, instead, __visual_state will be calculated automatically ( all true => true, at least one true => indeterminate, all false => false).
37
+ - ***onlyLeafCheckboxes*** ( bool, default: *false*)
38
+ you wont be able to click on any other checkboxes that on leaf nodes.
39
+ - ***checkboxesDisabled*** (bool, default: *false*)
40
+ will only disable checkboxes, instead of not showing them.
41
+ - ***dragAndDrop*** (bool, default: *false*)
42
+ will enable drag and drop behavior viz drag and drop section
43
+ - ***timeToNest*** (number in ms, default: *null*)
44
+ after that time hovering over one node, it will nest.
45
+ - ***pixelNestTreshold*** (number in px, default: *150*)
46
+ when you move cursor to then left by x pixels will nest
47
+ - ***expandCallback*** (function that takes node as argument, default: *null*)
48
+ called when node with **useCallback** set to true is expanded. Only called once.
49
+ - ***showContexMenu*** (bool, default: false)
50
+ Will show context menu you defined in context-menu slot when you right click any node
51
+ - ***beforeMovedCallback*** (function with params: (movedNode,oldParent,TargetNode,insType: ("before","inside","after")), default: null )
52
+ Called when you droped node before any recalculation takes place. You can cancel move by returning false
53
+ - ***dragEnterCallback*** (function with params: (movedNode,oldParent,TargetNode), default: null )
54
+ Called when dragged nodes enters different node. By returnting false, it will set that node as nonvalid target so you wont be able to it and it doesnt show guide lines. Dont do any expensive operations here and dont modify tree.
55
+ - ***enableVerticalLines*** (bool, default: false)
56
+ This property controls if vertical lines are displayed in front of each node for easier use
57
+ - ***recalculateNodePath*** (bool,default: true)
58
+ If true, will not change last part of nodePath of moved node. Use this is=f last part of your nodePath is **unique!**.
59
+ - ***expandedLevel*** (number,default:0)
60
+ will expand all nodes until this specific level(starting from 0). Set it to -1 to disable it. **expanded** has priority over this. It wont modify **expanded** on nodes so you can dynamicly change this and tree will rerender
61
+ - ***props***
62
+ property names used to store stuff in node objects
63
+ - ***readonly***(bool,false)
64
+ when true it will disable all expansion
65
+ - ***separator***(string,default: ".")
66
+ separator in nodePath
67
+
68
+ ```js
69
+ const defaultProps = {
70
+ nodePath: "nodePath",
71
+ hasChildren: "hasChildren",
72
+ expanded: "__expanded",
73
+ selected: "__selected",
74
+ useCallback: "__useCallback",
75
+ priority: "priority",
76
+ isDraggable: "isDraggable",
77
+ insertDisabled: "insertDisabled",
78
+ nestDisabled: "nestDisabled",
79
+ checkbox: "checkbox",
80
+ };
81
+ ```
82
+
83
+ - ***treeClass*** (string css class, default: *"treeview"*)
84
+ Setting this to anything else that default value will disable all styling so you can set everything yourself
85
+ - ***nodeClass*** (string css class, default: *""*)
86
+ - ***expandedToggleClass*** (string css class, default: *""*)
87
+ - ***collapsedToggleClass*** (string css class, default: *""*)
88
+ - ***currentlyDraggedClass*** (string css class, default: *"currently-dragged"*)
89
+ - ***expandClass*** (string css class, default: *"inserting-highlighted"*)
90
+ - ***inserLineClass*** (string css class, default: *""*)
91
+ - ***inserLineNestClass*** (string css class, default: *""*)
92
+ - ***currentlyDraggedClass*** (string css class, default: *"currently-dragged"*)
93
+
94
+ ## Events
95
+
96
+ - **expansion** { node: node,value: bool } = fired when user clicks on plus/minus icon
97
+ - **expanded** { node }
98
+ - **closed** { node }
99
+ - **moved** { oldParent: Node,newParent:Node oldNode: Node, newNode: Node,targetNode: Node,insType: ("before","inside","after")} = fires when user moved node with drag and drop. Target is element you dropped node at.
100
+ - **selection** { node: node,value: bool } = fired when user clicks on checkbox
101
+ - **selected** {node }
102
+ - **unselected** {node }
103
+
104
+ ## function on component
105
+
106
+ you call them on binded component
107
+
108
+ - **changeAllExpansion(changeTo)** = changes expansionn status of every that hasChildren to value you specify
109
+
110
+ example:
111
+
112
+ ```js
113
+ let thisTree
114
+
115
+
116
+ //...
117
+ <button on:click={thisTree.changeAllExpansion(true)} >expand All</button>
118
+ <button on:click={thisTree.changeAllExpansion(false)} >colapse All</button>
119
+
120
+ <TreeView
121
+ bind:this={thisTree}
122
+ bind:tree
123
+ treeId="tree"
124
+ let:node
125
+ >
126
+ {node.nodePath}
127
+ </TreeView>
128
+ ```
129
+
130
+ ## Helper functions
131
+
132
+ - **searchTree(tree, filterFunction, recursive,propNames)** = function that will filter tree using filterFunction and adds all parent so that it can render. If recursive is true, it will only search through "lef nodes" (nodes that dont have children)
133
+ - **mergeTrees(oldTree,addedTree,nodePath="nodePath")** = will merge new tree into old one, so that expanded, etc. wont be reseted.
134
+
135
+ usage:
136
+
137
+ ```js
138
+ import {TreeView,mergeTrees,searchTree} from "../index.js";
139
+ //will merger treeToAdd into tree, so expansion etc wont be effected
140
+ tree = mergeTrees(tree,treeToAdd);
141
+ //searches tree
142
+ filteredTree = searchTree(tree, filterFunction, recursive,propNames)
143
+ ```
144
+
145
+ ## basic usage
146
+
147
+ You need to provide treeId and tree, that is array of node where every node has nodepath defined. Parent nodes have to have hasChildren set to true. Next you have to set a default slot with how you want you nodes to be rendered.You can add your own props to nodes and used them here in events, contextmenus and callbacks. Treeview uses **expanded** to determine expansion.
148
+
149
+ example:
150
+
151
+ ```js
152
+ import {TreeView} from "svelte-treeview"
153
+ let tree = [
154
+ { nodePath: "1"},
155
+ { nodePath: "2"},
156
+ { nodePath: "3", hasChildren: true},
157
+ { nodePath: "3.1"},
158
+ { nodePath: "3.2", hasChildren: true},
159
+ { nodePath: "3.2.1"},
160
+ { nodePath: "3.2.2"},
161
+ { nodePath: "3.2.3" },
162
+ { nodePath: "3.2.4"},
163
+ { nodePath: "3.3"}
164
+ ]
165
+ //...
166
+
167
+ <TreeView
168
+ bind:tree
169
+ treeId="tree"
170
+ let:node
171
+ >
172
+ {node.nodePath}
173
+ </TreeView>
174
+
175
+ ```
176
+
177
+ ## callbacks
178
+
179
+ To dynamicly load data, you have to have hasChildren(to show + icon) and **useCallback** set to true on nodes you want to use callback on. Then expandCallback will be called with expanded node as parametr. Function should return Promise or array of nodes, that will be added to tree. **useCallback** will be then set to false, so that callback will only be called once.
180
+
181
+ example:
182
+
183
+ ```js
184
+ let tree = [
185
+ { nodePath: "1",__useCallback: true,},
186
+ { nodePath: "2",__useCallback: true,},
187
+ { nodePath: "3", hasChildren: true},
188
+ { nodePath: "3.1"},
189
+ { nodePath: "3.2", hasChildren: true},
190
+ { nodePath: "3.2.1"},
191
+ { nodePath: "3.2.2"},
192
+ { nodePath: "3.2.3" },
193
+ { nodePath: "3.2.4"},
194
+ { nodePath: "3.3",__useCallback: true,}
195
+ ]
196
+ let num =0
197
+ //...
198
+ <TreeView
199
+ bind:tree
200
+ treeId="tree"
201
+ let:node
202
+ expandCallback={(n) => {
203
+ return [
204
+ {nodePath: n.nodePath + "." + ++num,
205
+ __useCallback: true,hasChildren: true,}
206
+ ]
207
+ }}
208
+ >
209
+ {node.nodePath}
210
+
211
+ </TreeView>
212
+
213
+ ```
214
+
215
+ ## selection
216
+
217
+ ## search
218
+
219
+ ## drag and drop
220
+
221
+ After setting dragAndDrop to true, you will be able to change order of nodes and moving them between nodes by dragging.When **isDraggable** on node is set to false you wont be able to grab it. You can enable nesting by setting timeToNest of pixerNestTreshold. Node will be inserted as child of targeted note after *at least one* of tresholds is met. Before node will be moved, **beforeMovedCallback** fill be fired and if it returns false, move will be cancelled.
222
+ New id will be computed as biggest id of childred in targeted node +1 and new priority as 0 when nest or if not as priority of target +1. Then it recomputes all priorities so there wont be conficts. After this **moved** event will be fired with old parent, old node (copy of dragged node before changes to id, priority, etc.),new node (dragged node after changes), and target node (node you drop it at).
223
+ You can also customize line show when dragging by changing **inserLineNestClass** and **inserLineClass**
224
+
225
+ **dragEnterCallback** is called when you enter new node while dragging. If it return false, node wont be valid node location
226
+
227
+ TODO add note about insertDisabled and nestDisabled
228
+
229
+ ## context menu
230
+
231
+ To enable context menu you first need to add your desired context menu to slot named context-menu. you can accest clicked node with let:node. You can use MenuDivider and MenuOption from this package to easy creation of ctxmenu.Then just set **showContexMenu** to true and context menu will now be showen when you right click on node.
232
+
233
+ example:
234
+
235
+ ```js
236
+
237
+ <TreeView
238
+ //...
239
+ showContexMenu
240
+ //...
241
+ >
242
+ //...
243
+ <svelte:fragment slot="context-menu" let:node>
244
+ <MenuOption text={node.nodePath} isDisabled />
245
+ <MenuDivider />
246
+ <MenuOption text="do stuff" on:click={(node) => doStuff(node)} />
247
+ </svelte:fragment>
248
+ <TreeView>
249
+ ```
@@ -0,0 +1,58 @@
1
+ <script>
2
+ // @ts-nocheck
3
+
4
+ import { createEventDispatcher } from 'svelte';
5
+ import { checkboxesType } from './consts';
6
+
7
+ export let checkboxes;
8
+ export let helper;
9
+ export let recursive;
10
+ export let node;
11
+ export let onlyLeafCheckboxes;
12
+ export let checkboxesDisabled;
13
+ export let readonly = false;
14
+
15
+ const dispatch = createEventDispatcher();
16
+ </script>
17
+
18
+ {#if checkboxes == checkboxesType.perNode || checkboxes == checkboxesType.all}
19
+ {#if helper.selection.isSelectable(node, checkboxes)}
20
+ <!-- select node -->
21
+ {#if !recursive || (recursive && !node[helper.props.hasChildren])}
22
+ <input
23
+ type="checkbox"
24
+ on:change={() => dispatch('select', node)}
25
+ checked={node[helper.props.selected] ? 'false' : ''}
26
+ disabled={readonly}
27
+ />
28
+ <!-- select children-->
29
+ {:else if !onlyLeafCheckboxes}
30
+ <input
31
+ type="checkbox"
32
+ on:click={() => {
33
+ dispatch('select-children', {
34
+ node,
35
+ checked: node.__visual_state == 'true'
36
+ });
37
+ }}
38
+ checked={node.__visual_state == 'true' ? 'false' : ''}
39
+ indeterminate={node.__visual_state == 'indeterminate'}
40
+ disabled={readonly}
41
+ />
42
+ {:else}
43
+ <input
44
+ type="checkbox"
45
+ onclick="return false;"
46
+ disabled={true}
47
+ class:invisible={!checkboxesDisabled}
48
+ />
49
+ {/if}
50
+ {:else}
51
+ <input
52
+ type="checkbox"
53
+ onclick="return false;"
54
+ disabled={true}
55
+ class:invisible={!checkboxesDisabled}
56
+ />
57
+ {/if}
58
+ {/if}
@@ -0,0 +1,41 @@
1
+ /** @typedef {typeof __propDef.props} CheckboxProps */
2
+ /** @typedef {typeof __propDef.events} CheckboxEvents */
3
+ /** @typedef {typeof __propDef.slots} CheckboxSlots */
4
+ export default class Checkbox extends SvelteComponentTyped<{
5
+ checkboxes: any;
6
+ helper: any;
7
+ recursive: any;
8
+ node: any;
9
+ onlyLeafCheckboxes: any;
10
+ checkboxesDisabled: any;
11
+ readonly?: boolean | undefined;
12
+ }, {
13
+ select: CustomEvent<any>;
14
+ 'select-children': CustomEvent<any>;
15
+ } & {
16
+ [evt: string]: CustomEvent<any>;
17
+ }, {}> {
18
+ }
19
+ export type CheckboxProps = typeof __propDef.props;
20
+ export type CheckboxEvents = typeof __propDef.events;
21
+ export type CheckboxSlots = typeof __propDef.slots;
22
+ import { SvelteComponentTyped } from "svelte";
23
+ declare const __propDef: {
24
+ props: {
25
+ checkboxes: any;
26
+ helper: any;
27
+ recursive: any;
28
+ node: any;
29
+ onlyLeafCheckboxes: any;
30
+ checkboxesDisabled: any;
31
+ readonly?: boolean | undefined;
32
+ };
33
+ events: {
34
+ select: CustomEvent<any>;
35
+ 'select-children': CustomEvent<any>;
36
+ } & {
37
+ [evt: string]: CustomEvent<any>;
38
+ };
39
+ slots: {};
40
+ };
41
+ export {};