@tecsinapse/react-native-kit 1.12.10 → 1.12.14
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/CHANGELOG.md +32 -0
- package/dist/components/atoms/Modal/ModalLifecycleHandler.js +24 -22
- package/dist/components/atoms/Modal/ModalLifecycleHandler.js.map +1 -1
- package/dist/components/atoms/Modal/index.d.ts +1 -0
- package/dist/components/atoms/Modal/index.js +13 -0
- package/dist/components/atoms/Modal/index.js.map +1 -1
- package/dist/components/atoms/Modal/ui/BaseModalView.js +20 -8
- package/dist/components/atoms/Modal/ui/BaseModalView.js.map +1 -1
- package/dist/components/atoms/Modal/ui/types.d.ts +1 -0
- package/dist/components/atoms/Modal/useLazyModalManager.d.ts +8 -0
- package/dist/components/atoms/Modal/useLazyModalManager.js +40 -0
- package/dist/components/atoms/Modal/useLazyModalManager.js.map +1 -0
- package/dist/components/molecules/Calendar/Calendar.d.ts +1 -4
- package/dist/components/molecules/Calendar/Calendar.js +2 -2
- package/dist/components/molecules/Calendar/Calendar.js.map +1 -1
- package/dist/components/molecules/DatePicker/DatePicker.d.ts +3 -4
- package/dist/components/molecules/DatePicker/DatePicker.js +29 -3
- package/dist/components/molecules/DatePicker/DatePicker.js.map +1 -1
- package/dist/components/molecules/DatePicker/index.d.ts +1 -1
- package/dist/components/molecules/DatePicker/index.js +6 -0
- package/dist/components/molecules/DatePicker/index.js.map +1 -1
- package/dist/components/molecules/DatePicker/styled.d.ts +4 -0
- package/dist/components/molecules/DatePicker/styled.js +20 -0
- package/dist/components/molecules/DatePicker/styled.js.map +1 -0
- package/dist/components/molecules/DateTimePicker/DateTimePicker.d.ts +2 -1
- package/dist/components/molecules/DateTimePicker/DateTimePicker.js +18 -4
- package/dist/components/molecules/DateTimePicker/DateTimePicker.js.map +1 -1
- package/dist/components/molecules/DateTimePicker/index.d.ts +1 -1
- package/dist/components/molecules/DateTimePicker/index.js +6 -0
- package/dist/components/molecules/DateTimePicker/index.js.map +1 -1
- package/dist/components/molecules/Select/Modal.d.ts +7 -0
- package/dist/components/{atoms → molecules}/Select/Modal.js +31 -18
- package/dist/components/molecules/Select/Modal.js.map +1 -0
- package/dist/components/{atoms → molecules}/Select/Select.d.ts +2 -1
- package/dist/components/{atoms → molecules}/Select/Select.js +35 -36
- package/dist/components/molecules/Select/Select.js.map +1 -0
- package/dist/components/{atoms → molecules}/Select/index.d.ts +0 -0
- package/dist/components/{atoms → molecules}/Select/index.js +0 -0
- package/dist/components/molecules/Select/index.js.map +1 -0
- package/dist/components/{atoms → molecules}/Select/styled.d.ts +1 -1
- package/dist/components/{atoms → molecules}/Select/styled.js +14 -12
- package/dist/components/molecules/Select/styled.js.map +1 -0
- package/dist/index.d.ts +4 -4
- package/dist/index.js +22 -1
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/components/atoms/Modal/ModalLifecycleHandler.ts +22 -20
- package/src/components/atoms/Modal/index.ts +2 -1
- package/src/components/atoms/Modal/ui/BaseModalView.tsx +29 -15
- package/src/components/atoms/Modal/ui/types.ts +1 -0
- package/src/components/atoms/Modal/useLazyModalManager.ts +43 -0
- package/src/components/molecules/Calendar/Calendar.tsx +3 -7
- package/src/components/molecules/DatePicker/DatePicker.tsx +33 -10
- package/src/components/molecules/DatePicker/index.ts +1 -1
- package/src/components/molecules/DatePicker/styled.ts +6 -0
- package/src/components/molecules/DateTimePicker/DateTimePicker.tsx +24 -7
- package/src/components/molecules/DateTimePicker/index.ts +1 -1
- package/src/components/{atoms → molecules}/Select/Modal.tsx +32 -33
- package/src/components/{atoms → molecules}/Select/Select.tsx +38 -39
- package/src/components/{atoms → molecules}/Select/index.ts +0 -0
- package/src/components/{atoms → molecules}/Select/styled.ts +10 -8
- package/src/index.ts +4 -4
- package/dist/components/atoms/Select/Modal.d.ts +0 -7
- package/dist/components/atoms/Select/Modal.js.map +0 -1
- package/dist/components/atoms/Select/Select.js.map +0 -1
- package/dist/components/atoms/Select/index.js.map +0 -1
- package/dist/components/atoms/Select/styled.js.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { BoxContent } from "@tecsinapse/react-core";
|
|
2
2
|
import React, { FC, useCallback, useEffect, useRef, useState } from "react";
|
|
3
|
-
import { Animated, Easing, Keyboard,
|
|
3
|
+
import { Animated, Dimensions, Easing, Keyboard, LayoutChangeEvent, Pressable, StatusBar } from "react-native";
|
|
4
4
|
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
5
5
|
import { BackDropView, CloseBar, StyledPressableBackDrop } from "./styled";
|
|
6
6
|
import { IBaseModal } from "./types";
|
|
@@ -16,18 +16,30 @@ export const ModalView: FC<IBaseModal> = ({
|
|
|
16
16
|
BoxComponent = BoxContent,
|
|
17
17
|
frozen,
|
|
18
18
|
isLastShown,
|
|
19
|
+
showCloseBar = true,
|
|
19
20
|
close,
|
|
20
21
|
onClose
|
|
21
22
|
}) => {
|
|
22
23
|
|
|
23
24
|
const { bottom } = useSafeAreaInsets()
|
|
24
25
|
const [ ready, setReady ] = useState(false)
|
|
25
|
-
const [ keyboardOpened, setKeyboardOpened ] = useState(
|
|
26
|
+
const [ keyboardOpened, setKeyboardOpened ] = useState(0)
|
|
26
27
|
const [ boxHeight, setBoxHeight ] = useState(0)
|
|
27
28
|
const backgroundCarrier = useRef(new Animated.Value(0)).current
|
|
28
29
|
const translationCarrier = useRef(new Animated.Value(0)).current
|
|
29
30
|
const opacityCarrier = useRef(new Animated.Value(0)).current
|
|
30
|
-
const offset = isLastShown && keyboardOpened ? 0 : bottom
|
|
31
|
+
const offset = isLastShown && keyboardOpened > 0 ? 0 : bottom
|
|
32
|
+
|
|
33
|
+
const getKeyboardHeight = (keyboard: number) => {
|
|
34
|
+
if (keyboard === 0) return 0
|
|
35
|
+
|
|
36
|
+
let wHeight = Math.ceil(Dimensions.get('window').height)
|
|
37
|
+
let sHeight = Math.ceil(Dimensions.get('screen').height)
|
|
38
|
+
if (wHeight !== sHeight) {
|
|
39
|
+
return keyboard + (sHeight - wHeight - (StatusBar.currentHeight || 0))
|
|
40
|
+
}
|
|
41
|
+
return keyboard
|
|
42
|
+
}
|
|
31
43
|
|
|
32
44
|
const show = useCallback(() => {
|
|
33
45
|
Animated.sequence([
|
|
@@ -100,8 +112,8 @@ export const ModalView: FC<IBaseModal> = ({
|
|
|
100
112
|
}, [ready, visible])
|
|
101
113
|
|
|
102
114
|
useEffect(() => {
|
|
103
|
-
const showEvent = Keyboard.addListener('keyboardDidShow', () => setKeyboardOpened(
|
|
104
|
-
const hideEvent = Keyboard.addListener('keyboardDidHide', () => setKeyboardOpened(
|
|
115
|
+
const showEvent = Keyboard.addListener('keyboardDidShow', (e) => setKeyboardOpened(e.endCoordinates.height))
|
|
116
|
+
const hideEvent = Keyboard.addListener('keyboardDidHide', () => setKeyboardOpened(0))
|
|
105
117
|
return () => {
|
|
106
118
|
showEvent.remove()
|
|
107
119
|
hideEvent.remove()
|
|
@@ -111,16 +123,18 @@ export const ModalView: FC<IBaseModal> = ({
|
|
|
111
123
|
return (
|
|
112
124
|
<StyledPressableBackDrop onPress={!frozen ? close : undefined}>
|
|
113
125
|
<BackDropView style={{ backgroundColor: backgroundInterpolation }}>
|
|
114
|
-
<
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
126
|
+
<Animated.View style={{
|
|
127
|
+
paddingBottom: isLastShown ? getKeyboardHeight(keyboardOpened) : 0,
|
|
128
|
+
opacity: opacityCarrier,
|
|
129
|
+
transform: [{ translateY: translationCarrier }]
|
|
130
|
+
}}>
|
|
131
|
+
<Pressable>
|
|
132
|
+
<BoxComponent onLayout={handleBoxLayoutChanges} style={{ paddingBottom: offset }} variant="bottom">
|
|
133
|
+
{showCloseBar && <CloseBar/>}
|
|
134
|
+
{children}
|
|
135
|
+
</BoxComponent>
|
|
136
|
+
</Pressable>
|
|
137
|
+
</Animated.View>
|
|
124
138
|
</BackDropView>
|
|
125
139
|
</StyledPressableBackDrop>
|
|
126
140
|
)
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { ReactElement, useCallback, useEffect, useState } from "react"
|
|
2
|
+
import { v4 as uuidv4 } from 'uuid'
|
|
3
|
+
import { modalLifecycle } from "./ModalGroupManager"
|
|
4
|
+
import { IBaseModal } from "./ui/types"
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Use this hook to tell the modal lifecycle handler that you want to add
|
|
8
|
+
* a new modal component.
|
|
9
|
+
*
|
|
10
|
+
* @param id
|
|
11
|
+
* @param modal
|
|
12
|
+
* @returns
|
|
13
|
+
*/
|
|
14
|
+
export const useLazyModalManager = () => {
|
|
15
|
+
|
|
16
|
+
const [id] = useState(uuidv4())
|
|
17
|
+
|
|
18
|
+
const requestUpdate = useCallback(() => modalLifecycle.update(), [])
|
|
19
|
+
|
|
20
|
+
const sync = useCallback((modal: ReactElement<IBaseModal>) => {
|
|
21
|
+
modalLifecycle.sync(id, () => modal)
|
|
22
|
+
return null
|
|
23
|
+
}, [id])
|
|
24
|
+
|
|
25
|
+
const show = useCallback(() => {
|
|
26
|
+
modalLifecycle.show(id)
|
|
27
|
+
}, [id])
|
|
28
|
+
|
|
29
|
+
const close = useCallback(() => {
|
|
30
|
+
modalLifecycle.close(id)
|
|
31
|
+
}, [id])
|
|
32
|
+
|
|
33
|
+
useEffect(() => {
|
|
34
|
+
return () => modalLifecycle.destroy(id)
|
|
35
|
+
}, [])
|
|
36
|
+
|
|
37
|
+
return {
|
|
38
|
+
requestUpdate,
|
|
39
|
+
sync,
|
|
40
|
+
show,
|
|
41
|
+
close
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -1,16 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Calendar as CalendarCore,
|
|
3
|
-
CalendarProps,
|
|
4
|
-
SelectionType,
|
|
5
|
-
} from '@tecsinapse/react-core';
|
|
1
|
+
import { Calendar as CalendarCore, CalendarProps, SelectionType } from '@tecsinapse/react-core';
|
|
6
2
|
import React from 'react';
|
|
7
|
-
import { Text } from '../../atoms/Text';
|
|
8
3
|
import { getLocale } from '../../../utils/date';
|
|
4
|
+
import { Text } from '../../atoms/Text';
|
|
9
5
|
|
|
10
6
|
export const Calendar = <T extends SelectionType>({
|
|
11
7
|
locale,
|
|
12
8
|
...rest
|
|
13
|
-
}): JSX.Element => {
|
|
9
|
+
}: CalendarProps<T>): JSX.Element => {
|
|
14
10
|
return (
|
|
15
11
|
<CalendarCore
|
|
16
12
|
{...rest}
|
|
@@ -1,24 +1,47 @@
|
|
|
1
1
|
import {
|
|
2
|
-
DatePicker as DatePickerCore,
|
|
3
|
-
DatePickerProps,
|
|
4
|
-
SelectionType,
|
|
2
|
+
DatePicker as DatePickerCore, DatePickerProps, SelectionType, Value
|
|
5
3
|
} from '@tecsinapse/react-core';
|
|
6
|
-
import React from 'react';
|
|
4
|
+
import React, { FC } from 'react';
|
|
5
|
+
import { getLocale } from '../../../utils/date';
|
|
6
|
+
import { IBaseModal, ModalView, useLazyModalManager } from '../../atoms/Modal';
|
|
7
7
|
import { Text } from '../../atoms/Text';
|
|
8
8
|
import { Calendar } from '../Calendar';
|
|
9
|
-
import {
|
|
9
|
+
import { CalendarBoxContent } from './styled';
|
|
10
|
+
|
|
11
|
+
export type NativeDatePickerProps<T extends SelectionType> = Omit<DatePickerProps<T>, 'CalendarComponent' | 'renderCalendar' | 'requestCloseCalendar' | 'requestShowCalendar'>
|
|
12
|
+
|
|
13
|
+
export const DatePicker = <T extends SelectionType>({ locale, onChange, ...rest }: NativeDatePickerProps<T>): JSX.Element => {
|
|
10
14
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
+
const modal = useLazyModalManager()
|
|
16
|
+
|
|
17
|
+
const handleChange = (value?: Value<T>) => {
|
|
18
|
+
onChange?.(value)
|
|
19
|
+
modal.requestUpdate()
|
|
20
|
+
}
|
|
21
|
+
|
|
15
22
|
return (
|
|
16
23
|
<DatePickerCore
|
|
17
24
|
{...rest}
|
|
18
25
|
TextComponent={Text}
|
|
19
26
|
CalendarComponent={Calendar}
|
|
20
|
-
animationType="slide"
|
|
21
27
|
locale={locale ?? getLocale()}
|
|
28
|
+
onChange={handleChange}
|
|
29
|
+
requestShowCalendar={() => modal.show()}
|
|
30
|
+
requestCloseCalendar={() => modal.close()}
|
|
31
|
+
renderCalendar={(calendar, blur) => modal.sync(
|
|
32
|
+
<NativeModal onClose={blur}>
|
|
33
|
+
{calendar}
|
|
34
|
+
</NativeModal>
|
|
35
|
+
)}
|
|
22
36
|
/>
|
|
23
37
|
);
|
|
38
|
+
|
|
24
39
|
};
|
|
40
|
+
|
|
41
|
+
const NativeModal: FC<IBaseModal> = ({ children, ...others }) => {
|
|
42
|
+
return (
|
|
43
|
+
<ModalView BoxComponent={CalendarBoxContent} {...others}>
|
|
44
|
+
{children}
|
|
45
|
+
</ModalView>
|
|
46
|
+
)
|
|
47
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { DatePicker } from './DatePicker';
|
|
1
|
+
export { DatePicker, NativeDatePickerProps } from './DatePicker';
|
|
@@ -1,23 +1,40 @@
|
|
|
1
1
|
import {
|
|
2
2
|
DateTimePicker as DateTimePickerCore,
|
|
3
|
-
DateTimePickerProps
|
|
3
|
+
DateTimePickerProps
|
|
4
4
|
} from '@tecsinapse/react-core';
|
|
5
5
|
import React, { FC } from 'react';
|
|
6
|
+
import { getLocale } from '../../../utils/date';
|
|
7
|
+
import { IBaseModal, ModalView, useLazyModalManager } from '../../atoms/Modal';
|
|
6
8
|
import { Text } from '../../atoms/Text';
|
|
7
9
|
import { DateTimeSelector } from '../DateTimeSelector';
|
|
8
|
-
import { getLocale } from '../../../utils/date';
|
|
9
10
|
|
|
10
|
-
export
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
export type NativeDateTimePickerProps = Omit<DateTimePickerProps, 'DateTimeSelectorComponent' | 'renderSelector' | 'requestCloseSelector' | 'requestShowSelector'>
|
|
12
|
+
|
|
13
|
+
export const DateTimePicker: FC<NativeDateTimePickerProps> = ({ locale, ...rest }) => {
|
|
14
|
+
|
|
15
|
+
const modal = useLazyModalManager()
|
|
16
|
+
|
|
14
17
|
return (
|
|
15
18
|
<DateTimePickerCore
|
|
16
19
|
{...rest}
|
|
17
20
|
TextComponent={Text}
|
|
18
21
|
DateTimeSelectorComponent={DateTimeSelector}
|
|
19
|
-
animationType="slide"
|
|
20
22
|
locale={locale ?? getLocale()}
|
|
23
|
+
requestShowSelector={() => modal.show()}
|
|
24
|
+
requestCloseSelector={() => modal.close()}
|
|
25
|
+
renderSelector={(selector, blur) => modal.sync(
|
|
26
|
+
<NativeModal onClose={blur}>
|
|
27
|
+
{selector}
|
|
28
|
+
</NativeModal>
|
|
29
|
+
)}
|
|
21
30
|
/>
|
|
22
31
|
);
|
|
23
32
|
};
|
|
33
|
+
|
|
34
|
+
const NativeModal: FC<IBaseModal> = ({ children, ...others }) => {
|
|
35
|
+
return (
|
|
36
|
+
<ModalView {...others}>
|
|
37
|
+
{children}
|
|
38
|
+
</ModalView>
|
|
39
|
+
)
|
|
40
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { DateTimePicker } from './DateTimePicker';
|
|
1
|
+
export { DateTimePicker, NativeDateTimePickerProps } from './DateTimePicker';
|
|
@@ -1,23 +1,16 @@
|
|
|
1
|
+
import { Checkbox, getStatusBarHeight, RadioButton, useDebouncedState } from '@tecsinapse/react-core';
|
|
1
2
|
import * as React from 'react';
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
StyledModal,
|
|
9
|
-
} from './styled';
|
|
10
|
-
import { FlatList, Modal as RNModal, ModalProps, View } from 'react-native';
|
|
3
|
+
import { FlatList, StatusBar, View } from 'react-native';
|
|
4
|
+
import { Button } from '../../atoms/Button';
|
|
5
|
+
import { Header } from '../../atoms/Header';
|
|
6
|
+
import { Input } from '../../atoms/Input';
|
|
7
|
+
import { IBaseModal, ModalView } from '../../atoms/Modal';
|
|
8
|
+
import { Text } from '../../atoms/Text';
|
|
11
9
|
import { SelectNativeProps } from './Select';
|
|
12
|
-
import { Text } from '../Text';
|
|
13
10
|
import {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
useDebouncedState,
|
|
18
|
-
} from '@tecsinapse/react-core';
|
|
19
|
-
import { Input } from '../Input';
|
|
20
|
-
import { Header } from '../Header';
|
|
11
|
+
FetchIndicator, getStyledModal, ListItem, ModalFooter, SearchBarContainer,
|
|
12
|
+
SelectIcon
|
|
13
|
+
} from './styled';
|
|
21
14
|
|
|
22
15
|
interface LoadingProps {
|
|
23
16
|
loading?: boolean;
|
|
@@ -35,15 +28,18 @@ const Component = <Data, Type extends 'single' | 'multi'>({
|
|
|
35
28
|
value,
|
|
36
29
|
onSelect,
|
|
37
30
|
onSearch,
|
|
38
|
-
onRequestClose,
|
|
39
31
|
selectModalTitle,
|
|
40
32
|
selectModalTitleComponent,
|
|
41
33
|
confirmButtonText,
|
|
42
34
|
loading,
|
|
43
|
-
|
|
44
|
-
|
|
35
|
+
close,
|
|
36
|
+
closeOnPick,
|
|
37
|
+
...others
|
|
38
|
+
}: SelectNativeProps<Data, Type> & LoadingProps & IBaseModal): JSX.Element => {
|
|
45
39
|
const [selectedValues, setSelectedValues] = React.useState<Data[]>([]);
|
|
46
40
|
const [searchArg, setSearchArg] = useDebouncedState<string>('', onSearch);
|
|
41
|
+
const ModalComponent = React.useMemo(() => getStyledModal(getStatusBarHeight(true)), [])
|
|
42
|
+
const _closeOnPick = closeOnPick && type === 'single'
|
|
47
43
|
|
|
48
44
|
// Resets the temporary state to the initial state whenever the
|
|
49
45
|
// modal is reopened or the value changes
|
|
@@ -87,13 +83,19 @@ const Component = <Data, Type extends 'single' | 'multi'>({
|
|
|
87
83
|
});
|
|
88
84
|
};
|
|
89
85
|
|
|
86
|
+
React.useEffect(() => {
|
|
87
|
+
if (_closeOnPick && selectedValues[0] && (selectedValues[0] !== value)) {
|
|
88
|
+
handleConfirm()
|
|
89
|
+
}
|
|
90
|
+
}, [selectedValues[0], value, closeOnPick])
|
|
91
|
+
|
|
90
92
|
const handleConfirm = () => {
|
|
91
93
|
// TS Workaround since TS won't infer the ternary operator's result type correctly
|
|
92
94
|
type OnSelectArg = Parameters<typeof onSelect>[0];
|
|
93
95
|
onSelect(
|
|
94
96
|
(type === 'single' ? selectedValues[0] : selectedValues) as OnSelectArg
|
|
95
97
|
);
|
|
96
|
-
|
|
98
|
+
close?.()
|
|
97
99
|
};
|
|
98
100
|
|
|
99
101
|
const headerContent = selectModalTitleComponent ? (
|
|
@@ -105,16 +107,10 @@ const Component = <Data, Type extends 'single' | 'multi'>({
|
|
|
105
107
|
) : null;
|
|
106
108
|
|
|
107
109
|
return (
|
|
108
|
-
<
|
|
109
|
-
transparent
|
|
110
|
-
hardwareAccelerated
|
|
111
|
-
{...modalProps}
|
|
112
|
-
onRequestClose={onRequestClose}
|
|
113
|
-
>
|
|
114
|
-
<StyledModal>
|
|
110
|
+
<ModalView {...others} BoxComponent={ModalComponent} showCloseBar={false}>
|
|
115
111
|
<Header
|
|
116
112
|
rightButton={{
|
|
117
|
-
onPress:
|
|
113
|
+
onPress: close,
|
|
118
114
|
icon: {
|
|
119
115
|
name: 'close',
|
|
120
116
|
type: 'material-community',
|
|
@@ -124,6 +120,7 @@ const Component = <Data, Type extends 'single' | 'multi'>({
|
|
|
124
120
|
>
|
|
125
121
|
{headerContent}
|
|
126
122
|
</Header>
|
|
123
|
+
|
|
127
124
|
{!hideSearchBar && (
|
|
128
125
|
<SearchBarContainer>
|
|
129
126
|
<Input
|
|
@@ -136,9 +133,11 @@ const Component = <Data, Type extends 'single' | 'multi'>({
|
|
|
136
133
|
/>
|
|
137
134
|
</SearchBarContainer>
|
|
138
135
|
)}
|
|
136
|
+
|
|
139
137
|
{loading && (
|
|
140
138
|
<FetchIndicator animating={true} color={'grey'} size={'large'} />
|
|
141
139
|
)}
|
|
140
|
+
|
|
142
141
|
<FlatList
|
|
143
142
|
data={data}
|
|
144
143
|
keyExtractor={keyExtractor}
|
|
@@ -171,7 +170,8 @@ const Component = <Data, Type extends 'single' | 'multi'>({
|
|
|
171
170
|
</ListItem>
|
|
172
171
|
)}
|
|
173
172
|
/>
|
|
174
|
-
|
|
173
|
+
|
|
174
|
+
{ !_closeOnPick && <ModalFooter>
|
|
175
175
|
<Button
|
|
176
176
|
variant={'filled'}
|
|
177
177
|
color={'primary'}
|
|
@@ -182,9 +182,8 @@ const Component = <Data, Type extends 'single' | 'multi'>({
|
|
|
182
182
|
{confirmButtonText}
|
|
183
183
|
</Text>
|
|
184
184
|
</Button>
|
|
185
|
-
</ModalFooter>
|
|
186
|
-
|
|
187
|
-
</RNModal>
|
|
185
|
+
</ModalFooter>}
|
|
186
|
+
</ModalView>
|
|
188
187
|
);
|
|
189
188
|
};
|
|
190
189
|
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import * as React from 'react';
|
|
2
1
|
import {
|
|
3
|
-
InputContainerProps,
|
|
4
|
-
useInputFocus
|
|
5
|
-
HintInputContainer,
|
|
2
|
+
HintInputContainer, InputContainerProps,
|
|
3
|
+
useInputFocus
|
|
6
4
|
} from '@tecsinapse/react-core';
|
|
7
|
-
import
|
|
5
|
+
import * as React from 'react';
|
|
6
|
+
import { useEffect, useState } from 'react';
|
|
7
|
+
import { useLazyModalManager } from '../../atoms/Modal';
|
|
8
|
+
import { Text } from '../../atoms/Text';
|
|
8
9
|
import { Modal } from './Modal';
|
|
9
10
|
import { SelectIcon, StyledSelectionText } from './styled';
|
|
10
|
-
import { useEffect, useState } from 'react';
|
|
11
11
|
|
|
12
12
|
export interface SelectNativeProps<Data, Type extends 'single' | 'multi'>
|
|
13
13
|
extends Omit<InputContainerProps, 'value' | 'onChange' | 'onChangeText'> {
|
|
@@ -34,6 +34,7 @@ export interface SelectNativeProps<Data, Type extends 'single' | 'multi'>
|
|
|
34
34
|
confirmButtonText?: string;
|
|
35
35
|
selectModalTitle?: string;
|
|
36
36
|
selectModalTitleComponent?: JSX.Element;
|
|
37
|
+
closeOnPick?: boolean;
|
|
37
38
|
}
|
|
38
39
|
|
|
39
40
|
function Select<Data, Type extends 'single' | 'multi'>({
|
|
@@ -60,6 +61,7 @@ function Select<Data, Type extends 'single' | 'multi'>({
|
|
|
60
61
|
hintComponent,
|
|
61
62
|
hint,
|
|
62
63
|
style,
|
|
64
|
+
closeOnPick = type === 'single',
|
|
63
65
|
...rest
|
|
64
66
|
}: SelectNativeProps<Data, Type>): JSX.Element {
|
|
65
67
|
const { focused, handleBlur, handleFocus } = useInputFocus(
|
|
@@ -68,8 +70,8 @@ function Select<Data, Type extends 'single' | 'multi'>({
|
|
|
68
70
|
!disabled
|
|
69
71
|
);
|
|
70
72
|
|
|
71
|
-
const [modalVisible, setModalVisible] = React.useState(false);
|
|
72
73
|
const [selectOptions, setSelectOptions] = useState<Data[]>([]);
|
|
74
|
+
const modal = useLazyModalManager()
|
|
73
75
|
|
|
74
76
|
// TODO: Add Skeleton to modal height when loading is true
|
|
75
77
|
const [loading, setLoading] = useState<boolean>(false);
|
|
@@ -145,6 +147,7 @@ function Select<Data, Type extends 'single' | 'multi'>({
|
|
|
145
147
|
} catch (e) {
|
|
146
148
|
// TODO: Catch error
|
|
147
149
|
} finally {
|
|
150
|
+
modal.requestUpdate()
|
|
148
151
|
setLoading(false);
|
|
149
152
|
}
|
|
150
153
|
}
|
|
@@ -152,17 +155,6 @@ function Select<Data, Type extends 'single' | 'multi'>({
|
|
|
152
155
|
[options, value, keyExtractor]
|
|
153
156
|
);
|
|
154
157
|
|
|
155
|
-
const handlePressInput = async () => {
|
|
156
|
-
setModalVisible(true);
|
|
157
|
-
handleFocus();
|
|
158
|
-
await handleLazyFocus();
|
|
159
|
-
};
|
|
160
|
-
|
|
161
|
-
const handleCloseModal = () => {
|
|
162
|
-
setModalVisible(false);
|
|
163
|
-
handleBlur();
|
|
164
|
-
};
|
|
165
|
-
|
|
166
158
|
const getDisplayValue = () => {
|
|
167
159
|
if (Array.isArray(value)) {
|
|
168
160
|
if (value.length === 0) return placeholder;
|
|
@@ -189,6 +181,34 @@ function Select<Data, Type extends 'single' | 'multi'>({
|
|
|
189
181
|
}
|
|
190
182
|
};
|
|
191
183
|
|
|
184
|
+
modal.sync(
|
|
185
|
+
<Modal
|
|
186
|
+
options={selectOptions || []}
|
|
187
|
+
focused={true}
|
|
188
|
+
keyExtractor={keyExtractor}
|
|
189
|
+
labelExtractor={labelExtractor}
|
|
190
|
+
groupKeyExtractor={groupKeyExtractor}
|
|
191
|
+
searchBarPlaceholder={searchBarPlaceholder}
|
|
192
|
+
type={type}
|
|
193
|
+
onSelect={onSelect}
|
|
194
|
+
value={value}
|
|
195
|
+
hideSearchBar={hideSearchBar}
|
|
196
|
+
onSearch={handleOnSearch}
|
|
197
|
+
selectModalTitle={selectModalTitle}
|
|
198
|
+
selectModalTitleComponent={selectModalTitleComponent}
|
|
199
|
+
confirmButtonText={confirmButtonText}
|
|
200
|
+
loading={loading}
|
|
201
|
+
onClose={handleBlur}
|
|
202
|
+
closeOnPick={closeOnPick}
|
|
203
|
+
/>
|
|
204
|
+
)
|
|
205
|
+
|
|
206
|
+
const handlePressInput = async () => {
|
|
207
|
+
modal.show()
|
|
208
|
+
handleFocus();
|
|
209
|
+
await handleLazyFocus();
|
|
210
|
+
};
|
|
211
|
+
|
|
192
212
|
return (
|
|
193
213
|
<>
|
|
194
214
|
<HintInputContainer
|
|
@@ -212,27 +232,6 @@ function Select<Data, Type extends 'single' | 'multi'>({
|
|
|
212
232
|
{getDisplayValue() || ' '}
|
|
213
233
|
</StyledSelectionText>
|
|
214
234
|
</HintInputContainer>
|
|
215
|
-
<Modal
|
|
216
|
-
visible={modalVisible}
|
|
217
|
-
options={selectOptions || []}
|
|
218
|
-
focused={modalVisible}
|
|
219
|
-
keyExtractor={keyExtractor}
|
|
220
|
-
labelExtractor={labelExtractor}
|
|
221
|
-
groupKeyExtractor={groupKeyExtractor}
|
|
222
|
-
searchBarPlaceholder={searchBarPlaceholder}
|
|
223
|
-
type={type}
|
|
224
|
-
onSelect={onSelect}
|
|
225
|
-
value={value}
|
|
226
|
-
hideSearchBar={hideSearchBar}
|
|
227
|
-
onRequestClose={handleCloseModal}
|
|
228
|
-
animated
|
|
229
|
-
animationType={'slide'}
|
|
230
|
-
onSearch={handleOnSearch}
|
|
231
|
-
selectModalTitle={selectModalTitle}
|
|
232
|
-
selectModalTitleComponent={selectModalTitleComponent}
|
|
233
|
-
confirmButtonText={confirmButtonText}
|
|
234
|
-
loading={loading}
|
|
235
|
-
/>
|
|
236
235
|
</>
|
|
237
236
|
);
|
|
238
237
|
}
|
|
File without changes
|
|
@@ -7,19 +7,21 @@ import {
|
|
|
7
7
|
InputContainerProps,
|
|
8
8
|
PressableSurface,
|
|
9
9
|
PressableSurfaceProps,
|
|
10
|
+
RFValue,
|
|
10
11
|
RFValueStr,
|
|
11
12
|
StyleProps
|
|
12
13
|
} from '@tecsinapse/react-core';
|
|
13
14
|
import { ActivityIndicator, ModalProps, View, ViewProps } from 'react-native';
|
|
14
|
-
import { Input, InputNativeProps } from '
|
|
15
|
-
import { Text } from '
|
|
15
|
+
import { Input, InputNativeProps } from '../../atoms/Input';
|
|
16
|
+
import { Text } from '../../atoms/Text';
|
|
16
17
|
|
|
17
|
-
export const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
18
|
+
export const getStyledModal = (safeTop: number = 0) => {
|
|
19
|
+
return styled(View)<ModalProps & Partial<StyleProps>>`
|
|
20
|
+
padding-top: ${`${RFValue(safeTop)}px`};
|
|
21
|
+
background-color: ${({ theme }) => theme.miscellaneous.bodyColor};
|
|
22
|
+
height: 100%;
|
|
23
|
+
`
|
|
24
|
+
}
|
|
23
25
|
|
|
24
26
|
export const StyledSelectionText = styled(Text)(
|
|
25
27
|
(props: Partial<InputContainerProps> & Partial<StyleProps>) => css`
|
package/src/index.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export * from '@tecsinapse/react-core';
|
|
2
2
|
export { Header, HeaderProps } from './components/atoms/Header';
|
|
3
|
-
export { Select, SelectNativeProps } from './components/
|
|
3
|
+
export { Select, SelectNativeProps } from './components/molecules/Select';
|
|
4
4
|
export { Input, InputNativeProps } from './components/atoms/Input';
|
|
5
5
|
export { TextArea, TextAreaProps } from './components/atoms/TextArea';
|
|
6
6
|
export { Text, TextNativeProps } from './components/atoms/Text';
|
|
@@ -21,9 +21,9 @@ export {
|
|
|
21
21
|
} from './components/atoms/SnappingSlider';
|
|
22
22
|
export { Badge, BadgeNativeProps } from './components/atoms/Badge';
|
|
23
23
|
export { Snackbar, SnackbarNativeProps } from './components/molecules/Snackbar';
|
|
24
|
-
export { DatePicker } from './components/molecules/DatePicker';
|
|
25
|
-
export { DateTimePicker } from './components/molecules/DateTimePicker';
|
|
24
|
+
export { DatePicker, NativeDatePickerProps } from './components/molecules/DatePicker';
|
|
25
|
+
export { DateTimePicker, NativeDateTimePickerProps } from './components/molecules/DateTimePicker';
|
|
26
26
|
export { Avatar } from './components/atoms/Avatar';
|
|
27
27
|
export { Calendar } from './components/molecules/Calendar';
|
|
28
28
|
export { DateTimeSelector } from './components/molecules/DateTimeSelector';
|
|
29
|
-
export { ModalGroupManager, ModalView, ModalLifecycleHandler, useModalManager, IBaseModal } from './components/atoms/Modal';
|
|
29
|
+
export { ModalGroupManager, ModalView, ModalLifecycleHandler, useLazyModalManager, useModalManager, IBaseModal } from './components/atoms/Modal';
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { ModalProps } from 'react-native';
|
|
2
|
-
import { SelectNativeProps } from './Select';
|
|
3
|
-
interface LoadingProps {
|
|
4
|
-
loading?: boolean;
|
|
5
|
-
}
|
|
6
|
-
export declare const Modal: <Data, Type extends "single" | "multi">({ options, keyExtractor, labelExtractor, groupKeyExtractor, hideSearchBar, searchBarPlaceholder, focused, type, value, onSelect, onSearch, onRequestClose, selectModalTitle, selectModalTitleComponent, confirmButtonText, loading, ...modalProps }: SelectNativeProps<Data, Type> & import("react-native").ModalBaseProps & import("react-native").ModalPropsIOS & import("react-native").ModalPropsAndroid & import("react-native").ViewProps & LoadingProps) => JSX.Element;
|
|
7
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/components/atoms/Select/Modal.tsx"],"names":["Component","options","keyExtractor","labelExtractor","groupKeyExtractor","hideSearchBar","searchBarPlaceholder","focused","type","value","onSelect","onSearch","onRequestClose","selectModalTitle","selectModalTitleComponent","confirmButtonText","loading","modalProps","selectedValues","setSelectedValues","React","useState","searchArg","setSearchArg","useEffect","getData","map","option","index","_checked","find","data","handlePressItem","newArr","found","push","handleConfirm","headerContent","onPress","icon","name","fontColor","text","item","Modal"],"mappings":"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","sourcesContent":["import * as React from 'react';\nimport {\n FetchIndicator,\n ModalFooter,\n ListItem,\n SearchBarContainer,\n SelectIcon,\n StyledModal,\n} from './styled';\nimport { FlatList, Modal as RNModal, ModalProps, View } from 'react-native';\nimport { SelectNativeProps } from './Select';\nimport { Text } from '../Text';\nimport {\n Button,\n Checkbox,\n RadioButton,\n useDebouncedState,\n} from '@tecsinapse/react-core';\nimport { Input } from '../Input';\nimport { Header } from '../Header';\n\ninterface LoadingProps {\n loading?: boolean;\n}\n\nconst Component = <Data, Type extends 'single' | 'multi'>({\n options,\n keyExtractor,\n labelExtractor,\n groupKeyExtractor,\n hideSearchBar,\n searchBarPlaceholder,\n focused,\n type,\n value,\n onSelect,\n onSearch,\n onRequestClose,\n selectModalTitle,\n selectModalTitleComponent,\n confirmButtonText,\n loading,\n ...modalProps\n}: SelectNativeProps<Data, Type> & ModalProps & LoadingProps): JSX.Element => {\n const [selectedValues, setSelectedValues] = React.useState<Data[]>([]);\n const [searchArg, setSearchArg] = useDebouncedState<string>('', onSearch);\n\n // Resets the temporary state to the initial state whenever the\n // modal is reopened or the value changes\n React.useEffect(() => {\n setSelectedValues(\n (value ? (type === 'multi' ? value : [value]) : []) as Data[]\n );\n }, [value, focused, setSelectedValues]);\n\n const getData = (options: Data[]) => {\n return options?.map((option, index) => ({\n ...option,\n _checked:\n type === 'multi'\n ? !!selectedValues.find(\n value => keyExtractor(option, index) == keyExtractor(value, index)\n )\n : keyExtractor((selectedValues[0] || {}) as Data, index) ==\n keyExtractor(option, index),\n }));\n };\n\n const data = typeof options !== 'function' ? getData(options) : [];\n\n const handlePressItem = (option: Data) => () => {\n setSelectedValues(selectedValues => {\n if (type === 'multi') {\n const newArr: Data[] = [];\n let found = false;\n for (const value of selectedValues) {\n if (keyExtractor(value) != keyExtractor(option)) newArr.push(value);\n else found = true;\n }\n if (!found) newArr.push(option);\n return newArr;\n }\n return keyExtractor((selectedValues[0] || {}) as Data) ===\n keyExtractor(option)\n ? []\n : [option];\n });\n };\n\n const handleConfirm = () => {\n // TS Workaround since TS won't infer the ternary operator's result type correctly\n type OnSelectArg = Parameters<typeof onSelect>[0];\n onSelect(\n (type === 'single' ? selectedValues[0] : selectedValues) as OnSelectArg\n );\n onRequestClose && onRequestClose();\n };\n\n const headerContent = selectModalTitleComponent ? (\n selectModalTitleComponent\n ) : selectModalTitle ? (\n <Text typography=\"h4\" fontWeight=\"bold\">\n {selectModalTitle}\n </Text>\n ) : null;\n\n return (\n <RNModal\n transparent\n hardwareAccelerated\n {...modalProps}\n onRequestClose={onRequestClose}\n >\n <StyledModal>\n <Header\n rightButton={{\n onPress: onRequestClose,\n icon: {\n name: 'close',\n type: 'material-community',\n fontColor: 'light',\n },\n }}\n >\n {headerContent}\n </Header>\n {!hideSearchBar && (\n <SearchBarContainer>\n <Input\n placeholder={searchBarPlaceholder}\n value={searchArg}\n onChange={text => setSearchArg(text)}\n leftComponent={\n <SelectIcon name=\"search\" type=\"ionicon\" size=\"centi\" />\n }\n />\n </SearchBarContainer>\n )}\n {loading && (\n <FetchIndicator animating={true} color={'grey'} size={'large'} />\n )}\n <FlatList\n data={data}\n keyExtractor={keyExtractor}\n fadingEdgeLength={200}\n renderItem={({ item }) => (\n <ListItem onPress={handlePressItem(item)}>\n <View pointerEvents={'none'}>\n {type === 'multi' ? (\n <Checkbox\n color={'primary'}\n labelPosition={'right'}\n checked={item._checked}\n >\n <Text fontWeight={item._checked ? 'bold' : 'regular'}>\n {labelExtractor(item)}\n </Text>\n </Checkbox>\n ) : (\n <RadioButton\n color={'primary'}\n labelPosition={'right'}\n checked={item._checked}\n >\n <Text fontWeight={item._checked ? 'bold' : 'regular'}>\n {labelExtractor(item)}\n </Text>\n </RadioButton>\n )}\n </View>\n </ListItem>\n )}\n />\n <ModalFooter>\n <Button\n variant={'filled'}\n color={'primary'}\n onPress={handleConfirm}\n disabled={loading}\n >\n <Text fontColor={'light'} fontWeight=\"bold\">\n {confirmButtonText}\n </Text>\n </Button>\n </ModalFooter>\n </StyledModal>\n </RNModal>\n );\n};\n\nexport const Modal = Component;\n"],"file":"Modal.js"}
|