@etsoo/materialui 1.5.31 → 1.5.33

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.
@@ -0,0 +1,51 @@
1
+ import { DataTypes, IdType } from "@etsoo/shared";
2
+ import { ListProps } from "@mui/material/List";
3
+ import { ListItemProps } from "@mui/material/ListItem";
4
+ import { ListItemTextProps } from "@mui/material/ListItemText";
5
+ type ListItemLabel<T extends object> = DataTypes.Keys<T, string | undefined> | ((item: T) => string | undefined);
6
+ /**
7
+ * List multipler component props
8
+ */
9
+ export type ListMultiplerProps<T extends object> = ListProps & {
10
+ /**
11
+ * List data
12
+ */
13
+ data: T[];
14
+ /**
15
+ * Id field name
16
+ */
17
+ idField: DataTypes.Keys<T, IdType>;
18
+ /**
19
+ * Primary label field name or function
20
+ */
21
+ primaryLabel: ListItemLabel<T>;
22
+ /**
23
+ * Secondary label field name or function
24
+ */
25
+ secondaryLabel?: ListItemLabel<T>;
26
+ /**
27
+ * List item props
28
+ */
29
+ listItemProps?: ListItemProps;
30
+ /**
31
+ * List item text props
32
+ */
33
+ listItemTextProps?: Omit<ListItemTextProps, "primary" | "secondary">;
34
+ /**
35
+ * Input name
36
+ */
37
+ name?: string;
38
+ /**
39
+ * On change event
40
+ * @param items The selected items
41
+ * @param ids The selected IDs
42
+ */
43
+ onCheckItems?: (items: T[], ids: unknown[]) => void;
44
+ };
45
+ /**
46
+ * List multipler component
47
+ * @param props Props
48
+ * @returns Component
49
+ */
50
+ export declare function ListMultipler<T extends object>(props: ListMultiplerProps<T>): import("react/jsx-runtime").JSX.Element;
51
+ export {};
@@ -0,0 +1,61 @@
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.ListMultipler = ListMultipler;
7
+ const jsx_runtime_1 = require("react/jsx-runtime");
8
+ const Checkbox_1 = __importDefault(require("@mui/material/Checkbox"));
9
+ const List_1 = __importDefault(require("@mui/material/List"));
10
+ const ListItem_1 = __importDefault(require("@mui/material/ListItem"));
11
+ const ListItemButton_1 = __importDefault(require("@mui/material/ListItemButton"));
12
+ const ListItemIcon_1 = __importDefault(require("@mui/material/ListItemIcon"));
13
+ const ListItemText_1 = __importDefault(require("@mui/material/ListItemText"));
14
+ const react_1 = __importDefault(require("react"));
15
+ function GetListItemLabel(data, label) {
16
+ if (label == null)
17
+ return undefined;
18
+ if (typeof label === "function") {
19
+ return label(data);
20
+ }
21
+ else {
22
+ return data[label];
23
+ }
24
+ }
25
+ /**
26
+ * List multipler component
27
+ * @param props Props
28
+ * @returns Component
29
+ */
30
+ function ListMultipler(props) {
31
+ // Destruct
32
+ const { data, idField, primaryLabel, secondaryLabel, listItemProps, listItemTextProps, name, onCheckItems, ...rest } = props;
33
+ // Refs
34
+ const initialized = react_1.default.useRef(false);
35
+ react_1.default.useEffect(() => {
36
+ initialized.current = true;
37
+ }, []);
38
+ // State
39
+ const [checked, setChecked] = react_1.default.useState([]);
40
+ const ids = react_1.default.useMemo(() => {
41
+ const ids = checked.map((u) => u[idField]);
42
+ if (onCheckItems && initialized.current) {
43
+ onCheckItems(checked, ids);
44
+ }
45
+ return ids;
46
+ }, [checked]);
47
+ function handleToggle(id) {
48
+ if (ids.includes(id)) {
49
+ setChecked((prev) => prev.filter((u) => u[idField] !== id));
50
+ }
51
+ else {
52
+ const item = data.find((u) => u[idField] === id);
53
+ if (item) {
54
+ setChecked((prev) => [...prev, item]);
55
+ }
56
+ }
57
+ }
58
+ const inputType = typeof ids[0] === "string" ? "text" : "number";
59
+ // Layout
60
+ return ((0, jsx_runtime_1.jsxs)(List_1.default, { ...rest, children: [name && ((0, jsx_runtime_1.jsx)("input", { type: inputType, style: { display: "none" }, name: name, value: ids.join(","), readOnly: true })), data.map((u) => ((0, jsx_runtime_1.jsx)(ListItem_1.default, { ...listItemProps, children: (0, jsx_runtime_1.jsxs)(ListItemButton_1.default, { dense: true, onClick: () => handleToggle(u[idField]), children: [(0, jsx_runtime_1.jsx)(ListItemIcon_1.default, { children: (0, jsx_runtime_1.jsx)(Checkbox_1.default, { edge: "start", disableRipple: true, checked: ids.includes(u[idField]) }) }), (0, jsx_runtime_1.jsx)(ListItemText_1.default, { primary: GetListItemLabel(u, primaryLabel), secondary: GetListItemLabel(u, secondaryLabel), ...listItemTextProps })] }) }, `${u[idField]}`)))] }));
61
+ }
@@ -28,6 +28,22 @@ class HtmlDivElement extends HTMLElement {
28
28
  connectedCallback() {
29
29
  // Create a shadow root
30
30
  const shadow = this.attachShadow({ mode: "open" });
31
+ // Default styles
32
+ // Comply with @etsoo/editor default styles
33
+ const style = document.createElement("style");
34
+ style.textContent = `
35
+ :host {
36
+ box-sizing: border-box;
37
+ }
38
+ img {
39
+ max-width: 100%;
40
+ }
41
+ pre {
42
+ background-color: #f3f3f3;
43
+ padding: 12px;
44
+ }
45
+ `;
46
+ shadow.appendChild(style);
31
47
  // Create a wrapper element to hold the sanitized HTML content
32
48
  const wrapper = document.createElement("div");
33
49
  wrapper.style.cssText = this.displayStyle ?? "";
@@ -73,6 +73,7 @@ export * from "./LinkEx";
73
73
  export * from "./ListChooser";
74
74
  export * from "./ListItemRightIcon";
75
75
  export * from "./ListMoreDisplay";
76
+ export * from "./ListMultipler";
76
77
  export * from "./LoadingButton";
77
78
  export * from "./MaskInput";
78
79
  export * from "./MenuButton";
package/lib/cjs/index.js CHANGED
@@ -89,6 +89,7 @@ __exportStar(require("./LinkEx"), exports);
89
89
  __exportStar(require("./ListChooser"), exports);
90
90
  __exportStar(require("./ListItemRightIcon"), exports);
91
91
  __exportStar(require("./ListMoreDisplay"), exports);
92
+ __exportStar(require("./ListMultipler"), exports);
92
93
  __exportStar(require("./LoadingButton"), exports);
93
94
  __exportStar(require("./MaskInput"), exports);
94
95
  __exportStar(require("./MenuButton"), exports);
@@ -0,0 +1,51 @@
1
+ import { DataTypes, IdType } from "@etsoo/shared";
2
+ import { ListProps } from "@mui/material/List";
3
+ import { ListItemProps } from "@mui/material/ListItem";
4
+ import { ListItemTextProps } from "@mui/material/ListItemText";
5
+ type ListItemLabel<T extends object> = DataTypes.Keys<T, string | undefined> | ((item: T) => string | undefined);
6
+ /**
7
+ * List multipler component props
8
+ */
9
+ export type ListMultiplerProps<T extends object> = ListProps & {
10
+ /**
11
+ * List data
12
+ */
13
+ data: T[];
14
+ /**
15
+ * Id field name
16
+ */
17
+ idField: DataTypes.Keys<T, IdType>;
18
+ /**
19
+ * Primary label field name or function
20
+ */
21
+ primaryLabel: ListItemLabel<T>;
22
+ /**
23
+ * Secondary label field name or function
24
+ */
25
+ secondaryLabel?: ListItemLabel<T>;
26
+ /**
27
+ * List item props
28
+ */
29
+ listItemProps?: ListItemProps;
30
+ /**
31
+ * List item text props
32
+ */
33
+ listItemTextProps?: Omit<ListItemTextProps, "primary" | "secondary">;
34
+ /**
35
+ * Input name
36
+ */
37
+ name?: string;
38
+ /**
39
+ * On change event
40
+ * @param items The selected items
41
+ * @param ids The selected IDs
42
+ */
43
+ onCheckItems?: (items: T[], ids: unknown[]) => void;
44
+ };
45
+ /**
46
+ * List multipler component
47
+ * @param props Props
48
+ * @returns Component
49
+ */
50
+ export declare function ListMultipler<T extends object>(props: ListMultiplerProps<T>): import("react/jsx-runtime").JSX.Element;
51
+ export {};
@@ -0,0 +1,55 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import Checkbox from "@mui/material/Checkbox";
3
+ import List from "@mui/material/List";
4
+ import ListItem from "@mui/material/ListItem";
5
+ import ListItemButton from "@mui/material/ListItemButton";
6
+ import ListItemIcon from "@mui/material/ListItemIcon";
7
+ import ListItemText from "@mui/material/ListItemText";
8
+ import React from "react";
9
+ function GetListItemLabel(data, label) {
10
+ if (label == null)
11
+ return undefined;
12
+ if (typeof label === "function") {
13
+ return label(data);
14
+ }
15
+ else {
16
+ return data[label];
17
+ }
18
+ }
19
+ /**
20
+ * List multipler component
21
+ * @param props Props
22
+ * @returns Component
23
+ */
24
+ export function ListMultipler(props) {
25
+ // Destruct
26
+ const { data, idField, primaryLabel, secondaryLabel, listItemProps, listItemTextProps, name, onCheckItems, ...rest } = props;
27
+ // Refs
28
+ const initialized = React.useRef(false);
29
+ React.useEffect(() => {
30
+ initialized.current = true;
31
+ }, []);
32
+ // State
33
+ const [checked, setChecked] = React.useState([]);
34
+ const ids = React.useMemo(() => {
35
+ const ids = checked.map((u) => u[idField]);
36
+ if (onCheckItems && initialized.current) {
37
+ onCheckItems(checked, ids);
38
+ }
39
+ return ids;
40
+ }, [checked]);
41
+ function handleToggle(id) {
42
+ if (ids.includes(id)) {
43
+ setChecked((prev) => prev.filter((u) => u[idField] !== id));
44
+ }
45
+ else {
46
+ const item = data.find((u) => u[idField] === id);
47
+ if (item) {
48
+ setChecked((prev) => [...prev, item]);
49
+ }
50
+ }
51
+ }
52
+ const inputType = typeof ids[0] === "string" ? "text" : "number";
53
+ // Layout
54
+ return (_jsxs(List, { ...rest, children: [name && (_jsx("input", { type: inputType, style: { display: "none" }, name: name, value: ids.join(","), readOnly: true })), data.map((u) => (_jsx(ListItem, { ...listItemProps, children: _jsxs(ListItemButton, { dense: true, onClick: () => handleToggle(u[idField]), children: [_jsx(ListItemIcon, { children: _jsx(Checkbox, { edge: "start", disableRipple: true, checked: ids.includes(u[idField]) }) }), _jsx(ListItemText, { primary: GetListItemLabel(u, primaryLabel), secondary: GetListItemLabel(u, secondaryLabel), ...listItemTextProps })] }) }, `${u[idField]}`)))] }));
55
+ }
@@ -25,6 +25,22 @@ class HtmlDivElement extends HTMLElement {
25
25
  connectedCallback() {
26
26
  // Create a shadow root
27
27
  const shadow = this.attachShadow({ mode: "open" });
28
+ // Default styles
29
+ // Comply with @etsoo/editor default styles
30
+ const style = document.createElement("style");
31
+ style.textContent = `
32
+ :host {
33
+ box-sizing: border-box;
34
+ }
35
+ img {
36
+ max-width: 100%;
37
+ }
38
+ pre {
39
+ background-color: #f3f3f3;
40
+ padding: 12px;
41
+ }
42
+ `;
43
+ shadow.appendChild(style);
28
44
  // Create a wrapper element to hold the sanitized HTML content
29
45
  const wrapper = document.createElement("div");
30
46
  wrapper.style.cssText = this.displayStyle ?? "";
@@ -73,6 +73,7 @@ export * from "./LinkEx";
73
73
  export * from "./ListChooser";
74
74
  export * from "./ListItemRightIcon";
75
75
  export * from "./ListMoreDisplay";
76
+ export * from "./ListMultipler";
76
77
  export * from "./LoadingButton";
77
78
  export * from "./MaskInput";
78
79
  export * from "./MenuButton";
package/lib/mjs/index.js CHANGED
@@ -73,6 +73,7 @@ export * from "./LinkEx";
73
73
  export * from "./ListChooser";
74
74
  export * from "./ListItemRightIcon";
75
75
  export * from "./ListMoreDisplay";
76
+ export * from "./ListMultipler";
76
77
  export * from "./LoadingButton";
77
78
  export * from "./MaskInput";
78
79
  export * from "./MenuButton";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@etsoo/materialui",
3
- "version": "1.5.31",
3
+ "version": "1.5.33",
4
4
  "description": "TypeScript Material-UI Implementation",
5
5
  "main": "lib/cjs/index.js",
6
6
  "module": "lib/mjs/index.js",
@@ -40,7 +40,7 @@
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.25",
43
+ "@etsoo/appscript": "^1.6.26",
44
44
  "@etsoo/notificationbase": "^1.1.60",
45
45
  "@etsoo/react": "^1.8.40",
46
46
  "@etsoo/shared": "^1.2.69",
@@ -81,9 +81,9 @@
81
81
  "@types/react-dom": "^18.3.6",
82
82
  "@types/react-input-mask": "^3.0.6",
83
83
  "@types/react-window": "^1.8.8",
84
- "@vitejs/plugin-react": "^4.4.0",
84
+ "@vitejs/plugin-react": "^4.4.1",
85
85
  "jsdom": "^26.1.0",
86
86
  "typescript": "^5.8.3",
87
- "vitest": "^3.1.1"
87
+ "vitest": "^3.1.2"
88
88
  }
89
89
  }
@@ -0,0 +1,153 @@
1
+ import { DataTypes, IdType } from "@etsoo/shared";
2
+ import Checkbox from "@mui/material/Checkbox";
3
+ import List, { ListProps } from "@mui/material/List";
4
+ import ListItem, { ListItemProps } from "@mui/material/ListItem";
5
+ import ListItemButton from "@mui/material/ListItemButton";
6
+ import ListItemIcon from "@mui/material/ListItemIcon";
7
+ import ListItemText, { ListItemTextProps } from "@mui/material/ListItemText";
8
+ import React from "react";
9
+
10
+ type ListItemLabel<T extends object> =
11
+ | DataTypes.Keys<T, string | undefined>
12
+ | ((item: T) => string | undefined);
13
+
14
+ /**
15
+ * List multipler component props
16
+ */
17
+ export type ListMultiplerProps<T extends object> = ListProps & {
18
+ /**
19
+ * List data
20
+ */
21
+ data: T[];
22
+
23
+ /**
24
+ * Id field name
25
+ */
26
+ idField: DataTypes.Keys<T, IdType>;
27
+
28
+ /**
29
+ * Primary label field name or function
30
+ */
31
+ primaryLabel: ListItemLabel<T>;
32
+
33
+ /**
34
+ * Secondary label field name or function
35
+ */
36
+ secondaryLabel?: ListItemLabel<T>;
37
+
38
+ /**
39
+ * List item props
40
+ */
41
+ listItemProps?: ListItemProps;
42
+
43
+ /**
44
+ * List item text props
45
+ */
46
+ listItemTextProps?: Omit<ListItemTextProps, "primary" | "secondary">;
47
+
48
+ /**
49
+ * Input name
50
+ */
51
+ name?: string;
52
+
53
+ /**
54
+ * On change event
55
+ * @param items The selected items
56
+ * @param ids The selected IDs
57
+ */
58
+ onCheckItems?: (items: T[], ids: unknown[]) => void;
59
+ };
60
+
61
+ function GetListItemLabel<T extends object>(data: T, label?: ListItemLabel<T>) {
62
+ if (label == null) return undefined;
63
+ if (typeof label === "function") {
64
+ return label(data);
65
+ } else {
66
+ return data[label] as string | undefined;
67
+ }
68
+ }
69
+
70
+ /**
71
+ * List multipler component
72
+ * @param props Props
73
+ * @returns Component
74
+ */
75
+ export function ListMultipler<T extends object>(props: ListMultiplerProps<T>) {
76
+ // Destruct
77
+ const {
78
+ data,
79
+ idField,
80
+ primaryLabel,
81
+ secondaryLabel,
82
+ listItemProps,
83
+ listItemTextProps,
84
+ name,
85
+ onCheckItems,
86
+ ...rest
87
+ } = props;
88
+
89
+ // Refs
90
+ const initialized = React.useRef(false);
91
+ React.useEffect(() => {
92
+ initialized.current = true;
93
+ }, []);
94
+
95
+ // State
96
+ const [checked, setChecked] = React.useState<T[]>([]);
97
+
98
+ const ids = React.useMemo(() => {
99
+ const ids = checked.map((u) => u[idField]);
100
+
101
+ if (onCheckItems && initialized.current) {
102
+ onCheckItems(checked, ids);
103
+ }
104
+
105
+ return ids;
106
+ }, [checked]);
107
+
108
+ function handleToggle(id: T[DataTypes.Keys<T, IdType>]) {
109
+ if (ids.includes(id)) {
110
+ setChecked((prev) => prev.filter((u) => u[idField] !== id));
111
+ } else {
112
+ const item = data.find((u) => u[idField] === id);
113
+ if (item) {
114
+ setChecked((prev) => [...prev, item]);
115
+ }
116
+ }
117
+ }
118
+
119
+ const inputType = typeof ids[0] === "string" ? "text" : "number";
120
+
121
+ // Layout
122
+ return (
123
+ <List {...rest}>
124
+ {name && (
125
+ <input
126
+ type={inputType}
127
+ style={{ display: "none" }}
128
+ name={name}
129
+ value={ids.join(",")}
130
+ readOnly
131
+ />
132
+ )}
133
+ {data.map((u) => (
134
+ <ListItem key={`${u[idField]}`} {...listItemProps}>
135
+ <ListItemButton dense onClick={() => handleToggle(u[idField])}>
136
+ <ListItemIcon>
137
+ <Checkbox
138
+ edge="start"
139
+ disableRipple
140
+ checked={ids.includes(u[idField])}
141
+ />
142
+ </ListItemIcon>
143
+ <ListItemText
144
+ primary={GetListItemLabel(u, primaryLabel)}
145
+ secondary={GetListItemLabel(u, secondaryLabel)}
146
+ {...listItemTextProps}
147
+ />
148
+ </ListItemButton>
149
+ </ListItem>
150
+ ))}
151
+ </List>
152
+ );
153
+ }
@@ -32,6 +32,23 @@ class HtmlDivElement extends HTMLElement {
32
32
  // Create a shadow root
33
33
  const shadow = this.attachShadow({ mode: "open" });
34
34
 
35
+ // Default styles
36
+ // Comply with @etsoo/editor default styles
37
+ const style = document.createElement("style");
38
+ style.textContent = `
39
+ :host {
40
+ box-sizing: border-box;
41
+ }
42
+ img {
43
+ max-width: 100%;
44
+ }
45
+ pre {
46
+ background-color: #f3f3f3;
47
+ padding: 12px;
48
+ }
49
+ `;
50
+ shadow.appendChild(style);
51
+
35
52
  // Create a wrapper element to hold the sanitized HTML content
36
53
  const wrapper = document.createElement("div");
37
54
  wrapper.style.cssText = this.displayStyle ?? "";
package/src/index.ts CHANGED
@@ -79,6 +79,7 @@ export * from "./LinkEx";
79
79
  export * from "./ListChooser";
80
80
  export * from "./ListItemRightIcon";
81
81
  export * from "./ListMoreDisplay";
82
+ export * from "./ListMultipler";
82
83
  export * from "./LoadingButton";
83
84
  export * from "./MaskInput";
84
85
  export * from "./MenuButton";