@threadlabs/looma 0.1.13 → 0.1.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.
Files changed (69) hide show
  1. package/dist/{chunk-DQZJTDIB.js → chunk-SVINNT3E.js} +29 -27
  2. package/dist/cjs/loader.cjs.js +1 -1
  3. package/dist/cjs/looma.cjs.js +1 -1
  4. package/dist/cjs/ui-tree-item.cjs.entry.js +694 -0
  5. package/dist/cjs/ui-tree.cjs.entry.js +257 -0
  6. package/dist/collection/collection-manifest.json +3 -1
  7. package/dist/collection/components/ui-tree/ui-tree.css +11 -0
  8. package/dist/collection/components/ui-tree/ui-tree.js +252 -0
  9. package/dist/collection/components/ui-tree-item/ui-tree-item.css +213 -0
  10. package/dist/collection/components/ui-tree-item/ui-tree-item.js +347 -0
  11. package/dist/collection/utils/drag-drop.js +51 -0
  12. package/dist/components/index.d.ts +4 -0
  13. package/dist/components/index.js +1 -1
  14. package/dist/components/ui-tree-item.d.ts +11 -0
  15. package/dist/components/ui-tree-item.js +13 -0
  16. package/dist/components/ui-tree.d.ts +11 -0
  17. package/dist/components/ui-tree.js +1 -0
  18. package/dist/esm/loader.js +1 -1
  19. package/dist/esm/looma.js +1 -1
  20. package/dist/esm/ui-tree-item.entry.js +692 -0
  21. package/dist/esm/ui-tree.entry.js +255 -0
  22. package/dist/index.cjs +687 -15
  23. package/dist/index.d.cts +17 -1
  24. package/dist/index.d.ts +17 -1
  25. package/dist/index.js +44 -3
  26. package/dist/looma/looma.esm.js +1 -1
  27. package/dist/looma/p-95368dee.entry.js +1 -0
  28. package/dist/looma/p-ef9ca2ed.entry.js +13 -0
  29. package/dist/types/components/ui-tree/ui-tree.d.ts +28 -0
  30. package/dist/types/components/ui-tree-item/ui-tree-item.d.ts +36 -0
  31. package/dist/types/components.d.ts +176 -0
  32. package/dist/types/utils/drag-drop.d.ts +15 -0
  33. package/dist/{ui-affordance-scope.entry-SWTDTGGU.js → ui-affordance-scope.entry-PFP2TDKO.js} +1 -1
  34. package/dist/{ui-avatar-group.entry-VUYE2XOM.js → ui-avatar-group.entry-DQDP325O.js} +1 -1
  35. package/dist/{ui-avatar.entry-2CKHEJTS.js → ui-avatar.entry-WYIDMOFE.js} +1 -1
  36. package/dist/{ui-badge.entry-4SWSD3R5.js → ui-badge.entry-VGHXPEDT.js} +1 -1
  37. package/dist/{ui-button.entry-SS3AS32R.js → ui-button.entry-LKPLOJ22.js} +1 -1
  38. package/dist/{ui-checkbox.entry-V7OYTOLW.js → ui-checkbox.entry-J74HEA22.js} +1 -1
  39. package/dist/{ui-context-menu.entry-UCLTQESP.js → ui-context-menu.entry-MQM2FCLI.js} +1 -1
  40. package/dist/{ui-dialog.entry-PXIVZF7D.js → ui-dialog.entry-DQMMDO4Z.js} +1 -1
  41. package/dist/{ui-disclosure.entry-ZADBPM2D.js → ui-disclosure.entry-ONF7UZDC.js} +1 -1
  42. package/dist/{ui-floating-action-button.entry-WNBWY36T.js → ui-floating-action-button.entry-FKTGVC5T.js} +1 -1
  43. package/dist/{ui-form-field.entry-RZPSWN6Y.js → ui-form-field.entry-M3ISWQNU.js} +1 -1
  44. package/dist/{ui-icon-button.entry-ILU7RD7M.js → ui-icon-button.entry-AWFIQUHM.js} +1 -1
  45. package/dist/{ui-input.entry-FEIUK4EE.js → ui-input.entry-JZ6RETMT.js} +1 -1
  46. package/dist/{ui-menu-item.entry-UJVECPSK.js → ui-menu-item.entry-5MFR5LFL.js} +1 -1
  47. package/dist/{ui-menu.entry-MTCE3F5U.js → ui-menu.entry-IOEIDATQ.js} +1 -1
  48. package/dist/{ui-popover.entry-OAME35VB.js → ui-popover.entry-ELCMKO6Y.js} +1 -1
  49. package/dist/{ui-radio-group.entry-CPFX4LVA.js → ui-radio-group.entry-RJHUPPEM.js} +1 -1
  50. package/dist/{ui-radio.entry-44OTRYPB.js → ui-radio.entry-3VRDPOY4.js} +1 -1
  51. package/dist/{ui-search-result-row.entry-ZU5SL5OP.js → ui-search-result-row.entry-J34YPAV7.js} +1 -1
  52. package/dist/{ui-search-shell.entry-G7HG4RKU.js → ui-search-shell.entry-IJ4UUP27.js} +1 -1
  53. package/dist/{ui-select.entry-NAONXMFG.js → ui-select.entry-C6YD3HQ5.js} +1 -1
  54. package/dist/{ui-switch.entry-SE4ZTCS2.js → ui-switch.entry-UZDF5QTI.js} +1 -1
  55. package/dist/{ui-tabs.entry-2YG2JE3K.js → ui-tabs.entry-YRAKWOMR.js} +1 -1
  56. package/dist/{ui-textarea.entry-PV3APDLY.js → ui-textarea.entry-JLDKFT3K.js} +1 -1
  57. package/dist/{ui-toast-region.entry-WH2OL3FR.js → ui-toast-region.entry-GC7C7KXF.js} +1 -1
  58. package/dist/{ui-tooltip.entry-FY563DP4.js → ui-tooltip.entry-F26XDTYX.js} +1 -1
  59. package/dist/{ui-top-bar.entry-LJSZXFAH.js → ui-top-bar.entry-5W5UA5KV.js} +1 -1
  60. package/dist/ui-tree-item.entry-3LM7IXIK.js +385 -0
  61. package/dist/ui-tree.entry-X4FU42A6.js +244 -0
  62. package/editor.css +42 -0
  63. package/package.json +1 -1
  64. package/styles.css +18 -6
  65. package/vue/{chunk-YN4IUYVY.js → chunk-IITL6UBR.js} +7 -1
  66. package/vue/editor/index.d.ts +41 -3
  67. package/vue/editor/index.js +273 -4
  68. package/vue/index.d.ts +24 -1
  69. package/vue/index.js +5 -1
