Skip to content

Commit 62708e2

Browse files
committed
feat: change picker to native picker
1 parent af5d9a1 commit 62708e2

12 files changed

Lines changed: 346 additions & 160 deletions

File tree

src/components/Picker/Picker.mdx

Lines changed: 0 additions & 28 deletions
This file was deleted.

src/components/Picker/Picker.tsx

Lines changed: 0 additions & 37 deletions
This file was deleted.

src/components/Picker/PickerField.tsx

Lines changed: 0 additions & 21 deletions
This file was deleted.

src/components/Picker/PickerItem.tsx

Lines changed: 0 additions & 8 deletions
This file was deleted.

src/components/Picker/index.ts

Lines changed: 0 additions & 3 deletions
This file was deleted.
Lines changed: 47 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
1-
import { ViewStyle } from 'react-native';
1+
import { Platform, ViewStyle } from 'react-native';
22

33
import { Theme } from '../../theme/ThemeInterface';
44

5-
export type PickerAppearanceStyles = ViewStyle & {
6-
backgroundColor: string;
5+
export type NativePickerAppearanceStyles = ViewStyle & {
76
borderColor: string;
87
color: string;
98
};
109

11-
export type BaseState = PickerAppearanceStyles;
12-
export type DisabledState = Partial<PickerAppearanceStyles>;
13-
export type InvalidState = Partial<PickerAppearanceStyles>;
14-
export type FocusState = Partial<PickerAppearanceStyles>;
10+
export type BaseState = NativePickerAppearanceStyles;
11+
export type DisabledState = Partial<NativePickerAppearanceStyles>;
12+
export type InvalidState = Partial<NativePickerAppearanceStyles>;
13+
export type FocusState = Partial<NativePickerAppearanceStyles>;
1514

1615
export type SizeStyles = ViewStyle & {
1716
borderRadius: number;
@@ -21,27 +20,28 @@ export type SizeStyles = ViewStyle & {
2120
paddingRight: number;
2221
};
2322

24-
export interface PickerSizes {
23+
export interface NativePickerSizes {
2524
small: SizeStyles;
2625
medium: SizeStyles;
2726
large: SizeStyles;
2827
}
2928

30-
export type PickerSize = keyof PickerSizes;
29+
export type NativePickerSize = keyof NativePickerSizes;
3130

32-
export interface PickerVariables {
31+
export interface NativePickerVariables {
3332
base: BaseState;
3433
disabled: DisabledState;
3534
focus: FocusState;
3635
invalid: InvalidState;
3736
placeholderTextColor: string;
38-
sizes: PickerSizes;
37+
sizes: NativePickerSizes;
3938
}
4039

41-
export const getPickerVariables = (theme: Theme): PickerVariables => {
40+
export const getNativePickerVariables = (
41+
theme: Theme,
42+
): NativePickerVariables => {
4243
return {
4344
base: {
44-
backgroundColor: theme.colors.background.plain,
4545
borderColor: theme.colors.border.default,
4646
borderWidth: 1,
4747
color: theme.colors.text.default,
@@ -60,55 +60,78 @@ export const getPickerVariables = (theme: Theme): PickerVariables => {
6060
fontSize: theme.textSizes.small,
6161
height: theme.controlHeights.small,
6262
paddingLeft: theme.controlPaddings.small,
63-
paddingRight: theme.controlPaddings.small,
63+
paddingRight: 40,
6464
},
6565

6666
medium: {
6767
borderRadius: theme.controlBorderRadius.medium,
6868
fontSize: theme.textSizes.medium,
6969
height: theme.controlHeights.medium,
7070
paddingLeft: theme.controlPaddings.medium,
71-
paddingRight: theme.controlPaddings.medium,
71+
paddingRight: 40,
7272
},
7373

7474
large: {
7575
borderRadius: theme.controlBorderRadius.large,
7676
fontSize: theme.textSizes.large,
7777
height: theme.controlHeights.large,
7878
paddingLeft: theme.controlPaddings.large,
79-
paddingRight: theme.controlPaddings.large,
79+
paddingRight: 40,
8080
},
8181
},
8282
};
8383
};
8484

85-
export interface PickerStyles {
85+
export interface NativePickerStyles {
86+
containerStyle: ViewStyle;
87+
rightContainerStyle: ViewStyle;
8688
pickerStyle: ViewStyle;
8789
itemStyle: any;
8890
}
8991

90-
export interface PickerStylesProps {
91-
size: PickerSize;
92+
export interface NativePickerStylesProps {
93+
size: NativePickerSize;
9294
}
93-
export type GetPickerStyles = (
94-
pickerStylesProps: PickerStylesProps,
95+
export type GetNativePickerStyles = (
96+
pickerStylesProps: NativePickerStylesProps,
9597
theme: Theme,
96-
) => PickerStyles;
98+
) => NativePickerStyles;
9799

98-
export const getPickerStyles: GetPickerStyles = (pickerStylesProps, theme) => {
99-
const pickerVariables = getPickerVariables(theme);
100+
export const getNativePickerStyles: GetNativePickerStyles = (
101+
pickerStylesProps,
102+
theme,
103+
) => {
104+
const pickerVariables = getNativePickerVariables(theme);
100105
const { base, sizes } = pickerVariables;
101106
const { size } = pickerStylesProps;
102107

103108
const { fontSize, ...sizeStyles } = sizes[size];
104109

105110
return {
111+
containerStyle: {
112+
backgroundColor: theme.colors.background.plain,
113+
position: 'relative',
114+
},
106115
itemStyle: {
107116
fontSize,
108117
},
109118
pickerStyle: {
119+
backgroundColor: 'transparent',
110120
...base,
111121
...sizeStyles,
122+
...(Platform.OS === 'web' && {
123+
appearance: 'none',
124+
}),
125+
},
126+
rightContainerStyle: {
127+
alignItems: 'center',
128+
display: 'flex',
129+
height: '100%',
130+
justifyContent: 'center',
131+
paddingHorizontal: 8,
132+
position: 'absolute',
133+
right: 0,
134+
zIndex: -1,
112135
},
113136
};
114137
};
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import * as React from 'react';
2+
import {
3+
Picker as RNPicker,
4+
PickerProps as RNPickerProps,
5+
View,
6+
} from 'react-native';
7+
import { DeepPartial } from 'ts-essentials';
8+
9+
import { Icon } from '../../icons';
10+
import { ThemeContext } from '../../theme';
11+
import { mergeStyles, ReplaceReturnType } from '../../utils/mergeStyles';
12+
import {
13+
GetNativePickerStyles,
14+
getNativePickerStyles,
15+
NativePickerSize,
16+
NativePickerStyles,
17+
} from './NativePicker.styles';
18+
19+
export interface NativePickerProps extends RNPickerProps {
20+
size?: NativePickerSize;
21+
innerRef?: React.Ref<RNPicker>;
22+
rightIcon?: React.ReactNode;
23+
/**
24+
* Inline styles for components
25+
*/
26+
getStyles?: ReplaceReturnType<
27+
GetNativePickerStyles,
28+
DeepPartial<NativePickerStyles>
29+
>;
30+
}
31+
32+
const NativePickerBase = (props: NativePickerProps) => {
33+
const {
34+
size = 'medium',
35+
getStyles,
36+
innerRef,
37+
rightIcon,
38+
...pickerProps
39+
} = props;
40+
const theme = React.useContext(ThemeContext);
41+
42+
const {
43+
containerStyle,
44+
rightContainerStyle,
45+
pickerStyle,
46+
itemStyle,
47+
} = mergeStyles(getNativePickerStyles, getStyles)({ size }, theme);
48+
49+
return (
50+
<View style={containerStyle}>
51+
<RNPicker
52+
ref={innerRef}
53+
itemStyle={itemStyle}
54+
style={pickerStyle}
55+
{...pickerProps}
56+
/>
57+
<View style={rightContainerStyle}>
58+
{rightIcon || (
59+
<Icon
60+
name="chevron-down"
61+
size={32}
62+
color={theme.colors.text.default}
63+
/>
64+
)}
65+
</View>
66+
</View>
67+
);
68+
};
69+
70+
export const NativePicker = React.forwardRef<RNPicker, RNPickerProps>(
71+
(props, ref) => {
72+
return <NativePickerBase {...props} innerRef={ref} />;
73+
},
74+
);
75+
76+
export default NativePicker;
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import * as React from 'react';
2+
3+
import { withTheme } from '../../theme';
4+
import { FormField, FormFieldProps } from '../Form';
5+
import NativePicker, { NativePickerProps } from './NativePicker';
6+
7+
export interface NativePickerFieldProps
8+
extends FormFieldProps,
9+
NativePickerProps {}
10+
11+
const NativePickerFieldBase = (props: NativePickerFieldProps) => {
12+
const { label, error, description, ...passThroughProps } = props;
13+
14+
return (
15+
<FormField label={label} error={error} description={description}>
16+
<NativePicker {...passThroughProps} />
17+
</FormField>
18+
);
19+
};
20+
21+
export const NativePickerField = withTheme(NativePickerFieldBase);
22+
export default NativePickerField;
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { Picker as RNPicker, PickerItemProps } from 'react-native';
2+
3+
const NativePickerItem = RNPicker.Item;
4+
5+
// tslint:disable-next-line
6+
export interface NativePickerItemProps extends PickerItemProps {}
7+
8+
export default NativePickerItem;

src/components/Pickers/Pickers.mdx

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
---
2+
name: Pickers
3+
menu: Components
4+
---
5+
6+
import { Playground, PropsTable } from 'docz';
7+
import NativePicker from './NativePicker';
8+
import NativePickerItem from './NativePickerItem';
9+
10+
## NativePicker
11+
12+
<Playground>
13+
<NativePicker
14+
selectedValue="js"
15+
onValueChange={(itemValue, itemIndex) =>
16+
console.log('itemValue', itemValue)
17+
}
18+
>
19+
<NativePickerItem label="Java" value="java" />
20+
<NativePickerItem label="JavaScript" value="js" />
21+
</NativePicker>
22+
</Playground>
23+
24+
### Props
25+
26+
<PropsTable of={NativePicker} />

0 commit comments

Comments
 (0)