@tecsinapse/react-native-kit 3.4.1 → 3.5.0-beta.0
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/LICENSE.md +1 -1
- package/README.md +9 -7
- package/dist/cjs/components/atoms/Modal/ModalGroupManager.js +1 -0
- package/dist/cjs/components/atoms/Modal/ModalLifecycleHandler.js +5 -0
- package/dist/cjs/components/atoms/Modal/ui/BaseModalView.js +3 -6
- package/dist/cjs/components/molecules/Select/Select.js +42 -157
- package/dist/cjs/components/molecules/Select/components/Flat.js +24 -0
- package/dist/cjs/components/molecules/Select/components/Modal.js +96 -0
- package/dist/cjs/components/molecules/Select/components/Option.js +50 -0
- package/dist/cjs/components/molecules/Select/components/Section.js +29 -0
- package/dist/cjs/components/molecules/Select/functions.js +43 -0
- package/dist/cjs/components/molecules/Select/hooks/useModal.js +109 -0
- package/dist/cjs/components/molecules/Select/hooks/useSelect.js +147 -0
- package/dist/cjs/components/molecules/Select/styled.js +12 -2
- package/dist/esm/components/atoms/Modal/ModalGroupManager.js +1 -0
- package/dist/esm/components/atoms/Modal/ModalLifecycleHandler.js +5 -0
- package/dist/esm/components/atoms/Modal/ui/BaseModalView.js +3 -6
- package/dist/esm/components/molecules/Select/Select.js +44 -141
- package/dist/esm/components/molecules/Select/components/Flat.js +22 -0
- package/dist/esm/components/molecules/Select/components/Modal.js +94 -0
- package/dist/esm/components/molecules/Select/components/Option.js +48 -0
- package/dist/esm/components/molecules/Select/components/Section.js +27 -0
- package/dist/esm/components/molecules/Select/functions.js +35 -0
- package/dist/esm/components/molecules/Select/hooks/useModal.js +107 -0
- package/dist/esm/components/molecules/Select/hooks/useSelect.js +145 -0
- package/dist/esm/components/molecules/Select/styled.js +11 -3
- package/dist/types/components/atoms/Modal/ModalLifecycleHandler.d.ts +1 -0
- package/dist/types/components/molecules/Select/Select.d.ts +2 -23
- package/dist/types/components/molecules/Select/components/Flat.d.ts +8 -0
- package/dist/types/components/molecules/Select/components/Modal.d.ts +4 -0
- package/dist/types/components/molecules/Select/components/Option.d.ts +10 -0
- package/dist/types/components/molecules/Select/components/Section.d.ts +8 -0
- package/dist/types/components/molecules/Select/functions.d.ts +9 -0
- package/dist/types/components/molecules/Select/hooks/useModal.d.ts +66 -0
- package/dist/types/components/molecules/Select/hooks/useSelect.d.ts +58 -0
- package/dist/types/components/molecules/Select/index.d.ts +1 -1
- package/dist/types/components/molecules/Select/styled.d.ts +12 -0
- package/dist/types/components/molecules/Select/types.d.ts +33 -0
- package/package.json +9 -6
- package/dist/cjs/components/molecules/Select/Modal.js +0 -224
- package/dist/esm/components/molecules/Select/Modal.js +0 -203
- package/dist/types/components/molecules/Select/Modal.d.ts +0 -8
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import React__default from 'react';
|
|
2
|
+
import { ListItem, StyledTextItemSelect } from '../styled.js';
|
|
3
|
+
import { View } from 'react-native';
|
|
4
|
+
import { Checkbox, RadioButton } from '@tecsinapse/react-core';
|
|
5
|
+
|
|
6
|
+
const Component = ({
|
|
7
|
+
handlePressItem,
|
|
8
|
+
labelExtractor,
|
|
9
|
+
item,
|
|
10
|
+
type
|
|
11
|
+
}) => {
|
|
12
|
+
const label = labelExtractor(item);
|
|
13
|
+
return /* @__PURE__ */ React__default.createElement(ListItem, { onPress: () => handlePressItem(item) }, /* @__PURE__ */ React__default.createElement(View, { pointerEvents: "none" }, type === "multi" ? /* @__PURE__ */ React__default.createElement(
|
|
14
|
+
Checkbox,
|
|
15
|
+
{
|
|
16
|
+
color: "primary",
|
|
17
|
+
labelPosition: "right",
|
|
18
|
+
checked: item._checked
|
|
19
|
+
},
|
|
20
|
+
/* @__PURE__ */ React__default.createElement(
|
|
21
|
+
StyledTextItemSelect,
|
|
22
|
+
{
|
|
23
|
+
fontWeight: item._checked ? "bold" : "regular",
|
|
24
|
+
ellipsizeMode: "tail",
|
|
25
|
+
numberOfLines: 1
|
|
26
|
+
},
|
|
27
|
+
label
|
|
28
|
+
)
|
|
29
|
+
) : /* @__PURE__ */ React__default.createElement(
|
|
30
|
+
RadioButton,
|
|
31
|
+
{
|
|
32
|
+
color: "primary",
|
|
33
|
+
labelPosition: "right",
|
|
34
|
+
checked: item._checked
|
|
35
|
+
},
|
|
36
|
+
/* @__PURE__ */ React__default.createElement(
|
|
37
|
+
StyledTextItemSelect,
|
|
38
|
+
{
|
|
39
|
+
fontWeight: item._checked ? "bold" : "regular",
|
|
40
|
+
ellipsizeMode: "tail",
|
|
41
|
+
numberOfLines: 1
|
|
42
|
+
},
|
|
43
|
+
label
|
|
44
|
+
)
|
|
45
|
+
)));
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export { Component as default };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import React__default, { useMemo } from 'react';
|
|
2
|
+
import { Divider, SectionHeader } from '../styled.js';
|
|
3
|
+
import { SectionList } from 'react-native';
|
|
4
|
+
import Text from '../../../atoms/Text/Text.js';
|
|
5
|
+
|
|
6
|
+
const SectionHead = ({ section: { title } }) => /* @__PURE__ */ React__default.createElement(SectionHeader, null, /* @__PURE__ */ React__default.createElement(Text, { fontWeight: "bold" }, title));
|
|
7
|
+
const Section = ({ options, renderItem, getData, keyExtractor }) => {
|
|
8
|
+
const sectionList = useMemo(
|
|
9
|
+
() => options instanceof Map ? [...options].map(([key, value]) => ({
|
|
10
|
+
title: key,
|
|
11
|
+
data: getData(value)
|
|
12
|
+
})) : [],
|
|
13
|
+
[options, getData]
|
|
14
|
+
);
|
|
15
|
+
return /* @__PURE__ */ React__default.createElement(
|
|
16
|
+
SectionList,
|
|
17
|
+
{
|
|
18
|
+
sections: sectionList,
|
|
19
|
+
renderItem,
|
|
20
|
+
ItemSeparatorComponent: Divider,
|
|
21
|
+
renderSectionHeader: SectionHead,
|
|
22
|
+
keyExtractor
|
|
23
|
+
}
|
|
24
|
+
);
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export { Section as default };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
const findValue = (array, value, keyExtractor, idx) => array.find((it) => keyExtractor(value, idx) === keyExtractor(it, idx));
|
|
2
|
+
const isOptionChecked = (type, option, src, keyExtractor, idx) => type === "multi" ? !!findValue(src, option, keyExtractor, idx) : keyExtractor(src[0] ?? {}, idx) == keyExtractor(option, idx);
|
|
3
|
+
const multiBuilder = (option, src, keyExtractor) => {
|
|
4
|
+
const array = [];
|
|
5
|
+
let found = false;
|
|
6
|
+
for (const value of src) {
|
|
7
|
+
if (keyExtractor(value) != keyExtractor(option)) array.push(value);
|
|
8
|
+
else found = true;
|
|
9
|
+
}
|
|
10
|
+
if (!found) array.push(option);
|
|
11
|
+
return array;
|
|
12
|
+
};
|
|
13
|
+
const singleBuilder = (option, src, keyExtractor) => keyExtractor(src[0] ?? {}) === keyExtractor(option) ? [] : [option];
|
|
14
|
+
const mapToArray = (map) => [...map.values()].flatMap((v) => v);
|
|
15
|
+
const getMultiLabel = (value, placeholder, options, keyExtractor, labelExtractor) => {
|
|
16
|
+
if (value.length === 0) return placeholder;
|
|
17
|
+
else {
|
|
18
|
+
const optionsArray = options instanceof Map ? mapToArray(options) : options;
|
|
19
|
+
const available = optionsArray.length > 0 ? optionsArray : value;
|
|
20
|
+
return available?.reduce(
|
|
21
|
+
(acc, option, index) => findValue(value, option, keyExtractor, index) ? acc + labelExtractor(option) + ", " : acc,
|
|
22
|
+
""
|
|
23
|
+
).slice(0, -2);
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
const getSingleLabel = (value, placeholder, options, keyExtractor, labelExtractor) => {
|
|
27
|
+
if (!value) return placeholder;
|
|
28
|
+
const optionsArray = options instanceof Map ? mapToArray(options) : options;
|
|
29
|
+
const selectedOption = optionsArray?.find(
|
|
30
|
+
(option, index) => keyExtractor(option, index) == keyExtractor(value, index)
|
|
31
|
+
);
|
|
32
|
+
return labelExtractor(selectedOption ?? value);
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export { findValue, getMultiLabel, getSingleLabel, isOptionChecked, mapToArray, multiBuilder, singleBuilder };
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import React__default from 'react';
|
|
2
|
+
import { getStyledModal } from '../styled.js';
|
|
3
|
+
import Component from '../components/Option.js';
|
|
4
|
+
import { useDebouncedState, getStatusBarHeight } from '@tecsinapse/react-core';
|
|
5
|
+
import { isOptionChecked, multiBuilder, singleBuilder } from '../functions.js';
|
|
6
|
+
|
|
7
|
+
const useModal = ({
|
|
8
|
+
keyExtractor,
|
|
9
|
+
labelExtractor,
|
|
10
|
+
focused,
|
|
11
|
+
type,
|
|
12
|
+
value,
|
|
13
|
+
onSelect,
|
|
14
|
+
onSearch,
|
|
15
|
+
close,
|
|
16
|
+
closeOnPick,
|
|
17
|
+
...others
|
|
18
|
+
}) => {
|
|
19
|
+
const [selectedValues, setSelectedValues] = React__default.useState([]);
|
|
20
|
+
const [searchArg, setSearchArg] = useDebouncedState("", onSearch);
|
|
21
|
+
const ModalComponent = React__default.useMemo(
|
|
22
|
+
() => getStyledModal(getStatusBarHeight(true)),
|
|
23
|
+
[]
|
|
24
|
+
);
|
|
25
|
+
const _closeOnPick = closeOnPick && type === "single";
|
|
26
|
+
React__default.useEffect(() => {
|
|
27
|
+
setSelectedValues(
|
|
28
|
+
value ? type === "multi" ? value : [value] : []
|
|
29
|
+
);
|
|
30
|
+
}, [value, focused, setSelectedValues]);
|
|
31
|
+
const getData = React__default.useCallback(
|
|
32
|
+
(_options) => {
|
|
33
|
+
return _options.map((option, index) => {
|
|
34
|
+
return {
|
|
35
|
+
...option,
|
|
36
|
+
_checked: isOptionChecked(
|
|
37
|
+
type,
|
|
38
|
+
option,
|
|
39
|
+
selectedValues,
|
|
40
|
+
keyExtractor,
|
|
41
|
+
index
|
|
42
|
+
)
|
|
43
|
+
};
|
|
44
|
+
});
|
|
45
|
+
},
|
|
46
|
+
[type, selectedValues, keyExtractor]
|
|
47
|
+
);
|
|
48
|
+
const handlePressItem = React__default.useCallback(
|
|
49
|
+
(option) => {
|
|
50
|
+
setSelectedValues(
|
|
51
|
+
(prev) => type === "multi" ? multiBuilder(option, prev, keyExtractor) : singleBuilder(option, prev, keyExtractor)
|
|
52
|
+
);
|
|
53
|
+
},
|
|
54
|
+
[keyExtractor, type]
|
|
55
|
+
);
|
|
56
|
+
React__default.useEffect(() => {
|
|
57
|
+
if (_closeOnPick && selectedValues[0] && selectedValues[0] !== value) {
|
|
58
|
+
handleConfirm();
|
|
59
|
+
}
|
|
60
|
+
}, [selectedValues[0], value, closeOnPick]);
|
|
61
|
+
const handleConfirm = React__default.useCallback(() => {
|
|
62
|
+
onSelect(
|
|
63
|
+
type === "single" ? selectedValues[0] : selectedValues
|
|
64
|
+
);
|
|
65
|
+
close?.();
|
|
66
|
+
}, [selectedValues]);
|
|
67
|
+
const renderItem = React__default.useCallback(
|
|
68
|
+
({ item }) => /* @__PURE__ */ React__default.createElement(
|
|
69
|
+
Component,
|
|
70
|
+
{
|
|
71
|
+
item,
|
|
72
|
+
type,
|
|
73
|
+
handlePressItem: (t) => {
|
|
74
|
+
handlePressItem(t);
|
|
75
|
+
},
|
|
76
|
+
labelExtractor
|
|
77
|
+
}
|
|
78
|
+
),
|
|
79
|
+
[type, handlePressItem, labelExtractor]
|
|
80
|
+
);
|
|
81
|
+
return {
|
|
82
|
+
/**
|
|
83
|
+
* Hook props
|
|
84
|
+
*/
|
|
85
|
+
searchArg,
|
|
86
|
+
setSearchArg,
|
|
87
|
+
ModalComponent,
|
|
88
|
+
renderItem,
|
|
89
|
+
getData,
|
|
90
|
+
handleConfirm,
|
|
91
|
+
/**
|
|
92
|
+
* Component props
|
|
93
|
+
*/
|
|
94
|
+
keyExtractor,
|
|
95
|
+
labelExtractor,
|
|
96
|
+
focused,
|
|
97
|
+
type,
|
|
98
|
+
value,
|
|
99
|
+
onSelect,
|
|
100
|
+
onSearch,
|
|
101
|
+
close,
|
|
102
|
+
closeOnPick: _closeOnPick,
|
|
103
|
+
...others
|
|
104
|
+
};
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
export { useModal as default };
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import React__default, { useState, useEffect } from 'react';
|
|
2
|
+
import 'react-native';
|
|
3
|
+
import { useInputFocus } from '@tecsinapse/react-core';
|
|
4
|
+
import 'react-native-safe-area-context';
|
|
5
|
+
import '../../../atoms/Modal/ui/styled.js';
|
|
6
|
+
import { useLazyModalManager } from '../../../atoms/Modal/useLazyModalManager.js';
|
|
7
|
+
import { findValue, getMultiLabel, getSingleLabel } from '../functions.js';
|
|
8
|
+
|
|
9
|
+
const useSelect = ({
|
|
10
|
+
value,
|
|
11
|
+
options,
|
|
12
|
+
keyExtractor,
|
|
13
|
+
type,
|
|
14
|
+
labelExtractor,
|
|
15
|
+
placeholder,
|
|
16
|
+
onFocus,
|
|
17
|
+
onBlur,
|
|
18
|
+
disabled,
|
|
19
|
+
onSearch,
|
|
20
|
+
label,
|
|
21
|
+
...rest
|
|
22
|
+
}) => {
|
|
23
|
+
const { focused, handleBlur, handleFocus } = useInputFocus(
|
|
24
|
+
onFocus,
|
|
25
|
+
onBlur,
|
|
26
|
+
!disabled
|
|
27
|
+
);
|
|
28
|
+
const [selectOptions, setSelectOptions] = useState([]);
|
|
29
|
+
const modal = useLazyModalManager();
|
|
30
|
+
const [loading, setLoading] = useState(false);
|
|
31
|
+
const onlyLabel = label && !placeholder;
|
|
32
|
+
const hasValue = type === "single" ? !!value : (value || []).length > 0;
|
|
33
|
+
const _placeholder = onlyLabel ? label : placeholder;
|
|
34
|
+
const _label = hasValue ? label : void 0;
|
|
35
|
+
useEffect(() => {
|
|
36
|
+
if (typeof options !== "function") {
|
|
37
|
+
setSelectOptions(options);
|
|
38
|
+
}
|
|
39
|
+
}, [options]);
|
|
40
|
+
const handleLazyFocus = React__default.useCallback(async () => {
|
|
41
|
+
if (typeof options === "function" && !onSearch) {
|
|
42
|
+
setLoading(true);
|
|
43
|
+
try {
|
|
44
|
+
const result = await options();
|
|
45
|
+
if (result) {
|
|
46
|
+
const _value = value;
|
|
47
|
+
if (_value && !(result instanceof Map) && !findValue(result, _value, keyExtractor)) {
|
|
48
|
+
setSelectOptions([_value, ...result]);
|
|
49
|
+
} else setSelectOptions(result);
|
|
50
|
+
}
|
|
51
|
+
} catch (e) {
|
|
52
|
+
} finally {
|
|
53
|
+
setLoading(false);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}, [options, value, setSelectOptions]);
|
|
57
|
+
const handleOnSearch = React__default.useCallback(
|
|
58
|
+
async (searchInput) => {
|
|
59
|
+
if (searchInput !== void 0 && onSearch) {
|
|
60
|
+
setLoading(true);
|
|
61
|
+
modal.requestUpdate();
|
|
62
|
+
try {
|
|
63
|
+
const result = await onSearch(searchInput);
|
|
64
|
+
if (result) {
|
|
65
|
+
if (type === "single") {
|
|
66
|
+
const _value = value;
|
|
67
|
+
if (_value && !(result instanceof Map) && !findValue(result, _value, keyExtractor)) {
|
|
68
|
+
setSelectOptions([_value, ...result]);
|
|
69
|
+
} else setSelectOptions(result);
|
|
70
|
+
} else {
|
|
71
|
+
const _value = value;
|
|
72
|
+
if (_value?.length && !(result instanceof Map)) {
|
|
73
|
+
const selected = _value.filter((it) => !findValue(result, it, keyExtractor)) ?? [];
|
|
74
|
+
setSelectOptions([...selected, ...result]);
|
|
75
|
+
} else {
|
|
76
|
+
setSelectOptions(result);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
} catch (e) {
|
|
81
|
+
} finally {
|
|
82
|
+
modal.requestUpdate();
|
|
83
|
+
setLoading(false);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
[options, value, keyExtractor]
|
|
88
|
+
);
|
|
89
|
+
const getDisplayValue = React__default.useCallback(() => {
|
|
90
|
+
if (Array.isArray(value)) {
|
|
91
|
+
return getMultiLabel(
|
|
92
|
+
value,
|
|
93
|
+
String(_placeholder),
|
|
94
|
+
selectOptions,
|
|
95
|
+
keyExtractor,
|
|
96
|
+
labelExtractor
|
|
97
|
+
);
|
|
98
|
+
} else {
|
|
99
|
+
return getSingleLabel(
|
|
100
|
+
value,
|
|
101
|
+
String(_placeholder),
|
|
102
|
+
selectOptions,
|
|
103
|
+
keyExtractor,
|
|
104
|
+
labelExtractor
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
}, [_placeholder, value, selectOptions]);
|
|
108
|
+
const handlePressInput = async () => {
|
|
109
|
+
modal.show();
|
|
110
|
+
handleFocus();
|
|
111
|
+
await handleLazyFocus();
|
|
112
|
+
};
|
|
113
|
+
return {
|
|
114
|
+
/**
|
|
115
|
+
* Hook props
|
|
116
|
+
*/
|
|
117
|
+
focused,
|
|
118
|
+
handleBlur,
|
|
119
|
+
handlePressInput,
|
|
120
|
+
getDisplayValue,
|
|
121
|
+
handleOnSearch,
|
|
122
|
+
_label,
|
|
123
|
+
loading,
|
|
124
|
+
modal,
|
|
125
|
+
selectOptions,
|
|
126
|
+
setSelectOptions,
|
|
127
|
+
/**
|
|
128
|
+
* Component props
|
|
129
|
+
*/
|
|
130
|
+
value,
|
|
131
|
+
options,
|
|
132
|
+
keyExtractor,
|
|
133
|
+
type,
|
|
134
|
+
labelExtractor,
|
|
135
|
+
placeholder,
|
|
136
|
+
onFocus,
|
|
137
|
+
onBlur,
|
|
138
|
+
disabled,
|
|
139
|
+
onSearch,
|
|
140
|
+
label,
|
|
141
|
+
...rest
|
|
142
|
+
};
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
export { useSelect as default };
|
|
@@ -31,8 +31,6 @@ const SearchBarContainer = styled(View)`
|
|
|
31
31
|
position: relative;
|
|
32
32
|
`;
|
|
33
33
|
const ListItem = styled(PressableSurface)`
|
|
34
|
-
border-bottom-width: ${RFValueStr("1px")};
|
|
35
|
-
border-color: ${({ theme }) => theme.color.secondary.light};
|
|
36
34
|
padding-top: ${({ theme }) => theme.spacing.mili};
|
|
37
35
|
padding-bottom: ${({ theme }) => theme.spacing.mili};
|
|
38
36
|
padding-left: ${({ theme }) => theme.spacing.deca};
|
|
@@ -58,5 +56,15 @@ const TextTitleModal = styled(Text)`
|
|
|
58
56
|
const StyledTextItemSelect = styled(Text)`
|
|
59
57
|
width: 90%;
|
|
60
58
|
`;
|
|
59
|
+
const Divider = styled(View)`
|
|
60
|
+
height: ${RFValueStr("1px")};
|
|
61
|
+
display: flex;
|
|
62
|
+
flex: 1 1 auto;
|
|
63
|
+
background-color: ${({ theme }) => theme.color.secondary.light};
|
|
64
|
+
`;
|
|
65
|
+
const SectionHeader = styled(View)`
|
|
66
|
+
background-color: #fff;
|
|
67
|
+
padding: ${({ theme }) => theme.spacing.deca};
|
|
68
|
+
`;
|
|
61
69
|
|
|
62
|
-
export { FetchIndicator, ListItem, ModalFooter, SearchBarContainer, SelectIcon, StyledSelectionText, StyledTextItemSelect, TextTitleModal, getStyledModal };
|
|
70
|
+
export { Divider, FetchIndicator, ListItem, ModalFooter, SearchBarContainer, SectionHeader, SelectIcon, StyledSelectionText, StyledTextItemSelect, TextTitleModal, getStyledModal };
|
|
@@ -19,6 +19,7 @@ export declare class ModalLifecycleHandler {
|
|
|
19
19
|
private findNode;
|
|
20
20
|
show: (id: string) => void;
|
|
21
21
|
close: (id: string) => void;
|
|
22
|
+
closeLastOpenedModal: () => void;
|
|
22
23
|
}
|
|
23
24
|
export declare const createModalLifecycleHandler: () => ModalLifecycleHandler;
|
|
24
25
|
export {};
|
|
@@ -1,25 +1,4 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
options: ((searchInput?: string) => Promise<Data[]>) | Data[];
|
|
5
|
-
onSelect: (option: Type extends 'single' ? Data | undefined : Data[]) => never | void;
|
|
6
|
-
value: Type extends 'single' ? Data | null | undefined : Data[];
|
|
7
|
-
type: Type;
|
|
8
|
-
keyExtractor: (t: Data, index?: number) => string;
|
|
9
|
-
labelExtractor: (t: Data) => string;
|
|
10
|
-
groupKeyExtractor?: (t: Data) => string;
|
|
11
|
-
hideSearchBar?: boolean;
|
|
12
|
-
placeholder?: string;
|
|
13
|
-
onFocus?: () => void | never;
|
|
14
|
-
onBlur?: () => void | never;
|
|
15
|
-
onSearch?: ((searchArg: string) => void) | ((searchInput?: string) => Promise<Data[]>) | never;
|
|
16
|
-
searchBarPlaceholder?: string;
|
|
17
|
-
confirmButtonText?: string;
|
|
18
|
-
selectModalTitle?: string;
|
|
19
|
-
selectModalTitleComponent?: JSX.Element;
|
|
20
|
-
closeOnPick?: boolean;
|
|
21
|
-
controlComponent?: (onPress: () => void, displayValue?: string) => JSX.Element;
|
|
22
|
-
numberOfLines?: number;
|
|
23
|
-
}
|
|
24
|
-
declare function Select<Data, Type extends 'single' | 'multi'>({ value, options, keyExtractor, groupKeyExtractor, onSelect, type, labelExtractor, placeholder, onFocus, onBlur, disabled, onSearch, selectModalTitle, selectModalTitleComponent, searchBarPlaceholder, hideSearchBar, confirmButtonText, rightComponent, variant, hintComponent, hint, style, controlComponent, closeOnPick, label, numberOfLines, ...rest }: SelectNativeProps<Data, Type>): JSX.Element;
|
|
2
|
+
import { SelectNativeProps, SelectType } from './types';
|
|
3
|
+
declare function Select<Data, Type extends SelectType>(props: SelectNativeProps<Data, Type>): JSX.Element;
|
|
25
4
|
export default Select;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import { IBaseModal } from '../../../atoms/Modal';
|
|
3
|
+
import { LoadingProps, SelectNativeProps, SelectType } from '../types';
|
|
4
|
+
export declare const Modal: <Data, Type extends SelectType>(props: SelectNativeProps<Data, Type> & LoadingProps & IBaseModal) => JSX.Element;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import { OptionData, SelectType } from '../types';
|
|
3
|
+
interface IOption<Data> {
|
|
4
|
+
item: OptionData<Data>;
|
|
5
|
+
type: SelectType;
|
|
6
|
+
labelExtractor: (t: Data) => string;
|
|
7
|
+
handlePressItem: (t: Data) => void;
|
|
8
|
+
}
|
|
9
|
+
declare const Component: <Data>({ handlePressItem, labelExtractor, item, type, }: IOption<Data>) => JSX.Element;
|
|
10
|
+
export default Component;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Extractor, SelectType } from './types';
|
|
2
|
+
export declare const findValue: <Data>(array: Data[], value: Data, keyExtractor: Extractor<Data>, idx?: number) => Data | undefined;
|
|
3
|
+
export declare const isOptionChecked: <Data>(type: SelectType, option: Data, src: Data[], keyExtractor: Extractor<Data>, idx: number) => boolean;
|
|
4
|
+
export declare const multiBuilder: <Data>(option: Data, src: Data[], keyExtractor: Extractor<Data>) => Data[];
|
|
5
|
+
export declare const singleBuilder: <Data>(option: Data, src: Data[], keyExtractor: Extractor<Data>) => Data[];
|
|
6
|
+
export declare const isMap: <Data>(value: Data[] | Map<string, Data[]>) => boolean;
|
|
7
|
+
export declare const mapToArray: <Data>(map: Map<string, Data[]>) => Data[];
|
|
8
|
+
export declare const getMultiLabel: <Data>(value: Data[], placeholder: string, options: Data[] | Map<string, Data[]>, keyExtractor: Extractor<Data>, labelExtractor: Extractor<Data>) => string;
|
|
9
|
+
export declare const getSingleLabel: <Data>(value: Data, placeholder: string, options: Data[] | Map<string, Data[]>, keyExtractor: Extractor<Data>, labelExtractor: Extractor<Data>) => string;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { LoadingProps, OptionData, SelectNativeProps, SelectType } from '../types';
|
|
3
|
+
import { ListRenderItemInfo } from 'react-native';
|
|
4
|
+
import { IBaseModal } from '../../../atoms/Modal';
|
|
5
|
+
declare const useModal: <Data, Type extends SelectType>({ keyExtractor, labelExtractor, focused, type, value, onSelect, onSearch, close, closeOnPick, ...others }: SelectNativeProps<Data, Type> & LoadingProps & IBaseModal) => {
|
|
6
|
+
options: ((searchInput?: string | undefined) => Promise<Data[] | Map<string, Data[]>>) | Data[] | Map<string, Data[]>;
|
|
7
|
+
groupKeyExtractor?: import("../types").Extractor<Data> | undefined;
|
|
8
|
+
hideSearchBar?: boolean | undefined;
|
|
9
|
+
placeholder?: string | undefined;
|
|
10
|
+
onFocus?: (() => void) | undefined;
|
|
11
|
+
onBlur?: (() => void) | undefined;
|
|
12
|
+
searchBarPlaceholder?: string | undefined;
|
|
13
|
+
confirmButtonText?: string | undefined;
|
|
14
|
+
selectModalTitle?: string | undefined;
|
|
15
|
+
selectModalTitleComponent?: JSX.Element | undefined;
|
|
16
|
+
controlComponent?: ((onPress: () => void, displayValue?: string | undefined) => JSX.Element) | undefined;
|
|
17
|
+
numberOfLines?: number | undefined;
|
|
18
|
+
label?: string | undefined;
|
|
19
|
+
style?: import("react-native").StyleProp<import("react-native").ViewStyle>;
|
|
20
|
+
testID?: string | undefined;
|
|
21
|
+
borderColor?: keyof import("@tecsinapse/react-core").Color | undefined;
|
|
22
|
+
disabled?: boolean | undefined;
|
|
23
|
+
variant?: import("@tecsinapse/react-core").InputVariantType | undefined;
|
|
24
|
+
labelColor?: keyof import("@tecsinapse/react-core").FontColor | undefined;
|
|
25
|
+
labelColorVariant?: keyof import("@tecsinapse/react-core").Color | undefined;
|
|
26
|
+
labelColorTone?: keyof import("@tecsinapse/react-core").ColorGradation | undefined;
|
|
27
|
+
labelTypography?: keyof import("@tecsinapse/react-core").TypographyVariation | undefined;
|
|
28
|
+
labelStack?: keyof import("@tecsinapse/react-core").FontStack | undefined;
|
|
29
|
+
LabelComponent?: React.FC<import("@tecsinapse/react-core").TextProps> | undefined;
|
|
30
|
+
labelWeight?: keyof import("@tecsinapse/react-core").FontWeight | undefined;
|
|
31
|
+
leftComponent?: JSX.Element | undefined;
|
|
32
|
+
rightComponent?: JSX.Element | undefined;
|
|
33
|
+
borderColorGradation?: keyof import("@tecsinapse/react-core").ColorGradation | undefined;
|
|
34
|
+
inputContainerStyle?: import("react-native").StyleProp<import("react-native").ViewStyle>;
|
|
35
|
+
hint?: string | undefined;
|
|
36
|
+
hintComponent?: JSX.Element | undefined;
|
|
37
|
+
loading?: boolean | undefined;
|
|
38
|
+
visible?: boolean | undefined;
|
|
39
|
+
BoxComponent?: React.FC<any> | undefined;
|
|
40
|
+
frozen?: boolean | undefined;
|
|
41
|
+
isLastShown?: boolean | undefined;
|
|
42
|
+
showCloseBar?: boolean | undefined;
|
|
43
|
+
onClose?: (() => void) | undefined;
|
|
44
|
+
children?: React.ReactNode;
|
|
45
|
+
searchArg: string;
|
|
46
|
+
setSearchArg: React.Dispatch<React.SetStateAction<string>>;
|
|
47
|
+
ModalComponent: import("@emotion/native").StyledComponent<import("react-native").ViewProps & {
|
|
48
|
+
theme?: import("@emotion/react").Theme | undefined;
|
|
49
|
+
as?: React.ElementType<any> | undefined;
|
|
50
|
+
} & import("react-native").ModalBaseProps & import("react-native").ModalPropsIOS & import("react-native").ModalPropsAndroid & Partial<import("@tecsinapse/react-core").ThemeProviderProps>, {}, {
|
|
51
|
+
ref?: React.Ref<import("react-native").View> | undefined;
|
|
52
|
+
}>;
|
|
53
|
+
renderItem: ({ item }: ListRenderItemInfo<OptionData<Data>>) => JSX.Element;
|
|
54
|
+
getData: (_options: Data[]) => OptionData<Data>[];
|
|
55
|
+
handleConfirm: () => void;
|
|
56
|
+
keyExtractor: import("../types").Extractor<Data>;
|
|
57
|
+
labelExtractor: import("../types").Extractor<Data>;
|
|
58
|
+
focused: boolean | undefined;
|
|
59
|
+
type: Type;
|
|
60
|
+
value: Type extends "single" ? Data | null | undefined : Data[];
|
|
61
|
+
onSelect: (option: Type extends "single" ? Data | undefined : Data[]) => void;
|
|
62
|
+
onSearch: ((searchArg: string) => void) | ((searchInput?: string | undefined) => Promise<Data[] | Map<string, Data[]>>) | undefined;
|
|
63
|
+
close: (() => void) | undefined;
|
|
64
|
+
closeOnPick: boolean | undefined;
|
|
65
|
+
};
|
|
66
|
+
export default useModal;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { SelectNativeProps, SelectType } from '../types';
|
|
3
|
+
declare const useSelect: <Data, Type extends SelectType>({ value, options, keyExtractor, type, labelExtractor, placeholder, onFocus, onBlur, disabled, onSearch, label, ...rest }: SelectNativeProps<Data, Type>) => {
|
|
4
|
+
onSelect: (option: Type extends "single" ? Data | undefined : Data[]) => void;
|
|
5
|
+
groupKeyExtractor?: import("../types").Extractor<Data> | undefined;
|
|
6
|
+
hideSearchBar?: boolean | undefined;
|
|
7
|
+
searchBarPlaceholder?: string | undefined;
|
|
8
|
+
confirmButtonText?: string | undefined;
|
|
9
|
+
selectModalTitle?: string | undefined;
|
|
10
|
+
selectModalTitleComponent?: JSX.Element | undefined;
|
|
11
|
+
closeOnPick?: boolean | undefined;
|
|
12
|
+
controlComponent?: ((onPress: () => void, displayValue?: string | undefined) => JSX.Element) | undefined;
|
|
13
|
+
numberOfLines?: number | undefined;
|
|
14
|
+
style?: import("react-native").StyleProp<import("react-native").ViewStyle>;
|
|
15
|
+
testID?: string | undefined;
|
|
16
|
+
borderColor?: keyof import("@tecsinapse/react-core").Color | undefined;
|
|
17
|
+
variant?: import("@tecsinapse/react-core").InputVariantType | undefined;
|
|
18
|
+
labelColor?: keyof import("@tecsinapse/react-core").FontColor | undefined;
|
|
19
|
+
labelColorVariant?: keyof import("@tecsinapse/react-core").Color | undefined;
|
|
20
|
+
labelColorTone?: keyof import("@tecsinapse/react-core").ColorGradation | undefined;
|
|
21
|
+
labelTypography?: keyof import("@tecsinapse/react-core").TypographyVariation | undefined;
|
|
22
|
+
labelStack?: keyof import("@tecsinapse/react-core").FontStack | undefined;
|
|
23
|
+
LabelComponent?: React.FC<import("@tecsinapse/react-core").TextProps> | undefined;
|
|
24
|
+
labelWeight?: keyof import("@tecsinapse/react-core").FontWeight | undefined;
|
|
25
|
+
leftComponent?: JSX.Element | undefined;
|
|
26
|
+
rightComponent?: JSX.Element | undefined;
|
|
27
|
+
borderColorGradation?: keyof import("@tecsinapse/react-core").ColorGradation | undefined;
|
|
28
|
+
inputContainerStyle?: import("react-native").StyleProp<import("react-native").ViewStyle>;
|
|
29
|
+
focused: boolean;
|
|
30
|
+
hint?: string | undefined;
|
|
31
|
+
hintComponent?: JSX.Element | undefined;
|
|
32
|
+
handleBlur: () => void;
|
|
33
|
+
handlePressInput: () => Promise<void>;
|
|
34
|
+
getDisplayValue: () => string;
|
|
35
|
+
handleOnSearch: (searchInput: string | undefined) => Promise<void>;
|
|
36
|
+
_label: string | undefined;
|
|
37
|
+
loading: boolean;
|
|
38
|
+
modal: {
|
|
39
|
+
requestUpdate: () => void;
|
|
40
|
+
sync: (modal: React.ReactElement<import("../../../atoms/Modal").IBaseModal, string | React.JSXElementConstructor<any>>) => null;
|
|
41
|
+
show: () => void;
|
|
42
|
+
close: () => void;
|
|
43
|
+
};
|
|
44
|
+
selectOptions: Data[] | Map<string, Data[]>;
|
|
45
|
+
setSelectOptions: React.Dispatch<React.SetStateAction<Data[] | Map<string, Data[]>>>;
|
|
46
|
+
value: Type extends "single" ? Data | null | undefined : Data[];
|
|
47
|
+
options: ((searchInput?: string | undefined) => Promise<Data[] | Map<string, Data[]>>) | Data[] | Map<string, Data[]>;
|
|
48
|
+
keyExtractor: import("../types").Extractor<Data>;
|
|
49
|
+
type: Type;
|
|
50
|
+
labelExtractor: import("../types").Extractor<Data>;
|
|
51
|
+
placeholder: string | undefined;
|
|
52
|
+
onFocus: (() => void) | undefined;
|
|
53
|
+
onBlur: (() => void) | undefined;
|
|
54
|
+
disabled: boolean | undefined;
|
|
55
|
+
onSearch: ((searchArg: string) => void) | ((searchInput?: string | undefined) => Promise<Data[] | Map<string, Data[]>>) | undefined;
|
|
56
|
+
label: string | undefined;
|
|
57
|
+
};
|
|
58
|
+
export default useSelect;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { default as Select } from './Select';
|
|
2
|
-
export type { SelectNativeProps } from './
|
|
2
|
+
export type { SelectNativeProps } from './types';
|
|
@@ -51,3 +51,15 @@ export declare const StyledTextItemSelect: import("@emotion/native").StyledCompo
|
|
|
51
51
|
theme?: import("@emotion/react").Theme | undefined;
|
|
52
52
|
as?: import("react").ElementType<any> | undefined;
|
|
53
53
|
}, {}, {}>;
|
|
54
|
+
export declare const Divider: import("@emotion/native").StyledComponent<ViewProps & {
|
|
55
|
+
theme?: import("@emotion/react").Theme | undefined;
|
|
56
|
+
as?: import("react").ElementType<any> | undefined;
|
|
57
|
+
} & Partial<import("@tecsinapse/react-core").ThemeProviderProps>, {}, {
|
|
58
|
+
ref?: import("react").Ref<View> | undefined;
|
|
59
|
+
}>;
|
|
60
|
+
export declare const SectionHeader: import("@emotion/native").StyledComponent<ViewProps & {
|
|
61
|
+
theme?: import("@emotion/react").Theme | undefined;
|
|
62
|
+
as?: import("react").ElementType<any> | undefined;
|
|
63
|
+
} & Partial<import("@tecsinapse/react-core").ThemeProviderProps>, {}, {
|
|
64
|
+
ref?: import("react").Ref<View> | undefined;
|
|
65
|
+
}>;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import { InputContainerProps } from '@tecsinapse/react-core';
|
|
3
|
+
export type OptionData<T> = T & {
|
|
4
|
+
_checked: boolean;
|
|
5
|
+
};
|
|
6
|
+
export type SelectType = 'single' | 'multi';
|
|
7
|
+
export interface LoadingProps {
|
|
8
|
+
loading?: boolean;
|
|
9
|
+
}
|
|
10
|
+
type SearchFn<Data> = (searchInput?: string) => Promise<Data[] | Map<string, Data[]>>;
|
|
11
|
+
export type Extractor<Data> = (t: Data, index?: number) => string;
|
|
12
|
+
export interface SelectNativeProps<Data, Type extends SelectType> extends Omit<InputContainerProps, 'value' | 'onChange' | 'onChangeText'> {
|
|
13
|
+
options: SearchFn<Data> | Data[] | Map<string, Data[]>;
|
|
14
|
+
onSelect: (option: Type extends 'single' ? Data | undefined : Data[]) => never | void;
|
|
15
|
+
value: Type extends 'single' ? Data | null | undefined : Data[];
|
|
16
|
+
type: Type;
|
|
17
|
+
keyExtractor: Extractor<Data>;
|
|
18
|
+
labelExtractor: Extractor<Data>;
|
|
19
|
+
groupKeyExtractor?: Extractor<Data>;
|
|
20
|
+
hideSearchBar?: boolean;
|
|
21
|
+
placeholder?: string;
|
|
22
|
+
onFocus?: () => void | never;
|
|
23
|
+
onBlur?: () => void | never;
|
|
24
|
+
onSearch?: ((searchArg: string) => void) | SearchFn<Data> | never;
|
|
25
|
+
searchBarPlaceholder?: string;
|
|
26
|
+
confirmButtonText?: string;
|
|
27
|
+
selectModalTitle?: string;
|
|
28
|
+
selectModalTitleComponent?: JSX.Element;
|
|
29
|
+
closeOnPick?: boolean;
|
|
30
|
+
controlComponent?: (onPress: () => void, displayValue?: string) => JSX.Element;
|
|
31
|
+
numberOfLines?: number;
|
|
32
|
+
}
|
|
33
|
+
export {};
|