@etsoo/materialui 1.5.70 → 1.5.71

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 (50) hide show
  1. package/__tests__/tsconfig.json +1 -1
  2. package/lib/cjs/ButtonPopupCheckbox.js +1 -1
  3. package/lib/cjs/ButtonPopupRadio.js +1 -1
  4. package/lib/cjs/DnDList.js +1 -1
  5. package/lib/cjs/ScrollerListEx.js +1 -1
  6. package/lib/cjs/SelectEx.js +2 -2
  7. package/lib/cjs/app/ReactApp.d.ts +1 -3
  8. package/lib/cjs/custom/FieldDateInput.js +1 -1
  9. package/lib/cjs/custom/FieldInput.js +1 -1
  10. package/lib/cjs/custom/FieldJson.js +1 -1
  11. package/lib/cjs/custom/FieldNumberInput.js +1 -1
  12. package/lib/cjs/custom/FieldTexarea.js +1 -1
  13. package/lib/cjs/html/HtmlDiv.d.ts +24 -7
  14. package/lib/cjs/html/HtmlDiv.js +5 -1
  15. package/lib/cjs/pages/DataGridPage.js +1 -1
  16. package/lib/cjs/pages/FixedListPage.js +1 -1
  17. package/lib/cjs/pages/ListPage.js +1 -1
  18. package/lib/mjs/ButtonPopupCheckbox.js +1 -1
  19. package/lib/mjs/ButtonPopupRadio.js +1 -1
  20. package/lib/mjs/DnDList.js +1 -1
  21. package/lib/mjs/ScrollerListEx.js +1 -1
  22. package/lib/mjs/SelectEx.js +2 -2
  23. package/lib/mjs/app/ReactApp.d.ts +1 -3
  24. package/lib/mjs/custom/FieldDateInput.js +1 -1
  25. package/lib/mjs/custom/FieldInput.js +1 -1
  26. package/lib/mjs/custom/FieldJson.js +1 -1
  27. package/lib/mjs/custom/FieldNumberInput.js +1 -1
  28. package/lib/mjs/custom/FieldTexarea.js +1 -1
  29. package/lib/mjs/html/HtmlDiv.d.ts +24 -7
  30. package/lib/mjs/html/HtmlDiv.js +2 -1
  31. package/lib/mjs/pages/DataGridPage.js +1 -1
  32. package/lib/mjs/pages/FixedListPage.js +1 -1
  33. package/lib/mjs/pages/ListPage.js +1 -1
  34. package/package.json +6 -6
  35. package/setupTests.ts +2 -0
  36. package/src/ButtonPopupCheckbox.tsx +1 -1
  37. package/src/ButtonPopupRadio.tsx +1 -1
  38. package/src/DnDList.tsx +1 -1
  39. package/src/ScrollerListEx.tsx +1 -1
  40. package/src/SelectEx.tsx +2 -2
  41. package/src/custom/CustomFieldUtils.tsx +1 -1
  42. package/src/custom/FieldDateInput.tsx +1 -1
  43. package/src/custom/FieldInput.tsx +1 -1
  44. package/src/custom/FieldJson.tsx +1 -1
  45. package/src/custom/FieldNumberInput.tsx +1 -1
  46. package/src/custom/FieldTexarea.tsx +1 -1
  47. package/src/html/HtmlDiv.tsx +13 -9
  48. package/src/pages/DataGridPage.tsx +1 -1
  49. package/src/pages/FixedListPage.tsx +1 -1
  50. package/src/pages/ListPage.tsx +1 -1
@@ -12,7 +12,7 @@
12
12
  "resolveJsonModule": true,
13
13
  "isolatedModules": true,
14
14
  "noEmit": true,
15
- "jsx": "react",
15
+ "jsx": "react-jsx",
16
16
  "declaration": true,
17
17
  "types": ["vitest/globals"]
18
18
  },
@@ -115,7 +115,7 @@ function ButtonPopupCheckbox(props) {
115
115
  setSelectedIds(value);
116
116
  }, [value]);
117
117
  // Selected ids
118
- const tempSelectedIds = react_1.default.useRef();
118
+ const tempSelectedIds = react_1.default.useRef(null);
119
119
  // Click handler
