@headless-tree/core 0.0.0-20250725212154 → 0.0.0-20250726130412

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 (171) hide show
  1. package/CHANGELOG.md +4 -1
  2. package/dist/index.d.mts +568 -0
  3. package/dist/index.d.ts +568 -0
  4. package/dist/index.js +2284 -0
  5. package/dist/index.mjs +2239 -0
  6. package/package.json +18 -10
  7. package/tsconfig.json +1 -4
  8. package/lib/cjs/core/build-proxified-instance.d.ts +0 -2
  9. package/lib/cjs/core/build-proxified-instance.js +0 -58
  10. package/lib/cjs/core/build-static-instance.d.ts +0 -2
  11. package/lib/cjs/core/build-static-instance.js +0 -26
  12. package/lib/cjs/core/create-tree.d.ts +0 -2
  13. package/lib/cjs/core/create-tree.js +0 -191
  14. package/lib/cjs/features/async-data-loader/feature.d.ts +0 -2
  15. package/lib/cjs/features/async-data-loader/feature.js +0 -135
  16. package/lib/cjs/features/async-data-loader/types.d.ts +0 -47
  17. package/lib/cjs/features/async-data-loader/types.js +0 -2
  18. package/lib/cjs/features/checkboxes/feature.d.ts +0 -2
  19. package/lib/cjs/features/checkboxes/feature.js +0 -102
  20. package/lib/cjs/features/checkboxes/types.d.ts +0 -27
  21. package/lib/cjs/features/checkboxes/types.js +0 -9
  22. package/lib/cjs/features/drag-and-drop/feature.d.ts +0 -2
  23. package/lib/cjs/features/drag-and-drop/feature.js +0 -215
  24. package/lib/cjs/features/drag-and-drop/types.d.ts +0 -72
  25. package/lib/cjs/features/drag-and-drop/types.js +0 -9
  26. package/lib/cjs/features/drag-and-drop/utils.d.ts +0 -27
  27. package/lib/cjs/features/drag-and-drop/utils.js +0 -182
  28. package/lib/cjs/features/expand-all/feature.d.ts +0 -2
  29. package/lib/cjs/features/expand-all/feature.js +0 -70
  30. package/lib/cjs/features/expand-all/types.d.ts +0 -19
  31. package/lib/cjs/features/expand-all/types.js +0 -2
  32. package/lib/cjs/features/hotkeys-core/feature.d.ts +0 -2
  33. package/lib/cjs/features/hotkeys-core/feature.js +0 -107
  34. package/lib/cjs/features/hotkeys-core/types.d.ts +0 -27
  35. package/lib/cjs/features/hotkeys-core/types.js +0 -2
  36. package/lib/cjs/features/keyboard-drag-and-drop/feature.d.ts +0 -2
  37. package/lib/cjs/features/keyboard-drag-and-drop/feature.js +0 -206
  38. package/lib/cjs/features/keyboard-drag-and-drop/types.d.ts +0 -27
  39. package/lib/cjs/features/keyboard-drag-and-drop/types.js +0 -11
  40. package/lib/cjs/features/main/types.d.ts +0 -47
  41. package/lib/cjs/features/main/types.js +0 -2
  42. package/lib/cjs/features/prop-memoization/feature.d.ts +0 -2
  43. package/lib/cjs/features/prop-memoization/feature.js +0 -70
  44. package/lib/cjs/features/prop-memoization/types.d.ts +0 -15
  45. package/lib/cjs/features/prop-memoization/types.js +0 -2
  46. package/lib/cjs/features/renaming/feature.d.ts +0 -2
  47. package/lib/cjs/features/renaming/feature.js +0 -86
  48. package/lib/cjs/features/renaming/types.d.ts +0 -27
  49. package/lib/cjs/features/renaming/types.js +0 -2
  50. package/lib/cjs/features/search/feature.d.ts +0 -2
  51. package/lib/cjs/features/search/feature.js +0 -119
  52. package/lib/cjs/features/search/types.d.ts +0 -32
  53. package/lib/cjs/features/search/types.js +0 -2
  54. package/lib/cjs/features/selection/feature.d.ts +0 -2
  55. package/lib/cjs/features/selection/feature.js +0 -132
  56. package/lib/cjs/features/selection/types.d.ts +0 -21
  57. package/lib/cjs/features/selection/types.js +0 -2
  58. package/lib/cjs/features/sync-data-loader/feature.d.ts +0 -2
  59. package/lib/cjs/features/sync-data-loader/feature.js +0 -53
  60. package/lib/cjs/features/sync-data-loader/types.d.ts +0 -28
  61. package/lib/cjs/features/sync-data-loader/types.js +0 -2
  62. package/lib/cjs/features/tree/feature.d.ts +0 -2
  63. package/lib/cjs/features/tree/feature.js +0 -245
  64. package/lib/cjs/features/tree/types.d.ts +0 -63
  65. package/lib/cjs/features/tree/types.js +0 -2
  66. package/lib/cjs/index.d.ts +0 -33
  67. package/lib/cjs/index.js +0 -51
  68. package/lib/cjs/mddocs-entry.d.ts +0 -121
  69. package/lib/cjs/mddocs-entry.js +0 -17
  70. package/lib/cjs/test-utils/test-tree-do.d.ts +0 -23
  71. package/lib/cjs/test-utils/test-tree-do.js +0 -114
  72. package/lib/cjs/test-utils/test-tree-expect.d.ts +0 -17
  73. package/lib/cjs/test-utils/test-tree-expect.js +0 -66
  74. package/lib/cjs/test-utils/test-tree.d.ts +0 -48
  75. package/lib/cjs/test-utils/test-tree.js +0 -208
  76. package/lib/cjs/types/core.d.ts +0 -84
  77. package/lib/cjs/types/core.js +0 -2
  78. package/lib/cjs/types/deep-merge.d.ts +0 -13
  79. package/lib/cjs/types/deep-merge.js +0 -2
  80. package/lib/cjs/utilities/create-on-drop-handler.d.ts +0 -3
  81. package/lib/cjs/utilities/create-on-drop-handler.js +0 -20
  82. package/lib/cjs/utilities/errors.d.ts +0 -2
  83. package/lib/cjs/utilities/errors.js +0 -9
  84. package/lib/cjs/utilities/insert-items-at-target.d.ts +0 -3
  85. package/lib/cjs/utilities/insert-items-at-target.js +0 -40
  86. package/lib/cjs/utilities/remove-items-from-parents.d.ts +0 -2
  87. package/lib/cjs/utilities/remove-items-from-parents.js +0 -32
  88. package/lib/cjs/utils.d.ts +0 -6
  89. package/lib/cjs/utils.js +0 -53
  90. package/lib/esm/core/build-proxified-instance.d.ts +0 -2
  91. package/lib/esm/core/build-proxified-instance.js +0 -54
  92. package/lib/esm/core/build-static-instance.d.ts +0 -2
  93. package/lib/esm/core/build-static-instance.js +0 -22
  94. package/lib/esm/core/create-tree.d.ts +0 -2
  95. package/lib/esm/core/create-tree.js +0 -187
  96. package/lib/esm/features/async-data-loader/feature.d.ts +0 -2
  97. package/lib/esm/features/async-data-loader/feature.js +0 -132
  98. package/lib/esm/features/async-data-loader/types.d.ts +0 -47
  99. package/lib/esm/features/async-data-loader/types.js +0 -1
  100. package/lib/esm/features/checkboxes/feature.d.ts +0 -2
  101. package/lib/esm/features/checkboxes/feature.js +0 -99
  102. package/lib/esm/features/checkboxes/types.d.ts +0 -27
  103. package/lib/esm/features/checkboxes/types.js +0 -6
  104. package/lib/esm/features/drag-and-drop/feature.d.ts +0 -2
  105. package/lib/esm/features/drag-and-drop/feature.js +0 -212
  106. package/lib/esm/features/drag-and-drop/types.d.ts +0 -72
  107. package/lib/esm/features/drag-and-drop/types.js +0 -6
  108. package/lib/esm/features/drag-and-drop/utils.d.ts +0 -27
  109. package/lib/esm/features/drag-and-drop/utils.js +0 -172
  110. package/lib/esm/features/expand-all/feature.d.ts +0 -2
  111. package/lib/esm/features/expand-all/feature.js +0 -67
  112. package/lib/esm/features/expand-all/types.d.ts +0 -19
  113. package/lib/esm/features/expand-all/types.js +0 -1
  114. package/lib/esm/features/hotkeys-core/feature.d.ts +0 -2
  115. package/lib/esm/features/hotkeys-core/feature.js +0 -104
  116. package/lib/esm/features/hotkeys-core/types.d.ts +0 -27
  117. package/lib/esm/features/hotkeys-core/types.js +0 -1
  118. package/lib/esm/features/keyboard-drag-and-drop/feature.d.ts +0 -2
  119. package/lib/esm/features/keyboard-drag-and-drop/feature.js +0 -203
  120. package/lib/esm/features/keyboard-drag-and-drop/types.d.ts +0 -27
  121. package/lib/esm/features/keyboard-drag-and-drop/types.js +0 -8
  122. package/lib/esm/features/main/types.d.ts +0 -47
  123. package/lib/esm/features/main/types.js +0 -1
  124. package/lib/esm/features/prop-memoization/feature.d.ts +0 -2
  125. package/lib/esm/features/prop-memoization/feature.js +0 -67
  126. package/lib/esm/features/prop-memoization/types.d.ts +0 -15
  127. package/lib/esm/features/prop-memoization/types.js +0 -1
  128. package/lib/esm/features/renaming/feature.d.ts +0 -2
  129. package/lib/esm/features/renaming/feature.js +0 -83
  130. package/lib/esm/features/renaming/types.d.ts +0 -27
  131. package/lib/esm/features/renaming/types.js +0 -1
  132. package/lib/esm/features/search/feature.d.ts +0 -2
  133. package/lib/esm/features/search/feature.js +0 -116
  134. package/lib/esm/features/search/types.d.ts +0 -32
  135. package/lib/esm/features/search/types.js +0 -1
  136. package/lib/esm/features/selection/feature.d.ts +0 -2
  137. package/lib/esm/features/selection/feature.js +0 -129
  138. package/lib/esm/features/selection/types.d.ts +0 -21
  139. package/lib/esm/features/selection/types.js +0 -1
  140. package/lib/esm/features/sync-data-loader/feature.d.ts +0 -2
  141. package/lib/esm/features/sync-data-loader/feature.js +0 -50
  142. package/lib/esm/features/sync-data-loader/types.d.ts +0 -28
  143. package/lib/esm/features/sync-data-loader/types.js +0 -1
  144. package/lib/esm/features/tree/feature.d.ts +0 -2
  145. package/lib/esm/features/tree/feature.js +0 -242
  146. package/lib/esm/features/tree/types.d.ts +0 -63
  147. package/lib/esm/features/tree/types.js +0 -1
  148. package/lib/esm/index.d.ts +0 -33
  149. package/lib/esm/index.js +0 -32
  150. package/lib/esm/mddocs-entry.d.ts +0 -121
  151. package/lib/esm/mddocs-entry.js +0 -1
  152. package/lib/esm/test-utils/test-tree-do.d.ts +0 -23
  153. package/lib/esm/test-utils/test-tree-do.js +0 -110
  154. package/lib/esm/test-utils/test-tree-expect.d.ts +0 -17
  155. package/lib/esm/test-utils/test-tree-expect.js +0 -62
  156. package/lib/esm/test-utils/test-tree.d.ts +0 -48
  157. package/lib/esm/test-utils/test-tree.js +0 -204
  158. package/lib/esm/types/core.d.ts +0 -84
  159. package/lib/esm/types/core.js +0 -1
  160. package/lib/esm/types/deep-merge.d.ts +0 -13
  161. package/lib/esm/types/deep-merge.js +0 -1
  162. package/lib/esm/utilities/create-on-drop-handler.d.ts +0 -3
  163. package/lib/esm/utilities/create-on-drop-handler.js +0 -16
  164. package/lib/esm/utilities/errors.d.ts +0 -2
  165. package/lib/esm/utilities/errors.js +0 -4
  166. package/lib/esm/utilities/insert-items-at-target.d.ts +0 -3
  167. package/lib/esm/utilities/insert-items-at-target.js +0 -36
  168. package/lib/esm/utilities/remove-items-from-parents.d.ts +0 -2
  169. package/lib/esm/utilities/remove-items-from-parents.js +0 -28
  170. package/lib/esm/utils.d.ts +0 -6
  171. package/lib/esm/utils.js +0 -46
