|
11 | 11 | type ExternalDropTargetGetFeedbackArgs,
|
12 | 12 | } from "@atlaskit/pragmatic-drag-and-drop/external/adapter";
|
13 | 13 | import { DEV } from "esm-env";
|
14 |
| - import { getContext, hasContext, setContext, tick } from "svelte"; |
| 14 | + import { getContext, hasContext, setContext } from "svelte"; |
15 | 15 | import { SvelteSet } from "svelte/reactivity";
|
16 | 16 | import { falsePredicate, isControlOrMeta, noop, truePredicate } from "$lib/internal/helpers.js";
|
17 | 17 | import {
|
|
196 | 196 | return document.getElementById(elementId);
|
197 | 197 | }
|
198 | 198 |
|
199 |
| - function getFirstVisibleItem(item: TreeItemState<TFile, TFolder>) { |
200 |
| - let current: TreeItemState<TFile, TFolder> | undefined = item; |
201 |
| - while (!current.visible) { |
202 |
| - if (current.node.type === "folder") { |
203 |
| - current = items[current.order + current.node.count + 1]; |
204 |
| - } else { |
205 |
| - current = items[current.order + 1]; |
206 |
| - } |
207 |
| -
|
208 |
| - if (current === undefined) { |
209 |
| - return; |
210 |
| - } |
211 |
| - } |
212 |
| - return current; |
213 |
| - } |
214 |
| -
|
215 | 199 | function getNextVisibleItem(
|
216 | 200 | item: TreeItemState<TFile, TFolder>,
|
217 | 201 | options: { skipChildren?: boolean } = {},
|
218 | 202 | ) {
|
219 | 203 | const { skipChildren = false } = options;
|
220 | 204 |
|
221 |
| - let current: TreeItemState<TFile, TFolder> | undefined = item; |
222 |
| - if (current.node.type === "folder" && (skipChildren || !current.expanded)) { |
223 |
| - current = items[current.order + current.node.count + 1]; |
| 205 | + let current: TreeItemState<TFile, TFolder> | undefined; |
| 206 | + if (item.node.type === "folder" && (skipChildren || !item.expanded)) { |
| 207 | + current = items[item.order + item.node.count + 1]; |
224 | 208 | } else {
|
225 |
| - current = items[current.order + 1]; |
| 209 | + current = items[item.order + 1]; |
226 | 210 | }
|
227 | 211 |
|
228 |
| - if (current === undefined) { |
229 |
| - return; |
| 212 | + while (current !== undefined && !current.visible) { |
| 213 | + if (current.node.type === "folder") { |
| 214 | + current = items[current.order + current.node.count + 1]; |
| 215 | + } else { |
| 216 | + current = items[current.order + 1]; |
| 217 | + } |
230 | 218 | }
|
231 | 219 |
|
232 |
| - return getFirstVisibleItem(current); |
| 220 | + return current; |
233 | 221 | }
|
234 | 222 |
|
235 | 223 | function getPreviousVisibleItem(item: TreeItemState<TFile, TFolder>) {
|
236 |
| - let current: TreeItemState<TFile, TFolder> | undefined = item; |
237 |
| - do { |
| 224 | + let current = items[item.order - 1]; |
| 225 | + while (current !== undefined && !current.visible) { |
238 | 226 | current = items[current.order - 1];
|
239 |
| - } while (current !== undefined && !current.visible); |
| 227 | + } |
| 228 | + return current; |
| 229 | + } |
| 230 | +
|
| 231 | + function getFirstVisibleItem() { |
| 232 | + let current = items[0]; |
| 233 | + if (current !== undefined && !current.visible) { |
| 234 | + current = getNextVisibleItem(current); |
| 235 | + } |
| 236 | + return current; |
| 237 | + } |
| 238 | +
|
| 239 | + function getLastVisibleItem() { |
| 240 | + let current = items[items.length - 1]; |
| 241 | + if (current !== undefined && !current.visible) { |
| 242 | + while (current.parent !== undefined && !current.parent.visible) { |
| 243 | + current = current.parent; |
| 244 | + } |
| 245 | + current = getPreviousVisibleItem(current); |
| 246 | + } |
240 | 247 | return current;
|
241 | 248 | }
|
242 | 249 |
|
|
281 | 288 | }
|
282 | 289 | }
|
283 | 290 |
|
284 |
| - if (lastSelected === undefined) { |
285 |
| - let current: TreeItemState<TFile, TFolder> | undefined = items[0]!; |
| 291 | + if (lastSelected === undefined || !lastSelected.visible) { |
| 292 | + let current: TreeItemState<TFile, TFolder> | undefined = getFirstVisibleItem()!; |
286 | 293 | do {
|
287 | 294 | selectedIds.add(current.node.id);
|
288 | 295 | if (current.node === item.node) {
|
|
293 | 300 | return;
|
294 | 301 | }
|
295 | 302 |
|
296 |
| - const following = lastSelected.order < item.order; |
297 |
| - const navigate = following ? getNextVisibleItem : getPreviousVisibleItem; |
298 |
| -
|
| 303 | + const down = lastSelected.order < item.order; |
299 | 304 | let current: TreeItemState<TFile, TFolder> | undefined = lastSelected;
|
300 | 305 | while (current.node !== item.node) {
|
301 |
| - current = navigate(current); |
| 306 | + current = down ? getNextVisibleItem(current) : getPreviousVisibleItem(current); |
302 | 307 | if (current === undefined) {
|
303 | 308 | break;
|
304 | 309 | }
|
|
742 | 747 | case "PageDown":
|
743 | 748 | case "PageUp": {
|
744 | 749 | const down = event.key === "PageDown";
|
745 |
| - const navigate = down ? getNextVisibleItem : getPreviousVisibleItem; |
746 | 750 | const shouldSelectMultiple = event.shiftKey && isControlOrMeta(event);
|
747 | 751 |
|
748 | 752 | const maxScrollDistance = Math.min(
|
|
754 | 758 | let current = item;
|
755 | 759 | let currentElement: HTMLElement = event.currentTarget;
|
756 | 760 | while (true) {
|
757 |
| - const next = navigate(current); |
| 761 | + const next = down ? getNextVisibleItem(current) : getPreviousVisibleItem(current); |
758 | 762 | if (next === undefined) {
|
759 | 763 | break;
|
760 | 764 | }
|
|
790 | 794 | currentElement.focus();
|
791 | 795 | break;
|
792 | 796 | }
|
793 |
| - case "Home": { |
794 |
| - const first = getFirstVisibleItem(items[0]!)!; |
795 |
| - if (first === item) { |
796 |
| - break; |
797 |
| - } |
798 |
| -
|
799 |
| - if (event.shiftKey && isControlOrMeta(event)) { |
800 |
| - let current: TreeItemState<TFile, TFolder> | undefined = item; |
801 |
| - do { |
802 |
| - selectedIds.add(current.node.id); |
803 |
| - current = getPreviousVisibleItem(current); |
804 |
| - } while (current !== undefined); |
805 |
| - } else { |
806 |
| - selectedIds.clear(); |
807 |
| - selectedIds.add(first.node.id); |
808 |
| - } |
809 |
| -
|
810 |
| - focusItem(first); |
811 |
| - break; |
812 |
| - } |
| 797 | + case "Home": |
813 | 798 | case "End": {
|
814 |
| - const last = getPreviousVisibleItem(items[items.length - 1]!)!; |
815 |
| - if (last === item) { |
| 799 | + const down = event.key === "End"; |
| 800 | + const last = down ? getLastVisibleItem()! : getFirstVisibleItem()!; |
| 801 | + if (item === last) { |
816 | 802 | break;
|
817 | 803 | }
|
818 | 804 |
|
819 | 805 | if (event.shiftKey && isControlOrMeta(event)) {
|
820 | 806 | let current: TreeItemState<TFile, TFolder> | undefined = item;
|
821 | 807 | do {
|
822 | 808 | selectedIds.add(current.node.id);
|
823 |
| - current = getNextVisibleItem(current); |
| 809 | + current = down ? getNextVisibleItem(current) : getPreviousVisibleItem(current); |
824 | 810 | } while (current !== undefined);
|
825 | 811 | } else {
|
826 | 812 | selectedIds.clear();
|
|
862 | 848 | break;
|
863 | 849 | }
|
864 | 850 |
|
865 |
| - let current: TreeItemState<TFile, TFolder> | undefined = getFirstVisibleItem(items[0]!)!; |
| 851 | + let current: TreeItemState<TFile, TFolder> | undefined = getFirstVisibleItem()!; |
866 | 852 | do {
|
867 | 853 | selectedIds.add(current.node.id);
|
868 | 854 | current = getNextVisibleItem(current);
|
|
0 commit comments