-
Notifications
You must be signed in to change notification settings - Fork 734
Create new GridList component based on old GridView #1914
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
Changes from 2 commits
c76c2e5
21fe9a3
5d2c319
417ecee
9371830
fbd2df3
e6b0d17
1d2accd
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 |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import React, {Component} from 'react'; | ||
import {StyleSheet} from 'react-native'; | ||
import {View, Text, Constants, GridList, Card, Spacings, BorderRadiuses, GridListProps} from 'react-native-ui-lib'; | ||
import products from '../../data/products'; | ||
|
||
class GridListScreen extends Component { | ||
state = { | ||
orientation: Constants.orientation | ||
}; | ||
|
||
renderItem: GridListProps<typeof products[0]>['renderItem'] = ({item}) => { | ||
return ( | ||
<Card flex> | ||
<Card.Section imageSource={{uri: item.mediaUrl}} imageStyle={styles.itemImage}/> | ||
<View padding-s2> | ||
<Text>{item.name}</Text> | ||
<Text>{item.formattedPrice}</Text> | ||
{item.inventory.status === 'Out of Stock' && ( | ||
<Text text90M red30> | ||
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. Consider using 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. Fixed |
||
{item.inventory.status} | ||
</Text> | ||
)} | ||
</View> | ||
</Card> | ||
); | ||
}; | ||
|
||
render() { | ||
return ( | ||
<GridList<typeof products[0]> | ||
ListHeaderComponent={ | ||
<Text h1 marginB-s5> | ||
GridList | ||
</Text> | ||
} | ||
data={products} | ||
renderItem={this.renderItem} | ||
// numColumns={2} | ||
maxItemWidth={140} | ||
itemSpacing={Spacings.s3} | ||
listPadding={Spacings.s5} | ||
// keepItemSize | ||
contentContainerStyle={styles.list} | ||
/> | ||
); | ||
} | ||
} | ||
|
||
const styles = StyleSheet.create({ | ||
list: { | ||
padding: Spacings.s5 | ||
}, | ||
itemImage: { | ||
width: '100%', | ||
height: 85, | ||
borderRadius: BorderRadiuses.br10 | ||
} | ||
}); | ||
|
||
export default GridListScreen; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
/// <reference types="react" /> | ||
import { FlatListProps } from 'react-native'; | ||
export interface GridListProps<T> extends FlatListProps<T> { | ||
/** | ||
* Allow a responsive item width to the maximum item width | ||
*/ | ||
maxItemWidth?: number; | ||
/** | ||
* Number of items to show in a row (ignored when passing maxItemWidth) | ||
*/ | ||
numColumns?: number; | ||
/** | ||
* Spacing between each item | ||
*/ | ||
itemSpacing?: number; | ||
/** | ||
* List padding (used for item size calculation) | ||
*/ | ||
listPadding?: number; | ||
/** | ||
* whether to keep the items initial size when orientation changes, | ||
* in which case the apt number of columns will be calculated automatically. | ||
* Ignored when passing 'maxItemWidth' | ||
*/ | ||
keepItemSize?: boolean; | ||
/** | ||
* Pass when you want to use a custom container width for calculation (good for when list has outer padding) | ||
*/ | ||
containerWidth?: number; | ||
} | ||
declare function GridList<T = any>(props: GridListProps<T>): JSX.Element; | ||
export default GridList; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
{ | ||
"name": "GridList", | ||
"category": "layoutsAndTemplates", | ||
"description": "An auto-generated grid list that calculate item size according to given props", | ||
"extends": ["FlatList"], | ||
"example": "https://github.com/wix/react-native-ui-lib/blob/master/demo/src/screens/componentScreens/GridListScreen.tsx", | ||
"props": [ | ||
{"name": "numColumns", "type": "number", "description": "Number of items to show in a row"}, | ||
ethanshar marked this conversation as resolved.
Show resolved
Hide resolved
|
||
{"name": "itemSpacing", "type": "number", "description": "Spacing between each item"}, | ||
{ | ||
"name": "maxItemWidth", | ||
"type": "number", | ||
"description": "Allow a responsive item width to the maximum item width" | ||
}, | ||
{ | ||
"name": "listPadding", | ||
"type": "number", | ||
"description": "List padding (used for item size calculation)" | ||
}, | ||
{ | ||
"name": "containerWidth", | ||
"type": "number", | ||
"description": "Pass when you want to use a custom container width for calculation" | ||
}, | ||
{ | ||
"name": "keepItemSize", | ||
"type": "boolean", | ||
"description": "whether to keep the items initial size when orientation changes, in which case the apt number of columns will be calculated automatically." | ||
} | ||
], | ||
"snippet": [ | ||
"<GridList>", | ||
" data={items$1}", | ||
" maxItemWidth={140$2}", | ||
" numColumns={2$3}", | ||
" itemSpacing={Spacings.s3$4}", | ||
" containerWidth={Constants.screenWidth - (Spacings.s5 * 2)}", | ||
" contentContainerStyle={{padding: Spacings.s5}}", | ||
"/>" | ||
] | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
import React, {useCallback, useMemo} from 'react'; | ||
import {FlatList, FlatListProps} from 'react-native'; | ||
import {Spacings} from 'style'; | ||
import {useOrientation} from 'hooks'; | ||
import {Constants} from '../../commons/new'; | ||
import View from '../view'; | ||
|
||
const DEFAULT_NUM_COLUMNS = 3; | ||
const DEFAULT_ITEM_SPACINGS = Spacings.s4; | ||
|
||
export interface GridListProps<T> extends FlatListProps<T> { | ||
/** | ||
* Allow a responsive item width to the maximum item width | ||
*/ | ||
maxItemWidth?: number; | ||
/** | ||
* Number of items to show in a row (ignored when passing maxItemWidth) | ||
*/ | ||
numColumns?: number; | ||
/** | ||
* Spacing between each item | ||
*/ | ||
itemSpacing?: number; | ||
/** | ||
* List padding (used for item size calculation) | ||
*/ | ||
listPadding?: number; | ||
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. The
There is no padding on the right side. Or:
It looks like the right item is a little out of the screen 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. Well, technically the |
||
/** | ||
* whether to keep the items initial size when orientation changes, | ||
* in which case the apt number of columns will be calculated automatically. | ||
* Ignored when passing 'maxItemWidth' | ||
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.
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. Left overs from the old grid view implementation, removed |
||
*/ | ||
keepItemSize?: boolean; | ||
/** | ||
* Pass when you want to use a custom container width for calculation | ||
*/ | ||
containerWidth?: number; | ||
} | ||
|
||
function GridList<T = any>(props: GridListProps<T>) { | ||
const { | ||
renderItem, | ||
numColumns = DEFAULT_NUM_COLUMNS, | ||
itemSpacing = DEFAULT_ITEM_SPACINGS, | ||
maxItemWidth, | ||
listPadding = 0, | ||
keepItemSize, | ||
...others | ||
} = props; | ||
|
||
const {orientation} = useOrientation(); | ||
|
||
const containerWidth = useMemo(() => { | ||
return (props.containerWidth ?? Constants.screenWidth) - listPadding * 2; | ||
// eslint-disable-next-line react-hooks/exhaustive-deps | ||
}, [listPadding, orientation]); | ||
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. Shouldn't 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 containerWidth (the comment still relevant because of the orientation dep) |
||
|
||
const numberOfColumns = useMemo(() => { | ||
if (maxItemWidth) { | ||
return Math.ceil((containerWidth + itemSpacing) / (maxItemWidth + itemSpacing)); | ||
} else { | ||
return numColumns; | ||
} | ||
// eslint-disable-next-line react-hooks/exhaustive-deps | ||
}, [numColumns, maxItemWidth, itemSpacing, keepItemSize ? containerWidth : undefined]); | ||
|
||
const itemSize = useMemo(() => { | ||
return (containerWidth - itemSpacing * (numberOfColumns - 1)) / numberOfColumns; | ||
|
||
// eslint-disable-next-line react-hooks/exhaustive-deps | ||
}, [numberOfColumns, itemSpacing, keepItemSize ? undefined : containerWidth]); | ||
|
||
const itemContainerStyle = useMemo(() => { | ||
return {width: itemSize + itemSpacing, paddingRight: itemSpacing, marginBottom: itemSpacing}; | ||
}, [itemSize, itemSpacing]); | ||
|
||
const _renderItem = useCallback((...args) => { | ||
// @ts-expect-error | ||
return <View style={[itemContainerStyle]}>{renderItem?.(...args)}</View>; | ||
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 for the 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. True, removed |
||
}, | ||
[renderItem, itemContainerStyle]); | ||
|
||
return <FlatList key={numberOfColumns} {...others} renderItem={_renderItem} numColumns={numberOfColumns}/>; | ||
} | ||
|
||
export default GridList; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -69,6 +69,9 @@ export default { | |
get GridListItem() { | ||
return require('./components/gridListItem').default; | ||
}, | ||
get GridList() { | ||
return require('./components/gridList').default; | ||
}, | ||
get GridView() { | ||
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. Do we want to deprecate 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. Yes, definitely, I'll create a separate ticket for that |
||
return require('./components/gridView').default; | ||
}, | ||
|
Uh oh!
There was an error while loading. Please reload this page.
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.
Consider adding
$textDefault
for the texts inside the card