@@ -1,119 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.searchFeature = void 0;
4
- const utils_1 = require("../../utils");
5
- exports.searchFeature = {
6
- key: "search",
7
- getInitialState: (initialState) => (Object.assign({ search: null }, initialState)),
8
- getDefaultConfig: (defaultConfig, tree) => (Object.assign({ setSearch: (0, utils_1.makeStateUpdater)("search", tree), isSearchMatchingItem: (search, item) => search.length > 0 &&
9
- item.getItemName().toLowerCase().includes(search.toLowerCase()) }, defaultConfig)),
10
- stateHandlerNames: {
11
- search: "setSearch",
12
- },
13
- treeInstance: {
14
- setSearch: ({ tree }, search) => {
15
- var _a;
16
- tree.applySubStateUpdate("search", search);
17
- (_a = tree
18
- .getItems()
19
- .find((item) => { var _a, _b; return (_b = (_a = tree.getConfig()).isSearchMatchingItem) === null || _b === void 0 ? void 0 : _b.call(_a, tree.getSearchValue(), item); })) === null || _a === void 0 ? void 0 : _a.setFocused();
20
- },
21
- openSearch: ({ tree }, initialValue = "") => {
22
- var _a, _b;
23
- tree.setSearch(initialValue);
24
- (_b = (_a = tree.getConfig()).onOpenSearch) === null || _b === void 0 ? void 0 : _b.call(_a);
25
- setTimeout(() => {
26
- var _a;
27
- (_a = tree.getDataRef().current.searchInput) === null || _a === void 0 ? void 0 : _a.focus();
28
- });
29
- },
30
- closeSearch: ({ tree }) => {
31
- var _a, _b;
32
- tree.setSearch(null);
33
- (_b = (_a = tree.getConfig()).onCloseSearch) === null || _b === void 0 ? void 0 : _b.call(_a);
34
- tree.updateDomFocus();
35
- },
36
- isSearchOpen: ({ tree }) => tree.getState().search !== null,
37
- getSearchValue: ({ tree }) => tree.getState().search || "",
38
- registerSearchInputElement: ({ tree }, element) => {
39
- const dataRef = tree.getDataRef();
40
- dataRef.current.searchInput = element;
41
- if (element && dataRef.current.keydownHandler) {
42
- element.addEventListener("keydown", dataRef.current.keydownHandler);
43
- }
44
- },
45
- getSearchInputElement: ({ tree }) => { var _a; return (_a = tree.getDataRef().current.searchInput) !== null && _a !== void 0 ? _a : null; },
46
- // TODO memoize with propMemoizationFeature
47
- getSearchInputElementProps: ({ tree }) => ({
48
- value: tree.getSearchValue(),
49
- onChange: (e) => tree.setSearch(e.target.value),
50
- onBlur: () => tree.closeSearch(),
51
- ref: tree.registerSearchInputElement,
52
- }),
53
- getSearchMatchingItems: (0, utils_1.memo)(({ tree }) => [
54
- tree.getSearchValue(),
55
- tree.getItems(),
56
- tree.getConfig().isSearchMatchingItem,
57
- ], (search, items, isSearchMatchingItem) => items.filter((item) => search && (isSearchMatchingItem === null || isSearchMatchingItem === void 0 ? void 0 : isSearchMatchingItem(search, item)))),
58
- },
59
- itemInstance: {
60
- isMatchingSearch: ({ tree, item }) => tree.getSearchMatchingItems().some((i) => i.getId() === item.getId()),
61
- },
62
- hotkeys: {
63
- openSearch: {
64
- hotkey: "LetterOrNumber",
65
- preventDefault: true, // TODO make true default
66
- isEnabled: (tree) => !tree.isSearchOpen(),
67
- handler: (e, tree) => {
68
- e.stopPropagation();
69
- tree.openSearch(e.key);
70
- },
71
- },
72
- closeSearch: {
73
- // TODO allow multiple, i.e. Enter
74
- hotkey: "Escape",
75
- allowWhenInputFocused: true,
76
- isEnabled: (tree) => tree.isSearchOpen(),
77
- handler: (e, tree) => {
78
- tree.closeSearch();
79
- },
80
- },
81
- submitSearch: {
82
- hotkey: "Enter",
83
- allowWhenInputFocused: true,
84
- isEnabled: (tree) => tree.isSearchOpen(),
85
- handler: (e, tree) => {
86
- tree.closeSearch();
87
- tree.setSelectedItems([tree.getFocusedItem().getId()]);
88
- },
89
- },
90
- nextSearchItem: {
91
- hotkey: "ArrowDown",
92
- allowWhenInputFocused: true,
93
- canRepeat: true,
94
- isEnabled: (tree) => tree.isSearchOpen(),
95
- handler: (e, tree) => {
96
- const focusItem = tree
97
- .getSearchMatchingItems()
98
- .find((item) => item.getItemMeta().index >
99
- tree.getFocusedItem().getItemMeta().index);
100
- focusItem === null || focusItem === void 0 ? void 0 : focusItem.setFocused();
101
- focusItem === null || focusItem === void 0 ? void 0 : focusItem.scrollTo({ block: "nearest", inline: "nearest" });
102
- },
103
- },
104
- previousSearchItem: {
105
- hotkey: "ArrowUp",
106
- allowWhenInputFocused: true,
107
- canRepeat: true,
108
- isEnabled: (tree) => tree.isSearchOpen(),
109
- handler: (e, tree) => {
110
- const focusItem = [...tree.getSearchMatchingItems()]
111
- .reverse()
112
- .find((item) => item.getItemMeta().index <
113
- tree.getFocusedItem().getItemMeta().index);
114
- focusItem === null || focusItem === void 0 ? void 0 : focusItem.setFocused();
115
- focusItem === null || focusItem === void 0 ? void 0 : focusItem.scrollTo({ block: "nearest", inline: "nearest" });
116
- },
117
- },
118
- },
119
- };
@@ -1,32 +0,0 @@
1
- import { ItemInstance, SetStateFn } from "../../types/core";
2
- import { HotkeysCoreDataRef } from "../hotkeys-core/types";
3
- export interface SearchFeatureDataRef<T = any> extends HotkeysCoreDataRef {
4
- matchingItems: ItemInstance<T>[];
5
- searchInput: HTMLInputElement | null;
6
- }
7
- export type SearchFeatureDef<T> = {
8
- state: {
9
- search: string | null;
10
- };
11
- config: {
12
- setSearch?: SetStateFn<string | null>;
13
- onOpenSearch?: () => void;
14
- onCloseSearch?: () => void;
15
- isSearchMatchingItem?: (search: string, item: ItemInstance<T>) => boolean;
16
- };
17
- treeInstance: {
18
- setSearch: (search: string | null) => void;
19
- openSearch: (initialValue?: string) => void;
20
- closeSearch: () => void;
21
- isSearchOpen: () => boolean;
22
- getSearchValue: () => string;
23
- registerSearchInputElement: (element: HTMLInputElement | null) => void;
24
- getSearchInputElement: () => HTMLInputElement | null;
25
- getSearchInputElementProps: () => any;
26
- getSearchMatchingItems: () => ItemInstance<T>[];
27
- };
28
- itemInstance: {
29
- isMatchingSearch: () => boolean;
30
- };
31
- hotkeys: "openSearch" | "closeSearch" | "submitSearch" | "nextSearchItem" | "previousSearchItem";
32
- };
@@ -1,2 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,2 +0,0 @@
1
- import { FeatureImplementation } from "../../types/core";
2
- export declare const selectionFeature: FeatureImplementation;
@@ -1,132 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.selectionFeature = void 0;
4
- const utils_1 = require("../../utils");
5
- exports.selectionFeature = {
6
- key: "selection",
7
- getInitialState: (initialState) => (Object.assign({ selectedItems: [] }, initialState)),
8
- getDefaultConfig: (defaultConfig, tree) => (Object.assign({ setSelectedItems: (0, utils_1.makeStateUpdater)("selectedItems", tree) }, defaultConfig)),
9
- stateHandlerNames: {
10
- selectedItems: "setSelectedItems",
11
- },
12
- treeInstance: {
13
- setSelectedItems: ({ tree }, selectedItems) => {
14
- tree.applySubStateUpdate("selectedItems", selectedItems);
15
- },
16
- getSelectedItems: ({ tree }) => {
17
- return tree.getState().selectedItems.map(tree.getItemInstance);
18
- },
19
- },
20
- itemInstance: {
21
- select: ({ tree, itemId }) => {
22
- const { selectedItems } = tree.getState();
23
- tree.setSelectedItems(selectedItems.includes(itemId)
24
- ? selectedItems
25
- : [...selectedItems, itemId]);
26
- },
27
- deselect: ({ tree, itemId }) => {
28
- const { selectedItems } = tree.getState();
29
- tree.setSelectedItems(selectedItems.filter((id) => id !== itemId));
30
- },
31
- isSelected: ({ tree, itemId }) => {
32
- const { selectedItems } = tree.getState();
33
- return selectedItems.includes(itemId);
34
- },
35
- selectUpTo: ({ tree, item }, ctrl) => {
36
- const indexA = item.getItemMeta().index;
37
- // TODO dont use focused item as anchor, but last primary-clicked item
38
- const indexB = tree.getFocusedItem().getItemMeta().index;
39
- const [a, b] = indexA < indexB ? [indexA, indexB] : [indexB, indexA];
40
- const newSelectedItems = tree
41
- .getItems()
42
- .slice(a, b + 1)
43
- .map((treeItem) => treeItem.getItemMeta().itemId);
44
- if (!ctrl) {
45
- tree.setSelectedItems(newSelectedItems);
46
- return;
47
- }
48
- const { selectedItems } = tree.getState();
49
- const uniqueSelectedItems = [
50
- ...new Set([...selectedItems, ...newSelectedItems]),
51
- ];
52
- tree.setSelectedItems(uniqueSelectedItems);
53
- },
54
- toggleSelect: ({ item }) => {
55
- if (item.isSelected()) {
56
- item.deselect();
57
- }
58
- else {
59
- item.select();
60
- }
61
- },
62
- getProps: ({ tree, item, prev }) => (Object.assign(Object.assign({}, prev === null || prev === void 0 ? void 0 : prev()), { "aria-selected": item.isSelected() ? "true" : "false", onClick: (e) => {
63
- var _a, _b;
64
- if (e.shiftKey) {
65
- item.selectUpTo(e.ctrlKey || e.metaKey);
66
- }
67
- else if (e.ctrlKey || e.metaKey) {
68
- item.toggleSelect();
69
- }
70
- else {
71
- tree.setSelectedItems([item.getItemMeta().itemId]);
72
- }
73
- (_b = (_a = prev === null || prev === void 0 ? void 0 : prev()) === null || _a === void 0 ? void 0 : _a.onClick) === null || _b === void 0 ? void 0 : _b.call(_a, e);
74
- } })),
75
- },
76
- hotkeys: {
77
- // setSelectedItem: {
78
- // hotkey: "space",
79
- // handler: (e, tree) => {
80
- // tree.setSelectedItems([tree.getFocusedItem().getId()]);
81
- // },
82
- // },
83
- toggleSelectedItem: {
84
- hotkey: "Control+Space",
85
- preventDefault: true,
86
- handler: (_, tree) => {
87
- tree.getFocusedItem().toggleSelect();
88
- },
89
- },
90
- selectUpwards: {
91
- hotkey: "Shift+ArrowUp",
92
- handler: (e, tree) => {
93
- const focused = tree.getFocusedItem();
94
- const above = focused.getItemAbove();
95
- if (!above)
96
- return;
97
- if (focused.isSelected() && above.isSelected()) {
98
- focused.deselect();
99
- }
100
- else {
101
- above.select();
102
- }
103
- above.setFocused();
104
- tree.updateDomFocus();
105
- },
106
- },
107
- selectDownwards: {
108
- hotkey: "Shift+ArrowDown",
109
- handler: (e, tree) => {
110
- const focused = tree.getFocusedItem();
111
- const below = focused.getItemBelow();
112
- if (!below)
113
- return;
114
- if (focused.isSelected() && below.isSelected()) {
115
- focused.deselect();
116
- }
117
- else {
118
- below.select();
119
- }
120
- below.setFocused();
121
- tree.updateDomFocus();
122
- },
123
- },
124
- selectAll: {
125
- hotkey: "Control+KeyA",
126
- preventDefault: true,
127
- handler: (e, tree) => {
128
- tree.setSelectedItems(tree.getItems().map((item) => item.getId()));
129
- },
130
- },
131
- },
132
- };
@@ -1,21 +0,0 @@
1
- import { ItemInstance, SetStateFn } from "../../types/core";
2
- export type SelectionFeatureDef<T> = {
3
- state: {
4
- selectedItems: string[];
5
- };
6
- config: {
7
- setSelectedItems?: SetStateFn<string[]>;
8
- };
9
- treeInstance: {
10
- setSelectedItems: (selectedItems: string[]) => void;
11
- getSelectedItems: () => ItemInstance<T>[];
12
- };
13
- itemInstance: {
14
- select: () => void;
15
- deselect: () => void;
16
- toggleSelect: () => void;
17
- isSelected: () => boolean;
18
- selectUpTo: (ctrl: boolean) => void;
19
- };
20
- hotkeys: "toggleSelectedItem" | "selectUpwards" | "selectDownwards" | "selectAll";
21
- };
@@ -1,2 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,2 +0,0 @@
1
- import { FeatureImplementation } from "../../types/core";
2
- export declare const syncDataLoaderFeature: FeatureImplementation;
@@ -1,53 +0,0 @@
1
- "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.syncDataLoaderFeature = void 0;
13
- const utils_1 = require("../../utils");
14
- const errors_1 = require("../../utilities/errors");
15
- const undefErrorMessage = "sync dataLoader returned undefined";
16
- const promiseErrorMessage = "sync dataLoader returned promise";
17
- const unpromise = (data) => {
18
- if (!data) {
19
- throw (0, errors_1.throwError)(undefErrorMessage);
20
- }
21
- if (typeof data === "object" && "then" in data) {
22
- throw (0, errors_1.throwError)(promiseErrorMessage);
23
- }
24
- return data;
25
- };
26
- exports.syncDataLoaderFeature = {
27
- key: "sync-data-loader",
28
- getInitialState: (initialState) => (Object.assign({ loadingItemData: [], loadingItemChildrens: [] }, initialState)),
29
- getDefaultConfig: (defaultConfig, tree) => (Object.assign({ setLoadingItemData: (0, utils_1.makeStateUpdater)("loadingItemData", tree), setLoadingItemChildrens: (0, utils_1.makeStateUpdater)("loadingItemChildrens", tree) }, defaultConfig)),
30
- stateHandlerNames: {
31
- loadingItemData: "setLoadingItemData",
32
- loadingItemChildrens: "setLoadingItemChildrens",
33
- },
34
- treeInstance: {
35
- waitForItemDataLoaded: () => __awaiter(void 0, void 0, void 0, function* () { }),
36
- waitForItemChildrenLoaded: () => __awaiter(void 0, void 0, void 0, function* () { }),
37
- retrieveItemData: ({ tree }, itemId) => {
38
- return unpromise(tree.getConfig().dataLoader.getItem(itemId));
39
- },
40
- retrieveChildrenIds: ({ tree }, itemId) => {
41
- const { dataLoader } = tree.getConfig();
42
- if ("getChildren" in dataLoader) {
43
- return unpromise(dataLoader.getChildren(itemId));
44
- }
45
- return unpromise(dataLoader.getChildrenWithData(itemId)).map((c) => c.data);
46
- },
47
- loadItemData: ({ tree }, itemId) => tree.retrieveItemData(itemId),
48
- loadChildrenIds: ({ tree }, itemId) => tree.retrieveChildrenIds(itemId),
49
- },
50
- itemInstance: {
51
- isLoading: () => false,
52
- },
53
- };
@@ -1,28 +0,0 @@
1
- export type TreeDataLoader<T> = {
2
- getItem: (itemId: string) => T | Promise<T>;
3
- getChildren: (itemId: string) => string[] | Promise<string[]>;
4
- } | {
5
- getItem: (itemId: string) => T | Promise<T>;
6
- getChildrenWithData: (itemId: string) => {
7
- id: string;
8
- data: T;
9
- }[] | Promise<{
10
- id: string;
11
- data: T;
12
- }[]>;
13
- };
14
- export type SyncDataLoaderFeatureDef<T> = {
15
- state: {};
16
- config: {
17
- rootItemId: string;
18
- dataLoader: TreeDataLoader<T>;
19
- };
20
- treeInstance: {
21
- retrieveItemData: (itemId: string) => T;
22
- retrieveChildrenIds: (itemId: string) => string[];
23
- };
24
- itemInstance: {
25
- isLoading: () => boolean;
26
- };
27
- hotkeys: never;
28
- };
@@ -1,2 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,2 +0,0 @@
1
- import { FeatureImplementation } from "../../types/core";
2
- export declare const treeFeature: FeatureImplementation<any>;
@@ -1,245 +0,0 @@
1
- "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.treeFeature = void 0;
13
- const utils_1 = require("../../utils");
14
- const errors_1 = require("../../utilities/errors");
15
- exports.treeFeature = {
16
- key: "tree",
17
- getInitialState: (initialState) => (Object.assign({ expandedItems: [], focusedItem: null }, initialState)),
18
- getDefaultConfig: (defaultConfig, tree) => (Object.assign({ setExpandedItems: (0, utils_1.makeStateUpdater)("expandedItems", tree), setFocusedItem: (0, utils_1.makeStateUpdater)("focusedItem", tree) }, defaultConfig)),
19
- stateHandlerNames: {
20
- expandedItems: "setExpandedItems",
21
- focusedItem: "setFocusedItem",
22
- },
23
- treeInstance: {
24
- getItemsMeta: ({ tree }) => {
25
- const { rootItemId } = tree.getConfig();
26
- const { expandedItems } = tree.getState();
27
- const flatItems = [];
28
- const expandedItemsSet = new Set(expandedItems); // TODO support setting state expandedItems as set instead of array
29
- const recursiveAdd = (itemId, path, level, setSize, posInSet) => {
30
- var _a;
31
- if (path.includes(itemId)) {
32
- (0, errors_1.logWarning)(`Circular reference for ${path.join(".")}`);
33
- return;
34
- }
35
- flatItems.push({
36
- itemId,
37
- level,
38
- index: flatItems.length,
39
- parentId: path.at(-1),
40
- setSize,
41
- posInSet,
42
- });
43
- if (expandedItemsSet.has(itemId)) {
44
- const children = (_a = tree.retrieveChildrenIds(itemId)) !== null && _a !== void 0 ? _a : [];
45
- let i = 0;
46
- for (const childId of children) {
47
- recursiveAdd(childId, path.concat(itemId), level + 1, children.length, i++);
48
- }
49
- }
50
- };
51
- const children = tree.retrieveChildrenIds(rootItemId);
52
- let i = 0;
53
- for (const itemId of children) {
54
- recursiveAdd(itemId, [rootItemId], 0, children.length, i++);
55
- }
56
- return flatItems;
57
- },
58
- getFocusedItem: ({ tree }) => {
59
- var _a;
60
- const focusedItemId = tree.getState().focusedItem;
61
- return ((_a = (focusedItemId !== null ? tree.getItemInstance(focusedItemId) : null)) !== null && _a !== void 0 ? _a : tree.getItems()[0]);
62
- },
63
- getRootItem: ({ tree }) => {
64
- const { rootItemId } = tree.getConfig();
65
- return tree.getItemInstance(rootItemId);
66
- },
67
- focusNextItem: ({ tree }) => {
68
- var _a;
69
- const focused = tree.getFocusedItem().getItemMeta();
70
- if (!focused)
71
- return;
72
- const nextIndex = Math.min(focused.index + 1, tree.getItems().length - 1);
73
- (_a = tree.getItems()[nextIndex]) === null || _a === void 0 ? void 0 : _a.setFocused();
74
- },
75
- focusPreviousItem: ({ tree }) => {
76
- var _a;
77
- const focused = tree.getFocusedItem().getItemMeta();
78
- if (!focused)
79
- return;
80
- const nextIndex = Math.max(focused.index - 1, 0);
81
- (_a = tree.getItems()[nextIndex]) === null || _a === void 0 ? void 0 : _a.setFocused();
82
- },
83
- updateDomFocus: ({ tree }) => {
84
- // Required because if the state is managed outside in react, the state only updated during next render
85
- setTimeout(() => __awaiter(void 0, void 0, void 0, function* () {
86
- var _a, _b;
87
- const focusedItem = tree.getFocusedItem();
88
- (_b = (_a = tree.getConfig()).scrollToItem) === null || _b === void 0 ? void 0 : _b.call(_a, focusedItem);
89
- yield (0, utils_1.poll)(() => focusedItem.getElement() !== null, 20);
90
- const focusedElement = focusedItem.getElement();
91
- if (!focusedElement)
92
- return;
93
- focusedElement.focus();
94
- }));
95
- },
96
- getContainerProps: ({ prev, tree }, treeLabel) => (Object.assign(Object.assign({}, prev === null || prev === void 0 ? void 0 : prev()), { role: "tree", "aria-label": treeLabel !== null && treeLabel !== void 0 ? treeLabel : "", ref: tree.registerElement })),
97
- // relevant for hotkeys of this feature
98
- isSearchOpen: () => false,
99
- },
100
- itemInstance: {
101
- scrollTo: (_a, scrollIntoViewArg_1) => __awaiter(void 0, [_a, scrollIntoViewArg_1], void 0, function* ({ tree, item }, scrollIntoViewArg) {
102
- var _b, _c, _d;
103
- (_c = (_b = tree.getConfig()).scrollToItem) === null || _c === void 0 ? void 0 : _c.call(_b, item);
104
- yield (0, utils_1.poll)(() => item.getElement() !== null, 20);
105
- (_d = item.getElement()) === null || _d === void 0 ? void 0 : _d.scrollIntoView(scrollIntoViewArg);
106
- }),
107
- getId: ({ itemId }) => itemId,
108
- getKey: ({ itemId }) => itemId, // TODO apply to all stories to use
109
- getProps: ({ item, prev }) => {
110
- const itemMeta = item.getItemMeta();
111
- return Object.assign(Object.assign({}, prev === null || prev === void 0 ? void 0 : prev()), { ref: item.registerElement, role: "treeitem", "aria-setsize": itemMeta.setSize, "aria-posinset": itemMeta.posInSet + 1, "aria-selected": "false", "aria-label": item.getItemName(), "aria-level": itemMeta.level + 1, tabIndex: item.isFocused() ? 0 : -1, onClick: (e) => {
112
- item.setFocused();
113
- item.primaryAction();
114
- if (e.ctrlKey || e.shiftKey || e.metaKey) {
115
- return;
116
- }
117
- if (!item.isFolder()) {
118
- return;
119
- }
120
- if (item.isExpanded()) {
121
- item.collapse();
122
- }
123
- else {
124
- item.expand();
125
- }
126
- } });
127
- },
128
- expand: ({ tree, item, itemId }) => {
129
- var _a;
130
- if (!item.isFolder()) {
131
- return;
132
- }
133
- if ((_a = tree.getState().loadingItemChildrens) === null || _a === void 0 ? void 0 : _a.includes(itemId)) {
134
- return;
135
- }
136
- tree.applySubStateUpdate("expandedItems", (expandedItems) => [
137
- ...expandedItems,
138
- itemId,
139
- ]);
140
- tree.rebuildTree();
141
- },
142
- collapse: ({ tree, item, itemId }) => {
143
- if (!item.isFolder()) {
144
- return;
145
- }
146
- tree.applySubStateUpdate("expandedItems", (expandedItems) => expandedItems.filter((id) => id !== itemId));
147
- tree.rebuildTree();
148
- },
149
- getItemData: ({ tree, itemId }) => tree.retrieveItemData(itemId),
150
- equals: ({ item }, other) => item.getId() === (other === null || other === void 0 ? void 0 : other.getId()),
151
- isExpanded: ({ tree, itemId }) => tree.getState().expandedItems.includes(itemId),
152
- isDescendentOf: ({ item }, parentId) => {
153
- const parent = item.getParent();
154
- return Boolean((parent === null || parent === void 0 ? void 0 : parent.getId()) === parentId || (parent === null || parent === void 0 ? void 0 : parent.isDescendentOf(parentId)));
155
- },
156
- isFocused: ({ tree, item, itemId }) => tree.getState().focusedItem === itemId ||
157
- (tree.getState().focusedItem === null && item.getItemMeta().index === 0),
158
- isFolder: ({ tree, item }) => item.getItemMeta().level === -1 ||
159
- tree.getConfig().isItemFolder(item),
160
- getItemName: ({ tree, item }) => {
161
- const config = tree.getConfig();
162
- return config.getItemName(item);
163
- },
164
- setFocused: ({ tree, itemId }) => {
165
- tree.applySubStateUpdate("focusedItem", itemId);
166
- },
167
- primaryAction: ({ tree, item }) => { var _a, _b; return (_b = (_a = tree.getConfig()).onPrimaryAction) === null || _b === void 0 ? void 0 : _b.call(_a, item); },
168
- getParent: ({ tree, item }) => item.getItemMeta().parentId
169
- ? tree.getItemInstance(item.getItemMeta().parentId)
170
- : undefined,
171
- getIndexInParent: ({ item }) => item.getItemMeta().posInSet,
172
- getChildren: ({ tree, itemId }) => tree.retrieveChildrenIds(itemId).map((id) => tree.getItemInstance(id)),
173
- getTree: ({ tree }) => tree,
174
- getItemAbove: ({ tree, item }) => tree.getItems()[item.getItemMeta().index - 1],
175
- getItemBelow: ({ tree, item }) => tree.getItems()[item.getItemMeta().index + 1],
176
- },
177
- hotkeys: {
178
- focusNextItem: {
179
- hotkey: "ArrowDown",
180
- canRepeat: true,
181
- preventDefault: true,
182
- isEnabled: (tree) => { var _a, _b; return !((_b = (_a = tree.isSearchOpen) === null || _a === void 0 ? void 0 : _a.call(tree)) !== null && _b !== void 0 ? _b : false) && !tree.getState().dnd; }, // TODO what happens when the feature doesnt exist? proxy method still claims to exist
183
- handler: (e, tree) => {
184
- tree.focusNextItem();
185
- tree.updateDomFocus();
186
- },
187
- },
188
- focusPreviousItem: {
189
- hotkey: "ArrowUp",
190
- canRepeat: true,
191
- preventDefault: true,
192
- isEnabled: (tree) => { var _a, _b; return !((_b = (_a = tree.isSearchOpen) === null || _a === void 0 ? void 0 : _a.call(tree)) !== null && _b !== void 0 ? _b : false) && !tree.getState().dnd; },
193
- handler: (e, tree) => {
194
- tree.focusPreviousItem();
195
- tree.updateDomFocus();
196
- },
197
- },
198
- expandOrDown: {
199
- hotkey: "ArrowRight",
200
- canRepeat: true,
201
- handler: (e, tree) => {
202
- const item = tree.getFocusedItem();
203
- if (item.isExpanded() || !item.isFolder()) {
204
- tree.focusNextItem();
205
- tree.updateDomFocus();
206
- }
207
- else {
208
- item.expand();
209
- }
210
- },
211
- },
212
- collapseOrUp: {
213
- hotkey: "ArrowLeft",
214
- canRepeat: true,
215
- handler: (e, tree) => {
216
- var _a;
217
- const item = tree.getFocusedItem();
218
- if ((!item.isExpanded() || !item.isFolder()) &&
219
- item.getItemMeta().level !== 0) {
220
- (_a = item.getParent()) === null || _a === void 0 ? void 0 : _a.setFocused();
221
- tree.updateDomFocus();
222
- }
223
- else {
224
- item.collapse();
225
- }
226
- },
227
- },
228
- focusFirstItem: {
229
- hotkey: "Home",
230
- handler: (e, tree) => {
231
- var _a;
232
- (_a = tree.getItems()[0]) === null || _a === void 0 ? void 0 : _a.setFocused();
233
- tree.updateDomFocus();
234
- },
235
- },
236
- focusLastItem: {
237
- hotkey: "End",
238
- handler: (e, tree) => {
239
- var _a;
240
- (_a = tree.getItems()[tree.getItems().length - 1]) === null || _a === void 0 ? void 0 : _a.setFocused();
241
- tree.updateDomFocus();
242
- },
243
- },
244
- },
245
- };