@mui/x-tree-view-pro 7.12.0 → 7.12.1

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 (96) hide show
  1. package/{build/CHANGELOG.md → CHANGELOG.md} +70 -2
  2. package/{build/index.js → index.js} +1 -1
  3. package/{build/internals → internals}/utils/releaseInfo.js +1 -1
  4. package/{build/modern → modern}/index.js +1 -1
  5. package/{build/modern → modern}/internals/utils/releaseInfo.js +1 -1
  6. package/{build/node → node}/index.js +1 -1
  7. package/{build/node → node}/internals/utils/releaseInfo.js +1 -1
  8. package/package.json +16 -19
  9. package/build/LICENSE +0 -11
  10. package/build/README.md +0 -26
  11. package/build/package.json +0 -59
  12. package/src/RichTreeViewPro/RichTreeViewPro.plugins.ts +0 -54
  13. package/src/RichTreeViewPro/RichTreeViewPro.test.tsx +0 -20
  14. package/src/RichTreeViewPro/RichTreeViewPro.tsx +0 -383
  15. package/src/RichTreeViewPro/RichTreeViewPro.types.ts +0 -80
  16. package/src/RichTreeViewPro/index.ts +0 -8
  17. package/src/RichTreeViewPro/richTreeViewProClasses.ts +0 -18
  18. package/src/index.ts +0 -17
  19. package/src/internals/index.ts +0 -1
  20. package/src/internals/plugins/useTreeViewItemsReordering/index.ts +0 -7
  21. package/src/internals/plugins/useTreeViewItemsReordering/useTreeViewItemsReordering.itemPlugin.ts +0 -155
  22. package/src/internals/plugins/useTreeViewItemsReordering/useTreeViewItemsReordering.test.tsx +0 -370
  23. package/src/internals/plugins/useTreeViewItemsReordering/useTreeViewItemsReordering.ts +0 -278
  24. package/src/internals/plugins/useTreeViewItemsReordering/useTreeViewItemsReordering.types.ts +0 -160
  25. package/src/internals/plugins/useTreeViewItemsReordering/useTreeViewItemsReordering.utils.ts +0 -199
  26. package/src/internals/utils/releaseInfo.ts +0 -15
  27. package/src/internals/zero-styled/index.ts +0 -8
  28. package/src/themeAugmentation/components.d.ts +0 -13
  29. package/src/themeAugmentation/index.js +0 -1
  30. package/src/themeAugmentation/index.ts +0 -3
  31. package/src/themeAugmentation/overrides.d.ts +0 -13
  32. package/src/themeAugmentation/props.d.ts +0 -12
  33. package/src/themeAugmentation/themeAugmentation.spec.ts +0 -26
  34. package/tsconfig.build.json +0 -21
  35. package/tsconfig.build.tsbuildinfo +0 -1
  36. package/tsconfig.json +0 -14
  37. /package/{build/RichTreeViewPro → RichTreeViewPro}/RichTreeViewPro.d.ts +0 -0
  38. /package/{build/RichTreeViewPro → RichTreeViewPro}/RichTreeViewPro.js +0 -0
  39. /package/{build/RichTreeViewPro → RichTreeViewPro}/RichTreeViewPro.plugins.d.ts +0 -0
  40. /package/{build/RichTreeViewPro → RichTreeViewPro}/RichTreeViewPro.plugins.js +0 -0
  41. /package/{build/RichTreeViewPro → RichTreeViewPro}/RichTreeViewPro.types.d.ts +0 -0
  42. /package/{build/RichTreeViewPro → RichTreeViewPro}/RichTreeViewPro.types.js +0 -0
  43. /package/{build/RichTreeViewPro → RichTreeViewPro}/index.d.ts +0 -0
  44. /package/{build/RichTreeViewPro → RichTreeViewPro}/index.js +0 -0
  45. /package/{build/RichTreeViewPro → RichTreeViewPro}/package.json +0 -0
  46. /package/{build/RichTreeViewPro → RichTreeViewPro}/richTreeViewProClasses.d.ts +0 -0
  47. /package/{build/RichTreeViewPro → RichTreeViewPro}/richTreeViewProClasses.js +0 -0
  48. /package/{build/index.d.ts → index.d.ts} +0 -0
  49. /package/{build/internals → internals}/index.d.ts +0 -0
  50. /package/{build/internals → internals}/index.js +0 -0
  51. /package/{build/internals → internals}/package.json +0 -0
  52. /package/{build/internals → internals}/plugins/useTreeViewItemsReordering/index.d.ts +0 -0
  53. /package/{build/internals → internals}/plugins/useTreeViewItemsReordering/index.js +0 -0
  54. /package/{build/internals → internals}/plugins/useTreeViewItemsReordering/useTreeViewItemsReordering.d.ts +0 -0
  55. /package/{build/internals → internals}/plugins/useTreeViewItemsReordering/useTreeViewItemsReordering.itemPlugin.d.ts +0 -0
  56. /package/{build/internals → internals}/plugins/useTreeViewItemsReordering/useTreeViewItemsReordering.itemPlugin.js +0 -0
  57. /package/{build/internals → internals}/plugins/useTreeViewItemsReordering/useTreeViewItemsReordering.js +0 -0
  58. /package/{build/internals → internals}/plugins/useTreeViewItemsReordering/useTreeViewItemsReordering.types.d.ts +0 -0
  59. /package/{build/internals → internals}/plugins/useTreeViewItemsReordering/useTreeViewItemsReordering.types.js +0 -0
  60. /package/{build/internals → internals}/plugins/useTreeViewItemsReordering/useTreeViewItemsReordering.utils.d.ts +0 -0
  61. /package/{build/internals → internals}/plugins/useTreeViewItemsReordering/useTreeViewItemsReordering.utils.js +0 -0
  62. /package/{build/internals → internals}/utils/releaseInfo.d.ts +0 -0
  63. /package/{build/internals → internals}/zero-styled/index.d.ts +0 -0
  64. /package/{build/internals → internals}/zero-styled/index.js +0 -0
  65. /package/{build/modern → modern}/RichTreeViewPro/RichTreeViewPro.js +0 -0
  66. /package/{build/modern → modern}/RichTreeViewPro/RichTreeViewPro.plugins.js +0 -0
  67. /package/{build/modern → modern}/RichTreeViewPro/RichTreeViewPro.types.js +0 -0
  68. /package/{build/modern → modern}/RichTreeViewPro/index.js +0 -0
  69. /package/{build/modern → modern}/RichTreeViewPro/richTreeViewProClasses.js +0 -0
  70. /package/{build/modern → modern}/internals/index.js +0 -0
  71. /package/{build/modern → modern}/internals/plugins/useTreeViewItemsReordering/index.js +0 -0
  72. /package/{build/modern → modern}/internals/plugins/useTreeViewItemsReordering/useTreeViewItemsReordering.itemPlugin.js +0 -0
  73. /package/{build/modern → modern}/internals/plugins/useTreeViewItemsReordering/useTreeViewItemsReordering.js +0 -0
  74. /package/{build/modern → modern}/internals/plugins/useTreeViewItemsReordering/useTreeViewItemsReordering.types.js +0 -0
  75. /package/{build/modern → modern}/internals/plugins/useTreeViewItemsReordering/useTreeViewItemsReordering.utils.js +0 -0
  76. /package/{build/modern → modern}/internals/zero-styled/index.js +0 -0
  77. /package/{build/modern → modern}/themeAugmentation/index.js +0 -0
  78. /package/{build/node → node}/RichTreeViewPro/RichTreeViewPro.js +0 -0
  79. /package/{build/node → node}/RichTreeViewPro/RichTreeViewPro.plugins.js +0 -0
  80. /package/{build/node → node}/RichTreeViewPro/RichTreeViewPro.types.js +0 -0
  81. /package/{build/node → node}/RichTreeViewPro/index.js +0 -0
  82. /package/{build/node → node}/RichTreeViewPro/richTreeViewProClasses.js +0 -0
  83. /package/{build/node → node}/internals/index.js +0 -0
  84. /package/{build/node → node}/internals/plugins/useTreeViewItemsReordering/index.js +0 -0
  85. /package/{build/node → node}/internals/plugins/useTreeViewItemsReordering/useTreeViewItemsReordering.itemPlugin.js +0 -0
  86. /package/{build/node → node}/internals/plugins/useTreeViewItemsReordering/useTreeViewItemsReordering.js +0 -0
  87. /package/{build/node → node}/internals/plugins/useTreeViewItemsReordering/useTreeViewItemsReordering.types.js +0 -0
  88. /package/{build/node → node}/internals/plugins/useTreeViewItemsReordering/useTreeViewItemsReordering.utils.js +0 -0
  89. /package/{build/node → node}/internals/zero-styled/index.js +0 -0
  90. /package/{build/node → node}/themeAugmentation/index.js +0 -0
  91. /package/{build/themeAugmentation → themeAugmentation}/components.d.ts +0 -0
  92. /package/{build/themeAugmentation → themeAugmentation}/index.d.ts +0 -0
  93. /package/{build/themeAugmentation → themeAugmentation}/index.js +0 -0
  94. /package/{build/themeAugmentation → themeAugmentation}/overrides.d.ts +0 -0
  95. /package/{build/themeAugmentation → themeAugmentation}/package.json +0 -0
  96. /package/{build/themeAugmentation → themeAugmentation}/props.d.ts +0 -0
