-
Notifications
You must be signed in to change notification settings - Fork 692
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ExpandableSection - add minHeight #3040
Changes from 3 commits
f79f8f1
3876d3c
f3acf7e
a5d60c7
0a83d14
086bded
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
import React, {useMemo, useState} from 'react'; | ||
import React, {useCallback, useMemo, useState} from 'react'; | ||
import {LayoutChangeEvent, StyleSheet} from 'react-native'; | ||
import {useAnimatedStyle, useSharedValue, withTiming} from 'react-native-reanimated'; | ||
import {useDidUpdate} from '../../hooks'; | ||
import View from '../view'; | ||
import TouchableOpacity from '../touchableOpacity'; | ||
|
||
|
@@ -25,6 +26,12 @@ export type ExpandableSectionProps = { | |
* action for when pressing the header of the expandableSection | ||
*/ | ||
onPress?: () => void; | ||
/** | ||
* Set a minimum height for the expandableSection | ||
* If the children height is less than the minHeight, the expandableSection will collapse to that height | ||
* If the children height is greater than the minHeight, the expandableSection will result with only the children rendered | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not clear "will result with only the children rendered". Do you mean "no height limit will apply"? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added |
||
*/ | ||
minHeight?: number; | ||
/** | ||
* Testing identifier | ||
*/ | ||
|
@@ -38,25 +45,39 @@ export type ExpandableSectionProps = { | |
*/ | ||
|
||
function ExpandableSection(props: ExpandableSectionProps) { | ||
const {expanded, sectionHeader, onPress, children, top, testID} = props; | ||
const {minHeight, expanded, sectionHeader, onPress, children, top, testID} = props; | ||
const [height, setHeight] = useState(0); | ||
const animatedHeight = useSharedValue(0); | ||
const shouldShowSectionHeader = !minHeight || height > minHeight; | ||
|
||
const onLayout = (event: LayoutChangeEvent) => { | ||
const onLayoutHeight = event.nativeEvent.layout.height; | ||
const layoutHeight = event.nativeEvent.layout.height; | ||
|
||
if (onLayoutHeight > 0 && height !== onLayoutHeight) { | ||
setHeight(onLayoutHeight); | ||
if (layoutHeight > 0 && height !== layoutHeight) { | ||
setHeight(layoutHeight); | ||
} | ||
}; | ||
|
||
const expandableStyle = useAnimatedStyle(() => { | ||
animatedHeight.value = expanded ? withTiming(height) : withTiming(0); | ||
const animateHeight = useCallback((shouldAnimate = true) => { | ||
const collapsedHeight = Math.min(minHeight ?? 0, height); | ||
const toValue = expanded ? height : collapsedHeight; | ||
animatedHeight.value = shouldAnimate ? withTiming(toValue) : toValue; | ||
}, | ||
[animatedHeight, expanded, height, minHeight]); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. no need to break the line here There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is how prettify is indenting for me There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Weired |
||
|
||
useDidUpdate(() => { | ||
animateHeight(false); | ||
}, [height, minHeight]); | ||
|
||
useDidUpdate(() => { | ||
animateHeight(); | ||
}, [expanded]); | ||
|
||
const expandableStyle = useAnimatedStyle(() => { | ||
return { | ||
height: animatedHeight.value | ||
}; | ||
}, [expanded, height]); | ||
}, []); | ||
|
||
const style = useMemo(() => [styles.hidden, expandableStyle], [expandableStyle]); | ||
|
||
|
@@ -74,15 +95,19 @@ function ExpandableSection(props: ExpandableSectionProps) { | |
); | ||
}; | ||
|
||
return ( | ||
<View style={styles.hidden}> | ||
{top && renderChildren()} | ||
<TouchableOpacity onPress={onPress} testID={testID} accessibilityState={accessibilityState}> | ||
{sectionHeader} | ||
</TouchableOpacity> | ||
{!top && renderChildren()} | ||
</View> | ||
); | ||
if (shouldShowSectionHeader) { | ||
return ( | ||
<View style={styles.hidden}> | ||
{top && renderChildren()} | ||
<TouchableOpacity onPress={onPress} testID={testID} accessibilityState={accessibilityState}> | ||
{sectionHeader} | ||
</TouchableOpacity> | ||
{!top && renderChildren()} | ||
</View> | ||
); | ||
} else { | ||
return renderChildren(); | ||
} | ||
} | ||
|
||
export default ExpandableSection; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing our usual title "ExpandableSection"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some screens do not have that and we have it in the RNN title
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know, but it's strange the the title is "Minimum Height"...