mui-fast-start 0.2.0 → 0.3.1
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/README.md +76 -29
- package/README_KR.md +176 -127
- package/dist/components/Object/Checkbox/ObjCheckIcon.d.ts +4 -0
- package/dist/components/Object/Checkbox/ObjCheckIcon.d.ts.map +1 -0
- package/dist/components/Object/Checkbox/ObjCheckbox.d.ts +4 -0
- package/dist/components/Object/Checkbox/ObjCheckbox.d.ts.map +1 -0
- package/dist/components/Object/Select/ObjSelectOne.d.ts +4 -0
- package/dist/components/Object/Select/ObjSelectOne.d.ts.map +1 -0
- package/dist/components/Object/Select/ObjSelectRecord.d.ts +4 -0
- package/dist/components/Object/Select/ObjSelectRecord.d.ts.map +1 -0
- package/dist/components/Object/Textfield/ObjNumber.d.ts +7 -0
- package/dist/components/Object/Textfield/ObjNumber.d.ts.map +1 -0
- package/dist/components/Object/Textfield/ObjText.d.ts +4 -0
- package/dist/components/Object/Textfield/ObjText.d.ts.map +1 -0
- package/dist/components/Single/Checkbox/SingleCheckIcon.d.ts +3 -1
- package/dist/components/Single/Checkbox/SingleCheckIcon.d.ts.map +1 -1
- package/dist/components/Single/Checkbox/SingleCheckbox.d.ts +3 -1
- package/dist/components/Single/Checkbox/SingleCheckbox.d.ts.map +1 -1
- package/dist/components/Single/Select/BaseSingleSelect.d.ts +14 -0
- package/dist/components/Single/Select/BaseSingleSelect.d.ts.map +1 -0
- package/dist/components/Single/Select/SingleSelectOne.d.ts +5 -0
- package/dist/components/Single/Select/SingleSelectOne.d.ts.map +1 -0
- package/dist/components/Single/Select/SingleSelectRecord.d.ts +4 -0
- package/dist/components/Single/Select/SingleSelectRecord.d.ts.map +1 -0
- package/dist/components/Single/TextField/SingleNumber.d.ts +6 -0
- package/dist/components/Single/TextField/SingleNumber.d.ts.map +1 -0
- package/dist/components/Single/TextField/SingleText.d.ts +3 -1
- package/dist/components/Single/TextField/SingleText.d.ts.map +1 -1
- package/dist/components/index.d.ts +12 -10
- package/dist/components/index.d.ts.map +1 -1
- package/dist/hooks/index.d.ts +2 -2
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/splits/useSplitNumberProps.d.ts +7 -0
- package/dist/hooks/splits/useSplitNumberProps.d.ts.map +1 -0
- package/dist/hooks/splits/useSplitTextProps.d.ts +6 -0
- package/dist/hooks/splits/useSplitTextProps.d.ts.map +1 -0
- package/dist/hooks/state/useObjToSingle.d.ts +2 -2
- package/dist/hooks/state/useObjToSingle.d.ts.map +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +310 -235
- package/dist/styles/FastStartProps.d.ts +29 -0
- package/dist/styles/FastStartProps.d.ts.map +1 -0
- package/dist/styles/FastStartProvider.d.ts +2 -17
- package/dist/styles/FastStartProvider.d.ts.map +1 -1
- package/dist/types/props.d.ts +38 -23
- package/dist/types/props.d.ts.map +1 -1
- package/dist/types/props.internal.d.ts +12 -0
- package/dist/types/props.internal.d.ts.map +1 -0
- package/dist/types/provider.d.ts +20 -30
- package/dist/types/provider.d.ts.map +1 -1
- package/dist/utils/object/error.d.ts +3 -2
- package/dist/utils/object/error.d.ts.map +1 -1
- package/examples/basic/src/main.tsx +26 -33
- package/examples/basic/src/pages/ObjPage.tsx +92 -9
- package/examples/basic/src/pages/SinglePage.tsx +69 -2
- package/examples/basic/tsconfig.app.json +5 -0
- package/examples/basic/tsconfig.node.json +5 -0
- package/examples/basic/vite.config.ts +1 -1
- package/package.json +1 -1
- package/src/components/Object/Checkbox/ObjCheckIcon.tsx +29 -0
- package/src/components/Object/Checkbox/ObjCheckbox.tsx +31 -0
- package/src/components/Object/Select/ObjSelectOne.tsx +34 -0
- package/src/components/Object/Select/ObjSelectRecord.tsx +34 -0
- package/src/components/Object/Textfield/ObjNumber.tsx +51 -0
- package/src/components/Object/Textfield/ObjText.tsx +29 -0
- package/src/components/Single/Checkbox/SingleCheckIcon.tsx +7 -5
- package/src/components/Single/Checkbox/SingleCheckbox.tsx +7 -5
- package/src/components/Single/Select/BaseSingleSelect.tsx +46 -0
- package/src/components/Single/Select/SingleSelectOne.tsx +56 -0
- package/src/components/Single/Select/SingleSelectRecord.tsx +52 -0
- package/src/components/Single/TextField/SingleNumber.tsx +19 -0
- package/src/components/Single/TextField/SingleText.tsx +6 -5
- package/src/components/index.ts +14 -12
- package/src/hooks/index.ts +2 -2
- package/src/hooks/splits/{useSplitSingleNumberProps.ts → useSplitNumberProps.ts} +58 -56
- package/src/hooks/splits/useSplitTextProps.ts +36 -0
- package/src/hooks/state/useObjToSingle.ts +3 -2
- package/src/index.ts +0 -1
- package/src/styles/FastStartProps.ts +82 -0
- package/src/styles/FastStartProvider.tsx +2 -3
- package/src/types/props.internal.ts +21 -0
- package/src/types/props.ts +47 -33
- package/src/types/provider.ts +70 -45
- package/src/utils/number/calculate.ts +2 -2
- package/src/utils/object/error.ts +5 -4
- package/dist/components/Obj/Checkbox/ObjCheckIcon.d.ts +0 -3
- package/dist/components/Obj/Checkbox/ObjCheckIcon.d.ts.map +0 -1
- package/dist/components/Obj/Checkbox/ObjCheckbox.d.ts +0 -3
- package/dist/components/Obj/Checkbox/ObjCheckbox.d.ts.map +0 -1
- package/dist/components/Obj/Textfield/ObjFloat.d.ts +0 -3
- package/dist/components/Obj/Textfield/ObjFloat.d.ts.map +0 -1
- package/dist/components/Obj/Textfield/ObjInteger.d.ts +0 -3
- package/dist/components/Obj/Textfield/ObjInteger.d.ts.map +0 -1
- package/dist/components/Obj/Textfield/ObjText.d.ts +0 -3
- package/dist/components/Obj/Textfield/ObjText.d.ts.map +0 -1
- package/dist/components/Single/TextField/SingleFloat.d.ts +0 -3
- package/dist/components/Single/TextField/SingleFloat.d.ts.map +0 -1
- package/dist/components/Single/TextField/SingleInteger.d.ts +0 -3
- package/dist/components/Single/TextField/SingleInteger.d.ts.map +0 -1
- package/dist/hooks/splits/useSplitSingleNumberProps.d.ts +0 -6
- package/dist/hooks/splits/useSplitSingleNumberProps.d.ts.map +0 -1
- package/dist/hooks/splits/useSplitSingleTextProps.d.ts +0 -5
- package/dist/hooks/splits/useSplitSingleTextProps.d.ts.map +0 -1
- package/dist/styles/createDefaultProps.d.ts +0 -3
- package/dist/styles/createDefaultProps.d.ts.map +0 -1
- package/mui-fast-start-0.1.5.tgz +0 -0
- package/src/components/Obj/Checkbox/ObjCheckIcon.tsx +0 -19
- package/src/components/Obj/Checkbox/ObjCheckbox.tsx +0 -19
- package/src/components/Obj/Textfield/ObjFloat.tsx +0 -22
- package/src/components/Obj/Textfield/ObjInteger.tsx +0 -22
- package/src/components/Obj/Textfield/ObjText.tsx +0 -22
- package/src/components/Single/TextField/SingleFloat.tsx +0 -12
- package/src/components/Single/TextField/SingleInteger.tsx +0 -12
- package/src/hooks/splits/useSplitSingleTextProps.ts +0 -36
- package/src/styles/createDefaultProps.ts +0 -45
- package/src.zip +0 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import {useContext} from "react";
|
|
2
|
+
import {FastStartContext} from "../../../styles/FastStartProvider.tsx";
|
|
3
|
+
import {SingleSelectOne} from "../../Single/Select/SingleSelectOne.tsx";
|
|
4
|
+
import {SelectProps} from "@mui/material";
|
|
5
|
+
import {MfsObjectSelectOneProps} from "../../../types";
|
|
6
|
+
import useObjToSingle from "../../../hooks/state/useObjToSingle.ts";
|
|
7
|
+
import {errorObjectToString} from "../../../utils/object/error.ts";
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
export const ObjSelectOne = <
|
|
11
|
+
T extends object,
|
|
12
|
+
Item
|
|
13
|
+
>(customProps: Omit<SelectProps, 'name'> & MfsObjectSelectOneProps<T, Item>) => {
|
|
14
|
+
const defaultProps = useContext(FastStartContext)?.Object?.MfsSelectOne;
|
|
15
|
+
const {
|
|
16
|
+
get, set, err, name,
|
|
17
|
+
variant,
|
|
18
|
+
...props
|
|
19
|
+
} = defaultProps == null
|
|
20
|
+
? customProps
|
|
21
|
+
: Object.assign({...defaultProps}, customProps);
|
|
22
|
+
|
|
23
|
+
const [value, setValue] = useObjToSingle<T, Item>(name, get, set);
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
<SingleSelectOne<Item>
|
|
27
|
+
get={value} set={setValue}
|
|
28
|
+
name={name?.toString()}
|
|
29
|
+
err={errorObjectToString(name, err)}
|
|
30
|
+
variant={variant}
|
|
31
|
+
{...props}
|
|
32
|
+
/>
|
|
33
|
+
)
|
|
34
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import {useContext} from "react";
|
|
2
|
+
import {FastStartContext} from "../../../styles/FastStartProvider.tsx";
|
|
3
|
+
import useObjToSingle from "../../../hooks/state/useObjToSingle.ts";
|
|
4
|
+
import {SingleSelectRecord} from "../../Single/Select/SingleSelectRecord.tsx";
|
|
5
|
+
import {MfsObjectSelectRecordProps} from "../../../types";
|
|
6
|
+
import {SelectProps} from "@mui/material";
|
|
7
|
+
import {errorObjectToString} from "../../../utils/object/error.ts";
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
export const ObjSelectRecord = <
|
|
11
|
+
T extends object,
|
|
12
|
+
Item extends Record<PropertyKey, unknown>
|
|
13
|
+
>(customProps: Omit<SelectProps, 'name'> & MfsObjectSelectRecordProps<T, Item>) => {
|
|
14
|
+
const defaultProps = useContext(FastStartContext)?.Single?.MfsSelectRecord;
|
|
15
|
+
const {
|
|
16
|
+
get, set, err, name,
|
|
17
|
+
variant,
|
|
18
|
+
...props
|
|
19
|
+
} = defaultProps == null
|
|
20
|
+
? customProps
|
|
21
|
+
: Object.assign({...defaultProps}, customProps);
|
|
22
|
+
|
|
23
|
+
const [value, setValue] = useObjToSingle<T, Item>(name, get, set);
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
<SingleSelectRecord
|
|
27
|
+
get={value} set={setValue}
|
|
28
|
+
name={name?.toString()}
|
|
29
|
+
err={errorObjectToString(name, err)}
|
|
30
|
+
variant={variant}
|
|
31
|
+
{...props}
|
|
32
|
+
/>
|
|
33
|
+
)
|
|
34
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import {useContext} from "react";
|
|
2
|
+
import useObjToSingle from "../../../hooks/state/useObjToSingle.ts";
|
|
3
|
+
import {FastStartContext} from "../../../styles/FastStartProvider.tsx";
|
|
4
|
+
import {errorObjectToString} from "../../../utils/object/error.ts";
|
|
5
|
+
import {SingleFloat, SingleInteger} from "../../Single/TextField/SingleNumber.tsx";
|
|
6
|
+
import {MfsObjectNumberProps} from "../../../types";
|
|
7
|
+
import {TextFieldProps} from "@mui/material";
|
|
8
|
+
|
|
9
|
+
type ObjNumberProps<T extends object> = Omit<TextFieldProps, 'name'> & MfsObjectNumberProps<T>;
|
|
10
|
+
|
|
11
|
+
export const ObjFloat = <T extends object>(customProps: ObjNumberProps<T>) => {
|
|
12
|
+
const defaultProps = useContext(FastStartContext)?.Object?.MfsFloat;
|
|
13
|
+
const {
|
|
14
|
+
get, set, err, name,
|
|
15
|
+
...props
|
|
16
|
+
} = defaultProps == null
|
|
17
|
+
? customProps
|
|
18
|
+
: Object.assign({...defaultProps}, customProps);
|
|
19
|
+
|
|
20
|
+
const [value, setValue] = useObjToSingle<T, number>(name, get, set);
|
|
21
|
+
|
|
22
|
+
return (
|
|
23
|
+
<SingleFloat
|
|
24
|
+
get={value} set={setValue}
|
|
25
|
+
name={name?.toString()}
|
|
26
|
+
err={errorObjectToString(name, err)}
|
|
27
|
+
{...props}
|
|
28
|
+
/>
|
|
29
|
+
)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export const ObjInteger = <T extends object>(customProps: ObjNumberProps<T>) => {
|
|
33
|
+
const defaultProps = useContext(FastStartContext)?.Object?.MfsInteger;
|
|
34
|
+
const {
|
|
35
|
+
get, set, err, name,
|
|
36
|
+
...props
|
|
37
|
+
} = defaultProps == null
|
|
38
|
+
? customProps
|
|
39
|
+
: Object.assign({...defaultProps}, customProps);
|
|
40
|
+
|
|
41
|
+
const [value, setValue] = useObjToSingle<T, number>(name, get, set);
|
|
42
|
+
|
|
43
|
+
return (
|
|
44
|
+
<SingleInteger
|
|
45
|
+
get={value} set={setValue}
|
|
46
|
+
name={name?.toString()}
|
|
47
|
+
err={errorObjectToString(name, err)}
|
|
48
|
+
{...props}
|
|
49
|
+
/>
|
|
50
|
+
)
|
|
51
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import {useContext} from "react";
|
|
2
|
+
import {MfsObjectTextProps} from "../../../types";
|
|
3
|
+
import {FastStartContext} from "../../../styles/FastStartProvider.tsx";
|
|
4
|
+
import useObjToSingle from "../../../hooks/state/useObjToSingle.ts";
|
|
5
|
+
import {SingleText} from "../../Single/TextField/SingleText.tsx";
|
|
6
|
+
import {errorObjectToString} from "../../../utils/object/error.ts";
|
|
7
|
+
import {TextFieldProps} from "@mui/material";
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
export const ObjText = <T extends object>(
|
|
11
|
+
customProps: Omit<TextFieldProps, 'name'> & MfsObjectTextProps<T>
|
|
12
|
+
) => {
|
|
13
|
+
const defaultProps = useContext(FastStartContext)?.Object?.MfsText;
|
|
14
|
+
const {
|
|
15
|
+
get, set, err, name,
|
|
16
|
+
...props
|
|
17
|
+
} = defaultProps == null ? customProps : Object.assign({...defaultProps}, customProps);
|
|
18
|
+
|
|
19
|
+
const [value, setValue] = useObjToSingle<T, string>(name, get, set);
|
|
20
|
+
|
|
21
|
+
return (
|
|
22
|
+
<SingleText
|
|
23
|
+
get={value} set={setValue}
|
|
24
|
+
name={name?.toString()}
|
|
25
|
+
err={errorObjectToString(name, err)}
|
|
26
|
+
{...props}
|
|
27
|
+
/>
|
|
28
|
+
);
|
|
29
|
+
};
|
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
import {useCallback, useContext} from "react";
|
|
2
|
-
import {IconButton} from "@mui/material";
|
|
2
|
+
import {IconButton, IconButtonProps} from "@mui/material";
|
|
3
3
|
import {FastStartContext} from "../../../styles/FastStartProvider.tsx";
|
|
4
|
-
import {
|
|
5
|
-
import {fastDeepMerge} from "../../../utils";
|
|
4
|
+
import {MfsSingleCheckIconProps} from "../../../types";
|
|
6
5
|
|
|
6
|
+
export type SingleCheckIconProps = IconButtonProps & MfsSingleCheckIconProps;
|
|
7
7
|
|
|
8
8
|
export const SingleCheckIcon = (customProps: SingleCheckIconProps) => {
|
|
9
|
-
const defaultProps = useContext(FastStartContext)?.Single?.
|
|
9
|
+
const defaultProps = useContext(FastStartContext)?.Single?.MfsCheckIcon;
|
|
10
10
|
const {
|
|
11
11
|
get, set, on, off,
|
|
12
12
|
...props
|
|
13
|
-
} =
|
|
13
|
+
} = defaultProps == null
|
|
14
|
+
? customProps
|
|
15
|
+
: Object.assign({...defaultProps}, customProps);
|
|
14
16
|
|
|
15
17
|
const onClick = useCallback(() => set((state) => !state), [set]);
|
|
16
18
|
|
|
@@ -1,16 +1,18 @@
|
|
|
1
|
-
import {Checkbox, FormControlLabel} from "@mui/material";
|
|
1
|
+
import {Checkbox, CheckboxProps, FormControlLabel} from "@mui/material";
|
|
2
2
|
import React, {useCallback, useContext} from "react";
|
|
3
|
-
import {SingleCheckboxProps} from "../../../types";
|
|
4
3
|
import {FastStartContext} from "../../../styles/FastStartProvider.tsx";
|
|
5
|
-
import {
|
|
4
|
+
import {MfsSingleCheckboxProps} from "../../../types";
|
|
6
5
|
|
|
6
|
+
export type SingleCheckboxProps = CheckboxProps & MfsSingleCheckboxProps;
|
|
7
7
|
|
|
8
8
|
export const SingleCheckbox = (customProps: SingleCheckboxProps) => {
|
|
9
|
-
const defaultProps = useContext(FastStartContext)?.Single?.
|
|
9
|
+
const defaultProps = useContext(FastStartContext)?.Single?.MfsCheckbox;
|
|
10
10
|
const {
|
|
11
11
|
get, set, label,
|
|
12
12
|
...props
|
|
13
|
-
} =
|
|
13
|
+
} = defaultProps == null
|
|
14
|
+
? customProps
|
|
15
|
+
: Object.assign({...defaultProps}, customProps);
|
|
14
16
|
|
|
15
17
|
const onChange = useCallback(() => set((state) => !state), [set]);
|
|
16
18
|
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import {FormControl, FormHelperText, InputLabel, MenuItem, Select, SelectProps} from "@mui/material";
|
|
2
|
+
import React, {useId} from "react";
|
|
3
|
+
import {MfsSingleError} from "../../../types/props.internal.ts";
|
|
4
|
+
|
|
5
|
+
const BaseSingleSelect = <Value,>(props: {
|
|
6
|
+
emptyItem?: React.ReactNode,
|
|
7
|
+
label?: React.ReactNode,
|
|
8
|
+
err: MfsSingleError,
|
|
9
|
+
items: React.ReactNode,
|
|
10
|
+
get: Value,
|
|
11
|
+
onChange: SelectProps['onChange'],
|
|
12
|
+
selectProps: SelectProps
|
|
13
|
+
}) => {
|
|
14
|
+
const {emptyItem, label, selectProps} = props;
|
|
15
|
+
const labelId = useId();
|
|
16
|
+
|
|
17
|
+
const isError: boolean = !!props.err;
|
|
18
|
+
return (
|
|
19
|
+
<FormControl
|
|
20
|
+
error={isError}
|
|
21
|
+
fullWidth={selectProps.fullWidth}
|
|
22
|
+
variant={selectProps.variant}
|
|
23
|
+
size={selectProps.size}
|
|
24
|
+
sx={selectProps.sx}
|
|
25
|
+
disabled={selectProps.disabled}
|
|
26
|
+
required={selectProps.required}
|
|
27
|
+
margin={selectProps.margin}
|
|
28
|
+
>
|
|
29
|
+
{label && <InputLabel id={labelId}>{label}</InputLabel>}
|
|
30
|
+
<Select
|
|
31
|
+
labelId={labelId}
|
|
32
|
+
error={isError}
|
|
33
|
+
label={label}
|
|
34
|
+
value={props.get ?? ''}
|
|
35
|
+
onChange={props.onChange}
|
|
36
|
+
{...selectProps}
|
|
37
|
+
>
|
|
38
|
+
{emptyItem && <MenuItem key='' value=''>{emptyItem}</MenuItem>}
|
|
39
|
+
{props.items}
|
|
40
|
+
</Select>
|
|
41
|
+
{isError && <FormHelperText>{props.err}</FormHelperText>}
|
|
42
|
+
</FormControl>
|
|
43
|
+
)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export default BaseSingleSelect;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import {MenuItem, SelectProps} from "@mui/material";
|
|
2
|
+
import {MfsSingleSelectOneProps} from "../../../types";
|
|
3
|
+
import React, {useContext, useMemo} from "react";
|
|
4
|
+
import {FastStartContext} from "../../../styles/FastStartProvider.tsx";
|
|
5
|
+
import BaseSingleSelect from "./BaseSingleSelect.tsx";
|
|
6
|
+
|
|
7
|
+
export type SingleSelectOneProps<Item> = SelectProps & MfsSingleSelectOneProps<Item>;
|
|
8
|
+
|
|
9
|
+
export const SingleSelectOne = <Item,>(customProps: SingleSelectOneProps<Item>) => {
|
|
10
|
+
const defaultProps = useContext(FastStartContext)?.Single?.MfsSelectOne;
|
|
11
|
+
const {
|
|
12
|
+
get, set, err, label,
|
|
13
|
+
items, renderMenuItem,
|
|
14
|
+
emptyItem, emptyValue,
|
|
15
|
+
getKey, ...props
|
|
16
|
+
} = defaultProps == null
|
|
17
|
+
? customProps
|
|
18
|
+
: Object.assign({...defaultProps}, customProps);
|
|
19
|
+
|
|
20
|
+
const getKeyOrValue = useMemo(() => (
|
|
21
|
+
getKey ?? ((item: Item) => item as string | number)
|
|
22
|
+
), [getKey]);
|
|
23
|
+
|
|
24
|
+
const onChange: SelectProps['onChange'] = (event) => {
|
|
25
|
+
const value = event.target.value;
|
|
26
|
+
if (getKey == null) {
|
|
27
|
+
set((value == "" ? emptyValue : value) as Item);
|
|
28
|
+
} else {
|
|
29
|
+
const item: Item | undefined = items.find((item: Item) => getKeyOrValue(item) === value);
|
|
30
|
+
set(item as Item);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const MenuItems = useMemo(() => {
|
|
35
|
+
if (renderMenuItem != null) {
|
|
36
|
+
return items.map(renderMenuItem);
|
|
37
|
+
} else {
|
|
38
|
+
return items.map((item) => {
|
|
39
|
+
const key = getKeyOrValue(item);
|
|
40
|
+
return <MenuItem key={key} value={key}>{key}</MenuItem>;
|
|
41
|
+
})
|
|
42
|
+
}
|
|
43
|
+
}, [getKeyOrValue, items, renderMenuItem]);
|
|
44
|
+
|
|
45
|
+
return (
|
|
46
|
+
<BaseSingleSelect
|
|
47
|
+
label={label}
|
|
48
|
+
items={MenuItems}
|
|
49
|
+
emptyItem={emptyItem}
|
|
50
|
+
get={get}
|
|
51
|
+
err={err}
|
|
52
|
+
onChange={onChange}
|
|
53
|
+
selectProps={props}
|
|
54
|
+
/>
|
|
55
|
+
);
|
|
56
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import {MenuItem, SelectProps} from "@mui/material";
|
|
2
|
+
import {MfsSingleSelectRecordProps} from "../../../types";
|
|
3
|
+
import React, {useContext, useMemo} from "react";
|
|
4
|
+
import {FastStartContext} from "../../../styles/FastStartProvider.tsx";
|
|
5
|
+
import BaseSingleSelect from "./BaseSingleSelect.tsx";
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
export const SingleSelectRecord = <
|
|
9
|
+
T extends Record<string, unknown>,
|
|
10
|
+
Value = keyof T | undefined | null
|
|
11
|
+
>(customProps: SelectProps & MfsSingleSelectRecordProps<T, Value>) => {
|
|
12
|
+
const defaultProps = useContext(FastStartContext)?.Single?.MfsSelectRecord;
|
|
13
|
+
const {
|
|
14
|
+
get, set, err, label,
|
|
15
|
+
items, renderMenuItem,
|
|
16
|
+
emptyItem, emptyValue,
|
|
17
|
+
...props
|
|
18
|
+
} = defaultProps == null
|
|
19
|
+
? customProps
|
|
20
|
+
: Object.assign({...defaultProps}, customProps);
|
|
21
|
+
|
|
22
|
+
const onChange: SelectProps['onChange'] = (event) => {
|
|
23
|
+
const value = event.target.value;
|
|
24
|
+
set((value == "" ? emptyValue : value) as Value);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const MenuItems = useMemo(() => {
|
|
28
|
+
if (renderMenuItem != null) {
|
|
29
|
+
return Object.entries(items).map(([key, value], i) => (
|
|
30
|
+
renderMenuItem(key, value as T[keyof T], i)
|
|
31
|
+
));
|
|
32
|
+
} else {
|
|
33
|
+
return Object.entries(items).map(([key, value]) => (
|
|
34
|
+
<MenuItem key={key} value={key}>
|
|
35
|
+
{value?.toString()}
|
|
36
|
+
</MenuItem>
|
|
37
|
+
));
|
|
38
|
+
}
|
|
39
|
+
}, [items, renderMenuItem]);
|
|
40
|
+
|
|
41
|
+
return (
|
|
42
|
+
<BaseSingleSelect
|
|
43
|
+
label={label}
|
|
44
|
+
items={MenuItems}
|
|
45
|
+
emptyItem={emptyItem}
|
|
46
|
+
get={get}
|
|
47
|
+
err={err}
|
|
48
|
+
onChange={onChange}
|
|
49
|
+
selectProps={props}
|
|
50
|
+
/>
|
|
51
|
+
)
|
|
52
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import {useContext} from "react";
|
|
2
|
+
import {TextField, TextFieldProps} from "@mui/material";
|
|
3
|
+
import {FastStartContext} from "../../../styles/FastStartProvider.tsx";
|
|
4
|
+
import {MfsSingleNumberProps} from "../../../types";
|
|
5
|
+
import {useSplitSingleFloatProps, useSplitSingleIntegerProps} from "../../../hooks";
|
|
6
|
+
|
|
7
|
+
export type SingleNumberProps = TextFieldProps & MfsSingleNumberProps;
|
|
8
|
+
|
|
9
|
+
export const SingleFloat = (customProps: SingleNumberProps) => {
|
|
10
|
+
const defaultProps = useContext(FastStartContext)?.Single?.MfsFloat;
|
|
11
|
+
const props = useSplitSingleFloatProps(defaultProps, customProps);
|
|
12
|
+
return <TextField {...props}/>;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const SingleInteger = (customProps: SingleNumberProps) => {
|
|
16
|
+
const defaultProps = useContext(FastStartContext)?.Single?.MfsInteger;
|
|
17
|
+
const props = useSplitSingleIntegerProps(defaultProps, customProps);
|
|
18
|
+
return <TextField {...props}/>;
|
|
19
|
+
}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import {useContext} from "react";
|
|
2
|
-
import
|
|
3
|
-
import {TextField} from "@mui/material";
|
|
2
|
+
import useSplitTextProps from '../../../hooks/splits/useSplitTextProps.ts';
|
|
3
|
+
import {TextField, TextFieldProps} from "@mui/material";
|
|
4
4
|
import {FastStartContext} from "../../../styles/FastStartProvider.tsx";
|
|
5
|
-
import {
|
|
5
|
+
import {MfsSingleTextProps} from "../../../types";
|
|
6
6
|
|
|
7
|
+
export type SingleTextProps = TextFieldProps & MfsSingleTextProps;
|
|
7
8
|
|
|
8
9
|
export const SingleText = (customProps: SingleTextProps) => {
|
|
9
|
-
const defaultProps = useContext(FastStartContext)?.Single?.
|
|
10
|
-
const props =
|
|
10
|
+
const defaultProps = useContext(FastStartContext)?.Single?.MfsText;
|
|
11
|
+
const props = useSplitTextProps(defaultProps, customProps);
|
|
11
12
|
return <TextField {...props}/>;
|
|
12
13
|
}
|
package/src/components/index.ts
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
// Object components
|
|
2
|
-
export { ObjCheckbox } from './Obj/Checkbox/ObjCheckbox';
|
|
3
|
-
export { ObjCheckIcon } from './Obj/Checkbox/ObjCheckIcon';
|
|
4
|
-
export { ObjFloat } from './Obj/Textfield/ObjFloat';
|
|
5
|
-
export { ObjInteger } from './Obj/Textfield/ObjInteger';
|
|
6
|
-
export { ObjText } from './Obj/Textfield/ObjText';
|
|
7
|
-
|
|
8
1
|
// Single components
|
|
9
|
-
export { SingleCheckbox } from './Single/Checkbox/SingleCheckbox';
|
|
10
|
-
export { SingleCheckIcon } from './Single/Checkbox/SingleCheckIcon';
|
|
11
|
-
export { SingleFloat } from './Single/TextField/
|
|
12
|
-
export {
|
|
13
|
-
export {
|
|
2
|
+
export { SingleCheckbox } from './Single/Checkbox/SingleCheckbox.tsx';
|
|
3
|
+
export { SingleCheckIcon } from './Single/Checkbox/SingleCheckIcon.tsx';
|
|
4
|
+
export { SingleFloat, SingleInteger } from './Single/TextField/SingleNumber.tsx';
|
|
5
|
+
export { SingleText } from './Single/TextField/SingleText.tsx';
|
|
6
|
+
export { SingleSelectOne } from './Single/Select/SingleSelectOne.tsx';
|
|
7
|
+
export { SingleSelectRecord } from './Single/Select/SingleSelectRecord.tsx';
|
|
8
|
+
|
|
9
|
+
// Object components
|
|
10
|
+
export { ObjCheckbox } from './Object/Checkbox/ObjCheckbox.tsx';
|
|
11
|
+
export { ObjCheckIcon } from './Object/Checkbox/ObjCheckIcon.tsx';
|
|
12
|
+
export { ObjFloat, ObjInteger } from './Object/Textfield/ObjNumber.tsx';
|
|
13
|
+
export { ObjText } from './Object/Textfield/ObjText.tsx';
|
|
14
|
+
export { ObjSelectOne } from './Object/Select/ObjSelectOne.tsx';
|
|
15
|
+
export { ObjSelectRecord } from './Object/Select/ObjSelectRecord.tsx';
|
package/src/hooks/index.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export * from './splits/
|
|
2
|
-
export * from './splits/
|
|
1
|
+
export * from './splits/useSplitNumberProps.ts';
|
|
2
|
+
export * from './splits/useSplitTextProps.ts';
|
|
3
3
|
export * from './state/useObjToSingle';
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type {TextFieldProps} from "@mui/material";
|
|
2
2
|
import {fastDeepMerge, floatCalculate, integerCalculate, processFloat, processInteger} from "../../utils";
|
|
3
|
-
import React, {useCallback,
|
|
4
|
-
import {
|
|
3
|
+
import React, {useCallback, useState} from "react";
|
|
4
|
+
import {MfsSingleNumberProps} from "../../types";
|
|
5
|
+
import {SingleNumberProps} from "../../components/Single/TextField/SingleNumber.tsx";
|
|
5
6
|
|
|
6
7
|
type CalculateNumber = number | null | undefined;
|
|
7
8
|
type CalculateFunction = (
|
|
@@ -11,8 +12,8 @@ type CalculateFunction = (
|
|
|
11
12
|
def: CalculateNumber
|
|
12
13
|
) => CalculateNumber;
|
|
13
14
|
|
|
14
|
-
const
|
|
15
|
-
defaultProps:
|
|
15
|
+
const useSplitNumberProps = (
|
|
16
|
+
defaultProps: Partial<MfsSingleNumberProps> | undefined,
|
|
16
17
|
customProps: SingleNumberProps,
|
|
17
18
|
process: (value: string) => string,
|
|
18
19
|
calculate: CalculateFunction,
|
|
@@ -20,61 +21,67 @@ const useSplitSingleNumberProps = (
|
|
|
20
21
|
): TextFieldProps => {
|
|
21
22
|
const [draft, setDraft] = useState<string | null>(null);
|
|
22
23
|
const {
|
|
23
|
-
get, set,
|
|
24
|
+
get, set, err,
|
|
24
25
|
minLength, maxLength,
|
|
25
26
|
startAdornment, endAdornment,
|
|
26
|
-
|
|
27
|
+
def, min, max, step,
|
|
27
28
|
...props
|
|
28
|
-
} =
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
);
|
|
29
|
+
} = (defaultProps == null)
|
|
30
|
+
? customProps
|
|
31
|
+
: Object.assign({...defaultProps}, customProps);
|
|
32
32
|
|
|
33
|
-
const getCalculate =
|
|
34
|
-
|
|
35
|
-
)
|
|
33
|
+
const getCalculate = (
|
|
34
|
+
value: string | null
|
|
35
|
+
) => calculate(value, min, max, def);
|
|
36
36
|
|
|
37
|
-
const getKeyboardValue =
|
|
37
|
+
const getKeyboardValue = (
|
|
38
|
+
event: React.KeyboardEvent<HTMLInputElement>
|
|
39
|
+
) => {
|
|
38
40
|
const {value, valueAsNumber} = event.currentTarget;
|
|
39
41
|
return isNaN(valueAsNumber) ? getCalculate(value) : valueAsNumber;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
const getProcess = useCallback((event: React.ChangeEvent<HTMLInputElement>): string => {
|
|
43
|
-
const target = event.currentTarget;
|
|
44
|
-
const value: string = process(target.value);
|
|
45
|
-
if (value != target.value) {
|
|
46
|
-
target.value = value;
|
|
47
|
-
}
|
|
48
|
-
return value;
|
|
49
|
-
}, [process]);
|
|
50
|
-
|
|
42
|
+
}
|
|
51
43
|
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
const result: string = getProcess(event);
|
|
59
|
-
const num: CalculateNumber = getCalculate(result);
|
|
60
|
-
if (num != null && !isNaN(num) && get != num) {
|
|
61
|
-
set(num);
|
|
44
|
+
const getProcess = useCallback(
|
|
45
|
+
(event: React.ChangeEvent<HTMLInputElement>): string => {
|
|
46
|
+
const target = event.currentTarget;
|
|
47
|
+
const value: string = process(target.value);
|
|
48
|
+
if (value != target.value) {
|
|
49
|
+
target.value = value;
|
|
62
50
|
}
|
|
63
|
-
|
|
64
|
-
setDraft(event.currentTarget.value);
|
|
51
|
+
return value;
|
|
65
52
|
},
|
|
66
|
-
[
|
|
53
|
+
[process]
|
|
67
54
|
);
|
|
68
55
|
|
|
69
|
-
const
|
|
56
|
+
const onSelect = () => {
|
|
57
|
+
if (draft == null) setDraft(get.toString());
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const onChange = (
|
|
61
|
+
event: React.ChangeEvent<HTMLInputElement>
|
|
62
|
+
) => {
|
|
63
|
+
const result: string = getProcess(event);
|
|
64
|
+
const num: CalculateNumber = getCalculate(result);
|
|
65
|
+
if (num != null && !isNaN(num) && get != num) {
|
|
66
|
+
set(num);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
setDraft(event.currentTarget.value);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const onBlur = (
|
|
73
|
+
event: React.FocusEvent<HTMLInputElement>
|
|
74
|
+
) => {
|
|
70
75
|
const {value} = event.currentTarget;
|
|
71
76
|
|
|
72
77
|
setDraft(null);
|
|
73
78
|
const num: CalculateNumber = getCalculate(value);
|
|
74
79
|
if (get != num) set(num as number);
|
|
75
|
-
}
|
|
80
|
+
};
|
|
76
81
|
|
|
77
|
-
const onKeyDown =
|
|
82
|
+
const onKeyDown = (
|
|
83
|
+
event: React.KeyboardEvent<HTMLInputElement>
|
|
84
|
+
) => {
|
|
78
85
|
if (lockKeys.includes(event.key) || step == null) {
|
|
79
86
|
event.preventDefault();
|
|
80
87
|
return;
|
|
@@ -104,23 +111,18 @@ const useSplitSingleNumberProps = (
|
|
|
104
111
|
input.value = digitRound(num, step).toString();
|
|
105
112
|
}
|
|
106
113
|
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
const value = useMemo(() => (draft == null ? get : draft), [get, draft]);
|
|
110
|
-
const inputLabel: InputLabelType = useMemo(() => (
|
|
111
|
-
(draft == null && (!get || isNaN(get))) ? {} : { shrink: true }
|
|
112
|
-
), [draft, get]);
|
|
113
|
-
|
|
114
|
+
};
|
|
115
|
+
|
|
114
116
|
return fastDeepMerge<TextFieldProps>({
|
|
115
|
-
error: !!
|
|
116
|
-
helperText:
|
|
117
|
-
value,
|
|
117
|
+
error: !!err,
|
|
118
|
+
helperText: err,
|
|
119
|
+
value: (draft == null ? get : draft),
|
|
118
120
|
onChange,
|
|
119
121
|
onSelect,
|
|
120
122
|
onBlur,
|
|
121
123
|
slotProps: {
|
|
122
124
|
htmlInput: {step, min, max, minLength, maxLength, onKeyDown},
|
|
123
|
-
inputLabel:
|
|
125
|
+
inputLabel: (draft == null && (!get || isNaN(get))) ? {} : { shrink: true },
|
|
124
126
|
input: {startAdornment, endAdornment}
|
|
125
127
|
}
|
|
126
128
|
}, (props as TextFieldProps));
|
|
@@ -137,17 +139,17 @@ const digitRound = (num: number, step: number) => {
|
|
|
137
139
|
}
|
|
138
140
|
|
|
139
141
|
const useSplitSingleFloatProps = (
|
|
140
|
-
defaultProps:
|
|
142
|
+
defaultProps: Partial<MfsSingleNumberProps> | undefined,
|
|
141
143
|
customProps: SingleNumberProps,
|
|
142
|
-
): TextFieldProps =>
|
|
144
|
+
): TextFieldProps => useSplitNumberProps(
|
|
143
145
|
defaultProps, customProps,
|
|
144
146
|
processFloat, floatCalculate
|
|
145
147
|
);
|
|
146
148
|
|
|
147
149
|
const useSplitSingleIntegerProps = (
|
|
148
|
-
defaultProps:
|
|
150
|
+
defaultProps: Partial<MfsSingleNumberProps> | undefined,
|
|
149
151
|
customProps: SingleNumberProps,
|
|
150
|
-
): TextFieldProps =>
|
|
152
|
+
): TextFieldProps => useSplitNumberProps(
|
|
151
153
|
defaultProps, customProps,
|
|
152
154
|
processInteger, integerCalculate,
|
|
153
155
|
[".", "e", "E"]
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type {TextFieldProps} from "@mui/material";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import {fastDeepMerge} from "../../utils";
|
|
4
|
+
import {MfsSingleTextProps} from "../../types";
|
|
5
|
+
import {SingleTextProps} from "../../components/Single/TextField/SingleText.tsx";
|
|
6
|
+
|
|
7
|
+
const useSplitTextProps = (
|
|
8
|
+
defaultProps: Partial<MfsSingleTextProps> | undefined,
|
|
9
|
+
customProps: SingleTextProps
|
|
10
|
+
): TextFieldProps => {
|
|
11
|
+
const {
|
|
12
|
+
get, set, err,
|
|
13
|
+
minLength, maxLength,
|
|
14
|
+
startAdornment, endAdornment,
|
|
15
|
+
...props
|
|
16
|
+
} = defaultProps == null ? customProps : Object.assign({...defaultProps}, customProps);
|
|
17
|
+
|
|
18
|
+
const onChange = (
|
|
19
|
+
event: React.ChangeEvent<HTMLInputElement>
|
|
20
|
+
) => {
|
|
21
|
+
set(event.currentTarget.value);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return fastDeepMerge<TextFieldProps>({
|
|
25
|
+
error: !!err,
|
|
26
|
+
helperText: err,
|
|
27
|
+
value: get,
|
|
28
|
+
onChange,
|
|
29
|
+
slotProps: {
|
|
30
|
+
htmlInput: {minLength, maxLength},
|
|
31
|
+
input: {startAdornment, endAdornment}
|
|
32
|
+
}
|
|
33
|
+
}, (props as TextFieldProps));
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export default useSplitTextProps;
|