@etsoo/materialui 1.5.61 → 1.5.63

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.
@@ -65,8 +65,10 @@ function DnDList(props) {
65
65
  setItems(props.items);
66
66
  }, [props.items]);
67
67
  const doFormChange = react_1.default.useCallback((newItems) => {
68
- if (onFormChange)
69
- onFormChange(newItems ?? items);
68
+ if (onFormChange) {
69
+ const locals = Array.isArray(newItems) ? newItems : items;
70
+ onFormChange(locals);
71
+ }
70
72
  }, [items, onFormChange]);
71
73
  const changeItems = react_1.default.useCallback((newItems) => {
72
74
  // Possible to alter items with the handler
@@ -153,38 +155,27 @@ function DnDList(props) {
153
155
  ]);
154
156
  });
155
157
  }, []);
156
- const doChange = react_1.default.useCallback(() => doFormChange(), []);
157
158
  const setupDiv = (div, clearup = false) => {
158
159
  // Inputs
159
160
  div
160
161
  .querySelectorAll("input")
161
162
  .forEach((input) => clearup
162
- ? input.removeEventListener("change", doChange)
163
- : input.addEventListener("change", doChange));
163
+ ? input.removeEventListener("change", doFormChange)
164
+ : input.addEventListener("change", doFormChange));
164
165
  // Textareas
165
166
  div
166
167
  .querySelectorAll("textarea")
167
168
  .forEach((input) => clearup
168
- ? input.removeEventListener("change", doChange)
169
- : input.addEventListener("change", doChange));
169
+ ? input.removeEventListener("change", doFormChange)
170
+ : input.addEventListener("change", doFormChange));
170
171
  // Select
171
172
  div
172
173
  .querySelectorAll("select")
173
174
  .forEach((input) => clearup
174
- ? input.removeEventListener("change", doChange)
175
- : input.addEventListener("change", doChange));
175
+ ? input.removeEventListener("change", doFormChange)
176
+ : input.addEventListener("change", doFormChange));
176
177
  };
177
- const divRef = react_1.default.useRef(null);
178
- react_1.default.useEffect(() => {
179
- if (divRef.current) {
180
- setupDiv(divRef.current);
181
- }
182
- return () => {
183
- if (divRef.current) {
184
- setupDiv(divRef.current, true);
185
- }
186
- };
187
- }, []);
178
+ const divRef = react_1.default.useRef();
188
179
  if (dnd == null) {
189
180
  return (0, jsx_runtime_1.jsx)(Skeleton_1.default, { variant: "rectangular", width: "100%", height: height });
190
181
  }
@@ -233,7 +224,15 @@ function DnDList(props) {
233
224
  return ((0, jsx_runtime_1.jsx)(SortableItem, { id: id, useSortableType: useSortableType, CSSType: CSSType, style: getItemStyle(index, id === activeId), itemRenderer: (nodeRef, actionNodeRef) => itemRenderer(item, index, nodeRef, actionNodeRef) }, id));
234
225
  }) }) }) }));
235
226
  if (onFormChange) {
236
- return ((0, jsx_runtime_1.jsx)("div", { style: { width: "100%" }, ref: divRef, children: children }));
227
+ return ((0, jsx_runtime_1.jsx)("div", { style: { width: "100%" }, ref: (div) => {
228
+ if (div && divRef.current != div) {
229
+ if (divRef.current) {
230
+ setupDiv(divRef.current, true);
231
+ }
232
+ divRef.current = div;
233
+ setupDiv(div);
234
+ }
235
+ }, children: children }));
237
236
  }
238
237
  return children;
239
238
  }