@@ -1,370 +0,0 @@
1
- import { describeTreeView } from 'test/utils/tree-view/describeTreeView';
2
- import { expect } from 'chai';
3
- import { spy } from 'sinon';
4
- import { fireEvent, createEvent } from '@mui/internal-test-utils';
5
- import { UseTreeViewItemsReorderingSignature } from '@mui/x-tree-view-pro/internals';
6
- import { DragEventTypes, MockedDataTransfer } from 'test/utils/dragAndDrop';
7
- import {
8
- UseTreeViewExpansionSignature,
9
- UseTreeViewItemsSignature,
10
- } from '@mui/x-tree-view/internals';
11
- import { chooseActionToApply } from './useTreeViewItemsReordering.utils';
12
- import { TreeViewItemItemReorderingValidActions } from './useTreeViewItemsReordering.types';
13
-
14
- interface DragEventOptions {
15
- /**
16
- * Coordinates of the mouse pointer relative to the target element.
17
- * @default: { x: targetWidth / 2, y: targetHeight / 2 }
18
- */
19
- coordinates?: { x: number; y: number };
20
- }
21
-
22
- const buildTreeViewDragInteractions = (dataTransfer: DataTransfer) => {
23
- const createFireEvent =
24
- (type: DragEventTypes) =>
25
- (target: HTMLElement, options: DragEventOptions = {}) => {
26
- const rect = target.getBoundingClientRect();
27
- const coordinates = options.coordinates ?? { x: rect.width / 2, y: rect.height / 2 };
28
- const createdEvent = createEvent[type](target, {
29
- clientX: rect.left + coordinates.x,
30
- clientY: rect.top + coordinates.y,
31
- });
32
- Object.defineProperty(createdEvent, 'dataTransfer', {
33
- value: dataTransfer,
34
- });
35
-
36
- return fireEvent(target, createdEvent);
37
- };
38
-
39
- const dragStart = createFireEvent('dragStart');
40
- const dragEnter = createFireEvent('dragEnter');
41
- const dragOver = createFireEvent('dragOver');
42
- const dragEnd = createFireEvent('dragEnd');
43
-
44
- return {
45
- fullDragSequence: (
46
- draggedItem: HTMLElement,
47
- targetItem: HTMLElement,
48
- options: DragEventOptions = {},
49
- ) => {
50
- dragStart(draggedItem);
51
- dragEnter(targetItem);
52
- dragOver(targetItem, { coordinates: options.coordinates });
53
- dragEnd(draggedItem);
54
- },
55
- };
56
- };
57
-
58
- describeTreeView<
59
- [UseTreeViewItemsReorderingSignature, UseTreeViewItemsSignature, UseTreeViewExpansionSignature]
60
- >('useTreeViewItemsReordering', ({ render, treeViewComponentName }) => {
61
- if (treeViewComponentName === 'SimpleTreeView' || treeViewComponentName === 'RichTreeView') {
62
- return;
63
- }
64
-
65
- let dragEvents: ReturnType<typeof buildTreeViewDragInteractions>;
66
- // eslint-disable-next-line mocha/no-top-level-hooks
67
- beforeEach(() => {
68
- const dataTransfer = new MockedDataTransfer();
69
- dragEvents = buildTreeViewDragInteractions(dataTransfer);
70
- });
71
-
72
- // eslint-disable-next-line mocha/no-top-level-hooks
73
- afterEach(() => {
74
- dragEvents = {} as typeof dragEvents;
75
- });
76
-
77
- describe('itemReordering prop', () => {
78
- it('should allow to drag and drop items when props.itemsReordering={true}', () => {
79
- const response = render({
80
- experimentalFeatures: { indentationAtItemLevel: true, itemsReordering: true },
81
- items: [{ id: '1' }, { id: '2' }, { id: '3' }],
82
- itemsReordering: true,
83
- });
84
-
85
- dragEvents.fullDragSequence(response.getItemRoot('1'), response.getItemContent('2'));
86
- expect(response.getItemIdTree()).to.deep.equal([
87
- { id: '2', children: [{ id: '1' }] },
88
- { id: '3' },
89
- ]);
90
- });
91
-
92
- it('should not allow to drag and drop items when props.itemsReordering={false}', () => {
93
- const response = render({
94
- experimentalFeatures: { indentationAtItemLevel: true, itemsReordering: true },
95
- items: [{ id: '1' }, { id: '2' }, { id: '3' }],
96
- itemsReordering: false,
97
- });
98
-
99
- dragEvents.fullDragSequence(response.getItemRoot('1'), response.getItemContent('2'));
100
- expect(response.getItemIdTree()).to.deep.equal([{ id: '1' }, { id: '2' }, { id: '3' }]);
101
- });
102
-
103
- it('should not allow to drag and drop items when props.itemsReordering is not defined', () => {
104
- const response = render({
105
- experimentalFeatures: { indentationAtItemLevel: true },
106
- items: [{ id: '1' }, { id: '2' }, { id: '3' }],
107
- });
108
-
109
- dragEvents.fullDragSequence(response.getItemRoot('1'), response.getItemContent('2'));
110
- expect(response.getItemIdTree()).to.deep.equal([{ id: '1' }, { id: '2' }, { id: '3' }]);
111
- });
112
-
113
- it('should allow to expand the new parent of the dragged item when it was not expandable before', () => {
114
- const response = render({
115
- experimentalFeatures: { indentationAtItemLevel: true, itemsReordering: true },
116
- items: [{ id: '1', children: [{ id: '1.1' }] }, { id: '2' }],
117
- itemsReordering: true,
118
- defaultExpandedItems: ['1'],
119
- });
120
-
121
- dragEvents.fullDragSequence(response.getItemRoot('1.1'), response.getItemContent('2'));
122
-
123
- fireEvent.focus(response.getItemRoot('2'));
124
- fireEvent.keyDown(response.getItemRoot('2'), { key: 'Enter' });
125
-
126
- expect(response.getItemIdTree()).to.deep.equal([
127
- { id: '1', children: [] },
128
- { id: '2', children: [{ id: '1.1' }] },
129
- ]);
130
- });
131
- });
132
-
133
- describe('onItemPositionChange prop', () => {
134
- it('should call onItemPositionChange when an item is moved', () => {
135
- const onItemPositionChange = spy();
136
- const response = render({
137
- experimentalFeatures: { indentationAtItemLevel: true, itemsReordering: true },
138
- items: [{ id: '1' }, { id: '2' }, { id: '3' }],
139
- itemsReordering: true,
140
- onItemPositionChange,
141
- });
142
-
143
- dragEvents.fullDragSequence(response.getItemRoot('1'), response.getItemContent('2'));
144
- expect(onItemPositionChange.callCount).to.equal(1);
145
- expect(onItemPositionChange.lastCall.firstArg).to.deep.equal({
146
- itemId: '1',
147
- oldPosition: { parentId: null, index: 0 },
148
- newPosition: { parentId: '2', index: 0 },
149
- });
150
- });
151
- });
152
-
153
- describe('isItemReorderable prop', () => {
154
- it('should not allow to drag an item when isItemReorderable returns false', () => {
155
- const response = render({
156
- experimentalFeatures: { indentationAtItemLevel: true, itemsReordering: true },
157
- items: [{ id: '1' }, { id: '2' }, { id: '3' }],
158
- itemsReordering: true,
159
- canMoveItemToNewPosition: () => false,
160
- });
161
-
162
- dragEvents.fullDragSequence(response.getItemRoot('1'), response.getItemContent('2'));
163
- expect(response.getItemIdTree()).to.deep.equal([{ id: '1' }, { id: '2' }, { id: '3' }]);
164
- });
165
-
166
- it('should allow to drag an item when isItemReorderable returns true', () => {
167
- const response = render({
168
- experimentalFeatures: { indentationAtItemLevel: true, itemsReordering: true },
169
- items: [{ id: '1' }, { id: '2' }, { id: '3' }],
170
- itemsReordering: true,
171
- canMoveItemToNewPosition: () => true,
172
- });
173
-
174
- dragEvents.fullDragSequence(response.getItemRoot('1'), response.getItemContent('2'));
175
- expect(response.getItemIdTree()).to.deep.equal([
176
- { id: '2', children: [{ id: '1' }] },
177
- { id: '3' },
178
- ]);
179
- });
180
- });
181
-
182
- describe('canMoveItemToNewPosition prop', () => {
183
- it('should not allow to drop an item when canMoveItemToNewPosition returns false', () => {
184
- const response = render({
185
- experimentalFeatures: { indentationAtItemLevel: true, itemsReordering: true },
186
- items: [{ id: '1' }, { id: '2' }, { id: '3' }],
187
- itemsReordering: true,
188
- canMoveItemToNewPosition: () => false,
189
- });
190
-
191
- dragEvents.fullDragSequence(response.getItemRoot('1'), response.getItemContent('2'));
192
- expect(response.getItemIdTree()).to.deep.equal([{ id: '1' }, { id: '2' }, { id: '3' }]);
193
- });
194
-
195
- it('should allow to drop an item when canMoveItemToNewPosition returns true', () => {
196
- const response = render({
197
- experimentalFeatures: { indentationAtItemLevel: true, itemsReordering: true },
198
- items: [{ id: '1' }, { id: '2' }, { id: '3' }],
199
- itemsReordering: true,
200
- canMoveItemToNewPosition: () => true,
201
- });
202
-
203
- dragEvents.fullDragSequence(response.getItemRoot('1'), response.getItemContent('2'));
204
- expect(response.getItemIdTree()).to.deep.equal([
205
- { id: '2', children: [{ id: '1' }] },
206
- { id: '3' },
207
- ]);
208
- });
209
- });
210
- });
211
-
212
- describe('getNewPosition util', () => {
213
- // The actions use the following tree when dropping "1.1" on "1.2":
214
- // - 1
215
- // - 1.1
216
- // - 1.2
217
- // - 1.3
218
- // - 2
219
- const ALL_ACTIONS: TreeViewItemItemReorderingValidActions = {
220
- 'reorder-above': { parentId: '1', index: 0 },
221
- 'reorder-below': { parentId: '1', index: 1 },
222
- 'make-child': { parentId: '1.2', index: 0 },
223
- 'move-to-parent': { parentId: null, index: 2 },
224
- };
225
-
226
- const FAKE_CONTENT_ELEMENT = {} as HTMLDivElement;
227
-
228
- const COMMON_PROPERTIES = {
229
- itemChildrenIndentation: 12,
230
- validActions: ALL_ACTIONS,
231
- targetHeight: 100,
232
- targetDepth: 1,
233
- cursorY: 50,
234
- cursorX: 100,
235
- contentElement: FAKE_CONTENT_ELEMENT,
236
- };
237
-
238
- it('should choose the "reorder-above" action when the cursor is in the top quarter of the target item', () => {
239
- expect(
240
- chooseActionToApply({
241
- ...COMMON_PROPERTIES,
242
- cursorY: 1,
243
- }),
244
- ).to.equal('reorder-above');
245
-
246
- expect(
247
- chooseActionToApply({
248
- ...COMMON_PROPERTIES,
249
- cursorY: 24,
250
- }),
251
- ).to.equal('reorder-above');
252
- });
253
-
254
- it('should choose the "reorder-above" action when the cursor is in the top half of the target item and the "make-child" action is not valid', () => {
255
- expect(
256
- chooseActionToApply({
257
- ...COMMON_PROPERTIES,
258
- cursorY: 25,
259
- validActions: { ...ALL_ACTIONS, 'make-child': undefined },
260
- }),
261
- ).to.equal('reorder-above');
262
-
263
- expect(
264
- chooseActionToApply({
265
- ...COMMON_PROPERTIES,
266
- cursorY: 49,
267
- validActions: { ...ALL_ACTIONS, 'make-child': undefined },
268
- }),
269
- ).to.equal('reorder-above');
270
- });
271
-
272
- it('should choose the "reorder-below" action when the cursor is in the bottom quarter of the target item', () => {
273
- expect(
274
- chooseActionToApply({
275
- ...COMMON_PROPERTIES,
276
- cursorY: 99,
277
- }),
278
- ).to.equal('reorder-below');
279
-
280
- expect(
281
- chooseActionToApply({
282
- ...COMMON_PROPERTIES,
283
- cursorY: 76,
284
- }),
285
- ).to.equal('reorder-below');
286
- });
287
-
288
- it('should choose the "reorder-below" action when the cursor is in the bottom half of the target item and the "make-child" action is not valid', () => {
289
- expect(
290
- chooseActionToApply({
291
- ...COMMON_PROPERTIES,
292
- cursorY: 75,
293
- validActions: { ...ALL_ACTIONS, 'make-child': undefined },
294
- }),
295
- ).to.equal('reorder-below');
296
-
297
- expect(
298
- chooseActionToApply({
299
- ...COMMON_PROPERTIES,
300
- cursorY: 51,
301
- validActions: { ...ALL_ACTIONS, 'make-child': undefined },
302
- }),
303
- ).to.equal('reorder-below');
304
-
305
- expect(
306
- chooseActionToApply({
307
- ...COMMON_PROPERTIES,
308
- cursorY: 50,
309
- validActions: { ...ALL_ACTIONS, 'make-child': undefined },
310
- }),
311
- ).to.equal('reorder-below');
312
- });
313
-
314
- it('should choose the "make-child" action when the cursor is in the middle of the target item', () => {
315
- expect(
316
- chooseActionToApply({
317
- ...COMMON_PROPERTIES,
318
- cursorY: 25,
319
- }),
320
- ).to.equal('make-child');
321
-
322
- expect(
323
- chooseActionToApply({
324
- ...COMMON_PROPERTIES,
325
- cursorY: 50,
326
- }),
327
- ).to.equal('make-child');
328
-
329
- expect(
330
- chooseActionToApply({
331
- ...COMMON_PROPERTIES,
332
- cursorY: 74,
333
- }),
334
- ).to.equal('make-child');
335
- });
336
-
337
- it('should choose the "move-to-parent" action when the cursor is inside the depth-offset of the target item', () => {
338
- expect(
339
- chooseActionToApply({
340
- ...COMMON_PROPERTIES,
341
- cursorX: 1,
342
- cursorY: 1,
343
- }),
344
- ).to.equal('move-to-parent');
345
-
346
- expect(
347
- chooseActionToApply({
348
- ...COMMON_PROPERTIES,
349
- cursorX: 11,
350
- cursorY: 1,
351
- }),
352
- ).to.equal('move-to-parent');
353
-
354
- expect(
355
- chooseActionToApply({
356
- ...COMMON_PROPERTIES,
357
- cursorX: 1,
358
- cursorY: 50,
359
- }),
360
- ).to.equal('move-to-parent');
361
-
362
- expect(
363
- chooseActionToApply({
364
- ...COMMON_PROPERTIES,
365
- cursorX: 1,
366
- cursorY: 99,
367
- }),
368
- ).to.equal('move-to-parent');
369
- });
370
- });
@@ -1,278 +0,0 @@
1
- import * as React from 'react';
2
- import { warnOnce, TreeViewPlugin } from '@mui/x-tree-view/internals';
3
- import { TreeViewItemsReorderingAction } from '@mui/x-tree-view/models';
4
- import {
5
- TreeViewItemItemReorderingValidActions,
6
- TreeViewItemReorderPosition,
7
- UseTreeViewItemsReorderingInstance,
8
- UseTreeViewItemsReorderingSignature,
9
- } from './useTreeViewItemsReordering.types';
10
- import {
11
- chooseActionToApply,
12
- isAncestor,
13
- moveItemInTree,
14
- } from './useTreeViewItemsReordering.utils';
15
- import { useTreeViewItemsReorderingItemPlugin } from './useTreeViewItemsReordering.itemPlugin';
16
-
17
- export const useTreeViewItemsReordering: TreeViewPlugin<UseTreeViewItemsReorderingSignature> = ({
18
- params,
19
- instance,
20
- state,
21
- setState,
22
- experimentalFeatures,
23
- }) => {
24
- const isItemsReorderingEnabled =
25
- params.itemsReordering && !!experimentalFeatures?.itemsReordering;
26
-
27
- if (process.env.NODE_ENV !== 'production') {
28
- if (
29
- params.itemsReordering &&
30
- (!experimentalFeatures?.indentationAtItemLevel || !experimentalFeatures?.itemsReordering)
31
- ) {
32
- warnOnce([
33
- 'MUI X: The items reordering feature requires the `indentationAtItemLevel` and `itemsReordering` experimental features to be enabled.',
34
- 'You can do it by passing `experimentalFeatures={{ indentationAtItemLevel: true, itemsReordering: true }}` to the `RichTreeViewPro` component.',
35
- 'Check the documentation for more details: https://mui.com/x/react-tree-view/rich-tree-view/items/',
36
- ]);
37
- }
38
- }
39
-
40
- const canItemBeDragged = React.useCallback(
41
- (itemId: string) => {
42
- if (!isItemsReorderingEnabled) {
43
- return false;
44
- }
45
-
46
- const isItemReorderable = params.isItemReorderable;
47
- if (isItemReorderable) {
48
- return isItemReorderable(itemId);
49
- }
50
-
51
- return true;
52
- },
53
- [isItemsReorderingEnabled, params.isItemReorderable],
54
- );
55
-
56
- const getDroppingTargetValidActions = React.useCallback(
57
- (itemId: string) => {
58
- if (!state.itemsReordering) {
59
- throw new Error('There is no ongoing reordering.');
60
- }
61
-
62
- if (itemId === state.itemsReordering.draggedItemId) {
63
- return {};
64
- }
65
-
66
- const canMoveItemToNewPosition = params.canMoveItemToNewPosition;
67
- const targetItemMeta = instance.getItemMeta(itemId);
68
- const targetItemIndex = instance.getItemIndex(targetItemMeta.id);
69
- const draggedItemMeta = instance.getItemMeta(state.itemsReordering.draggedItemId);
70
- const draggedItemIndex = instance.getItemIndex(draggedItemMeta.id);
71
-
72
- const oldPosition: TreeViewItemReorderPosition = {
73
- parentId: draggedItemMeta.parentId,
74
- index: draggedItemIndex,
75
- };
76
-
77
- const checkIfPositionIsValid = (positionAfterAction: TreeViewItemReorderPosition) => {
78
- let isValid: boolean;
79
- // If the new position is equal to the old one, we don't want to show any dropping UI.
80
- if (
81
- positionAfterAction.parentId === oldPosition.parentId &&
82
- positionAfterAction.index === oldPosition.index
83
- ) {
84
- isValid = false;
85
- } else if (canMoveItemToNewPosition) {
86
- isValid = canMoveItemToNewPosition({
87
- itemId,
88
- oldPosition,
89
- newPosition: positionAfterAction,
90
- });
91
- } else {
92
- isValid = true;
93
- }
94
-
95
- return isValid;
96
- };
97
-
98
- const positionsAfterAction: Record<
99
- TreeViewItemsReorderingAction,
100
- TreeViewItemReorderPosition | null
101
- > = {
102
- 'make-child': { parentId: targetItemMeta.id, index: 0 },
103
- 'reorder-above': {
104
- parentId: targetItemMeta.parentId,
105
- index:
106
- targetItemMeta.parentId === draggedItemMeta.parentId &&
107
- targetItemIndex > draggedItemIndex
108
- ? targetItemIndex - 1
109
- : targetItemIndex,
110
- },
111
- 'reorder-below': targetItemMeta.expandable
112
- ? null
113
- : {
114
- parentId: targetItemMeta.parentId,
115
- index:
116
- targetItemMeta.parentId === draggedItemMeta.parentId &&
117
- targetItemIndex > draggedItemIndex
118
- ? targetItemIndex
119
- : targetItemIndex + 1,
120
- },
121
- 'move-to-parent':
122
- targetItemMeta.parentId == null
123
- ? null
124
- : {
125
- parentId: targetItemMeta.parentId,
126
- index: instance.getItemOrderedChildrenIds(targetItemMeta.parentId).length,
127
- },
128
- };
129
-
130
- const validActions: TreeViewItemItemReorderingValidActions = {};
131
- Object.keys(positionsAfterAction).forEach((action) => {
132
- const positionAfterAction = positionsAfterAction[action as TreeViewItemsReorderingAction];
133
- if (positionAfterAction != null && checkIfPositionIsValid(positionAfterAction)) {
134
- validActions[action as TreeViewItemsReorderingAction] = positionAfterAction;
135
- }
136
- });
137
-
138
- return validActions;
139
- },
140
- [instance, state.itemsReordering, params.canMoveItemToNewPosition],
141
- );
142
-
143
- const startDraggingItem = React.useCallback(
144
- (itemId: string) => {
145
- setState((prevState) => ({
146
- ...prevState,
147
- itemsReordering: {
148
- targetItemId: itemId,
149
- draggedItemId: itemId,
150
- action: null,
151
- newPosition: null,
152
- },
153
- }));
154
- },
155
- [setState],
156
- );
157
-
158
- const stopDraggingItem = React.useCallback(
159
- (itemId: string) => {
160
- if (state.itemsReordering == null || state.itemsReordering.draggedItemId !== itemId) {
161
- return;
162
- }
163
-
164
- if (
165
- state.itemsReordering.draggedItemId === state.itemsReordering.targetItemId ||
166
- state.itemsReordering.action == null ||
167
- state.itemsReordering.newPosition == null
168
- ) {
169
- setState((prevState) => ({ ...prevState, itemsReordering: null }));
170
- return;
171
- }
172
-
173
- const draggedItemMeta = instance.getItemMeta(state.itemsReordering.draggedItemId);
174
-
175
- const oldPosition: TreeViewItemReorderPosition = {
176
- parentId: draggedItemMeta.parentId,
177
- index: instance.getItemIndex(draggedItemMeta.id),
178
- };
179
-
180
- const newPosition = state.itemsReordering.newPosition;
181
-
182
- setState((prevState) => ({
183
- ...prevState,
184
- itemsReordering: null,
185
- items: moveItemInTree({
186
- itemToMoveId: itemId,
187
- newPosition,
188
- oldPosition,
189
- prevState: prevState.items,
190
- }),
191
- }));
192
-
193
- const onItemPositionChange = params.onItemPositionChange;
194
- onItemPositionChange?.({
195
- itemId,
196
- newPosition,
197
- oldPosition,
198
- });
199
- },
200
- [setState, state.itemsReordering, instance, params.onItemPositionChange],
201
- );
202
-
203
- const setDragTargetItem = React.useCallback<
204
- UseTreeViewItemsReorderingInstance['setDragTargetItem']
205
- >(
206
- ({ itemId, validActions, targetHeight, cursorY, cursorX, contentElement }) => {
207
- setState((prevState) => {
208
- const prevSubState = prevState.itemsReordering;
209
- if (prevSubState == null || isAncestor(instance, itemId, prevSubState.draggedItemId)) {
210
- return prevState;
211
- }
212
- const action = chooseActionToApply({
213
- itemChildrenIndentation: params.itemChildrenIndentation,
214
- validActions,
215
- targetHeight,
216
- targetDepth: prevState.items.itemMetaMap[itemId].depth!,
217
- cursorY,
218
- cursorX,
219
- contentElement,
220
- });
221
-
222
- const newPosition = action == null ? null : validActions[action]!;
223
-
224
- if (
225
- prevSubState.targetItemId === itemId &&
226
- prevSubState.action === action &&
227
- prevSubState.newPosition?.parentId === newPosition?.parentId &&
228
- prevSubState.newPosition?.index === newPosition?.index
229
- ) {
230
- return prevState;
231
- }
232
-
233
- return {
234
- ...prevState,
235
- itemsReordering: {
236
- ...prevSubState,
237
- targetItemId: itemId,
238
- newPosition,
239
- action,
240
- },
241
- };
242
- });
243
- },
244
- [instance, setState, params.itemChildrenIndentation],
245
- );
246
-
247
- return {
248
- instance: {
249
- canItemBeDragged,
250
- getDroppingTargetValidActions,
251
- startDraggingItem,
252
- stopDraggingItem,
253
- setDragTargetItem,
254
- },
255
- contextValue: {
256
- itemsReordering: {
257
- enabled: isItemsReorderingEnabled,
258
- currentDrag: state.itemsReordering,
259
- },
260
- },
261
- };
262
- };
263
-
264
- useTreeViewItemsReordering.itemPlugin = useTreeViewItemsReorderingItemPlugin;
265
-
266
- useTreeViewItemsReordering.getDefaultizedParams = (params) => ({
267
- ...params,
268
- itemsReordering: params.itemsReordering ?? false,
269
- });
270
-
271
- useTreeViewItemsReordering.getInitialState = () => ({ itemsReordering: null });
272
-
273
- useTreeViewItemsReordering.params = {
274
- itemsReordering: true,
275
- isItemReorderable: true,
276
- canMoveItemToNewPosition: true,
277
- onItemPositionChange: true,
278
- };