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 +1 -1
- package/src/index.js +3 -0
- package/src/screens/ExampleScreenPresenter.tsx +54 -14
- package/src/screens/MenuStructure.js +2 -1
- package/src/screens/componentScreens/ButtonsScreen.tsx +41 -2
- package/src/screens/incubatorScreens/IncubatorGradientScreen.tsx +114 -0
- package/src/screens/incubatorScreens/index.js +1 -0
package/package.json
CHANGED
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
|
|
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
|
-
|
|
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 =>
|
|
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
|
-
{
|
|
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]
|
|
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 =>
|
|
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}:
|
|
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
|
|
3
|
-
import {
|
|
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
|
}
|