@@ -0,0 +1,11 @@
1
+ import { InputFieldProps } from "./InputField";
2
+ /**
3
+ * JSON data input component properties
4
+ */
5
+ export type JsonDataInputProps = Omit<InputFieldProps, "multiple">;
6
+ /**
7
+ * JSON data input component
8
+ * @param props - Component properties
9
+ * @returns JSX Element
10
+ */
11
+ export declare function JsonDataInput(props: JsonDataInputProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,43 @@
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.JsonDataInput = JsonDataInput;
7
+ const jsx_runtime_1 = require("react/jsx-runtime");
8
+ const react_1 = __importDefault(require("react"));
9
+ const InputField_1 = require("./InputField");
10
+ const ReactApp_1 = require("./app/ReactApp");
11
+ /**
12
+ * JSON data input component
13
+ * @param props - Component properties
14
+ * @returns JSX Element
15
+ */
16
+ function JsonDataInput(props) {
17
+ // Destruct
18
+ const { onChange, rows = 3, ...rest } = props;
19
+ // Global app
20
+ const app = (0, ReactApp_1.useRequiredAppContext)();
21
+ const jsonError = app.get("jsonDataError") ?? "JSON format error";
22
+ // Error message
23
+ const [error, setError] = react_1.default.useState();
24
+ // Layout
25
+ return ((0, jsx_runtime_1.jsx)(InputField_1.InputField, { multiline: true, rows: rows, ...rest, error: !!error, helperText: error, onChange: (e) => {
26
+ if (onChange) {
27
+ onChange(e);
28
+ if (e.isDefaultPrevented())
29
+ return;
30
+ }
31
+ const json = e.target.value;
32
+ if (json) {
33
+ try {
34
+ JSON.parse(json);
35
+ }
36
+ catch (e) {
37
+ setError(`${jsonError}: ${e instanceof Error ? e.message : String(e)}`);
38
+ return;
39
+ }
40
+ }
41
+ setError(undefined);
42
+ } }));
43
+ }
@@ -70,6 +70,7 @@ export * from "./InputField";
70
70
  export * from "./InputTipField";
71
71
  export * from "./IntInputField";
72
72
  export * from "./ItemList";
73
+ export * from "./JsonDataInput";
73
74
  export * from "./LineChart";
74
75
  export * from "./LinkEx";
75
76
  export * from "./ListChooser";
package/lib/cjs/index.js CHANGED
@@ -86,6 +86,7 @@ __exportStar(require("./InputField"), exports);
86
86
  __exportStar(require("./InputTipField"), exports);
87
87
  __exportStar(require("./IntInputField"), exports);
88
88
  __exportStar(require("./ItemList"), exports);
89
+ __exportStar(require("./JsonDataInput"), exports);
89
90
  __exportStar(require("./LineChart"), exports);
90
91
  __exportStar(require("./LinkEx"), exports);
91
92
  __exportStar(require("./ListChooser"), exports);
@@ -57,8 +57,10 @@ export function DnDList(props) {
57
57
  setItems(props.items);
58
58
  }, [props.items]);
59
59
  const doFormChange = React.useCallback((newItems) => {
60
- if (onFormChange)
61
- onFormChange(newItems ?? items);
60
+ if (onFormChange) {
61
+ const locals = Array.isArray(newItems) ? newItems : items;
62
+ onFormChange(locals);
63
+ }
62
64
  }, [items, onFormChange]);
63
65
  const changeItems = React.useCallback((newItems) => {
64
66
  // Possible to alter items with the handler
@@ -145,38 +147,27 @@ export function DnDList(props) {
145
147
  ]);
146
148
  });
147
149
  }, []);
148
- const doChange = React.useCallback(() => doFormChange(), []);
149
150
  const setupDiv = (div, clearup = false) => {
150
151
  // Inputs
151
152
  div
152
153
  .querySelectorAll("input")
153
154
  .forEach((input) => clearup
154
- ? input.removeEventListener("change", doChange)
155
- : input.addEventListener("change", doChange));
155
+ ? input.removeEventListener("change", doFormChange)
156
+ : input.addEventListener("change", doFormChange));
156
157
  // Textareas
157
158
  div
158
159
  .querySelectorAll("textarea")
