Skip to content

Commit 7a584cb

Browse files
committed
merge master
2 parents be42c44 + a6f0546 commit 7a584cb

File tree

47 files changed

+786
-317
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+786
-317
lines changed

demo.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,9 @@
11
require('./demo/src/index');
22
require('./demo/src/demoApp'); // this is separated from demo/src/index by purpose
3+
4+
// comment out when measuring performance
5+
// if (process.env.NODE_ENV !== 'production') {
6+
// const whyDidYouRender = require('@welldone-software/why-did-you-render');
7+
// const React = require('react');
8+
// whyDidYouRender(React);
9+
// }

demo/src/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@ I18nManager.allowRTL(true);
55

66
module.exports = {
77
name: 'unicorn demo app',
8+
ExampleScreenPresenter: require('./screens/ExampleScreenPresenter')
89
};
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import React from 'react';
2+
import {View, Text, Checkbox, RadioGroup, RadioButton, ColorPalette, Colors, Slider} from 'react-native-ui-lib';
3+
import _ from 'lodash';
4+
5+
export function renderBooleanOption(title, key) {
6+
const value = this.state[key];
7+
return (
8+
<View row centerV spread marginB-s4>
9+
<Text text70M style={{flex: 1}}>
10+
{title}
11+
</Text>
12+
<Checkbox useCustomTheme textID={key} value={value} onValueChange={value => this.setState({[key]: value})}/>
13+
</View>
14+
);
15+
}
16+
17+
export function renderRadioGroup(title, key, options) {
18+
const value = this.state[key];
19+
return (
20+
<View marginB-s2>
21+
<Text text70M marginB-s2>
22+
{title}
23+
</Text>
24+
<RadioGroup initialValue={value} onValueChange={value => this.setState({[key]: value})}>
25+
{_.map(options, (value, key) => {
26+
return <RadioButton useCustomTheme testID={key} key={key} marginB-s2 label={value} value={options[key]}/>;
27+
})}
28+
</RadioGroup>
29+
</View>
30+
);
31+
}
32+
33+
export function renderColorOption(title,
34+
key,
35+
colors = ['transparent', Colors.blue30, Colors.grey10, Colors.yellow30, Colors.green30, Colors.purple30]) {
36+
const value = this.state[key];
37+
return (
38+
<View marginV-s2>
39+
<Text text70M>{title}</Text>
40+
<ColorPalette
41+
value={value}
42+
colors={colors}
43+
onValueChange={value => this.setState({[key]: value === 'transparent' ? undefined : value})}
44+
/>
45+
</View>
46+
);
47+
}
48+
49+
export function renderSliderOption(title, key, {min = 0, max = 10, step = 1, initial = 0}) {
50+
const value = this.state[key];
51+
return (
52+
<View marginV-s2>
53+
<Text marginB-s1 text70M>
54+
{title}
55+
</Text>
56+
<View row centerV>
57+
<Slider
58+
testID={key}
59+
value={initial}
60+
containerStyle={{flex: 1}}
61+
minimumValue={min}
62+
maximumValue={max}
63+
step={step}
64+
onValueChange={value => this.setState({[key]: value})}
65+
/>
66+
<Text marginL-s4 text70>
67+
text{value}
68+
</Text>
69+
</View>
70+
</View>
71+
);
72+
}

