Skip to content

Commit

Permalink
API update and bug fixes
Browse files Browse the repository at this point in the history
Reviewed By: bvaughn, yungsters

Differential Revision: D4563798

fbshipit-source-id: 0591cef7c854b525d77e526af783284d9696cb48
  • Loading branch information
sahrens authored and facebook-github-bot committed Feb 17, 2017
1 parent 5042bae commit 6283878
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 38 deletions.
10 changes: 5 additions & 5 deletions Examples/UIExplorer/js/ListExampleShared.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ const {
View,
} = ReactNative;

type Item = {title: string, text: string, key: number, pressed: boolean};
type Item = {title: string, text: string, key: number, pressed: boolean, noImage?: ?boolean};

function genItemData(count: number): Array<Item> {
const dataBlob = [];
Expand Down Expand Up @@ -73,7 +73,7 @@ class ItemComponent extends React.PureComponent {
style={horizontal ? styles.horizItem : styles.item}>
<View style={[
styles.row, horizontal && {width: HORIZ_WIDTH}]}>
<Image style={styles.thumb} source={imgSource} />
{!item.noImage && <Image style={styles.thumb} source={imgSource} />}
<Text
style={styles.text}
numberOfLines={(horizontal || fixedHeight) ? 3 : undefined}>
Expand Down Expand Up @@ -108,7 +108,7 @@ class FooterComponent extends React.PureComponent {
<View>
<SeparatorComponent />
<View style={styles.headerFooter}>
<Text>FOOTER</Text>
<Text>LIST FOOTER</Text>
</View>
</View>
);
Expand All @@ -120,7 +120,7 @@ class HeaderComponent extends React.PureComponent {
return (
<View>
<View style={styles.headerFooter}>
<Text>HEADER</Text>
<Text>LIST HEADER</Text>
</View>
<SeparatorComponent />
</View>
Expand Down Expand Up @@ -164,7 +164,7 @@ function hashCode(str: string): number {
return hash;
}

const HEADER = {height: 30, width: 80};
const HEADER = {height: 30, width: 100};
const SEPARATOR_HEIGHT = StyleSheet.hairlineWidth;

function getItemLayout(data: any, index: number, horizontal?: boolean) {
Expand Down
24 changes: 15 additions & 9 deletions Examples/UIExplorer/js/SectionListExample.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ const UIExplorerPage = require('./UIExplorerPage');
const infoLog = require('infoLog');

const {
HeaderComponent,
FooterComponent,
ItemComponent,
PlainInput,
Expand All @@ -53,10 +54,10 @@ const SectionHeaderComponent = ({section}) => (
</View>
);

const SectionSeparatorComponent = () => (
const CustomSeparatorComponent = ({text}) => (
<View>
<SeparatorComponent />
<Text style={styles.sectionSeparatorText}>SECTION SEPARATOR</Text>
<Text style={styles.separatorText}>{text}</Text>
<SeparatorComponent />
</View>
);
Expand Down Expand Up @@ -94,20 +95,25 @@ class SectionListExample extends React.PureComponent {
</View>
<SeparatorComponent />
<SectionList
FooterComponent={FooterComponent}
ListHeaderComponent={HeaderComponent}
ListFooterComponent={FooterComponent}
ItemComponent={this._renderItemComponent}
SectionHeaderComponent={SectionHeaderComponent}
SectionSeparatorComponent={SectionSeparatorComponent}
SeparatorComponent={SeparatorComponent}
SectionSeparatorComponent={() => <CustomSeparatorComponent text="SECTION SEPARATOR" />}
ItemSeparatorComponent={() => <CustomSeparatorComponent text="ITEM SEPARATOR" />}
enableVirtualization={this.state.virtualized}
onRefresh={() => alert('onRefresh: nothing to refresh :P')}
onViewableItemsChanged={this._onViewableItemsChanged}
refreshing={false}
sections={[
{ItemComponent: StackedItemComponent, key: 's1', data: [
{title: 'Item In Header Section', text: 's1', key: '0'}
{title: 'Item In Header Section', text: 'Section s1', key: '0'},
]},
{key: 's2', data: filteredData},
{key: 's2', data: [
{noImage: true, title: 'First item', text: 'Section s2', key: '0'},
{noImage: true, title: 'Second item', text: 'Section s2', key: '1'},
]},
{key: 'Filtered Items', data: filteredData},
]}
viewablePercentThreshold={100}
/>
Expand Down Expand Up @@ -143,11 +149,11 @@ const styles = StyleSheet.create({
searchRow: {
paddingHorizontal: 10,
},
sectionSeparatorText: {
separatorText: {
color: 'gray',
alignSelf: 'center',
padding: 4,
fontWeight: 'bold',
fontSize: 9,
},
});

Expand Down
40 changes: 24 additions & 16 deletions Libraries/Experimental/SectionList.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,27 +66,30 @@ type RequiredProps<SectionT: SectionBase<*>> = {
};

type OptionalProps<SectionT: SectionBase<*>> = {
/**
* Rendered after the last item in the last section.
*/
FooterComponent?: ?ReactClass<*>,
/**
* Default renderer for every item in every section.
*/
ItemComponent: ReactClass<{item: Item, index: number}>,
/**
* Rendered at the top of each section. In the future, a sticky option will be added.
* Rendered in between adjacent Items within each section.
*/
SectionHeaderComponent?: ?ReactClass<{section: SectionT}>,
ItemSeparatorComponent?: ?ReactClass<*>,
/**
* Rendered at the bottom of every Section, except the very last one, in place of the normal
* SeparatorComponent.
* Rendered at the very beginning of the list.
*/
SectionSeparatorComponent?: ?ReactClass<*>,
ListHeaderComponent?: ?ReactClass<*>,
/**
* Rendered at the bottom of every Item except the very last one in the last section.
* Rendered at the very end of the list.
*/
SeparatorComponent?: ?ReactClass<*>,
ListFooterComponent?: ?ReactClass<*>,
/**
* Rendered at the top of each section. Sticky headers are not yet supported.
*/
SectionHeaderComponent?: ?ReactClass<{section: SectionT}>,
/**
* Rendered in between each section.
*/
SectionSeparatorComponent?: ?ReactClass<*>,
/**
* Warning: Virtualization can drastically improve memory consumption for long lists, but trashes
* the state of items when they scroll out of the render window, so make sure all relavent data is
Expand Down Expand Up @@ -143,11 +146,16 @@ class SectionList<SectionT: SectionBase<*>>
static defaultProps: DefaultProps = VirtualizedSectionList.defaultProps;

render() {
if (this.props.legacyImplementation) {
return <MetroListView {...this.props} items={this.props.sections} />;
} else {
return <VirtualizedSectionList {...this.props} />;
}
const {ListFooterComponent, ListHeaderComponent, ItemSeparatorComponent} = this.props;
const List = this.props.legacyImplementation ? MetroListView : VirtualizedSectionList;
return (
<List
{...this.props}
FooterComponent={ListFooterComponent}
HeaderComponent={ListHeaderComponent}
SeparatorComponent={ItemSeparatorComponent}
/>
);
}
}

Expand Down
20 changes: 12 additions & 8 deletions Libraries/Experimental/VirtualizedSectionList.js
Original file line number Diff line number Diff line change
Expand Up @@ -163,14 +163,18 @@ class VirtualizedSectionList<SectionT: SectionBase>
const defaultKeyExtractor = this.props.keyExtractor;
for (let ii = 0; ii < this.props.sections.length; ii++) {
const section = this.props.sections[ii];
const keyExtractor = section.keyExtractor || defaultKeyExtractor;
const key = keyExtractor(section, ii);
const key = section.key;
warning(
key != null,
'VirtualizedSectionList: A `section` you supplied is missing the `key` property.'
);
itemIndex -= 1; // The section itself is an item
if (itemIndex >= section.data.length) {
itemIndex -= section.data.length;
} else if (itemIndex === -1) {
return {section, key, index: null};
} else {
const keyExtractor = section.keyExtractor || defaultKeyExtractor;
return {
section,
key: key + ':' + keyExtractor(section.data[itemIndex], itemIndex),
Expand Down Expand Up @@ -216,7 +220,8 @@ class VirtualizedSectionList<SectionT: SectionBase>
if (!info) {
return null;
} else if (info.index == null) {
return <this.props.SectionHeaderComponent section={info.section} />;
const {SectionHeaderComponent} = this.props;
return SectionHeaderComponent ? <SectionHeaderComponent section={info.section} /> : null;
} else {
const ItemComponent = info.section.ItemComponent || this.props.ItemComponent;
const SeparatorComponent = this._getSeparatorComponent(index, info);
Expand All @@ -236,13 +241,12 @@ class VirtualizedSectionList<SectionT: SectionBase>
}
const SeparatorComponent = info.section.SeparatorComponent || this.props.SeparatorComponent;
const {SectionSeparatorComponent} = this.props;
const lastItemIndex = this.state.childProps.getItemCount() - 1;
if (SectionSeparatorComponent &&
info.index === info.section.data.length - 1 &&
index < lastItemIndex) {
const isLastItemInList = index === this.state.childProps.getItemCount() - 1;
const isLastItemInSection = info.index === info.section.data.length - 1;
if (SectionSeparatorComponent && isLastItemInSection && !isLastItemInList) {
return SectionSeparatorComponent;
}
if (SeparatorComponent && index < lastItemIndex) {
if (SeparatorComponent && !isLastItemInSection && !isLastItemInList) {
return SeparatorComponent;
}
return null;
Expand Down

1 comment on commit 6283878

@hramos
Copy link
Contributor

@hramos hramos commented on 6283878 Feb 22, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This commit is breaking open source tests in Circle and will be reverted in #12526.

Please sign in to comment.