@etsoo/materialui 1.1.5 → 1.1.7

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.
@@ -1,114 +1,114 @@
1
1
  import {
2
- DataTypes,
3
- IdDefaultType,
4
- LabelDefaultType,
5
- ListType,
6
- Utils
7
- } from '@etsoo/shared';
2
+ DataTypes,
3
+ IdDefaultType,
4
+ LabelDefaultType,
5
+ ListType,
6
+ Utils
7
+ } from "@etsoo/shared";
8
8
  import {
9
- Box,
10
- Checkbox,
11
- FormControl,
12
- FormControlLabel,
13
- FormControlProps,
14
- FormGroup,
15
- FormHelperText,
16
- InputLabel,
17
- Radio,
18
- RadioGroup,
19
- useTheme
20
- } from '@mui/material';
21
- import NotchedOutline from '@mui/material/OutlinedInput';
22
- import React from 'react';
9
+ Box,
10
+ Checkbox,
11
+ FormControl,
12
+ FormControlLabel,
13
+ FormControlProps,
14
+ FormGroup,
15
+ FormHelperText,
16
+ InputLabel,
17
+ Radio,
18
+ RadioGroup,
19
+ useTheme
20
+ } from "@mui/material";
21
+ import NotchedOutline from "@mui/material/OutlinedInput";
22
+ import React from "react";
23
23
 
24
24
  /**
25
25
  * OptionGroup methods ref
26
26
  */
27
27
  export interface OptionGroupRef {
28
- /**
29
- * Disable specific items with their ids
30
- * @param ids Ids
31
- */
32
- disable(ids: unknown[]): void;
28
+ /**
29
+ * Disable specific items with their ids
30
+ * @param ids Ids
31
+ */
32
+ disable(ids: unknown[]): void;
33
33
  }
34
34
 
35
35
  /**
36
36
  * OptionGroup props
37
37
  */
38
38
  export type OptionGroupProps<
