@headless-tree/core 1.2.1 → 1.3.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.
Files changed (189) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/index.d.mts +577 -0
  3. package/dist/index.d.ts +577 -0
  4. package/dist/index.js +2321 -0
  5. package/dist/index.mjs +2276 -0
  6. package/package.json +18 -10
  7. package/src/core/create-tree.ts +26 -15
  8. package/src/features/async-data-loader/feature.ts +5 -0
  9. package/src/features/async-data-loader/types.ts +2 -0
  10. package/src/features/checkboxes/checkboxes.spec.ts +20 -5
  11. package/src/features/checkboxes/feature.ts +31 -16
  12. package/src/features/checkboxes/types.ts +1 -0
  13. package/src/features/drag-and-drop/drag-and-drop.spec.ts +11 -2
  14. package/src/features/drag-and-drop/feature.ts +51 -16
  15. package/src/features/drag-and-drop/types.ts +17 -0
  16. package/src/features/keyboard-drag-and-drop/feature.ts +8 -1
  17. package/src/features/keyboard-drag-and-drop/keyboard-drag-and-drop.spec.ts +34 -3
  18. package/src/features/main/types.ts +0 -2
  19. package/src/features/sync-data-loader/feature.ts +5 -1
  20. package/src/features/tree/feature.ts +4 -3
  21. package/src/features/tree/tree.spec.ts +14 -4
  22. package/src/test-utils/test-tree-do.ts +2 -0
  23. package/src/test-utils/test-tree.ts +1 -0
  24. package/tsconfig.json +1 -4
  25. package/vitest.config.ts +3 -1
  26. package/lib/cjs/core/build-proxified-instance.d.ts +0 -2
  27. package/lib/cjs/core/build-proxified-instance.js +0 -58
  28. package/lib/cjs/core/build-static-instance.d.ts +0 -2
  29. package/lib/cjs/core/build-static-instance.js +0 -26
  30. package/lib/cjs/core/create-tree.d.ts +0 -2
  31. package/lib/cjs/core/create-tree.js +0 -191
  32. package/lib/cjs/features/async-data-loader/feature.d.ts +0 -2
  33. package/lib/cjs/features/async-data-loader/feature.js +0 -135
  34. package/lib/cjs/features/async-data-loader/types.d.ts +0 -47
  35. package/lib/cjs/features/async-data-loader/types.js +0 -2
  36. package/lib/cjs/features/checkboxes/feature.d.ts +0 -2
  37. package/lib/cjs/features/checkboxes/feature.js +0 -94
  38. package/lib/cjs/features/checkboxes/types.d.ts +0 -26
  39. package/lib/cjs/features/checkboxes/types.js +0 -9
  40. package/lib/cjs/features/drag-and-drop/feature.d.ts +0 -2
  41. package/lib/cjs/features/drag-and-drop/feature.js +0 -205
  42. package/lib/cjs/features/drag-and-drop/types.d.ts +0 -71
  43. package/lib/cjs/features/drag-and-drop/types.js +0 -9
  44. package/lib/cjs/features/drag-and-drop/utils.d.ts +0 -27
  45. package/lib/cjs/features/drag-and-drop/utils.js +0 -182
  46. package/lib/cjs/features/expand-all/feature.d.ts +0 -2
  47. package/lib/cjs/features/expand-all/feature.js +0 -70
  48. package/lib/cjs/features/expand-all/types.d.ts +0 -19
  49. package/lib/cjs/features/expand-all/types.js +0 -2
  50. package/lib/cjs/features/hotkeys-core/feature.d.ts +0 -2
  51. package/lib/cjs/features/hotkeys-core/feature.js +0 -107
  52. package/lib/cjs/features/hotkeys-core/types.d.ts +0 -27
  53. package/lib/cjs/features/hotkeys-core/types.js +0 -2
  54. package/lib/cjs/features/keyboard-drag-and-drop/feature.d.ts +0 -2
  55. package/lib/cjs/features/keyboard-drag-and-drop/feature.js +0 -206
  56. package/lib/cjs/features/keyboard-drag-and-drop/types.d.ts +0 -27
  57. package/lib/cjs/features/keyboard-drag-and-drop/types.js +0 -11
  58. package/lib/cjs/features/main/types.d.ts +0 -47
  59. package/lib/cjs/features/main/types.js +0 -2
  60. package/lib/cjs/features/prop-memoization/feature.d.ts +0 -2
  61. package/lib/cjs/features/prop-memoization/feature.js +0 -70
  62. package/lib/cjs/features/prop-memoization/types.d.ts +0 -15
  63. package/lib/cjs/features/prop-memoization/types.js +0 -2
  64. package/lib/cjs/features/renaming/feature.d.ts +0 -2
  65. package/lib/cjs/features/renaming/feature.js +0 -86
  66. package/lib/cjs/features/renaming/types.d.ts +0 -27
  67. package/lib/cjs/features/renaming/types.js +0 -2
  68. package/lib/cjs/features/search/feature.d.ts +0 -2
  69. package/lib/cjs/features/search/feature.js +0 -119
  70. package/lib/cjs/features/search/types.d.ts +0 -32
  71. package/lib/cjs/features/search/types.js +0 -2
  72. package/lib/cjs/features/selection/feature.d.ts +0 -2
  73. package/lib/cjs/features/selection/feature.js +0 -132
  74. package/lib/cjs/features/selection/types.d.ts +0 -21
  75. package/lib/cjs/features/selection/types.js +0 -2
  76. package/lib/cjs/features/sync-data-loader/feature.d.ts +0 -2
  77. package/lib/cjs/features/sync-data-loader/feature.js +0 -49
  78. package/lib/cjs/features/sync-data-loader/types.d.ts +0 -28
  79. package/lib/cjs/features/sync-data-loader/types.js +0 -2
  80. package/lib/cjs/features/tree/feature.d.ts +0 -2
  81. package/lib/cjs/features/tree/feature.js +0 -244
  82. package/lib/cjs/features/tree/types.d.ts +0 -63
  83. package/lib/cjs/features/tree/types.js +0 -2
  84. package/lib/cjs/index.d.ts +0 -33
  85. package/lib/cjs/index.js +0 -51
  86. package/lib/cjs/mddocs-entry.d.ts +0 -121
  87. package/lib/cjs/mddocs-entry.js +0 -17
  88. package/lib/cjs/test-utils/test-tree-do.d.ts +0 -23
  89. package/lib/cjs/test-utils/test-tree-do.js +0 -112
  90. package/lib/cjs/test-utils/test-tree-expect.d.ts +0 -17
  91. package/lib/cjs/test-utils/test-tree-expect.js +0 -66
  92. package/lib/cjs/test-utils/test-tree.d.ts +0 -48
  93. package/lib/cjs/test-utils/test-tree.js +0 -207
  94. package/lib/cjs/types/core.d.ts +0 -84
  95. package/lib/cjs/types/core.js +0 -2
  96. package/lib/cjs/types/deep-merge.d.ts +0 -13
  97. package/lib/cjs/types/deep-merge.js +0 -2
  98. package/lib/cjs/utilities/create-on-drop-handler.d.ts +0 -3
  99. package/lib/cjs/utilities/create-on-drop-handler.js +0 -20
  100. package/lib/cjs/utilities/errors.d.ts +0 -2
  101. package/lib/cjs/utilities/errors.js +0 -9
  102. package/lib/cjs/utilities/insert-items-at-target.d.ts +0 -3
  103. package/lib/cjs/utilities/insert-items-at-target.js +0 -40
  104. package/lib/cjs/utilities/remove-items-from-parents.d.ts +0 -2
  105. package/lib/cjs/utilities/remove-items-from-parents.js +0 -32
  106. package/lib/cjs/utils.d.ts +0 -6
  107. package/lib/cjs/utils.js +0 -53
  108. package/lib/esm/core/build-proxified-instance.d.ts +0 -2
  109. package/lib/esm/core/build-proxified-instance.js +0 -54
  110. package/lib/esm/core/build-static-instance.d.ts +0 -2
  111. package/lib/esm/core/build-static-instance.js +0 -22
  112. package/lib/esm/core/create-tree.d.ts +0 -2
  113. package/lib/esm/core/create-tree.js +0 -187
  114. package/lib/esm/features/async-data-loader/feature.d.ts +0 -2
  115. package/lib/esm/features/async-data-loader/feature.js +0 -132
  116. package/lib/esm/features/async-data-loader/types.d.ts +0 -47
  117. package/lib/esm/features/async-data-loader/types.js +0 -1
  118. package/lib/esm/features/checkboxes/feature.d.ts +0 -2
  119. package/lib/esm/features/checkboxes/feature.js +0 -91
  120. package/lib/esm/features/checkboxes/types.d.ts +0 -26
  121. package/lib/esm/features/checkboxes/types.js +0 -6
  122. package/lib/esm/features/drag-and-drop/feature.d.ts +0 -2
  123. package/lib/esm/features/drag-and-drop/feature.js +0 -202
  124. package/lib/esm/features/drag-and-drop/types.d.ts +0 -71
  125. package/lib/esm/features/drag-and-drop/types.js +0 -6
  126. package/lib/esm/features/drag-and-drop/utils.d.ts +0 -27
  127. package/lib/esm/features/drag-and-drop/utils.js +0 -172
  128. package/lib/esm/features/expand-all/feature.d.ts +0 -2
  129. package/lib/esm/features/expand-all/feature.js +0 -67
  130. package/lib/esm/features/expand-all/types.d.ts +0 -19
  131. package/lib/esm/features/expand-all/types.js +0 -1
  132. package/lib/esm/features/hotkeys-core/feature.d.ts +0 -2
  133. package/lib/esm/features/hotkeys-core/feature.js +0 -104
  134. package/lib/esm/features/hotkeys-core/types.d.ts +0 -27
  135. package/lib/esm/features/hotkeys-core/types.js +0 -1
  136. package/lib/esm/features/keyboard-drag-and-drop/feature.d.ts +0 -2
  137. package/lib/esm/features/keyboard-drag-and-drop/feature.js +0 -203
  138. package/lib/esm/features/keyboard-drag-and-drop/types.d.ts +0 -27
  139. package/lib/esm/features/keyboard-drag-and-drop/types.js +0 -8
  140. package/lib/esm/features/main/types.d.ts +0 -47
  141. package/lib/esm/features/main/types.js +0 -1
  142. package/lib/esm/features/prop-memoization/feature.d.ts +0 -2
  143. package/lib/esm/features/prop-memoization/feature.js +0 -67
  144. package/lib/esm/features/prop-memoization/types.d.ts +0 -15
  145. package/lib/esm/features/prop-memoization/types.js +0 -1
  146. package/lib/esm/features/renaming/feature.d.ts +0 -2
  147. package/lib/esm/features/renaming/feature.js +0 -83
  148. package/lib/esm/features/renaming/types.d.ts +0 -27
  149. package/lib/esm/features/renaming/types.js +0 -1
  150. package/lib/esm/features/search/feature.d.ts +0 -2
  151. package/lib/esm/features/search/feature.js +0 -116
  152. package/lib/esm/features/search/types.d.ts +0 -32
  153. package/lib/esm/features/search/types.js +0 -1
  154. package/lib/esm/features/selection/feature.d.ts +0 -2
  155. package/lib/esm/features/selection/feature.js +0 -129
  156. package/lib/esm/features/selection/types.d.ts +0 -21
  157. package/lib/esm/features/selection/types.js +0 -1
  158. package/lib/esm/features/sync-data-loader/feature.d.ts +0 -2
  159. package/lib/esm/features/sync-data-loader/feature.js +0 -46
  160. package/lib/esm/features/sync-data-loader/types.d.ts +0 -28
  161. package/lib/esm/features/sync-data-loader/types.js +0 -1
  162. package/lib/esm/features/tree/feature.d.ts +0 -2
  163. package/lib/esm/features/tree/feature.js +0 -241
  164. package/lib/esm/features/tree/types.d.ts +0 -63
  165. package/lib/esm/features/tree/types.js +0 -1
  166. package/lib/esm/index.d.ts +0 -33
  167. package/lib/esm/index.js +0 -32
  168. package/lib/esm/mddocs-entry.d.ts +0 -121
  169. package/lib/esm/mddocs-entry.js +0 -1
  170. package/lib/esm/test-utils/test-tree-do.d.ts +0 -23
  171. package/lib/esm/test-utils/test-tree-do.js +0 -108
  172. package/lib/esm/test-utils/test-tree-expect.d.ts +0 -17
  173. package/lib/esm/test-utils/test-tree-expect.js +0 -62
  174. package/lib/esm/test-utils/test-tree.d.ts +0 -48
  175. package/lib/esm/test-utils/test-tree.js +0 -203
  176. package/lib/esm/types/core.d.ts +0 -84
  177. package/lib/esm/types/core.js +0 -1
  178. package/lib/esm/types/deep-merge.d.ts +0 -13
  179. package/lib/esm/types/deep-merge.js +0 -1
  180. package/lib/esm/utilities/create-on-drop-handler.d.ts +0 -3
  181. package/lib/esm/utilities/create-on-drop-handler.js +0 -16
  182. package/lib/esm/utilities/errors.d.ts +0 -2
  183. package/lib/esm/utilities/errors.js +0 -4
  184. package/lib/esm/utilities/insert-items-at-target.d.ts +0 -3
  185. package/lib/esm/utilities/insert-items-at-target.js +0 -36
  186. package/lib/esm/utilities/remove-items-from-parents.d.ts +0 -2
  187. package/lib/esm/utilities/remove-items-from-parents.js +0 -28
  188. package/lib/esm/utils.d.ts +0 -6
  189. 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,49 +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 promiseErrorMessage = "sync dataLoader returned promise";
