@difizen/libro-core 0.3.2 → 0.3.4

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 (37) hide show
  1. package/es/components/dnd-component/default-dnd-content.d.ts.map +1 -1
  2. package/es/components/dnd-component/default-dnd-content.js +88 -165
  3. package/es/components/dnd-component/dnd-list.d.ts +12 -0
  4. package/es/components/dnd-component/dnd-list.d.ts.map +1 -1
  5. package/es/components/dnd-component/dnd-list.js +306 -62
  6. package/es/components/dnd-component/index.d.ts +0 -2
  7. package/es/components/dnd-component/index.d.ts.map +1 -1
  8. package/es/components/dnd-component/index.js +0 -2
  9. package/es/components/dnd-component/index.less +84 -0
  10. package/es/components/dnd-component/virtualized-manager.d.ts.map +1 -1
  11. package/es/components/dnd-component/virtualized-manager.js +2 -8
  12. package/es/formatter/libro-formatter-json-contribution.d.ts +1 -1
  13. package/es/formatter/libro-formatter-string-contribution.d.ts +1 -1
  14. package/es/index.less +0 -22
  15. package/es/libro-model.js +1 -1
  16. package/es/libro-view.d.ts.map +1 -1
  17. package/es/libro-view.js +122 -135
  18. package/es/virtualized-manager.d.ts.map +1 -1
  19. package/es/virtualized-manager.js +1 -8
  20. package/package.json +10 -6
  21. package/src/components/dnd-component/default-dnd-content.tsx +99 -163
  22. package/src/components/dnd-component/dnd-list.tsx +303 -34
  23. package/src/components/dnd-component/index.less +84 -0
  24. package/src/components/dnd-component/index.tsx +0 -2
  25. package/src/components/dnd-component/virtualized-manager.ts +10 -7
  26. package/src/index.less +0 -22
  27. package/src/libro-model.ts +1 -1
  28. package/src/libro-view.tsx +22 -29
  29. package/src/virtualized-manager.ts +9 -7
  30. package/es/components/dnd-component/custom-drag-layer.d.ts +0 -9
  31. package/es/components/dnd-component/custom-drag-layer.d.ts.map +0 -1
  32. package/es/components/dnd-component/custom-drag-layer.js +0 -140
  33. package/es/components/dnd-component/dnd-context.d.ts +0 -3
  34. package/es/components/dnd-component/dnd-context.d.ts.map +0 -1
  35. package/es/components/dnd-component/dnd-context.js +0 -20
  36. package/src/components/dnd-component/custom-drag-layer.tsx +0 -144
  37. package/src/components/dnd-component/dnd-context.tsx +0 -28
@@ -2,30 +2,26 @@
2
2
  import { getOrigin, useInject, ViewInstance } from '@difizen/mana-app';
3
3
  import { useConfigurationValue } from '@difizen/mana-app';
4
4
  import { Button } from 'antd';
5
- import type { Identifier } from 'dnd-core';
6
5
  import React, {
7
6
  useCallback,
8
- useEffect,
9
7
  useLayoutEffect,
10
8
  useMemo,
11
9
  useRef,
12
10
  useState,
13
11
  forwardRef,
12
+ useContext,
14
13
  } from 'react';
15
- import { useDrag, useDragDropManager, useDrop } from 'react-dnd';
16
- import { getEmptyImage } from 'react-dnd-html5-backend';
17
14
  import 'resize-observer-polyfill';
18
15
 
19
- import type { CellService } from '../../cell/index.js';
20
- import { LibroCellService } from '../../cell/index.js';
21
16
  import { CellCollapsible } from '../../collapse-service.js';
22
- import { DragAreaKey, isCellView } from '../../libro-protocol.js';
23
17
  import type { CellView, DndContentProps } from '../../libro-protocol.js';
24
18
  import { MultiSelectionWhenShiftClick } from '../../libro-setting.js';
25
19
  import type { LibroView } from '../../libro-view.js';
26
20
  import { HolderOutlined, PlusOutlined } from '../../material-from-designer.js';
27
21
  import { BetweenCellProvider } from '../cell-protocol.js';
