Skip to content

Commit

Permalink
fix: added Picker and themeing
Browse files Browse the repository at this point in the history
  • Loading branch information
md-rehman committed Feb 19, 2021
1 parent b53efe0 commit ec848ab
Show file tree
Hide file tree
Showing 15 changed files with 441 additions and 181 deletions.
45 changes: 23 additions & 22 deletions example/storybook/stories/components/primitives/Select/Basic.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,30 @@
import React from 'react';
import { Icon, Select } from 'native-base';
import { Box, Select, VStack } from 'native-base';

export default function () {
let [language, setLanguage] = React.useState<string>('');
return (
<Select
placeholder="Pick language"
_placeholder={{ color: 'teal.500' }}
selectedValue={language}
width={150}
onValueChange={(itemValue: string) => setLanguage(itemValue)}
selectedItemBg={'blue.500'}
_selectedItem={{ color: 'white' }}
// isDisabled
dropdownOpenIcon={
<Icon name="arrow-drop-up" type="MaterialIcons" size={6} />
}
dropdownCloseIcon={
<Icon name="arrow-drop-down" type="MaterialIcons" size={6} />
}
_item={{ color: 'red.500' }}
>
<Select.Item label="JavaScript" value="js" />
<Select.Item label="TypeScript" value="ts" />
<Select.Item label="Java" value="java" />
</Select>
<VStack w="80%" space={4}>
<Select.Picker
// placeholder="Pick language"
selectedValue={language}
width={150}
onValueChange={(itemValue: string) => setLanguage(itemValue)}
// borderRadius="md"
// bg="transparent"
// color="teal.200"
// itemStyle={{
// color: 'green',
// }}
>
<Select.Item label="Pick something" value="" />
<Select.Item label="JavaScript" value="js" />
<Select.Item label="TypeScript" value="ts" />
<Select.Item label="C" value="c" />
<Select.Item label="Python" value="py" />
<Select.Item label="Java" value="java" />
</Select.Picker>
<Box>{language}</Box>
</VStack>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import React from 'react';
import { Icon, Select, VStack, Box } from 'native-base';

export default function () {
let [language, setLanguage] = React.useState<string>('');
return (
<VStack w="80%" space={4}>
<Select
placeholder="Pick language"
_placeholder={{ color: 'teal.500' }}
selectedValue={language}
width={150}
onValueChange={(itemValue: string) => setLanguage(itemValue)}
selectedItemBg={'blue.500'}
_selectedItem={{ color: 'white' }}
// isDisabled
dropdownOpenIcon={
<Icon name="arrow-drop-up" type="MaterialIcons" size={6} />
}
dropdownCloseIcon={
<Icon name="arrow-drop-down" type="MaterialIcons" size={6} />
}
_item={{ color: 'red.500' }}
>
<Select.Item label="JavaScript" value="js" />
<Select.Item label="TypeScript" value="ts" />
<Select.Item label="Java" value="java" />
<Select.Item label="C" value="c" />
<Select.Item label="Python" value="py" />
</Select>
<Box>{language}</Box>
</VStack>
);
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import React from 'react';
import { storiesOf } from '@storybook/react-native';
import { withKnobs } from '@storybook/addon-knobs';
import Universal from './Universal';
import Basic from './Basic';
import Wrapper from './../../Wrapper';

storiesOf('Select', module)
.addDecorator(withKnobs)
.addDecorator((getStory: any) => <Wrapper>{getStory()}</Wrapper>)
.add('Basic', () => <Basic />);
.add('Basic', () => <Basic />)
.add('Universal', () => <Universal />);
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from 'react';
import { storiesOf } from '@storybook/react-native';
import { withKnobs } from '@storybook/addon-knobs';
import Wrapper from './../../Wrapper';
import Basic from './basic';
import Basic from './Basic';

storiesOf('View', module)
.addDecorator(withKnobs)
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@
"@react-native-aria/interactions": "^0.2.1",
"@react-native-aria/radio": "^0.2.1",
"@react-native-aria/switch": "^0.2.1",
"@react-native-picker/picker": "^1.9.11",
"@react-stately/radio": "^3.2.1",
"babel-eslint": "^10.1.0",
"deepmerge": "^4.2.2",
Expand Down
3 changes: 3 additions & 0 deletions src/components/primitives/Select/Context.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import React from 'react';

export const SelectContext = React.createContext({ isPicker: false });
56 changes: 0 additions & 56 deletions src/components/primitives/Select/Item.tsx

This file was deleted.

84 changes: 84 additions & 0 deletions src/components/primitives/Select/Picker.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import React from 'react';
import { Picker as RNPicker } from '@react-native-picker/picker';
import styled from 'styled-components/native';
import {
border,
flex,
space,
color,
flexbox,
layout,
typography,
} from 'styled-system';
import {
customBorder,
customBackground,
customOutline,
customLayout,
customExtra,
customShadow,
customTypography,
} from '../../../utils/customProps';
import { SelectContext } from './Context';
import type { IPickerProps } from './types';
import { useThemeProps } from '../../../hooks';
import { Platform } from 'react-native';
import { useHover } from '@react-native-aria/interactions';

const StyledPicker = styled(RNPicker)<IPickerProps>(
flex,
color,
space,
layout,
flexbox,
border,
typography,
customBorder,
customBackground,
customOutline,
customShadow,
customExtra,
customTypography,
customLayout
);

const Picker = ({ children, ...props }: IPickerProps, ref: any) => {
const {
isDisabled,
isInvalid,
_item,
_ios,
_android,
_web,
_isInvalid,
_hover,
...newProps
} = useThemeProps('Picker', props);
const _ref = React.useRef(null);
const { isHovered } = useHover({}, ref ?? _ref);

return (
<SelectContext.Provider
value={{
isPicker: true,
}}
>
<StyledPicker
// Not getting ref on web
ref={ref ?? _ref}
enabled={!isDisabled}
itemStyle={_item}
{...newProps}
{...(Platform.OS === 'ios' && _ios)}
{...(Platform.OS === 'android' && _android)}
{...(Platform.OS === 'web' && _web)}
{...(isInvalid && _isInvalid)}
{...(isHovered && _hover)}
>
{children}
</StyledPicker>
</SelectContext.Provider>
);
};

export default React.memo(React.forwardRef<any, IPickerProps>(Picker));
107 changes: 107 additions & 0 deletions src/components/primitives/Select/Select.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import React from 'react';
import Text from '../Text';
import type { ISelectProps } from './types';
import { usePopover } from '../../../core';
import Button from '../Button';
import { ScrollView } from 'react-native';
import { SelectContext } from './Context';
import { useThemeProps } from '../../../hooks';
import { useHover } from '@react-native-aria/interactions';

const Select = (
{ onValueChange, children, ...props }: ISelectProps,
ref: any
) => {
const {
_item,
_placeholder,
selectedValue,
placeholder,
selectedItemBg,
_selectedItem,
_hover,
isDisabled,
dropdownIcon,
dropdownOpenIcon,
dropdownCloseIcon,
width,
style,
...newProps
} = useThemeProps('Select', props);
let triggerRef = React.useRef();
const { isHovered } = useHover({}, ref ?? triggerRef);
let [isOpen, toggle] = React.useState<boolean>(false);
let itemsList: Array<{ label: string; value: string }> = React.Children.map(
children,
(child: any) => {
return { label: child.props.label, value: child.props.value };
}
);
const { setPopover, closePopover } = usePopover();
const closeMenu = () => {
closePopover();
toggle(false);
};
const openMenu = () => {
if (!isDisabled) {
setPopover(<ScrollView>{children}</ScrollView>, {
triggerRef,
animationDuration: 200,
onClose: closeMenu,
placeOverTriggerElement: false,
parentComponentConfig: {
open: isOpen,
closeMenu,
closeOnSelect: true,
selectedValue,
selectedItemBg,
_selectedItem,
onValueChange,
itemsList,
_item,
width,
},
});
toggle(true);
}
};
const selectedItemArray = itemsList.filter(
(item: any) => item.value === selectedValue
);
const selectedItem =
selectedItemArray && selectedItemArray.length ? selectedItemArray[0] : null;
let icon =
!dropdownOpenIcon && !dropdownCloseIcon && dropdownIcon
? dropdownIcon
: isOpen
? dropdownOpenIcon
? dropdownOpenIcon
: null
: dropdownCloseIcon
? dropdownCloseIcon
: null;
const placeholderProps = selectedItem ? {} : _placeholder;
return (
<SelectContext.Provider
value={{
isPicker: false,
}}
>
<Button
onPress={openMenu}
width={width}
ref={ref ?? triggerRef}
{...newProps}
justifyContent="space-between"
{...(isHovered && _hover)}
style={style}
>
<Text opacity={selectedItem ? undefined : 0.5} {...placeholderProps}>
{selectedItem ? selectedItem.label : placeholder}
</Text>
{icon}
</Button>
</SelectContext.Provider>
);
};
export default React.forwardRef<any, ISelectProps>(Select);
Loading

0 comments on commit ec848ab

Please sign in to comment.