@@ -0,0 +1,257 @@
1
+ 'use strict';
2
+
3
+ var index = require('./index-D07f6BOw.js');
4
+ var events = require('./events-TcQIzpNv.js');
5
+
6
+ /**
7
+ * Classify the pointer against stable edge bands. Containers reserve their
8
+ * middle half for containment; leaf rows split cleanly at their midpoint.
9
+ */
10
+ function classifyDropPosition(rect, clientY, acceptsChildren) {
11
+ const progress = rect.height > 0
12
+ ? Math.min(1, Math.max(0, (clientY - rect.top) / rect.height))
13
+ : 0.5;
14
+ if (!acceptsChildren)
15
+ return progress < 0.5 ? 'before' : 'after';
16
+ if (progress < 0.25)
17
+ return 'before';
18
+ if (progress > 0.75)
19
+ return 'after';
20
+ return 'inside';
21
+ }
22
+ /** Use the rendered row—not the tiny handle—as the browser drag preview. */
23
+ function setElementDragImage(dataTransfer, element) {
24
+ if (!dataTransfer || typeof dataTransfer.setDragImage !== 'function')
25
+ return;
26
+ const { height } = element.getBoundingClientRect();
27
+ dataTransfer.setDragImage(element, 16, Math.max(0, height / 2));
28
+ }
29
+ /** A keyed, replaceable hover timer suitable for expansion and disclosure intent. */
30
+ function createHoverIntent(delay, onIntent) {
31
+ let timer;
32
+ let pendingKey;
33
+ function cancel() {
34
+ if (timer)
35
+ clearTimeout(timer);
36
+ timer = undefined;
37
+ pendingKey = undefined;
38
+ }
39
+ return {
40
+ schedule(key) {
41
+ if (pendingKey === key && timer)
42
+ return;
43
+ cancel();
44
+ pendingKey = key;
45
+ timer = setTimeout(() => {
46
+ timer = undefined;
47
+ const resolvedKey = pendingKey;
48
+ pendingKey = undefined;
49
+ if (resolvedKey)
50
+ onIntent(resolvedKey);
51
+ }, Math.max(0, delay));
52
+ },
53
+ cancel,
54
+ destroy: cancel,
55
+ };
56
+ }
57
+
58
+ const uiTreeCss = () => `:host{--ui-tree-indent:16px;display:block;min-inline-size:0;padding-inline-start:var(--ui-tree-gutter, 22px)}::slotted(ui-tree-item){--ui-tree-indent:inherit}`;
59
+
60
+ const UITree = class {
61
+ constructor(hostRef) {
62
+ index.registerInstance(this, hostRef);
63
+ }
64
+ get host() { return index.getElement(this); }
65
+ label = 'Tree';
66
+ hoverExpandDelay = 700;
67
+ source = null;
68
+ target = null;
69
+ position = null;
70
+ hoverIntent = null;
71
+ componentDidLoad() {
72
+ this.hoverIntent = createHoverIntent(this.hoverExpandDelay, this.expandTarget);
73
+ this.host.addEventListener('dragstart', this.onDragStart);
74
+ this.host.addEventListener('dragover', this.onDragOver);
75
+ this.host.addEventListener('dragleave', this.onDragLeave);
76
+ this.host.addEventListener('drop', this.onDrop);
77
+ this.host.addEventListener('dragend', this.onDragEnd);
78
+ this.host.addEventListener('keydown', this.onKeyDown);
79
+ }
80
+ disconnectedCallback() {
81
+ this.hoverIntent?.destroy();
82
+ this.host.removeEventListener('dragstart', this.onDragStart);
83
+ this.host.removeEventListener('dragover', this.onDragOver);
84
+ this.host.removeEventListener('dragleave', this.onDragLeave);
85
+ this.host.removeEventListener('drop', this.onDrop);
86
+ this.host.removeEventListener('dragend', this.onDragEnd);
87
+ this.host.removeEventListener('keydown', this.onKeyDown);
88
+ }
89
+ itemFromEvent(event) {
90
+ return event.composedPath().find(node => (node instanceof HTMLElement && node.localName === 'ui-tree-item')) ?? null;
91
+ }
92
+ itemId(item) {
93
+ return item.itemId || item.getAttribute('item-id') || '';
94
+ }
95
+ rowFor(item) {
96
+ return item.shadowRoot?.querySelector('[part="row"]') ?? null;
97
+ }
98
+ acceptsChildren(item) {
99
+ return Boolean(item.container ?? item.hasAttribute('container'))
100
+ && !Boolean(item.disabled ?? item.hasAttribute('disabled'));
101
+ }
102
+ itemMetadata(item) {
103
+ return {
104
+ type: item.getAttribute('data-drag-type') || item.getAttribute('drag-type') || 'item',
105
+ scope: item.getAttribute('data-drop-scope') || item.getAttribute('drop-scope') || '',
106
+ accepts: (item.getAttribute('data-accepts') || item.getAttribute('accepts') || '')
107
+ .split(',')
108
+ .map(value => value.trim())
109
+ .filter(Boolean),
110
+ };
111
+ }
112
+ permitsDrop(source, target, position) {
113
+ // A tree item can never move into (or beside) one of its own descendants.
114
+ // Reject the target before showing any insertion affordance so the preview
115
+ // stays truthful instead of promising a move the consumer must undo.
116
+ if (source.contains(target))
117
+ return false;
118
+ const sourceMeta = this.itemMetadata(source);
119
+ const targetMeta = this.itemMetadata(target);
120
+ if (position === 'inside') {
121
+ return this.acceptsChildren(target)
122
+ && (targetMeta.accepts.length === 0 || targetMeta.accepts.includes(sourceMeta.type));
123
+ }
124
+ return sourceMeta.type === targetMeta.type;
125
+ }
126
+ clearTarget() {
127
+ this.target?.removeAttribute('data-drop-position');
128
+ this.target = null;
129
+ this.position = null;
130
+ this.hoverIntent?.cancel();
131
+ }
132
+ finishDrag() {
133
+ this.source?.removeAttribute('data-dragging');
134
+ this.source = null;
135
+ this.clearTarget();
136
+ }
137
+ expandTarget = (itemId) => {
138
+ const item = Array.from(this.host.querySelectorAll('ui-tree-item'))
139
+ .find(candidate => this.itemId(candidate) === itemId);
140
+ if (!item || item.getAttribute('aria-expanded') !== 'false')
141
+ return;
142
+ item.dispatchEvent(new CustomEvent('ui-tree-auto-expand'));
143
+ };
144
+ onDragStart = (event) => {
145
+ const item = this.itemFromEvent(event);
146
+ if (!item || !Boolean(item.sortable ?? item.hasAttribute('sortable'))
147
+ || Boolean(item.disabled ?? item.hasAttribute('disabled')))
148
+ return;
149
+ const fromHandle = event.composedPath().some(node => (node instanceof HTMLElement && node.getAttribute('part') === 'drag-handle'));
150
+ if (!fromHandle) {
151
+ event.preventDefault();
152
+ return;
153
+ }
154
+ const sourceId = this.itemId(item);
155
+ const row = this.rowFor(item);
156
+ if (!sourceId || !row) {
157
+ event.preventDefault();
158
+ return;
159
+ }
160
+ this.source = item;
161
+ item.setAttribute('data-dragging', 'true');
162
+ if (event.dataTransfer) {
163
+ event.dataTransfer.effectAllowed = 'move';
164
+ event.dataTransfer.setData('text/plain', sourceId);
165
+ }
166
+ setElementDragImage(event.dataTransfer, row);
167
+ };
168
+ onDragOver = (event) => {
169
+ if (!this.source)
170
+ return;
171
+ const target = this.itemFromEvent(event);
172
+ if (!target || target === this.source) {
173
+ this.clearTarget();
174
+ return;
175
+ }
176
+ const row = this.rowFor(target);
177
+ if (!row)
178
+ return;
179
+ const position = classifyDropPosition(row.getBoundingClientRect(), event.clientY, this.acceptsChildren(target));
180
+ if (!this.permitsDrop(this.source, target, position)) {
181
+ if (event.dataTransfer)
182
+ event.dataTransfer.dropEffect = 'none';
183
+ this.clearTarget();
184
+ return;
185
+ }
186
+ event.preventDefault();
187
+ if (event.dataTransfer)
188
+ event.dataTransfer.dropEffect = 'move';
189
+ if (this.target !== target || this.position !== position) {
190
+ this.clearTarget();
191
+ this.target = target;
192
+ this.position = position;
193
+ target.setAttribute('data-drop-position', position);
194
+ }
195
+ if (position === 'inside' && target.getAttribute('aria-expanded') === 'false') {
196
+ this.hoverIntent?.schedule(this.itemId(target));
197
+ }
198
+ else {
199
+ this.hoverIntent?.cancel();
200
+ }
201
+ };
202
+ onDragLeave = (event) => {
203
+ const related = event.relatedTarget;
204
+ if (related instanceof Node && this.host.contains(related))
205
+ return;
206
+ this.clearTarget();
207
+ };
208
+ onDrop = (event) => {
209
+ if (!this.source || !this.target || !this.position)
210
+ return;
211
+ event.preventDefault();
212
+ const sourceId = this.itemId(this.source);
213
+ const targetId = this.itemId(this.target);
214
+ if (sourceId && targetId) {
215
+ const sourceMeta = this.itemMetadata(this.source);
216
+ const targetMeta = this.itemMetadata(this.target);
217
+ events.dispatchDetail(this.host, 'reorder', {
218
+ sourceId,
219
+ targetId,
220
+ position: this.position,
221
+ sourceType: sourceMeta.type,
222
+ targetType: targetMeta.type,
223
+ sourceScope: sourceMeta.scope,
224
+ targetScope: targetMeta.scope,
225
+ trigger: 'pointer',
226
+ });
227
+ }
228
+ this.finishDrag();
229
+ };
230
+ onDragEnd = () => {
231
+ this.finishDrag();
232
+ };
233
+ visibleItems() {
234
+ return Array.from(this.host.querySelectorAll('ui-tree-item'))
235
+ .filter(item => item.getClientRects().length > 0 && !item.hasAttribute('disabled'));
236
+ }
237
+ onKeyDown = (event) => {
238
+ const current = this.itemFromEvent(event);
239
+ if (!current)
240
+ return;
241
+ const items = this.visibleItems();
242
+ const index = items.indexOf(current);
243
+ if (index < 0)
244
+ return;
245
+ const next = event.key === 'ArrowDown' ? items[index + 1] : event.key === 'ArrowUp' ? items[index - 1] : null;
246
+ if (!next)
247
+ return;
248
+ event.preventDefault();
249
+ next.focus();
250
+ };
251
+ render() {
252
+ return (index.h(index.Host, { key: '5761d2840d2694340a4b937d46522f15f81973ac', role: "tree", "aria-label": this.label || 'Tree' }, index.h("slot", { key: '08e5a7b489eed4f4eae9de6462104fd12defd336' })));
253
+ }
254
+ };
255
+ UITree.style = uiTreeCss();
256
+
257
+ exports.ui_tree = UITree;
@@ -26,7 +26,9 @@
26
26
  "components/ui-textarea/ui-textarea.js",
