unicorn-demo-app 6.0.0 → 6.1.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "unicorn-demo-app",
3
- "version": "6.0.0",
3
+ "version": "6.1.0",
4
4
  "main": "src/index.js",
5
5
  "author": "Ethan Sharabi <ethan.shar@gmail.com>",
6
6
  "license": "MIT",
@@ -1,55 +1,57 @@
1
1
  import {Assets, Colors, Typography, Spacings, Incubator} from 'react-native-ui-lib'; // eslint-disable-line
2
2
 
3
- Assets.loadAssetsGroup('icons.demo', {
4
- chevronDown: require('./assets/icons/chevronDown.png'),
5
- add: require('./assets/icons/add.png'),
6
- camera: require('./assets/icons/cameraSelected.png'),
7
- close: require('./assets/icons/close.png'),
8
- dashboard: require('./assets/icons/dashboard.png'),
9
- image: require('./assets/icons/image.png'),
10
- plus: require('./assets/icons/plus.png'),
11
- refresh: require('./assets/icons/refresh.png'),
12
- search: require('./assets/icons/search.png'),
13
- share: require('./assets/icons/share.png')
14
- });
3
+ export const loadDemoConfigurations = () => {
4
+ Assets.loadAssetsGroup('icons.demo', {
5
+ chevronDown: require('./assets/icons/chevronDown.png'),
6
+ add: require('./assets/icons/add.png'),
7
+ camera: require('./assets/icons/cameraSelected.png'),
8
+ close: require('./assets/icons/close.png'),
9
+ dashboard: require('./assets/icons/dashboard.png'),
10
+ image: require('./assets/icons/image.png'),
11
+ plus: require('./assets/icons/plus.png'),
12
+ refresh: require('./assets/icons/refresh.png'),
13
+ search: require('./assets/icons/search.png'),
14
+ share: require('./assets/icons/share.png')
15
+ });
15
16
 
16
- Assets.loadAssetsGroup('images.demo', {
17
- brokenImage: require('./assets/images/placeholderMissingImage.png')
18
- });
17
+ Assets.loadAssetsGroup('images.demo', {
18
+ brokenImage: require('./assets/images/placeholderMissingImage.png')
19
+ });
19
20
 
20
- Assets.loadAssetsGroup('svgs.demo', {
21
- logo: require('./assets/svgs/headerLogo.svg').default
22
- });
21
+ Assets.loadAssetsGroup('svgs.demo', {
22
+ logo: require('./assets/svgs/headerLogo.svg').default
23
+ });
23
24
 
24
- Typography.loadTypographies({
25
- h1: {...Typography.text40},
26
- h2: {...Typography.text50},
27
- h3: {...Typography.text70M},
28
- body: Typography.text70,
29
- bodySmall: Typography.text80
30
- });
25
+ Typography.loadTypographies({
26
+ h1: {...Typography.text40},
27
+ h2: {...Typography.text50},
28
+ h3: {...Typography.text70M},
29
+ body: Typography.text70,
30
+ bodySmall: Typography.text80
31
+ });
31
32
 
32
- Spacings.loadSpacings({
33
- page: Spacings.s5
34
- });
33
+ Spacings.loadSpacings({
34
+ page: Spacings.s5
35
+ });
35
36
 
36
- /* Dark Mode Schemes */
37
- Colors.loadSchemes({
38
- light: {
39
- screenBG: 'transparent',
40
- textColor: Colors.grey10,
41
- moonOrSun: Colors.yellow30,
42
- mountainForeground: Colors.green30,
43
- mountainBackground: Colors.green50
44
- },
45
- dark: {
46
- screenBG: Colors.grey10,
47
- textColor: Colors.white,
48
- moonOrSun: Colors.grey80,
49
- mountainForeground: Colors.violet10,
50
- mountainBackground: Colors.violet20
51
- }
52
- });
37
+ /* Dark Mode Schemes */
38
+ Colors.loadSchemes({
39
+ light: {
40
+ screenBG: Colors.white,
41
+ textColor: Colors.grey10,
42
+ moonOrSun: Colors.yellow30,
43
+ mountainForeground: Colors.green30,
44
+ mountainBackground: Colors.green50
45
+ },
46
+ dark: {
47
+ screenBG: Colors.grey10,
48
+ textColor: Colors.white,
49
+ moonOrSun: Colors.grey80,
50
+ mountainForeground: Colors.violet10,
51
+ mountainBackground: Colors.violet20
52
+ }
53
+ });
53
54
 
54
- /* Components */
55
- Incubator.TextField.defaultProps = {...Incubator.TextField.defaultProps, preset: 'default'};
55
+ /* Components */
56
+ Incubator.TextField.defaultProps = {...Incubator.TextField.defaultProps, preset: 'default'};
57
+ };
package/src/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import {UIManager, I18nManager} from 'react-native';
2
2
  import {navigationData as menuStructure} from './screens/MenuStructure';
