unicorn-demo-app 7.46.2 → 7.46.3

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": "7.46.2",
3
+ "version": "7.46.3",
4
4
  "main": "src/index.js",
5
5
  "author": "Ethan Sharabi <ethan.shar@gmail.com>",
6
6
  "license": "MIT",
package/src/index.js CHANGED
@@ -263,6 +263,9 @@ module.exports = {
263
263
  get IncubatorCalendarScreen() {
264
264
  return require('./screens/incubatorScreens/IncubatorCalendarScreen').default;
265
265
  },
266
+ get IncubatorGradient() {
267
+ return require('./screens/incubatorScreens/IncubatorGradientScreen').default;
268
+ },
266
269
  // realExamples
267
270
  get AppleMusic() {
268
271
  return require('./screens/realExamples/AppleMusic').default;
@@ -16,12 +16,22 @@ import {
16
16
  View
17
17
  } from 'react-native-ui-lib';
18
18
 
19
- interface RadioGroupOptions {
19
+ interface StateOptions {
20
+ state?: string;
21
+ setState?: React.Dispatch<React.SetStateAction<any /** no suitable solution for enum */>>;
22
+ }
23
+
24
+ interface RadioGroupBaseOptions {
20
25
  isRow?: boolean;
21
- afterValueChanged?: () => void;
22
26
  useValueAsLabel?: boolean;
23
27
  }
24
28
 
29
+ type RadioGroupOptions =
30
+ | (RadioGroupBaseOptions & {
31
+ afterValueChanged?: () => void;
32
+ })
33
+ | (RadioGroupBaseOptions & StateOptions);
34
+
25
35
  interface BooleanGroupOptions {
26
36
  spread?: boolean;
27
37
  afterValueChanged?: () => void;
@@ -29,11 +39,6 @@ interface BooleanGroupOptions {
29
39
  setState?: React.Dispatch<React.SetStateAction<boolean>>;
30
40
  }
31
41
 
32
- interface SegmentsExtraOptions {
33
- state?: string;
34
- setState?: React.Dispatch<React.SetStateAction<any /** no suitable solution for enum */>>;
35
- }
36
-
37
42
  export function renderHeader(title: string, others?: TextProps) {
38
43
  return (
39
44
  <Text text30 $textDefault {...others}>
@@ -103,9 +108,10 @@ export function renderBooleanGroup(title: string, options: string[]) {
103
108
  export function renderRadioGroup(title: string,
104
109
  key: string,
105
110
  options: object,
106
- {isRow, afterValueChanged, useValueAsLabel}: RadioGroupOptions = {}) {
107
111
  // @ts-ignore
108
- const value = this.state[key];
112
+ {isRow, afterValueChanged, useValueAsLabel, state, setState}: RadioGroupOptions = {}) {
113
+ // @ts-ignore
114
+ const value = state ?? this.state[key];
109
115
  return (
110
116
  <View marginB-s2>
111
117
  {!_.isUndefined(title) && (
@@ -118,7 +124,18 @@ export function renderRadioGroup(title: string,
118
124
  style={isRow && styles.rowWrap}
119
125
  initialValue={value}
120
126
  // @ts-ignore
121
- onValueChange={value => this.setState({[key]: value}, afterValueChanged)}
127
+ onValueChange={value => {
128
+ if (setState) {
129
+ setState(value);
130
+ if (afterValueChanged) {
131
+ // eslint-disable-next-line no-restricted-syntax
132
+ console.error('afterValueChanged is not supported together with the state option');
133
+ }
134
+ } else {
135
+ // @ts-ignore
136
+ this.setState({[key]: value}, afterValueChanged);
137
+ }
138
+ }}
122
139
  >
123
140
  {_.map(options, (value, key) => {
124
141
  return (
@@ -159,9 +176,25 @@ export function renderColorOption(title: string,
159
176
 
160
177
  export function renderSliderOption(title: string,
161
178
  key: string,
162
- {min = 0, max = 10, step = 1, initial = 0, sliderText = ''}) {
179
+ {
180
+ min = 0,
181
+ max = 10,
182
+ step = 1,
183
+ initial = 0,
184
+ sliderText = '',
185
+ state,
186
+ setState
187
+ }: {
188
+ min?: number;
189
+ max?: number;
190
+ step?: number;
191
+ initial?: number;
192
+ sliderText?: string;
193
+ state?: number;
194
+ setState?: React.Dispatch<React.SetStateAction<number>>;
195
+ }) {
163
196
  // @ts-ignore
164
- const value = this.state[key] || initial;
197
+ const value = state ?? this.state[key] ?? initial;
165
198
  return (
166
199
  <View marginV-s2>
167
200
  <Text marginB-s1 text70M $textDefault>
@@ -177,7 +210,14 @@ export function renderSliderOption(title: string,
177
210
  maximumValue={max}
178
211
  step={step}
179
212
  // @ts-ignore
180
- onValueChange={value => this.setState({[key]: value})}
213
+ onValueChange={value => {
214
+ if (setState) {
215
+ setState(value);
216
+ } else {
217
+ // @ts-ignore
218
+ this.setState({[key]: value});
219
+ }
220
+ }}
181
221
  />
182
222
  <Text marginL-s4 text70 $textDefault style={styles.text}>
183
223
  {sliderText}
@@ -191,7 +231,7 @@ export function renderSliderOption(title: string,
191
231
  export function renderMultipleSegmentOptions(title: string,
192
232
  key: string,
193
233
  options: (SegmentedControlItemProps & {value: any})[],
194
- {state, setState}: SegmentsExtraOptions = {}) {
234
+ {state, setState}: StateOptions = {}) {
195
235
  // @ts-ignore
196
236
  const value = state ?? this.state[key];
197
237
  const index = _.findIndex(options, {value});
@@ -208,7 +208,8 @@ export const navigationData = {
208
208
  tags: 'text field expandable input picker',
209
209
  screen: 'unicorn.components.IncubatorExpandableOverlayScreen'
210
210
  },
211
- {title: 'PanView', tags: 'pan swipe drag', screen: 'unicorn.incubator.PanViewScreen'}
211
+ {title: 'PanView', tags: 'pan swipe drag', screen: 'unicorn.incubator.PanViewScreen'},
212
+ {title: 'Gradient', tags: 'gradient', screen: 'unicorn.components.IncubatorGradientScreen'}
212
213
  ]
213
214
  },
214
215
  Inspirations: {
@@ -1,6 +1,17 @@
1
1
  import React, {Component} from 'react';
2
- import {ScrollView, StyleSheet, Alert, Image} from 'react-native';
3
- import {Text, View, Assets, Constants, Button, Colors, Typography, ButtonProps} from 'react-native-ui-lib';
2
+ import {ScrollView, StyleSheet, Alert} from 'react-native';
3
+ import {
4
+ Text,
5
+ View,
6
+ Assets,
7
+ Constants,
8
+ Button,
9
+ Colors,
10
+ Typography,
11
+ ButtonProps,
12
+ Incubator,
13
+ Image
14
+ } from 'react-native-ui-lib';
4
15
 
5
16
  const ButtonSpace = 20;
6
17
  const plusIcon = Assets.getAssetByPath('icons.demo.plus');
@@ -267,6 +278,34 @@ export default class ButtonsScreen extends Component {
267
278
  <Button label="hyperlink button" hyperlink style={{marginBottom: ButtonSpace}}/>
268
279
 
269
280
  <Button label="Icon on right" iconSource={plusIcon} iconOnRight/>
281
+
282
+ <Text style={styles.header}>Custom Backgrounds</Text>
283
+ <Button
284
+ label="Gradient Background"
285
+ customBackground={
286
+ <Incubator.Gradient
287
+ colors={[Colors.$backgroundPrimaryHeavy, Colors.$backgroundPrimaryMedium]}
288
+ type="rectangle"
289
+ width={200}
290
+ height={50}
291
+ />
292
+ }
293
+ style={{marginBottom: ButtonSpace}}
294
+ />
295
+ <Button
296
+ label="Image Background"
297
+ customBackground={
298
+ <Image
299
+ source={{
300
+ uri: 'https://images.pexels.com/photos/748837/pexels-photo-748837.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260'
301
+ }}
302
+ style={{width: 200, height: 50}}
303
+ resizeMode="cover"
304
+ />
305
+ }
306
+ style={{marginBottom: ButtonSpace}}
307
+ $textNeutralHeavy
308
+ />
270
309
  </View>
271
310
 
272
311
  <View marginT-20>
@@ -0,0 +1,114 @@
1
+ import React, {useEffect, useMemo, useState} from 'react';
2
+ import {Assets, View, Text, Incubator, Icon, Colors} from 'react-native-ui-lib';
3
+ import {renderRadioGroup, renderSliderOption} from '../ExampleScreenPresenter';
4
+
5
+ const {Gradient} = Incubator;
6
+
7
+ const COLORS = [Colors.$backgroundPrimaryHeavy, Colors.$backgroundPrimaryHeavy, Colors.$backgroundPrimaryMedium];
8
+
9
+ const GradientScreen = () => {
10
+ const [type, setType] = useState('rectangle');
11
+ const [children, setChildren] = useState('none');
12
+ const [alignment, setAlignment] = useState('none');
13
+ const [size, setSize] = useState('fixed');
14
+ const [error, setError] = useState('');
15
+ const [angle, setAngle] = useState(0);
16
+
17
+ const gradientProps = useMemo(() => {
18
+ switch (type) {
19
+ case 'rectangle':
20
+ return size === 'fixed' ? {type: 'rectangle', width: 100, height: 100} : {type: 'rectangle'};
21
+ case 'circle':
22
+ return size === 'fixed' ? {type: 'circle', radius: 50} : {type: 'circle'};
23
+ case 'border':
24
+ return size === 'fixed' ? {type: 'border', width: 100, height: 100} : {type: 'border'};
25
+ }
26
+ }, [type, size]);
27
+
28
+ const childrenProps = useMemo(() => {
29
+ switch (children) {
30
+ case 'shortText':
31
+ return <Text>Lorem ipsum dolor sit amet.</Text>;
32
+ case 'text':
33
+ return (
34
+ <Text>
35
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et
36
+ dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex
37
+ ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat
38
+ nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit
39
+ anim id est laborum.
40
+ </Text>
41
+ );
42
+ case 'icon':
43
+ return <Icon source={Assets.icons.demo.search}/>;
44
+ }
45
+ }, [children]);
46
+
47
+ const alignmentProp = useMemo(() => {
48
+ switch (alignment) {
49
+ case 'none':
50
+ return undefined;
51
+ case 'center':
52
+ return {center: true};
53
+ case 'centerH':
54
+ return {centerH: true};
55
+ case 'centerV':
56
+ return {centerV: true};
57
+ }
58
+ }, [alignment]);
59
+
60
+ useEffect(() => {
61
+ if (children === 'none' && size === 'flex' && type !== 'border') {
62
+ setError('No children + flex gives no gradient');
63
+ } else if (size === 'flex' && type === 'circle') {
64
+ setError('flex size will result with an ellipse instead of a circle');
65
+ } else {
66
+ setError('');
67
+ }
68
+ }, [children, size, type]);
69
+
70
+ return (
71
+ <View padding-page>
72
+ {renderRadioGroup('Select type',
73
+ 'type',
74
+ {Rectangle: 'rectangle', Circle: 'circle', Border: 'border'},
75
+ {isRow: true, state: type, setState: setType})}
76
+ {renderRadioGroup('Select children',
77
+ 'children',
78
+ {No: 'none', 'Short text': 'shortText', Text: 'text', Icon: 'icon'},
79
+ {isRow: true, state: children, setState: setChildren})}
80
+ {renderRadioGroup('Select children`s alignment',
81
+ 'alignment',
82
+ {None: 'none', Center: 'center', CenterH: 'centerH', CenterV: 'centerV'},
83
+ {isRow: true, state: alignment, setState: setAlignment})}
84
+ {renderRadioGroup('Select size',
85
+ 'size',
86
+ {Fixed: 'fixed', Flex: 'flex'},
87
+ {isRow: true, state: size, setState: setSize})}
88
+ <View marginH-s10>
89
+ {renderSliderOption('Angle', 'angle', {
90
+ min: 0,
91
+ max: 360,
92
+ step: 1,
93
+ state: angle,
94
+ setState: setAngle
95
+ })}
96
+ </View>
97
+ <Gradient
98
+ colors={COLORS}
99
+ // @ts-expect-error
100
+ type={type}
101
+ {...gradientProps}
102
+ {...alignmentProp}
103
+ angle={angle}
104
+ >
105
+ {childrenProps}
106
+ </Gradient>
107
+ <Text marginT-s10 center $textDangerLight>
108
+ {error}
109
+ </Text>
110
+ </View>
111
+ );
112
+ };
113
+
114
+ export default GradientScreen;
@@ -6,4 +6,5 @@ export function registerScreens(registrar) {
6
6
  registrar('unicorn.components.IncubatorToastScreen', () => require('./IncubatorToastScreen').default);
7
7
  registrar('unicorn.incubator.PanViewScreen', () => require('./PanViewScreen').default);
8
8
  registrar('unicorn.components.IncubatorSliderScreen', () => require('./IncubatorSliderScreen').default);
9
+ registrar('unicorn.components.IncubatorGradientScreen', () => require('./IncubatorGradientScreen').default);
9
10
  }