Skip to content

Commit 9e9dad6

Browse files
Feat/segmentetControl new component (#1238)
* Feat/segmentetControl new component * support many segments * add onChangeIndex callback * change alret to console.warn * fix labels * animation + refactor * change to function component * change to function component * add some props * add some props * Fix animation + props naming * add useCallback and useMemo Co-authored-by: Ethan Sharabi <[email protected]>
1 parent 33b4956 commit 9e9dad6

File tree

11 files changed

+497
-0
lines changed

11 files changed

+497
-0
lines changed

demo/src/index.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@ module.exports = {
9191
get RadioButtonScreen() {
9292
return require('./screens/componentScreens/RadioButtonScreen').default;
9393
},
94+
get SegmentedControlScreen() {
95+
return require('./screens/componentScreens/SegmentedControlScreen').default;
96+
},
9497
get SharedTransitionScreen() {
9598
return require('./screens/componentScreens/SharedTransitionScreen').default;
9699
},

demo/src/screens/MenuStructure.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ export const navigationData = {
5656
{title: 'Picker', tags: 'picker form', screen: 'unicorn.components.PickerScreen'},
5757
{title: 'DateTimePicker', tags: 'date time picker form', screen: 'unicorn.components.DateTimePickerScreen'},
5858
{title: 'RadioButton', tags: 'radio button group controls', screen: 'unicorn.components.RadioButtonScreen'},
59+
{title: 'SegmentedControl', tags: 'segmented control switch toggle', screen: 'unicorn.components.SegmentedControlScreen'},
5960
{title: 'Stepper', tags: 'stepper form', screen: 'unicorn.components.StepperScreen'},
6061
{title: 'Slider', tags: 'slider', screen: 'unicorn.components.SliderScreen'},
6162
{title: 'Switch', tags: 'switch toggle', screen: 'unicorn.components.SwitchScreen'},
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import React from 'react';
2+
import {StyleSheet} from 'react-native';
3+
import {Text, View, Colors, SegmentedControl, Assets, Spacings, BorderRadiuses} from 'react-native-ui-lib';
4+
5+
const segments = {
6+
first: [{label: 'Left'}, {label: 'Right'}],
7+
second: [{label: '1'}, {label: '2'}, {label: '3'}, {label: Assets.emojis.airplane}, {label: '5'}],
8+
third: [
9+
{
10+
label: 'Very Long Label with icon',
11+
iconSource: Assets.icons.search,
12+
iconStyle: {marginLeft: Spacings.s1, width: 16, height: 16},
13+
iconOnRight: true
14+
},
15+
{label: 'Short'}
16+
],
17+
forth: [{label: 'With'}, {label: 'Custom'}, {label: 'Colors'}]
18+
};
19+
20+
const SegmentedControlScreen = () => {
21+
const onChangeIndex = (segment: string, index: number) => {
22+
console.warn('Index ' + index + ' of the ' + segment + ' segmentedControl was pressed');
23+
};
24+
25+
return (
26+
<View flex bottom padding-20>
27+
<View flex center>
28+
<SegmentedControl onChangeIndex={(index: number) => onChangeIndex('first', index)} segments={segments.first}/>
29+
<SegmentedControl
30+
onChangeIndex={(index: number) => onChangeIndex('second', index)}
31+
containerStyle={styles.container}
32+
segments={segments.second}
33+
initialIndex={2}
34+
/>
35+
<SegmentedControl
36+
onChangeIndex={(index: number) => onChangeIndex('third', index)}
37+
containerStyle={styles.container}
38+
activeColor={Colors.red30}
39+
segments={segments.third}
40+
/>
41+
<SegmentedControl
42+
onChangeIndex={(index: number) => onChangeIndex('forth', index)}
43+
containerStyle={styles.container}
44+
segments={segments.forth}
45+
activeColor={Colors.grey10}
46+
borderRadius={BorderRadiuses.br20}
47+
backgroundColor={Colors.grey10}
48+
activeBackgroundColor={Colors.grey40}
49+
inactiveColor={Colors.grey70}
50+
/>
51+
</View>
52+
<Text text40 dark10>
53+
Segmented Control
54+
</Text>
55+
</View>
56+
);
57+
};
58+
59+
const styles = StyleSheet.create({
60+
container: {
61+
marginTop: 20
62+
}
63+
});
64+
65+
export default SegmentedControlScreen;

demo/src/screens/componentScreens/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ export function registerScreens(registrar) {
3232
registrar('unicorn.animations.ProgressBarScreen', () => require('../componentScreens/ProgressBarScreen').default);
3333
registrar('unicorn.components.RadioButtonScreen', () => require('./RadioButtonScreen').default);
3434
registrar('unicorn.components.ScrollBarScreen', () => require('./ScrollBarScreen').default);
35+
registrar('unicorn.components.SegmentedControlScreen', () => require('./SegmentedControlScreen').default);
3536
registrar('unicorn.components.SharedTransitionScreen', () => require('./SharedTransitionScreen').default);
3637
registrar('unicorn.components.StepperScreen', () => require('./StepperScreen').default);
3738
registrar('unicorn.components.SwitchScreen', () => require('./SwitchScreen').default);
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import React from 'react';
2+
import { StyleProp, ViewStyle } from 'react-native';
3+
import { SegmentItemProps } from './segment';
4+
export declare type SegmentedControlProps = {
5+
/**
6+
* Array on segments.
7+
*/
8+
segments?: SegmentItemProps[];
9+
/**
10+
* The color of the active segment label.
11+
*/
12+
activeColor?: string;
13+
/**
14+
* The color of the inactive segments (label).
15+
*/
16+
inactiveColor?: string;
17+
/**
18+
* Callback for when index has change.
19+
*/
20+
onChangeIndex?: (index: number) => void;
21+
/**
22+
* Initial index to be active.
23+
*/
24+
initialIndex?: number;
25+
/**
26+
* The segmentedControl borderRadius
27+
*/
28+
borderRadius?: number;
29+
/**
30+
* The background color of the inactive segments
31+
*/
32+
backgroundColor?: string;
33+
/**
34+
* The background color of the active segment
35+
*/
36+
activeBackgroundColor?: string;
37+
/**
38+
* The color of the active segment outline
39+
*/
40+
outlineColor?: string;
41+
/**
42+
* The width of the active segment outline
43+
*/
44+
outlineWidth?: number;
45+
/**
46+
* Should the icon be on right of the label
47+
*/
48+
iconOnRight?: boolean;
49+
/**
50+
* Additional spacing styles for the container
51+
*/
52+
containerStyle?: StyleProp<ViewStyle>;
53+
testID?: string;
54+
};
55+
declare const _default: React.ComponentClass<SegmentedControlProps & {
56+
useCustomTheme?: boolean | undefined;
57+
}, any>;
58+
export default _default;
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import React from 'react';
2+
import { LayoutChangeEvent, ImageSourcePropType, ImageStyle, StyleProp } from 'react-native';
3+
export declare type SegmentItemProps = {
4+
/**
5+
* The label of the segment.
6+
*/
7+
label?: string;
8+
/**
9+
* An icon for the segment.
10+
*/
11+
iconSource?: ImageSourcePropType;
12+
/**
13+
* An icon for the segment.
14+
*/
15+
iconStyle?: StyleProp<ImageStyle>;
16+
/**
17+
* Should the icon be on right of the label
18+
*/
19+
iconOnRight?: boolean;
20+
};
21+
export declare type SegmentProps = SegmentItemProps & {
22+
/**
23+
* Is the item selected.
24+
*/
25+
isSelected?: boolean;
26+
/**
27+
* The color of the active segment (label and outline).
28+
*/
29+
activeColor?: string;
30+
/**
31+
* The color of the inactive segment (label).
32+
*/
33+
inactiveColor?: string;
34+
/**
35+
* Callback for when segment has pressed.
36+
*/
37+
onPress: (index: number) => void;
38+
/**
39+
* The index of the segment.
40+
*/
41+
index: number;
42+
/**
43+
* onLayout function.
44+
*/
45+
onLayout?: (index: number, event: LayoutChangeEvent) => void;
46+
};
47+
declare const _default: React.ComponentClass<SegmentItemProps & {
48+
/**
49+
* Is the item selected.
50+
*/
51+
isSelected?: boolean | undefined;
52+
/**
53+
* The color of the active segment (label and outline).
54+
*/
55+
activeColor?: string | undefined;
56+
/**
57+
* The color of the inactive segment (label).
58+
*/
59+
inactiveColor?: string | undefined;
60+
/**
61+
* Callback for when segment has pressed.
62+
*/
63+
onPress: (index: number) => void;
64+
/**
65+
* The index of the segment.
66+
*/
67+
index: number;
68+
/**
69+
* onLayout function.
70+
*/
71+
onLayout?: ((index: number, event: LayoutChangeEvent) => void) | undefined;
72+
} & {
73+
useCustomTheme?: boolean | undefined;
74+
}, any>;
75+
export default _default;

generatedTypes/index.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ export {default as Image, ImageProps} from './components/image';
4040
export {default as Overlay, OverlayTypes} from './components/overlay';
4141
export {default as RadioButton, RadioButtonPropTypes, RadioButtonProps} from './components/radioButton/RadioButton';
4242
export {default as RadioGroup, RadioGroupPropTypes, RadioGroupProps} from './components/radioButton/RadioGroup';
43+
export {default as SegmentedControl, SegmentedControlProps} from './components/segmentedControl';
4344
export {default as Switch, SwitchProps} from './components/switch';
4445
export {default as TabController, TabControllerProps, TabControllerItemProps} from './components/tabController';
4546
export {default as TabBar, TabBarProps} from './components/TabBar';

0 commit comments

Comments
 (0)