|
@@ -45,7 +45,9 @@ import {
|
|
|
uuid
|
|
uuid
|
|
|
} from "../../utils";
|
|
} from "../../utils";
|
|
|
import BottomSheet from "../bottomSheet";
|
|
import BottomSheet from "../bottomSheet";
|
|
|
|
|
+import TextInput from "../textInput";
|
|
|
import Text from "../text";
|
|
import Text from "../text";
|
|
|
|
|
+import Loading from "../loading";
|
|
|
|
|
|
|
|
const SelectBoxTypeIcon: Record<Exclude<SelectBoxType, "default">, NCoreUIKitIcon> = {
|
|
const SelectBoxTypeIcon: Record<Exclude<SelectBoxType, "default">, NCoreUIKitIcon> = {
|
|
|
"question": BadgeQuestionMarkIcon,
|
|
"question": BadgeQuestionMarkIcon,
|
|
@@ -60,12 +62,15 @@ function SelectBox<T>({
|
|
|
hintTextIcon: HintTextIconProp,
|
|
hintTextIcon: HintTextIconProp,
|
|
|
spreadBehaviour = "baseline",
|
|
spreadBehaviour = "baseline",
|
|
|
isShowHintTextIcon = false,
|
|
isShowHintTextIcon = false,
|
|
|
|
|
+ isWorkWithRealtime = true,
|
|
|
icon: IconComponentProp,
|
|
icon: IconComponentProp,
|
|
|
hintTextContainerStyle,
|
|
hintTextContainerStyle,
|
|
|
|
|
+ removeSelectValidation,
|
|
|
isCleanEnabled = false,
|
|
isCleanEnabled = false,
|
|
|
contentContainerStyle,
|
|
contentContainerStyle,
|
|
|
subTitle = "Optional",
|
|
subTitle = "Optional",
|
|
|
initialSelectedItems,
|
|
initialSelectedItems,
|
|
|
|
|
+ isSearchable = false,
|
|
|
onFocus: onFocusProp,
|
|
onFocus: onFocusProp,
|
|
|
isRequired = false,
|
|
isRequired = false,
|
|
|
isDisabled = false,
|
|
isDisabled = false,
|
|
@@ -76,6 +81,7 @@ function SelectBox<T>({
|
|
|
type = "default",
|
|
type = "default",
|
|
|
rightIconOnPress,
|
|
rightIconOnPress,
|
|
|
renderOptionIcon,
|
|
renderOptionIcon,
|
|
|
|
|
+ selectValidation,
|
|
|
rightIconStyle,
|
|
rightIconStyle,
|
|
|
isShowSubTitle,
|
|
isShowSubTitle,
|
|
|
cleanIconStyle,
|
|
cleanIconStyle,
|
|
@@ -85,11 +91,12 @@ function SelectBox<T>({
|
|
|
placeholder,
|
|
placeholder,
|
|
|
iconOnPress,
|
|
iconOnPress,
|
|
|
isOptional,
|
|
isOptional,
|
|
|
- validation,
|
|
|
|
|
|
|
+ renderItem,
|
|
|
customKey,
|
|
customKey,
|
|
|
iconStyle,
|
|
iconStyle,
|
|
|
onChange,
|
|
onChange,
|
|
|
hintText,
|
|
hintText,
|
|
|
|
|
+ onSearch,
|
|
|
style,
|
|
style,
|
|
|
title
|
|
title
|
|
|
}: ISelectBoxProps<T>, ref: Ref<ISelectBoxRef<T>>) {
|
|
}: ISelectBoxProps<T>, ref: Ref<ISelectBoxRef<T>>) {
|
|
@@ -114,6 +121,7 @@ function SelectBox<T>({
|
|
|
|
|
|
|
|
const {
|
|
const {
|
|
|
bottomSheetHeaderContainer: bottomSheetHeaderContainerDynamicStyle,
|
|
bottomSheetHeaderContainer: bottomSheetHeaderContainerDynamicStyle,
|
|
|
|
|
+ loadingContainer: loadingContainerDynamicStyle,
|
|
|
contentContainer: contentContainerDynamicStyle,
|
|
contentContainer: contentContainerDynamicStyle,
|
|
|
titleContainer: titleContainerDynamicStyle,
|
|
titleContainer: titleContainerDynamicStyle,
|
|
|
itemContainer: itemContainerDynamicStyle,
|
|
itemContainer: itemContainerDynamicStyle,
|
|
@@ -168,7 +176,7 @@ function SelectBox<T>({
|
|
|
const [
|
|
const [
|
|
|
isLoading,
|
|
isLoading,
|
|
|
setIsLoading
|
|
setIsLoading
|
|
|
- ] = useState(false);
|
|
|
|
|
|
|
+ ] = useState(true);
|
|
|
|
|
|
|
|
const [
|
|
const [
|
|
|
isMoreLoading,
|
|
isMoreLoading,
|
|
@@ -180,6 +188,13 @@ function SelectBox<T>({
|
|
|
setSelectedItems
|
|
setSelectedItems
|
|
|
] = useState<Array<SelectedItem>>(initialSelectedItems ?? []);
|
|
] = useState<Array<SelectedItem>>(initialSelectedItems ?? []);
|
|
|
|
|
|
|
|
|
|
+ const [
|
|
|
|
|
+ tempSelectedItems,
|
|
|
|
|
+ setTempSelectedItems
|
|
|
|
|
+ ] = useState<Array<SelectedItem>>(initialSelectedItems ?? []);
|
|
|
|
|
+
|
|
|
|
|
+ const mainSelectedItems = isWorkWithRealtime ? selectedItems : tempSelectedItems;
|
|
|
|
|
+
|
|
|
useImperativeHandle(
|
|
useImperativeHandle(
|
|
|
ref,
|
|
ref,
|
|
|
() => ({
|
|
() => ({
|
|
@@ -201,13 +216,33 @@ function SelectBox<T>({
|
|
|
}, [isActive]);
|
|
}, [isActive]);
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
useEffect(() => {
|
|
|
- if(searchText && searchText.length) {
|
|
|
|
|
-
|
|
|
|
|
|
|
+ if(isSearchable && searchText && searchText.length) {
|
|
|
|
|
+ if(onSearch) {
|
|
|
|
|
+ const _searchedData = prepareDatas(onSearch({
|
|
|
|
|
+ selectedItems: mainSelectedItems,
|
|
|
|
|
+ setIsLoading,
|
|
|
|
|
+ searchText,
|
|
|
|
|
+ data
|
|
|
|
|
+ }) as Array<T & SelectedItem>, mainSelectedItems);
|
|
|
|
|
+
|
|
|
|
|
+ setSearchedData(_searchedData);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ const _searchedData = prepareDatas(data.filter(dI => {
|
|
|
|
|
+ return dI.__title.toLocaleLowerCase().includes(searchText.toLocaleLowerCase());
|
|
|
|
|
+ }) as Array<T & SelectedItem>, mainSelectedItems);
|
|
|
|
|
+
|
|
|
|
|
+ setSearchedData(_searchedData);
|
|
|
|
|
+ }
|
|
|
|
|
+ } else if(searchedData && searchedData.length) {
|
|
|
|
|
+ setSearchedData([]);
|
|
|
}
|
|
}
|
|
|
- }, [searchText]);
|
|
|
|
|
|
|
+ }, [
|
|
|
|
|
+ data,
|
|
|
|
|
+ searchText
|
|
|
|
|
+ ]);
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
useEffect(() => {
|
|
|
- const initData = prepareDatas(initialData, initialSelectedItems);
|
|
|
|
|
|
|
+ const initData = prepareDatas(initialData as Array<T & SelectedItem>, initialSelectedItems);
|
|
|
|
|
|
|
|
setData(initData);
|
|
setData(initData);
|
|
|
}, []);
|
|
}, []);
|
|
@@ -235,7 +270,11 @@ function SelectBox<T>({
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
const cleanSelections = () => {
|
|
const cleanSelections = () => {
|
|
|
- setSelectedItems([]);
|
|
|
|
|
|
|
+ if(isWorkWithRealtime) {
|
|
|
|
|
+ setSelectedItems([]);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ setTempSelectedItems([]);
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
if(onChange) {
|
|
if(onChange) {
|
|
|
onChange([], data);
|
|
onChange([], data);
|
|
@@ -246,24 +285,27 @@ function SelectBox<T>({
|
|
|
const _newData = newData.map((bIItem, bIIndex) => {
|
|
const _newData = newData.map((bIItem, bIIndex) => {
|
|
|
return {
|
|
return {
|
|
|
...bIItem,
|
|
...bIItem,
|
|
|
- __title: titleExtractor(bIItem, bIIndex),
|
|
|
|
|
- __key: keyExtractor(bIItem, bIIndex)
|
|
|
|
|
|
|
+ __title: titleExtractor(bIItem as T & SelectedItem, bIIndex),
|
|
|
|
|
+ __key: keyExtractor(bIItem as T & SelectedItem, bIIndex)
|
|
|
};
|
|
};
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
setData(_newData);
|
|
setData(_newData);
|
|
|
|
|
|
|
|
- const _newSelectedItems = JSON.parse(JSON.stringify(newSelectedItems ? newSelectedItems : selectedItems)).map((sItem: SelectedItem) => {
|
|
|
|
|
|
|
+ const _newSelectedItems = JSON.parse(JSON.stringify(newSelectedItems ? newSelectedItems : mainSelectedItems)).map((sItem: SelectedItem) => {
|
|
|
const originalDataIndex = _newData.findIndex(ssItem => ssItem.__key === sItem.__key);
|
|
const originalDataIndex = _newData.findIndex(ssItem => ssItem.__key === sItem.__key);
|
|
|
|
|
|
|
|
return {
|
|
return {
|
|
|
- ...sItem,
|
|
|
|
|
__title: _newData[originalDataIndex]?.__title,
|
|
__title: _newData[originalDataIndex]?.__title,
|
|
|
__key: _newData[originalDataIndex]?.__key
|
|
__key: _newData[originalDataIndex]?.__key
|
|
|
};
|
|
};
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
- setSelectedItems(_newSelectedItems);
|
|
|
|
|
|
|
+ if(isWorkWithRealtime) {
|
|
|
|
|
+ setSelectedItems(_newSelectedItems);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ setTempSelectedItems(_newSelectedItems);
|
|
|
|
|
+ }
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
const updateSelections = (newSelectedItems: Array<SelectedItem>) => {
|
|
const updateSelections = (newSelectedItems: Array<SelectedItem>) => {
|
|
@@ -277,10 +319,14 @@ function SelectBox<T>({
|
|
|
};
|
|
};
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
- setSelectedItems(_newSelectedItems);
|
|
|
|
|
|
|
+ if(isWorkWithRealtime) {
|
|
|
|
|
+ setSelectedItems(_newSelectedItems);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ setTempSelectedItems(_newSelectedItems);
|
|
|
|
|
+ }
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
- const prepareDatas = (items: Array<T>, sItems?: Array<SelectedItem>) => {
|
|
|
|
|
|
|
+ const prepareDatas = (items: Array<T & SelectedItem>, sItems?: Array<SelectedItem>) => {
|
|
|
const initData: Array<SelectedItem | T & SelectedItem> = [];
|
|
const initData: Array<SelectedItem | T & SelectedItem> = [];
|
|
|
|
|
|
|
|
if(sItems && sItems.length) {
|
|
if(sItems && sItems.length) {
|
|
@@ -308,19 +354,38 @@ function SelectBox<T>({
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
const selectObject = (selectedItem: T & SelectedItem | SelectedItem) => {
|
|
const selectObject = (selectedItem: T & SelectedItem | SelectedItem) => {
|
|
|
- const isAlreadySelected = selectedItems.findIndex(sItem => sItem.__key === selectedItem.__key);
|
|
|
|
|
- let _selectedItems = JSON.parse(JSON.stringify(selectedItems));
|
|
|
|
|
|
|
+ const isAlreadySelected = mainSelectedItems.findIndex(sItem => sItem.__key === selectedItem.__key);
|
|
|
|
|
+ let _selectedItems = JSON.parse(JSON.stringify(mainSelectedItems));
|
|
|
|
|
|
|
|
if(isAlreadySelected !== -1) {
|
|
if(isAlreadySelected !== -1) {
|
|
|
- _selectedItems = _selectedItems.filter((sItem: SelectedItem) => sItem.__key !== selectedItem.__key);
|
|
|
|
|
|
|
+ if(removeSelectValidation) {
|
|
|
|
|
+ if(removeSelectValidation(selectedItem)) {
|
|
|
|
|
+ _selectedItems = _selectedItems.filter((sItem: SelectedItem) => sItem.__key !== selectedItem.__key);
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ _selectedItems = _selectedItems.filter((sItem: SelectedItem) => sItem.__key !== selectedItem.__key);
|
|
|
|
|
+ }
|
|
|
} else {
|
|
} else {
|
|
|
- _selectedItems.push({
|
|
|
|
|
- __title: selectedItem.__title,
|
|
|
|
|
- __key: selectedItem.__key
|
|
|
|
|
- });
|
|
|
|
|
|
|
+ if(selectValidation) {
|
|
|
|
|
+ if(selectValidation(selectedItem)) {
|
|
|
|
|
+ _selectedItems.push({
|
|
|
|
|
+ __title: selectedItem.__title,
|
|
|
|
|
+ __key: selectedItem.__key
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ _selectedItems.push({
|
|
|
|
|
+ __title: selectedItem.__title,
|
|
|
|
|
+ __key: selectedItem.__key
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- setSelectedItems(_selectedItems);
|
|
|
|
|
|
|
+ if(isWorkWithRealtime) {
|
|
|
|
|
+ setSelectedItems(_selectedItems);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ setTempSelectedItems(_selectedItems);
|
|
|
|
|
+ }
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
const onFocus = () => {
|
|
const onFocus = () => {
|
|
@@ -351,10 +416,14 @@ function SelectBox<T>({
|
|
|
cleanButtonDynamicStyle
|
|
cleanButtonDynamicStyle
|
|
|
]}
|
|
]}
|
|
|
onPress={() => {
|
|
onPress={() => {
|
|
|
- setSelectedItems([]);
|
|
|
|
|
|
|
+ if(isWorkWithRealtime) {
|
|
|
|
|
+ setSelectedItems([]);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ setTempSelectedItems([]);
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
if(onChange) {
|
|
if(onChange) {
|
|
|
- onChange([]);
|
|
|
|
|
|
|
+ onChange([], data);
|
|
|
}
|
|
}
|
|
|
}}
|
|
}}
|
|
|
>
|
|
>
|
|
@@ -572,15 +641,46 @@ function SelectBox<T>({
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
const renderBottomSheetContent = () => {
|
|
const renderBottomSheetContent = () => {
|
|
|
- return data.map((item: T, index: number) => {
|
|
|
|
|
|
|
+ if(isLoading) {
|
|
|
|
|
+ return <View
|
|
|
|
|
+ style={[
|
|
|
|
|
+ stylesheet.loadingContainer,
|
|
|
|
|
+ loadingContainerDynamicStyle
|
|
|
|
|
+ ]}
|
|
|
|
|
+ >
|
|
|
|
|
+ <Loading/>
|
|
|
|
|
+ </View>;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return data.map((item: T & SelectedItem | SelectedItem, index: number) => {
|
|
|
|
|
+ const isSelected = mainSelectedItems.findIndex((sI: SelectedItem) => {
|
|
|
|
|
+ return sI.__key === item.__key;
|
|
|
|
|
+ }) !== -1;
|
|
|
|
|
+
|
|
|
|
|
+ if(renderItem) {
|
|
|
|
|
+ return renderItem({
|
|
|
|
|
+ key: keyExtractor(item as T & SelectedItem, index),
|
|
|
|
|
+ onSelect: (sItem) => {
|
|
|
|
|
+ selectObject(sItem);
|
|
|
|
|
+ },
|
|
|
|
|
+ selectedItems: mainSelectedItems,
|
|
|
|
|
+ setIsLoading,
|
|
|
|
|
+ isSelected,
|
|
|
|
|
+ searchText,
|
|
|
|
|
+ index,
|
|
|
|
|
+ item,
|
|
|
|
|
+ data
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
return <TouchableOpacity
|
|
return <TouchableOpacity
|
|
|
- key={keyExtractor(item, index)}
|
|
|
|
|
|
|
+ key={keyExtractor(item as T & SelectedItem, index)}
|
|
|
style={[
|
|
style={[
|
|
|
stylesheet.itemContainer,
|
|
stylesheet.itemContainer,
|
|
|
itemContainerDynamicStyle
|
|
itemContainerDynamicStyle
|
|
|
]}
|
|
]}
|
|
|
onPress={() => {
|
|
onPress={() => {
|
|
|
- selectObject();
|
|
|
|
|
|
|
+ selectObject(item);
|
|
|
}}
|
|
}}
|
|
|
>
|
|
>
|
|
|
<View
|
|
<View
|
|
@@ -592,10 +692,23 @@ function SelectBox<T>({
|
|
|
item,
|
|
item,
|
|
|
index
|
|
index
|
|
|
}) : null}
|
|
}) : null}
|
|
|
- <Text>Geldi gül mevsimi</Text>
|
|
|
|
|
|
|
+ <Text
|
|
|
|
|
+ color={isSelected ? "onPrimary" : undefined}
|
|
|
|
|
+ >{item.__title}</Text>
|
|
|
</View>
|
|
</View>
|
|
|
- <View>
|
|
|
|
|
- <CheckIcon/>
|
|
|
|
|
|
|
+ <View
|
|
|
|
|
+ style={[
|
|
|
|
|
+ {
|
|
|
|
|
+ height: 24 + spaces.spacingSm,
|
|
|
|
|
+ width: 24 + spaces.spacingSm
|
|
|
|
|
+ }
|
|
|
|
|
+ ]}
|
|
|
|
|
+ >
|
|
|
|
|
+ {isSelected ?
|
|
|
|
|
+ <CheckIcon
|
|
|
|
|
+ color={colors.content.icon.onPrimary}
|
|
|
|
|
+ size={24}
|
|
|
|
|
+ /> : null}
|
|
|
</View>
|
|
</View>
|
|
|
</TouchableOpacity>;
|
|
</TouchableOpacity>;
|
|
|
});
|
|
});
|
|
@@ -620,6 +733,12 @@ function SelectBox<T>({
|
|
|
>
|
|
>
|
|
|
{title}
|
|
{title}
|
|
|
</Text>
|
|
</Text>
|
|
|
|
|
+ {isSearchable ? <TextInput
|
|
|
|
|
+ spreadBehaviour="stretch"
|
|
|
|
|
+ onChangeText={(text: string) => {
|
|
|
|
|
+ setSearchText(text);
|
|
|
|
|
+ }}
|
|
|
|
|
+ /> : null}
|
|
|
</View>;
|
|
</View>;
|
|
|
}}
|
|
}}
|
|
|
>
|
|
>
|