demo/src/screens/MenuStructure.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ export const navigationData = {
3333
{title: 'Floating Button', tags: 'floating button', screen: 'unicorn.components.FloatingButtonScreen'},
3434
{title: 'Feature Highlight', tags: 'feature overlay', screen: 'unicorn.components.FeatureHighlightScreen'},
3535
{title: 'Hint', tags: 'hints tooltip', screen: 'unicorn.components.HintsScreen'},
36+
{title: 'Image', tags: 'image cover overlay', screen: 'unicorn.components.ImageScreen'},
3637
{title: 'Overlays', tags: 'overlay image', screen: 'unicorn.components.OverlaysScreen'},
3738
{title: 'Page Control', tags: 'page', screen: 'unicorn.components.PageControlScreen'},
3839
{title: 'Pan Dismissible', tags: 'pan swipe drag dismiss', screen: 'unicorn.components.PanDismissibleScreen'},
@@ -41,6 +42,7 @@ export const navigationData = {
4142
{title: 'Shared Transition', tags: 'shared transition element', screen: 'unicorn.components.SharedTransitionScreen'},
4243
{title: 'Stack Aggregator', tags: 'stack aggregator', screen: 'unicorn.components.StackAggregatorScreen'},
4344
{title: 'TabBar', tags: 'tab bar', screen: 'unicorn.components.TabBarScreen'},
45+
{title: 'Text', tags: 'text', screen: 'unicorn.components.TextScreen'},
4446
{title: 'Toast', tags: 'toast top bottom snackbar', screen: 'unicorn.components.ToastsScreen'},
4547
{title: 'Wheel Picker Dialog', tags: 'wheel picker dialog', screen: 'unicorn.components.WheelPickerDialogScreen'},
4648
{title: 'Wizard', tags: 'wizard', screen: 'unicorn.components.WizardScreen'}
@@ -104,7 +106,7 @@ export const navigationData = {
104106
Incubator: {
105107
title: 'Incubator',
106108
screens: [
107-
{title: 'TabBarController', tags: 'tabbar controller native', screen: 'unicorn.incubator.TabControllerScreen'},
109+
{title: 'TabController', tags: 'tabbar controller native', screen: 'unicorn.incubator.TabControllerScreen'},
108110
{title: 'Native TouchableOpacity', tags: 'touchable native', screen: 'unicorn.incubator.TouchableOpacityScreen'}
109111
]
110112
},
Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
import {Navigation} from 'react-native-navigation';
2-
import CardScannerScreen from './CardScannerScreen';
3-
import ProgressBarScreen from './ProgressBarScreen';
4-
import CardAnimationsScreen from './CardAnimationsScreen';
5-
import ListAnimationsScreen from './ListAnimationsScreen';
62

7-
Navigation.registerComponent('unicorn.animations.CardScannerScreen', () => CardScannerScreen);
8-
Navigation.registerComponent('unicorn.animations.CardAnimationsScreen', () => CardAnimationsScreen);
9-
Navigation.registerComponent('unicorn.animations.ListAnimationsScreen', () => ListAnimationsScreen);
10-
Navigation.registerComponent('unicorn.animations.ProgressBarScreen', () => ProgressBarScreen);
3+
Navigation.registerComponent('unicorn.animations.CardScannerScreen', () => require('./CardScannerScreen').default);
4+
Navigation.registerComponent('unicorn.animations.CardAnimationsScreen', () => require('./CardAnimationsScreen').default);
5+
Navigation.registerComponent('unicorn.animations.ListAnimationsScreen', () => require('./ListAnimationsScreen').default);
6+
Navigation.registerComponent('unicorn.animations.ProgressBarScreen', () => require('./ProgressBarScreen').default);
Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
import {Navigation} from 'react-native-navigation';
2-
import EmptyStateScreen from './EmptyStateScreen';
3-
import LoadingScreen from './LoadingScreen';
4-
import ModalScreen from './ModalScreen';
52

6-
Navigation.registerComponent('unicorn.screens.EmptyStateScreen', () => EmptyStateScreen);
7-
Navigation.registerComponent('unicorn.screens.LoadingScreen', () => LoadingScreen);
8-
Navigation.registerComponent('unicorn.screens.ModalScreen', () => ModalScreen);
3+
Navigation.registerComponent('unicorn.screens.EmptyStateScreen', () => require('./EmptyStateScreen').default);
4+
Navigation.registerComponent('unicorn.screens.LoadingScreen', () => require('./LoadingScreen').default);
5+
Navigation.registerComponent('unicorn.screens.ModalScreen', () => require('./ModalScreen').default);

demo/src/screens/componentScreens/DateTimePickerScreen.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,14 @@ export default class DateTimePickerScreen extends Component {
1212
<DateTimePicker
1313
title={'Date'}
1414
placeholder={'Select a date'}
15-
dateFormat={'MMM D, YYYY'}
15+
// dateFormat={'MMM D, YYYY'}
1616
// value={new Date('October 13, 2014')}
1717
/>
1818
<DateTimePicker
1919
mode={'time'}
2020
title={'Time'}
2121
placeholder={'Select time'}
22-
timeFormat={'h:mm A'}
22+
// timeFormat={'h:mm A'}
2323
// value={new Date('2015-03-25T12:00:00-06:30')}
2424
/>
2525
</View>
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import React, {Component} from 'react';
2+
import {View, Text, Image, Colors} from 'react-native-ui-lib';
3+
import {renderBooleanOption, renderRadioGroup} from '../ExampleScreenPresenter';
4+
5+
import cameraIcon from '../../assets/icons/cameraSelected.png';
6+
7+
const IMAGE_URL =
8+
'https://images.pexels.com/photos/748837/pexels-photo-748837.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260';
9+
10+
const DEFAULT_SIZE = 100;
11+
class ImageScreen extends Component {
12+
state = {
13+
cover: true,
14+
showOverlayContent: false,
15+
overlayType: 'none'
16+
};
17+
18+
renderOverlayContent() {
19+
const {cover, overlayType, showOverlayContent} = this.state;
20+
if (showOverlayContent) {
21+
if (cover) {
22+
return (
23+
<View padding-20 flex bottom={overlayType === Image.overlayTypes.BOTTOM}>
24+
<View row centerV>
25+
<Image
26+
style={{margin: 5, marginRight: 10}}
27+
source={cameraIcon}
28+
tintColor={overlayType !== 'none' ? Colors.white : undefined}
29+
/>
30+
<Text text30 white={overlayType !== 'none'}>
31+
Overlay Content
32+
</Text>
33+
</View>
34+
</View>
35+
);
36+
} else {
37+
return <Image style={{margin: 5}} source={cameraIcon}/>;
38+
}
39+
}
40+
}
41+
render() {
42+
const {cover, overlayType} = this.state;
43+
44+
return (
45+
<View flex>
46+
<View centerH height={250}>
47+
<Image
48+
source={{uri: IMAGE_URL}}
49+
cover={cover}
50+
overlayType={overlayType !== 'none' ? overlayType : undefined}
51+
style={!cover && {width: DEFAULT_SIZE, height: DEFAULT_SIZE}}
52+
customOverlayContent={this.renderOverlayContent()}
53+
/>
54+
</View>
55+
<View height={2} bg-grey60/>
56+
<View useSafeArea flex>
57+
<View padding-20 bottom flex>
58+
<View flex>
59+
{renderBooleanOption.call(this, 'Show as Cover Image', 'cover')}
60+
{renderBooleanOption.call(this, 'Show Overlay Content', 'showOverlayContent')}
61+
{renderRadioGroup.call(this, 'Overlay Type', 'overlayType', {none: 'none', ...Image.overlayTypes})}
62+
</View>
63+
<Text text40>Image Screen</Text>
64+
</View>
65+
</View>
66+
</View>
67+
);
68+
}
69+
}
70+
71+
export default ImageScreen;

demo/src/screens/componentScreens/OverlaysScreen.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export default class OverlaysScreen extends Component {
1515
return (
1616
<View centerH>
1717
<Text dark10>{text}</Text>
18-
<Image style={styles.image} source={image} overlayType={type} customOverlayContent={customOverylay}/>
18+
<Image /* overlayColor={Colors.rgba(Colors.red40, 0.4)} */ style={styles.image} source={image} overlayType={type} customOverlayContent={customOverylay}/>
1919
</View>
2020
);
2121
};
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
import React, {Component} from 'react';
2+
import {ScrollView} from 'react-native';
3+
import {Colors, View, Text, TextField, Slider, ColorPalette} from 'react-native-ui-lib'; //eslint-disable-line
4+
import {Navigation} from 'react-native-navigation';
5+
6+
import {
7+
renderBooleanOption,
8+
renderRadioGroup,
9+
renderSliderOption,
10+
renderColorOption
11+
} from '../../ExampleScreenPresenter';
12+
13+
const ERROR_STATES = {
14+
noError: 'No Error',
15+
bottomError: 'Bottom Error',
16+
topError: 'Top Error'
17+
};
18+
19+
const GUIDING_TEXTS = {
20+
none: 'None',
21+
useTitle: 'Title',
22+
floatingPlaceholder: 'Floating Placeholder'
23+
};
24+
25+
export default class BasicTextFieldScreen extends Component {
26+
constructor(props) {
27+
super(props);
28+
29+
this.state = {
30+
hideUnderline: false,
31+
underlineColor: undefined,
32+
guidingText: GUIDING_TEXTS.none,
33+
disabled: false,
34+
centered: false,
35+
useHelperText: false,
36+
titleColor: undefined,
37+
error: ERROR_STATES.noError,
38+
multiline: false,
39+
typography: 70,
40+
charCount: 0
41+
};
42+
}
43+
44+
render() {
45+
const {
46+
hideUnderline,
47+
underlineColor,
48+
guidingText,
49+
titleColor,
50+
disabled,
51+
centered,
52+
useHelperText,
53+
multiline,
54+
charCount,
55+
typography,
56+
error
57+
} = this.state;
58+
59+
return (
60+
<View flex>
61+
<View padding-20>
62+
<Text marginB-20 text40>
63+
TextField
64+
</Text>
65+
<TextField
66+
key={centered ? 'centered' : 'not-centered'}
67+
{...{[`text${typography}`]: true}}
68+
placeholder={disabled ? 'Disabled' : 'Placeholder'}
69+
hideUnderline={hideUnderline}
70+
underlineColor={underlineColor}
71+
title={guidingText === GUIDING_TEXTS.useTitle ? 'Title' : undefined}
72+
titleColor={titleColor}
73+
floatingPlaceholder={guidingText === GUIDING_TEXTS.floatingPlaceholder}
74+
helperText={useHelperText ? 'Helper Text' : undefined}
75+
editable={!disabled}
76+
centered={centered}
77+
multiline={multiline}
78+
maxLength={charCount > 0 ? charCount : undefined}
79+
showCharacterCounter={charCount > 0}
80+
error={error !== ERROR_STATES.noError ? 'Custom error message' : undefined}
81+
useTopErrors={error === ERROR_STATES.topError}
82+
/>
83+
</View>
84+
<View paddingT-s1 bg-grey50/>
85+
<ScrollView keyboardShouldPersistTaps="always">
86+
<View padding-20>
87+
<Text text50M marginB-s4>
88+
Options
89+
</Text>
90+
{renderSliderOption.call(this, 'Typography (modifier)', 'typography', {
91+
min: 30,
92+
max: 100,
93+
step: 10,
94+
initial: 70
95+
})}
96+
{renderBooleanOption.call(this, 'Multiline', 'multiline')}
97+
{renderBooleanOption.call(this, 'Disabled', 'disabled')}
98+
{renderBooleanOption.call(this, 'Centered', 'centered')}
99+
{renderBooleanOption.call(this, 'Hide Underline', 'hideUnderline')}
100+
{renderColorOption.call(this, 'Underline Color', 'underlineColor')}
101+
{renderRadioGroup.call(this, 'Guiding Text', 'guidingText', GUIDING_TEXTS)}
102+
{renderColorOption.call(this, 'Title Color', 'titleColor')}
103+
{renderSliderOption.call(this, 'Character Counter', 'charCount', {min: 0, max: 150, step: 3})}
104+
{renderRadioGroup.call(this, 'Errors', 'error', ERROR_STATES)}
105+
</View>
106+
</ScrollView>
107+
</View>
108+
);
109+
}
110+
}
111+
112+
Navigation.registerComponent('unicorn.components.BasicTextFieldScreen', () => BasicTextFieldScreen);

demo/src/screens/componentScreens/TextFieldScreen/index.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,16 @@ import React, {Component} from 'react';
22
import {Colors, TouchableOpacity, Typography, View, Text} from 'react-native-ui-lib'; //eslint-disable-line
33
import {pushScreen} from '../../../navigation';
44

5-
import './InputsScreen';
5+
import './BasicTextFieldScreen';
66
import './InputValidationsScreen';
77
import './CustomInputsScreen';
8+
import './InputsScreen';
89

910
const SCREENS = [
10-
{title: 'Inputs', name: 'unicorn.components.InputsScreen'},
11+
{title: 'TextField Kitchen-Sink', name: 'unicorn.components.BasicTextFieldScreen'},
1112
{title: 'Custom Inputs', name: 'unicorn.components.CustomInputsScreen'},
12-
{title: 'Validations', name: 'unicorn.components.InputValidationsScreen'}
13+
{title: 'Validations', name: 'unicorn.components.InputValidationsScreen'},
14+
{title: 'Inputs Variations', name: 'unicorn.components.InputsScreen'}
1315
];
1416

1517
class TextFieldScreen extends Component {

0 commit comments

Comments
 (0)