28
22
 
23
+ import { DragContext } from './dnd-list.js';
24
+
29
25
  export interface Dragparams {
30
26
  cell: CellView;
31
27
  index: number;
@@ -42,11 +38,21 @@ export const DndCellContainer: React.FC<DndContentProps> = ({
42
38
  MultiSelectionWhenShiftClick,
43
39
  );
44
40
  const BetweenCellContent = useInject<BetweenCellProvider>(BetweenCellProvider);
45
- const cellService = useInject<CellService>(LibroCellService);
46
- const dragDropManager = useDragDropManager();
47
- const dragDropMonitor = dragDropManager.getMonitor();
41
+ const [isMouseOverDragArea, setIsMouseOverDragArea] = useState(false);
42
+ const [isDragDown, setIsDragDown] = useState(false);
48
43
  const ItemRender = getOrigin(instance.dndItemRender);
49
44
 
45
+ const {
46
+ dragOverIndex,
47
+ isDraging,
48
+ sourceIndex,
49
+ onDragStart,
50
+ onDragOver,
51
+ onDrop,
52
+ onDragEnd,
53
+ fragFromRef,
54
+ } = useContext(DragContext);
55
+
50
56
  useLayoutEffect(() => {
51
57
  if (typeof ref !== 'object') {
52
58
  return () => {
@@ -119,174 +125,102 @@ export const DndCellContainer: React.FC<DndContentProps> = ({
119
125
  return;
120
126
  }
121
127
  instance.model.selectCell(cell);
122
- instance.model.selections = [];
128
+ if (instance.model.selections.length !== 0) {
129
+ instance.model.selections = [];
130
+ }
123
131
  }, [instance, cell]);
124
132
 
125
- const scrollTimer = useRef<null | NodeJS.Timeout>(null);
126
- const unsubscribe = useRef<null | any>(null);
133
+ const isMultiSelected =
134
+ instance.model.selections.length !== 0 && instance.isSelected(cell);
135
+
136
+ const isDragOver = useMemo(() => {
137
+ return index === dragOverIndex;
138
+ }, [index, dragOverIndex]);
127
139
 
128
- const [{ isDrag }, drag, preview] = useDrag(
129
- {
130
- type: DragAreaKey,
131
- item: { cell, index },
132
- collect: (monitor) => ({
133
- isDrag: monitor.isDragging(),
134
- }),
135
- end() {
136
- instance.isDragging = false;
137
- if (scrollTimer.current) {
138
- clearInterval(scrollTimer.current);
139
- }
140
- },
140
+ const handleDragStart = useCallback(
141
+ (e: React.DragEvent) => {
142
+ if (!instance.model.cellsEditable) {
143
+ e.preventDefault();
144
+ return;
145
+ }
146
+ onDragStart?.(e, index);
141
147
  },
142
- [cell, index],
148
+ [index, instance.model.cellsEditable, onDragStart],
143
149
  );
144
150
 
145
- const libroViewContent = instance.container?.current?.getElementsByClassName(
146
- 'libro-view-content',
147
- )[0] as HTMLElement;
151
+ const handleDragOver = useCallback(
152
+ (e: React.DragEvent) => {
153
+ //判断拖拽来源是否cell
154
+ if (fragFromRef.current !== 'cell') {
155
+ return;
156
+ }
157
+ e.preventDefault();
158
+ instance.model.mouseMode = 'drag';
159
+ //判断是向下拖拽还是向上拖拽
160
+ if (sourceIndex! < index) {
161
+ setIsDragDown(true);
162
+ } else {
163
+ setIsDragDown(false);
164
+ }
165
+ onDragOver(e, index);
166
+ },
167
+ [fragFromRef, index, instance.model, onDragOver, sourceIndex],
168
+ );
148
169
 
149
- useEffect(() => {
150
- unsubscribe.current = dragDropMonitor.subscribeToStateChange(() => {
151
- instance.isDragging = dragDropMonitor.isDragging();
152
- scrollTimer.current = setInterval(() => {
153
- const currentOffset = dragDropMonitor.getClientOffset();
154
- if (libroViewContent && instance.isDragging && currentOffset) {
155
- const libroViewClientRect = libroViewContent.getBoundingClientRect();
156
- const { top, bottom } = libroViewClientRect;
157
- const { y } = currentOffset;
158
- const topLimit = top + 30;
159
- const bottomLimit = bottom - 50;
160
- if (y < topLimit) {
161
- libroViewContent.scrollTop -= 0.5;
162
- } else if (y > bottomLimit) {
163
- libroViewContent.scrollTop += 0.5;
164
- }
165
- }
166
- }, 10);
167
- return () => {
168
- if (scrollTimer.current) {
169
- clearInterval(scrollTimer.current);
170
- }
171
- if (unsubscribe.current) {
172
- unsubscribe.current();
173
- }
174
- };
175
- });
176
- }, [dragDropMonitor]);
170
+ const handleDrop = useCallback(
171
+ (e: React.DragEvent) => {
172
+ e.preventDefault();
173
+ if (fragFromRef.current !== 'cell') {
174
+ return;
175
+ }
176
+ onDrop(e, index);
177
+ },
178
+ [fragFromRef, index, onDrop],
179
+ );
177
180
 
178
- useEffect(() => {
179
- // This gets called after every render, by default
180
- // (the first one, and every one after that)
181
+ const handleDragEnd = useCallback(
182
+ (e: React.DragEvent) => {
183
+ if (fragFromRef.current !== 'cell') {
184
+ return;
185
+ }
186
+ onDragEnd(e, index);
187
+ },
188
+ [fragFromRef, index, onDragEnd],
189
+ );
181
190
 
182
- // Use empty image as a drag preview so browsers don't draw it
183
- // and we can draw whatever we want on the custom drag layer instead.
184
- preview(getEmptyImage(), {
185
- // IE fallback: specify that we'd rather screenshot the node
186
- // when it already knows it's being dragged so we can hide it with CSS.
187
- captureDraggingState: true,
188
- });
189
- }, [preview]);
191
+ const opacity = useMemo(() => {
192
+ return {
193
+ opacity: isDraging && sourceIndex === index ? 0.4 : 1,
194
+ };
195
+ }, [index, isDraging, sourceIndex]);
190
196
 
191
- const [{ handlerId, isDragOver }, drop] = useDrop<
192
- Dragparams,
193
- void,
194
- {
195
- handlerId: Identifier | null;
196
- isDragOver: boolean;
197
- }
198
- >({
199
- accept: DragAreaKey,
200
- drop(item, monitor) {
201
- cellService
202
- .getOrCreateView(
203
- {
204
- ...item.cell.model.options,
205
- modelId: item.cell.model.id,
206
- singleSelectionDragPreview: true,
207
- },
208
- item.cell.parent.id,
209
- )
210
- .then((view) => {
211
- view.dispose();
212
- return;
213
- })
214
- .catch((e) => {
215
- //
216
- });
217
- if (isCellView(item.cell)) {
218
- const didDrop = monitor.didDrop();
219
- if (didDrop) {
220
- return;
221
- }
222
- const dragIndex = instance.findCellIndex(item.cell);
223
- const dropIndex = instance.findCellIndex(cell);
224
- if (instance.model.selections.length > 0) {
225
- const isDragInSelections =
226
- instance.model.selections.findIndex(
227
- (selection) => selection.id === item.cell.id,
228
- ) > -1
229
- ? true
230
- : false;
231
- const isDropInSelections =
232
- instance.model.selections.findIndex(
233
- (selection) => selection.id === cell.id,
234
- ) > -1
235
- ? true
236
- : false;
237
- if (isDragInSelections && isDropInSelections) {
238
- return;
239
- }
240
- if (isDragInSelections) {
241
- instance.model.exchangeCells(instance.model.selections, dropIndex);
242
- instance.model.scrollToView(cell);
197
+ const onMouseOver = useCallback(() => {
198
+ setIsMouseOverDragArea(true);
199
+ }, []);
243
200
 
244
- return;
245
- }
246
- }
247
- if (dragIndex < dropIndex) {
248
- instance.model.exchangeCell(dragIndex, dropIndex - 1);
249
- instance.model.scrollToView(cell);
250
- }
251
- if (dragIndex > dropIndex) {
252
- instance.model.exchangeCell(dragIndex, dropIndex);
253
- instance.model.scrollToView(cell);
254
- }
255
- }
256
- return;
257
- },
258
- collect(monitor) {
259
- return {
260
- isDragOver: monitor.isOver(),
261
- canDrop: monitor.canDrop(),
262
- handlerId: monitor.getHandlerId(),
263
- };
264
- },
265
- });
266
- const opacity = isDrag ? 0.4 : 1;
267
- if (instance.model.cellsEditable) {
268
- drop(ref);
269
- }
270
- if (isDrag) {
271
- instance.model.mouseMode = 'drag';
272
- }
201
+ const onMouseLeave = useCallback(() => {
202
+ setIsMouseOverDragArea(false);
203
+ }, []);
273
204
 
274
- const isMultiSelected =
275
- instance.model.selections.length !== 0 && instance.isSelected(cell);
276
205
  // let isMouseOver = false;
277
- const [isMouseOverDragArea, setIsMouseOverDragArea] = useState(false);
278
206
  const hasCellHidden = useMemo(() => {
279
207
  return cell.hasCellHidden();
280
208
  }, [cell]);
281
209
  const isCollapsible = CellCollapsible.is(cell);
282
210
 
211
+ const wrapperclassName = useMemo(() => {
212
+ return `libro-dnd-cell-container ${isMultiSelected ? 'multi-selected' : ''} ${
213
+ hasCellHidden ? 'hidden' : ''
214
+ }`;
215
+ }, [isMultiSelected]);
216
+
283
217
  return (
284
218
  <div
285
- className={`libro-dnd-cell-container ${isMultiSelected ? 'multi-selected' : ''} ${
286
- hasCellHidden ? 'hidden' : ''
287
- }`}
288
- data-handler-id={handlerId}
289
- style={{ opacity }}
219
+ className={wrapperclassName}
220
+ onDragOver={handleDragOver}
221
+ onDrop={handleDrop}
222
+ onDragEnd={handleDragEnd}
223
+ style={opacity}
290
224
  ref={ref}
291
225
  id={cell.id}
292
226
  >
@@ -294,15 +228,16 @@ export const DndCellContainer: React.FC<DndContentProps> = ({
294
228
  index={position || index}
295
229
  addCell={cell.parent.addCellAbove}
296
230
  />
297
- {isDragOver && <div className="libro-drag-hoverline" />}
231
+ {!isDragDown && isDragOver && <div className="libro-drag-hoverline" />}
298
232
  {isMouseOverDragArea && <HolderOutlined className="libro-handle-style" />}
299
233
  <div
300
234
  className="libro-drag-area"
301
- ref={drag}
235
+ onDragStart={handleDragStart}
236
+ draggable={instance.model.cellsEditable}
302
237
  onMouseDown={handleMouseDown}
303
238
  onMouseUp={handleMouseUp}
304
- onMouseOver={() => setIsMouseOverDragArea(true)}
305
- onMouseLeave={() => setIsMouseOverDragArea(false)}
239
+ onMouseOver={onMouseOver}
240
+ onMouseLeave={onMouseLeave}
306
241
  />
307
242
  <div
308
243
  tabIndex={-1}
@@ -312,7 +247,7 @@ export const DndCellContainer: React.FC<DndContentProps> = ({
312
247
  >
313
248
  <ItemRender
314
249
  isDragOver={!!isDragOver}
315
- isDrag={!!isDrag}
250
+ isDrag={!!isDraging}
316
251
  cell={cell}
317
252
  isMouseOverDragArea={isMouseOverDragArea}
318
253
  />
@@ -329,6 +264,7 @@ export const DndCellContainer: React.FC<DndContentProps> = ({
329
264
  </Button>
330
265
  </div>
331
266
  )}
267
+ {isDragDown && isDragOver && <div className="libro-drag-hoverline-last-one" />}
332
268
  </div>
333
269
  );
334
270
  };