@etsoo/materialui 1.6.11 → 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.
@@ -1,5 +1,6 @@
1
1
  import { ButtonProps } from "@mui/material/Button";
2
- import { DataTypes, IdType } from "@etsoo/shared";
2
+ import { IdType } from "@etsoo/shared";
3
+ import { DnDSortableListProps } from "./DnDSortableList";
3
4
  type DnDItemType = {
4
5
  id: IdType;
5
6
  };
@@ -23,7 +24,7 @@ export type ButtonPopupCheckboxProps<D extends DnDItemType> = Omit<ButtonProps,
23
24
  /**
24
25
  * Label field in items
25
26
  */
26
- labelField: DataTypes.Keys<D>;
27
+ labelField: DnDSortableListProps<D>["labelField"];
27
28
  /**
28
29
  * Label formatter
29
30
  * @param item Item to be formatted
@@ -19,7 +19,7 @@ const TextField_1 = __importDefault(require("@mui/material/TextField"));
19
19
  const FlexBox_1 = require("./FlexBox");
20
20
  const ReactApp_1 = require("./app/ReactApp");
21
21
  const FormLabel_1 = __importDefault(require("@mui/material/FormLabel"));
22
- const DnDList_1 = require("./DnDList");
22
+ const DnDSortableList_1 = require("./DnDSortableList");
23
23
  function ButtonPopupList(props) {
24
24
  // Destruct
25
25
  const { addSplitter = /\s*[,;]\s*/, value = [], items, labelField, labelFormatter, labels, onAdd, onValueChange } = props;
@@ -40,18 +40,18 @@ function ButtonPopupList(props) {
40
40
  // Set selected ids
41
41
  setSelectedIdsHandler([...value]);
42
42
  }, [value]);