120
120
  const clickHandler = () => {
121
121
  app.showInputDialog({
@@ -102,7 +102,7 @@ function ButtonPopupRadio(props) {
102
102
  setCurrentValue(value);
103
103
  }, [value]);
104
104
  // Selected id
105
- const tempSelectedId = react_1.default.useRef();
105
+ const tempSelectedId = react_1.default.useRef(null);
106
106
  // Click handler
107
107
  const clickHandler = () => {
108
108
  app.showInputDialog({
@@ -175,7 +175,7 @@ function DnDList(props) {
175
175
  ? input.removeEventListener("change", doFormChange)
176
176
  : input.addEventListener("change", doFormChange));
177
177
  };
178
- const divRef = react_1.default.useRef();
178
+ const divRef = react_1.default.useRef(null);
179
179
  if (dnd == null) {
180
180
  return (0, jsx_runtime_1.jsx)(Skeleton_1.default, { variant: "rectangular", width: "100%", height: height });
181
181
  }
@@ -99,7 +99,7 @@ function defaultItemRenderer({ index, innerItemRenderer, data, onMouseDown, sele
99
99
  */
100
100
  function ScrollerListEx(props) {
101
101
  // Selected item ref
102
- const selectedItem = react_2.default.useRef();
102
+ const selectedItem = react_2.default.useRef(null);
103
103
  const onMouseDown = (div, data) => {
104
104
  // Destruct
105
105
  const [selectedDiv, selectedData] = selectedItem.current ?? [];
@@ -69,7 +69,7 @@ function SelectEx(props) {
69
69
  }, [options, propertyWay, setOptionsAdd]);
70
70
  // Value state
71
71
  const [valueState, setValueStateBase] = react_1.default.useState(valueSource);
72
- const valueRef = react_1.default.useRef();
72
+ const valueRef = react_1.default.useRef(null);
73
73
  const setValueState = (newValue) => {
74
74
  valueRef.current = newValue;
75
75
  setValueStateBase(newValue);
@@ -114,7 +114,7 @@ function SelectEx(props) {
114
114
  : option[labelField];
115
115
  };
116
116
  // Refs
117
- const divRef = react_1.default.useRef();
117
+ const divRef = react_1.default.useRef(null);
118
118
  // Refresh list data
119
119
  const refreshData = () => {
120
120
  if (loadData == null)
@@ -173,9 +173,7 @@ export declare class ReactApp<S extends IAppSettings, D extends IUser> extends C
173
173
  * @param props Props
174
174
  */
175
175
  showInputDialog({ title, message, callback, ...rest }: InputDialogProps): INotificationReact;
176
- stateDetector(props: IStateProps): React.FunctionComponentElement<{
177
- children?: React.ReactNode | undefined;
178
- }>;
176
+ stateDetector(props: IStateProps): React.FunctionComponentElement<React.FragmentProps>;
179
177
  /**
180
178
  * User login extended
181
179
  * @param user New user
@@ -16,7 +16,7 @@ const Typography_1 = __importDefault(require("@mui/material/Typography"));
16
16
  */
17
17
  const FieldDateInput = ({ field, mref, onChange, defaultValue }) => {
18
18
  // Ref
19
- const inputRef = react_1.default.useRef();
19
+ const inputRef = react_1.default.useRef(null);
20
20
  const getValue = () => inputRef.current == null
21
21
  ? undefined
22
22
  : shared_1.DateUtils.parse(inputRef.current.value);
@@ -15,7 +15,7 @@ const Typography_1 = __importDefault(require("@mui/material/Typography"));
15
15
  */
16
16
  const FieldInput = ({ field, mref, onChange, defaultValue }) => {
17
17
  // Ref
18
- const inputRef = react_1.default.useRef();
18
+ const inputRef = react_1.default.useRef(null);
19
19
  const getValue = () => inputRef.current?.value;
20
20
  react_1.default.useImperativeHandle(mref, () => ({
21
21
  getValue,
@@ -26,7 +26,7 @@ function parseJson(value) {
26
26
  */
27
27
  const FieldJson = ({ field, mref, onChange, defaultValue }) => {
28
28
  // Ref
29
- const inputRef = react_1.default.useRef();
29
+ const inputRef = react_1.default.useRef(null);
30
30
  const getValue = () => parseJson(inputRef.current?.value);
31
31
  const setValue = (value) => {
32
32
  if (inputRef.current) {
@@ -16,7 +16,7 @@ const Typography_1 = __importDefault(require("@mui/material/Typography"));
16
16
  */
17
17
  const FieldNumberInput = ({ field, mref, onChange, defaultValue }) => {
18
18
  // Ref
19
- const inputRef = react_1.default.useRef();
19
+ const inputRef = react_1.default.useRef(null);
20
20
  const getValue = () => {
21
21
  const value = inputRef.current?.valueAsNumber;
22
22
  return shared_1.NumberUtils.parse(value);
@@ -15,7 +15,7 @@ const Typography_1 = __importDefault(require("@mui/material/Typography"));
15
15
  */
16
16
  const FieldTexarea = ({ field, mref, onChange, defaultValue }) => {
17
17
  // Ref
18
- const inputRef = react_1.default.useRef();
18
+ const inputRef = react_1.default.useRef(null);
19
19
  const getValue = () => inputRef.current?.value;
20
20
  const setValue = (value) => {
21
21
  if (inputRef.current)
@@ -1,4 +1,27 @@
1
1
  import { HTMLAttributes } from "react";
2
+ declare class HtmlDivElement extends HTMLElement {
3
+ static get observedAttributes(): string[];
4
+ private wrapper;
5
+ private observer;
6
+ private _displayStyle?;
7
+ /**
8
+ * Display style
9
+ */
10
+ get displayStyle(): string | undefined;
11
+ set displayStyle(style: string | undefined);
12
+ constructor();
13
+ connectedCallback(): void;
14
+ disconnectedCallback(): void;
15
+ attributeChangedCallback(name: string, _oldValue: any, newValue: any): void;
16
+ setContent(): void;
17
+ }
18
+ declare module "react" {
19
+ namespace JSX {
20
+ interface IntrinsicElements {
21
+ "html-div": React.DetailedHTMLProps<React.HTMLAttributes<HtmlDivElement>, HtmlDivElement>;
22
+ }
23
+ }
24
+ }
2
25
  /**
3
26
  * Custom HTML element properties
4
27
  * 自定义 HTML 元素属性
@@ -10,13 +33,6 @@ export type HtmlDivProps = HTMLAttributes<HTMLElement> & {
10
33
  */
11
34
  displayStyle?: string;
12
35
  };
13
- declare global {
14
- namespace JSX {
15
- interface IntrinsicElements {
16
- "html-div": React.HTMLAttributes<HTMLElement>;
17
- }
18
- }
19
- }
20
36
  /**
21
37
  * Custom HTML element that sanitizes and displays HTML content
22
38
  * 自定义 HTML 元素,用于清理和显示 HTML 内容
@@ -24,3 +40,4 @@ declare global {
24
40
  * @returns Component
25
41
  */
26
42
  export declare function HtmlDiv(props: HtmlDivProps): import("react/jsx-runtime").JSX.Element;
43
+ export {};
@@ -1,8 +1,12 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.HtmlDiv = HtmlDiv;
4
7
  const jsx_runtime_1 = require("react/jsx-runtime");
5
8
  const shared_1 = require("@etsoo/shared");
9
+ const dompurify_1 = __importDefault(require("dompurify"));
6
10
  class HtmlDivElement extends HTMLElement {
7
11
  static get observedAttributes() {
8
12
  return ["displaystyle"];
@@ -86,7 +90,7 @@ class HtmlDivElement extends HTMLElement {
86
90
  wrapper.innerHTML = this.textContent;
87
91
  }
88
92
  else {
89
- wrapper.innerHTML = html;
93
+ wrapper.innerHTML = dompurify_1.default.sanitize(html);
90
94
  }
91
95
  this.textContent = null; // Clear the textContent to avoid duplication
92
96
  }
@@ -35,7 +35,7 @@ function DataGridPage(props) {
35
35
  states.ref = ref;
36
36
  //setStates({ ref });
37
37
  });
38
- const initLoadedRef = react_2.default.useRef();
38
+ const initLoadedRef = react_2.default.useRef(null);
39
39
  // On submit callback
40
40
  const onSubmit = (data, _reset) => {
41
41
  setStates({ data });
@@ -25,7 +25,7 @@ function FixedListPage(props) {
25
25
  pageProps.paddings ??= MUGlobal_1.MUGlobal.pagePaddings;
26
26
  // States
27
27
  const [states] = react_2.default.useState({});
28
- const initLoadedRef = react_2.default.useRef();
28
+ const initLoadedRef = react_2.default.useRef(null);
29
29
  // Scroll container
30
30
  const [scrollContainer, updateScrollContainer] = react_2.default.useState();
31
31
  const refs = (0, react_1.useCombinedRefs)(mRef, (ref) => {
@@ -33,7 +33,7 @@ function ListPage(props) {
33
33
  if (first)
34
34
  reset();
35
35
  });
36
- const initLoadedRef = react_2.default.useRef();
36
+ const initLoadedRef = react_2.default.useRef(null);
37
37
  const reset = () => {
38
38
  if (states.data == null || states.ref == null)
39
39
  return;
@@ -109,7 +109,7 @@ export function ButtonPopupCheckbox(props) {
109
109
  setSelectedIds(value);
110
110
  }, [value]);
111
111
  // Selected ids
112
- const tempSelectedIds = React.useRef();
112
+ const tempSelectedIds = React.useRef(null);
113
113
  // Click handler
114
114
  const clickHandler = () => {
115
115
  app.showInputDialog({
@@ -96,7 +96,7 @@ export function ButtonPopupRadio(props) {
96
96
  setCurrentValue(value);
97
97
  }, [value]);
98
98
  // Selected id
99
- const tempSelectedId = React.useRef();
99
+ const tempSelectedId = React.useRef(null);
100
100
  // Click handler
101
101
  const clickHandler = () => {
102
102
  app.showInputDialog({
@@ -167,7 +167,7 @@ export function DnDList(props) {
167
167
  ? input.removeEventListener("change", doFormChange)
168
168
  : input.addEventListener("change", doFormChange));
169
169
  };
170
- const divRef = React.useRef();
170
+ const divRef = React.useRef(null);
171
171
  if (dnd == null) {
172
172
  return _jsx(Skeleton, { variant: "rectangular", width: "100%", height: height });
173
173
  }
@@ -93,7 +93,7 @@ function defaultItemRenderer({ index, innerItemRenderer, data, onMouseDown, sele
93
93
  */
94
94
  export function ScrollerListEx(props) {
95
95
  // Selected item ref
96
- const selectedItem = React.useRef();
96
+ const selectedItem = React.useRef(null);
97
97
  const onMouseDown = (div, data) => {
98
98
  // Destruct
99
99
  const [selectedDiv, selectedData] = selectedItem.current ?? [];
@@ -63,7 +63,7 @@ export function SelectEx(props) {
63
63
  }, [options, propertyWay, setOptionsAdd]);
64
64
  // Value state
65
65
  const [valueState, setValueStateBase] = React.useState(valueSource);
66
- const valueRef = React.useRef();
66
+ const valueRef = React.useRef(null);
67
67
  const setValueState = (newValue) => {
68
68
  valueRef.current = newValue;
69
69
  setValueStateBase(newValue);
@@ -108,7 +108,7 @@ export function SelectEx(props) {
108
108
  : option[labelField];
109
109
  };
110
110
  // Refs
111
- const divRef = React.useRef();
111
+ const divRef = React.useRef(null);
112
112
  // Refresh list data
113
113
  const refreshData = () => {
114
114
  if (loadData == null)
@@ -173,9 +173,7 @@ export declare class ReactApp<S extends IAppSettings, D extends IUser> extends C
173
173
  * @param props Props
174
174
  */
175
175
  showInputDialog({ title, message, callback, ...rest }: InputDialogProps): INotificationReact;
176
- stateDetector(props: IStateProps): React.FunctionComponentElement<{
177
- children?: React.ReactNode | undefined;
178
- }>;
176
+ stateDetector(props: IStateProps): React.FunctionComponentElement<React.FragmentProps>;
179
177
  /**
180
178
  * User login extended
181
179
  * @param user New user
@@ -10,7 +10,7 @@ import Typography from "@mui/material/Typography";
10
10
  */
11
11
  export const FieldDateInput = ({ field, mref, onChange, defaultValue }) => {
12
12
  // Ref
13
- const inputRef = React.useRef();
13
+ const inputRef = React.useRef(null);
14
14
  const getValue = () => inputRef.current == null
15
15
  ? undefined
16
16
  : DateUtils.parse(inputRef.current.value);
@@ -9,7 +9,7 @@ import Typography from "@mui/material/Typography";
9
9
  */
10
10
  export const FieldInput = ({ field, mref, onChange, defaultValue }) => {
11
11
  // Ref
12
- const inputRef = React.useRef();
12
+ const inputRef = React.useRef(null);
13
13
  const getValue = () => inputRef.current?.value;
14
14
  React.useImperativeHandle(mref, () => ({
15
15
  getValue,
@@ -20,7 +20,7 @@ function parseJson(value) {
20
20
  */
21
21
  export const FieldJson = ({ field, mref, onChange, defaultValue }) => {
22
22
  // Ref
23
- const inputRef = React.useRef();
23
+ const inputRef = React.useRef(null);
24
24
  const getValue = () => parseJson(inputRef.current?.value);
25
25
  const setValue = (value) => {
26
26
  if (inputRef.current) {
@@ -10,7 +10,7 @@ import Typography from "@mui/material/Typography";
10
10
  */
11
11
  export const FieldNumberInput = ({ field, mref, onChange, defaultValue }) => {
12
12
  // Ref
13
- const inputRef = React.useRef();
13
+ const inputRef = React.useRef(null);
14
14
  const getValue = () => {
15
15
  const value = inputRef.current?.valueAsNumber;
16
16
  return NumberUtils.parse(value);
@@ -9,7 +9,7 @@ import Typography from "@mui/material/Typography";
9
9
  */
10
10
  export const FieldTexarea = ({ field, mref, onChange, defaultValue }) => {
11
11
  // Ref
12
- const inputRef = React.useRef();
12
+ const inputRef = React.useRef(null);
13
13
  const getValue = () => inputRef.current?.value;
14
14
  const setValue = (value) => {
15
15
  if (inputRef.current)
@@ -1,4 +1,27 @@
1
1
  import { HTMLAttributes } from "react";
2
+ declare class HtmlDivElement extends HTMLElement {
3
+ static get observedAttributes(): string[];
4
+ private wrapper;
5
+ private observer;
6
+ private _displayStyle?;
7
+ /**
8
+ * Display style
9
+ */
10
+ get displayStyle(): string | undefined;
11
+ set displayStyle(style: string | undefined);
12
+ constructor();
13
+ connectedCallback(): void;
14
+ disconnectedCallback(): void;
15
+ attributeChangedCallback(name: string, _oldValue: any, newValue: any): void;
16
+ setContent(): void;
17
+ }
18
+ declare module "react" {
19
+ namespace JSX {
20
+ interface IntrinsicElements {
21
+ "html-div": React.DetailedHTMLProps<React.HTMLAttributes<HtmlDivElement>, HtmlDivElement>;
22
+ }
23
+ }
24
+ }
2
25
  /**
3
26
  * Custom HTML element properties
4
27
  * 自定义 HTML 元素属性
@@ -10,13 +33,6 @@ export type HtmlDivProps = HTMLAttributes<HTMLElement> & {
10
33
  */
11
34
  displayStyle?: string;
12
35
  };
13
- declare global {
14
- namespace JSX {
15
- interface IntrinsicElements {
16
- "html-div": React.HTMLAttributes<HTMLElement>;
17
- }
18
- }
19
- }
20
36
  /**
21
37
  * Custom HTML element that sanitizes and displays HTML content
22
38
  * 自定义 HTML 元素,用于清理和显示 HTML 内容
@@ -24,3 +40,4 @@ declare global {
24
40
  * @returns Component
25
41
  */
26
42
  export declare function HtmlDiv(props: HtmlDivProps): import("react/jsx-runtime").JSX.Element;
43
+ export {};
@@ -1,5 +1,6 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { Utils } from "@etsoo/shared";
3
+ import DOMPurify from "dompurify";
3
4
  class HtmlDivElement extends HTMLElement {
4
5
  static get observedAttributes() {
5
6
  return ["displaystyle"];
@@ -83,7 +84,7 @@ class HtmlDivElement extends HTMLElement {
83
84
  wrapper.innerHTML = this.textContent;
84
85
  }
85
86
  else {
86
- wrapper.innerHTML = html;
87
+ wrapper.innerHTML = DOMPurify.sanitize(html);
87
88
  }
88
89
  this.textContent = null; // Clear the textContent to avoid duplication
89
90
  }
@@ -29,7 +29,7 @@ export function DataGridPage(props) {
29
29
  states.ref = ref;
30
30
  //setStates({ ref });
31
31
  });
32
- const initLoadedRef = React.useRef();
32
+ const initLoadedRef = React.useRef(null);
33
33
  // On submit callback
34
34
  const onSubmit = (data, _reset) => {
35
35
  setStates({ data });
@@ -19,7 +19,7 @@ export function FixedListPage(props) {
19
19
  pageProps.paddings ??= MUGlobal.pagePaddings;
20
20
  // States
21
21
  const [states] = React.useState({});
22
- const initLoadedRef = React.useRef();
22
+ const initLoadedRef = React.useRef(null);
23
23
  // Scroll container
24
24
  const [scrollContainer, updateScrollContainer] = React.useState();
25
25
  const refs = useCombinedRefs(mRef, (ref) => {
@@ -27,7 +27,7 @@ export function ListPage(props) {
27
27
  if (first)
28
28
  reset();
29
29
  });
30
- const initLoadedRef = React.useRef();
30
+ const initLoadedRef = React.useRef(null);
31
31
  const reset = () => {
32
32
  if (states.data == null || states.ref == null)
33
33
  return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@etsoo/materialui",
3
- "version": "1.5.70",
3
+ "version": "1.5.71",
4
4
  "description": "TypeScript Material-UI Implementation",
5
5
  "main": "lib/cjs/index.js",
6
6
  "module": "lib/mjs/index.js",
@@ -42,7 +42,7 @@
42
42
  "@emotion/styled": "^11.14.1",
43
43
  "@etsoo/appscript": "^1.6.43",
44
44
  "@etsoo/notificationbase": "^1.1.63",
45
- "@etsoo/react": "^1.8.49",
45
+ "@etsoo/react": "^1.8.51",
46
46
  "@etsoo/shared": "^1.2.75",
47
47
  "@mui/icons-material": "^7.3.1",
48
48
  "@mui/material": "^7.3.1",
@@ -53,10 +53,10 @@
53
53
  "eventemitter3": "^5.0.1",
54
54
  "pica": "^9.0.1",
55
55
  "pulltorefreshjs": "^0.1.22",
56
- "react": "^18.3.1",
56
+ "react": "^19.1.1",
57
57
  "react-avatar-editor": "^13.0.2",
58
58
  "react-chartjs-2": "^5.3.0",
59
- "react-dom": "^18.3.1",
59
+ "react-dom": "^19.1.1",
60
60
  "react-draggable": "^4.5.0",
61
61
  "react-imask": "7.6.1"
62
62
  },
@@ -76,9 +76,9 @@
76
76
  "@testing-library/react": "^16.3.0",
77
77
  "@types/pica": "^9.0.5",
78
78
  "@types/pulltorefreshjs": "^0.1.7",
79
- "@types/react": "^18.3.23",
79
+ "@types/react": "^19.1.10",
80
80
  "@types/react-avatar-editor": "^13.0.4",
81
- "@types/react-dom": "^18.3.7",
81
+ "@types/react-dom": "^19.1.7",
82
82
  "@types/react-input-mask": "^3.0.6",
83
83
  "@types/react-window": "^1.8.8",
84
84
  "@vitejs/plugin-react": "^5.0.1",
package/setupTests.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  import { vi } from "vitest";
2
2
 
3
+ (globalThis as any).IS_REACT_ACT_ENVIRONMENT = true;
4
+
3
5
  vi.mock("localStorage", () => {
4
6
  let store = {} as Storage;
5
7
  return {
@@ -323,7 +323,7 @@ export function ButtonPopupCheckbox<D extends DnDItemType>(
323
323
  }, [value]);
324
324
 
325
325
  // Selected ids
326
- const tempSelectedIds = React.useRef<D["id"][]>();
326
+ const tempSelectedIds = React.useRef<D["id"][]>(null);
327
327
 
328
328
  // Click handler
329
329
  const clickHandler = () => {
@@ -287,7 +287,7 @@ export function ButtonPopupRadio<D extends DnDItemType>(
287
287
  }, [value]);
288
288
 
289
289
  // Selected id
290
- const tempSelectedId = React.useRef<D["id"]>();
290
+ const tempSelectedId = React.useRef<D["id"]>(null);
291
291
 
292
292
  // Click handler
293
293
  const clickHandler = () => {
package/src/DnDList.tsx CHANGED
@@ -412,7 +412,7 @@ export function DnDList<
412
412
  );
413
413
  };
414
414
 
415
- const divRef = React.useRef<HTMLDivElement>();
415
+ const divRef = React.useRef<HTMLDivElement>(null);
416
416
 
417
417
  if (dnd == null) {
418
418
  return <Skeleton variant="rectangular" width="100%" height={height} />;
@@ -263,7 +263,7 @@ export function ScrollerListEx<T extends object>(
263
263
  props: ScrollerListExProps<T>
264
264
  ) {
265
265
  // Selected item ref
266
- const selectedItem = React.useRef<[HTMLDivElement, T]>();
266
+ const selectedItem = React.useRef<[HTMLDivElement, T]>(null);
267
267
 
268
268
  const onMouseDown = (div: HTMLDivElement, data: T) => {
269
269
  // Destruct
package/src/SelectEx.tsx CHANGED
@@ -210,7 +210,7 @@ export function SelectEx<
210
210
 
211
211
  // Value state
212
212
  const [valueState, setValueStateBase] = React.useState<unknown>(valueSource);
213
- const valueRef = React.useRef<unknown>();
213
+ const valueRef = React.useRef<unknown>(null);
214
214
  const setValueState = (newValue: unknown) => {
215
215
  valueRef.current = newValue;
216
216
  setValueStateBase(newValue);
@@ -268,7 +268,7 @@ export function SelectEx<
268
268
  };
269
269
 
270
270
  // Refs
271
- const divRef = React.useRef<HTMLDivElement>();
271
+ const divRef = React.useRef<HTMLDivElement>(null);
272
272
 
273
273
  // Refresh list data
274
274
  const refreshData = () => {
@@ -96,7 +96,7 @@ export namespace CustomFieldUtils {
96
96
  const Creator = creator;
97
97
  const mref = React.createRef<CustomFieldRef<unknown>>();
98
98
 
99
- let ui: JSX.Element | string = (
99
+ let ui: React.ReactNode = (
100
100
  <Creator
101
101
  field={field}
102
102
  mref={mref}
@@ -16,7 +16,7 @@ export const FieldDateInput: ICustomFieldReact<Date> = ({
16
16
  defaultValue
17
17
  }) => {
18
18
  // Ref
19
- const inputRef = React.useRef<HTMLInputElement>();
19
+ const inputRef = React.useRef<HTMLInputElement>(null);
20
20
 
21
21
  const getValue = () =>
22
22
  inputRef.current == null
@@ -15,7 +15,7 @@ export const FieldInput: ICustomFieldReact<string> = ({
15
15
  defaultValue
16
16
  }) => {
17
17
  // Ref
18
- const inputRef = React.useRef<HTMLInputElement>();
18
+ const inputRef = React.useRef<HTMLInputElement>(null);
19
19
 
20
20
  const getValue = () => inputRef.current?.value;
21
21
 
@@ -26,7 +26,7 @@ export const FieldJson: ICustomFieldReact<object> = ({
26
26
  defaultValue
27
27
  }) => {
28
28
  // Ref
29
- const inputRef = React.useRef<HTMLInputElement>();
29
+ const inputRef = React.useRef<HTMLInputElement>(null);
30
30
 
31
31
  const getValue = () => parseJson(inputRef.current?.value);
32
32
 
@@ -16,7 +16,7 @@ export const FieldNumberInput: ICustomFieldReact<number> = ({
16
16
  defaultValue
17
17
  }) => {
18
18
  // Ref
19
- const inputRef = React.useRef<HTMLInputElement>();
19
+ const inputRef = React.useRef<HTMLInputElement>(null);
20
20
 
21
21
  const getValue = () => {
22
22
  const value = inputRef.current?.valueAsNumber;
@@ -15,7 +15,7 @@ export const FieldTexarea: ICustomFieldReact<string> = ({
15
15
  defaultValue
16
16
  }) => {
17
17
  // Ref
18
- const inputRef = React.useRef<HTMLInputElement>();
18
+ const inputRef = React.useRef<HTMLInputElement>(null);
19
19
 
20
20
  const getValue = () => inputRef.current?.value;
21
21
 
@@ -1,5 +1,6 @@
1
1
  import { Utils } from "@etsoo/shared";
2
2
  import { HTMLAttributes } from "react";
3
+ import DOMPurify from "dompurify";
3
4
 
4
5
  class HtmlDivElement extends HTMLElement {
5
6
  static get observedAttributes() {
@@ -96,7 +97,7 @@ class HtmlDivElement extends HTMLElement {
96
97
  ) {
97
98
  wrapper.innerHTML = this.textContent;
98
99
  } else {
99
- wrapper.innerHTML = html;
100
+ wrapper.innerHTML = DOMPurify.sanitize(html);
100
101
  }
101
102
 
102
103
  this.textContent = null; // Clear the textContent to avoid duplication
@@ -108,6 +109,17 @@ if (!customElements.get("html-div")) {
108
109
  customElements.define("html-div", HtmlDivElement);
109
110
  }
110
111
 
112
+ declare module "react" {
113
+ namespace JSX {
114
+ interface IntrinsicElements {
115
+ "html-div": React.DetailedHTMLProps<
116
+ React.HTMLAttributes<HtmlDivElement>,
117
+ HtmlDivElement
118
+ >;
119
+ }
120
+ }
121
+ }
122
+
111
123
  /**
112
124
  * Custom HTML element properties
113
125
  * 自定义 HTML 元素属性
@@ -120,14 +132,6 @@ export type HtmlDivProps = HTMLAttributes<HTMLElement> & {
120
132
  displayStyle?: string;
121
133
  };
122
134
 
123
- declare global {
124
- namespace JSX {
125
- interface IntrinsicElements {
126
- "html-div": React.HTMLAttributes<HTMLElement>;
127
- }
128
- }
129
- }
130
-
131
135
  /**
132
136
  * Custom HTML element that sanitizes and displays HTML content
133
137
  * 自定义 HTML 元素,用于清理和显示 HTML 内容
@@ -70,7 +70,7 @@ export function DataGridPage<T extends object, F>(
70
70
  }
71
71
  );
72
72
 
73
- const initLoadedRef = React.useRef<boolean>();
73
+ const initLoadedRef = React.useRef<boolean>(null);
74
74
 
75
75
  // On submit callback
76
76
  const onSubmit = (data: FormData, _reset: boolean) => {
@@ -56,7 +56,7 @@ export function FixedListPage<T extends object, F>(
56
56
  ref?: ScrollerListForwardRef<T>;
57
57
  }>({});
58
58
 
59
- const initLoadedRef = React.useRef<boolean>();
59
+ const initLoadedRef = React.useRef<boolean>(null);
60
60
 
61
61
  // Scroll container
62
62
  const [scrollContainer, updateScrollContainer] = React.useState<
@@ -62,7 +62,7 @@ export function ListPage<T extends object, F>(props: ListPageProps<T, F>) {
62
62
  if (first) reset();
63
63
  });
64
64
 
65
- const initLoadedRef = React.useRef<boolean>();
65
+ const initLoadedRef = React.useRef<boolean>(null);
66
66
 
67
67
  const reset = () => {
68
68
  if (states.data == null || states.ref == null) return;