Skip to content

Commit 136ba44

Browse files
Feat/expandable list item new component (#943)
* expandableListItem new component * expandableSection * expandableSection fixes * generatedTypes * delete gradlew.bat * delete gradlew.bat * add useEffect * typing Co-authored-by: Ethan Sharabi <[email protected]>
1 parent d9476a2 commit 136ba44

File tree

11 files changed

+196
-84
lines changed

11 files changed

+196
-84
lines changed

demo/src/index.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ module.exports = {
4646
get DrawerScreen() {
4747
return require('./screens/componentScreens/DrawerScreen').default;
4848
},
49+
get ExpandableSectionScreen() {
50+
return require('./screens/componentScreens/ExpandableSectionScreen').default;
51+
},
4952
get TagsInputScreen() {
5053
return require('./screens/componentScreens/TagsInputScreen').default;
5154
},

demo/src/screens/MenuStructure.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ export const navigationData = {
3131
{title: 'Cards', tags: 'cards feed', screen: 'unicorn.components.CardsScreen'},
3232
{title: 'Connection Status Bar', tags: 'connection status bar', screen: 'unicorn.components.ConnectionStatusBar'},
3333
{title: 'Chip', tags: 'chip', screen: 'unicorn.components.ChipScreen'},
34+
{title: 'ExpandableSection', tags: 'expandable section', screen: 'unicorn.components.ExpandableSectionScreen'},
3435
// {title: 'Overlays', tags: 'overlay image', screen: 'unicorn.components.OverlaysScreen'},
3536
{title: 'Page Control', tags: 'page', screen: 'unicorn.components.PageControlScreen'},
3637
{title: 'ProgressBar', tags: 'progress bar animated', screen: 'unicorn.animations.ProgressBarScreen'},
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
import _ from 'lodash';
2+
import React, {PureComponent} from 'react';
3+
import {ScrollView, StyleSheet, TouchableOpacity} from 'react-native';
4+
import {Card, Text, Image, ListItem, Carousel, Spacings, View} from 'react-native-ui-lib';
5+
import ExpandableSection from '../../../../src/components/expandableSection';
6+
7+
const cardImage2 = require('../../assets/images/empty-state.jpg');
8+
const cardImage = require('../../assets/images/card-example.jpg');
9+
const chevronDown = require('../../assets/icons/chevronDown.png');
10+
const chevronUp = require('../../assets/icons/chevronUp.png');
11+
12+
const elements = [
13+
<Card style={{marginBottom: 10}} onPress={() => {}}>
14+
<Card.Section
15+
content={[
16+
{text: 'Card #1', text70: true, dark10: true},
17+
{text: 'card description', text90: true, dark50: true}
18+
]}
19+
style={{padding: 20}}
20+
/>
21+
<Card.Section imageSource={cardImage2} imageStyle={{height: 120}} />
22+
</Card>,
23+
<Card style={{marginBottom: 10}} onPress={() => {}}>
24+
<Card.Section
25+
content={[
26+
{text: 'Card #2', text70: true, dark10: true},
27+
{text: 'card description', text90: true, dark50: true}
28+
]}
29+
style={{padding: 20}}
30+
/>
31+
<Card.Section imageSource={cardImage} imageStyle={{height: 120}} />
32+
</Card>,
33+
<Card style={{marginBottom: 10}} onPress={() => {}}>
34+
<Card.Section
35+
content={[
36+
{text: 'Card #3', text70: true, dark10: true},
37+
{text: 'card description', text90: true, dark50: true}
38+
]}
39+
style={{padding: 20}}
40+
/>
41+
<Card.Section imageSource={cardImage2} imageStyle={{height: 120}} />
42+
</Card>
43+
];
44+
45+
class ExpandableSectionScreen extends PureComponent {
46+
state = {
47+
expanded: false
48+
};
49+
50+
onExpand() {
51+
this.setState({
52+
expanded: !this.state.expanded
53+
});
54+
}
55+
56+
getHeaderElement() {
57+
return (
58+
<TouchableOpacity onPress={() => this.onExpand()}>
59+
<Text margin-10 dark10 text60>
60+
ExpandableSection's sectionHeader
61+
</Text>
62+
<View style={styles.header}>
63+
<Image style={styles.icon} source={!this.state.expanded ? chevronUp : chevronDown} />
64+
</View>
65+
</TouchableOpacity>
66+
);
67+
}
68+
69+
getBodyElement() {
70+
return (
71+
<Carousel pageWidth={350} itemSpacings={Spacings.s2}>
72+
{_.map(elements, (element, key) => {
73+
return (
74+
<View key={key} margin-12>
75+
{element}
76+
</View>
77+
);
78+
})}
79+
</Carousel>
80+
);
81+
}
82+
83+
render() {
84+
const {expanded} = this.state;
85+
86+
return (
87+
<ScrollView>
88+
<ExpandableSection expanded={expanded} sectionHeader={this.getHeaderElement()}>
89+
{this.getBodyElement()}
90+
</ExpandableSection>
91+
<ListItem>
92+
<Text dark10 text60 marginL-10>
93+
{'The next item'}
94+
</Text>
95+
</ListItem>
96+
</ScrollView>
97+
);
98+
}
99+
}
100+
101+
export default ExpandableSectionScreen;
102+
103+
const styles = StyleSheet.create({
104+
header: {
105+
marginLeft: 380,
106+
marginTop: 20,
107+
position: 'absolute'
108+
},
109+
icon: {
110+
backgroundColor: 'transparent'
111+
}
112+
});

demo/src/screens/componentScreens/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export function registerScreens(registrar) {
1515
registrar('unicorn.components.ConnectionStatusBar', () => require('./ConnectionStatusBarScreen').default);
1616
registrar('unicorn.components.DialogScreen', () => require('./DialogScreen').default);
1717
registrar('unicorn.components.DrawerScreen', () => require('./DrawerScreen').default);
18+
registrar('unicorn.components.ExpandableSectionScreen', () => require('./ExpandableSectionScreen').default);
1819
registrar('unicorn.components.TagsInputScreen', () => require('./TagsInputScreen').default);
1920
registrar('unicorn.components.HintsScreen', () => require('./HintsScreen').default);
2021
registrar('unicorn.components.ImageScreen', () => require('./ImageScreen').default);

expoDemo/android/gradlew.bat

Lines changed: 0 additions & 84 deletions
This file was deleted.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/// <reference types="react" />
2+
export declare type ExpandableSectionProps = {
3+
/**
4+
* ExpandableSection text element
5+
*/
6+
textElement?: JSX.Element;
7+
/**
8+
* ExpandableSection icon color
9+
*/
10+
iconColor?: string;
11+
};
12+
declare function ExpandableSection(props: ExpandableSectionProps): JSX.Element;
13+
export default ExpandableSection;
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import React from 'react';
2+
export declare type ExpandableSectionProps = {
3+
/**
4+
* expandableSection header element
5+
*/
6+
sectionHeader?: JSX.Element;
7+
/**
8+
* expandableSection expandable children
9+
*/
10+
children?: React.ReactNode;
11+
/**
12+
* should the expandableSection be expanded
13+
*/
14+
expanded?: boolean;
15+
};
16+
declare function ExpandableSection(props: ExpandableSectionProps): JSX.Element;
17+
export default ExpandableSection;

generatedTypes/index.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export {default as RadioButton, RadioButtonPropTypes} from './components/radioBu
2121
export {default as RadioGroup, RadioGroupPropTypes} from './components/radioButton/RadioGroup';
2222
export {default as TabBar} from './components/TabBar';
2323
export {default as Fader, FaderProps, FaderPosition} from './components/fader';
24+
export {default as ExpandableSection, ExpandableSectionProps } from './components/ExpandableSection';
2425
export {default as Modal, ModalProps, ModalTopBarProps} from './components/modal';
2526
export {default as PanGestureView, PanGestureViewProps} from './components/panningViews/panGestureView';
2627
export {default as PanningContext} from './components/panningViews/panningContext';
@@ -48,6 +49,7 @@ export {
4849
ConnectionStatusBar,
4950
Dialog,
5051
Drawer,
52+
ExpandableSection,
5153
FeatureHighlight,
5254
Hint,
5355
BaseInput,
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import _ from 'lodash';
2+
import React, {useEffect} from 'react';
3+
import {LayoutAnimation, StyleSheet} from 'react-native';
4+
import View from '../view';
5+
6+
export type ExpandableSectionProps = {
7+
/**
8+
* expandableSection header element
9+
*/
10+
sectionHeader?: JSX.Element;
11+
/**
12+
* expandableSection expandable children
13+
*/
14+
children?: React.ReactNode;
15+
/**
16+
* should the expandableSection be expanded
17+
*/
18+
expanded?: boolean;
19+
};
20+
21+
function ExpandableSection(props: ExpandableSectionProps) {
22+
const {expanded, sectionHeader, children} = props;
23+
24+
useEffect(() => {
25+
LayoutAnimation.configureNext({...LayoutAnimation.Presets.easeInEaseOut, duration: 300});
26+
}, [expanded]);
27+
28+
29+
return (
30+
<View style={styles.container}>
31+
{sectionHeader}
32+
{expanded && children}
33+
</View>
34+
);
35+
}
36+
37+
export default ExpandableSection;
38+
39+
const styles = StyleSheet.create({
40+
container: {
41+
overflow: 'hidden'
42+
}
43+
});

src/index.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ export default {
5454
get Drawer() {
5555
return require('./components/drawer').default;
5656
},
57+
get ExpandableSection() {
58+
return require('./components/expandableSection').default;
59+
},
5760
get Fader() {
5861
return require('./components/fader').default;
5962
},

src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ export {default as RadioButton, RadioButtonPropTypes} from './components/radioBu
2323
export {default as RadioGroup, RadioGroupPropTypes} from './components/radioButton/RadioGroup';
2424
export {default as TabBar} from './components/TabBar';
2525
export {default as Fader, FaderProps, FaderPosition} from './components/fader';
26+
export {default as ExpandableSection, ExpandableSectionProps} from './components/expandableSection';
2627
export {default as Modal, ModalProps, ModalTopBarProps} from './components/modal';
2728
export {default as PanGestureView, PanGestureViewProps} from './components/panningViews/panGestureView';
2829
export {default as PanningContext} from './components/panningViews/panningContext';

0 commit comments

Comments
 (0)