Skip to content

Commit

Permalink
Merge de8361b into 002f4bf
Browse files Browse the repository at this point in the history
  • Loading branch information
daybrush committed Jun 12, 2018
2 parents 002f4bf + de8361b commit a0152aa
Show file tree
Hide file tree
Showing 19 changed files with 907 additions and 136 deletions.
1 change: 1 addition & 0 deletions packages/react-infinitegrid/.eslintrc
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"extends": ["naver"],
"rules": {
"array-element-newline": 0,
"comma-dangle": ["error", {
"arrays": "always-multiline",
"objects": "always-multiline",
Expand Down
29 changes: 14 additions & 15 deletions packages/react-infinitegrid/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

A react component that can easily use [egjs-infinitegrid](https://github.com/naver/egjs-infinitegrid)

* Demo
* [Demo](https://935xz7zy8r.codesandbox.io/)
* [API Documentation](https://github.com/naver/egjs-infinitegrid/wiki/react-infinitegrid-API-documentation)

## Install
Expand All @@ -23,6 +23,7 @@ import {GridLayout} from "@egjs/react-infinitegrid";
isOverflowScroll = {false}
isEqualSize = {false}
isConstantSize = {false}
useFit = {true}
useRecycle = {true}
horizontal = {false}
percentage = {false}
Expand All @@ -33,19 +34,17 @@ import {GridLayout} from "@egjs/react-infinitegrid";
onChange = {e => chnage}>
<Item groupKey={0} key={0}/>
<Item groupKey={0} key={1}/>
<Item groupKey={0} key={2}/>
<Item groupKey={0} key={3}/>
<Item groupKey={0} key={4}/>
<Item groupKey={0} key={5}/>
<Item groupKey={0} key={6}/>
<Item groupKey={1} key={2}/>
<Item groupKey={1} key={3}/>
<Item groupKey={2} key={4}/>
<Item groupKey={2} key={5}/>
<Item groupKey={2} key={6}/>
</GridLayout>
```

### More examples
```jsx
this.loading = (<div className="loading">Loading... append</div>);
this.state = {
loading: false,
list: loadItems(0, 0),
};
loadItems = (groupKey, start) => {
Expand All @@ -56,24 +55,24 @@ loadItems = (groupKey, start) => {
}
return items;
}
onAppend = ({groupKey}) => {
onAppend = ({groupKey, startLoading}) => {
const list = this.state.list;
const start = list.length;
const items = this.loadItems(groupKey + 1, start);

this.setState({loading: this.loading, list: list.concat(items)});
startLoading();
this.setState({list: list.concat(items)});
}
onLayoutComplete = ({isLayout}) => {
!isLayout && this.setState({loading: false});
onLayoutComplete = ({isLayout, endLoading}) => {
!isLayout && endLoading();
}
render() {
return (<GridLayout onAppend={this.onAppend}
onLayoutComplete={this.onLayoutComplete}
loading={this.state.loading}>
loading={<div className="loading">Loading... append</div>}>
{this.state.list}
</GridLayout>);
}

```

## Development
Expand All @@ -90,7 +89,7 @@ If you find a bug, please report it to us using the [Issues](https://github.com/


## License
react-layout is released under the [MIT license](https://github.com/naver/egjs-infinitegrid/blob/master/LICENSE).
react-infinitegrid is released under the [MIT license](https://github.com/naver/egjs-infinitegrid/blob/master/LICENSE).


```
Expand Down
1 change: 1 addition & 0 deletions packages/react-infinitegrid/__snapshots__/test layout.md
Original file line number Diff line number Diff line change
Expand Up @@ -538,6 +538,7 @@ Object {
"layout": false,
"processing": 0,
"requestIndex": 0,
"requestKey": 0,
"startIndex": 0,
"startKey": 0,
},
Expand Down
8 changes: 8 additions & 0 deletions packages/react-infinitegrid/examples/html/Youtube.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@

<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
<div class="demobox">
<div id="root"></div>
</div>

<script src="../build/commons.js"></script>
<script src="../build/Youtube.js"></script>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
80 changes: 80 additions & 0 deletions packages/react-infinitegrid/examples/js/Youtube.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import React from "react";
import ReactDOM from "react-dom";
// import { GridLayout } from "@egjs/react-infinitegrid";
import { GridLayout } from "../../src/index";
import getNextPage from "./Youtube/api";
import Header from "./Youtube/Header";
import Item from "./Youtube/Item";
import "./Youtube/index.css";

function getItems(items, groupKey, start) {
return items.map((props, i) => (
<Item groupKey={groupKey} key={`item${start + i}`} {...props} />
));
}
const Message = ({ message }) => (message ? <div className="nomore">{message}</div> : null);

class App extends React.Component {
constructor(props) {
super(props);
this.state = {
list: [],
nextPageToken: "",
query: "",
message: "",
};
}
onSearch = query => {
document.body.scrollTop = 0;
this.setState({query, list: [], nextPageToken: "", message: ""});
};
onAppend = e => {
const groupKey = parseFloat(e.groupKey || 0) + 1;
const pageToken = this.state.nextPageToken;

if (pageToken === -1) {
return;
}
e.startLoading();
getNextPage(this.state.query, pageToken).then(result => {
const {nextPageToken, items, error} = result;
const list = this.state.list;
const length = items.length;
const message =
error ||
(!nextPageToken &&
!list.length &&
`No results found for ${this.state.query}`);

this.setState({
message,
nextPageToken: (length && nextPageToken) || -1,
list: error ? [] : list.concat(getItems(items, groupKey, list.length))
});
(message || !length) && e.endLoading();
});
};
onLayoutComplete = e => {
!e.isLayout && e.endLoading();
};
render() {
return (
<div>
<Header onSearch={this.onSearch} />
<GridLayout
id="grid"
isEqualSize={true}
align="center"
onAppend={this.onAppend}
loading={<div className="loading">LOADING...</div>}
onLayoutComplete={this.onLayoutComplete}
>
{this.state.list}
</GridLayout>
<Message message={this.state.message} />
</div>
);
}
}

ReactDOM.render(<App />, document.getElementById("root"));
67 changes: 67 additions & 0 deletions packages/react-infinitegrid/examples/js/Youtube/Header.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import React from "react";
import ReactDOM from "react-dom";

export default class Header extends React.Component {
search = () => {
const query = this.input.value;

if (!query) {
this.input.focus();
return;
}
this.input.blur();
this.props.onSearch(query);
};
render() {
return (
<header className="header">
<div className="search">
<div className="search-input">
<input
type="text"
className="query"
placeholder="Search..."
ref={e => {
e && (this.input = e);
}}
onKeyUp={e => {
if (!this.input || e.keyCode !== 13) {
return;
}
this.search();
}}
/>
</div>
<button className="submit" onClick={this.search} />
</div>
<div className="menu">
<a href="https://github.com/naver/egjs-infinitegrid/tree/master/packages/react-infinitegrid" target="_blank">Github</a>
<a href="https://codesandbox.io/s/935xz7zy8r" target="_blank">Code</a>
<a href="https://github.com/naver/egjs-infinitegrid/wiki/react-infinitegrid-API-documentation" target="_blank">API</a>
</div>
</header>
);
}
componentDidMount() {
const header = ReactDOM.findDOMNode(this);
const search = header.querySelector(".search");
const menu = header.querySelector(".menu");
const scroll = e => {
const scrollTop =
window.pageYOffset ||
document.body.scrollTop ||
document.documentElement.scrollTop;
const height = 300 - Math.min(scrollTop, 220);
const scale = (Math.min(130, height) + 70) / 200;
const opacity = Math.max(0, 220 - scrollTop) / 220;

header.style.height = `${height}px`;
search.style.transform = `scale(${scale})`;
menu.style.opacity = opacity;
menu.style.display = opacity ? "block" : "none";
};

window.addEventListener("scroll", scroll);
scroll();
}
}
28 changes: 28 additions & 0 deletions packages/react-infinitegrid/examples/js/Youtube/Item.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React from "react";

const Item = ({
link,
width,
height,
title,
url,
channelLink,
channelTitle,
}) => (<div className="item">
<a href={link} target="_blank">
<span className="image-container">
<img
data-width={width}
data-height={height}
src={url}
alt="thumbnail"
/>
</span>
<span className="title">{title}</span>
</a>
<a href={channelLink} target="_blank">
<span className="channel">{channelTitle}</span>
</a>
</div>);

export default Item;
45 changes: 45 additions & 0 deletions packages/react-infinitegrid/examples/js/Youtube/api.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import fetch from "./mock";

function getItems(items) {
return items.filter(item => item.id && item.id.videoId).map(item => {
const {id, snippet} = item;
const {title, thumbnails, channelTitle, channelId} = snippet;
const {width, height, url} = thumbnails.medium;
const link = `https://www.youtube.com/watch?v=${id.videoId}`;
const channelLink = `https://www.youtube.com/channel/${channelId}`;

return {
link,
width,
height,
url,
title,
channelLink,
channelTitle,
};
});
}
// https://developers.google.com/youtube/v3/
// This key is only allowed on naver.github.io, 935xz7zy8r.codesandbox.io/
// use mock.js
const key = "";

export default function getNextPage(query, pageToken) {
const urls = [
"https://www.googleapis.com/youtube/v3/search?part=snippet",
`q=${query}`,
`key=${key}`,
`maxResults=30`,
];

pageToken && urls.push(`pageToken=${pageToken}`);

return fetch(urls.join("&"))
.then(e => e.json())
.then(e => (e.error ? Promise.reject({error: e.error.message}) : e))
.then(({nextPageToken, items}) => ({
nextPageToken,
items: getItems(items),
}))
.catch(e => ({error: e.error || "ERR", nextPageToken: -1, items: []}));
}
Loading

0 comments on commit a0152aa

Please sign in to comment.