|
3 | 3 | */ |
4 | 4 |
|
5 | 5 | class TreeView { |
| 6 | + /** Max children to render at once before showing a "Load more" button */ |
| 7 | + static CHUNK_SIZE = 100; |
| 8 | + |
6 | 9 | constructor(container) { |
7 | 10 | this.container = container; |
8 | 11 | this.data = null; |
@@ -202,16 +205,36 @@ class TreeView { |
202 | 205 | } |
203 | 206 |
|
204 | 207 | populateChildren(container, value, parentPathArray) { |
205 | | - if (Array.isArray(value)) { |
206 | | - value.forEach((item, index) => { |
207 | | - const childNode = this.createNode(item, index.toString(), parentPathArray); |
208 | | - container.appendChild(childNode); |
209 | | - }); |
210 | | - } else { |
211 | | - Object.entries(value).forEach(([key, val]) => { |
212 | | - const childNode = this.createNode(val, key, parentPathArray); |
213 | | - container.appendChild(childNode); |
| 208 | + const entries = Array.isArray(value) |
| 209 | + ? value.map((item, index) => ({ key: index.toString(), val: item })) |
| 210 | + : Object.entries(value).map(([key, val]) => ({ key, val })); |
| 211 | + |
| 212 | + this._renderChunk(container, entries, 0, parentPathArray); |
| 213 | + } |
| 214 | + |
| 215 | + /** |
| 216 | + * Render a slice of entries into `container`, appending a "Load more" button |
| 217 | + * if there are remaining items beyond this chunk. |
| 218 | + */ |
| 219 | + _renderChunk(container, entries, startIndex, parentPathArray) { |
| 220 | + const end = Math.min(startIndex + TreeView.CHUNK_SIZE, entries.length); |
| 221 | + |
| 222 | + for (let i = startIndex; i < end; i++) { |
| 223 | + const { key, val } = entries[i]; |
| 224 | + container.appendChild(this.createNode(val, key, parentPathArray)); |
| 225 | + } |
| 226 | + |
| 227 | + if (end < entries.length) { |
| 228 | + const remaining = entries.length - end; |
| 229 | + const loadMoreBtn = document.createElement('button'); |
| 230 | + loadMoreBtn.className = 'tree-load-more'; |
| 231 | + loadMoreBtn.textContent = `Load ${Math.min(remaining, TreeView.CHUNK_SIZE)} more… (${remaining} remaining)`; |
| 232 | + loadMoreBtn.addEventListener('click', (e) => { |
| 233 | + e.stopPropagation(); |
| 234 | + loadMoreBtn.remove(); |
| 235 | + this._renderChunk(container, entries, end, parentPathArray); |
214 | 236 | }); |
| 237 | + container.appendChild(loadMoreBtn); |
215 | 238 | } |
216 | 239 | } |
217 | 240 |
|
|
0 commit comments