27
27
  "components/ui-toast-region/ui-toast-region.js",
28
28
  "components/ui-tooltip/ui-tooltip.js",
29
- "components/ui-top-bar/ui-top-bar.js"
29
+ "components/ui-top-bar/ui-top-bar.js",
30
+ "components/ui-tree/ui-tree.js",
31
+ "components/ui-tree-item/ui-tree-item.js"
30
32
  ],
31
33
  "mixins": [],
32
34
  "compiler": {
@@ -0,0 +1,11 @@
1
+ :host {
2
+ --ui-tree-indent: 16px;
3
+
4
+ display: block;
5
+ min-inline-size: 0;
6
+ padding-inline-start: var(--ui-tree-gutter, 22px);
7
+ }
8
+
9
+ ::slotted(ui-tree-item) {
10
+ --ui-tree-indent: inherit;
11
+ }
@@ -0,0 +1,252 @@
1
+ import { Host, h } from "@stencil/core";
2
+ import { dispatchDetail } from "../../utils/events";
3
+ import { classifyDropPosition, createHoverIntent, setElementDragImage, } from "../../utils/drag-drop";
4
+ export class UITree {
5
+ host;
6
+ label = 'Tree';
7
+ hoverExpandDelay = 700;
8
+ source = null;
9
+ target = null;
10
+ position = null;
11
+ hoverIntent = null;
12
+ componentDidLoad() {
13
+ this.hoverIntent = createHoverIntent(this.hoverExpandDelay, this.expandTarget);
14
+ this.host.addEventListener('dragstart', this.onDragStart);
15
+ this.host.addEventListener('dragover', this.onDragOver);
16
+ this.host.addEventListener('dragleave', this.onDragLeave);
17
+ this.host.addEventListener('drop', this.onDrop);
18
+ this.host.addEventListener('dragend', this.onDragEnd);
19
+ this.host.addEventListener('keydown', this.onKeyDown);
20
+ }
21
+ disconnectedCallback() {
22
+ this.hoverIntent?.destroy();
23
+ this.host.removeEventListener('dragstart', this.onDragStart);
24
+ this.host.removeEventListener('dragover', this.onDragOver);
25
+ this.host.removeEventListener('dragleave', this.onDragLeave);
26
+ this.host.removeEventListener('drop', this.onDrop);
27
+ this.host.removeEventListener('dragend', this.onDragEnd);
28
+ this.host.removeEventListener('keydown', this.onKeyDown);
29
+ }
30
+ itemFromEvent(event) {
31
+ return event.composedPath().find(node => (node instanceof HTMLElement && node.localName === 'ui-tree-item')) ?? null;
32
+ }
33
+ itemId(item) {
34
+ return item.itemId || item.getAttribute('item-id') || '';
35
+ }
36
+ rowFor(item) {
37
+ return item.shadowRoot?.querySelector('[part="row"]') ?? null;
38
+ }
39
+ acceptsChildren(item) {
40
+ return Boolean(item.container ?? item.hasAttribute('container'))
41
+ && !Boolean(item.disabled ?? item.hasAttribute('disabled'));
42
+ }
43
+ itemMetadata(item) {
44
+ return {
45
+ type: item.getAttribute('data-drag-type') || item.getAttribute('drag-type') || 'item',
46
+ scope: item.getAttribute('data-drop-scope') || item.getAttribute('drop-scope') || '',
47
+ accepts: (item.getAttribute('data-accepts') || item.getAttribute('accepts') || '')
48
+ .split(',')
49
+ .map(value => value.trim())
50
+ .filter(Boolean),
51
+ };
52
+ }
53
+ permitsDrop(source, target, position) {
54
+ // A tree item can never move into (or beside) one of its own descendants.
55
+ // Reject the target before showing any insertion affordance so the preview
56
+ // stays truthful instead of promising a move the consumer must undo.
57
+ if (source.contains(target))
58
+ return false;
59
+ const sourceMeta = this.itemMetadata(source);
60
+ const targetMeta = this.itemMetadata(target);
61
+ if (position === 'inside') {
62
+ return this.acceptsChildren(target)
63
+ && (targetMeta.accepts.length === 0 || targetMeta.accepts.includes(sourceMeta.type));
64
+ }
65
+ return sourceMeta.type === targetMeta.type;
66
+ }
67
+ clearTarget() {
68
+ this.target?.removeAttribute('data-drop-position');
69
+ this.target = null;
70
+ this.position = null;
71
+ this.hoverIntent?.cancel();
72
+ }
73
+ finishDrag() {
74
+ this.source?.removeAttribute('data-dragging');
75
+ this.source = null;
76
+ this.clearTarget();
77
+ }
78
+ expandTarget = (itemId) => {
79
+ const item = Array.from(this.host.querySelectorAll('ui-tree-item'))
80
+ .find(candidate => this.itemId(candidate) === itemId);
81
+ if (!item || item.getAttribute('aria-expanded') !== 'false')
82
+ return;
83
+ item.dispatchEvent(new CustomEvent('ui-tree-auto-expand'));
84
+ };
85
+ onDragStart = (event) => {
86
+ const item = this.itemFromEvent(event);
87
+ if (!item || !Boolean(item.sortable ?? item.hasAttribute('sortable'))
88
+ || Boolean(item.disabled ?? item.hasAttribute('disabled')))
89
+ return;
90
+ const fromHandle = event.composedPath().some(node => (node instanceof HTMLElement && node.getAttribute('part') === 'drag-handle'));
91
+ if (!fromHandle) {
92
+ event.preventDefault();
93
+ return;
94
+ }
95
+ const sourceId = this.itemId(item);
96
+ const row = this.rowFor(item);
97
+ if (!sourceId || !row) {
98
+ event.preventDefault();
99
+ return;
100
+ }
101
+ this.source = item;
102
+ item.setAttribute('data-dragging', 'true');
103
+ if (event.dataTransfer) {
104
+ event.dataTransfer.effectAllowed = 'move';
105
+ event.dataTransfer.setData('text/plain', sourceId);
106
+ }
107
+ setElementDragImage(event.dataTransfer, row);
108
+ };
109
+ onDragOver = (event) => {
110
+ if (!this.source)
111
+ return;
112
+ const target = this.itemFromEvent(event);
113
+ if (!target || target === this.source) {
114
+ this.clearTarget();
115
+ return;
116
+ }
117
+ const row = this.rowFor(target);
118
+ if (!row)
119
+ return;
120
+ const position = classifyDropPosition(row.getBoundingClientRect(), event.clientY, this.acceptsChildren(target));
121
+ if (!this.permitsDrop(this.source, target, position)) {
122
+ if (event.dataTransfer)
123
+ event.dataTransfer.dropEffect = 'none';
124
+ this.clearTarget();
125
+ return;
126
+ }
127
+ event.preventDefault();
128
+ if (event.dataTransfer)
129
+ event.dataTransfer.dropEffect = 'move';
130
+ if (this.target !== target || this.position !== position) {
131
+ this.clearTarget();
132
+ this.target = target;
133
+ this.position = position;
134
+ target.setAttribute('data-drop-position', position);
135
+ }
136
+ if (position === 'inside' && target.getAttribute('aria-expanded') === 'false') {
137
+ this.hoverIntent?.schedule(this.itemId(target));
138
+ }
139
+ else {
140
+ this.hoverIntent?.cancel();
141
+ }
142
+ };
143
+ onDragLeave = (event) => {
144
+ const related = event.relatedTarget;
145
+ if (related instanceof Node && this.host.contains(related))
146
+ return;
147
+ this.clearTarget();
148
+ };
149
+ onDrop = (event) => {
150
+ if (!this.source || !this.target || !this.position)
151
+ return;
152
+ event.preventDefault();
153
+ const sourceId = this.itemId(this.source);
154
+ const targetId = this.itemId(this.target);
155
+ if (sourceId && targetId) {
156
+ const sourceMeta = this.itemMetadata(this.source);
157
+ const targetMeta = this.itemMetadata(this.target);
158
+ dispatchDetail(this.host, 'reorder', {
159
+ sourceId,
160
+ targetId,
161
+ position: this.position,
162
+ sourceType: sourceMeta.type,
163
+ targetType: targetMeta.type,
164
+ sourceScope: sourceMeta.scope,
165
+ targetScope: targetMeta.scope,
166
+ trigger: 'pointer',
167
+ });
168
+ }
169
+ this.finishDrag();
170
+ };
171
+ onDragEnd = () => {
172
+ this.finishDrag();
173
+ };
174
+ visibleItems() {
175
+ return Array.from(this.host.querySelectorAll('ui-tree-item'))
176
+ .filter(item => item.getClientRects().length > 0 && !item.hasAttribute('disabled'));
177
+ }
178
+ onKeyDown = (event) => {
179
+ const current = this.itemFromEvent(event);
180
+ if (!current)
181
+ return;
182
+ const items = this.visibleItems();
183
+ const index = items.indexOf(current);
184
+ if (index < 0)
185
+ return;
186
+ const next = event.key === 'ArrowDown' ? items[index + 1] : event.key === 'ArrowUp' ? items[index - 1] : null;
187
+ if (!next)
188
+ return;
189
+ event.preventDefault();
190
+ next.focus();
191
+ };
192
+ render() {
193
+ return (h(Host, { key: '5761d2840d2694340a4b937d46522f15f81973ac', role: "tree", "aria-label": this.label || 'Tree' }, h("slot", { key: '08e5a7b489eed4f4eae9de6462104fd12defd336' })));
194
+ }
195
+ static get is() { return "ui-tree"; }
196
+ static get encapsulation() { return "shadow"; }
197
+ static get originalStyleUrls() {
198
+ return {
199
+ "$": ["ui-tree.css"]
200
+ };
201
+ }
202
+ static get styleUrls() {
203
+ return {
204
+ "$": ["ui-tree.css"]
205
+ };
206
+ }
207
+ static get properties() {
208
+ return {
209
+ "label": {
210
+ "type": "string",
211
+ "mutable": false,
212
+ "complexType": {
213
+ "original": "string",
214
+ "resolved": "string",
215
+ "references": {}
216
+ },
217
+ "required": false,
218
+ "optional": false,
219
+ "docs": {
220
+ "tags": [],
221
+ "text": ""
222
+ },
223
+ "getter": false,
224
+ "setter": false,
225
+ "reflect": false,
226
+ "attribute": "label",
227
+ "defaultValue": "'Tree'"
228
+ },
229
+ "hoverExpandDelay": {
230
+ "type": "number",
231
+ "mutable": false,
232
+ "complexType": {
233
+ "original": "number",
234
+ "resolved": "number",
235
+ "references": {}
236
+ },
237
+ "required": false,
238
+ "optional": false,
239
+ "docs": {
240
+ "tags": [],
241
+ "text": ""
242
+ },
243
+ "getter": false,
244
+ "setter": false,
245
+ "reflect": false,
246
+ "attribute": "hover-expand-delay",
247
+ "defaultValue": "700"
248
+ }
249
+ };
250
+ }
251
+ static get elementRef() { return "host"; }
252
+ }