3
+ import {loadDemoConfigurations} from './configurations';
3
4
 
4
5
  UIManager.setLayoutAnimationEnabledExperimental && UIManager.setLayoutAnimationEnabledExperimental(true); // eslint-disable-line
5
6
  I18nManager.allowRTL(true);
@@ -7,6 +8,7 @@ I18nManager.allowRTL(true);
7
8
  module.exports = {
8
9
  name: 'unicorn demo app',
9
10
  menuStructure,
11
+ loadDemoConfigurations,
10
12
  // componentScreens
11
13
  get screens() {
12
14
  return {
@@ -219,6 +221,9 @@ module.exports = {
219
221
  get PanViewScreen() {
220
222
  return require('./screens/incubatorScreens/PanViewScreen').default;
221
223
  },
224
+ get TransitionViewScreen() {
225
+ return require('./screens/incubatorScreens/TransitionViewScreen').default;
226
+ },
222
227
  // realExamples
223
228
  get AppleMusic() {
224
229
  return require('./screens/realExamples/AppleMusic').default;
@@ -156,7 +156,8 @@ export const navigationData = {
156
156
  {title: '(New) TextField', tags: 'text field input', screen: 'unicorn.components.IncubatorTextFieldScreen'},
157
157
  {title: 'ExpandableOverlay', tags: 'text field expandable input picker', screen: 'unicorn.components.IncubatorExpandableOverlayScreen'},
158
158
  {title: 'WheelPicker (Incubator)', tags: 'wheel picker spinner experimental', screen: 'unicorn.incubator.WheelPickerScreen'},
159
- {title: 'Pan View', tags: 'pan swipe drag', screen: 'unicorn.incubator.PanViewScreen'}
159
+ {title: 'Pan View', tags: 'pan swipe drag', screen: 'unicorn.incubator.PanViewScreen'},
160
+ {title: 'Transition View', tags: 'transition animation enter exit', screen: 'unicorn.incubator.TransitionViewScreen'}
160
161
  ]
161
162
  },
162
163
  Inspirations: {
@@ -1,6 +1,6 @@
1
1
  import React, {Component} from 'react';
2
2
  import {ScrollView} from 'react-native';
3
- import {View, Text, Image, Colors, Assets} from 'react-native-ui-lib';
3
+ import {View, Text, Image, Colors, Assets, OverlayTypes} from 'react-native-ui-lib';
4
4
  import {renderBooleanOption, renderRadioGroup, renderSliderOption} from '../ExampleScreenPresenter';
5
5
 
6
6
  const IMAGE_URL =
@@ -38,11 +38,24 @@ enum SizeType {
38
38
  Percentage = '50%'
39
39
  }
40
40
 
41
- class ImageScreen extends Component {
41
+ interface State {
42
+ cover: boolean;
43
+ showOverlayContent: boolean;
44
+ overlayType: 'none' | OverlayTypes['type'];
45
+ overlayIntensity: OverlayTypes['intensity'];
46
+ margin: number;
47
+ showErrorImage: boolean;
48
+ showSvg: boolean;
49
+ isFile: boolean;
50
+ sizeType: SizeType;
51
+ }
52
+
53
+ class ImageScreen extends Component<{}, State> {
42
54
  state = {
43
55
  cover: true,
44
56
  showOverlayContent: false,
45
57
  overlayType: 'none',
58
+ overlayIntensity: Image.overlayIntensityType.LOW,
46
59
  margin: 0,
47
60
  showErrorImage: false,
48
61
  showSvg: false,
@@ -75,13 +88,15 @@ class ImageScreen extends Component {
75
88
  }
76
89
 
77
90
  renderImage() {
78
- const {cover, overlayType, margin, showErrorImage} = this.state;
91
+ const {cover, overlayType, overlayIntensity, margin, showErrorImage} = this.state;
79
92
  return (
80
93
  <Image
94
+ key={`${overlayType}-${overlayIntensity}`}
81
95
  source={{uri: showErrorImage ? BROKEN_URL : IMAGE_URL}}
82
96
  errorSource={Assets.images.demo.brokenImage}
83
97
  cover={cover}
84
98
  overlayType={overlayType !== 'none' ? overlayType : undefined}
99
+ overlayIntensity={overlayIntensity}
85
100
  style={!cover && {width: DEFAULT_SIZE, height: DEFAULT_SIZE}}
86
101
  customOverlayContent={this.renderOverlayContent()}
87
102
  {...{[`margin-${margin}`]: true}}
@@ -109,7 +124,10 @@ class ImageScreen extends Component {
109
124
  {renderBooleanOption.call(this, 'Show as Cover Image', 'cover')}
110
125
  {renderBooleanOption.call(this, 'Show Overlay Content', 'showOverlayContent')}
111
126
  {renderBooleanOption.call(this, 'Show Error Image', 'showErrorImage')}
112
- {renderRadioGroup.call(this, 'Overlay Type', 'overlayType', {none: 'none', ...Image.overlayTypes})}
127
+ <View row spread>
128
+ {renderRadioGroup.call(this, 'Overlay Type', 'overlayType', {none: 'none', ...Image.overlayTypes})}
129
+ {renderRadioGroup.call(this, 'Overlay Intensity', 'overlayIntensity', Image.overlayIntensityType)}
130
+ </View>
113
131
  {renderSliderOption.call(this, 'Margin(margin-XX)', 'margin', {step: 4, min: 0, max: 40})}
114
132
  </>
115
133
  );
@@ -64,7 +64,7 @@ const SectionsWheelPickerScreen = () => {
64
64
  {
65
65
  items: getItems(days),
66
66
  onChange: onDaysChange,
67
- selectedValue: selectedDays,
67
+ initialValue: selectedDays,
68
68
  label: 'Days',
69
69
  align: numOfSections === 1 ? WheelPicker.alignments.CENTER : WheelPicker.alignments.RIGHT,
70
70
  style: {flex: 1}
@@ -72,7 +72,7 @@ const SectionsWheelPickerScreen = () => {
72
72
  {
73
73
  items: getItems(hours),
74
74
  onChange: onHoursChange,
75
- selectedValue: selectedHours,
75
+ initialValue: selectedHours,
76
76
  label: 'Hrs',
77
77
  align: numOfSections === 2 ? WheelPicker.alignments.LEFT : WheelPicker.alignments.CENTER,
78
78
  style: numOfSections === 2 ? {flex: 1} : undefined
@@ -80,7 +80,7 @@ const SectionsWheelPickerScreen = () => {
80
80
  {
81
81
  items: getItems(minutes),
82
82
  onChange: onMinutesChange,
83
- selectedValue: selectedMinutes,
83
+ initialValue: selectedMinutes,
84
84
  label: 'Mins',
85
85
  align: WheelPicker.alignments.LEFT,
86
86
  style: {flex: 1}
@@ -1,7 +1,7 @@
1
1
  import _ from 'lodash';
2
2
  import React, {Component} from 'react';
3
3
  import {ScrollView} from 'react-native';
4
- import {View, Text, Button, ButtonSize, StackAggregator} from 'react-native-ui-lib';
4
+ import {View, Text, Button, StackAggregator} from 'react-native-ui-lib';
5
5
 
6
6
 
7
7
  const contents = [
@@ -24,7 +24,7 @@ export default class StackAggregatorScreen extends Component {
24
24
  renderItem = (_: string, index: number) => {
25
25
  return (
26
26
  <View key={index} center padding-12>
27
- <Button label={`${index}`} marginB-10 size={ButtonSize.small} onPress={() => this.onPress(index)}/>
27
+ <Button label={`${index}`} marginB-10 size={Button.sizes.small} onPress={() => this.onPress(index)}/>
28
28
  <Text>{contents[index]}</Text>
29
29
  </View>
30
30
  );
@@ -1,22 +1,46 @@
1
1
  import React, {Component} from 'react';
2
2
  import {StyleSheet} from 'react-native';
3
- import {View, Text, Constants} from 'react-native-ui-lib';
3
+ import {View, Text, Colors, Constants, SegmentedControl, SchemeType} from 'react-native-ui-lib';
4
+
5
+ const SCHEME_TYPES: {label: string; value: SchemeType}[] = [
6
+ {label: 'device (default)', value: 'default'},
7
+ {label: 'dark', value: 'dark'},
8
+ {label: 'light', value: 'light'}
9
+ ];
10
+
11
+ const DEVICE_DARK_MODE_MESSAGE = Constants.isIOS
12
+ ? 'Change to dark mode in simulator by pressing Cmd+Shift+A'
13
+ : 'Change to dark mode';
14
+ const MANUAL_DARK_MODE_MESSAGE = 'Setting the scheme manually will ignore device settings';
4
15
 
5
16
  class DarkModeScreen extends Component {
6
- state = {};
17
+ state = {
18
+ selectedSchemeType: 'default'
19
+ };
20
+
21
+ changeSchemeType = (index: number) => {
22
+ this.setState({selectedSchemeType: SCHEME_TYPES[index].value});
23
+ Colors.setScheme(SCHEME_TYPES[index].value);
24
+ };
25
+
7
26
  render() {
27
+ const {selectedSchemeType} = this.state;
28
+ const message = selectedSchemeType === 'default' ? DEVICE_DARK_MODE_MESSAGE : MANUAL_DARK_MODE_MESSAGE;
29
+
8
30
  return (
9
31
  <View flex padding-page bg-screenBG>
10
32
  <Text h1 textColor>
11
33
  Dark Mode
12
34
  </Text>
13
- {Constants.isIOS ? (
14
- <Text marginT-s2 body textColor>
15
- Change to dark mode in simulator by pressing Cmd+Shift+A
16
- </Text>
17
- ) : (
18
- <Text marginT-s2 body textColor>Change to dark mode</Text>
19
- )}
35
+ <SegmentedControl
36
+ containerStyle={{alignSelf: 'flex-start', marginTop: 20}}
37
+ segments={SCHEME_TYPES}
38
+ onChangeIndex={this.changeSchemeType}
39
+ />
40
+
41
+ <Text marginT-s2 body textColor>
42
+ {message}
43
+ </Text>
20
44
 
21
45
  <View style={styles.moonOrSun} bg-moonOrSun/>
22
46
  <View style={[styles.mountain, styles.mountainBackground]} bg-mountainBackground/>
@@ -5,6 +5,8 @@ import {Assets, Colors, Spacings, Typography, View, Text, Button, Keyboard, Incu
5
5
  const {TextField} = Incubator;
6
6
  const {KeyboardAwareInsetsView} = Keyboard;
7
7
 
8
+ const priceFormatter = Intl.NumberFormat('en-US');
9
+
8
10
  export default class TextFieldScreen extends Component {
9
11
  input = React.createRef<TextInput>();
10
12
  input2 = React.createRef<TextInput>();
@@ -47,7 +49,7 @@ export default class TextFieldScreen extends Component {
47
49
  }
48
50
 
49
51
  render() {
50
- const {errorPosition, shouldDisable} = this.state;
52
+ const {errorPosition, shouldDisable, price} = this.state;
51
53
  return (
52
54
  <ScrollView keyboardShouldPersistTaps="always">
53
55
  <View flex padding-page>
@@ -218,6 +220,21 @@ export default class TextFieldScreen extends Component {
218
220
  hint="1-6 chars including numeric chars"
219
221
  fieldStyle={styles.withUnderline}
220
222
  />
223
+ <Text h3 blue50 marginV-s4>
224
+ Formatter
225
+ </Text>
226
+ <TextField
227
+ value={price}
228
+ onChangeText={value => this.setState({price: value})}
229
+ label="Price"
230
+ placeholder="Enter price"
231
+ validate={'number'}
232
+ validationMessage="Invalid price"
233
+ // @ts-expect-error
234
+ formatter={(value) => (isNaN(value) ? value : priceFormatter.format(Number(value)))}
235
+ leadingAccessory={<Text marginR-s1 grey30>$</Text>}
236
+ fieldStyle={styles.withUnderline}
237
+ />
221
238
  </View>
222
239
  <KeyboardAwareInsetsView/>
223
240
  </ScrollView>
@@ -0,0 +1,59 @@
1
+ import React, {Component} from 'react';
2
+ import {View, Button, Incubator} from 'react-native-ui-lib';
3
+ const {TransitionView} = Incubator;
4
+ // @ts-ignore
5
+ import {renderRadioGroup} from '../ExampleScreenPresenter';
6
+
7
+ interface State {
8
+ enterDirection: Incubator.Direction;
9
+ exitDirection: Incubator.Direction;
10
+ key: number;
11
+ }
12
+
13
+ export default class TransitionViewScreen extends Component<{}, State> {
14
+ private ref = React.createRef<typeof TransitionView>();
15
+ state = {
16
+ enterDirection: 'left' as Incubator.Direction,
17
+ exitDirection: 'bottom' as Incubator.Direction,
18
+ key: 1
19
+ };
20
+
21
+ onPress = () => {
22
+ this.ref.current?.animateOut();
23
+ };
24
+
25
+ // onAnimationEnd = (type: Incubator.TransitionViewAnimationType) => {
26
+ // console.warn('Animation complete', type);
27
+ // };
28
+
29
+ render() {
30
+ const {key, enterDirection, exitDirection} = this.state;
31
+ return (
32
+ <View padding-20 bg-grey80 flex>
33
+ {renderRadioGroup.call(this,
34
+ 'Enter direction',
35
+ 'enterDirection',
36
+ {top: 'top', bottom: 'bottom', left: 'left', right: 'right'},
37
+ {isRow: true})}
38
+ {renderRadioGroup.call(this,
39
+ 'Exit direction',
40
+ 'exitDirection',
41
+ {top: 'top', bottom: 'bottom', left: 'left', right: 'right'},
42
+ {isRow: true})}
43
+ <Button label="Refresh" onPress={() => this.setState({key: key + 1})}/>
44
+ <View flex center>
45
+ <TransitionView
46
+ key={`${key}`}
47
+ // @ts-expect-error
48
+ ref={this.ref}
49
+ enterFrom={enterDirection}
50
+ exitTo={exitDirection}
51
+ // onAnimationEnd={this.onAnimationEnd}
52
+ >
53
+ <Button label="Press to remove" onPress={this.onPress}/>
54
+ </TransitionView>
55
+ </View>
56
+ </View>
57
+ );
58
+ }
59
+ }
@@ -5,6 +5,7 @@ export function registerScreens(registrar) {
5
5
  gestureHandlerRootHOC(require('./TouchableOpacityScreen').default));
6
6
  registrar('unicorn.components.IncubatorExpandableOverlayScreen', () => require('./IncubatorExpandableOverlayScreen').default);
7
7
  registrar('unicorn.components.IncubatorTextFieldScreen', () => require('./IncubatorTextFieldScreen').default);
8
- registrar('unicorn.incubator.WheelPickerScreen', () => gestureHandlerRootHOC(require('./WheelPickerScreen').default));
9
8
  registrar('unicorn.incubator.PanViewScreen', () => require('./PanViewScreen').default);
9
+ registrar('unicorn.incubator.TransitionViewScreen', () => require('./TransitionViewScreen').default);
10
+ registrar('unicorn.incubator.WheelPickerScreen', () => gestureHandlerRootHOC(require('./WheelPickerScreen').default));
10
11
  }
@@ -2,7 +2,7 @@ import {gestureHandlerRootHOC} from 'react-native-gesture-handler';
2
2
 
3
3
  export function registerScreens(registrar) {
4
4
  // load demo app presets
5
- require('../configurations');
5
+ require('../configurations').loadDemoConfigurations();
6
6
 
7
7
  require('./componentScreens').registerScreens(registrar);
8
8
  require('./foundationScreens').registerScreens(registrar);