Skip to content

Commit 5b4d05a

Browse files
committed
Merge branch 'master' of github.com:wix/react-native-ui-lib into release
2 parents 151d3b2 + a647cbb commit 5b4d05a

File tree

20 files changed

+374
-19
lines changed

20 files changed

+374
-19
lines changed

demo/src/index.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,9 @@ module.exports = {
267267
get Pinterest() {
268268
return require('./screens/realExamples/Pinterest').default;
269269
},
270+
get PieChartScreen() {
271+
return require('./screens/componentScreens/PieChartScreen.tsx').default;
272+
},
270273
get ListActionsScreen() {
271274
return require('./screens/realExamples/ListActions/ListActionsScreen').default;
272275
},

demo/src/screens/MenuStructure.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,12 @@ export const navigationData = {
104104
{title: 'SortableGridList', tags: 'sort grid list drag', screen: 'unicorn.components.SortableGridListScreen'}
105105
]
106106
},
107+
Charts: {
108+
title: 'Charts',
109+
screens: [
110+
{title: 'PieChart', tags: 'pie chart data', screen: 'unicorn.components.PieChartScreen'}
111+
]
112+
},
107113
LayoutsAndTemplates: {
108114
title: 'Layouts & Templates',
109115
screens: [

demo/src/screens/componentScreens/PickerScreen.tsx

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,15 @@ const dialogOptions = [
8383
{label: 'Option 8', value: 6}
8484
];
8585

86+
const statusOptions = [
87+
{label: 'Overview', value: 'overview'},
88+
{label: 'In Progress', value: 'inProgress'},
89+
{label: 'Completed', value: 'completed'},
90+
{label: 'Pending Review', value: 'pendingReview'},
91+
{label: 'Approved', value: 'approved'},
92+
{label: 'Rejected', value: 'rejected'}
93+
];
94+
8695
export default class PickerScreen extends Component {
8796
picker = React.createRef<PickerMethods>();
8897
state = {
@@ -96,6 +105,7 @@ export default class PickerScreen extends Component {
96105
dialogPickerValue: 'java',
97106
customModalValues: [],
98107
filter: undefined,
108+
statOption: [],
99109
scheme: undefined,
100110
contact: 0
101111
};
@@ -122,6 +132,15 @@ export default class PickerScreen extends Component {
122132
);
123133
};
124134

135+
onTopElementPress = (allOptionsSelected: boolean) => {
136+
if (allOptionsSelected) {
137+
this.setState({statOption: []});
138+
} else {
139+
const allValues = statusOptions.map(option => option.value);
140+
this.setState({statOption: allValues});
141+
}
142+
};
143+
125144
render() {
126145
return (
127146
<ScrollView keyboardShouldPersistTaps="always">
@@ -195,7 +214,32 @@ export default class PickerScreen extends Component {
195214
searchPlaceholder={'Search a language'}
196215
items={dialogOptions}
197216
/>
198-
217+
218+
<Text text70 $textDefault>
219+
Custom Top Element:
220+
</Text>
221+
<Picker
222+
placeholder="Status"
223+
floatingPlaceholder
224+
value={this.state.statOption}
225+
onChange={items => this.setState({statOption: items})}
226+
topBarProps={{title: 'Status'}}
227+
mode={Picker.modes.MULTI}
228+
items={statusOptions}
229+
renderCustomTopElement={value => {
230+
const allOptionsSelected = Array.isArray(value) && value.length === statusOptions.length;
231+
return (
232+
<View margin-s3>
233+
<Button
234+
label={allOptionsSelected ? 'Unselect All' : 'Select All'}
235+
onPress={() => this.onTopElementPress(allOptionsSelected)}
236+
size="small"
237+
/>
238+
</View>
239+
);
240+
}}
241+
/>
242+
199243
<Text marginB-10 text70 $textDefault>
200244
Custom Picker:
201245
</Text>
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
import React from 'react';
2+
import {ScrollView} from 'react-native';
3+
import {View, PieChart, Card, Text, Badge, PieChartSegmentProps, Colors} from 'react-native-ui-lib';
4+
5+
const SEGMENTS: PieChartSegmentProps[] = [
6+
{
7+
percentage: 40,
8+
color: Colors.blue30
9+
},
10+
{
11+
percentage: 30,
12+
color: Colors.red30
13+
},
14+
{
15+
percentage: 20,
16+
color: Colors.green30
17+
},
18+
{
19+
percentage: 10,
20+
color: Colors.purple30
21+
}
22+
];
23+
24+
const MONOCHROME_SEGMENTS: PieChartSegmentProps[] = [
25+
{
26+
percentage: 40,
27+
color: Colors.blue70
28+
},
29+
{
30+
percentage: 30,
31+
color: Colors.blue50
32+
},
33+
{
34+
percentage: 20,
35+
color: Colors.blue30
36+
},
37+
{
38+
percentage: 10,
39+
color: Colors.blue10
40+
}
41+
];
42+
43+
const NOT_FULL_PIECHART: PieChartSegmentProps[] = [
44+
{
45+
percentage: 30,
46+
color: Colors.blue30
47+
},
48+
{
49+
percentage: 40,
50+
color: Colors.red30
51+
}
52+
];
53+
54+
const PieChartScreen = () => {
55+
const renderSegmentLabel = (segment: PieChartSegmentProps, text: string) => {
56+
const {percentage, color} = segment;
57+
return (
58+
<View row gap-s1 marginB-s1 key={text}>
59+
<Badge size={10} containerStyle={{justifyContent: 'center'}} backgroundColor={color}/>
60+
<View>
61+
<Text>{text}</Text>
62+
<Text marginL-s1>{percentage}%</Text>
63+
</View>
64+
</View>
65+
);
66+
};
67+
68+
const renderPieChartCard = (segments: PieChartSegmentProps[]) => {
69+
return (
70+
<Card row spread paddingL-s2 paddingR-s10 paddingV-s2>
71+
<View centerV>
72+
<PieChart segments={segments} diameter={150}/>
73+
</View>
74+
<View height={'100%'} gap-s1>
75+
{segments.map((segment, index) => renderSegmentLabel(segment, `Value ${index + 1}`))}
76+
</View>
77+
</Card>
78+
);
79+
};
80+
81+
return (
82+
<ScrollView>
83+
<View padding-page gap-s2>
84+
<Text text50L marginB-s2>
85+
PieChart
86+
</Text>
87+
{renderPieChartCard(SEGMENTS)}
88+
<Text text50L marginV-s2>
89+
Monochrome colors
90+
</Text>
91+
{renderPieChartCard(MONOCHROME_SEGMENTS)}
92+
<Text text50L marginV-s2>
93+
Not Full PieChart
94+
</Text>
95+
{renderPieChartCard(NOT_FULL_PIECHART)}
96+
</View>
97+
</ScrollView>
98+
);
99+
};
100+
101+
export default PieChartScreen;

demo/src/screens/componentScreens/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
export function registerScreens(registrar) {
22
registrar('unicorn.components.ActionSheetScreen', () => require('./ActionSheetScreen').default);
3+
registrar('unicorn.components.PieChartScreen', () => require('./PieChartScreen').default);
34
registrar('unicorn.components.ActionBarScreen', () => require('./ActionBarScreen').default);
45
registrar('unicorn.components.AvatarsScreen', () => require('./AvatarsScreen').default);
56
registrar('unicorn.components.AnimatedImageScreen', () => require('./AnimatedImageScreen').default);

lib/package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "uilib-native",
3-
"version": "4.5.0",
3+
"version": "4.5.1",
44
"homepage": "https://github.com/wix/react-native-ui-lib",
55
"description": "uilib native components (separated from js components)",
66
"main": "components/index",
@@ -10,14 +10,14 @@
1010
"author": "Ethan Sharabi <ethan.shar@gmail.com>",
1111
"license": "MIT",
1212
"dependencies": {
13-
"lodash": "^4.0.0",
13+
"lodash": "^4.17.21",
1414
"prop-types": "^15.5.10"
1515
},
1616
"devDependencies": {
1717
"shell-utils": "^1.0.10"
1818
},
1919
"peerDependencies": {
20-
"react": "^16.0.0",
21-
"react-native": "^0.51.0"
20+
"react": ">=17.0.1",
21+
"react-native": ">=0.64.1"
2222
}
2323
}

src/components/button/types.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
import {TouchableOpacityProps} from '../touchableOpacity';
1111
import {TextProps} from '../text';
1212
import {ImageProps} from '../image';
13+
import type {IconProps} from '../icon';
1314

1415
export enum ButtonSize {
1516
xSmall = 'xSmall',
@@ -53,7 +54,7 @@ export type ButtonProps = TouchableOpacityProps &
5354
/**
5455
* Other image props that will be passed to the image
5556
*/
56-
iconProps?: Partial<ImageProps>;
57+
iconProps?: Partial<IconProps>;
5758
/**
5859
* Should the icon be right to the label
5960
*/

src/components/picker/PickerItemsList.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ const PickerItemsList = (props: PickerItemsListProps) => {
3434
mode,
3535
testID,
3636
showLoader,
37-
customLoaderElement
37+
customLoaderElement,
38+
renderCustomTopElement
3839
} = props;
3940
const context = useContext(PickerContext);
4041

@@ -167,6 +168,7 @@ const PickerItemsList = (props: PickerItemsListProps) => {
167168
) : (
168169
<>
169170
{renderSearchInput()}
171+
{renderCustomTopElement?.(context.value)}
170172
{renderList()}
171173
</>
172174
);

src/components/picker/api/picker.api.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@
4747
"type": "(value, {{...props, isSelected}}, itemLabel) => void",
4848
"description": "Render custom picker item"
4949
},
50+
{
51+
"name": "renderCustomTopElement",
52+
"type": "(value?: PickerValue) => React.ReactElement",
53+
"description": "Render custom top element"
54+
},
5055
{
5156
"name": "renderCustomModal",
5257
"type": "({visible, children, toggleModal}) => void)",

src/components/picker/index.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ const Picker = React.forwardRef((props: PickerProps, ref) => {
7878
items: propItems,
7979
showLoader,
8080
customLoaderElement,
81+
renderCustomTopElement,
8182
...others
8283
} = themeProps;
8384
const {preset, placeholder, style, trailingAccessory, label: propsLabel} = others;
@@ -245,6 +246,7 @@ const Picker = React.forwardRef((props: PickerProps, ref) => {
245246
useSafeArea={useSafeArea}
246247
showLoader={showLoader}
247248
customLoaderElement={customLoaderElement}
249+
renderCustomTopElement={renderCustomTopElement}
248250
>
249251
{filteredItems}
250252
</PickerItemsList>

src/components/picker/types.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,10 @@ export type PickerBaseProps = Omit<TextFieldProps, 'value' | 'onChange'> &
206206
itemProps: PickerItemProps & {isSelected: boolean; isItemDisabled: boolean},
207207
label?: string
208208
) => React.ReactElement;
209+
/**
210+
* Render custom top element
211+
*/
212+
renderCustomTopElement?: (value?: PickerValue) => React.ReactElement;
209213
/**
210214
* Add onPress callback for when pressing the picker
211215
*/
@@ -315,6 +319,7 @@ export type PickerItemsListProps = Pick<
315319
| 'useSafeArea'
316320
| 'showLoader'
317321
| 'customLoaderElement'
322+
| 'renderCustomTopElement'
318323
| 'showSearch'
319324
| 'searchStyle'
320325
| 'searchPlaceholder'
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"name": "PieChart",
3+
"category": "charts",
4+
"description": "Pie Chart",
5+
"example": "https://github.com/wix/react-native-ui-lib/blob/master/demo/src/screens/componentScreens/PieChartScreen.tsx",
6+
"props": [
7+
{"name": "segments", "type": "PieChartSegmentProps[]", "description": "Pie chart segments array"},
8+
{"name": "diameter", "type": "number", "description": "Pie chart diameter"},
9+
{"name": "dividerWidth", "type": "number", "description": "The width of the divider between the segments"},
10+
{"name": "dividerColor", "type": "ColorValue", "description": "The color of the divider between the segments"}
11+
],
12+
"snippet": [
13+
"<PieChart segments={[{percentage: 50, color: Colors.blue30}, {percentage: 30, color: Colors.red30}, {percentage: 20, color: Colors.green30}]} diameter={144}/>"
14+
]
15+
}

0 commit comments

Comments
 (0)