@etsoo/materialui 1.6.10 → 1.6.12

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.
package/src/DnDList.tsx DELETED
@@ -1,528 +0,0 @@
1
- import type {
2
- DndContext,
3
- DragEndEvent,
4
- DragStartEvent,
5
- UniqueIdentifier
6
- } from "@dnd-kit/core";
7
- import { SortableContext } from "@dnd-kit/sortable/dist/components/SortableContext";
8
- import { useSortable } from "@dnd-kit/sortable/dist/hooks/useSortable";
9
- import { horizontalListSortingStrategy } from "@dnd-kit/sortable/dist/strategies/horizontalListSorting";
10
- import { rectSortingStrategy } from "@dnd-kit/sortable/dist/strategies/rectSorting";
11
- import { rectSwappingStrategy } from "@dnd-kit/sortable/dist/strategies/rectSwapping";
12
- import { verticalListSortingStrategy } from "@dnd-kit/sortable/dist/strategies/verticalListSorting";
13
- import { SortingStrategy } from "@dnd-kit/sortable/dist/types/strategies";
14
- import type { CSS } from "@dnd-kit/utilities";
15
- import { DataTypes } from "@etsoo/shared";
16
- import Skeleton from "@mui/material/Skeleton";
17
- import { Theme, useTheme } from "@mui/material/styles";
18
- import React, { CSSProperties } from "react";
19
-
20
- function SortableItem(props: {
21
- id: UniqueIdentifier;
22
- useSortableType: typeof useSortable;
23
- CSSType: typeof CSS;
24
- itemRenderer: (
25
- nodeRef: React.ComponentProps<any>,
26
- actionNodeRef: React.ComponentProps<any>
27
- ) => React.ReactElement;
28
- style?: React.CSSProperties;
29
- }) {
30
- // Destruct
31
- const { id, useSortableType, CSSType, itemRenderer, style = {} } = props;
32
-
33
- // Use sortable
34
- const {
35
- attributes,
36
- listeners,
37
- setNodeRef,
38
- transform,
39
- transition,
40
- setActivatorNodeRef
41
- } = useSortableType({ id });
42
-
43
- const allStyle = {
44
- ...style,
45
- transform: CSSType.Transform.toString(transform),
46
- transition
47
- };
48
-
49
- const nodeRef = {
50
- style: allStyle,
51
- ref: setNodeRef,
52
- ...attributes
53
- };
54
-
55
- const actionNodeRef = {
56
- ...listeners,
57
- ref: setActivatorNodeRef
58
- };
59
-
60
- return itemRenderer(nodeRef, actionNodeRef);
61
- }
62
-
63
- /**
64
- * DnD item default style
65
- * @param index Item index
66
- * @param isDragging Is dragging
67
- * @param theme Theme
68
- * @returns Style
69
- */
70
- export const DnDItemStyle = (
71
- index: number,
72
- isDragging: boolean,
73
- theme: Theme
74
- ) => ({
75
- padding: theme.spacing(1),
76
- zIndex: isDragging ? 1 : "auto",
77
- background: isDragging
78
- ? theme.palette.primary.light
79
- : index % 2 === 0
80
- ? theme.palette.grey[100]
81
- : theme.palette.grey[50]
82
- });
83
-
84
- /**
85
- * DnD list forward ref
86
- */
87
- export interface DnDListRef<D extends object> {
88
- /**
89
- * Add item
90
- * @param item New item
91
- */
92
- addItem(item: D): void;
93
-
94
- /**
95
- * Add items
96
- * @param items items
97
- */
98
- addItems(items: D[]): void;
99
-
100
- /**
101
- * Delete item
102
- * @param index Item index
103
- */
104
- deleteItem(index: number): void;
105
-
106
- /**
107
- * Edit item
108
- * @param newItem New item
109
- * @param index Index
110
- */
111
- editItem(newItem: D, index: number): boolean;
112
-
113
- /**
114
- * Get all items
115
- */
116
- getItems(): D[];
117
- }
118
-
119
- /**
120
- * DnD sortable list properties
121
- */
122
- export interface DnDListPros<
123
- D extends { id: UniqueIdentifier },
124
- E extends React.ElementType = React.ElementType
125
- > {
126
- /**
127
- * Component type to render the list into
128
- * Default is React.Fragment
129
- */
130
- component?: E;
131
-
132
- /**
133
- * Component props
134
- */
135
- componentProps?: React.ComponentProps<E>;
136
-
137
- /**
138
- * Get list item style callback
139
- */
140
- getItemStyle?: (index: number, isDragging: boolean) => CSSProperties;
141
-
142
- /**
143
- * Item renderer
144
- */
145
- itemRenderer: (
146
- item: D,
147
- index: number,
148
- nodeRef: React.ComponentProps<any>,
149
- actionNodeRef: React.ComponentProps<any>
150
- ) => React.ReactElement;
151
-
152
- /**
153
- * Height
154
- */
155
- height?: string | number;
156
-
157
- /**
158
- * List items
159
- */
160
- items: D[];
161
-
162
- /**
163
- * Label field
164
- */
165
- labelField: DataTypes.Keys<D>;
166
-
167
- /**
168
- * Methods ref
169
- */
170
- mRef?: React.Ref<DnDListRef<D>>;
171
-
172
- /**
173
- * Sorting strategy
174
- */
175
- sortingStrategy?:
176
- | "rect"
177
- | "vertical"
178
- | "horizontal"
179
- | "rectSwapping"
180
- | (() => SortingStrategy);
181
-
182
- /**
183
- * Data change handler
184
- */
185
- onChange?: (items: D[]) => void;
186
-
187
- /**
188
- * Form data change handler
189
- */
190
- onFormChange?: (items: D[]) => void;
191
-
192
- /**
193
- * Drag end handler
194
- */
195
- onDragEnd?: (items: D[]) => void;
196
- }
197
-
198
- /**
199
- * DnD (Drag and Drop) sortable list
200
- * @param props Props
201
- * @returns Component
202
- */
203
- export function DnDList<
204
- D extends { id: UniqueIdentifier },
205
- E extends React.ElementType = React.ElementType
206
- >(props: DnDListPros<D, E>) {
207
- // Destruct
208
- const {
209
- componentProps,
210
- height = 360,
211
- itemRenderer,
212
- labelField,
213
- mRef,
214
- sortingStrategy,
215
- onChange,
216
- onFormChange,
217
- onDragEnd
218
- } = props;
219
-
220
- const Component = props.component || React.Fragment;
221
-
222
- // Theme
223
- const theme = useTheme();
224
-
225
- // States
226
- const [items, setItems] = React.useState<D[]>([]);
227
- const [activeId, setActiveId] = React.useState<UniqueIdentifier>();
228
-
229
- React.useEffect(() => {
230
- setItems(props.items);
231
- }, [props.items]);
232
-
233
- const doFormChange = React.useCallback(
234
- (newItems?: D[] | Event) => {
235
- if (onFormChange) {
236
- const locals = Array.isArray(newItems) ? newItems : items;
237
- onFormChange(locals);
238
- }
239
- },
240
- [items, onFormChange]
241
- );
242
-
243
- const changeItems = React.useCallback(
244
- (newItems: D[]) => {
245
- // Possible to alter items with the handler
246
- if (onChange) onChange(newItems);
247
-
248
- doFormChange(newItems);
249
-
250
- // Update state
251
- setItems(newItems);
252
- },
253
- [onChange, doFormChange]
254
- );
255
-
256
- // Methods
257
- React.useImperativeHandle(
258
- mRef,
259
- () => {
260
- return {
261
- addItem(newItem: D) {
262
- // Existence check
263
- if (items.some((item) => item[labelField] === newItem[labelField])) {
264
- return false;
265
- }
266
-
267
- // Clone
268
- const newItems = [newItem, ...items];
269
-
270
- // Update the state
271
- changeItems(newItems);
272
-
273
- return true;
274
- },
275
-
276
- addItems(inputItems: D[]) {
277
- // Clone
278
- const newItems = [...items];
279
-
280
- // Insert items
281
- inputItems.forEach((newItem) => {
282
- // Existence check
283
- if (
284
- newItems.some((item) => item[labelField] === newItem[labelField])
285
- ) {
286
- return;
287
- }
288
-
289
- newItems.push(newItem);
290
- });
291
-
292
- // Update the state
293
- changeItems(newItems);
294
-
295
- return newItems.length - items.length;
296
- },
297
-
298
- editItem(newItem: D, index: number) {
299
- // Existence check
300
- const newIndex = items.findIndex(
301
- (item) => item[labelField] === newItem[labelField]
302
- );
303
- if (newIndex >= 0 && newIndex !== index) {
304
- // Label field is the same with a different item
305
- return false;
306
- }
307
-
308
- // Clone
309
- const newItems = [...items];
310
-
311
- // Remove the item
312
- newItems.splice(index, 1, newItem);
313
-
314
- // Update the state
315
- changeItems(newItems);
316
-
317
- return true;
318
- },
319
-
320
- deleteItem(index: number) {
321
- // Clone
322
- const newItems = [...items];
323
-
324
- // Remove the item
325
- newItems.splice(index, 1);
326
-
327
- // Update the state
328
- changeItems(newItems);
329
- },
330
-
331
- getItems() {
332
- return items;
333
- }
334
- };
335
- },
336
- [items, labelField, changeItems]
337
- );
338
-
339
- // Dynamic import library
340
- const [dnd, setDnd] =
341
- React.useState<
342
- [
343
- typeof DndContext,
344
- typeof SortableContext,
345
- typeof useSortable,
346
- typeof rectSortingStrategy,
347
- typeof rectSwappingStrategy,
348
- typeof horizontalListSortingStrategy,
349
- typeof verticalListSortingStrategy,
350
- typeof CSS
351
- ]
352
- >();
353
-
354
- React.useEffect(() => {
355
- Promise.all([
356
- import("@dnd-kit/core"),
357
- import("@dnd-kit/sortable"),
358
- import("@dnd-kit/utilities")
359
- ]).then(
360
- ([
361
- { DndContext },
362
- {
363
- SortableContext,
364
- useSortable,
365
- rectSortingStrategy,
366
- rectSwappingStrategy,
367
- horizontalListSortingStrategy,
368
- verticalListSortingStrategy
369
- },
370
- { CSS }
371
- ]) => {
372
- setDnd([
373
- DndContext,
374
- SortableContext,
375
- useSortable,
376
- rectSortingStrategy,
377
- rectSwappingStrategy,
378
- horizontalListSortingStrategy,
379
- verticalListSortingStrategy,
380
- CSS
381
- ]);
382
- }
383
- );
384
- }, []);
385
-
386
- const setupDiv = (div: HTMLDivElement, clearup: boolean = false) => {
387
- // Inputs
388
- div
389
- .querySelectorAll("input")
390
- .forEach((input) =>
391
- clearup
392
- ? input.removeEventListener("change", doFormChange)
393
- : input.addEventListener("change", doFormChange)
394
- );
395
-
396
- // Textareas
397
- div
398
- .querySelectorAll("textarea")
399
- .forEach((input) =>
400
- clearup
401
- ? input.removeEventListener("change", doFormChange)
402
- : input.addEventListener("change", doFormChange)
403
- );
404
-
405
- // Select
406
- div
407
- .querySelectorAll("select")
408
- .forEach((input) =>
409
- clearup
410
- ? input.removeEventListener("change", doFormChange)
411
- : input.addEventListener("change", doFormChange)
412
- );
413
- };
414
-
415
- const divRef = React.useRef<HTMLDivElement>(null);
416
-
417
- if (dnd == null) {
418
- return <Skeleton variant="rectangular" width="100%" height={height} />;
419
- }
420
-
421
- const [
422
- DndContextType,
423
- SortableContextType,
424
- useSortableType,
425
- rectSortingStrategyType,
426
- rectSwappingStrategyType,
427
- horizontalListSortingStrategyType,
428
- verticalListSortingStrategyType,
429
- CSSType
430
- ] = dnd;
431
-
432
- const strategy: SortingStrategy | undefined =
433
- typeof sortingStrategy === "function"
434
- ? sortingStrategy()
435
- : sortingStrategy === "rect"
436
- ? rectSortingStrategyType
437
- : sortingStrategy === "rectSwapping"
438
- ? rectSwappingStrategyType
439
- : sortingStrategy === "horizontal"
440
- ? horizontalListSortingStrategyType
441
- : sortingStrategy === "vertical"
442
- ? verticalListSortingStrategyType
443
- : undefined;
444
-
445
- let getItemStyle = props.getItemStyle;
446
- if (getItemStyle == null) {
447
- getItemStyle = (index, isDragging) =>
448
- DnDItemStyle(index, isDragging, theme);
449
- }
450
-
451
- // Drag event handlers
452
- function handleDragStart(event: DragStartEvent) {
453
- const { active } = event;
454
- setActiveId(active.id);
455
- }
456
-
457
- function handleDragEnd(event: DragEndEvent) {
458
- const { active, over } = event;
459
-
460
- if (over && active.id !== over.id) {
461
- // Indices
462
- const oldIndex = items.findIndex((item) => item.id === active.id);
463
- const newIndex = items.findIndex((item) => item.id === over.id);
464
-
465
- // Clone
466
- const newItems = [...items];
467
-
468
- // Removed item
469
- const [removed] = newItems.splice(oldIndex, 1);
470
-
471
- // Insert to the destination index
472
- newItems.splice(newIndex, 0, removed);
473
-
474
- changeItems(newItems);
475
-
476
- // Drag end handler
477
- if (onDragEnd) onDragEnd(newItems);
478
- }
479
-
480
- setActiveId(undefined);
481
- }
482
-
483
- const children = (
484
- <DndContextType onDragStart={handleDragStart} onDragEnd={handleDragEnd}>
485
- <SortableContextType items={items} strategy={strategy}>
486
- <Component {...componentProps}>
487
- {items.map((item, index) => {
488
- const id = item.id;
489
- return (
490
- <SortableItem
491
- id={id}
492
- useSortableType={useSortableType}
493
- CSSType={CSSType}
494
- key={id}
495
- style={getItemStyle!(index, id === activeId)}
496
- itemRenderer={(nodeRef, actionNodeRef) =>
497
- itemRenderer(item, index, nodeRef, actionNodeRef)
498
- }
499
- />
500
- );
501
- })}
502
- </Component>
503
- </SortableContextType>
504
- </DndContextType>
505
- );
506
-
507
- if (onFormChange) {
508
- return (
509
- <div
510
- style={{ width: "100%" }}
511
- ref={(div) => {
512
- if (div && divRef.current != div) {
513
- if (divRef.current) {
514
- setupDiv(divRef.current, true);
515
- }
516
-
517
- divRef.current = div;
518
- setupDiv(div);
519
- }
520
- }}
521
- >
522
- {children}
523
- </div>
524
- );
525
- }
526
-
527
- return children;
528
- }