16
- const unpromise = (data) => {
17
- if (!data || (typeof data === "object" && "then" in data)) {
18
- throw (0, errors_1.throwError)(promiseErrorMessage);
19
- }
20
- return data;
21
- };
22
- exports.syncDataLoaderFeature = {
23
- key: "sync-data-loader",
24
- getInitialState: (initialState) => (Object.assign({ loadingItemData: [], loadingItemChildrens: [] }, initialState)),
25
- getDefaultConfig: (defaultConfig, tree) => (Object.assign({ setLoadingItemData: (0, utils_1.makeStateUpdater)("loadingItemData", tree), setLoadingItemChildrens: (0, utils_1.makeStateUpdater)("loadingItemChildrens", tree) }, defaultConfig)),
26
- stateHandlerNames: {
27
- loadingItemData: "setLoadingItemData",
28
- loadingItemChildrens: "setLoadingItemChildrens",
29
- },
30
- treeInstance: {
31
- waitForItemDataLoaded: () => __awaiter(void 0, void 0, void 0, function* () { }),
32
- waitForItemChildrenLoaded: () => __awaiter(void 0, void 0, void 0, function* () { }),
33
- retrieveItemData: ({ tree }, itemId) => {
34
- return unpromise(tree.getConfig().dataLoader.getItem(itemId));
35
- },
36
- retrieveChildrenIds: ({ tree }, itemId) => {
37
- const { dataLoader } = tree.getConfig();
38
- if ("getChildren" in dataLoader) {
39
- return unpromise(dataLoader.getChildren(itemId));
40
- }
41
- return unpromise(dataLoader.getChildrenWithData(itemId)).map((c) => c.data);
42
- },
43
- loadItemData: ({ tree }, itemId) => tree.retrieveItemData(itemId),
44
- loadChildrenIds: ({ tree }, itemId) => tree.retrieveChildrenIds(itemId),
45
- },
46
- itemInstance: {
47
- isLoading: () => false,
48
- },
49
- };
@@ -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,244 +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, _b;
60
- return ((_b = tree.getItemInstance((_a = tree.getState().focusedItem) !== null && _a !== void 0 ? _a : "")) !== null && _b !== void 0 ? _b : tree.getItems()[0]);
61
- },
62
- getRootItem: ({ tree }) => {
63
- const { rootItemId } = tree.getConfig();
64
- return tree.getItemInstance(rootItemId);
65
- },
66
- focusNextItem: ({ tree }) => {
67
- var _a;
68
- const focused = tree.getFocusedItem().getItemMeta();
69
- if (!focused)
70
- return;
71
- const nextIndex = Math.min(focused.index + 1, tree.getItems().length - 1);
72
- (_a = tree.getItems()[nextIndex]) === null || _a === void 0 ? void 0 : _a.setFocused();
73
- },
74
- focusPreviousItem: ({ tree }) => {
75
- var _a;
76
- const focused = tree.getFocusedItem().getItemMeta();
77
- if (!focused)
78
- return;
79
- const nextIndex = Math.max(focused.index - 1, 0);
80
- (_a = tree.getItems()[nextIndex]) === null || _a === void 0 ? void 0 : _a.setFocused();
81
- },
82
- updateDomFocus: ({ tree }) => {
83
- // Required because if the state is managed outside in react, the state only updated during next render
84
- setTimeout(() => __awaiter(void 0, void 0, void 0, function* () {
85
- var _a, _b;
86
- const focusedItem = tree.getFocusedItem();
87
- (_b = (_a = tree.getConfig()).scrollToItem) === null || _b === void 0 ? void 0 : _b.call(_a, focusedItem);
88
- yield (0, utils_1.poll)(() => focusedItem.getElement() !== null, 20);
89
- const focusedElement = focusedItem.getElement();
90
- if (!focusedElement)
91
- return;
92
- focusedElement.focus();
93
- }));
94
- },
95
- 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 })),
96
- // relevant for hotkeys of this feature
97
- isSearchOpen: () => false,
98
- },
99
- itemInstance: {
100
- scrollTo: (_a, scrollIntoViewArg_1) => __awaiter(void 0, [_a, scrollIntoViewArg_1], void 0, function* ({ tree, item }, scrollIntoViewArg) {
101
- var _b, _c, _d;
102
- (_c = (_b = tree.getConfig()).scrollToItem) === null || _c === void 0 ? void 0 : _c.call(_b, item);
103
- yield (0, utils_1.poll)(() => item.getElement() !== null, 20);
104
- (_d = item.getElement()) === null || _d === void 0 ? void 0 : _d.scrollIntoView(scrollIntoViewArg);
105
- }),
106
- getId: ({ itemId }) => itemId,
107
- getKey: ({ itemId }) => itemId, // TODO apply to all stories to use
108
- getProps: ({ item, prev }) => {
109
- const itemMeta = item.getItemMeta();
110
- 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, "aria-selected": "false", "aria-label": item.getItemName(), "aria-level": itemMeta.level, tabIndex: item.isFocused() ? 0 : -1, onClick: (e) => {
111
- item.setFocused();
112
- item.primaryAction();
113
- if (e.ctrlKey || e.shiftKey || e.metaKey) {
114
- return;
115
- }
116
- if (!item.isFolder()) {
117
- return;
118
- }
119
- if (item.isExpanded()) {
120
- item.collapse();
121
- }
122
- else {
123
- item.expand();
124
- }
125
- } });
126
- },
127
- expand: ({ tree, item, itemId }) => {
128
- var _a;
129
- if (!item.isFolder()) {
130
- return;
131
- }
132
- if ((_a = tree.getState().loadingItemChildrens) === null || _a === void 0 ? void 0 : _a.includes(itemId)) {
133
- return;
134
- }
135
- tree.applySubStateUpdate("expandedItems", (expandedItems) => [
136
- ...expandedItems,
137
- itemId,
138
- ]);
139
- tree.rebuildTree();
140
- },
141
- collapse: ({ tree, item, itemId }) => {
142
- if (!item.isFolder()) {
143
- return;
144
- }
145
- tree.applySubStateUpdate("expandedItems", (expandedItems) => expandedItems.filter((id) => id !== itemId));
146
- tree.rebuildTree();
147
- },
148
- getItemData: ({ tree, itemId }) => tree.retrieveItemData(itemId),
149
- equals: ({ item }, other) => item.getId() === (other === null || other === void 0 ? void 0 : other.getId()),
150
- isExpanded: ({ tree, itemId }) => tree.getState().expandedItems.includes(itemId),
151
- isDescendentOf: ({ item }, parentId) => {
152
- const parent = item.getParent();
153
- return Boolean((parent === null || parent === void 0 ? void 0 : parent.getId()) === parentId || (parent === null || parent === void 0 ? void 0 : parent.isDescendentOf(parentId)));
154
- },
155
- isFocused: ({ tree, item, itemId }) => tree.getState().focusedItem === itemId ||
156
- (tree.getState().focusedItem === null && item.getItemMeta().index === 0),
157
- isFolder: ({ tree, item }) => item.getItemMeta().level === -1 ||
158
- tree.getConfig().isItemFolder(item),
159
- getItemName: ({ tree, item }) => {
160
- const config = tree.getConfig();
161
- return config.getItemName(item);
162
- },
163
- setFocused: ({ tree, itemId }) => {
164
- tree.applySubStateUpdate("focusedItem", itemId);
165
- },
166
- primaryAction: ({ tree, item }) => { var _a, _b; return (_b = (_a = tree.getConfig()).onPrimaryAction) === null || _b === void 0 ? void 0 : _b.call(_a, item); },
167
- getParent: ({ tree, item }) => item.getItemMeta().parentId
168
- ? tree.getItemInstance(item.getItemMeta().parentId)
169
- : undefined,
170
- getIndexInParent: ({ item }) => item.getItemMeta().posInSet,
171
- getChildren: ({ tree, itemId }) => tree.retrieveChildrenIds(itemId).map((id) => tree.getItemInstance(id)),
172
- getTree: ({ tree }) => tree,
173
- getItemAbove: ({ tree, item }) => tree.getItems()[item.getItemMeta().index - 1],
174
- getItemBelow: ({ tree, item }) => tree.getItems()[item.getItemMeta().index + 1],
175
- },
176
- hotkeys: {
177
- focusNextItem: {
178
- hotkey: "ArrowDown",
179
- canRepeat: true,
180
- preventDefault: true,
181
- 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
182
- handler: (e, tree) => {
183
- tree.focusNextItem();
184
- tree.updateDomFocus();
185
- },
186
- },
187
- focusPreviousItem: {
188
- hotkey: "ArrowUp",
189
- canRepeat: true,
190
- preventDefault: true,
191
- 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; },
192
- handler: (e, tree) => {
193
- tree.focusPreviousItem();
194
- tree.updateDomFocus();
195
- },
196
- },
197
- expandOrDown: {
198
- hotkey: "ArrowRight",
199
- canRepeat: true,
200
- handler: (e, tree) => {
201
- const item = tree.getFocusedItem();
202
- if (item.isExpanded() || !item.isFolder()) {
203
- tree.focusNextItem();
204
- tree.updateDomFocus();
205
- }
206
- else {
207
- item.expand();
208
- }
209
- },
210
- },
211
- collapseOrUp: {
212
- hotkey: "ArrowLeft",
213
- canRepeat: true,
214
- handler: (e, tree) => {
215
- var _a;
216
- const item = tree.getFocusedItem();
217
- if ((!item.isExpanded() || !item.isFolder()) &&
218
- item.getItemMeta().level !== 0) {
219
- (_a = item.getParent()) === null || _a === void 0 ? void 0 : _a.setFocused();
220
- tree.updateDomFocus();
221
- }
222
- else {
223
- item.collapse();
224
- }
225
- },
226
- },
227
- focusFirstItem: {
228
- hotkey: "Home",
229
- handler: (e, tree) => {
230
- var _a;
231
- (_a = tree.getItems()[0]) === null || _a === void 0 ? void 0 : _a.setFocused();
232
- tree.updateDomFocus();
233
- },
234
- },
235
- focusLastItem: {
236
- hotkey: "End",
237
- handler: (e, tree) => {
238
- var _a;
239
- (_a = tree.getItems()[tree.getItems().length - 1]) === null || _a === void 0 ? void 0 : _a.setFocused();
240
- tree.updateDomFocus();
241
- },
242
- },
243
- },
244
- };