@shaquillehinds/react-native-dropdown-selector 0.0.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/LICENSE +20 -0
- package/README.md +526 -0
- package/lib/commonjs/DropDownSelector/DropDownSelector.controller.js +129 -0
- package/lib/commonjs/DropDownSelector/DropDownSelector.controller.js.map +1 -0
- package/lib/commonjs/DropDownSelector/DropDownSelector.js +136 -0
- package/lib/commonjs/DropDownSelector/DropDownSelector.js.map +1 -0
- package/lib/commonjs/DropDownSelector/DropDownSelector.types.js +6 -0
- package/lib/commonjs/DropDownSelector/DropDownSelector.types.js.map +1 -0
- package/lib/commonjs/DropDownSelector/index.js +28 -0
- package/lib/commonjs/DropDownSelector/index.js.map +1 -0
- package/lib/commonjs/DropDownSelector/svgs/ChevronUp.js +26 -0
- package/lib/commonjs/DropDownSelector/svgs/ChevronUp.js.map +1 -0
- package/lib/commonjs/index.js +21 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/package.json +1 -0
- package/lib/module/DropDownSelector/DropDownSelector.controller.js +125 -0
- package/lib/module/DropDownSelector/DropDownSelector.controller.js.map +1 -0
- package/lib/module/DropDownSelector/DropDownSelector.js +132 -0
- package/lib/module/DropDownSelector/DropDownSelector.js.map +1 -0
- package/lib/module/DropDownSelector/DropDownSelector.types.js +4 -0
- package/lib/module/DropDownSelector/DropDownSelector.types.js.map +1 -0
- package/lib/module/DropDownSelector/index.js +5 -0
- package/lib/module/DropDownSelector/index.js.map +1 -0
- package/lib/module/DropDownSelector/svgs/ChevronUp.js +21 -0
- package/lib/module/DropDownSelector/svgs/ChevronUp.js.map +1 -0
- package/lib/module/index.js +6 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/typescript/commonjs/package.json +1 -0
- package/lib/typescript/commonjs/src/DropDownSelector/DropDownSelector.controller.d.ts +28 -0
- package/lib/typescript/commonjs/src/DropDownSelector/DropDownSelector.controller.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/DropDownSelector/DropDownSelector.d.ts +3 -0
- package/lib/typescript/commonjs/src/DropDownSelector/DropDownSelector.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/DropDownSelector/DropDownSelector.types.d.ts +45 -0
- package/lib/typescript/commonjs/src/DropDownSelector/DropDownSelector.types.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/DropDownSelector/index.d.ts +3 -0
- package/lib/typescript/commonjs/src/DropDownSelector/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/DropDownSelector/svgs/ChevronUp.d.ts +5 -0
- package/lib/typescript/commonjs/src/DropDownSelector/svgs/ChevronUp.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/index.d.ts +4 -0
- package/lib/typescript/commonjs/src/index.d.ts.map +1 -0
- package/lib/typescript/module/package.json +1 -0
- package/lib/typescript/module/src/DropDownSelector/DropDownSelector.controller.d.ts +28 -0
- package/lib/typescript/module/src/DropDownSelector/DropDownSelector.controller.d.ts.map +1 -0
- package/lib/typescript/module/src/DropDownSelector/DropDownSelector.d.ts +3 -0
- package/lib/typescript/module/src/DropDownSelector/DropDownSelector.d.ts.map +1 -0
- package/lib/typescript/module/src/DropDownSelector/DropDownSelector.types.d.ts +45 -0
- package/lib/typescript/module/src/DropDownSelector/DropDownSelector.types.d.ts.map +1 -0
- package/lib/typescript/module/src/DropDownSelector/index.d.ts +3 -0
- package/lib/typescript/module/src/DropDownSelector/index.d.ts.map +1 -0
- package/lib/typescript/module/src/DropDownSelector/svgs/ChevronUp.d.ts +5 -0
- package/lib/typescript/module/src/DropDownSelector/svgs/ChevronUp.d.ts.map +1 -0
- package/lib/typescript/module/src/index.d.ts +4 -0
- package/lib/typescript/module/src/index.d.ts.map +1 -0
- package/package.json +203 -0
- package/src/DropDownSelector/DropDownSelector.controller.tsx +174 -0
- package/src/DropDownSelector/DropDownSelector.tsx +183 -0
- package/src/DropDownSelector/DropDownSelector.types.ts +44 -0
- package/src/DropDownSelector/index.ts +2 -0
- package/src/DropDownSelector/svgs/ChevronUp.tsx +18 -0
- package/src/index.tsx +4 -0
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AnimateComponent,
|
|
3
|
+
BaseText,
|
|
4
|
+
isAndroid,
|
|
5
|
+
Layout,
|
|
6
|
+
RNPressableLayout,
|
|
7
|
+
shadowStyles,
|
|
8
|
+
maxZIndex,
|
|
9
|
+
TouchableLayout,
|
|
10
|
+
ComponentMounter,
|
|
11
|
+
ModalForegroundWrapper,
|
|
12
|
+
ModalWrapper,
|
|
13
|
+
RadioIcon,
|
|
14
|
+
} from '@shaquillehinds/react-native-essentials';
|
|
15
|
+
import { ChevronUp } from './svgs/ChevronUp';
|
|
16
|
+
import { View } from 'react-native';
|
|
17
|
+
import { ScrollView } from 'react-native-gesture-handler';
|
|
18
|
+
import { DropDownSelectorController } from './DropDownSelector.controller';
|
|
19
|
+
import type { DropDownSelectorProps } from './DropDownSelector.types';
|
|
20
|
+
|
|
21
|
+
export function DropDownSelector<T>(props: DropDownSelectorProps<T>) {
|
|
22
|
+
const controller = DropDownSelectorController(props);
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<Layout
|
|
26
|
+
{...props.containerProps}
|
|
27
|
+
style={[{ zIndex: maxZIndex }, props.containerProps?.style]}
|
|
28
|
+
onLayout={controller.handleLayout}
|
|
29
|
+
>
|
|
30
|
+
<ComponentMounter
|
|
31
|
+
showComponent={controller.showItems}
|
|
32
|
+
setShowComponent={controller.setShowItems}
|
|
33
|
+
unMountDelayInMilliSeconds={controller.unMountDelayInMilliSeconds}
|
|
34
|
+
onComponentShow={props.onOpen}
|
|
35
|
+
onComponentClose={props.onClose}
|
|
36
|
+
component={
|
|
37
|
+
<ModalWrapper enableBackgroundContentPress>
|
|
38
|
+
<ModalForegroundWrapper>
|
|
39
|
+
<View
|
|
40
|
+
style={
|
|
41
|
+
!props.disableShadow
|
|
42
|
+
? { ...shadowStyles({ shadowOpacity: 0.15 }) }
|
|
43
|
+
: undefined
|
|
44
|
+
}
|
|
45
|
+
>
|
|
46
|
+
{!props.disableShadow && isAndroid && (
|
|
47
|
+
<AnimateComponent
|
|
48
|
+
ref={controller.animateAndroidShadowRef}
|
|
49
|
+
initialPosition={0}
|
|
50
|
+
style={controller.androidShadowAnimatedStyle}
|
|
51
|
+
autoStart
|
|
52
|
+
toPosition={controller.androidShadowAnimationConfig}
|
|
53
|
+
/>
|
|
54
|
+
)}
|
|
55
|
+
|
|
56
|
+
<ScrollView
|
|
57
|
+
ref={controller.scrollViewRef}
|
|
58
|
+
nestedScrollEnabled
|
|
59
|
+
showsVerticalScrollIndicator={false}
|
|
60
|
+
overScrollMode="never"
|
|
61
|
+
{...props.dropdownScrollViewProps}
|
|
62
|
+
style={[
|
|
63
|
+
controller.scrollViewStyle,
|
|
64
|
+
props.dropdownScrollViewProps?.style,
|
|
65
|
+
]}
|
|
66
|
+
>
|
|
67
|
+
<AnimateComponent
|
|
68
|
+
ref={controller.animateComponentRef}
|
|
69
|
+
style={controller.selectionItemsListAnimatedStyle}
|
|
70
|
+
initialPosition={
|
|
71
|
+
controller.canRenderDown
|
|
72
|
+
? -controller.relativeY(110)
|
|
73
|
+
: controller.relativeY(110)
|
|
74
|
+
}
|
|
75
|
+
autoStart
|
|
76
|
+
toPosition={
|
|
77
|
+
props.expandAnimationConfig
|
|
78
|
+
? { ...props.expandAnimationConfig, toValue: 0 }
|
|
79
|
+
: controller.selectionItemsListAnimationConfig
|
|
80
|
+
}
|
|
81
|
+
>
|
|
82
|
+
<Layout
|
|
83
|
+
borderRadius="soft"
|
|
84
|
+
backgroundColor={'#FAFAFA'}
|
|
85
|
+
padding={
|
|
86
|
+
controller.canRenderDown ? [5, 0, 0, 0] : [0, 0, 5, 0]
|
|
87
|
+
}
|
|
88
|
+
{...props.dropdownContentContainerProps}
|
|
89
|
+
>
|
|
90
|
+
{props.items.map((item) =>
|
|
91
|
+
props.DropdownItemComponent ? (
|
|
92
|
+
<props.DropdownItemComponent
|
|
93
|
+
key={item.label}
|
|
94
|
+
item={item}
|
|
95
|
+
isSelected={item.value === props.selectedItem}
|
|
96
|
+
/>
|
|
97
|
+
) : (
|
|
98
|
+
<TouchableLayout
|
|
99
|
+
key={item.label}
|
|
100
|
+
flexDirection="row"
|
|
101
|
+
center
|
|
102
|
+
spaceBetween
|
|
103
|
+
padding={[1, 5]}
|
|
104
|
+
{...props.dropdownItemProps}
|
|
105
|
+
onPress={() => {
|
|
106
|
+
props.onSelect(item.value);
|
|
107
|
+
controller.setShowItems(false);
|
|
108
|
+
props.onDropdownItemPress?.(item);
|
|
109
|
+
}}
|
|
110
|
+
>
|
|
111
|
+
<Layout width={'85%'}>
|
|
112
|
+
<BaseText
|
|
113
|
+
numberOfLines={1}
|
|
114
|
+
{...props.dropdownItemTextProps}
|
|
115
|
+
>
|
|
116
|
+
{item.label}
|
|
117
|
+
</BaseText>
|
|
118
|
+
</Layout>
|
|
119
|
+
{item.value === props.selectedItem ? (
|
|
120
|
+
props.DropdownItemSelectedIcon ? (
|
|
121
|
+
<props.DropdownItemSelectedIcon item={item} />
|
|
122
|
+
) : (
|
|
123
|
+
<RadioIcon isSelected={true} />
|
|
124
|
+
)
|
|
125
|
+
) : null}
|
|
126
|
+
</TouchableLayout>
|
|
127
|
+
)
|
|
128
|
+
)}
|
|
129
|
+
</Layout>
|
|
130
|
+
</AnimateComponent>
|
|
131
|
+
</ScrollView>
|
|
132
|
+
</View>
|
|
133
|
+
</ModalForegroundWrapper>
|
|
134
|
+
</ModalWrapper>
|
|
135
|
+
}
|
|
136
|
+
/>
|
|
137
|
+
<RNPressableLayout
|
|
138
|
+
disabled={props.isDisabled}
|
|
139
|
+
activeOpacity={1}
|
|
140
|
+
flexDirection="row"
|
|
141
|
+
backgroundColor={'white'}
|
|
142
|
+
borderRadius="medium"
|
|
143
|
+
padding={[1, 5]}
|
|
144
|
+
spaceBetween
|
|
145
|
+
center
|
|
146
|
+
{...props.dropdownButtonProps}
|
|
147
|
+
style={[
|
|
148
|
+
{
|
|
149
|
+
zIndex: maxZIndex + 3,
|
|
150
|
+
...shadowStyles({ shadowOpacity: 0.1 }),
|
|
151
|
+
},
|
|
152
|
+
props.dropdownButtonProps?.style,
|
|
153
|
+
]}
|
|
154
|
+
onPress={(e) => {
|
|
155
|
+
controller.pageYRef.current = e.nativeEvent.pageY;
|
|
156
|
+
controller.setShowItems((prev) => !prev);
|
|
157
|
+
props.dropdownButtonProps?.onPress?.(e);
|
|
158
|
+
}}
|
|
159
|
+
>
|
|
160
|
+
<BaseText numberOfLines={1} {...props.dropdownButtonTextProps}>
|
|
161
|
+
{controller.label || props.placeholder || 'Select an item'}
|
|
162
|
+
</BaseText>
|
|
163
|
+
{props.DropdownButtonIcon ? (
|
|
164
|
+
<props.DropdownButtonIcon
|
|
165
|
+
isOpen={controller.showItems}
|
|
166
|
+
expandDirection={
|
|
167
|
+
props.expandDirection || controller.canRenderDown ? 'down' : 'up'
|
|
168
|
+
}
|
|
169
|
+
/>
|
|
170
|
+
) : controller.canRenderDown === null ? undefined : (
|
|
171
|
+
<AnimateComponent
|
|
172
|
+
ref={controller.animateChevronRef}
|
|
173
|
+
style={controller.chevronAnimatedStyle}
|
|
174
|
+
initialPosition={controller.canRenderDown ? -1 : 1}
|
|
175
|
+
toPosition={controller.chevronAnimationConfig}
|
|
176
|
+
>
|
|
177
|
+
<ChevronUp color={'black'} />
|
|
178
|
+
</AnimateComponent>
|
|
179
|
+
)}
|
|
180
|
+
</RNPressableLayout>
|
|
181
|
+
</Layout>
|
|
182
|
+
);
|
|
183
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
BaseTextProps,
|
|
3
|
+
LayoutProps,
|
|
4
|
+
RNPressableLayoutProps,
|
|
5
|
+
TouchableLayoutProps,
|
|
6
|
+
} from '@shaquillehinds/react-native-essentials';
|
|
7
|
+
import type { Animated, ScrollViewProps } from 'react-native';
|
|
8
|
+
|
|
9
|
+
export type DropDownItemValue<T> = T;
|
|
10
|
+
|
|
11
|
+
export type DropDownItem<T> = {
|
|
12
|
+
label: string;
|
|
13
|
+
value: DropDownItemValue<T>;
|
|
14
|
+
};
|
|
15
|
+
export type DropDownSelectorProps<T> = {
|
|
16
|
+
items: DropDownItem<T>[];
|
|
17
|
+
selectedItem: T;
|
|
18
|
+
onSelect: (item: T) => void;
|
|
19
|
+
placeholder: string;
|
|
20
|
+
onOpen?: () => void;
|
|
21
|
+
onClose?: () => void;
|
|
22
|
+
unMountDelayInMilliSeconds?: number;
|
|
23
|
+
isDisabled?: boolean;
|
|
24
|
+
disableShadow?: boolean;
|
|
25
|
+
expandDirection?: 'up' | 'down';
|
|
26
|
+
expandDistance?: number;
|
|
27
|
+
expandAnimationConfig?:
|
|
28
|
+
| (Omit<Animated.TimingAnimationConfig, 'toValue'> & { type: 'timing' })
|
|
29
|
+
| (Omit<Animated.SpringAnimationConfig, 'toValue'> & { type: 'spring' });
|
|
30
|
+
containerProps?: LayoutProps;
|
|
31
|
+
dropdownButtonProps?: RNPressableLayoutProps;
|
|
32
|
+
dropdownButtonTextProps?: BaseTextProps;
|
|
33
|
+
//prettier-ignore
|
|
34
|
+
DropdownButtonIcon?: (props: { isOpen: boolean, expandDirection: 'up' | 'down' }) => React.JSX.Element;
|
|
35
|
+
dropdownScrollViewProps?: ScrollViewProps;
|
|
36
|
+
dropdownContentContainerProps?: LayoutProps;
|
|
37
|
+
//prettier-ignore
|
|
38
|
+
DropdownItemComponent?: (props: {item: DropDownItem<T>, isSelected: boolean }) => React.JSX.Element;
|
|
39
|
+
onDropdownItemPress?: (item: DropDownItem<T>) => void;
|
|
40
|
+
dropdownItemProps?: TouchableLayoutProps;
|
|
41
|
+
dropdownItemTextProps?: BaseTextProps;
|
|
42
|
+
//prettier-ignore
|
|
43
|
+
DropdownItemSelectedIcon?: (props: {item: DropDownItem<T>}) => React.JSX.Element;
|
|
44
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { normalize } from '@shaquillehinds/react-native-essentials';
|
|
2
|
+
import Svg, { Path } from 'react-native-svg';
|
|
3
|
+
|
|
4
|
+
export function ChevronUp({ size, color }: { size?: number; color?: string }) {
|
|
5
|
+
return (
|
|
6
|
+
<Svg
|
|
7
|
+
width={normalize(size || 24)}
|
|
8
|
+
height={normalize(size || 24)}
|
|
9
|
+
viewBox="0 0 24 24"
|
|
10
|
+
fill="none"
|
|
11
|
+
>
|
|
12
|
+
<Path
|
|
13
|
+
d="M19.9195 15.8001C19.7295 15.8001 19.5395 15.7301 19.3895 15.5801L12.8695 9.06008C12.3895 8.58008 11.6095 8.58008 11.1295 9.06008L4.60953 15.5801C4.31953 15.8701 3.83953 15.8701 3.54953 15.5801C3.25953 15.2901 3.25953 14.8101 3.54953 14.5201L10.0695 8.00008C11.1295 6.94008 12.8595 6.94008 13.9295 8.00008L20.4495 14.5201C20.7395 14.8101 20.7395 15.2901 20.4495 15.5801C20.2995 15.7201 20.1095 15.8001 19.9195 15.8001Z"
|
|
14
|
+
fill={color || '#292D32'}
|
|
15
|
+
/>
|
|
16
|
+
</Svg>
|
|
17
|
+
);
|
|
18
|
+
}
|
package/src/index.tsx
ADDED