@etsoo/materialui 1.1.6 → 1.1.7

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/lib/DnDList.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- import { UniqueIdentifier } from '@dnd-kit/core';
2
- import { DataTypes } from '@etsoo/shared';
3
- import { Theme } from '@mui/material';
4
- import React, { CSSProperties } from 'react';
1
+ import { UniqueIdentifier } from "@dnd-kit/core";
2
+ import { DataTypes } from "@etsoo/shared";
3
+ import { Theme } from "@mui/material";
4
+ import React, { CSSProperties } from "react";
5
5
  /**
6
6
  * DnD item default style
7
7
  * @param index Item index
@@ -76,6 +76,10 @@ export interface DnDListPros<D extends object, K extends DataTypes.Keys<D>> {
76
76
  * Data change handler
77
77
  */
78
78
  onChange?: (items: D[]) => void;
79
+ /**
80
+ * Form data change handler
81
+ */
82
+ onFormChange?: (items: D[]) => void;
79
83
  /**
80
84
  * Drag end handler
81
85
  */
package/lib/DnDList.js CHANGED
@@ -1,8 +1,8 @@
1
- import { DndContext } from '@dnd-kit/core';
2
- import { SortableContext, useSortable, verticalListSortingStrategy } from '@dnd-kit/sortable';
3
- import { CSS } from '@dnd-kit/utilities';
4
- import { useTheme } from '@mui/material';
5
- import React from 'react';
1
+ import { DndContext } from "@dnd-kit/core";
2
+ import { SortableContext, useSortable, verticalListSortingStrategy } from "@dnd-kit/sortable";
3
+ import { CSS } from "@dnd-kit/utilities";
4
+ import { useTheme } from "@mui/material";
5
+ import React from "react";
6
6
  function SortableItem(props) {
7
7
  // Destruct
8
8
  const { id, itemRenderer, style = {} } = props;
@@ -33,7 +33,7 @@ function SortableItem(props) {
33
33
  */
34
34
  export const DnDItemStyle = (index, isDragging, theme) => ({
35
35
  padding: theme.spacing(1),
36
- zIndex: isDragging ? 1 : 'auto',
36
+ zIndex: isDragging ? 1 : "auto",
37
37
  background: isDragging
38
38
  ? theme.palette.primary.light
39
39
  : index % 2 === 0
@@ -47,7 +47,7 @@ export const DnDItemStyle = (index, isDragging, theme) => ({
47
47
  */
48
48
  export function DnDList(props) {
49
49
  // Destruct
50
- const { keyField, itemRenderer, labelField, mRef, onChange, onDragEnd } = props;
50
+ const { keyField, itemRenderer, labelField, mRef, onChange, onFormChange, onDragEnd } = props;
51
51
  let getItemStyle = props.getItemStyle;
52
52
  if (getItemStyle == null) {
53
53
  // Theme
@@ -61,6 +61,8 @@ export function DnDList(props) {
61
61
  // Possible to alter items with the handler
62
62
  if (onChange)
63
63
  onChange(newItems);
64
+ if (onFormChange)
65
+ onFormChange(newItems);
64
66
  // Update state
65
67
  setItems(newItems);
66
68
  };
@@ -148,9 +150,13 @@ export function DnDList(props) {
148
150
  React.useEffect(() => {
149
151
  setItems(props.items);
150
152
  }, [props.items]);
151
- return (React.createElement(DndContext, { onDragStart: handleDragStart, onDragEnd: handleDragEnd },
152
- React.createElement(SortableContext, { items: items, strategy: verticalListSortingStrategy }, items.map((item, index) => {
153
- const id = item[keyField];
154
- return (React.createElement(SortableItem, { id: id, key: id, style: getItemStyle(index, id === activeId), itemRenderer: (nodeRef, actionNodeRef) => itemRenderer(item, index, nodeRef, actionNodeRef) }));
155
- }))));
153
+ return (React.createElement("form", { onChange: () => {
154
+ if (onFormChange)
155
+ onFormChange(items);
156
+ } },
157
+ React.createElement(DndContext, { onDragStart: handleDragStart, onDragEnd: handleDragEnd },
158
+ React.createElement(SortableContext, { items: items, strategy: verticalListSortingStrategy }, items.map((item, index) => {
159
+ const id = item[keyField];
160
+ return (React.createElement(SortableItem, { id: id, key: id, style: getItemStyle(index, id === activeId), itemRenderer: (nodeRef, actionNodeRef) => itemRenderer(item, index, nodeRef, actionNodeRef) }));
161
+ })))));
156
162
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@etsoo/materialui",
3
- "version": "1.1.6",
3
+ "version": "1.1.7",
4
4
  "description": "TypeScript Material-UI Implementation",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
package/src/DnDList.tsx CHANGED
@@ -1,58 +1,58 @@
1
1
  import {
2
- DndContext,
3
- DragEndEvent,
4
- DragStartEvent,
5
- UniqueIdentifier
6
- } from '@dnd-kit/core';
2
+ DndContext,
3
+ DragEndEvent,
4
+ DragStartEvent,
5
+ UniqueIdentifier
6
+ } from "@dnd-kit/core";
7
7
  import {
8
- SortableContext,
9
- useSortable,
10
- verticalListSortingStrategy
11
- } from '@dnd-kit/sortable';
12
- import { CSS } from '@dnd-kit/utilities';
13
- import { DataTypes } from '@etsoo/shared';
14
- import { Theme, useTheme } from '@mui/material';
15
- import React, { CSSProperties } from 'react';
8
+ SortableContext,
9
+ useSortable,
10
+ verticalListSortingStrategy
11
+ } from "@dnd-kit/sortable";
12
+ import { CSS } from "@dnd-kit/utilities";
13
+ import { DataTypes } from "@etsoo/shared";
14
+ import { Theme, useTheme } from "@mui/material";
15
+ import React, { CSSProperties } from "react";
16
16
 
17
17
  function SortableItem(props: {
18
- id: UniqueIdentifier;
19
- itemRenderer: (
20
- nodeRef: React.ComponentProps<any>,
21
- actionNodeRef: React.ComponentProps<any>
22
- ) => React.ReactElement;
23
- style?: React.CSSProperties;
18
+ id: UniqueIdentifier;
19
+ itemRenderer: (
20
+ nodeRef: React.ComponentProps<any>,
21
+ actionNodeRef: React.ComponentProps<any>
22
+ ) => React.ReactElement;
23
+ style?: React.CSSProperties;
24
24
  }) {
25
- // Destruct
26
- const { id, itemRenderer, style = {} } = props;
27
-
28
- // Use sortable
29
- const {
30
- attributes,
31
- listeners,
32
- setNodeRef,
33
- transform,
34
- transition,
35
- setActivatorNodeRef
36
- } = useSortable({ id });
37
-
38
- const allStyle = {
39
- ...style,
40
- transform: CSS.Transform.toString(transform),
41
- transition
42
- };
43
-
44
- const nodeRef = {
45
- style: allStyle,
46
- ref: setNodeRef,
47
- ...attributes
48
- };
49
-
50
- const actionNodeRef = {
51
- ...listeners,
52
- ref: setActivatorNodeRef
53
- };
54
-
55
- return itemRenderer(nodeRef, actionNodeRef);
25
+ // Destruct
26
+ const { id, itemRenderer, style = {} } = props;
27
+
28
+ // Use sortable
29
+ const {
30
+ attributes,
31
+ listeners,
32
+ setNodeRef,
33
+ transform,
34
+ transition,
35
+ setActivatorNodeRef
36
+ } = useSortable({ id });
37
+
38
+ const allStyle = {
39
+ ...style,
40
+ transform: CSS.Transform.toString(transform),
41
+ transition
42
+ };
43
+
44
+ const nodeRef = {
45
+ style: allStyle,
46
+ ref: setNodeRef,
47
+ ...attributes
48
+ };
49
+
50
+ const actionNodeRef = {
51
+ ...listeners,
52
+ ref: setActivatorNodeRef
53
+ };
54
+
55
+ return itemRenderer(nodeRef, actionNodeRef);
56
56
  }
57
57
 
58
58
  /**
@@ -63,102 +63,107 @@ function SortableItem(props: {
63
63
  * @returns Style
64
64
  */
65
65
  export const DnDItemStyle = (
66
- index: number,
67
- isDragging: boolean,
68
- theme: Theme
66
+ index: number,
67
+ isDragging: boolean,
68
+ theme: Theme
69
69
  ) => ({
70
- padding: theme.spacing(1),
71
- zIndex: isDragging ? 1 : 'auto',
72
- background: isDragging
73
- ? theme.palette.primary.light
74
- : index % 2 === 0
75
- ? theme.palette.grey[100]
76
- : theme.palette.grey[50]
70
+ padding: theme.spacing(1),
71
+ zIndex: isDragging ? 1 : "auto",
72
+ background: isDragging
73
+ ? theme.palette.primary.light
74
+ : index % 2 === 0
75
+ ? theme.palette.grey[100]
76
+ : theme.palette.grey[50]
77
77
  });
78
78
 
79
79
  /**
80
80
  * DnD list forward ref
81
81
  */
82
82
  export interface DnDListRef<D extends object> {
83
- /**
84
- * Add item
85
- * @param item New item
86
- */
87
- addItem(item: D): void;
88
-
89
- /**
90
- * Add items
91
- * @param items items
92
- */
93
- addItems(items: D[]): void;
94
-
95
- /**
96
- * Delete item
97
- * @param index Item index
98
- */
99
- deleteItem(index: number): void;
100
-
101
- /**
102
- * Edit item
103
- * @param newItem New item
104
- * @param index Index
105
- */
106
- editItem(newItem: D, index: number): boolean;
107
-
108
- /**
109
- * Get all items
110
- */
111
- getItems(): D[];
83
+ /**
84
+ * Add item
85
+ * @param item New item
86
+ */
87
+ addItem(item: D): void;
88
+
89
+ /**
90
+ * Add items
91
+ * @param items items
92
+ */
93
+ addItems(items: D[]): void;
94
+
95
+ /**
96
+ * Delete item
97
+ * @param index Item index
98
+ */
99
+ deleteItem(index: number): void;
100
+
101
+ /**
102
+ * Edit item
103
+ * @param newItem New item
104
+ * @param index Index
105
+ */
106
+ editItem(newItem: D, index: number): boolean;
107
+
108
+ /**
109
+ * Get all items
110
+ */
111
+ getItems(): D[];
112
112
  }
113
113
 
114
114
  /**
115
115
  * DnD sortable list properties
116
116
  */
117
117
  export interface DnDListPros<D extends object, K extends DataTypes.Keys<D>> {
118
- /**
119
- * Get list item style callback
120
- */
121
- getItemStyle?: (index: number, isDragging: boolean) => CSSProperties;
122
-
123
- /**
124
- * Item renderer
125
- */
126
- itemRenderer: (
127
- item: D,
128
- index: number,
129
- nodeRef: React.ComponentProps<any>,
130
- actionNodeRef: React.ComponentProps<any>
131
- ) => React.ReactElement;
132
-
133
- /**
134
- * List items
135
- */
136
- items: D[];
137
-
138
- /**
139
- * Unique key field
140
- */
141
- keyField: K;
142
-
143
- /**
144
- * Label field
145
- */
146
- labelField: K;
147
-
148
- /**
149
- * Methods ref
150
- */
151
- mRef?: React.Ref<DnDListRef<D>>;
152
-
153
- /**
154
- * Data change handler
155
- */
156
- onChange?: (items: D[]) => void;
157
-
158
- /**
159
- * Drag end handler
160
- */
161
- onDragEnd?: (items: D[]) => void;
118
+ /**
119
+ * Get list item style callback
120
+ */
121
+ getItemStyle?: (index: number, isDragging: boolean) => CSSProperties;
122
+
123
+ /**
124
+ * Item renderer
125
+ */
126
+ itemRenderer: (
127
+ item: D,
128
+ index: number,
129
+ nodeRef: React.ComponentProps<any>,
130
+ actionNodeRef: React.ComponentProps<any>
131
+ ) => React.ReactElement;
132
+
133
+ /**
134
+ * List items
135
+ */
136
+ items: D[];
137
+
138
+ /**
139
+ * Unique key field
140
+ */
141
+ keyField: K;
142
+
143
+ /**
144
+ * Label field
145
+ */
146
+ labelField: K;
147
+
148
+ /**
149
+ * Methods ref
150
+ */
151
+ mRef?: React.Ref<DnDListRef<D>>;
152
+
153
+ /**
154
+ * Data change handler
155
+ */
156
+ onChange?: (items: D[]) => void;
157
+
158
+ /**
159
+ * Form data change handler
160
+ */
161
+ onFormChange?: (items: D[]) => void;
162
+
163
+ /**
164
+ * Drag end handler
165
+ */
166
+ onDragEnd?: (items: D[]) => void;
162
167
  }
163
168
 
164
169
  /**
@@ -167,187 +172,186 @@ export interface DnDListPros<D extends object, K extends DataTypes.Keys<D>> {
167
172
  * @returns Component
168
173
  */
169
174
  export function DnDList<
170
- D extends { id: UniqueIdentifier },
171
- K extends DataTypes.Keys<D, UniqueIdentifier> = DataTypes.Keys<
172
- D,
173
- UniqueIdentifier
174
- >
175
+ D extends { id: UniqueIdentifier },
176
+ K extends DataTypes.Keys<D, UniqueIdentifier> = DataTypes.Keys<
177
+ D,
178
+ UniqueIdentifier
179
+ >
175
180
  >(props: DnDListPros<D, K>) {
176
- // Destruct
177
- const { keyField, itemRenderer, labelField, mRef, onChange, onDragEnd } =
178
- props;
179
-
180
- let getItemStyle = props.getItemStyle;
181
- if (getItemStyle == null) {
182
- // Theme
183
- const theme = useTheme();
184
- getItemStyle = (index, isDragging) =>
185
- DnDItemStyle(index, isDragging, theme);
181
+ // Destruct
182
+ const {
183
+ keyField,
184
+ itemRenderer,
185
+ labelField,
186
+ mRef,
187
+ onChange,
188
+ onFormChange,
189
+ onDragEnd
190
+ } = props;
191
+
192
+ let getItemStyle = props.getItemStyle;
193
+ if (getItemStyle == null) {
194
+ // Theme
195
+ const theme = useTheme();
196
+ getItemStyle = (index, isDragging) =>
197
+ DnDItemStyle(index, isDragging, theme);
198
+ }
199
+
200
+ // States
201
+ const [items, setItems] = React.useState<D[]>([]);
202
+ const [activeId, setActiveId] = React.useState<UniqueIdentifier>();
203
+
204
+ const changeItems = (newItems: D[]) => {
205
+ // Possible to alter items with the handler
206
+ if (onChange) onChange(newItems);
207
+ if (onFormChange) onFormChange(newItems);
208
+
209
+ // Update state
210
+ setItems(newItems);
211
+ };
212
+
213
+ // Drag event handlers
214
+ function handleDragStart(event: DragStartEvent) {
215
+ const { active } = event;
216
+ setActiveId(active.id);
217
+ }
218
+
219
+ function handleDragEnd(event: DragEndEvent) {
220
+ const { active, over } = event;
221
+
222
+ if (over && active.id !== over.id) {
223
+ // Indices
224
+ const oldIndex = items.findIndex((item) => item.id === active.id);
225
+ const newIndex = items.findIndex((item) => item.id === over.id);
226
+
227
+ // Clone
228
+ const newItems = [...items];
229
+
230
+ // Removed item
231
+ const [removed] = newItems.splice(oldIndex, 1);
232
+
233
+ // Insert to the destination index
234
+ newItems.splice(newIndex, 0, removed);
235
+
236
+ changeItems(newItems);
237
+
238
+ // Drag end handler
239
+ if (onDragEnd) onDragEnd(newItems);
186
240
  }
187
241
 
188
- // States
189
- const [items, setItems] = React.useState<D[]>([]);
190
- const [activeId, setActiveId] = React.useState<UniqueIdentifier>();
242
+ setActiveId(undefined);
243
+ }
191
244
 
192
- const changeItems = (newItems: D[]) => {
193
- // Possible to alter items with the handler
194
- if (onChange) onChange(newItems);
245
+ // Methods
246
+ React.useImperativeHandle(
247
+ mRef,
248
+ () => {
249
+ return {
250
+ addItem(newItem: D) {
251
+ // Existence check
252
+ if (items.some((item) => item[labelField] === newItem[labelField])) {
253
+ return false;
254
+ }
195
255
 
196
- // Update state
197
- setItems(newItems);
198
- };
256
+ // Clone
257
+ const newItems = [newItem, ...items];
199
258
 
200
- // Drag event handlers
201
- function handleDragStart(event: DragStartEvent) {
202
- const { active } = event;
203
- setActiveId(active.id);
204
- }
259
+ // Update the state
260
+ changeItems(newItems);
205
261
 
206
- function handleDragEnd(event: DragEndEvent) {
207
- const { active, over } = event;
262
+ return true;
263
+ },
208
264
 
209
- if (over && active.id !== over.id) {
210
- // Indices
211
- const oldIndex = items.findIndex((item) => item.id === active.id);
212
- const newIndex = items.findIndex((item) => item.id === over.id);
265
+ addItems(inputItems: D[]) {
266
+ // Clone
267
+ const newItems = [...items];
213
268
 
214
- // Clone
215
- const newItems = [...items];
269
+ // Insert items
270
+ inputItems.forEach((newItem) => {
271
+ // Existence check
272
+ if (
273
+ newItems.some((item) => item[labelField] === newItem[labelField])
274
+ ) {
275
+ return;
276
+ }
216
277
 
217
- // Removed item
218
- const [removed] = newItems.splice(oldIndex, 1);
278
+ newItems.push(newItem);
279
+ });
219
280
 
220
- // Insert to the destination index
221
- newItems.splice(newIndex, 0, removed);
281
+ // Update the state
282
+ changeItems(newItems);
222
283
 
223
- changeItems(newItems);
284
+ return newItems.length - items.length;
285
+ },
224
286
 
225
- // Drag end handler
226
- if (onDragEnd) onDragEnd(newItems);
227
- }
287
+ editItem(newItem: D, index: number) {
288
+ // Existence check
289
+ const newIndex = items.findIndex(
290
+ (item) => item[labelField] === newItem[labelField]
291
+ );
292
+ if (newIndex >= 0 && newIndex !== index) {
293
+ // Label field is the same with a different item
294
+ return false;
295
+ }
228
296
 
229
- setActiveId(undefined);
230
- }
297
+ // Clone
298
+ const newItems = [...items];
231
299
 
232
- // Methods
233
- React.useImperativeHandle(
234
- mRef,
235
- () => {
236
- return {
237
- addItem(newItem: D) {
238
- // Existence check
239
- if (
240
- items.some(
241
- (item) => item[labelField] === newItem[labelField]
242
- )
243
- ) {
244
- return false;
245
- }
246
-
247
- // Clone
248
- const newItems = [newItem, ...items];
249
-
250
- // Update the state
251
- changeItems(newItems);
252
-
253
- return true;
254
- },
255
-
256
- addItems(inputItems: D[]) {
257
- // Clone
258
- const newItems = [...items];
259
-
260
- // Insert items
261
- inputItems.forEach((newItem) => {
262
- // Existence check
263
- if (
264
- newItems.some(
265
- (item) =>
266
- item[labelField] === newItem[labelField]
267
- )
268
- ) {
269
- return;
270
- }
271
-
272
- newItems.push(newItem);
273
- });
274
-
275
- // Update the state
276
- changeItems(newItems);
277
-
278
- return newItems.length - items.length;
279
- },
280
-
281
- editItem(newItem: D, index: number) {
282
- // Existence check
283
- const newIndex = items.findIndex(
284
- (item) => item[labelField] === newItem[labelField]
285
- );
286
- if (newIndex >= 0 && newIndex !== index) {
287
- // Label field is the same with a different item
288
- return false;
289
- }
290
-
291
- // Clone
292
- const newItems = [...items];
293
-
294
- // Remove the item
295
- newItems.splice(index, 1, newItem);
296
-
297
- // Update the state
298
- changeItems(newItems);
299
-
300
- return true;
301
- },
302
-
303
- deleteItem(index: number) {
304
- // Clone
305
- const newItems = [...items];
306
-
307
- // Remove the item
308
- newItems.splice(index, 1);
309
-
310
- // Update the state
311
- changeItems(newItems);
312
- },
313
-
314
- getItems() {
315
- return items;
316
- }
317
- };
300
+ // Remove the item
301
+ newItems.splice(index, 1, newItem);
302
+
303
+ // Update the state
304
+ changeItems(newItems);
305
+
306
+ return true;
307
+ },
308
+
309
+ deleteItem(index: number) {
310
+ // Clone
311
+ const newItems = [...items];
312
+
313
+ // Remove the item
314
+ newItems.splice(index, 1);
315
+
316
+ // Update the state
317
+ changeItems(newItems);
318
318
  },
319
- [items]
320
- );
321
-
322
- React.useEffect(() => {
323
- setItems(props.items);
324
- }, [props.items]);
325
-
326
- return (
327
- <DndContext onDragStart={handleDragStart} onDragEnd={handleDragEnd}>
328
- <SortableContext
329
- items={items}
330
- strategy={verticalListSortingStrategy}
331
- >
332
- {items.map((item, index) => {
333
- const id = item[keyField] as unknown as UniqueIdentifier;
334
- return (
335
- <SortableItem
336
- id={id}
337
- key={id}
338
- style={getItemStyle!(index, id === activeId)}
339
- itemRenderer={(nodeRef, actionNodeRef) =>
340
- itemRenderer(
341
- item,
342
- index,
343
- nodeRef,
344
- actionNodeRef
345
- )
346
- }
347
- />
348
- );
349
- })}
350
- </SortableContext>
351
- </DndContext>
352
- );
319
+
320
+ getItems() {
321
+ return items;
322
+ }
323
+ };
324
+ },
325
+ [items]
326
+ );
327
+
328
+ React.useEffect(() => {
329
+ setItems(props.items);
330
+ }, [props.items]);
331
+
332
+ return (
333
+ <form
334
+ onChange={() => {
335
+ if (onFormChange) onFormChange(items);
336
+ }}
337
+ >
338
+ <DndContext onDragStart={handleDragStart} onDragEnd={handleDragEnd}>
339
+ <SortableContext items={items} strategy={verticalListSortingStrategy}>
340
+ {items.map((item, index) => {
341
+ const id = item[keyField] as unknown as UniqueIdentifier;
342
+ return (
343
+ <SortableItem
344
+ id={id}
345
+ key={id}
346
+ style={getItemStyle!(index, id === activeId)}
347
+ itemRenderer={(nodeRef, actionNodeRef) =>
348
+ itemRenderer(item, index, nodeRef, actionNodeRef)
349
+ }
350
+ />
351
+ );
352
+ })}
353
+ </SortableContext>
354
+ </DndContext>
355
+ </form>
356
+ );
353
357
  }