@etsoo/materialui 1.5.28 → 1.5.30

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.
@@ -29,6 +29,11 @@ export interface TabBoxProps extends Omit<TabsProps, "value"> {
29
29
  * Current index
30
30
  */
31
31
  index?: number;
32
+ /**
33
+ * Index field of the search params
34
+ * @default 'index'
35
+ */
36
+ indexField?: string;
32
37
  /**
33
38
  * Add a hidden input and its name
34
39
  */
package/lib/cjs/TabBox.js CHANGED
@@ -5,11 +5,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.TabBox = TabBox;
7
7
  const jsx_runtime_1 = require("react/jsx-runtime");
8
+ const react_1 = require("@etsoo/react");
8
9
  const shared_1 = require("@etsoo/shared");
9
10
  const Box_1 = __importDefault(require("@mui/material/Box"));
10
11
  const Tab_1 = __importDefault(require("@mui/material/Tab"));
11
12
  const Tabs_1 = __importDefault(require("@mui/material/Tabs"));
12
- const react_1 = __importDefault(require("react"));
13
+ const react_2 = __importDefault(require("react"));
13
14
  function isActionTab(children) {
14
15
  return typeof children === "function" && children.length === 0;
15
16
  }
@@ -20,16 +21,26 @@ function isActionTab(children) {
20
21
  */
21
22
  function TabBox(props) {
22
23
  // Destruct
23
- const { index, inputName, root, defaultIndex = 0, onChange, tabProps, tabs, ...rest } = props;
24
+ const { index, indexField = "index", inputName, root, defaultIndex = 0, onChange, tabProps, tabs, ...rest } = props;
24
25
  // State
25
- const [value, setValue] = react_1.default.useState(defaultIndex);
26
- react_1.default.useEffect(() => {
26
+ const [params, setSearchParams] = (0, react_1.useSearchParamsEx1)({
27
+ [indexField]: "number"
28
+ });
29
+ const [value, setValue] = react_2.default.useState(params[indexField] ?? defaultIndex);
30
+ react_2.default.useEffect(() => {
27
31
  if (index == null)
28
32
  return;
29
33
  setValue(index);
30
34
  }, [index]);
31
35
  // Layout
32
- return ((0, jsx_runtime_1.jsxs)(react_1.default.Fragment, { children: [inputName && (0, jsx_runtime_1.jsx)("input", { type: "hidden", name: inputName, value: value }), (0, jsx_runtime_1.jsx)(Box_1.default, { ...root, children: (0, jsx_runtime_1.jsx)(Tabs_1.default, { value: value, onChange: (event, newValue) => {
36
+ return ((0, jsx_runtime_1.jsxs)(react_2.default.Fragment, { children: [inputName && (0, jsx_runtime_1.jsx)("input", { type: "hidden", name: inputName, value: value }), (0, jsx_runtime_1.jsx)(Box_1.default, { ...root, children: (0, jsx_runtime_1.jsx)(Tabs_1.default, { value: value, onChange: (event, newValue) => {
37
+ setSearchParams((prev) => {
38
+ if (newValue == defaultIndex)
39
+ prev.delete(indexField);
40
+ else
41
+ prev.set(indexField, newValue);
42
+ return prev;
43
+ });
33
44
  const { children } = tabs[newValue];
34
45
  if (isActionTab(children)) {
35
46
  children();
@@ -39,5 +50,5 @@ function TabBox(props) {
39
50
  if (onChange)
40
51
  onChange(event, newValue);
41
52
  }
42
- }, ...rest, children: tabs.map(({ children, panelProps, ...tabRest }, index) => ((0, jsx_runtime_1.jsx)(Tab_1.default, { value: index, ...tabRest }, index))) }) }), tabs.map(({ children, panelProps }, index) => ((0, jsx_runtime_1.jsx)(Box_1.default, { hidden: value !== index, ...tabProps, ...panelProps, children: isActionTab(children) ? ((0, jsx_runtime_1.jsx)(react_1.default.Fragment, {})) : (shared_1.Utils.getResult(children, value === index)) }, index)))] }));
53
+ }, ...rest, children: tabs.map(({ children, panelProps, ...tabRest }, index) => ((0, jsx_runtime_1.jsx)(Tab_1.default, { value: index, ...tabRest }, index))) }) }), tabs.map(({ children, panelProps }, index) => ((0, jsx_runtime_1.jsx)(Box_1.default, { hidden: value !== index, ...tabProps, ...panelProps, children: isActionTab(children) ? ((0, jsx_runtime_1.jsx)(react_2.default.Fragment, {})) : (shared_1.Utils.getResult(children, value === index)) }, index)))] }));
43
54
  }
@@ -3,7 +3,20 @@ import { HTMLAttributes } from "react";
3
3
  * Custom HTML element properties
4
4
  * 自定义 HTML 元素属性
5
5
  */
6
- export type HtmlDivProps = HTMLAttributes<HTMLElement>;
6
+ export type HtmlDivProps = HTMLAttributes<HTMLElement> & {
7
+ /**
8
+ * Display style
9
+ * 显示样式
10
+ */
11
+ displayStyle?: string;
12
+ };
13
+ declare global {
14
+ namespace JSX {
15
+ interface IntrinsicElements {
16
+ "html-div": React.HTMLAttributes<HTMLElement>;
17
+ }
18
+ }
19
+ }
7
20
  /**
8
21
  * Custom HTML element that sanitizes and displays HTML content
9
22
  * 自定义 HTML 元素,用于清理和显示 HTML 内容
@@ -1,13 +1,27 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.HtmlDiv = HtmlDiv;
7
4
  const jsx_runtime_1 = require("react/jsx-runtime");
8
5
  const shared_1 = require("@etsoo/shared");
9
- const dompurify_1 = __importDefault(require("dompurify"));
10
6
  class HtmlDivElement extends HTMLElement {
7
+ static get observedAttributes() {
8
+ return ["displaystyle"];
9
+ }
10
+ wrapper = null;
11
+ observer = null;
12
+ _displayStyle = undefined;
13
+ /**
14
+ * Display style
15
+ */
16
+ get displayStyle() {
17
+ return this._displayStyle;
18
+ }
19
+ set displayStyle(style) {
20
+ this._displayStyle = style;
21
+ if (this.wrapper && style != null) {
22
+ this.wrapper.style.cssText = style;
23
+ }
24
+ }
11
25
  constructor() {
12
26
  super();
13
27
  }
@@ -16,17 +30,49 @@ class HtmlDivElement extends HTMLElement {
16
30
  const shadow = this.attachShadow({ mode: "open" });
17
31
  // Create a wrapper element to hold the sanitized HTML content
18
32
  const wrapper = document.createElement("div");
33
+ wrapper.style.cssText = this.displayStyle ?? "";
34
+ shadow.appendChild(wrapper);
35
+ this.wrapper = wrapper;
36
+ this.setContent();
37
+ let miliseconds = Date.now();
38
+ this.observer = new MutationObserver(() => {
39
+ const m = Date.now();
40
+ if (m - miliseconds < 50)
41
+ return; // Ignore fast changes
42
+ miliseconds = m;
43
+ this.setContent();
44
+ });
45
+ this.observer.observe(this, {
46
+ childList: true,
47
+ subtree: true,
48
+ characterData: true
49
+ });
50
+ }
51
+ disconnectedCallback() {
52
+ if (this.observer) {
53
+ this.observer.disconnect();
54
+ this.observer = null;
55
+ }
56
+ }
57
+ attributeChangedCallback(name, _oldValue, newValue) {
58
+ if (name === "displaystyle" && typeof newValue === "string") {
59
+ this.displayStyle = newValue;
60
+ }
61
+ }
62
+ setContent() {
63
+ const wrapper = this.wrapper;
64
+ if (!wrapper)
65
+ return;
19
66
  const html = this.innerHTML;
20
67
  if (shared_1.Utils.hasHtmlEntity(html) &&
21
68
  !shared_1.Utils.hasHtmlTag(html) &&
22
69
  this.textContent) {
23
- wrapper.innerHTML = dompurify_1.default.sanitize(this.textContent);
70
+ wrapper.innerHTML = this.textContent;
24
71
  }
25
72
  else {
26
- wrapper.innerHTML = dompurify_1.default.sanitize(html);
73
+ wrapper.innerHTML = html;
27
74
  }
28
75
  this.textContent = null; // Clear the textContent to avoid duplication
29
- shadow.appendChild(wrapper);
30
76
  }
31
77
  }
32
78
  // Define the custom element only once
@@ -29,6 +29,11 @@ export interface TabBoxProps extends Omit<TabsProps, "value"> {
29
29
  * Current index
30
30
  */
31
31
  index?: number;
32
+ /**
33
+ * Index field of the search params
34
+ * @default 'index'
35
+ */
36
+ indexField?: string;
32
37
  /**
33
38
  * Add a hidden input and its name
34
39
  */
package/lib/mjs/TabBox.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useSearchParamsEx1 } from "@etsoo/react";
2
3
  import { Utils } from "@etsoo/shared";
3
4
  import Box from "@mui/material/Box";
4
5
  import Tab from "@mui/material/Tab";
@@ -14,9 +15,12 @@ function isActionTab(children) {
14
15
  */
15
16
  export function TabBox(props) {
16
17
  // Destruct
17
- const { index, inputName, root, defaultIndex = 0, onChange, tabProps, tabs, ...rest } = props;
18
+ const { index, indexField = "index", inputName, root, defaultIndex = 0, onChange, tabProps, tabs, ...rest } = props;
18
19
  // State
19
- const [value, setValue] = React.useState(defaultIndex);
20
+ const [params, setSearchParams] = useSearchParamsEx1({
21
+ [indexField]: "number"
22
+ });
23
+ const [value, setValue] = React.useState(params[indexField] ?? defaultIndex);
20
24
  React.useEffect(() => {
21
25
  if (index == null)
22
26
  return;
@@ -24,6 +28,13 @@ export function TabBox(props) {
24
28
  }, [index]);
25
29
  // Layout
26
30
  return (_jsxs(React.Fragment, { children: [inputName && _jsx("input", { type: "hidden", name: inputName, value: value }), _jsx(Box, { ...root, children: _jsx(Tabs, { value: value, onChange: (event, newValue) => {
31
+ setSearchParams((prev) => {
32
+ if (newValue == defaultIndex)
33
+ prev.delete(indexField);
34
+ else
35
+ prev.set(indexField, newValue);
36
+ return prev;
37
+ });
27
38
  const { children } = tabs[newValue];
28
39
  if (isActionTab(children)) {
29
40
  children();
@@ -3,7 +3,20 @@ import { HTMLAttributes } from "react";
3
3
  * Custom HTML element properties
4
4
  * 自定义 HTML 元素属性
5
5
  */
6
- export type HtmlDivProps = HTMLAttributes<HTMLElement>;
6
+ export type HtmlDivProps = HTMLAttributes<HTMLElement> & {
7
+ /**
8
+ * Display style
9
+ * 显示样式
10
+ */
11
+ displayStyle?: string;
12
+ };
13
+ declare global {
14
+ namespace JSX {
15
+ interface IntrinsicElements {
16
+ "html-div": React.HTMLAttributes<HTMLElement>;
17
+ }
18
+ }
19
+ }
7
20
  /**
8
21
  * Custom HTML element that sanitizes and displays HTML content
9
22
  * 自定义 HTML 元素,用于清理和显示 HTML 内容
@@ -1,7 +1,24 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { Utils } from "@etsoo/shared";
3
- import DOMPurify from "dompurify";
4
3
  class HtmlDivElement extends HTMLElement {
4
+ static get observedAttributes() {
5
+ return ["displaystyle"];
6
+ }
7
+ wrapper = null;
8
+ observer = null;
9
+ _displayStyle = undefined;
10
+ /**
11
+ * Display style
12
+ */
13
+ get displayStyle() {
14
+ return this._displayStyle;
15
+ }
16
+ set displayStyle(style) {
17
+ this._displayStyle = style;
18
+ if (this.wrapper && style != null) {
19
+ this.wrapper.style.cssText = style;
20
+ }
21
+ }
5
22
  constructor() {
6
23
  super();
7
24
  }
@@ -10,17 +27,49 @@ class HtmlDivElement extends HTMLElement {
10
27
  const shadow = this.attachShadow({ mode: "open" });
11
28
  // Create a wrapper element to hold the sanitized HTML content
12
29
  const wrapper = document.createElement("div");
30
+ wrapper.style.cssText = this.displayStyle ?? "";
31
+ shadow.appendChild(wrapper);
32
+ this.wrapper = wrapper;
33
+ this.setContent();
34
+ let miliseconds = Date.now();
35
+ this.observer = new MutationObserver(() => {
36
+ const m = Date.now();
37
+ if (m - miliseconds < 50)
38
+ return; // Ignore fast changes
39
+ miliseconds = m;
40
+ this.setContent();
41
+ });
42
+ this.observer.observe(this, {
43
+ childList: true,
44
+ subtree: true,
45
+ characterData: true
46
+ });
47
+ }
48
+ disconnectedCallback() {
49
+ if (this.observer) {
50
+ this.observer.disconnect();
51
+ this.observer = null;
52
+ }
53
+ }
54
+ attributeChangedCallback(name, _oldValue, newValue) {
55
+ if (name === "displaystyle" && typeof newValue === "string") {
56
+ this.displayStyle = newValue;
57
+ }
58
+ }
59
+ setContent() {
60
+ const wrapper = this.wrapper;
61
+ if (!wrapper)
62
+ return;
13
63
  const html = this.innerHTML;
14
64
  if (Utils.hasHtmlEntity(html) &&
15
65
  !Utils.hasHtmlTag(html) &&
16
66
  this.textContent) {
17
- wrapper.innerHTML = DOMPurify.sanitize(this.textContent);
67
+ wrapper.innerHTML = this.textContent;
18
68
  }
19
69
  else {
20
- wrapper.innerHTML = DOMPurify.sanitize(html);
70
+ wrapper.innerHTML = html;
21
71
  }
22
72
  this.textContent = null; // Clear the textContent to avoid duplication
23
- shadow.appendChild(wrapper);
24
73
  }
25
74
  }
26
75
  // Define the custom element only once
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@etsoo/materialui",
3
- "version": "1.5.28",
3
+ "version": "1.5.30",
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.0",
43
43
  "@etsoo/appscript": "^1.6.22",
44
44
  "@etsoo/notificationbase": "^1.1.60",
45
- "@etsoo/react": "^1.8.38",
45
+ "@etsoo/react": "^1.8.39",
46
46
  "@etsoo/shared": "^1.2.68",
47
47
  "@mui/icons-material": "^7.0.2",
48
48
  "@mui/material": "^7.0.2",
package/src/TabBox.tsx CHANGED
@@ -1,3 +1,4 @@
1
+ import { useSearchParamsEx1 } from "@etsoo/react";
1
2
  import { Utils } from "@etsoo/shared";
2
3
  import Box, { BoxProps } from "@mui/material/Box";
3
4
  import Tab, { TabProps } from "@mui/material/Tab";
@@ -46,6 +47,12 @@ export interface TabBoxProps extends Omit<TabsProps, "value"> {
46
47
  */
47
48
  index?: number;
48
49
 
50
+ /**
51
+ * Index field of the search params
52
+ * @default 'index'
53
+ */
54
+ indexField?: string;
55
+
49
56
  /**
50
57
  * Add a hidden input and its name
51
58
  */
@@ -76,6 +83,7 @@ export function TabBox(props: TabBoxProps) {
76
83
  // Destruct
77
84
  const {
78
85
  index,
86
+ indexField = "index",
79
87
  inputName,
80
88
  root,
81
89
  defaultIndex = 0,
@@ -86,7 +94,10 @@ export function TabBox(props: TabBoxProps) {
86
94
  } = props;
87
95
 
88
96
  // State
89
- const [value, setValue] = React.useState(defaultIndex);
97
+ const [params, setSearchParams] = useSearchParamsEx1({
98
+ [indexField]: "number"
99
+ });
100
+ const [value, setValue] = React.useState(params[indexField] ?? defaultIndex);
90
101
 
91
102
  React.useEffect(() => {
92
103
  if (index == null) return;
@@ -101,6 +112,11 @@ export function TabBox(props: TabBoxProps) {
101
112
  <Tabs
102
113
  value={value}
103
114
  onChange={(event, newValue) => {
115
+ setSearchParams((prev) => {
116
+ if (newValue == defaultIndex) prev.delete(indexField);
117
+ else prev.set(indexField, newValue);
118
+ return prev;
119
+ });
104
120
  const { children } = tabs[newValue];
105
121
  if (isActionTab(children)) {
106
122
  children();
@@ -1,8 +1,29 @@
1
1
  import { Utils } from "@etsoo/shared";
2
- import DOMPurify from "dompurify";
3
2
  import { HTMLAttributes } from "react";
4
3
 
5
4
  class HtmlDivElement extends HTMLElement {
5
+ static get observedAttributes() {
6
+ return ["displaystyle"];
7
+ }
8
+
9
+ private wrapper: HTMLDivElement | null = null;
10
+ private observer: MutationObserver | null = null;
11
+
12
+ private _displayStyle?: string = undefined;
13
+
14
+ /**
15
+ * Display style
16
+ */
17
+ get displayStyle() {
18
+ return this._displayStyle;
19
+ }
20
+ set displayStyle(style: string | undefined) {
21
+ this._displayStyle = style;
22
+ if (this.wrapper && style != null) {
23
+ this.wrapper.style.cssText = style;
24
+ }
25
+ }
26
+
6
27
  constructor() {
7
28
  super();
8
29
  }
@@ -13,20 +34,55 @@ class HtmlDivElement extends HTMLElement {
13
34
 
14
35
  // Create a wrapper element to hold the sanitized HTML content
15
36
  const wrapper = document.createElement("div");
37
+ wrapper.style.cssText = this.displayStyle ?? "";
38
+ shadow.appendChild(wrapper);
39
+
40
+ this.wrapper = wrapper;
41
+ this.setContent();
42
+
43
+ let miliseconds = Date.now();
44
+ this.observer = new MutationObserver(() => {
45
+ const m = Date.now();
46
+ if (m - miliseconds < 50) return; // Ignore fast changes
47
+ miliseconds = m;
48
+ this.setContent();
49
+ });
50
+ this.observer.observe(this, {
51
+ childList: true,
52
+ subtree: true,
53
+ characterData: true
54
+ });
55
+ }
56
+
57
+ disconnectedCallback() {
58
+ if (this.observer) {
59
+ this.observer.disconnect();
60
+ this.observer = null;
61
+ }
62
+ }
63
+
64
+ attributeChangedCallback(name: string, _oldValue: any, newValue: any) {
65
+ if (name === "displaystyle" && typeof newValue === "string") {
66
+ this.displayStyle = newValue;
67
+ }
68
+ }
69
+
70
+ setContent() {
71
+ const wrapper = this.wrapper;
72
+ if (!wrapper) return;
73
+
16
74
  const html = this.innerHTML;
17
75
  if (
18
76
  Utils.hasHtmlEntity(html) &&
19
77
  !Utils.hasHtmlTag(html) &&
20
78
  this.textContent
21
79
  ) {
22
- wrapper.innerHTML = DOMPurify.sanitize(this.textContent);
80
+ wrapper.innerHTML = this.textContent;
23
81
  } else {
24
- wrapper.innerHTML = DOMPurify.sanitize(html);
82
+ wrapper.innerHTML = html;
25
83
  }
26
84
 
27
85
  this.textContent = null; // Clear the textContent to avoid duplication
28
-
29
- shadow.appendChild(wrapper);
30
86
  }
31
87
  }
32
88
 
@@ -39,7 +95,21 @@ if (!customElements.get("html-div")) {
39
95
  * Custom HTML element properties
40
96
  * 自定义 HTML 元素属性
41
97
  */
42
- export type HtmlDivProps = HTMLAttributes<HTMLElement>;
98
+ export type HtmlDivProps = HTMLAttributes<HTMLElement> & {
99
+ /**
100
+ * Display style
101
+ * 显示样式
102
+ */
103
+ displayStyle?: string;
104
+ };
105
+
106
+ declare global {
107
+ namespace JSX {
108
+ interface IntrinsicElements {
109
+ "html-div": React.HTMLAttributes<HTMLElement>;
110
+ }
111
+ }
112
+ }
43
113
 
44
114
  /**
45
115
  * Custom HTML element that sanitizes and displays HTML content
package/src/global.d.ts DELETED
@@ -1,5 +0,0 @@
1
- declare namespace JSX {
2
- interface IntrinsicElements {
3
- "html-div": React.HTMLAttributes<HTMLElement>;
4
- }
5
- }