@etsoo/materialui 1.0.5 → 1.0.6
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/lib/HiSelector.d.ts +58 -0
- package/lib/HiSelector.js +47 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/package.json +1 -1
- package/src/HiSelector.tsx +201 -0
- package/src/index.ts +1 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { DataTypes, IdDefaultType, LabelDefaultType } from '@etsoo/shared';
|
|
2
|
+
import { SelectChangeEvent } from '@mui/material';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
/**
|
|
5
|
+
* Hierarchy selector props
|
|
6
|
+
*/
|
|
7
|
+
export declare type HiSelectorProps<T extends object, D extends DataTypes.Keys<T> = IdDefaultType<T>, L extends DataTypes.Keys<T, string> = LabelDefaultType<T>> = {
|
|
8
|
+
/**
|
|
9
|
+
* Id field
|
|
10
|
+
*/
|
|
11
|
+
idField?: D;
|
|
12
|
+
/**
|
|
13
|
+
* Error
|
|
14
|
+
*/
|
|
15
|
+
error?: boolean;
|
|
16
|
+
/**
|
|
17
|
+
* The helper text content.
|
|
18
|
+
*/
|
|
19
|
+
helperText?: React.ReactNode;
|
|
20
|
+
/**
|
|
21
|
+
* Name, also hidden input field name
|
|
22
|
+
*/
|
|
23
|
+
name: string;
|
|
24
|
+
/**
|
|
25
|
+
* Label
|
|
26
|
+
*/
|
|
27
|
+
label?: string;
|
|
28
|
+
/**
|
|
29
|
+
* Label field
|
|
30
|
+
*/
|
|
31
|
+
labelField?: L;
|
|
32
|
+
/**
|
|
33
|
+
* Load data callback
|
|
34
|
+
*/
|
|
35
|
+
loadData: (parent?: T[D]) => PromiseLike<T[] | null | undefined>;
|
|
36
|
+
/**
|
|
37
|
+
* On value change event
|
|
38
|
+
*/
|
|
39
|
+
onChange?: (value: unknown) => void;
|
|
40
|
+
/**
|
|
41
|
+
* On item change event
|
|
42
|
+
*/
|
|
43
|
+
onItemChange?: (e: SelectChangeEvent<unknown>) => void;
|
|
44
|
+
/**
|
|
45
|
+
* Required
|
|
46
|
+
*/
|
|
47
|
+
required?: boolean;
|
|
48
|
+
/**
|
|
49
|
+
* Values
|
|
50
|
+
*/
|
|
51
|
+
values?: T[D][];
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* Hierarchy selector
|
|
55
|
+
* @param props Prop
|
|
56
|
+
* @returns Component
|
|
57
|
+
*/
|
|
58
|
+
export declare function HiSelector<T extends object, D extends DataTypes.Keys<T> = IdDefaultType<T>, L extends DataTypes.Keys<T, string> = LabelDefaultType<T>>(props: HiSelectorProps<T, D, L>): JSX.Element;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { FormLabel, Grid } from '@mui/material';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { SelectEx } from './SelectEx';
|
|
4
|
+
/**
|
|
5
|
+
* Hierarchy selector
|
|
6
|
+
* @param props Prop
|
|
7
|
+
* @returns Component
|
|
8
|
+
*/
|
|
9
|
+
export function HiSelector(props) {
|
|
10
|
+
// Destruct
|
|
11
|
+
const { idField = 'id', error, helperText, name, label = name, labelField = 'name', loadData, onChange, onItemChange, required, values = [] } = props;
|
|
12
|
+
const [localValues, setValues] = React.useState(values);
|
|
13
|
+
const updateValue = (value) => {
|
|
14
|
+
if (onChange)
|
|
15
|
+
onChange(value);
|
|
16
|
+
};
|
|
17
|
+
const doChange = (event, index) => {
|
|
18
|
+
const value = event.target.value;
|
|
19
|
+
const itemValue = value === '' ? undefined : value;
|
|
20
|
+
updateValue(itemValue);
|
|
21
|
+
const newValues = [...localValues.slice(0, index)];
|
|
22
|
+
if (itemValue != null)
|
|
23
|
+
newValues.push(itemValue);
|
|
24
|
+
setValues(newValues);
|
|
25
|
+
if (onItemChange)
|
|
26
|
+
onItemChange(event);
|
|
27
|
+
};
|
|
28
|
+
React.useEffect(() => {
|
|
29
|
+
if (values.length > 0) {
|
|
30
|
+
setValues(values);
|
|
31
|
+
updateValue(values.at(-1));
|
|
32
|
+
}
|
|
33
|
+
}, [values]);
|
|
34
|
+
const currentValue = localValues.at(-1);
|
|
35
|
+
return (React.createElement(React.Fragment, null,
|
|
36
|
+
React.createElement(Grid, { item: true, xs: 12 },
|
|
37
|
+
React.createElement(FormLabel, { required: required, sx: { fontSize: (theme) => theme.typography.caption } }, label),
|
|
38
|
+
React.createElement("input", { type: "hidden", name: name, value: `${currentValue !== null && currentValue !== void 0 ? currentValue : ''}` })),
|
|
39
|
+
React.createElement(Grid, { item: true, xs: 6, md: 4, lg: 3 },
|
|
40
|
+
React.createElement(SelectEx, { idField: idField, labelField: labelField, name: "tab1", search: true, fullWidth: true, loadData: () => loadData(), value: values[0], onChange: (event) => doChange(event, 0), inputRequired: required, error: error, helperText: helperText })),
|
|
41
|
+
localValues[0] != null && (React.createElement(Grid, { item: true, xs: 6, md: 4, lg: 3 },
|
|
42
|
+
React.createElement(SelectEx, { key: `${localValues[0]}`, idField: idField, labelField: labelField, name: "tab2", search: true, fullWidth: true, loadData: () => loadData(localValues[0]), value: values[1], onChange: (event) => doChange(event, 1) }))),
|
|
43
|
+
localValues[1] != null && (React.createElement(Grid, { item: true, xs: 6, md: 4, lg: 3 },
|
|
44
|
+
React.createElement(SelectEx, { key: `${localValues[1]}`, idField: idField, labelField: labelField, name: "tab3", search: true, fullWidth: true, loadData: () => loadData(localValues[1]), value: values[2], onChange: (event) => doChange(event, 2) }))),
|
|
45
|
+
localValues[2] != null && (React.createElement(Grid, { item: true, xs: 6, md: 4, lg: 3 },
|
|
46
|
+
React.createElement(SelectEx, { key: `${localValues[2]}`, idField: idField, labelField: labelField, name: "tab4", search: true, fullWidth: true, loadData: () => loadData(localValues[2]), value: values[3], onChange: (event) => doChange(event, 3) })))));
|
|
47
|
+
}
|
package/lib/index.d.ts
CHANGED
package/lib/index.js
CHANGED
package/package.json
CHANGED
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import { DataTypes, IdDefaultType, LabelDefaultType } from '@etsoo/shared';
|
|
2
|
+
import { FormLabel, Grid, SelectChangeEvent } from '@mui/material';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import { SelectEx } from './SelectEx';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Hierarchy selector props
|
|
8
|
+
*/
|
|
9
|
+
export type HiSelectorProps<
|
|
10
|
+
T extends object,
|
|
11
|
+
D extends DataTypes.Keys<T> = IdDefaultType<T>,
|
|
12
|
+
L extends DataTypes.Keys<T, string> = LabelDefaultType<T>
|
|
13
|
+
> = {
|
|
14
|
+
/**
|
|
15
|
+
* Id field
|
|
16
|
+
*/
|
|
17
|
+
idField?: D;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Error
|
|
21
|
+
*/
|
|
22
|
+
error?: boolean;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* The helper text content.
|
|
26
|
+
*/
|
|
27
|
+
helperText?: React.ReactNode;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Name, also hidden input field name
|
|
31
|
+
*/
|
|
32
|
+
name: string;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Label
|
|
36
|
+
*/
|
|
37
|
+
label?: string;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Label field
|
|
41
|
+
*/
|
|
42
|
+
labelField?: L;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Load data callback
|
|
46
|
+
*/
|
|
47
|
+
loadData: (parent?: T[D]) => PromiseLike<T[] | null | undefined>;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* On value change event
|
|
51
|
+
*/
|
|
52
|
+
onChange?: (value: unknown) => void;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* On item change event
|
|
56
|
+
*/
|
|
57
|
+
onItemChange?: (e: SelectChangeEvent<unknown>) => void;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Required
|
|
61
|
+
*/
|
|
62
|
+
required?: boolean;
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Values
|
|
66
|
+
*/
|
|
67
|
+
values?: T[D][];
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Hierarchy selector
|
|
72
|
+
* @param props Prop
|
|
73
|
+
* @returns Component
|
|
74
|
+
*/
|
|
75
|
+
export function HiSelector<
|
|
76
|
+
T extends object,
|
|
77
|
+
D extends DataTypes.Keys<T> = IdDefaultType<T>,
|
|
78
|
+
L extends DataTypes.Keys<T, string> = LabelDefaultType<T>
|
|
79
|
+
>(props: HiSelectorProps<T, D, L>) {
|
|
80
|
+
// Destruct
|
|
81
|
+
const {
|
|
82
|
+
idField = 'id' as D,
|
|
83
|
+
error,
|
|
84
|
+
helperText,
|
|
85
|
+
name,
|
|
86
|
+
label = name,
|
|
87
|
+
labelField = 'name' as L,
|
|
88
|
+
loadData,
|
|
89
|
+
onChange,
|
|
90
|
+
onItemChange,
|
|
91
|
+
required,
|
|
92
|
+
values = []
|
|
93
|
+
} = props;
|
|
94
|
+
|
|
95
|
+
// Value type
|
|
96
|
+
type ValueType = T[D];
|
|
97
|
+
const [localValues, setValues] = React.useState<ValueType[]>(values);
|
|
98
|
+
|
|
99
|
+
const updateValue = (value?: T[D]) => {
|
|
100
|
+
if (onChange) onChange(value);
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
const doChange = (event: SelectChangeEvent<unknown>, index: number) => {
|
|
104
|
+
const value = event.target.value;
|
|
105
|
+
const itemValue = value === '' ? undefined : (value as T[D]);
|
|
106
|
+
updateValue(itemValue);
|
|
107
|
+
|
|
108
|
+
const newValues = [...localValues.slice(0, index)];
|
|
109
|
+
if (itemValue != null) newValues.push(itemValue);
|
|
110
|
+
setValues(newValues);
|
|
111
|
+
|
|
112
|
+
if (onItemChange) onItemChange(event);
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
React.useEffect(() => {
|
|
116
|
+
if (values.length > 0) {
|
|
117
|
+
setValues(values);
|
|
118
|
+
updateValue(values.at(-1));
|
|
119
|
+
}
|
|
120
|
+
}, [values]);
|
|
121
|
+
|
|
122
|
+
const currentValue = localValues.at(-1);
|
|
123
|
+
|
|
124
|
+
return (
|
|
125
|
+
<React.Fragment>
|
|
126
|
+
<Grid item xs={12}>
|
|
127
|
+
<FormLabel
|
|
128
|
+
required={required}
|
|
129
|
+
sx={{ fontSize: (theme) => theme.typography.caption }}
|
|
130
|
+
>
|
|
131
|
+
{label}
|
|
132
|
+
</FormLabel>
|
|
133
|
+
<input
|
|
134
|
+
type="hidden"
|
|
135
|
+
name={name}
|
|
136
|
+
value={`${currentValue ?? ''}`}
|
|
137
|
+
/>
|
|
138
|
+
</Grid>
|
|
139
|
+
<Grid item xs={6} md={4} lg={3}>
|
|
140
|
+
<SelectEx<T, D, L>
|
|
141
|
+
idField={idField}
|
|
142
|
+
labelField={labelField}
|
|
143
|
+
name="tab1"
|
|
144
|
+
search
|
|
145
|
+
fullWidth
|
|
146
|
+
loadData={() => loadData()}
|
|
147
|
+
value={values[0]}
|
|
148
|
+
onChange={(event) => doChange(event, 0)}
|
|
149
|
+
inputRequired={required}
|
|
150
|
+
error={error}
|
|
151
|
+
helperText={helperText}
|
|
152
|
+
/>
|
|
153
|
+
</Grid>
|
|
154
|
+
{localValues[0] != null && (
|
|
155
|
+
<Grid item xs={6} md={4} lg={3}>
|
|
156
|
+
<SelectEx<T, D, L>
|
|
157
|
+
key={`${localValues[0]}`}
|
|
158
|
+
idField={idField}
|
|
159
|
+
labelField={labelField}
|
|
160
|
+
name="tab2"
|
|
161
|
+
search
|
|
162
|
+
fullWidth
|
|
163
|
+
loadData={() => loadData(localValues[0])}
|
|
164
|
+
value={values[1]}
|
|
165
|
+
onChange={(event) => doChange(event, 1)}
|
|
166
|
+
/>
|
|
167
|
+
</Grid>
|
|
168
|
+
)}
|
|
169
|
+
{localValues[1] != null && (
|
|
170
|
+
<Grid item xs={6} md={4} lg={3}>
|
|
171
|
+
<SelectEx<T, D, L>
|
|
172
|
+
key={`${localValues[1]}`}
|
|
173
|
+
idField={idField}
|
|
174
|
+
labelField={labelField}
|
|
175
|
+
name="tab3"
|
|
176
|
+
search
|
|
177
|
+
fullWidth
|
|
178
|
+
loadData={() => loadData(localValues[1])}
|
|
179
|
+
value={values[2]}
|
|
180
|
+
onChange={(event) => doChange(event, 2)}
|
|
181
|
+
/>
|
|
182
|
+
</Grid>
|
|
183
|
+
)}
|
|
184
|
+
{localValues[2] != null && (
|
|
185
|
+
<Grid item xs={6} md={4} lg={3}>
|
|
186
|
+
<SelectEx<T, D, L>
|
|
187
|
+
key={`${localValues[2]}`}
|
|
188
|
+
idField={idField}
|
|
189
|
+
labelField={labelField}
|
|
190
|
+
name="tab4"
|
|
191
|
+
search
|
|
192
|
+
fullWidth
|
|
193
|
+
loadData={() => loadData(localValues[2])}
|
|
194
|
+
value={values[3]}
|
|
195
|
+
onChange={(event) => doChange(event, 3)}
|
|
196
|
+
/>
|
|
197
|
+
</Grid>
|
|
198
|
+
)}
|
|
199
|
+
</React.Fragment>
|
|
200
|
+
);
|
|
201
|
+
}
|
package/src/index.ts
CHANGED