159
160
  .forEach((input) => clearup
160
- ? input.removeEventListener("change", doChange)
161
- : input.addEventListener("change", doChange));
161
+ ? input.removeEventListener("change", doFormChange)
162
+ : input.addEventListener("change", doFormChange));
162
163
  // Select
163
164
  div
164
165
  .querySelectorAll("select")
165
166
  .forEach((input) => clearup
166
- ? input.removeEventListener("change", doChange)
167
- : input.addEventListener("change", doChange));
167
+ ? input.removeEventListener("change", doFormChange)
168
+ : input.addEventListener("change", doFormChange));
168
169
  };
169
- const divRef = React.useRef(null);
170
- React.useEffect(() => {
171
- if (divRef.current) {
172
- setupDiv(divRef.current);
173
- }
174
- return () => {
175
- if (divRef.current) {
176
- setupDiv(divRef.current, true);
177
- }
178
- };
179
- }, []);
170
+ const divRef = React.useRef();
180
171
  if (dnd == null) {
181
172
  return _jsx(Skeleton, { variant: "rectangular", width: "100%", height: height });
182
173
  }
@@ -225,7 +216,15 @@ export function DnDList(props) {
225
216
  return (_jsx(SortableItem, { id: id, useSortableType: useSortableType, CSSType: CSSType, style: getItemStyle(index, id === activeId), itemRenderer: (nodeRef, actionNodeRef) => itemRenderer(item, index, nodeRef, actionNodeRef) }, id));
226
217
  }) }) }) }));
227
218
  if (onFormChange) {
228
- return (_jsx("div", { style: { width: "100%" }, ref: divRef, children: children }));
219
+ return (_jsx("div", { style: { width: "100%" }, ref: (div) => {
220
+ if (div && divRef.current != div) {
221
+ if (divRef.current) {
222
+ setupDiv(divRef.current, true);
223
+ }
224
+ divRef.current = div;
225
+ setupDiv(div);
226
+ }
227
+ }, children: children }));
229
228
  }
230
229
  return children;
231
230
  }
