@etsoo/materialui 1.5.86 → 1.5.88
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.
- package/__tests__/ComboBox.tsx +16 -17
- package/__tests__/CustomFields.tsx +2 -2
- package/__tests__/InputTipField.tsx +76 -0
- package/lib/cjs/InputTipField.d.ts +42 -30
- package/lib/cjs/InputTipField.js +3 -3
- package/lib/mjs/InputTipField.d.ts +42 -30
- package/lib/mjs/InputTipField.js +3 -3
- package/package.json +2 -2
- package/src/InputTipField.tsx +57 -47
package/__tests__/ComboBox.tsx
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
|
-
import React from "react";
|
|
2
1
|
import { ComboBox } from "../src";
|
|
3
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
act,
|
|
4
|
+
fireEvent,
|
|
5
|
+
render,
|
|
6
|
+
screen,
|
|
7
|
+
waitFor
|
|
8
|
+
} from "@testing-library/react";
|
|
4
9
|
|
|
5
10
|
it("Render ComboBox", async () => {
|
|
6
11
|
// Arrange
|
|
@@ -21,21 +26,15 @@ it("Render ComboBox", async () => {
|
|
|
21
26
|
);
|
|
22
27
|
});
|
|
23
28
|
|
|
24
|
-
await
|
|
25
|
-
|
|
26
|
-
await screen.findByRole("button");
|
|
27
|
-
},
|
|
28
|
-
{
|
|
29
|
-
timeout: 500, // default is 1000
|
|
30
|
-
interval: 20 // default is 50
|
|
31
|
-
}
|
|
32
|
-
);
|
|
29
|
+
await waitFor(async () => {
|
|
30
|
+
const button = await screen.findByRole("button");
|
|
33
31
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
32
|
+
// Act, click the list
|
|
33
|
+
const clicked = fireEvent.click(button);
|
|
34
|
+
expect(clicked).toBeTruthy();
|
|
37
35
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
36
|
+
// Get list item
|
|
37
|
+
const item = await screen.findByText("Name 1");
|
|
38
|
+
expect(item.nodeName).toBe("LI");
|
|
39
|
+
});
|
|
41
40
|
});
|
|
@@ -137,13 +137,13 @@ it("Render FieldSelect", async () => {
|
|
|
137
137
|
);
|
|
138
138
|
});
|
|
139
139
|
|
|
140
|
-
const button = screen.
|
|
140
|
+
const button = await screen.findByRole("combobox");
|
|
141
141
|
|
|
142
142
|
act(() => {
|
|
143
143
|
// Act, click to open the dropdown list
|
|
144
144
|
vi.useFakeTimers();
|
|
145
145
|
fireEvent.mouseDown(button);
|
|
146
|
-
vi.
|
|
146
|
+
vi.runAllTimers();
|
|
147
147
|
});
|
|
148
148
|
|
|
149
149
|
const input = document.querySelector<HTMLInputElement>("input");
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { fireEvent, render, screen, waitFor } from "@testing-library/react";
|
|
2
|
+
import { act } from "react";
|
|
3
|
+
import { InputTipField } from "../src";
|
|
4
|
+
|
|
5
|
+
it("Render default InputTipField", async () => {
|
|
6
|
+
// Render component
|
|
7
|
+
act(() => {
|
|
8
|
+
render(
|
|
9
|
+
<InputTipField
|
|
10
|
+
name="amount"
|
|
11
|
+
type="number"
|
|
12
|
+
componentProps={{
|
|
13
|
+
loadData: (_value) => Promise.resolve([])
|
|
14
|
+
}}
|
|
15
|
+
slotProps={{ htmlInput: { role: "input" } }}
|
|
16
|
+
/>
|
|
17
|
+
);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
const input = screen.getByRole<HTMLInputElement>("input");
|
|
21
|
+
expect(input.type).toBe("number");
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it("Render email InputTipField", async () => {
|
|
25
|
+
// Arrange
|
|
26
|
+
type T = { id: number; name: string };
|
|
27
|
+
const options: T[] = [
|
|
28
|
+
{ id: 1, name: "Name 1" },
|
|
29
|
+
{ id: 2, name: "Name 2" }
|
|
30
|
+
];
|
|
31
|
+
|
|
32
|
+
const changeHandler = vi.fn();
|
|
33
|
+
|
|
34
|
+
const flag = "2 items";
|
|
35
|
+
|
|
36
|
+
// Render component
|
|
37
|
+
act(() => {
|
|
38
|
+
render(
|
|
39
|
+
<InputTipField<T>
|
|
40
|
+
component="email"
|
|
41
|
+
componentProps={{
|
|
42
|
+
loadData: (_value) => Promise.resolve([options, flag]),
|
|
43
|
+
itemLabel: (item) => item.name + ` (${item.id})`
|
|
44
|
+
}}
|
|
45
|
+
onChangeDelay={changeHandler}
|
|
46
|
+
slotProps={{ htmlInput: { role: "input" } }}
|
|
47
|
+
/>
|
|
48
|
+
);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
const input = screen.getByRole<HTMLInputElement>("input");
|
|
52
|
+
expect(input.type).toBe("email");
|
|
53
|
+
|
|
54
|
+
act(() => {
|
|
55
|
+
vi.useFakeTimers();
|
|
56
|
+
|
|
57
|
+
fireEvent.change(input, { target: { value: "info@etsoo.com" } });
|
|
58
|
+
expect(input.value).toBe("info@etsoo.com");
|
|
59
|
+
|
|
60
|
+
vi.runAllTimers();
|
|
61
|
+
expect(changeHandler).toHaveBeenCalled();
|
|
62
|
+
|
|
63
|
+
// Restore timers, otherwise 'waitFor' will fail
|
|
64
|
+
vi.useRealTimers();
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
await waitFor(() => {
|
|
68
|
+
const button = screen.getByText(flag);
|
|
69
|
+
expect(button.nodeName).toBe("P");
|
|
70
|
+
|
|
71
|
+
fireEvent.click(button);
|
|
72
|
+
|
|
73
|
+
const item = screen.getByText("Name 2 (2)");
|
|
74
|
+
expect(item.nodeName).toBe("LI");
|
|
75
|
+
});
|
|
76
|
+
});
|
|
@@ -1,58 +1,70 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { IdType } from "@etsoo/shared";
|
|
2
2
|
import { TypographyProps } from "@mui/material/Typography";
|
|
3
3
|
import React from "react";
|
|
4
|
-
import {
|
|
4
|
+
import { InputFieldProps } from "./InputField";
|
|
5
5
|
import { EmailInput } from "./EmailInput";
|
|
6
6
|
import { MobileInput } from "./MobileInput";
|
|
7
7
|
import { PhoneInput } from "./PhoneInput";
|
|
8
|
-
type ItemType =
|
|
8
|
+
type ItemType = {
|
|
9
|
+
id: IdType;
|
|
10
|
+
};
|
|
9
11
|
declare const componentMap: {
|
|
10
|
-
input: typeof InputField;
|
|
11
12
|
email: typeof EmailInput;
|
|
12
13
|
phone: typeof PhoneInput;
|
|
13
14
|
mobile: typeof MobileInput;
|
|
14
15
|
};
|
|
15
16
|
type ComponentMap = typeof componentMap;
|
|
16
17
|
type ComponentKey = keyof ComponentMap;
|
|
18
|
+
type ComponentProps<T extends ItemType> = {
|
|
19
|
+
/**
|
|
20
|
+
* Load data
|
|
21
|
+
* @param value Duplicate test value
|
|
22
|
+
*/
|
|
23
|
+
loadData(value: string): Promise<[T[]?, string?]>;
|
|
24
|
+
/**
|
|
25
|
+
* Label props
|
|
26
|
+
*/
|
|
27
|
+
labelProps?: Omit<TypographyProps, "onClick">;
|
|
28
|
+
/**
|
|
29
|
+
* Custom item label
|
|
30
|
+
* @param item List item data
|
|
31
|
+
* @returns Result
|
|
32
|
+
*/
|
|
33
|
+
itemLabel?: (item: T) => React.ReactNode;
|
|
34
|
+
/**
|
|
35
|
+
* Custom render item
|
|
36
|
+
* @param item List item data
|
|
37
|
+
* @returns Result
|
|
38
|
+
*/
|
|
39
|
+
renderItem?: (item: T) => React.ReactNode;
|
|
40
|
+
};
|
|
17
41
|
/**
|
|
18
42
|
* InputField with tips properties
|
|
19
43
|
*/
|
|
20
|
-
export type InputTipFieldProps<T extends ItemType = ItemType
|
|
44
|
+
export type InputTipFieldProps<T extends ItemType = ItemType> = {
|
|
21
45
|
/**
|
|
22
|
-
* Component
|
|
46
|
+
* Component properties
|
|
23
47
|
*/
|
|
24
|
-
|
|
48
|
+
componentProps: ComponentProps<T>;
|
|
49
|
+
} & (({
|
|
25
50
|
/**
|
|
26
51
|
* Component properties
|
|
27
52
|
*/
|
|
28
|
-
componentProps:
|
|
53
|
+
componentProps: ComponentProps<T>;
|
|
54
|
+
} & {
|
|
55
|
+
[K in ComponentKey]: {
|
|
29
56
|
/**
|
|
30
|
-
*
|
|
31
|
-
* @param value Duplicate test value
|
|
57
|
+
* Component key
|
|
32
58
|
*/
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Custom item label
|
|
40
|
-
* @param item List item data
|
|
41
|
-
* @returns Result
|
|
42
|
-
*/
|
|
43
|
-
itemLabel?: (item: T) => React.ReactNode;
|
|
44
|
-
/**
|
|
45
|
-
* Custom render item
|
|
46
|
-
* @param item List item data
|
|
47
|
-
* @returns Result
|
|
48
|
-
*/
|
|
49
|
-
renderItem?: (item: T) => React.ReactNode;
|
|
50
|
-
};
|
|
51
|
-
};
|
|
59
|
+
component: K;
|
|
60
|
+
} & Omit<React.ComponentProps<ComponentMap[K]>, "component">;
|
|
61
|
+
}[ComponentKey]) | ({
|
|
62
|
+
component?: "input";
|
|
63
|
+
} & Omit<InputFieldProps, "component">));
|
|
52
64
|
/**
|
|
53
65
|
* InputField with tips
|
|
54
66
|
* @param props Props
|
|
55
67
|
* @returns Component
|
|
56
68
|
*/
|
|
57
|
-
export declare function InputTipField<T extends ItemType = ItemType
|
|
69
|
+
export declare function InputTipField<T extends ItemType = ItemType>(props: InputTipFieldProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
58
70
|
export {};
|
package/lib/cjs/InputTipField.js
CHANGED
|
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.InputTipField = InputTipField;
|
|
7
7
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
8
|
+
const shared_1 = require("@etsoo/shared");
|
|
8
9
|
const Typography_1 = __importDefault(require("@mui/material/Typography"));
|
|
9
10
|
const react_1 = __importDefault(require("react"));
|
|
10
11
|
const InputField_1 = require("./InputField");
|
|
@@ -17,7 +18,6 @@ const EmailInput_1 = require("./EmailInput");
|
|
|
17
18
|
const MobileInput_1 = require("./MobileInput");
|
|
18
19
|
const PhoneInput_1 = require("./PhoneInput");
|
|
19
20
|
const componentMap = {
|
|
20
|
-
input: InputField_1.InputField,
|
|
21
21
|
email: EmailInput_1.EmailInput,
|
|
22
22
|
phone: PhoneInput_1.PhoneInput,
|
|
23
23
|
mobile: MobileInput_1.MobileInput
|
|
@@ -39,9 +39,9 @@ function InputTipField(props) {
|
|
|
39
39
|
const { labelProps = {
|
|
40
40
|
title: app?.get("clickForDetails"),
|
|
41
41
|
sx: { color: (theme) => theme.palette.error.main, cursor: "pointer" }
|
|
42
|
-
}, loadData, itemLabel = (item) => item
|
|
42
|
+
}, loadData, itemLabel = (item) => shared_1.DataTypes.getObjectItemLabel(item), renderItem = (item) => (0, jsx_runtime_1.jsx)(ListItem_1.default, { children: itemLabel(item) }, item.id) } = componentProps;
|
|
43
43
|
const { input, ...slotRests } = slotProps;
|
|
44
|
-
const Component = componentMap[component];
|
|
44
|
+
const Component = component === "input" ? InputField_1.InputField : componentMap[component];
|
|
45
45
|
const load = (value) => {
|
|
46
46
|
if (value.length < 2) {
|
|
47
47
|
setTitle(undefined);
|
|
@@ -1,58 +1,70 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { IdType } from "@etsoo/shared";
|
|
2
2
|
import { TypographyProps } from "@mui/material/Typography";
|
|
3
3
|
import React from "react";
|
|
4
|
-
import {
|
|
4
|
+
import { InputFieldProps } from "./InputField";
|
|
5
5
|
import { EmailInput } from "./EmailInput";
|
|
6
6
|
import { MobileInput } from "./MobileInput";
|
|
7
7
|
import { PhoneInput } from "./PhoneInput";
|
|
8
|
-
type ItemType =
|
|
8
|
+
type ItemType = {
|
|
9
|
+
id: IdType;
|
|
10
|
+
};
|
|
9
11
|
declare const componentMap: {
|
|
10
|
-
input: typeof InputField;
|
|
11
12
|
email: typeof EmailInput;
|
|
12
13
|
phone: typeof PhoneInput;
|
|
13
14
|
mobile: typeof MobileInput;
|
|
14
15
|
};
|
|
15
16
|
type ComponentMap = typeof componentMap;
|
|
16
17
|
type ComponentKey = keyof ComponentMap;
|
|
18
|
+
type ComponentProps<T extends ItemType> = {
|
|
19
|
+
/**
|
|
20
|
+
* Load data
|
|
21
|
+
* @param value Duplicate test value
|
|
22
|
+
*/
|
|
23
|
+
loadData(value: string): Promise<[T[]?, string?]>;
|
|
24
|
+
/**
|
|
25
|
+
* Label props
|
|
26
|
+
*/
|
|
27
|
+
labelProps?: Omit<TypographyProps, "onClick">;
|
|
28
|
+
/**
|
|
29
|
+
* Custom item label
|
|
30
|
+
* @param item List item data
|
|
31
|
+
* @returns Result
|
|
32
|
+
*/
|
|
33
|
+
itemLabel?: (item: T) => React.ReactNode;
|
|
34
|
+
/**
|
|
35
|
+
* Custom render item
|
|
36
|
+
* @param item List item data
|
|
37
|
+
* @returns Result
|
|
38
|
+
*/
|
|
39
|
+
renderItem?: (item: T) => React.ReactNode;
|
|
40
|
+
};
|
|
17
41
|
/**
|
|
18
42
|
* InputField with tips properties
|
|
19
43
|
*/
|
|
20
|
-
export type InputTipFieldProps<T extends ItemType = ItemType
|
|
44
|
+
export type InputTipFieldProps<T extends ItemType = ItemType> = {
|
|
21
45
|
/**
|
|
22
|
-
* Component
|
|
46
|
+
* Component properties
|
|
23
47
|
*/
|
|
24
|
-
|
|
48
|
+
componentProps: ComponentProps<T>;
|
|
49
|
+
} & (({
|
|
25
50
|
/**
|
|
26
51
|
* Component properties
|
|
27
52
|
*/
|
|
28
|
-
componentProps:
|
|
53
|
+
componentProps: ComponentProps<T>;
|
|
54
|
+
} & {
|
|
55
|
+
[K in ComponentKey]: {
|
|
29
56
|
/**
|
|
30
|
-
*
|
|
31
|
-
* @param value Duplicate test value
|
|
57
|
+
* Component key
|
|
32
58
|
*/
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Custom item label
|
|
40
|
-
* @param item List item data
|
|
41
|
-
* @returns Result
|
|
42
|
-
*/
|
|
43
|
-
itemLabel?: (item: T) => React.ReactNode;
|
|
44
|
-
/**
|
|
45
|
-
* Custom render item
|
|
46
|
-
* @param item List item data
|
|
47
|
-
* @returns Result
|
|
48
|
-
*/
|
|
49
|
-
renderItem?: (item: T) => React.ReactNode;
|
|
50
|
-
};
|
|
51
|
-
};
|
|
59
|
+
component: K;
|
|
60
|
+
} & Omit<React.ComponentProps<ComponentMap[K]>, "component">;
|
|
61
|
+
}[ComponentKey]) | ({
|
|
62
|
+
component?: "input";
|
|
63
|
+
} & Omit<InputFieldProps, "component">));
|
|
52
64
|
/**
|
|
53
65
|
* InputField with tips
|
|
54
66
|
* @param props Props
|
|
55
67
|
* @returns Component
|
|
56
68
|
*/
|
|
57
|
-
export declare function InputTipField<T extends ItemType = ItemType
|
|
69
|
+
export declare function InputTipField<T extends ItemType = ItemType>(props: InputTipFieldProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
58
70
|
export {};
|
package/lib/mjs/InputTipField.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { DataTypes } from "@etsoo/shared";
|
|
2
3
|
import Typography from "@mui/material/Typography";
|
|
3
4
|
import React from "react";
|
|
4
5
|
import { InputField } from "./InputField";
|
|
@@ -11,7 +12,6 @@ import { EmailInput } from "./EmailInput";
|
|
|
11
12
|
import { MobileInput } from "./MobileInput";
|
|
12
13
|
import { PhoneInput } from "./PhoneInput";
|
|
13
14
|
const componentMap = {
|
|
14
|
-
input: InputField,
|
|
15
15
|
email: EmailInput,
|
|
16
16
|
phone: PhoneInput,
|
|
17
17
|
mobile: MobileInput
|
|
@@ -33,9 +33,9 @@ export function InputTipField(props) {
|
|
|
33
33
|
const { labelProps = {
|
|
34
34
|
title: app?.get("clickForDetails"),
|
|
35
35
|
sx: { color: (theme) => theme.palette.error.main, cursor: "pointer" }
|
|
36
|
-
}, loadData, itemLabel = (item) => item
|
|
36
|
+
}, loadData, itemLabel = (item) => DataTypes.getObjectItemLabel(item), renderItem = (item) => _jsx(ListItem, { children: itemLabel(item) }, item.id) } = componentProps;
|
|
37
37
|
const { input, ...slotRests } = slotProps;
|
|
38
|
-
const Component = componentMap[component];
|
|
38
|
+
const Component = component === "input" ? InputField : componentMap[component];
|
|
39
39
|
const load = (value) => {
|
|
40
40
|
if (value.length < 2) {
|
|
41
41
|
setTitle(undefined);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@etsoo/materialui",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.88",
|
|
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.48",
|
|
44
44
|
"@etsoo/notificationbase": "^1.1.66",
|
|
45
|
-
"@etsoo/react": "^1.8.
|
|
45
|
+
"@etsoo/react": "^1.8.63",
|
|
46
46
|
"@etsoo/shared": "^1.2.79",
|
|
47
47
|
"@mui/icons-material": "^7.3.5",
|
|
48
48
|
"@mui/material": "^7.3.5",
|
package/src/InputTipField.tsx
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { DataTypes } from "@etsoo/shared";
|
|
1
|
+
import { DataTypes, IdType } from "@etsoo/shared";
|
|
2
2
|
import Typography, { TypographyProps } from "@mui/material/Typography";
|
|
3
3
|
import React from "react";
|
|
4
|
-
import { InputField } from "./InputField";
|
|
4
|
+
import { InputField, InputFieldProps } from "./InputField";
|
|
5
5
|
import { useAppContext } from "./app/ReactApp";
|
|
6
6
|
import ListItem from "@mui/material/ListItem";
|
|
7
7
|
import Popover from "@mui/material/Popover";
|
|
@@ -11,10 +11,11 @@ import { EmailInput } from "./EmailInput";
|
|
|
11
11
|
import { MobileInput } from "./MobileInput";
|
|
12
12
|
import { PhoneInput } from "./PhoneInput";
|
|
13
13
|
|
|
14
|
-
type ItemType =
|
|
14
|
+
type ItemType = {
|
|
15
|
+
id: IdType;
|
|
16
|
+
};
|
|
15
17
|
|
|
16
18
|
const componentMap = {
|
|
17
|
-
input: InputField,
|
|
18
19
|
email: EmailInput,
|
|
19
20
|
phone: PhoneInput,
|
|
20
21
|
mobile: MobileInput
|
|
@@ -23,58 +24,66 @@ const componentMap = {
|
|
|
23
24
|
type ComponentMap = typeof componentMap;
|
|
24
25
|
type ComponentKey = keyof ComponentMap;
|
|
25
26
|
|
|
26
|
-
|
|
27
|
-
* InputField with tips properties
|
|
28
|
-
*/
|
|
29
|
-
export type InputTipFieldProps<
|
|
30
|
-
T extends ItemType = ItemType,
|
|
31
|
-
K extends ComponentKey = "input"
|
|
32
|
-
> = Omit<React.ComponentProps<ComponentMap[K]>, "component"> & {
|
|
27
|
+
type ComponentProps<T extends ItemType> = {
|
|
33
28
|
/**
|
|
34
|
-
*
|
|
29
|
+
* Load data
|
|
30
|
+
* @param value Duplicate test value
|
|
35
31
|
*/
|
|
36
|
-
|
|
32
|
+
loadData(value: string): Promise<[T[]?, string?]>;
|
|
37
33
|
|
|
38
34
|
/**
|
|
39
|
-
*
|
|
35
|
+
* Label props
|
|
40
36
|
*/
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
* @returns Result
|
|
57
|
-
*/
|
|
58
|
-
itemLabel?: (item: T) => React.ReactNode;
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Custom render item
|
|
62
|
-
* @param item List item data
|
|
63
|
-
* @returns Result
|
|
64
|
-
*/
|
|
65
|
-
renderItem?: (item: T) => React.ReactNode;
|
|
66
|
-
};
|
|
37
|
+
labelProps?: Omit<TypographyProps, "onClick">;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Custom item label
|
|
41
|
+
* @param item List item data
|
|
42
|
+
* @returns Result
|
|
43
|
+
*/
|
|
44
|
+
itemLabel?: (item: T) => React.ReactNode;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Custom render item
|
|
48
|
+
* @param item List item data
|
|
49
|
+
* @returns Result
|
|
50
|
+
*/
|
|
51
|
+
renderItem?: (item: T) => React.ReactNode;
|
|
67
52
|
};
|
|
68
53
|
|
|
54
|
+
/**
|
|
55
|
+
* InputField with tips properties
|
|
56
|
+
*/
|
|
57
|
+
export type InputTipFieldProps<T extends ItemType = ItemType> = {
|
|
58
|
+
/**
|
|
59
|
+
* Component properties
|
|
60
|
+
*/
|
|
61
|
+
componentProps: ComponentProps<T>;
|
|
62
|
+
} & (
|
|
63
|
+
| ({
|
|
64
|
+
/**
|
|
65
|
+
* Component properties
|
|
66
|
+
*/
|
|
67
|
+
componentProps: ComponentProps<T>;
|
|
68
|
+
} & {
|
|
69
|
+
[K in ComponentKey]: {
|
|
70
|
+
/**
|
|
71
|
+
* Component key
|
|
72
|
+
*/
|
|
73
|
+
component: K;
|
|
74
|
+
} & Omit<React.ComponentProps<ComponentMap[K]>, "component">;
|
|
75
|
+
}[ComponentKey])
|
|
76
|
+
| ({ component?: "input" } & Omit<InputFieldProps, "component">)
|
|
77
|
+
);
|
|
78
|
+
|
|
69
79
|
/**
|
|
70
80
|
* InputField with tips
|
|
71
81
|
* @param props Props
|
|
72
82
|
* @returns Component
|
|
73
83
|
*/
|
|
74
|
-
export function InputTipField<
|
|
75
|
-
T
|
|
76
|
-
|
|
77
|
-
>(props: InputTipFieldProps<T, K>) {
|
|
84
|
+
export function InputTipField<T extends ItemType = ItemType>(
|
|
85
|
+
props: InputTipFieldProps<T>
|
|
86
|
+
) {
|
|
78
87
|
// Global app
|
|
79
88
|
const app = useAppContext();
|
|
80
89
|
|
|
@@ -100,13 +109,14 @@ export function InputTipField<
|
|
|
100
109
|
sx: { color: (theme) => theme.palette.error.main, cursor: "pointer" }
|
|
101
110
|
},
|
|
102
111
|
loadData,
|
|
103
|
-
itemLabel = (item) => item
|
|
112
|
+
itemLabel = (item) => DataTypes.getObjectItemLabel(item),
|
|
104
113
|
renderItem = (item) => <ListItem key={item.id}>{itemLabel(item)}</ListItem>
|
|
105
114
|
} = componentProps;
|
|
106
115
|
|
|
107
116
|
const { input, ...slotRests } = slotProps;
|
|
108
117
|
|
|
109
|
-
const Component =
|
|
118
|
+
const Component =
|
|
119
|
+
component === "input" ? InputField : componentMap[component];
|
|
110
120
|
|
|
111
121
|
const load = (value: string) => {
|
|
112
122
|
if (value.length < 2) {
|
|
@@ -158,7 +168,7 @@ export function InputTipField<
|
|
|
158
168
|
},
|
|
159
169
|
...slotRests
|
|
160
170
|
}}
|
|
161
|
-
{...
|
|
171
|
+
{...rest}
|
|
162
172
|
/>
|
|
163
173
|
</React.Fragment>
|
|
164
174
|
);
|