39
- T extends object,
40
- D extends DataTypes.Keys<T>,
41
- L extends DataTypes.Keys<T, string>
42
- > = Omit<FormControlProps<'fieldset'>, 'defaultValue'> & {
43
- /**
44
- * Default value
45
- */
46
- defaultValue?: T[D] | T[D][];
47
-
48
- /**
49
- * Get option label function
50
- */
51
- getOptionLabel?: (option: T) => string;
52
-
53
- /**
54
- * Id field
55
- */
56
- idField?: D;
57
-
58
- /**
59
- * Label
60
- */
61
- label?: string;
62
-
63
- /**
64
- * Label field
65
- */
66
- labelField?: L;
67
-
68
- /**
69
- * Methods
70
- */
71
- mRef?: React.Ref<OptionGroupRef>;
72
-
73
- /**
74
- * Multiple choose item
75
- */
76
- multiple?: boolean;
77
-
78
- /**
79
- * Field name
80
- */
81
- name: string;
82
-
83
- /**
84
- * On value change handler
85
- */
86
- onValueChange?: (value: T[D] | T[D][] | undefined) => void;
87
-
88
- /**
89
- * Array of options.
90
- */
91
- options: ReadonlyArray<T>;
92
-
93
- /**
94
- * Is the field read only?
95
- */
96
- readOnly?: boolean;
97
-
98
- /**
99
- * Display group of elements in a compact row
100
- */
101
- row?: boolean;
102
-
103
- /**
104
- * Item size
105
- */
106
- itemSize?: 'small' | 'medium';
107
-
108
- /**
109
- * Helper text
110
- */
111
- helperText?: React.ReactNode;
39
+ T extends object,
40
+ D extends DataTypes.Keys<T>,
41
+ L extends DataTypes.Keys<T, string>
42
+ > = Omit<FormControlProps<"fieldset">, "defaultValue"> & {
43
+ /**
44
+ * Default value
45
+ */
46
+ defaultValue?: T[D] | T[D][];
47
+
48
+ /**
49
+ * Get option label function
50
+ */
51
+ getOptionLabel?: (option: T) => string;
52
+
53
+ /**
54
+ * Id field
55
+ */
56
+ idField?: D;
57
+
58
+ /**
59
+ * Label
60
+ */
61
+ label?: string;
62
+
63
+ /**
64
+ * Label field
65
+ */
66
+ labelField?: L;
67
+
68
+ /**
69
+ * Methods
70
+ */
71
+ mRef?: React.Ref<OptionGroupRef>;
72
+
73
+ /**
74
+ * Multiple choose item
75
+ */
76
+ multiple?: boolean;
77
+
78
+ /**
79
+ * Field name
80
+ */
81
+ name: string;
82
+
83
+ /**
84
+ * On value change handler
85
+ */
86
+ onValueChange?: (value: T[D] | T[D][] | undefined) => void;
87
+
88
+ /**
89
+ * Array of options.
90
+ */
91
+ options: ReadonlyArray<T>;
92
+
93
+ /**
94
+ * Is the field read only?
95
+ */
96
+ readOnly?: boolean;
97
+
98
+ /**
99
+ * Display group of elements in a compact row
100
+ */
101
+ row?: boolean;
102
+
103
+ /**
104
+ * Item size
105
+ */
106
+ itemSize?: "small" | "medium";
107
+
108
+ /**
109
+ * Helper text
110
+ */
111
+ helperText?: React.ReactNode;
112
112
  };
113
113
 
114
114
  /**
@@ -117,186 +117,187 @@ export type OptionGroupProps<
117
117
  * @returns Component
118
118
  */
119
119
  export function OptionGroup<
120
- T extends object = ListType,
121
- D extends DataTypes.Keys<T> = IdDefaultType<T>,
122
- L extends DataTypes.Keys<T, string> = LabelDefaultType<T>
120
+ T extends object = ListType,
121
+ D extends DataTypes.Keys<T> = IdDefaultType<T>,
122
+ L extends DataTypes.Keys<T, string> = LabelDefaultType<T>
123
123
  >(props: OptionGroupProps<T, D, L>) {
124
- // Destruct
125
- const {
126
- getOptionLabel,
127
- defaultValue,
128
- idField = 'id' as D,
129
- label,
130
- labelField = 'label' as L,
131
- multiple = false,
132
- mRef,
133
- name,
134
- onValueChange,
135
- options,
136
- readOnly,
137
- row,
138
- itemSize,
139
- helperText,
140
- variant,
141
- required,
142
- ...rest
143
- } = props;
144
-
145
- // Theme
146
- const theme = useTheme();
147
-
148
- // Get option value
149
- // D type should be the source id type
150
- const getOptionValue = (option: T): T[D] | null => {
151
- const value = DataTypes.getValue(option, idField);
152
- if (value == null) return null;
153
- return value as T[D];
154
- };
155
-
156
- // Checkbox values
157
- const [values, setValues] = React.useState<T[D][]>([]);
158
-
159
- // Values
160
- const dv = React.useMemo(
161
- () =>
162
- defaultValue == null
163
- ? []
164
- : Array.isArray(defaultValue)
165
- ? defaultValue
166
- : [defaultValue],
167
- [defaultValue]
168
- );
169
-
170
- React.useEffect(() => {
171
- setValues(dv);
172
- }, [dv]);
173
-
174
- // Disabled ids
175
- const [disabledIds, setDisabledIds] = React.useState<unknown[]>();
176
-
177
- // Item checked
178
- const itemChecked = (option: T) => {
179
- // Value
180
- const value = getOptionValue(option);
181
- if (value == null) return false;
182
-
183
- return values.includes(value);
184
- };
185
-
186
- React.useImperativeHandle(mRef, () => ({
187
- disable(ids: unknown[]) {
188
- setDisabledIds(ids);
189
- }
190
- }));
191
-
192
- // First item value
193
- const firstOptionValue = getOptionValue(options[0]);
194
-
195
- // Items
196
- const list = options.map((option) => {
197
- // Value
198
- const ov = getOptionValue(option);
199
-
200
- // Control
201
- const control = multiple ? (
202
- <Checkbox
203
- name={name}
204
- readOnly={readOnly}
205
- size={itemSize}
206
- checked={itemChecked(option)}
207
- disabled={disabledIds?.includes(ov)}
208
- onChange={(event) => {
209
- if (firstOptionValue == null) return;
210
-
211
- const typeValue = Utils.parseString(
212
- event.target.value,
213
- firstOptionValue
214
- );
215
-
216
- const changedValues = [...values];
217
- if (event.target.checked) {
218
- if (changedValues.includes(typeValue)) return;
219
- changedValues.push(typeValue);
220
- } else {
221
- const index = changedValues.findIndex(
222
- (v) => v === typeValue
223
- );
224
- if (index === -1) return;
225
- changedValues.splice(index, 1);
226
- }
227
-
228
- if (onValueChange) onValueChange(changedValues);
229
- setValues(changedValues);
230
- }}
231
- />
232
- ) : (
233
- <Radio
234
- disabled={disabledIds?.includes(ov)}
235
- size={itemSize}
236
- readOnly={readOnly}
237
- />
238
- );
239
-
240
- // Label
241
- const label =
242
- getOptionLabel == null
243
- ? `${option[labelField]}`
244
- : getOptionLabel(option);
245
-
246
- // Value, convert to string
247
- // Will fail when type is number
248
- const value = getOptionValue(option) as unknown as React.Key;
249
-
250
- return (
251
- <FormControlLabel
252
- key={value}
253
- control={control}
254
- value={value}
255
- label={label}
256
- />
257
- );
258
- });
259
-
260
- // Group
261
- const group = multiple ? (
262
- <FormGroup row={row}>{list}</FormGroup>
124
+ // Destruct
125
+ const {
126
+ getOptionLabel,
127
+ defaultValue,
128
+ idField = "id" as D,
129
+ label,
130
+ labelField = "label" as L,
131
+ multiple = false,
132
+ mRef,
133
+ name,
134
+ onValueChange,
135
+ options,
136
+ readOnly,
137
+ row,
138
+ itemSize,
139
+ helperText,
140
+ variant,
141
+ required,
142
+ fullWidth,
143
+ ...rest
144
+ } = props;
145
+
146
+ // Theme
147
+ const theme = useTheme();
148
+
149
+ // Get option value
150
+ // D type should be the source id type
151
+ const getOptionValue = (option: T): T[D] | null => {
152
+ const value = DataTypes.getValue(option, idField);
153
+ if (value == null) return null;
154
+ return value as T[D];
155
+ };
156
+
157
+ // Checkbox values
158
+ const [values, setValues] = React.useState<T[D][]>([]);
159
+
160
+ // Values
161
+ const dv = React.useMemo(
162
+ () =>
163
+ defaultValue == null
164
+ ? []
165
+ : Array.isArray(defaultValue)
166
+ ? defaultValue
167
+ : [defaultValue],
168
+ [defaultValue]
169
+ );
170
+
171
+ React.useEffect(() => {
172
+ setValues(dv);
173
+ }, [dv]);
174
+
175
+ // Disabled ids
176
+ const [disabledIds, setDisabledIds] = React.useState<unknown[]>();
177
+
178
+ // Item checked
179
+ const itemChecked = (option: T) => {
180
+ // Value
181
+ const value = getOptionValue(option);
182
+ if (value == null) return false;
183
+
184
+ return values.includes(value);
185
+ };
186
+
187
+ React.useImperativeHandle(mRef, () => ({
188
+ disable(ids: unknown[]) {
189
+ setDisabledIds(ids);
190
+ }
191
+ }));
192
+
193
+ // First item value
194
+ const firstOptionValue = getOptionValue(options[0]);
195
+
196
+ // Items
197
+ const list = options.map((option) => {
198
+ // Value
199
+ const ov = getOptionValue(option);
200
+
201
+ // Control
202
+ const control = multiple ? (
203
+ <Checkbox
204
+ name={name}
205
+ readOnly={readOnly}
206
+ size={itemSize}
207
+ checked={itemChecked(option)}
208
+ disabled={disabledIds?.includes(ov)}
209
+ onChange={(event) => {
210
+ if (firstOptionValue == null) return;
211
+
212
+ const typeValue = Utils.parseString(
213
+ event.target.value,
214
+ firstOptionValue
215
+ );
216
+
217
+ const changedValues = [...values];
218
+ if (event.target.checked) {
219
+ if (changedValues.includes(typeValue)) return;
220
+ changedValues.push(typeValue);
221
+ } else {
222
+ const index = changedValues.findIndex((v) => v === typeValue);
223
+ if (index === -1) return;
224
+ changedValues.splice(index, 1);
225
+ }
226
+
227
+ if (onValueChange) onValueChange(changedValues);
228
+ setValues(changedValues);
229
+ }}
230
+ />
263
231
  ) : (
264
- <RadioGroup
265
- row={row}
266
- name={name}
267
- value={values[0] ?? ''}
268
- onChange={(_event, value) => {
269
- if (firstOptionValue == null) return;
270
- const typeValue = Utils.parseString(value, firstOptionValue);
271
- if (onValueChange) onValueChange(typeValue);
272
- setValues([typeValue]);
273
- }}
274
- >
275
- {list}
276
- </RadioGroup>
232
+ <Radio
233
+ disabled={disabledIds?.includes(ov)}
234
+ size={itemSize}
235
+ readOnly={readOnly}
236
+ />
277
237
  );
278
238
 
279
- // Layout
239
+ // Label
240
+ const label =
241
+ getOptionLabel == null ? `${option[labelField]}` : getOptionLabel(option);
242
+
243
+ // Value, convert to string
244
+ // Will fail when type is number
245
+ const value = getOptionValue(option) as unknown as React.Key;
246
+
280
247
  return (
281
- <React.Fragment>
282
- <FormControl component="fieldset" {...rest}>
283
- {label && (
284
- <InputLabel required={required} variant={variant} shrink>
285
- {label}
286
- </InputLabel>
287
- )}
288
- <Box paddingLeft={2} paddingY="7px">
289
- {group}
290
- </Box>
291
- {variant === 'outlined' && (
292
- <NotchedOutline
293
- label={label && required ? label + ' *' : label}
294
- notched
295
- style={{ borderRadius: theme.shape.borderRadius }}
296
- />
297
- )}
298
- </FormControl>
299
- {helperText && <FormHelperText>{helperText}</FormHelperText>}
300
- </React.Fragment>
248
+ <FormControlLabel
249
+ key={value}
250
+ control={control}
251
+ value={value}
252
+ label={label}
253
+ />
301
254
  );
255
+ });
256
+
257
+ // Group
258
+ const group = multiple ? (
259
+ <FormGroup row={row}>{list}</FormGroup>
260
+ ) : (
261
+ <RadioGroup
262
+ row={row}
263
+ name={name}
264
+ value={values[0] ?? ""}
265
+ onChange={(_event, value) => {
266
+ if (firstOptionValue == null) return;
267
+ const typeValue = Utils.parseString(value, firstOptionValue);
268
+ if (onValueChange) onValueChange(typeValue);
269
+ setValues([typeValue]);
270
+ }}
271
+ >
272
+ {list}
273
+ </RadioGroup>
274
+ );
275
+
276
+ // Layout
277
+ return (
278
+ <React.Fragment>
279
+ <FormControl component="fieldset" fullWidth={fullWidth} {...rest}>
280
+ {label && (
281
+ <InputLabel required={required} variant={variant} shrink>
282
+ {label}
283
+ </InputLabel>
284
+ )}
285
+ <Box paddingLeft={2} paddingY="7px">
286
+ {group}
287
+ </Box>
288
+ {variant === "outlined" && (
289
+ <NotchedOutline
290
+ label={label && required ? label + " *" : label}
291
+ notched
292
+ style={{
293
+ position: "absolute",
294
+ borderRadius: theme.shape.borderRadius,
295
+ width: fullWidth ? "100%" : "auto"
296
+ }}
297
+ />
298
+ )}
299
+ </FormControl>
300
+ {helperText && <FormHelperText>{helperText}</FormHelperText>}
301
+ </React.Fragment>
302
+ );
302
303
  }