@@ -0,0 +1,11 @@
1
+ import { InputFieldProps } from "./InputField";
2
+ /**
3
+ * JSON data input component properties
4
+ */
5
+ export type JsonDataInputProps = Omit<InputFieldProps, "multiple">;
6
+ /**
7
+ * JSON data input component
8
+ * @param props - Component properties
9
+ * @returns JSX Element
10
+ */
11
+ export declare function JsonDataInput(props: JsonDataInputProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,37 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import React from "react";
3
+ import { InputField } from "./InputField";
4
+ import { useRequiredAppContext } from "./app/ReactApp";
5
+ /**
6
+ * JSON data input component
7
+ * @param props - Component properties
8
+ * @returns JSX Element
9
+ */
10
+ export function JsonDataInput(props) {
11
+ // Destruct
12
+ const { onChange, rows = 3, ...rest } = props;
13
+ // Global app
14
+ const app = useRequiredAppContext();
15
+ const jsonError = app.get("jsonDataError") ?? "JSON format error";
16
+ // Error message
17
+ const [error, setError] = React.useState();
18
+ // Layout
19
+ return (_jsx(InputField, { multiline: true, rows: rows, ...rest, error: !!error, helperText: error, onChange: (e) => {
20
+ if (onChange) {
21
+ onChange(e);
22
+ if (e.isDefaultPrevented())
23
+ return;
24
+ }
25
+ const json = e.target.value;
26
+ if (json) {
27
+ try {
28
+ JSON.parse(json);
29
+ }
30
+ catch (e) {
31
+ setError(`${jsonError}: ${e instanceof Error ? e.message : String(e)}`);
32
+ return;
33
+ }
34
+ }
35
+ setError(undefined);
36
+ } }));
37
+ }
@@ -70,6 +70,7 @@ export * from "./InputField";
70
70
  export * from "./InputTipField";
71
71
  export * from "./IntInputField";
72
72
  export * from "./ItemList";
73
+ export * from "./JsonDataInput";
73
74
  export * from "./LineChart";
74
75
  export * from "./LinkEx";
75
76
  export * from "./ListChooser";
package/lib/mjs/index.js CHANGED
@@ -70,6 +70,7 @@ export * from "./InputField";
70
70
  export * from "./InputTipField";
71
71
  export * from "./IntInputField";
72
72
  export * from "./ItemList";
73
+ export * from "./JsonDataInput";
73
74
  export * from "./LineChart";
74
75
  export * from "./LinkEx";
75
76
  export * from "./ListChooser";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@etsoo/materialui",
3
- "version": "1.5.61",
3
+ "version": "1.5.63",
4
4
  "description": "TypeScript Material-UI Implementation",
5
5
  "main": "lib/cjs/index.js",
6
6
  "module": "lib/mjs/index.js",
@@ -40,14 +40,14 @@
40
40
  "@dnd-kit/sortable": "^10.0.0",
41
41
  "@emotion/react": "^11.14.0",
42
42
  "@emotion/styled": "^11.14.0",
43
- "@etsoo/appscript": "^1.6.38",
44
- "@etsoo/notificationbase": "^1.1.62",
45
- "@etsoo/react": "^1.8.48",
46
- "@etsoo/shared": "^1.2.74",
47
- "@mui/icons-material": "^7.1.1",
48
- "@mui/material": "^7.1.1",
49
- "@mui/x-data-grid": "^8.5.1",
50
- "chart.js": "^4.4.9",
43
+ "@etsoo/appscript": "^1.6.41",
44
+ "@etsoo/notificationbase": "^1.1.63",
45
+ "@etsoo/react": "^1.8.49",
46
+ "@etsoo/shared": "^1.2.75",
47
+ "@mui/icons-material": "^7.1.2",
48
+ "@mui/material": "^7.1.2",
49
+ "@mui/x-data-grid": "^8.5.3",
50
+ "chart.js": "^4.5.0",
51
51
  "chartjs-plugin-datalabels": "^2.2.0",
52
52
  "dompurify": "^3.2.6",
53
53
  "eventemitter3": "^5.0.1",
@@ -81,9 +81,9 @@
81
81
  "@types/react-dom": "^18.3.7",
82
82
  "@types/react-input-mask": "^3.0.6",
83
83
  "@types/react-window": "^1.8.8",
84
- "@vitejs/plugin-react": "^4.5.1",
84
+ "@vitejs/plugin-react": "^4.5.2",
85
85
  "jsdom": "^26.1.0",
86
86
  "typescript": "^5.8.3",
87
- "vitest": "^3.2.2"
87
+ "vitest": "^3.2.4"
88
88
  }
89
89
  }
package/src/DnDList.tsx CHANGED
@@ -231,8 +231,11 @@ export function DnDList<
231
231
  }, [props.items]);
232
232
 
233
233
  const doFormChange = React.useCallback(
234
- (newItems?: D[]) => {
235
- if (onFormChange) onFormChange(newItems ?? items);
234
+ (newItems?: D[] | Event) => {
235
+ if (onFormChange) {
236
+ const locals = Array.isArray(newItems) ? newItems : items;
237
+ onFormChange(locals);
238
+ }
236
239
  },
237
240
  [items, onFormChange]
238
241
  );
@@ -380,16 +383,14 @@ export function DnDList<
380
383
  );
381
384
  }, []);
382
385
 