43
- return ((0, jsx_runtime_1.jsxs)(FlexBox_1.VBox, { gap: 2, children: [(0, jsx_runtime_1.jsx)(DnDList_1.DnDList, { component: Grid_1.default, componentProps: { container: true, spacing: 0 }, items: items, labelField: labelField, onFormChange: (items) => {
43
+ return ((0, jsx_runtime_1.jsxs)(FlexBox_1.VBox, { gap: 2, children: [(0, jsx_runtime_1.jsx)(DnDSortableList_1.DnDSortableList, { component: Grid_1.default, componentProps: { container: true, spacing: 0 }, items: items, labelField: labelField, onChange: (items) => {
44
44
  const ids = items
45
45
  .filter((item) => tempSelectedIds.current.includes(item.id))
46
46
  .map((item) => item.id);
47
47
  onValueChange(ids);
48
- }, itemRenderer: (item, index, nodeRef, actionNodeRef) => ((0, jsx_runtime_1.jsxs)(Grid_1.default, { size: { xs: 12, md: 6, lg: 4 }, display: "flex", justifyContent: "flex-start", alignItems: "center", gap: 1, ...nodeRef, children: [(0, jsx_runtime_1.jsx)(IconButton_1.default, { style: { cursor: "move" }, size: "small", title: labels?.dragIndicator, ...actionNodeRef, children: (0, jsx_runtime_1.jsx)(DragIndicator_1.default, {}) }), (0, jsx_runtime_1.jsx)(FormControlLabel_1.default, { control: (0, jsx_runtime_1.jsx)(Checkbox_1.default, { name: "item", value: item.id, checked: selectedIds.includes(item.id), onChange: (e) => {
48
+ }, itemRenderer: (item, style, { sortable: { index }, ref, handleRef }) => ((0, jsx_runtime_1.jsxs)(Grid_1.default, { size: { xs: 12, md: 6, lg: 4 }, display: "flex", justifyContent: "flex-start", alignItems: "center", gap: 1, ref: ref, style: style, children: [(0, jsx_runtime_1.jsx)(IconButton_1.default, { style: { cursor: "move" }, size: "small", title: labels?.dragIndicator, ref: handleRef, children: (0, jsx_runtime_1.jsx)(DragIndicator_1.default, {}) }), (0, jsx_runtime_1.jsx)(FormControlLabel_1.default, { control: (0, jsx_runtime_1.jsx)(Checkbox_1.default, { name: "item", value: item.id, checked: selectedIds.includes(item.id), onChange: (e) => {
49
49
  const checked = e.target.checked;
50
50
  const newIds = [
51
51
  ...selectedIds.toggleItem(item.id, checked)
52
52
  ];
53
53
  setSelectedIdsHandler(newIds);
54
- } }), label: `${index + 1}. ${labelFormatter(item)}` })] })), height: 200, mRef: dndRef }), onAdd && ((0, jsx_runtime_1.jsxs)(FlexBox_1.HBox, { gap: 1, children: [(0, jsx_runtime_1.jsx)(TextField_1.default, { variant: "outlined", label: labels?.more, fullWidth: true, inputRef: inputRef }), (0, jsx_runtime_1.jsx)(Button_1.default, { sx: { width: "120px" }, variant: "contained", startIcon: (0, jsx_runtime_1.jsx)(Add_1.default, {}), size: "small", onClick: async () => {
54
+ } }), label: `${index + 1}. ${labelFormatter(item)}` })] })), mRef: dndRef }), onAdd && ((0, jsx_runtime_1.jsxs)(FlexBox_1.HBox, { gap: 1, children: [(0, jsx_runtime_1.jsx)(TextField_1.default, { variant: "outlined", label: labels?.more, fullWidth: true, inputRef: inputRef }), (0, jsx_runtime_1.jsx)(Button_1.default, { sx: { width: "120px" }, variant: "contained", startIcon: (0, jsx_runtime_1.jsx)(Add_1.default, {}), size: "small", onClick: async () => {
55
55
  if (inputRef.current == null)
56
56
  return;
57
57
  const input = inputRef.current.value.trim();
@@ -82,6 +82,8 @@ function ButtonPopupCheckbox(props) {
82
82
  const app = (0, ReactApp_1.useRequiredAppContext)();
83
83
  // Destruct
84
84
  const { addSplitter, value = [], inputName, label, labelEnd, labelFormatter = (data) => {
85
+ if (typeof labelField === "function")
86
+ return labelField(data);
85
87
  if (labelField in data) {
86
88
  return data[labelField];
87
89
  }
@@ -0,0 +1,105 @@
1
+ import { DataTypes, IdType } from "@etsoo/shared";
2
+ import React from "react";
3
+ import { CSSProperties, Theme } from "@mui/material/styles";
4
+ import { useSortable } from "@dnd-kit/react/sortable";
5
+ import { DragDropEvents } from "@dnd-kit/react";
6
+ /**
7
+ * DnD sortable item default style
8
+ * @param index Item index
9
+ * @param isDragging Is dragging
10
+ * @param theme Theme
11
+ * @returns Style
12
+ */
13
+ export declare const DnDSortableItemStyle: (index: number, isDragging: boolean, theme: Theme) => {
14
+ padding: string;
15
+ transform: string;
16
+ zIndex: string | number;
17
+ boxShadow: string;
18
+ background: string;
19
+ };
20
+ /**
21
+ * DnD sortable list forward ref
22
+ */
23
+ export interface DnDSortableListRef<D extends object> {
24
+ /**
25
+ * Add item
26
+ * @param item New item
27
+ */
28
+ addItem(item: D): void;
29
+ /**
30
+ * Add items
31
+ * @param items items
32
+ */
33
+ addItems(items: D[]): void;
34
+ /**
35
+ * Delete item
36
+ * @param index Item index
37
+ */
38
+ deleteItem(index: number): void;
39
+ /**
40
+ * Edit item
41
+ * @param newItem New item
42
+ * @param index Index
43
+ */
44
+ editItem(newItem: D, index: number): boolean;
45
+ /**
46
+ * Get all items
47
+ */
48
+ getItems(): D[];
49
+ }
50
+ /**
51
+ * DnD sortable list props
52
+ */
53
+ export type DnDSortableListProps<D extends object, E extends React.ElementType = React.ElementType> = {
54
+ /**
55
+ * Component type to render the list into
56
+ * Default is React.Fragment
57
+ */
58
+ component?: E;
59
+ /**
60
+ * Component props
61
+ */
62
+ componentProps?: React.ComponentProps<E>;
63
+ /**
64
+ * List items
65
+ */
66
+ items: D[];
67
+ /**
68
+ * Id field
69
+ */
70
+ idField?: DataTypes.Keys<D> | ((item: D) => IdType);
71
+ /**
72
+ * Label field
73
+ */
74
+ labelField: DataTypes.Keys<D, string> | ((item: D) => string);
75
+ /**
76
+ * Methods ref
77
+ */
78
+ mRef?: React.Ref<DnDSortableListRef<D>>;
79
+ /**
80
+ * Item renderer
81
+ */
82
+ itemRenderer: (data: D, style: CSSProperties, state: ReturnType<typeof useSortable<D>>) => React.ReactElement;
83
+ /**
84
+ * Get list item style callback
85
+ */
86
+ itemStyle?: (index: number, isDragging: boolean) => CSSProperties;
87
+ /**
88
+ * Data change handler
89
+ */
90
+ onChange?: (items: D[]) => void;
91
+ /**
92
+ * Drag start handler
93
+ */
94
+ onDragStart?: (items: D[], source: Parameters<DragDropEvents["dragstart"]>[0]) => void;
95
+ /**
96
+ * Drag end handler
97
+ */
98
+ onDragEnd?: (items: D[], ...args: Parameters<DragDropEvents["dragend"]>) => void;
99
+ };
100
+ /**
101
+ * DnD sortable list component
102
+ * @param props Props
103
+ * @returns Component
104
+ */
105
+ export declare function DnDSortableList<D extends object, E extends React.ElementType = React.ElementType>(props: DnDSortableListProps<D, E>): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,130 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.DnDSortableItemStyle = void 0;
7
+ exports.DnDSortableList = DnDSortableList;
8
+ const jsx_runtime_1 = require("react/jsx-runtime");
9
+ const react_1 = __importDefault(require("react"));
10
+ const styles_1 = require("@mui/material/styles");
11
+ const sortable_1 = require("@dnd-kit/react/sortable");
12
+ const react_2 = require("@dnd-kit/react");
13
+ /**
14
+ * DnD sortable item default style
15
+ * @param index Item index
16
+ * @param isDragging Is dragging
17
+ * @param theme Theme
18
+ * @returns Style
19
+ */
20
+ const DnDSortableItemStyle = (index, isDragging, theme) => ({
21
+ padding: theme.spacing(1),
22
+ transform: isDragging ? "scale(1.03)" : "none",
23
+ zIndex: isDragging ? 1 : "auto",
24
+ boxShadow: isDragging
25
+ ? `-1px 0 8px 0 ${theme.palette.grey[400]}, 0px 8px 8px 0 ${theme.palette.grey[200]}`
26
+ : "none",
27
+ background: isDragging
28
+ ? theme.palette.primary.light
29
+ : index % 2 === 0
30
+ ? theme.palette.grey[100]
31
+ : theme.palette.grey[50]
32
+ });
33
+ exports.DnDSortableItemStyle = DnDSortableItemStyle;
34
+ function SortableItem(props) {
35
+ const theme = (0, styles_1.useTheme)();
36
+ const { id, data, index, itemRenderer, itemStyle = (index, isDragging) => (0, exports.DnDSortableItemStyle)(index, isDragging, theme) } = props;
37
+ const state = (0, sortable_1.useSortable)({ id, data, index });
38
+ const style = itemStyle(index, state.isDragging);
39
+ return itemRenderer(data, style, state);
40
+ }
41
+ /**
42
+ * DnD sortable list component
43
+ * @param props Props
44
+ * @returns Component
45
+ */
46
+ function DnDSortableList(props) {
47
+ // Destruct
48
+ const Component = props.component || react_1.default.Fragment;
49
+ const { componentProps, idField, itemRenderer, itemStyle, labelField, mRef, onChange, onDragStart, onDragEnd } = props;
50
+ const idFn = typeof idField === "function"
51
+ ? idField
52
+ : (item) => !idField
53
+ ? Reflect.get(item, "id")
54
+ : item[idField];
55
+ const labelFn = react_1.default.useCallback(typeof labelField === "function"
56
+ ? labelField
57
+ : (item) => item[labelField], [labelField]);
58
+ // States
59
+ const [items, setItems] = react_1.default.useState([]);
60
+ react_1.default.useEffect(() => {
61
+ setItems(props.items);
62
+ }, [props.items]);
63
+ const changeItems = react_1.default.useCallback((newItems) => {
64
+ // Possible to alter items with the handler
65
+ onChange?.(newItems);
66
+ // Update state
67
+ setItems(newItems);
68
+ }, [onChange]);
69
+ // Methods
70
+ react_1.default.useImperativeHandle(mRef, () => {
71
+ return {
72
+ addItem(newItem) {
73
+ // Existence check
74
+ if (items.some((item) => labelFn(item) === labelFn(newItem))) {
75
+ return false;
76
+ }
77
+ // Clone
78
+ const newItems = [newItem, ...items];
79
+ // Update the state
80
+ changeItems(newItems);
81
+ return true;
82
+ },
83
+ addItems(inputItems) {
84
+ // Clone
85
+ const newItems = [...items];
86
+ // Insert items
87
+ inputItems.forEach((newItem) => {
88
+ // Existence check
89
+ if (newItems.some((item) => labelFn(item) === labelFn(newItem))) {
90
+ return;
91
+ }
92
+ newItems.push(newItem);
93
+ });
94
+ // Update the state
95
+ changeItems(newItems);
96
+ return newItems.length - items.length;
97
+ },
98
+ editItem(newItem, index) {
99
+ // Existence check
100
+ const newIndex = items.findIndex((item) => labelFn(item) === labelFn(newItem));
101
+ if (newIndex >= 0 && newIndex !== index) {
102
+ // Label field is the same with a different item
103
+ return false;
104
+ }
105
+ // Clone
106
+ const newItems = [...items];
107
+ // Remove the item
108
+ newItems.splice(index, 1, newItem);
109
+ // Update the state
110
+ changeItems(newItems);
111
+ return true;
112
+ },
113
+ deleteItem(index) {
114
+ // Clone
115
+ const newItems = [...items];
116
+ // Remove the item
117
+ newItems.splice(index, 1);
118
+ // Update the state
119
+ changeItems(newItems);
120
+ },
121
+ getItems() {
122
+ return items;
123
+ }
124
+ };
125
+ }, [items, labelFn, changeItems]);
126
+ return ((0, jsx_runtime_1.jsx)(react_2.DragDropProvider, { onDragStart: (source) => onDragStart?.(items, source), onDragEnd: (source, target) => onDragEnd?.(items, source, target), children: (0, jsx_runtime_1.jsx)(Component, { ...componentProps, children: items.map((item, index) => {
127
+ const id = idFn(item);
128
+ return ((0, jsx_runtime_1.jsx)(SortableItem, { id: id, index: index, data: item, itemRenderer: itemRenderer, itemStyle: itemStyle }, id));
129
+ }) }) }));
130
+ }
@@ -54,7 +54,7 @@ export * from "./DataLoadField";
54
54
  export * from "./DataSteps";
55
55
  export * from "./DataTable";
56
56
  export * from "./DialogButton";
57
- export * from "./DnDList";
57
+ export * from "./DnDSortableList";
58
58
  export * from "./DownUpButton";
59
59
  export * from "./DraggablePaperComponent";
60
60
  export * from "./EmailInput";
package/lib/cjs/index.js CHANGED
@@ -70,7 +70,7 @@ __exportStar(require("./DataLoadField"), exports);
70
70
  __exportStar(require("./DataSteps"), exports);
71
71
  __exportStar(require("./DataTable"), exports);
72
72
  __exportStar(require("./DialogButton"), exports);
73
- __exportStar(require("./DnDList"), exports);
73
+ __exportStar(require("./DnDSortableList"), exports);
74
74
  __exportStar(require("./DownUpButton"), exports);
75
75
  __exportStar(require("./DraggablePaperComponent"), exports);
76
76
  __exportStar(require("./EmailInput"), exports);
@@ -1,5 +1,6 @@
1
1
  import { ButtonProps } from "@mui/material/Button";
2
- import { DataTypes, IdType } from "@etsoo/shared";
2
+ import { IdType } from "@etsoo/shared";
3
+ import { DnDSortableListProps } from "./DnDSortableList";
3
4
  type DnDItemType = {
4
5
  id: IdType;
5
6
  };
@@ -23,7 +24,7 @@ export type ButtonPopupCheckboxProps<D extends DnDItemType> = Omit<ButtonProps,
23
24
  /**
24
25
  * Label field in items
25
26
  */
26
- labelField: DataTypes.Keys<D>;
27
+ labelField: DnDSortableListProps<D>["labelField"];
27
28
  /**
28
29
  * Label formatter
29
30
  * @param item Item to be formatted
@@ -13,7 +13,7 @@ import TextField from "@mui/material/TextField";
13
13
  import { HBox, VBox } from "./FlexBox";
14
14
  import { useRequiredAppContext } from "./app/ReactApp";
15
15
  import FormLabel from "@mui/material/FormLabel";
16
- import { DnDList } from "./DnDList";
16
+ import { DnDSortableList } from "./DnDSortableList";
17
17
  function ButtonPopupList(props) {
18
18
  // Destruct
19
19
  const { addSplitter = /\s*[,;]\s*/, value = [], items, labelField, labelFormatter, labels, onAdd, onValueChange } = props;
@@ -34,18 +34,18 @@ function ButtonPopupList(props) {
34
34
  // Set selected ids
35
35
  setSelectedIdsHandler([...value]);
36
36
  }, [value]);
37
- return (_jsxs(VBox, { gap: 2, children: [_jsx(DnDList, { component: Grid, componentProps: { container: true, spacing: 0 }, items: items, labelField: labelField, onFormChange: (items) => {
37
+ return (_jsxs(VBox, { gap: 2, children: [_jsx(DnDSortableList, { component: Grid, componentProps: { container: true, spacing: 0 }, items: items, labelField: labelField, onChange: (items) => {
38
38
  const ids = items
39
39
  .filter((item) => tempSelectedIds.current.includes(item.id))
40
40
  .map((item) => item.id);
41
41
  onValueChange(ids);
42
- }, itemRenderer: (item, index, nodeRef, actionNodeRef) => (_jsxs(Grid, { size: { xs: 12, md: 6, lg: 4 }, display: "flex", justifyContent: "flex-start", alignItems: "center", gap: 1, ...nodeRef, children: [_jsx(IconButton, { style: { cursor: "move" }, size: "small", title: labels?.dragIndicator, ...actionNodeRef, children: _jsx(DragIndicatorIcon, {}) }), _jsx(FormControlLabel, { control: _jsx(Checkbox, { name: "item", value: item.id, checked: selectedIds.includes(item.id), onChange: (e) => {
42
+ }, itemRenderer: (item, style, { sortable: { index }, ref, handleRef }) => (_jsxs(Grid, { size: { xs: 12, md: 6, lg: 4 }, display: "flex", justifyContent: "flex-start", alignItems: "center", gap: 1, ref: ref, style: style, children: [_jsx(IconButton, { style: { cursor: "move" }, size: "small", title: labels?.dragIndicator, ref: handleRef, children: _jsx(DragIndicatorIcon, {}) }), _jsx(FormControlLabel, { control: _jsx(Checkbox, { name: "item", value: item.id, checked: selectedIds.includes(item.id), onChange: (e) => {
43
43
  const checked = e.target.checked;
44
44
  const newIds = [
45
45
  ...selectedIds.toggleItem(item.id, checked)
46
46
  ];
47
47
  setSelectedIdsHandler(newIds);
48
- } }), label: `${index + 1}. ${labelFormatter(item)}` })] })), height: 200, mRef: dndRef }), onAdd && (_jsxs(HBox, { gap: 1, children: [_jsx(TextField, { variant: "outlined", label: labels?.more, fullWidth: true, inputRef: inputRef }), _jsx(Button, { sx: { width: "120px" }, variant: "contained", startIcon: _jsx(AddIcon, {}), size: "small", onClick: async () => {
48
+ } }), label: `${index + 1}. ${labelFormatter(item)}` })] })), mRef: dndRef }), onAdd && (_jsxs(HBox, { gap: 1, children: [_jsx(TextField, { variant: "outlined", label: labels?.more, fullWidth: true, inputRef: inputRef }), _jsx(Button, { sx: { width: "120px" }, variant: "contained", startIcon: _jsx(AddIcon, {}), size: "small", onClick: async () => {
49
49
  if (inputRef.current == null)
50
50
  return;
51
51
  const input = inputRef.current.value.trim();
@@ -76,6 +76,8 @@ export function ButtonPopupCheckbox(props) {
76
76
  const app = useRequiredAppContext();
77
77
  // Destruct
78
78
  const { addSplitter, value = [], inputName, label, labelEnd, labelFormatter = (data) => {
79
+ if (typeof labelField === "function")
80
+ return labelField(data);
79
81
  if (labelField in data) {
80
82
  return data[labelField];
81
83
  }
@@ -0,0 +1,105 @@
1
+ import { DataTypes, IdType } from "@etsoo/shared";
2
+ import React from "react";
3
+ import { CSSProperties, Theme } from "@mui/material/styles";
4
+ import { useSortable } from "@dnd-kit/react/sortable";
5
+ import { DragDropEvents } from "@dnd-kit/react";
6
+ /**
7
+ * DnD sortable item default style
8
+ * @param index Item index
9
+ * @param isDragging Is dragging
10
+ * @param theme Theme
11
+ * @returns Style
12
+ */
13
+ export declare const DnDSortableItemStyle: (index: number, isDragging: boolean, theme: Theme) => {
14
+ padding: string;
15
+ transform: string;
16
+ zIndex: string | number;
17
+ boxShadow: string;
18
+ background: string;
19
+ };
20
+ /**
21
+ * DnD sortable list forward ref
22
+ */
23
+ export interface DnDSortableListRef<D extends object> {
24
+ /**
25
+ * Add item
26
+ * @param item New item
27
+ */
28
+ addItem(item: D): void;
29
+ /**
30
+ * Add items
31
+ * @param items items
32
+ */
33
+ addItems(items: D[]): void;
34
+ /**
35
+ * Delete item
36
+ * @param index Item index
37
+ */
38
+ deleteItem(index: number): void;
39
+ /**
40
+ * Edit item
41
+ * @param newItem New item
42
+ * @param index Index
43
+ */
44
+ editItem(newItem: D, index: number): boolean;
45
+ /**
46
+ * Get all items
47
+ */
48
+ getItems(): D[];
49
+ }
50
+ /**
51
+ * DnD sortable list props
52
+ */
53
+ export type DnDSortableListProps<D extends object, E extends React.ElementType = React.ElementType> = {
54
+ /**
55
+ * Component type to render the list into
56
+ * Default is React.Fragment
57
+ */
58
+ component?: E;
59
+ /**
60
+ * Component props
61
+ */
62
+ componentProps?: React.ComponentProps<E>;
63
+ /**
64
+ * List items
65
+ */
66
+ items: D[];
67
+ /**
68
+ * Id field
69
+ */
70
+ idField?: DataTypes.Keys<D> | ((item: D) => IdType);
71
+ /**
72
+ * Label field
73
+ */
74
+ labelField: DataTypes.Keys<D, string> | ((item: D) => string);
75
+ /**
76
+ * Methods ref
77
+ */
78
+ mRef?: React.Ref<DnDSortableListRef<D>>;
79
+ /**
80
+ * Item renderer
81
+ */
82
+ itemRenderer: (data: D, style: CSSProperties, state: ReturnType<typeof useSortable<D>>) => React.ReactElement;
83
+ /**
84
+ * Get list item style callback
85
+ */
86
+ itemStyle?: (index: number, isDragging: boolean) => CSSProperties;
87
+ /**
88
+ * Data change handler
89
+ */
90
+ onChange?: (items: D[]) => void;
91
+ /**
92
+ * Drag start handler
93
+ */
94
+ onDragStart?: (items: D[], source: Parameters<DragDropEvents["dragstart"]>[0]) => void;
95
+ /**
96
+ * Drag end handler
97
+ */
98
+ onDragEnd?: (items: D[], ...args: Parameters<DragDropEvents["dragend"]>) => void;
99
+ };
100
+ /**
101
+ * DnD sortable list component
102
+ * @param props Props
103
+ * @returns Component
104
+ */
105
+ export declare function DnDSortableList<D extends object, E extends React.ElementType = React.ElementType>(props: DnDSortableListProps<D, E>): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,122 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import React from "react";
3
+ import { useTheme } from "@mui/material/styles";
4
+ import { useSortable } from "@dnd-kit/react/sortable";
5
+ import { DragDropProvider } from "@dnd-kit/react";
6
+ /**
7
+ * DnD sortable item default style
8
+ * @param index Item index
9
+ * @param isDragging Is dragging
10
+ * @param theme Theme
11
+ * @returns Style
12
+ */
13
+ export const DnDSortableItemStyle = (index, isDragging, theme) => ({
14
+ padding: theme.spacing(1),
15
+ transform: isDragging ? "scale(1.03)" : "none",
16
+ zIndex: isDragging ? 1 : "auto",
17
+ boxShadow: isDragging
18
+ ? `-1px 0 8px 0 ${theme.palette.grey[400]}, 0px 8px 8px 0 ${theme.palette.grey[200]}`
19
+ : "none",
20
+ background: isDragging
21
+ ? theme.palette.primary.light
22
+ : index % 2 === 0
23
+ ? theme.palette.grey[100]
24
+ : theme.palette.grey[50]
25
+ });
26
+ function SortableItem(props) {
27
+ const theme = useTheme();
28
+ const { id, data, index, itemRenderer, itemStyle = (index, isDragging) => DnDSortableItemStyle(index, isDragging, theme) } = props;
29
+ const state = useSortable({ id, data, index });
30
+ const style = itemStyle(index, state.isDragging);
31
+ return itemRenderer(data, style, state);
32
+ }
33
+ /**
34
+ * DnD sortable list component
35
+ * @param props Props
36
+ * @returns Component
37
+ */
38
+ export function DnDSortableList(props) {
39
+ // Destruct
40
+ const Component = props.component || React.Fragment;
41
+ const { componentProps, idField, itemRenderer, itemStyle, labelField, mRef, onChange, onDragStart, onDragEnd } = props;
42
+ const idFn = typeof idField === "function"
43
+ ? idField
44
+ : (item) => !idField
45
+ ? Reflect.get(item, "id")
46
+ : item[idField];
47
+ const labelFn = React.useCallback(typeof labelField === "function"
48
+ ? labelField
49
+ : (item) => item[labelField], [labelField]);
50
+ // States
51
+ const [items, setItems] = React.useState([]);
52
+ React.useEffect(() => {
53
+ setItems(props.items);
54
+ }, [props.items]);
55
+ const changeItems = React.useCallback((newItems) => {
56
+ // Possible to alter items with the handler
57
+ onChange?.(newItems);
58
+ // Update state
59
+ setItems(newItems);
60
+ }, [onChange]);
61
+ // Methods
62
+ React.useImperativeHandle(mRef, () => {
63
+ return {
64
+ addItem(newItem) {
65
+ // Existence check
66
+ if (items.some((item) => labelFn(item) === labelFn(newItem))) {
67
+ return false;
68
+ }
69
+ // Clone
70
+ const newItems = [newItem, ...items];
71
+ // Update the state
72
+ changeItems(newItems);
73
+ return true;
74
+ },
75
+ addItems(inputItems) {
76
+ // Clone
77
+ const newItems = [...items];
78
+ // Insert items
79
+ inputItems.forEach((newItem) => {
80
+ // Existence check
81
+ if (newItems.some((item) => labelFn(item) === labelFn(newItem))) {
82
+ return;
83
+ }
84
+ newItems.push(newItem);
85
+ });
86
+ // Update the state
87
+ changeItems(newItems);
88
+ return newItems.length - items.length;
89
+ },
90
+ editItem(newItem, index) {
91
+ // Existence check
92
+ const newIndex = items.findIndex((item) => labelFn(item) === labelFn(newItem));
93
+ if (newIndex >= 0 && newIndex !== index) {
94
+ // Label field is the same with a different item
95
+ return false;
96
+ }
97
+ // Clone
98
+ const newItems = [...items];
99
+ // Remove the item
100
+ newItems.splice(index, 1, newItem);
101
+ // Update the state
102
+ changeItems(newItems);
103
+ return true;
104
+ },
105
+ deleteItem(index) {
106
+ // Clone
107
+ const newItems = [...items];
108
+ // Remove the item
109
+ newItems.splice(index, 1);
110
+ // Update the state
111
+ changeItems(newItems);
112
+ },
113
+ getItems() {
114
+ return items;
115
+ }
116
+ };
117
+ }, [items, labelFn, changeItems]);
118
+ return (_jsx(DragDropProvider, { onDragStart: (source) => onDragStart?.(items, source), onDragEnd: (source, target) => onDragEnd?.(items, source, target), children: _jsx(Component, { ...componentProps, children: items.map((item, index) => {
119
+ const id = idFn(item);
120
+ return (_jsx(SortableItem, { id: id, index: index, data: item, itemRenderer: itemRenderer, itemStyle: itemStyle }, id));
121
+ }) }) }));
122
+ }
@@ -54,7 +54,7 @@ export * from "./DataLoadField";
54
54
  export * from "./DataSteps";
55
55
  export * from "./DataTable";
56
56
  export * from "./DialogButton";
57
- export * from "./DnDList";
57
+ export * from "./DnDSortableList";
58
58
  export * from "./DownUpButton";
59
59
  export * from "./DraggablePaperComponent";
60
60
  export * from "./EmailInput";
package/lib/mjs/index.js CHANGED
@@ -54,7 +54,7 @@ export * from "./DataLoadField";
54
54
  export * from "./DataSteps";
55
55
  export * from "./DataTable";
56
56
  export * from "./DialogButton";
57
- export * from "./DnDList";
57
+ export * from "./DnDSortableList";
58
58
  export * from "./DownUpButton";
59
59
  export * from "./DraggablePaperComponent";
60
60
  export * from "./EmailInput";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@etsoo/materialui",
3
- "version": "1.6.11",
3
+ "version": "1.6.12",
4
4
  "description": "TypeScript Material-UI Implementation",
5
5
  "main": "lib/cjs/index.js",
6
6
  "module": "lib/mjs/index.js",
@@ -36,8 +36,7 @@
36
36
  },
37
37
  "homepage": "https://github.com/ETSOO/ReactMU#readme",
38
38
  "dependencies": {
39
- "@dnd-kit/core": "^6.3.1",
40
- "@dnd-kit/sortable": "^10.0.0",
39
+ "@dnd-kit/react": "^0.3.2",
41
40
  "@emotion/react": "^11.14.0",
42
41
  "@emotion/styled": "^11.14.1",
43
42
  "@etsoo/appscript": "^1.6.53",
@@ -46,7 +45,7 @@
46
45
  "@etsoo/shared": "^1.2.80",
47
46
  "@mui/icons-material": "^7.3.8",
48
47
  "@mui/material": "^7.3.8",
49
- "@mui/x-data-grid": "^8.27.1",
48
+ "@mui/x-data-grid": "^8.27.3",
50
49
  "chart.js": "^4.5.1",
51
50
  "chartjs-plugin-datalabels": "^2.2.0",
52
51
  "dompurify": "^3.3.1",