383
- const doChange = React.useCallback(() => doFormChange(), []);
384
-
385
386
  const setupDiv = (div: HTMLDivElement, clearup: boolean = false) => {
386
387
  // Inputs
387
388
  div
388
389
  .querySelectorAll("input")
389
390
  .forEach((input) =>
390
391
  clearup
391
- ? input.removeEventListener("change", doChange)
392
- : input.addEventListener("change", doChange)
392
+ ? input.removeEventListener("change", doFormChange)
393
+ : input.addEventListener("change", doFormChange)
393
394
  );
394
395
 
395
396
  // Textareas
@@ -397,8 +398,8 @@ export function DnDList<
397
398
  .querySelectorAll("textarea")
398
399
  .forEach((input) =>
399
400
  clearup
400
- ? input.removeEventListener("change", doChange)
401
- : input.addEventListener("change", doChange)
401
+ ? input.removeEventListener("change", doFormChange)
402
+ : input.addEventListener("change", doFormChange)
402
403
  );
403
404
 
404
405
  // Select
@@ -406,24 +407,12 @@ export function DnDList<
406
407
  .querySelectorAll("select")
407
408
  .forEach((input) =>
408
409
  clearup
409
- ? input.removeEventListener("change", doChange)
410
- : input.addEventListener("change", doChange)
410
+ ? input.removeEventListener("change", doFormChange)
411
+ : input.addEventListener("change", doFormChange)
411
412
  );
412
413
  };
413
414
 
414
- const divRef = React.useRef<HTMLDivElement>(null);
415
-
416
- React.useEffect(() => {
417
- if (divRef.current) {
418
- setupDiv(divRef.current);
419
- }
420
-
421
- return () => {
422
- if (divRef.current) {
423
- setupDiv(divRef.current, true);
424
- }
425
- };
426
- }, []);
415
+ const divRef = React.useRef<HTMLDivElement>();
427
416
 
428
417
  if (dnd == null) {
429
418
  return <Skeleton variant="rectangular" width="100%" height={height} />;
@@ -517,7 +506,19 @@ export function DnDList<
517
506
 
518
507
  if (onFormChange) {
519
508
  return (
520
- <div style={{ width: "100%" }} ref={divRef}>
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
+ >
521
522
  {children}
522
523
  </div>
523
524
  );
@@ -0,0 +1,56 @@
1
+ import React from "react";
2
+ import { InputField, InputFieldProps } from "./InputField";
3
+ import { useRequiredAppContext } from "./app/ReactApp";
4
+
5
+ /**
6
+ * JSON data input component properties
7
+ */
8
+ export type JsonDataInputProps = Omit<InputFieldProps, "multiple">;
9
+
10
+ /**
11
+ * JSON data input component
12
+ * @param props - Component properties
13
+ * @returns JSX Element
14
+ */
15
+ export function JsonDataInput(props: JsonDataInputProps) {
16
+ // Destruct
17
+ const { onChange, rows = 3, ...rest } = props;
18
+
19
+ // Global app
20
+ const app = useRequiredAppContext();
21
+ const jsonError = app.get("jsonDataError") ?? "JSON format error";
22
+
23
+ // Error message
24
+ const [error, setError] = React.useState<string>();
25
+
26
+ // Layout
27
+ return (
28
+ <InputField
29
+ multiline
30
+ rows={rows}
31
+ {...rest}
32
+ error={!!error}
33
+ helperText={error}
34
+ onChange={(e) => {
35
+ if (onChange) {
36
+ onChange(e);
37
+ if (e.isDefaultPrevented()) return;
38
+ }
39
+
40
+ const json = e.target.value;
41
+ if (json) {
42
+ try {
43
+ JSON.parse(json);
44
+ } catch (e) {
45
+ setError(
46
+ `${jsonError}: ${e instanceof Error ? e.message : String(e)}`
47
+ );
48
+ return;
49
+ }
50
+ }
51
+
52
+ setError(undefined);
53
+ }}
54
+ />
55
+ );
56
+ }
package/src/index.ts CHANGED
@@ -76,6 +76,7 @@ export * from "./InputField";
76
76
  export * from "./InputTipField";
77
77
  export * from "./IntInputField";
78
78
  export * from "./ItemList";
79
+ export * from "./JsonDataInput";
79
80
  export * from "./LineChart";
80
81
  export * from "./LinkEx";
81
82
  export * from "./ListChooser";